diff options
Diffstat (limited to 'source/ShiftUI/ToolStrip')
70 files changed, 15423 insertions, 0 deletions
diff --git a/source/ShiftUI/ToolStrip/ToolStrip.cs b/source/ShiftUI/ToolStrip/ToolStrip.cs new file mode 100644 index 0000000..b784458 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStrip.cs @@ -0,0 +1,1778 @@ +// +// ToolStrip.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Drawing; +using ShiftUI.Layout; +using System.Collections.Generic; +using System.ComponentModel.Design.Serialization; + +namespace ShiftUI +{ + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDispatch)] + [DefaultEvent ("ItemClicked")] + [DefaultProperty ("Items")] + public class ToolStrip : ScrollableWidget, IComponent, IDisposable, IToolStripData + { + #region Private Variables + private bool allow_item_reorder; + private bool allow_merge; + private Color back_color; + private bool can_overflow; + private ToolStrip currently_merged_with; + private ToolStripDropDownDirection default_drop_down_direction; + internal ToolStripItemCollection displayed_items; + private Color fore_color; + private Padding grip_margin; + private ToolStripGripStyle grip_style; + private List<ToolStripItem> hidden_merged_items; + private ImageList image_list; + private Size image_scaling_size; + private bool is_currently_merged; + private ToolStripItemCollection items; + private bool keyboard_active; + private LayoutEngine layout_engine; + private LayoutSettings layout_settings; + private ToolStripLayoutStyle layout_style; + private Orientation orientation; + private ToolStripOverflowButton overflow_button; + private List<ToolStripItem> pre_merge_items; + private ToolStripRenderer renderer; + private ToolStripRenderMode render_mode; + private ToolStripTextDirection text_direction; + private Timer tooltip_timer; + private ToolTip tooltip_window; + private bool show_item_tool_tips; + private bool stretch; + + private ToolStripItem mouse_currently_over; + internal bool menu_selected; + private ToolStripItem tooltip_currently_showing; + private ToolTip.TipState tooltip_state; + + const int InitialToolTipDelay = 500; + const int ToolTipDelay = 5000; + #endregion + + #region Public Constructors + public ToolStrip () : this (null) + { + } + + public ToolStrip (params ToolStripItem[] items) : base () + { + SetStyle (Widgetstyles.AllPaintingInWmPaint, true); + SetStyle (Widgetstyles.OptimizedDoubleBuffer, true); + SetStyle (Widgetstyles.Selectable, false); + SetStyle (Widgetstyles.SupportsTransparentBackColor, true); + + this.SuspendLayout (); + + this.items = new ToolStripItemCollection (this, items, true); + this.allow_merge = true; + base.AutoSize = true; + this.SetAutoSizeMode (AutoSizeMode.GrowAndShrink); + this.back_color = Widget.DefaultBackColor; + this.can_overflow = true; + base.CausesValidation = false; + this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight; + this.displayed_items = new ToolStripItemCollection (this, null, true); + this.Dock = this.DefaultDock; + base.Font = new Font ("Tahoma", 8.25f); + this.fore_color = Widget.DefaultForeColor; + this.grip_margin = this.DefaultGripMargin; + this.grip_style = ToolStripGripStyle.Visible; + this.image_scaling_size = new Size (16, 16); + this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow; + this.orientation = Orientation.Horizontal; + if (!(this is ToolStripDropDown)) + this.overflow_button = new ToolStripOverflowButton (this); + this.renderer = null; + this.render_mode = ToolStripRenderMode.ManagerRenderMode; + this.show_item_tool_tips = this.DefaultShowItemToolTips; + base.TabStop = false; + this.text_direction = ToolStripTextDirection.Horizontal; + this.ResumeLayout (); + + // Register with the ToolStripManager + ToolStripManager.AddToolStrip (this); + } + #endregion + + #region Public Properties + [MonoTODO ("Stub, does nothing")] + public override bool AllowDrop { + get { return base.AllowDrop; } + set { base.AllowDrop = value; } + } + + [MonoTODO ("Stub, does nothing")] + [DefaultValue (false)] + public bool AllowItemReorder { + get { return this.allow_item_reorder; } + set { this.allow_item_reorder = value; } + } + + [DefaultValue (true)] + public bool AllowMerge { + get { return this.allow_merge; } + set { this.allow_merge = value; } + } + + public override AnchorStyles Anchor { + get { return base.Anchor; } + set { base.Anchor = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override bool AutoScroll { + get { return base.AutoScroll; } + set { base.AutoScroll = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMargin { + get { return base.AutoScrollMargin; } + set { base.AutoScrollMargin = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMinSize { + get { return base.AutoScrollMinSize; } + set { base.AutoScrollMinSize = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Point AutoScrollPosition { + get { return base.AutoScrollPosition; } + set { base.AutoScrollPosition = value; } + } + + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)] + [Browsable (true)] + //[EditorBrowsable (EditorBrowsableState.Always)] + [DefaultValue (true)] + public override bool AutoSize { + get { return base.AutoSize; } + set { base.AutoSize = value; } + } + + new public Color BackColor { + get { return this.back_color; } + set { this.back_color = value; } + } + + public override BindingContext BindingContext { + get { return base.BindingContext; } + set { base.BindingContext = value; } + } + + [DefaultValue (true)] + public bool CanOverflow { + get { return this.can_overflow; } + set { this.can_overflow = value; } + } + + [Browsable (false)] + [DefaultValue (false)] + public new bool CausesValidation { + get { return base.CausesValidation; } + set { base.CausesValidation = value; } + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new WidgetCollection Widgets { + get { return base.Widgets; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Cursor Cursor { + get { return base.Cursor; } + set { base.Cursor = value; } + } + + [Browsable (false)] + public virtual ToolStripDropDownDirection DefaultDropDownDirection { + get { return this.default_drop_down_direction; } + set { + if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value)); + + this.default_drop_down_direction = value; + } + } + + public override Rectangle DisplayRectangle { + get { + if (this.orientation == Orientation.Horizontal) + if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table) + return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical); + else + return new Rectangle (this.GripRectangle.Right + this.GripMargin.Right, this.Padding.Top, this.Width - this.Padding.Horizontal - this.GripRectangle.Right - this.GripMargin.Right, this.Height - this.Padding.Vertical); + else + if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table) + return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical); + else + return new Rectangle (this.Padding.Left, this.GripRectangle.Bottom + this.GripMargin.Bottom + this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical - this.GripRectangle.Bottom - this.GripMargin.Bottom); + } + } + + [DefaultValue (DockStyle.Top)] + public override DockStyle Dock { + get { return base.Dock; } + set { + if (base.Dock != value) { + base.Dock = value; + + switch (value) { + case DockStyle.Top: + case DockStyle.Bottom: + case DockStyle.None: + this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow; + break; + case DockStyle.Left: + case DockStyle.Right: + this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow; + break; + } + } + } + } + + public override Font Font { + get { return base.Font; } + set { + if (base.Font != value) { + base.Font = value; + + foreach (ToolStripItem tsi in this.Items) + tsi.OnOwnerFontChanged (EventArgs.Empty); + } + } + } + + [Browsable (false)] + public new Color ForeColor { + get { return this.fore_color; } + set { + if (this.fore_color != value) { + this.fore_color = value; + this.OnForeColorChanged (EventArgs.Empty); + } + } + } + + [Browsable (false)] + public ToolStripGripDisplayStyle GripDisplayStyle { + get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; } + } + + public Padding GripMargin { + get { return this.grip_margin; } + set { + if (this.grip_margin != value) { + this.grip_margin = value; + this.PerformLayout (); + } + } + } + + [Browsable (false)] + public Rectangle GripRectangle { + get { + if (this.grip_style == ToolStripGripStyle.Hidden) + return Rectangle.Empty; + + if (this.orientation == Orientation.Horizontal) + return new Rectangle (this.grip_margin.Left + this.Padding.Left, this.Padding.Top, 3, this.Height); + else + return new Rectangle (this.Padding.Left, this.grip_margin.Top + this.Padding.Top, this.Width, 3); + } + } + + [DefaultValue (ToolStripGripStyle.Visible)] + public ToolStripGripStyle GripStyle { + get { return this.grip_style; } + set { + if (this.grip_style != value) { + if (!Enum.IsDefined (typeof (ToolStripGripStyle), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value)); + this.grip_style = value; + this.PerformLayout (this, "GripStyle"); + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool HasChildren { + get { return base.HasChildren; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new HScrollProperties HorizontalScroll { + get { return base.HorizontalScroll; } + } + + [Browsable (false)] + [DefaultValue (null)] + public ImageList ImageList { + get { return this.image_list; } + set { this.image_list = value; } + } + + [DefaultValue ("{Width=16, Height=16}")] + public Size ImageScalingSize { + get { return this.image_scaling_size; } + set { this.image_scaling_size = value; } + } + + [MonoTODO ("Always returns false, dragging not implemented yet.")] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public bool IsCurrentlyDragging { + get { return false; } + } + + [Browsable (false)] + public bool IsDropDown { + get { + if (this is ToolStripDropDown) + return true; + + return false; + } + } + + [MergableProperty (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + public virtual ToolStripItemCollection Items { + get { return this.items; } + } + + public override LayoutEngine LayoutEngine { + get { + if (layout_engine == null) + this.layout_engine = new ToolStripSplitStackLayout (); + + return this.layout_engine; + } + } + + [Browsable (false)] + [DefaultValue (null)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public LayoutSettings LayoutSettings { + get { return this.layout_settings; } + set { + if (this.layout_settings != value) { + this.layout_settings = value; + PerformLayout (this, "LayoutSettings"); + } + } + } + + [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)] + public ToolStripLayoutStyle LayoutStyle { + get { return layout_style; } + set { + if (this.layout_style != value) { + if (!Enum.IsDefined (typeof (ToolStripLayoutStyle), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value)); + + this.layout_style = value; + + if (this.layout_style == ToolStripLayoutStyle.Flow) + this.layout_engine = new FlowLayout (); + else + this.layout_engine = new ToolStripSplitStackLayout (); + + if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) { + if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right) + this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow; + else + this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow; + } + + if (this.layout_style == ToolStripLayoutStyle.HorizontalStackWithOverflow) + this.orientation = Orientation.Horizontal; + else if (this.layout_style == ToolStripLayoutStyle.VerticalStackWithOverflow) + this.orientation = Orientation.Vertical; + + this.layout_settings = this.CreateLayoutSettings (value); + + this.PerformLayout (this, "LayoutStyle"); + this.OnLayoutStyleChanged (EventArgs.Empty); + } + } + } + + [Browsable (false)] + public Orientation Orientation { + get { return this.orientation; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public ToolStripOverflowButton OverflowButton { + get { return this.overflow_button; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ToolStripRenderer Renderer { + get { + if (this.render_mode == ToolStripRenderMode.ManagerRenderMode) + return ToolStripManager.Renderer; + + return this.renderer; + } + set { + if (this.renderer != value) { + this.renderer = value; + this.render_mode = ToolStripRenderMode.Custom; + this.PerformLayout (this, "Renderer"); + this.OnRendererChanged (EventArgs.Empty); + } + } + } + + public ToolStripRenderMode RenderMode { + get { return this.render_mode; } + set { + if (!Enum.IsDefined (typeof (ToolStripRenderMode), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value)); + + if (value == ToolStripRenderMode.Custom && this.renderer == null) + throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom"); + else if (value == ToolStripRenderMode.Professional) + this.Renderer = new ToolStripProfessionalRenderer (); + else if (value == ToolStripRenderMode.System) + this.Renderer = new ToolStripSystemRenderer (); + + this.render_mode = value; + } + } + + [DefaultValue (true)] + public bool ShowItemToolTips { + get { return this.show_item_tool_tips; } + set { this.show_item_tool_tips = value; } + } + + [DefaultValue (false)] + public bool Stretch { + get { return this.stretch; } + set { this.stretch = value; } + } + + [DefaultValue (false)] + [DispId(-516)] + public new bool TabStop { + get { return base.TabStop; } + set { + base.TabStop = value; + SetStyle (Widgetstyles.Selectable, value); + } + } + + [DefaultValue (ToolStripTextDirection.Horizontal)] + public virtual ToolStripTextDirection TextDirection { + get { return this.text_direction; } + set { + if (!Enum.IsDefined (typeof (ToolStripTextDirection), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value)); + + if (this.text_direction != value) { + this.text_direction = value; + + this.PerformLayout (this, "TextDirection"); + + this.Invalidate (); + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new VScrollProperties VerticalScroll { + get { return base.VerticalScroll; } + } + #endregion + + #region Protected Properties + protected virtual DockStyle DefaultDock { get { return DockStyle.Top; } } + protected virtual Padding DefaultGripMargin { get { return new Padding (2); } } + protected override Padding DefaultMargin { get { return Padding.Empty; } } + protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); } } + protected virtual bool DefaultShowItemToolTips { get { return true; } } + protected override Size DefaultSize { get { return new Size (100, 25); } } + protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } } + protected internal virtual Size MaxItemSize { + get { return new Size (Width - (GripStyle == ToolStripGripStyle.Hidden ? 1 : 8), Height); } + } + #endregion + + #region Public Methods + //[EditorBrowsable (EditorBrowsableState.Never)] + public new Widget GetChildAtPoint (Point point) + { + return base.GetChildAtPoint (point); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public new Widget GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue) + { + return base.GetChildAtPoint (pt, skipValue); + } + + public ToolStripItem GetItemAt (Point point) + { + foreach (ToolStripItem tsi in this.displayed_items) + if (tsi.Visible && tsi.Bounds.Contains (point)) + return tsi; + + return null; + } + + public ToolStripItem GetItemAt (int x, int y) + { + return GetItemAt (new Point (x, y)); + } + + public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction) + { + if (!Enum.IsDefined (typeof (ArrowDirection), direction)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction)); + + ToolStripItem current_best = null; + int current_best_point; + + switch (direction) { + case ArrowDirection.Right: + current_best_point = int.MaxValue; + + if (start != null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Left >= start.Right && loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Left; + } + + if (current_best == null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Left; + } + + break; + case ArrowDirection.Up: + current_best_point = int.MinValue; + + if (start != null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Bottom <= start.Top && loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Top; + } + + if (current_best == null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Top; + } + + break; + case ArrowDirection.Left: + current_best_point = int.MinValue; + + if (start != null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Right <= start.Left && loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Left; + } + + if (current_best == null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Left; + } + + break; + case ArrowDirection.Down: + current_best_point = int.MaxValue; + + if (start != null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Top >= start.Bottom && loop_tsi.Bottom < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Top; + } + + if (current_best == null) + foreach (ToolStripItem loop_tsi in this.DisplayedItems) + if (loop_tsi.Top < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) { + current_best = loop_tsi; + current_best_point = loop_tsi.Top; + } + + break; + } + + return current_best; + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public void ResetMinimumSize () + { + this.MinimumSize = new Size (-1, -1); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public new void SetAutoScrollMargin (int x, int y) + { + base.SetAutoScrollMargin (x, y); + } + + public override string ToString () + { + return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ()); + } + #endregion + + #region Protected Methods + protected override AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripAccessibleObject (this); + } + + protected override WidgetCollection CreateWidgetsInstance () + { + return base.CreateWidgetsInstance (); + } + + protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick) + { + if (text == "-") + return new ToolStripSeparator (); + + if (this is ToolStripDropDown) + return new ToolStripMenuItem (text, image, onClick); + + return new ToolStripButton (text, image, onClick); + } + + protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle) + { + switch (layoutStyle) { + case ToolStripLayoutStyle.Flow: + return new FlowLayoutSettings (this); + case ToolStripLayoutStyle.Table: + //return new TableLayoutSettings (); + case ToolStripLayoutStyle.StackWithOverflow: + case ToolStripLayoutStyle.HorizontalStackWithOverflow: + case ToolStripLayoutStyle.VerticalStackWithOverflow: + default: + return null; + } + } + + protected override void Dispose (bool disposing) + { + if (!IsDisposed) { + + if(disposing) { + // Event Handler must be stopped before disposing Items. + Events.Dispose(); + + CloseToolTip (null); + // ToolStripItem.Dispose modifes the collection, + // so we iterate it in reverse order + for (int i = Items.Count - 1; i >= 0; i--) + Items [i].Dispose (); + + if (this.overflow_button != null && this.overflow_button.drop_down != null) + this.overflow_button.drop_down.Dispose (); + + ToolStripManager.RemoveToolStrip (this); + } + base.Dispose (disposing); + } + } + + [MonoTODO ("Stub, never called")] + protected virtual void OnBeginDrag (EventArgs e) + { + EventHandler eh = (EventHandler)(Events[BeginDragEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnDockChanged (EventArgs e) + { + base.OnDockChanged (e); + } + + [MonoTODO ("Stub, never called")] + protected virtual void OnEndDrag (EventArgs e) + { + EventHandler eh = (EventHandler)(Events[EndDragEvent]); + if (eh != null) + eh (this, e); + } + + protected override bool IsInputChar (char charCode) + { + return base.IsInputChar (charCode); + } + + protected override bool IsInputKey (Keys keyData) + { + return base.IsInputKey (keyData); + } + + protected override void OnEnabledChanged (EventArgs e) + { + base.OnEnabledChanged (e); + + foreach (ToolStripItem tsi in this.Items) + tsi.OnParentEnabledChanged (EventArgs.Empty); + } + + protected override void OnFontChanged (EventArgs e) + { + base.OnFontChanged (e); + } + + protected override void OnHandleCreated (EventArgs e) + { + base.OnHandleCreated (e); + } + + protected override void OnHandleDestroyed (EventArgs e) + { + base.OnHandleDestroyed (e); + } + + protected override void OnInvalidated (InvalidateEventArgs e) + { + base.OnInvalidated (e); + } + + protected internal virtual void OnItemAdded (ToolStripItemEventArgs e) + { + if (e.Item.InternalVisible) + e.Item.Available = true; + + e.Item.SetPlacement (ToolStripItemPlacement.Main); + + if (this.Created) + this.PerformLayout (); + + ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e) + { + if (this.KeyboardActive) + ToolStripManager.SetActiveToolStrip (null, false); + + ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]); + if (eh != null) + eh (this, e); + } + + protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e) + { + ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnLayout (LayoutEventArgs e) + { + base.OnLayout (e); + + this.SetDisplayedItems (); + this.OnLayoutCompleted (EventArgs.Empty); + this.Invalidate (); + } + + protected virtual void OnLayoutCompleted (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnLayoutStyleChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnLeave (EventArgs e) + { + base.OnLeave (e); + } + + protected override void OnLostFocus (EventArgs e) + { + base.OnLostFocus (e); + } + + protected override void OnMouseCaptureChanged (EventArgs e) + { + base.OnMouseCaptureChanged (e); + } + + protected override void OnMouseDown (MouseEventArgs mea) + { + if (mouse_currently_over != null) + { + ToolStripItem focused = GetCurrentlyFocusedItem (); + + if (focused != null && focused != mouse_currently_over) + this.FocusInternal (true); + + if (this is MenuStrip && !menu_selected) { + (this as MenuStrip).FireMenuActivate (); + menu_selected = true; + } + + mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown); + + if (this is MenuStrip && mouse_currently_over is ToolStripMenuItem && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) + return; + } else { + this.Dismiss (ToolStripDropDownCloseReason.AppClicked); + } + + if (this is MenuStrip) + this.Capture = false; + + base.OnMouseDown (mea); + } + + protected override void OnMouseLeave (EventArgs e) + { + if (mouse_currently_over != null) { + MouseLeftItem (mouse_currently_over); + mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave); + mouse_currently_over = null; + } + + base.OnMouseLeave (e); + } + + protected override void OnMouseMove (MouseEventArgs mea) + { + ToolStripItem tsi; + // Find the item we are now + if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location)) + tsi = this.overflow_button; + else + tsi = this.GetItemAt (mea.X, mea.Y); + + if (tsi != null) { + // If we were already hovering on this item, just send a mouse move + if (tsi == mouse_currently_over) + tsi.FireEvent (mea, ToolStripItemEventType.MouseMove); + else { + // If we were over a different item, fire a mouse leave on it + if (mouse_currently_over != null) { + MouseLeftItem (tsi); + mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave); + } + + // Set the new item we are currently over + mouse_currently_over = tsi; + + // Fire mouse enter and mouse move + tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter); + MouseEnteredItem (tsi); + tsi.FireEvent (mea, ToolStripItemEventType.MouseMove); + + // If we're over something with a drop down, show it + if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems) + (mouse_currently_over as ToolStripDropDownItem).ShowDropDown (); + } + } else { + // We're not over anything now, just fire the mouse leave on what we used to be over + if (mouse_currently_over != null) { + MouseLeftItem (tsi); + mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave); + mouse_currently_over = null; + } + } + + base.OnMouseMove (mea); + } + + protected override void OnMouseUp (MouseEventArgs mea) + { + // If we're currently over an item (set in MouseMove) + if (mouse_currently_over != null && !(mouse_currently_over is ToolStripWidgetHost) && mouse_currently_over.Enabled) { + // Fire our ItemClicked event, but only for a left mouse click. + if (mea.Button == MouseButtons.Left) + OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over)); + + // Fire the item's MouseUp event + if (mouse_currently_over != null) + mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp); + + // The event handler may have blocked until the mouse moved off of the ToolStripItem + if (mouse_currently_over == null) + return; + } + + base.OnMouseUp (mea); + } + + protected override void OnPaint (PaintEventArgs e) + { + base.OnPaint (e); + + // Draw the grip + this.OnPaintGrip (e); + + // Make each item draw itself + for (int i = 0; i < displayed_items.Count; i++) { + ToolStripItem tsi = displayed_items[i]; + + if (tsi.Visible) { + e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top); + tsi.FireEvent (e, ToolStripItemEventType.Paint); + e.Graphics.ResetTransform (); + } + } + + // Paint the Overflow button if it's visible + if (this.overflow_button != null && this.overflow_button.Visible) { + e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top); + this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint); + e.Graphics.ResetTransform (); + } + + Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size); + + ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty); + pevent.InternalConnectedArea = CalculateConnectedArea (); + + this.Renderer.DrawToolStripBorder (pevent); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override void OnPaintBackground (PaintEventArgs e) + { + base.OnPaintBackground (e); + + Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size); + ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control); + + this.Renderer.DrawToolStripBackground (tsrea); + } + + protected internal virtual void OnPaintGrip (PaintEventArgs e) + { + // Never draw a grip with these two layouts + if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table) + return; + + PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]); + if (eh != null) + eh (this, e); + + if (!(this is MenuStrip)) { + if (this.orientation == Orientation.Horizontal) + e.Graphics.TranslateTransform (2, 0); + else + e.Graphics.TranslateTransform (0, 2); + } + + this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style)); + e.Graphics.ResetTransform (); + } + + protected virtual void OnRendererChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [RendererChangedEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override void OnRightToLeftChanged (EventArgs e) + { + base.OnRightToLeftChanged (e); + + foreach (ToolStripItem tsi in this.Items) + tsi.OnParentRightToLeftChanged (e); + } + + protected override void OnScroll (ScrollEventArgs se) + { + base.OnScroll (se); + } + + protected override void OnTabStopChanged (EventArgs e) + { + base.OnTabStopChanged (e); + } + + protected override void OnVisibleChanged (EventArgs e) + { + if (!Visible) + CloseToolTip (null); + + base.OnVisibleChanged (e); + } + + protected override bool ProcessCmdKey (ref Message m, Keys keyData) + { + return base.ProcessCmdKey (ref m, keyData); + } + + protected override bool ProcessDialogKey (Keys keyData) + { + if (!this.KeyboardActive) + return false; + + // Give each item a chance to handle the key + foreach (ToolStripItem tsi in this.Items) + if (tsi.ProcessDialogKey (keyData)) + return true; + + // See if I want to handle it + if (this.ProcessArrowKey (keyData)) + return true; + + ToolStrip ts = null; + + switch (keyData) { + case Keys.Escape: + this.Dismiss (ToolStripDropDownCloseReason.Keyboard); + return true; + + case Keys.Widget | Keys.Tab: + ts = ToolStripManager.GetNextToolStrip (this, true); + + if (ts != null) { + foreach (ToolStripItem tsi in this.Items) + tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard); + + ToolStripManager.SetActiveToolStrip (ts, true); + ts.SelectNextToolStripItem (null, true); + } + + return true; + case Keys.Widget | Keys.Shift | Keys.Tab: + ts = ToolStripManager.GetNextToolStrip (this, false); + + if (ts != null) { + foreach (ToolStripItem tsi in this.Items) + tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard); + + ToolStripManager.SetActiveToolStrip (ts, true); + ts.SelectNextToolStripItem (null, true); + } + + return true; + case Keys.Down: + case Keys.Up: + case Keys.Left: + case Keys.Right: + if (GetCurrentlySelectedItem () is ToolStripWidgetHost) + return false; + break; + } + + return base.ProcessDialogKey (keyData); + } + + protected override bool ProcessMnemonic (char charCode) + { + // If any item has an explicit mnemonic, it gets the message + foreach (ToolStripItem tsi in this.Items) + if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Widget.IsMnemonic (charCode, tsi.Text)) + return tsi.ProcessMnemonic (charCode); + + // Do not try to match any further here. See Xamarin bug 23532. + + return base.ProcessMnemonic (charCode); + } + + [MonoTODO ("Stub, does nothing")] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void RestoreFocus () + { + } + + protected override void Select (bool directed, bool forward) + { + foreach (ToolStripItem tsi in this.DisplayedItems) + if (tsi.CanSelect) { + tsi.Select (); + break; + } + } + + protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified) + { + base.SetBoundsCore (x, y, width, height, specified); + } + + protected virtual void SetDisplayedItems () + { + this.displayed_items.ClearInternal (); + + foreach (ToolStripItem tsi in this.items) + if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) { + this.displayed_items.AddNoOwnerOrLayout (tsi); + tsi.Parent = this; + } + else if (tsi.Placement == ToolStripItemPlacement.Overflow) + tsi.Parent = this.OverflowButton.DropDown; + + if (this.OverflowButton != null) + this.OverflowButton.DropDown.SetDisplayedItems (); + } + + protected internal void SetItemLocation (ToolStripItem item, Point location) + { + if (item == null) + throw new ArgumentNullException ("item"); + + if (item.Owner != this) + throw new NotSupportedException ("The item is not owned by this ToolStrip"); + + item.SetBounds (new Rectangle (location, item.Size)); + } + + protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent) + { + if (item.Owner != null) { + item.Owner.Items.RemoveNoOwnerOrLayout (item); + + if (item.Owner is ToolStripOverflow) + (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item); + } + + parent.Items.AddNoOwnerOrLayout (item); + item.Parent = parent; + } + + protected override void SetVisibleCore (bool visible) + { + base.SetVisibleCore (visible); + } + + protected override void WndProc (ref Message m) + { + base.WndProc (ref m); + } + #endregion + + #region Public Events + static object BeginDragEvent = new object (); + static object EndDragEvent = new object (); + static object ItemAddedEvent = new object (); + static object ItemClickedEvent = new object (); + static object ItemRemovedEvent = new object (); + static object LayoutCompletedEvent = new object (); + static object LayoutStyleChangedEvent = new object (); + static object PaintGripEvent = new object (); + static object RendererChangedEvent = new object (); + + [Browsable (true)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler AutoSizeChanged { + add { base.AutoSizeChanged += value; } + remove { base.AutoSizeChanged -= value; } + } + + [MonoTODO ("Event never raised")] + public event EventHandler BeginDrag { + add { Events.AddHandler (BeginDragEvent, value); } + remove { Events.RemoveHandler (BeginDragEvent, value); } + } + + [Browsable (false)] + public new event EventHandler CausesValidationChanged { + add { base.CausesValidationChanged += value; } + remove { base.CausesValidationChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event WidgetEventHandler WidgetAdded { + add { base.WidgetAdded += value; } + remove { base.WidgetAdded -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event WidgetEventHandler WidgetRemoved { + add { base.WidgetRemoved += value; } + remove { base.WidgetRemoved -= value; } + } + + [Browsable (false)] + public new event EventHandler CursorChanged { + add { base.CursorChanged += value; } + remove { base.CursorChanged -= value; } + } + + [MonoTODO ("Event never raised")] + public event EventHandler EndDrag { + add { Events.AddHandler (EndDragEvent, value); } + remove { Events.RemoveHandler (EndDragEvent, value); } + } + + [Browsable (false)] + public new event EventHandler ForeColorChanged { + add { base.ForeColorChanged += value; } + remove { base.ForeColorChanged -= value; } + } + + public event ToolStripItemEventHandler ItemAdded { + add { Events.AddHandler (ItemAddedEvent, value); } + remove { Events.RemoveHandler (ItemAddedEvent, value); } + } + + public event ToolStripItemClickedEventHandler ItemClicked { + add { Events.AddHandler (ItemClickedEvent, value); } + remove { Events.RemoveHandler (ItemClickedEvent, value); } + } + + public event ToolStripItemEventHandler ItemRemoved { + add { Events.AddHandler (ItemRemovedEvent, value); } + remove { Events.RemoveHandler (ItemRemovedEvent, value); } + } + + public event EventHandler LayoutCompleted { + add { Events.AddHandler (LayoutCompletedEvent, value); } + remove { Events.RemoveHandler (LayoutCompletedEvent, value); } + } + + public event EventHandler LayoutStyleChanged { + add { Events.AddHandler (LayoutStyleChangedEvent, value); } + remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); } + } + + public event PaintEventHandler PaintGrip { + add { Events.AddHandler (PaintGripEvent, value); } + remove { Events.RemoveHandler (PaintGripEvent, value); } + } + + public event EventHandler RendererChanged { + add { Events.AddHandler (RendererChangedEvent, value); } + remove { Events.RemoveHandler (RendererChangedEvent, value); } + } + #endregion + + #region Internal Properties + internal virtual bool KeyboardActive + { + get { return this.keyboard_active; } + set { + if (this.keyboard_active != value) { + this.keyboard_active = value; + + if (value) + Application.KeyboardCapture = this; + else if (Application.KeyboardCapture == this) { + Application.KeyboardCapture = null; + ToolStripManager.ActivatedByKeyboard = false; + } + + // Redraw for mnemonic underlines + this.Invalidate (); + } + } + } + #endregion + + #region Private Methods + internal virtual Rectangle CalculateConnectedArea () + { + return Rectangle.Empty; + } + + internal void ChangeSelection (ToolStripItem nextItem) + { + if (Application.KeyboardCapture != this) + ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard); + + foreach (ToolStripItem tsi in this.Items) + if (tsi != nextItem) + tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard); + + ToolStripItem current = GetCurrentlySelectedItem (); + + if (current != null && !(current is ToolStripWidgetHost)) + this.FocusInternal (true); + + if (nextItem is ToolStripWidgetHost) + (nextItem as ToolStripWidgetHost).Focus (); + + nextItem.Select (); + + if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown) + (nextItem as ToolStripMenuItem).HandleAutoExpansion (); + } + + internal virtual void Dismiss () + { + this.Dismiss (ToolStripDropDownCloseReason.AppClicked); + } + + internal virtual void Dismiss (ToolStripDropDownCloseReason reason) + { + // Release our stranglehold on the keyboard + this.KeyboardActive = false; + + // Set our drop down flag to false; + this.menu_selected = false; + + // Make sure all of our items are deselected and repainted + foreach (ToolStripItem tsi in this.Items) + tsi.Dismiss (reason); + + // We probably need to redraw for mnemonic underlines + this.Invalidate (); + } + + internal ToolStripItem GetCurrentlySelectedItem () + { + foreach (ToolStripItem tsi in this.DisplayedItems) + if (tsi.Selected) + return tsi; + + return null; + } + + internal ToolStripItem GetCurrentlyFocusedItem () + { + foreach (ToolStripItem tsi in this.DisplayedItems) + if ((tsi is ToolStripWidgetHost) && (tsi as ToolStripWidgetHost).Widget.Focused) + return tsi; + + return null; + } + + internal override Size GetPreferredSizeCore (Size proposedSize) + { + return GetToolStripPreferredSize (proposedSize); + } + + internal virtual Size GetToolStripPreferredSize (Size proposedSize) + { + Size new_size = Size.Empty; + + // TODO: This is total duct tape. We really have to call into the correct + // layout engine, do a dry run of the layout, and find out our true + // preferred dimensions. + if (this.LayoutStyle == ToolStripLayoutStyle.Flow) { + Point currentLocation = Point.Empty; + int tallest = 0; + + foreach (ToolStripItem tsi in items) + if (tsi.Available) { + Size tsi_preferred = tsi.GetPreferredSize (Size.Empty); + + if ((DisplayRectangle.Width - currentLocation.X) < (tsi_preferred.Width + tsi.Margin.Horizontal)) { + + currentLocation.Y += tallest; + tallest = 0; + + currentLocation.X = DisplayRectangle.Left; + } + + // Offset the left margin and set the Widget to our point + currentLocation.Offset (tsi.Margin.Left, 0); + tallest = Math.Max (tallest, tsi_preferred.Height + tsi.Margin.Vertical); + + // Update our location pointer + currentLocation.X += tsi_preferred.Width + tsi.Margin.Right; + } + + currentLocation.Y += tallest; + return new Size (currentLocation.X + this.Padding.Horizontal, currentLocation.Y + this.Padding.Vertical); + } + + if (this.orientation == Orientation.Vertical) { + foreach (ToolStripItem tsi in this.items) + if (tsi.Available) { + Size tsi_preferred = tsi.GetPreferredSize (Size.Empty); + new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom; + + if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal)) + new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal); + } + + new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4); + + if (new_size.Width == 0) + new_size.Width = ExplicitBounds.Width; + + return new_size; + } else { + foreach (ToolStripItem tsi in this.items) + if (tsi.Available) { + Size tsi_preferred = tsi.GetPreferredSize (Size.Empty); + new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right; + + if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical)) + new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical); + } + + new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4); + + if (new_size.Height == 0) + new_size.Height = ExplicitBounds.Height; + + if (this is StatusStrip) + new_size.Height = Math.Max (new_size.Height, 22); + + return new_size; + } + } + + internal virtual ToolStrip GetTopLevelToolStrip () + { + return this; + } + + internal virtual void HandleItemClick (ToolStripItem dismissingItem) + { + this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked); + } + + internal void NotifySelectedChanged (ToolStripItem tsi) + { + foreach (ToolStripItem tsi2 in this.DisplayedItems) + if (tsi != tsi2) + if (tsi2 is ToolStripDropDownItem) + (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard); + + if (this.OverflowButton != null) { + ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems; + + foreach (ToolStripItem tsi2 in tsic) + if (tsi != tsi2) + if (tsi2 is ToolStripDropDownItem) + (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard); + + this.OverflowButton.HideDropDown (); + } + + foreach (ToolStripItem tsi2 in this.Items) + if (tsi != tsi2) + tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard); + } + + internal virtual bool OnMenuKey () + { + return false; + } + + internal virtual bool ProcessArrowKey (Keys keyData) + { + ToolStripItem tsi; + + switch (keyData) { + case Keys.Right: + tsi = this.GetCurrentlySelectedItem (); + + if (tsi is ToolStripWidgetHost) + return false; + + tsi = this.SelectNextToolStripItem (tsi, true); + + if (tsi is ToolStripWidgetHost) + (tsi as ToolStripWidgetHost).Focus (); + + return true; + case Keys.Tab: + tsi = this.GetCurrentlySelectedItem (); + + tsi = this.SelectNextToolStripItem (tsi, true); + + if (tsi is ToolStripWidgetHost) + (tsi as ToolStripWidgetHost).Focus (); + + return true; + case Keys.Left: + tsi = this.GetCurrentlySelectedItem (); + + if (tsi is ToolStripWidgetHost) + return false; + + tsi = this.SelectNextToolStripItem (tsi, false); + + if (tsi is ToolStripWidgetHost) + (tsi as ToolStripWidgetHost).Focus (); + + return true; + case Keys.Shift | Keys.Tab: + tsi = this.GetCurrentlySelectedItem (); + + tsi = this.SelectNextToolStripItem (tsi, false); + + if (tsi is ToolStripWidgetHost) + (tsi as ToolStripWidgetHost).Focus (); + + return true; + } + + return false; + } + + internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward) + { + ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left); + + if (next_item == null) + return next_item; + + this.ChangeSelection (next_item); + + if (next_item is ToolStripWidgetHost) + (next_item as ToolStripWidgetHost).Focus (); + + return next_item; + } + + #region Stuff for ToolTips + private void MouseEnteredItem (ToolStripItem item) + { + if (this.show_item_tool_tips && !(item is ToolStripTextBox)) { + ToolTipTimer.Interval = InitialToolTipDelay; + tooltip_state = ToolTip.TipState.Initial; + tooltip_currently_showing = item; + ToolTipTimer.Start (); + } + } + + private void CloseToolTip (ToolStripItem item) + { + ToolTipTimer.Stop (); + ToolTipWindow.Hide (this); + tooltip_currently_showing = null; + tooltip_state = ToolTip.TipState.Down; + } + + private void MouseLeftItem (ToolStripItem item) + { + CloseToolTip (item); + } + + private Timer ToolTipTimer { + get { + if (tooltip_timer == null) { + tooltip_timer = new Timer (); + tooltip_timer.Enabled = false; + tooltip_timer.Interval = InitialToolTipDelay; + tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick); + } + + return tooltip_timer; + } + } + + private ToolTip ToolTipWindow { + get { + if (tooltip_window == null) + tooltip_window = new ToolTip (); + + return tooltip_window; + } + } + + private void ShowToolTip () + { + string tooltip = tooltip_currently_showing.GetToolTip (); + + if (!string.IsNullOrEmpty (tooltip)) { + ToolTipWindow.Present (this, tooltip); + ToolTipTimer.Interval = ToolTipDelay; + ToolTipTimer.Start (); + tooltip_state = ToolTip.TipState.Show; + } + + tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover); + } + + private void ToolTipTimer_Tick (object o, EventArgs args) + { + ToolTipTimer.Stop (); + + switch (tooltip_state) { + case ToolTip.TipState.Initial: + ShowToolTip (); + break; + case ToolTip.TipState.Show: + CloseToolTip (null); + break; + } + } + #endregion + + #region Stuff for Merging + internal ToolStrip CurrentlyMergedWith { + get { return this.currently_merged_with; } + set { this.currently_merged_with = value; } + } + + internal List<ToolStripItem> HiddenMergedItems { + get { + if (this.hidden_merged_items == null) + this.hidden_merged_items = new List<ToolStripItem> (); + + return this.hidden_merged_items; + } + } + + internal bool IsCurrentlyMerged { + get { return this.is_currently_merged; } + set { + this.is_currently_merged = value; + + if (!value && this is MenuStrip) + foreach (ToolStripMenuItem tsmi in this.Items) + tsmi.DropDown.IsCurrentlyMerged = value; + } + } + + internal void BeginMerge () + { + if (!IsCurrentlyMerged) { + IsCurrentlyMerged = true; + + if (this.pre_merge_items == null) { + this.pre_merge_items = new List<ToolStripItem> (); + + foreach (ToolStripItem tsi in this.Items) + this.pre_merge_items.Add (tsi); + } + } + } + + internal void RevertMergeItem (ToolStripItem item) + { + int index = 0; + + // Remove it from it's current Parent + if (item.Parent != null && item.Parent != this) { + if (item.Parent is ToolStripOverflow) + (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item); + else + item.Parent.Items.RemoveNoOwnerOrLayout (item); + + item.Parent = item.Owner; + } + + // Find where the item was before the merge + index = item.Owner.pre_merge_items.IndexOf (item); + + // Find the first pre-merge item that was after this item, that + // is currently in the Items collection. Insert our item before + // that one. + for (int i = index; i < this.pre_merge_items.Count; i++) { + if (this.Items.Contains (this.pre_merge_items[i])) { + item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item); + return; + } + } + + // There aren't any items that are supposed to be after this item, + // so just append it to the end. + item.Owner.Items.AddNoOwnerOrLayout (item); + } + #endregion + #endregion + + #region ToolStripAccessibleObject + [ComVisible (true)] + public class ToolStripAccessibleObject : WidgetAccessibleObject + { + #region Public Constructor + public ToolStripAccessibleObject (ToolStrip owner) : base (owner) + { + } + #endregion + + #region Public Properties + public override AccessibleRole Role { + get { return AccessibleRole.ToolBar; } + } + #endregion + + #region Public Methods + public override AccessibleObject GetChild (int index) + { + return base.GetChild (index); + } + + public override int GetChildCount () + { + return (owner as ToolStrip).Items.Count; + } + + public override AccessibleObject HitTest (int x, int y) + { + return base.HitTest (x, y); + } + #endregion + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripArrowRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripArrowRenderEventArgs.cs new file mode 100644 index 0000000..f11b44f --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripArrowRenderEventArgs.cs @@ -0,0 +1,79 @@ +// +// ToolStripArrowRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System; + +namespace ShiftUI +{ + public class ToolStripArrowRenderEventArgs : EventArgs + { + private Color arrow_color; + private Rectangle arrow_rectangle; + private ArrowDirection arrow_direction; + private Graphics graphics; + private ToolStripItem tool_strip_item; + + #region Public Constructors + public ToolStripArrowRenderEventArgs (Graphics g, ToolStripItem toolStripItem, Rectangle arrowRectangle, Color arrowColor, ArrowDirection arrowDirection) + : base () + { + this.graphics = g; + this.tool_strip_item = toolStripItem; + this.arrow_rectangle = arrowRectangle; + this.arrow_color = arrowColor; + this.arrow_direction = arrowDirection; + } + #endregion // Public Constructors + + #region Public Instance Properties + public Color ArrowColor { + get { return this.arrow_color; } + set { this.arrow_color = value; } + } + + public Rectangle ArrowRectangle { + get { return this.arrow_rectangle; } + set { this.arrow_rectangle = value; } + } + + public ArrowDirection Direction { + get { return this.arrow_direction; } + set { this.arrow_direction = value; } + } + + public Graphics Graphics { + get { return this.graphics; } + } + + public ToolStripItem Item { + get { return this.tool_strip_item; } + } + #endregion // Public Instance Properties + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripArrowRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripArrowRenderEventHandler.cs new file mode 100644 index 0000000..1e6e139 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripArrowRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripArrowRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripArrowRenderEventHandler (object sender, ToolStripArrowRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripButton.cs b/source/ShiftUI/ToolStrip/ToolStripButton.cs new file mode 100644 index 0000000..939ba5b --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripButton.cs @@ -0,0 +1,250 @@ +// +// ToolStripButton.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip)] + public class ToolStripButton : ToolStripItem + { + private CheckState checked_state; + private bool check_on_click; + + #region Public Constructors + public ToolStripButton () + : this (null, null, null, String.Empty) + { + } + + public ToolStripButton (Image image) + : this (null, image, null, String.Empty) + { + } + + public ToolStripButton (string text) + : this (text, null, null, String.Empty) + { + } + + public ToolStripButton (string text, Image image) + : this (text, image, null, String.Empty) + { + } + + public ToolStripButton (string text, Image image, EventHandler onClick) + : this (text, image, onClick, String.Empty) + { + } + + public ToolStripButton (string text, Image image, EventHandler onClick, string name) + : base (text, image, onClick, name) + { + this.checked_state = CheckState.Unchecked; + this.ToolTipText = String.Empty; + } + #endregion + + #region Public Properties + [DefaultValue (true)] + public new bool AutoToolTip { + get { return base.AutoToolTip; } + set { base.AutoToolTip = value; } + } + + public override bool CanSelect { + get { return true; } + } + + [DefaultValue (false)] + public bool Checked { + get { + switch (this.checked_state) { + case CheckState.Unchecked: + default: + return false; + case CheckState.Checked: + case CheckState.Indeterminate: + return true; + } + } + set { + if (this.checked_state != (value ? CheckState.Checked : CheckState.Unchecked)) { + this.checked_state = value ? CheckState.Checked : CheckState.Unchecked; + this.OnCheckedChanged (EventArgs.Empty); + this.OnCheckStateChanged (EventArgs.Empty); + this.Invalidate (); + } + } + } + + [DefaultValue (false)] + public bool CheckOnClick { + get { return this.check_on_click; } + set { + if (this.check_on_click != value) { + this.check_on_click = value; + OnUIACheckOnClickChangedEvent (EventArgs.Empty); + } + } + } + + [DefaultValue (CheckState.Unchecked)] + public CheckState CheckState { + get { return this.checked_state; } + set { + if (this.checked_state != value) { + if (!Enum.IsDefined (typeof (CheckState), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for CheckState", value)); + + this.checked_state = value; + this.OnCheckedChanged (EventArgs.Empty); + this.OnCheckStateChanged (EventArgs.Empty); + this.Invalidate (); + } + } + } + #endregion + + #region Protected Properties + protected override bool DefaultAutoToolTip { get { return true; } } + #endregion + + #region Public Methods + public override Size GetPreferredSize (Size constrainingSize) + { + Size retval = base.GetPreferredSize (constrainingSize); + + if (retval.Width < 23) + retval.Width = 23; + + return retval; + } + #endregion + + #region Protected Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override AccessibleObject CreateAccessibilityInstance () + { + ToolStripItemAccessibleObject ao = new ToolStripItemAccessibleObject (this); + + ao.default_action = "Press"; + ao.role = AccessibleRole.PushButton; + ao.state = AccessibleStates.Focusable; + + return ao; + } + + protected virtual void OnCheckedChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [CheckedChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnCheckStateChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [CheckStateChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnClick (EventArgs e) + { + if (this.check_on_click) + this.Checked = !this.Checked; + + base.OnClick (e); + + ToolStrip ts = this.GetTopLevelToolStrip (); + + if (ts != null) + ts.Dismiss (ToolStripDropDownCloseReason.ItemClicked); + } + + protected override void OnPaint (ShiftUI.PaintEventArgs e) + { + base.OnPaint (e); + + if (this.Owner != null) { + Color font_color = this.Enabled ? this.ForeColor : SystemColors.GrayText; + Image draw_image = this.Enabled ? this.Image : ToolStripRenderer.CreateDisabledImage (this.Image); + + this.Owner.Renderer.DrawButtonBackground (new ShiftUI.ToolStripItemRenderEventArgs (e.Graphics, this)); + + Rectangle text_layout_rect; + Rectangle image_layout_rect; + + this.CalculateTextAndImageRectangles (out text_layout_rect, out image_layout_rect); + + if (text_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign)); + if (image_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemImage (new ShiftUI.ToolStripItemImageRenderEventArgs (e.Graphics, this, draw_image, image_layout_rect)); + + return; + } + } + #endregion + + #region Public Events + static object CheckedChangedEvent = new object (); + static object CheckStateChangedEvent = new object (); + + public event EventHandler CheckedChanged { + add { Events.AddHandler (CheckedChangedEvent, value); } + remove { Events.RemoveHandler (CheckedChangedEvent, value); } + } + + public event EventHandler CheckStateChanged { + add { Events.AddHandler (CheckStateChangedEvent, value); } + remove { Events.RemoveHandler (CheckStateChangedEvent, value); } + } + #endregion + + #region UIA Framework Events + static object UIACheckOnClickChangedEvent = new object (); + + internal event EventHandler UIACheckOnClickChanged { + add { Events.AddHandler (UIACheckOnClickChangedEvent, value); } + remove { Events.RemoveHandler (UIACheckOnClickChangedEvent, value); } + } + + internal void OnUIACheckOnClickChangedEvent (EventArgs args) + { + EventHandler eh + = (EventHandler) Events [UIACheckOnClickChangedEvent]; + if (eh != null) + eh (this, args); + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripComboBox.cs b/source/ShiftUI/ToolStrip/ToolStripComboBox.cs new file mode 100644 index 0000000..617253a --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripComboBox.cs @@ -0,0 +1,421 @@ +// +// ToolStripComboBox.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; +using System; + +namespace ShiftUI +{ + [DefaultProperty ("Items")] + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.MenuStrip | ToolStripItemDesignerAvailability.ContextMenuStrip)] + public class ToolStripComboBox : ToolStripWidgetHost + { + #region Public Constructors + public ToolStripComboBox () : base (new ToolStripComboBoxWidget ()) + { + // The default size of a new ToolStripComboBox doesn't seem + // to be DefaultSize. + Size = new Size (121, 21); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public ToolStripComboBox (Widget c) : base (c) + { + throw new NotSupportedException (); + } + + public ToolStripComboBox (string name) : this () + { + base.Name = name; + } + #endregion + + #region Public Properties + [Browsable (true)] + [Localizable (true)] + //[EditorBrowsable (EditorBrowsableState.Always)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + //[Editor ("ShiftUI.Design.ListWidgetStringCollectionEditor, " + Consts.AssemblySystem_Design, + // //"System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)] + public AutoCompleteStringCollection AutoCompleteCustomSource { + get { return ComboBox.AutoCompleteCustomSource; } + set { ComboBox.AutoCompleteCustomSource = value; } + } + + [Browsable (true)] + [DefaultValue (AutoCompleteMode.None)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public AutoCompleteMode AutoCompleteMode { + get { return ComboBox.AutoCompleteMode; } + set { ComboBox.AutoCompleteMode = value; } + } + + [Browsable (true)] + [DefaultValue (AutoCompleteSource.None)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public AutoCompleteSource AutoCompleteSource { + get { return ComboBox.AutoCompleteSource; } + set { ComboBox.AutoCompleteSource = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Image BackgroundImage { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override ImageLayout BackgroundImageLayout { + get { return base.BackgroundImageLayout; } + set { base.BackgroundImageLayout = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ComboBox ComboBox { + get { return (ComboBox)base.Widget; } + } + + [Browsable (true)] + [DefaultValue (106)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public int DropDownHeight { + get { return this.ComboBox.DropDownHeight; } + set { this.ComboBox.DropDownHeight = value; } + } + + [DefaultValue (ComboBoxStyle.DropDown)] + [RefreshProperties (RefreshProperties.Repaint)] + public ComboBoxStyle DropDownStyle { + get { return this.ComboBox.DropDownStyle; } + set { this.ComboBox.DropDownStyle = value; } + } + + public int DropDownWidth { + get { return this.ComboBox.DropDownWidth; } + set { this.ComboBox.DropDownWidth = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public bool DroppedDown { + get { return this.ComboBox.DroppedDown; } + set { this.ComboBox.DroppedDown = value; } + } + + [LocalizableAttribute (true)] + [DefaultValue (FlatStyle.Popup)] + public FlatStyle FlatStyle { + get { return ComboBox.FlatStyle; } + set { ComboBox.FlatStyle = value; } + } + + [Localizable (true)] + [DefaultValue (true)] + public bool IntegralHeight { + get { return this.ComboBox.IntegralHeight; } + set { this.ComboBox.IntegralHeight = value; } + } + + [Localizable (true)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + //[Editor ("ShiftUI.Design.ListWidgetStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] + public ComboBox.ObjectCollection Items { + get { return this.ComboBox.Items; } + } + + [Localizable (true)] + [DefaultValue (8)] + public int MaxDropDownItems { + get { return this.ComboBox.MaxDropDownItems; } + set { this.ComboBox.MaxDropDownItems = value; } + } + + [Localizable (true)] + [DefaultValue (0)] + public int MaxLength { + get { return this.ComboBox.MaxLength; } + set { this.ComboBox.MaxLength = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public int SelectedIndex { + get { return this.ComboBox.SelectedIndex; } + set { + this.ComboBox.SelectedIndex = value; + + if (this.ComboBox.SelectedIndex >= 0) + Text = Items [value].ToString (); + } + } + + [Bindable (true)] + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public Object SelectedItem { + get { return this.ComboBox.SelectedItem; } + set { this.ComboBox.SelectedItem = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public string SelectedText { + get { return this.ComboBox.SelectedText; } + set { this.ComboBox.SelectedText = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public int SelectionLength { + get { return this.ComboBox.SelectionLength; } + set { this.ComboBox.SelectionLength = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public int SelectionStart { + get { return this.ComboBox.SelectionStart; } + set { this.ComboBox.SelectionStart = value; } + } + + [DefaultValue (false)] + public bool Sorted { + get { return this.ComboBox.Sorted; } + set { this.ComboBox.Sorted = value; } + } + #endregion + + #region Protected Properties + protected internal override Padding DefaultMargin { get { return new Padding (1, 0, 1, 0); } } + protected override Size DefaultSize { get { return new Size (100, 22); } } + #endregion + + #region Public Methods + public void BeginUpdate () + { + this.ComboBox.BeginUpdate (); + } + + public void EndUpdate () + { + this.ComboBox.EndUpdate (); + } + + public int FindString (string s) + { + return this.ComboBox.FindString (s); + } + + public int FindString (string s, int startIndex) + { + return this.ComboBox.FindString (s, startIndex); + } + + public int FindStringExact (string s) + { + return this.ComboBox.FindStringExact (s); + } + + public int FindStringExact (string s, int startIndex) + { + return this.ComboBox.FindStringExact (s, startIndex); + } + + public int GetItemHeight (int index) + { + return this.ComboBox.GetItemHeight (index); + } + + public override Size GetPreferredSize (Size constrainingSize) + { + return base.GetPreferredSize (constrainingSize); + } + + public void Select (int start, int length) + { + this.ComboBox.Select (start, length); + } + + public void SelectAll () + { + this.ComboBox.SelectAll (); + } + + public override string ToString () + { + return this.ComboBox.ToString (); + } + #endregion + + #region Protected Methods + protected virtual void OnDropDown (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [DropDownEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnDropDownClosed (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [DropDownClosedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnDropDownStyleChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [DropDownStyleChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnSelectedIndexChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnSelectionChangeCommitted (EventArgs e) + { + } + + protected override void OnSubscribeWidgetEvents (Widget Widget) + { + base.OnSubscribeWidgetEvents (Widget); + + this.ComboBox.DropDown += new EventHandler (HandleDropDown); + this.ComboBox.DropDownClosed += new EventHandler(HandleDropDownClosed); + this.ComboBox.DropDownStyleChanged += new EventHandler (HandleDropDownStyleChanged); + this.ComboBox.SelectedIndexChanged += new EventHandler (HandleSelectedIndexChanged); + this.ComboBox.TextChanged += new EventHandler (HandleTextChanged); + this.ComboBox.TextUpdate += new EventHandler (HandleTextUpdate); + } + + protected virtual void OnTextUpdate (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [TextUpdateEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnUnsubscribeWidgetEvents (Widget Widget) + { + base.OnUnsubscribeWidgetEvents (Widget); + } + #endregion + + #region Public Events + static object DropDownEvent = new object (); + static object DropDownClosedEvent = new object (); + static object DropDownStyleChangedEvent = new object (); + static object SelectedIndexChangedEvent = new object (); + static object TextUpdateEvent = new object (); + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler DoubleClick { + add { base.DoubleClick += value; } + remove { base.DoubleClick -= value; } + } + + public event EventHandler DropDown { + add { Events.AddHandler (DropDownEvent, value); } + remove { Events.RemoveHandler (DropDownEvent, value); } + } + + public event EventHandler DropDownClosed { + add { Events.AddHandler (DropDownClosedEvent, value); } + remove { Events.RemoveHandler (DropDownClosedEvent, value); } + } + + public event EventHandler DropDownStyleChanged { + add { Events.AddHandler (DropDownStyleChangedEvent, value); } + remove { Events.RemoveHandler (DropDownStyleChangedEvent, value); } + } + + public event EventHandler SelectedIndexChanged { + add { Events.AddHandler (SelectedIndexChangedEvent, value); } + remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); } + } + + public event EventHandler TextUpdate { + add { Events.AddHandler (TextUpdateEvent, value); } + remove { Events.RemoveHandler (TextUpdateEvent, value); } + } + #endregion + + #region Private Methods + private void HandleDropDown (object sender, EventArgs e) + { + OnDropDown (e); + } + + private void HandleDropDownClosed (object sender, EventArgs e) + { + OnDropDownClosed (e); + } + + private void HandleDropDownStyleChanged (object sender, EventArgs e) + { + OnDropDownStyleChanged (e); + } + + private void HandleSelectedIndexChanged (object sender, EventArgs e) + { + OnSelectedIndexChanged (e); + } + + private void HandleTextChanged (object sender, EventArgs e) + { + OnTextChanged (e); + } + + private void HandleTextUpdate (object sender, EventArgs e) + { + OnTextUpdate (e); + } + #endregion + + private class ToolStripComboBoxWidget : ComboBox + { + public ToolStripComboBoxWidget () : base () + { + this.border_style = BorderStyle.None; + this.FlatStyle = FlatStyle.Popup; + } + } + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripContainer.cs b/source/ShiftUI/ToolStrip/ToolStripContainer.cs new file mode 100644 index 0000000..09e0373 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripContainer.cs @@ -0,0 +1,310 @@ +// +// ToolStripContainer.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace ShiftUI +{ + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDispatch)] + //[Designer ("ShiftUI.Design.ToolStripContainerDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + public class ToolStripContainer : ContainerWidget + { + private ToolStripPanel bottom_panel; + private ToolStripContentPanel content_panel; + private ToolStripPanel left_panel; + private ToolStripPanel right_panel; + private ToolStripPanel top_panel; + + #region Public Constructors + public ToolStripContainer () : base () + { + SetStyle (Widgetstyles.SupportsTransparentBackColor, true); + SetStyle (Widgetstyles.ResizeRedraw, true); + + content_panel = new ToolStripContentPanel (); + content_panel.Dock = DockStyle.Fill; + this.Widgets.Add (content_panel); + + this.top_panel = new ToolStripPanel (); + this.top_panel.Dock = DockStyle.Top; + this.top_panel.Height = 0; + this.Widgets.Add (top_panel); + + this.bottom_panel = new ToolStripPanel (); + this.bottom_panel.Dock = DockStyle.Bottom; + this.bottom_panel.Height = 0; + this.Widgets.Add (bottom_panel); + + this.left_panel = new ToolStripPanel (); + this.left_panel.Dock = DockStyle.Left; + this.left_panel.Width = 0; + this.Widgets.Add (left_panel); + + this.right_panel = new ToolStripPanel (); + this.right_panel.Dock = DockStyle.Right; + this.right_panel.Width = 0; + this.Widgets.Add (right_panel); + } + #endregion + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override bool AutoScroll { + get { return base.AutoScroll; } + set { base.AutoScroll = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMargin { + get { return base.AutoScrollMargin; } + set { base.AutoScrollMargin = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMinSize { + get { return base.AutoScrollMinSize; } + set { base.AutoScrollMinSize = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Color BackColor { + get { return base.BackColor; } + set { base.BackColor = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Image BackgroundImage { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override ImageLayout BackgroundImageLayout { + get { return base.BackgroundImageLayout; } + set { base.BackgroundImageLayout = value; } + } + + [Localizable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + public ToolStripPanel BottomToolStripPanel { + get { return this.bottom_panel; } + } + + [DefaultValue (true)] + public bool BottomToolStripPanelVisible { + get { return this.bottom_panel.Visible; } + set { this.bottom_panel.Visible = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool CausesValidation { + get { return base.CausesValidation; } + set { base.CausesValidation = value; } + } + + [Localizable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + public ToolStripContentPanel ContentPanel { + get { return this.content_panel; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ContextMenuStrip ContextMenuStrip { + get { return base.ContextMenuStrip; } + set { base.ContextMenuStrip = value; } + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new WidgetCollection Widgets { + get { return base.Widgets; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Cursor Cursor { + get { return base.Cursor; } + set { base.Cursor = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Color ForeColor { + get { return base.ForeColor; } + set { base.ForeColor = value; } + } + + [Localizable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + public ToolStripPanel LeftToolStripPanel { + get { return this.left_panel; } + } + + [DefaultValue (true)] + public bool LeftToolStripPanelVisible { + get { return this.left_panel.Visible; } + set { this.left_panel.Visible = value; } + } + + [Localizable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + public ToolStripPanel RightToolStripPanel { + get { return this.right_panel; } + } + + [DefaultValue (true)] + public bool RightToolStripPanelVisible { + get { return this.right_panel.Visible; } + set { this.right_panel.Visible = value; } + } + + [Localizable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + public ToolStripPanel TopToolStripPanel { + get { return this.top_panel; } + } + + [DefaultValue (true)] + public bool TopToolStripPanelVisible { + get { return this.top_panel.Visible; } + set { this.top_panel.Visible = value; } + } + #endregion + + #region Protected Properties + protected override Size DefaultSize { + get { return new Size (150, 175); } + } + #endregion + + #region Protected Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override WidgetCollection CreateWidgetsInstance () + { + return new ToolStripContainerTypedWidgetCollection (this); + } + + protected override void OnRightToLeftChanged (EventArgs e) + { + base.OnRightToLeftChanged (e); + } + + protected override void OnSizeChanged (EventArgs e) + { + base.OnSizeChanged (e); + } + #endregion + + #region Public Events + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler BackColorChanged { + add { base.BackColorChanged += value; } + remove { base.BackColorChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler BackgroundImageChanged { + add { base.BackgroundImageChanged += value; } + remove { base.BackgroundImageChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler BackgroundImageLayoutChanged { + add { base.BackgroundImageLayoutChanged += value; } + remove { base.BackgroundImageLayoutChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler CausesValidationChanged { + add { base.CausesValidationChanged += value; } + remove { base.CausesValidationChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler ContextMenuStripChanged { + add { base.ContextMenuStripChanged += value; } + remove { base.ContextMenuStripChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler CursorChanged { + add { base.CursorChanged += value; } + remove { base.CursorChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler ForeColorChanged { + add { base.ForeColorChanged += value; } + remove { base.ForeColorChanged -= value; } + } + #endregion + + #region Private Class : ToolStripContainerTypedWidgetCollection + private class ToolStripContainerTypedWidgetCollection : WidgetCollection + { + public ToolStripContainerTypedWidgetCollection (Widget owner) : base (owner) + { + } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripContentPanel.cs b/source/ShiftUI/ToolStrip/ToolStripContentPanel.cs new file mode 100644 index 0000000..8719922 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripContentPanel.cs @@ -0,0 +1,304 @@ +// +// ToolStripContentPanel.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.Runtime.InteropServices; +using ShiftUI.Layout; +using System.ComponentModel; +using System; + +namespace ShiftUI +{ + [ComVisible(true)] + [ClassInterface(ClassInterfaceType.AutoDispatch)] + [DefaultEvent ("Load")] + [ToolboxItem (false)] + [Docking (DockingBehavior.Never)] + [InitializationEvent ("Load")] + //[Designer ("ShiftUI.Design.ToolStripContentPanelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + public class ToolStripContentPanel : Panel + { + private ToolStripRenderMode render_mode; + private ToolStripRenderer renderer; + + #region Public Constructors + public ToolStripContentPanel () : base () + { + this.RenderMode = ToolStripRenderMode.System; + } + #endregion + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override AnchorStyles Anchor { + get { return base.Anchor; } + set { base.Anchor = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public override bool AutoScroll { + get { return base.AutoScroll; } + set { base.AutoScroll = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMargin { + get { return base.AutoScrollMargin; } + set { base.AutoScrollMargin = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMinSize { + get { return base.AutoScrollMinSize; } + set { base.AutoScrollMinSize = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override bool AutoSize { + get { return base.AutoSize; } + set { base.AutoSize = value; } + } + + [Browsable (false)] + [Localizable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override AutoSizeMode AutoSizeMode { + get { return base.AutoSizeMode; } + set { base.AutoSizeMode = value; } + } + + public override Color BackColor { + get { return base.BackColor; } + set { base.BackColor = value; + + if (this.Parent != null) + this.Parent.BackColor = value; + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool CausesValidation { + get { return base.CausesValidation; } + set { base.CausesValidation = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override DockStyle Dock { + get { return base.Dock; } + set { base.Dock = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Point Location { + get { return base.Location; } + set { base.Location = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Size MaximumSize { + get { return base.MaximumSize; } + set { base.MaximumSize = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Size MinimumSize { + get { return base.MinimumSize; } + set { base.MinimumSize = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new string Name { + get { return base.Name; } + set { base.Name = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ToolStripRenderer Renderer { + get { + if (this.render_mode == ToolStripRenderMode.ManagerRenderMode) + return ToolStripManager.Renderer; + + return this.renderer; + } + set { + if (this.renderer != value) { + this.renderer = value; + this.render_mode = ToolStripRenderMode.Custom; + this.OnRendererChanged (EventArgs.Empty); + } + } + } + + public ToolStripRenderMode RenderMode { + get { return this.render_mode; } + set { + if (!Enum.IsDefined (typeof (ToolStripRenderMode), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value)); + + if (value == ToolStripRenderMode.Custom && this.renderer == null) + throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom"); + else if (value == ToolStripRenderMode.Professional) + this.renderer = new ToolStripProfessionalRenderer (); + else if (value == ToolStripRenderMode.System) + this.renderer = new ToolStripSystemRenderer (); + + this.render_mode = value; + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new int TabIndex { + get { return base.TabIndex; } + set { base.TabIndex = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool TabStop { + get { return base.TabStop; } + set { base.TabStop = value; } + } + #endregion + + #region Protected Methods + protected override void OnHandleCreated (EventArgs e) + { + base.OnHandleCreated (e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnLoad (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [LoadEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override void OnPaintBackground (PaintEventArgs e) + { + base.OnPaintBackground (e); + + this.Renderer.DrawToolStripContentPanelBackground (new ToolStripContentPanelRenderEventArgs (e.Graphics, this)); + } + + protected virtual void OnRendererChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [RendererChangedEvent]); + if (eh != null) + eh (this, e); + } + #endregion + + #region Public Events + static object LoadEvent = new object (); + static object RendererChangedEvent = new object (); + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler AutoSizeChanged { + add { base.AutoSizeChanged += value; } + remove { base.AutoSizeChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler CausesValidationChanged { + add { base.CausesValidationChanged += value; } + remove { base.CausesValidationChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler DockChanged { + add { base.DockChanged += value; } + remove { base.DockChanged -= value; } + } + + public event EventHandler Load { + add { Events.AddHandler (LoadEvent, value); } + remove { Events.RemoveHandler (LoadEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new event EventHandler LocationChanged { + add { base.LocationChanged += value; } + remove { base.LocationChanged -= value; } + } + + public event EventHandler RendererChanged { + add { Events.AddHandler (RendererChangedEvent, value); } + remove { Events.RemoveHandler (RendererChangedEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TabIndexChanged { + add { base.TabIndexChanged += value; } + remove { base.TabIndexChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TabStopChanged { + add { base.TabStopChanged += value; } + remove { base.TabStopChanged -= value; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripContentPanelRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripContentPanelRenderEventArgs.cs new file mode 100644 index 0000000..313e0e5 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripContentPanelRenderEventArgs.cs @@ -0,0 +1,62 @@ +// +// ToolStripContentPanelRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System; + +namespace ShiftUI +{ + public class ToolStripContentPanelRenderEventArgs : EventArgs + { + private Graphics graphics; + private bool handled; + private ToolStripContentPanel tool_strip_content_panel; + + public ToolStripContentPanelRenderEventArgs (Graphics g, ToolStripContentPanel contentPanel) : base () + { + this.graphics = g; + this.tool_strip_content_panel = contentPanel; + this.handled = false; + } + + #region Public Properties + public Graphics Graphics { + get { return this.graphics; } + } + + public bool Handled { + get { return this.handled; } + set { this.handled = value; } + } + + public ToolStripContentPanel ToolStripContentPanel { + get { return this.tool_strip_content_panel; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripContentPanelRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripContentPanelRenderEventHandler.cs new file mode 100644 index 0000000..4901230 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripContentPanelRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripContentPanelRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripContentPanelRenderEventHandler (object sender, ToolStripContentPanelRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripControlHost.cs b/source/ShiftUI/ToolStrip/ToolStripControlHost.cs new file mode 100644 index 0000000..cf2aeb1 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripControlHost.cs @@ -0,0 +1,577 @@ +// +// ToolStripWidgetHost.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using System; + +namespace ShiftUI +{ + public class ToolStripWidgetHost : ToolStripItem + { + private Widget _Widget; + private ContentAlignment Widget_align; + private bool double_click_enabled; + + #region Public Constructors + public ToolStripWidgetHost (Widget c) : base () + { + if (c == null) + throw new ArgumentNullException ("c"); + + this.RightToLeft = RightToLeft.No; + this._Widget = c; + this._Widget.Alignment = ContentAlignment.MiddleCenter; + this._Widget.TabStop = false; + this._Widget.Resize += WidgetResizeHandler; + this.Size = DefaultSize; + this.OnSubscribeWidgetEvents (this.Widget); + } + + public ToolStripWidgetHost (Widget c, string name) : this (c) + { + base.Name = name; + } + #endregion + + #region Public Properties + public override Color BackColor { + get { return Widget.BackColor; } + set { Widget.BackColor = value; + } + } + + [Localizable (true)] + [DefaultValue (null)] + public override Image BackgroundImage { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + [Localizable (true)] + [DefaultValue (ImageLayout.Tile)] + public override ImageLayout BackgroundImageLayout { + get { return base.BackgroundImageLayout; } + set { base.BackgroundImageLayout = value; } + } + + public override bool CanSelect { + get { return Widget.CanSelect; } + } + + [DefaultValue (true)] + public bool CausesValidation { + get { return Widget.CausesValidation; } + set { Widget.CausesValidation = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public Widget Widget { + get { return this._Widget; } + } + + [Browsable (false)] + [DefaultValue (ContentAlignment.MiddleCenter)] + public ContentAlignment WidgetAlign { + get { return this.Widget_align; } + set { + if (Widget_align != value) { + if (!Enum.IsDefined (typeof (ContentAlignment), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value)); + + this.Widget_align = value; + + if (Widget != null) + Widget.Bounds = AlignInRectangle (this.Bounds, Widget.Size, this.Widget_align); + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ToolStripItemDisplayStyle DisplayStyle { + get { return base.DisplayStyle; } + set { base.DisplayStyle = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + [DefaultValue (false)] + public new bool DoubleClickEnabled { + get { return this.double_click_enabled; } + set { this.double_click_enabled = value; } + } + + public override bool Enabled { + get { return base.Enabled; } + set { + base.Enabled = value; + Widget.Enabled = value; + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public virtual bool Focused { + get { return Widget.Focused; } + } + + public override Font Font { + get { return Widget.Font; } + set { Widget.Font = value; } + } + + public override Color ForeColor { + get { return Widget.ForeColor; } + set { Widget.ForeColor = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Image Image { + get { return base.Image; } + set { base.Image = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ContentAlignment ImageAlign { + get { return base.ImageAlign; } + set { base.ImageAlign = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ToolStripItemImageScaling ImageScaling { + get { return base.ImageScaling; } + set { base.ImageScaling = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Color ImageTransparentColor { + get { return base.ImageTransparentColor; } + set { base.ImageTransparentColor = value; } + } + + public override RightToLeft RightToLeft { + get { return base.RightToLeft; } + set { base.RightToLeft = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool RightToLeftAutoMirrorImage { + get { return base.RightToLeftAutoMirrorImage; } + set { base.RightToLeftAutoMirrorImage = value; } + } + + public override bool Selected { + get { return base.Selected; } + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public override ISite Site { + get { return Widget.Site; } + set { Widget.Site = value; + } + } + + public override Size Size { + get { return base.Size; } + set { Widget.Size = value; base.Size = value; if (this.Owner != null) this.Owner.PerformLayout (); } + } + + [DefaultValue ("")] + public override string Text { + get { return Widget.Text; } + set { + base.Text = value; + Widget.Text = value; + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new ContentAlignment TextAlign { + get { return base.TextAlign; } + set { base.TextAlign = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + [DefaultValue (ToolStripTextDirection.Horizontal)] + public override ToolStripTextDirection TextDirection { + get { return base.TextDirection; } + set { base.TextDirection = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new TextImageRelation TextImageRelation { + get { return base.TextImageRelation; } + set { base.TextImageRelation = value; } + } + #endregion + + #region Protected Properties + protected override Size DefaultSize { + get { + if (Widget == null) + return new Size (23, 23); + + return Widget.Size; + } + } + #endregion + + #region Public Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public void Focus () + { + Widget.Focus (); + } + + public override Size GetPreferredSize (Size constrainingSize) + { + return Widget.GetPreferredSize (constrainingSize); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public override void ResetBackColor () + { + base.ResetBackColor (); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public override void ResetForeColor () + { + base.ResetForeColor (); + } + #endregion + + #region Protected Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override AccessibleObject CreateAccessibilityInstance () + { + return Widget.AccessibilityObject; + } + + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + + if (Widget.Created && !Widget.IsDisposed) + Widget.Dispose (); + } + + protected override void OnBoundsChanged () + { + if (Widget != null) + Widget.Bounds = AlignInRectangle (this.Bounds, Widget.Size, this.Widget_align); + + base.OnBoundsChanged (); + } + + protected virtual void OnEnter (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [EnterEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnGotFocus (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [GotFocusEvent]); + if (eh != null) + eh (this, e); + } + + void WidgetResizeHandler (object obj, EventArgs args) + { + OnHostedWidgetResize (args); + } + + protected virtual void OnHostedWidgetResize (EventArgs e) + { + // Since the Widget size has been just adjusted, only update the location + if (Widget != null) + Widget.Location = AlignInRectangle (this.Bounds, Widget.Size, this.Widget_align).Location; + } + + protected virtual void OnKeyDown (KeyEventArgs e) + { + KeyEventHandler eh = (KeyEventHandler)(Events [KeyDownEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnKeyPress (KeyPressEventArgs e) + { + KeyPressEventHandler eh = (KeyPressEventHandler)(Events [KeyPressEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnKeyUp (KeyEventArgs e) + { + KeyEventHandler eh = (KeyEventHandler)(Events [KeyUpEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnLayout (LayoutEventArgs e) + { + base.OnLayout (e); + + if (Widget != null) + Widget.Bounds = AlignInRectangle (this.Bounds, Widget.Size, this.Widget_align); + } + + protected virtual void OnLeave (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [LeaveEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnLostFocus (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [LostFocusEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnPaint (PaintEventArgs e) + { + base.OnPaint (e); + } + + protected override void OnParentChanged (ToolStrip oldParent, ToolStrip newParent) + { + base.OnParentChanged (oldParent, newParent); + + if (oldParent != null) + oldParent.Widgets.Remove (Widget); + + if (newParent != null) + newParent.Widgets.Add (Widget); + } + + protected virtual void OnSubscribeWidgetEvents (Widget Widget) + { + this.Widget.Enter += new EventHandler (HandleEnter); + this.Widget.GotFocus += new EventHandler (HandleGotFocus); + this.Widget.KeyDown += new KeyEventHandler (HandleKeyDown); + this.Widget.KeyPress += new KeyPressEventHandler (HandleKeyPress); + this.Widget.KeyUp += new KeyEventHandler (HandleKeyUp); + this.Widget.Leave += new EventHandler (HandleLeave); + this.Widget.LostFocus += new EventHandler (HandleLostFocus); + this.Widget.Validated += new EventHandler (HandleValidated); + this.Widget.Validating += new CancelEventHandler (HandleValidating); + } + + protected virtual void OnUnsubscribeWidgetEvents (Widget Widget) + { + } + + protected virtual void OnValidated (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [ValidatedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnValidating (CancelEventArgs e) + { + CancelEventHandler eh = (CancelEventHandler)(Events [ValidatingEvent]); + if (eh != null) + eh (this, e); + } + + protected internal override bool ProcessCmdKey (ref Message m, Keys keyData) + { + return base.ProcessCmdKey (ref m, keyData); + } + + protected internal override bool ProcessDialogKey (Keys keyData) + { + return base.ProcessDialogKey (keyData); + } + + protected override void SetVisibleCore (bool visible) + { + base.SetVisibleCore (visible); + this.Widget.Visible = visible; + + if (Widget != null) + Widget.Bounds = AlignInRectangle (this.Bounds, Widget.Size, this.Widget_align); + } + #endregion + + #region Public Events + static object EnterEvent = new object (); + static object GotFocusEvent = new object (); + static object KeyDownEvent = new object (); + static object KeyPressEvent = new object (); + static object KeyUpEvent = new object (); + static object LeaveEvent = new object (); + static object LostFocusEvent = new object (); + static object ValidatedEvent = new object (); + static object ValidatingEvent = new object (); + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler DisplayStyleChanged { + add { base.DisplayStyleChanged += value; } + remove { base.DisplayStyleChanged -= value; } + } + + public event EventHandler Enter { + add { Events.AddHandler (EnterEvent, value); } + remove { Events.RemoveHandler (EnterEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event EventHandler GotFocus { + add { Events.AddHandler (GotFocusEvent, value); } + remove { Events.RemoveHandler (GotFocusEvent, value); } + } + + public event KeyEventHandler KeyDown { + add { Events.AddHandler (KeyDownEvent, value); } + remove { Events.RemoveHandler (KeyDownEvent, value); } + } + + public event KeyPressEventHandler KeyPress { + add { Events.AddHandler (KeyPressEvent, value); } + remove { Events.RemoveHandler (KeyPressEvent, value); } + } + + public event KeyEventHandler KeyUp { + add { Events.AddHandler (KeyUpEvent, value); } + remove { Events.RemoveHandler (KeyUpEvent, value); } + } + + public event EventHandler Leave { + add { Events.AddHandler (LeaveEvent, value); } + remove { Events.RemoveHandler (LeaveEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event EventHandler LostFocus { + add { Events.AddHandler (LostFocusEvent, value); } + remove { Events.RemoveHandler (LostFocusEvent, value); } + } + + public event EventHandler Validated { + add { Events.AddHandler (ValidatedEvent, value); } + remove { Events.RemoveHandler (ValidatedEvent, value); } + } + + public event CancelEventHandler Validating { + add { Events.AddHandler (ValidatingEvent, value); } + remove { Events.RemoveHandler (ValidatingEvent, value); } + } + #endregion + + #region Private Methods + internal override ToolStripTextDirection DefaultTextDirection { get { return ToolStripTextDirection.Horizontal; } } + + internal override void Dismiss (ToolStripDropDownCloseReason reason) + { + if (this.Selected) + this.Parent.Focus (); + + base.Dismiss (reason); + } + + private void HandleEnter (object sender, EventArgs e) + { + this.OnEnter (e); + } + + private void HandleGotFocus (object sender, EventArgs e) + { + this.OnGotFocus (e); + } + + private void HandleKeyDown (object sender, KeyEventArgs e) + { + this.OnKeyDown (e); + } + + private void HandleKeyPress (object sender, KeyPressEventArgs e) + { + this.OnKeyPress (e); + } + + private void HandleKeyUp (object sender, KeyEventArgs e) + { + this.OnKeyUp (e); + } + + private void HandleLeave (object sender, EventArgs e) + { + this.OnLeave (e); + } + + private void HandleLostFocus (object sender, EventArgs e) + { + this.OnLostFocus (e); + } + + private void HandleValidated (object sender, EventArgs e) + { + this.OnValidated (e); + } + + private void HandleValidating (object sender, CancelEventArgs e) + { + this.OnValidating (e); + } + + internal override bool InternalVisible { + get { return base.InternalVisible; } + set { + Widget.Visible = value; + base.InternalVisible = value; + } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDown.cs b/source/ShiftUI/ToolStrip/ToolStripDropDown.cs new file mode 100644 index 0000000..443684e --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDown.cs @@ -0,0 +1,1051 @@ +// +// ToolStripDropDown.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System; + +namespace ShiftUI +{ + [ClassInterface (ClassInterfaceType.AutoDispatch)] + [ComVisible (true)] + //[Designer ("ShiftUI.Design.ToolStripDropDownDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + public class ToolStripDropDown : ToolStrip + { + private bool allow_transparency; + private bool auto_close; + private bool can_overflow; + private bool drop_shadow_enabled = true; + private double opacity = 1D; + private ToolStripItem owner_item; + + #region Public Constructor + public ToolStripDropDown () : base () + { + SetStyle (Widgetstyles.UserPaint | Widgetstyles.AllPaintingInWmPaint, true); + SetStyle (Widgetstyles.ResizeRedraw, true); + + this.auto_close = true; + is_visible = false; + this.DefaultDropDownDirection = ToolStripDropDownDirection.Right; + this.GripStyle = ToolStripGripStyle.Hidden; + this.is_toplevel = true; + } + #endregion + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new bool AllowItemReorder { + get { return base.AllowItemReorder; } + set { base.AllowItemReorder = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public bool AllowTransparency { + get { return allow_transparency; } + set { + if (value == allow_transparency) + return; + + if ((XplatUI.SupportsTransparency () & TransparencySupport.Set) != 0) { + allow_transparency = value; + + if (this.IsHandleCreated) { + if (value) + XplatUI.SetWindowTransparency (Handle, Opacity, Color.Empty); + else + UpdateStyles (); // Remove the WS_EX_LAYERED style + } + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public override AnchorStyles Anchor { + get { return base.Anchor; } + set { base.Anchor = value; } + } + + [DefaultValue (true)] + public bool AutoClose + { + get { return this.auto_close; } + set { this.auto_close = value; } + } + + [DefaultValue (true)] + public override bool AutoSize { + get { return base.AutoSize; } + set { base.AutoSize = value; } + } + + [Browsable (false)] + [DefaultValue (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new bool CanOverflow { + get { return this.can_overflow; } + set { this.can_overflow = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new ContextMenuStrip ContextMenuStrip { + get { return null; } + set { } + } + + public override ToolStripDropDownDirection DefaultDropDownDirection { + get { return base.DefaultDropDownDirection; } + set { base.DefaultDropDownDirection = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + [DefaultValue (DockStyle.None)] + public override DockStyle Dock { + get { return base.Dock; } + set { base.Dock = value; } + } + + public bool DropShadowEnabled { + get { return this.drop_shadow_enabled; } + set { + if (this.drop_shadow_enabled == value) + return; + + this.drop_shadow_enabled = value; + UpdateStyles (); // Re-CreateParams + } + } + + public override Font Font { + get { return base.Font; } + set { base.Font = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new ToolStripGripDisplayStyle GripDisplayStyle { + get { return ToolStripGripDisplayStyle.Vertical; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Padding GripMargin { + get { return Padding.Empty; } + set { } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new Rectangle GripRectangle { + get { return Rectangle.Empty; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + [DefaultValue (ToolStripGripStyle.Hidden)] + public new ToolStripGripStyle GripStyle { + get { return base.GripStyle; } + set { base.GripStyle = value; } + } + + [Browsable (false)] + public bool IsAutoGenerated { + get { return this is ToolStripOverflow; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Point Location { + get { return base.Location; } + set { base.Location = value; } + } + + [DefaultValue (1D)] + [TypeConverter (typeof (OpacityConverter))] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public double Opacity { + get { return this.opacity; } + set { + if (this.opacity == value) + return; + + this.opacity = value; + this.allow_transparency = true; + + if (this.IsHandleCreated) { + UpdateStyles (); + XplatUI.SetWindowTransparency (Handle, opacity, Color.Empty); + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new ToolStripOverflowButton OverflowButton { + get { return base.OverflowButton; } + } + + [Browsable (false)] + [DefaultValue (null)] + public ToolStripItem OwnerItem { + get { return this.owner_item; } + set { this.owner_item = value; + + if (this.owner_item != null) { + if (this.owner_item.Owner != null && this.owner_item.Owner.RenderMode != ToolStripRenderMode.ManagerRenderMode) + this.Renderer = this.owner_item.Owner.Renderer; + + Font = owner_item.Font; + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new Region Region { + get { return base.Region; } + set { base.Region = value; } + } + + [Localizable (true)] + [AmbientValue (RightToLeft.Inherit)] + public override RightToLeft RightToLeft { + get { return base.RightToLeft; } + set { base.RightToLeft = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new bool Stretch { + get { return false; } + set { } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new int TabIndex { + get { return 0; } + set { } + } + + [Browsable (false)] + [DefaultValue (ToolStripTextDirection.Horizontal)] + public override ToolStripTextDirection TextDirection { + get { return base.TextDirection; } + set { base.TextDirection = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public bool TopLevel { + get { return GetTopLevel (); } + set { SetTopLevel (value); } + } + + [Browsable (false)] + [Localizable (true)] + [DefaultValue (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool Visible { + get { return base.Visible; } + set { base.Visible = value; } + } + #endregion + + #region Protected Properties + protected override CreateParams CreateParams { + get { + CreateParams cp = base.CreateParams; + + cp.Style = unchecked ((int)(WindowStyles.WS_POPUP | WindowStyles.WS_CLIPCHILDREN)); + cp.ClassStyle |= (int)XplatUIWin32.ClassStyle.CS_DROPSHADOW; + cp.ExStyle |= (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST); + + if (Opacity < 1.0 && allow_transparency) + cp.ExStyle |= (int)WindowExStyles.WS_EX_LAYERED; + if (TopMost) + cp.ExStyle |= (int) WindowExStyles.WS_EX_TOPMOST; + + return cp; + } + } + + protected override DockStyle DefaultDock { + get { return DockStyle.None; } + } + + protected override Padding DefaultPadding { + get { return new Padding (1, 2, 1, 2); } + } + + protected override bool DefaultShowItemToolTips { + get { return true; } + } + + protected internal override Size MaxItemSize { + get { return new Size (Screen.PrimaryScreen.Bounds.Width - 2, Screen.PrimaryScreen.Bounds.Height - 34); } + } + + protected virtual bool TopMost { + get { return true; } + } + #endregion + + #region Public Methods + public void Close () + { + this.Close (ToolStripDropDownCloseReason.CloseCalled); + } + + public void Close (ToolStripDropDownCloseReason reason) + { + if (!this.Visible) + return; + + // Give users a chance to cancel the close + ToolStripDropDownClosingEventArgs e = new ToolStripDropDownClosingEventArgs (reason); + this.OnClosing (e); + + if (e.Cancel) + return; + + // Don't actually close if AutoClose == true unless explicitly called + if (!this.auto_close && reason != ToolStripDropDownCloseReason.CloseCalled) + return; + + // Detach from the tracker + ToolStripManager.AppClicked -= new EventHandler (ToolStripMenuTracker_AppClicked); ; + ToolStripManager.AppFocusChange -= new EventHandler (ToolStripMenuTracker_AppFocusChange); + + // Hide this dropdown + this.Hide (); + + // Owner MenuItem needs to be told to redraw (it's no longer selected) + if (owner_item != null) + owner_item.Invalidate (); + + // Recursive hide all child dropdowns + foreach (ToolStripItem tsi in this.Items) + tsi.Dismiss (reason); + + this.OnClosed (new ToolStripDropDownClosedEventArgs (reason)); + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new void Show () + { + Show (Location, DefaultDropDownDirection); + } + + public void Show (Point screenLocation) + { + Show (screenLocation, DefaultDropDownDirection); + } + + public void Show (Widget Widget, Point position) + { + if (Widget == null) + throw new ArgumentNullException ("Widget"); + + XplatUI.SetOwner (Handle, Widget.Handle); + Show (Widget.PointToScreen (position), DefaultDropDownDirection); + } + + public void Show (int x, int y) + { + Show (new Point (x, y), DefaultDropDownDirection); + } + + public void Show (Point position, ToolStripDropDownDirection direction) + { + this.PerformLayout (); + + Point show_point = position; + Point max_screen = new Point (SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height); + + if (this is ContextMenuStrip) { + // If we are going to go offscreen, adjust our direction so we don't... + // X direction + switch (direction) { + case ToolStripDropDownDirection.AboveLeft: + if (show_point.X - this.Width < 0) + direction = ToolStripDropDownDirection.AboveRight; + break; + case ToolStripDropDownDirection.BelowLeft: + if (show_point.X - this.Width < 0) + direction = ToolStripDropDownDirection.BelowRight; + break; + case ToolStripDropDownDirection.Left: + if (show_point.X - this.Width < 0) + direction = ToolStripDropDownDirection.Right; + break; + case ToolStripDropDownDirection.AboveRight: + if (show_point.X + this.Width > max_screen.X) + direction = ToolStripDropDownDirection.AboveLeft; + break; + case ToolStripDropDownDirection.BelowRight: + case ToolStripDropDownDirection.Default: + if (show_point.X + this.Width > max_screen.X) + direction = ToolStripDropDownDirection.BelowLeft; + break; + case ToolStripDropDownDirection.Right: + if (show_point.X + this.Width > max_screen.X) + direction = ToolStripDropDownDirection.Left; + break; + } + + // Y direction + switch (direction) { + case ToolStripDropDownDirection.AboveLeft: + if (show_point.Y - this.Height < 0) + direction = ToolStripDropDownDirection.BelowLeft; + break; + case ToolStripDropDownDirection.AboveRight: + if (show_point.Y - this.Height < 0) + direction = ToolStripDropDownDirection.BelowRight; + break; + case ToolStripDropDownDirection.BelowLeft: + if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) + direction = ToolStripDropDownDirection.AboveLeft; + break; + case ToolStripDropDownDirection.BelowRight: + case ToolStripDropDownDirection.Default: + if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) + direction = ToolStripDropDownDirection.AboveRight; + break; + case ToolStripDropDownDirection.Left: + if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) + direction = ToolStripDropDownDirection.AboveLeft; + break; + case ToolStripDropDownDirection.Right: + if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) + direction = ToolStripDropDownDirection.AboveRight; + break; + } + } + + switch (direction) { + case ToolStripDropDownDirection.AboveLeft: + show_point.Y -= this.Height; + show_point.X -= this.Width; + break; + case ToolStripDropDownDirection.AboveRight: + show_point.Y -= this.Height; + break; + case ToolStripDropDownDirection.BelowLeft: + show_point.X -= this.Width; + break; + case ToolStripDropDownDirection.Left: + show_point.X -= this.Width; + break; + case ToolStripDropDownDirection.Right: + break; + } + + // Fix offscreen horizontal positions + if ((show_point.X + this.Width) > max_screen.X) + show_point.X = max_screen.X - this.Width; + if (show_point.X < 0) + show_point.X = 0; + + // Fix offscreen vertical positions + if ((show_point.Y + this.Height) > max_screen.Y) + show_point.Y = max_screen.Y - this.Height; + if (show_point.Y < 0) + show_point.Y = 0; + + if (this.Location != show_point) + this.Location = show_point; + + CancelEventArgs e = new CancelEventArgs (); + this.OnOpening (e); + + if (e.Cancel) + return; + + // The tracker lets us know when the form is clicked or loses focus + ToolStripManager.AppClicked += new EventHandler (ToolStripMenuTracker_AppClicked); + ToolStripManager.AppFocusChange += new EventHandler (ToolStripMenuTracker_AppFocusChange); + + base.Show (); + + ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard); + + this.OnOpened (EventArgs.Empty); + } + + public void Show (Widget Widget, int x, int y) + { + if (Widget == null) + throw new ArgumentNullException ("Widget"); + + Show (Widget, new Point (x, y)); + } + + public void Show (Widget Widget, Point position, ToolStripDropDownDirection direction) + { + if (Widget == null) + throw new ArgumentNullException ("Widget"); + + XplatUI.SetOwner (Handle, Widget.Handle); + Show (Widget.PointToScreen (position), direction); + } + #endregion + + #region Protected Methods + protected override AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripDropDownAccessibleObject (this); + } + + protected override void CreateHandle () + { + base.CreateHandle (); + } + + protected override LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle style) + { + return base.CreateLayoutSettings (style); + } + + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + } + + protected virtual void OnClosed (ToolStripDropDownClosedEventArgs e) + { + ToolStripDropDownClosedEventHandler eh = (ToolStripDropDownClosedEventHandler)(Events [ClosedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnClosing (ToolStripDropDownClosingEventArgs e) + { + ToolStripDropDownClosingEventHandler eh = (ToolStripDropDownClosingEventHandler)(Events [ClosingEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnHandleCreated (EventArgs e) + { + base.OnHandleCreated (e); + + if (Application.MWFThread.Current.Context != null && Application.MWFThread.Current.Context.MainForm != null) + XplatUI.SetOwner (this.Handle, Application.MWFThread.Current.Context.MainForm.Handle); + } + + protected override void OnItemClicked (ToolStripItemClickedEventArgs e) + { + base.OnItemClicked (e); + } + + protected override void OnLayout (LayoutEventArgs e) + { + // Find the widest menu item, so we know how wide to make our dropdown + int widest = 0; + + foreach (ToolStripItem tsi in this.Items) { + if (!tsi.Available) + continue; + + tsi.SetPlacement (ToolStripItemPlacement.Main); + + widest = Math.Max (widest, tsi.GetPreferredSize (Size.Empty).Width + tsi.Margin.Horizontal); + } + + // Add any padding our dropdown has set + widest += this.Padding.Horizontal; + + int x = this.Padding.Left; + int y = this.Padding.Top; + + foreach (ToolStripItem tsi in this.Items) { + if (!tsi.Available) + continue; + + y += tsi.Margin.Top; + + int height = 0; + + Size preferred_size = tsi.GetPreferredSize (Size.Empty); + + if (preferred_size.Height > 22) + height = preferred_size.Height; + else if (tsi is ToolStripSeparator) + height = 7; + else + height = 22; + + tsi.SetBounds (new Rectangle (x, y, preferred_size.Width, height)); + y += height + tsi.Margin.Bottom; + } + + this.Size = new Size (widest, y + this.Padding.Bottom); + this.SetDisplayedItems (); + this.OnLayoutCompleted (EventArgs.Empty); + this.Invalidate (); + } + + protected override void OnMouseUp (MouseEventArgs mea) + { + base.OnMouseUp (mea); + } + + protected virtual void OnOpened (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [OpenedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnOpening (CancelEventArgs e) + { + CancelEventHandler eh = (CancelEventHandler)(Events [OpeningEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnParentChanged (EventArgs e) + { + base.OnParentChanged (e); + + if (Parent is ToolStrip) + this.Renderer = (Parent as ToolStrip).Renderer; + } + + protected override void OnVisibleChanged (EventArgs e) + { + base.OnVisibleChanged (e); + + if (owner_item != null && owner_item is ToolStripDropDownItem) { + ToolStripDropDownItem dropdown_owner = (ToolStripDropDownItem)owner_item; + if (Visible) + dropdown_owner.OnDropDownOpened (EventArgs.Empty); + else + dropdown_owner.OnDropDownClosed (EventArgs.Empty); + } + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override bool ProcessDialogChar (char charCode) + { + return base.ProcessDialogChar (charCode); + } + + protected override bool ProcessDialogKey (Keys keyData) + { + // We don't want to let our base change the active ToolStrip + switch (keyData) { + case Keys.Widget | Keys.Tab: + case Keys.Widget | Keys.Shift | Keys.Tab: + return true; + } + + return base.ProcessDialogKey (keyData); + } + + protected override bool ProcessMnemonic (char charCode) + { + return base.ProcessMnemonic (charCode); + } + + protected override void ScaleWidget (SizeF factor, BoundsSpecified specified) + { + base.ScaleWidget (factor, specified); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + protected override void ScaleCore (float dx, float dy) + { + base.ScaleCore (dx, dy); + } + + protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified) + { + base.SetBoundsCore (x, y, width, height, specified); + } + + protected override void SetVisibleCore (bool visible) + { + base.SetVisibleCore (visible); + } + + protected override void WndProc (ref Message m) + { + const int MA_NOACTIVATE = 0x0003; + + // Don't activate when the WM tells us to + if ((Msg)m.Msg == Msg.WM_MOUSEACTIVATE) { + m.Result = (IntPtr)MA_NOACTIVATE; + return; + } + + base.WndProc (ref m); + } + #endregion + + #region Public Events + static object ClosedEvent = new object (); + static object ClosingEvent = new object (); + static object OpenedEvent = new object (); + static object OpeningEvent = new object (); + static object ScrollEvent = new object (); + + [Browsable (false)] + public new event EventHandler BackgroundImageChanged { + add { base.BackgroundImageChanged += value; } + remove { base.BackgroundImageChanged -= value; } + } + + [Browsable (false)] + public new event EventHandler BackgroundImageLayoutChanged { + add { base.BackgroundImageLayoutChanged += value; } + remove { base.BackgroundImageLayoutChanged -= value; } + } + + [Browsable (false)] + public new event EventHandler BindingContextChanged { + add { base.BindingContextChanged += value; } + remove { base.BindingContextChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event UICuesEventHandler ChangeUICues { + add { base.ChangeUICues += value; } + remove { base.ChangeUICues -= value; } + } + + public event ToolStripDropDownClosedEventHandler Closed { + add { Events.AddHandler (ClosedEvent, value); } + remove { Events.RemoveHandler (ClosedEvent, value); } + } + + public event ToolStripDropDownClosingEventHandler Closing { + add { Events.AddHandler (ClosingEvent, value); } + remove { Events.RemoveHandler (ClosingEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler ContextMenuChanged { + add { base.ContextMenuChanged += value; } + remove { base.ContextMenuChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler ContextMenuStripChanged { + add { base.ContextMenuStripChanged += value; } + remove { base.ContextMenuStripChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler DockChanged { + add { base.DockChanged += value; } + remove { base.DockChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler Enter { + add { base.Enter += value; } + remove { base.Enter -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler FontChanged { + add { base.FontChanged += value; } + remove { base.FontChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler ForeColorChanged { + add { base.ForeColorChanged += value; } + remove { base.ForeColorChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event GiveFeedbackEventHandler GiveFeedback { + add { base.GiveFeedback += value; } + remove { base.GiveFeedback -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event HelpEventHandler HelpRequested { + add { base.HelpRequested += value; } + remove { base.HelpRequested -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler ImeModeChanged { + add { base.ImeModeChanged += value; } + remove { base.ImeModeChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event KeyEventHandler KeyDown { + add { base.KeyDown += value; } + remove { base.KeyDown -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event KeyPressEventHandler KeyPress { + add { base.KeyPress += value; } + remove { base.KeyPress -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event KeyEventHandler KeyUp { + add { base.KeyUp += value; } + remove { base.KeyUp -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler Leave { + add { base.Leave += value; } + remove { base.Leave -= value; } + } + + public event EventHandler Opened { + add { Events.AddHandler (OpenedEvent, value); } + remove { Events.RemoveHandler (OpenedEvent, value); } + } + + public event CancelEventHandler Opening { + add { Events.AddHandler (OpeningEvent, value); } + remove { Events.RemoveHandler (OpeningEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler RegionChanged { + add { base.RegionChanged += value; } + remove { base.RegionChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event ScrollEventHandler Scroll { + add { Events.AddHandler (ScrollEvent, value); } + remove { Events.RemoveHandler (ScrollEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler StyleChanged { + add { base.StyleChanged += value; } + remove { base.StyleChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TabIndexChanged { + add { base.TabIndexChanged += value; } + remove { base.TabIndexChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TabStopChanged { + add { base.TabStopChanged += value; } + remove { base.TabStopChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TextChanged { + add { base.TextChanged += value; } + remove { base.TextChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler Validated { + add { base.Validated += value; } + remove { base.Validated -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event CancelEventHandler Validating { + add { base.Validating += value; } + remove { base.Validating -= value; } + } + #endregion + + #region Private Methods + internal override void Dismiss (ToolStripDropDownCloseReason reason) + { + this.Close (reason); + base.Dismiss (reason); + + // ContextMenuStrip won't have a parent + if (this.OwnerItem == null) + return; + + // Ensure Submenu loes keyboard capture when closing. + ToolStripManager.SetActiveToolStrip (null, false); + } + + internal override ToolStrip GetTopLevelToolStrip () + { + if (this.OwnerItem == null) + return this; + + return this.OwnerItem.GetTopLevelToolStrip (); + } + + internal override bool ProcessArrowKey (Keys keyData) + { + switch (keyData) { + case Keys.Down: + case Keys.Tab: + this.SelectNextToolStripItem (this.GetCurrentlySelectedItem (), true); + return true; + case Keys.Up: + case Keys.Shift | Keys.Tab: + this.SelectNextToolStripItem (this.GetCurrentlySelectedItem (), false); + return true; + case Keys.Right: + this.GetTopLevelToolStrip ().SelectNextToolStripItem (this.TopLevelOwnerItem, true); + return true; + case Keys.Left: + case Keys.Escape: + this.Dismiss (ToolStripDropDownCloseReason.Keyboard); + + // ContextMenuStrip won't have a parent + if (this.OwnerItem == null) + return true; + + ToolStrip parent_strip = this.OwnerItem.Parent; + ToolStripManager.SetActiveToolStrip (parent_strip, true); + + if (parent_strip is MenuStrip && keyData == Keys.Left) { + parent_strip.SelectNextToolStripItem (this.TopLevelOwnerItem, false); + this.TopLevelOwnerItem.Invalidate (); + } else if (parent_strip is MenuStrip && keyData == Keys.Escape) { + (parent_strip as MenuStrip).MenuDroppedDown = false; + this.TopLevelOwnerItem.Select (); + } + return true; + } + + return false; + } + + internal override ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward) + { + ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Down : ArrowDirection.Up); + + if (next_item != null) + this.ChangeSelection (next_item); + + return (next_item); + } + + private void ToolStripMenuTracker_AppFocusChange (object sender, EventArgs e) + { + this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.AppFocusChange); + } + + private void ToolStripMenuTracker_AppClicked (object sender, EventArgs e) + { + this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.AppClicked); + } + #endregion + + #region Internal Properties + internal override bool ActivateOnShow { get { return false; } } + + internal ToolStripItem TopLevelOwnerItem { + get { + ToolStripItem owner_item = this.OwnerItem; + ToolStrip ts = null; + + while (owner_item != null) { + ts = owner_item.Owner; + + if (ts != null && (ts is ToolStripDropDown)) + owner_item = (ts as ToolStripDropDown).OwnerItem; + else + return owner_item; + } + + return null; + } + } + #endregion + + #region ToolStripDropDownAccessibleObject + [ComVisible (true)] + public class ToolStripDropDownAccessibleObject : ToolStripAccessibleObject + { + #region Public Constructor + public ToolStripDropDownAccessibleObject (ToolStripDropDown owner) : base (owner) + { + } + #endregion + + #region Public Properties + public override string Name { + get { return base.Name; } + set { base.Name = value; } + } + + public override AccessibleRole Role { + get { return AccessibleRole.MenuPopup; } + } + #endregion + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownButton.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownButton.cs new file mode 100644 index 0000000..2e8ecd8 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownButton.cs @@ -0,0 +1,185 @@ +// +// ToolStripDropDownButton.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.Runtime.InteropServices; +using ShiftUI.Design; +using System.ComponentModel; +using System; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)] + public class ToolStripDropDownButton : ToolStripDropDownItem + { + private bool show_drop_down_arrow = true; + + #region Public Constructors + public ToolStripDropDownButton() + : this (string.Empty, null, null, string.Empty) + { + } + + public ToolStripDropDownButton (Image image) + : this (string.Empty, image, null, string.Empty) + { + } + + public ToolStripDropDownButton (string text) + : this (text, null, null, string.Empty) + { + } + + public ToolStripDropDownButton (string text, Image image) + : this (text, image, null, string.Empty) + { + } + + public ToolStripDropDownButton (string text, Image image, EventHandler onClick) + : this (text, image, onClick, string.Empty) + { + } + + public ToolStripDropDownButton (string text, Image image, params ToolStripItem[] dropDownItems) + : base (text, image, dropDownItems) + { + } + + public ToolStripDropDownButton (string text, Image image, EventHandler onClick, string name) + : base (text, image, onClick, name) + { + } + #endregion + + #region Public Properties + [DefaultValue (true)] + public new bool AutoToolTip { + get { return base.AutoToolTip; } + set { base.AutoToolTip = value; } + } + + [DefaultValue (true)] + public bool ShowDropDownArrow { + get { return this.show_drop_down_arrow; } + set { + if (this.show_drop_down_arrow != value) { + this.show_drop_down_arrow = value; + CalculateAutoSize (); + } + } + } + #endregion + + #region Protected Properties + protected override bool DefaultAutoToolTip { + get { return true; } + } + #endregion + + #region Protected Methods + protected override ToolStripDropDown CreateDefaultDropDown () + { + ToolStripDropDownMenu tsdd = new ToolStripDropDownMenu (); + tsdd.OwnerItem = this; + return tsdd; + } + + protected override void OnMouseDown (MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) { + if (this.DropDown.Visible) + this.HideDropDown (ToolStripDropDownCloseReason.ItemClicked); + else + this.ShowDropDown (); + } + + base.OnMouseDown (e); + } + + protected override void OnMouseLeave (EventArgs e) + { + base.OnMouseLeave (e); + } + + protected override void OnMouseUp (MouseEventArgs e) + { + base.OnMouseUp (e); + } + + protected override void OnPaint (PaintEventArgs e) + { + base.OnPaint (e); + + if (this.Owner != null) { + Color font_color = this.Enabled ? this.ForeColor : SystemColors.GrayText; + Image draw_image = this.Enabled ? this.Image : ToolStripRenderer.CreateDisabledImage (this.Image); + + this.Owner.Renderer.DrawDropDownButtonBackground (new ShiftUI.ToolStripItemRenderEventArgs (e.Graphics, this)); + + Rectangle text_layout_rect; + Rectangle image_layout_rect; + + this.CalculateTextAndImageRectangles (out text_layout_rect, out image_layout_rect); + + if (text_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign)); + if (image_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemImage (new ShiftUI.ToolStripItemImageRenderEventArgs (e.Graphics, this, draw_image, image_layout_rect)); + if (this.ShowDropDownArrow) + this.Owner.Renderer.DrawArrow (new ToolStripArrowRenderEventArgs (e.Graphics, this, new Rectangle (this.Width - 10, 0, 6, this.Height), Color.Black, ArrowDirection.Down)); + return; + } + } + + protected internal override bool ProcessMnemonic (char charCode) + { + if (!this.Selected) + this.Parent.ChangeSelection (this); + + if (this.HasDropDownItems) + this.ShowDropDown (); + else + this.PerformClick (); + + return true; + } + #endregion + + #region Internal Methods + internal override Size CalculatePreferredSize (Size constrainingSize) + { + Size preferred_size = base.CalculatePreferredSize (constrainingSize); + + if (this.ShowDropDownArrow) + preferred_size.Width += 9; + + return preferred_size; + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownCloseReason.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownCloseReason.cs new file mode 100644 index 0000000..0d56a86 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownCloseReason.cs @@ -0,0 +1,40 @@ +// +// ToolStripDropDownCloseReason.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripDropDownCloseReason + { + AppFocusChange = 0, + AppClicked = 1, + ItemClicked = 2, + Keyboard = 3, + CloseCalled = 4 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownClosedEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownClosedEventArgs.cs new file mode 100644 index 0000000..d95fbe6 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownClosedEventArgs.cs @@ -0,0 +1,49 @@ +// +// ToolStripDropDownClosedEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// +using System; + +namespace ShiftUI +{ + public class ToolStripDropDownClosedEventArgs : EventArgs + { + private ToolStripDropDownCloseReason close_reason; + + #region Public Constructors + public ToolStripDropDownClosedEventArgs (ToolStripDropDownCloseReason reason) : base () + { + this.close_reason = reason; + } + #endregion // Public Constructors + + #region Public Instance Properties + public ToolStripDropDownCloseReason CloseReason { + get { return this.close_reason; } + } + #endregion // Public Instance Properties + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownClosedEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownClosedEventHandler.cs new file mode 100644 index 0000000..01fea1d --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownClosedEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripDropDownClosedEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripDropDownClosedEventHandler (object sender, ToolStripDropDownClosedEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownClosingEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownClosingEventArgs.cs new file mode 100644 index 0000000..8301df7 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownClosingEventArgs.cs @@ -0,0 +1,50 @@ +// +// ToolStripDropDownClosingEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.ComponentModel; + +namespace ShiftUI +{ + public class ToolStripDropDownClosingEventArgs : CancelEventArgs + { + private ToolStripDropDownCloseReason close_reason; + + #region Public Constructors + public ToolStripDropDownClosingEventArgs (ToolStripDropDownCloseReason reason) : base () + { + this.close_reason = reason; + } + #endregion // Public Constructors + + #region Public Instance Properties + public ToolStripDropDownCloseReason CloseReason { + get { return this.close_reason; } + } + #endregion // Public Instance Properties + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownClosingEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownClosingEventHandler.cs new file mode 100644 index 0000000..76ec5a8 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownClosingEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripDropDownClosingEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripDropDownClosingEventHandler (object sender, ToolStripDropDownClosingEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownDirection.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownDirection.cs new file mode 100644 index 0000000..2313ab4 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownDirection.cs @@ -0,0 +1,42 @@ +// +// ToolStripDropDownDirection.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripDropDownDirection + { + AboveLeft = 0, + AboveRight = 1, + BelowLeft = 2, + BelowRight = 3, + Left = 4, + Right = 5, + Default = 7 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownItem.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownItem.cs new file mode 100644 index 0000000..b79c9aa --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownItem.cs @@ -0,0 +1,348 @@ +// +// ToolStripDropDownItem.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.ComponentModel; +using System.Threading; + +namespace ShiftUI +{ + [DefaultProperty ("DropDownItems")] + //[Designer ("ShiftUI.Design.ToolStripMenuItemDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + public abstract class ToolStripDropDownItem : ToolStripItem + { + internal ToolStripDropDown drop_down; + private ToolStripDropDownDirection drop_down_direction; + + #region Protected Constructors + protected ToolStripDropDownItem () : this (string.Empty, null, null, string.Empty) + { + } + + protected ToolStripDropDownItem (string text, Image image, EventHandler onClick) + : this (text, image, onClick, string.Empty) + { + } + + protected ToolStripDropDownItem (string text, Image image, params ToolStripItem[] dropDownItems) + : this (text, image, null, string.Empty) + { + } + + protected ToolStripDropDownItem (string text, Image image, EventHandler onClick, string name) + : base (text, image, onClick, name) + { + } + #endregion + + #region Public Properties + [TypeConverter (typeof (ReferenceConverter))] + public ToolStripDropDown DropDown { + get { + if (this.drop_down == null) { + this.drop_down = CreateDefaultDropDown (); + this.drop_down.ItemAdded += new ToolStripItemEventHandler (DropDown_ItemAdded); + } + + return this.drop_down; + } + set { + this.drop_down = value; + this.drop_down.OwnerItem = this; + } + } + + [Browsable (false)] + public ToolStripDropDownDirection DropDownDirection { + get { return this.drop_down_direction; } + set { + if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value)); + + this.drop_down_direction = value; + } + } + + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + public ToolStripItemCollection DropDownItems { + get { return this.DropDown.Items; } + } + + [Browsable (false)] + public virtual bool HasDropDownItems { + get { return this.drop_down != null && this.DropDown.Items.Count != 0; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override bool Pressed { + get { return base.Pressed || (this.drop_down != null && this.DropDown.Visible); } + } + #endregion + + #region Protected Properties + protected internal virtual Point DropDownLocation { + get { + Point p; + + if (this.IsOnDropDown) { + p = Parent.PointToScreen (new Point (this.Bounds.Left, this.Bounds.Top - 1)); + p.X += this.Bounds.Width; + p.Y += this.Bounds.Left; + return p; + } + else + p = new Point (this.Bounds.Left, this.Bounds.Bottom - 1); + + return Parent.PointToScreen (p); + } + } + #endregion + + #region Public Methods + public void HideDropDown () + { + if (this.drop_down == null || !this.DropDown.Visible) + return; + + // OnDropDownHide is called before actually closing DropDown + this.OnDropDownHide (EventArgs.Empty); + this.DropDown.Close (ToolStripDropDownCloseReason.CloseCalled); + this.is_pressed = false; + this.Invalidate (); + } + + public void ShowDropDown () + { + // Don't go through this whole deal if + // the DropDown is already visible + if (this.DropDown.Visible) + return; + + // Call this before the HasDropDownItems check to give + // users a chance to handle it and add drop down items + this.OnDropDownShow (EventArgs.Empty); + + if (!this.HasDropDownItems) + return; + + this.Invalidate (); + this.DropDown.Show (this.DropDownLocation); + } + #endregion + + #region Protected Methods + protected override AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripDropDownItemAccessibleObject (this); + } + + protected virtual ToolStripDropDown CreateDefaultDropDown () + { + ToolStripDropDown tsdd = new ToolStripDropDown (); + tsdd.OwnerItem = this; + return tsdd; + } + + protected override void Dispose (bool disposing) + { + if (!IsDisposed) { + if(disposing) { + if (this.HasDropDownItems) + foreach (ToolStripItem tsi in this.DropDownItems) + if (tsi is ToolStripMenuItem) + ToolStripManager.RemoveToolStripMenuItem ((ToolStripMenuItem)tsi); + + if (drop_down != null) + ToolStripManager.RemoveToolStrip (drop_down); + } + base.Dispose (disposing); + } + } + + protected override void OnBoundsChanged () + { + base.OnBoundsChanged (); + } + + protected internal virtual void OnDropDownClosed (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [DropDownClosedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnDropDownHide (EventArgs e) + { + } + + protected internal virtual void OnDropDownItemClicked (ToolStripItemClickedEventArgs e) + { + ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [DropDownItemClickedEvent]); + if (eh != null) + eh (this, e); + } + + protected internal virtual void OnDropDownOpened (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [DropDownOpenedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnDropDownShow (EventArgs e) + { + EventHandler eh = (EventHandler)(Events[DropDownOpeningEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnFontChanged (EventArgs e) + { + base.OnFontChanged (e); + + // don't use DropDown directly, since doing that + // would created the DropDown Widget + if (drop_down != null) + drop_down.Font = Font; + } + + protected override void OnRightToLeftChanged (EventArgs e) + { + base.OnRightToLeftChanged (e); + } + + protected internal override bool ProcessCmdKey (ref Message m, Keys keyData) + { + if (this.HasDropDownItems) + foreach (ToolStripItem tsi in this.DropDownItems) + if (tsi.ProcessCmdKey (ref m, keyData) == true) + return true; + + return base.ProcessCmdKey (ref m, keyData); + } + + protected internal override bool ProcessDialogKey (Keys keyData) + { + if (!this.Selected || !this.HasDropDownItems) + return base.ProcessDialogKey (keyData); + + if (!this.IsOnDropDown) { + if (this.Parent.Orientation == Orientation.Horizontal) { + if (keyData == Keys.Down || keyData == Keys.Enter) { + if (this.Parent is MenuStrip) + (this.Parent as MenuStrip).MenuDroppedDown = true; + this.ShowDropDown (); + this.DropDown.SelectNextToolStripItem (null, true); + return true; + } + } else { + if (keyData == Keys.Right || keyData == Keys.Enter) { + if (this.Parent is MenuStrip) + (this.Parent as MenuStrip).MenuDroppedDown = true; + this.ShowDropDown (); + this.DropDown.SelectNextToolStripItem (null, true); + return true; + } + } + } else { + if (keyData == Keys.Right || keyData == Keys.Enter) { + if (this.HasDropDownItems) { + this.ShowDropDown (); + this.DropDown.SelectNextToolStripItem (null, true); + return true; + } + } + } + + + return base.ProcessDialogKey (keyData); + } + #endregion + + #region Public Events + static object DropDownClosedEvent = new object (); + static object DropDownItemClickedEvent = new object (); + static object DropDownOpenedEvent = new object (); + static object DropDownOpeningEvent = new object (); + + public event EventHandler DropDownClosed { + add { Events.AddHandler (DropDownClosedEvent, value); } + remove { Events.RemoveHandler (DropDownClosedEvent, value); } + } + + public event ToolStripItemClickedEventHandler DropDownItemClicked { + add { Events.AddHandler (DropDownItemClickedEvent, value); } + remove { Events.RemoveHandler (DropDownItemClickedEvent, value); } + } + + public event EventHandler DropDownOpened { + add { Events.AddHandler (DropDownOpenedEvent, value); } + remove { Events.RemoveHandler (DropDownOpenedEvent, value); } + } + + public event EventHandler DropDownOpening { + add { Events.AddHandler (DropDownOpeningEvent, value); } + remove { Events.RemoveHandler (DropDownOpeningEvent, value); } + } + #endregion + + #region Internal Methods + internal override void Dismiss (ToolStripDropDownCloseReason reason) + { + if (this.HasDropDownItems && this.DropDown.Visible) + this.DropDown.Dismiss (reason); + + base.Dismiss (reason); + } + + internal override void HandleClick (int mouse_clicks, EventArgs e) + { + OnClick (e); + } + + internal void HideDropDown (ToolStripDropDownCloseReason reason) + { + if (this.drop_down == null || !this.DropDown.Visible) + return; + + // OnDropDownHide is called before actually closing DropDown + this.OnDropDownHide (EventArgs.Empty); + this.DropDown.Close (reason); + this.is_pressed = false; + this.Invalidate (); + } + + private void DropDown_ItemAdded (object sender, ToolStripItemEventArgs e) + { + e.Item.owner_item = this; + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownItemAccessibleObject.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownItemAccessibleObject.cs new file mode 100644 index 0000000..c4385b5 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownItemAccessibleObject.cs @@ -0,0 +1,66 @@ +// +// ToolStripDropDownItemAccessibleObject.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; + +namespace ShiftUI +{ + public class ToolStripDropDownItemAccessibleObject : ToolStripItem.ToolStripItemAccessibleObject + { + #region Public Constructor + public ToolStripDropDownItemAccessibleObject (ToolStripDropDownItem item) : base (item) + { + } + #endregion + + #region Public Properties + public override AccessibleRole Role { + get { return base.Role; } + } + #endregion + + #region Public Methods + public override void DoDefaultAction () + { + base.DoDefaultAction (); + } + + public override AccessibleObject GetChild (int index) + { + return (owner_item as ToolStripDropDownItem).DropDownItems[index].AccessibilityObject; + } + + public override int GetChildCount () + { + return (owner_item as ToolStripDropDownItem).DropDownItems.Count; + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripDropDownMenu.cs b/source/ShiftUI/ToolStrip/ToolStripDropDownMenu.cs new file mode 100644 index 0000000..7b5ed6f --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripDropDownMenu.cs @@ -0,0 +1,196 @@ +// +// ToolStripDropDownMenu.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using System.Runtime.InteropServices; +using ShiftUI.Layout; +using System; + +namespace ShiftUI +{ + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDispatch)] + //[Designer ("ShiftUI.Design.ToolStripDropDownDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + public class ToolStripDropDownMenu : ToolStripDropDown + { + private ToolStripLayoutStyle layout_style; + private bool show_check_margin; + private bool show_image_margin; + + #region Public Constructors + public ToolStripDropDownMenu () : base () + { + this.layout_style = ToolStripLayoutStyle.Flow; + this.show_image_margin = true; + } + #endregion + + #region Public Properties + public override Rectangle DisplayRectangle { + get { return base.DisplayRectangle; } + } + + public override LayoutEngine LayoutEngine { + get { return base.LayoutEngine; } + } + + [DefaultValue (ToolStripLayoutStyle.Flow)] + public new ToolStripLayoutStyle LayoutStyle { + get { return this.layout_style; } + set { this.layout_style = value; } + } + + [DefaultValue (false)] + public bool ShowCheckMargin { + get { return this.show_check_margin; } + set { + if (this.show_check_margin != value) { + this.show_check_margin = value; + PerformLayout (this, "ShowCheckMargin"); + } + } + } + + [DefaultValue (true)] + public bool ShowImageMargin { + get { return this.show_image_margin; } + set { + if (this.show_image_margin != value) { + this.show_image_margin = value; + PerformLayout (this, "ShowImageMargin"); + } + } + } + #endregion + + #region Protected Properties + protected override Padding DefaultPadding { + get { return base.DefaultPadding; } + } + + protected internal override Size MaxItemSize { + get { return Size; } + } + #endregion + + #region Protected Methods + protected internal override ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick) + { + return base.CreateDefaultItem (text, image, onClick); + } + + protected override void OnFontChanged (EventArgs e) + { + base.OnFontChanged (e); + } + + protected override void OnLayout (LayoutEventArgs e) + { + // Find the widest menu item + int widest = 0; + + foreach (ToolStripItem tsi in this.Items) { + if (!tsi.Available) + continue; + + tsi.SetPlacement (ToolStripItemPlacement.Main); + + widest = Math.Max (widest, tsi.GetPreferredSize (Size.Empty).Width); + } + + int x = this.Padding.Left; + + if (show_check_margin || show_image_margin) + widest += 68 - this.Padding.Horizontal; + else + widest += 47 - this.Padding.Horizontal; + + int y = this.Padding.Top; + + foreach (ToolStripItem tsi in this.Items) { + if (!tsi.Available) + continue; + + y += tsi.Margin.Top; + + int height = 0; + + Size preferred_size = tsi.GetPreferredSize (Size.Empty); + + if (preferred_size.Height > 22) + height = preferred_size.Height; + else if (tsi is ToolStripSeparator) + height = 7; + else + height = 22; + + tsi.SetBounds (new Rectangle (x, y, widest, height)); + y += height + tsi.Margin.Bottom; + } + + this.Size = new Size (widest + this.Padding.Horizontal, y + this.Padding.Bottom);// + 2); + this.SetDisplayedItems (); + this.OnLayoutCompleted (EventArgs.Empty); + this.Invalidate (); + } + + protected override void OnPaintBackground (PaintEventArgs e) + { + Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size); + + ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control); + tsrea.InternalConnectedArea = CalculateConnectedArea (); + + this.Renderer.DrawToolStripBackground (tsrea); + + if (this.ShowCheckMargin || this.ShowImageMargin) { + tsrea = new ToolStripRenderEventArgs (e.Graphics, this, new Rectangle (tsrea.AffectedBounds.Location, new Size (25, tsrea.AffectedBounds.Height)), SystemColors.Control); + this.Renderer.DrawImageMargin (tsrea); + } + } + + protected override void SetDisplayedItems () + { + base.SetDisplayedItems (); + } + #endregion + + #region Internal Methods + internal override Rectangle CalculateConnectedArea () + { + if (this.OwnerItem != null && !this.OwnerItem.IsOnDropDown && !(this.OwnerItem is MdiWidgetStrip.SystemMenuItem)) { + Point owner_screen_loc = OwnerItem.GetCurrentParent ().PointToScreen (OwnerItem.Location); + return new Rectangle (owner_screen_loc.X - Left, 0, this.OwnerItem.Width - 1, 2); + } + + return base.CalculateConnectedArea (); + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripGripDisplayStyle.cs b/source/ShiftUI/ToolStrip/ToolStripGripDisplayStyle.cs new file mode 100644 index 0000000..60e7fcc --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripGripDisplayStyle.cs @@ -0,0 +1,37 @@ +// +// ToolStripGripDisplayStyle.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripGripDisplayStyle + { + Horizontal = 0, + Vertical = 1 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripGripRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripGripRenderEventArgs.cs new file mode 100644 index 0000000..54c26b9 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripGripRenderEventArgs.cs @@ -0,0 +1,70 @@ +// +// ToolStripGripRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; + +namespace ShiftUI +{ + public class ToolStripGripRenderEventArgs : ToolStripRenderEventArgs + { + private Rectangle grip_bounds; + private ToolStripGripDisplayStyle grip_display_style; + private ToolStripGripStyle grip_style; + + public ToolStripGripRenderEventArgs (Graphics g, ToolStrip toolStrip) + : base (g, toolStrip) + { + this.grip_bounds = new Rectangle (2, 0, 3, 25); + this.grip_display_style = ToolStripGripDisplayStyle.Vertical; + this.grip_style = ToolStripGripStyle.Visible; + } + + // There seems to be no public way to set these properties :/ + internal ToolStripGripRenderEventArgs (Graphics g, ToolStrip toolStrip, Rectangle gripBounds, ToolStripGripDisplayStyle displayStyle, ToolStripGripStyle gripStyle) + : base (g, toolStrip) + { + this.grip_bounds = gripBounds; + this.grip_display_style = displayStyle; + this.grip_style = gripStyle; + } + + #region Public Properties + public Rectangle GripBounds { + get { return this.grip_bounds; } + } + + public ToolStripGripDisplayStyle GripDisplayStyle { + get { return this.grip_display_style; } + } + + public ToolStripGripStyle GripStyle { + get { return this.grip_style; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripGripRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripGripRenderEventHandler.cs new file mode 100644 index 0000000..5b89c15 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripGripRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripGripRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripGripRenderEventHandler (object sender, ToolStripGripRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripGripStyle.cs b/source/ShiftUI/ToolStrip/ToolStripGripStyle.cs new file mode 100644 index 0000000..87354da --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripGripStyle.cs @@ -0,0 +1,37 @@ +// +// ToolStripGripStyle.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripGripStyle + { + Hidden = 0, + Visible = 1 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItem.cs b/source/ShiftUI/ToolStrip/ToolStripItem.cs new file mode 100644 index 0000000..0a8ad4a --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItem.cs @@ -0,0 +1,2077 @@ +// +// ToolStripItem.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +using System; +using System.Drawing; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace ShiftUI +{ + [DefaultEvent ("Click")] + [DefaultProperty ("Text")] + [DesignTimeVisible (false)] + [ToolboxItem (false)] + //[Designer ("ShiftUI.Design.ToolStripItemDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + public abstract class ToolStripItem : Component, IDropTarget, IComponent, IDisposable + { + #region Private Variables + private AccessibleObject accessibility_object; + private string accessible_default_action_description; + private bool allow_drop; + private ToolStripItemAlignment alignment; + private AnchorStyles anchor; + private bool available; + private bool auto_size; + private bool auto_tool_tip; + private Color back_color; + private Image background_image; + private ImageLayout background_image_layout; + private Rectangle bounds; + private bool can_select; + private ToolStripItemDisplayStyle display_style; + private DockStyle dock; + private bool double_click_enabled; + private bool enabled; + private Size explicit_size; + private Font font; + private Color fore_color; + private Image image; + private ContentAlignment image_align; + private int image_index; + private string image_key; + private ToolStripItemImageScaling image_scaling; + private Color image_transparent_color; + private bool is_disposed; + internal bool is_pressed; + private bool is_selected; + private Padding margin; + private MergeAction merge_action; + private int merge_index; + private string name; + private ToolStripItemOverflow overflow; + private ToolStrip owner; + internal ToolStripItem owner_item; + private Padding padding; + private ToolStripItemPlacement placement; + private RightToLeft right_to_left; + private bool right_to_left_auto_mirror_image; + private Object tag; + private string text; + private ContentAlignment text_align; + private ToolStripTextDirection text_direction; + private TextImageRelation text_image_relation; + private string tool_tip_text; + private bool visible; + + private EventHandler frame_handler; // For animating images + private ToolStrip parent; + private Size text_size; + #endregion + + #region Public Constructors + protected ToolStripItem () + : this (String.Empty, null, null, String.Empty) + { + } + + protected ToolStripItem (string text, Image image, EventHandler onClick) + : this (text, image, onClick, String.Empty) + { + } + + protected ToolStripItem (string text, Image image, EventHandler onClick, string name) + { + this.alignment = ToolStripItemAlignment.Left; + this.anchor = AnchorStyles.Left | AnchorStyles.Top; + this.auto_size = true; + this.auto_tool_tip = this.DefaultAutoToolTip; + this.available = true; + this.back_color = Color.Empty; + this.background_image_layout = ImageLayout.Tile; + this.can_select = true; + this.display_style = this.DefaultDisplayStyle; + this.dock = DockStyle.None; + this.enabled = true; + this.fore_color = Color.Empty; + this.image = image; + this.image_align = ContentAlignment.MiddleCenter; + this.image_index = -1; + this.image_key = string.Empty; + this.image_scaling = ToolStripItemImageScaling.SizeToFit; + this.image_transparent_color = Color.Empty; + this.margin = this.DefaultMargin; + this.merge_action = MergeAction.Append; + this.merge_index = -1; + this.name = name; + this.overflow = ToolStripItemOverflow.AsNeeded; + this.padding = this.DefaultPadding; + this.placement = ToolStripItemPlacement.None; + this.right_to_left = RightToLeft.Inherit; + this.bounds.Size = this.DefaultSize; + this.text = text; + this.text_align = ContentAlignment.MiddleCenter; + this.text_direction = DefaultTextDirection; + this.text_image_relation = TextImageRelation.ImageBeforeText; + this.visible = true; + + this.Click += onClick; + OnLayout (new LayoutEventArgs (null, string.Empty)); + } + #endregion + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public AccessibleObject AccessibilityObject { + get { + if (this.accessibility_object == null) + this.accessibility_object = CreateAccessibilityInstance (); + + return this.accessibility_object; + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public string AccessibleDefaultActionDescription { + get { + if (this.accessibility_object == null) + return null; + + return this.accessible_default_action_description; + } + set { this.accessible_default_action_description = value; } + } + + [Localizable (true)] + [DefaultValue (null)] + public string AccessibleDescription { + get { + if (this.accessibility_object == null) + return null; + + return this.AccessibilityObject.Description; + } + set { this.AccessibilityObject.description = value; } + } + + [Localizable (true)] + [DefaultValue (null)] + public string AccessibleName { + get { + if (this.accessibility_object == null) + return null; + + return this.AccessibilityObject.Name; + } + set { this.AccessibilityObject.Name = value; } + } + + [DefaultValue (AccessibleRole.Default)] + public AccessibleRole AccessibleRole { + get + { + if (this.accessibility_object == null) + return AccessibleRole.Default; + + return this.AccessibilityObject.Role; + } + set { this.AccessibilityObject.role = value; } + } + + [DefaultValue (ToolStripItemAlignment.Left)] + public ToolStripItemAlignment Alignment { + get { return this.alignment; } + set { + if (!Enum.IsDefined (typeof (ToolStripItemAlignment), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemAlignment", value)); + + if (this.alignment != value) { + this.alignment = value; + this.CalculateAutoSize (); + } + } + } + + [MonoTODO ("Stub, does nothing")] + [Browsable (false)] + [DefaultValue (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public virtual bool AllowDrop { + get { return this.allow_drop; } + set { this.allow_drop = value; } + } + + [Browsable (false)] + [DefaultValue (AnchorStyles.Top | AnchorStyles.Left)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public AnchorStyles Anchor { + get { return this.anchor; } + set { this.anchor = value; } + } + + [Localizable (true)] + [DefaultValue (true)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)] + [RefreshProperties (RefreshProperties.All)] + public bool AutoSize { + get { return this.auto_size; } + set { + this.auto_size = value; + this.CalculateAutoSize (); + } + } + + [DefaultValue (false)] + public bool AutoToolTip { + get { return this.auto_tool_tip; } + set { this.auto_tool_tip = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public bool Available { + get { return this.available; } + set { + if (this.available != value) { + available = value; + visible = value; + + if (this.parent != null) + parent.PerformLayout (); + + OnAvailableChanged (EventArgs.Empty); + OnVisibleChanged (EventArgs.Empty); + } + } + } + + public virtual Color BackColor { + get { + if (back_color != Color.Empty) + return back_color; + + if (Parent != null) + return parent.BackColor; + + return Widget.DefaultBackColor; + } + set { + if (this.back_color != value) { + back_color = value; + OnBackColorChanged (EventArgs.Empty); + this.Invalidate (); + } + } + } + + [Localizable (true)] + [DefaultValue (null)] + public virtual Image BackgroundImage { + get { return this.background_image; } + set { + if (this.background_image != value) { + this.background_image = value; + this.Invalidate (); + } + } + } + + [Localizable (true)] + [DefaultValue (ImageLayout.Tile)] + public virtual ImageLayout BackgroundImageLayout { + get { return this.background_image_layout; } + set { + if (this.background_image_layout != value) { + this.background_image_layout = value; + this.Invalidate (); + } + } + } + + [Browsable (false)] + public virtual Rectangle Bounds { + get { return this.bounds; } + } + + [Browsable (false)] + public virtual bool CanSelect { + get { return this.can_select; } + } + + [Browsable (false)] + public Rectangle ContentRectangle { + get { + // ToolStripLabels don't have a border + if (this is ToolStripLabel || this is ToolStripStatusLabel) + return new Rectangle (0, 0, this.bounds.Width, this.bounds.Height); + + if (this is ToolStripDropDownButton && (this as ToolStripDropDownButton).ShowDropDownArrow) + return new Rectangle (2, 2, this.bounds.Width - 13, this.bounds.Height - 4); + + return new Rectangle (2, 2, this.bounds.Width - 4, this.bounds.Height - 4); + } + } + + public virtual ToolStripItemDisplayStyle DisplayStyle { + get { return this.display_style; } + set { + if (this.display_style != value) { + this.display_style = value; + this.CalculateAutoSize (); + OnDisplayStyleChanged (EventArgs.Empty); + } + } + } + + [Browsable (false)] + public bool IsDisposed { + get { return this.is_disposed; } + } + + [Browsable (false)] + [DefaultValue (DockStyle.None)] + public DockStyle Dock { + get { return this.dock; } + set { + if (this.dock != value) { + if (!Enum.IsDefined (typeof (DockStyle), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for DockStyle", value)); + + this.dock = value; + this.CalculateAutoSize (); + } + } + } + + [DefaultValue (false)] + public bool DoubleClickEnabled { + get { return this.double_click_enabled; } + set { this.double_click_enabled = value; } + } + + [Localizable (true)] + [DefaultValue (true)] + public virtual bool Enabled { + get { + if (Parent != null) + if (!Parent.Enabled) + return false; + + if (Owner != null) + if (!Owner.Enabled) + return false; + + return enabled; + } + set { + if (this.enabled != value) { + this.enabled = value; + OnEnabledChanged (EventArgs.Empty); + this.Invalidate (); + } + } + } + + [Localizable (true)] + public virtual Font Font { + get { + if (font != null) + return font; + + if (Parent != null) + return Parent.Font; + + return DefaultFont; + } + set { + if (this.font != value) { + this.font = value; + this.CalculateAutoSize (); + this.OnFontChanged (EventArgs.Empty); + this.Invalidate (); + } + } + } + + public virtual Color ForeColor { + get { + if (fore_color != Color.Empty) + return fore_color; + + if (Parent != null) + return parent.ForeColor; + + return Widget.DefaultForeColor; + } + set { + if (this.fore_color != value) { + this.fore_color = value; + this.OnForeColorChanged (EventArgs.Empty); + this.Invalidate (); + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public int Height { + get { return this.Size.Height; } + set { + this.Size = new Size (this.Size.Width, value); + this.explicit_size.Height = value; + + if (this.Visible) { + this.CalculateAutoSize (); + this.OnBoundsChanged (); + this.Invalidate (); + } + } + } + + [Localizable (true)] + public virtual Image Image { + get { + if (this.image != null) + return this.image; + + if (this.image_index >= 0) + if (this.owner != null && this.owner.ImageList != null && this.owner.ImageList.Images.Count > this.image_index) + return this.owner.ImageList.Images[this.image_index]; + + + if (!string.IsNullOrEmpty (this.image_key)) + if (this.owner != null && this.owner.ImageList != null && this.owner.ImageList.Images.Count > this.image_index) + return this.owner.ImageList.Images[this.image_key]; + + return null; + } + set { + if (this.image != value) { + StopAnimation (); + + this.image = value; + this.image_index = -1; + this.image_key = string.Empty; + this.CalculateAutoSize (); + this.Invalidate (); + + BeginAnimation (); + } + } + } + + [Localizable (true)] + [DefaultValue (ContentAlignment.MiddleCenter)] + public ContentAlignment ImageAlign { + get { return this.image_align; } + set { + if (!Enum.IsDefined (typeof (ContentAlignment), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value)); + + if (image_align != value) { + this.image_align = value; + this.CalculateAutoSize (); + } + } + } + + [Localizable (true)] + [Browsable (false)] + [RelatedImageList ("Owner.ImageList")] + [TypeConverter (typeof (NoneExcludedImageIndexConverter))] + [RefreshProperties (RefreshProperties.Repaint)] + //[Editor ("ShiftUI.Design.ToolStripImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] + public int ImageIndex { + get { return this.image_index; } + set { + if (this.image_index != value) { + // Lamespec: MSDN says ArgumentException, tests say otherwise + if (value < -1) + throw new ArgumentOutOfRangeException ("ImageIndex cannot be less than -1"); + + this.image_index = value; + this.image = null; + this.image_key = string.Empty; + this.CalculateAutoSize (); + this.Invalidate (); + } + } + } + + [Localizable (true)] + [Browsable (false)] + [RelatedImageList ("Owner.ImageList")] + [TypeConverter (typeof (ImageKeyConverter))] + [RefreshProperties (RefreshProperties.Repaint)] + //[Editor ("ShiftUI.Design.ToolStripImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] + public string ImageKey { + get { return this.image_key; } + set { + if (this.image_key != value) { + this.image = null; + this.image_index = -1; + this.image_key = value; + this.CalculateAutoSize (); + this.Invalidate (); + } + } + } + + [Localizable (true)] + [DefaultValue (ToolStripItemImageScaling.SizeToFit)] + public ToolStripItemImageScaling ImageScaling { + get { return this.image_scaling; } + set { + if (image_scaling != value) { + this.image_scaling = value; + this.CalculateAutoSize (); + } + } + } + + [Localizable (true)] + public Color ImageTransparentColor { + get { return this.image_transparent_color; } + set { this.image_transparent_color = value; } + } + + [Browsable (false)] + public bool IsOnDropDown { + get { + if (this.parent != null && this.parent is ToolStripDropDown) + return true; + + return false; + } + } + + [Browsable (false)] + public bool IsOnOverflow { + get { return this.placement == ToolStripItemPlacement.Overflow; } + } + + public Padding Margin { + get { return this.margin; } + set { + this.margin = value; + this.CalculateAutoSize (); + } + } + + [DefaultValue (MergeAction.Append)] + public MergeAction MergeAction { + get { return this.merge_action; } + set { + if (!Enum.IsDefined (typeof (MergeAction), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for MergeAction", value)); + + this.merge_action = value; + } + } + + [DefaultValue (-1)] + public int MergeIndex { + get { return this.merge_index; } + set { this.merge_index = value; } + } + + [DefaultValue (null)] + [Browsable (false)] + public string Name { + get { return this.name; } + set { this.name = value; } + } + + [DefaultValue (ToolStripItemOverflow.AsNeeded)] + public ToolStripItemOverflow Overflow { + get { return this.overflow; } + set { + if (this.overflow != value) { + if (!Enum.IsDefined (typeof (ToolStripItemOverflow), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemOverflow", value)); + + this.overflow = value; + + if (owner != null) + owner.PerformLayout (); + } + } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ToolStrip Owner { + get { return this.owner; } + set { + if (this.owner != value) { + if (this.owner != null) + this.owner.Items.Remove (this); + + if (value != null) + value.Items.Add (this); + else + this.owner = null; + } + } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ToolStripItem OwnerItem { + get { return this.owner_item; } + } + + public virtual Padding Padding { + get { return this.padding; } + set { + this.padding = value; + this.CalculateAutoSize (); + this.Invalidate (); + } + } + + [Browsable (false)] + public ToolStripItemPlacement Placement { + get { return this.placement; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public virtual bool Pressed { get { return this.is_pressed; } } + + [MonoTODO ("RTL not implemented")] + [Localizable (true)] + public virtual RightToLeft RightToLeft { + get { return this.right_to_left; } + set { + if (this.right_to_left != value) { + this.right_to_left = value; + this.OnRightToLeftChanged (EventArgs.Empty); + } + } + } + + [Localizable (true)] + [DefaultValue (false)] + public bool RightToLeftAutoMirrorImage { + get { return this.right_to_left_auto_mirror_image; } + set { + if (this.right_to_left_auto_mirror_image != value) { + this.right_to_left_auto_mirror_image = value; + this.Invalidate (); + } + } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public virtual bool Selected { get { return this.is_selected; } } + + [Localizable (true)] + public virtual Size Size { + get { + if (!this.AutoSize && this.explicit_size != Size.Empty) + return this.explicit_size; + + return this.bounds.Size; + } + set { + this.bounds.Size = value; + this.explicit_size = value; + + if (this.Visible) { + this.CalculateAutoSize (); + this.OnBoundsChanged (); + } + } + } + + [Localizable (false)] + [Bindable (true)] + [DefaultValue (null)] + [TypeConverter (typeof (StringConverter))] + public Object Tag { + get { return this.tag; } + set { this.tag = value; } + } + + [Localizable (true)] + [DefaultValue ("")] + public virtual string Text + { + get { return this.text; } + set { + if (this.text != value) { + this.text = value; + this.Invalidate (); + this.CalculateAutoSize (); + this.Invalidate (); + this.OnTextChanged (EventArgs.Empty); + } + } + } + + [Localizable (true)] + [DefaultValue (ContentAlignment.MiddleCenter)] + public virtual ContentAlignment TextAlign { + get { return this.text_align; } + set { + if (!Enum.IsDefined (typeof (ContentAlignment), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value)); + + if (this.text_align != value) { + this.text_align = value; + this.CalculateAutoSize (); + } + } + } + + public virtual ToolStripTextDirection TextDirection { + get { + if (this.text_direction == ToolStripTextDirection.Inherit) { + if (this.Parent != null) + return this.Parent.TextDirection; + else + return ToolStripTextDirection.Horizontal; + } + + return this.text_direction; + } + set { + if (!Enum.IsDefined (typeof (ToolStripTextDirection), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value)); + + if (this.text_direction != value) { + this.text_direction = value; + this.CalculateAutoSize (); + this.Invalidate (); + } + } + } + + [Localizable (true)] + [DefaultValue (TextImageRelation.ImageBeforeText)] + public TextImageRelation TextImageRelation { + get { return this.text_image_relation; } + set { + this.text_image_relation = value; + this.CalculateAutoSize (); + this.Invalidate (); + } + } + + [Localizable (true)] + //[Editor ("System.ComponentModel.Design.MultilineStringEditor, " + Consts.AssemblySystem_Design, + // //"System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)] + public string ToolTipText { + get { return this.tool_tip_text; } + set { this.tool_tip_text = value; } + } + + [Localizable (true)] + public bool Visible { + get { + if (this.parent == null) + return false; + + return this.visible && this.parent.Visible; + } + set { + if (this.visible != value) { + this.available = value; + this.SetVisibleCore (value); + if (this.Owner != null) + this.Owner.PerformLayout (); + } + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Always)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public int Width { + get { return this.Size.Width; } + set { + this.Size = new Size (value, this.Size.Height); + this.explicit_size.Width = value; + + if (this.Visible) { + this.CalculateAutoSize (); + this.OnBoundsChanged (); + this.Invalidate (); + } + } + } + #endregion + + #region Protected Properties + protected virtual bool DefaultAutoToolTip { get { return false; } } + protected virtual ToolStripItemDisplayStyle DefaultDisplayStyle { get { return ToolStripItemDisplayStyle.ImageAndText; } } + protected internal virtual Padding DefaultMargin { get { return new Padding (0, 1, 0, 2); } } + protected virtual Padding DefaultPadding { get { return new Padding (); } } + protected virtual Size DefaultSize { get { return new Size (23, 23); } } + protected internal virtual bool DismissWhenClicked { get { return true; } } + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + protected internal ToolStrip Parent { + get { return this.parent; } + set { + if (this.parent != value) { + ToolStrip old_parent = this.parent; + this.parent = value; + OnParentChanged(old_parent, this.parent); + } + } + } + protected internal virtual bool ShowKeyboardCues { get { return false; } } + #endregion + + #region Public Methods + [MonoTODO ("Stub, does nothing")] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public DragDropEffects DoDragDrop (Object data, DragDropEffects allowedEffects) + { + return allowedEffects; + } + + public ToolStrip GetCurrentParent () + { + return this.parent; + } + + public virtual Size GetPreferredSize (Size constrainingSize) + { + return this.CalculatePreferredSize (constrainingSize); + } + + public void Invalidate () + { + if (parent != null) + parent.Invalidate (this.bounds); + } + + public void Invalidate (Rectangle r) + { + if (parent != null) + parent.Invalidate (r); + } + + public void PerformClick () + { + this.OnClick (EventArgs.Empty); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetBackColor () { this.BackColor = Color.Empty; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetDisplayStyle () { this.display_style = this.DefaultDisplayStyle; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetFont () { this.font = null; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetForeColor () { this.ForeColor = Color.Empty; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetImage () { this.image = null; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public void ResetMargin () { this.margin = this.DefaultMargin; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public void ResetPadding () { this.padding = this.DefaultPadding; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetRightToLeft () { this.right_to_left = RightToLeft.Inherit; } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetTextDirection () { this.TextDirection = this.DefaultTextDirection; } + + public void Select () + { + if (!this.is_selected && this.CanSelect) { + this.is_selected = true; + + if (this.Parent != null) { + if (this.Visible && this.Parent.Focused && this is ToolStripWidgetHost) + (this as ToolStripWidgetHost).Focus (); + + this.Invalidate (); + this.Parent.NotifySelectedChanged (this); + } + OnUIASelectionChanged (); + } + } + + public override string ToString () + { + return this.text; + } + #endregion + + #region Protected Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripItemAccessibleObject (this); + } + + protected override void Dispose (bool disposing) + { + if (!is_disposed && disposing) + is_disposed = true; + + if (image != null) { + StopAnimation (); + image = null; + } + + if (owner != null && disposing) + owner.Items.Remove (this); + + base.Dispose (disposing); + } + + protected internal virtual bool IsInputChar (char charCode) + { + return false; + } + + protected internal virtual bool IsInputKey (Keys keyData) + { + return false; + } + + protected virtual void OnAvailableChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [AvailableChangedEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnBackColorChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [BackColorChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnBoundsChanged () + { + OnLayout (new LayoutEventArgs(null, string.Empty)); + } + + protected virtual void OnClick (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [ClickEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnDisplayStyleChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [DisplayStyleChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnDoubleClick (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [DoubleClickEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnDragDrop (DragEventArgs dragEvent) + { + DragEventHandler eh = (DragEventHandler)(Events[DragDropEvent]); + if (eh != null) + eh (this, dragEvent); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnDragEnter (DragEventArgs dragEvent) + { + DragEventHandler eh = (DragEventHandler)(Events[DragEnterEvent]); + if (eh != null) + eh (this, dragEvent); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnDragLeave (EventArgs e) + { + EventHandler eh = (EventHandler)(Events[DragLeaveEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnDragOver (DragEventArgs dragEvent) + { + DragEventHandler eh = (DragEventHandler)(Events[DragOverEvent]); + if (eh != null) + eh (this, dragEvent); + } + + protected virtual void OnEnabledChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [EnabledChangedEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnFontChanged (EventArgs e) + { + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnForeColorChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [ForeColorChangedEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnGiveFeedback (GiveFeedbackEventArgs giveFeedbackEvent) + { + GiveFeedbackEventHandler eh = (GiveFeedbackEventHandler)(Events[GiveFeedbackEvent]); + if (eh != null) + eh (this, giveFeedbackEvent); + } + + protected virtual void OnLayout (LayoutEventArgs e) + { + } + + protected virtual void OnLocationChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [LocationChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnMouseDown (MouseEventArgs e) + { + if (this.Enabled) { + this.is_pressed = true; + this.Invalidate (); + + MouseEventHandler eh = (MouseEventHandler)(Events [MouseDownEvent]); + if (eh != null) + eh (this, e); + } + } + + protected virtual void OnMouseEnter (EventArgs e) + { + this.Select (); + + EventHandler eh = (EventHandler)(Events [MouseEnterEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnMouseHover (EventArgs e) + { + if (this.Enabled) { + EventHandler eh = (EventHandler)(Events [MouseHoverEvent]); + if (eh != null) + eh (this, e); + } + } + + protected virtual void OnMouseLeave (EventArgs e) + { + if (this.CanSelect) { + this.is_selected = false; + this.is_pressed = false; + this.Invalidate (); + OnUIASelectionChanged (); + } + + EventHandler eh = (EventHandler)(Events [MouseLeaveEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnMouseMove (MouseEventArgs mea) + { + if (this.Enabled) { + MouseEventHandler eh = (MouseEventHandler)(Events [MouseMoveEvent]); + if (eh != null) + eh (this, mea); + } + } + + protected virtual void OnMouseUp (MouseEventArgs e) + { + if (this.Enabled) { + this.is_pressed = false; + this.Invalidate (); + + if (this.IsOnDropDown) + if (!(this is ToolStripDropDownItem) || !(this as ToolStripDropDownItem).HasDropDownItems || (this as ToolStripDropDownItem).DropDown.Visible == false) { + if ((this.Parent as ToolStripDropDown).OwnerItem != null) + ((this.Parent as ToolStripDropDown).OwnerItem as ToolStripDropDownItem).HideDropDown (); + else + (this.Parent as ToolStripDropDown).Hide (); + } + + + MouseEventHandler eh = (MouseEventHandler)(Events [MouseUpEvent]); + if (eh != null) + eh (this, e); + } + } + + protected virtual void OnOwnerChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [OwnerChangedEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected internal virtual void OnOwnerFontChanged (EventArgs e) + { + this.CalculateAutoSize (); + OnFontChanged (EventArgs.Empty); + } + + void OnPaintInternal (PaintEventArgs e) + { + // Have the background rendered independently from OnPaint + if (this.parent != null) + this.parent.Renderer.DrawItemBackground (new ToolStripItemRenderEventArgs (e.Graphics, this)); + + OnPaint (e); + } + + protected virtual void OnPaint (PaintEventArgs e) + { + PaintEventHandler eh = (PaintEventHandler)(Events [PaintEvent]); + if (eh != null) + eh (this, e); + } + + // This is never called. + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnParentBackColorChanged (EventArgs e) + { + } + + protected virtual void OnParentChanged (ToolStrip oldParent, ToolStrip newParent) + { + this.text_size = + TextRenderer.MeasureText (this.Text == null ? string.Empty : this.text, this.Font, Size.Empty, TextFormatFlags.HidePrefix); + + if (oldParent != null) + oldParent.PerformLayout (); + + if (newParent != null) + newParent.PerformLayout (); + } + + protected internal virtual void OnParentEnabledChanged (EventArgs e) + { + this.OnEnabledChanged (e); + } + + // This is never called. + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnParentForeColorChanged (EventArgs e) + { + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected internal virtual void OnParentRightToLeftChanged (EventArgs e) + { + this.OnRightToLeftChanged (e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnQueryContinueDrag (QueryContinueDragEventArgs queryContinueDragEvent) + { + QueryContinueDragEventHandler eh = (QueryContinueDragEventHandler)(Events[QueryContinueDragEvent]); + if (eh != null) + eh (this, queryContinueDragEvent); + } + + protected virtual void OnRightToLeftChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events[RightToLeftChangedEvent]); + if (eh != null) + eh (this, e); + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected virtual void OnTextChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [TextChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected virtual void OnVisibleChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [VisibleChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected internal virtual bool ProcessCmdKey (ref Message m, Keys keyData) + { + return false; + } + + protected internal virtual bool ProcessDialogKey (Keys keyData) + { + if (this.Selected && keyData == Keys.Enter) { + this.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click); + return true; + } + + return false; + } + + // ProcessMnemonic will only be called if we are supposed to handle + // it. None of that fancy "thinking" needed! + protected internal virtual bool ProcessMnemonic (char charCode) + { + ToolStripManager.SetActiveToolStrip (this.Parent, true); + this.PerformClick (); + return true; + } + + protected internal virtual void SetBounds (Rectangle bounds) + { + if (this.bounds != bounds) { + this.bounds = bounds; + OnBoundsChanged (); + } + } + + protected virtual void SetVisibleCore (bool visible) + { + this.visible = visible; + this.OnVisibleChanged (EventArgs.Empty); + + if (this.visible) + BeginAnimation (); + else + StopAnimation (); + this.Invalidate (); + } + #endregion + + #region Public Events + static object AvailableChangedEvent = new object (); + static object BackColorChangedEvent = new object (); + static object ClickEvent = new object (); + static object DisplayStyleChangedEvent = new object (); + static object DoubleClickEvent = new object (); + static object DragDropEvent = new object (); + static object DragEnterEvent = new object (); + static object DragLeaveEvent = new object (); + static object DragOverEvent = new object (); + static object EnabledChangedEvent = new object (); + static object ForeColorChangedEvent = new object (); + static object GiveFeedbackEvent = new object (); + static object LocationChangedEvent = new object (); + static object MouseDownEvent = new object (); + static object MouseEnterEvent = new object (); + static object MouseHoverEvent = new object (); + static object MouseLeaveEvent = new object (); + static object MouseMoveEvent = new object (); + static object MouseUpEvent = new object (); + static object OwnerChangedEvent = new object (); + static object PaintEvent = new object (); + static object QueryAccessibilityHelpEvent = new object (); + static object QueryContinueDragEvent = new object (); + static object RightToLeftChangedEvent = new object (); + static object TextChangedEvent = new object (); + static object VisibleChangedEvent = new object (); + + [Browsable (false)] + public event EventHandler AvailableChanged { + add { Events.AddHandler (AvailableChangedEvent, value); } + remove {Events.RemoveHandler (AvailableChangedEvent, value); } + } + + public event EventHandler BackColorChanged { + add { Events.AddHandler (BackColorChangedEvent, value); } + remove {Events.RemoveHandler (BackColorChangedEvent, value); } + } + + public event EventHandler Click { + add { Events.AddHandler (ClickEvent, value); } + remove {Events.RemoveHandler (ClickEvent, value); } + } + + public event EventHandler DisplayStyleChanged { + add { Events.AddHandler (DisplayStyleChangedEvent, value); } + remove {Events.RemoveHandler (DisplayStyleChangedEvent, value); } + } + + public event EventHandler DoubleClick { + add { Events.AddHandler (DoubleClickEvent, value); } + remove {Events.RemoveHandler (DoubleClickEvent, value); } + } + + [MonoTODO ("Event never raised")] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event DragEventHandler DragDrop { + add { Events.AddHandler (DragDropEvent, value); } + remove { Events.RemoveHandler (DragDropEvent, value); } + } + + [MonoTODO ("Event never raised")] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event DragEventHandler DragEnter { + add { Events.AddHandler (DragEnterEvent, value); } + remove { Events.RemoveHandler (DragEnterEvent, value); } + } + + [MonoTODO ("Event never raised")] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event EventHandler DragLeave { + add { Events.AddHandler (DragLeaveEvent, value); } + remove { Events.RemoveHandler (DragLeaveEvent, value); } + } + + [MonoTODO ("Event never raised")] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event DragEventHandler DragOver { + add { Events.AddHandler (DragOverEvent, value); } + remove { Events.RemoveHandler (DragOverEvent, value); } + } + + public event EventHandler EnabledChanged { + add { Events.AddHandler (EnabledChangedEvent, value); } + remove {Events.RemoveHandler (EnabledChangedEvent, value); } + } + + public event EventHandler ForeColorChanged { + add { Events.AddHandler (ForeColorChangedEvent, value); } + remove {Events.RemoveHandler (ForeColorChangedEvent, value); } + } + + [MonoTODO ("Event never raised")] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event GiveFeedbackEventHandler GiveFeedback { + add { Events.AddHandler (GiveFeedbackEvent, value); } + remove { Events.RemoveHandler (GiveFeedbackEvent, value); } + } + + public event EventHandler LocationChanged { + add { Events.AddHandler (LocationChangedEvent, value); } + remove {Events.RemoveHandler (LocationChangedEvent, value); } + } + + public event MouseEventHandler MouseDown { + add { Events.AddHandler (MouseDownEvent, value); } + remove {Events.RemoveHandler (MouseDownEvent, value); } + } + + public event EventHandler MouseEnter { + add { Events.AddHandler (MouseEnterEvent, value); } + remove {Events.RemoveHandler (MouseEnterEvent, value); } + } + + public event EventHandler MouseHover { + add { Events.AddHandler (MouseHoverEvent, value); } + remove {Events.RemoveHandler (MouseHoverEvent, value); } + } + + public event EventHandler MouseLeave { + add { Events.AddHandler (MouseLeaveEvent, value); } + remove {Events.RemoveHandler (MouseLeaveEvent, value); } + } + + public event MouseEventHandler MouseMove { + add { Events.AddHandler (MouseMoveEvent, value); } + remove {Events.RemoveHandler (MouseMoveEvent, value); } + } + + public event MouseEventHandler MouseUp { + add { Events.AddHandler (MouseUpEvent, value); } + remove {Events.RemoveHandler (MouseUpEvent, value); } + } + + public event EventHandler OwnerChanged { + add { Events.AddHandler (OwnerChangedEvent, value); } + remove {Events.RemoveHandler (OwnerChangedEvent, value); } + } + + public event PaintEventHandler Paint { + add { Events.AddHandler (PaintEvent, value); } + remove {Events.RemoveHandler (PaintEvent, value); } + } + + [MonoTODO ("Event never raised")] + public event QueryAccessibilityHelpEventHandler QueryAccessibilityHelp { + add { Events.AddHandler (QueryAccessibilityHelpEvent, value); } + remove { Events.RemoveHandler (QueryAccessibilityHelpEvent, value); } + } + + [MonoTODO ("Event never raised")] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public event QueryContinueDragEventHandler QueryContinueDrag { + add { Events.AddHandler (QueryContinueDragEvent, value); } + remove { Events.RemoveHandler (QueryContinueDragEvent, value); } + } + + public event EventHandler RightToLeftChanged { + add { Events.AddHandler (RightToLeftChangedEvent, value); } + remove { Events.RemoveHandler (RightToLeftChangedEvent, value); } + } + + public event EventHandler TextChanged { + add { Events.AddHandler (TextChangedEvent, value); } + remove {Events.RemoveHandler (TextChangedEvent, value); } + } + + public event EventHandler VisibleChanged { + add { Events.AddHandler (VisibleChangedEvent, value); } + remove {Events.RemoveHandler (VisibleChangedEvent, value); } + } + #endregion + + #region Internal Methods + internal Rectangle AlignInRectangle (Rectangle outer, Size inner, ContentAlignment align) + { + int x = 0; + int y = 0; + + if (align == ContentAlignment.BottomLeft || align == ContentAlignment.MiddleLeft || align == ContentAlignment.TopLeft) + x = outer.X; + else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.MiddleCenter || align == ContentAlignment.TopCenter) + x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left); + else if (align == ContentAlignment.BottomRight || align == ContentAlignment.MiddleRight || align == ContentAlignment.TopRight) + x = outer.Right - inner.Width; + if (align == ContentAlignment.TopCenter || align == ContentAlignment.TopLeft || align == ContentAlignment.TopRight) + y = outer.Y; + else if (align == ContentAlignment.MiddleCenter || align == ContentAlignment.MiddleLeft || align == ContentAlignment.MiddleRight) + y = outer.Y + (outer.Height - inner.Height) / 2; + else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.BottomRight || align == ContentAlignment.BottomLeft) + y = outer.Bottom - inner.Height; + + return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height)); + } + + internal void CalculateAutoSize () + { + this.text_size = TextRenderer.MeasureText (this.Text == null ? string.Empty: this.text, this.Font, Size.Empty, TextFormatFlags.HidePrefix); + + // If our text is rotated, flip the width and height + ToolStripTextDirection direction = this.TextDirection; + + if (direction == ToolStripTextDirection.Vertical270 || direction == ToolStripTextDirection.Vertical90) + this.text_size = new Size (this.text_size.Height, this.text_size.Width); + + if (!this.auto_size || this is ToolStripWidgetHost) + return; + //this.text_size.Width += 6; + + Size final_size = this.CalculatePreferredSize (Size.Empty); + + if (final_size != this.Size) { + this.bounds.Width = final_size.Width; + if (this.parent != null) + this.parent.PerformLayout (); + } + } + + internal virtual Size CalculatePreferredSize (Size constrainingSize) + { + if (!this.auto_size) + return this.explicit_size; + + Size preferred_size = this.DefaultSize; + + switch (this.display_style) { + case ToolStripItemDisplayStyle.Text: + int width = text_size.Width + this.padding.Horizontal; + int height = text_size.Height + this.padding.Vertical; + preferred_size = new Size (width, height); + break; + case ToolStripItemDisplayStyle.Image: + if (this.GetImageSize () == Size.Empty) + preferred_size = this.DefaultSize; + else { + switch (this.image_scaling) { + case ToolStripItemImageScaling.None: + preferred_size = this.GetImageSize (); + break; + case ToolStripItemImageScaling.SizeToFit: + if (this.parent == null) + preferred_size = this.GetImageSize (); + else + preferred_size = this.parent.ImageScalingSize; + break; + } + } + break; + case ToolStripItemDisplayStyle.ImageAndText: + int width2 = text_size.Width + this.padding.Horizontal; + int height2 = text_size.Height + this.padding.Vertical; + + if (this.GetImageSize () != Size.Empty) { + Size image_size = this.GetImageSize (); + + if (this.image_scaling == ToolStripItemImageScaling.SizeToFit && this.parent != null) + image_size = this.parent.ImageScalingSize; + + switch (this.text_image_relation) { + case TextImageRelation.Overlay: + width2 = Math.Max (width2, image_size.Width); + height2 = Math.Max (height2, image_size.Height); + break; + case TextImageRelation.ImageAboveText: + case TextImageRelation.TextAboveImage: + width2 = Math.Max (width2, image_size.Width); + height2 += image_size.Height; + break; + case TextImageRelation.ImageBeforeText: + case TextImageRelation.TextBeforeImage: + height2 = Math.Max (height2, image_size.Height); + width2 += image_size.Width; + break; + } + } + + preferred_size = new Size (width2, height2); + break; + } + + if (!(this is ToolStripLabel)) { // Everything but labels have a border + preferred_size.Height += 4; + preferred_size.Width += 4; + } + + return preferred_size; + } + + internal void CalculateTextAndImageRectangles (out Rectangle text_rect, out Rectangle image_rect) + { + this.CalculateTextAndImageRectangles (this.ContentRectangle, out text_rect, out image_rect); + } + + internal void CalculateTextAndImageRectangles (Rectangle contentRectangle, out Rectangle text_rect, out Rectangle image_rect) + { + text_rect = Rectangle.Empty; + image_rect = Rectangle.Empty; + + switch (this.display_style) { + case ToolStripItemDisplayStyle.None: + break; + case ToolStripItemDisplayStyle.Text: + if (this.text != string.Empty) + text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align); + break; + case ToolStripItemDisplayStyle.Image: + if (this.Image != null && this.UseImageMargin) + image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align); + break; + case ToolStripItemDisplayStyle.ImageAndText: + if (this.text != string.Empty && (this.Image == null || !this.UseImageMargin)) + text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align); + else if (this.text == string.Empty && (this.Image == null || !this.UseImageMargin)) + break; + else if (this.text == string.Empty && this.Image != null) + image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align); + else { + Rectangle text_area; + Rectangle image_area; + + switch (this.text_image_relation) { + case TextImageRelation.Overlay: + text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align); + image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align); + break; + case TextImageRelation.ImageAboveText: + text_area = new Rectangle (contentRectangle.Left, contentRectangle.Bottom - text_size.Height, contentRectangle.Width, text_size.Height); + image_area = new Rectangle (contentRectangle.Left, contentRectangle.Top, contentRectangle.Width, contentRectangle.Height - text_area.Height); + + text_rect = AlignInRectangle (text_area, this.text_size, this.text_align); + image_rect = AlignInRectangle (image_area, GetImageSize (), this.image_align); + break; + case TextImageRelation.TextAboveImage: + text_area = new Rectangle (contentRectangle.Left, contentRectangle.Top, contentRectangle.Width, text_size.Height); + image_area = new Rectangle (contentRectangle.Left, text_area.Bottom, contentRectangle.Width, contentRectangle.Height - text_area.Height); + + text_rect = AlignInRectangle (text_area, this.text_size, this.text_align); + image_rect = AlignInRectangle (image_area, GetImageSize (), this.image_align); + break; + case TextImageRelation.ImageBeforeText: + LayoutTextBeforeOrAfterImage (contentRectangle, false, text_size, GetImageSize (), text_align, image_align, out text_rect, out image_rect); + break; + case TextImageRelation.TextBeforeImage: + LayoutTextBeforeOrAfterImage (contentRectangle, true, text_size, GetImageSize (), text_align, image_align, out text_rect, out image_rect); + break; + } + } + break; + } + } + + private static Font DefaultFont { get { return new Font ("Tahoma", 8.25f); } } + + internal virtual ToolStripTextDirection DefaultTextDirection { get { return ToolStripTextDirection.Inherit; } } + + internal virtual void Dismiss (ToolStripDropDownCloseReason reason) + { + if (is_selected) { + this.is_selected = false; + this.Invalidate (); + OnUIASelectionChanged (); + } + } + + internal virtual ToolStrip GetTopLevelToolStrip () + { + if (this.Parent != null) + return this.Parent.GetTopLevelToolStrip (); + + return null; + } + + private void LayoutTextBeforeOrAfterImage (Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, ContentAlignment textAlign, ContentAlignment imageAlign, out Rectangle textRect, out Rectangle imageRect) + { + int element_spacing = 0; // Spacing between the Text and the Image + int total_width = textSize.Width + element_spacing + imageSize.Width; + int excess_width = totalArea.Width - total_width; + int offset = 0; + + Rectangle final_text_rect; + Rectangle final_image_rect; + + HorizontalAlignment h_text = GetHorizontalAlignment (textAlign); + HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign); + + if (h_image == HorizontalAlignment.Left) + offset = 0; + else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right) + offset = excess_width; + else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center)) + offset += (int)(excess_width / 3); + else + offset += (int)(2 * (excess_width / 3)); + + if (textFirst) { + final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height); + final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height); + } else { + final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height); + final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height); + } + + textRect = final_text_rect; + imageRect = final_image_rect; + } + + private HorizontalAlignment GetHorizontalAlignment (ContentAlignment align) + { + switch (align) { + case ContentAlignment.BottomLeft: + case ContentAlignment.MiddleLeft: + case ContentAlignment.TopLeft: + return HorizontalAlignment.Left; + case ContentAlignment.BottomCenter: + case ContentAlignment.MiddleCenter: + case ContentAlignment.TopCenter: + return HorizontalAlignment.Center; + case ContentAlignment.BottomRight: + case ContentAlignment.MiddleRight: + case ContentAlignment.TopRight: + return HorizontalAlignment.Right; + } + + return HorizontalAlignment.Left; + } + + internal Size GetImageSize () + { + // Get the actual size of our internal image -or- + // Get the ImageList.ImageSize if we are using ImageLists + if (this.image_scaling == ToolStripItemImageScaling.None) { + if (this.image != null) + return image.Size; + + if (this.image_index >= 0 || !string.IsNullOrEmpty (this.image_key)) + if (this.owner != null && this.owner.ImageList != null) + return this.owner.ImageList.ImageSize; + } else { + // If we have an image and a parent, return ImageScalingSize + if (this.Parent == null) + return Size.Empty; + + if (this.image != null) + return this.Parent.ImageScalingSize; + + if (this.image_index >= 0 || !string.IsNullOrEmpty (this.image_key)) + if (this.owner != null && this.owner.ImageList != null) + return this.Parent.ImageScalingSize; + } + + return Size.Empty; + } + + internal string GetToolTip () + { + if (this.auto_tool_tip && string.IsNullOrEmpty (this.tool_tip_text)) + return this.Text; + + return this.tool_tip_text; + } + + internal void FireEvent (EventArgs e, ToolStripItemEventType met) + { + // If we're disabled, don't fire any of these events, except Paint + if (!this.Enabled && met != ToolStripItemEventType.Paint) + return; + + switch (met) { + case ToolStripItemEventType.MouseUp: + if (((MouseEventArgs)e).Button == MouseButtons.Left) + this.HandleClick (((MouseEventArgs)e).Clicks, e); + this.OnMouseUp ((MouseEventArgs)e); + break; + case ToolStripItemEventType.MouseDown: + this.OnMouseDown ((MouseEventArgs)e); + break; + case ToolStripItemEventType.MouseEnter: + this.OnMouseEnter (e); + break; + case ToolStripItemEventType.MouseHover: + this.OnMouseHover (e); + break; + case ToolStripItemEventType.MouseLeave: + this.OnMouseLeave (e); + break; + case ToolStripItemEventType.MouseMove: + this.OnMouseMove ((MouseEventArgs)e); + break; + case ToolStripItemEventType.Paint: + this.OnPaintInternal ((PaintEventArgs)e); + break; + case ToolStripItemEventType.Click: + this.HandleClick (1, e); + break; + } + } + + internal virtual void HandleClick (int mouse_clicks, EventArgs e) + { + if (Parent == null) + return; + this.Parent.HandleItemClick (this); + if (mouse_clicks == 2 && double_click_enabled) + this.OnDoubleClick (e); + else + this.OnClick (e); + } + + internal virtual void SetPlacement (ToolStripItemPlacement placement) + { + this.placement = placement; + } + + private void BeginAnimation () + { + if (image != null && ImageAnimator.CanAnimate (image)) { + frame_handler = new EventHandler (OnAnimateImage); + ImageAnimator.Animate (image, frame_handler); + } + } + + private void OnAnimateImage (object sender, EventArgs e) + { + // This is called from a worker thread,BeginInvoke is used + // so the Widget is updated from the correct thread + + // Check if we have a handle again, since it may have gotten + // destroyed since the last time we checked. + if (Parent == null || !Parent.IsHandleCreated) + return; + + Parent.BeginInvoke (new EventHandler (UpdateAnimatedImage), new object[] { this, e }); + } + + private void StopAnimation () + { + if (frame_handler == null) + return; + + ImageAnimator.StopAnimate (image, frame_handler); + frame_handler = null; + } + + private void UpdateAnimatedImage (object sender, EventArgs e) + { + // Check if we have a handle again, since it may have gotten + // destroyed since the last time we checked. + if (Parent == null || !Parent.IsHandleCreated) + return; + + ImageAnimator.UpdateFrames (image); + Invalidate (); + } + + internal bool ShowMargin { + get { + if (!this.IsOnDropDown) + return true; + + if (!(this.Owner is ToolStripDropDownMenu)) + return false; + + ToolStripDropDownMenu tsddm = (ToolStripDropDownMenu)this.Owner; + + return tsddm.ShowCheckMargin || tsddm.ShowImageMargin; + } + } + + internal bool UseImageMargin { + get { + if (!this.IsOnDropDown) + return true; + + if (!(this.Owner is ToolStripDropDownMenu)) + return false; + + ToolStripDropDownMenu tsddm = (ToolStripDropDownMenu)this.Owner; + + return tsddm.ShowImageMargin || tsddm.ShowCheckMargin; + } + } + + internal virtual bool InternalVisible { + get { return this.visible; } + set { this.visible = value; Invalidate (); } + } + + internal ToolStrip InternalOwner { + set { + if (this.owner != value) { + this.owner = value; + if (this.owner != null) + this.CalculateAutoSize (); + OnOwnerChanged (EventArgs.Empty); + } + } + } + + internal Point Location { + get { return this.bounds.Location; } + set { + if (this.bounds.Location != value) { + this.bounds.Location = value; + this.OnLocationChanged (EventArgs.Empty); + } + } + } + + internal int Top { + get { return this.bounds.Y; } + set { + if (this.bounds.Y != value) { + this.bounds.Y = value; + this.OnLocationChanged (EventArgs.Empty); + } + } + } + + internal int Left { + get { return this.bounds.X; } + set { + if (this.bounds.X != value) { + this.bounds.X = value; + this.OnLocationChanged (EventArgs.Empty); + } + } + } + + internal int Right { get { return this.bounds.Right; } } + internal int Bottom { get { return this.bounds.Bottom; } } + #endregion + + #region IDropTarget Members + void IDropTarget.OnDragDrop (DragEventArgs dragEvent) + { + OnDragDrop (dragEvent); + } + + void IDropTarget.OnDragEnter (DragEventArgs dragEvent) + { + OnDragEnter (dragEvent); + } + + void IDropTarget.OnDragLeave (EventArgs e) + { + OnDragLeave (e); + } + + void IDropTarget.OnDragOver (DragEventArgs dragEvent) + { + OnDragOver (dragEvent); + } + #endregion + + #region UIA Framework: Methods, Properties and Events + + static object UIASelectionChangedEvent = new object (); + + internal event EventHandler UIASelectionChanged { + add { Events.AddHandler (UIASelectionChangedEvent, value); } + remove { Events.RemoveHandler (UIASelectionChangedEvent, value); } + } + + internal void OnUIASelectionChanged () + { + EventHandler eh = (EventHandler)(Events [UIASelectionChangedEvent]); + if (eh != null) + eh (this, EventArgs.Empty); + } + + #endregion + + [ComVisible (true)] + public class ToolStripItemAccessibleObject : AccessibleObject + { + internal ToolStripItem owner_item; + + public ToolStripItemAccessibleObject (ToolStripItem ownerItem) + { + if (ownerItem == null) + throw new ArgumentNullException ("ownerItem"); + + this.owner_item = ownerItem; + base.default_action = string.Empty; + base.keyboard_shortcut = string.Empty; + base.name = string.Empty; + base.value = string.Empty; + } + + #region Public Properties + public override Rectangle Bounds { + get { + return owner_item.Visible ? owner_item.Bounds : Rectangle.Empty; + } + } + + public override string DefaultAction { + get { return base.DefaultAction; } + } + + public override string Description { + get { return base.Description; } + } + + public override string Help { + get { return base.Help; } + } + + public override string KeyboardShortcut { + get { return base.KeyboardShortcut; } + } + + public override string Name { + get { + if (base.name == string.Empty) + return owner_item.Text; + + return base.Name; + } + set { base.Name = value; } + } + + public override AccessibleObject Parent { + get { return base.Parent; } + } + + public override AccessibleRole Role { + get { return base.Role; } + } + + public override AccessibleStates State { + get { return base.State; } + } + #endregion + + #region Public Methods + public void AddState (AccessibleStates state) + { + base.state = state; + } + + public override void DoDefaultAction () + { + base.DoDefaultAction (); + } + + public override int GetHelpTopic (out string fileName) + { + return base.GetHelpTopic (out fileName); + } + + public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) + { + return base.Navigate (navigationDirection); + } + + public override string ToString () + { + return string.Format ("ToolStripItemAccessibleObject: Owner = {0}", owner_item.ToString()); + } + #endregion + } + } + + internal class NoneExcludedImageIndexConverter : ImageIndexConverter + { + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemAlignment.cs b/source/ShiftUI/ToolStrip/ToolStripItemAlignment.cs new file mode 100644 index 0000000..5bd4bbf --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemAlignment.cs @@ -0,0 +1,37 @@ +// +// ToolStripItemAlignment.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripItemAlignment + { + Left = 0, + Right = 1 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemClickedEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripItemClickedEventArgs.cs new file mode 100644 index 0000000..65c9d34 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemClickedEventArgs.cs @@ -0,0 +1,47 @@ +// +// ToolStripItemClickedEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// +using System; + +namespace ShiftUI +{ + public class ToolStripItemClickedEventArgs : EventArgs + { + private ToolStripItem clicked_item; + + public ToolStripItemClickedEventArgs (ToolStripItem clickedItem) : base () + { + this.clicked_item = clickedItem; + } + + #region Public Properties + public ToolStripItem ClickedItem { + get { return this.clicked_item; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemClickedEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripItemClickedEventHandler.cs new file mode 100644 index 0000000..66ab988 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemClickedEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripItemClickedEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripItemClickedEventHandler (object sender, ToolStripItemClickedEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemCollection.cs b/source/ShiftUI/ToolStrip/ToolStripItemCollection.cs new file mode 100644 index 0000000..46d3072 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemCollection.cs @@ -0,0 +1,385 @@ +// +// ToolStripItemCollection.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using ShiftUI.Layout; +using System; + +namespace ShiftUI +{ + [ListBindable (false)] + //[Editor ("ShiftUI.Design.ToolStripCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] + public class ToolStripItemCollection : ArrangedElementCollection, IList, ICollection, IEnumerable + { + private ToolStrip owner; + private bool internal_created; + + #region Public Constructor + public ToolStripItemCollection (ToolStrip owner, ToolStripItem[] value) : base () + { + if (owner == null) + throw new ArgumentNullException ("owner"); + + if (value == null) + throw new ArgumentNullException ("toolStripItems"); + + this.owner = owner; + + foreach (ToolStripItem tsi in value) + this.AddNoOwnerOrLayout (tsi); + } + + internal ToolStripItemCollection (ToolStrip owner, ToolStripItem[] value, bool internalcreated) : base () + { + if (owner == null) + throw new ArgumentNullException ("owner"); + + this.internal_created = internalcreated; + this.owner = owner; + + if (value != null) + foreach (ToolStripItem tsi in value) + this.AddNoOwnerOrLayout (tsi); + } + #endregion + + #region Public Properties + public override bool IsReadOnly { get { return base.IsReadOnly; } } + + public new virtual ToolStripItem this[int index] { get { return (ToolStripItem)base[index]; } } + + public virtual ToolStripItem this[string key] { + get { + foreach (ToolStripItem tsi in this) + if (tsi.Name == key) + return tsi; + + return null; + } + } + #endregion + + #region Public Methods + public ToolStripItem Add (Image image) + { + ToolStripItem tsb = owner.CreateDefaultItem (string.Empty, image, null); + this.Add (tsb); + return tsb; + } + + public ToolStripItem Add (string text) + { + ToolStripItem tsb = owner.CreateDefaultItem (text, null, null); + this.Add (tsb); + return tsb; + } + + public int Add (ToolStripItem value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + if (Contains (value)) + return IndexOf (value); + + value.InternalOwner = owner; + + if (value is ToolStripMenuItem && (value as ToolStripMenuItem).ShortcutKeys != Keys.None) + ToolStripManager.AddToolStripMenuItem ((ToolStripMenuItem)value); + + int index = base.Add (value); + + if (this.internal_created) + owner.OnItemAdded (new ToolStripItemEventArgs (value)); + + return index; + } + + public ToolStripItem Add (string text, Image image) + { + ToolStripItem tsb = owner.CreateDefaultItem (text, image, null); + this.Add (tsb); + return tsb; + } + + public ToolStripItem Add (string text, Image image, EventHandler onClick) + { + ToolStripItem tsb = owner.CreateDefaultItem (text, image, onClick); + this.Add (tsb); + return tsb; + } + + public void AddRange (ToolStripItem[] toolStripItems) + { + if (toolStripItems == null) + throw new ArgumentNullException ("toolStripItems"); + if (this.IsReadOnly) + throw new NotSupportedException ("This collection is read-only"); + + this.owner.SuspendLayout (); + + foreach (ToolStripItem tsi in toolStripItems) + this.Add (tsi); + + this.owner.ResumeLayout (); + } + + public void AddRange (ToolStripItemCollection toolStripItems) + { + if (toolStripItems == null) + throw new ArgumentNullException ("toolStripItems"); + if (this.IsReadOnly) + throw new NotSupportedException ("This collection is read-only"); + + this.owner.SuspendLayout (); + + foreach (ToolStripItem tsi in toolStripItems) + this.Add (tsi); + + this.owner.ResumeLayout (); + } + + public new virtual void Clear () + { + if (this.IsReadOnly) + throw new NotSupportedException ("This collection is read-only"); + + if (internal_created) + foreach (ToolStripItem item in this) { + item.InternalOwner = null; + item.Parent = null; + } + + base.Clear (); + owner.PerformLayout (); + } + + // Don't modify Owner or Parent - used by internal collection instances. + internal void ClearInternal () + { + base.Clear (); + owner.PerformLayout (); + } + + public bool Contains (ToolStripItem value) + { + return base.Contains (value); + } + + public virtual bool ContainsKey (string key) + { + return this[key] != null; + } + + public void CopyTo (ToolStripItem[] array, int index) + { + base.CopyTo (array, index); + } + + [MonoTODO ("searchAllChildren parameter isn't used")] + public ToolStripItem[] Find (string key, bool searchAllChildren) + { + if (key == null || key.Length == 0) + throw new ArgumentNullException ("key"); + + List<ToolStripItem> list = new List<ToolStripItem> (); + + foreach (ToolStripItem tsi in this) { + if (String.Compare (tsi.Name, key, true) == 0) { + list.Add (tsi); + + if (searchAllChildren) { + // TODO: tsi does not have an items property yet.. + } + } + } + + return list.ToArray (); + } + + public int IndexOf (ToolStripItem value) + { + return base.IndexOf (value); + } + + public virtual int IndexOfKey (string key) + { + ToolStripItem tsi = this[key]; + + if (tsi == null) + return -1; + + return this.IndexOf (tsi); + } + + public void Insert (int index, ToolStripItem value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + if (value is ToolStripMenuItem && (value as ToolStripMenuItem).ShortcutKeys != Keys.None) + ToolStripManager.AddToolStripMenuItem ((ToolStripMenuItem)value); + + if (value.Owner != null) + value.Owner.Items.Remove (value); + + base.Insert (index, value); + + if (internal_created) { + value.InternalOwner = owner; + owner.OnItemAdded (new ToolStripItemEventArgs (value)); + } + + if (owner.Created) + owner.PerformLayout (); + } + + public void Remove (ToolStripItem value) + { + if (this.IsReadOnly) + throw new NotSupportedException ("This collection is read-only"); + + base.Remove (value); + + if (value != null && internal_created) { + value.InternalOwner = null; + value.Parent = null; + } + + if (internal_created) + owner.OnItemRemoved (new ToolStripItemEventArgs (value)); + + if (owner.Created) + owner.PerformLayout (); + } + + public void RemoveAt (int index) + { + if (this.IsReadOnly) + throw new NotSupportedException ("This collection is read-only"); + + ToolStripItem tsi = (ToolStripItem)base[index]; + this.Remove (tsi); + } + + public virtual void RemoveByKey (string key) + { + if (this.IsReadOnly) + throw new NotSupportedException ("This collection is read-only"); + + ToolStripItem tsi = this[key]; + + if (tsi != null) + this.Remove (tsi); + + return; + } + #endregion + + #region Internal Methods + // When we create DisplayedItems, we don't want to modify the item's + // parent or trigger a layout. + internal int AddNoOwnerOrLayout (ToolStripItem value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + int index = base.Add (value); + return index; + } + + internal void InsertNoOwnerOrLayout (int index, ToolStripItem value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + if (index > Count) + base.Add (value); + else + base.Insert (index, value); + } + + internal void RemoveNoOwnerOrLayout (ToolStripItem value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + base.Remove (value); + } + #endregion + + #region IList Members + int IList.Add (object value) + { + return this.Add ((ToolStripItem)value); + } + + void IList.Clear () + { + this.Clear (); + } + + bool IList.Contains (object value) + { + return this.Contains ((ToolStripItem)value); + } + + int IList.IndexOf (object value) + { + return this.IndexOf ((ToolStripItem)value); + } + + void IList.Insert (int index, object value) + { + this.Insert (index, (ToolStripItem)value); + } + + bool IList.IsFixedSize { + get { return this.IsFixedSize; } + } + + void IList.Remove (object value) + { + this.Remove ((ToolStripItem)value); ; + } + + void IList.RemoveAt (int index) + { + this.RemoveAt (index); + } + + object IList.this[int index] { + get { return this[index]; } + set { throw new NotSupportedException (); } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemDisplayStyle.cs b/source/ShiftUI/ToolStrip/ToolStripItemDisplayStyle.cs new file mode 100644 index 0000000..a090648 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemDisplayStyle.cs @@ -0,0 +1,39 @@ +// +// ToolStripItemDisplayStyle.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripItemDisplayStyle + { + None = 0, + Text = 1, + Image = 2, + ImageAndText = 3 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripItemEventArgs.cs new file mode 100644 index 0000000..71a826b --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemEventArgs.cs @@ -0,0 +1,50 @@ +// +// ToolStripItemEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System; + +namespace ShiftUI +{ + public class ToolStripItemEventArgs : EventArgs + { + private ToolStripItem item; + + public ToolStripItemEventArgs (ToolStripItem item) : base () + { + this.item = item; + } + + #region Public Properties + public ToolStripItem Item + { + get { return item; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripItemEventHandler.cs new file mode 100644 index 0000000..a10eabe --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripItemEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripItemEventHandler (object sender, ToolStripItemEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemEventType.cs b/source/ShiftUI/ToolStrip/ToolStripItemEventType.cs new file mode 100644 index 0000000..c58efa2 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemEventType.cs @@ -0,0 +1,42 @@ +// +// ToolStripItemEventType.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + internal enum ToolStripItemEventType + { + MouseDown = 1, + MouseEnter = 2, + MouseHover = 3, + MouseLeave = 4, + MouseMove = 5, + MouseUp = 6, + Paint = 7, + Click = 8 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemImageRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripItemImageRenderEventArgs.cs new file mode 100644 index 0000000..864ed9a --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemImageRenderEventArgs.cs @@ -0,0 +1,60 @@ +// +// ToolStripItemImageRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; + +namespace ShiftUI +{ + public class ToolStripItemImageRenderEventArgs : ToolStripItemRenderEventArgs + { + private Image image; + private Rectangle image_rectangle; + + public ToolStripItemImageRenderEventArgs (Graphics g, ToolStripItem item, Rectangle imageRectangle) + : this (g, item, null, imageRectangle) + { + } + + public ToolStripItemImageRenderEventArgs (Graphics g, ToolStripItem item, Image image, Rectangle imageRectangle) + : base (g, item) + { + this.image = image; + this.image_rectangle = imageRectangle; + } + + #region Public Properties + public Image Image { + get { return this.image; } + } + + public Rectangle ImageRectangle { + get { return this.image_rectangle; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemImageRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripItemImageRenderEventHandler.cs new file mode 100644 index 0000000..3d475c8 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemImageRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripItemImageRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripItemImageRenderEventHandler (object sender, ToolStripItemImageRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemImageScaling.cs b/source/ShiftUI/ToolStrip/ToolStripItemImageScaling.cs new file mode 100644 index 0000000..b2293c5 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemImageScaling.cs @@ -0,0 +1,37 @@ +// +// ToolStripItemImageScaling.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripItemImageScaling + { + None = 0, + SizeToFit = 1 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemOverflow.cs b/source/ShiftUI/ToolStrip/ToolStripItemOverflow.cs new file mode 100644 index 0000000..6410f0b --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemOverflow.cs @@ -0,0 +1,38 @@ +// +// ToolStripItemOverflow.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripItemOverflow + { + Never = 0, + Always = 1, + AsNeeded = 2 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemPlacement.cs b/source/ShiftUI/ToolStrip/ToolStripItemPlacement.cs new file mode 100644 index 0000000..0edde1d --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemPlacement.cs @@ -0,0 +1,38 @@ +// +// ToolStripItemPlacement.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripItemPlacement + { + Main = 0, + Overflow = 1, + None = 2 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripItemRenderEventArgs.cs new file mode 100644 index 0000000..ecea083 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemRenderEventArgs.cs @@ -0,0 +1,59 @@ +// +// ToolStripItemRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System; + +namespace ShiftUI +{ + public class ToolStripItemRenderEventArgs : EventArgs + { + private Graphics graphics; + private ToolStripItem item; + + public ToolStripItemRenderEventArgs (Graphics g, ToolStripItem item) : base () + { + this.graphics = g; + this.item = item; + } + + #region Public Properties + public Graphics Graphics { + get { return this.graphics; } + } + + public ToolStripItem Item { + get { return this.item; } + } + + public ToolStrip ToolStrip { + get { return this.item.Owner; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripItemRenderEventHandler.cs new file mode 100644 index 0000000..cada3ef --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripItemRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripItemRenderEventHandler (object sender, ToolStripItemRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemTextRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripItemTextRenderEventArgs.cs new file mode 100644 index 0000000..f712f53 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemTextRenderEventArgs.cs @@ -0,0 +1,131 @@ +// +// ToolStripItemTextRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; + +namespace ShiftUI +{ + public class ToolStripItemTextRenderEventArgs : ToolStripItemRenderEventArgs + { + private string text; + private Color text_color; + private ToolStripTextDirection text_direction; + private Font text_font; + private TextFormatFlags text_format; + private Rectangle text_rectangle; + + #region Public Constructors + public ToolStripItemTextRenderEventArgs (Graphics g, ToolStripItem item, string text, Rectangle textRectangle, Color textColor, Font textFont, ContentAlignment textAlign) + : base (g, item) + { + this.text = text; + this.text_rectangle = textRectangle; + this.text_color = textColor; + this.text_font = textFont; + this.text_direction = item.TextDirection; + + switch (textAlign) { + case ContentAlignment.BottomCenter: + this.text_format = TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter; + break; + case ContentAlignment.BottomLeft: + this.text_format = TextFormatFlags.Bottom | TextFormatFlags.Left; + break; + case ContentAlignment.BottomRight: + this.text_format = TextFormatFlags.Bottom | TextFormatFlags.Right; + break; + case ContentAlignment.MiddleCenter: + this.text_format = TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter; + break; + case ContentAlignment.MiddleLeft: + default: + this.text_format = (TextFormatFlags.VerticalCenter | TextFormatFlags.Left); + break; + case ContentAlignment.MiddleRight: + this.text_format = TextFormatFlags.VerticalCenter | TextFormatFlags.Right; + break; + case ContentAlignment.TopCenter: + this.text_format = TextFormatFlags.Top | TextFormatFlags.HorizontalCenter; + break; + case ContentAlignment.TopLeft: + this.text_format = TextFormatFlags.Top | TextFormatFlags.Left; + break; + case ContentAlignment.TopRight: + this.text_format = TextFormatFlags.Top | TextFormatFlags.Right; + break; + } + + if ((Application.KeyboardCapture == null || !ToolStripManager.ActivatedByKeyboard) && !SystemInformation.MenuAccessKeysUnderlined) + this.text_format |= TextFormatFlags.HidePrefix; + } + + public ToolStripItemTextRenderEventArgs (Graphics g, ToolStripItem item, string text, Rectangle textRectangle, Color textColor, Font textFont, TextFormatFlags format) + : base (g, item) + { + this.text = text; + this.text_rectangle = textRectangle; + this.text_color = textColor; + this.text_font = textFont; + this.text_format = format; + this.text_direction = ToolStripTextDirection.Horizontal; + } + #endregion + + #region Public Properties + public string Text { + get { return this.text; } + set { this.text = value; } + } + + public Color TextColor { + get { return this.text_color; } + set { this.text_color = value; } + } + + public ToolStripTextDirection TextDirection { + get { return this.text_direction; } + set { this.text_direction = value; } + } + + public Font TextFont { + get { return this.text_font; } + set { this.text_font = value; } + } + + public TextFormatFlags TextFormat { + get { return this.text_format; } + set { this.text_format = value; } + } + + public Rectangle TextRectangle { + get { return this.text_rectangle; } + set { this.text_rectangle = value; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripItemTextRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripItemTextRenderEventHandler.cs new file mode 100644 index 0000000..f265b3d --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripItemTextRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripItemTextRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripItemTextRenderEventHandler (object sender, ToolStripItemTextRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripLabel.cs b/source/ShiftUI/ToolStrip/ToolStripLabel.cs new file mode 100644 index 0000000..9f70b80 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripLabel.cs @@ -0,0 +1,288 @@ +// +// ToolStripLabel.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; +using System; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip)] + public class ToolStripLabel : ToolStripItem + { + private Color active_link_color; + private bool is_link; + private LinkBehavior link_behavior; + private Color link_color; + private bool link_visited; + private Color visited_link_color; + + #region UIA FrameWork Events + static object UIAIsLinkChangedEvent = new object (); + + internal event EventHandler UIAIsLinkChanged { + add { Events.AddHandler (UIAIsLinkChangedEvent, value); } + remove { Events.RemoveHandler (UIAIsLinkChangedEvent, value); } + } + + internal void OnUIAIsLinkChanged (EventArgs e) + { + EventHandler eh = (EventHandler) Events [UIAIsLinkChangedEvent]; + if (eh != null) + eh (this, e); + } + #endregion + + #region Public Constructors + public ToolStripLabel () + : this (null, null, false, null, String.Empty) + { + } + + public ToolStripLabel (Image image) + : this (null, image, false, null, String.Empty) + { + } + + public ToolStripLabel (string text) + : this (text, null, false, null, String.Empty) + { + } + + public ToolStripLabel (string text, Image image) + : this (text, image, false, null, String.Empty) + { + } + + public ToolStripLabel (string text, Image image, bool isLink) + : this (text, image, isLink, null, String.Empty) + { + } + + public ToolStripLabel (string text, Image image, bool isLink, EventHandler onClick) + : this (text, image, isLink, onClick, String.Empty) + { + } + + public ToolStripLabel (string text, Image image, bool isLink, EventHandler onClick, string name) + : base (text, image, onClick, name) + { + this.active_link_color = Color.Red; + this.is_link = isLink; + this.link_behavior = LinkBehavior.SystemDefault; + this.link_color = Color.FromArgb (0, 0, 255); + this.link_visited = false; + this.visited_link_color = Color.FromArgb (128, 0, 128); + } + #endregion + + #region Public Properties + public Color ActiveLinkColor { + get { return this.active_link_color; } + set { + this.active_link_color = value; + this.Invalidate (); + } + } + + public override bool CanSelect { get { return false; } } + + [DefaultValue (false)] + public bool IsLink { + get { return this.is_link; } + set { + this.is_link = value; + this.Invalidate (); + + // UIA Framework Event: IsLink Changed + OnUIAIsLinkChanged (EventArgs.Empty); + } + } + + [DefaultValue (LinkBehavior.SystemDefault)] + public LinkBehavior LinkBehavior { + get { return this.link_behavior; } + set { + this.link_behavior = value; + this.Invalidate (); + } + } + + public Color LinkColor { + get { return this.link_color; } + set { + this.link_color = value; + this.Invalidate (); + } + } + + [DefaultValue (false)] + public bool LinkVisited { + get { return this.link_visited; } + set { + this.link_visited = value; + this.Invalidate (); + } + } + + public Color VisitedLinkColor + { + get { return this.visited_link_color; } + set { + this.visited_link_color = value; + this.Invalidate (); + } + } + #endregion + + #region Protected Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override AccessibleObject CreateAccessibilityInstance () + { + ToolStripItemAccessibleObject ao = new ToolStripItemAccessibleObject (this); + + ao.role = AccessibleRole.StaticText; + ao.state = AccessibleStates.ReadOnly; + + return ao; + } + + protected override void OnFontChanged (EventArgs e) + { + base.OnFontChanged (e); + } + + protected override void OnMouseEnter (EventArgs e) + { + base.OnMouseEnter (e); + } + + protected override void OnMouseLeave (EventArgs e) + { + base.OnMouseLeave (e); + } + + protected override void OnPaint (ShiftUI.PaintEventArgs e) + { + if (this.Owner != null) { + Color font_color = this.Enabled ? this.ForeColor : SystemColors.GrayText; + Image draw_image = this.Enabled ? this.Image : ToolStripRenderer.CreateDisabledImage (this.Image); + + this.Owner.Renderer.DrawLabelBackground (new ShiftUI.ToolStripItemRenderEventArgs (e.Graphics, this)); + + Rectangle text_layout_rect; + Rectangle image_layout_rect; + + this.CalculateTextAndImageRectangles (out text_layout_rect, out image_layout_rect); + + if (this.IsOnDropDown) { + if (this.ShowMargin) + text_layout_rect = new Rectangle (35, text_layout_rect.Top, text_layout_rect.Width, text_layout_rect.Height); + else + text_layout_rect = new Rectangle (7, text_layout_rect.Top, text_layout_rect.Width, text_layout_rect.Height); + if (image_layout_rect != Rectangle.Empty) + image_layout_rect = new Rectangle (new Point (4, 3), base.GetImageSize ()); + } + + if (image_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemImage (new ShiftUI.ToolStripItemImageRenderEventArgs (e.Graphics, this, draw_image, image_layout_rect)); + if (text_layout_rect != Rectangle.Empty) + if (this.is_link) { + if (this.Pressed) // Mouse Down + { + switch (this.link_behavior) { + case LinkBehavior.SystemDefault: + case LinkBehavior.AlwaysUnderline: + case LinkBehavior.HoverUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.active_link_color, new Font (this.Font, FontStyle.Underline), this.TextAlign)); + break; + case LinkBehavior.NeverUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.active_link_color, this.Font, this.TextAlign)); + break; + } + } + else if (this.Selected) // Hover + { + switch (this.link_behavior) { + case LinkBehavior.SystemDefault: + case LinkBehavior.AlwaysUnderline: + case LinkBehavior.HoverUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.link_color, new Font (this.Font, FontStyle.Underline), this.TextAlign)); + break; + case LinkBehavior.NeverUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.link_color, this.Font, this.TextAlign)); + break; + } + } + else { + + if (this.link_visited) // Normal, Visited + { + switch (this.link_behavior) { + case LinkBehavior.SystemDefault: + case LinkBehavior.AlwaysUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.visited_link_color, new Font (this.Font, FontStyle.Underline), this.TextAlign)); + break; + case LinkBehavior.NeverUnderline: + case LinkBehavior.HoverUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.visited_link_color, this.Font, this.TextAlign)); + break; + } + } + else // Normal + { + switch (this.link_behavior) { + case LinkBehavior.SystemDefault: + case LinkBehavior.AlwaysUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.link_color, new Font (this.Font, FontStyle.Underline), this.TextAlign)); + break; + case LinkBehavior.NeverUnderline: + case LinkBehavior.HoverUnderline: + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, this.link_color, this.Font, this.TextAlign)); + break; + } + + } + } + } else + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign)); + } + + // call Paint handlers last. + base.OnPaint (e); + } + + protected internal override bool ProcessMnemonic (char charCode) + { + this.Parent.SelectNextToolStripItem (this, true); + return true; + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripLayoutStyle.cs b/source/ShiftUI/ToolStrip/ToolStripLayoutStyle.cs new file mode 100644 index 0000000..39d3c10 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripLayoutStyle.cs @@ -0,0 +1,40 @@ +// +// ToolStripLayoutStyle.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripLayoutStyle + { + StackWithOverflow = 0, + HorizontalStackWithOverflow = 1, + VerticalStackWithOverflow = 2, + Flow = 3, + Table = 4 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripManager.cs b/source/ShiftUI/ToolStrip/ToolStripManager.cs new file mode 100644 index 0000000..f580413 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripManager.cs @@ -0,0 +1,634 @@ +// +// ToolStripManager.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Collections.Generic; +using System; + +namespace ShiftUI +{ + public sealed class ToolStripManager + { + private static ToolStripRenderer renderer = new ToolStripProfessionalRenderer (); + private static ToolStripManagerRenderMode render_mode = ToolStripManagerRenderMode.Professional; + private static bool visual_styles_enabled = Application.RenderWithVisualStyles; + private static List<WeakReference> toolstrips = new List<WeakReference> (); + private static List<ToolStripMenuItem> menu_items = new List<ToolStripMenuItem> (); + private static bool activated_by_keyboard; + + #region Private Constructor + private ToolStripManager () + { + } + #endregion + + #region Public Properties + public static ToolStripRenderer Renderer { + get { return ToolStripManager.renderer; } + set { + if (ToolStripManager.Renderer != value) { + ToolStripManager.renderer = value; + ToolStripManager.OnRendererChanged (EventArgs.Empty); + } + } + } + + public static ToolStripManagerRenderMode RenderMode { + get { return ToolStripManager.render_mode; } + set { + if (!Enum.IsDefined (typeof (ToolStripManagerRenderMode), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripManagerRenderMode", value)); + + if (ToolStripManager.render_mode != value) { + ToolStripManager.render_mode = value; + + switch (value) { + case ToolStripManagerRenderMode.Custom: + throw new NotSupportedException (); + case ToolStripManagerRenderMode.System: + ToolStripManager.Renderer = new ToolStripSystemRenderer (); + break; + case ToolStripManagerRenderMode.Professional: + ToolStripManager.Renderer = new ToolStripProfessionalRenderer (); + break; + } + } + } + } + + public static bool VisualStylesEnabled { + get { return ToolStripManager.visual_styles_enabled; } + set { + if (ToolStripManager.visual_styles_enabled != value) { + ToolStripManager.visual_styles_enabled = value; + + if (ToolStripManager.render_mode == ToolStripManagerRenderMode.Professional) { + (ToolStripManager.renderer as ToolStripProfessionalRenderer).ColorTable.UseSystemColors = !value; + ToolStripManager.OnRendererChanged (EventArgs.Empty); + } + } + } + } + #endregion + + #region Public Methods + public static ToolStrip FindToolStrip (string toolStripName) + { + lock (toolstrips) + foreach (WeakReference wr in toolstrips) { + ToolStrip ts = (ToolStrip)wr.Target; + + if (ts == null) + continue; + + if (ts.Name == toolStripName) + return ts; + } + + return null; + } + + public static bool IsShortcutDefined (Keys shortcut) + { + lock (menu_items) + foreach (ToolStripMenuItem tsmi in menu_items) + if (tsmi.ShortcutKeys == shortcut) + return true; + + return false; + } + + public static bool IsValidShortcut (Keys shortcut) + { + // Anything with an F1 - F12 is a shortcut + if ((shortcut & Keys.F1) == Keys.F1) + return true; + else if ((shortcut & Keys.F2) == Keys.F2) + return true; + else if ((shortcut & Keys.F3) == Keys.F3) + return true; + else if ((shortcut & Keys.F4) == Keys.F4) + return true; + else if ((shortcut & Keys.F5) == Keys.F5) + return true; + else if ((shortcut & Keys.F6) == Keys.F6) + return true; + else if ((shortcut & Keys.F7) == Keys.F7) + return true; + else if ((shortcut & Keys.F8) == Keys.F8) + return true; + else if ((shortcut & Keys.F9) == Keys.F9) + return true; + else if ((shortcut & Keys.F10) == Keys.F10) + return true; + else if ((shortcut & Keys.F11) == Keys.F11) + return true; + else if ((shortcut & Keys.F12) == Keys.F12) + return true; + + // Modifier keys alone are not shortcuts + switch (shortcut) { + case Keys.Alt: + case Keys.Widget: + case Keys.Shift: + case Keys.Alt | Keys.Widget: + case Keys.Alt | Keys.Shift: + case Keys.Widget | Keys.Shift: + case Keys.Alt | Keys.Widget | Keys.Shift: + return false; + } + + // Anything else with a modifier key is a shortcut + if ((shortcut & Keys.Alt) == Keys.Alt) + return true; + else if ((shortcut & Keys.Widget) == Keys.Widget) + return true; + else if ((shortcut & Keys.Shift) == Keys.Shift) + return true; + + // Anything else is not a shortcut + return false; + } + + [MonoTODO ("Stub, does nothing")] + public static void LoadSettings (Form targetForm) + { + if (targetForm == null) + throw new ArgumentNullException ("targetForm"); + } + + [MonoTODO ("Stub, does nothing")] + public static void LoadSettings (Form targetForm, string key) + { + if (targetForm == null) + throw new ArgumentNullException ("targetForm"); + if (string.IsNullOrEmpty (key)) + throw new ArgumentNullException ("key"); + } + + [MonoLimitation ("Only supports one level of merging, cannot merge the same ToolStrip multiple times")] + public static bool Merge (ToolStrip sourceToolStrip, string targetName) + { + if (string.IsNullOrEmpty (targetName)) + throw new ArgumentNullException ("targetName"); + + return Merge (sourceToolStrip, FindToolStrip (targetName)); + } + + [MonoLimitation ("Only supports one level of merging, cannot merge the same ToolStrip multiple times")] + public static bool Merge (ToolStrip sourceToolStrip, ToolStrip targetToolStrip) + { + // Check for exceptions + if (sourceToolStrip == null) + throw new ArgumentNullException ("sourceToolStrip"); + + if (targetToolStrip == null) + throw new ArgumentNullException ("targetName"); + + if (targetToolStrip == sourceToolStrip) + throw new ArgumentException ("Source and target ToolStrip must be different."); + + // If the toolstrips don't allow merging, don't merge them + if (!sourceToolStrip.AllowMerge || !targetToolStrip.AllowMerge) + return false; + + // We currently can't support merging multiple times + if (sourceToolStrip.IsCurrentlyMerged || targetToolStrip.IsCurrentlyMerged) + return false; + + // What I wouldn't give to be able to modify a collection + // while enumerating through it... + + List<ToolStripItem> items_to_move = new List<ToolStripItem> (); + + // Create a list of every ToolStripItem we plan on moving + foreach (ToolStripItem tsi in sourceToolStrip.Items) { + switch (tsi.MergeAction) { + case MergeAction.Append: + default: + items_to_move.Add (tsi); + break; + case MergeAction.Insert: + if (tsi.MergeIndex >= 0) + items_to_move.Add (tsi); + break; + case MergeAction.Replace: + case MergeAction.Remove: + case MergeAction.MatchOnly: + foreach (ToolStripItem target_tsi in targetToolStrip.Items) + if (tsi.Text == target_tsi.Text) { + items_to_move.Add (tsi); + break; + } + break; + } + } + + // If there was nothing valid to merge, return false + if (items_to_move.Count == 0) + return false; + + // Set some state so we can unmerge later + sourceToolStrip.BeginMerge (); + targetToolStrip.BeginMerge (); + + sourceToolStrip.SuspendLayout (); + targetToolStrip.SuspendLayout (); + + while (items_to_move.Count > 0) { + ToolStripItem tsi = items_to_move[0]; + items_to_move.Remove (tsi); + + switch (tsi.MergeAction) { + case MergeAction.Append: + default: + // Just changing the parent will append it to the target + // and remove it from the source + ToolStrip.SetItemParent (tsi, targetToolStrip); + + break; + case MergeAction.Insert: + // Do the same work as Append, except Insert it into the + // location specified by the MergeIndex + RemoveItemFromParentToolStrip (tsi); + + if (tsi.MergeIndex == -1) + continue; + else if (tsi.MergeIndex >= CountRealToolStripItems (targetToolStrip)) + targetToolStrip.Items.AddNoOwnerOrLayout (tsi); + else + targetToolStrip.Items.InsertNoOwnerOrLayout (AdjustItemMergeIndex (targetToolStrip, tsi), tsi); + + tsi.Parent = targetToolStrip; + + break; + case MergeAction.Replace: + // Find a target ToolStripItem with the same Text, remove it + // and replace it with the source one + foreach (ToolStripItem target_tsi in targetToolStrip.Items) + if (tsi.Text == target_tsi.Text) { + RemoveItemFromParentToolStrip (tsi); + + // Insert where the old one is, then remove the old one + targetToolStrip.Items.InsertNoOwnerOrLayout (targetToolStrip.Items.IndexOf (target_tsi), tsi); + targetToolStrip.Items.RemoveNoOwnerOrLayout (target_tsi); + + // Store the replaced one so we can get it back in unmerge + targetToolStrip.HiddenMergedItems.Add (target_tsi); + break; + } + + break; + case MergeAction.Remove: + // Find a target ToolStripItem with the same Text, and remove + // it from the target, nothing else + foreach (ToolStripItem target_tsi in targetToolStrip.Items) + if (tsi.Text == target_tsi.Text) { + targetToolStrip.Items.RemoveNoOwnerOrLayout (target_tsi); + + // Store the removed one so we can get it back in unmerge + targetToolStrip.HiddenMergedItems.Add (target_tsi); + break; + } + + break; + case MergeAction.MatchOnly: + // Ugh, find the target ToolStripItem with the same Text, and take + // all the subitems from the source one, and append it to the target one + foreach (ToolStripItem target_tsi in targetToolStrip.Items) + if (tsi.Text == target_tsi.Text) { + if (target_tsi is ToolStripMenuItem && tsi is ToolStripMenuItem) { + ToolStripMenuItem source = (ToolStripMenuItem)tsi; + ToolStripMenuItem target = (ToolStripMenuItem)target_tsi; + + ToolStripManager.Merge (source.DropDown, target.DropDown); + } + + break; + } + + break; + } + } + + sourceToolStrip.ResumeLayout (); + targetToolStrip.ResumeLayout (); + + // Store who we merged with, so we can unmerge when only given the target toolstrip + sourceToolStrip.CurrentlyMergedWith = targetToolStrip; + targetToolStrip.CurrentlyMergedWith = sourceToolStrip; + + return true; + } + + public static bool RevertMerge (string targetName) + { + return RevertMerge (FindToolStrip (targetName)); + } + + public static bool RevertMerge (ToolStrip targetToolStrip) + { + if (targetToolStrip == null) + return false; + + return RevertMerge (targetToolStrip, targetToolStrip.CurrentlyMergedWith); + } + + public static bool RevertMerge (ToolStrip targetToolStrip, ToolStrip sourceToolStrip) + { + if (sourceToolStrip == null) + return false; + + List<ToolStripItem> items_to_move = new List<ToolStripItem> (); + + // Find every ToolStripItem who's Owner is the source toolstrip + // - If it's a TSMI, see if any of the subitems need to be moved back + foreach (ToolStripItem tsi in targetToolStrip.Items) { + if (tsi.Owner == sourceToolStrip) + items_to_move.Add (tsi); + else if (tsi is ToolStripMenuItem) + foreach (ToolStripItem menuitem in (tsi as ToolStripMenuItem).DropDownItems) + foreach (ToolStripMenuItem tsmi in sourceToolStrip.Items) + if (menuitem.Owner == tsmi.DropDown) + items_to_move.Add (menuitem); + } + + // If we didn't find anything, return false + if (items_to_move.Count == 0 && targetToolStrip.HiddenMergedItems.Count == 0) + return false; + + // Put back all the target's items removed in the merge + while (targetToolStrip.HiddenMergedItems.Count > 0) { + targetToolStrip.RevertMergeItem (targetToolStrip.HiddenMergedItems[0]); + targetToolStrip.HiddenMergedItems.RemoveAt (0); + } + + sourceToolStrip.SuspendLayout (); + targetToolStrip.SuspendLayout (); + + // Revert everything + while (items_to_move.Count > 0) { + sourceToolStrip.RevertMergeItem (items_to_move[0]); + items_to_move.Remove (items_to_move[0]); + } + + sourceToolStrip.ResumeLayout (); + targetToolStrip.ResumeLayout (); + + sourceToolStrip.IsCurrentlyMerged = false; + targetToolStrip.IsCurrentlyMerged = false; + + sourceToolStrip.CurrentlyMergedWith = null; + targetToolStrip.CurrentlyMergedWith = null; + + return true; + } + + public static void SaveSettings (Form sourceForm) + { + if (sourceForm == null) + throw new ArgumentNullException ("sourceForm"); + } + + public static void SaveSettings (Form sourceForm, string key) + { + if (sourceForm == null) + throw new ArgumentNullException ("sourceForm"); + if (string.IsNullOrEmpty (key)) + throw new ArgumentNullException ("key"); + } + #endregion + + #region Public Events + public static event EventHandler RendererChanged; + #endregion + + #region Private/Internal Methods + internal static bool ActivatedByKeyboard { + get { return activated_by_keyboard; } + set { activated_by_keyboard = value; } + } + + internal static void AddToolStrip (ToolStrip ts) + { + lock (toolstrips) + toolstrips.Add (new WeakReference (ts)); + } + + // When we have merged in MDI items like the min/max/close buttons, we + // can't count them for the sake of menu merging or it will mess up + // where people are trying to put them + private static int AdjustItemMergeIndex (ToolStrip ts, ToolStripItem tsi) + { + if (ts.Items[0] is MdiWidgetStrip.SystemMenuItem) + return tsi.MergeIndex + 1; + + return tsi.MergeIndex; + } + + private static int CountRealToolStripItems (ToolStrip ts) + { + int count = 0; + + foreach (ToolStripItem tsi in ts.Items) + if (!(tsi is MdiWidgetStrip.WidgetBoxMenuItem) && !(tsi is MdiWidgetStrip.SystemMenuItem)) + count++; + + return count; + } + + internal static ToolStrip GetNextToolStrip (ToolStrip ts, bool forward) + { + lock (toolstrips) { + List<ToolStrip> tools = new List<ToolStrip> (); + + foreach (WeakReference wr in toolstrips) { + ToolStrip t = (ToolStrip)wr.Target; + + if (t != null) + tools.Add (t); + } + + int index = tools.IndexOf (ts); + + if (forward) { + // Look for any toolstrip after this one in the collection + for (int i = index + 1; i < tools.Count; i++) + if (tools[i].TopLevelWidget == ts.TopLevelWidget && !(tools[i] is StatusStrip)) + return tools[i]; + + // Look for any toolstrip before this one in the collection + for (int i = 0; i < index; i++) + if (tools[i].TopLevelWidget == ts.TopLevelWidget && !(tools[i] is StatusStrip)) + return tools[i]; + } else { + // Look for any toolstrip before this one in the collection + for (int i = index - 1; i >= 0; i--) + if (tools[i].TopLevelWidget == ts.TopLevelWidget && !(tools[i] is StatusStrip)) + return tools[i]; + + // Look for any toolstrip after this one in the collection + for (int i = tools.Count - 1; i > index; i--) + if (tools[i].TopLevelWidget == ts.TopLevelWidget && !(tools[i] is StatusStrip)) + return tools[i]; + } + } + + return null; + } + + internal static bool ProcessCmdKey (ref Message m, Keys keyData) + { + lock (menu_items) + foreach (ToolStripMenuItem tsmi in menu_items) + if (tsmi.ProcessCmdKey (ref m, keyData) == true) + return true; + + return false; + } + + internal static bool ProcessMenuKey (ref Message m) + { + // If we have a currently active menu, deactivate it + if (Application.KeyboardCapture != null) { + if (Application.KeyboardCapture.OnMenuKey ()) + return true; + } + + // Get the parent form of this message + Form f = (Form)Widget.FromHandle (m.HWnd).TopLevelWidget; + + // If there isn't a Form with this, there isn't much we can do + if (f == null) + return false; + + // Check the MainMenuStrip property first + if (f.MainMenuStrip != null) + if (f.MainMenuStrip.OnMenuKey ()) + return true; + + // Look for any MenuStrip in the form + lock (toolstrips) + foreach (WeakReference wr in toolstrips) { + ToolStrip ts = (ToolStrip)wr.Target; + + if (ts == null) + continue; + + if (ts.TopLevelWidget == f) + if (ts.OnMenuKey ()) + return true; + } + + return false; + } + + internal static void SetActiveToolStrip (ToolStrip toolStrip, bool keyboard) + { + if (Application.KeyboardCapture != null) + Application.KeyboardCapture.KeyboardActive = false; + + if (toolStrip == null) { + activated_by_keyboard = false; + return; + } + + activated_by_keyboard = keyboard; + + toolStrip.KeyboardActive = true; + } + + internal static void AddToolStripMenuItem (ToolStripMenuItem tsmi) + { + lock (menu_items) + menu_items.Add (tsmi); + } + + internal static void RemoveToolStrip (ToolStrip ts) + { + lock (toolstrips) { + foreach (WeakReference wr in toolstrips) + if (wr.Target == ts) { + toolstrips.Remove (wr); + return; + } + } + } + + internal static void RemoveToolStripMenuItem (ToolStripMenuItem tsmi) + { + lock (menu_items) + menu_items.Remove (tsmi); + } + + internal static void FireAppClicked () + { + if (AppClicked != null) AppClicked (null, EventArgs.Empty); + + if (Application.KeyboardCapture != null) + Application.KeyboardCapture.Dismiss (ToolStripDropDownCloseReason.AppClicked); + } + + internal static void FireAppFocusChanged (Form form) + { + if (AppFocusChange != null) AppFocusChange (form, EventArgs.Empty); + + if (Application.KeyboardCapture != null) + Application.KeyboardCapture.Dismiss (ToolStripDropDownCloseReason.AppFocusChange); + } + + internal static void FireAppFocusChanged (object sender) + { + if (AppFocusChange != null) AppFocusChange (sender, EventArgs.Empty); + + if (Application.KeyboardCapture != null) + Application.KeyboardCapture.Dismiss (ToolStripDropDownCloseReason.AppFocusChange); + } + + private static void OnRendererChanged (EventArgs e) + { + if (RendererChanged != null) RendererChanged (null, e); + } + + private static void RemoveItemFromParentToolStrip (ToolStripItem tsi) + { + if (tsi.Owner != null) { + tsi.Owner.Items.RemoveNoOwnerOrLayout (tsi); + + if (tsi.Owner is ToolStripOverflow) + (tsi.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (tsi); + } + } + + internal static event EventHandler AppClicked; + internal static event EventHandler AppFocusChange; + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripManagerRenderMode.cs b/source/ShiftUI/ToolStrip/ToolStripManagerRenderMode.cs new file mode 100644 index 0000000..d8f008b --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripManagerRenderMode.cs @@ -0,0 +1,41 @@ +// +// ToolStripManagerRenderMode.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.ComponentModel; + +namespace ShiftUI +{ + public enum ToolStripManagerRenderMode + { + [Browsable (false)] + Custom = 0, + + System = 1, + Professional = 2 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripMenuItem.cs b/source/ShiftUI/ToolStrip/ToolStripMenuItem.cs new file mode 100644 index 0000000..1b83dee --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripMenuItem.cs @@ -0,0 +1,548 @@ +// +// ToolStripMenuItem.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; +using System.ComponentModel.Design.Serialization; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.MenuStrip | ToolStripItemDesignerAvailability.ContextMenuStrip)] + //[DesignerSerializer ("ShiftUI.Design.ToolStripMenuItemCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)] + public class ToolStripMenuItem : ToolStripDropDownItem + { + private CheckState checked_state; + private bool check_on_click; + private bool close_on_mouse_release; + private string shortcut_display_string; + private Keys shortcut_keys = Keys.None; + private bool show_shortcut_keys = true; + private Form mdi_client_form; + + #region Public Constructors + public ToolStripMenuItem () + : this (null, null, null, string.Empty) + { + } + + public ToolStripMenuItem (Image image) + : this (null, image, null, string.Empty) + { + } + + public ToolStripMenuItem (string text) + : this (text, null, null, string.Empty) + { + } + + public ToolStripMenuItem (string text, Image image) + : this (text, image, null, string.Empty) + { + } + + public ToolStripMenuItem (string text, Image image, EventHandler onClick) + : this (text, image, onClick, string.Empty) + { + } + + public ToolStripMenuItem (string text, Image image, params ToolStripItem[] dropDownItems) + : this (text, image, null, string.Empty) + { + if (dropDownItems != null) + foreach (ToolStripItem tsi in dropDownItems) + this.DropDownItems.Add (tsi); + } + + public ToolStripMenuItem (string text, Image image, EventHandler onClick, Keys shortcutKeys) + : this (text, image, onClick, string.Empty) + { + } + + public ToolStripMenuItem (string text, Image image, EventHandler onClick, string name) + : base (text, image, onClick, name) + { + base.Overflow = ToolStripItemOverflow.Never; + } + #endregion + + #region Public Properties + [Bindable (true)] + [DefaultValue (false)] + [RefreshProperties (RefreshProperties.All)] + public bool Checked { + get { + switch (this.checked_state) { + case CheckState.Unchecked: + default: + return false; + case CheckState.Checked: + case CheckState.Indeterminate: + return true; + } + } + set { + CheckState = value ? CheckState.Checked : CheckState.Unchecked; + } + } + + [DefaultValue (false)] + public bool CheckOnClick { + get { return this.check_on_click; } + set { + if (this.check_on_click != value) { + this.check_on_click = value; + OnUIACheckOnClickChangedEvent (EventArgs.Empty); + } + } + } + + [Bindable (true)] + [DefaultValue (CheckState.Unchecked)] + [RefreshProperties (RefreshProperties.All)] + public CheckState CheckState { + get { return this.checked_state; } + set + { + if (!Enum.IsDefined (typeof (CheckState), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for CheckState", value)); + + if (value == checked_state) + return; + + this.checked_state = value; + this.Invalidate (); + this.OnCheckedChanged (EventArgs.Empty); + this.OnCheckStateChanged (EventArgs.Empty); + } + } + + public override bool Enabled { + get { return base.Enabled; } + set { base.Enabled = value; } + } + + [Browsable (false)] + public bool IsMdiWindowListEntry { + get { return this.mdi_client_form != null; } + } + + [DefaultValue (ToolStripItemOverflow.Never)] + public new ToolStripItemOverflow Overflow { + get { return base.Overflow; } + set { base.Overflow = value; } + } + + [Localizable (true)] + [DefaultValue (true)] + public bool ShowShortcutKeys { + get { return this.show_shortcut_keys; } + set { this.show_shortcut_keys = value; } + } + + [Localizable (true)] + [DefaultValue (null)] + public string ShortcutKeyDisplayString { + get { return this.shortcut_display_string; } + set { this.shortcut_display_string = value; } + } + + [Localizable (true)] + [DefaultValue (Keys.None)] + public Keys ShortcutKeys { + get { return this.shortcut_keys; } + set { + if (this.shortcut_keys != value) { + this.shortcut_keys = value; + + if (this.Parent != null) + ToolStripManager.AddToolStripMenuItem (this); + } + } + } + #endregion + + #region Protected Properties + protected internal override Padding DefaultMargin { + get { return new Padding (0); } + } + + protected override Padding DefaultPadding { + get { return new Padding (4, 0, 4, 0); } + } + + protected override Size DefaultSize { + get { return new Size (32, 19); } + } + #endregion + + #region Protected Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripMenuItemAccessibleObject (); + } + + protected override ToolStripDropDown CreateDefaultDropDown () + { + ToolStripDropDownMenu tsddm = new ToolStripDropDownMenu (); + tsddm.OwnerItem = this; + return tsddm; + } + + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + } + + protected virtual void OnCheckedChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [CheckedChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnCheckStateChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [CheckStateChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected override void OnClick (EventArgs e) + { + if (!this.Enabled) + return; + + if (this.HasDropDownItems) { + base.OnClick (e); + return; + } + + if (this.OwnerItem is ToolStripDropDownItem) + (this.OwnerItem as ToolStripDropDownItem).OnDropDownItemClicked (new ToolStripItemClickedEventArgs (this)); + + if (this.IsOnDropDown) { + ToolStrip ts = this.GetTopLevelToolStrip (); + + if (ts != null) + ts.Dismiss (ToolStripDropDownCloseReason.ItemClicked); + } + + if (this.IsMdiWindowListEntry) { + this.mdi_client_form.MdiParent.MdiContainer.ActivateChild (this.mdi_client_form); + return; + } + + if (this.check_on_click) + this.Checked = !this.Checked; + + base.OnClick (e); + + if (!this.IsOnDropDown && !this.HasDropDownItems) { + ToolStrip ts = this.GetTopLevelToolStrip (); + + if (ts != null) + ts.Dismiss (ToolStripDropDownCloseReason.ItemClicked); + } + } + + protected override void OnDropDownHide (EventArgs e) + { + base.OnDropDownHide (e); + } + + protected override void OnDropDownShow (EventArgs e) + { + base.OnDropDownShow (e); + } + + protected override void OnFontChanged (EventArgs e) + { + base.OnFontChanged (e); + } + + protected override void OnMouseDown (MouseEventArgs e) + { + if (!this.IsOnDropDown && this.HasDropDownItems && this.DropDown.Visible) + this.close_on_mouse_release = true; + + if (Enabled && !this.DropDown.Visible) + this.ShowDropDown (); + + base.OnMouseDown (e); + } + + protected override void OnMouseEnter (EventArgs e) + { + if (this.IsOnDropDown && this.HasDropDownItems && Enabled) + this.ShowDropDown (); + + base.OnMouseEnter (e); + } + + protected override void OnMouseLeave (EventArgs e) + { + base.OnMouseLeave (e); + } + + protected override void OnMouseUp (MouseEventArgs e) + { + if (this.close_on_mouse_release) { + this.Parent.Dismiss (ToolStripDropDownCloseReason.ItemClicked); + this.Invalidate (); + this.close_on_mouse_release = false; + } + + if (!this.HasDropDownItems && Enabled) + base.OnMouseUp (e); + } + + protected override void OnOwnerChanged (EventArgs e) + { + base.OnOwnerChanged (e); + } + + protected override void OnPaint (ShiftUI.PaintEventArgs e) + { + base.OnPaint (e); + + // Can't render without an owner + if (this.Owner == null) + return; + + // If DropDown.ShowImageMargin is false, we don't display the image + Image draw_image = this.UseImageMargin ? this.Image : null; + + // Disable this color detection until we do the color detection for ToolStrip *completely* + // Color font_color = this.ForeColor == SystemColors.ControlText ? SystemColors.MenuText : this.ForeColor; + Color font_color = ForeColor; + + if ((this.Selected || this.Pressed) && this.IsOnDropDown && font_color == SystemColors.MenuText) + font_color = SystemColors.HighlightText; + + if (!this.Enabled && this.ForeColor == SystemColors.ControlText) + font_color = SystemColors.GrayText; + + // Gray stuff out if we're disabled + draw_image = this.Enabled ? draw_image : ToolStripRenderer.CreateDisabledImage (draw_image); + + // Draw our background + this.Owner.Renderer.DrawMenuItemBackground (new ToolStripItemRenderEventArgs (e.Graphics, this)); + + // Figure out where our text and image go + Rectangle text_layout_rect; + Rectangle image_layout_rect; + + this.CalculateTextAndImageRectangles (out text_layout_rect, out image_layout_rect); + + if (this.IsOnDropDown) { + if (!this.UseImageMargin) { + image_layout_rect = Rectangle.Empty; + text_layout_rect = new Rectangle (8, text_layout_rect.Top, text_layout_rect.Width, text_layout_rect.Height); + } else { + text_layout_rect = new Rectangle (35, text_layout_rect.Top, text_layout_rect.Width, text_layout_rect.Height); + + if (image_layout_rect != Rectangle.Empty) + image_layout_rect = new Rectangle (new Point (4, 3), base.GetImageSize ()); + } + + if (this.Checked && this.ShowMargin) + this.Owner.Renderer.DrawItemCheck (new ToolStripItemImageRenderEventArgs (e.Graphics, this, new Rectangle (2, 1, 19, 19))); + } + if (text_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemText (new ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign)); + + string key_string = GetShortcutDisplayString (); + + if (!string.IsNullOrEmpty (key_string) && !this.HasDropDownItems) { + int offset = 15; + Size key_string_size = TextRenderer.MeasureText (key_string, this.Font); + Rectangle key_string_rect = new Rectangle (this.ContentRectangle.Right - key_string_size.Width - offset, text_layout_rect.Top, key_string_size.Width, text_layout_rect.Height); + this.Owner.Renderer.DrawItemText (new ToolStripItemTextRenderEventArgs (e.Graphics, this, key_string, key_string_rect, font_color, this.Font, this.TextAlign)); + } + + if (image_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemImage (new ToolStripItemImageRenderEventArgs (e.Graphics, this, draw_image, image_layout_rect)); + + if (this.IsOnDropDown && this.HasDropDownItems && this.Parent is ToolStripDropDownMenu) + this.Owner.Renderer.DrawArrow (new ToolStripArrowRenderEventArgs (e.Graphics, this, new Rectangle (this.Bounds.Width - 17, 2, 10, 20), Color.Black, ArrowDirection.Right)); + + return; + } + + protected internal override bool ProcessCmdKey (ref Message m, Keys keyData) + { + Widget source = Widget.FromHandle (m.HWnd); + Form f = source == null ? null : (Form)source.TopLevelWidget; + + if (this.Enabled && keyData == this.shortcut_keys && GetTopLevelWidget () == f) { + this.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click); + return true; + } + + return base.ProcessCmdKey (ref m, keyData); + } + + Widget GetTopLevelWidget () + { + ToolStripItem item = this; + while (item.OwnerItem != null) + item = item.OwnerItem; + + if (item.Owner == null) + return null; + + if (item.Owner is ContextMenuStrip) { + Widget container = ((ContextMenuStrip)item.Owner).container; + return container == null ? null : container.TopLevelWidget; + } + + // MainMenuStrip + return item.Owner.TopLevelWidget; + } + + protected internal override bool ProcessMnemonic (char charCode) + { + if (!this.Selected) + this.Parent.ChangeSelection (this); + + if (this.HasDropDownItems) { + ToolStripManager.SetActiveToolStrip (this.Parent, true); + this.ShowDropDown (); + this.DropDown.SelectNextToolStripItem (null, true); + } else + this.PerformClick (); + + return true; + } + + protected internal override void SetBounds (Rectangle rect) + { + base.SetBounds (rect); + } + #endregion + + #region Public Events + static object CheckedChangedEvent = new object (); + static object CheckStateChangedEvent = new object (); + + public event EventHandler CheckedChanged { + add { Events.AddHandler (CheckedChangedEvent, value); } + remove {Events.RemoveHandler (CheckedChangedEvent, value); } + } + + public event EventHandler CheckStateChanged { + add { Events.AddHandler (CheckStateChangedEvent, value); } + remove {Events.RemoveHandler (CheckStateChangedEvent, value); } + } + #endregion + + #region UIA Framework Events + static object UIACheckOnClickChangedEvent = new object (); + + internal event EventHandler UIACheckOnClickChanged { + add { Events.AddHandler (UIACheckOnClickChangedEvent, value); } + remove { Events.RemoveHandler (UIACheckOnClickChangedEvent, value); } + } + + internal void OnUIACheckOnClickChangedEvent (EventArgs args) + { + EventHandler eh + = (EventHandler) Events [UIACheckOnClickChangedEvent]; + if (eh != null) + eh (this, args); + } + #endregion + + #region Internal Properties + internal Form MdiClientForm { + get { return this.mdi_client_form; } + set { this.mdi_client_form = value; } + } + #endregion + + #region Internal Methods + internal override Size CalculatePreferredSize (Size constrainingSize) + { + Size base_size = base.CalculatePreferredSize (constrainingSize); + + string key_string = GetShortcutDisplayString (); + + if (string.IsNullOrEmpty (key_string)) + return base_size; + + Size text_size = TextRenderer.MeasureText (key_string, this.Font); + + return new Size (base_size.Width + text_size.Width - 25, base_size.Height); + } + + internal string GetShortcutDisplayString () + { + if (this.show_shortcut_keys == false) + return string.Empty; + if (this.Parent == null || !(this.Parent is ToolStripDropDownMenu)) + return string.Empty; + + string key_string = string.Empty; + + if (!string.IsNullOrEmpty (this.shortcut_display_string)) + key_string = this.shortcut_display_string; + else if (this.shortcut_keys != Keys.None) { + KeysConverter kc = new KeysConverter (); + key_string = kc.ConvertToString (this.shortcut_keys); + } + + return key_string; + } + + internal void HandleAutoExpansion () + { + if (this.HasDropDownItems) { + this.ShowDropDown (); + this.DropDown.SelectNextToolStripItem (null, true); + } + } + + internal override void HandleClick (int mouse_clicks, EventArgs e) + { + this.OnClick (e); + + if (Parent != null) + Parent.Invalidate (); + } + #endregion + + #region ToolStripMenuItemAccessibleObject + private class ToolStripMenuItemAccessibleObject : AccessibleObject + { + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripOverflow.cs b/source/ShiftUI/ToolStrip/ToolStripOverflow.cs new file mode 100644 index 0000000..3e8fd92 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripOverflow.cs @@ -0,0 +1,151 @@ +// +// ToolStripOverflow.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Drawing; +using ShiftUI.Layout; + +namespace ShiftUI +{ + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDispatch)] + public class ToolStripOverflow : ToolStripDropDown, IComponent, IDisposable + { + private LayoutEngine layout_engine; + + #region Public Constructors + public ToolStripOverflow (ToolStripItem parentItem) + { + this.OwnerItem = parentItem; + } + #endregion + + #region Public Properties + // XXX - This probably adds ToolStripOverflowButton to the returned collection + public override ToolStripItemCollection Items { + get { return base.Items; } + } + + public override LayoutEngine LayoutEngine { + get { + if (this.layout_engine == null) + this.layout_engine = new FlowLayout (); + + return base.LayoutEngine; + } + } + #endregion + + #region Protected Properties + protected internal override ToolStripItemCollection DisplayedItems { + get { return base.DisplayedItems; } + } + #endregion + + #region Public Methods + public override Size GetPreferredSize (Size constrainingSize) + { + return base.GetToolStripPreferredSize (constrainingSize); + } + #endregion + + #region Protected Methods + protected override AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripOverflowAccessibleObject (); + } + + [MonoInternalNote ("This should stack in rows of ~3, but for now 1 column will work.")] + protected override void OnLayout (LayoutEventArgs e) + { + SetDisplayedItems (); + + // Find the widest menu item + int widest = 0; + + foreach (ToolStripItem tsi in this.DisplayedItems) { + if (!tsi.Available) + continue; + if (tsi.GetPreferredSize (Size.Empty).Width > widest) + widest = tsi.GetPreferredSize (Size.Empty).Width; + } + + int x = this.Padding.Left; + widest += this.Padding.Horizontal; + int y = this.Padding.Top; + + foreach (ToolStripItem tsi in this.DisplayedItems) { + if (!tsi.Available) + continue; + + y += tsi.Margin.Top; + + int height = 0; + + if (tsi is ToolStripSeparator) + height = 7; + else + height = tsi.GetPreferredSize (Size.Empty).Height; + + tsi.SetBounds (new Rectangle (x, y, widest, height)); + y += tsi.Height + tsi.Margin.Bottom; + } + + this.Size = new Size (widest + this.Padding.Horizontal, y + this.Padding.Bottom);// + 2); + } + + protected override void SetDisplayedItems () + { + this.displayed_items.ClearInternal (); + + if (this.OwnerItem != null && this.OwnerItem.Parent != null) + foreach (ToolStripItem tsi in this.OwnerItem.Parent.Items) + if (tsi.Placement == ToolStripItemPlacement.Overflow && tsi.Available && !(tsi is ToolStripSeparator)) { + this.displayed_items.AddNoOwnerOrLayout (tsi); + //tsi.Parent = this; + } + + this.PerformLayout (); + } + #endregion + + #region Internal Methods + internal ToolStrip ParentToolStrip { + get { return (ToolStrip)this.OwnerItem.Parent; } + } + #endregion + + #region ToolStripOverflowAccessibleObject Class + private class ToolStripOverflowAccessibleObject : AccessibleObject + { + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripOverflowButton.cs b/source/ShiftUI/ToolStrip/ToolStripOverflowButton.cs new file mode 100644 index 0000000..f9415ed --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripOverflowButton.cs @@ -0,0 +1,113 @@ +// +// ToolStripOverflowButton.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Drawing; +using ShiftUI.Design; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.None)] + public class ToolStripOverflowButton : ToolStripDropDownButton + { + #region Internal Constructor + internal ToolStripOverflowButton (ToolStrip ts) + { + this.InternalOwner = ts; + this.Parent = ts; + this.Visible = false; + } + #endregion + + #region Public Properties + public override bool HasDropDownItems { + get { + if (this.drop_down == null) + return false; + + return this.DropDown.DisplayedItems.Count > 0; + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool RightToLeftAutoMirrorImage { + get { return base.RightToLeftAutoMirrorImage; } + set { base.RightToLeftAutoMirrorImage = value; } + } + #endregion + + #region Protected Properties + protected internal override Padding DefaultMargin { + get { return new Padding (0, 1, 0, 2); } + } + #endregion + + #region Public Methods + public override Size GetPreferredSize (Size constrainingSize) + { + return new Size (16, this.Parent.Height); + } + #endregion + + #region Protected Methods + protected override AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripOverflowButtonAccessibleObject (); + } + + protected override ToolStripDropDown CreateDefaultDropDown () + { + ToolStripDropDown tsdd = new ToolStripOverflow (this); + tsdd.DefaultDropDownDirection = ToolStripDropDownDirection.BelowLeft; + tsdd.OwnerItem = this; + return tsdd; + } + + protected override void OnPaint (PaintEventArgs e) + { + if (this.Owner != null) + this.Owner.Renderer.DrawOverflowButtonBackground (new ToolStripItemRenderEventArgs (e.Graphics, this)); + } + + protected internal override void SetBounds (Rectangle bounds) + { + base.SetBounds (bounds); + } + #endregion + + #region ToolStripOverflowButtonAccessibleObject Class + private class ToolStripOverflowButtonAccessibleObject : AccessibleObject + { + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripPanel.cs b/source/ShiftUI/ToolStrip/ToolStripPanel.cs new file mode 100644 index 0000000..86def53 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripPanel.cs @@ -0,0 +1,618 @@ +// +// ToolStripPanel.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using ShiftUI.Layout; +using System; + +namespace ShiftUI +{ + [ComVisible (true)] + [ToolboxBitmap ("")] + [ClassInterface (ClassInterfaceType.AutoDispatch)] + //[Designer ("ShiftUI.Design.ToolStripPanelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + public class ToolStripPanel : ContainerWidget, IComponent, IDisposable, IBindableComponent, IDropTarget + { + private bool done_first_layout; + private LayoutEngine layout_engine; + private bool locked; + private Orientation orientation; + private ToolStripRenderer renderer; + private ToolStripRenderMode render_mode; + private Padding row_margin; + private ToolStripPanelRowCollection rows; + + public ToolStripPanel () : base () + { + base.AutoSize = true; + this.locked = false; + this.renderer = null; + this.render_mode = ToolStripRenderMode.ManagerRenderMode; + this.row_margin = new Padding (3, 0, 0, 0); + this.rows = new ToolStripPanelRowCollection (this); + } + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override bool AllowDrop { + get { return base.AllowDrop; } + set { base.AllowDrop = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override bool AutoScroll { + get { return base.AutoScroll; } + set { base.AutoScroll = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMargin { + get { return base.AutoScrollMargin; } + set { base.AutoScrollMargin = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMinSize { + get { return base.AutoScrollMinSize; } + set { base.AutoScrollMinSize = value; } + } + + [DefaultValue (true)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)] + public override bool AutoSize { + get { return base.AutoSize; } + set { base.AutoSize = value; } + } + + public override DockStyle Dock { + get { return base.Dock; } + set { + base.Dock = value; + + switch (value) { + case DockStyle.Top: + case DockStyle.Bottom: + case DockStyle.None: + this.orientation = Orientation.Horizontal; + break; + case DockStyle.Left: + case DockStyle.Right: + this.orientation = Orientation.Vertical; + break; + } + } + } + + public override LayoutEngine LayoutEngine { + get { + if (this.layout_engine == null) + this.layout_engine = new FlowLayout (); + + return this.layout_engine; + } + } + + [Browsable (false)] + [DefaultValue (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public bool Locked { + get { return this.locked; } + set { this.locked = value; } + } + + public Orientation Orientation { + get { return this.orientation; } + set { this.orientation = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ToolStripRenderer Renderer { + get { + if (this.render_mode == ToolStripRenderMode.ManagerRenderMode) + return ToolStripManager.Renderer; + + return this.renderer; + } + set { + if (this.renderer != value) { + this.renderer = value; + this.render_mode = ToolStripRenderMode.Custom; + this.OnRendererChanged (EventArgs.Empty); + } + } + } + + public ToolStripRenderMode RenderMode { + get { return this.render_mode; } + set { + if (!Enum.IsDefined (typeof (ToolStripRenderMode), value)) + throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value)); + + if (value == ToolStripRenderMode.Custom && this.renderer == null) + throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom"); + if (value == ToolStripRenderMode.Professional || value == ToolStripRenderMode.System) + this.Renderer = new ToolStripProfessionalRenderer (); + + this.render_mode = value; + } + } + + public Padding RowMargin { + get { return this.row_margin; } + set { this.row_margin = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ToolStripPanelRow[] Rows { + get { + ToolStripPanelRow[] retval = new ToolStripPanelRow [this.rows.Count]; + this.rows.CopyTo (retval, 0); + return retval; + } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new int TabIndex { + get { return base.TabIndex; } + set { base.TabIndex = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool TabStop { + get { return base.TabStop; } + set { base.TabStop = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override string Text { + get { return base.Text; } + set { base.Text = value; } + } + #endregion + + #region Protected Properties + protected override Padding DefaultMargin { + get { return new Padding (0); } + } + + protected override Padding DefaultPadding { + get { return new Padding (0); } + } + #endregion + + #region Public Methods + public void BeginInit () + { + } + + public void EndInit () + { + } + + [MonoTODO("Not implemented")] + public void Join (ToolStrip toolStripToDrag) + { + if (!Contains (toolStripToDrag)) + Widgets.Add (toolStripToDrag); + } + + [MonoTODO("Not implemented")] + public void Join (ToolStrip toolStripToDrag, int row) + { + Join (toolStripToDrag); + } + + [MonoTODO("Not implemented")] + public void Join (ToolStrip toolStripToDrag, Point location) + { + Join (toolStripToDrag); + } + + [MonoTODO("Not implemented")] + public void Join (ToolStrip toolStripToDrag, int x, int y) + { + Join (toolStripToDrag); + } + + public ToolStripPanelRow PointToRow (Point clientLocation) + { + foreach (ToolStripPanelRow row in this.rows) + if (row.Bounds.Contains (clientLocation)) + return row; + + return null; + } + #endregion + + #region Protected Methods + protected override WidgetCollection CreateWidgetsInstance () + { + return new ToolStripPanelWidgetCollection (this); + } + + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + } + + protected override void OnWidgetAdded (WidgetEventArgs e) + { + if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right) + (e.Widget as ToolStrip).LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow; + else + (e.Widget as ToolStrip).LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow; + + if (done_first_layout && e.Widget is ToolStrip) + this.AddWidgetToRows (e.Widget); + + base.OnWidgetAdded (e); + } + + protected override void OnWidgetRemoved (WidgetEventArgs e) + { + base.OnWidgetRemoved (e); + + foreach (ToolStripPanelRow row in this.rows) + if (row.Widgets.Contains (e.Widget)) + row.OnWidgetRemoved (e.Widget, 0); + } + + protected override void OnDockChanged (EventArgs e) + { + base.OnDockChanged (e); + } + + protected override void OnLayout (LayoutEventArgs e) + { + // Don't see any reason to layout if we aren't created + if (!this.Created) + return; + + // The first time through, we have to layout everything where it belongs. + // The key is that when we resize and stuff, we don't resize or move toolstrips. + if (!done_first_layout) { + ArrayList al = new ArrayList (this.Widgets); + al.Sort (new TabIndexComparer ()); + + foreach (ToolStrip ts in al) + this.AddWidgetToRows (ts); + + done_first_layout = true; + } + + // Lay out all the rows + Point position = this.DisplayRectangle.Location; + + if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right) { + foreach (ToolStripPanelRow row in this.rows) { + row.SetBounds (new Rectangle (position, new Size (row.Bounds.Width, this.Height))); + + position.X += row.Bounds.Width; + } + + // Find how big we are so we can autosize ourself + if (this.rows.Count > 0) { + int last_row_right = this.rows[this.rows.Count - 1].Bounds.Right; + + if (last_row_right != this.Width) + this.SetBounds (bounds.X, bounds.Y, last_row_right, bounds.Bottom); + } + } else { + foreach (ToolStripPanelRow row in this.rows) { + row.SetBounds (new Rectangle (position, new Size (this.Width, row.Bounds.Height))); + + position.Y += row.Bounds.Height; + } + + // Find how big we are so we can autosize ourself + if (this.rows.Count > 0) { + int last_row_bottom = this.rows[this.rows.Count - 1].Bounds.Bottom; + + if (last_row_bottom != this.Height) + this.SetBounds (bounds.X, bounds.Y, bounds.Width, last_row_bottom); + } + } + + this.Invalidate (); + + return; + } + + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override void OnPaintBackground (PaintEventArgs e) + { + base.OnPaintBackground (e); + + this.Renderer.DrawToolStripPanelBackground (new ToolStripPanelRenderEventArgs (e.Graphics, this)); + } + + protected override void OnParentChanged (EventArgs e) + { + base.OnParentChanged (e); + } + + protected virtual void OnRendererChanged (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [RendererChangedEvent]); + if (eh != null) + eh (this, e); + } + + protected override void OnRightToLeftChanged (EventArgs e) + { + base.OnRightToLeftChanged (e); + } + #endregion + + #region Public Events + static object RendererChangedEvent = new object (); + + [Browsable (true)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public new event EventHandler AutoSizeChanged { + add { base.AutoSizeChanged += value; } + remove { base.AutoSizeChanged -= value; } + } + + public event EventHandler RendererChanged { + add { Events.AddHandler (RendererChangedEvent, value); } + remove { Events.RemoveHandler (RendererChangedEvent, value); } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TabIndexChanged { + add { base.TabIndexChanged += value; } + remove { base.TabIndexChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TabStopChanged { + add { base.TabStopChanged += value; } + remove { base.TabStopChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TextChanged { + add { base.TextChanged += value; } + remove { base.TextChanged -= value; } + } + #endregion + + #region Private Methods + + private void AddWidgetToRows (Widget Widget) + { + if (this.rows.Count > 0) + if (this.rows[this.rows.Count - 1].CanMove ((ToolStrip)Widget)) { + this.rows[this.rows.Count - 1].OnWidgetAdded (Widget, 0); + return; + } + + ToolStripPanelRow new_row = new ToolStripPanelRow (this); + + if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right) + new_row.SetBounds (new Rectangle (0, 0, 25, this.Height)); + else + new_row.SetBounds (new Rectangle (0, 0, this.Width, 25)); + + this.rows.Add (new_row); + new_row.OnWidgetAdded (Widget, 0); + } + /* + private Region FindBackgroundRegion () + { + Region r = new Region (this.Bounds); + + foreach (Widget c in this.Widgets) + r.Exclude (c.Bounds); + + return r; + } + */ + #endregion + + #region Nested Classes + [ComVisible (false)] + [ListBindable (false)] + public class ToolStripPanelRowCollection : ArrangedElementCollection, IList, ICollection, IEnumerable + { + //private ToolStripPanel owner; + + public ToolStripPanelRowCollection (ToolStripPanel owner) : base () + { + //this.owner = owner; + } + + public ToolStripPanelRowCollection (ToolStripPanel owner, ToolStripPanelRow[] value) : this (owner) + { + if (value != null) + foreach (ToolStripPanelRow tspr in value) + this.Add (tspr); + } + + public new virtual ToolStripPanelRow this [int index] { + get { return (ToolStripPanelRow)base[index]; } + } + + #region Public Methods + public int Add (ToolStripPanelRow value) + { + return base.Add (value); + } + + public void AddRange (ToolStripPanelRowCollection value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + foreach (ToolStripPanelRow tspr in value) + this.Add (tspr); + } + + public void AddRange (ToolStripPanelRow[] value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + foreach (ToolStripPanelRow tspr in value) + this.Add (tspr); + } + + public new virtual void Clear () + { + base.Clear (); + } + + public bool Contains (ToolStripPanelRow value) + { + return base.Contains (value); + } + + public void CopyTo (ToolStripPanelRow[] array, int index) + { + base.CopyTo (array, index); + } + + public int IndexOf (ToolStripPanelRow value) + { + return base.IndexOf (value); + } + + public void Insert (int index, ToolStripPanelRow value) + { + base.Insert (index, value); + } + + public void Remove (ToolStripPanelRow value) + { + base.Remove (value); + } + + public void RemoveAt (int index) + { + base.InternalRemoveAt (index); + } + #endregion + + #region IList Members + object IList.this [int index] { + get { return this [index]; } + [MonoTODO ("Stub, does nothing")] + set { } + } + + bool IList.IsFixedSize { + get { return IsFixedSize; } + } + + bool IList.IsReadOnly { + get { return IsReadOnly; } + } + + int IList.Add (object value) + { + return Add (value as ToolStripPanelRow); + } + + void IList.Clear () + { + Clear (); + } + + bool IList.Contains (object value) + { + return Contains (value as ToolStripPanelRow); + } + + int IList.IndexOf (object value) + { + return IndexOf (value as ToolStripPanelRow); + } + + void IList.Insert (int index, object value) + { + Insert (index, value as ToolStripPanelRow); + } + + void IList.Remove (object value) + { + Remove (value as ToolStripPanelRow); + } + + void IList.RemoveAt (int index) + { + base.InternalRemoveAt (index); + } + #endregion + } + + private class ToolStripPanelWidgetCollection : WidgetCollection + { + public ToolStripPanelWidgetCollection (Widget owner) : base (owner) + { + } + } + + private class TabIndexComparer : IComparer + { + #region IComparer Members + public int Compare (object x, object y) + { + if (!(x is Widget) || !(y is Widget)) + throw new ArgumentException (); + + return (x as Widget).TabIndex - (y as Widget).TabIndex; + } + #endregion + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripPanelRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripPanelRenderEventArgs.cs new file mode 100644 index 0000000..88fceaf --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripPanelRenderEventArgs.cs @@ -0,0 +1,62 @@ +// +// ToolStripPanelRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System; + +namespace ShiftUI +{ + public class ToolStripPanelRenderEventArgs : EventArgs + { + private Graphics graphics; + private bool handled; + private ToolStripPanel tool_strip_panel; + + public ToolStripPanelRenderEventArgs (Graphics g, ToolStripPanel toolStripPanel) + { + this.graphics = g; + this.tool_strip_panel = toolStripPanel; + this.handled = false; + } + + #region Public Properties + public Graphics Graphics { + get { return this.graphics; } + } + + public bool Handled { + get { return this.handled; } + set { this.handled = value; } + } + + public ToolStripPanel ToolStripPanel { + get { return this.tool_strip_panel; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripPanelRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripPanelRenderEventHandler.cs new file mode 100644 index 0000000..ecf71ed --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripPanelRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripPanelRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripPanelRenderEventHandler (object sender, ToolStripPanelRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripPanelRow.cs b/source/ShiftUI/ToolStrip/ToolStripPanelRow.cs new file mode 100644 index 0000000..ae2e8a8 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripPanelRow.cs @@ -0,0 +1,227 @@ +// +// ToolStripPanelRow.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.Runtime.InteropServices; +using System.ComponentModel; +using ShiftUI.Layout; +using System.Collections.Generic; +using System; + +namespace ShiftUI +{ + [ToolboxItem (false)] + public class ToolStripPanelRow : Component, IComponent, IDisposable, IBounds + { + private Rectangle bounds; + internal List<Widget> _Widgets; + private LayoutEngine layout_engine; + private Padding margin; + private Padding padding; + private ToolStripPanel parent; + + #region Public Constructors + public ToolStripPanelRow (ToolStripPanel parent) + { + this.bounds = Rectangle.Empty; + this._Widgets = new List<Widget> (); + this.layout_engine = new DefaultLayout (); + this.parent = parent; + } + #endregion + + #region Public Properties + public Rectangle Bounds { + get { return this.bounds; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public List<Widget> Widgets { + get { return this._Widgets; } + } + + public Rectangle DisplayRectangle { + get { return this.Bounds; } + } + + public LayoutEngine LayoutEngine { + get { + if (this.layout_engine == null) + this.layout_engine = new DefaultLayout (); + + return this.layout_engine; + } + } + + public Padding Margin { + get { return this.margin; } + set { this.margin = value; } + } + + public Orientation Orientation { + get { return this.parent.Orientation; } + } + + public virtual Padding Padding { + get { return this.padding; } + set { this.padding = value; } + } + + public ToolStripPanel ToolStripPanel { + get { return this.parent; } + } + #endregion + + #region Protected Properties + protected virtual Padding DefaultMargin { get { return Padding.Empty; } } + protected virtual Padding DefaultPadding { get { return Padding.Empty; } } + #endregion + + #region Public Methods + public bool CanMove (ToolStrip toolStripToDrag) + { + // If something uses Stretch, it gets a whole Row to itself + if (this.Widgets.Count > 0) + if (toolStripToDrag.Stretch || (this.Widgets[0] as ToolStrip).Stretch) + return false; + + int width = 0; + + foreach (ToolStrip ts in this.Widgets) + width += (ts.Width + ts.Margin.Horizontal); + + if (width + toolStripToDrag.Width + toolStripToDrag.Margin.Horizontal <= this.bounds.Width) + return true; + + return false; + } + #endregion + + #region Protected Methods + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + } + + protected void OnBoundsChanged (Rectangle oldBounds, Rectangle newBounds) + { + } + + protected internal virtual void OnWidgetAdded (Widget Widget, int index) + { + Widget.SizeChanged += new EventHandler (Widget_SizeChanged); + Widgets.Add (Widget); + this.OnLayout (new LayoutEventArgs (Widget, string.Empty)); + } + + protected internal virtual void OnWidgetRemoved (Widget Widget, int index) + { + Widget.SizeChanged -= new EventHandler (Widget_SizeChanged); + Widgets.Remove (Widget); + this.OnLayout (new LayoutEventArgs (Widget, string.Empty)); + } + + protected virtual void OnLayout (LayoutEventArgs e) + { + int height = 0; + + if (this.Orientation == Orientation.Horizontal) { + foreach (ToolStrip ts in this.Widgets) + if (ts.Height > height) + height = ts.Height; + + if (height != this.bounds.Height) + this.bounds.Height = height; + } else { + foreach (ToolStrip ts in this.Widgets) + if (ts.GetPreferredSize (Size.Empty).Width > height) + height = ts.GetPreferredSize (Size.Empty).Width; + + if (height != this.bounds.Width) + this.bounds.Width = height; + } + + this.Layout (this, e); + } + + protected internal virtual void OnOrientationChanged () + { + } + #endregion + + #region Private/Internal Methods + internal void SetBounds (Rectangle bounds) + { + if (this.bounds != bounds) { + Rectangle old_bounds = this.bounds; + this.bounds = bounds; + this.OnBoundsChanged (old_bounds, bounds); + this.OnLayout (new LayoutEventArgs (null, "Bounds")); + } + } + + private bool Layout (object container, LayoutEventArgs args) + { + ToolStripPanelRow tspr = (ToolStripPanelRow)container; + Point position = tspr.DisplayRectangle.Location; + foreach (ToolStrip ts in tspr.Widgets) + { + if (Orientation == Orientation.Horizontal) { + if (ts.Stretch) + ts.Width = this.bounds.Width - ts.Margin.Horizontal - this.Padding.Horizontal; + else + ts.Width = ts.GetToolStripPreferredSize (Size.Empty).Width; + + position.X += ts.Margin.Left; + ts.Location = position; + + position.X += (ts.Width + ts.Margin.Left); + } else { + if (ts.Stretch) + ts.Size = new Size (ts.GetToolStripPreferredSize (Size.Empty).Width, this.bounds.Height - ts.Margin.Vertical - this.Padding.Vertical); + else + ts.Size = ts.GetToolStripPreferredSize (Size.Empty); + + position.Y += ts.Margin.Top; + ts.Location = position; + + position.Y += (ts.Height + ts.Margin.Top); + } + } + + return false; + } + + void Widget_SizeChanged (object sender, EventArgs e) + { + this.OnLayout (new LayoutEventArgs ((Widget)sender, string.Empty)); + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripProfessionalRenderer.cs b/source/ShiftUI/ToolStrip/ToolStripProfessionalRenderer.cs new file mode 100644 index 0000000..018d02b --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripProfessionalRenderer.cs @@ -0,0 +1,470 @@ +// +// ToolStripProfessionalRenderer.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; + +namespace ShiftUI +{ + public class ToolStripProfessionalRenderer : ToolStripRenderer + { + private ProfessionalColorTable color_table; + private bool rounded_edges; + + #region Public Constructor + public ToolStripProfessionalRenderer () : this (new ProfessionalColorTable ()) + { + } + + public ToolStripProfessionalRenderer (ProfessionalColorTable professionalColorTable) : base () + { + color_table = professionalColorTable; + rounded_edges = true; + } + #endregion + + #region Public Properties + public ProfessionalColorTable ColorTable { + get { return this.color_table; } + } + + public bool RoundedEdges { + get { return this.rounded_edges; } + set { this.rounded_edges = value; } + } + #endregion + + #region Protected Methods + protected override void OnRenderArrow (ToolStripArrowRenderEventArgs e) + { + base.OnRenderArrow (e); + } + + protected override void OnRenderButtonBackground (ToolStripItemRenderEventArgs e) + { + if (e.Item.Enabled == false) + return; + + Rectangle paint_here = new Rectangle (0, 0, e.Item.Width, e.Item.Height); + + // Paint gradient background + if (e.Item is ToolStripButton && (e.Item as ToolStripButton).Checked && !e.Item.Selected) { + if (this.ColorTable.UseSystemColors) + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.ButtonCheckedHighlight), paint_here); + else + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonCheckedGradientBegin, this.ColorTable.ButtonCheckedGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); } + else + if (e.Item is ToolStripDropDownItem && e.Item.Pressed) // || (e.Item as ToolStripMenuItem).DropDown.Visible == true)) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ToolStripGradientBegin, this.ColorTable.ToolStripGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + else if (e.Item.Pressed || (e.Item is ToolStripButton && (e.Item as ToolStripButton).Checked)) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonPressedGradientBegin, this.ColorTable.ButtonPressedGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + else if (e.Item.Selected) // && !e.Item.Pressed) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonSelectedGradientBegin, this.ColorTable.ButtonSelectedGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty) + using (Brush b = new SolidBrush (e.Item.BackColor)) + e.Graphics.FillRectangle (b, paint_here); + + paint_here.Width -= 1; + paint_here.Height -= 1; + + // Paint border + if (e.Item.Selected && !e.Item.Pressed) + using (Pen p = new Pen (this.ColorTable.ButtonSelectedBorder)) + e.Graphics.DrawRectangle (p, paint_here); + else if (e.Item.Pressed) + using (Pen p = new Pen (this.ColorTable.ButtonPressedBorder)) + e.Graphics.DrawRectangle (p, paint_here); + else if (e.Item is ToolStripButton && (e.Item as ToolStripButton).Checked) + using (Pen p = new Pen (this.ColorTable.ButtonPressedBorder)) + e.Graphics.DrawRectangle (p, paint_here); + + base.OnRenderButtonBackground (e); + } + + protected override void OnRenderDropDownButtonBackground (ToolStripItemRenderEventArgs e) + { + Rectangle paint_here = new Rectangle (0, 0, e.Item.Width, e.Item.Height); + + // Paint gradient background + if (e.Item.Selected && !e.Item.Pressed) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonSelectedGradientBegin, this.ColorTable.ButtonSelectedGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + else if (e.Item.Pressed) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ImageMarginGradientMiddle, this.ColorTable.ImageMarginGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + + paint_here.Width -= 1; + paint_here.Height -= 1; + + // Paint border + if (e.Item.Selected && !e.Item.Pressed) + using (Pen p = new Pen (this.ColorTable.ButtonSelectedBorder)) + e.Graphics.DrawRectangle (p, paint_here); + else if (e.Item.Pressed) + using (Pen p = new Pen (this.ColorTable.MenuBorder)) + e.Graphics.DrawRectangle (p, paint_here); + + base.OnRenderDropDownButtonBackground (e); + } + + protected override void OnRenderGrip (ToolStripGripRenderEventArgs e) + { + if (e.GripStyle == ToolStripGripStyle.Hidden) + return; + + if (e.GripDisplayStyle == ToolStripGripDisplayStyle.Vertical) { + Rectangle r = new Rectangle (e.GripBounds.Left, e.GripBounds.Top + 5, 2, 2); + + for (int i = 0; i < e.GripBounds.Height - 12; i += 4) { + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.GripLight), r); + r.Offset (0, 4); + } + + Rectangle r2 = new Rectangle (e.GripBounds.Left - 1, e.GripBounds.Top + 4, 2, 2); + + for (int i = 0; i < e.GripBounds.Height - 12; i += 4) { + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.GripDark), r2); + r2.Offset (0, 4); + } + } + else { + Rectangle r = new Rectangle (e.GripBounds.Left + 5, e.GripBounds.Top, 2, 2); + + for (int i = 0; i < e.GripBounds.Width - 11; i += 4) { + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.GripLight), r); + r.Offset (4, 0); + } + + Rectangle r2 = new Rectangle (e.GripBounds.Left + 4, e.GripBounds.Top - 1, 2, 2); + + for (int i = 0; i < e.GripBounds.Width - 11; i += 4) { + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.GripDark), r2); + r2.Offset (4, 0); + } + } + + base.OnRenderGrip (e); + } + + protected override void OnRenderImageMargin (ToolStripRenderEventArgs e) + { + if (!(e.ToolStrip is ToolStripOverflow)) { + Rectangle side_gradient = new Rectangle (1, 2, 24, e.ToolStrip.Height - 3); + using (LinearGradientBrush b = new LinearGradientBrush (side_gradient, this.ColorTable.ToolStripGradientBegin, this.ColorTable.ToolStripGradientEnd, LinearGradientMode.Horizontal)) + e.Graphics.FillRectangle (b, side_gradient); + } + + base.OnRenderImageMargin (e); + } + + protected override void OnRenderItemCheck (ToolStripItemImageRenderEventArgs e) + { + if (e.Item.Selected) + { + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.CheckPressedBackground), e.ImageRectangle); + e.Graphics.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (this.ColorTable.ButtonPressedBorder), e.ImageRectangle); + } + else if (e.Item.Pressed) + { + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.CheckSelectedBackground), e.ImageRectangle); + e.Graphics.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (this.ColorTable.ButtonSelectedBorder), e.ImageRectangle); + } + else + { + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.CheckSelectedBackground), e.ImageRectangle); + e.Graphics.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (this.ColorTable.ButtonSelectedBorder), e.ImageRectangle); + } + if (e.Item.Image == null) + WidgetPaint.DrawMenuGlyph(e.Graphics, new Rectangle (6,5,7,6), MenuGlyph.Checkmark); + + base.OnRenderItemCheck (e); + } + + protected override void OnRenderItemImage (ToolStripItemImageRenderEventArgs e) + { + base.OnRenderItemImage (e); + } + + protected override void OnRenderItemText (ToolStripItemTextRenderEventArgs e) + { + base.OnRenderItemText (e); + } + + protected override void OnRenderLabelBackground (ToolStripItemRenderEventArgs e) + { + base.OnRenderLabelBackground (e); + } + + protected override void OnRenderMenuItemBackground (ToolStripItemRenderEventArgs e) + { + ToolStripMenuItem tsmi = (ToolStripMenuItem)e.Item; + Rectangle paint_here; + + if (tsmi.IsOnDropDown) { + paint_here = new Rectangle (1, 0, e.Item.Bounds.Width - 3, e.Item.Bounds.Height - 1); + + if (e.Item.Selected || e.Item.Pressed) + if (e.Item.Enabled) + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.MenuItemSelectedGradientEnd), paint_here); + + if (tsmi.Selected || tsmi.Pressed) + using (Pen p = new Pen (this.ColorTable.MenuItemBorder)) + e.Graphics.DrawRectangle (p, paint_here); + } + else { + paint_here = new Rectangle (0, 0, e.Item.Width, e.Item.Height); + + if (e.Item.Pressed) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ToolStripGradientBegin, this.ColorTable.ToolStripGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + else if (e.Item.Selected) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonSelectedGradientBegin, this.ColorTable.ButtonSelectedGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty) + using (Brush b = new SolidBrush (e.Item.BackColor)) + e.Graphics.FillRectangle (b, paint_here); + + paint_here.Width -= 1; + paint_here.Height -= 1; + + if (tsmi.Selected || tsmi.Pressed) { + if (tsmi.HasDropDownItems && tsmi.DropDown.Visible) + using (Pen p = new Pen (this.ColorTable.MenuBorder)) + e.Graphics.DrawRectangle (p, paint_here); + else + using (Pen p = new Pen (this.ColorTable.MenuItemBorder)) + e.Graphics.DrawRectangle (p, paint_here); + } + } + + base.OnRenderMenuItemBackground (e); + } + + protected override void OnRenderOverflowButtonBackground (ToolStripItemRenderEventArgs e) + { + Rectangle paint_here; + LinearGradientMode gradient_direction = e.ToolStrip.Orientation == Orientation.Vertical ? LinearGradientMode.Horizontal : LinearGradientMode.Vertical; + + if (e.ToolStrip.Orientation == Orientation.Horizontal) + paint_here = new Rectangle (e.Item.Width - 11, 0, 11, e.Item.Height - 1); + else + paint_here = new Rectangle (0, e.Item.Height - 11, e.Item.Width - 1, 11); + + // Paint gradient background + if (e.Item.Selected && !e.Item.Pressed) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonSelectedGradientBegin, this.ColorTable.ButtonSelectedGradientEnd, gradient_direction)) + e.Graphics.FillRectangle (b, paint_here); + else if (e.Item.Pressed) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonPressedGradientBegin, this.ColorTable.ButtonPressedGradientEnd, gradient_direction)) + e.Graphics.FillRectangle (b, paint_here); + else + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.OverflowButtonGradientBegin, this.ColorTable.OverflowButtonGradientEnd, gradient_direction)) + e.Graphics.FillRectangle (b, paint_here); + + // Paint the arrow + PaintOverflowArrow (e, paint_here); + + base.OnRenderOverflowButtonBackground (e); + } + + protected override void OnRenderSeparator (ToolStripSeparatorRenderEventArgs e) + { + if (e.Vertical) { + Rectangle r = new Rectangle (4, 6, 1, e.Item.Height - 10); + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.SeparatorLight), r); + + Rectangle r2 = new Rectangle (3, 5, 1, e.Item.Height - 10); + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.SeparatorDark), r2); + } + else { + if (!e.Item.IsOnDropDown) { + Rectangle r = new Rectangle (6, 4, e.Item.Width - 10, 1); + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.SeparatorLight), r); + } + + Rectangle r3; + if (e.Item.IsOnDropDown) { + if (e.Item.UseImageMargin) + r3 = new Rectangle (35, 3, e.Item.Width - 36, 1); + else + r3 = new Rectangle (7, 3, e.Item.Width - 7, 1); + } else + r3 = new Rectangle (5, 3, e.Item.Width - 10, 1); + + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (this.ColorTable.SeparatorDark), r3); + } + + base.OnRenderSeparator (e); + } + + protected override void OnRenderSplitButtonBackground (ToolStripItemRenderEventArgs e) + { + ToolStripSplitButton tssb = (ToolStripSplitButton)e.Item; + Rectangle paint_here = new Rectangle (0, 0, tssb.Width, tssb.Height); + Rectangle button_part = new Rectangle (0, 0, tssb.ButtonBounds.Width, tssb.ButtonBounds.Height); + + // Paint gradient background + if (tssb.ButtonSelected && !tssb.DropDownButtonPressed) + using (Brush b = new LinearGradientBrush (paint_here, this.ColorTable.ButtonSelectedGradientBegin, this.ColorTable.ButtonSelectedGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, paint_here); + if (tssb.ButtonPressed) + using (Brush b = new LinearGradientBrush (button_part, this.ColorTable.ButtonPressedGradientBegin, this.ColorTable.ButtonPressedGradientEnd, LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, button_part); + + paint_here.Width -= 1; + paint_here.Height -= 1; + + // Paint border + if (e.Item.Selected && !tssb.DropDownButtonPressed) + using (Pen p = new Pen (this.ColorTable.ButtonSelectedBorder)) + { + e.Graphics.DrawRectangle (p, paint_here); + e.Graphics.DrawLine (p, button_part.Right, 0, button_part.Right, button_part.Height); + } + else if (e.Item.Pressed) + using (Pen p = new Pen (this.ColorTable.MenuBorder)) + e.Graphics.DrawRectangle (p, paint_here); + + base.OnRenderSplitButtonBackground (e); + } + + protected override void OnRenderToolStripBackground (ToolStripRenderEventArgs e) + { + // Don't clear and fill the background if we already painted an image there + if (e.ToolStrip.BackgroundImage != null) { + if (e.ToolStrip is StatusStrip) + e.Graphics.DrawLine (Pens.White, e.AffectedBounds.Left, e.AffectedBounds.Top, e.AffectedBounds.Right, e.AffectedBounds.Top); + + return; + } + + if (e.ToolStrip is ToolStripDropDown) { + e.Graphics.Clear (this.ColorTable.ToolStripDropDownBackground); + return; + } + + if (e.ToolStrip is MenuStrip || e.ToolStrip is StatusStrip) { + using (LinearGradientBrush b = new LinearGradientBrush (e.AffectedBounds, this.ColorTable.MenuStripGradientBegin, this.ColorTable.MenuStripGradientEnd, e.ToolStrip.Orientation == Orientation.Horizontal ? LinearGradientMode.Horizontal : LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, e.AffectedBounds); + } + else + using (LinearGradientBrush b = new LinearGradientBrush (e.AffectedBounds, this.ColorTable.ToolStripGradientBegin, this.ColorTable.ToolStripGradientEnd, e.ToolStrip.Orientation == Orientation.Vertical ? LinearGradientMode.Horizontal : LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, e.AffectedBounds); + + if (e.ToolStrip is StatusStrip) + e.Graphics.DrawLine (Pens.White, e.AffectedBounds.Left, e.AffectedBounds.Top, e.AffectedBounds.Right, e.AffectedBounds.Top); + + base.OnRenderToolStripBackground (e); + } + + protected override void OnRenderToolStripBorder (ToolStripRenderEventArgs e) + { + if (e.ToolStrip is ToolStripDropDown) { + if (e.ToolStrip is ToolStripOverflow) + e.Graphics.DrawLines (ThemeEngine.Current.ResPool.GetPen (this.ColorTable.MenuBorder), new Point[] { e.AffectedBounds.Location, new Point (e.AffectedBounds.Left, e.AffectedBounds.Bottom - 1), new Point (e.AffectedBounds.Right - 1, e.AffectedBounds.Bottom - 1), new Point (e.AffectedBounds.Right - 1, e.AffectedBounds.Top), new Point (e.AffectedBounds.Left, e.AffectedBounds.Top) }); + else + e.Graphics.DrawLines (ThemeEngine.Current.ResPool.GetPen (this.ColorTable.MenuBorder), new Point[] { new Point (e.AffectedBounds.Left + e.ConnectedArea.Left, e.AffectedBounds.Top), e.AffectedBounds.Location, new Point (e.AffectedBounds.Left, e.AffectedBounds.Bottom - 1), new Point (e.AffectedBounds.Right - 1, e.AffectedBounds.Bottom - 1), new Point (e.AffectedBounds.Right - 1, e.AffectedBounds.Top), new Point (e.AffectedBounds.Left + e.ConnectedArea.Right, e.AffectedBounds.Top) }); + return; + } + + if (e.ToolStrip is MenuStrip || e.ToolStrip is StatusStrip) + return; + + using (Pen p = new Pen (this.ColorTable.ToolStripBorder)) { + if (this.RoundedEdges == true) { + e.Graphics.DrawLine (p, new Point (2, e.ToolStrip.Height - 1), new Point (e.ToolStrip.Width - 3, e.ToolStrip.Height - 1)); + e.Graphics.DrawLine (p, new Point (e.ToolStrip.Width - 2, e.ToolStrip.Height - 2), new Point (e.ToolStrip.Width - 1, e.ToolStrip.Height - 2)); + e.Graphics.DrawLine (p, new Point (e.ToolStrip.Width - 1, 2), new Point (e.ToolStrip.Width - 1, e.ToolStrip.Height - 3)); + } + else + e.Graphics.DrawLine (p, new Point (e.ToolStrip.Left, e.ToolStrip.Bottom - 1), new Point (e.ToolStrip.Width, e.ToolStrip.Bottom - 1)); + } + + base.OnRenderToolStripBorder (e); + } + + protected override void OnRenderToolStripContentPanelBackground (ToolStripContentPanelRenderEventArgs e) + { + base.OnRenderToolStripContentPanelBackground (e); + } + + protected override void OnRenderToolStripPanelBackground (ToolStripPanelRenderEventArgs e) + { + using (LinearGradientBrush b = new LinearGradientBrush (e.ToolStripPanel.Bounds, this.ColorTable.MenuStripGradientBegin, this.ColorTable.MenuStripGradientEnd, e.ToolStripPanel.Orientation == Orientation.Horizontal ? LinearGradientMode.Horizontal : LinearGradientMode.Vertical)) + e.Graphics.FillRectangle (b, e.ToolStripPanel.Bounds); + + base.OnRenderToolStripPanelBackground (e); + } + + protected override void OnRenderToolStripStatusLabelBackground (ToolStripItemRenderEventArgs e) + { + base.OnRenderToolStripStatusLabelBackground (e); + } + #endregion + + #region Private Methods + private static void PaintOverflowArrow (ToolStripItemRenderEventArgs e, Rectangle paint_here) + { + if (e.ToolStrip.Orientation == Orientation.Horizontal) { + // Paint down arrow + Point arrow_loc = new Point (paint_here.X + 2, paint_here.Bottom - 9); + + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 1, arrow_loc.Y + 1, arrow_loc.X + 5, arrow_loc.Y + 1); + e.Graphics.DrawLine (Pens.Black, arrow_loc.X, arrow_loc.Y, arrow_loc.X + 4, arrow_loc.Y); + + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 3, arrow_loc.Y + 4, arrow_loc.X + 5, arrow_loc.Y + 4); + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 3, arrow_loc.Y + 5, arrow_loc.X + 4, arrow_loc.Y + 5); + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 3, arrow_loc.Y + 4, arrow_loc.X + 3, arrow_loc.Y + 6); + + e.Graphics.DrawLine (Pens.Black, arrow_loc.X, arrow_loc.Y + 3, arrow_loc.X + 4, arrow_loc.Y + 3); + e.Graphics.DrawLine (Pens.Black, arrow_loc.X + 1, arrow_loc.Y + 4, arrow_loc.X + 3, arrow_loc.Y + 4); + e.Graphics.DrawLine (Pens.Black, arrow_loc.X + 2, arrow_loc.Y + 4, arrow_loc.X + 2, arrow_loc.Y + 5); + } else { + Point arrow_loc = new Point (paint_here.Right - 9, paint_here.Y + 2); + + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 1, arrow_loc.Y + 1, arrow_loc.X + 1, arrow_loc.Y + 5); + e.Graphics.DrawLine (Pens.Black, arrow_loc.X, arrow_loc.Y, arrow_loc.X, arrow_loc.Y + 4); + + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 4, arrow_loc.Y + 3, arrow_loc.X + 4, arrow_loc.Y + 5); + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 5, arrow_loc.Y + 3, arrow_loc.X + 5, arrow_loc.Y + 4); + e.Graphics.DrawLine (Pens.White, arrow_loc.X + 4, arrow_loc.Y + 3, arrow_loc.X + 6, arrow_loc.Y + 3); + + e.Graphics.DrawLine (Pens.Black, arrow_loc.X + 3, arrow_loc.Y, arrow_loc.X + 3, arrow_loc.Y + 4); + e.Graphics.DrawLine (Pens.Black, arrow_loc.X + 4, arrow_loc.Y + 1, arrow_loc.X + 4, arrow_loc.Y + 3); + e.Graphics.DrawLine (Pens.Black, arrow_loc.X + 4, arrow_loc.Y + 2, arrow_loc.X + 5, arrow_loc.Y + 2); + } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripProgressBar.cs b/source/ShiftUI/ToolStrip/ToolStripProgressBar.cs new file mode 100644 index 0000000..91ec88e --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripProgressBar.cs @@ -0,0 +1,223 @@ +// +// ToolStripProgressBar.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using System; + +namespace ShiftUI +{ + [DefaultProperty ("Value")] + public class ToolStripProgressBar : ToolStripWidgetHost + { + #region Public Constructors + public ToolStripProgressBar () : base (new ProgressBar ()) + { + } + + public ToolStripProgressBar (string name) : this () + { + this.Name = name; + } + #endregion + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Image BackgroundImage { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override ImageLayout BackgroundImageLayout { + get { return base.BackgroundImageLayout; } + set { base.BackgroundImageLayout = value; } + } + + [DefaultValue (100)] + public int MarqueeAnimationSpeed { + get { return this.ProgressBar.MarqueeAnimationSpeed; } + set { this.ProgressBar.MarqueeAnimationSpeed = value; } + } + + [DefaultValue (100)] + [RefreshProperties (RefreshProperties.Repaint)] + public int Maximum { + get { return this.ProgressBar.Maximum; } + set { this.ProgressBar.Maximum = value; } + } + + [DefaultValue (0)] + [RefreshProperties (RefreshProperties.Repaint)] + public int Minimum { + get { return this.ProgressBar.Minimum; } + set { this.ProgressBar.Minimum = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public ProgressBar ProgressBar { + get { return (ProgressBar)base.Widget; } + } + + [Localizable (true)] + [DefaultValue (false)] + public virtual bool RightToLeftLayout { + get { return this.ProgressBar.RightToLeftLayout; } + set { this.ProgressBar.RightToLeftLayout = value; } + } + + [DefaultValue (10)] + public int Step { + get { return this.ProgressBar.Step; } + set { this.ProgressBar.Step = value; } + } + + [DefaultValue (ProgressBarStyle.Blocks)] + public ProgressBarStyle Style { + get { return this.ProgressBar.Style; } + set { this.ProgressBar.Style = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override string Text { + get { return base.Text; } + set { base.Text = value; } + } + + [Bindable (true)] + [DefaultValue (0)] + public int Value { + get { return this.ProgressBar.Value; } + set { this.ProgressBar.Value = value; } + } + #endregion + + #region Protected Properties + protected internal override Padding DefaultMargin { get { return new Padding (1, 2, 1, 1); } } + protected override Size DefaultSize { get { return new Size (100, 15); } } + #endregion + + #region Public Methods + public void Increment (int value) + { + this.ProgressBar.Increment (value); + } + + public void PerformStep () + { + this.ProgressBar.PerformStep (); + } + #endregion + + #region Protected Methods + protected virtual void OnRightToLeftLayoutChanged (EventArgs e) + { + } + + protected override void OnSubscribeWidgetEvents (Widget Widget) + { + base.OnSubscribeWidgetEvents (Widget); + } + + protected override void OnUnsubscribeWidgetEvents (Widget Widget) + { + base.OnUnsubscribeWidgetEvents (Widget); + } + #endregion + + #region Public Events + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event KeyEventHandler KeyDown { + add { base.KeyDown += value; } + remove { base.KeyDown -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event KeyPressEventHandler KeyPress { + add { base.KeyPress += value; } + remove { base.KeyPress -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event KeyEventHandler KeyUp { + add { base.KeyUp += value; } + remove { base.KeyUp -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler LocationChanged { + add { base.LocationChanged += value; } + remove { base.LocationChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler OwnerChanged { + add { base.OwnerChanged += value; } + remove { base.OwnerChanged -= value; } + } + + public event EventHandler RightToLeftLayoutChanged { + add { ProgressBar.RightToLeftLayoutChanged += value; } + remove { ProgressBar.RightToLeftLayoutChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TextChanged { + add { base.TextChanged += value; } + remove { base.TextChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler Validated { + add { base.Validated += value; } + remove { base.Validated -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event CancelEventHandler Validating { + add { base.Validating += value; } + remove { base.Validating -= value; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripRenderEventArgs.cs new file mode 100644 index 0000000..2accf17 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripRenderEventArgs.cs @@ -0,0 +1,85 @@ +// +// ToolStripRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System; + +namespace ShiftUI +{ + public class ToolStripRenderEventArgs : EventArgs + { + private Rectangle affected_bounds; + private Color back_color; + private Rectangle connected_area; + private Graphics graphics; + private ToolStrip tool_strip; + + #region Public Constructors + public ToolStripRenderEventArgs (Graphics g, ToolStrip toolStrip) + : this (g, toolStrip, new Rectangle (0, 0, 100, 25), SystemColors.Control) + { + } + + public ToolStripRenderEventArgs (Graphics g, ToolStrip toolStrip, Rectangle affectedBounds, Color backColor) + { + this.graphics = g; + this.tool_strip = toolStrip; + this.affected_bounds = affectedBounds; + this.back_color = backColor; + } + #endregion + + #region Public Properties + public Rectangle AffectedBounds { + get { return this.affected_bounds; } + } + + public Color BackColor { + get { return this.back_color; } + } + + public Rectangle ConnectedArea { + get { return this.connected_area; } + } + + public Graphics Graphics { + get { return this.graphics; } + } + + public ToolStrip ToolStrip { + get { return this.tool_strip; } + } + #endregion + + #region Internal Properties + internal Rectangle InternalConnectedArea { + set { this.connected_area = value; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripRenderEventHandler.cs new file mode 100644 index 0000000..539fe3c --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripRenderEventHandler (object sender, ToolStripRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripRenderMode.cs b/source/ShiftUI/ToolStrip/ToolStripRenderMode.cs new file mode 100644 index 0000000..ada6dfc --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripRenderMode.cs @@ -0,0 +1,43 @@ +// +// ToolStripRenderMode.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +using System.ComponentModel; + +namespace ShiftUI +{ + public enum ToolStripRenderMode + { + [Browsable (false)] + Custom = 0, + + System = 1, + Professional = 2, + ManagerRenderMode = 3 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripRenderer.cs b/source/ShiftUI/ToolStrip/ToolStripRenderer.cs new file mode 100644 index 0000000..9066352 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripRenderer.cs @@ -0,0 +1,572 @@ +// +// ToolStripRenderer.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Drawing.Drawing2D; + +namespace ShiftUI +{ + public abstract class ToolStripRenderer + { + private static ColorMatrix grayscale_matrix = new ColorMatrix (new float[][] { + new float[] {0.22f, 0.22f, 0.22f, 0, 0}, + new float[] {0.27f, 0.27f, 0.27f, 0, 0}, + new float[] {0.04f, 0.04f, 0.04f, 0, 0}, + new float[] {0.365f, 0.365f, 0.365f, 0.7f, 0}, + new float[] {0, 0, 0, 0, 1} + }); + + protected ToolStripRenderer () + { + } + + #region Public Methods + public static Image CreateDisabledImage(Image normalImage) + { + if (normalImage == null) + return null; + + // Code adapted from ThemeWin32Classic.cs + ImageAttributes ia = new ImageAttributes(); + ia.SetColorMatrix (grayscale_matrix); + + Bitmap b = new Bitmap(normalImage.Width, normalImage.Height); + using (Graphics g = Graphics.FromImage(b)) + g.DrawImage(normalImage, new Rectangle (0, 0, normalImage.Width, normalImage.Height), 0, 0, normalImage.Width, normalImage.Height, GraphicsUnit.Pixel, ia); + + return b; + } + + public void DrawArrow (ToolStripArrowRenderEventArgs e) + { this.OnRenderArrow (e); } + + public void DrawButtonBackground (ToolStripItemRenderEventArgs e) + { this.OnRenderButtonBackground (e); } + + public void DrawDropDownButtonBackground (ToolStripItemRenderEventArgs e) + { this.OnRenderDropDownButtonBackground (e); } + + public void DrawGrip (ToolStripGripRenderEventArgs e) + { this.OnRenderGrip (e); } + + public void DrawImageMargin (ToolStripRenderEventArgs e) + { this.OnRenderImageMargin (e); } + + public void DrawItemBackground (ToolStripItemRenderEventArgs e) + { this.OnRenderItemBackground (e); } + + public void DrawItemCheck (ToolStripItemImageRenderEventArgs e) + { this.OnRenderItemCheck (e); } + + public void DrawItemImage (ToolStripItemImageRenderEventArgs e) + { this.OnRenderItemImage (e); } + + public void DrawItemText (ToolStripItemTextRenderEventArgs e) + { this.OnRenderItemText (e); } + + public void DrawLabelBackground (ToolStripItemRenderEventArgs e) + { this.OnRenderLabelBackground (e); } + + public void DrawMenuItemBackground (ToolStripItemRenderEventArgs e) + { this.OnRenderMenuItemBackground (e); } + + public void DrawOverflowButtonBackground (ToolStripItemRenderEventArgs e) + { this.OnRenderOverflowButtonBackground (e); } + + public void DrawSeparator (ToolStripSeparatorRenderEventArgs e) + { this.OnRenderSeparator (e); } + + public void DrawSplitButton (ToolStripItemRenderEventArgs e) + { this.OnRenderSplitButtonBackground (e); } + + public void DrawStatusStripSizingGrip (ToolStripRenderEventArgs e) + { this.OnRenderStatusStripSizingGrip (e); } + + public void DrawToolStripBackground (ToolStripRenderEventArgs e) + { this.OnRenderToolStripBackground (e); } + + public void DrawToolStripBorder (ToolStripRenderEventArgs e) + { this.OnRenderToolStripBorder (e); } + + public void DrawToolStripContentPanelBackground (ToolStripContentPanelRenderEventArgs e) + { this.OnRenderToolStripContentPanelBackground (e); } + + public void DrawToolStripPanelBackground (ToolStripPanelRenderEventArgs e) + { this.OnRenderToolStripPanelBackground (e); } + + public void DrawToolStripStatusLabelBackground (ToolStripItemRenderEventArgs e) + { this.OnRenderToolStripStatusLabelBackground (e); } + #endregion + + #region Protected Methods + protected internal virtual void Initialize (ToolStrip toolStrip) {} + protected internal virtual void InitializeContentPanel (ToolStripContentPanel contentPanel) {} + protected internal virtual void InitializeItem (ToolStripItem item) {} + protected internal virtual void InitializePanel (ToolStripPanel toolStripPanel) {} + + protected virtual void OnRenderArrow (ToolStripArrowRenderEventArgs e) + { + switch (e.Direction) { + case ArrowDirection.Down: + using (Pen p = new Pen (e.ArrowColor)) { + int x = e.ArrowRectangle.Left + (e.ArrowRectangle.Width / 2) - 3; + int y = e.ArrowRectangle.Top + (e.ArrowRectangle.Height / 2) - 2; + + DrawDownArrow (e.Graphics, p, x, y); + } + break; + case ArrowDirection.Left: + break; + case ArrowDirection.Right: + using (Pen p = new Pen (e.ArrowColor)) { + int x = e.ArrowRectangle.Left + (e.ArrowRectangle.Width / 2) - 3; + int y = e.ArrowRectangle.Top + (e.ArrowRectangle.Height / 2) - 4; + + DrawRightArrow (e.Graphics, p, x, y); + } + break; + case ArrowDirection.Up: + break; + } + + ToolStripArrowRenderEventHandler eh = (ToolStripArrowRenderEventHandler)Events[RenderArrowEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderButtonBackground (ToolStripItemRenderEventArgs e) + { + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderButtonBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderDropDownButtonBackground (ToolStripItemRenderEventArgs e) + { + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderDropDownButtonBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderGrip (ToolStripGripRenderEventArgs e) + { + ToolStripGripRenderEventHandler eh = (ToolStripGripRenderEventHandler)Events [RenderGripEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderImageMargin (ToolStripRenderEventArgs e) + { + ToolStripRenderEventHandler eh = (ToolStripRenderEventHandler)Events [RenderImageMarginEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderItemBackground (ToolStripItemRenderEventArgs e) + { + if (e.Item.BackColor != Widget.DefaultBackColor) { + // Only paint the BackColor if it's not the default one, + // to avoid painting a solid background color over the parent ToolStrip gradient. + Rectangle item_bounds = new Rectangle (0, 0, e.Item.Width, e.Item.Height); + e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (e.Item.BackColor), item_bounds); + } + + if (e.Item.BackgroundImage != null) { + Rectangle item_bounds = new Rectangle (0, 0, e.Item.Width, e.Item.Height); + DrawBackground (e.Graphics, item_bounds, e.Item.BackgroundImage, e.Item.BackgroundImageLayout); + } + + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderItemBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderItemCheck (ToolStripItemImageRenderEventArgs e) + { + ToolStripItemImageRenderEventHandler eh = (ToolStripItemImageRenderEventHandler)Events [RenderItemCheckEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderItemImage (ToolStripItemImageRenderEventArgs e) + { + bool need_dispose = false; + Image i = e.Image; + + if (e.Item.RightToLeft == RightToLeft.Yes && e.Item.RightToLeftAutoMirrorImage == true) { + i = CreateMirrorImage (i); + need_dispose = true; + } + + if (e.Item.ImageTransparentColor != Color.Empty) { + ImageAttributes ia = new ImageAttributes (); + ia.SetColorKey (e.Item.ImageTransparentColor, e.Item.ImageTransparentColor); + e.Graphics.DrawImage (i, e.ImageRectangle, 0, 0, i.Width, i.Height, GraphicsUnit.Pixel, ia); + ia.Dispose (); + } + else + e.Graphics.DrawImage (i, e.ImageRectangle); + + if (need_dispose) + i.Dispose (); + + ToolStripItemImageRenderEventHandler eh = (ToolStripItemImageRenderEventHandler)Events [RenderItemImageEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderItemText (ToolStripItemTextRenderEventArgs e) + { + if (e.TextDirection == ToolStripTextDirection.Vertical90) { + GraphicsState gs = e.Graphics.Save (); + PointF p = new PointF (e.Graphics.Transform.OffsetX, e.Graphics.Transform.OffsetY); + + e.Graphics.ResetTransform (); + e.Graphics.RotateTransform (90); + + RectangleF r = new RectangleF ((e.Item.Height - e.TextRectangle.Height) / 2, (e.TextRectangle.Width + p.X) * -1 - 18, e.TextRectangle.Height, e.TextRectangle.Width); + + StringFormat sf = new StringFormat (); + sf.Alignment = StringAlignment.Center; + + e.Graphics.DrawString (e.Text, e.TextFont, ThemeEngine.Current.ResPool.GetSolidBrush (e.TextColor), r, sf); + + e.Graphics.Restore (gs); + } else if (e.TextDirection == ToolStripTextDirection.Vertical270) { + GraphicsState gs = e.Graphics.Save (); + PointF p = new PointF (e.Graphics.Transform.OffsetX, e.Graphics.Transform.OffsetY); + + e.Graphics.ResetTransform (); + e.Graphics.RotateTransform (270); + + RectangleF r = new RectangleF (-e.TextRectangle.Height - (e.Item.Height - e.TextRectangle.Height) / 2, (e.TextRectangle.Width + p.X) + 4, e.TextRectangle.Height, e.TextRectangle.Width); + + StringFormat sf = new StringFormat (); + sf.Alignment = StringAlignment.Center; + + e.Graphics.DrawString (e.Text, e.TextFont, ThemeEngine.Current.ResPool.GetSolidBrush (e.TextColor), r, sf); + + e.Graphics.Restore (gs); + } else + TextRenderer.DrawText (e.Graphics, e.Text, e.TextFont, e.TextRectangle, e.TextColor, e.TextFormat); + + ToolStripItemTextRenderEventHandler eh = (ToolStripItemTextRenderEventHandler)Events[RenderItemTextEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderLabelBackground (ToolStripItemRenderEventArgs e) + { + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderLabelBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderMenuItemBackground (ToolStripItemRenderEventArgs e) + { + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderMenuItemBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderOverflowButtonBackground (ToolStripItemRenderEventArgs e) + { + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderOverflowButtonBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderSeparator (ToolStripSeparatorRenderEventArgs e) + { + ToolStripSeparatorRenderEventHandler eh = (ToolStripSeparatorRenderEventHandler)Events [RenderSeparatorEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderSplitButtonBackground (ToolStripItemRenderEventArgs e) + { + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderSplitButtonBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderStatusStripSizingGrip (ToolStripRenderEventArgs e) + { + StatusStrip ss = (StatusStrip)e.ToolStrip; + + if (ss.SizingGrip == true) + DrawSizingGrip (e.Graphics, ss.SizeGripBounds); + + ToolStripRenderEventHandler eh = (ToolStripRenderEventHandler)Events [RenderStatusStripSizingGripEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderToolStripBackground (ToolStripRenderEventArgs e) + { + ToolStripRenderEventHandler eh = (ToolStripRenderEventHandler)Events [RenderToolStripBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderToolStripBorder (ToolStripRenderEventArgs e) + { + ToolStripRenderEventHandler eh = (ToolStripRenderEventHandler)Events [RenderToolStripBorderEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderToolStripContentPanelBackground (ToolStripContentPanelRenderEventArgs e) + { + ToolStripContentPanelRenderEventHandler eh = (ToolStripContentPanelRenderEventHandler)Events [RenderToolStripContentPanelBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderToolStripPanelBackground (ToolStripPanelRenderEventArgs e) + { + ToolStripPanelRenderEventHandler eh = (ToolStripPanelRenderEventHandler)Events [RenderToolStripPanelBackgroundEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnRenderToolStripStatusLabelBackground (ToolStripItemRenderEventArgs e) + { + ToolStripItemRenderEventHandler eh = (ToolStripItemRenderEventHandler)Events [RenderToolStripStatusLabelBackgroundEvent]; + if (eh != null) + eh (this, e); + } + #endregion + + #region Public Events + EventHandlerList events; + + EventHandlerList Events { + get { + if (events == null) + events = new EventHandlerList (); + return events; + } + } + + static object RenderArrowEvent = new object (); + static object RenderButtonBackgroundEvent = new object (); + static object RenderDropDownButtonBackgroundEvent = new object (); + static object RenderGripEvent = new object (); + static object RenderImageMarginEvent = new object (); + static object RenderItemBackgroundEvent = new object (); + static object RenderItemCheckEvent = new object (); + static object RenderItemImageEvent = new object (); + static object RenderItemTextEvent = new object (); + static object RenderLabelBackgroundEvent = new object (); + static object RenderMenuItemBackgroundEvent = new object (); + static object RenderOverflowButtonBackgroundEvent = new object (); + static object RenderSeparatorEvent = new object (); + static object RenderSplitButtonBackgroundEvent = new object (); + static object RenderStatusStripSizingGripEvent = new object (); + static object RenderToolStripBackgroundEvent = new object (); + static object RenderToolStripBorderEvent = new object (); + static object RenderToolStripContentPanelBackgroundEvent = new object (); + static object RenderToolStripPanelBackgroundEvent = new object (); + static object RenderToolStripStatusLabelBackgroundEvent = new object (); + + public event ToolStripArrowRenderEventHandler RenderArrow { + add { Events.AddHandler (RenderArrowEvent, value); } + remove {Events.RemoveHandler (RenderArrowEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderButtonBackground { + add { Events.AddHandler (RenderButtonBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderButtonBackgroundEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderDropDownButtonBackground { + add { Events.AddHandler (RenderDropDownButtonBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderDropDownButtonBackgroundEvent, value); } + } + public event ToolStripGripRenderEventHandler RenderGrip { + add { Events.AddHandler (RenderGripEvent, value); } + remove {Events.RemoveHandler (RenderGripEvent, value); } + } + public event ToolStripRenderEventHandler RenderImageMargin { + add { Events.AddHandler (RenderImageMarginEvent, value); } + remove {Events.RemoveHandler (RenderImageMarginEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderItemBackground { + add { Events.AddHandler (RenderItemBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderItemBackgroundEvent, value); } + } + public event ToolStripItemImageRenderEventHandler RenderItemCheck { + add { Events.AddHandler (RenderItemCheckEvent, value); } + remove {Events.RemoveHandler (RenderItemCheckEvent, value); } + } + public event ToolStripItemImageRenderEventHandler RenderItemImage { + add { Events.AddHandler (RenderItemImageEvent, value); } + remove {Events.RemoveHandler (RenderItemImageEvent, value); } + } + public event ToolStripItemTextRenderEventHandler RenderItemText { + add { Events.AddHandler (RenderItemTextEvent, value); } + remove {Events.RemoveHandler (RenderItemTextEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderLabelBackground { + add { Events.AddHandler (RenderLabelBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderLabelBackgroundEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderMenuItemBackground { + add { Events.AddHandler (RenderMenuItemBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderMenuItemBackgroundEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderOverflowButtonBackground { + add { Events.AddHandler (RenderOverflowButtonBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderOverflowButtonBackgroundEvent, value); } + } + public event ToolStripSeparatorRenderEventHandler RenderSeparator { + add { Events.AddHandler (RenderSeparatorEvent, value); } + remove {Events.RemoveHandler (RenderSeparatorEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderSplitButtonBackground { + add { Events.AddHandler (RenderSplitButtonBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderSplitButtonBackgroundEvent, value); } + } + public event ToolStripRenderEventHandler RenderStatusStripSizingGrip { + add { Events.AddHandler (RenderStatusStripSizingGripEvent, value); } + remove {Events.RemoveHandler (RenderStatusStripSizingGripEvent, value); } + } + public event ToolStripRenderEventHandler RenderToolStripBackground { + add { Events.AddHandler (RenderToolStripBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderToolStripBackgroundEvent, value); } + } + public event ToolStripRenderEventHandler RenderToolStripBorder { + add { Events.AddHandler (RenderToolStripBorderEvent, value); } + remove {Events.RemoveHandler (RenderToolStripBorderEvent, value); } + } + public event ToolStripContentPanelRenderEventHandler RenderToolStripContentPanelBackground { + add { Events.AddHandler (RenderToolStripContentPanelBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderToolStripContentPanelBackgroundEvent, value); } + } + public event ToolStripPanelRenderEventHandler RenderToolStripPanelBackground { + add { Events.AddHandler (RenderToolStripPanelBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderToolStripPanelBackgroundEvent, value); } + } + public event ToolStripItemRenderEventHandler RenderToolStripStatusLabelBackground { + add { Events.AddHandler (RenderToolStripStatusLabelBackgroundEvent, value); } + remove {Events.RemoveHandler (RenderToolStripStatusLabelBackgroundEvent, value); } + } + #endregion + + #region Private Methods + internal static Image CreateMirrorImage (Image normalImage) + { + if (normalImage == null) + return null; + + Bitmap b = new Bitmap (normalImage); + b.RotateFlip (RotateFlipType.RotateNoneFlipX); + + return b; + } + + private void DrawBackground (Graphics g, Rectangle bounds, Image image, ImageLayout layout) + { + // Center and Tile don't matter if the image is larger than the Widget + if (layout == ImageLayout.Center || layout == ImageLayout.Tile) + if (image.Size.Width >= bounds.Size.Width && image.Size.Height >= bounds.Size.Height) + layout = ImageLayout.None; + + switch (layout) { + case ImageLayout.None: + g.DrawImageUnscaledAndClipped (image, bounds); + break; + case ImageLayout.Tile: + int x = 0; + int y = 0; + + while (y < bounds.Height) { + while (x < bounds.Width) { + g.DrawImageUnscaledAndClipped (image, bounds); + x += image.Width; + } + x = 0; + y += image.Height; + } + break; + case ImageLayout.Center: + Rectangle r = new Rectangle ((bounds.Size.Width - image.Size.Width) / 2, (bounds.Size.Height - image.Size.Height) / 2, image.Width, image.Height); + g.DrawImageUnscaledAndClipped (image, r); + break; + case ImageLayout.Stretch: + g.DrawImage (image, bounds); + break; + case ImageLayout.Zoom: + if (((float)image.Height / (float)image.Width) < ((float)bounds.Height / (float)bounds.Width)) { + Rectangle rzoom = new Rectangle (0, 0, bounds.Width, (int)((float)bounds.Width * ((float)image.Height / (float)image.Width))); + rzoom.Y = (bounds.Height - rzoom.Height)/ 2; + g.DrawImage (image, rzoom); + } else { + Rectangle rzoom = new Rectangle (0, 0, (int)((float)bounds.Height * ((float)image.Width / (float)image.Height)), bounds.Height); + rzoom.X = (bounds.Width - rzoom.Width) / 2; + g.DrawImage (image, rzoom); + } + break; + } + } + + internal static void DrawRightArrow (Graphics g, Pen p, int x, int y) + { + g.DrawLine (p, x, y, x, y + 6); + g.DrawLine (p, x + 1, y + 1, x + 1, y + 5); + g.DrawLine (p, x + 2, y + 2, x + 2, y + 4); + g.DrawLine (p, x + 2, y + 3, x + 3, y + 3); + } + + internal static void DrawDownArrow (Graphics g, Pen p, int x, int y) + { + g.DrawLine (p, x + 1, y, x + 5, y); + g.DrawLine (p, x + 2, y + 1, x + 4, y + 1); + g.DrawLine (p, x + 3, y + 1, x + 3, y + 2); + } + + private void DrawSizingGrip (Graphics g, Rectangle rect) + { + DrawGripBox (g, rect.Right - 5, rect.Bottom - 5); + DrawGripBox (g, rect.Right - 9, rect.Bottom - 5); + DrawGripBox (g, rect.Right - 5, rect.Bottom - 9); + DrawGripBox (g, rect.Right - 13, rect.Bottom - 5); + DrawGripBox (g, rect.Right - 5, rect.Bottom - 13); + DrawGripBox (g, rect.Right - 9, rect.Bottom - 9); + } + + private void DrawGripBox (Graphics g, int x, int y) + { + g.DrawRectangle (Pens.White, x + 1, y + 1, 1, 1); + g.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (Color.FromArgb (172, 168, 153)), x, y, 1, 1); + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripSeparator.cs b/source/ShiftUI/ToolStrip/ToolStripSeparator.cs new file mode 100644 index 0000000..3f91d8d --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripSeparator.cs @@ -0,0 +1,278 @@ +// +// ToolStripSeparator.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; +using System; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.ContextMenuStrip)] + public class ToolStripSeparator : ToolStripItem + { + public ToolStripSeparator () : base () + { + Dock = DockStyle.Fill; + } + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool AutoToolTip { + get { return base.AutoToolTip; } + set { base.AutoToolTip = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Image BackgroundImage { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override ImageLayout BackgroundImageLayout { + get { return base.BackgroundImageLayout; } + set { base.BackgroundImageLayout = value; } + } + + public override bool CanSelect { get { return false; } } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ToolStripItemDisplayStyle DisplayStyle { + get { return base.DisplayStyle; } + set { base.DisplayStyle = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool DoubleClickEnabled { + get { return base.DoubleClickEnabled; } + set { base.DoubleClickEnabled = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override bool Enabled { + get { return base.Enabled; } + set { base.Enabled = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Font Font { + get { return base.Font; } + set { base.Font = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Image Image { + get { return base.Image; } + set { base.Image = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ContentAlignment ImageAlign { + get { return base.ImageAlign; } + set { base.ImageAlign = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [RefreshProperties (RefreshProperties.Repaint)] + public new int ImageIndex { + get { return base.ImageIndex; } + set { base.ImageIndex = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new string ImageKey { + get { return base.ImageKey; } + set { base.ImageKey = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ToolStripItemImageScaling ImageScaling { + get { return base.ImageScaling; } + set { base.ImageScaling = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new Color ImageTransparentColor { + get { return base.ImageTransparentColor; } + set { base.ImageTransparentColor = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new bool RightToLeftAutoMirrorImage { + get { return base.RightToLeftAutoMirrorImage; } + set { base.RightToLeftAutoMirrorImage = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override string Text { + get { return base.Text; } + set { base.Text = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new ContentAlignment TextAlign { + get { return base.TextAlign; } + set { base.TextAlign = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + [DefaultValue (ToolStripTextDirection.Horizontal)] + public override ToolStripTextDirection TextDirection { + get { return base.TextDirection; } + set { base.TextDirection = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new TextImageRelation TextImageRelation { + get { return base.TextImageRelation; } + set { base.TextImageRelation = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public new string ToolTipText { + get { return base.ToolTipText; } + set { base.ToolTipText = value; } + } + #endregion + + #region Protected Properties + protected internal override Padding DefaultMargin { get { return new Padding(); } } + protected override Size DefaultSize { get { return new Size(6, 6); } } + #endregion + + #region Public Methods + public override Size GetPreferredSize (Size constrainingSize) + { + return new Size(6, 6); + } + #endregion + + #region Protected Methods + //[EditorBrowsable (EditorBrowsableState.Advanced)] + protected override AccessibleObject CreateAccessibilityInstance () + { + ToolStripItemAccessibleObject ao = new ToolStripItemAccessibleObject (this); + + ao.default_action = "Press"; + ao.role = AccessibleRole.Separator; + ao.state = AccessibleStates.None; + + return ao; + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + protected override void OnFontChanged (EventArgs e) + { + base.OnFontChanged (e); + } + + protected override void OnPaint (PaintEventArgs e) + { + base.OnPaint (e); + + if (this.Owner != null) + { + if (this.IsOnDropDown) + this.Owner.Renderer.DrawSeparator (new ToolStripSeparatorRenderEventArgs (e.Graphics, this, this.Owner.Orientation == Orientation.Horizontal ? false : true)); + else + this.Owner.Renderer.DrawSeparator (new ToolStripSeparatorRenderEventArgs (e.Graphics, this, this.Owner.Orientation == Orientation.Horizontal ? true : false)); + } + } + + protected internal override void SetBounds (Rectangle rect) + { + base.SetBounds (rect); + } + #endregion + + #region Public Events + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler DisplayStyleChanged { + add { base.DisplayStyleChanged += value; } + remove { base.DisplayStyleChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler EnabledChanged { + add { base.EnabledChanged += value; } + remove { base.EnabledChanged -= value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler TextChanged { + add { base.TextChanged += value; } + remove { base.TextChanged -= value; } + } + #endregion + + #region Internal Method/Properties + internal override ToolStripTextDirection DefaultTextDirection { get { return ToolStripTextDirection.Horizontal; } } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripSeparatorRenderEventArgs.cs b/source/ShiftUI/ToolStrip/ToolStripSeparatorRenderEventArgs.cs new file mode 100644 index 0000000..de46025 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripSeparatorRenderEventArgs.cs @@ -0,0 +1,49 @@ +// +// ToolStripSeparatorRenderEventArgs.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; + +namespace ShiftUI +{ + public class ToolStripSeparatorRenderEventArgs : ToolStripItemRenderEventArgs + { + private bool vertical; + + public ToolStripSeparatorRenderEventArgs (Graphics g, ToolStripSeparator separator, bool vertical) + : base (g, separator) + { + this.vertical = vertical; + } + + #region Public Properties + public bool Vertical { + get { return this.vertical; } + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripSeparatorRenderEventHandler.cs b/source/ShiftUI/ToolStrip/ToolStripSeparatorRenderEventHandler.cs new file mode 100644 index 0000000..c362bcf --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripSeparatorRenderEventHandler.cs @@ -0,0 +1,32 @@ +// +// ToolStripSeparatorRenderEventHandler.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +namespace ShiftUI +{ + public delegate void ToolStripSeparatorRenderEventHandler (object sender, ToolStripSeparatorRenderEventArgs e); +} diff --git a/source/ShiftUI/ToolStrip/ToolStripSplitButton.cs b/source/ShiftUI/ToolStrip/ToolStripSplitButton.cs new file mode 100644 index 0000000..e845b3c --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripSplitButton.cs @@ -0,0 +1,372 @@ +// +// ToolStripSplitButton.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; + +namespace ShiftUI +{ + [DefaultEvent ("ButtonClick")] + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)] + public class ToolStripSplitButton : ToolStripDropDownItem + { + private bool button_pressed; + private ToolStripItem default_item; + private bool drop_down_button_selected; + private int drop_down_button_width; + + #region Public Constructors + public ToolStripSplitButton() + : this (string.Empty, null, null, string.Empty) + { + } + + public ToolStripSplitButton (Image image) + : this (string.Empty, image, null, string.Empty) + { + } + + public ToolStripSplitButton (string text) + : this (text, null, null, string.Empty) + { + } + + public ToolStripSplitButton (string text, Image image) + : this (text, image, null, string.Empty) + { + } + + public ToolStripSplitButton (string text, Image image, EventHandler onClick) + : this (text, image, onClick, string.Empty) + { + } + + public ToolStripSplitButton (string text, Image image, params ToolStripItem[] dropDownItems) + : base (text, image, dropDownItems) + { + this.ResetDropDownButtonWidth (); + } + + public ToolStripSplitButton (string text, Image image, EventHandler onClick, string name) + : base (text, image, onClick, name) + { + this.ResetDropDownButtonWidth (); + } + #endregion + + #region Public Properties + [DefaultValue (true)] + public new bool AutoToolTip { + get { return base.AutoToolTip; } + set { base.AutoToolTip = value; } + } + + [Browsable (false)] + public Rectangle ButtonBounds { + get { return new Rectangle (Bounds.Left, Bounds.Top, this.Bounds.Width - this.drop_down_button_width - 1, this.Height); } + } + + [Browsable (false)] + public bool ButtonPressed { + get { return this.button_pressed; } + } + + [Browsable (false)] + public bool ButtonSelected { + get { return base.Selected; } + } + + [Browsable (false)] + [DefaultValue (null)] + public ToolStripItem DefaultItem { + get { return this.default_item; } + set { + if (this.default_item != value) { + this.default_item = value; + this.OnDefaultItemChanged (EventArgs.Empty); + } + } + } + + [Browsable (false)] + public Rectangle DropDownButtonBounds { + get { return new Rectangle (this.Bounds.Right - this.drop_down_button_width, 0, this.drop_down_button_width, this.Bounds.Height); } + } + + [Browsable (false)] + public bool DropDownButtonPressed { + get { return this.drop_down_button_selected || (this.HasDropDownItems && this.DropDown.Visible); } + } + + [Browsable (false)] + public bool DropDownButtonSelected { + get { return base.Selected; } + } + + public int DropDownButtonWidth { + get { return this.drop_down_button_width; } + set { + if (value < 0) + throw new ArgumentOutOfRangeException (); + if (this.drop_down_button_width != value) { + this.drop_down_button_width = value; + CalculateAutoSize (); + } + } + } + + [Browsable (false)] + public Rectangle SplitterBounds { + get { return new Rectangle (this.Bounds.Width - this.drop_down_button_width - 1, 0, 1, this.Height); } + } + #endregion + + #region Protected Properties + protected override bool DefaultAutoToolTip { + get { return true; } + } + + protected internal override bool DismissWhenClicked { + get { return true; } + } + #endregion + + #region Public Methods + public override Size GetPreferredSize (Size constrainingSize) + { + // base should calculate the button part for us, add the splitter + // and drop down arrow part to that + Size s = base.GetPreferredSize (constrainingSize); + + if (s.Width < 23) + s.Width = 23; + + // If we are a fixed size, we can't add more in for the drop down + // button, but we can for autosize + if (AutoSize) + s.Width += (this.drop_down_button_width - 2); + + return s; + } + + public virtual void OnButtonDoubleClick (EventArgs e) + { + EventHandler eh = (EventHandler)(Events [ButtonDoubleClickEvent]); + if (eh != null) + eh (this, e); + } + + public void PerformButtonClick () + { + if (this.Enabled) + this.OnButtonClick (EventArgs.Empty); + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public virtual void ResetDropDownButtonWidth () + { + this.DropDownButtonWidth = 11; + } + #endregion + + #region Protected Methods + protected override AccessibleObject CreateAccessibilityInstance () + { + return new ToolStripSplitButtonAccessibleObject (this); + } + + protected override ToolStripDropDown CreateDefaultDropDown () + { + ToolStripDropDownMenu tsddm = new ToolStripDropDownMenu (); + tsddm.OwnerItem = this; + return tsddm; + } + + protected virtual void OnButtonClick (EventArgs e) + { + EventHandler eh = (EventHandler)Events [ButtonClickEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnDefaultItemChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [DefaultItemChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected override void OnMouseDown (MouseEventArgs e) + { + if (this.ButtonBounds.Contains (e.Location)) + { + this.button_pressed = true; + this.Invalidate (); + base.OnMouseDown (e); + } + else if (this.DropDownButtonBounds.Contains (e.Location)) + { + if (this.DropDown.Visible) + this.HideDropDown (ToolStripDropDownCloseReason.ItemClicked); + else + this.ShowDropDown (); + + this.Invalidate (); + base.OnMouseDown (e); + } + } + + protected override void OnMouseLeave (EventArgs e) + { + this.drop_down_button_selected = false; + this.button_pressed = false; + + this.Invalidate (); + + base.OnMouseLeave (e); + } + + protected override void OnMouseUp (MouseEventArgs e) + { + this.button_pressed = false; + this.Invalidate (); + + base.OnMouseUp (e); + } + + protected override void OnPaint (PaintEventArgs e) + { + base.OnPaint (e); + + if (this.Owner != null) { + Color font_color = this.Enabled ? this.ForeColor : SystemColors.GrayText; + Image draw_image = this.Enabled ? this.Image : ToolStripRenderer.CreateDisabledImage (this.Image); + + this.Owner.Renderer.DrawSplitButton (new ShiftUI.ToolStripItemRenderEventArgs (e.Graphics, this)); + + Rectangle text_layout_rect; + Rectangle image_layout_rect; + + Rectangle r = this.ContentRectangle; + r.Width -= (this.drop_down_button_width + 1); + + this.CalculateTextAndImageRectangles (r, out text_layout_rect, out image_layout_rect); + + if (text_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemText (new ShiftUI.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign)); + if (image_layout_rect != Rectangle.Empty) + this.Owner.Renderer.DrawItemImage (new ShiftUI.ToolStripItemImageRenderEventArgs (e.Graphics, this, draw_image, image_layout_rect)); + + this.Owner.Renderer.DrawArrow (new ToolStripArrowRenderEventArgs (e.Graphics, this, new Rectangle (this.Width - 9, 1, 6, this.Height), Color.Black, ArrowDirection.Down)); + + return; + } + } + + protected override void OnRightToLeftChanged (EventArgs e) + { + base.OnRightToLeftChanged (e); + } + + protected internal override bool ProcessDialogKey (Keys keyData) + { + if (this.Selected && keyData == Keys.Enter && this.DefaultItem != null) { + this.DefaultItem.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click); + return true; + } + + return base.ProcessDialogKey (keyData); + } + + protected internal override bool ProcessMnemonic (char charCode) + { + if (!this.Selected) + this.Parent.ChangeSelection (this); + + if (this.HasDropDownItems) + this.ShowDropDown (); + else + this.PerformClick (); + + return true; + } + #endregion + + #region Internal Methods + internal override void HandleClick (int mouse_clicks, EventArgs e) + { + base.HandleClick (mouse_clicks, e); + + MouseEventArgs mea = e as MouseEventArgs; + + if (mea != null) + if (ButtonBounds.Contains (mea.Location)) + OnButtonClick (EventArgs.Empty); + } + #endregion + + #region Public Events + static object ButtonClickEvent = new object (); + static object ButtonDoubleClickEvent = new object (); + static object DefaultItemChangedEvent = new object (); + + public event EventHandler ButtonClick { + add { Events.AddHandler (ButtonClickEvent, value); } + remove {Events.RemoveHandler (ButtonClickEvent, value); } + } + public event EventHandler ButtonDoubleClick { + add { Events.AddHandler (ButtonDoubleClickEvent, value); } + remove {Events.RemoveHandler (ButtonDoubleClickEvent, value); } + } + public event EventHandler DefaultItemChanged { + add { Events.AddHandler (DefaultItemChangedEvent, value); } + remove {Events.RemoveHandler (DefaultItemChangedEvent, value); } + } + #endregion + + #region ToolStripSplitButtonAccessibleObject Class + public class ToolStripSplitButtonAccessibleObject : ToolStripItemAccessibleObject + { + #region Public Constructor + public ToolStripSplitButtonAccessibleObject (ToolStripSplitButton item) : base (item) + { + } + #endregion + + #region Public Method + public override void DoDefaultAction () + { + (owner_item as ToolStripSplitButton).PerformButtonClick (); + } + #endregion + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripSplitStackLayout.cs b/source/ShiftUI/ToolStrip/ToolStripSplitStackLayout.cs new file mode 100644 index 0000000..9124adb --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripSplitStackLayout.cs @@ -0,0 +1,264 @@ +// +// ToolStripSplitStackLayout.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using ShiftUI.Layout; + +namespace ShiftUI +{ + class ToolStripSplitStackLayout : LayoutEngine + { + public override bool Layout (object container, LayoutEventArgs args) + { + if (container is ToolStrip) + { + ToolStrip ts = (ToolStrip)container; + + if (ts.Items == null) + return false; + + Rectangle ts_rect = ts.DisplayRectangle; + + // Mono hasn't yet implemented ToolStripLayoutStyle.Table, so it comes here + // for layout. The default (minimal) Table layout is 1 column, any number of rows, + // which translates effectively to Vertical orientation. + if (ts.Orientation == Orientation.Horizontal && ts.LayoutStyle != ToolStripLayoutStyle.Table) + LayoutHorizontalToolStrip (ts, ts_rect); + else + LayoutVerticalToolStrip (ts, ts_rect); + + return false; + } else { + ToolStripContentPanel ts = (ToolStripContentPanel)container; + int x = ts.DisplayRectangle.Left; + int y = ts.DisplayRectangle.Top; + + foreach (ToolStrip tsi in ts.Widgets) { + Rectangle new_bounds = new Rectangle (); + + x += tsi.Margin.Left; + + new_bounds.Location = new Point (x, y + tsi.Margin.Top); + new_bounds.Height = ts.DisplayRectangle.Height - tsi.Margin.Vertical; + new_bounds.Width = tsi.GetToolStripPreferredSize (new Size (0, new_bounds.Height)).Width; + + tsi.Width = new_bounds.Width + 12; + + x += new_bounds.Width + tsi.Margin.Right; + } + } + + return false; + } + + private void LayoutHorizontalToolStrip (ToolStrip ts, Rectangle bounds) + { + //if (!ts.Visible) return; + + ToolStripItemOverflow[] overflow = new ToolStripItemOverflow[ts.Items.Count]; + ToolStripItemPlacement[] placement = new ToolStripItemPlacement[ts.Items.Count]; + Size proposedSize = new Size (0, bounds.Height); + int[] widths = new int[ts.Items.Count]; + int total_width = 0; + int toolstrip_width = bounds.Width; + int i = 0; + bool can_overflow = ts.CanOverflow & !(ts is MenuStrip) & !(ts is StatusStrip); + bool need_overflow = false; + + foreach (ToolStripItem tsi in ts.Items) { + overflow[i] = tsi.Overflow; + placement[i] = tsi.Overflow == ToolStripItemOverflow.Always ? ToolStripItemPlacement.Overflow : ToolStripItemPlacement.Main; + widths[i] = tsi.GetPreferredSize (proposedSize).Width + tsi.Margin.Horizontal; + if (!tsi.Available) + placement[i] = ToolStripItemPlacement.None; + total_width += placement[i] == ToolStripItemPlacement.Main ? widths[i] : 0; + + if (placement[i] == ToolStripItemPlacement.Overflow) + need_overflow = true; + i++; + } + + // This is needed for a button set to Overflow = Always + if (need_overflow) { + ts.OverflowButton.Visible = true; + ts.OverflowButton.SetBounds (new Rectangle (ts.Width - 16, 0, 16, ts.Height)); + toolstrip_width -= ts.OverflowButton.Width; + } else + ts.OverflowButton.Visible = false; + + while (total_width > toolstrip_width) { + // If we can overflow, get our overflow button setup, and subtract it's width + // from our available width + if (can_overflow && !ts.OverflowButton.Visible) { + ts.OverflowButton.Visible = true; + ts.OverflowButton.SetBounds (new Rectangle (ts.Width - 16, 0, 16, ts.Height)); + toolstrip_width -= ts.OverflowButton.Width; + } + + bool removed_one = false; + + // Start at the right, removing Overflow.AsNeeded first + for (int j = widths.Length - 1; j >= 0; j--) + if (overflow[j] == ToolStripItemOverflow.AsNeeded && placement[j] == ToolStripItemPlacement.Main) { + placement[j] = ToolStripItemPlacement.Overflow; + total_width -= widths[j]; + removed_one = true; + break; + } + + // If we didn't remove any AsNeeded ones, we have to start removing Never ones + // These are not put on the Overflow, they are simply not shown + if (!removed_one) + for (int j = widths.Length - 1; j >= 0; j--) + if (overflow[j] == ToolStripItemOverflow.Never && placement[j] == ToolStripItemPlacement.Main) { + placement[j] = ToolStripItemPlacement.None; + total_width -= widths[j]; + removed_one = true; + break; + } + + // There's nothing left to remove, break or we will loop forever + if (!removed_one) + break; + } + + i = 0; + Point start_layout_pointer = new Point (ts.DisplayRectangle.Left, ts.DisplayRectangle.Top); + Point end_layout_pointer = new Point (ts.DisplayRectangle.Right, ts.DisplayRectangle.Top); + int button_height = ts.DisplayRectangle.Height; + + // Now we should know where everything goes, so lay everything out + foreach (ToolStripItem tsi in ts.Items) { + tsi.SetPlacement (placement[i]); + + if (placement[i] == ToolStripItemPlacement.Main) { + if (tsi.Alignment == ToolStripItemAlignment.Left) { + tsi.SetBounds (new Rectangle (start_layout_pointer.X + tsi.Margin.Left, start_layout_pointer.Y + tsi.Margin.Top, widths[i] - tsi.Margin.Horizontal, button_height - tsi.Margin.Vertical)); + start_layout_pointer.X += widths[i]; + } else { + tsi.SetBounds (new Rectangle (end_layout_pointer.X - tsi.Margin.Right - tsi.Width, end_layout_pointer.Y + tsi.Margin.Top, widths[i] - tsi.Margin.Horizontal, button_height - tsi.Margin.Vertical)); + end_layout_pointer.X -= widths[i]; + } + } + + i++; + } + } + + private void LayoutVerticalToolStrip (ToolStrip ts, Rectangle bounds) + { + if (!ts.Visible) return; + + ToolStripItemOverflow[] overflow = new ToolStripItemOverflow[ts.Items.Count]; + ToolStripItemPlacement[] placement = new ToolStripItemPlacement[ts.Items.Count]; + Size proposedSize = new Size (bounds.Width, 0); + int[] heights = new int[ts.Items.Count]; + int[] widths = new int[ts.Items.Count]; // needed if ts.LayoutStyle == ToolStripLayoutStyle.Table + int total_height = 0; + int toolstrip_height = bounds.Height; + int i = 0; + bool can_overflow = ts.CanOverflow & !(ts is MenuStrip) & !(ts is StatusStrip); + + foreach (ToolStripItem tsi in ts.Items) { + overflow[i] = tsi.Overflow; + placement[i] = tsi.Overflow == ToolStripItemOverflow.Always ? ToolStripItemPlacement.Overflow : ToolStripItemPlacement.Main; + var size = tsi.GetPreferredSize (proposedSize); + heights[i] = size.Height + tsi.Margin.Vertical; + widths[i] = size.Width + tsi.Margin.Horizontal; + if (!tsi.Available) + placement[i] = ToolStripItemPlacement.None; + total_height += placement[i] == ToolStripItemPlacement.Main ? heights[i] : 0; + i++; + } + + ts.OverflowButton.Visible = false; + + while (total_height > toolstrip_height) { + // If we can overflow, get our overflow button setup, and subtract it's width + // from our available width + if (can_overflow && !ts.OverflowButton.Visible) { + ts.OverflowButton.Visible = true; + ts.OverflowButton.SetBounds (new Rectangle (0, ts.Height - 16, ts.Width, 16)); + toolstrip_height -= ts.OverflowButton.Height; + } + + bool removed_one = false; + + // Start at the right, removing Overflow.AsNeeded first + for (int j = heights.Length - 1; j >= 0; j--) + if (overflow[j] == ToolStripItemOverflow.AsNeeded && placement[j] == ToolStripItemPlacement.Main) { + placement[j] = ToolStripItemPlacement.Overflow; + total_height -= heights[j]; + removed_one = true; + break; + } + + // If we didn't remove any AsNeeded ones, we have to start removing Never ones + // These are not put on the Overflow, they are simply not shown + if (!removed_one) + for (int j = heights.Length - 1; j >= 0; j--) + if (overflow[j] == ToolStripItemOverflow.Never && placement[j] == ToolStripItemPlacement.Main) { + placement[j] = ToolStripItemPlacement.None; + total_height -= heights[j]; + removed_one = true; + break; + } + + // There's nothing left to remove, break or we will loop forever + if (!removed_one) + break; + } + + i = 0; + Point start_layout_pointer = new Point (ts.DisplayRectangle.Left, ts.DisplayRectangle.Top); + Point end_layout_pointer = new Point (ts.DisplayRectangle.Left, ts.DisplayRectangle.Bottom); + int button_width = ts.DisplayRectangle.Width; + + // Now we should know where everything goes, so lay everything out + foreach (ToolStripItem tsi in ts.Items) { + tsi.SetPlacement (placement[i]); + // Table layout is defined to lay out items flush left. + if (ts.LayoutStyle == ToolStripLayoutStyle.Table) + button_width = widths[i]; + + if (placement[i] == ToolStripItemPlacement.Main) { + if (tsi.Alignment == ToolStripItemAlignment.Left) { + tsi.SetBounds (new Rectangle (start_layout_pointer.X + tsi.Margin.Left, start_layout_pointer.Y + tsi.Margin.Top, button_width - tsi.Margin.Horizontal, heights[i] - tsi.Margin.Vertical)); + start_layout_pointer.Y += heights[i]; + } else { + tsi.SetBounds (new Rectangle (end_layout_pointer.X + tsi.Margin.Left, end_layout_pointer.Y - tsi.Margin.Bottom - tsi.Height, button_width - tsi.Margin.Horizontal, heights[i] - tsi.Margin.Vertical)); + start_layout_pointer.Y += heights[i]; + } + } + + i++; + } + } + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripStatusLabel.cs b/source/ShiftUI/ToolStrip/ToolStripStatusLabel.cs new file mode 100644 index 0000000..83236d3 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripStatusLabel.cs @@ -0,0 +1,129 @@ +// +// StatusStrip.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.ComponentModel; +using System.Runtime.InteropServices; +using ShiftUI.Design; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.StatusStrip)] + public class ToolStripStatusLabel : ToolStripLabel + { + private ToolStripStatusLabelBorderSides border_sides; + private Border3DStyle border_style; + private bool spring; + + #region Public Constructors + public ToolStripStatusLabel () + : this (String.Empty, null, null, String.Empty) + { + } + + public ToolStripStatusLabel (Image image) + : this (String.Empty, image, null, String.Empty) + { + } + + public ToolStripStatusLabel (string text) + : this (text, null, null, String.Empty) + { + } + + public ToolStripStatusLabel (string text, Image image) + : this (text, image, null, String.Empty) + { + } + + public ToolStripStatusLabel (string text, Image image, EventHandler onClick) + : this (text, image, onClick, String.Empty) + { + } + + public ToolStripStatusLabel (string text, Image image, EventHandler onClick, string name) + : base (text, image, false, onClick, name) + { + this.border_style = Border3DStyle.Flat; + } + #endregion + + #region Public Properties + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Advanced)] + public new ToolStripItemAlignment Alignment { + get { return base.Alignment; } + set { base.Alignment = value; } + } + + [DefaultValue (ToolStripStatusLabelBorderSides.None)] + public ToolStripStatusLabelBorderSides BorderSides { + get { return this.border_sides; } + set { this.border_sides = value; } + } + + [DefaultValue (Border3DStyle.Flat)] + public Border3DStyle BorderStyle { + get { return this.border_style; } + set { this.border_style = value; } + } + + [DefaultValue (false)] + public bool Spring { + get { return this.spring; } + set { + if (this.spring != value) { + this.spring = value; + CalculateAutoSize (); + } + } + } + #endregion + + #region Protected Properties + protected internal override Padding DefaultMargin { + get { return new Padding (0, 3, 0, 2); } + } + #endregion + + #region Public Methods + public override Size GetPreferredSize (Size constrainingSize) + { + return base.GetPreferredSize (constrainingSize); + } + #endregion + + #region Protected Methods + protected override void OnPaint (PaintEventArgs e) + { + base.OnPaint (e); + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripStatusLabelBorderSides.cs b/source/ShiftUI/ToolStrip/ToolStripStatusLabelBorderSides.cs new file mode 100644 index 0000000..1a500cb --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripStatusLabelBorderSides.cs @@ -0,0 +1,49 @@ +// +// ToolStripStatusLabelBorderSides.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +using System.Runtime.InteropServices; +using System.ComponentModel; +using System; + +namespace ShiftUI +{ + [Flags] + [ComVisible(true)] + //[Editor ("ShiftUI.Design.BorderSidesEditor, " + Consts.AssemblySystem_Design, + //"System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)] + public enum ToolStripStatusLabelBorderSides + { + None = 0, + Left = 1, + Top = 2, + Right = 4, + Bottom = 8, + All = 15 + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripSystemRenderer.cs b/source/ShiftUI/ToolStrip/ToolStripSystemRenderer.cs new file mode 100644 index 0000000..beccd13 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripSystemRenderer.cs @@ -0,0 +1,130 @@ +// +// ToolStripSystemRenderer.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using ShiftUI.Theming; + +namespace ShiftUI +{ + public class ToolStripSystemRenderer : ToolStripRenderer + { + #region Public Constructor + public ToolStripSystemRenderer () + { + } + #endregion + + #region Protected Methods + protected override void OnRenderButtonBackground (ToolStripItemRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderButtonBackground (e); + + base.OnRenderButtonBackground (e); + } + + protected override void OnRenderDropDownButtonBackground (ToolStripItemRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderDropDownButtonBackground (e); + + base.OnRenderDropDownButtonBackground (e); + } + + protected override void OnRenderGrip (ToolStripGripRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderGrip (e); + + base.OnRenderGrip (e); + } + + protected override void OnRenderImageMargin (ToolStripRenderEventArgs e) + { + base.OnRenderImageMargin (e); + } + + protected override void OnRenderItemBackground (ToolStripItemRenderEventArgs e) + { + base.OnRenderItemBackground (e); + } + + protected override void OnRenderLabelBackground (ToolStripItemRenderEventArgs e) + { + base.OnRenderLabelBackground (e); + } + + protected override void OnRenderMenuItemBackground (ToolStripItemRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderMenuItemBackground (e); + + base.OnRenderMenuItemBackground (e); + } + + protected override void OnRenderOverflowButtonBackground (ToolStripItemRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderOverflowButtonBackground (e); + + base.OnRenderOverflowButtonBackground (e); + } + + protected override void OnRenderSeparator (ToolStripSeparatorRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderSeparator (e); + + base.OnRenderSeparator (e); + } + + protected override void OnRenderSplitButtonBackground (ToolStripItemRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderSplitButtonBackground (e); + + base.OnRenderSplitButtonBackground (e); + } + + protected override void OnRenderToolStripBackground (ToolStripRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderToolStripBackground (e); + + base.OnRenderToolStripBackground (e); + } + + protected override void OnRenderToolStripBorder (ToolStripRenderEventArgs e) + { + ThemeElements.CurrentTheme.ToolStripPainter.OnRenderToolStripBorder (e); + + base.OnRenderToolStripBorder (e); + } + + protected override void OnRenderToolStripStatusLabelBackground (ToolStripItemRenderEventArgs e) + { + base.OnRenderToolStripStatusLabelBackground (e); + } + #endregion + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripTextBox.cs b/source/ShiftUI/ToolStrip/ToolStripTextBox.cs new file mode 100644 index 0000000..eeabbba --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripTextBox.cs @@ -0,0 +1,590 @@ +// +// ToolStripTextBox.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System.Drawing; +using System.ComponentModel; +using ShiftUI.Design; +using System.Runtime.InteropServices; +using System; + +namespace ShiftUI +{ + [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.MenuStrip | ToolStripItemDesignerAvailability.ContextMenuStrip)] + public class ToolStripTextBox : ToolStripWidgetHost + { + private BorderStyle border_style; + + #region Public Constructors + public ToolStripTextBox () : base (new ToolStripTextBoxWidget ()) + { + ToolStripTextBoxWidget text_box = TextBox as ToolStripTextBoxWidget; + text_box.OwnerItem = this; + text_box.border_style = BorderStyle.None; + text_box.TopMargin = 3; // need to explicitly set the margin + text_box.Border = BorderStyle.Fixed3D; // ToolStripTextBoxWidget impl, not TextBox + this.border_style = BorderStyle.Fixed3D; + } + + //[EditorBrowsable (EditorBrowsableState.Never)] + public ToolStripTextBox (Widget c) : base (c) + { + throw new NotSupportedException ("This construtor cannot be used."); + } + + public ToolStripTextBox (string name) : this () + { + base.Name = name; + } + #endregion + + #region Public Properties + [DefaultValue (false)] + public bool AcceptsReturn { + get { return this.TextBox.AcceptsReturn; } + set { this.TextBox.AcceptsReturn = value; } + } + + [DefaultValue (false)] + public bool AcceptsTab { + get { return this.TextBox.AcceptsTab; } + set { this.TextBox.AcceptsTab = value; } + } + + [MonoTODO ("AutoCompletion algorithm is currently not implemented.")] + [Browsable (true)] + [Localizable (true)] + //[EditorBrowsable (EditorBrowsableState.Always)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] + //[Editor ("ShiftUI.Design.ListWidgetStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] + public AutoCompleteStringCollection AutoCompleteCustomSource { + get { return this.TextBox.AutoCompleteCustomSource; } + set { this.TextBox.AutoCompleteCustomSource = value; } + } + + [MonoTODO("AutoCompletion algorithm is currently not implemented.")] + [Browsable (true)] + [DefaultValue (AutoCompleteMode.None)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public AutoCompleteMode AutoCompleteMode { + get { return this.TextBox.AutoCompleteMode; } + set { this.TextBox.AutoCompleteMode = value; } + } + + [MonoTODO("AutoCompletion algorithm is currently not implemented.")] + [Browsable (true)] + [DefaultValue (AutoCompleteSource.None)] + //[EditorBrowsable (EditorBrowsableState.Always)] + public AutoCompleteSource AutoCompleteSource { + get { return this.TextBox.AutoCompleteSource; } + set { this.TextBox.AutoCompleteSource = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override Image BackgroundImage { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override ImageLayout BackgroundImageLayout { + get { return base.BackgroundImageLayout; } + set { base.BackgroundImageLayout = value; } + } + + [DefaultValue (BorderStyle.Fixed3D)] + [DispId (-504)] + public BorderStyle BorderStyle { + get { return this.border_style; } + set { + if (this.border_style != value) { + this.border_style = value; + (base.Widget as ToolStripTextBoxWidget).Border = value; + this.OnBorderStyleChanged (EventArgs.Empty); + } + } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public bool CanUndo { + get { return this.TextBox.CanUndo; } + } + + [DefaultValue (CharacterCasing.Normal)] + public CharacterCasing CharacterCasing { + get { return this.TextBox.CharacterCasing; } + set { this.TextBox.CharacterCasing = value; } + } + + [DefaultValue (true)] + public bool HideSelection { + get { return this.TextBox.HideSelection; } + set { this.TextBox.HideSelection = value; } + } + + [Localizable (true)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + //[Editor ("ShiftUI.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] + public string[] Lines { + get { return this.TextBox.Lines; } + set { this.TextBox.Lines = value; } + } + + [Localizable (true)] + [DefaultValue (32767)] + public int MaxLength { + get { return this.TextBox.MaxLength; } + set { this.TextBox.MaxLength = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public bool Modified { + get { return this.TextBox.Modified; } + set { this.TextBox.Modified = value; } + } + + [Localizable (true)] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + [DefaultValue (false)] + [RefreshProperties (RefreshProperties.All)] + public bool Multiline { + get { return this.TextBox.Multiline; } + set { this.TextBox.Multiline = value; } + } + + [DefaultValue (false)] + public bool ReadOnly { + get { return this.TextBox.ReadOnly; } + set { this.TextBox.ReadOnly = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public string SelectedText { + get { return this.TextBox.SelectedText; } + set { this.TextBox.SelectedText = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public int SelectionLength { + get { return this.TextBox.SelectionLength == -1 ? 0 : this.TextBox.SelectionLength; } + set { this.TextBox.SelectionLength = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public int SelectionStart { + get { return this.TextBox.SelectionStart; } + set { this.TextBox.SelectionStart = value; } + } + + [DefaultValue (true)] + public bool ShortcutsEnabled { + get { return this.TextBox.ShortcutsEnabled; } + set { this.TextBox.ShortcutsEnabled = value; } + } + + [Browsable (false)] + //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public TextBox TextBox { + get { return (TextBox)base.Widget; } + } + + [Localizable (true)] + [DefaultValue (HorizontalAlignment.Left)] + public HorizontalAlignment TextBoxTextAlign { + get { return this.TextBox.TextAlign; } + set { this.TextBox.TextAlign = value; } + } + + [Browsable (false)] + public int TextLength { + get { return this.TextBox.TextLength; } + } + + [Localizable (true)] + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + [DefaultValue (true)] + public bool WordWrap { + get { return this.TextBox.WordWrap; } + set { this.TextBox.WordWrap = value; } + } + #endregion + + #region Protected Properties + protected internal override Padding DefaultMargin { get { return new Padding (1, 0, 1, 0); } } + protected override Size DefaultSize { get { return new Size (100, 22); } } + #endregion + + #region Public Methods + public void AppendText (string text) + { + this.TextBox.AppendText (text); + } + + public void Clear () + { + this.TextBox.Clear (); + } + + public void ClearUndo () + { + this.TextBox.ClearUndo (); + } + + public void Copy () + { + this.TextBox.Copy (); + } + + public void Cut () + { + this.TextBox.Cut (); + } + + public void DeselectAll () + { + this.TextBox.DeselectAll (); + } + + public char GetCharFromPosition (Point pt) + { + return this.TextBox.GetCharFromPosition (pt); + } + + public int GetCharIndexFromPosition (Point pt) + { + return this.TextBox.GetCharIndexFromPosition (pt); + } + + public int GetFirstCharIndexFromLine (int lineNumber) + { + return this.TextBox.GetFirstCharIndexFromLine (lineNumber); + } + + public int GetFirstCharIndexOfCurrentLine () + { + return this.TextBox.GetFirstCharIndexOfCurrentLine (); + } + + public int GetLineFromCharIndex (int index) + { + return this.TextBox.GetLineFromCharIndex (index); + } + + public Point GetPositionFromCharIndex (int index) + { + return this.TextBox.GetPositionFromCharIndex (index); + } + + public override Size GetPreferredSize (Size constrainingSize) + { + return base.GetPreferredSize (constrainingSize); + } + + public void Paste () + { + this.TextBox.Paste (); + } + + public void ScrollToCaret () + { + this.TextBox.ScrollToCaret (); + } + + public void Select (int start, int length) + { + this.TextBox.Select (start, length); + } + + public void SelectAll () + { + this.TextBox.SelectAll (); + } + + public void Undo () + { + this.TextBox.Undo (); + } + #endregion + + #region Protected Methods + protected virtual void OnAcceptsTabChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [AcceptsTabChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnBorderStyleChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [BorderStyleChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnHideSelectionChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [HideSelectionChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnModifiedChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [ModifiedChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnMultilineChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [MultilineChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected virtual void OnReadOnlyChanged (EventArgs e) + { + EventHandler eh = (EventHandler)Events [ReadOnlyChangedEvent]; + if (eh != null) + eh (this, e); + } + + protected override void OnSubscribeWidgetEvents (Widget Widget) + { + base.OnSubscribeWidgetEvents (Widget); + + this.TextBox.AcceptsTabChanged += new EventHandler (HandleAcceptsTabChanged); + this.TextBox.HideSelectionChanged += new EventHandler (HandleHideSelectionChanged); + this.TextBox.ModifiedChanged += new EventHandler (HandleModifiedChanged); + this.TextBox.MultilineChanged += new EventHandler (HandleMultilineChanged); + this.TextBox.ReadOnlyChanged += new EventHandler (HandleReadOnlyChanged); + this.TextBox.TextAlignChanged += new EventHandler (HandleTextAlignChanged); + this.TextBox.TextChanged += new EventHandler (HandleTextChanged); + } + + protected override void OnUnsubscribeWidgetEvents (Widget Widget) + { + base.OnUnsubscribeWidgetEvents (Widget); + } + #endregion + + #region Public Events + static object AcceptsTabChangedEvent = new object (); + static object BorderStyleChangedEvent = new object (); + static object HideSelectionChangedEvent = new object (); + static object ModifiedChangedEvent = new object (); + static object MultilineChangedEvent = new object (); + static object ReadOnlyChangedEvent = new object (); + static object TextBoxTextAlignChangedEvent = new object (); + + public event EventHandler AcceptsTabChanged { + add { Events.AddHandler (AcceptsTabChangedEvent, value); } + remove {Events.RemoveHandler (AcceptsTabChangedEvent, value); } + } + public event EventHandler BorderStyleChanged { + add { Events.AddHandler (BorderStyleChangedEvent, value); } + remove {Events.RemoveHandler (BorderStyleChangedEvent, value); } + } + public event EventHandler HideSelectionChanged { + add { Events.AddHandler (HideSelectionChangedEvent, value); } + remove {Events.RemoveHandler (HideSelectionChangedEvent, value); } + } + public event EventHandler ModifiedChanged { + add { Events.AddHandler (ModifiedChangedEvent, value); } + remove {Events.RemoveHandler (ModifiedChangedEvent, value); } + } + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public event EventHandler MultilineChanged { + add { Events.AddHandler (MultilineChangedEvent, value); } + remove {Events.RemoveHandler (MultilineChangedEvent, value); } + } + public event EventHandler ReadOnlyChanged { + add { Events.AddHandler (ReadOnlyChangedEvent, value); } + remove {Events.RemoveHandler (ReadOnlyChangedEvent, value); } + } + public event EventHandler TextBoxTextAlignChanged { + add { Events.AddHandler (TextBoxTextAlignChangedEvent, value); } + remove {Events.RemoveHandler (TextBoxTextAlignChangedEvent, value); } + } + #endregion + + #region Private Methods + private void HandleTextAlignChanged (object sender, EventArgs e) + { + EventHandler eh = (EventHandler)(Events [TextBoxTextAlignChangedEvent]); + if (eh != null) + eh (this, e); + } + + private void HandleReadOnlyChanged (object sender, EventArgs e) + { + OnReadOnlyChanged (e); + } + + private void HandleMultilineChanged (object sender, EventArgs e) + { + OnMultilineChanged (e); + } + + private void HandleModifiedChanged (object sender, EventArgs e) + { + OnModifiedChanged (e); + } + + private void HandleHideSelectionChanged (object sender, EventArgs e) + { + OnHideSelectionChanged (e); + } + + private void HandleAcceptsTabChanged (object sender, EventArgs e) + { + OnAcceptsTabChanged (e); + } + + private void HandleTextChanged (object sender, EventArgs e) + { + OnTextChanged (e); + } + #endregion + + private class ToolStripTextBoxWidget : TextBox + { + private BorderStyle border; + private Timer tooltip_timer; + private ToolTip tooltip_window; + private ToolStripItem owner_item; + + public ToolStripTextBoxWidget () : base () + { + } + + protected override void OnLostFocus (EventArgs e) + { + base.OnLostFocus (e); + Invalidate (); + } + + protected override void OnMouseEnter (EventArgs e) + { + base.OnMouseEnter (e); + Invalidate (); + + if (ShowToolTips) + ToolTipTimer.Start (); + + } + + protected override void OnMouseLeave (EventArgs e) + { + base.OnMouseLeave (e); + Invalidate (); + + ToolTipTimer.Stop (); + ToolTipWindow.Hide (this); + } + + internal override void OnPaintInternal (PaintEventArgs e) + { + base.OnPaintInternal (e); + + if ((this.Focused || this.Entered || border == BorderStyle.FixedSingle) && border != BorderStyle.None) { + ToolStripRenderer tsr = (this.Parent as ToolStrip).Renderer; + + if (tsr is ToolStripProfessionalRenderer) + using (Pen p = new Pen ((tsr as ToolStripProfessionalRenderer).ColorTable.ButtonSelectedBorder)) + e.Graphics.DrawRectangle (p, new Rectangle (0, 0, this.Width - 1, this.Height - 1)); + } + } + + internal BorderStyle Border { + set { + border = value; + Invalidate (); + } + } + + internal ToolStripItem OwnerItem { + set { owner_item = value; } + } + + #region Stuff for ToolTips + private bool ShowToolTips { + get { + if (Parent == null) + return false; + + return (Parent as ToolStrip).ShowItemToolTips; + } + } + + private Timer ToolTipTimer { + get { + if (tooltip_timer == null) { + tooltip_timer = new Timer (); + tooltip_timer.Enabled = false; + tooltip_timer.Interval = 500; + tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick); + } + + return tooltip_timer; + } + } + + private ToolTip ToolTipWindow { + get { + if (tooltip_window == null) + tooltip_window = new ToolTip (); + + return tooltip_window; + } + } + + private void ToolTipTimer_Tick (object o, EventArgs args) + { + string tooltip = owner_item.GetToolTip (); + + if (!string.IsNullOrEmpty (tooltip)) + ToolTipWindow.Present (this, tooltip); + + ToolTipTimer.Stop (); + } + #endregion + } + } +} diff --git a/source/ShiftUI/ToolStrip/ToolStripTextDirection.cs b/source/ShiftUI/ToolStrip/ToolStripTextDirection.cs new file mode 100644 index 0000000..4670889 --- /dev/null +++ b/source/ShiftUI/ToolStrip/ToolStripTextDirection.cs @@ -0,0 +1,39 @@ +// +// ToolStripTextDirection.cs +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2006 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// + + +namespace ShiftUI +{ + public enum ToolStripTextDirection + { + Inherit = 0, + Horizontal = 1, + Vertical90 = 2, + Vertical270 = 3 + } +} |
