using System; using System.Text; using System.Drawing; namespace DevComponents.DotNetBar.Presentation { internal class Shape { #region Private Variables private Location m_Location = new Location(); private SizeInfo m_Size = new SizeInfo(); private ShapeCollection m_Children = null; private PaddingInfo m_Padding = null; private bool m_SetChildClip = false; #endregion #region Internal Implementation /// /// Gets the location of the shape. /// public Location Location { get { return m_Location; } } /// /// Gets the size of the shape. /// public SizeInfo Size { get { return m_Size; } } /// /// Gets the shape padding. Padding is the inside spacing between shape and it's child shapes. /// public PaddingInfo Padding { get { return m_Padding; } set { m_Padding = value; } } /// /// Gets the collection of child shapes. /// public ShapeCollection Children { get { if (m_Children == null) m_Children = new ShapeCollection(); return m_Children; } } /// /// Gets or sets whether this shape will set the ShapePaintInfo.ChildContentClip property to the region that represents the inside content of the shape. /// This is used when there is inside content of the shape which is not part of the shape itself and calling routine needs /// access to the region that defines the shape inside bounds. /// public bool SetChildClip { get { return m_SetChildClip; } set { m_SetChildClip = value; } } /// /// Paints the shape on canvas. If overriden base implementation must be called to paint any child shapes. /// /// Shape paint information. public virtual void Paint(ShapePaintInfo p) { if (m_Children != null && m_Children.Count > 0) { System.Drawing.Rectangle originalBounds = p.Bounds; System.Drawing.Rectangle bounds = new System.Drawing.Rectangle(this.GetLocation(p.Bounds), this.GetSize(p.Bounds)); if (m_Padding != null) { bounds.Width -= m_Padding.HorizontalPadding; bounds.Height -= m_Padding.VerticalPadding; bounds.X += m_Padding.Left; bounds.Y += m_Padding.Top; } p.Bounds = bounds; Region clip = ClipChildren(p.Graphics, bounds); if (m_SetChildClip && p.Graphics.Clip!=null) { p.ChildContentClip = p.Graphics.Clip as Region; } foreach (Shape shape in m_Children) { shape.Paint(p); } if (p.ChildContentClip != null) { p.ChildContentClip.Dispose(); p.ChildContentClip = null; } if (clip != null) { p.Graphics.Clip = clip; clip.Dispose(); } else p.Graphics.ResetClip(); p.Bounds = originalBounds; if (clip != null) clip.Dispose(); } } protected virtual Region ClipChildren(Graphics g, System.Drawing.Rectangle childBounds) { Region clip = g.Clip; g.SetClip(childBounds); return clip; } /// /// Returns absolute location of the shape based on parent bounds. /// /// Parent absolute bounds. /// Absolute location of the shape protected virtual Point GetLocation(System.Drawing.Rectangle bounds) { return GetLocation(bounds, m_Location); } protected virtual Point GetLocation(System.Drawing.Rectangle bounds, Location refLocation) { Point loc = bounds.Location; if (refLocation.RelativeX == eRelativeLocation.Right) loc.X = bounds.Right; else if (refLocation.RelativeX == eRelativeLocation.Top) loc.X = bounds.Y; else if (refLocation.RelativeX == eRelativeLocation.Bottom) loc.X = bounds.Bottom; if (refLocation.RelativeY == eRelativeLocation.Bottom) loc.Y = bounds.Bottom; else if (refLocation.RelativeY == eRelativeLocation.Right) loc.Y = bounds.Right; else if (refLocation.RelativeY == eRelativeLocation.Left) loc.Y = bounds.X; loc.Offset(refLocation.X, refLocation.Y); return loc; } /// /// Returns absolute size of the shape based on the parent bounds. /// /// Absolute parent bounds. /// Absolute size of the shape. protected virtual Size GetSize(System.Drawing.Rectangle bounds) { Size size = bounds.Size; if (m_Size.RelativeWidth == eRelativeSize.Width) size.Width = bounds.Width + m_Size.Width; else if (m_Size.RelativeWidth == eRelativeSize.Height) size.Width = bounds.Height + m_Size.Height; else if (m_Size.Width != 0) size.Width = m_Size.Width; if (m_Size.RelativeHeight == eRelativeSize.Height) size.Height = bounds.Height + m_Size.Height; else if (m_Size.RelativeHeight == eRelativeSize.Width) size.Height = bounds.Width + m_Size.Height; else if (m_Size.Height != 0) size.Height = m_Size.Height; return size; } /// /// Gets the absolute bounds of the shape. /// /// Parent bounds. /// Absolute bounds of the shape. protected virtual System.Drawing.Rectangle GetBounds(System.Drawing.Rectangle parentBounds) { return new System.Drawing.Rectangle(GetLocation(parentBounds), GetSize(parentBounds)); } #endregion } }