1 // System.Windows.Forms.ToolBar.cs
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Ravindra (rkumar@novell.com)
24 // Mike Kestner <mkestner@novell.com>
25 // Everaldo Canuto <ecanuto@novell.com>
27 // Copyright (C) 2004-2006 Novell, Inc. (http://www.novell.com)
30 using System.Collections;
31 using System.ComponentModel;
32 using System.ComponentModel.Design;
34 using System.Drawing.Text;
35 using System.Drawing.Imaging;
36 using System.Runtime.InteropServices;
38 namespace System.Windows.Forms
40 [DefaultEvent ("ButtonClick")]
41 [DefaultProperty ("Buttons")]
42 [Designer ("System.Windows.Forms.Design.ToolBarDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
43 public class ToolBar : Control
45 #region Instance Variables
46 private bool size_specified = false;
47 private ToolBarItem current_item;
48 internal ToolBarItem[] items;
49 #endregion Instance Variables
52 static object ButtonClickEvent = new object ();
53 static object ButtonDropDownEvent = new object ();
56 [EditorBrowsable (EditorBrowsableState.Never)]
57 public new event EventHandler BackColorChanged {
58 add { base.BackColorChanged += value; }
59 remove { base.BackColorChanged -= value; }
63 [EditorBrowsable (EditorBrowsableState.Never)]
64 public new event EventHandler BackgroundImageChanged {
65 add { base.BackgroundImageChanged += value; }
66 remove { base.BackgroundImageChanged -= value; }
69 public event ToolBarButtonClickEventHandler ButtonClick {
70 add { Events.AddHandler (ButtonClickEvent, value); }
71 remove {Events.RemoveHandler (ButtonClickEvent, value); }
74 public event ToolBarButtonClickEventHandler ButtonDropDown {
75 add { Events.AddHandler (ButtonDropDownEvent, value); }
76 remove {Events.RemoveHandler (ButtonDropDownEvent, value); }
80 [EditorBrowsable (EditorBrowsableState.Never)]
81 public new event EventHandler ForeColorChanged {
82 add { base.ForeColorChanged += value; }
83 remove { base.ForeColorChanged -= value; }
87 [EditorBrowsable (EditorBrowsableState.Never)]
88 public new event EventHandler ImeModeChanged {
89 add { base.ImeModeChanged += value; }
90 remove { base.ImeModeChanged -= value; }
94 [EditorBrowsable (EditorBrowsableState.Never)]
95 public new event PaintEventHandler Paint {
96 add { base.Paint += value; }
97 remove { base.Paint -= value; }
101 [EditorBrowsable (EditorBrowsableState.Never)]
102 public new event EventHandler RightToLeftChanged {
103 add { base.RightToLeftChanged += value; }
104 remove { base.RightToLeftChanged -= value; }
108 [EditorBrowsable (EditorBrowsableState.Never)]
109 public new event EventHandler TextChanged {
110 add { base.TextChanged += value; }
111 remove { base.TextChanged -= value; }
118 background_color = ThemeEngine.Current.DefaultControlBackColor;
119 foreground_color = ThemeEngine.Current.DefaultControlForeColor;
120 buttons = new ToolBarButtonCollection (this);
121 Dock = DockStyle.Top;
123 GotFocus += new EventHandler (FocusChanged);
124 LostFocus += new EventHandler (FocusChanged);
125 MouseDown += new MouseEventHandler (ToolBar_MouseDown);
126 MouseHover += new EventHandler (ToolBar_MouseHover);
127 MouseLeave += new EventHandler (ToolBar_MouseLeave);
128 MouseMove += new MouseEventHandler (ToolBar_MouseMove);
129 MouseUp += new MouseEventHandler (ToolBar_MouseUp);
130 BackgroundImageChanged += new EventHandler (ToolBar_BackgroundImageChanged);
134 SetStyle (ControlStyles.UserPaint, false);
135 SetStyle (ControlStyles.FixedHeight, true);
136 SetStyle (ControlStyles.FixedWidth, false);
138 #endregion Constructor
140 #region protected Properties
141 protected override CreateParams CreateParams {
142 get { return base.CreateParams; }
145 protected override ImeMode DefaultImeMode {
146 get { return ImeMode.Disable; }
149 protected override Size DefaultSize {
150 get { return ThemeEngine.Current.ToolBarDefaultSize; }
154 ToolBarAppearance appearance = ToolBarAppearance.Normal;
156 #region Public Properties
157 [DefaultValue (ToolBarAppearance.Normal)]
159 public ToolBarAppearance Appearance {
160 get { return appearance; }
162 if (value == appearance)
170 bool autosize = true;
172 [DefaultValue (true)]
174 public new bool AutoSize {
175 get { return autosize; }
177 if (value == autosize)
186 [EditorBrowsable (EditorBrowsableState.Never)]
187 public override Color BackColor {
188 get { return background_color; }
190 if (value == background_color)
193 background_color = value;
194 OnBackColorChanged (EventArgs.Empty);
200 [EditorBrowsable (EditorBrowsableState.Never)]
201 public override Image BackgroundImage {
202 get { return base.BackgroundImage; }
203 set { base.BackgroundImage = value; }
206 [DefaultValue (BorderStyle.None)]
207 [DispIdAttribute (-504)]
208 public BorderStyle BorderStyle {
209 get { return InternalBorderStyle; }
210 set { InternalBorderStyle = value; }
213 ToolBarButtonCollection buttons;
215 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
217 [MergableProperty (false)]
218 public ToolBarButtonCollection Buttons {
219 get { return buttons; }
225 [RefreshProperties (RefreshProperties.All)]
226 public Size ButtonSize {
228 if (!button_size.IsEmpty)
231 if (buttons.Count == 0)
232 return new Size (39, 36);
234 Size result = CalcButtonSize ();
236 return new Size (24, 22);
241 size_specified = value != Size.Empty;
242 if (button_size == value)
252 [DefaultValue (true)]
253 public bool Divider {
254 get { return divider; }
256 if (value == divider)
264 [DefaultValue (DockStyle.Top)]
266 public override DockStyle Dock {
267 get { return base.Dock; }
269 if (base.Dock == value)
273 SetStyle (ControlStyles.FixedWidth, AutoSize);
274 SetStyle (ControlStyles.FixedHeight, false);
276 SetStyle (ControlStyles.FixedHeight, AutoSize);
277 SetStyle (ControlStyles.FixedWidth, false);
286 bool drop_down_arrows = true;
288 [DefaultValue (false)]
290 public bool DropDownArrows {
291 get { return drop_down_arrows; }
293 if (value == drop_down_arrows)
296 drop_down_arrows = value;
302 [EditorBrowsable (EditorBrowsableState.Never)]
303 public override Color ForeColor {
304 get { return foreground_color; }
306 if (value == foreground_color)
309 foreground_color = value;
310 OnForeColorChanged (EventArgs.Empty);
315 ImageList image_list;
317 [DefaultValue (null)]
318 public ImageList ImageList {
319 get { return image_list; }
321 if (image_list == value)
329 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
330 [EditorBrowsable (EditorBrowsableState.Advanced)]
331 public Size ImageSize {
333 if (ImageList == null)
336 return ImageList.ImageSize;
340 // XXX this should probably go away and it should call
341 // into Control.ImeMode instead.
342 new ImeMode ime_mode = ImeMode.Disable;
345 [EditorBrowsable (EditorBrowsableState.Never)]
346 public new ImeMode ImeMode {
347 get { return ime_mode; }
349 if (value == ime_mode)
353 OnImeModeChanged (EventArgs.Empty);
358 [EditorBrowsable (EditorBrowsableState.Never)]
359 public override RightToLeft RightToLeft {
360 get { return base.RightToLeft; }
362 if (value == base.RightToLeft)
365 base.RightToLeft = value;
366 OnRightToLeftChanged (EventArgs.Empty);
370 // Default value is "false" but after make a test in .NET we get "true" result as default.
371 bool show_tooltips = true;
373 [DefaultValue (false)]
375 public bool ShowToolTips {
376 get { return show_tooltips; }
377 set { show_tooltips = value; }
380 [DefaultValue (false)]
381 public new bool TabStop {
382 get { return base.TabStop; }
383 set { base.TabStop = value; }
388 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
389 [EditorBrowsable (EditorBrowsableState.Never)]
390 public override string Text {
391 get { return base.Text; }
393 if (value == base.Text)
401 ToolBarTextAlign text_alignment = ToolBarTextAlign.Underneath;
403 [DefaultValue (ToolBarTextAlign.Underneath)]
405 public ToolBarTextAlign TextAlign {
406 get { return text_alignment; }
408 if (value == text_alignment)
411 text_alignment = value;
416 bool wrappable = true;
418 [DefaultValue (true)]
420 public bool Wrappable {
421 get { return wrappable; }
423 if (value == wrappable)
430 #endregion Public Properties
432 #region Public Methods
433 public override string ToString ()
435 int count = this.Buttons.Count;
438 return string.Format ("System.Windows.Forms.ToolBar, Buttons.Count: 0");
440 return string.Format ("System.Windows.Forms.ToolBar, Buttons.Count: {0}, Buttons[0]: {1}",
441 count, this.Buttons [0].ToString ());
443 #endregion Public Methods
445 #region Protected Methods
446 protected override void CreateHandle ()
448 base.CreateHandle ();
451 protected override void Dispose (bool disposing)
456 base.Dispose (disposing);
459 protected virtual void OnButtonClick (ToolBarButtonClickEventArgs e)
461 if (e.Button.Style == ToolBarButtonStyle.ToggleButton) {
462 if (! e.Button.Pushed)
463 e.Button.Pushed = true;
465 e.Button.Pushed = false;
468 current_item.Pressed = false;
469 current_item.Invalidate ();
471 ToolBarButtonClickEventHandler eh = (ToolBarButtonClickEventHandler)(Events [ButtonClickEvent]);
476 protected virtual void OnButtonDropDown (ToolBarButtonClickEventArgs e)
478 ToolBarButtonClickEventHandler eh = (ToolBarButtonClickEventHandler)(Events [ButtonDropDownEvent]);
482 if (e.Button.DropDownMenu == null)
485 Point loc = new Point (current_item.Rectangle.X + 1, current_item.Rectangle.Bottom + 1);
486 ((ContextMenu) e.Button.DropDownMenu).Show (this, loc);
488 current_item.DDPressed = false;
489 current_item.Hilight = false;
490 Invalidate (current_item.Rectangle);
493 protected override void OnFontChanged (EventArgs e)
495 base.OnFontChanged (e);
499 protected override void OnHandleCreated (EventArgs e)
501 base.OnHandleCreated (e);
504 protected override void OnResize (EventArgs e)
510 private int requested_size = -1;
512 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
515 if (!AutoSize && (requested_size != width) && ((specified & BoundsSpecified.Width) != BoundsSpecified.None))
516 requested_size = width;
518 if (!AutoSize && (requested_size != height) && ((specified & BoundsSpecified.Height) != BoundsSpecified.None))
519 requested_size = height;
522 base.SetBoundsCore (x, y, width, height, specified);
525 protected override void WndProc (ref Message m)
527 base.WndProc (ref m);
530 internal override bool InternalPreProcessMessage (ref Message msg)
532 if (msg.Msg == (int)Msg.WM_KEYDOWN) {
533 Keys key_data = (Keys)msg.WParam.ToInt32();
534 if (HandleKeyDown (key_data))
537 return base.InternalPreProcessMessage (ref msg);
540 #endregion Protected Methods
542 #region Private Methods
543 private void FocusChanged (object sender, EventArgs args)
545 if (Appearance != ToolBarAppearance.Flat || Buttons.Count == 0)
548 ToolBarItem prelit = null;
549 foreach (ToolBarItem item in items) {
556 if (Focused && prelit == null) {
557 foreach (ToolBarItem item in items) {
558 if (item.Button.Enabled) {
563 } else if (prelit != null) {
564 prelit.Hilight = false;
568 private bool HandleKeyDown (Keys key_data)
570 if (Appearance != ToolBarAppearance.Flat || Buttons.Count == 0)
576 HighlightButton (-1);
587 void HighlightButton (int offset)
589 ArrayList enabled = new ArrayList ();
592 ToolBarItem curr_item = null;
593 foreach (ToolBarItem item in items) {
599 if (item.Button.Enabled) {
605 int next = (start + offset) % count;
612 if (curr_item != null)
613 curr_item.Hilight = false;
614 (enabled [next] as ToolBarItem).Hilight = true;
617 private void ToolBar_BackgroundImageChanged (object sender, EventArgs args)
619 Redraw (false, true);
622 private void ToolBar_MouseDown (object sender, MouseEventArgs me)
624 if ((!Enabled) || ((me.Button & MouseButtons.Left) == 0))
627 Point loc = new Point (me.X, me.Y);
629 if (ItemAtPoint (loc) == null)
632 // Hide tooltip when left mouse button
633 if ((tip_window != null) && (tip_window.Visible) && ((me.Button & MouseButtons.Left) == MouseButtons.Left)) {
634 TipDownTimer.Stop ();
638 // draw the pushed button
639 foreach (ToolBarItem item in items) {
640 if (item.Button.Enabled && item.Rectangle.Contains (loc)) {
641 // Mark the DropDown rect as pressed.
642 // We don't redraw the dropdown rect.
643 if (item.Button.Style == ToolBarButtonStyle.DropDownButton) {
644 Rectangle rect = item.Rectangle;
645 if (DropDownArrows) {
646 rect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
647 rect.X = item.Rectangle.Right - rect.Width;
650 if (rect.Contains (loc)) {
651 if (item.Button.DropDownMenu != null) {
652 item.DDPressed = true;
666 private void ToolBar_MouseUp (object sender, MouseEventArgs me)
668 if ((!Enabled) || ((me.Button & MouseButtons.Left) == 0))
671 Point loc = new Point (me.X, me.Y);
673 // draw the normal button
674 // Make a copy in case the list is modified during enumeration
675 ArrayList items = new ArrayList (this.items);
676 foreach (ToolBarItem item in items) {
677 if (item.Button.Enabled && item.Rectangle.Contains (loc)) {
678 if (item.Button.Style == ToolBarButtonStyle.DropDownButton) {
679 Rectangle ddRect = item.Rectangle;
680 ddRect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
681 ddRect.X = item.Rectangle.Right - ddRect.Width;
682 if (ddRect.Contains (loc)) {
685 OnButtonDropDown (new ToolBarButtonClickEventArgs (item.Button));
689 // Fire a ButtonClick
691 if ((item.Pressed) && ((me.Button & MouseButtons.Left) == MouseButtons.Left))
692 OnButtonClick (new ToolBarButtonClickEventArgs (item.Button));
693 } else if (item.Pressed) {
694 item.Pressed = false;
700 private ToolBarItem ItemAtPoint (Point pt)
702 foreach (ToolBarItem item in items)
703 if (item.Rectangle.Contains (pt))
709 ToolTip.ToolTipWindow tip_window = null;
710 Timer tipdown_timer = null;
712 private void PopDownTip (object o, EventArgs args)
717 private Timer TipDownTimer {
719 if (tipdown_timer == null) {
720 tipdown_timer = new Timer ();
721 tipdown_timer.Enabled = false;
722 tipdown_timer.Interval = 5000;
723 tipdown_timer.Tick += new EventHandler (PopDownTip);
725 return tipdown_timer;
729 private void ToolBar_MouseHover (object sender, EventArgs e)
734 if (tip_window == null)
735 tip_window = new ToolTip.ToolTipWindow ();
737 ToolBarItem item = ItemAtPoint (PointToClient (Control.MousePosition));
740 if (item == null || item.Button.ToolTipText.Length == 0)
743 tip_window.Present (this, item.Button.ToolTipText);
744 TipDownTimer.Start ();
747 private void ToolBar_MouseLeave (object sender, EventArgs e)
749 if (tipdown_timer != null)
750 tipdown_timer.Dispose ();
751 tipdown_timer = null;
752 if (tip_window != null)
753 tip_window.Dispose ();
756 if (!Enabled || current_item == null)
759 current_item.Hilight = false;
763 private void ToolBar_MouseMove (object sender, MouseEventArgs me)
768 if (tip_window != null && tip_window.Visible) {
769 TipDownTimer.Stop ();
770 TipDownTimer.Start ();
773 Point loc = new Point (me.X, me.Y);
776 // If the button was pressed and we leave, release the
777 // button press and vice versa
778 foreach (ToolBarItem item in items) {
780 (item.Inside != item.Rectangle.Contains (loc))) {
781 item.Inside = item.Rectangle.Contains (loc);
782 item.Hilight = false;
789 if (current_item != null && current_item.Rectangle.Contains (loc)) {
790 if (appearance == ToolBarAppearance.Flat) {
791 if (current_item.Hilight || current_item.Button.Pushed || !current_item.Button.Enabled)
793 current_item.Hilight = true;
796 if (tip_window != null) {
797 if (tip_window.Visible) {
799 TipDownTimer.Stop ();
801 current_item = ItemAtPoint (loc);
802 if (current_item != null && current_item.Button.ToolTipText.Length > 0) {
803 tip_window.Present (this, current_item.Button.ToolTipText);
804 TipDownTimer.Start ();
808 if (appearance == ToolBarAppearance.Flat) {
809 foreach (ToolBarItem item in items) {
810 if (item.Rectangle.Contains (loc) && item.Button.Enabled) {
812 if (current_item.Hilight || current_item.Button.Pushed)
814 current_item.Hilight = true;
816 else if (item.Hilight) {
817 item.Hilight = false;
824 internal override void OnPaintInternal (PaintEventArgs pevent)
826 ThemeEngine.Current.DrawToolBar (pevent.Graphics, pevent.ClipRectangle, this);
829 internal void Redraw (bool recalculate)
831 Redraw (recalculate, true);
834 internal void Redraw (bool recalculate, bool force)
836 bool invalidate = true;
839 invalidate = LayoutToolBar ();
841 if (force || invalidate)
845 internal bool SizeSpecified {
846 get { return size_specified; }
849 private bool Vertical {
850 get { return (Dock == DockStyle.Left) || (Dock == DockStyle.Right); }
853 internal const int text_padding = 3;
855 private Size CalcButtonSize ()
857 if (Buttons.Count == 0)
860 string longest_text = Buttons [0].Text;
861 for (int i = 1; i < Buttons.Count; i++) {
862 if (Buttons[i].Text.Length > longest_text.Length)
863 longest_text = Buttons[i].Text;
866 Size size = Size.Empty;
867 if (longest_text != null && longest_text.Length > 0) {
868 SizeF sz = DeviceContext.MeasureString (longest_text, Font);
869 if (sz != SizeF.Empty)
870 size = new Size ((int) Math.Ceiling (sz.Width) + 2 * text_padding, (int) Math.Ceiling (sz.Height));
873 Size img_size = ImageList == null ? new Size (16, 16) : ImageSize;
875 Theme theme = ThemeEngine.Current;
876 int imgWidth = img_size.Width + 2 * theme.ToolBarImageGripWidth;
877 int imgHeight = img_size.Height + 2 * theme.ToolBarImageGripWidth;
879 if (text_alignment == ToolBarTextAlign.Right) {
880 size.Width = imgWidth + size.Width;
881 size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
883 size.Height = imgHeight + size.Height;
884 size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
887 size.Width += theme.ToolBarImageGripWidth;
888 size.Height += theme.ToolBarImageGripWidth;
892 // Flat toolbars disregard specified sizes. Normal toolbars grow the
893 // button size to be at least large enough to show the image.
894 private Size AdjustedButtonSize {
896 Size size = ButtonSize;
897 if (size_specified) {
898 if (Appearance == ToolBarAppearance.Flat)
899 size = CalcButtonSize ();
901 int grip = ThemeEngine.Current.ToolBarImageGripWidth;
902 if (size.Width < ImageSize.Width + 2 * grip )
903 size.Width = ImageSize.Width + 2 * grip;
904 if (size.Height < ImageSize.Height + 2 * grip)
905 size.Height = ImageSize.Height + 2 * grip;
912 private bool LayoutToolBar ()
914 bool changed = false;
915 Theme theme = ThemeEngine.Current;
916 int x = theme.ToolBarGripWidth;
917 int y = theme.ToolBarGripWidth;
919 Size adjusted_size = AdjustedButtonSize;
921 int calculated_size = (Vertical ? adjusted_size.Width : adjusted_size.Height) + theme.ToolBarGripWidth;
923 int separator_index = -1;
925 items = new ToolBarItem [buttons.Count];
927 for (int i = 0; i < buttons.Count; i++) {
928 ToolBarButton button = buttons [i];
930 ToolBarItem item = new ToolBarItem (button);
936 if (size_specified && (button.Style != ToolBarButtonStyle.Separator))
937 changed = item.Layout (adjusted_size);
939 changed = item.Layout ();
941 bool is_separator = button.Style == ToolBarButtonStyle.Separator;
944 if (y + item.Rectangle.Height < Height || is_separator || !Wrappable) {
945 if (item.Location.X != x || item.Location.Y != y)
947 item.Location = new Point (x, y);
948 y += item.Rectangle.Height;
951 } else if (separator_index > 0) {
953 separator_index = -1;
954 y = theme.ToolBarGripWidth;
955 x += calculated_size;
957 y = theme.ToolBarGripWidth;
958 x += calculated_size;
959 if (item.Location.X != x || item.Location.Y != y)
961 item.Location = new Point (x, y);
962 y += item.Rectangle.Height;
965 if (x + item.Rectangle.Width < Width || is_separator || !Wrappable) {
966 if (item.Location.X != x || item.Location.Y != y)
968 item.Location = new Point (x, y);
969 x += item.Rectangle.Width;
972 } else if (separator_index > 0) {
974 separator_index = -1;
975 x = theme.ToolBarGripWidth;
976 y += calculated_size;
978 x = theme.ToolBarGripWidth;
979 y += calculated_size;
980 if (item.Location.X != x || item.Location.Y != y)
982 item.Location = new Point (x, y);
983 x += item.Rectangle.Width;
992 calculated_size += Vertical ? x : y;
995 Width = AutoSize ? calculated_size : requested_size;
997 Height = AutoSize ? calculated_size : requested_size;
1001 #endregion Private Methods
1004 public class ToolBarButtonCollection : IList, ICollection, IEnumerable
1006 #region instance variables
1007 private ArrayList list; // ToolBarButton list
1008 private ToolBar owner; // ToolBar associated to Collection
1009 private bool redraw; // Flag if needs to redraw after add/remove operations
1012 #region constructors
1013 public ToolBarButtonCollection (ToolBar owner)
1015 this.list = new ArrayList ();
1024 get { return list.Count; }
1027 public bool IsReadOnly {
1028 get { return list.IsReadOnly; }
1031 public virtual ToolBarButton this [int index] {
1032 get { return (ToolBarButton) list [index]; }
1034 value.SetParent (owner);
1035 list [index] = value;
1036 owner.Redraw (true);
1040 bool ICollection.IsSynchronized {
1041 get { return list.IsSynchronized; }
1044 object ICollection.SyncRoot {
1045 get { return list.SyncRoot; }
1048 bool IList.IsFixedSize {
1049 get { return list.IsFixedSize; }
1052 object IList.this [int index] {
1053 get { return this [index]; }
1055 if (! (value is ToolBarButton))
1056 throw new ArgumentException("Not of type ToolBarButton", "value");
1057 this [index] = (ToolBarButton) value;
1063 public int Add (string text)
1065 ToolBarButton button = new ToolBarButton (text);
1066 return this.Add (button);
1069 public int Add (ToolBarButton button)
1072 button.SetParent (owner);
1073 result = list.Add (button);
1075 owner.Redraw (true);
1079 public void AddRange (ToolBarButton [] buttons)
1083 foreach (ToolBarButton button in buttons)
1088 owner.Redraw (true);
1092 public void Clear ()
1095 owner.Redraw (false);
1098 public bool Contains (ToolBarButton button)
1100 return list.Contains (button);
1103 public IEnumerator GetEnumerator ()
1105 return list.GetEnumerator ();
1108 void ICollection.CopyTo (Array dest, int index)
1110 list.CopyTo (dest, index);
1113 int IList.Add (object button)
1115 if (! (button is ToolBarButton)) {
1116 throw new ArgumentException("Not of type ToolBarButton", "button");
1119 return this.Add ((ToolBarButton) button);
1122 bool IList.Contains (object button)
1124 if (! (button is ToolBarButton)) {
1125 throw new ArgumentException("Not of type ToolBarButton", "button");
1128 return this.Contains ((ToolBarButton) button);
1131 int IList.IndexOf (object button)
1133 if (! (button is ToolBarButton)) {
1134 throw new ArgumentException("Not of type ToolBarButton", "button");
1137 return this.IndexOf ((ToolBarButton) button);
1140 void IList.Insert (int index, object button)
1142 if (! (button is ToolBarButton)) {
1143 throw new ArgumentException("Not of type ToolBarButton", "button");
1146 this.Insert (index, (ToolBarButton) button);
1149 void IList.Remove (object button)
1151 if (! (button is ToolBarButton)) {
1152 throw new ArgumentException("Not of type ToolBarButton", "button");
1155 this.Remove ((ToolBarButton) button);
1158 public int IndexOf (ToolBarButton button)
1160 return list.IndexOf (button);
1163 public void Insert (int index, ToolBarButton button)
1165 list.Insert (index, button);
1166 owner.Redraw (true);
1169 public void Remove (ToolBarButton button)
1171 list.Remove (button);
1172 owner.Redraw (true);
1175 public void RemoveAt (int index)
1177 list.RemoveAt (index);
1178 owner.Redraw (true);
1187 // Because same button can be added to toolbar multiple times, we need to maintain
1188 // a list of button information for each positions.
1189 internal class ToolBarItem : Component
1191 #region Instance variables
1193 private ToolBar toolbar; // Parent toolbar
1194 private ToolBarButton button; // Associated toolBar button
1195 private Rectangle bounds; // Toolbar button bounds
1196 private Rectangle image_rect; // Image button bounds
1197 private Rectangle text_rect; // Text button bounds
1199 private bool dd_pressed = false; // to check for a mouse down on dropdown rect
1200 private bool inside = false; // to handle the mouse move event with mouse pressed
1201 private bool hilight = false; // to hilight buttons in flat style
1202 private bool pressed = false; // this is to check for mouse down on a button
1206 #region Constructors
1208 public ToolBarItem (ToolBarButton button)
1210 this.toolbar = button.Parent;
1211 this.button = button;
1214 #endregion Constructors
1218 public ToolBarButton Button {
1219 get { return this.button; }
1222 public Rectangle Rectangle {
1224 if (!button.Visible || toolbar == null)
1225 return Rectangle.Empty;
1227 if (button.Style == ToolBarButtonStyle.DropDownButton && toolbar.DropDownArrows) {
1228 Rectangle result = bounds;
1229 result.Width += ThemeEngine.Current.ToolBarDropDownWidth;
1235 set { this.bounds = value; }
1238 public Point Location {
1239 get { return bounds.Location; }
1240 set { bounds.Location = value; }
1243 public Rectangle ImageRectangle {
1245 Rectangle result = image_rect;
1246 result.X += bounds.X;
1247 result.Y += bounds.Y;
1252 public Rectangle TextRectangle {
1254 Rectangle result = text_rect;
1255 result.X += bounds.X;
1256 result.Y += bounds.Y;
1261 private Size TextSize {
1263 StringFormat text_format = new StringFormat ();
1264 text_format.HotkeyPrefix = HotkeyPrefix.Hide;
1266 SizeF sz = toolbar.DeviceContext.MeasureString (button.Text, toolbar.Font, SizeF.Empty, text_format);
1267 if (sz == SizeF.Empty)
1269 return new Size ((int) Math.Ceiling (sz.Width) + 2 * ToolBar.text_padding, (int) Math.Ceiling (sz.Height));
1273 public bool Pressed {
1274 get { return (pressed && inside); }
1275 set { pressed = value; }
1278 public bool DDPressed {
1279 get { return dd_pressed; }
1280 set { dd_pressed = value; }
1283 public bool Inside {
1284 get { return inside; }
1285 set { inside = value; }
1288 public bool Hilight {
1289 get { return hilight; }
1291 if (hilight == value)
1299 #endregion Properties
1303 public Size CalculateSize ()
1305 Theme theme = ThemeEngine.Current;
1307 int ht = toolbar.ButtonSize.Height + 2 * theme.ToolBarGripWidth;
1309 if (button.Style == ToolBarButtonStyle.Separator)
1310 return new Size (theme.ToolBarSeparatorWidth, ht);
1312 Size size = TextSize;
1313 Size image_size = (toolbar.ImageSize == Size.Empty) ? new Size (16, 16) : toolbar.ImageSize;
1315 int image_width = image_size.Width + 2 * theme.ToolBarImageGripWidth;
1316 int image_height = image_size.Height + 2 * theme.ToolBarImageGripWidth;
1318 if (toolbar.TextAlign == ToolBarTextAlign.Right) {
1319 size.Width = image_width + size.Width;
1320 size.Height = (size.Height > image_height) ? size.Height : image_height;
1322 size.Height = image_height + size.Height;
1323 size.Width = (size.Width > image_width) ? size.Width : image_width;
1326 size.Width += theme.ToolBarGripWidth;
1327 size.Height += theme.ToolBarGripWidth;
1332 public bool Layout ()
1334 if (toolbar == null || !button.Visible)
1337 Size psize = toolbar.ButtonSize;
1339 if ((!toolbar.SizeSpecified) || (button.Style == ToolBarButtonStyle.Separator)) {
1340 size = CalculateSize ();
1341 if (size.Width == 0 || size.Height == 0)
1344 return Layout (size);
1347 public bool Layout (Size size)
1349 if (toolbar == null || !button.Visible)
1354 Size image_size = (toolbar.ImageSize == Size.Empty) ? new Size (16, 16) : toolbar.ImageSize;
1355 int grip = ThemeEngine.Current.ToolBarImageGripWidth;
1357 Rectangle new_image_rect, new_text_rect;
1359 if (toolbar.TextAlign == ToolBarTextAlign.Underneath) {
1360 new_image_rect = new Rectangle ((bounds.Size.Width - image_size.Width) / 2 - grip, 0, image_size.Width + 2 + grip, image_size.Height + 2 * grip);
1361 new_text_rect = new Rectangle (0, new_image_rect.Height, bounds.Size.Width, bounds.Size.Height - new_image_rect.Height - 2 * grip);
1363 new_image_rect = new Rectangle (0, 0, image_size.Width + 2 * grip, image_size.Height + 2 * grip);
1364 new_text_rect = new Rectangle (new_image_rect.Width, 0, bounds.Size.Width - new_image_rect.Width, bounds.Size.Height - 2 * grip);
1367 bool changed = false;
1369 if (new_image_rect != image_rect || new_text_rect != text_rect)
1372 image_rect = new_image_rect;
1373 text_rect = new_text_rect;
1378 public void Invalidate ()
1380 if (toolbar != null)
1381 toolbar.Invalidate (Rectangle);