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 } }