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