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