using System; //using System.Drawing; using Gwen.ControlInternal; namespace Gwen.Control { /// /// Menu item. /// public class MenuItem : Button { private bool m_OnStrip; private bool m_Checkable; private bool m_Checked; private Menu m_Menu; private Base m_SubmenuArrow; private Label m_Accelerator; /// /// Indicates whether the item is on a menu strip. /// public bool IsOnStrip { get { return m_OnStrip; } set { m_OnStrip = value; } } /// /// Determines if the menu item is checkable. /// public bool IsCheckable { get { return m_Checkable; } set { m_Checkable = value; } } /// /// Indicates if the parent menu is open. /// public bool IsMenuOpen { get { if (m_Menu == null) return false; return !m_Menu.IsHidden; } } /// /// Gets or sets the check value. /// public bool IsChecked { get { return m_Checked; } set { if (value == m_Checked) return; m_Checked = value; if (CheckChanged != null) CheckChanged.Invoke(this); if (value) { if (Checked != null) Checked.Invoke(this); } else { if (UnChecked != null) UnChecked.Invoke(this); } } } /// /// Gets the parent menu. /// public Menu Menu { get { if (null == m_Menu) { m_Menu = new Menu(GetCanvas()); m_Menu.IsHidden = true; if (!m_OnStrip) { if (m_SubmenuArrow != null) m_SubmenuArrow.Dispose(); m_SubmenuArrow = new RightArrow(this); m_SubmenuArrow.SetSize(15, 15); } Invalidate(); } return m_Menu; } } /// /// Invoked when the item is selected. /// public event GwenEventHandler Selected; /// /// Invoked when the item is checked. /// public event GwenEventHandler Checked; /// /// Invoked when the item is unchecked. /// public event GwenEventHandler UnChecked; /// /// Invoked when the item's check value is changed. /// public event GwenEventHandler CheckChanged; /// /// Initializes a new instance of the class. /// /// Parent control. public MenuItem(Base parent) : base(parent) { m_OnStrip = false; IsTabable = false; IsCheckable = false; IsChecked = false; m_Accelerator = new Label(this); } /// /// Renders the control using specified skin. /// /// Skin to use. protected override void Render(Skin.Base skin) { skin.DrawMenuItem(this, IsMenuOpen, m_Checkable ? m_Checked : false); } /// /// Lays out the control's interior according to alignment, padding, dock etc. /// /// Skin to use. protected override void Layout(Skin.Base skin) { if (m_SubmenuArrow != null) { m_SubmenuArrow.Position(Pos.Right | Pos.CenterV, 4, 0); } base.Layout(skin); } /// /// Internal OnPressed implementation. /// protected override void OnClicked() { if (m_Menu != null) { ToggleMenu(); } else if (!m_OnStrip) { IsChecked = !IsChecked; if (Selected != null) Selected.Invoke(this); GetCanvas().CloseMenus(); } base.OnClicked(); } /// /// Toggles the menu open state. /// public void ToggleMenu() { if (IsMenuOpen) CloseMenu(); else OpenMenu(); } /// /// Opens the menu. /// public void OpenMenu() { if (null == m_Menu) return; m_Menu.IsHidden = false; m_Menu.BringToFront(); Point p = LocalPosToCanvas(Point.Empty); // Strip menus open downwards if (m_OnStrip) { m_Menu.SetPosition(p.X, p.Y + Height + 1); } // Submenus open sidewards else { m_Menu.SetPosition(p.X + Width, p.Y); } // TODO: Option this. // TODO: Make sure on screen, open the other side of the // parent if it's better... } /// /// Closes the menu. /// public void CloseMenu() { if (null == m_Menu) return; m_Menu.Close(); m_Menu.CloseAll(); } public override void SizeToContents() { base.SizeToContents(); if (m_Accelerator != null) { m_Accelerator.SizeToContents(); Width = Width + m_Accelerator.Width; } } public MenuItem SetAction(GwenEventHandler handler) { if (m_Accelerator != null) { AddAccelerator(m_Accelerator.Text, handler); } Selected += handler; return this; } public void SetAccelerator(String acc) { if (m_Accelerator != null) { //m_Accelerator.DelayedDelete(); // to prevent double disposing m_Accelerator = null; } if (acc == string.Empty) return; m_Accelerator = new Label(this); m_Accelerator.Dock = Pos.Right; m_Accelerator.Alignment = Pos.Right | Pos.CenterV; m_Accelerator.Text = acc; m_Accelerator.Margin = new Margin(0, 0, 16, 0); // todo } } }