2006-11-30 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStripDropDown.cs
1 //\r
2 // ToolStripDropDown.cs\r
3 //\r
4 // Permission is hereby granted, free of charge, to any person obtaining\r
5 // a copy of this software and associated documentation files (the\r
6 // "Software"), to deal in the Software without restriction, including\r
7 // without limitation the rights to use, copy, modify, merge, publish,\r
8 // distribute, sublicense, and/or sell copies of the Software, and to\r
9 // permit persons to whom the Software is furnished to do so, subject to\r
10 // the following conditions:\r
11 // \r
12 // The above copyright notice and this permission notice shall be\r
13 // included in all copies or substantial portions of the Software.\r
14 // \r
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22 //\r
23 // Copyright (c) 2006 Jonathan Pobst\r
24 //\r
25 // Authors:\r
26 //      Jonathan Pobst (monkey@jpobst.com)\r
27 //\r
28 \r
29 #if NET_2_0\r
30 using System.Drawing;\r
31 using System.Runtime.InteropServices;\r
32 using System.ComponentModel;\r
33 \r
34 namespace System.Windows.Forms\r
35 {\r
36         [ClassInterface (ClassInterfaceType.AutoDispatch)]\r
37         [ComVisible (true)]\r
38         public class ToolStripDropDown : ToolStrip\r
39         {\r
40                 private bool allow_transparency;\r
41                 private bool auto_close;\r
42                 private bool drop_shadow_enabled = true;\r
43                 private double opacity = 1D;\r
44                 private ToolStripItem owner_item;\r
45 \r
46                 #region Public Constructor\r
47                 public ToolStripDropDown () : base ()\r
48                 {\r
49                         SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);\r
50                         SetStyle (ControlStyles.ResizeRedraw, true);\r
51 \r
52                         this.auto_close = true;\r
53                         is_visible = false;\r
54                         Hwnd.ObjectFromHandle (this.Handle).no_activate = true;\r
55                         this.GripStyle = ToolStripGripStyle.Hidden;\r
56                 }\r
57                 #endregion\r
58 \r
59                 #region Public Properties\r
60                 [Browsable (false)]\r
61                 [EditorBrowsable (EditorBrowsableState.Never)]\r
62                 public bool AllowTransparency {\r
63                         get { return allow_transparency; }\r
64                         set {\r
65                                 if (value == allow_transparency)\r
66                                         return;\r
67 \r
68                                 if ((XplatUI.SupportsTransparency () & TransparencySupport.Set) != 0) {\r
69                                         allow_transparency = value;\r
70 \r
71                                         if (value) \r
72                                                 XplatUI.SetWindowTransparency (Handle, Opacity, Color.Empty);\r
73                                         else\r
74                                                 UpdateStyles (); // Remove the WS_EX_LAYERED style\r
75                                 }\r
76                         }\r
77                 }\r
78 \r
79                 [Browsable (false)]\r
80                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]\r
81                 public override AnchorStyles Anchor {\r
82                         get { return base.Anchor; }\r
83                         set { base.Anchor = value; }\r
84                 }\r
85 \r
86                 [Browsable (false)]\r
87                 [EditorBrowsable (EditorBrowsableState.Never)]\r
88                 public bool AutoClose\r
89                 {\r
90                         get { return this.auto_close; }\r
91                         set { this.auto_close = value; }\r
92                 }\r
93 \r
94                 [DefaultValue (true)]\r
95                 public override bool AutoSize {\r
96                         get { return base.AutoSize; }\r
97                         set { base.AutoSize = value; }\r
98                 }\r
99 \r
100                 [Browsable (false)]\r
101                 [EditorBrowsable (EditorBrowsableState.Never)]\r
102                 public ContextMenu ContextMenu {\r
103                         get { return null; }\r
104                         set { }\r
105                 }\r
106 \r
107                 //[Browsable (false)]\r
108                 //[EditorBrowsable (EditorBrowsableState.Never)]\r
109                 //public ContextMenuStrip ContextMenuStrip {\r
110                 //        get { return null; }\r
111                 //        set { }\r
112                 //}\r
113 \r
114                 [Browsable (false)]\r
115                 [EditorBrowsable (EditorBrowsableState.Never)]\r
116                 public override DockStyle Dock {\r
117                         get { return base.Dock; }\r
118                         set { base.Dock = value; }\r
119                 }\r
120                 \r
121                 public bool DropShadowEnabled {\r
122                         get { return this.drop_shadow_enabled; }\r
123                         set {\r
124                                 if (this.drop_shadow_enabled == value)\r
125                                         return;\r
126                                         \r
127                                 this.drop_shadow_enabled = value;\r
128                                 UpdateStyles ();        // Re-CreateParams\r
129                         }\r
130                 }\r
131 \r
132                 public override Font Font {\r
133                         get { return base.Font; }\r
134                         set { base.Font = value; }\r
135                 }\r
136 \r
137                 [Browsable (false)]\r
138                 [EditorBrowsable (EditorBrowsableState.Never)]\r
139                 public ToolStripGripDisplayStyle GripDisplayStyle {\r
140                         get { return ToolStripGripDisplayStyle.Vertical; }\r
141                         set { }\r
142                 }\r
143 \r
144                 [Browsable (false)]\r
145                 [EditorBrowsable (EditorBrowsableState.Never)]\r
146                 public Padding GripMargin {\r
147                         get { return Padding.Empty; }\r
148                         set { }\r
149                 }\r
150 \r
151                 [Browsable (false)]\r
152                 [EditorBrowsable (EditorBrowsableState.Never)]\r
153                 public Rectangle GripRectangle {\r
154                         get { return Rectangle.Empty; }\r
155                         set { }\r
156                 }\r
157 \r
158                 [Browsable (false)]\r
159                 [EditorBrowsable (EditorBrowsableState.Never)]\r
160                 public ToolStripGripStyle GripStyle {\r
161                         get { return base.GripStyle; }\r
162                         set { base.GripStyle = value; }\r
163                 }\r
164 \r
165                 [Browsable (false)]\r
166                 [EditorBrowsable (EditorBrowsableState.Never)]\r
167                 public Point Location {\r
168                         get { return base.Location; }\r
169                         set { base.Location = value; }\r
170                 }\r
171 \r
172                 public double Opacity {\r
173                         get { return this.opacity; }\r
174                         set {\r
175                                 if (this.opacity == value)\r
176                                         return;\r
177                                         \r
178                                 this.opacity = value;\r
179                                 this.allow_transparency = true;\r
180 \r
181                                 UpdateStyles ();\r
182                                 XplatUI.SetWindowTransparency (Handle, opacity, Color.Empty);\r
183                         }\r
184                 }\r
185 \r
186                 public ToolStripItem OwnerItem {\r
187                         get { return this.owner_item; }\r
188                         set { this.owner_item = value; \r
189                                 \r
190                                 if (this.owner_item != null)\r
191                                         if (this.owner_item.Owner != null)\r
192                                                 this.Renderer = this.owner_item.Owner.Renderer;\r
193                         }\r
194                 }\r
195                 \r
196                 public Region Region {\r
197                         get { return base.Region; }\r
198                         set { base.Region = value; }\r
199                 }\r
200 \r
201                 [Localizable (true)]\r
202                 public override RightToLeft RightToLeft {\r
203                         get { return base.RightToLeft; }\r
204                         set { base.RightToLeft = value; }\r
205                 }\r
206 \r
207                 [Browsable (false)]\r
208                 [EditorBrowsable (EditorBrowsableState.Never)]\r
209                 public bool Stretch {\r
210                         get { return false; }\r
211                         set { }\r
212                 }\r
213 \r
214                 [Browsable (false)]\r
215                 [EditorBrowsable (EditorBrowsableState.Never)]\r
216                 public int TabIndex {\r
217                         get { return 0; }\r
218                         set { }\r
219                 }\r
220 \r
221                 public bool TopLevel {\r
222                         get { return this.TopMost; }\r
223                         set { }\r
224                 }\r
225                 \r
226                 [Localizable (true)]\r
227                 public bool Visible {\r
228                         get { return base.Visible; }\r
229                         set { base.Visible = value; }\r
230                 }\r
231                 #endregion\r
232 \r
233                 #region Protected Properties\r
234                 protected override CreateParams CreateParams {\r
235                         get {\r
236                                 CreateParams cp = base.CreateParams;\r
237 \r
238                                 cp.Style = unchecked ((int)(WindowStyles.WS_POPUP | WindowStyles.WS_CLIPCHILDREN));\r
239                                 cp.ClassStyle = unchecked ((int)0x82000000);\r
240                                 cp.ExStyle |= (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST);\r
241 \r
242                                 if (Opacity < 1.0 && allow_transparency)\r
243                                         cp.ExStyle |= (int)WindowExStyles.WS_EX_LAYERED;\r
244 \r
245                                 return cp;\r
246                         }\r
247                 }\r
248 \r
249                 protected override DockStyle DefaultDock {\r
250                         get { return DockStyle.None; }\r
251                 }\r
252 \r
253                 protected override Padding DefaultPadding {\r
254                         get { return new Padding (1, 2, 1, 2); }\r
255                 }\r
256 \r
257                 protected override bool DefaultShowItemToolTips {\r
258                         get { return true; }\r
259                 }\r
260 \r
261                 //protected internal override Size MaxItemSize {\r
262                 //        get {  return new Size (Screen.PrimaryScreen.Bounds.Width - 2, Screen.PrimaryScreen.Bounds.Height - 34); }\r
263                 //}\r
264 \r
265                 protected virtual bool TopMost {\r
266                         get { return true; }\r
267                 }\r
268                 #endregion\r
269 \r
270                 #region Public Methods\r
271                 public void Close ()\r
272                 {\r
273                         this.Close (ToolStripDropDownCloseReason.CloseCalled);\r
274                 }\r
275 \r
276                 public void Close (ToolStripDropDownCloseReason reason)\r
277                 {\r
278                         // Give users a chance to cancel the close\r
279                         ToolStripDropDownClosingEventArgs e = new ToolStripDropDownClosingEventArgs (reason);\r
280                         this.OnClosing (e);\r
281 \r
282                         if (e.Cancel)\r
283                                 return;\r
284 \r
285                         // Don't actually close if AutoClose == true unless explicitly called\r
286                         if (!this.auto_close && reason != ToolStripDropDownCloseReason.CloseCalled)\r
287                                 return;\r
288 \r
289                         // Detach from the tracker\r
290                         ToolStripManager.AppClicked -= new EventHandler (ToolStripMenuTracker_AppClicked); ;\r
291                         ToolStripManager.AppFocusChange -= new EventHandler (ToolStripMenuTracker_AppFocusChange);\r
292 \r
293                         // Owner MenuItem needs to be told to redraw (it's no longer selected)\r
294                         if (owner_item != null)\r
295                                 owner_item.Invalidate ();\r
296 \r
297                         // Recursive hide all child dropdowns\r
298                         foreach (ToolStripItem tsi in this.Items)\r
299                                 if (tsi is ToolStripMenuItem)\r
300                                         (tsi as ToolStripMenuItem).HideDropDown (reason);\r
301 \r
302                         // Hide this dropdown\r
303                         this.Hide ();\r
304                         \r
305                         this.OnClosed (new ToolStripDropDownClosedEventArgs (reason));\r
306                 }\r
307 \r
308                 public void Show ()\r
309                 {\r
310                         CancelEventArgs e = new CancelEventArgs ();\r
311                         this.OnOpening (e);\r
312                         \r
313                         if (e.Cancel)\r
314                                 return;\r
315 \r
316                         // The tracker lets us know when the form is clicked or loses focus\r
317                         ToolStripManager.AppClicked += new EventHandler (ToolStripMenuTracker_AppClicked);\r
318                         ToolStripManager.AppFocusChange += new EventHandler (ToolStripMenuTracker_AppFocusChange);\r
319 \r
320                         base.Show ();\r
321                         \r
322                         this.OnOpened (EventArgs.Empty);\r
323                 }\r
324                 \r
325                 public void Show (Point screenLocation)\r
326                 {\r
327                         this.Location = screenLocation;\r
328                         Show ();\r
329                 }\r
330                 \r
331                 public void Show (Control control, Point position)\r
332                 {\r
333                         if (control == null)\r
334                                 throw new ArgumentNullException ("control");\r
335                                 \r
336                         this.Location = control.PointToScreen (position);\r
337                 }\r
338                 \r
339                 public void Show (int x, int y)\r
340                 {\r
341                         this.Location = new Point (x, y);\r
342                         Show ();\r
343                 }\r
344                 \r
345                 public void Show (Control control, int x, int y)\r
346                 {\r
347                         Show (control, new Point (x, y));\r
348                         \r
349                 }\r
350                 #endregion\r
351 \r
352                 #region Protected Methods\r
353                 protected override void CreateHandle ()\r
354                 {\r
355                         base.CreateHandle ();\r
356                 }\r
357 \r
358                 protected override void Dispose (bool disposing)\r
359                 {\r
360                         base.Dispose (disposing);\r
361                 }\r
362 \r
363                 protected virtual void OnClosed (ToolStripDropDownClosedEventArgs e)\r
364                 {\r
365                         if (Closed != null) Closed (this, e);\r
366                 }\r
367 \r
368                 protected virtual void OnClosing (ToolStripDropDownClosingEventArgs e)\r
369                 {\r
370                         if (Closing != null) Closing (this, e);\r
371                 }\r
372 \r
373                 protected override void OnHandleCreated (EventArgs e)\r
374                 {\r
375                         base.OnHandleCreated (e);\r
376                 }\r
377 \r
378                 protected override void OnItemClicked (ToolStripItemClickedEventArgs e)\r
379                 {\r
380                         base.OnItemClicked (e);\r
381                 }\r
382 \r
383                 protected override void OnLayout (LayoutEventArgs e)\r
384                 {\r
385                         base.OnLayout (e);\r
386 \r
387                         // Find the widest menu item\r
388                         int widest = 0;\r
389 \r
390                         foreach (ToolStripItem tsi in this.Items)\r
391                                 if (tsi.GetPreferredSize (Size.Empty).Width > widest)\r
392                                         widest = tsi.GetPreferredSize (Size.Empty).Width;\r
393 \r
394                         int x = this.Padding.Left;\r
395                         widest += 68 - this.Padding.Horizontal;\r
396                         int y = this.Padding.Top;\r
397 \r
398                         foreach (ToolStripItem tsi in this.Items) {\r
399                                 y += tsi.Margin.Top;\r
400 \r
401                                 int height = 0;\r
402 \r
403                                 if (tsi is ToolStripSeparator)\r
404                                         height = 7;\r
405                                 else\r
406                                         height = 22;\r
407 \r
408                                 tsi.SetBounds (new Rectangle (x, y, widest, height));\r
409                                 y += tsi.Height + tsi.Margin.Bottom;\r
410                         }\r
411 \r
412                         this.Size = new Size (widest + this.Padding.Horizontal, y + this.Padding.Bottom);// + 2);\r
413                 }\r
414 \r
415                 protected override void OnMouseUp (MouseEventArgs mea)\r
416                 {\r
417                         base.OnMouseUp (mea);\r
418                 }\r
419 \r
420                 protected virtual void OnOpened (EventArgs e)\r
421                 {\r
422                         if (Opened != null) Opened (this, e);\r
423                 }\r
424 \r
425                 protected virtual void OnOpening (CancelEventArgs e)\r
426                 {\r
427                         if (Opening != null) Opening (this, e);\r
428                 }\r
429 \r
430                 protected override void OnParentChanged (EventArgs e)\r
431                 {\r
432                         base.OnParentChanged (e);\r
433                         \r
434                         if (parent is ToolStrip)\r
435                                 this.Renderer = (parent as ToolStrip).Renderer;\r
436                 }\r
437 \r
438                 protected override void OnVisibleChanged (EventArgs e)\r
439                 {\r
440                         base.OnVisibleChanged (e);\r
441                 }\r
442 \r
443                 protected override bool ProcessDialogChar (char charCode)\r
444                 {\r
445                         return base.ProcessDialogChar (charCode);\r
446                 }\r
447 \r
448                 protected override bool ProcessDialogKey (Keys keyData)\r
449                 {\r
450                         return base.ProcessDialogKey (keyData);\r
451                 }\r
452 \r
453                 protected override bool ProcessMnemonic (char charCode)\r
454                 {\r
455                         return base.ProcessMnemonic (charCode);\r
456                 }\r
457 \r
458                 protected override void ScaleCore (float dx, float dy)\r
459                 {\r
460                         base.ScaleCore (dx, dy);\r
461                 }\r
462 \r
463                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)\r
464                 {\r
465                         base.SetBoundsCore (x, y, width, height, specified);\r
466                 }\r
467 \r
468                 protected override void SetVisibleCore (bool value)\r
469                 {\r
470                         base.SetVisibleCore (value);\r
471                 }\r
472 \r
473                 protected override void WndProc (ref Message m)\r
474                 {\r
475                         const int MA_NOACTIVATE = 0x0003;\r
476 \r
477                         // Don't activate when the WM tells us to\r
478                         if ((Msg)m.Msg == Msg.WM_MOUSEACTIVATE) {\r
479                                 m.Result = (IntPtr)MA_NOACTIVATE;\r
480                                 return;\r
481                         }\r
482 \r
483                         base.WndProc (ref m);\r
484                 }\r
485                 #endregion\r
486 \r
487                 #region Public Events\r
488                 public event EventHandler BackgroundImageChanged;\r
489                 public event EventHandler BackgroundImageLayoutChanged;\r
490                 public event EventHandler BindingContextChanged;\r
491                 public event UICuesEventHandler ChangeUICues;\r
492                 public event ToolStripDropDownClosedEventHandler Closed;\r
493                 public event ToolStripDropDownClosingEventHandler Closing;\r
494                 [Browsable (false)]\r
495                 [EditorBrowsable (EditorBrowsableState.Never)]\r
496                 public event EventHandler ContextMenuChanged;\r
497                 [Browsable (false)]\r
498                 [EditorBrowsable (EditorBrowsableState.Never)]\r
499                 public event EventHandler ContextMenuStripChanged;\r
500                 [Browsable (false)]\r
501                 [EditorBrowsable (EditorBrowsableState.Never)]\r
502                 public event EventHandler DockChanged;\r
503                 public event EventHandler Enter;\r
504                 public event EventHandler FontChanged;\r
505                 public event EventHandler ForeColorChanged;\r
506                 [Browsable (false)]\r
507                 [EditorBrowsable (EditorBrowsableState.Never)]\r
508                 public event GiveFeedbackEventHandler GiveFeedback;\r
509                 public event HelpEventHandler HelpRequested;\r
510                 public event EventHandler ImeModeChanged;\r
511                 public event KeyEventHandler KeyDown;\r
512                 public event KeyPressEventHandler KeyPress;\r
513                 public event KeyEventHandler KeyUp;\r
514                 public event EventHandler Leave;\r
515                 public event EventHandler Opened;\r
516                 public event CancelEventHandler Opening;\r
517                 public event EventHandler RegionChanged;\r
518                 [Browsable (false)]\r
519                 [EditorBrowsable (EditorBrowsableState.Never)]\r
520                 public event ScrollEventHandler Scroll;\r
521                 public event EventHandler StyleChanged;\r
522                 [Browsable (false)]\r
523                 [EditorBrowsable (EditorBrowsableState.Never)]\r
524                 public event EventHandler TabIndexChanged;\r
525                 [Browsable (false)]\r
526                 [EditorBrowsable (EditorBrowsableState.Never)]\r
527                 public event EventHandler TabStopChanged;\r
528                 [Browsable (false)]\r
529                 [EditorBrowsable (EditorBrowsableState.Never)]\r
530                 public event EventHandler TextChanged;\r
531                 [Browsable (false)]\r
532                 [EditorBrowsable (EditorBrowsableState.Never)]\r
533                 public event EventHandler Validated;\r
534                 [Browsable (false)]\r
535                 [EditorBrowsable (EditorBrowsableState.Never)]\r
536                 public event CancelEventHandler Validating;\r
537                 #endregion\r
538 \r
539                 #region Private Methods\r
540                 private void ToolStripMenuTracker_AppFocusChange (object sender, EventArgs e)\r
541                 {\r
542                         this.Close (ToolStripDropDownCloseReason.AppFocusChange);\r
543                 }\r
544 \r
545                 private void ToolStripMenuTracker_AppClicked (object sender, EventArgs e)\r
546                 {\r
547                         this.Close (ToolStripDropDownCloseReason.AppClicked);\r
548                 }\r
549                 #endregion\r
550         }\r
551 }\r
552 #endif