4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2006 Jonathan Pobst
26 // Jonathan Pobst (monkey@jpobst.com)
31 using System
.Runtime
.InteropServices
;
32 using System
.ComponentModel
;
34 using System
.Windows
.Forms
.Layout
;
36 namespace System
.Windows
.Forms
39 [ClassInterface (ClassInterfaceType
.AutoDispatch
)]
40 [DefaultEvent ("ItemClicked")]
41 [DefaultProperty ("Items")]
42 public class ToolStrip
: ScrollableControl
, IComponent
, IDisposable
44 #region Private Variables
45 private Color back_color
;
46 private bool can_overflow
;
47 private ToolStripDropDownDirection default_drop_down_direction
;
48 internal ToolStripItemCollection displayed_items
;
49 private Color fore_color
;
50 private Padding grip_margin
;
51 private ToolStripGripStyle grip_style
;
52 private ImageList image_list
;
53 private Size image_scaling_size
;
54 private ToolStripItemCollection items
;
55 private LayoutEngine layout_engine
;
56 private LayoutSettings layout_settings
;
57 private ToolStripLayoutStyle layout_style
;
58 private Orientation orientation
;
59 private ToolStripOverflowButton overflow_button
;
60 private ToolStripRenderer renderer
;
61 private ToolStripRenderMode render_mode
;
62 private bool show_item_tool_tips
;
65 private ToolStripItem mouse_currently_over
;
66 private bool menu_selected
;
69 #region Public Constructors
70 public ToolStrip () : this (null)
74 public ToolStrip (params ToolStripItem
[] items
) : base ()
76 SetStyle (ControlStyles
.AllPaintingInWmPaint
, true);
77 SetStyle (ControlStyles
.OptimizedDoubleBuffer
, true);
78 SetStyle (ControlStyles
.Selectable
, false);
79 SetStyle (ControlStyles
.SupportsTransparentBackColor
, true);
81 this.SuspendLayout ();
82 this.items
= new ToolStripItemCollection (this, items
);
84 this.back_color
= Control
.DefaultBackColor
;
85 this.can_overflow
= true;
86 base.CausesValidation
= false;
87 this.default_drop_down_direction
= ToolStripDropDownDirection
.BelowRight
;
88 this.displayed_items
= new ToolStripItemCollection (this, null);
89 this.Dock
= this.DefaultDock
;
90 base.Font
= new Font ("Tahoma", 8.25f
);
91 this.fore_color
= Control
.DefaultForeColor
;
92 this.grip_margin
= this.DefaultGripMargin
;
93 this.grip_style
= ToolStripGripStyle
.Visible
;
94 this.image_scaling_size
= new Size (16, 16);
95 this.layout_engine
= new ToolStripSplitStackLayout ();
96 this.layout_style
= ToolStripLayoutStyle
.HorizontalStackWithOverflow
;
97 this.orientation
= Orientation
.Horizontal
;
98 if (!(this is ToolStripDropDown
))
99 this.overflow_button
= new ToolStripOverflowButton (this);
100 this.Padding
= this.DefaultPadding
;
101 this.renderer
= null;
102 this.render_mode
= ToolStripRenderMode
.ManagerRenderMode
;
103 this.show_item_tool_tips
= this.DefaultShowItemToolTips
;
104 base.TabStop
= false;
105 this.ResumeLayout ();
108 // Register with the ToolStripManager
109 ToolStripManager
.AddToolStrip (this);
113 #region Public Properties
114 public override AnchorStyles Anchor
{
115 get { return base.Anchor; }
118 base.dock_style
= DockStyle
.None
;
122 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Visible
)]
124 [EditorBrowsable (EditorBrowsableState
.Always
)]
125 [DefaultValue (true)]
126 public override bool AutoSize
{
127 get { return base.AutoSize; }
128 set { base.AutoSize = value; }
131 new public Color BackColor
{
132 get { return this.back_color; }
133 set { this.back_color = value; }
136 [DefaultValue (true)]
137 public bool CanOverflow
{
138 get { return this.can_overflow; }
139 set { this.can_overflow = value; }
143 [DefaultValue (false)]
144 public new bool CausesValidation
{
145 get { return base.CausesValidation; }
146 set { base.CausesValidation = value; }
149 [EditorBrowsable (EditorBrowsableState
.Never
)]
150 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
151 public new ControlCollection Controls
{
152 get { return base.Controls; }
156 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
157 public override Cursor Cursor
{
158 get { return base.Cursor; }
159 set { base.Cursor = value; }
163 public virtual ToolStripDropDownDirection DefaultDropDownDirection
{
164 get { return this.default_drop_down_direction; }
166 if (!Enum
.IsDefined (typeof (ToolStripDropDownDirection
), value))
167 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
169 this.default_drop_down_direction
= value;
173 public override Rectangle DisplayRectangle
{
175 if (this.orientation
== Orientation
.Horizontal
)
176 if (this.grip_style
== ToolStripGripStyle
.Hidden
|| this.layout_style
== ToolStripLayoutStyle
.Flow
|| this.layout_style
== ToolStripLayoutStyle
.Table
)
177 return new Rectangle (this.Padding
.Left
, this.Padding
.Top
, this.Width
- this.Padding
.Horizontal
, this.Height
- this.Padding
.Vertical
);
179 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
);
181 if (this.grip_style
== ToolStripGripStyle
.Hidden
|| this.layout_style
== ToolStripLayoutStyle
.Flow
|| this.layout_style
== ToolStripLayoutStyle
.Table
)
182 return new Rectangle (this.Padding
.Left
, this.Padding
.Top
, this.Width
- this.Padding
.Horizontal
, this.Height
- this.Padding
.Vertical
);
184 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
);
188 [DefaultValue (DockStyle
.Top
)]
189 public override DockStyle Dock
{
190 get { return base.Dock; }
192 if (base.Dock
!= value) {
193 if (!Enum
.IsDefined (typeof (DockStyle
), value))
194 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for DockStyle", value));
196 base.anchor_style
= AnchorStyles
.Left
| AnchorStyles
.Top
;
200 case DockStyle
.Bottom
:
202 this.LayoutStyle
= ToolStripLayoutStyle
.HorizontalStackWithOverflow
;
205 case DockStyle
.Right
:
206 this.LayoutStyle
= ToolStripLayoutStyle
.VerticalStackWithOverflow
;
215 public override Font Font
{
216 get { return base.Font; }
218 if (base.Font
!= value) {
221 foreach (ToolStripItem tsi
in this.Items
)
222 tsi
.OnOwnerFontChanged (EventArgs
.Empty
);
228 public new Color ForeColor
{
229 get { return this.fore_color; }
231 if (this.fore_color
!= value) {
232 this.fore_color
= value;
233 this.OnForeColorChanged (EventArgs
.Empty
);
239 public ToolStripGripDisplayStyle GripDisplayStyle
{
240 get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; }
243 public Padding GripMargin
{
244 get { return this.grip_margin; }
246 if (this.grip_margin
!= value) {
247 this.grip_margin
= value;
248 this.PerformLayout ();
254 public Rectangle GripRectangle
{
256 if (this.grip_style
== ToolStripGripStyle
.Hidden
)
257 return Rectangle
.Empty
;
259 if (this.orientation
== Orientation
.Horizontal
)
260 return new Rectangle (this.grip_margin
.Left
+ this.Padding
.Left
, this.Padding
.Top
, 3, this.Height
);
262 return new Rectangle (this.Padding
.Left
, this.grip_margin
.Top
+ this.Padding
.Top
, this.Width
, 3);
266 [DefaultValue (ToolStripGripStyle
.Visible
)]
267 public ToolStripGripStyle GripStyle
{
268 get { return this.grip_style; }
270 if (this.grip_style
!= value) {
271 if (!Enum
.IsDefined (typeof (ToolStripGripStyle
), value))
272 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value));
273 this.grip_style
= value;
274 this.PerformLayout ();
280 [EditorBrowsable (EditorBrowsableState
.Never
)]
281 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
282 public new bool HasChildren
{
283 get { return base.HasChildren; }
287 [DefaultValue (null)]
288 public ImageList ImageList
{
289 get { return this.image_list; }
290 set { this.image_list = value; }
293 [DefaultValue ("{Width=16, Height=16}")]
294 public Size ImageScalingSize
{
295 get { return this.image_scaling_size; }
296 set { this.image_scaling_size = value; }
299 [MonoTODO ("Always returns false, dragging not implemented yet.")]
301 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
302 public bool IsCurrentlyDragging
{
303 get { return false; }
307 public bool IsDropDown
{
309 if (this is ToolStripDropDown
)
316 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Content
)]
317 public virtual ToolStripItemCollection Items
{
318 get { return this.items; }
321 public override LayoutEngine LayoutEngine
{
322 get { return this.layout_engine;; }
326 [DefaultValue (null)]
327 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
328 public LayoutSettings LayoutSettings
{
329 get { return this.layout_settings; }
330 set { this.layout_settings = value; }
333 [AmbientValue (ToolStripLayoutStyle
.StackWithOverflow
)]
334 public ToolStripLayoutStyle LayoutStyle
{
335 get { return layout_style; }
337 if (this.layout_style
!= value) {
338 if (!Enum
.IsDefined (typeof (ToolStripLayoutStyle
), value))
339 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value));
341 this.layout_style
= value;
343 if (this.layout_style
== ToolStripLayoutStyle
.Flow
)
344 this.layout_engine
= new FlowLayout ();
346 this.layout_engine
= new ToolStripSplitStackLayout ();
348 if (this.layout_style
== ToolStripLayoutStyle
.StackWithOverflow
) {
349 if (this.Dock
== DockStyle
.Left
|| this.Dock
== DockStyle
.Right
)
350 this.layout_style
= ToolStripLayoutStyle
.VerticalStackWithOverflow
;
352 this.layout_style
= ToolStripLayoutStyle
.HorizontalStackWithOverflow
;
355 if (this.layout_style
== ToolStripLayoutStyle
.HorizontalStackWithOverflow
)
356 this.orientation
= Orientation
.Horizontal
;
357 else if (this.layout_style
== ToolStripLayoutStyle
.VerticalStackWithOverflow
)
358 this.orientation
= Orientation
.Vertical
;
360 this.layout_settings
= this.CreateLayoutSettings (value);
362 this.PerformLayout ();
363 this.OnLayoutStyleChanged (EventArgs
.Empty
);
369 public Orientation Orientation
{
370 get { return this.orientation; }
374 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
375 public ToolStripOverflowButton OverflowButton
{
376 get { return this.overflow_button; }
380 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
381 public ToolStripRenderer Renderer
{
383 if (this.render_mode
== ToolStripRenderMode
.ManagerRenderMode
)
384 return ToolStripManager
.Renderer
;
386 return this.renderer
;
389 if (this.renderer
!= value) {
390 this.renderer
= value;
391 this.render_mode
= ToolStripRenderMode
.Custom
;
392 this.PerformLayout ();
393 this.OnRendererChanged (EventArgs
.Empty
);
398 public ToolStripRenderMode RenderMode
{
399 get { return this.render_mode; }
401 if (!Enum
.IsDefined (typeof (ToolStripRenderMode
), value))
402 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
404 if (value == ToolStripRenderMode
.Custom
&& this.renderer
== null)
405 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
406 if (value == ToolStripRenderMode
.Professional
|| value == ToolStripRenderMode
.System
)
407 this.Renderer
= new ToolStripProfessionalRenderer ();
409 this.render_mode
= value;
413 [MonoTODO ("Need 2.0 ToolTip to implement tool tips.")]
414 [DefaultValue (true)]
415 public bool ShowItemToolTips
{
416 get { return this.show_item_tool_tips; }
417 set { this.show_item_tool_tips = value; }
420 [DefaultValue (false)]
421 public bool Stretch
{
422 get { return this.stretch; }
423 set { this.stretch = value; }
426 [DefaultValue (false)]
428 public new bool TabStop
{
429 get { return base.TabStop; }
430 set { base.TabStop = value; }
434 #region Protected Properties
435 protected virtual DockStyle DefaultDock { get { return DockStyle.Top; }
}
436 protected virtual Padding DefaultGripMargin { get { return new Padding (2); }
}
437 protected override Padding DefaultMargin { get { return Padding.Empty; }
}
438 protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); }
}
439 protected virtual bool DefaultShowItemToolTips { get { return true; }
}
440 protected override Size DefaultSize { get { return new Size (100, 25); }
}
441 protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; }
}
444 #region Public Methods
446 public new Control
GetChildAtPoint (Point point
)
448 return base.GetChildAtPoint (point
);
451 public ToolStripItem
GetItemAt (Point point
)
453 foreach (ToolStripItem tsi
in this.displayed_items
)
454 if (tsi
.Visible
&& tsi
.Bounds
.Contains (point
))
460 public ToolStripItem
GetItemAt (int x
, int y
)
462 return GetItemAt (new Point (x
, y
));
465 public virtual ToolStripItem
GetNextItem (ToolStripItem start
, ArrowDirection direction
)
467 if (!Enum
.IsDefined (typeof (ArrowDirection
), direction
))
468 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction
));
470 int index
= this.items
.IndexOf (start
);
473 case ArrowDirection
.Left
:
474 case ArrowDirection
.Up
:
476 return this.items
[index
- 1];
478 return this.items
[this.items
.Count
- 1];
479 case ArrowDirection
.Right
:
480 case ArrowDirection
.Down
:
481 if (index
+ 1 >= this.items
.Count
)
482 return this.items
[0];
484 return this.items
[index
+ 1];
490 public override string ToString ()
492 return String
.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name
, this.items
.Count
.ToString ());
496 #region Protected Methods
497 protected override AccessibleObject
CreateAccessibilityInstance ()
499 AccessibleObject ao
= new AccessibleObject (this);
501 ao
.role
= AccessibleRole
.ToolBar
;
506 protected override ControlCollection
CreateControlsInstance ()
508 return base.CreateControlsInstance ();
511 protected internal virtual ToolStripItem
CreateDefaultItem (string text
, Image image
, EventHandler onClick
)
514 return new ToolStripSeparator ();
516 if (this is ToolStripDropDown
)
517 return new ToolStripMenuItem (text
, image
, onClick
);
519 return new ToolStripButton (text
, image
, onClick
);
522 protected virtual LayoutSettings
CreateLayoutSettings (ToolStripLayoutStyle layoutStyle
)
524 switch (layoutStyle
) {
525 case ToolStripLayoutStyle
.Flow
:
526 return new FlowLayoutSettings ();
527 case ToolStripLayoutStyle
.Table
:
528 //return new TableLayoutSettings ();
529 case ToolStripLayoutStyle
.StackWithOverflow
:
530 case ToolStripLayoutStyle
.HorizontalStackWithOverflow
:
531 case ToolStripLayoutStyle
.VerticalStackWithOverflow
:
537 protected override void Dispose (bool disposing
)
540 ToolStripManager
.RemoveToolStrip (this);
541 base.Dispose (disposing
);
545 protected override void OnDockChanged (EventArgs e
)
547 base.OnDockChanged (e
);
550 protected override void OnEnabledChanged (EventArgs e
)
552 base.OnEnabledChanged (e
);
554 foreach (ToolStripItem tsi
in this.Items
)
555 tsi
.OnParentEnabledChanged (EventArgs
.Empty
);
558 protected override void OnFontChanged (EventArgs e
)
560 base.OnFontChanged (e
);
563 protected override void OnHandleCreated (EventArgs e
)
565 base.OnHandleCreated (e
);
568 protected override void OnHandleDestroyed (EventArgs e
)
570 base.OnHandleDestroyed (e
);
573 protected override void OnInvalidated (InvalidateEventArgs e
)
575 base.OnInvalidated (e
);
578 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e
)
581 this.PerformLayout ();
583 ToolStripItemEventHandler eh
= (ToolStripItemEventHandler
)(Events
[ItemAddedEvent
]);
588 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e
)
590 ToolStripItemClickedEventHandler eh
= (ToolStripItemClickedEventHandler
)(Events
[ItemClickedEvent
]);
595 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e
)
597 ToolStripItemEventHandler eh
= (ToolStripItemEventHandler
)(Events
[ItemRemovedEvent
]);
602 protected override void OnLayout (LayoutEventArgs e
)
607 this.SetDisplayedItems ();
608 this.OnLayoutCompleted (EventArgs
.Empty
);
612 protected virtual void OnLayoutCompleted (EventArgs e
)
614 EventHandler eh
= (EventHandler
)(Events
[LayoutCompletedEvent
]);
619 protected virtual void OnLayoutStyleChanged (EventArgs e
)
621 EventHandler eh
= (EventHandler
)(Events
[LayoutStyleChangedEvent
]);
626 protected override void OnLeave (EventArgs e
)
631 protected override void OnLostFocus (EventArgs e
)
633 base.OnLostFocus (e
);
636 protected override void OnMouseDown (MouseEventArgs mea
)
638 if (mouse_currently_over
!= null)
640 if (this is MenuStrip
&& !(mouse_currently_over
as ToolStripMenuItem
).HasDropDownItems
) {
642 (this as MenuStrip
).FireMenuActivate ();
647 mouse_currently_over
.FireEvent (mea
, ToolStripItemEventType
.MouseDown
);
649 if (this is MenuStrip
&& !menu_selected
) {
650 (this as MenuStrip
).FireMenuActivate ();
651 menu_selected
= true;
654 if (this is MenuStrip
)
655 this.HideMenus (true, ToolStripDropDownCloseReason
.AppClicked
);
658 if (this is MenuStrip
)
659 this.Capture
= false;
661 base.OnMouseDown (mea
);
664 protected override void OnMouseLeave (EventArgs e
)
666 if (mouse_currently_over
!= null) {
667 mouse_currently_over
.FireEvent (e
, ToolStripItemEventType
.MouseLeave
);
668 mouse_currently_over
= null;
671 base.OnMouseLeave (e
);
674 protected override void OnMouseMove (MouseEventArgs mea
)
677 // Find the item we are now
678 if (this.overflow_button
!= null && this.overflow_button
.Visible
&& this.overflow_button
.Bounds
.Contains (mea
.Location
))
679 tsi
= this.overflow_button
;
681 tsi
= this.GetItemAt (mea
.X
, mea
.Y
);
684 // If we were already hovering on this item, just send a mouse move
685 if (tsi
== mouse_currently_over
)
686 tsi
.FireEvent (mea
, ToolStripItemEventType
.MouseMove
);
688 // If we were over a different item, fire a mouse leave on it
689 if (mouse_currently_over
!= null)
690 mouse_currently_over
.FireEvent (mea
, ToolStripItemEventType
.MouseLeave
);
692 // Set the new item we are currently over
693 mouse_currently_over
= tsi
;
695 // Fire mouse enter and mouse move
696 tsi
.FireEvent (mea
, ToolStripItemEventType
.MouseEnter
);
697 tsi
.FireEvent (mea
, ToolStripItemEventType
.MouseMove
);
699 // If we're over something with a drop down, show it
700 if (menu_selected
&& mouse_currently_over
.Enabled
&& mouse_currently_over
is ToolStripDropDownItem
&& (mouse_currently_over
as ToolStripDropDownItem
).HasDropDownItems
)
701 (mouse_currently_over
as ToolStripDropDownItem
).ShowDropDown ();
704 // We're not over anything now, just fire the mouse leave on what we used to be over
705 if (mouse_currently_over
!= null) {
706 mouse_currently_over
.FireEvent (mea
, ToolStripItemEventType
.MouseLeave
);
707 mouse_currently_over
= null;
711 base.OnMouseMove (mea
);
714 protected override void OnMouseUp (MouseEventArgs mea
)
716 // If we're currently over an item (set in MouseMove)
717 if (mouse_currently_over
!= null) {
718 // Fire the item's MouseUp event
719 mouse_currently_over
.FireEvent (mea
, ToolStripItemEventType
.MouseUp
);
721 // The event handler may have blocked until the mouse moved off of the ToolStripItem
722 if (mouse_currently_over
== null)
725 // Fire our ItemClicked event
726 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over
));
729 base.OnMouseUp (mea
);
732 protected override void OnPaint (PaintEventArgs e
)
737 this.OnPaintGrip (e
);
739 // Make each item draw itself
740 foreach (ToolStripItem tsi
in this.displayed_items
) {
741 e
.Graphics
.TranslateTransform (tsi
.Bounds
.Left
, tsi
.Bounds
.Top
);
742 tsi
.FireEvent (e
, ToolStripItemEventType
.Paint
);
743 e
.Graphics
.ResetTransform ();
746 // Paint the Overflow button if it's visible
747 if (this.overflow_button
!= null && this.overflow_button
.Visible
) {
748 e
.Graphics
.TranslateTransform (this.overflow_button
.Bounds
.Left
, this.overflow_button
.Bounds
.Top
);
749 this.overflow_button
.FireEvent (e
, ToolStripItemEventType
.Paint
);
750 e
.Graphics
.ResetTransform ();
753 Rectangle affected_bounds
= new Rectangle (new Point (0, 0), this.Size
);
754 Rectangle connected_area
= Rectangle
.Empty
;
756 if (this is ToolStripDropDown
&& (this as ToolStripDropDown
).OwnerItem
!= null && !(this as ToolStripDropDown
).OwnerItem
.IsOnDropDown
)
757 connected_area
= new Rectangle (1, 0, (this as ToolStripDropDown
).OwnerItem
.Width
- 2, 2);
759 ToolStripRenderEventArgs pevent
= new ToolStripRenderEventArgs (e
.Graphics
, this, affected_bounds
, Color
.Empty
);
760 pevent
.InternalConnectedArea
= connected_area
;
762 this.Renderer
.DrawToolStripBorder (pevent
);
765 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
766 protected override void OnPaintBackground (PaintEventArgs pevent
)
768 base.OnPaintBackground (pevent
);
770 Rectangle affected_bounds
= new Rectangle (new Point (0, 0), this.Size
);
771 Rectangle connected_area
= Rectangle
.Empty
;
773 if (this is ToolStripDropDown
&& (this as ToolStripDropDown
).OwnerItem
!= null && !(this as ToolStripDropDown
).OwnerItem
.IsOnDropDown
)
774 connected_area
= new Rectangle (1, 0, (this as ToolStripDropDown
).OwnerItem
.Width
- 2, 2);
776 ToolStripRenderEventArgs e
= new ToolStripRenderEventArgs (pevent
.Graphics
, this, affected_bounds
, Color
.Empty
);
777 e
.InternalConnectedArea
= connected_area
;
779 this.Renderer
.DrawToolStripBackground (e
);
782 protected internal virtual void OnPaintGrip (PaintEventArgs e
)
784 // Never draw a grip with these two layouts
785 if (this.layout_style
== ToolStripLayoutStyle
.Flow
|| this.layout_style
== ToolStripLayoutStyle
.Table
)
788 PaintEventHandler eh
= (PaintEventHandler
)(Events
[PaintGripEvent
]);
792 if (!(this is MenuStrip
)) {
793 if (this.orientation
== Orientation
.Horizontal
)
794 e
.Graphics
.TranslateTransform (2, 0);
796 e
.Graphics
.TranslateTransform (0, 2);
799 this.Renderer
.DrawGrip (new ToolStripGripRenderEventArgs (e
.Graphics
, this, this.GripRectangle
, this.GripDisplayStyle
, this.grip_style
));
800 e
.Graphics
.ResetTransform ();
803 protected virtual void OnRendererChanged (EventArgs e
)
805 EventHandler eh
= (EventHandler
)(Events
[RendererChangedEvent
]);
810 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
811 protected override void OnRightToLeftChanged (EventArgs e
)
813 base.OnRightToLeftChanged (e
);
816 protected override void OnTabStopChanged (EventArgs e
)
818 base.OnTabStopChanged (e
);
821 protected override void OnVisibleChanged (EventArgs e
)
823 base.OnVisibleChanged (e
);
826 protected override bool ProcessCmdKey (ref Message msg
, Keys keyData
)
828 return base.ProcessCmdKey (ref msg
, keyData
);
831 protected override void SetBoundsCore (int x
, int y
, int width
, int height
, BoundsSpecified specified
)
833 base.SetBoundsCore (x
, y
, width
, height
, specified
);
836 protected virtual void SetDisplayedItems ()
838 this.displayed_items
.Clear ();
840 foreach (ToolStripItem tsi
in this.items
)
841 if (tsi
.Placement
== ToolStripItemPlacement
.Main
&& tsi
.Available
) {
842 this.displayed_items
.AddNoOwnerOrLayout (tsi
);
845 else if (tsi
.Placement
== ToolStripItemPlacement
.Overflow
)
846 tsi
.Parent
= this.OverflowButton
.DropDown
;
848 if (this.OverflowButton
!= null)
849 this.OverflowButton
.DropDown
.SetDisplayedItems ();
852 protected internal void SetItemLocation (ToolStripItem item
, Point location
)
855 throw new ArgumentNullException ("item");
857 if (item
.Owner
!= this)
858 throw new NotSupportedException ("The item is not owned by this ToolStrip");
860 item
.SetBounds (new Rectangle (location
, item
.Size
));
863 protected static void SetItemParent (ToolStripItem item
, ToolStrip parent
)
865 item
.Parent
= parent
;
868 protected override void SetVisibleCore (bool value)
870 base.SetVisibleCore (value);
873 protected override void WndProc (ref Message m
)
875 base.WndProc (ref m
);
879 #region To Be Removed
880 // These are things I overrode to get the behavior I needed, but MS's API
881 // says they aren't overridden. So I need to hide them (?) or implement
882 // them some other way...
883 protected override void OnMouseHover (EventArgs e
)
885 base.OnMouseHover (e
);
887 if (mouse_currently_over
!= null)
888 mouse_currently_over
.FireEvent (e
, ToolStripItemEventType
.MouseHover
);
892 #region Public Events
893 static object ItemAddedEvent
= new object ();
894 static object ItemClickedEvent
= new object ();
895 static object ItemRemovedEvent
= new object ();
896 static object LayoutCompletedEvent
= new object ();
897 static object LayoutStyleChangedEvent
= new object ();
898 static object PaintGripEvent
= new object ();
899 static object RendererChangedEvent
= new object ();
902 [EditorBrowsable (EditorBrowsableState
.Always
)]
903 public new event EventHandler AutoSizeChanged
{
904 add { base.AutoSizeChanged += value; }
905 remove { base.AutoSizeChanged -= value; }
909 public new event EventHandler CausesValidationChanged
{
910 add { base.CausesValidationChanged += value; }
911 remove { base.CausesValidationChanged -= value; }
915 public new event EventHandler CursorChanged
{
916 add { base.CursorChanged += value; }
917 remove { base.CursorChanged -= value; }
921 public new event EventHandler ForeColorChanged
{
922 add { base.ForeColorChanged += value; }
923 remove { base.ForeColorChanged -= value; }
926 public event ToolStripItemEventHandler ItemAdded
{
927 add { Events.AddHandler (ItemAddedEvent, value); }
928 remove { Events.RemoveHandler (ItemAddedEvent, value); }
931 public event ToolStripItemClickedEventHandler ItemClicked
{
932 add { Events.AddHandler (ItemClickedEvent, value); }
933 remove { Events.RemoveHandler (ItemClickedEvent, value); }
936 public event ToolStripItemEventHandler ItemRemoved
{
937 add { Events.AddHandler (ItemRemovedEvent, value); }
938 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
941 public event EventHandler LayoutCompleted
{
942 add { Events.AddHandler (LayoutCompletedEvent, value); }
943 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
946 public event EventHandler LayoutStyleChanged
{
947 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
948 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
951 public event PaintEventHandler PaintGrip
{
952 add { Events.AddHandler (PaintGripEvent, value); }
953 remove { Events.RemoveHandler (PaintGripEvent, value); }
956 public event EventHandler RendererChanged
{
957 add { Events.AddHandler (RendererChangedEvent, value); }
958 remove { Events.RemoveHandler (RendererChangedEvent, value); }
962 #region Private Methods
963 private void DoAutoSize ()
965 if (this.AutoSize
== true && this.Dock
== DockStyle
.None
)
966 this.Size
= GetPreferredSize (Size
.Empty
);
968 if (this.AutoSize
== true && this.Orientation
== Orientation
.Horizontal
&& (this.Dock
== DockStyle
.Top
|| this.Dock
== DockStyle
.Bottom
))
969 this.Height
= GetPreferredSize (Size
.Empty
).Height
;
972 public override Size
GetPreferredSize (Size proposedSize
)
974 Size new_size
= new Size (0, this.Height
);
976 if (this.orientation
== Orientation
.Vertical
) {
977 foreach (ToolStripItem tsi
in this.items
)
978 if (tsi
.GetPreferredSize (Size
.Empty
).Height
+ tsi
.Margin
.Top
+ tsi
.Margin
.Bottom
> new_size
.Height
)
979 new_size
.Height
= tsi
.GetPreferredSize (Size
.Empty
).Height
+ tsi
.Margin
.Top
+ tsi
.Margin
.Bottom
;
981 new_size
.Height
+= this.Padding
.Top
+ this.Padding
.Bottom
;
982 new_size
.Width
= this.Width
;
984 foreach (ToolStripItem tsi
in this.items
)
986 Size tsi_preferred
= tsi
.GetPreferredSize (Size
.Empty
);
987 new_size
.Width
+= tsi_preferred
.Width
+ tsi
.Margin
.Left
+ tsi
.Margin
.Right
;
989 if (new_size
.Height
< (this.Padding
.Vertical
+ tsi_preferred
.Height
))
990 new_size
.Height
= (this.Padding
.Vertical
+ tsi_preferred
.Height
);
994 new_size
.Width
+= (this.GripRectangle
.Width
+ this.GripMargin
.Horizontal
+ this.Padding
.Horizontal
+ 4);
998 internal void HideMenus (bool release
, ToolStripDropDownCloseReason reason
)
1000 if (this is MenuStrip
&& release
&& menu_selected
)
1001 (this as MenuStrip
).FireMenuDeactivate ();
1004 menu_selected
= false;
1006 NotifySelectedChanged (null);
1009 internal void NotifySelectedChanged (ToolStripItem tsi
)
1011 foreach (ToolStripItem tsi2
in this.DisplayedItems
)
1013 if (tsi2
is ToolStripDropDownItem
)
1014 (tsi2
as ToolStripDropDownItem
).HideDropDown (ToolStripDropDownCloseReason
.Keyboard
);
1016 if (this.OverflowButton
!= null) {
1017 ToolStripItemCollection tsic
= this.OverflowButton
.DropDown
.DisplayedItems
;
1019 foreach (ToolStripItem tsi2
in tsic
)
1021 if (tsi2
is ToolStripDropDownItem
)
1022 (tsi2
as ToolStripDropDownItem
).HideDropDown (ToolStripDropDownCloseReason
.Keyboard
);
1024 this.OverflowButton
.HideDropDown ();