2015-04-16 16:55:32 +00:00
|
|
|
/*
|
|
|
|
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;
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
GWEN_CONTROL_CONSTRUCTOR(Menu)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
SetBounds(0, 0, 10, 10);
|
|
|
|
SetPadding(Padding(2, 2, 2, 2));
|
2015-04-16 16:55:32 +00:00
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
SetDisableIconMargin(false);
|
2015-04-16 16:55:32 +00:00
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
SetAutoHideBars(true);
|
|
|
|
SetScroll(false, true);
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
void Menu::Render(Skin::Base* skin)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
skin->DrawMenu(this, IconMarginDisabled());
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
void Menu::RenderUnder(Skin::Base* skin)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
BaseClass::RenderUnder(skin);
|
|
|
|
skin->DrawShadow(this);
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
void Menu::Layout(Skin::Base* skin)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
|
|
|
int childrenHeight = 0;
|
2018-09-23 21:17:31 +00:00
|
|
|
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
|
|
|
Base* pChild = (*it);
|
2018-09-23 21:17:31 +00:00
|
|
|
if (!pChild)
|
2015-04-16 16:55:32 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
childrenHeight += pChild->Height();
|
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
if (Y() + childrenHeight > GetCanvas()->Height())
|
2015-04-16 16:55:32 +00:00
|
|
|
childrenHeight = GetCanvas()->Height() - Y();
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
SetSize(Width(), childrenHeight);
|
2015-04-16 16:55:32 +00:00
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
BaseClass::Layout(skin);
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
MenuItem* Menu::AddItem(const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
MenuItem* pItem = new MenuItem(this);
|
|
|
|
pItem->SetText(strName);
|
|
|
|
pItem->SetImage(strIconName);
|
2015-04-16 16:55:32 +00:00
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
if (fn && pHandler)
|
|
|
|
{
|
|
|
|
pItem->onMenuItemSelected.Add(pHandler, fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
OnAddItem(pItem);
|
2015-04-16 16:55:32 +00:00
|
|
|
|
|
|
|
return pItem;
|
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
void Menu::OnAddItem(MenuItem* item)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
item->Dock(Pos::Top);
|
|
|
|
item->SetTextPadding(Padding(IconMarginDisabled() ? 0 : 24, 0, 16, 0));
|
|
|
|
item->SetPadding(Padding(4, 4, 4, 4));
|
2015-04-16 16:55:32 +00:00
|
|
|
item->SizeToContents();
|
2018-09-23 21:17:31 +00:00
|
|
|
item->SetAlignment(Pos::CenterV | Pos::Left);
|
|
|
|
item->onHoverEnter.Add(this, &Menu::OnHoverItem);
|
2015-04-16 16:55:32 +00:00
|
|
|
|
|
|
|
// Do this here - after Top Docking these values mean nothing in layout
|
|
|
|
int w = item->Width() + 10 + 32;
|
2018-09-23 21:17:31 +00:00
|
|
|
if (w < Width()) w = Width();
|
|
|
|
SetSize(w, Height());
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::ClearItems()
|
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
|
|
|
Base* pChild = *it;
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
if (!pChild) continue;
|
2015-04-16 16:55:32 +00:00
|
|
|
pChild->DelayedDelete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
MenuItem* Menu::AddItem(const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
return AddItem(Gwen::Utility::StringToUnicode(strName), Gwen::Utility::StringToUnicode(strIconName), pHandler, fn);
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::CloseAll()
|
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
|
|
|
Base* pChild = *it;
|
|
|
|
MenuItem* pItem = pChild->DynamicCastMenuItem();
|
2018-09-23 21:17:31 +00:00
|
|
|
if (!pItem) continue;
|
2015-04-16 16:55:32 +00:00
|
|
|
|
|
|
|
pItem->CloseMenu();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Menu::IsMenuOpen()
|
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
|
|
|
Base* pChild = *it;
|
|
|
|
MenuItem* pItem = pChild->DynamicCastMenuItem();
|
2018-09-23 21:17:31 +00:00
|
|
|
if (!pItem) continue;
|
2015-04-16 16:55:32 +00:00
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
if (pItem->IsMenuOpen())
|
2015-04-16 16:55:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
void Menu::OnHoverItem(Gwen::Controls::Base* pControl)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
if (!ShouldHoverOpenMenu()) return;
|
2015-04-16 16:55:32 +00:00
|
|
|
|
|
|
|
MenuItem* pItem = pControl->DynamicCastMenuItem();
|
|
|
|
if (!pItem) return;
|
2018-09-23 21:17:31 +00:00
|
|
|
if (pItem->IsMenuOpen()) return;
|
2015-04-16 16:55:32 +00:00
|
|
|
|
|
|
|
CloseAll();
|
|
|
|
pItem->OpenMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::Close()
|
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
SetHidden(true);
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::CloseMenus()
|
|
|
|
{
|
|
|
|
BaseClass::CloseMenus();
|
|
|
|
|
|
|
|
CloseAll();
|
|
|
|
Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::AddDivider()
|
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
MenuDivider* divider = new MenuDivider(this);
|
|
|
|
divider->Dock(Pos::Top);
|
|
|
|
divider->SetMargin(Margin(IconMarginDisabled() ? 0 : 24, 0, 4, 0));
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|
|
|
|
|
2018-09-23 21:17:31 +00:00
|
|
|
void MenuDivider::Render(Gwen::Skin::Base* skin)
|
2015-04-16 16:55:32 +00:00
|
|
|
{
|
2018-09-23 21:17:31 +00:00
|
|
|
skin->DrawMenuDivider(this);
|
2015-04-16 16:55:32 +00:00
|
|
|
}
|