2008-05-06 George Giolfan <georgegiolfan@yahoo.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolBar.cs
1 // System.Windows.Forms.ToolBar.cs
2 //
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:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
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.
21 //
22 // Author:
23 //      Ravindra (rkumar@novell.com)
24 //      Mike Kestner <mkestner@novell.com>
25 //      Everaldo Canuto <ecanuto@novell.com>
26 //
27 // Copyright (C) 2004-2006  Novell, Inc. (http://www.novell.com)
28 //
29
30 using System.Collections;
31 using System.ComponentModel;
32 using System.ComponentModel.Design;
33 using System.Drawing;
34 using System.Drawing.Text;
35 using System.Drawing.Imaging;
36 using System.Runtime.InteropServices;
37
38 namespace System.Windows.Forms
39 {
40 #if NET_2_0
41         [ComVisible (true)]
42         [ClassInterface (ClassInterfaceType.AutoDispatch)]
43 #endif
44         [DefaultEvent ("ButtonClick")]
45         [DefaultProperty ("Buttons")]
46         [Designer ("System.Windows.Forms.Design.ToolBarDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
47         public class ToolBar : Control
48         {
49                 #region Instance Variables
50                 private bool size_specified = false;
51                 private ToolBarItem current_item;
52                 internal ToolBarItem[] items;
53                 internal Size default_size;
54                 #endregion Instance Variables
55
56                 #region Events
57                 static object ButtonClickEvent = new object ();
58                 static object ButtonDropDownEvent = new object ();
59
60 #if NET_2_0
61                 [Browsable (true)]
62                 [EditorBrowsable (EditorBrowsableState.Always)]
63                 public new event EventHandler AutoSizeChanged {
64                         add { base.AutoSizeChanged += value; }
65                         remove { base.AutoSizeChanged -= value; }
66                 }
67 #endif
68
69                 [Browsable (false)]
70                 [EditorBrowsable (EditorBrowsableState.Never)]
71                 public new event EventHandler BackColorChanged {
72                         add { base.BackColorChanged += value; }
73                         remove { base.BackColorChanged -= value; }
74                 }
75
76                 [Browsable (false)]
77                 [EditorBrowsable (EditorBrowsableState.Never)]
78                 public new event EventHandler BackgroundImageChanged {
79                         add { base.BackgroundImageChanged += value; }
80                         remove { base.BackgroundImageChanged -= value; }
81                 }
82
83 #if NET_2_0
84                 [Browsable (false)]
85                 [EditorBrowsable (EditorBrowsableState.Never)]
86                 public new event EventHandler BackgroundImageLayoutChanged {
87                         add { base.BackgroundImageLayoutChanged += value; }
88                         remove { base.BackgroundImageLayoutChanged -= value; }
89                 }
90 #endif
91
92                 public event ToolBarButtonClickEventHandler ButtonClick {
93                         add { Events.AddHandler (ButtonClickEvent, value); }
94                         remove {Events.RemoveHandler (ButtonClickEvent, value); }
95                 }
96
97                 public event ToolBarButtonClickEventHandler ButtonDropDown {
98                         add { Events.AddHandler (ButtonDropDownEvent, value); }
99                         remove {Events.RemoveHandler (ButtonDropDownEvent, value); }
100                 }
101
102                 [Browsable (false)]
103                 [EditorBrowsable (EditorBrowsableState.Never)]
104                 public new event EventHandler ForeColorChanged {
105                         add { base.ForeColorChanged += value; }
106                         remove { base.ForeColorChanged -= value; }
107                 }
108
109                 [Browsable (false)]
110                 [EditorBrowsable (EditorBrowsableState.Never)]
111                 public new event EventHandler ImeModeChanged {
112                         add { base.ImeModeChanged += value; }
113                         remove { base.ImeModeChanged -= value; }
114                 }
115
116                 [Browsable (false)]
117                 [EditorBrowsable (EditorBrowsableState.Never)]
118                 public new event PaintEventHandler Paint {
119                         add { base.Paint += value; }
120                         remove { base.Paint -= value; }
121                 }
122
123                 [Browsable (false)]
124                 [EditorBrowsable (EditorBrowsableState.Never)]
125                 public new event EventHandler RightToLeftChanged {
126                         add { base.RightToLeftChanged += value; }
127                         remove { base.RightToLeftChanged -= value; }
128                 }
129
130                 [Browsable (false)]
131                 [EditorBrowsable (EditorBrowsableState.Never)]
132                 public new event EventHandler TextChanged {
133                         add { base.TextChanged += value; }
134                         remove { base.TextChanged -= value; }
135                 }
136                 #endregion Events
137
138                 #region Constructor
139                 public ToolBar ()
140                 {
141                         background_color = ThemeEngine.Current.DefaultControlBackColor;
142                         foreground_color = ThemeEngine.Current.DefaultControlForeColor;
143                         buttons = new ToolBarButtonCollection (this);
144                         Dock = DockStyle.Top;
145                         
146                         GotFocus += new EventHandler (FocusChanged);
147                         LostFocus += new EventHandler (FocusChanged);
148                         MouseDown += new MouseEventHandler (ToolBar_MouseDown);
149                         MouseHover += new EventHandler (ToolBar_MouseHover);
150                         MouseLeave += new EventHandler (ToolBar_MouseLeave);
151                         MouseMove += new MouseEventHandler (ToolBar_MouseMove);
152                         MouseUp += new MouseEventHandler (ToolBar_MouseUp);
153                         BackgroundImageChanged += new EventHandler (ToolBar_BackgroundImageChanged);
154
155                         TabStop = false;
156                         
157                         SetStyle (ControlStyles.UserPaint, false);
158                         SetStyle (ControlStyles.FixedHeight, true);
159                         SetStyle (ControlStyles.FixedWidth, false);
160                 }
161                 #endregion Constructor
162
163                 #region protected Properties
164                 protected override CreateParams CreateParams {
165                         get { 
166                                 CreateParams create_params = base.CreateParams;
167                                 
168                                 if (appearance == ToolBarAppearance.Flat) {
169                                         create_params.Style |= (int) ToolBarStyles.TBSTYLE_FLAT;
170                                 }
171                                 
172                                 return create_params;
173                         }
174                 }
175
176                 protected override ImeMode DefaultImeMode {
177                         get { return ImeMode.Disable; }
178                 }
179
180                 protected override Size DefaultSize {
181                         get { return ThemeEngine.Current.ToolBarDefaultSize; }
182                 }
183
184 #if NET_2_0
185                 [EditorBrowsable (EditorBrowsableState.Never)]
186                 protected override bool DoubleBuffered {
187                         get { return base.DoubleBuffered; }
188                         set { base.DoubleBuffered = value; }
189                 }
190 #endif
191                 #endregion
192
193                 ToolBarAppearance appearance = ToolBarAppearance.Normal;
194
195                 #region Public Properties
196                 [DefaultValue (ToolBarAppearance.Normal)]
197                 [Localizable (true)]
198                 public ToolBarAppearance Appearance {
199                         get { return appearance; }
200                         set {
201                                 if (value == appearance)
202                                         return;
203
204                                 appearance = value;
205                                 Redraw (true);
206                         }
207                 }
208
209                 bool autosize = true;
210
211 #if NET_2_0
212                 [Browsable (true)]
213                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
214                 [EditorBrowsable (EditorBrowsableState.Always)]
215 #endif
216                 [DefaultValue (true)]
217                 [Localizable (true)]
218                 public 
219 #if NET_2_0
220                 override
221 #else
222                 new
223 #endif
224                 bool AutoSize {
225                         get { return autosize; }
226                         set {
227                                 if (value == autosize)
228                                         return;
229
230                                 autosize = value;
231                                 
232                                 if (IsHandleCreated)
233                                         Redraw (true);
234                         }
235                 }
236
237                 [Browsable (false)]
238                 [EditorBrowsable (EditorBrowsableState.Never)]
239                 public override Color BackColor {
240                         get { return background_color; }
241                         set {
242                                 if (value == background_color)
243                                         return;
244
245                                 background_color = value;
246                                 OnBackColorChanged (EventArgs.Empty);
247                                 Redraw (false);
248                         }
249                 }
250
251                 [Browsable (false)]
252                 [EditorBrowsable (EditorBrowsableState.Never)]
253                 public override Image BackgroundImage {
254                         get { return base.BackgroundImage; }
255                         set { base.BackgroundImage = value; }
256                 }
257
258 #if NET_2_0
259                 [Browsable (false)]
260                 [EditorBrowsable (EditorBrowsableState.Never)]
261                 public override ImageLayout BackgroundImageLayout {
262                         get { return base.BackgroundImageLayout; }
263                         set { base.BackgroundImageLayout = value; }
264                 }
265 #endif
266
267                 [DefaultValue (BorderStyle.None)]
268                 [DispIdAttribute (-504)]
269                 public BorderStyle BorderStyle {
270                         get { return InternalBorderStyle; }
271                         set { InternalBorderStyle = value; }
272                 }
273
274                 ToolBarButtonCollection buttons;
275
276                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
277                 [Localizable (true)]
278                 [MergableProperty (false)]
279                 public ToolBarButtonCollection Buttons {
280                         get { return buttons; }
281                 }
282
283                 Size button_size;
284
285                 [Localizable (true)]
286                 [RefreshProperties (RefreshProperties.All)]
287                 public Size ButtonSize {
288                         get {
289                                 if (!button_size.IsEmpty)
290                                         return button_size; 
291                                 
292                                 if (buttons.Count == 0)
293                                         return new Size (39, 36);
294                                         
295                                 Size result = CalcButtonSize ();
296                                 if (result.IsEmpty)
297                                         return new Size (24, 22);
298                                 else
299                                         return result;
300                         }
301                         set {
302                                 size_specified = value != Size.Empty;
303                                 if (button_size == value)
304                                         return;
305
306                                 button_size = value;
307                                 Redraw (true);
308                         }
309                 }
310
311                 bool divider = true;
312
313                 [DefaultValue (true)]
314                 public bool Divider {
315                         get { return divider; }
316                         set {
317                                 if (value == divider)
318                                         return;
319
320                                 divider = value;
321                                 Redraw (false);
322                         }
323                 }
324
325                 [DefaultValue (DockStyle.Top)]
326                 [Localizable (true)]
327                 public override DockStyle Dock {
328                         get { return base.Dock; }
329                         set {
330                                 if (base.Dock == value) {
331                                         // Call base anyways so layout_type gets set correctly
332                                         if (value != DockStyle.None)
333                                                 base.Dock = value;
334                                         return;
335                                 }
336                                         
337                                 if (Vertical) {
338                                         SetStyle (ControlStyles.FixedWidth, AutoSize);
339                                         SetStyle (ControlStyles.FixedHeight, false);
340                                 } else {
341                                         SetStyle (ControlStyles.FixedHeight, AutoSize);
342                                         SetStyle (ControlStyles.FixedWidth, false);
343                                 }
344                                 
345                                 LayoutToolBar ();
346                                 
347                                 base.Dock = value;
348                         }
349                 }
350
351                 bool drop_down_arrows = true;
352
353                 [DefaultValue (false)]
354                 [Localizable (true)]
355                 public bool DropDownArrows {
356                         get { return drop_down_arrows; }
357                         set {
358                                 if (value == drop_down_arrows)
359                                         return;
360
361                                 drop_down_arrows = value;
362                                 Redraw (true);
363                         }
364                 }
365
366                 [Browsable (false)]
367                 [EditorBrowsable (EditorBrowsableState.Never)]
368                 public override Color ForeColor {
369                         get { return foreground_color; }
370                         set {
371                                 if (value == foreground_color)
372                                         return;
373
374                                 foreground_color = value;
375                                 OnForeColorChanged (EventArgs.Empty);
376                                 Redraw (false);
377                         }
378                 }
379
380                 ImageList image_list;
381
382                 [DefaultValue (null)]
383                 public ImageList ImageList {
384                         get { return image_list; }
385                         set { 
386                                 if (image_list == value)
387                                         return;
388                                 image_list = value;
389                                 Redraw (true);
390                         }
391                 }
392
393                 [Browsable (false)]
394                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
395                 [EditorBrowsable (EditorBrowsableState.Advanced)]
396                 public Size ImageSize {
397                         get {
398                                 if (ImageList == null)
399                                         return Size.Empty;
400
401                                 return ImageList.ImageSize;
402                         }
403                 }
404
405                 // XXX this should probably go away and it should call
406                 // into Control.ImeMode instead.
407                 new ImeMode ime_mode = ImeMode.Disable;
408
409                 [Browsable (false)]
410                 [EditorBrowsable (EditorBrowsableState.Never)]
411                 public new ImeMode ImeMode {
412                         get { return ime_mode; }
413                         set {
414                                 if (value == ime_mode)
415                                         return;
416
417                                 ime_mode = value;
418                                 OnImeModeChanged (EventArgs.Empty);
419                         }
420                 }
421
422                 [Browsable (false)]
423                 [EditorBrowsable (EditorBrowsableState.Never)]
424                 public override RightToLeft RightToLeft {
425                         get { return base.RightToLeft; }
426                         set {
427                                 if (value == base.RightToLeft)
428                                         return;
429
430                                 base.RightToLeft = value;
431                                 OnRightToLeftChanged (EventArgs.Empty);
432                         }
433                 }
434
435                 // Default value is "false" but after make a test in .NET we get "true" result as default.  
436                 bool show_tooltips = true;
437
438                 [DefaultValue (false)]
439                 [Localizable (true)]
440                 public bool ShowToolTips {
441                         get { return show_tooltips; }
442                         set { show_tooltips = value; }
443                 }
444
445                 [DefaultValue (false)]
446                 public new bool TabStop {
447                         get { return base.TabStop; }
448                         set { base.TabStop = value; }
449                 }
450
451                 [Bindable (false)]
452                 [Browsable (false)]
453                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
454                 [EditorBrowsable (EditorBrowsableState.Never)]
455                 public override string Text {
456                         get { return base.Text; } 
457                         set {
458                                 if (value == base.Text)
459                                         return;
460
461                                 base.Text = value;
462                                 Redraw (true);
463                         }
464                 }
465
466                 ToolBarTextAlign text_alignment = ToolBarTextAlign.Underneath;
467
468                 [DefaultValue (ToolBarTextAlign.Underneath)]
469                 [Localizable (true)]
470                 public ToolBarTextAlign TextAlign {
471                         get { return text_alignment; }
472                         set {
473                                 if (value == text_alignment)
474                                         return;
475
476                                 text_alignment = value;
477                                 Redraw (true);
478                         }
479                 }
480
481                 bool wrappable = true;
482
483                 [DefaultValue (true)]
484                 [Localizable (true)]
485                 public bool Wrappable {
486                         get { return wrappable; }
487                         set {
488                                 if (value == wrappable)
489                                         return;
490
491                                 wrappable = value;
492                                 Redraw (true);
493                         }
494                 }
495                 #endregion Public Properties
496
497                 #region Public Methods
498                 public override string ToString ()
499                 {
500                         int count = this.Buttons.Count;
501
502                         if (count == 0)
503                                 return string.Format ("System.Windows.Forms.ToolBar, Buttons.Count: 0");
504                         else
505                                 return string.Format ("System.Windows.Forms.ToolBar, Buttons.Count: {0}, Buttons[0]: {1}",
506                                                       count, this.Buttons [0].ToString ());
507                 }
508                 #endregion Public Methods
509
510                 #region Protected Methods
511                 protected override void CreateHandle ()
512                 {
513                         base.CreateHandle ();
514                         default_size = CalcButtonSize ();
515                         
516                         // In win32 the recalculate size only happens for not flat style
517                         if (appearance != ToolBarAppearance.Flat)
518                                 Redraw (true);
519                 }
520
521                 protected override void Dispose (bool disposing)
522                 {
523                         if (disposing)
524                                 ImageList = null;
525
526                         base.Dispose (disposing);
527                 }
528
529                 protected virtual void OnButtonClick (ToolBarButtonClickEventArgs e)
530                 {
531                         if (e.Button.Style == ToolBarButtonStyle.ToggleButton) {
532                                 if (! e.Button.Pushed)
533                                         e.Button.Pushed = true;
534                                 else
535                                         e.Button.Pushed = false;
536                         }
537                         
538                         current_item.Pressed = false;
539                         current_item.Invalidate ();
540                         
541                         ToolBarButtonClickEventHandler eh = (ToolBarButtonClickEventHandler)(Events [ButtonClickEvent]);
542                         if (eh != null)
543                                 eh (this, e);
544                 }
545
546                 protected virtual void OnButtonDropDown (ToolBarButtonClickEventArgs e) 
547                 {
548                         ToolBarButtonClickEventHandler eh = (ToolBarButtonClickEventHandler)(Events [ButtonDropDownEvent]);
549                         if (eh != null)
550                                 eh (this, e);
551
552                         if (e.Button.DropDownMenu == null)
553                                 return;
554
555                         ToolBarItem item = current_item;
556
557                         Point loc = new Point (item.Rectangle.X + 1, item.Rectangle.Bottom + 1);
558                         ((ContextMenu) e.Button.DropDownMenu).Show (this, loc);
559
560                         item.DDPressed = false;
561                         item.Hilight = false;
562                         item.Invalidate ();
563                 }
564
565                 protected override void OnFontChanged (EventArgs e)
566                 {
567                         base.OnFontChanged (e);
568                         Redraw (true);
569                 }
570
571                 protected override void OnHandleCreated (EventArgs e)
572                 {
573                         base.OnHandleCreated (e);
574                 }
575
576                 protected override void OnResize (EventArgs e)
577                 {
578                         base.OnResize (e);
579                         LayoutToolBar ();
580                 }
581
582 #if NET_2_0
583                 protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
584                 {
585                         specified &= ~BoundsSpecified.Height;
586                         
587                         base.ScaleControl (factor, specified);
588                 }
589
590                 [EditorBrowsable (EditorBrowsableState.Never)]
591                 protected override void ScaleCore (float dx, float dy)
592                 {
593                         dy = 1.0f;
594                         
595                         base.ScaleCore (dx, dy);
596                 }
597 #endif
598
599                 private int requested_size = -1;
600
601                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
602                 {
603                         if (Vertical) {
604                                 if (!AutoSize && (requested_size != width) && ((specified & BoundsSpecified.Width) != BoundsSpecified.None)) 
605                                         requested_size = width;
606                         } else {
607                                 if (!AutoSize && (requested_size != height) && ((specified & BoundsSpecified.Height) != BoundsSpecified.None)) 
608                                         requested_size = height;
609                         }
610                         
611                         base.SetBoundsCore (x, y, width, height, specified);
612                 }
613
614                 protected override void WndProc (ref Message m)
615                 {
616                         base.WndProc (ref m);
617                 }
618
619                 internal override bool InternalPreProcessMessage (ref Message msg)
620                 {
621                         if (msg.Msg == (int)Msg.WM_KEYDOWN) {
622                                 Keys key_data = (Keys)msg.WParam.ToInt32();
623                                 if (HandleKeyDown (key_data))
624                                         return true;
625                         } 
626                         return base.InternalPreProcessMessage (ref msg);
627                 }
628                         
629                 #endregion Protected Methods
630
631                 #region Private Methods
632                 private void FocusChanged (object sender, EventArgs args)
633                 {
634                         if (Appearance != ToolBarAppearance.Flat || Buttons.Count == 0)
635                                 return;
636
637                         ToolBarItem prelit = null;
638                         foreach (ToolBarItem item in items) {
639                                 if (item.Hilight) {
640                                         prelit = item;
641                                         break;
642                                 }
643                         }
644
645                         if (Focused && prelit == null) {
646                                 foreach (ToolBarItem item in items) {
647                                         if (item.Button.Enabled) {
648                                                 item.Hilight = true;
649                                                 break;
650                                         }
651                                 }
652                         } else if (prelit != null) {
653                                 prelit.Hilight = false;
654                         }
655                 }
656
657                 private bool HandleKeyDown (Keys key_data)
658                 {
659                         if (Appearance != ToolBarAppearance.Flat || Buttons.Count == 0)
660                                 return false;
661
662                         switch (key_data) {
663                                 case Keys.Left:
664                                 case Keys.Up:
665                                         HighlightButton (-1);
666                                         return true;
667                                 case Keys.Right:
668                                 case Keys.Down:
669                                         HighlightButton (1);
670                                         return true;
671                                 default:
672                                         return false;
673                         }
674                 }
675
676                 void HighlightButton (int offset)
677                 {
678                         ArrayList enabled = new ArrayList ();
679                         int count = 0;
680                         int start = -1;
681                         ToolBarItem curr_item = null;
682                         foreach (ToolBarItem item in items) {
683                                 if (item.Hilight) {
684                                         start = count;
685                                         curr_item = item;
686                                 }
687
688                                 if (item.Button.Enabled) {
689                                         enabled.Add (item);
690                                         count++;
691                                 }
692                         }
693
694                         int next = (start + offset) % count;
695                         if (next < 0)
696                                 next = count - 1;
697
698                         if (next == start)
699                                 return;
700
701                         if (curr_item != null)
702                                 curr_item.Hilight = false;
703                         (enabled [next] as ToolBarItem).Hilight = true;
704                 }
705
706                 private void ToolBar_BackgroundImageChanged (object sender, EventArgs args)
707                 {
708                         Redraw (false, true);
709                 }
710
711                 private void ToolBar_MouseDown (object sender, MouseEventArgs me)
712                 {
713                         if ((!Enabled) || ((me.Button & MouseButtons.Left) == 0))
714                                 return;
715
716                         Point loc = new Point (me.X, me.Y);
717
718                         if (ItemAtPoint (loc) == null)
719                                 return;
720                         
721                         // Hide tooltip when left mouse button 
722                         if ((tip_window != null) && (tip_window.Visible) && ((me.Button & MouseButtons.Left) == MouseButtons.Left)) {
723                                 TipDownTimer.Stop ();
724                                 tip_window.Hide (this);
725                         }
726                         
727                         // draw the pushed button
728                         foreach (ToolBarItem item in items) {
729                                 if (item.Button.Enabled && item.Rectangle.Contains (loc)) {
730                                         // Mark the DropDown rect as pressed.
731                                         // We don't redraw the dropdown rect.
732                                         if (item.Button.Style == ToolBarButtonStyle.DropDownButton) {
733                                                 Rectangle rect = item.Rectangle;
734                                                 if (DropDownArrows) {
735                                                         rect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
736                                                         rect.X = item.Rectangle.Right - rect.Width;
737                                                 }
738                                                 
739                                                 if (rect.Contains (loc)) {
740                                                         if (item.Button.DropDownMenu != null) {
741                                                                 item.DDPressed = true;
742                                                                 Invalidate (rect);
743                                                         }
744                                                         break;
745                                                 }
746                                         }
747                                         item.Pressed = true;
748                                         item.Inside = true;
749                                         item.Invalidate ();
750                                         break;
751                                 }
752                         }
753                 }
754
755                 private void ToolBar_MouseUp (object sender, MouseEventArgs me)
756                 {
757                         if ((!Enabled) || ((me.Button & MouseButtons.Left) == 0))
758                                 return;
759
760                         Point loc = new Point (me.X, me.Y);
761
762                         // draw the normal button
763                         // Make a copy in case the list is modified during enumeration
764                         ArrayList items = new ArrayList (this.items);
765                         foreach (ToolBarItem item in items) {
766                                 if (item.Button.Enabled && item.Rectangle.Contains (loc)) {
767                                         if (item.Button.Style == ToolBarButtonStyle.DropDownButton) {
768                                                 Rectangle ddRect = item.Rectangle;
769                                                 ddRect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
770                                                 ddRect.X = item.Rectangle.Right - ddRect.Width;
771                                                 if (ddRect.Contains (loc)) {
772                                                         current_item = item;
773                                                         if (item.DDPressed)
774                                                                 OnButtonDropDown (new ToolBarButtonClickEventArgs (item.Button));
775                                                         continue;
776                                                 }
777                                         }
778                                         // Fire a ButtonClick
779                                         current_item = item;
780                                         if ((item.Pressed) && ((me.Button & MouseButtons.Left) == MouseButtons.Left))
781                                                 OnButtonClick (new ToolBarButtonClickEventArgs (item.Button));
782                                 } else if (item.Pressed) {
783                                         item.Pressed = false;
784                                         item.Invalidate ();
785                                 }
786                         }
787                 }
788
789                 private ToolBarItem ItemAtPoint (Point pt)
790                 {
791                         foreach (ToolBarItem item in items)
792                                 if (item.Rectangle.Contains (pt)) 
793                                         return item;
794
795                         return null;
796                 }
797
798                 ToolTip tip_window = null;
799                 Timer tipdown_timer = null;
800
801                 private void PopDownTip (object o, EventArgs args)
802                 {
803                         tip_window.Hide (this);
804                 }
805
806                 private Timer TipDownTimer {
807                         get {
808                                 if (tipdown_timer == null) {
809                                         tipdown_timer = new Timer ();
810                                         tipdown_timer.Enabled = false;
811                                         tipdown_timer.Interval = 5000;
812                                         tipdown_timer.Tick += new EventHandler (PopDownTip);
813                                 }
814                                 return tipdown_timer;
815                         }
816                 }
817
818                 private void ToolBar_MouseHover (object sender, EventArgs e)
819                 {
820                         if (Capture)
821                                 return;
822
823                         if (tip_window == null)
824                                 tip_window = new ToolTip ();
825
826                         ToolBarItem item = ItemAtPoint (PointToClient (Control.MousePosition));
827                         current_item = item;
828
829                         if (item == null || item.Button.ToolTipText.Length == 0)
830                                 return;
831
832                         tip_window.Present (this, item.Button.ToolTipText);
833                         TipDownTimer.Start ();
834                 }
835
836                 private void ToolBar_MouseLeave (object sender, EventArgs e)
837                 {
838                         if (tipdown_timer != null)
839                                 tipdown_timer.Dispose ();
840                         tipdown_timer = null;
841                         if (tip_window != null)
842                                 tip_window.Dispose ();
843                         tip_window = null;
844
845                         if (!Enabled || current_item == null) 
846                                 return;
847
848                         current_item.Hilight = false;
849                         current_item = null;
850                 }
851
852                 private void ToolBar_MouseMove (object sender, MouseEventArgs me)
853                 {
854                         if (!Enabled) 
855                                 return;
856
857                         if (tip_window != null && tip_window.Visible) {
858                                 TipDownTimer.Stop ();
859                                 TipDownTimer.Start ();
860                         }
861
862                         Point loc = new Point (me.X, me.Y);
863
864                         if (Capture) {
865                                 // If the button was pressed and we leave, release the 
866                                 // button press and vice versa
867                                 foreach (ToolBarItem item in items) {
868                                         if (item.Pressed &&
869                                             (item.Inside != item.Rectangle.Contains (loc))) {
870                                                 item.Inside = item.Rectangle.Contains (loc);
871                                                 item.Hilight = false;
872                                                 break;
873                                         }
874                                 }
875                                 return;
876                         } 
877
878                         if (current_item != null && current_item.Rectangle.Contains (loc)) {
879                                 if (appearance == ToolBarAppearance.Flat) {
880                                         if (current_item.Hilight || current_item.Button.Pushed || !current_item.Button.Enabled)
881                                                 return;
882                                         current_item.Hilight = true;
883                                 }
884                         } else {
885                                 if (tip_window != null) {
886                                         if (tip_window.Visible) {
887                                                 tip_window.Hide (this);
888                                                 TipDownTimer.Stop ();
889                                         }
890                                         current_item = ItemAtPoint (loc);
891                                         if (current_item != null && current_item.Button.ToolTipText.Length > 0) {
892                                                 tip_window.Present (this, current_item.Button.ToolTipText);
893                                                 TipDownTimer.Start ();
894                                         }
895                                 }
896
897                                 if (appearance == ToolBarAppearance.Flat) {
898                                         foreach (ToolBarItem item in items) {
899                                                 if (item.Rectangle.Contains (loc) && item.Button.Enabled) {
900                                                         current_item = item;
901                                                         if (current_item.Hilight || current_item.Button.Pushed)
902                                                                 continue;
903                                                         current_item.Hilight = true;
904                                                 }
905                                                 else if (item.Hilight) {
906                                                         item.Hilight = false;
907                                                 }
908                                         }
909                                 }
910                         }
911                 }
912
913                 internal override void OnPaintInternal (PaintEventArgs pevent)
914                 {
915                         if (GetStyle (ControlStyles.UserPaint))
916                                 return;
917                                 
918                         ThemeEngine.Current.DrawToolBar (pevent.Graphics, pevent.ClipRectangle, this);
919                         
920                         // Toolbars do not raise OnPaint unless UserPaint is set
921                         pevent.Handled = true;
922                 }
923
924                 internal void Redraw (bool recalculate)
925                 {
926                         Redraw (recalculate, true);
927                 }
928
929                 internal void Redraw (bool recalculate, bool force)
930                 {
931                         bool invalidate = true;
932                         
933                         if (recalculate)
934                                 invalidate = LayoutToolBar ();
935
936                         if (force || invalidate)
937                                 Invalidate ();
938                 }
939
940                 internal bool SizeSpecified {
941                         get { return size_specified; }
942                 }
943                 
944                 internal bool Vertical {
945                         get { return (Dock == DockStyle.Left) || (Dock == DockStyle.Right); }
946                 }
947
948                 internal const int text_padding = 3;
949
950                 private Size CalcButtonSize ()
951                 {
952                         if (Buttons.Count == 0)
953                                 return Size.Empty;
954
955                         string longest_text = Buttons [0].Text;
956                         for (int i = 1; i < Buttons.Count; i++) {
957                                 if (Buttons[i].Text.Length > longest_text.Length)
958                                         longest_text = Buttons[i].Text;
959                         }
960
961                         Size size = Size.Empty;
962                         if (longest_text != null && longest_text.Length > 0) {
963                                 SizeF sz = TextRenderer.MeasureString (longest_text, Font);
964                                 if (sz != SizeF.Empty)
965                                         size = new Size ((int) Math.Ceiling (sz.Width) + 2 * text_padding, (int) Math.Ceiling (sz.Height));
966                         }
967
968                         Size img_size = ImageList == null ? new Size (16, 16) : ImageSize;
969
970                         Theme theme = ThemeEngine.Current;
971                         int imgWidth = img_size.Width + 2 * theme.ToolBarImageGripWidth; 
972                         int imgHeight = img_size.Height + 2 * theme.ToolBarImageGripWidth;
973
974                         if (text_alignment == ToolBarTextAlign.Right) {
975                                 size.Width = imgWidth + size.Width;
976                                 size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
977                         } else {
978                                 size.Height = imgHeight + size.Height;
979                                 size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
980                         }
981
982                         size.Width += theme.ToolBarImageGripWidth;
983                         size.Height += theme.ToolBarImageGripWidth;
984                         return size;
985                 }
986
987                 // Flat toolbars disregard specified sizes.  Normal toolbars grow the
988                 // button size to be at least large enough to show the image.
989                 private Size AdjustedButtonSize {
990                         get {
991                                 Size size;
992
993                                 if (default_size.IsEmpty || Appearance == ToolBarAppearance.Normal) 
994                                         size = ButtonSize;
995                                 else
996                                         size = default_size;
997                                 
998                                 if (size_specified) {
999                                         if (Appearance == ToolBarAppearance.Flat)
1000                                                 size = CalcButtonSize ();
1001                                         else {
1002                                                 int grip = ThemeEngine.Current.ToolBarImageGripWidth;
1003                                                 if (size.Width < ImageSize.Width + 2 * grip )
1004                                                         size.Width = ImageSize.Width + 2 * grip;
1005                                                 if (size.Height < ImageSize.Height + 2 * grip)
1006                                                         size.Height = ImageSize.Height + 2 * grip;
1007                                         }
1008                                 }
1009                                 return size;
1010                         }
1011                 }
1012
1013                 private bool LayoutToolBar ()
1014                 {
1015                         bool changed = false;
1016                         Theme theme = ThemeEngine.Current;
1017                         int x = theme.ToolBarGripWidth;
1018                         int y = theme.ToolBarGripWidth;
1019
1020                         Size adjusted_size = AdjustedButtonSize;
1021                         
1022                         int calculated_size = (Vertical ? adjusted_size.Width : adjusted_size.Height) + theme.ToolBarGripWidth;
1023                         
1024                         int separator_index = -1;
1025
1026                         items = new ToolBarItem [buttons.Count];
1027                         
1028                         for (int i = 0; i < buttons.Count; i++) {
1029                                 ToolBarButton button = buttons [i];
1030                                 
1031                                 ToolBarItem item = new ToolBarItem (button);
1032                                 items [i] = item;
1033
1034                                 if (!button.Visible)
1035                                         continue;
1036
1037                                 if (size_specified && (button.Style != ToolBarButtonStyle.Separator))
1038                                         changed = item.Layout (adjusted_size);
1039                                 else
1040                                         changed = item.Layout (Vertical, calculated_size);
1041                                 
1042                                 bool is_separator = button.Style == ToolBarButtonStyle.Separator;
1043                                 
1044                                 if (Vertical) {
1045                                         if (y + item.Rectangle.Height < Height || is_separator || !Wrappable) {
1046                                                 if (item.Location.X != x || item.Location.Y != y)
1047                                                         changed = true;
1048                                                 item.Location = new Point (x, y);
1049                                                 y += item.Rectangle.Height;
1050                                                 if (is_separator)
1051                                                         separator_index = i;
1052                                         } else if (separator_index > 0) {
1053                                                 i = separator_index;
1054                                                 separator_index = -1;
1055                                                 y = theme.ToolBarGripWidth;
1056                                                 x += calculated_size; 
1057                                         } else {
1058                                                 y = theme.ToolBarGripWidth;
1059                                                 x += calculated_size; 
1060                                                 if (item.Location.X != x || item.Location.Y != y)
1061                                                         changed = true;
1062                                                 item.Location = new Point (x, y);
1063                                                 y += item.Rectangle.Height;
1064                                         }
1065                                 } else {
1066                                         if (x + item.Rectangle.Width < Width || is_separator || !Wrappable) {
1067                                                 if (item.Location.X != x || item.Location.Y != y)
1068                                                         changed = true;
1069                                                 item.Location = new Point (x, y);
1070                                                 x += item.Rectangle.Width;
1071                                                 if (is_separator)
1072                                                         separator_index = i;
1073                                         } else if (separator_index > 0) {
1074                                                 i = separator_index;
1075                                                 separator_index = -1;
1076                                                 x = theme.ToolBarGripWidth;
1077                                                 y += calculated_size; 
1078                                         } else {
1079                                                 x = theme.ToolBarGripWidth;
1080                                                 y += calculated_size; 
1081                                                 if (item.Location.X != x || item.Location.Y != y)
1082                                                         changed = true;
1083                                                 item.Location = new Point (x, y);
1084                                                 x += item.Rectangle.Width;
1085                                         }
1086                                 }
1087                         }
1088                         
1089                         if (Parent == null)
1090                                 return changed;
1091                         
1092                         if (Wrappable)
1093                                 calculated_size += Vertical ? x : y;
1094                         
1095                         if (IsHandleCreated) {
1096                                 if (Vertical)
1097                                         Width = calculated_size;
1098                                 else
1099                                         Height = calculated_size; 
1100                         }
1101                         
1102                         return changed;
1103                 }
1104                 #endregion Private Methods
1105
1106                 #region subclass
1107                 public class ToolBarButtonCollection : IList, ICollection, IEnumerable
1108                 {
1109                         #region instance variables
1110                         private ArrayList list; // ToolBarButton list
1111                         private ToolBar owner;  // ToolBar associated to Collection
1112                         private bool redraw;    // Flag if needs to redraw after add/remove operations
1113                         #endregion
1114
1115                         #region constructors
1116                         public ToolBarButtonCollection (ToolBar owner)
1117                         {
1118                                 this.list   = new ArrayList ();
1119                                 this.owner  = owner;
1120                                 this.redraw = true;
1121                         }
1122                         #endregion
1123
1124                         #region properties
1125                         [Browsable (false)]
1126                         public int Count {
1127                                 get { return list.Count; }
1128                         }
1129
1130                         public bool IsReadOnly {
1131                                 get { return list.IsReadOnly; }
1132                         }
1133
1134                         public virtual ToolBarButton this [int index] {
1135                                 get { return (ToolBarButton) list [index]; }
1136                                 set {
1137                                         value.SetParent (owner);
1138                                         list [index] = value;
1139                                         owner.Redraw (true);
1140                                 }
1141                         }
1142
1143 #if NET_2_0
1144                         public virtual ToolBarButton this[string key] {
1145                                 get {
1146                                         if (string.IsNullOrEmpty (key))
1147                                                 return null;
1148                                                 
1149                                         foreach (ToolBarButton b in list)
1150                                                 if (string.Compare (b.Name, key, true) == 0)
1151                                                         return b;
1152                                                         
1153                                         return null;
1154                                 }
1155                         }
1156 #endif
1157
1158                         bool ICollection.IsSynchronized {
1159                                 get { return list.IsSynchronized; }
1160                         }
1161
1162                         object ICollection.SyncRoot {
1163                                 get { return list.SyncRoot; }
1164                         }
1165
1166                         bool IList.IsFixedSize {
1167                                 get { return list.IsFixedSize; }
1168                         }
1169
1170                         object IList.this [int index] {
1171                                 get { return this [index]; }
1172                                 set {
1173                                         if (! (value is ToolBarButton))
1174                                                 throw new ArgumentException("Not of type ToolBarButton", "value");
1175                                         this [index] = (ToolBarButton) value;
1176                                 }
1177                         }
1178                         #endregion
1179
1180                         #region methods
1181                         public int Add (string text)
1182                         {
1183                                 ToolBarButton button = new ToolBarButton (text);
1184                                 return this.Add (button);
1185                         }
1186
1187                         public int Add (ToolBarButton button)
1188                         {
1189                                 int result;
1190                                 button.SetParent (owner);
1191                                 result = list.Add (button);
1192                                 if (redraw)
1193                                         owner.Redraw (true);
1194                                 return result;
1195                         }
1196
1197                         public void AddRange (ToolBarButton [] buttons)
1198                         {
1199                                 try {
1200                                         redraw = false;
1201                                         foreach (ToolBarButton button in buttons)
1202                                                 Add (button);
1203                                 }
1204                                 finally {
1205                                         redraw = true;
1206                                         owner.Redraw (true);
1207                                 }
1208                         }
1209
1210                         public void Clear ()
1211                         {
1212                                 list.Clear ();
1213                                 owner.Redraw (false);
1214                         }
1215
1216                         public bool Contains (ToolBarButton button)
1217                         {
1218                                 return list.Contains (button);
1219                         }
1220
1221 #if NET_2_0
1222                         public virtual bool ContainsKey (string key)
1223                         {
1224                                 return !(this[key] == null);
1225                         }
1226 #endif
1227
1228                         public IEnumerator GetEnumerator ()
1229                         {
1230                                 return list.GetEnumerator ();
1231                         }
1232
1233                         void ICollection.CopyTo (Array dest, int index)
1234                         {
1235                                 list.CopyTo (dest, index);
1236                         }
1237
1238                         int IList.Add (object button)
1239                         {
1240                                 if (! (button is ToolBarButton)) {
1241                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1242                                 }
1243
1244                                 return this.Add ((ToolBarButton) button);
1245                         }
1246
1247                         bool IList.Contains (object button)
1248                         {
1249                                 if (! (button is ToolBarButton)) {
1250                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1251                                 }
1252
1253                                 return this.Contains ((ToolBarButton) button);
1254                         }
1255
1256                         int IList.IndexOf (object button)
1257                         {
1258                                 if (! (button is ToolBarButton)) {
1259                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1260                                 }
1261
1262                                 return this.IndexOf ((ToolBarButton) button);
1263                         }
1264
1265                         void IList.Insert (int index, object button)
1266                         {
1267                                 if (! (button is ToolBarButton)) {
1268                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1269                                 }
1270
1271                                 this.Insert (index, (ToolBarButton) button);
1272                         }
1273
1274                         void IList.Remove (object button)
1275                         {
1276                                 if (! (button is ToolBarButton)) {
1277                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1278                                 }
1279
1280                                 this.Remove ((ToolBarButton) button);
1281                         }
1282
1283                         public int IndexOf (ToolBarButton button)
1284                         {
1285                                 return list.IndexOf (button);
1286                         }
1287
1288 #if NET_2_0
1289                         public virtual int IndexOfKey (string key)
1290                         {
1291                                 return IndexOf (this[key]);
1292                         }
1293 #endif
1294
1295                         public void Insert (int index, ToolBarButton button)
1296                         {
1297                                 list.Insert (index, button);
1298                                 owner.Redraw (true);
1299                         }
1300
1301                         public void Remove (ToolBarButton button)
1302                         {
1303                                 list.Remove (button);
1304                                 owner.Redraw (true);
1305                         }
1306
1307                         public void RemoveAt (int index)
1308                         {
1309                                 list.RemoveAt (index);
1310                                 owner.Redraw (true);
1311                         }
1312
1313 #if NET_2_0
1314                         public virtual void RemoveByKey (string key)
1315                         {
1316                                 Remove (this[key]);
1317                         }
1318 #endif
1319                         #endregion methods
1320                 }
1321                 
1322                 #endregion subclass
1323         }
1324         
1325         
1326         // Because same button can be added to toolbar multiple times, we need to maintain
1327         // a list of button information for each positions. 
1328         internal class ToolBarItem : Component
1329         {
1330                 #region Instance variables
1331                 
1332                 private ToolBar       toolbar;    // Parent toolbar
1333                 private ToolBarButton button;     // Associated toolBar button 
1334                 private Rectangle     bounds;     // Toolbar button bounds
1335                 private Rectangle     image_rect; // Image button bounds
1336                 private Rectangle     text_rect;  // Text button bounds
1337
1338                 private bool dd_pressed = false;  // to check for a mouse down on dropdown rect
1339                 private bool inside     = false;  // to handle the mouse move event with mouse pressed
1340                 private bool hilight    = false;  // to hilight buttons in flat style
1341                 private bool pressed    = false;  // this is to check for mouse down on a button
1342                 
1343                 #endregion
1344                 
1345                 #region Constructors
1346                 
1347                 public ToolBarItem (ToolBarButton button)
1348                 {
1349                         this.toolbar = button.Parent;
1350                         this.button  = button;
1351                 }
1352                 
1353                 #endregion Constructors
1354         
1355                 #region Properties
1356
1357                 public ToolBarButton Button {
1358                         get { return this.button; }
1359                 }
1360                 
1361                 public Rectangle Rectangle {
1362                         get { 
1363                                 if (!button.Visible || toolbar == null)
1364                                         return Rectangle.Empty;
1365
1366                                 if (button.Style == ToolBarButtonStyle.DropDownButton && toolbar.DropDownArrows) {
1367                                         Rectangle result = bounds;
1368                                         result.Width += ThemeEngine.Current.ToolBarDropDownWidth;
1369                                         return result;
1370                                 }
1371                                  
1372                                 return bounds;
1373                         }
1374                         set { this.bounds = value; }
1375                 }
1376
1377                 public Point Location {
1378                         get { return bounds.Location; }
1379                         set { bounds.Location = value; }
1380                 }
1381
1382                 public Rectangle ImageRectangle {
1383                         get {
1384                                 Rectangle result = image_rect;
1385                                 result.X += bounds.X;
1386                                 result.Y += bounds.Y;
1387                                 return result; 
1388                         }
1389                 }
1390                 
1391                 public Rectangle TextRectangle {
1392                         get { 
1393                                 Rectangle result = text_rect;
1394                                 result.X += bounds.X;
1395                                 result.Y += bounds.Y;
1396                                 return result; 
1397                         }
1398                 }
1399
1400                 private Size TextSize {
1401                         get {
1402                                 StringFormat text_format = new StringFormat ();
1403                                 text_format.HotkeyPrefix = HotkeyPrefix.Hide;
1404
1405                                 SizeF sz = TextRenderer.MeasureString (button.Text, toolbar.Font, SizeF.Empty, text_format);
1406                                 if (sz == SizeF.Empty)
1407                                         return Size.Empty;
1408                                 return new Size ((int) Math.Ceiling (sz.Width) + 2 * ToolBar.text_padding, (int) Math.Ceiling (sz.Height));
1409                         }
1410                 }
1411                 
1412                 public bool Pressed {
1413                         get { return (pressed && inside); }
1414                         set { pressed = value; }
1415                 }
1416
1417                 public bool DDPressed {
1418                         get { return dd_pressed; }
1419                         set { dd_pressed = value; }
1420                 }
1421
1422                 public bool Inside {
1423                         get { return inside; }
1424                         set { inside = value; }
1425                 }
1426
1427                 public bool Hilight {
1428                         get { return hilight; }
1429                         set {
1430                                 if (hilight == value)
1431                                         return;
1432
1433                                 hilight = value;
1434                                 Invalidate ();
1435                         }
1436                 }       
1437                 
1438                 #endregion Properties
1439
1440                 #region Methods
1441                 
1442                 public Size CalculateSize ()
1443                 {
1444                         Theme theme = ThemeEngine.Current;
1445
1446                         int ht = toolbar.ButtonSize.Height + 2 * theme.ToolBarGripWidth;
1447
1448                         if (button.Style == ToolBarButtonStyle.Separator)
1449                                 return new Size (theme.ToolBarSeparatorWidth, ht);
1450
1451                         Size size;
1452                         if (TextSize.IsEmpty && (button.Image == null))
1453                                 size = toolbar.default_size;
1454                         else
1455                                 size = TextSize;
1456                         
1457                         Size image_size = (toolbar.ImageSize == Size.Empty) ? new Size (16, 16) : toolbar.ImageSize;
1458
1459                         int image_width = image_size.Width + 2 * theme.ToolBarImageGripWidth; 
1460                         int image_height = image_size.Height + 2 * theme.ToolBarImageGripWidth; 
1461
1462                         if (toolbar.TextAlign == ToolBarTextAlign.Right) {
1463                                 size.Width =  image_width + size.Width;
1464                                 size.Height = (size.Height > image_height) ? size.Height : image_height;
1465                         } else {
1466                                 size.Height = image_height + size.Height;
1467                                 size.Width = (size.Width > image_width) ? size.Width : image_width;
1468                         }
1469
1470                         size.Width += theme.ToolBarGripWidth;
1471                         size.Height += theme.ToolBarGripWidth;
1472                         return size;
1473                 }
1474
1475                 
1476                 public bool Layout (bool vertical, int calculated_size)
1477                 {
1478                         if (toolbar == null || !button.Visible)
1479                                 return false;
1480
1481                         Size psize = toolbar.ButtonSize;
1482                         Size size = psize;
1483                         if ((!toolbar.SizeSpecified) || (button.Style == ToolBarButtonStyle.Separator)) {
1484                                 size = CalculateSize ();
1485
1486                                 if (size.Width == 0 || size.Height == 0)
1487                                         size = psize;
1488
1489                                 if (vertical)
1490                                         size.Width = calculated_size;
1491                                 else
1492                                         size.Height = calculated_size;
1493                         }
1494                         return Layout (size);
1495                 }
1496
1497                 public bool Layout (Size size)
1498                 {
1499                         if (toolbar == null || !button.Visible)
1500                                 return false;
1501
1502                         bounds.Size = size;
1503
1504                         Size image_size = (toolbar.ImageSize == Size.Empty) ? new Size (16, 16) : toolbar.ImageSize;
1505                         int grip = ThemeEngine.Current.ToolBarImageGripWidth;
1506
1507                         Rectangle new_image_rect, new_text_rect;
1508                         
1509                         if (toolbar.TextAlign == ToolBarTextAlign.Underneath) {
1510                                 new_image_rect = new Rectangle ((bounds.Size.Width - image_size.Width) / 2 - grip, 0, image_size.Width + 2 + grip, image_size.Height + 2 * grip);
1511                                 new_text_rect = new Rectangle (0, new_image_rect.Height, bounds.Size.Width, bounds.Size.Height - new_image_rect.Height - 2 * grip);
1512                         } else {
1513                                 new_image_rect = new Rectangle (0, 0, image_size.Width + 2 * grip, image_size.Height + 2 * grip);
1514                                 new_text_rect = new Rectangle (new_image_rect.Width, 0, bounds.Size.Width - new_image_rect.Width, bounds.Size.Height - 2 * grip);
1515                         }
1516
1517                         bool changed = false;
1518
1519                         if (new_image_rect != image_rect || new_text_rect != text_rect)
1520                                 changed = true;
1521
1522                         image_rect = new_image_rect;
1523                         text_rect = new_text_rect;
1524                         
1525                         return changed;
1526                 }
1527                 
1528                 public void Invalidate ()
1529                 {
1530                         if (toolbar != null)
1531                                 toolbar.Invalidate (Rectangle);
1532                 }
1533
1534                 #endregion Methods
1535         }
1536 }