178 lines
3.4 KiB
C++
178 lines
3.4 KiB
C++
|
/*
|
||
|
GWEN
|
||
|
Copyright (c) 2010 Facepunch Studios
|
||
|
See license in Gwen.h
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include "../gwen.h"
|
||
|
#include "gwen_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 );
|
||
|
SetDeleteOnClose( false );
|
||
|
}
|
||
|
|
||
|
|
||
|
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 TextObject& strName, const TextObject& strIconName, const TextObject& strAccelerator )
|
||
|
{
|
||
|
MenuItem* pItem = new MenuItem( this );
|
||
|
|
||
|
pItem->SetPadding( Padding( 2, 4, 4, 4 ) );
|
||
|
pItem->SetText( strName );
|
||
|
pItem->SetImage( strIconName );
|
||
|
pItem->SetAccelerator( strAccelerator );
|
||
|
|
||
|
OnAddItem( pItem );
|
||
|
|
||
|
return pItem;
|
||
|
}
|
||
|
|
||
|
void Menu::OnAddItem( MenuItem* item )
|
||
|
{
|
||
|
item->SetTextPadding( Padding( IconMarginDisabled() ? 0 : 24, 0, 16, 0 ) );
|
||
|
item->Dock( Pos::Top );
|
||
|
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();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Menu::CloseAll()
|
||
|
{
|
||
|
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
|
||
|
{
|
||
|
Base* pChild = *it;
|
||
|
MenuItem* pItem = gwen_cast<MenuItem>(pChild);
|
||
|
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 = gwen_cast<MenuItem>(pChild);
|
||
|
if ( !pItem ) continue;
|
||
|
|
||
|
if ( pItem->IsMenuOpen() )
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void Menu::OnHoverItem( Gwen::Controls::Base* pControl )
|
||
|
{
|
||
|
if ( !ShouldHoverOpenMenu() ) return;
|
||
|
|
||
|
MenuItem* pItem = gwen_cast<MenuItem>(pControl);
|
||
|
if (!pItem) return;
|
||
|
if ( pItem->IsMenuOpen() ) return;
|
||
|
|
||
|
CloseAll();
|
||
|
pItem->OpenMenu();
|
||
|
}
|
||
|
|
||
|
void Menu::Open( unsigned int iPos )
|
||
|
{
|
||
|
SetHidden( false );
|
||
|
BringToFront();
|
||
|
|
||
|
Gwen::Point MousePos = Input::GetMousePosition();
|
||
|
SetPos( MousePos.x, MousePos.y );
|
||
|
}
|
||
|
|
||
|
void Menu::Close()
|
||
|
{
|
||
|
SetHidden( true );
|
||
|
|
||
|
if ( DeleteOnClose() )
|
||
|
{
|
||
|
DelayedDelete();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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 );
|
||
|
}
|