diff --git a/src/test/ee.cpp b/src/test/ee.cpp index 5439c7635..b6afd7886 100644 --- a/src/test/ee.cpp +++ b/src/test/ee.cpp @@ -656,13 +656,13 @@ void cEETest::CreateUI() { Menu2->AddSubMenu( L"Hello World", NULL, Menu3 ); Menu->AddSeparator(); - Menu->AddSubMenu( L"Teh Menuh", NULL, Menu2 ) ; + Menu->AddSubMenu( L"Sub-Menu", NULL, Menu2 ) ; Menu->AddSeparator(); Menu->Add( L"Quit" ); Menu->AddEventListener( cUIEvent::EventOnItemClicked, cb::Make1( this, &cEETest::ItemClick ) ); - Menu->GetItem( L"Quit" )->AddEventListener( cUIEvent::EventMouseClick, cb::Make1( this, &cEETest::QuitClick ) ); + Menu->GetItem( L"Quit" )->AddEventListener( cUIEvent::EventMouseUp, cb::Make1( this, &cEETest::QuitClick ) ); cUIManager::instance()->MainControl()->AddEventListener( cUIEvent::EventMouseClick, cb::Make1( this, &cEETest::MainClick ) ); cUITextEdit::CreateParams TEParams; @@ -721,11 +721,16 @@ void cEETest::CreateUI() { C->StartRotation( 0, 360, 500.f, SINEOUT ); cUIWindow::CreateParams WinParams; + WinParams.Flags = UI_HALIGN_CENTER; WinParams.PosSet( 200, 50 ); WinParams.Size = eeSize( 530, 380 ); WinParams.ButtonsPositionFixer.x = -4; WinParams.ButtonsPositionFixer.y = -2; + WinParams.BaseAlpha = 240; + //WinParams.BorderAutoSize = false; + //WinParams.BorderSize = eeSize( 8, 8 ); cUIWindow * mWindow = eeNew( cUIWindow, ( WinParams ) ); + mWindow->Title( L"Test Window" ); mWindow->ToBack(); mWindow->Show(); } diff --git a/src/ui/cuimanager.cpp b/src/ui/cuimanager.cpp index 6f2de8442..49f82a3e3 100644 --- a/src/ui/cuimanager.cpp +++ b/src/ui/cuimanager.cpp @@ -135,6 +135,7 @@ void cUIManager::Update() { FocusControl( mOverControl ); mOverControl->OnMouseDown( mKM->GetMousePos(), mKM->PressTrigger() ); + SendMsg( mOverControl, cUIMessage::MsgMouseDown, mKM->PressTrigger() ); } if ( !mFirstPress ) { @@ -206,4 +207,8 @@ cInput * cUIManager::GetInput() const { return mKM; } +const Uint32& cUIManager::PressTrigger() const { + return mKM->PressTrigger(); +} + }} diff --git a/src/ui/cuimanager.hpp b/src/ui/cuimanager.hpp index 999b69753..cbd371c2c 100644 --- a/src/ui/cuimanager.hpp +++ b/src/ui/cuimanager.hpp @@ -41,6 +41,8 @@ class EE_API cUIManager : public tSingleton { eeVector2i GetMousePos(); cInput * GetInput() const; + + const Uint32& PressTrigger() const; protected: cEngine * mEE; cInput * mKM; diff --git a/src/ui/cuimessage.hpp b/src/ui/cuimessage.hpp index 7e70db93b..1c725b7fd 100644 --- a/src/ui/cuimessage.hpp +++ b/src/ui/cuimessage.hpp @@ -15,6 +15,7 @@ class EE_API cUIMessage { MsgDoubleClick, MsgMouseEnter, MsgMouseExit, + MsgMouseDown, MsgMouseUp, MsgWindowResize, MsgFocus, diff --git a/src/ui/cuiwindow.cpp b/src/ui/cuiwindow.cpp index 7445dd369..3a47d1017 100644 --- a/src/ui/cuiwindow.cpp +++ b/src/ui/cuiwindow.cpp @@ -9,11 +9,15 @@ cUIWindow::cUIWindow( const cUIWindow::CreateParams& Params ) : mButtonClose( NULL ), mButtonMinimize( NULL ), mButtonMaximize( NULL ), + mTitle( NULL ), mDecoSize( Params.DecorationSize ), mBorderSize( Params.BorderSize ), mMinWindowSize( Params.MinWindowSize ), mButtonsPositionFixer( Params.ButtonsPositionFixer ), mButtonsSeparation( Params.ButtonsSeparation ), + mMinCornerDistance( Params.MinCornerDistance ), + mTitleFontColor( Params.TitleFontColor ), + mBaseAlpha( Params.BaseAlpha ), mDecoAutoSize( Params.DecorationAutoSize ), mBorderAutoSize( Params.BorderAutoSize ) { @@ -79,6 +83,8 @@ cUIWindow::cUIWindow( const cUIWindow::CreateParams& Params ) : } } + Alpha( mBaseAlpha ); + DragEnable( true ); ApplyDefaultTheme(); @@ -145,11 +151,40 @@ void cUIWindow::SetTheme( cUITheme *Theme ) { } FixChildsSize(); + GetMinWinSize(); +} + +void cUIWindow::GetMinWinSize() { + eeSize tSize; + + tSize.x = mBorderLeft->Size().Width() + mBorderRight->Size().Width() - mButtonsPositionFixer.x; + tSize.y = mWindowDecoration->Size().Height() + mBorderBottom->Size().Height(); + + if ( NULL != mButtonClose ) + tSize.x += mButtonClose->Size().Width(); + + if ( NULL != mButtonMaximize ) + tSize.x += mButtonMaximize->Size().Width(); + + if ( NULL != mButtonMinimize ) + tSize.x += mButtonMinimize->Size().Width(); + + if ( mMinWindowSize.x < tSize.x ) + mMinWindowSize.x = tSize.x; + + if ( mMinWindowSize.y < tSize.y ) + mMinWindowSize.y = tSize.y; } void cUIWindow::OnSizeChange() { - if ( ( 0 != mMinWindowSize.x && 0 != mMinWindowSize.y ) && ( mSize.x < mMinWindowSize.x || mSize.y < mMinWindowSize.y ) ) { - Size( mMinWindowSize ); + if ( mSize.x < mMinWindowSize.x || mSize.y < mMinWindowSize.y ) { + if ( mSize.x < mMinWindowSize.x && mSize.y < mMinWindowSize.y ) { + Size( mMinWindowSize ); + } else if ( mSize.x < mMinWindowSize.x ) { + Size( eeSize( mMinWindowSize.x, mSize.y ) ); + } else { + Size( eeSize( mSize.x, mMinWindowSize.y ) ); + } } else { FixChildsSize(); @@ -227,6 +262,8 @@ void cUIWindow::FixChildsSize() { } } } + + FixTitleSize(); } Uint32 cUIWindow::OnMessage( const cUIMessage * Msg ) { @@ -236,11 +273,235 @@ Uint32 cUIWindow::OnMessage( const cUIMessage * Msg ) { ToFront(); break; } + case cUIMessage::MsgMouseDown: + { + DoResize( Msg ); + break; + } } return cUIComplexControl::OnMessage( Msg ); } + +void cUIWindow::DoResize ( const cUIMessage * Msg ) { + if ( !( mWinFlags & UI_WIN_RESIZEABLE ) || !( Msg->Flags() & EE_BUTTON_LMASK ) || RESIZE_NONE != mResizeType ) + return; + + DecideResizeType( Msg->Sender() ); +} + +void cUIWindow::DecideResizeType( cUIControl * Control ) { + eeVector2i Pos = cUIManager::instance()->GetMousePos(); + + ScreenToControl( Pos ); + + if ( Control == this ) { + if ( Pos.x <= mBorderLeft->Size().Width() ) { + TryResize( RESIZE_TOPLEFT ); + } else if ( Pos.x >= ( mSize.Width() - mBorderRight->Size().Width() ) ) { + TryResize( RESIZE_TOPRIGHT ); + } else if ( Pos.y <= mBorderBottom->Size().Height() ) { + if ( Pos.x < mMinCornerDistance ) { + TryResize( RESIZE_TOPLEFT ); + } else if ( Pos.x > mSize.Width() - mMinCornerDistance ) { + TryResize( RESIZE_TOPRIGHT ); + } else { + TryResize( RESIZE_TOP ); + } + } + } else if ( Control == mBorderBottom ) { + if ( Pos.x < mMinCornerDistance ) { + TryResize( RESIZE_LEFTBOTTOM ); + } else if ( Pos.x > mSize.Width() - mMinCornerDistance ) { + TryResize( RESIZE_RIGHTBOTTOM ); + } else { + TryResize( RESIZE_BOTTOM ); + } + } else if ( Control == mBorderLeft ) { + if ( Pos.y >= mSize.Height() - mMinCornerDistance ) { + TryResize( RESIZE_LEFTBOTTOM ); + } else { + TryResize( RESIZE_LEFT ); + } + } else if ( Control == mBorderRight ) { + if ( Pos.y >= mSize.Height() - mMinCornerDistance ) { + TryResize( RESIZE_RIGHTBOTTOM ); + } else { + TryResize( RESIZE_RIGHT ); + } + } +} + +void cUIWindow::TryResize( const UI_RESIZE_TYPE& Type ) { + if ( RESIZE_NONE != mResizeType ) + return; + + DragEnable( false ); + + eeVector2i Pos = cUIManager::instance()->GetMousePos(); + + ScreenToControl( Pos ); + + mResizeType = Type; + + switch ( mResizeType ) + { + case RESIZE_RIGHT: + { + mResizePos.x = mSize.Width() - Pos.x; + break; + } + case RESIZE_LEFT: + { + mResizePos.x = Pos.x; + break; + } + case RESIZE_TOP: + { + mResizePos.y = Pos.y; + break; + } + case RESIZE_BOTTOM: + { + mResizePos.y = mSize.Height() - Pos.y; + break; + } + case RESIZE_RIGHTBOTTOM: + { + mResizePos.x = mSize.Width() - Pos.x; + mResizePos.y = mSize.Height() - Pos.y; + break; + } + case RESIZE_LEFTBOTTOM: + { + mResizePos.x = Pos.x; + mResizePos.y = mSize.Height() - Pos.y; + break; + } + case RESIZE_TOPLEFT: + { + mResizePos.x = Pos.x; + mResizePos.y = Pos.y; + break; + } + case RESIZE_TOPRIGHT: + { + mResizePos.y = Pos.y; + mResizePos.x = mSize.Width() - Pos.x; + break; + } + case RESIZE_NONE: + { + } + } +} + +void cUIWindow::EndResize() { + mResizeType = RESIZE_NONE; +} + +void cUIWindow::UpdateResize() { + if ( RESIZE_NONE == mResizeType ) + return; + + if ( !( cUIManager::instance()->PressTrigger() & EE_BUTTON_LMASK ) ) { + EndResize(); + DragEnable( true ); + return; + } + + eeVector2i Pos = cUIManager::instance()->GetMousePos(); + + ScreenToControl( Pos ); + + switch ( mResizeType ) { + case RESIZE_RIGHT: + { + InternalSize( Pos.x + mResizePos.x, mSize.Height() ); + break; + } + case RESIZE_BOTTOM: + { + InternalSize( mSize.Width(), Pos.y + mResizePos.y ); + break; + } + case RESIZE_LEFT: + { + Pos.x -= mResizePos.x; + cUIControl::Pos( mPos.x + Pos.x, mPos.y ); + InternalSize( mSize.Width() - Pos.x, mSize.Height() ); + break; + } + case RESIZE_TOP: + { + Pos.y -= mResizePos.y; + cUIControl::Pos( mPos.x, mPos.y + Pos.y ); + InternalSize( mSize.Width(), mSize.Height() - Pos.y ); + break; + } + case RESIZE_RIGHTBOTTOM: + { + Pos += mResizePos; + InternalSize( Pos.x, Pos.y ); + break; + } + case RESIZE_TOPLEFT: + { + Pos -= mResizePos; + cUIControl::Pos( mPos.x + Pos.x, mPos.y + Pos.y ); + InternalSize( mSize.Width() - Pos.x, mSize.Height() - Pos.y ); + break; + } + case RESIZE_TOPRIGHT: + { + Pos.y -= mResizePos.y; + Pos.x += mResizePos.x; + cUIControl::Pos( mPos.x, mPos.y + Pos.y ); + InternalSize( Pos.x, mSize.Height() - Pos.y ); + break; + } + case RESIZE_LEFTBOTTOM: + { + Pos.x -= mResizePos.x; + Pos.y += mResizePos.y; + cUIControl::Pos( mPos.x + Pos.x, mPos.y ); + InternalSize( mSize.Width() - Pos.x, Pos.y ); + break; + } + case RESIZE_NONE: + { + } + } +} + +void cUIWindow::InternalSize( const Int32& w, const Int32& h ) { + InternalSize( eeSize( w, h ) ); +} + +void cUIWindow::InternalSize( eeSize Size ) { + if ( Size.x < mMinWindowSize.x || Size.y < mMinWindowSize.y ) { + if ( Size.x < mMinWindowSize.x && Size.y < mMinWindowSize.y ) { + Size = mMinWindowSize; + } else if ( Size.x < mMinWindowSize.x ) { + Size.x = mMinWindowSize.x; + } else { + Size.y = mMinWindowSize.y; + } + } + + if ( Size != mSize ) { + mSize = Size; + OnSizeChange(); + } +} + +void cUIWindow::Update() { + cUIComplexControl::Update(); + + UpdateResize(); +} + cUIControlAnim * cUIWindow::Container() const { return mContainer; } @@ -262,10 +523,10 @@ bool cUIWindow::Show() { Enabled( true ); Visible( true ); - if ( 255.f == Alpha() ) { - StartAlphaAnim( 0.f, 255.f, cUIThemeManager::instance()->ControlsFadeInTime() ); + if ( mBaseAlpha == Alpha() ) { + StartAlphaAnim( 0.f, mBaseAlpha, cUIThemeManager::instance()->ControlsFadeInTime() ); } else { - CreateFadeIn( cUIThemeManager::instance()->ControlsFadeInTime() ); + StartAlphaAnim( mAlpha, mBaseAlpha, cUIThemeManager::instance()->ControlsFadeInTime() ); } return true; @@ -291,4 +552,71 @@ bool cUIWindow::Hide() { return false; } + +void cUIWindow::OnAlphaChange() { + if ( mWinFlags & UI_WIN_SHARE_ALPHA_WITH_CHILDS ) { + cUIControlAnim * AnimChild; + cUIControl * CurChild = mChild; + + while ( NULL != CurChild ) { + if ( CurChild->IsAnimated() ) { + AnimChild = reinterpret_cast ( CurChild ); + AnimChild->Alpha( mAlpha ); + } + + CurChild = CurChild->NextGet(); + } + } +} + +void cUIWindow::BaseAlpha( const Uint8& Alpha ) { + if ( mAlpha == mBaseAlpha ) { + cUIControlAnim::Alpha( Alpha ); + } + + mBaseAlpha = Alpha; +} + +const Uint8& cUIWindow::BaseAlpha() const { + return mBaseAlpha; +} + +void cUIWindow::Title( const std::wstring& Text ) { + if ( NULL == mTitle ) { + cUITextBox::CreateParams Params; + Params.Parent( this ); + Params.Flags = UI_CLIP_ENABLE | UI_VALIGN_CENTER; + Params.FontColor = mTitleFontColor; + + if ( mFlags & UI_HALIGN_CENTER ) + Params.Flags |= UI_HALIGN_CENTER; + + mTitle = eeNew( cUITextBox, ( Params ) ); + mTitle->Enabled( false ); + mTitle->Visible( true ); + } + + mTitle->Text( Text ); + + FixTitleSize(); +} + +void cUIWindow::FixTitleSize() { + if ( NULL != mTitle ) { + mTitle->Size( mWindowDecoration->Size().Width() - mBorderLeft->Size().Width() - mBorderRight->Size().Width(), mWindowDecoration->Size().Height() ); + mTitle->Pos( mBorderLeft->Size().Width(), 0 ); + } +} + +std::wstring cUIWindow::Title() const { + if ( NULL != mTitle ) + return mTitle->Text(); + + return std::wstring(); +} + +cUITextBox * cUIWindow::TitleTextBox() const { + return mTitle; +} + }} diff --git a/src/ui/cuiwindow.hpp b/src/ui/cuiwindow.hpp index b23c76ab6..ac3db78e3 100644 --- a/src/ui/cuiwindow.hpp +++ b/src/ui/cuiwindow.hpp @@ -3,6 +3,7 @@ #include "cuicomplexcontrol.hpp" #include "cuipushbutton.hpp" +#include "cuitextbox.hpp" namespace EE { namespace UI { @@ -15,15 +16,19 @@ class cUIWindow : public cUIComplexControl { UI_WIN_MAXIMIZE_BUTTON = ( 1 << 3 ), UI_WIN_USE_DEFAULT_BUTTONS_ACTIONS = ( 1 << 4 ), UI_WIN_RESIZEABLE = ( 1 << 5 ), - UI_WIN_DRAGABLE_CONTAINER = ( 1 << 6 ) + UI_WIN_DRAGABLE_CONTAINER = ( 1 << 6 ), + UI_WIN_SHARE_ALPHA_WITH_CHILDS = ( 1 << 7 ) }; class CreateParams : public cUIComplexControl::CreateParams { public: inline CreateParams() : cUIComplexControl::CreateParams(), - WinFlags( UI_WIN_CLOSE_BUTTON | UI_WIN_USE_DEFAULT_BUTTONS_ACTIONS | UI_WIN_RESIZEABLE ), + WinFlags( UI_WIN_CLOSE_BUTTON | UI_WIN_USE_DEFAULT_BUTTONS_ACTIONS | UI_WIN_RESIZEABLE | UI_WIN_SHARE_ALPHA_WITH_CHILDS ), ButtonsSeparation( 4 ), + MinCornerDistance( 24 ), + TitleFontColor( 255, 255, 255, 255), + BaseAlpha( 255 ), DecorationAutoSize( true ), BorderAutoSize( true ) { @@ -37,6 +42,9 @@ class cUIWindow : public cUIComplexControl { eeSize MinWindowSize; eeVector2i ButtonsPositionFixer; Uint32 ButtonsSeparation; + Int32 MinCornerDistance; + eeColorA TitleFontColor; + Uint8 BaseAlpha; bool DecorationAutoSize; bool BorderAutoSize; }; @@ -62,7 +70,31 @@ class cUIWindow : public cUIComplexControl { virtual bool Show(); virtual bool Hide(); + + virtual void Update(); + + void BaseAlpha( const Uint8& Alpha ); + + const Uint8& BaseAlpha() const; + + void Title( const std::wstring& Text ); + + std::wstring Title() const; + + cUITextBox * TitleTextBox() const; protected: + enum UI_RESIZE_TYPE { + RESIZE_NONE, + RESIZE_LEFT, + RESIZE_RIGHT, + RESIZE_TOP, + RESIZE_BOTTOM, + RESIZE_LEFTBOTTOM, + RESIZE_RIGHTBOTTOM, + RESIZE_TOPLEFT, + RESIZE_TOPRIGHT + }; + Uint32 mWinFlags; cUIControlAnim * mWindowDecoration; @@ -74,6 +106,7 @@ class cUIWindow : public cUIComplexControl { cUIComplexControl * mButtonClose; cUIComplexControl * mButtonMinimize; cUIComplexControl * mButtonMaximize; + cUITextBox * mTitle; eeSize mDecoSize; eeSize mBorderSize; @@ -82,11 +115,22 @@ class cUIWindow : public cUIComplexControl { eeSize mNonMaxSize; eeVector2i mButtonsPositionFixer; Uint32 mButtonsSeparation; + Int32 mMinCornerDistance; + + UI_RESIZE_TYPE mResizeType; + eeVector2i mResizePos; + + eeColorA mTitleFontColor; + + Uint8 mBaseAlpha; + bool mDecoAutoSize; bool mBorderAutoSize; virtual void OnSizeChange(); + virtual void OnAlphaChange(); + void ButtonCloseClick( const cUIEvent * Event ); void ButtonMaximizeClick( const cUIEvent * Event ); @@ -96,6 +140,24 @@ class cUIWindow : public cUIComplexControl { void ContainerPosChange( const cUIEvent * Event ); void FixChildsSize(); + + void DoResize ( const cUIMessage * Msg ); + + void DecideResizeType( cUIControl * Control ); + + void TryResize( const UI_RESIZE_TYPE& Type ); + + void EndResize(); + + void UpdateResize(); + + void InternalSize( eeSize Size ); + + void InternalSize( const Int32& w, const Int32& h ); + + void GetMinWinSize(); + + void FixTitleSize(); }; }}