X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FManaged.Windows.Forms%2FSystem.Windows.Forms%2FToolStrip.cs;h=30c0d89f5fb40633ee7a05e3dc555e6408b74e67;hb=0b3c3126ea203240ba9864ab9082c44935f32f4f;hp=6c04b09f99244e90e581617c1a2f60939fd07b65;hpb=d579eeb969330fad7d183c7f8f1b6fa0bc9f1a0e;p=mono.git diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs index 6c04b09f992..30c0d89f5fb 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs @@ -26,13 +26,13 @@ // Jonathan Pobst (monkey@jpobst.com) // -#if NET_2_0 using System; using System.Runtime.InteropServices; using System.ComponentModel; using System.Drawing; using System.Windows.Forms.Layout; using System.Collections.Generic; +using System.ComponentModel.Design.Serialization; namespace System.Windows.Forms { @@ -40,9 +40,12 @@ namespace System.Windows.Forms [ClassInterface (ClassInterfaceType.AutoDispatch)] [DefaultEvent ("ItemClicked")] [DefaultProperty ("Items")] - public class ToolStrip : ScrollableControl, IComponent, IDisposable + [Designer ("System.Windows.Forms.Design.ToolStripDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + [DesignerSerializer ("System.Windows.Forms.Design.ToolStripCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)] + public class ToolStrip : ScrollableControl, IComponent, IDisposable, IToolStripData { #region Private Variables + private bool allow_item_reorder; private bool allow_merge; private Color back_color; private bool can_overflow; @@ -66,14 +69,19 @@ namespace System.Windows.Forms private List pre_merge_items; private ToolStripRenderer renderer; private ToolStripRenderMode render_mode; + private ToolStripTextDirection text_direction; private Timer tooltip_timer; - private ToolTip.ToolTipWindow tooltip_window; + 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 @@ -89,14 +97,16 @@ namespace System.Windows.Forms SetStyle (ControlStyles.SupportsTransparentBackColor, true); this.SuspendLayout (); - this.items = new ToolStripItemCollection (this, items); + + this.items = new ToolStripItemCollection (this, items, true); this.allow_merge = true; base.AutoSize = true; + this.SetAutoSizeMode (AutoSizeMode.GrowAndShrink); this.back_color = Control.DefaultBackColor; this.can_overflow = true; base.CausesValidation = false; this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight; - this.displayed_items = new ToolStripItemCollection (this, null); + this.displayed_items = new ToolStripItemCollection (this, null, true); this.Dock = this.DefaultDock; base.Font = new Font ("Tahoma", 8.25f); this.fore_color = Control.DefaultForeColor; @@ -111,8 +121,8 @@ namespace System.Windows.Forms this.render_mode = ToolStripRenderMode.ManagerRenderMode; this.show_item_tool_tips = this.DefaultShowItemToolTips; base.TabStop = false; + this.text_direction = ToolStripTextDirection.Horizontal; this.ResumeLayout (); - DoAutoSize (); // Register with the ToolStripManager ToolStripManager.AddToolStrip (this); @@ -120,9 +130,23 @@ namespace System.Windows.Forms #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 = false; } + set { this.allow_merge = value; } } public override AnchorStyles Anchor { @@ -132,6 +156,7 @@ namespace System.Windows.Forms [Browsable (false)] [EditorBrowsable (EditorBrowsableState.Never)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public override bool AutoScroll { get { return base.AutoScroll; } set { base.AutoScroll = value; } @@ -139,6 +164,7 @@ namespace System.Windows.Forms [Browsable (false)] [EditorBrowsable (EditorBrowsableState.Never)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public new Size AutoScrollMargin { get { return base.AutoScrollMargin; } set { base.AutoScrollMargin = value; } @@ -146,6 +172,7 @@ namespace System.Windows.Forms [Browsable (false)] [EditorBrowsable (EditorBrowsableState.Never)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public new Size AutoScrollMinSize { get { return base.AutoScrollMinSize; } set { base.AutoScrollMinSize = value; } @@ -153,6 +180,7 @@ namespace System.Windows.Forms [Browsable (false)] [EditorBrowsable (EditorBrowsableState.Never)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public new Point AutoScrollPosition { get { return base.AutoScrollPosition; } set { base.AutoScrollPosition = value; } @@ -172,6 +200,11 @@ namespace System.Windows.Forms 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; } @@ -305,7 +338,7 @@ namespace System.Windows.Forms 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.PerformLayout (this, "GripStyle"); } } } @@ -353,6 +386,7 @@ namespace System.Windows.Forms } } + [MergableProperty (false)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public virtual ToolStripItemCollection Items { get { return this.items; } @@ -372,7 +406,12 @@ namespace System.Windows.Forms [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public LayoutSettings LayoutSettings { get { return this.layout_settings; } - set { this.layout_settings = value; } + set { + if (this.layout_settings != value) { + this.layout_settings = value; + PerformLayout (this, "LayoutSettings"); + } + } } [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)] @@ -404,7 +443,7 @@ namespace System.Windows.Forms this.layout_settings = this.CreateLayoutSettings (value); - this.PerformLayout (); + this.PerformLayout (this, "LayoutStyle"); this.OnLayoutStyleChanged (EventArgs.Empty); } } @@ -434,7 +473,7 @@ namespace System.Windows.Forms if (this.renderer != value) { this.renderer = value; this.render_mode = ToolStripRenderMode.Custom; - this.PerformLayout (); + this.PerformLayout (this, "Renderer"); this.OnRendererChanged (EventArgs.Empty); } } @@ -448,9 +487,11 @@ namespace System.Windows.Forms 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) + else if (value == ToolStripRenderMode.Professional) this.Renderer = new ToolStripProfessionalRenderer (); - + else if (value == ToolStripRenderMode.System) + this.Renderer = new ToolStripSystemRenderer (); + this.render_mode = value; } } @@ -471,7 +512,27 @@ namespace System.Windows.Forms [DispId(-516)] public new bool TabStop { get { return base.TabStop; } - set { base.TabStop = value; } + set { + base.TabStop = value; + SetStyle (ControlStyles.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)] @@ -489,13 +550,23 @@ namespace System.Windows.Forms 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 Control GetChildAtPoint (Point point) { return base.GetChildAtPoint (point); } + + [EditorBrowsable (EditorBrowsableState.Never)] + public new Control GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue) + { + return base.GetChildAtPoint (pt, skipValue); + } public ToolStripItem GetItemAt (Point point) { @@ -597,12 +668,12 @@ namespace System.Windows.Forms return current_best; } + [EditorBrowsable (EditorBrowsableState.Never)] public void ResetMinimumSize () { this.MinimumSize = new Size (-1, -1); } - [Browsable (false)] [EditorBrowsable (EditorBrowsableState.Never)] public new void SetAutoScrollMargin (int x, int y) { @@ -618,11 +689,7 @@ namespace System.Windows.Forms #region Protected Methods protected override AccessibleObject CreateAccessibilityInstance () { - AccessibleObject ao = new AccessibleObject (this); - - ao.role = AccessibleRole.ToolBar; - - return ao; + return new ToolStripAccessibleObject (this); } protected override ControlCollection CreateControlsInstance () @@ -645,7 +712,7 @@ namespace System.Windows.Forms { switch (layoutStyle) { case ToolStripLayoutStyle.Flow: - return new FlowLayoutSettings (); + return new FlowLayoutSettings (this); case ToolStripLayoutStyle.Table: //return new TableLayoutSettings (); case ToolStripLayoutStyle.StackWithOverflow: @@ -659,16 +726,47 @@ namespace System.Windows.Forms protected override void Dispose (bool disposing) { if (!IsDisposed) { - ToolStripManager.RemoveToolStrip (this); + + 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); @@ -709,10 +807,13 @@ namespace System.Windows.Forms protected internal virtual void OnItemAdded (ToolStripItemEventArgs e) { - e.Item.Available = true; + if (e.Item.InternalVisible) + e.Item.Available = true; + e.Item.SetPlacement (ToolStripItemPlacement.Main); - this.DoAutoSize (); - this.PerformLayout (); + + if (this.Created) + this.PerformLayout (); ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]); if (eh != null) @@ -721,7 +822,8 @@ namespace System.Windows.Forms protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e) { - ToolStripManager.SetActiveToolStrip (null); + if (this.KeyboardActive) + ToolStripManager.SetActiveToolStrip (null, false); ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]); if (eh != null) @@ -737,7 +839,6 @@ namespace System.Windows.Forms protected override void OnLayout (LayoutEventArgs e) { - DoAutoSize (); base.OnLayout (e); this.SetDisplayedItems (); @@ -778,22 +879,22 @@ namespace System.Windows.Forms { if (mouse_currently_over != null) { - if (this is MenuStrip && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) { - if (!menu_selected) - (this as MenuStrip).FireMenuActivate (); - - return; - } - - mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown); - + 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 { - if (this is MenuStrip) - this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked); + this.Dismiss (ToolStripDropDownCloseReason.AppClicked); } if (this is MenuStrip) @@ -860,16 +961,17 @@ namespace System.Windows.Forms protected override void OnMouseUp (MouseEventArgs mea) { // If we're currently over an item (set in MouseMove) - if (mouse_currently_over != null) { + if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) { + // Fire our ItemClicked event + OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over)); + // Fire the item's MouseUp event - mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp); + 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; - - // Fire our ItemClicked event - OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over)); } base.OnMouseUp (mea); @@ -883,10 +985,14 @@ namespace System.Windows.Forms this.OnPaintGrip (e); // Make each item draw itself - foreach (ToolStripItem tsi in this.displayed_items) { - e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top); - tsi.FireEvent (e, ToolStripItemEventType.Paint); - e.Graphics.ResetTransform (); + 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 @@ -896,33 +1002,23 @@ namespace System.Windows.Forms e.Graphics.ResetTransform (); } - Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size); - Rectangle connected_area = Rectangle.Empty; - - if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown) - connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2); + Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size); ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty); - pevent.InternalConnectedArea = connected_area; + pevent.InternalConnectedArea = CalculateConnectedArea (); this.Renderer.DrawToolStripBorder (pevent); } [EditorBrowsable (EditorBrowsableState.Advanced)] - protected override void OnPaintBackground (PaintEventArgs pevent) + protected override void OnPaintBackground (PaintEventArgs e) { - base.OnPaintBackground (pevent); - - Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size); - Rectangle connected_area = Rectangle.Empty; + base.OnPaintBackground (e); - if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown) - connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2); - - ToolStripRenderEventArgs e = new ToolStripRenderEventArgs (pevent.Graphics, this, affected_bounds, Color.Empty); - e.InternalConnectedArea = connected_area; + Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size); + ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control); - this.Renderer.DrawToolStripBackground (e); + this.Renderer.DrawToolStripBackground (tsrea); } protected internal virtual void OnPaintGrip (PaintEventArgs e) @@ -974,16 +1070,22 @@ namespace System.Windows.Forms protected override void OnVisibleChanged (EventArgs e) { + if (!Visible) + CloseToolTip (null); + base.OnVisibleChanged (e); } - protected override bool ProcessCmdKey (ref Message msg, Keys keyData) + protected override bool ProcessCmdKey (ref Message m, Keys keyData) { - return base.ProcessCmdKey (ref msg, 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)) @@ -993,10 +1095,44 @@ namespace System.Windows.Forms if (this.ProcessArrowKey (keyData)) return true; + ToolStrip ts = null; + switch (keyData) { case Keys.Escape: this.Dismiss (ToolStripDropDownCloseReason.Keyboard); return true; + + case Keys.Control | 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.Control | 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 ToolStripControlHost) + return false; + break; } return base.ProcessDialogKey (keyData); @@ -1004,8 +1140,36 @@ namespace System.Windows.Forms 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) && Control.IsMnemonic (charCode, tsi.Text)) + return tsi.ProcessMnemonic (charCode); + + string code = Char.ToUpper (charCode).ToString (); + + // If any item's text starts with our letter, it gets the message + if ((Control.ModifierKeys & Keys.Alt) != 0 || this is ToolStripDropDownMenu) + foreach (ToolStripItem tsi in this.Items) + if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code) && !(tsi is ToolStripControlHost)) + return tsi.ProcessMnemonic (charCode); + 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) { @@ -1014,7 +1178,7 @@ namespace System.Windows.Forms protected virtual void SetDisplayedItems () { - this.displayed_items.Clear (); + this.displayed_items.ClearInternal (); foreach (ToolStripItem tsi in this.items) if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) { @@ -1041,20 +1205,20 @@ namespace System.Windows.Forms protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent) { - if (item.Parent != null) { - item.Parent.Items.RemoveNoOwnerOrLayout (item); - - if (item.Parent is ToolStripOverflow) - (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item); + 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 value) + protected override void SetVisibleCore (bool visible) { - base.SetVisibleCore (value); + base.SetVisibleCore (visible); } protected override void WndProc (ref Message m) @@ -1064,6 +1228,8 @@ namespace System.Windows.Forms #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 (); @@ -1079,6 +1245,12 @@ namespace System.Windows.Forms 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; } @@ -1086,12 +1258,14 @@ namespace System.Windows.Forms } [Browsable (false)] + [EditorBrowsable (EditorBrowsableState.Never)] public new event ControlEventHandler ControlAdded { add { base.ControlAdded += value; } remove { base.ControlAdded -= value; } } [Browsable (false)] + [EditorBrowsable (EditorBrowsableState.Never)] public new event ControlEventHandler ControlRemoved { add { base.ControlRemoved += value; } remove { base.ControlRemoved -= value; } @@ -1103,6 +1277,12 @@ namespace System.Windows.Forms 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; } @@ -1155,23 +1335,41 @@ namespace System.Windows.Forms if (value) Application.KeyboardCapture = this; - else if (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.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 ToolStripControlHost)) + this.FocusInternal (true); + + if (nextItem is ToolStripControlHost) + (nextItem as ToolStripControlHost).Focus (); + nextItem.Select (); if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown) @@ -1194,15 +1392,9 @@ namespace System.Windows.Forms // Make sure all of our items are deselected and repainted foreach (ToolStripItem tsi in this.Items) tsi.Dismiss (reason); - } - - private void DoAutoSize () - { - if (this.AutoSize == true && this.Dock == DockStyle.None) - this.Size = GetPreferredSize (Size.Empty); - if (this.AutoSize == true && this.Orientation == Orientation.Horizontal && (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom)) - this.Height = GetPreferredSize (Size.Empty).Height; + // We probably need to redraw for mnemonic underlines + this.Invalidate (); } internal ToolStripItem GetCurrentlySelectedItem () @@ -1214,30 +1406,91 @@ namespace System.Windows.Forms return null; } - public override Size GetPreferredSize (Size proposedSize) + internal ToolStripItem GetCurrentlyFocusedItem () + { + foreach (ToolStripItem tsi in this.DisplayedItems) + if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused) + return tsi; + + return null; + } + + internal override Size GetPreferredSizeCore (Size proposedSize) + { + return GetToolStripPreferredSize (proposedSize); + } + + internal virtual Size GetToolStripPreferredSize (Size proposedSize) { - Size new_size = new Size (0, this.Height); + 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 control 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.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom > new_size.Height) - new_size.Height = tsi.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom; + if (tsi.Available) { + Size tsi_preferred = tsi.GetPreferredSize (Size.Empty); + new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom; - new_size.Height += this.Padding.Top + this.Padding.Bottom; - new_size.Width = this.Width; + 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)) - new_size.Height = (this.Padding.Vertical + tsi_preferred.Height); + 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; - new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4); - return new_size; + if (this is StatusStrip) + new_size.Height = Math.Max (new_size.Height, 22); + + return new_size; + } } internal virtual ToolStrip GetTopLevelToolStrip () @@ -1245,23 +1498,11 @@ namespace System.Windows.Forms return this; } - internal void HandleItemClick (ToolStripItem dismissingItem) + internal virtual void HandleItemClick (ToolStripItem dismissingItem) { this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked); - this.OnItemClicked (new ToolStripItemClickedEventArgs (dismissingItem)); } - internal void HideMenus (bool release, ToolStripDropDownCloseReason reason) - { - if (this is MenuStrip && release && menu_selected) - (this as MenuStrip).FireMenuDeactivate (); - - if (release) - menu_selected = false; - - NotifySelectedChanged (null); - } - internal void NotifySelectedChanged (ToolStripItem tsi) { foreach (ToolStripItem tsi2 in this.DisplayedItems) @@ -1292,49 +1533,101 @@ namespace System.Windows.Forms internal virtual bool ProcessArrowKey (Keys keyData) { + ToolStripItem tsi; + switch (keyData) { case Keys.Right: + tsi = this.GetCurrentlySelectedItem (); + + if (tsi is ToolStripControlHost) + return false; + + tsi = this.SelectNextToolStripItem (tsi, true); + + if (tsi is ToolStripControlHost) + (tsi as ToolStripControlHost).Focus (); + + return true; case Keys.Tab: - this.SelectNextToolStripItem (this.GetCurrentlySelectedItem (), true); + tsi = this.GetCurrentlySelectedItem (); + + tsi = this.SelectNextToolStripItem (tsi, true); + + if (tsi is ToolStripControlHost) + (tsi as ToolStripControlHost).Focus (); + return true; case Keys.Left: + tsi = this.GetCurrentlySelectedItem (); + + if (tsi is ToolStripControlHost) + return false; + + tsi = this.SelectNextToolStripItem (tsi, false); + + if (tsi is ToolStripControlHost) + (tsi as ToolStripControlHost).Focus (); + + return true; case Keys.Shift | Keys.Tab: - this.SelectNextToolStripItem (this.GetCurrentlySelectedItem (), false); + tsi = this.GetCurrentlySelectedItem (); + + tsi = this.SelectNextToolStripItem (tsi, false); + + if (tsi is ToolStripControlHost) + (tsi as ToolStripControlHost).Focus (); + return true; } return false; } - internal virtual void SelectNextToolStripItem (ToolStripItem start, bool forward) + 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 ToolStripControlHost) + (next_item as ToolStripControlHost).Focus (); + + return next_item; } #region Stuff for ToolTips private void MouseEnteredItem (ToolStripItem item) { - if (this.show_item_tool_tips) { + 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 MouseLeftItem (ToolStripItem item) + + private void CloseToolTip (ToolStripItem item) { ToolTipTimer.Stop (); - ToolTipWindow.Hide (); + 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 = 500; + tooltip_timer.Interval = InitialToolTipDelay; tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick); } @@ -1342,25 +1635,41 @@ namespace System.Windows.Forms } } - private ToolTip.ToolTipWindow ToolTipWindow { + private ToolTip ToolTipWindow { get { if (tooltip_window == null) - tooltip_window = new ToolTip.ToolTipWindow (); + tooltip_window = new ToolTip (); return tooltip_window; } } - private void ToolTipTimer_Tick (object o, EventArgs args) + private void ShowToolTip () { string tooltip = tooltip_currently_showing.GetToolTip (); - if (!string.IsNullOrEmpty (tooltip)) + 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 @@ -1401,10 +1710,6 @@ namespace System.Windows.Forms foreach (ToolStripItem tsi in this.Items) this.pre_merge_items.Add (tsi); } - - if (this is MenuStrip) - foreach (ToolStripMenuItem tsmi in this.Items) - tsmi.DropDown.BeginMerge (); } } @@ -1441,6 +1746,40 @@ namespace System.Windows.Forms } #endregion #endregion + + #region ToolStripAccessibleObject + [ComVisible (true)] + public class ToolStripAccessibleObject : ControlAccessibleObject + { + #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 } } -#endif