From 9f4f013a9eae7b2dade09a2e94279ce4bf67d2cc Mon Sep 17 00:00:00 2001 From: spartanj Date: Mon, 18 Apr 2011 19:45:13 -0300 Subject: [PATCH] Added cUISelectButton control. Added cUIWinMenu control ( window menu ). Some minor changes on the UI controls. --- src/ee.h | 2 + src/test/eetest.cpp | 48 ++++++- src/test/eetest.hpp | 1 + src/ui/cuicomplexcontrol.cpp | 8 +- src/ui/cuicomplexcontrol.hpp | 2 + src/ui/cuicontrol.cpp | 1 + src/ui/cuicontrol.hpp | 2 +- src/ui/cuicontrolanim.cpp | 4 + src/ui/cuicontrolanim.hpp | 2 + src/ui/cuigenericgrid.cpp | 1 - src/ui/cuilistbox.cpp | 1 - src/ui/cuilistboxitem.cpp | 2 +- src/ui/cuilistboxitem.hpp | 2 +- src/ui/cuimanager.cpp | 2 +- src/ui/cuimenu.cpp | 3 +- src/ui/cuimessage.hpp | 1 + src/ui/cuipopupmenu.cpp | 18 ++- src/ui/cuiselectbutton.cpp | 57 ++++++++ src/ui/cuiselectbutton.hpp | 25 ++++ src/ui/cuitheme.cpp | 2 + src/ui/cuiwindow.cpp | 10 +- src/ui/cuiwindow.hpp | 2 + src/ui/cuiwinmenu.cpp | 255 +++++++++++++++++++++++++++++++++++ src/ui/cuiwinmenu.hpp | 110 +++++++++++++++ src/ui/uihelper.hpp | 5 +- 25 files changed, 543 insertions(+), 23 deletions(-) create mode 100644 src/ui/cuiselectbutton.cpp create mode 100644 src/ui/cuiselectbutton.hpp create mode 100644 src/ui/cuiwinmenu.cpp create mode 100644 src/ui/cuiwinmenu.hpp diff --git a/src/ee.h b/src/ee.h index b6efaf5ff..2f207b262 100755 --- a/src/ee.h +++ b/src/ee.h @@ -192,6 +192,8 @@ #include "ui/cuigridcell.hpp" #include "ui/cuigenericgrid.hpp" #include "ui/cuiwindow.hpp" + #include "ui/cuiselectbutton.hpp" + #include "ui/cuiwinmenu.hpp" using namespace EE::UI; #include "physics/cphysicsmanager.hpp" diff --git a/src/test/eetest.cpp b/src/test/eetest.cpp index b89930e30..f6f35b092 100644 --- a/src/test/eetest.cpp +++ b/src/test/eetest.cpp @@ -430,7 +430,7 @@ void cEETest::CreateUI() { mComboBox->ListBox()->SetSelected( 0 ); cUIPopUpMenu::CreateParams MenuParams; - MenuParams. Parent( cUIManager::instance()->MainControl() ); + MenuParams.Parent( cUIManager::instance()->MainControl() ); MenuParams.Flags = UI_AUTO_SIZE | UI_AUTO_PADDING; MenuParams.Size = eeSize( 0, 200 ); MenuParams.MinWidth = 100; @@ -537,17 +537,57 @@ void cEETest::CreateUI() { C->Scale( 0 ); CreateDecoratedWindow(); + + CreateWinMenu(); + //mUIWindow->Show(); Log->Writef( "CreateUI time: %f", TE.ElapsedSinceStart() ); } +void cEETest::CreateWinMenu() { + cUIWinMenu::CreateParams WinMenuParams; + + WinMenuParams.Parent( mUIWindow->Container() ); + WinMenuParams.ButtonMargin = 8; + WinMenuParams.FontSelectedColor = eeColorA( 255, 255, 255, 255 ); + + cUIWinMenu * WinMenu = eeNew( cUIWinMenu, ( WinMenuParams ) ); + + cUIPopUpMenu::CreateParams MenuParams; + MenuParams.Parent( cUIManager::instance()->MainControl() ); + MenuParams.Flags = UI_AUTO_SIZE | UI_AUTO_PADDING; + MenuParams.Size = eeSize( 0, 200 ); + MenuParams.MinWidth = 100; + MenuParams.MinSpaceForIcons = 16; + MenuParams.PosSet( 0, 0 ); + MenuParams.FontSelectedColor = eeColorA( 255, 255, 255, 255 ); + MenuParams.MinRightMargin = 8; + + cUIPopUpMenu * PopMenu = eeNew( cUIPopUpMenu, ( MenuParams ) ); + PopMenu->Add( "File" ); + PopMenu->Add( "Open" ); + PopMenu->Add( "Close" ); + PopMenu->Add( "Quit" ); + + cUIPopUpMenu * PopMenu2 = eeNew( cUIPopUpMenu, ( MenuParams ) ); + PopMenu2->Add( "Bla" ); + PopMenu2->Add( "Bla 2" ); + PopMenu2->Add( "Bla 3" ); + PopMenu2->Add( "Bla 4" ); + + WinMenu->AddMenuButton( "File", PopMenu ); + WinMenu->AddMenuButton( "Edit", PopMenu2 ); + WinMenu->Enabled( true ); + WinMenu->Visible( true ); +} + void cEETest::CreateDecoratedWindow() { cUIWindow::CreateParams WinParams; WinParams.Flags = UI_HALIGN_CENTER; WinParams.WinFlags |= cUIWindow::UI_WIN_MAXIMIZE_BUTTON; WinParams.PosSet( 200, 50 ); - WinParams.Size = eeSize( 530, 380 ); + WinParams.Size = eeSize( 530, 400 ); WinParams.ButtonsPositionFixer.x = -4; WinParams.ButtonsPositionFixer.y = -2; WinParams.BaseAlpha = 200; @@ -562,7 +602,7 @@ void cEETest::CreateDecoratedWindow() { cUIPushButton::CreateParams ButtonParams; ButtonParams.Parent( mUIWindow->Container() ); ButtonParams.Flags = UI_VALIGN_CENTER | UI_HALIGN_CENTER | UI_ANCHOR_RIGHT; - ButtonParams.PosSet( 10, 10 ); + ButtonParams.PosSet( 10, 25 ); ButtonParams.Size = eeSize( 510, 22 ); cUIPushButton * Button = eeNew( cUIPushButton, ( ButtonParams ) ); @@ -572,7 +612,7 @@ void cEETest::CreateDecoratedWindow() { cUITextEdit::CreateParams TEParams; TEParams.Parent( mUIWindow->Container() ); - TEParams.PosSet( 10, 40 ); + TEParams.PosSet( 10, 55 ); TEParams.Size = eeSize( 510, 300 ); TEParams.Flags = UI_AUTO_PADDING | UI_CLIP_ENABLE | UI_ANCHOR_RIGHT | UI_ANCHOR_BOTTOM; cUITextEdit * TextEdit = eeNew( cUITextEdit, ( TEParams ) ); diff --git a/src/test/eetest.hpp b/src/test/eetest.hpp index db8072370..3cf40a62a 100644 --- a/src/test/eetest.hpp +++ b/src/test/eetest.hpp @@ -215,6 +215,7 @@ class cEETest : private cThread { void ButtonClick( const cUIEvent * Event ); void OnValueChange( const cUIEvent * Event ); void CreateDecoratedWindow(); + void CreateWinMenu(); void CreateAquaTextureAtlas(); cUIControlAnim * C; diff --git a/src/ui/cuicomplexcontrol.cpp b/src/ui/cuicomplexcontrol.cpp index 99dd572e7..8c46c8cde 100644 --- a/src/ui/cuicomplexcontrol.cpp +++ b/src/ui/cuicomplexcontrol.cpp @@ -10,7 +10,7 @@ cUIComplexControl::cUIComplexControl( const cUIComplexControl::CreateParams& Par { mType |= UI_TYPE_GET( UI_TYPE_CONTROL_COMPLEX ); - mDistToBorder = eeVector2i( mParentCtrl->Size().x - ( mPos.x + mSize.x ), mParentCtrl->Size().y - ( mPos.y + mSize.y ) ); + CalcDistToBorder(); TooltipText( Params.TooltipText ); } @@ -19,6 +19,10 @@ cUIComplexControl::~cUIComplexControl() { eeSAFE_DELETE( mTooltip ); } +void cUIComplexControl::CalcDistToBorder() { + mDistToBorder = eeVector2i( mParentCtrl->Size().x - ( mPos.x + mSize.x ), mParentCtrl->Size().y - ( mPos.y + mSize.y ) ); +} + void cUIComplexControl::Update() { if ( mVisible && NULL != mTooltip && mTooltip->Text().size() ) { if ( IsMouseOverMeOrChilds() ) { @@ -130,7 +134,7 @@ void cUIComplexControl::OnParentSizeChange() { } if ( mFlags & UI_ANCHOR_RIGHT ) { - newSize.x = mParentCtrl->Size().x - mPos.x - mDistToBorder.x; + newSize.x = mParentCtrl->Size().Width() - mPos.x - mDistToBorder.x; if ( newSize.x < mMinControlSize.Width() ) newSize.y = mMinControlSize.Width(); diff --git a/src/ui/cuicomplexcontrol.hpp b/src/ui/cuicomplexcontrol.hpp index 99a4bd5ba..b2a1e93b0 100644 --- a/src/ui/cuicomplexcontrol.hpp +++ b/src/ui/cuicomplexcontrol.hpp @@ -49,6 +49,8 @@ class EE_API cUIComplexControl : public cUIControlAnim { void CreateTooltip(); virtual void OnParentSizeChange(); + + void CalcDistToBorder(); }; }} diff --git a/src/ui/cuicontrol.cpp b/src/ui/cuicontrol.cpp index d087aed26..075c698fe 100644 --- a/src/ui/cuicontrol.cpp +++ b/src/ui/cuicontrol.cpp @@ -352,6 +352,7 @@ Uint32 cUIControl::OnFocusLoss() { } void cUIControl::OnComplexControlFocusLoss() { + SendCommonEvent( cUIEvent::EventOnComplexControlFocusLoss ); } bool cUIControl::HasFocus() const { diff --git a/src/ui/cuicontrol.hpp b/src/ui/cuicontrol.hpp index 8e35de969..937a1ca3a 100644 --- a/src/ui/cuicontrol.hpp +++ b/src/ui/cuicontrol.hpp @@ -122,7 +122,7 @@ class EE_API cUIControl { void Center(); - void Close(); + virtual void Close(); virtual void Draw(); diff --git a/src/ui/cuicontrolanim.cpp b/src/ui/cuicontrolanim.cpp index ffddae61f..c0727e726 100644 --- a/src/ui/cuicontrolanim.cpp +++ b/src/ui/cuicontrolanim.cpp @@ -131,6 +131,10 @@ void cUIControlAnim::Update() { } } +bool cUIControlAnim::FadingOut() { + return 0 != ( mControlFlags & UI_CTRL_FLAG_DISABLE_FADE_OUT ); +} + bool cUIControlAnim::Animating() { return ( NULL != mAlphaAnim && mAlphaAnim->Enabled() ) || ( NULL != mAngleAnim && mAngleAnim->Enabled() ) || ( NULL != mScaleAnim && mScaleAnim->Enabled() ) || ( NULL != mMoveAnim && mMoveAnim->Enabled() ); } diff --git a/src/ui/cuicontrolanim.hpp b/src/ui/cuicontrolanim.hpp index 04491c441..7ab8b2122 100644 --- a/src/ui/cuicontrolanim.hpp +++ b/src/ui/cuicontrolanim.hpp @@ -54,6 +54,8 @@ class EE_API cUIControlAnim : public cUIDragable { cWaypoints * MovementInterpolation(); virtual void Draw(); + + bool FadingOut(); protected: friend class cUIManager; diff --git a/src/ui/cuigenericgrid.cpp b/src/ui/cuigenericgrid.cpp index 8c6ae4574..e478a8294 100644 --- a/src/ui/cuigenericgrid.cpp +++ b/src/ui/cuigenericgrid.cpp @@ -520,7 +520,6 @@ Uint32 cUIGenericGrid::OnMessage( const cUIMessage * Msg ) { cUIControl * FocusCtrl = cUIManager::instance()->FocusControl(); if ( this != FocusCtrl && !IsParentOf( FocusCtrl ) ) { - SendCommonEvent( cUIEvent::EventOnComplexControlFocusLoss ); OnComplexControlFocusLoss(); } diff --git a/src/ui/cuilistbox.cpp b/src/ui/cuilistbox.cpp index 8468680ff..ae87bde2e 100644 --- a/src/ui/cuilistbox.cpp +++ b/src/ui/cuilistbox.cpp @@ -845,7 +845,6 @@ Uint32 cUIListBox::OnMessage( const cUIMessage * Msg ) { cUIControl * FocusCtrl = cUIManager::instance()->FocusControl(); if ( this != FocusCtrl && !IsParentOf( FocusCtrl ) ) { - SendCommonEvent( cUIEvent::EventOnComplexControlFocusLoss ); OnComplexControlFocusLoss(); } diff --git a/src/ui/cuilistboxitem.cpp b/src/ui/cuilistboxitem.cpp index 3900dd21c..b7ab55bb4 100644 --- a/src/ui/cuilistboxitem.cpp +++ b/src/ui/cuilistboxitem.cpp @@ -4,7 +4,7 @@ namespace EE { namespace UI { -cUIListBoxItem::cUIListBoxItem( cUITextBox::CreateParams& Params ) : +cUIListBoxItem::cUIListBoxItem( const cUITextBox::CreateParams& Params ) : cUITextBox( Params ) { ApplyDefaultTheme(); diff --git a/src/ui/cuilistboxitem.hpp b/src/ui/cuilistboxitem.hpp index 68759123d..00f0fe4eb 100644 --- a/src/ui/cuilistboxitem.hpp +++ b/src/ui/cuilistboxitem.hpp @@ -10,7 +10,7 @@ class cUIListBox; class EE_API cUIListBoxItem : public cUITextBox { public: - cUIListBoxItem( cUITextBox::CreateParams& Params ); + cUIListBoxItem( const cUITextBox::CreateParams& Params ); virtual ~cUIListBoxItem(); diff --git a/src/ui/cuimanager.cpp b/src/ui/cuimanager.cpp index 99969eac3..10e0638d9 100644 --- a/src/ui/cuimanager.cpp +++ b/src/ui/cuimanager.cpp @@ -31,7 +31,7 @@ void cUIManager::Init() { Shutdown(); mInit = true; - mControl = eeNew( cUIControlAnim, ( cUIControl::CreateParams( NULL, eeVector2i( 0, 0 ), eeSize( cEngine::instance()->GetWidth(), cEngine::instance()->GetHeight() ) ) ) ); + mControl = eeNew( cUIControlAnim, ( cUIControl::CreateParams( NULL, eeVector2i( 0, 0 ), eeSize( cEngine::instance()->GetWidth(), cEngine::instance()->GetHeight() ), UI_HALIGN_LEFT | UI_VALIGN_CENTER | UI_REPORT_SIZE_CHANGE_TO_CHILDS ) ) ); mControl->Visible( true ); mControl->Enabled( true ); diff --git a/src/ui/cuimenu.cpp b/src/ui/cuimenu.cpp index 2fdc40934..c63180f50 100644 --- a/src/ui/cuimenu.cpp +++ b/src/ui/cuimenu.cpp @@ -318,8 +318,7 @@ Uint32 cUIMenu::OnMessage( const cUIMessage * Msg ) { { cUIControl * FocusCtrl = cUIManager::instance()->FocusControl(); - if ( this != FocusCtrl && !IsParentOf( FocusCtrl ) && !IsSubMenu( FocusCtrl ) ) { - SendCommonEvent( cUIEvent::EventOnComplexControlFocusLoss ); + if ( this != FocusCtrl && !IsParentOf( FocusCtrl ) && !IsSubMenu( FocusCtrl ) ) { OnComplexControlFocusLoss(); } diff --git a/src/ui/cuimessage.hpp b/src/ui/cuimessage.hpp index 1c725b7fd..ae87093b3 100644 --- a/src/ui/cuimessage.hpp +++ b/src/ui/cuimessage.hpp @@ -21,6 +21,7 @@ class EE_API cUIMessage { MsgFocus, MsgFocusLoss, MsgCellClicked, + MsgSelected, MsgUser, MsgForceDWord = 0xFFFFFFFF }; diff --git a/src/ui/cuipopupmenu.cpp b/src/ui/cuipopupmenu.cpp index cc221076d..784ef6bb9 100644 --- a/src/ui/cuipopupmenu.cpp +++ b/src/ui/cuipopupmenu.cpp @@ -6,6 +6,8 @@ namespace EE { namespace UI { cUIPopUpMenu::cUIPopUpMenu( cUIPopUpMenu::CreateParams Params ) : cUIMenu( Params ) { + mType |= UI_TYPE_GET(UI_TYPE_POPUPMENU); + ApplyDefaultTheme(); } @@ -38,11 +40,13 @@ bool cUIPopUpMenu::Show() { bool cUIPopUpMenu::Hide() { if ( Visible() ) { - if ( cUIThemeManager::instance()->DefaultEffectsEnabled() ) { - DisableFadeOut( cUIThemeManager::instance()->ControlsFadeOutTime() ); - } else { - Enabled( false ); - Visible( false ); + if ( !FadingOut() ) { + if ( cUIThemeManager::instance()->DefaultEffectsEnabled() ) { + DisableFadeOut( cUIThemeManager::instance()->ControlsFadeOutTime() ); + } else { + Enabled( false ); + Visible( false ); + } } if ( NULL != mItemSelected ) @@ -59,6 +63,8 @@ bool cUIPopUpMenu::Hide() { void cUIPopUpMenu::OnComplexControlFocusLoss() { Hide(); + + cUIMenu::OnComplexControlFocusLoss(); } Uint32 cUIPopUpMenu::OnMessage( const cUIMessage * Msg ) { @@ -68,6 +74,8 @@ Uint32 cUIPopUpMenu::OnMessage( const cUIMessage * Msg ) { if ( !Msg->Sender()->IsType( UI_TYPE_MENUSUBMENU ) && ( Msg->Flags() & EE_BUTTONS_LRM ) ) { SendCommonEvent( cUIEvent::EventOnHideByClick ); + cUIManager::instance()->MainControl()->SetFocus(); + Hide(); } } diff --git a/src/ui/cuiselectbutton.cpp b/src/ui/cuiselectbutton.cpp new file mode 100644 index 000000000..8f96f02bd --- /dev/null +++ b/src/ui/cuiselectbutton.cpp @@ -0,0 +1,57 @@ +#include "cuiselectbutton.hpp" +#include "cuiwinmenu.hpp" + +namespace EE { namespace UI { + +cUISelectButton::cUISelectButton( const cUIPushButton::CreateParams& Params ) : + cUIPushButton( Params ) +{ + mType |= UI_TYPE_GET(UI_TYPE_SELECTBUTTON); +} + +cUISelectButton::~cUISelectButton() { +} + +void cUISelectButton::Select() { + bool wasSelected = Selected(); + + SetSkinState( cUISkinState::StateSelected ); + + mControlFlags |= UI_CTRL_FLAG_SELECTED; + + if ( !wasSelected ) { + cUIMessage tMsg( this, cUIMessage::MsgSelected, 0 ); + MessagePost( &tMsg ); + } +} + +void cUISelectButton::Unselect() { + if ( mControlFlags & UI_CTRL_FLAG_SELECTED ) + mControlFlags &= ~UI_CTRL_FLAG_SELECTED; + + SetSkinState( cUISkinState::StateNormal ); +} + +bool cUISelectButton::Selected() const { + return 0 != ( mControlFlags & UI_CTRL_FLAG_SELECTED ); +} + +void cUISelectButton::OnStateChange() { + if ( mSkinState->GetState() != cUISkinState::StateSelected && Selected() ) { + SetSkinState( cUISkinState::StateSelected ); + } + + if ( Parent()->Type() & UI_TYPE_WINMENU ) { + cUIWinMenu * Menu = reinterpret_cast ( Parent() ); + + if ( mSkinState->GetState() == cUISkinState::StateSelected ) { + TextBox()->Color( Menu->FontSelectedColor() ); + } else if ( mSkinState->GetState() == cUISkinState::StateMouseEnter ) { + TextBox()->Color( Menu->FontOverColor() ); + } else { + TextBox()->Color( Menu->FontColor() ); + } + } +} + +}} diff --git a/src/ui/cuiselectbutton.hpp b/src/ui/cuiselectbutton.hpp new file mode 100644 index 000000000..b0873b694 --- /dev/null +++ b/src/ui/cuiselectbutton.hpp @@ -0,0 +1,25 @@ +#ifndef EE_UICUISELECTBUTTON_HPP +#define EE_UICUISELECTBUTTON_HPP + +#include "cuipushbutton.hpp" + +namespace EE { namespace UI { + +class cUISelectButton : public cUIPushButton { + public: + cUISelectButton( const cUIPushButton::CreateParams& Params ); + + virtual ~cUISelectButton(); + + virtual bool Selected() const; + + virtual void Unselect(); + + virtual void Select(); + protected: + virtual void OnStateChange(); +}; + +}} + +#endif diff --git a/src/ui/cuitheme.cpp b/src/ui/cuitheme.cpp index 53f030d3b..a3ddac8f1 100644 --- a/src/ui/cuitheme.cpp +++ b/src/ui/cuitheme.cpp @@ -69,6 +69,8 @@ static void LoadThemeElements() { UI_THEME_ELEMENTS.push_back( "winmax" ); UI_THEME_ELEMENTS.push_back( "winmin" ); UI_THEME_ELEMENTS.push_back( "winshade" ); + UI_THEME_ELEMENTS.push_back( "winmenu" ); + UI_THEME_ELEMENTS.push_back( "winmenubutton" ); } } diff --git a/src/ui/cuiwindow.cpp b/src/ui/cuiwindow.cpp index 71dfa73c4..dfb58e3d3 100644 --- a/src/ui/cuiwindow.cpp +++ b/src/ui/cuiwindow.cpp @@ -108,12 +108,16 @@ void cUIWindow::ContainerPosChange( const cUIEvent * Event ) { } void cUIWindow::ButtonCloseClick( const cUIEvent * Event ) { + Close(); + + SendCommonEvent( cUIEvent::EventOnWindowCloseClick ); +} + +void cUIWindow::Close() { if ( 0 != cUIThemeManager::instance()->ControlsFadeOutTime() ) CloseFadeOut( cUIThemeManager::instance()->ControlsFadeOutTime() ); else - Close(); - - SendCommonEvent( cUIEvent::EventOnWindowCloseClick ); + cUIComplexControl::Close(); } void cUIWindow::ButtonMaximizeClick( const cUIEvent * Event ) { diff --git a/src/ui/cuiwindow.hpp b/src/ui/cuiwindow.hpp index c07dda11a..3ad2a2d82 100644 --- a/src/ui/cuiwindow.hpp +++ b/src/ui/cuiwindow.hpp @@ -73,6 +73,8 @@ class cUIWindow : public cUIComplexControl { virtual void Update(); + virtual void Close(); + void BaseAlpha( const Uint8& Alpha ); const Uint8& BaseAlpha() const; diff --git a/src/ui/cuiwinmenu.cpp b/src/ui/cuiwinmenu.cpp new file mode 100644 index 000000000..670a4e236 --- /dev/null +++ b/src/ui/cuiwinmenu.cpp @@ -0,0 +1,255 @@ +#include "cuiwinmenu.hpp" +#include "cuimanager.hpp" + +namespace EE { namespace UI { + +cUIWinMenu::cUIWinMenu( const cUIWinMenu::CreateParams& Params ) : + cUIComplexControl( Params ), + mFont( Params.Font ), + mFontColor( Params.FontColor ), + mFontShadowColor( Params.FontShadowColor ), + mFontOverColor( Params.FontOverColor ), + mFontSelectedColor( Params.FontSelectedColor ), + mCurrentMenu( NULL ), + mMarginBetweenButtons( Params.MarginBetweenButtons ), + mButtonMargin( Params.ButtonMargin ), + mFirstButtonMargin( Params.FirstButtonMargin ) +{ + mType |= UI_TYPE_GET(UI_TYPE_WINMENU); + + if ( !(mFlags & UI_ANCHOR_RIGHT) ) + mFlags |= UI_ANCHOR_RIGHT; + + Size( Parent()->Size().Width(), Params.MenuHeight ); + + CalcDistToBorder(); + + ApplyDefaultTheme(); +} + +cUIWinMenu::~cUIWinMenu() +{ +} + +void cUIWinMenu::AddMenuButton( const String& ButtonText, cUIPopUpMenu * Menu ) { + eeASSERT( NULL != Menu ); + + cUISelectButton::CreateParams ButtonParams; + ButtonParams.Parent( this ); + ButtonParams.Flags = UI_HALIGN_CENTER | UI_VALIGN_CENTER; + + if ( mFlags & UI_DRAW_SHADOW ) + ButtonParams.Flags |= UI_DRAW_SHADOW; + + ButtonParams.Font = mFont; + ButtonParams.FontColor = mFontColor; + ButtonParams.FontShadowColor = mFontShadowColor; + ButtonParams.FontOverColor = mFontOverColor; + + cUISelectButton * Button = eeNew( cUISelectButton, ( ButtonParams ) ); + Button->Text( ButtonText ); + Button->Visible( true ); + Button->Enabled( true ); + Button->ForceThemeSkin( mSkinState->GetSkin()->Theme(), "winmenubutton" ); + + Menu->Visible( false ); + Menu->Enabled( false ); + Menu->Parent( cUIManager::instance()->MainControl() ); + Menu->AddEventListener( cUIEvent::EventOnComplexControlFocusLoss, cb::Make1( this, &cUIWinMenu::OnMenuFocusLoss ) ); + + mButtons.push_back( std::make_pair( Button, Menu ) ); + + RefreshButtons(); +} + +void cUIWinMenu::SetTheme( cUITheme * Theme ) { + cUIComplexControl::SetTheme( Theme, "winmenu" ); + + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + it->first->ForceThemeSkin( Theme, "winmenubutton" ); + } +} + +void cUIWinMenu::RemoveMenuButton( const String& ButtonText ) { + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + if ( it->first->Text() == ButtonText ) { + mButtons.erase( it ); + break; + } + } + + RefreshButtons(); +} + +cUISelectButton * cUIWinMenu::GetButton( const String& ButtonText ) { + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + if ( it->first->Text() == ButtonText ) { + return it->first; + } + } + + return NULL; +} + +cUIPopUpMenu * cUIWinMenu::GetPopUpMenu( const String& ButtonText ) { + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + if ( it->first->Text() == ButtonText ) { + return it->second; + } + } + + return NULL; +} + +void cUIWinMenu::RefreshButtons() { + Uint32 xpos = mFirstButtonMargin; + + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + cUISelectButton * pbut = it->first; + cUITextBox * tbox = pbut->TextBox(); + + pbut->Size( tbox->GetTextWidth() + mButtonMargin, Size().Height() ); + pbut->Pos( xpos, 0 ); + + xpos += pbut->Size().Width() + mMarginBetweenButtons; + } +} + +Uint32 cUIWinMenu::OnMessage( const cUIMessage * Msg ) { + switch ( Msg->Msg() ) { + case cUIMessage::MsgMouseUp: + case cUIMessage::MsgMouseEnter: + { + if ( Msg->Sender()->IsType( UI_TYPE_SELECTBUTTON ) ) { + cUISelectButton * tbut = reinterpret_cast ( Msg->Sender() ); + cUIPopUpMenu * tpop = GetMenuFromButton( tbut ); + + eeVector2i pos( tbut->Pos().x, tbut->Size().Height() ); + tbut->ControlToScreen( pos ); + tpop->Pos( pos ); + + if ( NULL != mCurrentMenu && tpop != mCurrentMenu ) { + mCurrentMenu->Hide(); + } + + if ( Msg->Msg() == cUIMessage::MsgMouseEnter ) { + if ( NULL != mCurrentMenu ) { + mCurrentMenu = tpop; + + tbut->Select(); + tpop->Show(); + } + } else { + mCurrentMenu = tpop; + + tbut->Select(); + tpop->Show(); + } + + return 1; + } + + break; + } + case cUIMessage::MsgSelected: + { + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + if ( it->first != Msg->Sender() ) { + it->first->Unselect(); + } + } + + return 1; + } + case cUIMessage::MsgFocusLoss: + { + cUIControl * FocusCtrl = cUIManager::instance()->FocusControl(); + + if ( !IsParentOf( FocusCtrl ) && !IsPopUpMenuChild( FocusCtrl ) ) { + OnComplexControlFocusLoss(); + } + + return 1; + } + } + + return 0; +} + +void cUIWinMenu::UnselectButtons() { + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + it->first->Unselect(); + } +} + +cUIPopUpMenu * cUIWinMenu::GetMenuFromButton( cUISelectButton * Button ) { + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + if ( it->first == Button ) { + return it->second; + } + } + + return NULL; +} + +bool cUIWinMenu::IsPopUpMenuChild( cUIControl * Ctrl ) { + for ( WinMenuList::iterator it = mButtons.begin(); it != mButtons.end(); it++ ) { + if ( it->second == Ctrl || it->second->IsParentOf( Ctrl ) ) { + return true; + } + } + + return false; +} + +void cUIWinMenu::OnMenuFocusLoss( const cUIEvent * Event ) { + cUIControl * FocusCtrl = cUIManager::instance()->FocusControl(); + + if ( !IsParentOf( FocusCtrl ) && !IsPopUpMenuChild( FocusCtrl ) ) { + OnComplexControlFocusLoss(); + } +} + +void cUIWinMenu::OnComplexControlFocusLoss() { + cUIComplexControl::OnComplexControlFocusLoss(); + + if ( NULL != mCurrentMenu ) { + mCurrentMenu->Hide(); + + mCurrentMenu = NULL; + } + + UnselectButtons(); +} + + +void cUIWinMenu::FontColor( const eeColorA& Color ) { + mFontColor = Color; +} + +const eeColorA& cUIWinMenu::FontColor() const { + return mFontColor; +} + +void cUIWinMenu::FontOverColor( const eeColorA& Color ) { + mFontOverColor = Color; +} + +const eeColorA& cUIWinMenu::FontOverColor() const { + return mFontOverColor; +} + +void cUIWinMenu::FontSelectedColor( const eeColorA& Color ) { + mFontSelectedColor = Color; +} + +const eeColorA& cUIWinMenu::FontSelectedColor() const { + return mFontSelectedColor; +} + +cFont * cUIWinMenu::Font() const { + return mFont; +} + + +}} diff --git a/src/ui/cuiwinmenu.hpp b/src/ui/cuiwinmenu.hpp new file mode 100644 index 000000000..dcb067425 --- /dev/null +++ b/src/ui/cuiwinmenu.hpp @@ -0,0 +1,110 @@ +#ifndef EE_UICUIWINMENU_HPP +#define EE_UICUIWINMENU_HPP + +#include "base.hpp" +#include "cuicomplexcontrol.hpp" +#include "cuiselectbutton.hpp" +#include "cuipopupmenu.hpp" + +namespace EE { namespace UI { + +class EE_API cUIWinMenu : public cUIComplexControl { + public: + class CreateParams : public cUIComplexControl::CreateParams { + public: + inline CreateParams() : + cUIComplexControl::CreateParams(), + Font( NULL ), + FontColor( 0, 0, 0, 255 ), + FontShadowColor( 0, 0, 0, 255 ), + FontOverColor( 0, 0, 0, 255 ), + FontSelectedColor( 0, 0, 0, 255 ), + MarginBetweenButtons(0), + ButtonMargin(4), + MenuHeight(22), + FirstButtonMargin(1) + { + cUITheme * Theme = cUIThemeManager::instance()->DefaultTheme(); + + if ( NULL != Theme ) { + Font = Theme->Font(); + FontColor = Theme->FontColor(); + FontShadowColor = Theme->FontShadowColor(); + FontOverColor = Theme->FontOverColor(); + FontSelectedColor = FontOverColor; + } + + if ( NULL == Font ) + Font = cUIThemeManager::instance()->DefaultFont(); + } + + cFont * Font; + eeColorA FontColor; + eeColorA FontShadowColor; + eeColorA FontOverColor; + eeColorA FontSelectedColor; + Uint32 MarginBetweenButtons; + Uint32 ButtonMargin; + Uint32 MenuHeight; + Uint32 FirstButtonMargin; + }; + + cUIWinMenu( const cUIWinMenu::CreateParams& Params ); + + virtual ~cUIWinMenu(); + + void AddMenuButton( const String& ButtonText, cUIPopUpMenu * Menu ); + + void RemoveMenuButton( const String& ButtonText ); + + virtual void SetTheme( cUITheme * Theme ); + + void FontColor( const eeColorA& Color ); + + const eeColorA& FontColor() const; + + void FontOverColor( const eeColorA& Color ); + + const eeColorA& FontOverColor() const; + + void FontSelectedColor( const eeColorA& Color ); + + const eeColorA& FontSelectedColor() const; + + cFont * Font() const; + + cUISelectButton * GetButton( const String& ButtonText ); + + cUIPopUpMenu * GetPopUpMenu( const String& ButtonText ); + protected: + typedef std::list< std::pair< cUISelectButton *, cUIPopUpMenu * > > WinMenuList; + + cFont * mFont; + eeColorA mFontColor; + eeColorA mFontShadowColor; + eeColorA mFontOverColor; + eeColorA mFontSelectedColor; + cUIPopUpMenu * mCurrentMenu; + Uint32 mMarginBetweenButtons; + Uint32 mButtonMargin; + Uint32 mFirstButtonMargin; + WinMenuList mButtons; + + void RefreshButtons(); + + virtual Uint32 OnMessage( const cUIMessage * Msg ); + + virtual void OnComplexControlFocusLoss(); + + cUIPopUpMenu * GetMenuFromButton( cUISelectButton * Button ); + + bool IsPopUpMenuChild( cUIControl * Ctrl ); + + void OnMenuFocusLoss( const cUIEvent * Event ); + + void UnselectButtons(); +}; + +}} + +#endif diff --git a/src/ui/uihelper.hpp b/src/ui/uihelper.hpp index 2a8265269..408bc613e 100644 --- a/src/ui/uihelper.hpp +++ b/src/ui/uihelper.hpp @@ -92,7 +92,10 @@ enum UI_CONTROL_TYPES { UI_TYPE_TEXTEDIT = 22, UI_TYPE_TOOLTIP = 23, UI_TYPE_GENERICGRID = 24, - UI_TYPE_WINDOW = 25 + UI_TYPE_WINDOW = 25, + UI_TYPE_WINMENU = 26, + UI_TYPE_SELECTBUTTON = 27, + UI_TYPE_POPUPMENU = 28 }; #define UI_TYPE_GET(X) ( 1 << (X) )