This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
gwen-dotnet/Gwen/Control/Menu.cs
Gered 10e057953e initial commit
Contains changes from "gwen-dotnet" removing dependancies on Windows,
which ultimately means certain features (e.g. file load/save dialogs)
do not work. Those classes still exist, but the code has been commented
out.
2013-03-28 18:47:01 -04:00

210 lines
6.4 KiB
C#

using System;
using System.Drawing;
using System.Linq;
using Gwen.ControlInternal;
namespace Gwen.Control
{
/// <summary>
/// Popup menu.
/// </summary>
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; } }
/// <summary>
/// Determines whether the menu should be disposed on close.
/// </summary>
public bool DeleteOnClose { get { return m_DeleteOnClose; } set { m_DeleteOnClose = value; } }
/// <summary>
/// Determines whether the menu should open on mouse hover.
/// </summary>
protected virtual bool ShouldHoverOpenMenu { get { return true; } }
/// <summary>
/// Initializes a new instance of the <see cref="Menu"/> class.
/// </summary>
/// <param name="parent">Parent control.</param>
public Menu(Base parent)
: base(parent)
{
SetBounds(0, 0, 10, 10);
Padding = Padding.Two;
IconMarginDisabled = false;
AutoHideBars = true;
EnableScroll(false, true);
DeleteOnClose = false;
}
/// <summary>
/// Renders the control using specified skin.
/// </summary>
/// <param name="skin">Skin to use.</param>
protected override void Render(Skin.Base skin)
{
skin.DrawMenu(this, IconMarginDisabled);
}
/// <summary>
/// Renders under the actual control (shadows etc).
/// </summary>
/// <param name="skin">Skin to use.</param>
protected override void RenderUnder(Skin.Base skin)
{
base.RenderUnder(skin);
skin.DrawShadow(this);
}
/// <summary>
/// Opens the menu.
/// </summary>
/// <param name="pos">Unused.</param>
public void Open(Pos pos)
{
IsHidden = false;
BringToFront();
Point mouse = Input.InputHandler.MousePosition;
SetPosition(mouse.X, mouse.Y);
}
/// <summary>
/// Lays out the control's interior according to alignment, padding, dock etc.
/// </summary>
/// <param name="skin">Skin to use.</param>
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);
}
/// <summary>
/// Adds a new menu item.
/// </summary>
/// <param name="text">Item text.</param>
/// <returns>Newly created control.</returns>
public virtual MenuItem AddItem(String text)
{
return AddItem(text, String.Empty);
}
/// <summary>
/// Adds a new menu item.
/// </summary>
/// <param name="text">Item text.</param>
/// <param name="iconName">Icon texture name.</param>
/// <param name="accelerator">Accelerator for this item.</param>
/// <returns>Newly created control.</returns>
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;
}
/// <summary>
/// Add item handler.
/// </summary>
/// <param name="item">Item added.</param>
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);
}
/// <summary>
/// Closes all submenus.
/// </summary>
public virtual void CloseAll()
{
//System.Diagnostics.Debug.Print("Menu.CloseAll: {0}", this);
Children.ForEach(child => { if (child is MenuItem) (child as MenuItem).CloseMenu(); });
}
/// <summary>
/// Indicates whether any (sub)menu is open.
/// </summary>
/// <returns></returns>
public virtual bool IsMenuOpen()
{
return Children.Any(child => { if (child is MenuItem) return (child as MenuItem).IsMenuOpen; return false; });
}
/// <summary>
/// Mouse hover handler.
/// </summary>
/// <param name="control">Event source.</param>
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();
}
/// <summary>
/// Closes the current menu.
/// </summary>
public virtual void Close()
{
//System.Diagnostics.Debug.Print("Menu.Close: {0}", this);
IsHidden = true;
if (DeleteOnClose)
{
DelayedDelete();
}
}
/// <summary>
/// Closes all submenus and the current menu.
/// </summary>
public override void CloseMenus()
{
//System.Diagnostics.Debug.Print("Menu.CloseMenus: {0}", this);
base.CloseMenus();
CloseAll();
Close();
}
/// <summary>
/// Adds a divider menu item.
/// </summary>
public virtual void AddDivider()
{
MenuDivider divider = new MenuDivider(this);
divider.Dock = Pos.Top;
divider.Margin = new Margin(IconMarginDisabled ? 0 : 24, 0, 4, 0);
}
}
}