1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2005 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
29 using System.Collections;
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
33 using System.Drawing.Text;
35 namespace System.Windows.Forms
37 [DefaultProperty("Text")]
38 [DefaultEvent("Click")]
39 [DesignTimeVisible(false)]
41 public class MenuItem : Menu
43 internal bool separator;
45 internal bool bar_break;
46 private Shortcut shortcut;
48 private bool checked_;
49 private bool radiocheck;
51 private char mnemonic;
52 private bool showshortcut;
55 private bool defaut_item;
57 private bool ownerdraw;
59 private int mergeorder;
61 private int menuheight;
63 private DrawItemState status;
64 private MenuMerge mergetype;
66 public MenuItem (): base (null)
68 CommonConstructor (string.Empty);
69 shortcut = Shortcut.None;
72 public MenuItem (string text) : base (null)
74 CommonConstructor (text);
75 shortcut = Shortcut.None;
78 public MenuItem (string text, EventHandler onClick) : base (null)
80 CommonConstructor (text);
81 shortcut = Shortcut.None;
85 public MenuItem (string text, MenuItem[] items) : base (items)
87 CommonConstructor (text);
88 shortcut = Shortcut.None;
91 public MenuItem (string text, EventHandler onClick, Shortcut shortcut) : base (null)
93 CommonConstructor (text);
95 this.shortcut = shortcut;
98 public MenuItem (MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string text,
99 EventHandler onClick, EventHandler onPopup, EventHandler onSelect, MenuItem[] items)
102 CommonConstructor (text);
103 this.shortcut = shortcut;
104 mergeorder = mergeOrder;
105 mergetype = mergeType;
112 private void CommonConstructor (string text)
124 status = DrawItemState.None;
132 mergetype = MenuMerge.Add;
133 Text = text; // Text can change separator status
137 public event EventHandler Click;
138 public event DrawItemEventHandler DrawItem;
139 public event MeasureItemEventHandler MeasureItem;
140 public event EventHandler Popup;
141 public event EventHandler Select;
144 #region Public Properties
147 [DefaultValue(false)]
148 public bool BarBreak {
149 get { return break_; }
150 set { break_ = value; }
154 [DefaultValue(false)]
156 get { return bar_break; }
157 set { bar_break = value; }
160 [DefaultValue(false)]
161 public bool Checked {
162 get { return checked_; }
163 set { checked_ = value; }
166 [DefaultValue(false)]
167 public bool DefaultItem {
168 get { return defaut_item; }
169 set { defaut_item = value; }
174 public bool Enabled {
175 get { return enabled; }
176 set { enabled = value; }
181 get { return index; }
183 if (Parent != null && Parent.MenuItems != null && (value < 0 || value >= Parent.MenuItems.Count))
184 throw new ArgumentException ("'" + value + "' is not a valid value for 'value'");
190 public override bool IsParent {
191 get { return IsPopup; }
194 [DefaultValue(false)]
195 public bool MdiList {
196 get { return mdilist; }
197 set { mdilist = value; }
200 protected int MenuID {
201 get { return menuid; }
205 public int MergeOrder {
206 get { return mergeorder; }
207 set { mergeorder = value; }
210 [DefaultValue(MenuMerge.Add)]
211 public MenuMerge MergeType {
212 get { return mergetype; }
214 if (!Enum.IsDefined (typeof (MenuMerge), value))
215 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for MenuMerge", value));
222 public char Mnemonic {
223 get { return mnemonic; }
226 [DefaultValue(false)]
227 public bool OwnerDraw {
228 get { return ownerdraw; }
229 set { ownerdraw = value; }
234 get { return parent_menu;}
237 [DefaultValue(false)]
238 public bool RadioCheck {
239 get { return radiocheck; }
240 set { radiocheck = value; }
243 [DefaultValue(Shortcut.None)]
245 public Shortcut Shortcut {
246 get { return shortcut;}
248 if (!Enum.IsDefined (typeof (Shortcut), value))
249 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Shortcut", value));
257 public bool ShowShortcut {
258 get { return showshortcut;}
259 set { showshortcut = value; }
279 public bool Visible {
280 get { return visible;}
282 if (value == visible)
287 if (menu_items != null) {
288 foreach (MenuItem mi in menu_items)
292 if (parent_menu != null) {
293 parent_menu.IsDirty = true;
294 parent_menu.creating = false;
299 #endregion Public Properties
301 #region Private Properties
303 internal bool IsPopup {
305 if (menu_items.Count > 0)
312 internal bool MeasureEventDefined {
314 if (ownerdraw == true && MeasureItem != null) {
322 internal bool MenuBar {
323 get { return menubar; }
324 set { menubar = value; }
327 internal int MenuHeight {
328 get { return menuheight; }
329 set { menuheight = value; }
332 internal bool Separator {
333 get { return separator; }
334 set { separator = value; }
337 internal DrawItemState Status {
338 get { return status; }
339 set { status = value; }
344 set { xtab = value; }
347 #endregion Private Properties
349 #region Public Methods
351 public virtual MenuItem CloneMenu ()
353 MenuItem item = new MenuItem ();
354 item.CloneMenu (this);
358 protected void CloneMenu (MenuItem menuitem)
360 base.CloneMenu (menuitem); // Copy subitems
363 BarBreak = menuitem.BarBreak;
364 Break = menuitem.Break;
365 Checked = menuitem.Checked;
366 DefaultItem = menuitem.DefaultItem;
367 Enabled = menuitem.Enabled;
368 MergeOrder = menuitem.MergeOrder;
369 MergeType = menuitem.MergeType;
370 OwnerDraw = menuitem.OwnerDraw;
371 //Parent = menuitem.Parent;
372 RadioCheck = menuitem.RadioCheck;
373 Shortcut = menuitem.Shortcut;
374 ShowShortcut = menuitem.ShowShortcut;
375 Text = menuitem.Text;
376 Visible = menuitem.Visible;
379 Click = menuitem.Click;
380 DrawItem = menuitem.DrawItem;
381 MeasureItem = menuitem.MeasureItem;
382 Popup = menuitem.Popup;
383 Select = menuitem.Select;
386 protected override void Dispose (bool disposing)
388 base.Dispose (disposing);
391 // This really clones the item
392 public virtual MenuItem MergeMenu ()
394 MenuItem item = new MenuItem ();
395 item.CloneMenu (this);
399 public void MergeMenu (MenuItem menuitem)
401 base.MergeMenu (menuitem);
404 protected virtual void OnClick (EventArgs e)
410 protected virtual void OnDrawItem (DrawItemEventArgs e)
412 if (DrawItem != null) {
417 ThemeEngine.Current.DrawMenuItem (this, e);
421 protected virtual void OnInitMenuPopup (EventArgs e)
426 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
428 if (MeasureItem != null)
429 MeasureItem (this, e);
432 protected virtual void OnPopup (EventArgs e)
438 protected virtual void OnSelect (EventArgs e)
444 public void PerformClick ()
446 OnClick (EventArgs.Empty);
449 public virtual void PerformSelect ()
451 OnSelect (EventArgs.Empty);
454 public override string ToString ()
456 return base.ToString () + ", Items.Count: " + MenuItems.Count + ", Text: " + text;
459 #endregion Public Methods
461 #region Private Methods
463 internal void Create ()
465 IntPtr hSubMenu = IntPtr.Zero;
467 menuid = index = MenuAPI.InsertMenuItem (Parent.Handle, -1, true, this, ref hSubMenu);
471 menu_handle = hSubMenu;
476 internal void PerformDrawItem (DrawItemEventArgs e)
481 internal void PerformMeasureItem (MeasureItemEventArgs e)
486 private void ProcessMnemonic ()
488 if (text.Length < 2) {
493 bool bPrevAmp = false;
494 for (int i = 0; i < text.Length -1 ; i++) {
495 if (text[i] == '&') {
496 if (bPrevAmp == false && (text[i+1] != '&')) {
497 mnemonic = Char.ToUpper (text[i+1]);
510 private string GetShortCutTextCtrl () { return "Ctrl"; }
511 private string GetShortCutTextAlt () { return "Alt"; }
512 private string GetShortCutTextShift () { return "Shift"; }
514 internal string GetShortCutText ()
516 /* Ctrl+A - Ctrl+Z */
517 if (Shortcut >= Shortcut.CtrlA && Shortcut <= Shortcut.CtrlZ)
518 return GetShortCutTextCtrl () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlA));
521 if (Shortcut >= Shortcut.Alt0 && Shortcut <= Shortcut.Alt9)
522 return GetShortCutTextAlt () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Alt0));
524 /* Alt+F1 - Alt+F2 */
525 if (Shortcut >= Shortcut.AltF1 && Shortcut <= Shortcut.AltF9)
526 return GetShortCutTextAlt () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.AltF1));
528 /* Ctrl+0 - Ctrl+9 */
529 if (Shortcut >= Shortcut.Ctrl0 && Shortcut <= Shortcut.Ctrl9)
530 return GetShortCutTextCtrl () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Ctrl0));
532 /* Ctrl+F0 - Ctrl+F9 */
533 if (Shortcut >= Shortcut.CtrlF1 && Shortcut <= Shortcut.CtrlF9)
534 return GetShortCutTextCtrl () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlF1));
536 /* Ctrl+Shift+0 - Ctrl+Shift+9 */
537 if (Shortcut >= Shortcut.CtrlShift0 && Shortcut <= Shortcut.CtrlShift9)
538 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.CtrlShift0));
540 /* Ctrl+Shift+A - Ctrl+Shift+Z */
541 if (Shortcut >= Shortcut.CtrlShiftA && Shortcut <= Shortcut.CtrlShiftZ)
542 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlShiftA));
544 /* Ctrl+Shift+F1 - Ctrl+Shift+F9 */
545 if (Shortcut >= Shortcut.CtrlShiftF1 && Shortcut <= Shortcut.CtrlShiftF9)
546 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlShiftF1));
549 if (Shortcut >= Shortcut.F1 && Shortcut <= Shortcut.F9)
550 return "F" + (char)((int) '1' + (int)(Shortcut - Shortcut.F1));
552 /* Shift+F1 - Shift+F9 */
553 if (Shortcut >= Shortcut.ShiftF1 && Shortcut <= Shortcut.ShiftF9)
554 return GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.ShiftF1));
558 case Shortcut.AltBksp:
560 case Shortcut.AltF10:
561 return GetShortCutTextAlt () + "+F10";
562 case Shortcut.AltF11:
563 return GetShortCutTextAlt () + "+F11";
564 case Shortcut.AltF12:
565 return GetShortCutTextAlt () + "+F12";
566 case Shortcut.CtrlDel:
567 return GetShortCutTextCtrl () + "+Del";
568 case Shortcut.CtrlF10:
569 return GetShortCutTextCtrl () + "+F10";
570 case Shortcut.CtrlF11:
571 return GetShortCutTextCtrl () + "+F11";
572 case Shortcut.CtrlF12:
573 return GetShortCutTextCtrl () + "+F12";
574 case Shortcut.CtrlIns:
575 return GetShortCutTextCtrl () + "+Ins";
576 case Shortcut.CtrlShiftF10:
577 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F10";
578 case Shortcut.CtrlShiftF11:
579 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F11";
580 case Shortcut.CtrlShiftF12:
581 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F12";
594 case Shortcut.ShiftDel:
595 return GetShortCutTextShift () + "+Del";
596 case Shortcut.ShiftF10:
597 return GetShortCutTextShift () + "+F10";
598 case Shortcut.ShiftF11:
599 return GetShortCutTextShift () + "+F11";
600 case Shortcut.ShiftF12:
601 return GetShortCutTextShift () + "+F12";
602 case Shortcut.ShiftIns:
603 return GetShortCutTextShift () + "+Ins";
611 #endregion Private Methods