**** Merged from MCS ****
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolBar.cs
blob31be48bdabb96d2a32100ae8f48e731bb54efa6a
1 //
2 // System.Windows.Forms.ToolBar.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Author:
24 // Ravindra (rkumar@novell.com)
26 // TODO:
27 // - Drawing ellipsis when text is too big to draw on a button
28 // - RightToLeft
29 // - DropDown ContextMenu
30 // - Tooltip
32 // Copyright (C) Novell, Inc. 2004 (http://www.novell.com)
35 // $Revision: 1.17 $
36 // $Modtime: $
37 // $Log: ToolBar.cs,v $
38 // Revision 1.17 2004/10/26 09:33:42 ravindra
39 // ToolBar should use the user specified button size, if there is any. Added a size_specified flag for the same.
41 // Revision 1.16 2004/10/14 11:14:05 ravindra
42 // - Changed Redraw () to do a Refresh () always.
43 // - Fixed the MouseMove event handling when mouse is pressed,
44 // ie drag event handling.
45 // - Replaced the usage of ToolBarButton.Pressed property to
46 // ToolBarButton.pressed internal variable.
48 // Revision 1.15 2004/10/06 09:59:05 jordi
49 // removes warnings from compilation
51 // Revision 1.14 2004/10/05 09:07:07 ravindra
52 // - Removed a private method, Draw ().
53 // - Fixed the ButtonDropDown event handling.
54 // - Fixed MouseMove event handling.
56 // Revision 1.13 2004/10/05 04:56:12 jackson
57 // Let the base Control handle the buffers, derived classes should not have to CreateBuffers themselves.
59 // Revision 1.12 2004/09/28 18:44:25 pbartok
60 // - Streamlined Theme interfaces:
61 // * Each DrawXXX method for a control now is passed the object for the
62 // control to be drawn in order to allow accessing any state the theme
63 // might require
65 // * ControlPaint methods for the theme now have a CP prefix to avoid
66 // name clashes with the Draw methods for controls
68 // * Every control now retrieves it's DefaultSize from the current theme
70 // Revision 1.11 2004/09/16 13:00:19 ravindra
71 // Invalidate should be done before redrawing.
73 // Revision 1.10 2004/09/09 11:25:03 ravindra
74 // Make redraw accessible from ToolBarButton.
76 // Revision 1.9 2004/08/25 20:04:40 ravindra
77 // Added the missing divider code and grip for ToolBar Control.
79 // Revision 1.8 2004/08/25 00:43:13 ravindra
80 // Fixed wrapping related issues in ToolBar control.
82 // Revision 1.7 2004/08/22 01:20:14 ravindra
83 // Correcting the formatting mess of VS.NET.
85 // Revision 1.6 2004/08/22 00:49:37 ravindra
86 // Probably this completes the missing attributes in toolbar control.
88 // Revision 1.5 2004/08/22 00:03:20 ravindra
89 // Fixed toolbar control signatures.
91 // Revision 1.4 2004/08/21 01:52:08 ravindra
92 // Improvments in mouse event handling in the ToolBar control.
94 // Revision 1.3 2004/08/17 02:00:54 ravindra
95 // Added attributes.
97 // Revision 1.2 2004/08/17 00:48:50 ravindra
98 // Added attributes.
100 // Revision 1.1 2004/08/15 23:13:15 ravindra
101 // First Implementation of ToolBar control.
105 // NOT COMPLETE
107 using System.Collections;
108 using System.ComponentModel;
109 using System.ComponentModel.Design;
110 using System.Drawing;
111 using System.Drawing.Imaging;
112 using System.Runtime.InteropServices;
114 namespace System.Windows.Forms
116 [DefaultEvent ("ButtonClick")]
117 [DefaultProperty ("Buttons")]
118 [Designer ("System.Windows.Forms.Design.ToolBarDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
119 public class ToolBar : Control
121 #region Instance Variables
122 internal ToolBarAppearance appearance;
123 internal bool autosize;
124 internal BorderStyle borderStyle;
125 internal ToolBarButtonCollection buttons;
126 internal Size buttonSize;
127 internal bool divider;
128 internal bool dropDownArrows;
129 internal ImageList imageList;
130 internal ImeMode imeMode;
131 internal bool showToolTips;
132 internal ToolBarTextAlign textAlignment;
133 internal bool wrappable; // flag to make the toolbar wrappable
134 internal bool redraw; // flag to force redrawing the control
135 private bool size_specified; // flag to know if button size is fixed.
136 internal ToolBarButton currentButton; // the highlighted button
137 #endregion Instance Variables
139 #region Events
140 [Browsable (false)]
141 [EditorBrowsable (EditorBrowsableState.Never)]
142 public new event EventHandler BackColorChanged;
144 [Browsable (false)]
145 [EditorBrowsable (EditorBrowsableState.Never)]
146 public new event EventHandler BackgroundImageChanged;
148 public event ToolBarButtonClickEventHandler ButtonClick;
149 public event ToolBarButtonClickEventHandler ButtonDropDown;
151 [Browsable (false)]
152 [EditorBrowsable (EditorBrowsableState.Never)]
153 public new event EventHandler ForeColorChanged;
155 [Browsable (false)]
156 [EditorBrowsable (EditorBrowsableState.Never)]
157 public new event EventHandler ImeModeChanged;
159 [Browsable (false)]
160 [EditorBrowsable (EditorBrowsableState.Never)]
161 public new event PaintEventHandler Paint;
163 [Browsable (false)]
164 [EditorBrowsable (EditorBrowsableState.Never)]
165 public new event EventHandler RightToLeftChanged;
167 [Browsable (false)]
168 [EditorBrowsable (EditorBrowsableState.Never)]
169 public new event EventHandler TextChanged;
170 #endregion Events
172 #region Constructor
173 public ToolBar ()
175 appearance = ToolBarAppearance.Normal;
176 autosize = true;
177 background_color = ThemeEngine.Current.DefaultControlBackColor;
178 borderStyle = BorderStyle.None;
179 buttons = new ToolBarButtonCollection (this);
180 buttonSize = Size.Empty;
181 divider = true;
182 dropDownArrows = false;
183 foreground_color = ThemeEngine.Current.DefaultControlForeColor;
184 showToolTips = false;
185 textAlignment = ToolBarTextAlign.Underneath;
186 wrappable = true;
187 dock_style = DockStyle.Top;
188 redraw = true;
189 size_specified = false;
191 // event handlers
192 this.MouseDown += new MouseEventHandler (ToolBar_MouseDown);
193 this.MouseLeave += new EventHandler (ToolBar_MouseLeave);
194 this.MouseMove += new MouseEventHandler (ToolBar_MouseMove);
195 this.MouseUp += new MouseEventHandler (ToolBar_MouseUp);
196 base.Paint += new PaintEventHandler (ToolBar_Paint);
198 #endregion Constructor
200 #region protected Properties
201 protected override CreateParams CreateParams
203 get { return base.CreateParams; }
206 protected override ImeMode DefaultImeMode {
207 get { return ImeMode.Disable; }
210 protected override Size DefaultSize {
211 get { return ThemeEngine.Current.ToolBarDefaultSize; }
213 #endregion
215 #region Public Properties
216 [DefaultValue (ToolBarAppearance.Normal)]
217 [Localizable (true)]
218 public ToolBarAppearance Appearance {
219 get { return appearance; }
220 set {
221 if (value == appearance)
222 return;
224 appearance = value;
225 Redraw (false);
229 [DefaultValue (true)]
230 [Localizable (true)]
231 public bool AutoSize {
232 get { return autosize; }
233 set {
234 if (value == autosize)
235 return;
237 autosize = value;
238 Redraw (true);
242 [Browsable (false)]
243 [EditorBrowsable (EditorBrowsableState.Never)]
244 public override Color BackColor {
245 get { return background_color; }
246 set {
247 if (value == background_color)
248 return;
250 background_color = value;
251 if (BackColorChanged != null)
252 BackColorChanged (this, new EventArgs ());
253 Redraw (false);
257 [Browsable (false)]
258 [EditorBrowsable (EditorBrowsableState.Never)]
259 public override Image BackgroundImage {
260 get { return background_image; }
261 set {
262 if (value == background_image)
263 return;
265 background_image = value;
266 if (BackgroundImageChanged != null)
267 BackgroundImageChanged (this, new EventArgs ());
268 Redraw (false);
272 [DefaultValue (BorderStyle.None)]
273 [DispIdAttribute (-504)]
274 public BorderStyle BorderStyle {
275 get { return borderStyle; }
276 set {
277 if (value == borderStyle)
278 return;
280 borderStyle = value;
281 Redraw (false);
285 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
286 [Localizable (true)]
287 [MergableProperty (false)]
288 public ToolBarButtonCollection Buttons {
289 get { return buttons; }
292 [Localizable (true)]
293 [RefreshProperties (RefreshProperties.All)]
294 public Size ButtonSize {
295 get {
296 if (buttonSize.IsEmpty) {
297 if (buttons.Count == 0)
298 return new Size (39, 36);
299 else
300 return CalcButtonSize ();
302 return buttonSize;
304 set {
305 if (buttonSize.Width == value.Width && buttonSize.Height == value.Height)
306 return;
308 buttonSize = value;
309 size_specified = true;
310 Redraw (true);
314 [DefaultValue (true)]
315 public bool Divider {
316 get { return divider; }
317 set {
318 if (value == divider)
319 return;
321 divider = value;
322 Redraw (false);
326 [DefaultValue (DockStyle.Top)]
327 [Localizable (true)]
328 public override DockStyle Dock {
329 get { return base.Dock; }
330 set { base.Dock = value; }
333 [DefaultValue (false)]
334 [Localizable (true)]
335 public bool DropDownArrows {
336 get { return dropDownArrows; }
337 set {
338 if (value == dropDownArrows)
339 return;
341 dropDownArrows = value;
342 Redraw (true);
346 [Browsable (false)]
347 [EditorBrowsable (EditorBrowsableState.Never)]
348 public override Color ForeColor {
349 get { return foreground_color; }
350 set {
351 if (value == foreground_color)
352 return;
354 foreground_color = value;
355 if (ForeColorChanged != null)
356 ForeColorChanged (this, new EventArgs ());
357 Redraw (false);
361 [DefaultValue (null)]
362 public ImageList ImageList {
363 get { return imageList; }
364 set { imageList = value; }
367 [Browsable (false)]
368 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
369 [EditorBrowsable (EditorBrowsableState.Advanced)]
370 public Size ImageSize {
371 get {
372 if (imageList == null)
373 return Size.Empty;
375 return imageList.ImageSize;
379 [Browsable (false)]
380 [EditorBrowsable (EditorBrowsableState.Never)]
381 public new ImeMode ImeMode {
382 get { return imeMode; }
383 set {
384 if (value == imeMode)
385 return;
387 imeMode = value;
388 if (ImeModeChanged != null)
389 ImeModeChanged (this, new EventArgs ());
393 [Browsable (false)]
394 [EditorBrowsable (EditorBrowsableState.Never)]
395 public override RightToLeft RightToLeft {
396 get { return base.RightToLeft; }
397 set {
398 if (value == base.RightToLeft)
399 return;
401 base.RightToLeft = value;
402 if (RightToLeftChanged != null)
403 RightToLeftChanged (this, new EventArgs ());
407 [DefaultValue (false)]
408 [Localizable (true)]
409 public bool ShowToolTips {
410 get { return showToolTips; }
411 set { showToolTips = value; }
414 [DefaultValue (false)]
415 public new bool TabStop {
416 get { return base.TabStop; }
417 set { base.TabStop = value; }
420 [Bindable (false)]
421 [Browsable (false)]
422 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
423 [EditorBrowsable (EditorBrowsableState.Never)]
424 public override string Text {
425 get { return text; }
426 set {
427 if (value == text)
428 return;
430 text = value;
431 Redraw (true);
432 if (TextChanged != null)
433 TextChanged (this, new EventArgs ());
437 [DefaultValue (ToolBarTextAlign.Underneath)]
438 [Localizable (true)]
439 public ToolBarTextAlign TextAlign {
440 get { return textAlignment; }
441 set {
442 if (value == textAlignment)
443 return;
445 textAlignment = value;
446 Redraw (true);
450 [DefaultValue (true)]
451 [Localizable (true)]
452 public bool Wrappable {
453 get { return wrappable; }
454 set {
455 if (value == wrappable)
456 return;
458 wrappable = value;
459 Redraw (true);
462 #endregion Public Properties
464 #region Public Methods
465 public override string ToString ()
467 int count = this.Buttons.Count;
469 if (count == 0)
470 return string.Format ("System.Windows.Forms.ToolBar, Button.Count: 0");
471 else
472 return string.Format ("System.Windows.Forms.ToolBar, Button.Count: {0}, Buttons[0]: {1}",
473 count, this.Buttons [0].ToString ());
475 #endregion Public Methods
477 #region Internal Methods
478 internal Rectangle GetChildBounds (ToolBarButton button)
480 if (button.Style == ToolBarButtonStyle.Separator)
481 return new Rectangle (button.Location.X, button.Location.Y,
482 ThemeEngine.Current.ToolBarSeparatorWidth, this.ButtonSize.Height);
484 if (size_specified)
485 return new Rectangle (button.Location, this.ButtonSize);
487 SizeF sz = this.DeviceContext.MeasureString (button.Text, this.Font);
488 Size size = new Size ((int) Math.Ceiling (sz.Width), (int) Math.Ceiling (sz.Height));
490 if (imageList != null) {
491 // adjustment for the image grip
492 int imgWidth = this.ImageSize.Width + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
493 int imgHeight = this.ImageSize.Height + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
495 if (textAlignment == ToolBarTextAlign.Right) {
496 size.Width = imgWidth + size.Width;
497 size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
499 else {
500 size.Height = imgHeight + size.Height;
501 size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
504 if (button.Style == ToolBarButtonStyle.DropDownButton && this.dropDownArrows)
505 size.Width += ThemeEngine.Current.ToolBarDropDownWidth;
507 return new Rectangle (button.Location, size);
509 #endregion Internal Methods
511 #region Protected Methods
512 protected override void CreateHandle ()
514 base.CreateHandle ();
517 protected override void Dispose (bool disposing)
519 if (disposing) {
520 if (imageList != null)
521 imageList.Dispose ();
524 base.Dispose (disposing);
527 protected virtual void OnButtonClick (ToolBarButtonClickEventArgs e)
529 if (e.Button.Style == ToolBarButtonStyle.ToggleButton) {
530 if (! e.Button.Pushed)
531 e.Button.Pushed = true;
532 else
533 e.Button.Pushed = false;
535 e.Button.pressed = false;
537 Invalidate (e.Button.Rectangle);
538 Redraw (false);
540 if (ButtonClick != null)
541 ButtonClick (this, e);
542 else
543 return;
546 protected virtual void OnButtonDropDown (ToolBarButtonClickEventArgs e)
548 // if (e.Button.DropDownMenu == null) return;
549 // TODO: Display the dropdown menu
551 // Reset the flag set on DropDown
552 e.Button.dd_pressed = false;
554 if (ButtonDropDown != null)
555 ButtonDropDown (this, e);
556 else
557 return;
560 protected override void OnFontChanged (EventArgs e)
562 base.OnFontChanged (e);
563 Redraw (true);
566 protected override void OnHandleCreated (EventArgs e)
568 base.OnHandleCreated (e);
571 protected override void OnResize (EventArgs e)
573 base.OnResize (e);
575 if (this.Width <= 0 || this.Height <= 0 || this.Visible == false)
576 return;
578 Redraw (true);
581 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
583 base.SetBoundsCore (x, y, width, height, specified);
586 protected override void WndProc (ref Message m)
588 base.WndProc (ref m);
591 #endregion Protected Methods
593 #region Private Methods
594 private void ToolBar_MouseDown (object sender, MouseEventArgs me)
596 if (! this.Enabled) return;
598 Point hit = new Point (me.X, me.Y);
599 this.Capture = true;
601 // draw the pushed button
602 foreach (ToolBarButton button in buttons) {
603 if (button.Enabled && button.Rectangle.Contains (hit)) {
604 // Mark the DropDown rect as pressed.
605 // We don't redraw the dropdown rect.
606 if (button.Style == ToolBarButtonStyle.DropDownButton) {
607 Rectangle ddRect = Rectangle.Empty;
608 Rectangle rect = button.Rectangle;
609 ddRect.Height = rect.Height;
610 ddRect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
611 ddRect.X = rect.X + rect.Width - ddRect.Width;
612 ddRect.Y = rect.Y;
613 if (ddRect.Contains (hit)) {
614 button.dd_pressed = true;
615 break;
618 // If it is not dropdown then we treat it as a normal
619 // button press.
620 button.pressed = true;
621 button.inside = true;
622 Invalidate (button.Rectangle);
623 Redraw (false);
624 break;
629 private void ToolBar_MouseUp (object sender, MouseEventArgs me)
631 if (! this.Enabled) return;
633 Point hit = new Point (me.X, me.Y);
634 this.Capture = false;
636 // draw the normal button
637 foreach (ToolBarButton button in buttons) {
638 if (button.Enabled && button.Rectangle.Contains (hit)) {
639 if (button.Style == ToolBarButtonStyle.DropDownButton) {
640 Rectangle ddRect = Rectangle.Empty;
641 Rectangle rect = button.Rectangle;
642 ddRect.Height = rect.Height;
643 ddRect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
644 ddRect.X = rect.X + rect.Width - ddRect.Width;
645 ddRect.Y = rect.Y;
646 // Fire a ButtonDropDown event
647 if (ddRect.Contains (hit)) {
648 if (button.dd_pressed)
649 this.OnButtonDropDown (new ToolBarButtonClickEventArgs (button));
650 continue;
653 // Fire a ButtonClick
654 if (button.pressed)
655 this.OnButtonClick (new ToolBarButtonClickEventArgs (button));
657 // Clear the button press flags, if any
658 else if (button.pressed) {
659 button.pressed = false;
660 Invalidate (button.Rectangle);
661 Redraw (false);
666 private void ToolBar_MouseLeave (object sender, EventArgs e)
668 if (! this.Enabled || appearance != ToolBarAppearance.Flat) return;
670 if (currentButton != null && currentButton.Hilight) {
671 currentButton.Hilight = false;
672 Invalidate (currentButton.Rectangle);
673 Redraw (false);
675 currentButton = null;
678 private void ToolBar_MouseMove (object sender, MouseEventArgs me)
680 if (! this.Enabled) return;
682 Point hit = new Point (me.X, me.Y);
684 if (this.Capture) {
685 // If the button was pressed and we leave, release the
686 // button press and vice versa
687 foreach (ToolBarButton button in buttons) {
688 if (button.pressed &&
689 (button.inside != button.Rectangle.Contains (hit))) {
690 button.inside = button.Rectangle.Contains (hit);
691 button.Hilight = false;
692 Invalidate (button.Rectangle);
693 Redraw (false);
694 break;
698 // following is only for flat style toolbar
699 else if (appearance == ToolBarAppearance.Flat) {
700 if (currentButton != null && currentButton.Rectangle.Contains (hit)) {
701 if (currentButton.Hilight || currentButton.Pushed)
702 return;
703 currentButton.Hilight = true;
704 Invalidate (currentButton.Rectangle);
705 Redraw (false);
707 else {
708 foreach (ToolBarButton button in buttons) {
709 if (button.Rectangle.Contains (hit) && button.Enabled) {
710 currentButton = button;
711 if (currentButton.Hilight || currentButton.Pushed)
712 continue;
713 currentButton.Hilight = true;
714 Invalidate (currentButton.Rectangle);
715 Redraw (false);
717 else if (button.Hilight) {
718 button.Hilight = false;
719 Invalidate (button.Rectangle);
720 Redraw (false);
727 private void ToolBar_Paint (object sender, PaintEventArgs pe)
729 if (this.Width <= 0 || this.Height <= 0 || this.Visible == false)
730 return;
732 if (redraw) {
733 ThemeEngine.Current.DrawToolBar (this.DeviceContext, pe.ClipRectangle, this);
734 redraw = false;
737 // paint on the screen
738 pe.Graphics.DrawImage (this.ImageBuffer, pe.ClipRectangle, pe.ClipRectangle, GraphicsUnit.Pixel);
740 if (Paint != null)
741 Paint (this, pe);
744 internal void Redraw (bool recalculate)
746 if (recalculate)
747 CalcToolBar ();
749 redraw = true;
750 Refresh ();
753 private Size CalcButtonSize ()
755 String longestText = buttons [0].Text;
756 for (int i = 1; i < buttons.Count; i++) {
757 if (buttons[i].Text.Length > longestText.Length)
758 longestText = buttons[i].Text;
761 SizeF sz = this.DeviceContext.MeasureString (longestText, this.Font);
762 Size size = new Size ((int) Math.Ceiling (sz.Width), (int) Math.Ceiling (sz.Height));
764 if (imageList != null) {
765 // adjustment for the image grip
766 int imgWidth = this.ImageSize.Width + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
767 int imgHeight = this.ImageSize.Height + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
769 if (textAlignment == ToolBarTextAlign.Right) {
770 size.Width = imgWidth + size.Width;
771 size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
773 else {
774 size.Height = imgHeight + size.Height;
775 size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
778 return size;
781 /* Checks for the separators and sets the location of a button and its wrapper flag */
782 private void CalcToolBar ()
784 int wd = this.Width; // the amount of space we have for rest of the buttons
785 int ht = this.ButtonSize.Height; // all buttons are displayed with the same height
786 Point loc; // the location to place the next button, leave the space for border
787 loc = new Point (ThemeEngine.Current.ToolBarGripWidth, ThemeEngine.Current.ToolBarGripWidth);
789 // clear all the wrappers if toolbar is not wrappable
790 if (! wrappable && ! autosize) {
791 if (this.Height != this.DefaultSize.Height)
792 this.Height = this.DefaultSize.Height;
793 foreach (ToolBarButton button in buttons) {
794 button.Location = loc;
795 button.Wrapper = false;
796 loc.X = loc.X + button.Rectangle.Width;
799 else if (! wrappable) { // autosizeable
800 if (ht != this.Height)
801 this.Height = ht;
802 foreach (ToolBarButton button in buttons) {
803 button.Location = loc;
804 button.Wrapper = false;
805 loc.X = loc.X + button.Rectangle.Width;
808 else { // wrappable
809 bool seenSeparator = false;
810 int separatorIndex = -1;
811 ToolBarButton button;
813 for (int i = 0; i < buttons.Count; i++) {
814 button = buttons [i];
815 if (button.Visible) {
816 if (button.Style == ToolBarButtonStyle.Separator) {
817 wd -= ThemeEngine.Current.ToolBarSeparatorWidth;
818 if (wd > 0) {
819 button.Wrapper = false; // clear the old flag in case it was set
820 button.Location = loc;
821 loc.X = loc.X + ThemeEngine.Current.ToolBarSeparatorWidth;
823 else {
824 button.Wrapper = true;
825 button.Location = loc;
826 loc.X = ThemeEngine.Current.ToolBarGripWidth;
827 wd = this.Width;
828 // we need space to draw horizontal separator
829 loc.Y = loc.Y + ThemeEngine.Current.ToolBarSeparatorWidth + ht;
831 seenSeparator = true;
832 separatorIndex = i;
834 else {
835 Rectangle rect = button.Rectangle;
836 wd -= rect.Width;
837 if (wd > 0) {
838 button.Wrapper = false;
839 button.Location = loc;
840 loc.X = loc.X + rect.Width;
842 else if (seenSeparator) {
843 // wrap at the separator and reassign the locations
844 i = separatorIndex; // for loop is going to increment it
845 buttons [separatorIndex].Wrapper = true;
846 seenSeparator = false;
847 separatorIndex = -1;
848 loc.X = ThemeEngine.Current.ToolBarGripWidth;
849 // we need space to draw horizontal separator
850 loc.Y = loc.Y + ht + ThemeEngine.Current.ToolBarSeparatorWidth;
851 wd = this.Width;
852 continue;
854 else {
855 button.Wrapper = true;
856 wd = this.Width;
857 loc.X = 0;
858 loc.Y += ht;
859 button.Location = loc;
860 loc.X = loc.X + rect.Width;
864 else // don't consider invisible buttons
865 continue;
867 /* adjust the control height, if we are autosizeable */
868 if (autosize) // wrappable
869 if (this.Height != (loc.Y + ht + ThemeEngine.Current.ToolBarGripWidth))
870 this.Height = loc.Y + ht + ThemeEngine.Current.ToolBarGripWidth;
874 private void DumpToolBar (string msg)
876 Console.WriteLine (msg);
877 Console.WriteLine ("ToolBar: name: " + this.Text);
878 Console.WriteLine ("ToolBar: wd, ht: " + this.Size);
879 Console.WriteLine ("ToolBar: img size: " + this.ImageSize);
880 Console.WriteLine ("ToolBar: button sz: " + this.buttonSize);
881 Console.WriteLine ("ToolBar: textalignment: "+ this.TextAlign);
882 Console.WriteLine ("ToolBar: appearance: "+ this.Appearance);
883 Console.WriteLine ("ToolBar: wrappable: "+ this.Wrappable);
884 Console.WriteLine ("ToolBar: buttons count: " + this.Buttons.Count);
886 int i= 0;
887 foreach (ToolBarButton b in buttons) {
888 Console.WriteLine ("ToolBar: button [{0}]:",i++);
889 b.Dump ();
892 #endregion Private Methods
894 #region subclass
895 public class ToolBarButtonCollection : IList, ICollection, IEnumerable
897 #region instance variables
898 private ArrayList buttonsList;
899 private ToolBar owner;
900 #endregion
902 #region constructors
903 public ToolBarButtonCollection (ToolBar owner)
905 this.owner = owner;
906 this.buttonsList = new ArrayList ();
908 #endregion
910 #region properties
911 [Browsable (false)]
912 public virtual int Count {
913 get { return buttonsList.Count; }
916 public virtual bool IsReadOnly {
917 get { return buttonsList.IsReadOnly; }
920 public virtual ToolBarButton this [int index] {
921 get { return (ToolBarButton) buttonsList [index]; }
922 set {
923 value.SetParent (owner);
924 buttonsList [index] = value;
925 owner.Redraw (true);
929 bool ICollection.IsSynchronized {
930 get { return buttonsList.IsSynchronized; }
933 object ICollection.SyncRoot {
934 get { return buttonsList.SyncRoot; }
937 bool IList.IsFixedSize {
938 get { return buttonsList.IsFixedSize; }
941 object IList.this [int index] {
942 get { return this [index]; }
943 set {
944 if (! (value is ToolBarButton))
945 throw new ArgumentException("Not of type ToolBarButton", "value");
946 this [index] = (ToolBarButton) value;
949 #endregion
951 #region methods
952 public int Add (string text)
954 ToolBarButton button = new ToolBarButton (text);
955 return this.Add (button);
958 public int Add (ToolBarButton button)
960 int result;
961 button.SetParent (owner);
962 result = buttonsList.Add (button);
963 owner.Redraw (true);
964 return result;
967 public void AddRange (ToolBarButton [] buttons)
969 foreach (ToolBarButton button in buttons)
970 Add (button);
973 public virtual void Clear ()
975 buttonsList.Clear ();
976 owner.Redraw (false);
979 public bool Contains (ToolBarButton button)
981 return buttonsList.Contains (button);
984 public virtual IEnumerator GetEnumerator ()
986 return buttonsList.GetEnumerator ();
989 void ICollection.CopyTo (Array dest, int index)
991 buttonsList.CopyTo (dest, index);
994 int IList.Add (object button)
996 if (! (button is ToolBarButton)) {
997 throw new ArgumentException("Not of type ToolBarButton", "button");
1000 return this.Add ((ToolBarButton) button);
1003 bool IList.Contains (object button)
1005 if (! (button is ToolBarButton)) {
1006 throw new ArgumentException("Not of type ToolBarButton", "button");
1009 return this.Contains ((ToolBarButton) button);
1012 int IList.IndexOf (object button)
1014 if (! (button is ToolBarButton)) {
1015 throw new ArgumentException("Not of type ToolBarButton", "button");
1018 return this.IndexOf ((ToolBarButton) button);
1021 void IList.Insert (int index, object button)
1023 if (! (button is ToolBarButton)) {
1024 throw new ArgumentException("Not of type ToolBarButton", "button");
1027 this.Insert (index, (ToolBarButton) button);
1030 void IList.Remove (object button)
1032 if (! (button is ToolBarButton)) {
1033 throw new ArgumentException("Not of type ToolBarButton", "button");
1036 this.Remove ((ToolBarButton) button);
1039 public int IndexOf (ToolBarButton button)
1041 return buttonsList.IndexOf (button);
1044 public void Insert (int index, ToolBarButton button)
1046 buttonsList.Insert (index, button);
1047 owner.Redraw (true);
1050 public void Remove (ToolBarButton button)
1052 buttonsList.Remove (button);
1053 owner.Redraw (true);
1056 public virtual void RemoveAt (int index)
1058 buttonsList.RemoveAt (index);
1059 owner.Redraw (true);
1061 #endregion methods
1063 #endregion subclass