Merge pull request #268 from pcc/menudeactivate
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStrip.cs
index 13be4db4e6eed4c5fd08933d2d4be5569e0160fb..30c0d89f5fb40633ee7a05e3dc555e6408b74e67 100644 (file)
@@ -26,7 +26,6 @@
 //     Jonathan Pobst (monkey@jpobst.com)
 //
 
-#if NET_2_0
 using System;
 using System.Runtime.InteropServices;
 using System.ComponentModel;
@@ -79,6 +78,10 @@ namespace System.Windows.Forms
                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
@@ -127,13 +130,13 @@ namespace System.Windows.Forms
                #endregion
 
                #region Public Properties
-               [MonoTODO ()]
+               [MonoTODO ("Stub, does nothing")]
                public override bool AllowDrop {
                        get { return base.AllowDrop; }
                        set { base.AllowDrop = value; }
                }
-               
-               [MonoTODO ()]
+
+               [MonoTODO ("Stub, does nothing")]
                [DefaultValue (false)]
                public bool AllowItemReorder {
                        get { return this.allow_item_reorder; }
@@ -335,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");
                                }
                        }
                }
@@ -403,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)]
@@ -435,7 +443,7 @@ namespace System.Windows.Forms
                                                
                                        this.layout_settings = this.CreateLayoutSettings (value);
                                        
-                                       this.PerformLayout ();
+                                       this.PerformLayout (this, "LayoutStyle");
                                        this.OnLayoutStyleChanged (EventArgs.Empty);
                                }
                        }
@@ -465,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);
                                }
                        }
@@ -704,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:
@@ -718,18 +726,27 @@ namespace System.Windows.Forms
                protected override void Dispose (bool disposing)
                {
                        if (!IsDisposed) {
-                               foreach (ToolStripItem tsi in Items)
-                                       tsi.Dispose ();
-                                       
-                               if (this.overflow_button != null && this.overflow_button.drop_down != null)
-                                       this.overflow_button.drop_down.Dispose ();
 
-                               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 ("Not called")]
+               [MonoTODO ("Stub, never called")]
                protected virtual void OnBeginDrag (EventArgs e)
                {
                        EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
@@ -742,7 +759,7 @@ namespace System.Windows.Forms
                        base.OnDockChanged (e);
                }
 
-               [MonoTODO ("Not called")]
+               [MonoTODO ("Stub, never called")]
                protected virtual void OnEndDrag (EventArgs e)
                {
                        EventHandler eh = (EventHandler)(Events[EndDragEvent]);
@@ -867,22 +884,17 @@ namespace System.Windows.Forms
                                if (focused != null && focused != mouse_currently_over)
                                        this.FocusInternal (true);
 
-                               if (this is MenuStrip && mouse_currently_over is ToolStripMenuItem && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) {
-                                       if (!menu_selected)
-                                               (this as MenuStrip).FireMenuActivate ();
-                                       
-                                       return;
-                               }
-                                       
-                               mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
-                               
                                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)
@@ -973,7 +985,9 @@ namespace System.Windows.Forms
                        this.OnPaintGrip (e);
 
                        // Make each item draw itself
-                       foreach (ToolStripItem tsi in this.displayed_items) {
+                       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);
@@ -1056,6 +1070,9 @@ namespace System.Windows.Forms
 
                protected override void OnVisibleChanged (EventArgs e)
                {
+                       if (!Visible)
+                               CloseToolTip (null);
+
                        base.OnVisibleChanged (e);
                }
 
@@ -1131,21 +1148,20 @@ namespace System.Windows.Forms
                        string code = Char.ToUpper (charCode).ToString ();
                        
                        // If any item's text starts with our letter, it gets the message
-                       if (this is ToolStripDropDownMenu)
+                       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 ()]
+
+               [MonoTODO ("Stub, does nothing")]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                protected virtual void RestoreFocus ()
                {
                }
 
-               [MonoTODO ()]
                protected override void Select (bool directed, bool forward)
                {
                        foreach (ToolStripItem tsi in this.DisplayedItems)
@@ -1162,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) {
@@ -1229,7 +1245,7 @@ namespace System.Windows.Forms
                        remove { base.AutoSizeChanged -= value; }
                }
 
-               [MonoTODO ()]
+               [MonoTODO ("Event never raised")]
                public event EventHandler BeginDrag {
                        add { Events.AddHandler (BeginDragEvent, value); }
                        remove { Events.RemoveHandler (BeginDragEvent, value); }
@@ -1261,7 +1277,7 @@ namespace System.Windows.Forms
                        remove { base.CursorChanged -= value; }
                }
 
-               [MonoTODO ()]
+               [MonoTODO ("Event never raised")]
                public event EventHandler EndDrag {
                        add { Events.AddHandler (EndDragEvent, value); }
                        remove { Events.RemoveHandler (EndDragEvent, value); }
@@ -1415,25 +1431,28 @@ namespace System.Windows.Forms
                                Point currentLocation = Point.Empty;
                                int tallest = 0;
                                
-                               foreach (ToolStripItem tsi in items) {
-                                       if ((DisplayRectangle.Width - currentLocation.X) < (tsi.Width + tsi.Margin.Horizontal)) {
+                               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.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);
                                                
-                                               currentLocation.X = DisplayRectangle.Left;
+                                               // Update our location pointer
+                                               currentLocation.X += tsi_preferred.Width + tsi.Margin.Right;
                                        }
 
-                                       // Offset the left margin and set the control to our point
-                                       currentLocation.Offset (tsi.Margin.Left, 0);
-                                       tallest = Math.Max (tallest, tsi.Height + tsi.Margin.Vertical);
-                                       
-                                       // Update our location pointer
-                                       currentLocation.X += tsi.Width + tsi.Margin.Right;
-                               }
-
                                currentLocation.Y += tallest;
-                               return new Size (currentLocation.X, currentLocation.Y);
+                               return new Size (currentLocation.X + this.Padding.Horizontal, currentLocation.Y + this.Padding.Vertical);
                        }
                                
                        if (this.orientation == Orientation.Vertical) {
@@ -1484,17 +1503,6 @@ namespace System.Windows.Forms
                        this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
                }
                
-               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)
@@ -1594,24 +1602,32 @@ namespace System.Windows.Forms
                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 MouseLeftItem (ToolStripItem item)
+       
+               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 = 500;
+                                       tooltip_timer.Interval = InitialToolTipDelay;
                                        tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
                                }
                                
@@ -1628,16 +1644,32 @@ namespace System.Windows.Forms
                        }
                }
                
-               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
 
@@ -1751,4 +1783,3 @@ namespace System.Windows.Forms
                #endregion
        }
 }
-#endif