Implemented double linked-list in the UI Controls, to optimize some process ( ChildAdd, ChildRemove, OverFind ).

Added cUITextBoxSimple, like cUITextBox without vertex buffers.
Added cUIListBoxContainer, a class to optimize the cUIListBox.
Added keyboard navigation in cUIListBox.
This commit is contained in:
spartanj
2010-11-16 04:38:41 -03:00
parent 19b7fa703e
commit 8538eb7eb3
15 changed files with 726 additions and 151 deletions

View File

@@ -160,5 +160,6 @@
#include "ui/cuiscrollbar.hpp"
#include "ui/cuiprogressbar.hpp"
#include "ui/cuilistbox.hpp"
#include "ui/cuilistboxitem.hpp"
using namespace EE::UI;
#endif

View File

@@ -549,14 +549,20 @@ void cEETest::CreateUI() {
LBParams.Parent( C );
LBParams.PosSet( 325, 8 );
LBParams.Size = eeSize( 200, 240-16 );
LBParams.Flags = UI_CLIP_ENABLE | UI_MULTI_SELECT | UI_AUTO_PADDING;
LBParams.Flags = UI_CLIP_ENABLE | UI_AUTO_PADDING; // | UI_MULTI_SELECT
LBParams.FontSelectedColor = eeColorA( 255, 255, 255, 255 );
mListBox = eeNew( cUIListBox, ( LBParams ) );
mListBox->Visible( true );
mListBox->Enabled( true );
for ( Int32 i = 1; i <= 12; i++ )
mListBox->AddListBoxItem( L"Test ListBox " + toWStr(i) + L" testing it right now!" );
Int32 wsize = 100;
std::vector<std::wstring> wstr(wsize);
for ( Int32 i = 1; i <= wsize; i++ )
wstr[i-1] = L"Test ListBox " + toWStr(i) + L" testing it right now!";
mListBox->AddListBoxItems( wstr );
mBuda = L"El mono ve el pez en el agua y sufre. Piensa que su mundo es el único que existe, el mejor, el real. Sufre porque es bueno y tiene compasión, lo ve y piensa: \"Pobre se está ahogando no puede respirar\". Y lo saca, lo saca y se queda tranquilo, por fin lo salvé. Pero el pez se retuerce de dolor y muere. Por eso te mostré el sueño, es imposible meter el mar en tu cabeza, que es un balde.";
TTFB->ShrinkText( mBuda, 400 );

View File

@@ -13,7 +13,9 @@ cUIControl::cUIControl( const CreateParams& Params ) :
mType( 0 ),
mData( 0 ),
mChild( NULL ),
mChildLast( NULL ),
mNext( NULL ),
mPrev( NULL ),
mBackground( Params.Background ),
mBorder( Params.Border ),
mControlFlags( 0 ),
@@ -103,10 +105,7 @@ Uint32 cUIControl::OnMessage( const cUIMessage * Msg ) {
}
bool cUIControl::IsInside( const eeVector2i& Pos ) const {
if ( Pos.x >= 0 && Pos.y >= 0 && Pos.x < mSize.Width() && Pos.y < mSize.Height() )
return true;
return false;
return ( Pos.x >= 0 && Pos.y >= 0 && Pos.x < mSize.Width() && Pos.y < mSize.Height() );
}
void cUIControl::Pos( const eeVector2i& Pos ) {
@@ -221,7 +220,7 @@ void cUIControl::Update() {
while ( NULL != ChildLoop ) {
ChildLoop->Update();
ChildLoop = ChildLoop->NextGet();
ChildLoop = ChildLoop->mNext;
}
}
@@ -301,6 +300,8 @@ Uint32 cUIControl::OnMouseExit( const eeVector2i& Pos, const Uint32 Flags ) {
}
Uint32 cUIControl::OnFocus() {
mControlFlags |= UI_CTRL_FLAG_HAS_FOCUS;
SendCommonEvent( cUIEvent::EventOnFocus );
SetSkinState( cUISkinState::StateFocus );
@@ -309,19 +310,19 @@ Uint32 cUIControl::OnFocus() {
}
Uint32 cUIControl::OnFocusLoss() {
mControlFlags &= ~UI_CTRL_FLAG_HAS_FOCUS;
SendCommonEvent( cUIEvent::EventOnFocusLoss );
return 1;
}
Uint32 cUIControl::OnValueChange() {
SendCommonEvent( cUIEvent::EventOnValueChange );
return 1;
}
Uint32 cUIControl::HAlign() const {
return mFlags & UI_HALIGN_MASK;
}
@@ -356,9 +357,13 @@ cUIControl * cUIControl::NextGet() const {
return mNext;
}
cUIControl * cUIControl::PrevGet() const {
return mPrev;
}
cUIControl * cUIControl::NextGetLoop() const {
if ( NULL == mNext )
return Parent()->ChildAt( 0 );
return Parent()->ChildGetFirst();
else
return mNext;
}
@@ -371,26 +376,6 @@ const Uint32& cUIControl::Data() const {
return mData;
}
cUIControl * cUIControl::ChildGetAt( eeVector2i CtrlPos, eeUint RecursiveLevel ) {
cUIControl * Ctrl = NULL;
for( cUIControl * pLoop = mChild; NULL != pLoop && NULL == Ctrl; pLoop = pLoop->NextGet() )
{
if ( !pLoop->Visible() )
continue;
if ( pLoop->Rect().Contains( CtrlPos ) ) {
if ( RecursiveLevel )
Ctrl = ChildGetAt( CtrlPos - pLoop->Pos(), RecursiveLevel - 1 );
if ( NULL == Ctrl )
Ctrl = pLoop;
}
}
return Ctrl;
}
const Uint32& cUIControl::Flags() const {
return mFlags;
}
@@ -475,20 +460,21 @@ const Uint32& cUIControl::ControlFlags() const {
}
void cUIControl::CheckClose() {
if ( mControlFlags & UI_CTRL_FLAG_DISABLE_CHECK_CLOSE_CHILDS )
return;
cUIControl * ChildLoop = mChild;
while( NULL != ChildLoop ) {
if ( ChildLoop->ControlFlags() & UI_CTRL_FLAG_CLOSE ) {
if ( ChildLoop->mControlFlags & UI_CTRL_FLAG_CLOSE ) {
eeDelete( ChildLoop );
ChildLoop = mChild;
continue;
}
ChildLoop->CheckClose();
ChildLoop = ChildLoop->NextGet();
ChildLoop = ChildLoop->mNext;
}
}
@@ -512,11 +498,11 @@ void cUIControl::DrawChilds() {
cUIControl * ChildLoop = mChild;
while ( NULL != ChildLoop ) {
if ( ChildLoop->Visible() ) {
if ( ChildLoop->mVisible ) {
ChildLoop->InternalDraw();
}
ChildLoop = ChildLoop->NextGet();
ChildLoop = ChildLoop->mNext;
}
}
@@ -564,15 +550,22 @@ void cUIControl::ChildDeleteAll() {
}
void cUIControl::ChildAdd( cUIControl * ChildCtrl ) {
if ( NULL == mChild )
mChild = ChildCtrl;
else {
if ( NULL == mChild ) {
mChild = ChildCtrl;
mChildLast = ChildCtrl;
} else {
/*
cUIControl * ChildLoop = mChild;
while ( NULL != ChildLoop->NextGet() )
ChildLoop = ChildLoop->NextGet();
while ( NULL != ChildLoop->mNext )
ChildLoop = ChildLoop->mNext;
ChildLoop->mNext = ChildCtrl;
*/
mChildLast->mNext = ChildCtrl;
ChildCtrl->mPrev = mChildLast;
mChildLast = ChildCtrl;
}
}
@@ -580,12 +573,16 @@ void cUIControl::ChildAddAt( cUIControl * ChildCtrl, Uint32 Pos ) {
cUIControl * ChildLoop = mChild;
if( Pos == 0 ) {
if( mChild == NULL) {
mChild = ChildCtrl;
ChildCtrl->mNext = NULL;
if ( mChild == NULL ) {
mChild = ChildCtrl;
mChildLast = ChildCtrl;
ChildCtrl->mNext = NULL;
ChildCtrl->mPrev = NULL;
} else {
ChildCtrl->mNext = mChild;
mChild = ChildCtrl;
mChild->mPrev = ChildCtrl;
ChildCtrl->mNext = mChild;
ChildCtrl->mPrev = NULL;
mChild = ChildCtrl;
}
} else {
Uint32 i = 0;
@@ -596,15 +593,22 @@ void cUIControl::ChildAddAt( cUIControl * ChildCtrl, Uint32 Pos ) {
}
cUIControl * ChildTmp = ChildLoop->mNext;
ChildLoop->mNext = ChildCtrl;
ChildCtrl->mNext = ChildTmp;
ChildLoop->mNext = ChildCtrl;
ChildCtrl->mPrev = ChildLoop;
ChildCtrl->mNext = ChildTmp;
ChildTmp->mPrev = ChildCtrl;
}
}
void cUIControl::ChildRemove( cUIControl * ChildCtrl ) {
if ( ChildCtrl == mChild )
mChild = mChild->mNext;
else {
if ( ChildCtrl == mChild ) {
mChild = mChild->mNext;
if ( NULL != mChild )
mChild->mPrev = NULL;
} else {
/*
cUIControl * ChildLoop = mChild;
while ( NULL != ChildLoop->mNext ) {
@@ -615,6 +619,15 @@ void cUIControl::ChildRemove( cUIControl * ChildCtrl ) {
ChildLoop = ChildLoop->mNext;
}
*/
if ( mChildLast == ChildCtrl )
mChildLast = mChildLast->mPrev;
ChildCtrl->mPrev->mNext = ChildCtrl->mNext;
if ( NULL != ChildCtrl->mNext )
ChildCtrl->mNext->mPrev = ChildCtrl->mPrev;
}
}
@@ -646,7 +659,7 @@ Uint32 cUIControl::ChildCount() const {
cUIControl * cUIControl::ChildAt( Uint32 Index ) const {
cUIControl * ChildLoop = mChild;
while( NULL != ChildLoop && Index) {
while( NULL != ChildLoop && Index ) {
ChildLoop = ChildLoop->mNext;
Index--;
}
@@ -655,6 +668,7 @@ cUIControl * cUIControl::ChildAt( Uint32 Index ) const {
}
cUIControl * cUIControl::ChildPrev( cUIControl * Ctrl, bool Loop ) const {
/*
cUIControl * ChildLoop = NULL;
if ( NULL != mChild ) {
@@ -662,37 +676,44 @@ cUIControl * cUIControl::ChildPrev( cUIControl * Ctrl, bool Loop ) const {
ChildLoop = mChild;
while ( NULL != ChildLoop ) {
if ( ChildLoop->NextGet() == Ctrl )
if ( ChildLoop->mNext == Ctrl )
break;
ChildLoop = ChildLoop->NextGet();
ChildLoop = ChildLoop->mNext;
}
} else if ( Loop ) {
ChildLoop = mChild;
while ( NULL != ChildLoop->NextGet() )
ChildLoop = ChildLoop->NextGet();
while ( NULL != ChildLoop->mNext )
ChildLoop = ChildLoop->mNext;
}
}
return ChildLoop;
*/
if ( Loop && Ctrl == mChild && NULL != mChild->mNext )
return mChildLast;
return Ctrl->mPrev;
}
cUIControl * cUIControl::ChildNext( cUIControl * Ctrl, bool Loop ) const {
cUIControl * Return = Ctrl->NextGet();
if ( NULL == Ctrl->mNext && Loop )
return mChild;
if ( NULL == Return && Loop ) {
Return = mChild;
}
return Return;
return Ctrl->mNext;
}
cUIControl * cUIControl::ChildGetFirst() const {
return mChild;
}
cUIControl * cUIControl::ChildGetLast() const {
return mChildLast;
}
cUIControl * cUIControl::OverFind( const eeVector2f& Point ) {
cUIControl * pOver = NULL;
@@ -700,6 +721,7 @@ cUIControl * cUIControl::OverFind( const eeVector2f& Point ) {
UpdateQuad();
if ( PointInsidePolygon2( mPoly, Point ) ) {
/*
cUIControl * ChildLoop = mChild;
while ( NULL != ChildLoop ) {
@@ -710,6 +732,21 @@ cUIControl * cUIControl::OverFind( const eeVector2f& Point ) {
ChildLoop = ChildLoop->mNext;
}
*/
cUIControl * ChildLoop = mChildLast;
while ( NULL != ChildLoop ) {
cUIControl * ChildOver = ChildLoop->OverFind( Point );
if ( NULL != ChildOver ) {
pOver = ChildOver;
break; // Search from top to bottom, so the first over will be the topmost
}
ChildLoop = ChildLoop->mPrev;
}
if ( NULL == pOver )
pOver = const_cast<cUIControl *>( reinterpret_cast<const cUIControl *>( this ) );
@@ -719,6 +756,26 @@ cUIControl * cUIControl::OverFind( const eeVector2f& Point ) {
return pOver;
}
cUIControl * cUIControl::ChildGetAt( eeVector2i CtrlPos, eeUint RecursiveLevel ) {
cUIControl * Ctrl = NULL;
for( cUIControl * pLoop = mChild; NULL != pLoop && NULL == Ctrl; pLoop = pLoop->mNext )
{
if ( !pLoop->Visible() )
continue;
if ( pLoop->Rect().Contains( CtrlPos ) ) {
if ( RecursiveLevel )
Ctrl = ChildGetAt( CtrlPos - pLoop->Pos(), RecursiveLevel - 1 );
if ( NULL == Ctrl )
Ctrl = pLoop;
}
}
return Ctrl;
}
Uint32 cUIControl::IsAnimated() {
return mControlFlags & UI_CTRL_FLAG_ANIM;
}
@@ -939,4 +996,9 @@ eeRecti cUIControl::MakePadding( bool PadLeft, bool PadRight, bool PadTop, bool
return tPadding;
}
void cUIControl::DisableChildCloseCheck() {
if ( !( mControlFlags & UI_CTRL_FLAG_DISABLE_CHECK_CLOSE_CHILDS ) )
mControlFlags |= UI_CTRL_FLAG_DISABLE_CHECK_CLOSE_CHILDS;
}
}}

View File

@@ -168,6 +168,8 @@ class EE_API cUIControl {
cUIControl * NextGet() const;
cUIControl * PrevGet() const;
cUIControl * NextGetLoop() const;
void Data( const Uint32& data );
@@ -218,6 +220,8 @@ class EE_API cUIControl {
cUIControl * ChildGetFirst() const;
cUIControl * ChildGetLast() const;
bool IsMouseOver();
const eePolygon2f& GetPolygon() const;
@@ -225,7 +229,11 @@ class EE_API cUIControl {
const eeVector2f& GetPolygonCenter() const;
void SetSkinState( const Uint32& State );
void DisableChildCloseCheck();
protected:
friend class cUIListBoxContainer;
bool mVisible;
bool mEnabled;
eeVector2i mPos;
@@ -236,8 +244,10 @@ class EE_API cUIControl {
Uint32 mType;
Uint32 mData;
cUIControl * mChild; // Pointer to the first child of the control
cUIControl * mNext; // Pointer to the next child
cUIControl * mChild; //! Pointer to the first child of the control
cUIControl * mChildLast; //! Pointer to the last child added
cUIControl * mNext; //! Pointer to the next child of the father
cUIControl * mPrev; //! Pointer to the prev child of the father
cUIBackground mBackground;
cUIBorder mBorder;
@@ -270,7 +280,7 @@ class EE_API cUIControl {
void CheckClose();
virtual void InternalDraw();
void InternalDraw();
void ChildDeleteAll();
@@ -290,7 +300,7 @@ class EE_API cUIControl {
cUIControl * ChildNext( cUIControl * Ctrl, bool Loop = false ) const;
cUIControl * OverFind( const eeVector2f& Point );
virtual cUIControl * OverFind( const eeVector2f& Point );
virtual void UpdateQuad();
@@ -304,7 +314,7 @@ class EE_API cUIControl {
void ClipTo();
void DrawChilds();
virtual void DrawChilds();
eeFloat Elapsed();

View File

@@ -7,7 +7,7 @@ cUIListBox::cUIListBox( cUIListBox::CreateParams& Params ) :
cUIControlAnim( Params ),
mRowHeight( Params.RowHeight ),
mScrollAlwaysVisible( Params.ScrollAlwaysVisible ),
mSoftScroll( Params.SoftScroll ),
mSmoothScroll( Params.SmoothScroll ),
mPaddingContainer( Params.PaddingContainer ),
mContainer( NULL ),
mScrollBar( NULL ),
@@ -21,7 +21,10 @@ cUIListBox::cUIListBox( cUIListBox::CreateParams& Params ) :
mMaxTextWidth(0),
mAllowHorizontalScroll( Params.AllowHorizontalScroll ),
mHScrollInit(0),
mItemsNotVisible(0)
mItemsNotVisible(0),
mLastTickMove(0),
mVisibleFirst(0),
mVisibleLast(0)
{
mType |= UI_TYPE_LISTBOX;
@@ -30,7 +33,7 @@ cUIListBox::cUIListBox( cUIListBox::CreateParams& Params ) :
CParams.PosSet( mPaddingContainer.Left, mPaddingContainer.Top );
CParams.Size = eeSize( mSize.Width() - mPaddingContainer.Right - mPaddingContainer.Left, mSize.Height() - mPaddingContainer.Top - mPaddingContainer.Bottom );
CParams.Flags = Params.Flags;
mContainer = eeNew( cUIControl, ( CParams ) );
mContainer = eeNew( cUIListBoxContainer, ( CParams ) );
mContainer->Visible( true );
mContainer->Enabled( true );
@@ -131,10 +134,10 @@ Uint32 cUIListBox::AddListBoxItem( const std::string& Text ) {
Uint32 cUIListBox::AddListBoxItem( const std::wstring& Text ) {
cUITextBox::CreateParams TextParams;
TextParams.Parent( mContainer );
TextParams.Flags = UI_VALIGN_CENTER | UI_HALIGN_LEFT;
TextParams.Font = mFont;
TextParams.FontColor = mFontColor;
cUIListBoxItem * tItem = eeNew( cUIListBoxItem, ( TextParams ) );
TextParams.Flags = UI_VALIGN_CENTER | UI_HALIGN_LEFT;
TextParams.Font = mFont;
TextParams.FontColor = mFontColor;
cUIListBoxItem * tItem = eeNew( cUIListBoxItem, ( TextParams ) );
tItem->Text( Text );
return AddListBoxItem( tItem );
@@ -177,7 +180,7 @@ void cUIListBox::RemoveListBoxItems( std::vector<Uint32> ItemsIndex ) {
if ( !erase ) {
ItemsCpy.push_back( mItems[i] );
} else {
mItems[i]->Close();
eeDelete( mItems[i] ); // doesn't call to mItems[i]->Close(); because is not checking for close.
}
}
@@ -276,7 +279,7 @@ void cUIListBox::FindMaxWidth() {
mMaxTextWidth = 0;
for ( Uint32 i = 0; i < size; i++ ) {
width = mItems[i]->GetTextCache().GetTextWidth();
width = mItems[i]->GetTextWidth();
if ( width > (Int32)mMaxTextWidth )
mMaxTextWidth = (Uint32)width;
@@ -292,7 +295,7 @@ void cUIListBox::UpdateListBoxItemsSize() {
}
void cUIListBox::ItemUpdateSize( cUIListBoxItem * Item ) {
Int32 width = Item->GetTextCache().GetTextWidth();
Int32 width = Item->GetTextWidth();
if ( width > (Int32)mMaxTextWidth )
mMaxTextWidth = (Uint32)width;
@@ -324,9 +327,8 @@ void cUIListBox::UpdateScroll( bool FromScrollChange ) {
return;
cUIListBoxItem * Item;
Uint32 i, RelPos = 0;
Int32 ItemPos;
Uint32 i, RelPos = 0, RelPosMax;
Int32 ItemPos, ItemPosMax;
Int32 tHLastScroll = mHScrollInit;
Uint32 VisibleItems = mContainer->Size().Height() / mRowHeight;
@@ -383,9 +385,11 @@ void cUIListBox::UpdateScroll( bool FromScrollChange ) {
Uint32 Scrolleable = mItems.size() * mRowHeight - mContainer->Size().Height();
bool isScrollVisible = mScrollBar->Visible();
bool isHScrollVisible = mHScrollBar->Visible();
bool FirstVisible = false;
if ( Clipped && mSoftScroll ) {
RelPos = (Uint32)( mScrollBar->Value() * Scrolleable );
if ( Clipped && mSmoothScroll ) {
RelPos = (Uint32)( mScrollBar->Value() * Scrolleable );
RelPosMax = RelPos + mContainer->Size().Height() + mRowHeight;
if ( ( FromScrollChange && 0xFFFFFFFF != mLastPos && mLastPos == RelPos ) && ( tHLastScroll == mHScrollInit ) )
return;
@@ -395,11 +399,19 @@ void cUIListBox::UpdateScroll( bool FromScrollChange ) {
for ( i = 0; i < mItems.size(); i++ ) {
Item = mItems[i];
ItemPos = mRowHeight * i;
ItemPosMax = ItemPos + mRowHeight;
if ( ItemPos >= (Int32)RelPos || ItemPos + mRowHeight >= RelPos ) {
if ( ( ItemPos >= (Int32)RelPos || ItemPosMax >= (Int32)RelPos ) && ( ItemPos <= (Int32)RelPosMax ) ) {
Item->Pos( mHScrollInit, ItemPos - RelPos );
Item->Enabled( true );
Item->Visible( true );
if ( !FirstVisible ) {
mVisibleFirst = i;
FirstVisible = true;
}
mVisibleLast = i;
} else {
Item->Enabled( false );
Item->Visible( false );
@@ -409,7 +421,7 @@ void cUIListBox::UpdateScroll( bool FromScrollChange ) {
ItemUpdateSize( Item );
}
} else {
Uint32 RelPosMax = mItems.size();
RelPosMax = mItems.size();
if ( mItemsNotVisible > 0 ) {
RelPos = (Uint32)( mScrollBar->Value() * mItemsNotVisible );
@@ -433,6 +445,13 @@ void cUIListBox::UpdateScroll( bool FromScrollChange ) {
Item->Enabled( true );
Item->Visible( true );
if ( !FirstVisible ) {
mVisibleFirst = i;
FirstVisible = true;
}
mVisibleLast = i;
} else {
Item->Enabled( false );
Item->Visible( false );
@@ -563,16 +582,16 @@ const eeRecti& cUIListBox::PaddingContainer() const {
return mPaddingContainer;
}
void cUIListBox::SoftScroll( const bool& soft ) {
if ( soft != mSoftScroll ) {
mSoftScroll = soft;
void cUIListBox::SmoothScroll( const bool& soft ) {
if ( soft != mSmoothScroll ) {
mSmoothScroll = soft;
UpdateScroll();
}
}
const bool& cUIListBox::SoftScroll() const {
return mSoftScroll;
const bool& cUIListBox::SmoothScroll() const {
return mSmoothScroll;
}
void cUIListBox::ScrollAlwaysVisible( const bool& visible ) {
@@ -617,4 +636,76 @@ Uint32 cUIListBox::Size() {
return mItems.size();
}
void cUIListBox::ManageKeyboard() {
if ( !mSelected.size() || mFlags & UI_MULTI_SELECT )
return;
cInput * KM = cUIManager::instance()->GetInput();
Int32 SelIndex = 0;
if ( eeGetTicks() - mLastTickMove > 100 ) {
if ( KM->IsKeyDown( KEY_DOWN ) ) {
mLastTickMove = eeGetTicks();
SelIndex = mSelected.front() + 1;
if ( SelIndex < (Int32)mItems.size() ) {
mItems[ mSelected.front() ]->Unselect();
if ( ScrollBar()->Visible() ) {
if ( mItems[ SelIndex ]->Pos().y + (Int32)RowHeight() > mContainer->Size().Height() ) {
ScrollBar()->Value( (eeFloat)( SelIndex * mRowHeight ) / (eeFloat)( ( mItems.size() - 1 ) * mRowHeight ) );
cUIManager::instance()->FocusControl( mItems[ SelIndex ] );
}
}
mItems[ SelIndex ]->Select();
}
} else if ( KM->IsKeyDown( KEY_UP ) ) {
mLastTickMove = eeGetTicks();
SelIndex = mSelected.front() - 1;
if ( SelIndex >= 0 ) {
mItems[ mSelected.front() ]->Unselect();
if ( ScrollBar()->Visible() ) {
if ( mItems[ SelIndex ]->Pos().y < 0 ) {
ScrollBar()->Value( (eeFloat)( SelIndex * mRowHeight ) / (eeFloat)( ( mItems.size() - 1 ) * mRowHeight ) );
cUIManager::instance()->FocusControl( mItems[ SelIndex ] );
}
}
mItems[ mSelected.front() - 1 ]->Select();
}
} else if ( KM->IsKeyDown( KEY_PAGEUP ) ) {
mLastTickMove = eeGetTicks();
if ( mSelected.front() != 0 ) {
mItems[ mSelected.front() ]->Unselect();
ScrollBar()->Value( 0 );
cUIManager::instance()->FocusControl( mItems[ 0 ] );
mItems[ 0 ]->Select();
}
} else if ( KM->IsKeyDown( KEY_PAGEDOWN ) ) {
mLastTickMove = eeGetTicks();
if ( mSelected.front() != Size() - 1 ) {
mItems[ mSelected.front() ]->Unselect();
ScrollBar()->Value( 1 );
cUIManager::instance()->FocusControl( mItems[ Size() - 1 ] );
mItems[ Size() - 1 ]->Select();
}
}
}
}
}}

View File

@@ -4,6 +4,7 @@
#include "cuicontrolanim.hpp"
#include "cuiscrollbar.hpp"
#include "cuilistboxitem.hpp"
#include "cuilistboxcontainer.hpp"
namespace EE { namespace UI {
@@ -15,7 +16,7 @@ class EE_API cUIListBox : public cUIControlAnim {
cUIControl::CreateParams(),
RowHeight( 0 ),
ScrollAlwaysVisible( false ),
SoftScroll( true ),
SmoothScroll( true ),
AllowHorizontalScroll( true ),
PaddingContainer(),
Font( NULL ),
@@ -29,7 +30,7 @@ class EE_API cUIListBox : public cUIControlAnim {
Uint32 RowHeight;
bool ScrollAlwaysVisible;
bool SoftScroll;
bool SmoothScroll;
bool AllowHorizontalScroll;
eeRecti PaddingContainer;
cFont * Font;
@@ -98,9 +99,9 @@ class EE_API cUIListBox : public cUIControlAnim {
const eeRecti& PaddingContainer() const;
void SoftScroll( const bool& soft );
void SmoothScroll( const bool& soft );
const bool& SoftScroll() const;
const bool& SmoothScroll() const;
void ScrollAlwaysVisible( const bool& visible );
@@ -117,12 +118,13 @@ class EE_API cUIListBox : public cUIControlAnim {
Uint32 Size();
protected:
friend class cUIListBoxItem;
friend class cUIListBoxContainer;
Uint32 mRowHeight;
bool mScrollAlwaysVisible;
bool mSoftScroll;
bool mSmoothScroll;
eeRecti mPaddingContainer;
cUIControl * mContainer;
cUIListBoxContainer * mContainer;
cUIScrollBar * mScrollBar;
cUIScrollBar * mHScrollBar;
cFont * mFont;
@@ -135,6 +137,11 @@ class EE_API cUIListBox : public cUIControlAnim {
bool mAllowHorizontalScroll;
Int32 mHScrollInit;
Int32 mItemsNotVisible;
Uint32 mLastTickMove;
Uint32 mVisibleFirst;
Uint32 mVisibleLast;
std::list<Uint32> mSelected;
std::vector<cUIListBoxItem *> mItems;
@@ -167,6 +174,8 @@ class EE_API cUIListBox : public cUIControlAnim {
void AutoPadding();
void FindMaxWidth();
void ManageKeyboard();
};
}}

View File

@@ -0,0 +1,62 @@
#include "cuilistboxcontainer.hpp"
#include "cuilistbox.hpp"
#include "cuilistboxitem.hpp"
namespace EE { namespace UI {
cUIListBoxContainer::cUIListBoxContainer( cUIControl::CreateParams& Params ) :
cUIControl( Params )
{
DisableChildCloseCheck();
}
cUIListBoxContainer::~cUIListBoxContainer()
{
}
void cUIListBoxContainer::Update() {
cUIListBox * LBParent = reinterpret_cast<cUIListBox*> ( Parent() );
if ( LBParent->mItems.size() ) {
for ( Uint32 i = LBParent->mVisibleFirst; i <= LBParent->mVisibleLast; i++ )
LBParent->mItems[i]->Update();
}
}
void cUIListBoxContainer::DrawChilds() {
cUIListBox * LBParent = reinterpret_cast<cUIListBox*> ( Parent() );
if ( LBParent->mItems.size() ) {
for ( Uint32 i = LBParent->mVisibleFirst; i <= LBParent->mVisibleLast; i++ )
LBParent->mItems[i]->InternalDraw();
}
}
cUIControl * cUIListBoxContainer::OverFind( const eeVector2f& Point ) {
cUIListBox * LBParent = reinterpret_cast<cUIListBox*> ( Parent() );
cUIControl * pOver = NULL;
if ( mVisible && mEnabled && LBParent->mItems.size() ) {
UpdateQuad();
if ( PointInsidePolygon2( mPoly, Point ) ) {
for ( Uint32 i = LBParent->mVisibleFirst; i <= LBParent->mVisibleLast; i++ ) {
cUIControl * ChildOver = LBParent->mItems[i]->OverFind( Point );
if ( NULL != ChildOver ) {
pOver = ChildOver;
break;
}
}
if ( NULL == pOver )
pOver = const_cast<cUIControl *>( reinterpret_cast<const cUIControl *>( this ) );
}
}
return pOver;
}
}}

View File

@@ -0,0 +1,23 @@
#ifndef EE_UICUILISTBOXCONTAINER_HPP
#define EE_UICUILISTBOXCONTAINER_HPP
#include "cuicontrol.hpp"
namespace EE { namespace UI {
class cUIListBoxContainer : public cUIControl {
public:
cUIListBoxContainer( cUIControl::CreateParams& Params );
~cUIListBoxContainer();
void Update();
void DrawChilds();
cUIControl * OverFind( const eeVector2f& Point );
};
}}
#endif

View File

@@ -5,8 +5,7 @@
namespace EE { namespace UI {
cUIListBoxItem::cUIListBoxItem( cUITextBox::CreateParams& Params ) :
cUITextBox( Params ),
mSelected( false )
cUITextBox( Params )
{
mType |= UI_TYPE_LISTBOXITEM;
@@ -22,70 +21,81 @@ void cUIListBoxItem::SetTheme( cUITheme * Theme ) {
}
Uint32 cUIListBoxItem::OnMouseClick( const eeVector2i& Pos, const Uint32 Flags ) {
cUIListBox * LBParent = reinterpret_cast<cUIListBox*> ( Parent()->Parent() );
if ( Flags & EE_BUTTONS_LRM ) {
bool wasSelected = mSelected;
LBParent->ItemClicked( this );
if ( LBParent->IsMultiSelect() ) {
if ( !wasSelected ) {
SetSkinState( cUISkinState::StateSelected );
mSelected = true;
LBParent->mSelected.push_back( LBParent->GetItemIndex( this ) );
LBParent->OnSelected();
} else {
mSelected = false;
LBParent->mSelected.remove( LBParent->GetItemIndex( this ) );
}
} else {
SetSkinState( cUISkinState::StateSelected );
mSelected = true;
LBParent->mSelected.clear();
LBParent->mSelected.push_back( LBParent->GetItemIndex( this ) );
LBParent->OnSelected();
}
Select();
}
return 1;
}
void cUIListBoxItem::Update() {
if ( mEnabled && mVisible && IsMouseOver() ) {
Uint32 Flags = cUIManager::instance()->GetInput()->ClickTrigger();
void cUIListBoxItem::Select() {
cUIListBox * LBParent = reinterpret_cast<cUIListBox*> ( Parent()->Parent() );
if ( Flags & EE_BUTTONS_WUWD ) {
cUIListBox * LBParent = reinterpret_cast<cUIListBox*> ( Parent()->Parent() );
bool wasSelected = mControlFlags & UI_CTRL_FLAG_SELECTED;
LBParent->ScrollBar()->Slider()->ManageClick( Flags );
LBParent->ItemClicked( this );
if ( LBParent->IsMultiSelect() ) {
if ( !wasSelected ) {
SetSkinState( cUISkinState::StateSelected );
mControlFlags |= UI_CTRL_FLAG_SELECTED;
LBParent->mSelected.push_back( LBParent->GetItemIndex( this ) );
LBParent->OnSelected();
} else {
mControlFlags &= ~UI_CTRL_FLAG_SELECTED;
LBParent->mSelected.remove( LBParent->GetItemIndex( this ) );
}
} else {
SetSkinState( cUISkinState::StateSelected );
mControlFlags |= UI_CTRL_FLAG_SELECTED;
LBParent->mSelected.clear();
LBParent->mSelected.push_back( LBParent->GetItemIndex( this ) );
if ( !wasSelected ) {
LBParent->OnSelected();
}
}
}
Uint32 cUIListBoxItem::OnMouseExit( const eeVector2i& Pos, const Uint32 Flags ) {
cUITextBox::OnMouseExit( Pos, Flags );
void cUIListBoxItem::Update() {
if ( mEnabled && mVisible ) {
cUIListBox * LBParent = reinterpret_cast<cUIListBox*> ( Parent()->Parent() );
Uint32 Flags = cUIManager::instance()->GetInput()->ClickTrigger();
if ( mSelected )
if ( IsMouseOver() ) {
if ( Flags & EE_BUTTONS_WUWD )
LBParent->ScrollBar()->Slider()->ManageClick( Flags );
}
if ( ( mControlFlags & UI_CTRL_FLAG_HAS_FOCUS ) )
LBParent->ManageKeyboard();
}
}
Uint32 cUIListBoxItem::OnMouseExit( const eeVector2i& Pos, const Uint32 Flags ) {
cUIControl::OnMouseExit( Pos, Flags );
if ( mControlFlags & UI_CTRL_FLAG_SELECTED )
SetSkinState( cUISkinState::StateSelected );
return 1;
}
void cUIListBoxItem::Unselect() {
mSelected = false;
if ( mControlFlags & UI_CTRL_FLAG_SELECTED )
mControlFlags &= ~UI_CTRL_FLAG_SELECTED;
SetSkinState( cUISkinState::StateNormal );
}
const bool& cUIListBoxItem::Selected() const {
return mSelected;
bool cUIListBoxItem::Selected() const {
return mControlFlags & UI_CTRL_FLAG_SELECTED;
}
void cUIListBoxItem::OnStateChange() {

View File

@@ -19,12 +19,12 @@ class EE_API cUIListBoxItem : public cUITextBox {
virtual void Update();
const bool& Selected() const;
bool Selected() const;
void Unselect();
protected:
bool mSelected;
void Select();
protected:
virtual void OnStateChange();
};

View File

@@ -174,4 +174,16 @@ cTextCache& cUITextBox::GetTextCache() {
return mTextCache;
}
eeFloat cUITextBox::GetTextWidth() {
return mTextCache.GetTextWidth();
}
eeFloat cUITextBox::GetTextHeight() {
return mTextCache.GetTextHeight();
}
const eeInt& cUITextBox::GetNumLines() const {
return mTextCache.GetNumLines();
}
}}

View File

@@ -61,6 +61,12 @@ class EE_API cUITextBox : public cUIControlAnim {
virtual void SetTheme( cUITheme * Theme );
cTextCache& GetTextCache();
eeFloat GetTextWidth();
eeFloat GetTextHeight();
const eeInt& GetNumLines() const;
protected:
cTextCache mTextCache;
eeColorA mFontColor;

200
src/ui/cuitextboxsimple.cpp Normal file
View File

@@ -0,0 +1,200 @@
#include "cuitextboxsimple.hpp"
#include "cuimanager.hpp"
#include "cuithememanager.hpp"
namespace EE { namespace UI {
cUITextBoxSimple::cUITextBoxSimple( const cUITextBox::CreateParams& Params ) :
cUIControl( Params ),
mFont( NULL ),
mCachedWidth( NULL ),
mNumLines( 1 ),
mFontColor( Params.FontColor ),
mFontShadowColor( Params.FontShadowColor ),
mAlignOffset( 0.f, 0.f )
{
mType |= UI_TYPE_GET(UI_TYPE_TEXTBOX);
mFont = Params.Font;
if ( NULL == Params.Font && NULL != cUIThemeManager::instance()->DefaultFont() ) {
mFont = cUIThemeManager::instance()->DefaultFont();
} else {
eePRINT( "cUITextBoxSimple::cUITextBoxSimple : Created a UI TextBox without a defined font." );
}
AutoAlign();
}
cUITextBoxSimple::~cUITextBoxSimple() {
}
void cUITextBoxSimple::Draw() {
if ( mVisible ) {
cUIControl::Draw();
if ( mCachedWidth ) {
if ( mFlags & UI_CLIP_ENABLE )
cUIManager::instance()->ClipEnable( mScreenPos.x + mPadding.Left, mScreenPos.y + mPadding.Top, mSize.Width() - mPadding.Left - mPadding.Right, mSize.Height() - mPadding.Bottom );
eeColorA OldColor = mFont->Color();
eeColorA OldShadowColor = mFont->ShadowColor();
mFont->Color( mFontColor );
mFont->ShadowColor( mFontShadowColor );
mFont->Draw( mText, (eeFloat)mScreenPos.x + mAlignOffset.x + (eeFloat)mPadding.Left + 1.f, (eeFloat)mScreenPos.y + mAlignOffset.y + (eeFloat)mPadding.Top, Flags(), 1.f, 0.f, mBlend );
mFont->Color( OldColor );
mFont->ShadowColor( OldShadowColor );
if ( mFlags & UI_CLIP_ENABLE )
cUIManager::instance()->ClipDisable();
}
}
}
cFont * cUITextBoxSimple::Font() const {
return mFont;
}
void cUITextBoxSimple::Font( cFont * font ) {
mFont = font;
AutoShrink();
AutoSize();
AutoAlign();
OnFontChanged();
}
const std::wstring& cUITextBoxSimple::Text() {
return mText;
}
void cUITextBoxSimple::Text( const std::string& text ) {
Text( stringTowstring( text ) );
}
void cUITextBoxSimple::Text( const std::wstring& text ) {
mText = text;
if ( NULL != mFont && mText.size() ) {
std::vector<eeFloat> LinesWidth;
mFont->CacheWidth( mText, LinesWidth, mCachedWidth, mNumLines );
}else {
mCachedWidth = 0;
}
AutoShrink();
AutoSize();
AutoAlign();
OnTextChanged();
}
const eeColorA& cUITextBoxSimple::Color() const {
return mFontColor;
}
void cUITextBoxSimple::Color( const eeColorA& color ) {
mFontColor = color;
Alpha( color.A() );
}
const eeColorA& cUITextBoxSimple::ShadowColor() const {
return mFontShadowColor;
}
void cUITextBoxSimple::ShadowColor( const eeColorA& color ) {
mFontShadowColor = color;
Alpha( color.A() );
}
void cUITextBoxSimple::Alpha( const eeFloat& alpha ) {
mFontColor.Alpha = (Uint8)alpha;
mFontShadowColor.Alpha = (Uint8)alpha;
}
void cUITextBoxSimple::AutoShrink() {
if ( Flags() & UI_AUTO_SHRINK_TEXT ) {
mFont->ShrinkText( mText, mSize.Width() );
}
}
void cUITextBoxSimple::AutoSize() {
if ( Flags() & UI_AUTO_SIZE ) {
mSize.Width( mCachedWidth );
mSize.Height( (eeFloat)mFont->GetFontSize() * (eeFloat)mNumLines );
}
}
void cUITextBoxSimple::AutoAlign() {
switch ( FontHAlignGet( Flags() ) ) {
case UI_HALIGN_CENTER:
mAlignOffset.x = (eeFloat)( (Int32)( mSize.x - mCachedWidth ) / 2 );
break;
case UI_HALIGN_RIGHT:
mAlignOffset.x = ( (eeFloat)mSize.x - (eeFloat)mCachedWidth );
break;
case UI_HALIGN_LEFT:
mAlignOffset.x = 0.f;
break;
}
switch ( FontVAlignGet( Flags() ) ) {
case UI_VALIGN_CENTER:
mAlignOffset.y = (eeFloat)( ( (Int32)( mSize.y - GetTextHeight() ) ) / 2 );
break;
case UI_VALIGN_BOTTOM:
mAlignOffset.y = ( (eeFloat)mSize.y - GetTextHeight() );
break;
case UI_VALIGN_TOP:
mAlignOffset.y = 0.f;
break;
}
}
void cUITextBoxSimple::OnSizeChange() {
AutoShrink();
AutoSize();
AutoAlign();
cUIControl::OnSizeChange();
}
void cUITextBoxSimple::OnTextChanged() {
SendCommonEvent( cUIEvent::EventOnTextChanged );
}
void cUITextBoxSimple::OnFontChanged() {
SendCommonEvent( cUIEvent::EventOnFontChanged );
}
void cUITextBoxSimple::Padding( const eeRecti& padding ) {
mPadding = padding;
}
const eeRecti& cUITextBoxSimple::Padding() const {
return mPadding;
}
void cUITextBoxSimple::SetTheme( cUITheme * Theme ) {
cUIControl::SetTheme( Theme );
if ( NULL == mFont && NULL != Theme->DefaultFont() ) {
mFont = Theme->DefaultFont();
}
}
eeFloat cUITextBoxSimple::GetTextWidth() {
return mCachedWidth;
}
eeFloat cUITextBoxSimple::GetTextHeight() {
return ( (eeFloat)mFont->GetFontSize() * (eeFloat)mNumLines );
}
const eeInt& cUITextBoxSimple::GetNumLines() const {
return mNumLines;
}
}}

View File

@@ -0,0 +1,74 @@
#ifndef EE_UICUITEXTBOXSIMPLE_H
#define EE_UICUITEXTBOXSIMPLE_H
#include "cuicontrol.hpp"
#include "cuitextbox.hpp"
namespace EE { namespace UI {
class EE_API cUITextBoxSimple : public cUIControl {
public:
cUITextBoxSimple( const cUITextBox::CreateParams& Params );
~cUITextBoxSimple();
virtual void Draw();
virtual void Alpha( const eeFloat& alpha );
cFont * Font() const;
void Font( cFont * font );
virtual const std::wstring& Text();
virtual void Text( const std::wstring& text );
virtual void Text( const std::string& text );
const eeColorA& Color() const;
void Color( const eeColorA& color );
const eeColorA& ShadowColor() const;
void ShadowColor( const eeColorA& color );
virtual void OnTextChanged();
virtual void OnFontChanged();
virtual void Padding( const eeRecti& padding );
const eeRecti& Padding() const;
virtual void SetTheme( cUITheme * Theme );
eeFloat GetTextWidth();
eeFloat GetTextHeight();
const eeInt& GetNumLines() const;
protected:
std::wstring mText;
cFont * mFont;
eeFloat mCachedWidth;
eeInt mNumLines;
eeColorA mFontColor;
eeColorA mFontShadowColor;
eeVector2f mAlignOffset;
eeRecti mPadding;
virtual void OnSizeChange();
void AutoShrink();
void AutoSize();
void AutoAlign();
};
}}
#endif

View File

@@ -19,17 +19,26 @@ Uint32 EE_API HAlignGet( Uint32 Flags );
Uint32 EE_API VAlignGet( Uint32 Flags );
#define UI_CTRL_FLAG_CLOSE_POS (0)
#define UI_CTRL_FLAG_CLOSE (1 << UI_CTRL_FLAG_CLOSE_POS)
#define UI_CTRL_FLAG_CLOSE_POS (0)
#define UI_CTRL_FLAG_CLOSE (1 << UI_CTRL_FLAG_CLOSE_POS)
#define UI_CTRL_FLAG_CLOSE_FO_POS (1)
#define UI_CTRL_FLAG_CLOSE_FO (1 << UI_CTRL_FLAG_CLOSE_FO_POS)
#define UI_CTRL_FLAG_CLOSE_FO_POS (1)
#define UI_CTRL_FLAG_CLOSE_FO (1 << UI_CTRL_FLAG_CLOSE_FO_POS)
#define UI_CTRL_FLAG_ANIM_POS (2)
#define UI_CTRL_FLAG_ANIM (1 << UI_CTRL_FLAG_ANIM_POS)
#define UI_CTRL_FLAG_ANIM_POS (2)
#define UI_CTRL_FLAG_ANIM (1 << UI_CTRL_FLAG_ANIM_POS)
#define UI_CTRL_FLAG_MOUSEOVER_POS (3)
#define UI_CTRL_FLAG_MOUSEOVER (1 << UI_CTRL_FLAG_MOUSEOVER_POS)
#define UI_CTRL_FLAG_MOUSEOVER_POS (3)
#define UI_CTRL_FLAG_MOUSEOVER (1 << UI_CTRL_FLAG_MOUSEOVER_POS)
#define UI_CTRL_FLAG_HAS_FOCUS_POS (4)
#define UI_CTRL_FLAG_HAS_FOCUS (1 << UI_CTRL_FLAG_HAS_FOCUS_POS)
#define UI_CTRL_FLAG_SELECTED_POS (5)
#define UI_CTRL_FLAG_SELECTED (1 << UI_CTRL_FLAG_SELECTED_POS)
#define UI_CTRL_FLAG_DISABLE_CHECK_CLOSE_CHILDS_POS (6)
#define UI_CTRL_FLAG_DISABLE_CHECK_CLOSE_CHILDS (1 << UI_CTRL_FLAG_DISABLE_CHECK_CLOSE_CHILDS_POS)
#define UI_TEXT_DRAW_SHADOW FONT_DRAW_SHADOW
#define UI_AUTO_SIZE (1 << 6)
@@ -58,7 +67,7 @@ Uint32 EE_API VAlignGet( Uint32 Flags );
#define UI_TYPE_LISTBOX (12)
#define UI_TYPE_LISTBOXITEM (13)
#define UI_TYPE_GET(X) ( 1 << (X) )
#define UI_TYPE_GET(X) ( 1 << (X) )
}}