diff --git a/demo.srd b/demo.srd index f62b065..fa7878f 100644 --- a/demo.srd +++ b/demo.srd @@ -163,9 +163,8 @@ (min 0) (max 50000) (step .1)) (float "Maximum blur" dof-max-blur (min 1) (max 64) (slider)) - { NOT IMPLEMENTED - (int dof-samples (min 1) (max 64) (step .1)) - } + (int "Samples" dof-samples + (min 1) (max 64) (slider)) ) ) ) diff --git a/syncoverrides.cc b/syncoverrides.cc index 0378f09..5bcdffd 100644 --- a/syncoverrides.cc +++ b/syncoverrides.cc @@ -164,6 +164,105 @@ bool FloatSetDecimals_( T_SRDParserData const& data ) return true; } +/*------------------------------------------------------------------------------*/ + +using SP_Int = T_SharedPtr< A_Integer >; + +bool EnterInt1_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + SP_Int ptr{ NewShared< T_Integer >( input[ 2 ].stringValue( ) , + input[ 1 ].stringValue( ) ) }; + ptr->location( ) = input[ 0 ].location( ); + *( data.targetData ) = std::move( ptr ); + return true; +} + +bool EnterInt2_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + SP_Int ptr{ NewShared< T_Integer2 >( + input[ 2 ].stringValue( ) , input[ 3 ].stringValue( ) , + input[ 1 ].stringValue( ) ) }; + ptr->location( ) = input[ 0 ].location( ); + *( data.targetData ) = std::move( ptr ); + return true; +} + +bool EnterInt3_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + SP_Int ptr{ NewShared< T_Integer3 >( + input[ 2 ].stringValue( ) , input[ 3 ].stringValue( ) , + input[ 4 ].stringValue( ) , + input[ 1 ].stringValue( ) ) }; + ptr->location( ) = input[ 0 ].location( ); + *( data.targetData ) = std::move( ptr ); + return true; +} + +bool EnterInt4_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + SP_Int ptr{ NewShared< T_Integer4 >( + input[ 2 ].stringValue( ) , input[ 3 ].stringValue( ) , + input[ 4 ].stringValue( ) , input[ 5 ].stringValue( ) , + input[ 1 ].stringValue( ) ) }; + ptr->location( ) = input[ 0 ].location( ); + *( data.targetData ) = std::move( ptr ); + return true; +} + +bool AddInt_( T_SRDParserData const& data ) +{ + auto& fl( data.currentData->value< SP_Int >( ) ); + auto& parent( data.targetData->value< SP_Section >( ) ); + + if ( fl->min( ) > fl->max( ) ) { + data.errors.add( "invalid bounds" , (*data.input)[ 0 ] ); + } + parent->overrides.add( fl.makeOwned( ) ); + return true; +} + +/*------------------------------------------------------------------------------*/ + +bool IntSetSlider_( T_SRDParserData const& data ) +{ + data.currentData->value< SP_Int >( )->setSlider( ); + return true; +} + +bool IntSetMin_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + if ( !data.currentData->value< SP_Int >( )->setMin( input[ 1 ].longValue( ) ) ) { + data.errors.add( "duplicate minimal value" , (*data.input)[ 0 ] ); + } + return true; +} + +bool IntSetMax_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + if ( !data.currentData->value< SP_Int >( )->setMax( input[ 1 ].longValue( ) ) ) { + data.errors.add( "duplicate maximal value" , (*data.input)[ 0 ] ); + } + return true; +} + +bool IntSetStep_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + const auto v( input[ 1 ].floatValue( ) ); + if ( v <= 0 ) { + data.errors.add( "invalid step value" , (*data.input)[ 1 ] ); + } else if ( !data.currentData->value< SP_Int >( )->setStep( v ) ) { + data.errors.add( "duplicate step value" , (*data.input)[ 0 ] ); + } + return true; +} + } // namespace /*------------------------------------------------------------------------------*/ @@ -208,6 +307,26 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( ) << EnterContext( "float" ) << OnEnter( EnterFloat4_ ) << OnExit( AddFloat_ ) ) + // Integer controls + << ( Rule() << "int" << Text( ) << Word( ) + << EnterContext( "int" ) + << OnEnter( EnterInt1_ ) + << OnExit( AddInt_ ) ) + << ( Rule() << "int2" << Text( ) + << ( SRD::Times( 2 ) << Word( ) ) + << EnterContext( "int" ) + << OnEnter( EnterInt2_ ) + << OnExit( AddInt_ ) ) + << ( Rule() << "int3" << Text( ) + << ( SRD::Times( 3 ) << Word( ) ) + << EnterContext( "int" ) + << OnEnter( EnterInt3_ ) + << OnExit( AddInt_ ) ) + << ( Rule() << "int4" << Text( ) + << ( SRD::Times( 4 ) << Word( ) ) + << EnterContext( "int" ) + << OnEnter( EnterInt4_ ) + << OnExit( AddInt_ ) ) ; // Floating point control parameters @@ -220,6 +339,14 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( ) << ( Rule() << "decimals" << Integer() << FloatSetDecimals_ ) ; + // Integer control parameters + defs.context( "int" ) + << ( Rule() << "slider" << IntSetSlider_ ) + << ( Rule() << "min" << Int32() << IntSetMin_ ) + << ( Rule() << "max" << Int32() << IntSetMax_ ) + << ( Rule() << "step" << Numeric() << IntSetStep_ ) + ; + return T_SRDParserConfig{ defs }; } @@ -312,7 +439,7 @@ T_Float2::T_Float2( T_String const& input0 , T_String const& input1 , T_String const& title ) noexcept - : A_Float( "float" , title ) + : A_Float( "float2" , title ) { inputs_.add( input0 ); inputs_.add( input1 ); @@ -348,7 +475,7 @@ T_Float3::T_Float3( T_String const& input1 , T_String const& input2 , T_String const& title ) noexcept - : A_Float( "float" , title ) + : A_Float( "float3" , title ) { inputs_.add( input0 ); inputs_.add( input1 ); @@ -386,7 +513,7 @@ T_Float4::T_Float4( T_String const& input2 , T_String const& input3 , T_String const& title ) noexcept - : A_Float( "float" , title ) + : A_Float( "float4" , title ) { inputs_.add( input0 ); inputs_.add( input1 ); @@ -415,3 +542,170 @@ void T_Float4::makeEditWidgets( } } } + + +/*= A_Integer ==================================================================*/ + +bool A_Integer::setMin( + const int32_t v ) noexcept +{ + M_SETOPT_( min_ , v ); +} + +bool A_Integer::setMax( + const int32_t v ) noexcept +{ + M_SETOPT_( max_ , v ); +} + +bool A_Integer::setStep( + const float v ) noexcept +{ + assert( v > 0 ); + M_SETOPT_( step_ , v ); +} + +void A_Integer::setSlider( ) noexcept +{ + slider_ = true; +} + + +/*= T_Integer ==================================================================*/ + +T_Integer::T_Integer( + T_String const& input , + T_String const& title ) noexcept + : A_Integer( "int" , title ) +{ + inputs_.add( input ); +} + +void T_Integer::makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept +{ + using namespace ImGui; + int32_t v[ 1 ] = { + int32_t( Globals::Sync( ).inputs( )[ inputPos_[ 0 ] ] ) + }; + + char const* const label( buildLabel( counter , sb ) ); + const bool changed( slider( ) + ? SliderInt( label , v , min( ) , max( ) ) + : DragInt( label , v , step( ) , min( ) , max( ) ) ); + if ( changed ) { + Globals::Sync( ).inputs( )[ inputPos_[ 0 ] ] = v[ 0 ]; + } +} + + +/*= T_Integer2 =================================================================*/ + +T_Integer2::T_Integer2( + T_String const& input0 , + T_String const& input1 , + T_String const& title ) noexcept + : A_Integer( "int2" , title ) +{ + inputs_.add( input0 ); + inputs_.add( input1 ); +} + +void T_Integer2::makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept +{ + using namespace ImGui; + auto& sinp( Globals::Sync( ).inputs( ) ); + int32_t v[ 2 ]; + for ( auto i = 0 ; i < 2 ; i ++ ) { + v[ i ] = sinp[ inputPos_[ i ] ]; + } + + char const* const label( buildLabel( counter , sb ) ); + const bool changed( slider( ) + ? SliderInt2( label , v , min( ) , max( ) ) + : DragInt2( label , v , step( ) , min( ) , max( ) ) ); + if ( changed ) { + for ( auto i = 0 ; i < 2 ; i ++ ) { + sinp[ inputPos_[ i ] ] = v[ i ]; + } + } +} + + +/*= T_Integer3 =================================================================*/ + +T_Integer3::T_Integer3( + T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& title ) noexcept + : A_Integer( "int3" , title ) +{ + inputs_.add( input0 ); + inputs_.add( input1 ); + inputs_.add( input2 ); +} + +void T_Integer3::makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept +{ + using namespace ImGui; + auto& sinp( Globals::Sync( ).inputs( ) ); + int32_t v[ 3 ]; + for ( auto i = 0 ; i < 3 ; i ++ ) { + v[ i ] = sinp[ inputPos_[ i ] ]; + } + + char const* const label( buildLabel( counter , sb ) ); + const bool changed( slider( ) + ? SliderInt3( label , v , min( ) , max( ) ) + : DragInt3( label , v , step( ) , min( ) , max( ) ) ); + if ( changed ) { + for ( auto i = 0 ; i < 3 ; i ++ ) { + sinp[ inputPos_[ i ] ] = v[ i ]; + } + } +} + + +/*= T_Integer4 =================================================================*/ + +T_Integer4::T_Integer4( + T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& input3 , + T_String const& title ) noexcept + : A_Integer( "int4" , title ) +{ + inputs_.add( input0 ); + inputs_.add( input1 ); + inputs_.add( input2 ); + inputs_.add( input3 ); +} + +void T_Integer4::makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept +{ + using namespace ImGui; + auto& sinp( Globals::Sync( ).inputs( ) ); + int32_t v[ 4 ]; + for ( auto i = 0 ; i < 4 ; i ++ ) { + v[ i ] = sinp[ inputPos_[ i ] ]; + } + + char const* const label( buildLabel( counter , sb ) ); + const bool changed( slider( ) + ? SliderInt4( label , v , min( ) , max( ) ) + : DragInt4( label , v , step( ) , min( ) , max( ) ) ); + if ( changed ) { + for ( auto i = 0 ; i < 4 ; i ++ ) { + sinp[ inputPos_[ i ] ] = v[ i ]; + } + } +} diff --git a/syncoverrides.hh b/syncoverrides.hh index dc4c1dd..d4855a4 100644 --- a/syncoverrides.hh +++ b/syncoverrides.hh @@ -96,6 +96,94 @@ class T_Float4 : public A_Float }; +/*= INTEGER DRAGGERS/SLIDES ====================================================*/ + +// Integers, common +class A_Integer : public A_SyncOverride +{ + private: + T_Optional< int32_t > min_; + T_Optional< int32_t > max_; + T_Optional< float > step_; + bool slider_; + + protected: + A_Integer( char const* const type , + T_String const& title ) noexcept + : A_SyncOverride( type , title ) + {} + + public: + A_Integer( T_String const& input , + T_String const& title ) noexcept; + + bool setMin( const int32_t v ) noexcept; + bool setMax( const int32_t v ) noexcept; + bool setStep( const float v ) noexcept; + bool setPower( const float v ) noexcept; + void setSlider( ) noexcept; + + float min( ) const noexcept { return min_ ? *min_ : 0.0f; } + float max( ) const noexcept { return max_ ? *max_ : 0.0f; } + float step( ) const noexcept { return step_ ? *step_ : .001f; } + bool slider( ) const noexcept { return slider_; } +}; + +// Single integers +class T_Integer : public A_Integer +{ + protected: + void makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept override; + public: + T_Integer( T_String const& input , + T_String const& title ) noexcept; +}; + +// 2 integers +class T_Integer2 : public A_Integer +{ + protected: + void makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept override; + public: + T_Integer2( T_String const& input0 , + T_String const& input1 , + T_String const& title ) noexcept; +}; + +// 3 integers +class T_Integer3 : public A_Integer +{ + protected: + void makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept override; + public: + T_Integer3( T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& title ) noexcept; +}; + +// 4 integers +class T_Integer4 : public A_Integer +{ + protected: + void makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept override; + public: + T_Integer4( T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& input3 , + T_String const& title ) noexcept; +}; + + /*= PARSER CONFIGURATION =======================================================*/ // Get a parser configuration that will be able to parse UI override definitions.