diff --git a/ee.linux.cbp b/ee.linux.cbp
index fd85919b9..b5c13f916 100644
--- a/ee.linux.cbp
+++ b/ee.linux.cbp
@@ -538,6 +538,8 @@
+
+
diff --git a/src/ee.h b/src/ee.h
index 78afad2a1..b8cb0d8ea 100755
--- a/src/ee.h
+++ b/src/ee.h
@@ -156,5 +156,6 @@
#include "ui/cuicheckbox.hpp"
#include "ui/cuiradiobutton.hpp"
#include "ui/cuislider.hpp"
+ #include "ui/cuispinbox.hpp"
using namespace EE::UI;
#endif
diff --git a/src/test/ee.cpp b/src/test/ee.cpp
index a228eac25..94ec9869c 100644
--- a/src/test/ee.cpp
+++ b/src/test/ee.cpp
@@ -194,8 +194,22 @@ class cEETest : private cThread {
cVertexBuffer * mVBO;
void ButtonClick( const cUIEvent * Event );
+ void CreateAquaTextureAtlas();
};
+void cEETest::CreateAquaTextureAtlas() {
+ std::string Path( MyPath + "data/aqua" );
+
+ if ( !FileExists( Path + ".etg" ) ) {
+ cTexturePacker tp( 512, 512, true, 2 );
+ tp.AddTexturesPath( Path );
+ tp.PackTextures();
+ tp.Save( Path + ".png", EE_SAVE_TYPE_PNG );
+ } else {
+ cTextureGroupLoader tgl;
+ tgl.UpdateTextureAtlas( Path + ".etg", Path );
+ }
+}
void cEETest::Init() {
EE = cEngine::instance();
@@ -223,6 +237,8 @@ void cEETest::Init() {
MyPath = AppPath();
+ CreateAquaTextureAtlas();
+
cIniFile Ini( MyPath + "data/ee.ini" );
Ini.ReadFile();
@@ -413,7 +429,6 @@ void cEETest::CreateUI() {
InputParams.Size = eeSize( 300, 22 );
InputParams.Flags = UI_VALIGN_CENTER | UI_HALIGN_LEFT | UI_CLIP_ENABLE; // | UI_BORDER | UI_FILL_BACKGROUND
InputParams.Font = TTF;
- InputParams.SupportNewLine = false;
cUITextInput * Input = eeNew( cUITextInput, ( InputParams ) );
Input->Padding( eeRectf( 4, -2, -8, 0 ) );
Input->Visible( true );
@@ -426,6 +441,7 @@ void cEETest::CreateUI() {
Button->Visible( true );
Button->Enabled( true );
Button->Text( L"Click Me" );
+ Button->Padding( eeRectf( 0, -1, 0, 0 ) );
Button->AddEventListener( cUIEvent::EventMouseClick, cb::Make1( this, &cEETest::ButtonClick ) );
TextParams.PosSet( 120, 20 );
@@ -462,10 +478,34 @@ void cEETest::CreateUI() {
mSlider->Visible( true );
mSlider->Enabled( true );
+ cUISpinBox::CreateParams SpinBoxParams;
+ SpinBoxParams.Parent( C );
+ SpinBoxParams.PosSet( 80, 150 );
+ SpinBoxParams.Size = eeSize( 80, 23 );
+ SpinBoxParams.Flags = UI_VALIGN_CENTER | UI_HALIGN_LEFT | UI_CLIP_ENABLE; // | UI_BORDER | UI_FILL_BACKGROUND
+ SpinBoxParams.Font = TTF;
+ SpinBoxParams.AllowDotsInNumbers = true;
+ cUISpinBox * mSpinBox = eeNew( cUISpinBox, ( SpinBoxParams ) );
+ mSpinBox->Visible( true );
+ mSpinBox->Enabled( true );
+ mSpinBox->Padding( eeRectf( 2, 0, -2, 0 ) );
+
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.\nPowered by Text Shrinker =)";
TTF->ShrinkText( mBuda, 400 );
/** Replace this with the texture atlas and an auto theme loader */
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_normal_ml.png" ), "aqua_button_normal_ml" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_normal_mr.png" ), "aqua_button_normal_mr" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_normal_m.png" ), "aqua_button_normal_m" ) ) );
+
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_menter_ml.png" ), "aqua_button_menter_ml" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_menter_mr.png" ), "aqua_button_menter_mr" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_menter_m.png" ), "aqua_button_menter_m" ) ) );
+
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_mdown_ml.png" ), "aqua_button_mdown_ml" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_mdown_mr.png" ), "aqua_button_mdown_mr" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_button_mdown_m.png" ), "aqua_button_mdown_m" ) ) );
+
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_textinput_normal.png" ), "aqua_textinput_normal" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_textinput_focus.png" ), "aqua_textinput_focus" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_textinput_normal_dl.png" ), "aqua_textinput_normal_dl" ) ) );
@@ -477,29 +517,43 @@ void cEETest::CreateUI() {
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_textinput_normal_ul.png" ), "aqua_textinput_normal_ul" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_textinput_normal_ur.png" ), "aqua_textinput_normal_ur" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_textinput_normal_m.png" ), "aqua_textinput_normal_m" ) ) );
+
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_checkbox_active_menter.png" ), "aqua_checkbox_active_menter" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_checkbox_active_normal.png" ), "aqua_checkbox_active_normal" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_checkbox_inactive_menter.png" ), "aqua_checkbox_inactive_menter" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_checkbox_inactive_normal.png" ), "aqua_checkbox_inactive_normal" ) ) );
+
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_radiobutton_active_menter.png" ), "aqua_radiobutton_active_menter" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_radiobutton_active_normal.png" ), "aqua_radiobutton_active_normal" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_radiobutton_inactive_menter.png" ), "aqua_radiobutton_inactive_menter" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_radiobutton_inactive_normal.png" ), "aqua_radiobutton_inactive_normal" ) ) );
+
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_hslider_button_normal.png" ), "aqua_hslider_button_normal" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_hslider_button_menter.png" ), "aqua_hslider_button_menter" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_hslider_bg_normal_m.png" ), "aqua_hslider_bg_normal_m" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_hslider_bg_normal_ml.png" ), "aqua_hslider_bg_normal_ml" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_hslider_bg_normal_mr.png" ), "aqua_hslider_bg_normal_mr" ) ) );
+
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_vslider_button_normal.png" ), "aqua_vslider_button_normal" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_vslider_button_menter.png" ), "aqua_vslider_button_menter" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_vslider_bg_normal_m.png" ), "aqua_vslider_bg_normal_m" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_vslider_bg_normal_u.png" ), "aqua_vslider_bg_normal_u" ) ) );
cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_vslider_bg_normal_d.png" ), "aqua_vslider_bg_normal_d" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_input_normal_ml.png" ), "aqua_spinbox_input_normal_ml" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_input_normal_m.png" ), "aqua_spinbox_input_normal_m" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_input_normal_d.png" ), "aqua_spinbox_input_normal_d" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_input_normal_dl.png" ), "aqua_spinbox_input_normal_dl" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_input_normal_u.png" ), "aqua_spinbox_input_normal_u" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_input_normal_ul.png" ), "aqua_spinbox_input_normal_ul" ) ) );
+
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_btnup_normal.png" ), "aqua_spinbox_btnup_normal" ) ) );
+ cGlobalShapeGroup::instance()->Add( eeNew( cShape, ( TF->Load( MyPath + "data/aqua/aqua_spinbox_btndown_normal.png" ), "aqua_spinbox_btndown_normal" ) ) );
+
cUITheme * AquaTheme = eeNew( cUITheme, ( "aqua", "aqua" ) );
cUISkinComplex * AquaTextInput = eeNew( cUISkinComplex, ( "aqua_textinput" ) );
- cUISkinComplex * AquaButton = AquaTextInput->Copy( "aqua_button" );
+ cUISkinComplex * AquaButton = eeNew( cUISkinComplex, ( "aqua_button" ) );
cUISkinSimple * AquaCheckboxActive = eeNew( cUISkinSimple, ( "aqua_checkbox_active" ) );
cUISkinSimple * AquaCheckboxInactive = eeNew( cUISkinSimple, ( "aqua_checkbox_inactive" ) );
cUISkinSimple * AquaRadioButtonActive = eeNew( cUISkinSimple, ( "aqua_radiobutton_active" ) );
@@ -508,11 +562,15 @@ void cEETest::CreateUI() {
cUISkinSimple * AquaSliderButton = eeNew( cUISkinSimple, ( "aqua_hslider_button" ) );
cUISkinComplex * AquaVSliderBg = eeNew( cUISkinComplex, ( "aqua_vslider_bg" ) );
cUISkinSimple * AquaVSliderButton = eeNew( cUISkinSimple, ( "aqua_vslider_button" ) );
+ cUISkinComplex * AquaSpinBox = eeNew( cUISkinComplex, ( "aqua_spinbox_input" ) );
+ cUISkinSimple * AquaSpinBoxBtnUp = eeNew( cUISkinSimple, ( "aqua_spinbox_btnup" ) );
+ cUISkinSimple * AquaSpinBoxBtnDown = eeNew( cUISkinSimple, ( "aqua_spinbox_btndown" ) );
+
AquaTextInput->SetColor ( cUISkin::StateNormal , eeColorA( 240, 240, 255, 255 ) );
AquaTextInput->SetColor ( cUISkin::StateFocus , eeColorA( 250, 250, 255, 255 ) );
- AquaButton->SetColor ( cUISkin::StateMouseEnter , eeColorA( 200, 255, 200, 255 ) );
- AquaButton->SetColor ( cUISkin::StateMouseDown , eeColorA( 150, 255, 150, 255 ) );
+ //AquaButton->SetColor ( cUISkin::StateMouseEnter , eeColorA( 200, 255, 200, 255 ) );
+ //AquaButton->SetColor ( cUISkin::StateMouseDown , eeColorA( 150, 255, 150, 255 ) );
AquaTheme->Add( AquaTextInput );
AquaTheme->Add( AquaButton );
@@ -524,6 +582,9 @@ void cEETest::CreateUI() {
AquaTheme->Add( AquaSliderButton );
AquaTheme->Add( AquaVSliderBg );
AquaTheme->Add( AquaVSliderButton );
+ AquaTheme->Add( AquaSpinBox );
+ AquaTheme->Add( AquaSpinBoxBtnUp );
+ AquaTheme->Add( AquaSpinBoxBtnDown );
/***************/
cUIThemeManager::instance()->Add( AquaTheme );
@@ -1329,25 +1390,6 @@ void cEETest::Particles() {
}
int main (int argc, char * argv []) {
-/* std::string Path( "/home/downloads/files/temp/bnb/allin/" );
-*/
-/*
- cTextureGroupLoader * tgl = eeNew( cTextureGroupLoader, () );
- tgl->UpdateTextureAtlas( AppPath() + "data/bnb/bnb.etg", Path );
- eeDelete( tgl );
-*/
-/*
- cTexturePacker tp( 512, 512 );
-
- if ( argc > 1 )
- Path = std::string( argv[1] );
-
- tp.AddTexturesPath( Path );
-
- tp.PackTextures();
-
- tp.Save( AppPath() + "data/bnb/bnb.png", EE_SAVE_TYPE_PNG );
-*/
cEETest * Test = eeNew( cEETest, () );
Test->Process();
diff --git a/src/ui/cuicheckbox.cpp b/src/ui/cuicheckbox.cpp
index 211093398..e02287d86 100644
--- a/src/ui/cuicheckbox.cpp
+++ b/src/ui/cuicheckbox.cpp
@@ -89,6 +89,8 @@ void cUICheckBox::Active( const bool& active ) {
mActive = true;
}
+
+ OnValueChange();
}
const bool& cUICheckBox::Active() const {
diff --git a/src/ui/cuicontrol.cpp b/src/ui/cuicontrol.cpp
index 0e400ce15..0e580195b 100644
--- a/src/ui/cuicontrol.cpp
+++ b/src/ui/cuicontrol.cpp
@@ -310,6 +310,14 @@ Uint32 cUIControl::OnFocusLoss() {
return 1;
}
+
+Uint32 cUIControl::OnValueChange() {
+ SendCommonEvent( cUIEvent::EventOnValueChange );
+
+ return 1;
+}
+
+
Uint32 cUIControl::HAlign() const {
return mFlags & UI_HALIGN_MASK;
}
diff --git a/src/ui/cuicontrol.hpp b/src/ui/cuicontrol.hpp
index ffc01d64d..59c7e1627 100644
--- a/src/ui/cuicontrol.hpp
+++ b/src/ui/cuicontrol.hpp
@@ -146,6 +146,8 @@ class EE_API cUIControl {
virtual Uint32 OnFocus();
virtual Uint32 OnFocusLoss();
+
+ virtual Uint32 OnValueChange();
Uint32 HAlign() const;
diff --git a/src/ui/cuievent.hpp b/src/ui/cuievent.hpp
index f43b26e89..353223222 100644
--- a/src/ui/cuievent.hpp
+++ b/src/ui/cuievent.hpp
@@ -31,6 +31,7 @@ class EE_API cUIEvent {
EventOnTextChanged,
EventOnFontChanged,
EventOnPressEnter,
+ EventOnValueChange,
EventUser,
EventForceDWord = 0xFFFFFFFF
};
diff --git a/src/ui/cuiradiobutton.cpp b/src/ui/cuiradiobutton.cpp
index 8028d8a03..ee7bf4419 100644
--- a/src/ui/cuiradiobutton.cpp
+++ b/src/ui/cuiradiobutton.cpp
@@ -88,19 +88,23 @@ void cUIRadioButton::Active( const bool& active ) {
mInactiveButton->Visible( true );
mActive = false;
+
+ OnValueChange();
}
} else {
mActiveButton->Visible( true );
mInactiveButton->Visible( false );
mActive = true;
+
+ OnValueChange();
}
if ( active && NULL != mParentCtrl ) {
cUIControl * tChild = mParentCtrl->ChildGetFirst();
while ( NULL != tChild ) {
- if ( tChild->Type() & UI_TYPE_GET( UI_TYPE_RADIOBUTTON ) ) {
+ if ( tChild->IsType( UI_TYPE_RADIOBUTTON ) ) {
if ( tChild != this ) {
cUIRadioButton * tRB = reinterpret_cast ( tChild );
@@ -119,7 +123,7 @@ bool cUIRadioButton::CheckActives() {
cUIControl * tChild = mParentCtrl->ChildGetFirst();
while ( NULL != tChild ) {
- if ( tChild->Type() & UI_TYPE_GET( UI_TYPE_RADIOBUTTON ) ) {
+ if ( tChild->IsType( UI_TYPE_RADIOBUTTON ) ) {
if ( tChild != this ) {
cUIRadioButton * tRB = reinterpret_cast ( tChild );
@@ -142,7 +146,7 @@ void cUIRadioButton::AutoActivate() {
cUIControl * tChild = mParentCtrl->ChildGetFirst();
while ( NULL != tChild ) {
- if ( tChild->Type() & UI_TYPE_GET( UI_TYPE_RADIOBUTTON ) ) {
+ if ( tChild->IsType( UI_TYPE_RADIOBUTTON ) ) {
if ( tChild != this ) {
cUIRadioButton * tRB = reinterpret_cast ( tChild );
diff --git a/src/ui/cuislider.cpp b/src/ui/cuislider.cpp
index 6eb3183a3..68787a053 100644
--- a/src/ui/cuislider.cpp
+++ b/src/ui/cuislider.cpp
@@ -141,6 +141,8 @@ void cUISlider::Value( const eeFloat& Val ) {
else
mSlider->Pos( mSlider->Pos().x, mBackSlider->Size().Height() * ( Val - mMinValue ) );
}
+
+ OnValueChange();
}
}
diff --git a/src/ui/cuispinbox.cpp b/src/ui/cuispinbox.cpp
new file mode 100644
index 000000000..20cdd7213
--- /dev/null
+++ b/src/ui/cuispinbox.cpp
@@ -0,0 +1,204 @@
+#include "cuispinbox.hpp"
+
+namespace EE { namespace UI {
+
+cUISpinBox::cUISpinBox( const cUISpinBox::CreateParams& Params ) :
+ cUIControlAnim( Params ),
+ mMinValue( 0.f ),
+ mMaxValue( 1024.f ),
+ mValue( Params.DefaultValue ),
+ mClickStep( 1.f )
+{
+ mType |= UI_TYPE_GET(UI_TYPE_SPINBOX);
+
+ cUITextInput::CreateParams InputParams( Params );
+ InputParams.PosSet( 0, 0 );
+ InputParams.Parent( this );
+
+ mInput = eeNew( cUITextInput, ( InputParams ) );
+
+ cUIPushButton::CreateParams BtnParams( Params );
+ BtnParams.Parent( this );
+ BtnParams.Size = eeSize( 16, 16 );
+
+ mPushUp = eeNew( cUIPushButton, ( BtnParams ) );
+ mPushDown = eeNew( cUIPushButton, ( BtnParams ) );
+
+ mInput->Visible ( true );
+ mInput->Enabled ( true );
+ mPushUp->Visible ( true );
+ mPushUp->Enabled ( true );
+ mPushDown->Visible ( true );
+ mPushDown->Enabled ( true );
+
+ mInput->GetInputTextBuffer()->AllowOnlyNumbers( true, Params.AllowDotsInNumbers );
+
+ InternalValue( mValue, true );
+
+ AdjustChilds();
+}
+
+cUISpinBox::~cUISpinBox() {
+
+}
+
+void cUISpinBox::SetTheme( cUITheme * Theme ) {
+ cUIControl::SetTheme ( Theme, "spinbox" );
+
+ mInput->ForceThemeSkin ( Theme, "spinbox_input" );
+ mPushUp->ForceThemeSkin ( Theme, "spinbox_btnup" );
+ mPushDown->ForceThemeSkin ( Theme, "spinbox_btndown" );
+
+ cShape * tShape = NULL;
+ cUISkin * tSkin = NULL;
+
+ tSkin = mPushUp->GetSkin();
+
+ if ( NULL != tSkin ) {
+ tShape = tSkin->GetShape( cUISkin::StateNormal );
+
+ if ( NULL != tShape ) {
+ mPushUp->Size( tShape->RealSize() );
+ }
+ }
+
+ tSkin = mPushDown->GetSkin();
+
+ if ( NULL != tSkin ) {
+ tShape = tSkin->GetShape( cUISkin::StateNormal );
+
+ if ( NULL != tShape ) {
+ mPushDown->Size( tShape->RealSize() );
+ }
+ }
+
+ AdjustChilds();
+}
+
+void cUISpinBox::AdjustChilds() {
+ mPushUp->Pos( mSize.Width() - mPushUp->Size().Width(), 0 );
+ mPushDown->Pos( mSize.Width() - mPushDown->Size().Width(), mPushUp->Size().Height() );
+ mInput->Size( mSize.Width() - mPushUp->Size().Width(), mSize.Height() );
+}
+
+void cUISpinBox::Padding( const eeRectf& padding ) {
+ mInput->Padding( padding );
+}
+
+const eeRectf& cUISpinBox::Padding() const {
+ return mInput->Padding();
+}
+
+void cUISpinBox::ClickStep( const eeFloat& step ) {
+ mClickStep = step;
+}
+
+const eeFloat& cUISpinBox::ClickStep() const {
+ return mClickStep;
+}
+
+Uint32 cUISpinBox::OnMessage( const cUIMessage * Msg ) {
+ switch ( Msg->Msg() ) {
+ case cUIMessage::MsgClick:
+ {
+ if ( Msg->Flags() & EE_BUTTON_LMASK ) {
+ if ( Msg->Sender() == mPushUp ) {
+ AddValue( mClickStep );
+ } else if ( Msg->Sender() == mPushDown ) {
+ AddValue( -mClickStep );
+ }
+ } else if ( Msg->Flags() & EE_BUTTONS_WUWD ) {
+ if ( Msg->Flags() & EE_BUTTON( EE_BUTTON_WHEELUP ) )
+ AddValue( mClickStep );
+ else
+ AddValue( -mClickStep );
+ }
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void cUISpinBox::AddValue( const eeFloat& value ) {
+ if ( !mInput->Text().size() )
+ mInput->Text( L"0" );
+
+ Value( mValue + value );
+}
+
+void cUISpinBox::InternalValue( const eeFloat& Val, const bool& Force ) {
+ if ( Force || Val != mValue ) {
+ if ( Val >= mMinValue && Val <= mMaxValue ) {
+ eeFloat iValN = (Int32) Val;
+ eeFloat fValN = (eeFloat)iValN;
+
+ if ( fValN == Val ) {
+ mInput->Text( toWStr( iValN ) );
+ } else {
+ mInput->Text( toWStr( Val ) );
+ }
+
+ mValue = Val;
+
+ OnValueChange();
+ }
+ }
+}
+
+void cUISpinBox::Value( const eeFloat& Val ) {
+ InternalValue( Val, false );
+}
+
+const eeFloat& cUISpinBox::Value() const {
+ return mValue;
+}
+
+void cUISpinBox::MinValue( const eeFloat& MinVal ) {
+ mMinValue = MinVal;
+
+ if ( mValue < mMinValue )
+ mValue = mMinValue;
+}
+
+const eeFloat& cUISpinBox::MinValue() const {
+ return mMinValue;
+}
+
+void cUISpinBox::MaxValue( const eeFloat& MaxVal ) {
+ mMaxValue = MaxVal;
+
+ if ( mValue > mMaxValue )
+ mValue = mMaxValue;
+}
+
+const eeFloat& cUISpinBox::MaxValue() const {
+ return mMaxValue;
+}
+
+void cUISpinBox::Update() {
+ cUIControlAnim::Update();
+
+ if ( mInput->GetInputTextBuffer()->ChangedSinceLastUpdate() ) {
+ if ( !mInput->Text().size() ) {
+ Value( 0 );
+ } else {
+ eeFloat Val = mValue;
+
+ if ( L'.' == mInput->Text()[ mInput->Text().size() - 1 ] ) {
+ Uint32 pos = mInput->Text().find_first_of( L"." );
+
+ if ( pos != mInput->Text().size() - 1 )
+ mInput->Text( mInput->Text().substr( 0, mInput->Text().size() - 1 ) );
+ } else {
+ bool Res = fromWString( Val, mInput->Text() );
+
+ if ( Res )
+ Value( Val );
+ }
+ }
+ }
+}
+
+}}
diff --git a/src/ui/cuispinbox.hpp b/src/ui/cuispinbox.hpp
new file mode 100644
index 000000000..01f638167
--- /dev/null
+++ b/src/ui/cuispinbox.hpp
@@ -0,0 +1,74 @@
+#ifndef EE_UICUISPINBOX_HPP
+#define EE_UICUISPINBOX_HPP
+
+#include "cuitextinput.hpp"
+#include "cuipushbutton.hpp"
+
+namespace EE { namespace UI {
+
+class EE_API cUISpinBox : public cUIControlAnim {
+ public:
+ class CreateParams : public cUITextInput::CreateParams {
+ public:
+ inline CreateParams() :
+ cUITextInput::CreateParams()
+ {
+ MaxLenght = 24;
+ DefaultValue = 0.f;
+ }
+
+ inline ~CreateParams() {}
+
+ eeFloat DefaultValue;
+ bool AllowDotsInNumbers;
+ };
+
+ cUISpinBox( const cUISpinBox::CreateParams& Params );
+
+ ~cUISpinBox();
+
+ virtual void SetTheme( cUITheme * Theme );
+
+ virtual void Padding( const eeRectf& padding );
+
+ const eeRectf& Padding() const;
+
+ virtual void ClickStep( const eeFloat& step );
+
+ const eeFloat& ClickStep() const;
+
+ virtual Uint32 OnMessage( const cUIMessage * Msg );
+
+ void AddValue( const eeFloat& value );
+
+ virtual void MinValue( const eeFloat& MinVal );
+
+ const eeFloat& MinValue() const;
+
+ virtual void MaxValue( const eeFloat& MaxVal );
+
+ const eeFloat& MaxValue() const;
+
+ virtual void Value( const eeFloat& Val );
+
+ const eeFloat& Value() const;
+
+ virtual void Update();
+ protected:
+ cUITextInput * mInput;
+ cUIPushButton * mPushUp;
+ cUIPushButton * mPushDown;
+ eeFloat mMinValue;
+ eeFloat mMaxValue;
+ eeFloat mValue;
+ eeFloat mClickStep;
+
+ void AdjustChilds();
+
+ void InternalValue( const eeFloat& Val, const bool& Force = false );
+
+};
+
+}}
+
+#endif
diff --git a/src/ui/cuitextbox.cpp b/src/ui/cuitextbox.cpp
index 961bb81f3..b77ae2f6e 100644
--- a/src/ui/cuitextbox.cpp
+++ b/src/ui/cuitextbox.cpp
@@ -29,7 +29,7 @@ void cUITextBox::Draw() {
if ( IsClipped() )
cUIManager::instance()->ClipEnable( mScreenPos.x + (Int32)mPadding.Left, mScreenPos.y + (Int32)mPadding.Top, mSize.Width() + (Int32)mPadding.Right, mSize.Height() + (Int32)mPadding.Bottom );
- mTextCache.Draw( (eeFloat)mScreenPos.x + mAlignOffset.x + mPadding.Left + 1, (eeFloat)mScreenPos.y + mAlignOffset.y + mPadding.Top, Flags(), 1.f, 0.f, mBlend );
+ mTextCache.Draw( (eeFloat)mScreenPos.x + mAlignOffset.x + mPadding.Left + 1.f, (eeFloat)mScreenPos.y + mAlignOffset.y + mPadding.Top, Flags(), 1.f, 0.f, mBlend );
if ( IsClipped() )
cUIManager::instance()->ClipDisable();
@@ -105,7 +105,7 @@ void cUITextBox::AutoSize() {
void cUITextBox::AutoAlign() {
switch ( FontHAlignGet( Flags() ) ) {
case UI_HALIGN_CENTER:
- mAlignOffset.x = ( (eeFloat)mSize.x - (eeFloat)mTextCache.GetTextWidth() ) * 0.5f;
+ mAlignOffset.x = (eeFloat)( (Int32)( mSize.x - mTextCache.GetTextWidth() ) / 2 );
break;
case UI_HALIGN_RIGHT:
mAlignOffset.x = ( (eeFloat)mSize.x - (eeFloat)mTextCache.GetTextWidth() );
@@ -117,7 +117,7 @@ void cUITextBox::AutoAlign() {
switch ( FontVAlignGet( Flags() ) ) {
case UI_VALIGN_CENTER:
- mAlignOffset.y = ( (eeFloat)mSize.y - (eeFloat)mTextCache.GetTextHeight() ) * 0.5f;
+ mAlignOffset.y = (eeFloat)( ( (Int32)( mSize.y - mTextCache.GetTextHeight() ) ) / 2 );
break;
case UI_VALIGN_BOTTOM:
mAlignOffset.y = ( (eeFloat)mSize.y - (eeFloat)mTextCache.GetTextHeight() );
diff --git a/src/ui/cuitextbox.hpp b/src/ui/cuitextbox.hpp
index c18482d33..9ff62c887 100644
--- a/src/ui/cuitextbox.hpp
+++ b/src/ui/cuitextbox.hpp
@@ -32,11 +32,11 @@ class EE_API cUITextBox : public cUIControlAnim {
void Font( cFont * font );
- const std::wstring& Text();
+ virtual const std::wstring& Text();
- void Text( const std::wstring& text );
+ virtual void Text( const std::wstring& text );
- void Text( const std::string& text );
+ virtual void Text( const std::string& text );
const eeColorA& Color() const;
diff --git a/src/ui/cuitextinput.cpp b/src/ui/cuitextinput.cpp
index 4333aacc2..9825b5f61 100644
--- a/src/ui/cuitextinput.cpp
+++ b/src/ui/cuitextinput.cpp
@@ -8,10 +8,9 @@ cUITextInput::cUITextInput( const cUITextInput::CreateParams& Params ) :
mCursorPos(0)
{
mType |= UI_TYPE_GET(UI_TYPE_TEXTINPUT);
-
+
mTextBuffer.Start();
mTextBuffer.Active( false );
- mTextBuffer.SupportNewLine( Params.SupportNewLine );
mTextBuffer.SupportFreeEditing( Params.SupportFreeEditing );
mTextBuffer.MaxLenght( Params.MaxLenght );
mTextBuffer.SetReturnCallback( cb::Make0( this, &cUITextInput::PrivOnPressEnter ) );
@@ -138,4 +137,22 @@ void cUITextInput::SetTheme( cUITheme * Theme ) {
cUIControl::SetTheme( Theme, "textinput" );
}
+cInputTextBuffer * cUITextInput::GetInputTextBuffer() {
+ return &mTextBuffer;
+}
+
+void cUITextInput::Text( const std::wstring& text ) {
+ cUITextBox::Text( text );
+
+ mTextBuffer.Buffer( text );
+}
+
+void cUITextInput::Text( const std::string& text ) {
+ cUITextBox::Text( text );
+}
+
+const std::wstring& cUITextInput::Text() {
+ return cUITextBox::Text();
+}
+
}}
diff --git a/src/ui/cuitextinput.hpp b/src/ui/cuitextinput.hpp
index 98f93cddf..059d5cfce 100644
--- a/src/ui/cuitextinput.hpp
+++ b/src/ui/cuitextinput.hpp
@@ -10,15 +10,15 @@ class EE_API cUITextInput : public cUITextBox {
public:
class CreateParams : public cUITextBox::CreateParams {
public:
- inline CreateParams() : cUITextBox::CreateParams() {
- SupportNewLine = true;
- SupportFreeEditing = true;
- MaxLenght = 256;
+ inline CreateParams() :
+ cUITextBox::CreateParams(),
+ SupportFreeEditing( true ),
+ MaxLenght( 256 )
+ {
}
inline ~CreateParams() {}
- bool SupportNewLine;
bool SupportFreeEditing;
Uint32 MaxLenght;
};
@@ -37,9 +37,17 @@ class EE_API cUITextInput : public cUITextBox {
virtual Uint32 OnPressEnter();
+ virtual void Text( const std::wstring& text );
+
+ virtual void Text( const std::string& text );
+
+ virtual const std::wstring& Text();
+
void PushIgnoredChar( const Uint32& ch );
virtual void SetTheme( cUITheme * Theme );
+
+ cInputTextBuffer * GetInputTextBuffer();
protected:
cInputTextBuffer mTextBuffer;
bool mShowingWait;
diff --git a/src/ui/uihelper.hpp b/src/ui/uihelper.hpp
index 131140ade..031acd518 100644
--- a/src/ui/uihelper.hpp
+++ b/src/ui/uihelper.hpp
@@ -44,12 +44,13 @@ Uint32 EE_API VAlignGet( Uint32 Flags );
#define UI_TYPE_CONTROL (0)
#define UI_TYPE_CONTROL_ANIM (1)
#define UI_TYPE_GFX (2)
-#define UI_TYPE_TEXTBOX (3)
+#define UI_TYPE_TEXTBOX (3)
#define UI_TYPE_TEXTINPUT (4)
#define UI_TYPE_PUSHBUTTON (5)
#define UI_TYPE_CHECKBOX (6)
#define UI_TYPE_RADIOBUTTON (7)
#define UI_TYPE_SLIDER (8)
+#define UI_TYPE_SPINBOX (9)
#define UI_TYPE_GET(X) ( 1 << (X) )
diff --git a/src/utils/string.cpp b/src/utils/string.cpp
index 2d32281d0..ca038954a 100644
--- a/src/utils/string.cpp
+++ b/src/utils/string.cpp
@@ -6,7 +6,10 @@ bool isCharacter( const eeInt& mValue ) {
return (mValue >= 32 && mValue <= 126) || (mValue >= 161 && mValue <= 255) || (mValue == 9);
}
-bool isNumber( const eeInt& mValue ) {
+bool isNumber( const eeInt& mValue, bool AllowDot ) {
+ if ( AllowDot )
+ return ( mValue >= 48 && mValue <= 57 ) || mValue == 46;
+
return mValue >= 48 && mValue <= 57;
}
diff --git a/src/utils/string.hpp b/src/utils/string.hpp
index c7d5700c8..e34059edf 100755
--- a/src/utils/string.hpp
+++ b/src/utils/string.hpp
@@ -9,7 +9,7 @@ namespace EE { namespace Utils {
bool EE_API isCharacter( const eeInt& mValue );
/** @return If the value passed is a number */
-bool EE_API isNumber( const eeInt& mValue );
+bool EE_API isNumber( const eeInt& mValue, bool AllowDot = false );
/** @return If the value passed is a letter */
bool EE_API isLetter( const eeInt& mValue );
diff --git a/src/window/cinputtextbuffer.cpp b/src/window/cinputtextbuffer.cpp
index e3ef27f2b..3712e24b3 100755
--- a/src/window/cinputtextbuffer.cpp
+++ b/src/window/cinputtextbuffer.cpp
@@ -3,13 +3,15 @@
namespace EE { namespace Window {
cInputTextBuffer::cInputTextBuffer( const bool& Active, const bool& SupportNewLine, const bool& SupportFreeEditing, const Uint32& MaxLenght ) :
+ mActive( Active ),
+ mFlags(0),
mChangeSinceLastUpdate(false),
mCallback(0),
mPromptPos(0),
mPromptAutoPos(true)
{
- mActive = Active;
- mSupportNewLine = SupportNewLine;
+ this->SupportNewLine( SupportNewLine );
+
mPromtPosSupport = SupportFreeEditing;
mMaxLenght = MaxLenght;
SetAutoPromp();
@@ -17,12 +19,13 @@ cInputTextBuffer::cInputTextBuffer( const bool& Active, const bool& SupportNewLi
cInputTextBuffer::cInputTextBuffer() :
mActive(true),
- mSupportNewLine(true),
+ mFlags(0),
mChangeSinceLastUpdate(false),
mCallback(0),
mPromtPosSupport(true),
mMaxLenght(0xFFFFFFFF)
{
+ SupportNewLine( false );
SetAutoPromp();
}
@@ -63,7 +66,7 @@ void cInputTextBuffer::Update( EE_Event* Event ) {
}
}
} else if ( ( c == KEY_RETURN || c == KEY_KP_ENTER ) && !cInput::instance()->MetaPressed() && !cInput::instance()->AltPressed() && !cInput::instance()->ControlPressed() ) {
- if ( mSupportNewLine && CanAdd() ) {
+ if ( SupportNewLine() && CanAdd() ) {
InsertChar( mText, mPromptPos, L'\n' );
mPromptPos++;
}
@@ -86,6 +89,10 @@ void cInputTextBuffer::Update( EE_Event* Event ) {
} else if ( CanAdd() && isCharacter(c) && !cInput::instance()->MetaPressed() && !cInput::instance()->AltPressed() && !cInput::instance()->ControlPressed() ) {
bool Ignored = false;
+ if ( AllowOnlyNumbers() && !isNumber( c, AllowDotsInNumbers() ) ) {
+ Ignored = true;
+ }
+
if ( mIgnoredChars.size() ) {
for ( eeUint i = 0; i < mIgnoredChars.size(); i++ ) {
if ( mIgnoredChars[i] == (Uint32)c )
@@ -125,13 +132,15 @@ void cInputTextBuffer::Update( EE_Event* Event ) {
if ( c == KEY_BACKSPACE && mText.size() > 0 ) {
mText.resize( mText.size() - 1 );
} else if ( (c == KEY_RETURN || c == KEY_KP_ENTER) && !cInput::instance()->MetaPressed() && !cInput::instance()->AltPressed() && !cInput::instance()->ControlPressed() ) {
- if ( mSupportNewLine && CanAdd() )
+ if ( SupportNewLine() && CanAdd() )
mText += L'\n';
if ( mEnterCall.IsSet() )
mEnterCall();
} else if ( CanAdd() && isCharacter(c) && !cInput::instance()->MetaPressed() && !cInput::instance()->AltPressed() && !cInput::instance()->ControlPressed() ) {
- mText += c;
+ if ( !( AllowOnlyNumbers() && !isNumber( c, AllowDotsInNumbers() ) ) ) {
+ mText += c;
+ }
}
}
}
@@ -161,9 +170,11 @@ void cInputTextBuffer::SetAutoPromp( const bool& set ) {
}
void cInputTextBuffer::Buffer( const std::wstring& str ) {
- mText = str;
- mChangeSinceLastUpdate = true;
-
+ if ( mText != str ) {
+ mText = str;
+ mChangeSinceLastUpdate = true;
+ }
+
if ( mPromtPosSupport )
SetAutoPromp();
}
@@ -213,4 +224,45 @@ const Uint32& cInputTextBuffer::MaxLenght() const {
return mMaxLenght;
}
+std::wstring cInputTextBuffer::Buffer() const {
+ return mText;
+}
+
+bool cInputTextBuffer::Active() const {
+ return mActive;
+}
+
+void cInputTextBuffer::Active( const bool& Active ) {
+ mActive = Active;
+}
+
+bool cInputTextBuffer::SupportNewLine() {
+ return 0 != ( mFlags & ( 1 << INPUT_TB_SUPPORT_NEW_LINE ) );
+}
+
+void cInputTextBuffer::SupportNewLine( const bool& SupportNewLine ) {
+ Write32BitKey( &mFlags, INPUT_TB_SUPPORT_NEW_LINE, SupportNewLine == true );
+}
+
+void cInputTextBuffer::AllowOnlyNumbers( const bool& onlynums, const bool& allowdots ) {
+ Write32BitKey( &mFlags, INPUT_TB_ALLOW_ONLY_NUMBERS, onlynums == true );
+ Write32BitKey( &mFlags, INPUT_TB_ALLOW_DOT_IN_NUMBERS, allowdots == true );
+}
+
+bool cInputTextBuffer::AllowOnlyNumbers() {
+ return 0 != ( mFlags & ( 1 << INPUT_TB_ALLOW_ONLY_NUMBERS ) );
+}
+
+bool cInputTextBuffer::AllowDotsInNumbers() {
+ return 0 != ( mFlags & ( 1 << INPUT_TB_ALLOW_DOT_IN_NUMBERS ) );
+}
+
+bool cInputTextBuffer::SupportFreeEditing() const {
+ return mPromtPosSupport;
+}
+
+void cInputTextBuffer::SupportFreeEditing( const bool& SupportNewLine ) {
+ mPromtPosSupport = SupportNewLine;
+}
+
}}
diff --git a/src/window/cinputtextbuffer.hpp b/src/window/cinputtextbuffer.hpp
index 1fc82f708..de6880bdb 100755
--- a/src/window/cinputtextbuffer.hpp
+++ b/src/window/cinputtextbuffer.hpp
@@ -6,6 +6,10 @@
namespace EE { namespace Window {
+#define INPUT_TB_SUPPORT_NEW_LINE (0)
+#define INPUT_TB_ALLOW_ONLY_NUMBERS (1)
+#define INPUT_TB_ALLOW_DOT_IN_NUMBERS (2)
+
class EE_API cInputTextBuffer {
public:
typedef cb::Callback0 EnterCallback;
@@ -15,28 +19,37 @@ class EE_API cInputTextBuffer {
~cInputTextBuffer();
/** @return The current buffer */
- std::wstring Buffer() const { return mText; };
+ std::wstring Buffer() const;
/** Set a new current buffer */
void Buffer( const std::wstring& str );
/** @return If input buffer is active */
- bool Active() const { return mActive; }
+ bool Active() const;
/** Set the state of the input buffer */
- void Active( const bool& Active ) { mActive = Active; }
+ void Active( const bool& Active );
/** @return If new line is supported */
- bool SupportNewLine() const { return mSupportNewLine; }
+ bool SupportNewLine();
/** Support new line consist of allowing to add a new line when key return is pressed. */
- void SupportNewLine( const bool& SupportNewLine ) { mSupportNewLine = SupportNewLine; }
+ void SupportNewLine( const bool& SupportNewLine );
/** @return If Free Editing is enabled */
- bool SupportFreeEditing() const { return mPromtPosSupport; }
+ bool SupportFreeEditing() const;
/** Free editing consist on the capability of moving the cursor position over the buffer, to write over the buffer, and not only after the last character. */
- void SupportFreeEditing( const bool& SupportNewLine ) { mPromtPosSupport = SupportNewLine; }
+ void SupportFreeEditing( const bool& SupportNewLine );
+
+ /** Block all the inserts, allow only numeric characters. */
+ void AllowOnlyNumbers( const bool& onlynums, const bool& allowdots = false );
+
+ /** @return If is only allowing numbers */
+ bool AllowOnlyNumbers();
+
+ /** @return If is only allowing numbers, it allow floating point numbers? */
+ bool AllowDotsInNumbers();
/** Start the input buffer */
void Start();
@@ -78,7 +91,7 @@ class EE_API cInputTextBuffer {
std::wstring mText;
bool mActive;
- bool mSupportNewLine;
+ Uint32 mFlags;
bool mChangeSinceLastUpdate;
Uint32 mCallback;