1013 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1013 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.ComponentModel;
 | |
| using DevComponents.DotNetBar.Events;
 | |
| using DevComponents.DotNetBar.Rendering;
 | |
| using System.Drawing;
 | |
| using System.Windows.Forms;
 | |
| using System.Threading;
 | |
| 
 | |
| namespace DevComponents.DotNetBar
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Represents the switch button UI element.
 | |
|     /// </summary>
 | |
|     [DefaultEvent("ValueChanged"), DefaultProperty("Value")]
 | |
|     public class SwitchButtonItem : BaseItem
 | |
|     {
 | |
|         #region Events
 | |
|         /// <summary>
 | |
|         /// Occurs before Value property has changed and it allows you to cancel the change.
 | |
|         /// </summary>
 | |
|         public event EventHandler ValueChanging;
 | |
|         /// <summary>
 | |
|         /// Raises ValueChanging event.
 | |
|         /// </summary>
 | |
|         /// <param name="e">Provides event arguments.</param>
 | |
|         protected virtual void OnValueChanging(CancelableEventSourceArgs e)
 | |
|         {
 | |
|             EventHandler handler = ValueChanging;
 | |
|             if (handler != null)
 | |
|                 handler(this, e);
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Occurs after Value property has changed.
 | |
|         /// </summary>
 | |
|         public event EventHandler ValueChanged;
 | |
|         /// <summary>
 | |
|         /// Raises ValueChanged event.
 | |
|         /// </summary>
 | |
|         /// <param name="e">Provides event arguments.</param>
 | |
|         protected virtual void OnValueChanged(EventSourceArgs e)
 | |
|         {
 | |
|             EventHandler handler = ValueChanged;
 | |
|             if (handler != null)
 | |
|                 handler(this, e);
 | |
|         }
 | |
|         #endregion
 | |
| 
 | |
|         #region Constructor
 | |
|         internal static readonly int TextButtonSpacing = 3;
 | |
|         /// <summary>
 | |
|         /// Creates new instance of SwitchButtonItem.
 | |
|         /// </summary>
 | |
|         public SwitchButtonItem() : this("", "") { }
 | |
|         /// <summary>
 | |
|         /// Creates new instance of SwitchButtonItem and assigns the name to it.
 | |
|         /// </summary>
 | |
|         /// <param name="sItemName">Item name.</param>
 | |
|         public SwitchButtonItem(string sItemName) : this(sItemName, "") { }
 | |
|         /// <summary>
 | |
|         /// Creates new instance of SwitchButtonItem and assigns the name and text to it.
 | |
|         /// </summary>
 | |
|         /// <param name="sItemName">Item name.</param>
 | |
|         /// <param name="itemText">item text.</param>
 | |
|         public SwitchButtonItem(string sItemName, string itemText)
 | |
|             : base(sItemName, itemText)
 | |
|         {
 | |
|             _Margin.PropertyChanged += MarginPropertyChanged;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Returns copy of the item.
 | |
|         /// </summary>
 | |
|         public override BaseItem Copy()
 | |
|         {
 | |
|             SwitchButtonItem objCopy = new SwitchButtonItem(m_Name);
 | |
|             this.CopyToItem(objCopy);
 | |
|             return objCopy;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Copies the SwitchButtonItem specific properties to new instance of the item.
 | |
|         /// </summary>
 | |
|         /// <param name="copy">New SwitchButtonItem instance.</param>
 | |
|         internal void InternalCopyToItem(SwitchButtonItem copy)
 | |
|         {
 | |
|             CopyToItem(copy);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Copies the SwitchButtonItem specific properties to new instance of the item.
 | |
|         /// </summary>
 | |
|         /// <param name="copy">New SwitchButtonItem instance.</param>
 | |
|         protected override void CopyToItem(BaseItem copy)
 | |
|         {
 | |
|             SwitchButtonItem objCopy = copy as SwitchButtonItem;
 | |
| 
 | |
|             if (objCopy != null)
 | |
|             {
 | |
|                 objCopy.Value = this.Value;
 | |
|                 objCopy.BorderColor = this.BorderColor;
 | |
|                 objCopy.OffBackColor = this.OffBackColor;
 | |
|                 objCopy.OffText = this.OffText;
 | |
|                 objCopy.OffTextColor = this.OffTextColor;
 | |
|                 objCopy.OnBackColor = this.OnBackColor;
 | |
|                 objCopy.OnText = this.OnText;
 | |
|                 objCopy.OnTextColor = this.OnTextColor;
 | |
|                 objCopy.SwitchBackColor = this.SwitchBackColor;
 | |
|                 objCopy.SwitchBorderColor = this.SwitchBorderColor;
 | |
|                 objCopy.SwitchWidth = this.SwitchWidth;
 | |
|                 objCopy.ButtonWidth = this.ButtonWidth;
 | |
|                 objCopy.ButtonHeight = this.ButtonHeight;
 | |
| 
 | |
|                 base.CopyToItem(objCopy);
 | |
|             }
 | |
|         }
 | |
|         #endregion
 | |
| 
 | |
|         #region Implementation
 | |
|         protected override void Dispose(bool disposing)
 | |
|         {
 | |
|             CancelAnimation();
 | |
|             base.Dispose(disposing);
 | |
|         }
 | |
| 
 | |
|         public override void Paint(ItemPaintArgs p)
 | |
|         {
 | |
|             BaseRenderer renderer = p.Renderer;
 | |
|             if (renderer != null)
 | |
|             {
 | |
|                 SwitchButtonRenderEventArgs e = new SwitchButtonRenderEventArgs(p.Graphics, this, p.Colors, p.Font, p.RightToLeft);
 | |
|                 e.ItemPaintArgs = p;
 | |
|                 renderer.DrawSwitchButton(e);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 SwitchButtonPainter painter = PainterFactory.CreateSwitchButtonPainter(this);
 | |
|                 if (painter != null)
 | |
|                 {
 | |
|                     SwitchButtonRenderEventArgs e = new SwitchButtonRenderEventArgs(p.Graphics, this, p.Colors, p.Font, p.RightToLeft);
 | |
|                     e.ItemPaintArgs = p;
 | |
|                     painter.Paint(e);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             this.DrawInsertMarker(p.Graphics);
 | |
|         }
 | |
| 
 | |
|         public override void RecalcSize()
 | |
|         {
 | |
|             Size size = new Size(Dpi.Width(_ButtonWidth + _Margin.Horizontal), Dpi.Height(_ButtonHeight + _Margin.Vertical));
 | |
| 
 | |
|             if (_TextVisible && !string.IsNullOrEmpty(this.Text))
 | |
|             {
 | |
|                 Control parent = this.ContainerControl as Control;
 | |
|                 if (parent != null)
 | |
|                 {
 | |
|                     Font font = parent.Font;
 | |
|                     using (Graphics g = parent.CreateGraphics())
 | |
|                     {
 | |
|                         Size textSize = ButtonItemLayout.MeasureItemText(this, g, 0, font, eTextFormat.WordBreak, parent.RightToLeft == RightToLeft.Yes);
 | |
|                         textSize.Width += Dpi.Width(_TextPadding.Horizontal + TextButtonSpacing);
 | |
|                         textSize.Height += Dpi.Height(_TextPadding.Vertical);
 | |
|                         size.Width += textSize.Width;
 | |
|                         size.Height = Math.Max(size.Height, textSize.Height);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             m_Rect.Width = size.Width;
 | |
|             m_Rect.Height = size.Height;
 | |
| 
 | |
|             base.RecalcSize();
 | |
|         }
 | |
| 
 | |
|         internal Size GetPreferredSize()
 | |
|         {
 | |
|             Size size = new Size(Dpi.Width(_SwitchWidth + _Margin.Horizontal), Dpi.Height8);
 | |
| 
 | |
|             Control parent = this.ContainerControl as Control;
 | |
|             if (parent != null)
 | |
|             {
 | |
|                 Font font = parent.Font;
 | |
|                 using (Graphics g = parent.CreateGraphics())
 | |
|                 {
 | |
|                     Size textOnSize = TextDrawing.MeasureString(g, _OnText, font);
 | |
|                     Size textOffSize = TextDrawing.MeasureString(g, _OffText, font);
 | |
|                     size.Width += Math.Max(textOnSize.Width, textOffSize.Width) + 8;
 | |
|                     size.Height = Math.Max(size.Height, textOffSize.Height + _Margin.Vertical + 4);
 | |
| 
 | |
|                     if (_TextVisible && !string.IsNullOrEmpty(this.Text))
 | |
|                     {
 | |
|                         Size textSize = ButtonItemLayout.MeasureItemText(this, g, 0, font, eTextFormat.WordBreak, parent.RightToLeft == RightToLeft.Yes);
 | |
|                         textSize.Width += _TextPadding.Horizontal + TextButtonSpacing;
 | |
|                         textSize.Height += _TextPadding.Vertical;
 | |
|                         size.Width += textSize.Width;
 | |
|                         size.Height = Math.Max(size.Height, textSize.Height);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return size;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets whether item supports text markup. Default is false.
 | |
|         /// </summary>
 | |
|         protected override bool IsMarkupSupported
 | |
|         {
 | |
|             get { return _EnableMarkup; }
 | |
|         }
 | |
| 
 | |
|         private bool _EnableMarkup = true;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true.
 | |
|         /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for items Text property.")]
 | |
|         public bool EnableMarkup
 | |
|         {
 | |
|             get { return _EnableMarkup; }
 | |
|             set
 | |
|             {
 | |
|                 if (_EnableMarkup != value)
 | |
|                 {
 | |
|                     _EnableMarkup = value;
 | |
|                     NeedRecalcSize = true;
 | |
|                     OnTextChanged();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the text associated with this item.
 | |
|         /// </summary>
 | |
|         [Browsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Description("The text contained in the item."), Localizable(true), DefaultValue("")]
 | |
|         public override string Text
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return base.Text;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 base.Text = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private bool _Value;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the switch value.
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Appearance"), Description("Indicates switch value."), Bindable(true)]
 | |
|         public bool Value
 | |
|         {
 | |
|             get { return _Value; }
 | |
|             set
 | |
|             {
 | |
|                 if (_Value != value)
 | |
|                     SetValue(value, eEventSource.Code);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Sets the value of the control and specifies the source of the action.
 | |
|         /// </summary>
 | |
|         /// <param name="newValue">New value for Value property.</param>
 | |
|         /// <param name="source">Source of the action.</param>
 | |
|         public void SetValue(bool newValue, eEventSource source)
 | |
|         {
 | |
|             CancelableEventSourceArgs cancelEventArgs = new CancelableEventSourceArgs(source);
 | |
|             OnValueChanging(cancelEventArgs);
 | |
|             if (cancelEventArgs.Cancel)
 | |
|             {
 | |
|                 SwitchOffset = 0;
 | |
|                 this.Refresh();
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             _Value = newValue;
 | |
|             _AsyncValue = newValue;
 | |
| 
 | |
|             if (ShouldSyncProperties)
 | |
|                 BarFunctions.SyncProperty(this, "Value");
 | |
| 
 | |
|             SwitchOffset = 0;
 | |
| 
 | |
|             if (this.Displayed)
 | |
|                 this.Refresh();
 | |
| 
 | |
|             ExecuteCommand();
 | |
|             EventSourceArgs sourceEventArgs = new EventSourceArgs(source);
 | |
|             OnValueChanged(sourceEventArgs);
 | |
|         }
 | |
| 
 | |
|         private Point _MouseDownPoint = Point.Empty;
 | |
|         public override void InternalMouseDown(MouseEventArgs objArg)
 | |
|         {
 | |
|             if (this.Enabled && !_IsReadOnly && !this.DesignMode && objArg.Button == MouseButtons.Left)
 | |
|             {
 | |
|                 if (!Value && _OffPartBounds.Contains(objArg.X, objArg.Y))
 | |
|                     this.SetValueAndAnimate(true, eEventSource.Mouse);
 | |
|                 else if (Value && _OnPartBounds.Contains(objArg.X, objArg.Y))
 | |
|                     this.SetValueAndAnimate(false, eEventSource.Mouse);
 | |
|                 else if (_SwitchBounds.Contains(objArg.X, objArg.Y))
 | |
|                 {
 | |
|                     _MouseDownPoint = new Point(objArg.X, objArg.Y);
 | |
|                     SwitchPressed = true;
 | |
|                 }
 | |
|             }
 | |
|             base.InternalMouseDown(objArg);
 | |
|         }
 | |
| 
 | |
|         public override void InternalMouseMove(MouseEventArgs objArg)
 | |
|         {
 | |
|             if (_SwitchPressed)
 | |
|             {
 | |
|                 if (objArg.Button == MouseButtons.Left)
 | |
|                 {
 | |
|                     Point mouseDownPoint = _MouseDownPoint;
 | |
|                     int offsetX = objArg.X - mouseDownPoint.X;
 | |
|                     if (offsetX != 0)
 | |
|                     {
 | |
|                         if (!Value && offsetX > 0)
 | |
|                         {
 | |
|                             if (_SwitchBounds.Right + offsetX >= _ButtonBounds.Right)
 | |
|                             {
 | |
|                                 SetValue(true, eEventSource.Mouse);
 | |
|                                 _MouseDownPoint = new Point(objArg.X, objArg.Y);
 | |
|                             }
 | |
|                             else
 | |
|                                 SwitchOffset = offsetX;
 | |
|                         }
 | |
|                         else if (Value && offsetX < 0)
 | |
|                         {
 | |
|                             if (_SwitchBounds.X + offsetX <= _ButtonBounds.X)
 | |
|                             {
 | |
|                                 SetValue(false, eEventSource.Mouse);
 | |
|                                 _MouseDownPoint = new Point(objArg.X, objArg.Y);
 | |
|                             }
 | |
|                             else
 | |
|                                 SwitchOffset = Math.Abs(offsetX);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     SwitchPressed = false;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             base.InternalMouseMove(objArg);
 | |
|         }
 | |
| 
 | |
|         public override void InternalMouseUp(MouseEventArgs objArg)
 | |
|         {
 | |
|             if (_SwitchPressed)
 | |
|             {
 | |
|                 SwitchPressed = false;
 | |
|                 if (_SwitchClickTogglesValue && objArg.Button == MouseButtons.Left && _MouseDownPoint == objArg.Location)
 | |
|                     SetValue(!Value, eEventSource.Mouse);
 | |
|             }
 | |
|             base.InternalMouseUp(objArg);
 | |
|         }
 | |
| 
 | |
|         private bool _SwitchClickTogglesValue;
 | |
|         /// <summary>
 | |
|         /// Indicates whether clicking left mouse button on the switch part of the item will toggle the switch Value.
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Behavior"), Description("Indicates whether clicking left mouse button on the switch part of the item will toggle the switch Value.")]
 | |
|         public bool SwitchClickTogglesValue
 | |
|         {
 | |
|             get { return _SwitchClickTogglesValue; }
 | |
|             set { _SwitchClickTogglesValue = value; }
 | |
|         }
 | |
|         
 | |
|         private Rectangle _SwitchBounds;
 | |
|         /// <summary>
 | |
|         /// Gets the switch bounds.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         public Rectangle SwitchBounds
 | |
|         {
 | |
|             get { return _SwitchBounds; }
 | |
|             internal set { _SwitchBounds = value; }
 | |
|         }
 | |
| 
 | |
|         private Rectangle _ButtonBounds;
 | |
|         /// <summary>
 | |
|         /// Gets the button bounds.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         public Rectangle ButtonBounds
 | |
|         {
 | |
|             get { return _ButtonBounds; }
 | |
|             internal set { _ButtonBounds = value; }
 | |
|         }
 | |
| 
 | |
|         private Rectangle _OnPartBounds;
 | |
|         /// <summary>
 | |
|         /// Gets the On part of the switch button bounds excluding the SwitchBounds.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         public Rectangle OnPartBounds
 | |
|         {
 | |
|             get { return _OnPartBounds; }
 | |
|             internal set { _OnPartBounds = value; }
 | |
|         }
 | |
| 
 | |
|         private Rectangle _OffPartBounds;
 | |
|         /// <summary>
 | |
|         /// Gets the Off part of the switch button bounds excluding the SwitchBounds.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         public Rectangle OffPartBounds
 | |
|         {
 | |
|             get { return _OffPartBounds; }
 | |
|             internal set { _OffPartBounds = value; }
 | |
|         }
 | |
| 
 | |
|         private int _SwitchOffset;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the switch offset from its initial position. Used for animation and dragging of the switch.
 | |
|         /// </summary>
 | |
|         internal int SwitchOffset
 | |
|         {
 | |
|             get { return _SwitchOffset; }
 | |
|             set
 | |
|             {
 | |
|                 _SwitchOffset = value;
 | |
|                 this.Refresh();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private bool _SwitchPressed;
 | |
|         /// <summary>
 | |
|         /// Gets whether switch part of the button is pressed using mouse left button.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         public bool SwitchPressed
 | |
|         {
 | |
|             get { return _SwitchPressed; }
 | |
|             internal set 
 | |
|             {
 | |
|                 _SwitchPressed = value;
 | |
|                 SwitchOffset = 0;
 | |
|                 this.Refresh();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private int _SwitchWidth = 28;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the width in pixels of the switch part of the button. Minimum value is 6.
 | |
|         /// </summary>
 | |
|         [DefaultValue(28), Category("Appearance"), Description("Indicates width in pixels of the switch part of the button.")]
 | |
|         public int SwitchWidth
 | |
|         {
 | |
|             get { return _SwitchWidth; }
 | |
|             set
 | |
|             {
 | |
|                 if (value < 6) value = 6;
 | |
|                 if (_SwitchWidth != value)
 | |
|                 {
 | |
|                     _SwitchWidth = value;
 | |
|                     this.Refresh();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private string _OnText = "ON";
 | |
|         /// <summary>
 | |
|         /// Gets or sets the text that is displayed on switch when Value property is set to true.
 | |
|         /// </summary>
 | |
|         [DefaultValue("ON"), Localizable(true), Category("Appearance"), Description("Indicates text that is displayed on switch when Value property is set to true.")]
 | |
|         public string OnText
 | |
|         {
 | |
|             get { return _OnText; }
 | |
|             set
 | |
|             {
 | |
|                 if (value == null) value = "";
 | |
|                 if (_OnText != value)
 | |
|                 {
 | |
|                     _OnText = value;
 | |
|                     this.Refresh();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private string _OffText = "OFF";
 | |
|         /// <summary>
 | |
|         /// Gets or sets the text that is displayed on switch when Value property is set to false.
 | |
|         /// </summary>
 | |
|         [DefaultValue("OFF"), Localizable(true), Category("Appearance"), Description("Indicates text that is displayed on switch when Value property is set to true.")]
 | |
|         public string OffText
 | |
|         {
 | |
|             get { return _OffText; }
 | |
|             set
 | |
|             {
 | |
|                 if (value == null) value = "";
 | |
|                 if (_OffText != value)
 | |
|                 {
 | |
|                     _OffText = value;
 | |
|                     this.Refresh();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private bool _AsyncValue;
 | |
|         private eEventSource _AsyncSource;
 | |
|         private int _AsyncTotalSwitchOffset;
 | |
|         private BackgroundWorker _AnimationWorker;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Sets the value of the control with state transition animation (if enabled) and specifies the source of the action.
 | |
|         /// </summary>
 | |
|         /// <param name="value">New value for Value property.</param>
 | |
|         /// <param name="source">Source of the action.</param>
 | |
|         public void SetValueAndAnimate(bool value, eEventSource source)
 | |
|         {
 | |
|             if (!IsAnimationEnabled)
 | |
|             {
 | |
|                 SetValue(value, source);
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             BackgroundWorker worker = _AnimationWorker;
 | |
|             if (worker != null)
 | |
|             {
 | |
|                 worker.CancelAsync();
 | |
|                 SetValue(value, source);
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             if (Value != value)
 | |
|             {
 | |
|                 _AsyncValue = value;
 | |
|                 _AsyncSource = source;
 | |
|                 _AsyncTotalSwitchOffset = _ButtonBounds.Width - Dpi.Width(SwitchWidth);
 | |
| 
 | |
|                 _AnimationWorker = new BackgroundWorker();
 | |
| 
 | |
|                 _AnimationWorker.WorkerSupportsCancellation = true;
 | |
|                 _AnimationWorker.DoWork += AnimationWorkerDoWork;
 | |
|                 _AnimationWorker.RunWorkerCompleted += AnimationWorkerRunWorkerCompleted;
 | |
| 
 | |
|                 _AnimationWorker.RunWorkerAsync();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void AnimationWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 | |
|         {
 | |
|             BackgroundWorker worker = _AnimationWorker;
 | |
|             _AnimationWorker = null;
 | |
| 
 | |
|             if (worker != null)
 | |
|                 worker.Dispose();
 | |
| 
 | |
|             if (e.Cancelled == false)
 | |
|                 SetValue(_AsyncValue, _AsyncSource);
 | |
|         }
 | |
| 
 | |
|         private void AnimationWorkerDoWork(object sender, DoWorkEventArgs e)
 | |
|         {
 | |
|             DateTime start = DateTime.Now;
 | |
| 
 | |
|             int steps = Math.Max(9, _AsyncTotalSwitchOffset / 5);
 | |
| 
 | |
|             for (int i = 0; i < _AsyncTotalSwitchOffset; i += steps)
 | |
|             {
 | |
|                 if (_AnimationWorker.CancellationPending == true)
 | |
|                 {
 | |
|                     e.Cancel = true;
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 SwitchOffset = i;
 | |
|                 try
 | |
|                 {
 | |
|                     using (
 | |
|                                         System.Threading.ManualResetEvent wait =
 | |
|                                             new System.Threading.ManualResetEvent(false))
 | |
|                         wait.WaitOne(40);
 | |
|                     //Thread.Sleep(40);
 | |
|                 }
 | |
|                 catch 
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 if (DateTime.Now.Subtract(start).TotalMilliseconds > 400)
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Cancels any current inprogress animation.
 | |
|         /// </summary>
 | |
|         internal void CancelAnimation()
 | |
|         {
 | |
|             BackgroundWorker worker = _AnimationWorker;
 | |
| 
 | |
|             if (worker != null)
 | |
|             {
 | |
|                 if (worker.IsBusy)
 | |
|                 {
 | |
|                     worker.CancelAsync();
 | |
| 
 | |
|                     if (Value != _AsyncValue)
 | |
|                         SetValue(_AsyncValue, _AsyncSource);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets whether fade effect is enabled.
 | |
|         /// </summary>
 | |
|         protected virtual bool IsAnimationEnabled
 | |
|         {
 | |
|             get { return _AnimationEnabled; }
 | |
|         }
 | |
| 
 | |
|         private bool _AnimationEnabled = true;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether state transition animation is enabled.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Appearance"), Description("Indicates whether state transition animation is enabled.")]
 | |
|         public bool AnimationEnabled
 | |
|         {
 | |
|             get { return _AnimationEnabled; }
 | |
|             set { _AnimationEnabled = value; }
 | |
|         }
 | |
| 
 | |
|         private int _ButtonWidth = 66;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the width of the switch button. Must be greater than SwitchWidth.
 | |
|         /// </summary>
 | |
|         [DefaultValue(66), Category("Appearance"), Description("Indicates width of the switch button. Must be greater than SwitchWidth.")]
 | |
|         public int ButtonWidth
 | |
|         {
 | |
|             get { return _ButtonWidth; }
 | |
|             set
 | |
|             {
 | |
|                 if (value < _SwitchWidth)
 | |
|                     value = _SwitchWidth + 1;
 | |
|                 _ButtonWidth = value;
 | |
|                 NeedRecalcSize = true;
 | |
|                 this.Refresh();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private int _ButtonHeight = 22;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the height of the switch button. Must be greater than 5.
 | |
|         /// </summary>
 | |
|         [DefaultValue(22), Category("Appearance"), Description("Indicates height of the switch button. Must be greater than 5.")]
 | |
|         public int ButtonHeight
 | |
|         {
 | |
|             get { return _ButtonHeight; }
 | |
|             set
 | |
|             {
 | |
|                 if (value < 6) value = 6;
 | |
|                 _ButtonHeight = value;
 | |
|                 NeedRecalcSize = true;
 | |
|                 this.Refresh();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private Padding _TextPadding = new Padding(0, 0, 0, 0);
 | |
|         /// <summary>
 | |
|         /// Gets or sets text padding.
 | |
|         /// </summary>
 | |
|         [Browsable(true), Category("Appearance"), Description("Gets or sets text padding."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public Padding TextPadding
 | |
|         {
 | |
|             get { return _TextPadding; }
 | |
|         }
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeTextPadding()
 | |
|         {
 | |
|             return _TextPadding.Bottom != 0 || _TextPadding.Top != 0 || _TextPadding.Left != 0 || _TextPadding.Right != 0;
 | |
|         }
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         private void ResetTextPadding()
 | |
|         {
 | |
|             _TextPadding = new Padding(0, 0, 0, 0);
 | |
|         }
 | |
|         //private void TextPaddingPropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         //{
 | |
|         //    NeedRecalcSize = true;
 | |
|         //    this.Refresh();
 | |
|         //}
 | |
| 
 | |
|         private Padding _Margin = new Padding(0, 0, 0, 0);
 | |
|         /// <summary>
 | |
|         /// Gets or sets switch margin.
 | |
|         /// </summary>
 | |
|         [Browsable(true), Category("Appearance"), Description("Gets or sets switch margin."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public Padding Margin
 | |
|         {
 | |
|             get { return _Margin; }
 | |
|         }
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeMargin()
 | |
|         {
 | |
|             return _Margin.Bottom != 0 || _Margin.Top != 0 || _Margin.Left != 0 || _Margin.Right != 0;
 | |
|         }
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         private void ResetMargin()
 | |
|         {
 | |
|             _Margin = new Padding(0, 0, 0, 0);
 | |
|         }
 | |
|         private void MarginPropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             NeedRecalcSize = true;
 | |
|             this.Refresh();
 | |
|         }
 | |
| 
 | |
|         private Color _OffBackColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the color of the OFF state background.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates color of OFF state background.")]
 | |
|         public Color OffBackColor
 | |
|         {
 | |
|             get { return _OffBackColor; }
 | |
|             set { _OffBackColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeOffBackColor()
 | |
|         {
 | |
|             return !_OffBackColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetOffBackColor()
 | |
|         {
 | |
|             this.OffBackColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private Color _OnBackColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the color of the ON state background.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates color of ON state background.")]
 | |
|         public Color OnBackColor
 | |
|         {
 | |
|             get { return _OnBackColor; }
 | |
|             set { _OnBackColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeOnBackColor()
 | |
|         {
 | |
|             return !_OnBackColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetOnBackColor()
 | |
|         {
 | |
|             this.OnBackColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private Color _OnTextColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the color of the ON state text.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates color of ON state text.")]
 | |
|         public Color OnTextColor
 | |
|         {
 | |
|             get { return _OnTextColor; }
 | |
|             set { _OnTextColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeOnTextColor()
 | |
|         {
 | |
|             return !_OnTextColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetOnTextColor()
 | |
|         {
 | |
|             this.OnTextColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private Color _OffTextColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the color of the OFF state text.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates color of OFF state text.")]
 | |
|         public Color OffTextColor
 | |
|         {
 | |
|             get { return _OffTextColor; }
 | |
|             set { _OffTextColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeOffTextColor()
 | |
|         {
 | |
|             return !_OffTextColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetOffTextColor()
 | |
|         {
 | |
|             this.OffTextColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private Color _BorderColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the item border color.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates item border color.")]
 | |
|         public Color BorderColor
 | |
|         {
 | |
|             get { return _BorderColor; }
 | |
|             set { _BorderColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeBorderColor()
 | |
|         {
 | |
|             return !_BorderColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetBorderColor()
 | |
|         {
 | |
|             this.BorderColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private Color _SwitchBorderColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the border color of the button switch.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates border color of the button switch.")]
 | |
|         public Color SwitchBorderColor
 | |
|         {
 | |
|             get { return _SwitchBorderColor; }
 | |
|             set { _SwitchBorderColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeSwitchBorderColor()
 | |
|         {
 | |
|             return !_SwitchBorderColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetSwitchBorderColor()
 | |
|         {
 | |
|             this.SwitchBorderColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private Color _SwitchBackColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the background color of the switch button.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates background color of the switch button.")]
 | |
|         public Color SwitchBackColor
 | |
|         {
 | |
|             get { return _SwitchBackColor; }
 | |
|             set { _SwitchBackColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeSwitchBackColor()
 | |
|         {
 | |
|             return !_SwitchBackColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetSwitchBackColor()
 | |
|         {
 | |
|             this.SwitchBackColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private bool _TextVisible = true;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether caption/label set using Text property is visible.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Appearance"), Description("Indicates whether caption/label set using Text property is visible.")]
 | |
|         public bool TextVisible
 | |
|         {
 | |
|             get { return _TextVisible; }
 | |
|             set
 | |
|             {
 | |
|                 _TextVisible = value;
 | |
|                 NeedRecalcSize = true;
 | |
|                 this.Refresh();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private Color _TextColor = Color.Empty;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the text color.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates text color.")]
 | |
|         public Color TextColor
 | |
|         {
 | |
|             get { return _TextColor; }
 | |
|             set { _TextColor = value; }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeTextColor()
 | |
|         {
 | |
|             return !_TextColor.IsEmpty;
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetTextColor()
 | |
|         {
 | |
|             this.TextColor = Color.Empty;
 | |
|         }
 | |
| 
 | |
|         private Font _SwitchFont;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the font that is used to draw ON/OFF text on the switch button.
 | |
|         /// </summary>
 | |
|         [DefaultValue(null), Category("Appearance"), Description("Indicates font that is used to draw ON/OFF text on the switch button.")]
 | |
|         public Font SwitchFont
 | |
|         {
 | |
|             get { return _SwitchFont; }
 | |
|             set { _SwitchFont = value; this.Refresh(); }
 | |
|         }
 | |
| 
 | |
|         private bool _IsReadOnly;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether button is in read-only state meaning that it appears as enabled but user cannot change its state.
 | |
|         /// </summary>
 | |
|         [DefaultValue(false), Category("Behavior"), Description("Indicates whether button is in read-only state meaning that it appears as enabled but user cannot change its state.")]
 | |
|         public bool IsReadOnly
 | |
|         {
 | |
|             get { return _IsReadOnly; }
 | |
|             set { _IsReadOnly = value; this.Refresh(); }
 | |
|         }
 | |
| 
 | |
|         private bool _ShowReadOnlyMarker = true;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether lock marker is visible on face of the control when IsReadOnly is set to true.
 | |
|         /// Default value is true.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true), Category("Appearance"), Description("Indicates whether lock marker is visible on face of the control when IsReadOnly is set to true.")]
 | |
|         public bool ShowReadOnlyMarker
 | |
|         {
 | |
|             get { return _ShowReadOnlyMarker; }
 | |
|             set { _ShowReadOnlyMarker = value; this.Refresh(); }
 | |
|         }
 | |
| 
 | |
|         private static readonly Color DefaultReadOnlyMarkerColor = ColorScheme.GetColor(0xC0504D);
 | |
|         private Color _ReadOnlyMarkerColor = DefaultReadOnlyMarkerColor;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the color of the read-only marker.
 | |
|         /// </summary>
 | |
|         [Category("Appearance"), Description("Indicates color of read-only marker.")]
 | |
|         public Color ReadOnlyMarkerColor
 | |
|         {
 | |
|             get { return _ReadOnlyMarkerColor; }
 | |
|             set { _ReadOnlyMarkerColor = value; this.Refresh(); }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Gets whether property should be serialized.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public bool ShouldSerializeReadOnlyMarkerColor()
 | |
|         {
 | |
|             return !_ReadOnlyMarkerColor.Equals(DefaultReadOnlyMarkerColor);
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// Resets property to its default value.
 | |
|         /// </summary>
 | |
|         [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|         public void ResetReadOnlyMarkerColor()
 | |
|         {
 | |
|             this.ReadOnlyMarkerColor = DefaultReadOnlyMarkerColor;
 | |
|         }
 | |
|         #endregion
 | |
|     }
 | |
| }
 |