2008-03-27 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStripDropDownItem.cs
1 //
2 // ToolStripDropDownItem.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:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
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.
22 //
23 // Copyright (c) 2006 Jonathan Pobst
24 //
25 // Authors:
26 //      Jonathan Pobst (monkey@jpobst.com)
27 //
28 #if NET_2_0
29
30 using System;
31 using System.Drawing;
32 using System.ComponentModel;
33 using System.Threading;
34
35 namespace System.Windows.Forms
36 {
37         [DefaultProperty ("DropDownItems")]
38         [Designer ("System.Windows.Forms.Design.ToolStripMenuItemDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
39         public abstract class ToolStripDropDownItem : ToolStripItem
40         {
41                 internal ToolStripDropDown drop_down;
42                 private ToolStripDropDownDirection drop_down_direction;
43
44                 #region Protected Constructors
45                 protected ToolStripDropDownItem () : this (string.Empty, null, null, string.Empty)
46                 {
47                 }
48
49                 protected ToolStripDropDownItem (string text, Image image, EventHandler onClick)
50                         : this (text, image, onClick, string.Empty)
51                 {
52                 }
53
54                 protected ToolStripDropDownItem (string text, Image image, params ToolStripItem[] dropDownItems)
55                         : this (text, image, null, string.Empty)
56                 {
57                 }
58
59                 protected ToolStripDropDownItem (string text, Image image, EventHandler onClick, string name)
60                         : base (text, image, onClick, name)
61                 {
62                 }
63                 #endregion
64
65                 #region Public Properties
66                 [TypeConverter (typeof (ReferenceConverter))]
67                 public ToolStripDropDown DropDown {
68                         get {
69                                 if (this.drop_down == null) {
70                                         this.drop_down = CreateDefaultDropDown ();
71                                         this.drop_down.ItemAdded += new ToolStripItemEventHandler (DropDown_ItemAdded);
72                                 }
73                         
74                                 return this.drop_down;
75                         }
76                         set { this.drop_down = value; }
77                 }
78
79                 [Browsable (false)]
80                 public ToolStripDropDownDirection DropDownDirection {
81                         get { return this.drop_down_direction; }
82                         set {
83                                 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
84                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
85
86                                 this.drop_down_direction = value;
87                         }
88                 }
89
90                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
91                 public ToolStripItemCollection DropDownItems {
92                         get { return this.DropDown.Items; }
93                 }
94
95                 [Browsable (false)]
96                 public virtual bool HasDropDownItems {
97                         get { return this.drop_down != null && this.DropDown.Items.Count != 0; }
98                 }
99
100                 [Browsable (false)]
101                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
102                 public override bool Pressed {
103                         get { return base.Pressed || (this.drop_down != null && this.DropDown.Visible); }
104                 }
105                 #endregion
106
107                 #region Protected Properties
108                 protected internal virtual Point DropDownLocation {
109                         get {
110                                 Point p;
111
112                                 if (this.IsOnDropDown) {
113                                         p = Parent.PointToScreen (new Point (this.Bounds.Left, this.Bounds.Top - 1));
114                                         p.X += this.Bounds.Width;
115                                         p.Y += this.Bounds.Left;
116                                         return p;
117                                 }
118                                 else
119                                         p = new Point (this.Bounds.Left, this.Bounds.Bottom - 1);
120
121                                 return Parent.PointToScreen (p);
122                         }
123                 }
124                 #endregion
125
126                 #region Public Methods
127                 public void HideDropDown ()
128                 {
129                         if (this.drop_down == null || !this.DropDown.Visible)
130                                 return;
131
132                         this.DropDown.Close (ToolStripDropDownCloseReason.CloseCalled);
133                         this.is_pressed = false;
134                         this.Invalidate ();
135                         this.OnDropDownHide (EventArgs.Empty);
136                         this.OnDropDownClosed (EventArgs.Empty);
137                 }
138
139                 public void ShowDropDown ()
140                 {
141                         if (!this.HasDropDownItems)
142                                 return;
143                         
144                         this.Invalidate ();
145                         this.OnDropDownOpening (this, EventArgs.Empty);
146                         this.DropDown.Show (this.DropDownLocation);
147                         this.OnDropDownShow (EventArgs.Empty);
148                         this.OnDropDownOpened (EventArgs.Empty);
149                 }
150                 #endregion
151
152                 #region Protected Methods
153                 protected override AccessibleObject CreateAccessibilityInstance ()
154                 {
155                         return new ToolStripDropDownItemAccessibleObject (this);
156                 }
157                 
158                 protected virtual ToolStripDropDown CreateDefaultDropDown ()
159                 {
160                         ToolStripDropDown tsdd = new ToolStripDropDown ();
161                         tsdd.OwnerItem = this;
162                         return tsdd;
163                 }
164
165                 protected override void Dispose (bool disposing)
166                 {
167                         if (!IsDisposed) {
168                                 if (this.HasDropDownItems)
169                                         foreach (ToolStripItem tsi in this.DropDownItems)
170                                                 if (tsi is ToolStripMenuItem)
171                                                         ToolStripManager.RemoveToolStripMenuItem ((ToolStripMenuItem)tsi);
172                                         
173                                 base.Dispose (disposing);
174                         }
175                 }
176
177                 protected override void OnBoundsChanged ()
178                 {
179                         base.OnBoundsChanged ();
180                 }
181
182                 protected internal virtual void OnDropDownClosed (EventArgs e)
183                 {
184                         EventHandler eh = (EventHandler)(Events [DropDownClosedEvent]);
185                         if (eh != null)
186                                 eh (this, e);
187                 }
188
189                 protected virtual void OnDropDownHide (EventArgs e)
190                 {
191                 }
192
193                 protected internal virtual void OnDropDownItemClicked (ToolStripItemClickedEventArgs e)
194                 {
195                         ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [DropDownClosedEvent]);
196                         if (eh != null)
197                                 eh (this, e);
198                 }
199
200                 protected internal virtual void OnDropDownOpened (EventArgs e)
201                 {
202                         EventHandler eh = (EventHandler)(Events [DropDownOpenedEvent]);
203                         if (eh != null)
204                                 eh (this, e);
205                 }
206
207                 protected virtual void OnDropDownShow (EventArgs e)
208                 {
209                 }
210
211                 protected override void OnFontChanged (EventArgs e)
212                 {
213                         base.OnFontChanged (e);
214                 }
215
216                 protected override void OnRightToLeftChanged (EventArgs e)
217                 {
218                         base.OnRightToLeftChanged (e);
219                 }
220                 
221                 protected internal override bool ProcessCmdKey (ref Message m, Keys keyData)
222                 {
223                         if (this.HasDropDownItems)
224                                 foreach (ToolStripItem tsi in this.DropDownItems)
225                                         if (tsi.ProcessCmdKey (ref m, keyData) == true)
226                                                 return true;
227
228                         return base.ProcessCmdKey (ref m, keyData);
229                 }
230
231                 protected internal override bool ProcessDialogKey (Keys keyData)
232                 {
233                         if (!this.Selected || !this.HasDropDownItems)
234                                 return base.ProcessDialogKey (keyData);
235                                 
236                         if (!this.IsOnDropDown) {
237                                 if (this.Parent.Orientation == Orientation.Horizontal) {
238                                         if (keyData == Keys.Down || keyData == Keys.Enter) {
239                                                 if (this.Parent is MenuStrip)
240                                                         (this.Parent as MenuStrip).MenuDroppedDown = true;
241                                                 this.ShowDropDown ();
242                                                 this.DropDown.SelectNextToolStripItem (null, true);
243                                                 return true;
244                                         }
245                                 } else {
246                                         if (keyData == Keys.Right || keyData == Keys.Enter) {
247                                                 if (this.Parent is MenuStrip)
248                                                         (this.Parent as MenuStrip).MenuDroppedDown = true;
249                                                 this.ShowDropDown ();
250                                                 this.DropDown.SelectNextToolStripItem (null, true);
251                                                 return true;
252                                         }
253                                 }
254                         } else {
255                                 if (keyData == Keys.Right || keyData == Keys.Enter) {
256                                         if (this.HasDropDownItems) {
257                                                 this.ShowDropDown ();
258                                                 this.DropDown.SelectNextToolStripItem (null, true);
259                                                 return true;
260                                         }
261                                 }
262                         }
263                         
264                         
265                         return base.ProcessDialogKey (keyData);
266                 }
267                 #endregion
268
269                 #region Public Events
270                 static object DropDownClosedEvent = new object ();
271                 static object DropDownItemClickedEvent = new object ();
272                 static object DropDownOpenedEvent = new object ();
273                 static object DropDownOpeningEvent = new object ();
274
275                 public event EventHandler DropDownClosed {
276                         add { Events.AddHandler (DropDownClosedEvent, value); }
277                         remove { Events.RemoveHandler (DropDownClosedEvent, value); }
278                 }
279
280                 public event ToolStripItemClickedEventHandler DropDownItemClicked {
281                         add { Events.AddHandler (DropDownItemClickedEvent, value); }
282                         remove { Events.RemoveHandler (DropDownItemClickedEvent, value); }
283                 }
284
285                 public event EventHandler DropDownOpened {
286                         add { Events.AddHandler (DropDownOpenedEvent, value); }
287                         remove { Events.RemoveHandler (DropDownOpenedEvent, value); }
288                 }
289
290                 public event EventHandler DropDownOpening {
291                         add { Events.AddHandler (DropDownOpeningEvent, value); }
292                         remove { Events.RemoveHandler (DropDownOpeningEvent, value); }
293                 }
294                 #endregion
295
296                 #region Internal Methods
297                 internal override void Dismiss (ToolStripDropDownCloseReason reason)
298                 {
299                         if (this.HasDropDownItems && this.DropDown.Visible)
300                                 this.DropDown.Dismiss (reason);
301                                 
302                         base.Dismiss (reason);
303                 }
304
305                 internal override void HandleClick (EventArgs e)
306                 {
307                         base.OnClick (e);
308                 }
309                 
310                 internal void HideDropDown (ToolStripDropDownCloseReason reason)
311                 {
312                         if (this.drop_down == null || !this.DropDown.Visible)
313                                 return;
314
315                         this.DropDown.Close (reason);
316                         this.is_pressed = false;
317                         this.Invalidate ();
318                         this.OnDropDownHide (EventArgs.Empty);
319                         this.OnDropDownClosed (EventArgs.Empty);
320                 }
321                 
322                 private void DropDown_ItemAdded (object sender, ToolStripItemEventArgs e)
323                 {
324                         e.Item.owner_item = this;
325                 }
326                 
327                 private void OnDropDownOpening (object sender, EventArgs e)
328                 {
329                         EventHandler eh = (EventHandler)(Events[DropDownOpeningEvent]);
330                         if (eh != null)
331                                 eh (this, e);
332                 }
333                 #endregion
334         }
335 }
336 #endif