2159 lines
79 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Layout
{
/// <summary>
/// Represents the base item for layout control.
/// </summary>
[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
/// <summary>
/// Initializes a new instance of the LayoutItemBase class.
/// </summary>
public LayoutItemBase()
{
_Style = new SimpleStyle();
_Style.PropertyChanged += StylePropertyChanged;
}
#endregion
#region Implementation
/// <summary>
/// Paints the item. Actual code doing painting goes into the OnPaint method which should be overridden.
/// </summary>
/// <param name="context">Provides Paint Context.</param>
internal void Paint(PaintContext context)
{
OnPaint(context);
}
/// <summary>
/// Paints the background of the item.
/// </summary>
/// <param name="context"></param>
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);
}
/// <summary>
/// Actual painting implementation.
/// </summary>
/// <param name="context"></param>
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);
}
/// <summary>
/// Returns whether strip text base line value is used when calculating position of the rendered text label.
/// </summary>
protected bool UseStripBaseline
{
get
{
return TextBaseLineEnabled && TextPosition == eLayoutPosition.Default && (!IsImageVisible || IsImageVisible && (_ImagePosition == eLayoutPosition.Default || _ImagePosition == eLayoutPosition.Left || _ImagePosition == eLayoutPosition.Right));
}
}
private bool _TextBaseLineEnabled = true;
/// <summary>
/// Indicates whether shared text baseline between items is enabled so the text-base aligns.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when TextBaseLineEnabled property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTextBaseLineEnabledChanged(bool oldValue, bool newValue)
{
UpdateTextBounds();
this.Invalidate();
OnPropertyChanged(new PropertyChangedEventArgs("TextBaseLineEnabled"));
}
private static readonly Color SelectionColor = ColorHelpers.GetColor(0x696969);
/// <summary>
/// Paints the selection adorner around the item.
/// </summary>
/// <param name="context"></param>
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);
}
}
/// <summary>
/// Updates bounds of the item in response to the scrolling of LayoutControl.
/// </summary>
/// <param name="xScroll"></param>
/// <param name="yScroll"></param>
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;
/// <summary>
/// Gets the bounds of the item.
/// </summary>
[Browsable(false)]
public virtual Rectangle Bounds
{
get
{
return _Bounds;
}
}
/// <summary>
/// Processes accelerator key for the item.
/// </summary>
/// <param name="charCode"></param>
internal virtual bool ProcessMnemonic(char charCode)
{
return false;
}
/// <summary>
/// Sets new bounds of the item.
/// </summary>
/// <param name="r">New bounds.</param>
public virtual void SetBounds(Rectangle r)
{
_Bounds = r;
UpdateLayout();
}
/// <summary>
/// Sets new bounds of the item and actual text size.
/// </summary>
/// <param name="r"></param>
/// <param name="actualTextSize"></param>
public virtual void SetBounds(Rectangle r, Size actualTextSize)
{
_Bounds = r;
ActualTextSize = actualTextSize;
UpdateLayout();
}
/// <summary>
/// Updates the item layout. Actual layout is performed in OnUpdateLayout method.
/// </summary>
internal void UpdateLayout()
{
OnUpdateLayout();
}
/// <summary>
/// Actual layout update implementation.
/// </summary>
protected virtual void OnUpdateLayout()
{
UpdateTextBounds();
}
/// <summary>
/// Updates the layout of the text inside of item.
/// </summary>
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);
}
}
/// <summary>
/// Scales item in response to the scaling of the LayoutControl. Should never be called directly.
/// </summary>
/// <param name="factor"></param>
[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;
}
}
/// <summary>
/// Measures the size of the item text. Actual measurement is done in OnMeasureText method.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Returns the size of the items text.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
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;
//<summary>
// Returns the real text-size for the text label that is valid after MeasureText is called.
//</summary>
[Browsable(false)]
public Size RealTextSize
{
get
{
return _RealTextSize;
}
}
private int _StripTextBaseline = 0;
/// <summary>
/// Gets or sets the text-baseline that is used by whole strip.
/// </summary>
internal virtual int StripTextBaseline
{
get { return _StripTextBaseline; }
set
{
_StripTextBaseline = value;
}
}
private int _TextBaseline = 0;
/// <summary>
/// Returns the text base line.
/// </summary>
internal virtual int TextBaseline
{
get
{
return _TextBaseline;
}
set
{
_TextBaseline = value;
}
}
private object _Tag = "";
/// <summary>
/// Gets or sets an object that contains additional data attached to the item.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Tag property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTagChanged(object oldValue, object newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Tag"));
}
private string _Text = "";
/// <summary>
/// Indicates the item caption.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Text property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTextChanged(string oldValue, string newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Text"));
MarkupTextChanged();
InvalidateLayout();
}
private Size _TextSize = Size.Empty;
/// <summary>
/// Gets or sets the explicit size of the text part of item.
/// </summary>
[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;
}
/// <summary>
/// Called when TextSize property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTextSizeChanged(Size oldValue, Size newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("TextSize"));
InvalidateLayout();
}
private Rectangle _ActualTextBounds = Rectangle.Empty;
/// <summary>
/// Gets actual text bounds.
/// </summary>
[Browsable(false)]
public Rectangle ActualTextBounds
{
get
{
return _ActualTextBounds;
}
internal set
{
_ActualTextBounds = value;
}
}
private Size _ActualTextSize = Size.Empty;
/// <summary>
/// Gets actual text-size as used by the layout item.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
public Size ActualTextSize
{
get { return _ActualTextSize; }
internal set
{
if (value != _ActualTextSize)
{
Size oldValue = _ActualTextSize;
_ActualTextSize = value;
OnActualTextSizeChanged(oldValue, value);
}
}
}
/// <summary>
/// Called when ActualTextSize property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
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);
/// <summary>
/// Gets or sets text padding.
/// </summary>
[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);
}
/// <summary>
/// Called when TextPadding property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
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;
/// <summary>
/// Indicates whether caption/text is visible.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when TextVisible property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTextVisibleChanged(bool oldValue, bool newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("TextVisible"));
InvalidateLayout();
}
private eLayoutPosition _TextPosition = eLayoutPosition.Default;
/// <summary>
/// Gets or sets the text position in relation to the other parts of the layout item. Default is same as Left.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when TextPosition property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTextPositionChanged(eLayoutPosition oldValue, eLayoutPosition newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("TextPosition"));
InvalidateLayout();
}
private int _Width = 0;
/// <summary>
/// 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.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Width property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnWidthChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Width"));
InvalidateLayout();
}
private eLayoutSizeType _WidthType = eLayoutSizeType.Absolute;
/// <summary>
/// Indicates width type used by the item.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when WidthType property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnWidthTypeChanged(eLayoutSizeType oldValue, eLayoutSizeType newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("WidthType"));
InvalidateLayout();
}
/// <summary>
/// Indicates whether width type is the fixed width type, different than eLayoutSizeType.Percent
/// </summary>
[Browsable(false)]
public bool IsWidthFixed
{
get
{
return (_WidthType != eLayoutSizeType.Percent);
}
}
private int _Height = 0;
/// <summary>
/// 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.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Height property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnHeightChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Height"));
InvalidateLayout();
}
private eLayoutSizeType _HeightType = eLayoutSizeType.Absolute;
/// <summary>
/// Indicates height type used by the item.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when HeightType property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnHeightTypeChanged(eLayoutSizeType oldValue, eLayoutSizeType newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("HeightType"));
InvalidateLayout();
}
/// <summary>
/// Indicates whether height type is the fixed height type, different than eLayoutSizeType.Percent
/// </summary>
[Browsable(false)]
public bool IsHeightFixed
{
get
{
return (_HeightType != eLayoutSizeType.Percent);
}
}
private Size _MinSize = Size.Empty;
/// <summary>
/// Indicates the minimum size of the item. Setting Width or Height to zero indicates unconstrained minimum size for given dimension.
/// </summary>
[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;
}
/// <summary>
/// Called when MinSize property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnMinSizeChanged(Size oldValue, Size newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("MinSize"));
InvalidateLayout();
}
private int _SuggestedGroupId = 0;
/// <summary>
/// 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.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when SuggestedGroupId property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnSuggestedGroupIdChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("SuggestedGroupId"));
}
private bool _MnemonicsEnabled = true;
/// <summary>
/// Indicates whether accelerator keys assigned to item Text property are processed by items which respond to them.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when MnemonicsEnabled property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnMnemonicsEnabledChanged(bool oldValue, bool newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("MnemonicsEnabled"));
}
private SimpleStyle _Style;
/// <summary>
/// Gets the style for the background of the control.
/// </summary>
[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;
/// <summary>
/// Specifies the amount of padding inside of the item. Padding is the spacing between the edges of item and its content.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Padding property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
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;
/// <summary>
/// Indicates the absolute index of the item inside of the LayoutControl.
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int AbsoluteIndex
{
get { return _AbsoluteIndex; }
internal set
{
if (value != _AbsoluteIndex)
{
int oldValue = _AbsoluteIndex;
_AbsoluteIndex = value;
OnAbsoluteIndexChanged(oldValue, value);
}
}
}
/// <summary>
/// Called when AbsoluteIndex property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnAbsoluteIndexChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("AbsoluteIndex"));
}
/// <summary>
/// Returns the LayoutControl which hosts the item, if available.
/// </summary>
/// <returns>reference to LayoutControl or null.</returns>
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;
}
/// <summary>
/// Invalidates the paint region of the item.
/// </summary>
public void Invalidate()
{
LayoutControl control = GetLayoutControl();
if (control != null)
control.Invalidate(_Bounds);
}
/// <summary>
/// Invalidates layout of the item and causes the LayoutControl to perform layout.
/// </summary>
public void InvalidateLayout()
{
LayoutControl control = GetLayoutControl();
if (control != null)
{
if (this.DesignMode)
control.Invalidate(true);
control.PerformLayout();
}
}
private LayoutControl _LayoutControl = null;
/// <summary>
/// Gets the LayoutControl this group is directly attached too through RootGroup property.
/// </summary>
[Browsable(false)]
internal LayoutControl LayoutControl
{
get
{
return _LayoutControl;
}
set
{
_LayoutControl = value;
}
}
private LayoutItemBase _Parent = null;
/// <summary>
/// Gets the reference to parent item.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Parent property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnParentChanged(LayoutItemBase oldValue, LayoutItemBase newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Parent"));
}
/// <summary>
/// Returns whether item is contained as child item by this item or one of its children.
/// </summary>
/// <param name="value">Item to check.</param>
/// <returns>true if item is contained otherwise false</returns>
public virtual bool IsChildItem(LayoutItemBase value)
{
return false;
}
private bool _IsKeyboardFocusWithin = false;
/// <summary>
/// Gets whether keyboard focus is within the control which is assigned to the item.
/// </summary>
[Browsable(false)]
public bool IsKeyboardFocusWithin
{
get
{
return _IsKeyboardFocusWithin;
}
internal set
{
if (value != _IsKeyboardFocusWithin)
{
_IsKeyboardFocusWithin = value;
this.Invalidate();
}
}
}
private Image _Image = null;
/// <summary>
/// Indicates the image that is displayed next to the item text label.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Image property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnImageChanged(Image oldValue, Image newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Image"));
this.InvalidateLayout();
}
private int _ImageTextSpacing = 4;
/// <summary>
/// Specifies the distance between image and text.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when ImageTextSpacing property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnImageTextSpacingChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("ImageTextSpacing"));
this.InvalidateLayout();
}
private eLayoutPosition _ImagePosition = eLayoutPosition.Default;
/// <summary>
/// Indicates the position of the image in relation to the text label of item.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when ImagePosition property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnImagePositionChanged(eLayoutPosition oldValue, eLayoutPosition newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("ImagePosition"));
this.InvalidateLayout();
}
private Rectangle _ActualImageBounds = Rectangle.Empty;
/// <summary>
/// Gets actual image bounds if visible or Rectangle.Empty if image is not visible.
/// </summary>
[Browsable(false)]
public Rectangle ActualImageBounds
{
get { return _ActualImageBounds; }
internal set { _ActualImageBounds = value; }
}
private Color _SymbolColor = Color.Empty;
/// <summary>
/// Gets or sets the color of the Symbol.
/// </summary>
[Category("Appearance"), Description("Indicates color of the Symbol.")]
public Color SymbolColor
{
get { return _SymbolColor; }
set { _SymbolColor = value; this.Invalidate(); }
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeSymbolColor()
{
return !_SymbolColor.IsEmpty;
}
/// <summary>
/// Resets property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetSymbolColor()
{
this.SymbolColor = Color.Empty;
}
private Size _SymbolTextSize = Size.Empty;
private string _Symbol = "";
/// <summary>
/// Indicates the symbol displayed on face of the item instead of the image. Setting the symbol overrides the image setting.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Symbol property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnSymbolChanged(string oldValue, string newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Symbol"));
this.InvalidateLayout();
this.Invalidate();
}
private float _SymbolSize = 0f;
/// <summary>
/// Indicates the size of the symbol in points.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when SymbolSize property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnSymbolSizeChanged(float oldValue, float newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("SymbolSize"));
this.InvalidateLayout();
this.Invalidate();
}
private bool _SharedTextSizeEnabled = true;
/// <summary>
/// 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.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when SharedTextSizeEnabled property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnSharedTextSizeEnabledChanged(bool oldValue, bool newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("SharedTextSizeEnabled"));
this.InvalidateLayout();
this.Invalidate();
}
/// <summary>
/// Brings item into view by scrolling the control if necessary.
/// </summary>
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
/// <summary>
/// Occurs when item is disposed.
/// </summary>
[Description("Occurs when item is disposed.")]
public event EventHandler Disposed;
private string _Name = "";
/// <summary>
/// Gets or sets the name of the item.
/// </summary>
[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;
/// <summary>
/// Gets or sets the Site associated with this component. Used by Windows forms designer.
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual System.ComponentModel.ISite Site
{
get
{
return _ComponentSite;
}
set
{
_ComponentSite = value;
}
}
private bool _DesignMode = false;
/// <summary>
/// Returns whether item is in design mode.
/// </summary>
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);
}
}
}
/// <summary>
/// Called when IsSelected property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
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;
/// <summary>
/// Indicates the text alignment within the text bounds. Depending on layout item type not all alignments are available.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when TextAlignment property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTextAlignmentChanged(eTextAlignment oldValue, eTextAlignment newValue)
{
this.InvalidateLayout();
this.Invalidate();
OnPropertyChanged(new PropertyChangedEventArgs("TextAlignment"));
}
private eTextLineAlignment _TextLineAlignment = eTextLineAlignment.Default;
/// <summary>
/// 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.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when TextLineAlignment property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTextLineAlignmentChanged(eTextLineAlignment oldValue, eTextLineAlignment newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("TextLineAlignment"));
this.Invalidate();
}
/// <summary>
/// Gets whether this item text-size is shared with other items inside of its parent group.
/// </summary>
[Browsable(false)]
public virtual bool IsTextSizeShared
{
get
{
return _SharedTextSizeEnabled;
}
}
/// <summary>
/// Gets whether this item's text-baseline is shared with other items inside of its parent group.
/// </summary>
[Browsable(false)]
public virtual bool IsTextBaselineShared
{
get
{
return true;
}
}
private bool _Visible = true;
/// <summary>
/// Indicates visibility of the item.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when Visible property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnVisibleChanged(bool oldValue, bool newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Visible"));
InvalidateLayout();
}
#endregion
#region TextMarkup
/// <summary>
/// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example:
/// <a name="MyLink">Markup link</a>
/// </summary>
[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;
}
/// <summary>
/// Gets reference to parsed markup body element if text was markup otherwise returns null.
/// </summary>
internal TextMarkup.BodyElement TextMarkupBody
{
get { return _TextMarkup; }
}
private bool _TextMarkupEnabled = true;
/// <summary>
/// Gets or sets whether item supports and renders text markup. Default value is true.
/// </summary>
[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();
}
}
}
/// <summary>
/// Gets whether item supports text markup. Default is false.
/// </summary>
protected virtual bool IsMarkupSupported
{
get { return _TextMarkupEnabled; }
}
private bool _IsMouseOver = false;
/// <summary>
/// Gets whether mouse is over the item.
/// </summary>
[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
/// <summary>
/// Occurs after Tooltip text has changed.
/// </summary>
protected virtual void OnTooltipChanged() { }
private string _Tooltip = "";
/// <summary>
/// Gets/Sets informational text (tooltip) for the cell.
/// </summary>
[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();
}
}
/// <summary>
/// Gets whether tooltip is visible or not.
/// </summary>
internal protected bool ToolTipVisible
{
get
{
return (_ToolTipWnd != null);
}
}
/// <summary>
/// Called when tooltip is shown and hidden.
/// </summary>
/// <param name="isShown">true if tooltip is being shown otherwise false.</param>
protected virtual void OnTooltip(bool isShown)
{
}
private DevComponents.DotNetBar.ToolTip _ToolTipWnd = null;
/// <summary>
/// Shows tooltip for this item.
/// </summary>
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();
}
}
/// <summary>
/// Destroys tooltip window.
/// </summary>
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);
}
}
}
/// <summary>
/// Resets Hoover timer.
/// </summary>
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;
}
/// <summary>
/// Occurs when item's tooltip visibility has changed.
/// </summary>
[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;
/// <summary>
/// Gets or sets whether tooltips are shown when mouse is over the item when Tooltip property is set.
/// </summary>
[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
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Provides event arguments.</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, e);
}
/// <summary>
/// Occurs when property on object has changed.
/// </summary>
[Description("Occurs when property on object has changed.")]
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
/// <summary>
/// Specifies how layout items elements should be sized relative to their container.
/// </summary>
public enum eLayoutSizeType
{
/// <summary>
/// The item should be sized to an exact number of pixels.
/// </summary>
Absolute,
/// <summary>
/// The item should be sized as a percentage of the parent container.
/// </summary>
Percent,
}
/// <summary>
/// Contains values that specify how a specific element is positioned relative to another element.
/// </summary>
public enum eLayoutPosition
{
/// <summary>
/// Default location, i.e. left.
/// </summary>
Default = 0,
/// <summary>
/// Item is located at the left edge of another item.
/// </summary>
Left = 1,
/// <summary>
/// Item is located at the right edge of another item.
/// </summary>
Right = 2,
/// <summary>
/// Item is located at the top edge of another item.
/// </summary>
Top = 3,
/// <summary>
/// Item is located at the bottom edge of another item.
/// </summary>
Bottom = 4,
}
/// <summary>
/// Specifies layout text alignment within the text bounds.
/// </summary>
public enum eTextAlignment
{
Default,
Left,
Right,
Center
}
/// <summary>
/// Specifies layout text line alignment within the text bounds.
/// </summary>
public enum eTextLineAlignment
{
Default,
Top,
Middle,
Bottom
}
#region MarkupLinkClickEventArgs
/// <summary>
/// Provides more information about MarkupLinkClick event.
/// </summary>
public class MarkupLinkClickEventArgs : EventArgs
{
/// <summary>
/// Gets the value of href attribute from the markup link that was clicked.
/// </summary>
public readonly string HRef = "";
/// <summary>
/// Gets the value of name attribute from the markup link that was clicked.
/// </summary>
public readonly string Name = "";
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="name">Value of name attribute.</param>
/// <param name="href">Value of href attribute.</param>
public MarkupLinkClickEventArgs(string name, string href)
{
this.HRef = href;
this.Name = name;
}
}
/// <summary>
/// Defines delegate for MarkupLinkClick event.
/// </summary>
public delegate void MarkupLinkClickEventHandler(object sender, MarkupLinkClickEventArgs e);
#endregion
}