mattercontrol/CustomWidgets/DropDownMenuWidget.cs
2014-01-29 19:09:30 -08:00

273 lines
8.7 KiB
C#

using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MatterHackers.VectorMath;
using MatterHackers.MatterControl;
using MatterHackers.Agg.VertexSource;
namespace MatterHackers.Agg.UI
{
public class DropDownMenu : Menu
{
public event EventHandler SelectionChanged;
TextWidget mainControlText;
public bool MenuAsWideAsItems { get; set; }
int borderWidth = 1;
public int BorderWidth
{
get { return borderWidth; }
set { borderWidth = value; }
}
RGBA_Bytes borderColor;
public RGBA_Bytes BorderColor
{
get { return borderColor; }
set { borderColor = value; }
}
RGBA_Bytes arrowColor;
public RGBA_Bytes ArrowColor
{
get { return arrowColor; }
set { arrowColor = value; }
}
RGBA_Bytes normalColor;
public RGBA_Bytes NormalColor
{
get { return normalColor; }
set { normalColor = value; }
}
RGBA_Bytes hoverColor;
public RGBA_Bytes HoverColor
{
get { return hoverColor; }
set { hoverColor = value; }
}
RGBA_Bytes textColor = RGBA_Bytes.Black;
public RGBA_Bytes TextColor
{
get { return textColor; }
set
{
textColor = value;
//mainControlText.TextColor = TextColor;
}
}
int selectedIndex = -1;
public int SelectedIndex
{
get { return selectedIndex; }
set
{
selectedIndex = value;
OnSelectionChanged(null);
Invalidate();
}
}
public String SelectedValue
{
get { return GetValue(SelectedIndex); }
}
public string GetValue(int itemIndex)
{
return MenuItems[SelectedIndex].Value;
}
public DropDownMenu(GuiWidget topMenuWidget, Direction direction = Direction.Down)
: base(direction)
{
}
public DropDownMenu(string topMenuText, Direction direction = Direction.Down, double pointSize = 12)
: base(direction)
{
MenuAsWideAsItems = true;
SetDisplayAttributes();
MenuItems.CollectionChanged += new NotifyCollectionChangedEventHandler(MenuItems_CollectionChanged);
mainControlText = new TextWidget(topMenuText, pointSize: pointSize);
mainControlText.TextColor = this.TextColor;
mainControlText.AutoExpandBoundsToText = true;
mainControlText.VAnchor = UI.VAnchor.ParentCenter;
mainControlText.HAnchor = UI.HAnchor.ParentLeft;
AddChild(mainControlText);
HAnchor = HAnchor.FitToChildren;
VAnchor = VAnchor.FitToChildren;
MouseEnter += new EventHandler(DropDownList_MouseEnter);
MouseLeave += new EventHandler(DropDownList_MouseLeave);
NormalColor = normalColor;
HoverColor = hoverColor;
BackgroundColor = normalColor;
BorderColor = normalColor;
//IE Don't show arrow unless color is set explicitly
ArrowColor = new RGBA_Bytes(255, 255, 255, 0);
}
void DropDownList_MouseLeave(object sender, EventArgs e)
{
if (!this.IsOpen)
{
BackgroundColor = NormalColor;
ArrowColor = new RGBA_Bytes(255, 255, 255, 0);
}
}
void DropDownList_MouseEnter(object sender, EventArgs e)
{
BackgroundColor = HoverColor;
ArrowColor = TextColor;
}
void OnSelectionChanged(EventArgs e)
{
if (SelectionChanged != null)
{
SelectionChanged(this, e);
}
}
void MenuItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Vector2 minSize = new Vector2(LocalBounds.Width, LocalBounds.Height);
string startText = mainControlText.Text;
foreach (MenuItem item in MenuItems)
{
mainControlText.Text = item.Text;
minSize.x = Math.Max(minSize.x, LocalBounds.Width);
minSize.y = Math.Max(minSize.y, LocalBounds.Height);
}
mainControlText.Text = startText;
if (MenuAsWideAsItems)
{
this.MinimumSize = minSize;
}
foreach (MenuItem item in e.NewItems)
{
item.MinimumSize = minSize;
// remove it if it is there so we don't have two. It is ok to remove a delagate that is not present.
item.Selected -= new EventHandler(item_Selected);
item.Selected += new EventHandler(item_Selected);
}
}
void item_Selected(object sender, EventArgs e)
{
int newSelectedIndex = 0;
foreach (MenuItem item in MenuItems)
{
if (item == sender)
{
break;
}
newSelectedIndex++;
}
SelectedIndex = newSelectedIndex;
BackgroundColor = NormalColor;
}
private void SetDisplayAttributes()
{
this.TextColor = RGBA_Bytes.White;
this.NormalColor = ActiveTheme.Instance.PrimaryBackgroundColor;
this.HoverColor = RGBA_Bytes.Gray;
this.MenuItemsBorderWidth = 1;
this.MenuItemsBackgroundColor = RGBA_Bytes.White;
this.MenuItemsBorderColor = RGBA_Bytes.Gray;
this.MenuItemsPadding = new BorderDouble(10, 10, 10, 10);
}
public override void OnDraw(Graphics2D graphics2D)
{
base.OnDraw(graphics2D);
this.DrawBorder(graphics2D);
this.DrawDirectionalArrow(graphics2D);
}
private void DrawDirectionalArrow(Graphics2D graphics2D)
{
PathStorage littleArrow = new PathStorage();
if (this.MenuDirection == Direction.Down)
{
littleArrow.MoveTo(-4, 0);
littleArrow.LineTo(4, 0);
littleArrow.LineTo(0, -5);
}
else if (this.MenuDirection == Direction.Up)
{
littleArrow.MoveTo(-4, -5);
littleArrow.LineTo(4, -5);
littleArrow.LineTo(0, 0);
}
else
{
throw new NotImplementedException("Pulldown direction has not been implemented");
}
graphics2D.Render(littleArrow, LocalBounds.Right - 10, LocalBounds.Bottom + Height - 4, arrowColor);
}
private void DrawBorder(Graphics2D graphics2D)
{
RectangleDouble Bounds = LocalBounds;
RoundedRect borderRect = new RoundedRect(this.LocalBounds, 0);
Stroke strokeRect = new Stroke(borderRect, borderWidth);
graphics2D.Render(strokeRect, borderColor);
}
public void AddItem(string name, string value = null, double pointSize = 12)
{
if (value == null)
{
value = name;
}
mainControlText.Margin = MenuItemsPadding;
GuiWidget normalTextWithMargin = new GuiWidget();
normalTextWithMargin.HAnchor = UI.HAnchor.ParentLeft;
normalTextWithMargin.BackgroundColor = MenuItemsBackgroundColor;
TextWidget normal = new TextWidget(name, pointSize: pointSize);
normal.Margin = MenuItemsPadding;
normal.TextColor = MenuItemsTextColor;
normalTextWithMargin.AddChild(normal);
normalTextWithMargin.HAnchor = HAnchor.FitToChildren;
normalTextWithMargin.VAnchor = VAnchor.FitToChildren;
GuiWidget hoverTextWithMargin = new GuiWidget();
hoverTextWithMargin.HAnchor = UI.HAnchor.ParentLeft;
hoverTextWithMargin.BackgroundColor = MenuItemsBackgroundHoverColor;
TextWidget hover = new TextWidget(name, pointSize: pointSize);
hover.Margin = MenuItemsPadding;
hover.TextColor = mainControlText.TextColor;
hoverTextWithMargin.AddChild(hover);
hoverTextWithMargin.HAnchor = HAnchor.FitToChildren;
hoverTextWithMargin.VAnchor = VAnchor.FitToChildren;
MenuItem menuItem = new MenuItem(new MenuItemStatesView(normalTextWithMargin, hoverTextWithMargin), value);
menuItem.Text = name;
MenuItems.Add(menuItem);
}
}
}