2007-03-19 Chris Toshok <toshok@ximian.com>
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStrip.cs
blob9e3bbc778ae81c50b1b796b374c8304616c4c24b
1 //
2 // ToolStrip.cs
3 //
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:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
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
25 // Authors:
26 // Jonathan Pobst (monkey@jpobst.com)
29 #if NET_2_0
30 using System;
31 using System.Runtime.InteropServices;
32 using System.ComponentModel;
33 using System.Drawing;
34 using System.Windows.Forms.Layout;
36 namespace System.Windows.Forms
38 [ComVisible (true)]
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;
63 private bool stretch;
65 private ToolStripItem mouse_currently_over;
66 private bool menu_selected;
67 #endregion
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);
83 base.AutoSize = true;
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 ();
106 DoAutoSize ();
108 // Register with the ToolStripManager
109 ToolStripManager.AddToolStrip (this);
111 #endregion
113 #region Public Properties
114 public override AnchorStyles Anchor {
115 get { return base.Anchor; }
116 set {
117 base.Anchor = value;
118 base.dock_style = DockStyle.None;
122 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
123 [Browsable (true)]
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; }
142 [Browsable (false)]
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; }
155 [Browsable (false)]
156 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
157 public override Cursor Cursor {
158 get { return base.Cursor; }
159 set { base.Cursor = value; }
162 [Browsable (false)]
163 public virtual ToolStripDropDownDirection DefaultDropDownDirection {
164 get { return this.default_drop_down_direction; }
165 set {
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 {
174 get {
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);
178 else
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);
180 else
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);
183 else
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; }
191 set {
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));
195 base.Dock = value;
196 base.anchor_style = AnchorStyles.Left | AnchorStyles.Top;
198 switch (value) {
199 case DockStyle.Top:
200 case DockStyle.Bottom:
201 case DockStyle.None:
202 this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
203 break;
204 case DockStyle.Left:
205 case DockStyle.Right:
206 this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
207 break;
210 DoAutoSize ();
215 public override Font Font {
216 get { return base.Font; }
217 set {
218 if (base.Font != value) {
219 base.Font = value;
221 foreach (ToolStripItem tsi in this.Items)
222 tsi.OnOwnerFontChanged (EventArgs.Empty);
227 [Browsable (false)]
228 public new Color ForeColor {
229 get { return this.fore_color; }
230 set {
231 if (this.fore_color != value) {
232 this.fore_color = value;
233 this.OnForeColorChanged (EventArgs.Empty);
238 [Browsable (false)]
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; }
245 set {
246 if (this.grip_margin != value) {
247 this.grip_margin = value;
248 this.PerformLayout ();
253 [Browsable (false)]
254 public Rectangle GripRectangle {
255 get {
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);
261 else
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; }
269 set {
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 ();
279 [Browsable (false)]
280 [EditorBrowsable (EditorBrowsableState.Never)]
281 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
282 public new bool HasChildren {
283 get { return base.HasChildren; }
286 [Browsable (false)]
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.")]
300 [Browsable (false)]
301 [EditorBrowsable (EditorBrowsableState.Advanced)]
302 public bool IsCurrentlyDragging {
303 get { return false; }
306 [Browsable (false)]
307 public bool IsDropDown {
308 get {
309 if (this is ToolStripDropDown)
310 return true;
312 return false;
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;; }
325 [Browsable (false)]
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; }
336 set {
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 ();
345 else
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;
351 else
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);
368 [Browsable (false)]
369 public Orientation Orientation {
370 get { return this.orientation; }
373 [Browsable (false)]
374 [EditorBrowsable (EditorBrowsableState.Advanced)]
375 public ToolStripOverflowButton OverflowButton {
376 get { return this.overflow_button; }
379 [Browsable (false)]
380 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
381 public ToolStripRenderer Renderer {
382 get {
383 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
384 return ToolStripManager.Renderer;
386 return this.renderer;
388 set {
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; }
400 set {
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)]
427 [DispId(-516)]
428 public new bool TabStop {
429 get { return base.TabStop; }
430 set { base.TabStop = value; }
432 #endregion
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; } }
442 #endregion
444 #region Public Methods
445 [Browsable (false)]
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))
455 return tsi;
457 return null;
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);
472 switch (direction) {
473 case ArrowDirection.Left:
474 case ArrowDirection.Up:
475 if (index > 0)
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];
487 return null;
490 public override string ToString ()
492 return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
494 #endregion
496 #region Protected Methods
497 protected override AccessibleObject CreateAccessibilityInstance ()
499 AccessibleObject ao = new AccessibleObject (this);
501 ao.role = AccessibleRole.ToolBar;
503 return ao;
506 protected override ControlCollection CreateControlsInstance ()
508 return base.CreateControlsInstance ();
511 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
513 if (text == "-")
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:
532 default:
533 return null;
537 protected override void Dispose (bool disposing)
539 if (!IsDisposed) {
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)
580 this.DoAutoSize ();
581 this.PerformLayout ();
583 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
584 if (eh != null)
585 eh (this, e);
588 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
590 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
591 if (eh != null)
592 eh (this, e);
595 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
597 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
598 if (eh != null)
599 eh (this, e);
602 protected override void OnLayout (LayoutEventArgs e)
604 DoAutoSize ();
605 base.OnLayout (e);
607 this.SetDisplayedItems ();
608 this.OnLayoutCompleted (EventArgs.Empty);
609 this.Invalidate ();
612 protected virtual void OnLayoutCompleted (EventArgs e)
614 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
615 if (eh != null)
616 eh (this, e);
619 protected virtual void OnLayoutStyleChanged (EventArgs e)
621 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
622 if (eh != null)
623 eh (this, e);
626 protected override void OnLeave (EventArgs e)
628 base.OnLeave (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) {
641 if (!menu_selected)
642 (this as MenuStrip).FireMenuActivate ();
644 return;
647 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
649 if (this is MenuStrip && !menu_selected) {
650 (this as MenuStrip).FireMenuActivate ();
651 menu_selected = true;
653 } else {
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)
676 ToolStripItem tsi;
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;
680 else
681 tsi = this.GetItemAt (mea.X, mea.Y);
683 if (tsi != null) {
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);
687 else {
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 ();
703 } else {
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)
723 return;
725 // Fire our ItemClicked event
726 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
729 base.OnMouseUp (mea);
732 protected override void OnPaint (PaintEventArgs e)
734 base.OnPaint (e);
736 // Draw the grip
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)
786 return;
788 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
789 if (eh != null)
790 eh (this, e);
792 if (!(this is MenuStrip)) {
793 if (this.orientation == Orientation.Horizontal)
794 e.Graphics.TranslateTransform (2, 0);
795 else
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]);
806 if (eh != null)
807 eh (this, e);
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);
843 tsi.Parent = this;
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)
854 if (item == null)
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);
877 #endregion
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);
890 #endregion
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 ();
901 [Browsable (true)]
902 [EditorBrowsable (EditorBrowsableState.Always)]
903 public new event EventHandler AutoSizeChanged {
904 add { base.AutoSizeChanged += value; }
905 remove { base.AutoSizeChanged -= value; }
908 [Browsable (false)]
909 public new event EventHandler CausesValidationChanged {
910 add { base.CausesValidationChanged += value; }
911 remove { base.CausesValidationChanged -= value; }
914 [Browsable (false)]
915 public new event EventHandler CursorChanged {
916 add { base.CursorChanged += value; }
917 remove { base.CursorChanged -= value; }
920 [Browsable (false)]
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); }
960 #endregion
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;
983 } else {
984 foreach (ToolStripItem tsi in this.items)
985 if (tsi.Available) {
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);
995 return new_size;
998 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1000 if (this is MenuStrip && release && menu_selected)
1001 (this as MenuStrip).FireMenuDeactivate ();
1003 if (release)
1004 menu_selected = false;
1006 NotifySelectedChanged (null);
1009 internal void NotifySelectedChanged (ToolStripItem tsi)
1011 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1012 if (tsi != tsi2)
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)
1020 if (tsi != tsi2)
1021 if (tsi2 is ToolStripDropDownItem)
1022 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1024 this.OverflowButton.HideDropDown ();
1027 #endregion
1030 #endif