private int index;
private bool mdilist;
private Hashtable mdilist_items;
+ private Hashtable mdilist_forms;
private MdiClient mdicontainer;
+ private bool is_window_menu_item;
private bool defaut_item;
private bool visible;
private bool ownerdraw;
private int xtab;
private int menuheight;
private bool menubar;
- private DrawItemState status;
private MenuMerge mergetype;
internal Rectangle bounds;
showshortcut = true;
visible = true;
ownerdraw = false;
- status = DrawItemState.None;
menubar = false;
menuheight = 0;
xtab = 0;
}
#region Events
- public event EventHandler Click;
- public event DrawItemEventHandler DrawItem;
- public event MeasureItemEventHandler MeasureItem;
- public event EventHandler Popup;
- public event EventHandler Select;
+ static object ClickEvent = new object ();
+ static object DrawItemEvent = new object ();
+ static object MeasureItemEvent = new object ();
+ static object PopupEvent = new object ();
+ static object SelectEvent = new object ();
+
+ public event EventHandler Click {
+ add { Events.AddHandler (ClickEvent, value); }
+ remove { Events.RemoveHandler (ClickEvent, value); }
+ }
+
+ public event DrawItemEventHandler DrawItem {
+ add { Events.AddHandler (DrawItemEvent, value); }
+ remove { Events.RemoveHandler (DrawItemEvent, value); }
+ }
+
+ public event MeasureItemEventHandler MeasureItem {
+ add { Events.AddHandler (MeasureItemEvent, value); }
+ remove { Events.RemoveHandler (MeasureItemEvent, value); }
+ }
+
+ public event EventHandler Popup {
+ add { Events.AddHandler (PopupEvent, value); }
+ remove { Events.RemoveHandler (PopupEvent, value); }
+ }
+
+ public event EventHandler Select {
+ add { Events.AddHandler (SelectEvent, value); }
+ remove { Events.RemoveHandler (SelectEvent, value); }
+ }
#endregion // Events
#region Public Properties
[Localizable(true)]
public bool Enabled {
get { return enabled; }
- set { enabled = value; }
+ set {
+ if (enabled == value)
+ return;
+
+ enabled = value;
+ Invalidate ();
+ }
}
[Browsable(false)]
MenuItems.Remove (item);
mdilist_items.Clear ();
mdilist_items = null;
-
}
}
separator = false;
ProcessMnemonic ();
+ Invalidate ();
}
}
internal bool MeasureEventDefined {
get {
- if (ownerdraw == true && MeasureItem != null) {
+ if (ownerdraw == true && Events [MeasureItemEvent] != null) {
return true;
} else {
return false;
set { menuheight = value; }
}
+ bool selected;
+ internal bool Selected {
+ get { return selected; }
+ set { selected = value; }
+ }
+
internal bool Separator {
get { return separator; }
set { separator = value; }
}
internal DrawItemState Status {
- get { return status; }
- set { status = value; }
+ get {
+ DrawItemState status = DrawItemState.None;
+ MenuTracker tracker = Parent.Tracker;
+ if (Selected)
+ status |= (tracker.active || tracker.Navigating ? DrawItemState.Selected : DrawItemState.HotLight);
+ if (!Enabled)
+ status |= DrawItemState.Grayed | DrawItemState.Disabled;
+ if (Checked)
+ status |= DrawItemState.Checked;
+ if (!tracker.Navigating)
+ status |= DrawItemState.NoAccelerator;
+ return status;
+ }
}
+ internal bool VisibleItems {
+ get {
+ if (menu_items != null) {
+ foreach (MenuItem mi in menu_items)
+ if (mi.Visible)
+ return true;
+ }
+ return false;
+ }
+ }
+
internal new int Width {
get { return bounds.Width; }
set { bounds.Width = value; }
{
base.CloneMenu (menuitem); // Copy subitems
+ // Window list
+ MdiList = menuitem.MdiList;
+ is_window_menu_item = menuitem.is_window_menu_item;
+ // Remove items corresponding to window menu items, and add new items
+ // (Otherwise window menu items would show up twice, since the PopulateWindowMenu doesn't
+ // now them)
+ bool populated = false;
+ for (int i = MenuItems.Count - 1; i >= 0; i--) {
+ if (MenuItems [i].is_window_menu_item) {
+ MenuItems.RemoveAt (i);
+ populated = true;
+ }
+ }
+ if (populated)
+ PopulateWindowMenu ();
+
// Properties
BarBreak = menuitem.BarBreak;
Break = menuitem.Break;
Visible = menuitem.Visible;
// Events
- Click = menuitem.Click;
- DrawItem = menuitem.DrawItem;
- MeasureItem = menuitem.MeasureItem;
- Popup = menuitem.Popup;
- Select = menuitem.Select;
+ Events[ClickEvent] = menuitem.Events[ClickEvent];
+ Events[DrawItemEvent] = menuitem.Events[DrawItemEvent];
+ Events[MeasureItemEvent] = menuitem.Events[MeasureItemEvent];
+ Events[PopupEvent] = menuitem.Events[PopupEvent];
+ Events[SelectEvent] = menuitem.Events[SelectEvent];
}
protected override void Dispose (bool disposing)
protected virtual void OnClick (EventArgs e)
{
- if (Click != null)
- Click (this, e);
+ EventHandler eh = (EventHandler)(Events [ClickEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnDrawItem (DrawItemEventArgs e)
{
- if (DrawItem != null) {
- DrawItem (this, e);
+ if (OwnerDraw) {
+ DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
+ if (eh != null)
+ eh (this, e);
return;
}
-
+
ThemeEngine.Current.DrawMenuItem (this, e);
}
protected virtual void OnMeasureItem (MeasureItemEventArgs e)
{
- if (MeasureItem != null)
- MeasureItem (this, e);
+ if (!OwnerDraw)
+ return;
+
+ MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnPopup (EventArgs e)
{
- if (Popup != null)
- Popup (this, e);
+ EventHandler eh = (EventHandler)(Events [PopupEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnSelect (EventArgs e)
{
- if (Select != null)
- Select (this, e);
+ EventHandler eh = (EventHandler)(Events [SelectEvent]);
+ if (eh != null)
+ eh (this, e);
}
public void PerformClick ()
#region Private Methods
+ internal virtual void Invalidate ()
+ {
+ if ((Parent != null) && (Parent is MainMenu) && Parent.Wnd != null)
+ XplatUI.RequestNCRecalc (Parent.Wnd.FindForm ().Handle);
+ }
+
internal void PerformPopup ()
{
OnPopup (EventArgs.Empty);
internal void PerformDrawItem (DrawItemEventArgs e)
{
- if (mdilist && mdilist_items == null) {
- do {
- // Add the mdilist for the first time
+ PopulateWindowMenu ();
+ OnDrawItem (e);
+ }
+
+ private void PopulateWindowMenu ()
+ {
+ if (mdilist) {
+ if (mdilist_items == null) {
mdilist_items = new Hashtable ();
-
+ mdilist_forms = new Hashtable ();
+ }
+
+ do {
MainMenu main = GetMainMenu ();
if (main == null || main.GetForm () == null)
break;
if (mdicontainer == null)
break;
- foreach (Form mdichild in mdicontainer.Controls) {
- MenuItem item = new MenuItem (mdichild.Text);
- item.Click += new EventHandler (MdiWindowClickHandler);
- MenuItems.Add (item);
- mdilist_items.Add (item, form);
+
+ // Remove closed forms
+ MenuItem[] items = new MenuItem[mdilist_items.Count];
+ mdilist_items.Keys.CopyTo (items, 0);
+ foreach (MenuItem item in items) {
+ Form mdichild = (Form) mdilist_items [item];
+ if (!mdicontainer.mdi_child_list.Contains(mdichild)) {
+ mdilist_items.Remove (item);
+ mdilist_forms.Remove (mdichild);
+ MenuItems.Remove (item);
+ }
+ }
+
+ // Add new forms and update state for existing forms.
+ for (int i = 0; i < mdicontainer.mdi_child_list.Count; i++) {
+ Form mdichild = (Form)mdicontainer.mdi_child_list[i];
+ MenuItem item;
+ if (mdilist_forms.Contains (mdichild)) {
+ item = (MenuItem) mdilist_forms [mdichild];
+ } else {
+ item = new MenuItem ();
+ item.is_window_menu_item = true;
+ item.Click += new EventHandler (MdiWindowClickHandler);
+ mdilist_items [item] = mdichild;
+ mdilist_forms [mdichild] = item;
+ MenuItems.AddNoEvents (item);
+ }
+ item.Visible = mdichild.Visible;
+ item.Text = "&" + (i + 1).ToString () + " " + mdichild.Text;
+ item.Checked = form.ActiveMdiChild == mdichild;
}
-
} while (false);
+ } else {
+ // Remove all forms
+ if (mdilist_items != null) {
+ foreach (MenuItem item in mdilist_items.Values) {
+ MenuItems.Remove (item);
+ }
+
+ mdilist_forms.Clear ();
+ mdilist_items.Clear ();
+ }
}
-
- OnDrawItem (e);
}
internal void PerformMeasureItem (MeasureItemEventArgs e)
private void ProcessMnemonic ()
{
- if (text.Length < 2) {
+ if (text == null || text.Length < 2) {
mnemonic = '\0';
return;
}
private void MdiWindowClickHandler (object sender, EventArgs e)
{
- Form mdichild = (Form) mdilist_items [SelectedItem];
+ Form mdichild = (Form) mdilist_items [sender];
// people could add weird items to the Window menu
// so we can't assume its just us