6bcf21192d9eca4f726d6777d8060e7c5a020812
[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                         ThemeEngine.Current.DrawToolBar (pevent.Graphics, pevent.ClipRectangle, this);
916                 }
917
918                 internal void Redraw (bool recalculate)
919                 {
920                         Redraw (recalculate, true);
921                 }
922
923                 internal void Redraw (bool recalculate, bool force)
924                 {
925                         bool invalidate = true;
926                         
927                         if (recalculate)
928                                 invalidate = LayoutToolBar ();
929
930                         if (force || invalidate)
931                                 Invalidate ();
932                 }
933
934                 internal bool SizeSpecified {
935                         get { return size_specified; }
936                 }
937                 
938                 private bool Vertical {
939                         get { return (Dock == DockStyle.Left) || (Dock == DockStyle.Right); }
940                 }
941
942                 internal const int text_padding = 3;
943
944                 private Size CalcButtonSize ()
945                 {
946                         if (Buttons.Count == 0)
947                                 return Size.Empty;
948
949                         string longest_text = Buttons [0].Text;
950                         for (int i = 1; i < Buttons.Count; i++) {
951                                 if (Buttons[i].Text.Length > longest_text.Length)
952                                         longest_text = Buttons[i].Text;
953                         }
954
955                         Size size = Size.Empty;
956                         if (longest_text != null && longest_text.Length > 0) {
957                                 SizeF sz = TextRenderer.MeasureString (longest_text, Font);
958                                 if (sz != SizeF.Empty)
959                                         size = new Size ((int) Math.Ceiling (sz.Width) + 2 * text_padding, (int) Math.Ceiling (sz.Height));
960                         }
961
962                         Size img_size = ImageList == null ? new Size (16, 16) : ImageSize;
963
964                         Theme theme = ThemeEngine.Current;
965                         int imgWidth = img_size.Width + 2 * theme.ToolBarImageGripWidth; 
966                         int imgHeight = img_size.Height + 2 * theme.ToolBarImageGripWidth;
967
968                         if (text_alignment == ToolBarTextAlign.Right) {
969                                 size.Width = imgWidth + size.Width;
970                                 size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
971                         } else {
972                                 size.Height = imgHeight + size.Height;
973                                 size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
974                         }
975
976                         size.Width += theme.ToolBarImageGripWidth;
977                         size.Height += theme.ToolBarImageGripWidth;
978                         return size;
979                 }
980
981                 // Flat toolbars disregard specified sizes.  Normal toolbars grow the
982                 // button size to be at least large enough to show the image.
983                 private Size AdjustedButtonSize {
984                         get {
985                                 Size size;
986
987                                 if (default_size.IsEmpty || Appearance == ToolBarAppearance.Normal) 
988                                         size = ButtonSize;
989                                 else
990                                         size = default_size;
991                                 
992                                 if (size_specified) {
993                                         if (Appearance == ToolBarAppearance.Flat)
994                                                 size = CalcButtonSize ();
995                                         else {
996                                                 int grip = ThemeEngine.Current.ToolBarImageGripWidth;
997                                                 if (size.Width < ImageSize.Width + 2 * grip )
998                                                         size.Width = ImageSize.Width + 2 * grip;
999                                                 if (size.Height < ImageSize.Height + 2 * grip)
1000                                                         size.Height = ImageSize.Height + 2 * grip;
1001                                         }
1002                                 }
1003                                 return size;
1004                         }
1005                 }
1006
1007                 private bool LayoutToolBar ()
1008                 {
1009                         bool changed = false;
1010                         Theme theme = ThemeEngine.Current;
1011                         int x = theme.ToolBarGripWidth;
1012                         int y = theme.ToolBarGripWidth;
1013
1014                         Size adjusted_size = AdjustedButtonSize;
1015                         
1016                         int calculated_size = (Vertical ? adjusted_size.Width : adjusted_size.Height) + theme.ToolBarGripWidth;
1017                         
1018                         int separator_index = -1;
1019
1020                         items = new ToolBarItem [buttons.Count];
1021                         
1022                         for (int i = 0; i < buttons.Count; i++) {
1023                                 ToolBarButton button = buttons [i];
1024                                 
1025                                 ToolBarItem item = new ToolBarItem (button);
1026                                 items [i] = item;
1027
1028                                 if (!button.Visible)
1029                                         continue;
1030
1031                                 if (size_specified && (button.Style != ToolBarButtonStyle.Separator))
1032                                         changed = item.Layout (adjusted_size);
1033                                 else
1034                                         changed = item.Layout (Vertical, calculated_size);
1035                                 
1036                                 bool is_separator = button.Style == ToolBarButtonStyle.Separator;
1037                                 
1038                                 if (Vertical) {
1039                                         if (y + item.Rectangle.Height < Height || is_separator || !Wrappable) {
1040                                                 if (item.Location.X != x || item.Location.Y != y)
1041                                                         changed = true;
1042                                                 item.Location = new Point (x, y);
1043                                                 y += item.Rectangle.Height;
1044                                                 if (is_separator)
1045                                                         separator_index = i;
1046                                         } else if (separator_index > 0) {
1047                                                 i = separator_index;
1048                                                 separator_index = -1;
1049                                                 y = theme.ToolBarGripWidth;
1050                                                 x += calculated_size; 
1051                                         } else {
1052                                                 y = theme.ToolBarGripWidth;
1053                                                 x += calculated_size; 
1054                                                 if (item.Location.X != x || item.Location.Y != y)
1055                                                         changed = true;
1056                                                 item.Location = new Point (x, y);
1057                                                 y += item.Rectangle.Height;
1058                                         }
1059                                 } else {
1060                                         if (x + item.Rectangle.Width < Width || is_separator || !Wrappable) {
1061                                                 if (item.Location.X != x || item.Location.Y != y)
1062                                                         changed = true;
1063                                                 item.Location = new Point (x, y);
1064                                                 x += item.Rectangle.Width;
1065                                                 if (is_separator)
1066                                                         separator_index = i;
1067                                         } else if (separator_index > 0) {
1068                                                 i = separator_index;
1069                                                 separator_index = -1;
1070                                                 x = theme.ToolBarGripWidth;
1071                                                 y += calculated_size; 
1072                                         } else {
1073                                                 x = theme.ToolBarGripWidth;
1074                                                 y += calculated_size; 
1075                                                 if (item.Location.X != x || item.Location.Y != y)
1076                                                         changed = true;
1077                                                 item.Location = new Point (x, y);
1078                                                 x += item.Rectangle.Width;
1079                                         }
1080                                 }
1081                         }
1082                         
1083                         if (Parent == null)
1084                                 return changed;
1085                         
1086                         if (Wrappable)
1087                                 calculated_size += Vertical ? x : y;
1088                         
1089                         if (IsHandleCreated) {
1090                                 if (Vertical)
1091                                         Width = calculated_size;
1092                                 else
1093                                         Height = calculated_size; 
1094                         }
1095                         
1096                         return changed;
1097                 }
1098                 #endregion Private Methods
1099
1100                 #region subclass
1101                 public class ToolBarButtonCollection : IList, ICollection, IEnumerable
1102                 {
1103                         #region instance variables
1104                         private ArrayList list; // ToolBarButton list
1105                         private ToolBar owner;  // ToolBar associated to Collection
1106                         private bool redraw;    // Flag if needs to redraw after add/remove operations
1107                         #endregion
1108
1109                         #region constructors
1110                         public ToolBarButtonCollection (ToolBar owner)
1111                         {
1112                                 this.list   = new ArrayList ();
1113                                 this.owner  = owner;
1114                                 this.redraw = true;
1115                         }
1116                         #endregion
1117
1118                         #region properties
1119                         [Browsable (false)]
1120                         public int Count {
1121                                 get { return list.Count; }
1122                         }
1123
1124                         public bool IsReadOnly {
1125                                 get { return list.IsReadOnly; }
1126                         }
1127
1128                         public virtual ToolBarButton this [int index] {
1129                                 get { return (ToolBarButton) list [index]; }
1130                                 set {
1131                                         value.SetParent (owner);
1132                                         list [index] = value;
1133                                         owner.Redraw (true);
1134                                 }
1135                         }
1136
1137 #if NET_2_0
1138                         public virtual ToolBarButton this[string key] {
1139                                 get {
1140                                         if (string.IsNullOrEmpty (key))
1141                                                 return null;
1142                                                 
1143                                         foreach (ToolBarButton b in list)
1144                                                 if (string.Compare (b.Name, key, true) == 0)
1145                                                         return b;
1146                                                         
1147                                         return null;
1148                                 }
1149                         }
1150 #endif
1151
1152                         bool ICollection.IsSynchronized {
1153                                 get { return list.IsSynchronized; }
1154                         }
1155
1156                         object ICollection.SyncRoot {
1157                                 get { return list.SyncRoot; }
1158                         }
1159
1160                         bool IList.IsFixedSize {
1161                                 get { return list.IsFixedSize; }
1162                         }
1163
1164                         object IList.this [int index] {
1165                                 get { return this [index]; }
1166                                 set {
1167                                         if (! (value is ToolBarButton))
1168                                                 throw new ArgumentException("Not of type ToolBarButton", "value");
1169                                         this [index] = (ToolBarButton) value;
1170                                 }
1171                         }
1172                         #endregion
1173
1174                         #region methods
1175                         public int Add (string text)
1176                         {
1177                                 ToolBarButton button = new ToolBarButton (text);
1178                                 return this.Add (button);
1179                         }
1180
1181                         public int Add (ToolBarButton button)
1182                         {
1183                                 int result;
1184                                 button.SetParent (owner);
1185                                 result = list.Add (button);
1186                                 if (redraw)
1187                                         owner.Redraw (true);
1188                                 return result;
1189                         }
1190
1191                         public void AddRange (ToolBarButton [] buttons)
1192                         {
1193                                 try {
1194                                         redraw = false;
1195                                         foreach (ToolBarButton button in buttons)
1196                                                 Add (button);
1197                                 }
1198                                 finally {
1199                                         redraw = true;
1200                                         owner.Redraw (true);
1201                                 }
1202                         }
1203
1204                         public void Clear ()
1205                         {
1206                                 list.Clear ();
1207                                 owner.Redraw (false);
1208                         }
1209
1210                         public bool Contains (ToolBarButton button)
1211                         {
1212                                 return list.Contains (button);
1213                         }
1214
1215 #if NET_2_0
1216                         public virtual bool ContainsKey (string key)
1217                         {
1218                                 return !(this[key] == null);
1219                         }
1220 #endif
1221
1222                         public IEnumerator GetEnumerator ()
1223                         {
1224                                 return list.GetEnumerator ();
1225                         }
1226
1227                         void ICollection.CopyTo (Array dest, int index)
1228                         {
1229                                 list.CopyTo (dest, index);
1230                         }
1231
1232                         int IList.Add (object button)
1233                         {
1234                                 if (! (button is ToolBarButton)) {
1235                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1236                                 }
1237
1238                                 return this.Add ((ToolBarButton) button);
1239                         }
1240
1241                         bool IList.Contains (object button)
1242                         {
1243                                 if (! (button is ToolBarButton)) {
1244                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1245                                 }
1246
1247                                 return this.Contains ((ToolBarButton) button);
1248                         }
1249
1250                         int IList.IndexOf (object button)
1251                         {
1252                                 if (! (button is ToolBarButton)) {
1253                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1254                                 }
1255
1256                                 return this.IndexOf ((ToolBarButton) button);
1257                         }
1258
1259                         void IList.Insert (int index, object button)
1260                         {
1261                                 if (! (button is ToolBarButton)) {
1262                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1263                                 }
1264
1265                                 this.Insert (index, (ToolBarButton) button);
1266                         }
1267
1268                         void IList.Remove (object button)
1269                         {
1270                                 if (! (button is ToolBarButton)) {
1271                                         throw new ArgumentException("Not of type ToolBarButton", "button");
1272                                 }
1273
1274                                 this.Remove ((ToolBarButton) button);
1275                         }
1276
1277                         public int IndexOf (ToolBarButton button)
1278                         {
1279                                 return list.IndexOf (button);
1280                         }
1281
1282 #if NET_2_0
1283                         public virtual int IndexOfKey (string key)
1284                         {
1285                                 return IndexOf (this[key]);
1286                         }
1287 #endif
1288
1289                         public void Insert (int index, ToolBarButton button)
1290                         {
1291                                 list.Insert (index, button);
1292                                 owner.Redraw (true);
1293                         }
1294
1295                         public void Remove (ToolBarButton button)
1296                         {
1297                                 list.Remove (button);
1298                                 owner.Redraw (true);
1299                         }
1300
1301                         public void RemoveAt (int index)
1302                         {
1303                                 list.RemoveAt (index);
1304                                 owner.Redraw (true);
1305                         }
1306
1307 #if NET_2_0
1308                         public virtual void RemoveByKey (string key)
1309                         {
1310                                 Remove (this[key]);
1311                         }
1312 #endif
1313                         #endregion methods
1314                 }
1315                 
1316                 #endregion subclass
1317         }
1318         
1319         
1320         // Because same button can be added to toolbar multiple times, we need to maintain
1321         // a list of button information for each positions. 
1322         internal class ToolBarItem : Component
1323         {
1324                 #region Instance variables
1325                 
1326                 private ToolBar       toolbar;    // Parent toolbar
1327                 private ToolBarButton button;     // Associated toolBar button 
1328                 private Rectangle     bounds;     // Toolbar button bounds
1329                 private Rectangle     image_rect; // Image button bounds
1330                 private Rectangle     text_rect;  // Text button bounds
1331
1332                 private bool dd_pressed = false;  // to check for a mouse down on dropdown rect
1333                 private bool inside     = false;  // to handle the mouse move event with mouse pressed
1334                 private bool hilight    = false;  // to hilight buttons in flat style
1335                 private bool pressed    = false;  // this is to check for mouse down on a button
1336                 
1337                 #endregion
1338                 
1339                 #region Constructors
1340                 
1341                 public ToolBarItem (ToolBarButton button)
1342                 {
1343                         this.toolbar = button.Parent;
1344                         this.button  = button;
1345                 }
1346                 
1347                 #endregion Constructors
1348         
1349                 #region Properties
1350
1351                 public ToolBarButton Button {
1352                         get { return this.button; }
1353                 }
1354                 
1355                 public Rectangle Rectangle {
1356                         get { 
1357                                 if (!button.Visible || toolbar == null)
1358                                         return Rectangle.Empty;
1359
1360                                 if (button.Style == ToolBarButtonStyle.DropDownButton && toolbar.DropDownArrows) {
1361                                         Rectangle result = bounds;
1362                                         result.Width += ThemeEngine.Current.ToolBarDropDownWidth;
1363                                         return result;
1364                                 }
1365                                  
1366                                 return bounds;
1367                         }
1368                         set { this.bounds = value; }
1369                 }
1370
1371                 public Point Location {
1372                         get { return bounds.Location; }
1373                         set { bounds.Location = value; }
1374                 }
1375
1376                 public Rectangle ImageRectangle {
1377                         get {
1378                                 Rectangle result = image_rect;
1379                                 result.X += bounds.X;
1380                                 result.Y += bounds.Y;
1381                                 return result; 
1382                         }
1383                 }
1384                 
1385                 public Rectangle TextRectangle {
1386                         get { 
1387                                 Rectangle result = text_rect;
1388                                 result.X += bounds.X;
1389                                 result.Y += bounds.Y;
1390                                 return result; 
1391                         }
1392                 }
1393
1394                 private Size TextSize {
1395                         get {
1396                                 StringFormat text_format = new StringFormat ();
1397                                 text_format.HotkeyPrefix = HotkeyPrefix.Hide;
1398
1399                                 SizeF sz = TextRenderer.MeasureString (button.Text, toolbar.Font, SizeF.Empty, text_format);
1400                                 if (sz == SizeF.Empty)
1401                                         return Size.Empty;
1402                                 return new Size ((int) Math.Ceiling (sz.Width) + 2 * ToolBar.text_padding, (int) Math.Ceiling (sz.Height));
1403                         }
1404                 }
1405                 
1406                 public bool Pressed {
1407                         get { return (pressed && inside); }
1408                         set { pressed = value; }
1409                 }
1410
1411                 public bool DDPressed {
1412                         get { return dd_pressed; }
1413                         set { dd_pressed = value; }
1414                 }
1415
1416                 public bool Inside {
1417                         get { return inside; }
1418                         set { inside = value; }
1419                 }
1420
1421                 public bool Hilight {
1422                         get { return hilight; }
1423                         set {
1424                                 if (hilight == value)
1425                                         return;
1426
1427                                 hilight = value;
1428                                 Invalidate ();
1429                         }
1430                 }       
1431                 
1432                 #endregion Properties
1433
1434                 #region Methods
1435                 
1436                 public Size CalculateSize ()
1437                 {
1438                         Theme theme = ThemeEngine.Current;
1439
1440                         int ht = toolbar.ButtonSize.Height + 2 * theme.ToolBarGripWidth;
1441
1442                         if (button.Style == ToolBarButtonStyle.Separator)
1443                                 return new Size (theme.ToolBarSeparatorWidth, ht);
1444
1445                         Size size;
1446                         if (TextSize.IsEmpty && (button.Image == null))
1447                                 size = toolbar.default_size;
1448                         else
1449                                 size = TextSize;
1450                         
1451                         Size image_size = (toolbar.ImageSize == Size.Empty) ? new Size (16, 16) : toolbar.ImageSize;
1452
1453                         int image_width = image_size.Width + 2 * theme.ToolBarImageGripWidth; 
1454                         int image_height = image_size.Height + 2 * theme.ToolBarImageGripWidth; 
1455
1456                         if (toolbar.TextAlign == ToolBarTextAlign.Right) {
1457                                 size.Width =  image_width + size.Width;
1458                                 size.Height = (size.Height > image_height) ? size.Height : image_height;
1459                         } else {
1460                                 size.Height = image_height + size.Height;
1461                                 size.Width = (size.Width > image_width) ? size.Width : image_width;
1462                         }
1463
1464                         size.Width += theme.ToolBarGripWidth;
1465                         size.Height += theme.ToolBarGripWidth;
1466                         return size;
1467                 }
1468
1469                 
1470                 public bool Layout (bool vertical, int calculated_size)
1471                 {
1472                         if (toolbar == null || !button.Visible)
1473                                 return false;
1474
1475                         Size psize = toolbar.ButtonSize;
1476                         Size size = psize;
1477                         if ((!toolbar.SizeSpecified) || (button.Style == ToolBarButtonStyle.Separator)) {
1478                                 size = CalculateSize ();
1479
1480                                 if (size.Width == 0 || size.Height == 0)
1481                                         size = psize;
1482
1483                                 if (vertical)
1484                                         size.Width = calculated_size;
1485                                 else
1486                                         size.Height = calculated_size;
1487                         }
1488                         return Layout (size);
1489                 }
1490
1491                 public bool Layout (Size size)
1492                 {
1493                         if (toolbar == null || !button.Visible)
1494                                 return false;
1495
1496                         bounds.Size = size;
1497
1498                         Size image_size = (toolbar.ImageSize == Size.Empty) ? new Size (16, 16) : toolbar.ImageSize;
1499                         int grip = ThemeEngine.Current.ToolBarImageGripWidth;
1500
1501                         Rectangle new_image_rect, new_text_rect;
1502                         
1503                         if (toolbar.TextAlign == ToolBarTextAlign.Underneath) {
1504                                 new_image_rect = new Rectangle ((bounds.Size.Width - image_size.Width) / 2 - grip, 0, image_size.Width + 2 + grip, image_size.Height + 2 * grip);
1505                                 new_text_rect = new Rectangle (0, new_image_rect.Height, bounds.Size.Width, bounds.Size.Height - new_image_rect.Height - 2 * grip);
1506                         } else {
1507                                 new_image_rect = new Rectangle (0, 0, image_size.Width + 2 * grip, image_size.Height + 2 * grip);
1508                                 new_text_rect = new Rectangle (new_image_rect.Width, 0, bounds.Size.Width - new_image_rect.Width, bounds.Size.Height - 2 * grip);
1509                         }
1510
1511                         bool changed = false;
1512
1513                         if (new_image_rect != image_rect || new_text_rect != text_rect)
1514                                 changed = true;
1515
1516                         image_rect = new_image_rect;
1517                         text_rect = new_text_rect;
1518                         
1519                         return changed;
1520                 }
1521                 
1522                 public void Invalidate ()
1523                 {
1524                         if (toolbar != null)
1525                                 toolbar.Invalidate (Rectangle);
1526                 }
1527
1528                 #endregion Methods
1529         }
1530 }