/* GWEN Copyright (c) 2010 Facepunch Studios See license in Gwen.h */ #include "Gwen/Gwen.h" #include "Gwen/Controls/Menu.h" #include "Gwen/Skin.h" #include "Gwen/Utility.h" using namespace Gwen; using namespace Gwen::Controls; GWEN_CONTROL_CONSTRUCTOR(Menu) { SetBounds(0, 0, 10, 10); SetPadding(Padding(2, 2, 2, 2)); SetDisableIconMargin(false); SetAutoHideBars(true); SetScroll(false, true); } void Menu::Render(Skin::Base* skin) { skin->DrawMenu(this, IconMarginDisabled()); } void Menu::RenderUnder(Skin::Base* skin) { BaseClass::RenderUnder(skin); skin->DrawShadow(this); } void Menu::Layout(Skin::Base* skin) { int childrenHeight = 0; for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it) { Base* pChild = (*it); if (!pChild) continue; childrenHeight += pChild->Height(); } if (Y() + childrenHeight > GetCanvas()->Height()) childrenHeight = GetCanvas()->Height() - Y(); SetSize(Width(), childrenHeight); BaseClass::Layout(skin); } MenuItem* Menu::AddItem(const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn) { MenuItem* pItem = new MenuItem(this); pItem->SetText(strName); pItem->SetImage(strIconName); if (fn && pHandler) { pItem->onMenuItemSelected.Add(pHandler, fn); } OnAddItem(pItem); return pItem; } void Menu::OnAddItem(MenuItem* item) { item->Dock(Pos::Top); item->SetTextPadding(Padding(IconMarginDisabled() ? 0 : 24, 0, 16, 0)); item->SetPadding(Padding(4, 4, 4, 4)); item->SizeToContents(); item->SetAlignment(Pos::CenterV | Pos::Left); item->onHoverEnter.Add(this, &Menu::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()); } void Menu::ClearItems() { for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it) { Base* pChild = *it; if (!pChild) continue; pChild->DelayedDelete(); } } MenuItem* Menu::AddItem(const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn) { return AddItem(Gwen::Utility::StringToUnicode(strName), Gwen::Utility::StringToUnicode(strIconName), pHandler, fn); } void Menu::CloseAll() { for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it) { Base* pChild = *it; MenuItem* pItem = pChild->DynamicCastMenuItem(); if (!pItem) continue; pItem->CloseMenu(); } } bool Menu::IsMenuOpen() { for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it) { Base* pChild = *it; MenuItem* pItem = pChild->DynamicCastMenuItem(); if (!pItem) continue; if (pItem->IsMenuOpen()) return true; } return false; } void Menu::OnHoverItem(Gwen::Controls::Base* pControl) { if (!ShouldHoverOpenMenu()) return; MenuItem* pItem = pControl->DynamicCastMenuItem(); if (!pItem) return; if (pItem->IsMenuOpen()) return; CloseAll(); pItem->OpenMenu(); } void Menu::Close() { SetHidden(true); } void Menu::CloseMenus() { BaseClass::CloseMenus(); CloseAll(); Close(); } void Menu::AddDivider() { MenuDivider* divider = new MenuDivider(this); divider->Dock(Pos::Top); divider->SetMargin(Margin(IconMarginDisabled() ? 0 : 24, 0, 4, 0)); } void MenuDivider::Render(Gwen::Skin::Base* skin) { skin->DrawMenuDivider(this); }