* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolBarButton.cs
1 // System.Windows.Forms.ToolBarButton.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 // Copyright (C) 2004-2006 Novell, Inc. (http://www.novell.com)
23 //
24 // Authors:
25 //      Ravindra (rkumar@novell.com)
26 //      Mike Kestner <mkestner@novell.com>
27
28
29 using System.ComponentModel;
30 using System.ComponentModel.Design;
31 using System.Drawing;
32 using System.Drawing.Imaging;
33
34 namespace System.Windows.Forms
35 {
36         [DefaultProperty ("Text")]
37         [Designer ("System.Windows.Forms.Design.ToolBarButtonDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
38         [DesignTimeVisible (false)]
39         [ToolboxItem (false)]
40         public class ToolBarButton : Component
41         {
42                 #region instance variable
43                 private bool enabled = true;
44                 private int image_index = -1;
45                 private ContextMenu menu;
46                 private ToolBar parent;
47                 private bool partial_push = false;
48                 private bool pushed = false;
49                 private ToolBarButtonStyle style = ToolBarButtonStyle.PushButton;
50                 private object tag;
51                 private string text = "";
52                 private string tooltip = "";
53                 private bool visible = true;
54                 internal bool dd_pressed = false; // to check for a mouse down on dropdown rect
55                 internal bool hilight = false;    // to hilight buttons in flat style
56                 internal bool inside = false;     // to handle the mouse move event with mouse pressed
57                 internal bool pressed = false;    // this is to check for mouse down on a button
58                 #endregion
59
60                 #region constructors
61                 public ToolBarButton () { }
62
63                 public ToolBarButton (string text)
64                 {
65                         this.text = text;
66                 }
67                 #endregion
68
69                 #region internal properties
70                 internal bool Hilight {
71                         get { return hilight; }
72                         set {
73                                 if (hilight == value)
74                                         return;
75
76                                 hilight = value;
77                                 Invalidate ();
78                         }
79                 }
80
81                 internal Image Image {
82                         get {
83                                 if (Parent == null || Parent.ImageList == null)
84                                         return null;
85
86                                 ImageList list = Parent.ImageList;
87                                 if (ImageIndex > -1 && ImageIndex < list.Images.Count)
88                                         return list.Images [ImageIndex];
89
90                                 return null;
91                         }
92                 }
93
94                 Rectangle image_rect;
95                 internal Rectangle ImageRectangle {
96                         get {
97                                 Rectangle result = image_rect;
98                                 result.X += bounds.X;
99                                 result.Y += bounds.Y;
100                                 return result; 
101                         }
102                 }
103
104                 Rectangle text_rect;
105                 internal Rectangle TextRectangle {
106                         get { 
107                                 Rectangle result = text_rect;
108                                 result.X += bounds.X;
109                                 result.Y += bounds.Y;
110                                 return result; 
111                         }
112                 }
113
114                 Rectangle bounds;
115                 internal Point Location {
116                         //get { return location; }
117                         set { 
118                                 if (bounds.Location == value)
119                                         return;
120
121                                 if (bounds != Rectangle.Empty)
122                                         Invalidate ();
123
124                                 bounds.Location = value;
125                                 Invalidate ();
126                         }
127                 }
128
129                 internal bool Pressed {
130                         get {
131                                 if (pressed && inside)
132                                         return true;
133                                 else
134                                         return false;
135                         }
136                         set { pressed = value; }
137                 }
138                 #endregion internal properties
139
140                 #region properties
141                 [DefaultValue (null)]
142                 [TypeConverter (typeof (ReferenceConverter))]
143                 public Menu DropDownMenu {
144                         get { return menu; }
145
146                         set {
147                                 if (value is ContextMenu)
148                                         menu = (ContextMenu) value;
149                                 else
150                                         throw new ArgumentException ("DropDownMenu must be of type ContextMenu.");
151                         }
152                 }
153
154                 [DefaultValue (true)]
155                 [Localizable (true)]
156                 public bool Enabled {
157                         get { return enabled; }
158                         set {
159                                 if (value == enabled)
160                                         return;
161
162                                 enabled = value;
163                                 Invalidate ();
164                         }
165                 }
166
167                 [DefaultValue (-1)]
168                 [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
169                 [Localizable (true)]
170                 [TypeConverter (typeof (ImageIndexConverter))]
171                 public int ImageIndex {
172                         get { return image_index; }
173                         set {
174                                 if (value < -1)
175                                         throw new ArgumentException ("ImageIndex value must be above or equal to -1.");
176
177                                 if (value == image_index)
178                                         return;
179
180                                 image_index = value;
181                                 if (bounds.Size != CalculateSize ())
182                                         Parent.Redraw (true);
183                                 else
184                                         Invalidate ();
185                         }
186                 }
187
188                 [Browsable (false)]
189                 public ToolBar Parent {
190                         get { return parent; }
191                 }
192
193                 [DefaultValue (false)]
194                 public bool PartialPush {
195                         get { return partial_push; }
196                         set {
197                                 if (value == partial_push)
198                                         return;
199
200                                 partial_push = value;
201                                 Invalidate ();
202                         }
203                 }
204
205                 [DefaultValue (false)]
206                 public bool Pushed {
207                         get { return pushed; }
208                         set {
209                                 if (value == pushed)
210                                         return;
211
212                                 pushed = value;
213                                 Invalidate ();
214                         }
215                 }
216
217                 public Rectangle Rectangle {
218                         get {
219                                 if (Visible && Parent != null && Parent.Visible) {
220                                         Rectangle result = bounds;
221                                         if (Style == ToolBarButtonStyle.DropDownButton && Parent.DropDownArrows)
222                                                 result.Width += ThemeEngine.Current.ToolBarDropDownWidth;
223                                         return result;
224                                 } else
225                                         return Rectangle.Empty;
226                         }
227                 }
228
229                 [DefaultValue (ToolBarButtonStyle.PushButton)]
230                 [RefreshProperties (RefreshProperties.Repaint)]
231                 public ToolBarButtonStyle Style {
232                         get { return style; }
233                         set {
234                                 if (value == style)
235                                         return;
236
237                                 style = value;
238                                 Invalidate ();
239                         }
240                 }
241
242                 [Bindable (true)]
243                 [DefaultValue (null)]
244                 [Localizable (false)]
245                 [TypeConverter (typeof (StringConverter))]
246                 public object Tag {
247                         get { return tag; }
248                         set { tag = value; }
249                 }
250
251                 [DefaultValue ("")]
252                 [Localizable (true)]
253                 public string Text {
254                         get { return text; }
255                         set {
256                                 if (value == text)
257                                         return;
258
259                                 text = value;
260                                 Invalidate ();
261                         }
262                 }
263
264                 [DefaultValue ("")]
265                 [Localizable (true)]
266                 public string ToolTipText {
267                         get { return tooltip; }
268                         set { tooltip = value; }
269                 }
270
271                 [DefaultValue (true)]
272                 [Localizable (true)]
273                 public bool Visible {
274                         get { return visible; }
275                         set {
276                                 if (value == visible)
277                                         return;
278
279                                 visible = value;
280                                 if (Parent != null)
281                                         Parent.Redraw (true);
282                         }
283                 }
284                 #endregion
285
286                 #region internal methods
287                 internal void SetParent (ToolBar parent)
288                 {
289                         if (Parent == parent)
290                                 return;
291
292                         if (Parent != null)
293                                 Parent.Buttons.Remove (this);
294
295                         this.parent = parent;
296                 }
297
298                 internal void Layout ()
299                 {
300                         if (Parent == null || !Visible)
301                                 return;
302
303                         Size psize = Parent.ButtonSize;
304                         Size size = psize;
305                         if (!Parent.SizeSpecified) {
306                                 size = CalculateSize ();
307                                 if (size.Width == 0 || size.Height == 0)
308                                         size = psize;
309                         }
310                         Layout (size);
311                 }
312
313                 internal void Layout (Size size)
314                 {
315                         if (Parent == null || !Visible)
316                                 return;
317
318                         bounds.Size = size;
319
320                         Size image_size = (Parent.ImageSize == Size.Empty) ? new Size (16, 16) : Parent.ImageSize;
321                         int grip = ThemeEngine.Current.ToolBarImageGripWidth;
322
323                         if (Parent.TextAlign == ToolBarTextAlign.Underneath) {
324                                 image_rect = new Rectangle ((bounds.Size.Width - image_size.Width) / 2 - grip, 0, image_size.Width + 2 + grip, image_size.Height + 2 * grip);
325                                 text_rect = new Rectangle (0, image_rect.Height, bounds.Size.Width, bounds.Size.Height - image_rect.Height);
326                         } else {
327                                 image_rect = new Rectangle (0, 0, image_size.Width + 2 * grip, image_size.Height + 2 * grip);
328                                 text_rect = new Rectangle (image_rect.Width, 0, bounds.Size.Width - image_rect.Width, bounds.Size.Height);
329                         }
330                 }
331
332                 const int text_padding = 3;
333
334                 Size TextSize {
335                         get {
336                                 SizeF sz = Parent.DeviceContext.MeasureString (Text, Parent.Font);
337                                 if (sz == SizeF.Empty)
338                                         return Size.Empty;
339                                 return new Size ((int) Math.Ceiling (sz.Width) + 2 * text_padding, (int) Math.Ceiling (sz.Height));
340                         }
341                 }
342
343                 Size CalculateSize ()
344                 {
345                         if (Parent == null)
346                                 return Size.Empty;
347
348                         Theme theme = ThemeEngine.Current;
349
350                         int ht = Parent.ButtonSize.Height + 2 * theme.ToolBarGripWidth;
351
352                         if (Style == ToolBarButtonStyle.Separator)
353                                 return new Size (theme.ToolBarSeparatorWidth, ht);
354
355                         Size size = TextSize;
356                         Size image_size = (Parent.ImageSize == Size.Empty) ? new Size (16, 16) : Parent.ImageSize;
357
358                         int image_width = image_size.Width + 2 * theme.ToolBarImageGripWidth; 
359                         int image_height = image_size.Height + 2 * theme.ToolBarImageGripWidth; 
360
361                         if (Parent.TextAlign == ToolBarTextAlign.Right) {
362                                 size.Width =  image_width + size.Width;
363                                 size.Height = (size.Height > image_height) ? size.Height : image_height;
364                         } else {
365                                 size.Height = image_height + size.Height;
366                                 size.Width = (size.Width > image_width) ? size.Width : image_width;
367                         }
368
369                         size.Width += theme.ToolBarGripWidth;
370                         size.Height += theme.ToolBarGripWidth;
371                         return size;
372                 }
373
374                 void Invalidate ()
375                 {
376                         if (Parent != null)
377                                 Parent.Invalidate (Rectangle);
378                 }
379
380                 #endregion Internal Methods
381
382                 #region methods
383                 protected override void Dispose (bool disposing)
384                 {
385                         base.Dispose (disposing);
386                 }
387
388                 public override string ToString ()
389                 {
390                         return string.Format ("ToolBarButton: {0}, Style: {1}", text, style);
391                 }
392                 #endregion
393         }
394 }