using System; using System.Drawing; using System.Linq; using Gwen.ControlInternal; namespace Gwen.Control { /// /// Popup menu. /// public class Menu : ScrollControl { private bool m_DisableIconMargin; private bool m_DeleteOnClose; internal override bool IsMenuComponent { get { return true; } } public bool IconMarginDisabled { get { return m_DisableIconMargin; } set { m_DisableIconMargin = value; } } /// /// Determines whether the menu should be disposed on close. /// public bool DeleteOnClose { get { return m_DeleteOnClose; } set { m_DeleteOnClose = value; } } /// /// Determines whether the menu should open on mouse hover. /// protected virtual bool ShouldHoverOpenMenu { get { return true; } } /// /// Initializes a new instance of the class. /// /// Parent control. public Menu(Base parent) : base(parent) { SetBounds(0, 0, 10, 10); Padding = Padding.Two; IconMarginDisabled = false; AutoHideBars = true; EnableScroll(false, true); DeleteOnClose = false; } /// /// Renders the control using specified skin. /// /// Skin to use. protected override void Render(Skin.Base skin) { skin.DrawMenu(this, IconMarginDisabled); } /// /// Renders under the actual control (shadows etc). /// /// Skin to use. protected override void RenderUnder(Skin.Base skin) { base.RenderUnder(skin); skin.DrawShadow(this); } /// /// Opens the menu. /// /// Unused. public void Open(Pos pos) { IsHidden = false; BringToFront(); Point mouse = Input.InputHandler.MousePosition; SetPosition(mouse.X, mouse.Y); } /// /// Lays out the control's interior according to alignment, padding, dock etc. /// /// Skin to use. protected override void Layout(Skin.Base skin) { int childrenHeight = Children.Sum(child => child != null ? child.Height : 0); if (Y + childrenHeight > GetCanvas().Height) childrenHeight = GetCanvas().Height - Y; SetSize(Width, childrenHeight); base.Layout(skin); } /// /// Adds a new menu item. /// /// Item text. /// Newly created control. public virtual MenuItem AddItem(String text) { return AddItem(text, String.Empty); } /// /// Adds a new menu item. /// /// Item text. /// Icon texture name. /// Accelerator for this item. /// Newly created control. public virtual MenuItem AddItem(String text, String iconName, String accelerator = "") { MenuItem item = new MenuItem(this); item.Padding = Padding.Four; item.SetText(text); item.SetImage(iconName); item.SetAccelerator(accelerator); OnAddItem(item); return item; } /// /// Add item handler. /// /// Item added. protected virtual void OnAddItem(MenuItem item) { item.TextPadding = new Padding(IconMarginDisabled ? 0 : 24, 0, 16, 0); item.Dock = Pos.Top; item.SizeToContents(); item.Alignment = Pos.CenterV | Pos.Left; item.HoverEnter += OnHoverItem; // Do this here - after Top Docking these values mean nothing in layout int w = item.Width + 10 + 32; if (w < Width) w = Width; SetSize(w, Height); } /// /// Closes all submenus. /// public virtual void CloseAll() { //System.Diagnostics.Debug.Print("Menu.CloseAll: {0}", this); Children.ForEach(child => { if (child is MenuItem) (child as MenuItem).CloseMenu(); }); } /// /// Indicates whether any (sub)menu is open. /// /// public virtual bool IsMenuOpen() { return Children.Any(child => { if (child is MenuItem) return (child as MenuItem).IsMenuOpen; return false; }); } /// /// Mouse hover handler. /// /// Event source. protected virtual void OnHoverItem(Base control) { if (!ShouldHoverOpenMenu) return; MenuItem item = control as MenuItem; if (null == item) return; if (item.IsMenuOpen) return; CloseAll(); item.OpenMenu(); } /// /// Closes the current menu. /// public virtual void Close() { //System.Diagnostics.Debug.Print("Menu.Close: {0}", this); IsHidden = true; if (DeleteOnClose) { DelayedDelete(); } } /// /// Closes all submenus and the current menu. /// public override void CloseMenus() { //System.Diagnostics.Debug.Print("Menu.CloseMenus: {0}", this); base.CloseMenus(); CloseAll(); Close(); } /// /// Adds a divider menu item. /// public virtual void AddDivider() { MenuDivider divider = new MenuDivider(this); divider.Dock = Pos.Top; divider.Margin = new Margin(IconMarginDisabled ? 0 : 24, 0, 4, 0); } } }