bullet3/btgui/Gwen/Controls/Menu.cpp
2013-03-12 23:52:31 -07:00

172 lines
3.6 KiB
C++

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