2006-07-17 Mike Kestner <mkestner@novell.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolBar.cs
1 // System.Windows.Forms.ToolBar.cs
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 // Author:
23 //      Ravindra (rkumar@novell.com)
24 //      Mike Kestner <mkestner@novell.com>
25 //
26 // TODO:
27 //   - Tooltip
28 //
29 // Copyright (C) 2004-2006  Novell, Inc. (http://www.novell.com)
30 //
31
32
33 // NOT COMPLETE
34
35 using System.Collections;
36 using System.ComponentModel;
37 using System.ComponentModel.Design;
38 using System.Drawing;
39 using System.Drawing.Imaging;
40 using System.Runtime.InteropServices;
41
42 namespace System.Windows.Forms
43 {       
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                 bool size_specified = false;
51                 ToolBarButton current_button;
52                 #endregion Instance Variables
53
54                 #region Events
55                 [Browsable (false)]
56                 [EditorBrowsable (EditorBrowsableState.Never)]
57                 public new event EventHandler BackColorChanged {
58                         add { base.BackColorChanged += value; }
59                         remove { base.BackColorChanged -= value; }
60                 }
61
62                 [Browsable (false)]
63                 [EditorBrowsable (EditorBrowsableState.Never)]
64                 public new event EventHandler BackgroundImageChanged {
65                         add { base.BackgroundImageChanged += value; }
66                         remove { base.BackgroundImageChanged -= value; }
67                 }
68
69                 public event ToolBarButtonClickEventHandler ButtonClick;
70                 public event ToolBarButtonClickEventHandler ButtonDropDown;
71
72                 [Browsable (false)]
73                 [EditorBrowsable (EditorBrowsableState.Never)]
74                 public new event EventHandler ForeColorChanged {
75                         add { base.ForeColorChanged += value; }
76                         remove { base.ForeColorChanged -= value; }
77                 }
78
79                 [Browsable (false)]
80                 [EditorBrowsable (EditorBrowsableState.Never)]
81                 public new event EventHandler ImeModeChanged {
82                         add { base.ImeModeChanged += value; }
83                         remove { base.ImeModeChanged -= value; }
84                 }
85
86                 [Browsable (false)]
87                 [EditorBrowsable (EditorBrowsableState.Never)]
88                 public new event PaintEventHandler Paint {
89                         add { base.Paint += value; }
90                         remove { base.Paint -= value; }
91                 }
92
93                 [Browsable (false)]
94                 [EditorBrowsable (EditorBrowsableState.Never)]
95                 public new event EventHandler RightToLeftChanged {
96                         add { base.RightToLeftChanged += value; }
97                         remove { base.RightToLeftChanged -= value; }
98                 }
99
100                 [Browsable (false)]
101                 [EditorBrowsable (EditorBrowsableState.Never)]
102                 public new event EventHandler TextChanged {
103                         add { base.TextChanged += value; }
104                         remove { base.TextChanged -= value; }
105                 }
106                 #endregion Events
107
108                 #region Constructor
109                 public ToolBar ()
110                 {
111                         background_color = ThemeEngine.Current.DefaultControlBackColor;
112                         foreground_color = ThemeEngine.Current.DefaultControlForeColor;
113                         buttons = new ToolBarButtonCollection (this);
114                         dock_style = DockStyle.Top;
115                         
116                         MouseDown += new MouseEventHandler (ToolBar_MouseDown);
117                         MouseLeave += new EventHandler (ToolBar_MouseLeave);
118                         MouseMove += new MouseEventHandler (ToolBar_MouseMove);
119                         MouseUp += new MouseEventHandler (ToolBar_MouseUp);
120
121                         SetStyle (ControlStyles.UserPaint, false);
122                         SetStyle (ControlStyles.FixedHeight, true);
123                 }
124                 #endregion Constructor
125
126                 #region protected Properties
127                 protected override CreateParams CreateParams 
128                 {
129                         get { return base.CreateParams; }
130                 }
131
132                 protected override ImeMode DefaultImeMode {
133                         get { return ImeMode.Disable; }
134                 }
135
136                 protected override Size DefaultSize {
137                         get { return ThemeEngine.Current.ToolBarDefaultSize; }
138                 }
139                 #endregion
140
141                 ToolBarAppearance appearance = ToolBarAppearance.Normal;
142
143                 #region Public Properties
144                 [DefaultValue (ToolBarAppearance.Normal)]
145                 [Localizable (true)]
146                 public ToolBarAppearance Appearance {
147                         get { return appearance; }
148                         set {
149                                 if (value == appearance)
150                                         return;
151
152                                 appearance = value;
153                                 Redraw (true);
154                         }
155                 }
156
157                 bool autosize = true;
158
159                 [DefaultValue (true)]
160                 [Localizable (true)]
161                 public bool AutoSize {
162                         get { return autosize; }
163                         set {
164                                 if (value == autosize)
165                                         return;
166
167                                 autosize = value;
168                                 Redraw (true);
169                         }
170                 }
171
172                 [Browsable (false)]
173                 [EditorBrowsable (EditorBrowsableState.Never)]
174                 public override Color BackColor {
175                         get { return background_color; }
176                         set {
177                                 if (value == background_color)
178                                         return;
179
180                                 background_color = value;
181                                 OnBackColorChanged (EventArgs.Empty);
182                                 Redraw (false);
183                         }
184                 }
185
186                 [Browsable (false)]
187                 [EditorBrowsable (EditorBrowsableState.Never)]
188                 public override Image BackgroundImage {
189                         get { return background_image; }
190                         set {
191                                 if (value == background_image)
192                                         return;
193
194                                 background_image = value;
195                                 OnBackgroundImageChanged (EventArgs.Empty);
196                                 Redraw (false);
197                         }
198                 }
199
200                 [DefaultValue (BorderStyle.None)]
201                 [DispIdAttribute (-504)]
202                 public BorderStyle BorderStyle {
203                         get { return InternalBorderStyle; }
204                         set { InternalBorderStyle = value; }
205                 }
206
207                 ToolBarButtonCollection buttons;
208
209                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
210                 [Localizable (true)]
211                 [MergableProperty (false)]
212                 public ToolBarButtonCollection Buttons {
213                         get { return buttons; }
214                 }
215
216                 Size button_size;
217
218                 [Localizable (true)]
219                 [RefreshProperties (RefreshProperties.All)]
220                 public Size ButtonSize {
221                         get {
222                                 if (button_size.IsEmpty) {
223                                         if (buttons.Count == 0)
224                                                 return new Size (24, 22);
225                                         Size result = CalcButtonSize ();
226                                         if (result.IsEmpty)
227                                                 return new Size (24, 22);
228                                         else
229                                                 return result;
230                                 }
231                                 return button_size;
232                         }
233                         set {
234                                 size_specified = value != Size.Empty;
235                                 if (button_size == value)
236                                         return;
237
238                                 button_size = value;
239                                 Redraw (true);
240                         }
241                 }
242
243                 bool divider = true;
244
245                 [DefaultValue (true)]
246                 public bool Divider {
247                         get { return divider; }
248                         set {
249                                 if (value == divider)
250                                         return;
251
252                                 divider = value;
253                                 Redraw (false);
254                         }
255                 }
256
257                 [DefaultValue (DockStyle.Top)]
258                 [Localizable (true)]
259                 public override DockStyle Dock {
260                         get { return base.Dock; }
261                         set { base.Dock = value; } 
262                 }
263
264                 bool drop_down_arrows = false;
265
266                 [DefaultValue (false)]
267                 [Localizable (true)]
268                 public bool DropDownArrows {
269                         get { return drop_down_arrows; }
270                         set {
271                                 if (value == drop_down_arrows)
272                                         return;
273
274                                 drop_down_arrows = value;
275                                 Redraw (true);
276                         }
277                 }
278
279                 [Browsable (false)]
280                 [EditorBrowsable (EditorBrowsableState.Never)]
281                 public override Color ForeColor {
282                         get { return foreground_color; }
283                         set {
284                                 if (value == foreground_color)
285                                         return;
286
287                                 foreground_color = value;
288                                 OnForeColorChanged (EventArgs.Empty);
289                                 Redraw (false);
290                         }
291                 }
292
293                 ImageList image_list;
294
295                 [DefaultValue (null)]
296                 public ImageList ImageList {
297                         get { return image_list; }
298                         set { 
299                                 if (image_list == value)
300                                         return;
301                                 image_list = value;
302                                 Redraw (true);
303                         }
304                 }
305
306                 [Browsable (false)]
307                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
308                 [EditorBrowsable (EditorBrowsableState.Advanced)]
309                 public Size ImageSize {
310                         get {
311                                 if (ImageList == null)
312                                         return Size.Empty;
313
314                                 return ImageList.ImageSize;
315                         }
316                 }
317
318                 ImeMode ime_mode;
319
320                 [Browsable (false)]
321                 [EditorBrowsable (EditorBrowsableState.Never)]
322                 public new ImeMode ImeMode {
323                         get { return ime_mode; }
324                         set {
325                                 if (value == ime_mode)
326                                         return;
327
328                                 ime_mode = value;
329                                 OnImeModeChanged (EventArgs.Empty);
330                         }
331                 }
332
333                 [Browsable (false)]
334                 [EditorBrowsable (EditorBrowsableState.Never)]
335                 public override RightToLeft RightToLeft {
336                         get { return base.RightToLeft; }
337                         set {
338                                 if (value == base.RightToLeft)
339                                         return;
340
341                                 base.RightToLeft = value;
342                                 OnRightToLeftChanged (EventArgs.Empty);
343                         }
344                 }
345
346                 bool show_tooltips = false;
347
348                 [DefaultValue (false)]
349                 [Localizable (true)]
350                 public bool ShowToolTips {
351                         get { return show_tooltips; }
352                         set { show_tooltips = value; }
353                 }
354
355                 [DefaultValue (false)]
356                 public new bool TabStop {
357                         get { return base.TabStop; }
358                         set { base.TabStop = value; }
359                 }
360
361                 [Bindable (false)]
362                 [Browsable (false)]
363                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
364                 [EditorBrowsable (EditorBrowsableState.Never)]
365                 public override string Text {
366                         get { return text; } 
367                         set {
368                                 if (value == text)
369                                         return;
370
371                                 text = value;
372                                 Redraw (true);
373                                 OnTextChanged (EventArgs.Empty);
374                         }
375                 }
376
377                 ToolBarTextAlign text_alignment = ToolBarTextAlign.Underneath;
378
379                 [DefaultValue (ToolBarTextAlign.Underneath)]
380                 [Localizable (true)]
381                 public ToolBarTextAlign TextAlign {
382                         get { return text_alignment; }
383                         set {
384                                 if (value == text_alignment)
385                                         return;
386
387                                 text_alignment = value;
388                                 Redraw (true);
389                         }
390                 }
391
392                 bool wrappable = true;
393
394                 [DefaultValue (true)]
395                 [Localizable (true)]
396                 public bool Wrappable {
397                         get { return wrappable; }
398                         set {
399                                 if (value == wrappable)
400                                         return;
401
402                                 wrappable = value;
403                                 Redraw (true);
404                         }
405                 }
406                 #endregion Public Properties
407
408                 #region Public Methods
409                 public override string ToString ()
410                 {
411                         int count = this.Buttons.Count;
412
413                         if (count == 0)
414                                 return string.Format ("System.Windows.Forms.ToolBar, Button.Count: 0");
415                         else
416                                 return string.Format ("System.Windows.Forms.ToolBar, Button.Count: {0}, Buttons[0]: {1}",
417                                                       count, this.Buttons [0].ToString ());
418                 }
419                 #endregion Public Methods
420
421                 #region Protected Methods
422                 protected override void CreateHandle ()
423                 {
424                         base.CreateHandle ();
425                 }
426
427                 protected override void Dispose (bool disposing)
428                 {
429                         if (disposing)
430                                 ImageList = null;
431
432                         base.Dispose (disposing);
433                 }
434
435                 protected virtual void OnButtonClick (ToolBarButtonClickEventArgs e)
436                 {
437                         if (e.Button.Style == ToolBarButtonStyle.ToggleButton) {
438                                 if (! e.Button.Pushed)
439                                         e.Button.Pushed = true;
440                                 else
441                                         e.Button.Pushed = false;
442                         }
443                         e.Button.pressed = false;
444
445                         Invalidate (e.Button.Rectangle);
446                         Redraw (false);
447
448                         if (ButtonClick != null)
449                                 ButtonClick (this, e);
450                 }
451
452                 protected virtual void OnButtonDropDown (ToolBarButtonClickEventArgs e) 
453                 {
454                         if (ButtonDropDown != null)
455                                 ButtonDropDown (this, e);
456
457                         if (e.Button.DropDownMenu == null)
458                                 return;
459
460                         Point loc = new Point (e.Button.Rectangle.X + 1, e.Button.Rectangle.Bottom + 1);
461                         ((ContextMenu) e.Button.DropDownMenu).Show (this, loc);
462
463                         e.Button.dd_pressed = false;
464                         Invalidate (e.Button.Rectangle);
465                 }
466
467                 protected override void OnFontChanged (EventArgs e)
468                 {
469                         base.OnFontChanged (e);
470                         Redraw (true);
471                 }
472
473                 protected override void OnHandleCreated (EventArgs e)
474                 {
475                         base.OnHandleCreated (e);
476                 }
477
478                 protected override void OnResize (EventArgs e)
479                 {
480                         base.OnResize (e);
481
482                         if (Width <= 0 || Height <= 0 || !Visible)
483                                 return;
484
485                         Redraw (true);
486                 }
487
488                 bool height_specified = false;
489                 int requested_height = -1;
490
491                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
492                 {
493                         if ((specified & BoundsSpecified.Height) != 0) {
494                                 requested_height = height;
495                                 height_specified = true;
496                         }
497                         base.SetBoundsCore (x, y, width, height, specified);
498                 }
499
500                 protected override void WndProc (ref Message m)
501                 {
502                         base.WndProc (ref m);
503                 }
504
505                 #endregion Protected Methods
506
507                 #region Private Methods
508                 private void ToolBar_MouseDown (object sender, MouseEventArgs me)
509                 {
510                         if (!Enabled) 
511                                 return;
512
513                         Point loc = new Point (me.X, me.Y);
514
515                         // draw the pushed button
516                         foreach (ToolBarButton button in buttons) {
517                                 if (button.Enabled && button.Rectangle.Contains (loc)) {
518                                         // Mark the DropDown rect as pressed.
519                                         // We don't redraw the dropdown rect.
520                                         if (button.Style == ToolBarButtonStyle.DropDownButton) {
521                                                 Rectangle rect = button.Rectangle;
522                                                 rect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
523                                                 rect.X = button.Rectangle.Right - rect.Width;
524                                                 if (rect.Contains (loc)) {
525                                                         if (button.DropDownMenu != null) {
526                                                                 button.dd_pressed = true;
527                                                                 Invalidate (rect);
528                                                         }
529                                                         break;
530                                                 }
531                                         }
532                                         button.pressed = true;
533                                         button.inside = true;
534                                         Invalidate (button.Rectangle);
535                                         break;
536                                 }
537                         }
538                 }
539
540                 private void ToolBar_MouseUp (object sender, MouseEventArgs me)
541                 {
542                         if (!Enabled) 
543                                 return;
544
545                         Point loc = new Point (me.X, me.Y);
546
547                         // draw the normal button
548                         // Make a copy in case the list is modified during enumeration
549                         ArrayList buttons = new ArrayList (this.buttons);
550                         foreach (ToolBarButton button in buttons) {
551                                 if (button.Enabled && button.Rectangle.Contains (loc)) {
552                                         if (button.Style == ToolBarButtonStyle.DropDownButton) {
553                                                 Rectangle ddRect = button.Rectangle;
554                                                 ddRect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
555                                                 ddRect.X = button.Rectangle.Right - ddRect.Width;
556                                                 if (ddRect.Contains (loc)) {
557                                                         if (button.dd_pressed)
558                                                                 OnButtonDropDown (new ToolBarButtonClickEventArgs (button));
559                                                         continue;
560                                                 }
561                                         }
562                                         // Fire a ButtonClick
563                                         if (button.pressed)
564                                                 OnButtonClick (new ToolBarButtonClickEventArgs (button));
565                                 } else if (button.pressed) {
566                                         button.pressed = false;
567                                         Invalidate (button.Rectangle);
568                                 }
569                         }
570                 }
571
572                 private void ToolBar_MouseLeave (object sender, EventArgs e)
573                 {
574                         if (!Enabled || appearance != ToolBarAppearance.Flat || current_button == null) 
575                                 return;
576
577                         if (current_button.Hilight) {
578                                 current_button.Hilight = false;
579                                 Invalidate (current_button.Rectangle);
580                                 Redraw (false);
581                         }
582                         current_button = null;
583                 }
584
585                 private void ToolBar_MouseMove (object sender, MouseEventArgs me)
586                 {
587                         if (!Enabled) 
588                                 return;
589
590                         Point loc = new Point (me.X, me.Y);
591
592                         if (this.Capture) {
593                                 // If the button was pressed and we leave, release the 
594                                 // button press and vice versa
595                                 foreach (ToolBarButton button in buttons) {
596                                         if (button.pressed &&
597                                             (button.inside != button.Rectangle.Contains (loc))) {
598                                                 button.inside = button.Rectangle.Contains (loc);
599                                                 button.Hilight = false;
600                                                 Invalidate (button.Rectangle);
601                                                 Redraw (false);
602                                                 break;
603                                         }
604                                 }
605                         }
606                         // following is only for flat style toolbar
607                         else if (appearance == ToolBarAppearance.Flat) {
608                                 if (current_button != null && current_button.Rectangle.Contains (loc)) {
609                                         if (current_button.Hilight || current_button.Pushed)
610                                                 return;
611                                         current_button.Hilight = true;
612                                         Invalidate (current_button.Rectangle);
613                                         Redraw (false);
614                                 }
615                                 else {
616                                         foreach (ToolBarButton button in buttons) {
617                                                 if (button.Rectangle.Contains (loc) && button.Enabled) {
618                                                         current_button = button;
619                                                         if (current_button.Hilight || current_button.Pushed)
620                                                                 continue;
621                                                         current_button.Hilight = true;
622                                                         Invalidate (current_button.Rectangle);
623                                                         Redraw (false);
624                                                 }
625                                                 else if (button.Hilight) {
626                                                         button.Hilight = false;
627                                                         Invalidate (button.Rectangle);
628                                                         Redraw (false);
629                                                 }
630                                         }
631                                 }
632                         }
633                 }
634
635                 internal override void OnPaintInternal (PaintEventArgs pevent)
636                 {
637                         ThemeEngine.Current.DrawToolBar (pevent.Graphics, pevent.ClipRectangle, this);
638                 }
639
640                 internal void Redraw (bool recalculate)
641                 {
642                         if (recalculate)
643                                 Layout ();
644
645                         Refresh ();
646                 }
647
648                 internal bool SizeSpecified {
649                         get { return size_specified; }
650                 }
651
652                 const int text_padding = 3;
653
654                 private Size CalcButtonSize ()
655                 {
656                         if (Buttons.Count == 0)
657                                 return Size.Empty;
658
659                         string longest_text = Buttons [0].Text;
660                         for (int i = 1; i < Buttons.Count; i++) {
661                                 if (Buttons[i].Text.Length > longest_text.Length)
662                                         longest_text = Buttons[i].Text;
663                         }
664
665                         Size size = Size.Empty;
666                         if (longest_text != null && longest_text.Length > 0) {
667                                 SizeF sz = DeviceContext.MeasureString (longest_text, Font);
668                                 if (sz != SizeF.Empty)
669                                         size = new Size ((int) Math.Ceiling (sz.Width) + 2 * text_padding, (int) Math.Ceiling (sz.Height));
670                         }
671
672                         Size img_size = ImageList == null ? new Size (16, 16) : ImageSize;
673
674                         Theme theme = ThemeEngine.Current;
675                         int imgWidth = img_size.Width + 2 * theme.ToolBarImageGripWidth; 
676                         int imgHeight = img_size.Height + 2 * theme.ToolBarImageGripWidth;
677
678                         if (text_alignment == ToolBarTextAlign.Right) {
679                                 size.Width = imgWidth + size.Width;
680                                 size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
681                         } else {
682                                 size.Height = imgHeight + size.Height;
683                                 size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
684                         }
685
686                         size.Width += theme.ToolBarImageGripWidth;
687                         size.Height += theme.ToolBarImageGripWidth;
688                         return size;
689                 }
690
691                 // Flat toolbars disregard specified sizes.  Normal toolbars grow the
692                 // button size to be at least large enough to show the image.
693                 Size AdjustedButtonSize {
694                         get {
695                                 Size size = ButtonSize;
696                                 if (size_specified) {
697                                         if (Appearance == ToolBarAppearance.Flat)
698                                                 size = CalcButtonSize ();
699                                         else {
700                                                 int grip = ThemeEngine.Current.ToolBarImageGripWidth;
701                                                 if (size.Width < ImageSize.Width + 2 * grip )
702                                                         size.Width = ImageSize.Width + 2 * grip;
703                                                 if (size.Height < ImageSize.Height + 2 * grip)
704                                                         size.Height = ImageSize.Height + 2 * grip;
705                                         }
706                                 }
707                                 return size;
708                         }
709                 }
710
711                 void Layout ()
712                 {
713                         Theme theme = ThemeEngine.Current;
714                         int x = theme.ToolBarGripWidth;
715                         int y = theme.ToolBarGripWidth;
716
717                         Size button_size = AdjustedButtonSize;
718
719                         int ht = button_size.Height + theme.ToolBarGripWidth;
720
721                         if (Wrappable && Parent != null) {
722                                 int separator_index = -1;
723
724                                 for (int i = 0; i < buttons.Count; i++) {
725                                         ToolBarButton button = buttons [i];
726
727                                         if (!button.Visible)
728                                                 continue;
729
730                                         if (size_specified)
731                                                 button.Layout (button_size);
732                                         else
733                                                 button.Layout ();
734
735                                         bool is_separator = button.Style == ToolBarButtonStyle.Separator;
736
737                                         if (x + button.Rectangle.Width < Width || is_separator) {
738                                                 button.Location = new Point (x, y);
739                                                 x += button.Rectangle.Width;
740                                                 if (is_separator)
741                                                         separator_index = i;
742                                         } else if (separator_index > 0) { 
743                                                 i = separator_index;
744                                                 separator_index = -1;
745                                                 x = theme.ToolBarGripWidth;
746                                                 y += ht; 
747                                         } else {
748                                                 x = theme.ToolBarGripWidth;
749                                                 y += ht; 
750                                                 button.Location = new Point (x, y);
751                                                 x += button.Rectangle.Width;
752                                         }
753                                 }
754                                 if (AutoSize)
755                                         Height = y + ht;
756                         } else {
757                                 if (AutoSize)
758                                         Height = ht;
759                                 else if (!height_specified)
760                                         Height = DefaultSize.Height;
761                                 foreach (ToolBarButton button in buttons) {
762                                         if (size_specified)
763                                                 button.Layout (button_size);
764                                         else
765                                                 button.Layout ();
766                                         button.Location = new Point (x, y);
767                                         x += button.Rectangle.Width;
768                                 }
769                         }
770                 }
771                 #endregion Private Methods
772
773                 #region subclass
774                 public class ToolBarButtonCollection : IList, ICollection, IEnumerable
775                 {
776                         #region instance variables
777                         private ArrayList list;
778                         private ToolBar owner;
779                         #endregion
780
781                         #region constructors
782                         public ToolBarButtonCollection (ToolBar owner)
783                         {
784                                 this.owner = owner;
785                                 list = new ArrayList ();
786                         }
787                         #endregion
788
789                         #region properties
790                         [Browsable (false)]
791                         public int Count {
792                                 get { return list.Count; }
793                         }
794
795                         public bool IsReadOnly {
796                                 get { return list.IsReadOnly; }
797                         }
798
799                         public virtual ToolBarButton this [int index] {
800                                 get { return (ToolBarButton) list [index]; }
801                                 set {
802                                         value.SetParent (owner);
803                                         list [index] = value;
804                                         owner.Redraw (true);
805                                 }
806                         }
807
808                         bool ICollection.IsSynchronized {
809                                 get { return list.IsSynchronized; }
810                         }
811
812                         object ICollection.SyncRoot {
813                                 get { return list.SyncRoot; }
814                         }
815
816                         bool IList.IsFixedSize {
817                                 get { return list.IsFixedSize; }
818                         }
819
820                         object IList.this [int index] {
821                                 get { return this [index]; }
822                                 set {
823                                         if (! (value is ToolBarButton))
824                                                 throw new ArgumentException("Not of type ToolBarButton", "value");
825                                         this [index] = (ToolBarButton) value;
826                                 }
827                         }
828                         #endregion
829
830                         #region methods
831                         public int Add (string text)
832                         {
833                                 ToolBarButton button = new ToolBarButton (text);
834                                 return this.Add (button);
835                         }
836
837                         public int Add (ToolBarButton button)
838                         {
839                                 int result;
840                                 button.SetParent (owner);
841                                 result = list.Add (button);
842                                 owner.Redraw (true);
843                                 return result;
844                         }
845
846                         public void AddRange (ToolBarButton [] buttons)
847                         {
848                                 foreach (ToolBarButton button in buttons)
849                                         Add (button);
850                         }
851
852                         public void Clear ()
853                         {
854                                 list.Clear ();
855                                 owner.Redraw (false);
856                         }
857
858                         public bool Contains (ToolBarButton button)
859                         {
860                                 return list.Contains (button);
861                         }
862
863                         public IEnumerator GetEnumerator ()
864                         {
865                                 return list.GetEnumerator ();
866                         }
867
868                         void ICollection.CopyTo (Array dest, int index)
869                         {
870                                 list.CopyTo (dest, index);
871                         }
872
873                         int IList.Add (object button)
874                         {
875                                 if (! (button is ToolBarButton)) {
876                                         throw new ArgumentException("Not of type ToolBarButton", "button");
877                                 }
878
879                                 return this.Add ((ToolBarButton) button);
880                         }
881
882                         bool IList.Contains (object button)
883                         {
884                                 if (! (button is ToolBarButton)) {
885                                         throw new ArgumentException("Not of type ToolBarButton", "button");
886                                 }
887
888                                 return this.Contains ((ToolBarButton) button);
889                         }
890
891                         int IList.IndexOf (object button)
892                         {
893                                 if (! (button is ToolBarButton)) {
894                                         throw new ArgumentException("Not of type ToolBarButton", "button");
895                                 }
896
897                                 return this.IndexOf ((ToolBarButton) button);
898                         }
899
900                         void IList.Insert (int index, object button)
901                         {
902                                 if (! (button is ToolBarButton)) {
903                                         throw new ArgumentException("Not of type ToolBarButton", "button");
904                                 }
905
906                                 this.Insert (index, (ToolBarButton) button);
907                         }
908
909                         void IList.Remove (object button)
910                         {
911                                 if (! (button is ToolBarButton)) {
912                                         throw new ArgumentException("Not of type ToolBarButton", "button");
913                                 }
914
915                                 this.Remove ((ToolBarButton) button);
916                         }
917
918                         public int IndexOf (ToolBarButton button)
919                         {
920                                 return list.IndexOf (button);
921                         }
922
923                         public void Insert (int index, ToolBarButton button)
924                         {
925                                 list.Insert (index, button);
926                                 owner.Redraw (true);
927                         }
928
929                         public void Remove (ToolBarButton button)
930                         {
931                                 list.Remove (button);
932                                 owner.Redraw (true);
933                         }
934
935                         public void RemoveAt (int index)
936                         {
937                                 list.RemoveAt (index);
938                                 owner.Redraw (true);
939                         }
940                         #endregion methods
941                 }
942                 #endregion subclass
943         }
944 }