diff --git a/demo.cc b/demo.cc index f5ee2b2..a65169d 100644 --- a/demo.cc +++ b/demo.cc @@ -103,12 +103,22 @@ bool T_Demo::runInit( ov->setMin( 0 ); ov->setMax( 1000 ); ov->setStep( .1 ); +// ov->setSlider( true ); ov->setup( ); T_SyncOverrideSection sos( "" ); sos.subsections.add( NewOwned< T_SyncOverrideSection >( "Testing" ) ); sos.subsections[ 0 ]->subsections.add( NewOwned< T_SyncOverrideSection >( "Yeah really" ) ); sos.subsections[ 0 ]->subsections[ 0 ]->overrides.add( std::move( ov ) ); + + auto ov2{ NewOwned< sov::T_Float4 >( + "bloom-bw0" , "bloom-bw1" , "bloom-bw2" , "bloom-bw3" , + "Blur weights" ) }; + ov2->setMax( 1 ); + ov2->setSlider( ); + ov2->setup( ); + sos.subsections[ 0 ]->overrides.add( std::move( ov2 ) ); + Globals::Sync( ).mergeOverrides( sos ); return true; diff --git a/sync.cc b/sync.cc index c81dcd7..920f631 100644 --- a/sync.cc +++ b/sync.cc @@ -361,9 +361,9 @@ uint32_t T_SyncValues::indexOf( /*= A_SyncOverride ===========================================================*/ A_SyncOverride::A_SyncOverride( - T_String type , + char const* const type , T_String const& title ) noexcept - : type_( std::move( type ) ) , title_( title.size( ) + 1 ) + : type_( T_String::Pooled( type ) ) , title_( title.size( ) + 1 ) { char const* src( title.data( ) ); for ( auto i = 0u ; i < title_.size( ) - 1 ; i ++ ) { @@ -394,15 +394,18 @@ void A_SyncOverride::makeUI( ) noexcept { using namespace ImGui; - Text( "%s" , &title_[ 0 ] ); - if ( Checkbox( "Enable override" , &enabled_ ) ) { - // FIXME: set/clear inputs override flag + if ( Checkbox( &title_[ 0 ] , &enabled_ ) ) { + Globals::Sync( ).setOverridesActive( enabled_ , inputPos_.size( ) , &inputPos_[ 0 ] ); } if ( !enabled_ ) { PushItemFlag( ImGuiItemFlags_Disabled , true ); PushStyleVar( ImGuiStyleVar_Alpha , GetStyle( ).Alpha * 0.5f ); } + Indent( ); + PushItemWidth( -1 ); makeEditWidgets( ); + PopItemWidth( ); + Unindent( ); if ( !enabled_ ) { PopItemFlag( ); PopStyleVar( ); @@ -654,6 +657,26 @@ void T_SyncManager::makeOverridesWindow( ) ImGui::End( ); } +void T_SyncManager::setOverridesActive( + const bool active , + const uint32_t n , + uint32_t const* const pos ) +{ + for ( auto i = 0u ; i < n ; i ++ ) { + assert( values_.overriden[ pos[ i ] ] != active ); + values_.overriden[ pos[ i ] ] = active; + } + if ( !active ) { + for ( auto i = 0u ; i < n ; i ++ ) { + const auto p{ pos[ i ] }; + auto const& cc( curveCaches_[ p ] ); + if ( cc ) { + values_.values[ p ] = cc->value( time_ , curves_ ); + } + } + } +} + #if 0 void T_SyncManager::makeUI( ) { diff --git a/sync.hh b/sync.hh index f4386b4..99df68d 100644 --- a/sync.hh +++ b/sync.hh @@ -178,7 +178,7 @@ class A_SyncOverride ebcl::UseTag< ebcl::ArrayBacked< 8 > >( ) }; T_AutoArray< uint32_t , 8 > inputPos_; - A_SyncOverride( T_String type , + A_SyncOverride( char const* type , T_String const& title ) noexcept; // Draw the UI for that specific override. @@ -268,6 +268,8 @@ struct T_SyncManager { return values_.indexOf( name ); } T_Array< float > const& inputs( ) const noexcept { return values_.values; } + T_Array< float >& inputs( ) noexcept + { return values_.values; } // --------------------------------------------------------------------- // Curves @@ -288,6 +290,11 @@ struct T_SyncManager void mergeOverrides( T_SyncOverrideSection& overrides ); void makeOverridesWindow( ); + // Mark a bunch of inputs as overridden / not overridden + void setOverridesActive( bool active , + uint32_t n , + uint32_t const* pos ); + // --------------------------------------------------------------------- // Update diff --git a/syncoverrides.cc b/syncoverrides.cc index 3af87cf..6bceb92 100644 --- a/syncoverrides.cc +++ b/syncoverrides.cc @@ -10,39 +10,28 @@ using namespace sov; return true -/*= T_Float ====================================================================*/ +/*= A_Float ====================================================================*/ -T_Float::T_Float( - T_String const& input , - T_String const& title ) noexcept - : A_SyncOverride( T_String::Pooled( "float" ) , title ) , - title_( title ) -{ - inputs_.add( input ); -} - -/*------------------------------------------------------------------------------*/ - -bool T_Float::setMin( +bool A_Float::setMin( const float v ) noexcept { M_SETOPT_( min_ , v ); } -bool T_Float::setMax( +bool A_Float::setMax( const float v ) noexcept { M_SETOPT_( max_ , v ); } -bool T_Float::setStep( +bool A_Float::setStep( const float v ) noexcept { assert( v > 0 ); M_SETOPT_( step_ , v ); } -bool T_Float::setDecimals( +bool A_Float::setDecimals( const uint32_t n ) noexcept { assert( n <= 100 ); @@ -61,22 +50,142 @@ bool T_Float::setDecimals( return true; } -bool T_Float::setPower( +bool A_Float::setPower( const float v ) noexcept { assert( v > 0 ); M_SETOPT_( power_ , v ); } -/*------------------------------------------------------------------------------*/ +void A_Float::setSlider( ) noexcept +{ + slider_ = true; +} + + +/*= T_Float ====================================================================*/ + +T_Float::T_Float( + T_String const& input , + T_String const& title ) noexcept + : A_Float( "float" , title ) +{ + inputs_.add( input ); +} void T_Float::makeEditWidgets( ) noexcept { + using namespace ImGui; float v[ 1 ] = { Globals::Sync( ).inputs( )[ inputPos_[ 0 ] ] }; - if ( ImGui::DragFloat( "" , v , step( ) , - min( ) , max( ) , decimals( ) , power( ) ) ) { - // FIXME Globals::Sync( ).inputs( )[ inputPos_[ 0 ] ] = v[ 0 ]; + + const bool changed( slider( ) + ? SliderFloat( "" , v , min( ) , max( ) , decimals( ) , power( ) ) + : DragFloat( "" , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) ); + if ( changed ) { + Globals::Sync( ).inputs( )[ inputPos_[ 0 ] ] = v[ 0 ]; + } +} + + +/*= T_Float2 ===================================================================*/ + +T_Float2::T_Float2( + T_String const& input0 , + T_String const& input1 , + T_String const& title ) noexcept + : A_Float( "float" , title ) +{ + inputs_.add( input0 ); + inputs_.add( input1 ); +} + +void T_Float2::makeEditWidgets( ) noexcept +{ + using namespace ImGui; + auto& sinp( Globals::Sync( ).inputs( ) ); + float v[ 2 ]; + for ( auto i = 0 ; i < 2 ; i ++ ) { + v[ i ] = sinp[ inputPos_[ i ] ]; + } + + const bool changed( slider( ) + ? SliderFloat2( "" , v , min( ) , max( ) , decimals( ) , power( ) ) + : DragFloat2( "" , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) ); + if ( changed ) { + for ( auto i = 0 ; i < 2 ; i ++ ) { + sinp[ inputPos_[ i ] ] = v[ i ]; + } + } +} + + +/*= T_Float3 ===================================================================*/ + +T_Float3::T_Float3( + T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& title ) noexcept + : A_Float( "float" , title ) +{ + inputs_.add( input0 ); + inputs_.add( input1 ); + inputs_.add( input2 ); +} + +void T_Float3::makeEditWidgets( ) noexcept +{ + using namespace ImGui; + auto& sinp( Globals::Sync( ).inputs( ) ); + float v[ 3 ]; + for ( auto i = 0 ; i < 3 ; i ++ ) { + v[ i ] = sinp[ inputPos_[ i ] ]; + } + + const bool changed( slider( ) + ? SliderFloat3( "" , v , min( ) , max( ) , decimals( ) , power( ) ) + : DragFloat3( "" , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) ); + if ( changed ) { + for ( auto i = 0 ; i < 3 ; i ++ ) { + sinp[ inputPos_[ i ] ] = v[ i ]; + } + } +} + + +/*= T_Float4 ===================================================================*/ + +T_Float4::T_Float4( + T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& input3 , + T_String const& title ) noexcept + : A_Float( "float" , title ) +{ + inputs_.add( input0 ); + inputs_.add( input1 ); + inputs_.add( input2 ); + inputs_.add( input3 ); +} + +void T_Float4::makeEditWidgets( ) noexcept +{ + using namespace ImGui; + auto& sinp( Globals::Sync( ).inputs( ) ); + float v[ 4 ]; + for ( auto i = 0 ; i < 4 ; i ++ ) { + v[ i ] = sinp[ inputPos_[ i ] ]; + } + + const bool changed( slider( ) + ? SliderFloat4( "" , v , min( ) , max( ) , decimals( ) , power( ) ) + : DragFloat4( "" , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) ); + if ( changed ) { + for ( auto i = 0 ; i < 4 ; i ++ ) { + sinp[ inputPos_[ i ] ] = v[ i ]; + } } } diff --git a/syncoverrides.hh b/syncoverrides.hh index fb4ae14..0cf134e 100644 --- a/syncoverrides.hh +++ b/syncoverrides.hh @@ -3,24 +3,27 @@ namespace sov { -/*= FLOATING POINT SLIDERS =====================================================*/ +/*= FLOATING POINT DRAGGERS/SLIDERS ============================================*/ -// Single float value -class T_Float : public A_SyncOverride +// Float values, common +class A_Float : public A_SyncOverride { private: - T_String title_; T_Optional< float > min_; T_Optional< float > max_; T_Optional< float > step_; T_Optional< ebcl::T_StaticArray< char , 12 > > decimals_; T_Optional< float > power_; + bool slider_; protected: - void makeEditWidgets( ) noexcept override; + A_Float( char const* const type , + T_String const& title ) noexcept + : A_SyncOverride( type , title ) + {} public: - T_Float( T_String const& input , + A_Float( T_String const& input , T_String const& title ) noexcept; bool setMin( const float v ) noexcept; @@ -28,13 +31,62 @@ class T_Float : public A_SyncOverride bool setStep( const float v ) noexcept; bool setDecimals( const uint32_t n ) 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; } char const* decimals( ) const noexcept { return decimals_ ? &(*decimals_)[ 0 ] : "%.3f"; } float power( ) const noexcept { return power_ ? *power_ : 1.0f; } + bool slider( ) const noexcept { return slider_; } +}; + +// Single float values +class T_Float : public A_Float +{ + protected: + void makeEditWidgets( ) noexcept override; + public: + T_Float( T_String const& input , + T_String const& title ) noexcept; +}; + +// 2 float values +class T_Float2 : public A_Float +{ + protected: + void makeEditWidgets( ) noexcept override; + public: + T_Float2( T_String const& input0 , + T_String const& input1 , + T_String const& title ) noexcept; +}; + +// 3 float values +class T_Float3 : public A_Float +{ + protected: + void makeEditWidgets( ) noexcept override; + public: + T_Float3( T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& title ) noexcept; +}; + +// 4 float values +class T_Float4 : public A_Float +{ + protected: + void makeEditWidgets( ) noexcept override; + public: + T_Float4( T_String const& input0 , + T_String const& input1 , + T_String const& input2 , + T_String const& input3 , + T_String const& title ) noexcept; }; + } // namespace