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);
}
}
}