diff --git a/Makefile b/Makefile index 657dac4..4918771 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,9 @@ COMMON = \ profiling.cc \ shaders.cc \ odbg.cc \ + \ sync.cc \ + syncoverrides.cc \ \ ops.cc \ opast.cc \ diff --git a/demo.cc b/demo.cc index e808411..f5ee2b2 100644 --- a/demo.cc +++ b/demo.cc @@ -8,6 +8,9 @@ #include #include +#warning remove this later +#include "syncoverrides.hh" + bool T_Demo::initialise( const uint32_t w , @@ -94,5 +97,19 @@ bool T_Demo::runInit( } Globals::Sync( ).updateCurveCaches( ); +#warning silly test here + T_OwnPtr< sov::T_Float > ov{ NewOwned< sov::T_Float >( + "dof-sharp-distance" , "Sharp distance" ) }; + ov->setMin( 0 ); + ov->setMax( 1000 ); + ov->setStep( .1 ); + 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 ) ); + Globals::Sync( ).mergeOverrides( sos ); + return true; } diff --git a/demo.srd b/demo.srd index fc1fac0..5e787a0 100644 --- a/demo.srd +++ b/demo.srd @@ -153,12 +153,16 @@ # Input overrides { NOT IMPLEMENTED - (ui-overrides "Post-processing" "Depth of Field" - (float dof-sharp-distance (min 0) (max 1000) (step .1)) - (float dof-sharp-range (min 0) (max 500) (step .1)) - (float dof-falloff (min 0) (max 500) (step .1)) - (float dof-max-blur (min 1) (max 64) (step .1)) - (int dof-samples (min 1) (max 64) (step .1)) + (ui-overrides + (section "Post-processing" + (section "Depth of Field" + (float dof-sharp-distance (min 0) (max 1000) (step .1)) + (float dof-sharp-range (min 0) (max 500) (step .1)) + (float dof-falloff (min 0) (max 500) (step .1)) + (float dof-max-blur (min 1) (max 64) (step .1)) + (int dof-samples (min 1) (max 64) (step .1)) + ) + ) ) } ) diff --git a/imgui b/imgui index d851775..4faf99e 160000 --- a/imgui +++ b/imgui @@ -1 +1 @@ -Subproject commit d851775c80aac7312369739aae6afa25ac31e4ad +Subproject commit 4faf99eff564d68bef9e43cb293c851fc489afc3 diff --git a/main.cc b/main.cc index f199989..df33fb5 100644 --- a/main.cc +++ b/main.cc @@ -187,6 +187,10 @@ void T_Main::makeUI( ) ImGui::Checkbox( "Profiler" , &Globals::Profiler( ).uiEnabled( ) ); ImGui::Checkbox( "Shaders" , &Globals::Shaders( ).uiEnabled( ) ); +#warning big fucking FIXME + static bool lol{ false }; + ImGui::Checkbox( "Input overrides" , &lol ); + if ( demo ) { ImGui::Separator( ); auto& sync( Globals::Sync( ) ); @@ -207,6 +211,9 @@ void T_Main::makeUI( ) Globals::Profiler( ).makeUI( ); Globals::ODbg( ).makeUI( ); Globals::Shaders( ).makeUI( ); + if ( lol ) { + Globals::Sync( ).makeOverridesWindow( ); + } } void T_Main::render( ) diff --git a/sync.cc b/sync.cc index 18b62df..c81dcd7 100644 --- a/sync.cc +++ b/sync.cc @@ -361,9 +361,16 @@ uint32_t T_SyncValues::indexOf( /*= A_SyncOverride ===========================================================*/ A_SyncOverride::A_SyncOverride( - T_String type ) noexcept - : type_( std::move( type ) ) -{ } + T_String type , + T_String const& title ) noexcept + : type_( std::move( type ) ) , title_( title.size( ) + 1 ) +{ + char const* src( title.data( ) ); + for ( auto i = 0u ; i < title_.size( ) - 1 ; i ++ ) { + title_[ i ] = src[ i ]; + } + title_[ title_.size( ) - 1 ] = 0; +} A_SyncOverride::~A_SyncOverride( ) { } @@ -378,7 +385,27 @@ void A_SyncOverride::setup( ) noexcept // FIXME: insufficient; the manager should be made aware of // the presence of an override for that value (and it should // fail for missing values). - inputPos_.add( Globals::Sync( ).inputPos( inputs_[ ni ] ) ); + inputPos_.add( Globals::Sync( ).inputPos( inputs_[ i ] ) ); + } +} + + +void A_SyncOverride::makeUI( ) noexcept +{ + using namespace ImGui; + + Text( "%s" , &title_[ 0 ] ); + if ( Checkbox( "Enable override" , &enabled_ ) ) { + // FIXME: set/clear inputs override flag + } + if ( !enabled_ ) { + PushItemFlag( ImGuiItemFlags_Disabled , true ); + PushStyleVar( ImGuiStyleVar_Alpha , GetStyle( ).Alpha * 0.5f ); + } + makeEditWidgets( ); + if ( !enabled_ ) { + PopItemFlag( ); + PopStyleVar( ); } } @@ -387,7 +414,8 @@ void A_SyncOverride::setup( ) noexcept T_SyncOverrideSection::T_SyncOverrideSection( T_String title ) noexcept - : title( std::move( title ) ) + : title( std::move( title ) ) , + cTitle( this->title.toOSString( ) ) { } void T_SyncOverrideSection::merge( @@ -404,10 +432,9 @@ void T_SyncOverrideSection::merge( void T_SyncOverrideSection::makeUI( const bool topLevel ) noexcept { - // FIXME: fuck that toOSString shit. const bool display( topLevel - ? ImGui::CollapsingHeader( (char*) title.toOSString( ).data( ) ) - : ImGui::TreeNode( (char*) title.toOSString( ).data( ) ) ); + ? ImGui::CollapsingHeader( &cTitle[ 0 ] ) + : ImGui::TreeNode( &cTitle[ 0 ] ) ); if ( !display ) { return; } @@ -455,12 +482,13 @@ T_SyncOverrideSection const* T_SyncOverrideSection::section( T_SyncManager::T_SyncManager( ) : pConfig_( MakeCurvesParser_( ) ) , - pdOverrides_( "default" ) + pdOverrides_( "default" ) , + soRoot_( "*root*" ) { using namespace ebcl::SRD; pdOverrides_.context( "default" ) - << ( Rule( ) << "category" << Text( ) << EnterContext( "category" ) ); - pdOverrides_.context( "category" ); + << ( Rule( ) << "section" << Text( ) << EnterContext( "section" ) ); + pdOverrides_.context( "section" ); } /*----------------------------------------------------------------------------*/ @@ -589,16 +617,43 @@ void T_SyncManager::updateValues( ) /*----------------------------------------------------------------------------*/ -void T_SyncManager::registerOverride( +void T_SyncManager::registerOverrideRule( ebcl::T_SRDInputRule rule ) { - pdOverrides_.context( "category" ) << rule; + pdOverrides_.context( "section" ) << rule; if ( pcOverrides_ ) { pcOverrides_.clear( ); } // pcOverrides_ = NewOwned< T_SRDParserConfig >( pdOverrides_ ); } +void T_SyncManager::mergeOverrides( + T_SyncOverrideSection& overrides ) +{ + assert( overrides.overrides.empty( ) ); + soRoot_.merge( overrides ); +} + +void T_SyncManager::makeOverridesWindow( ) +{ + auto const& dspSize( ImGui::GetIO( ).DisplaySize ); + ImGui::SetNextWindowSize( ImVec2( 300 , dspSize.y - 300 ) , + ImGuiSetCond_Once ); + ImGui::SetNextWindowPos( ImVec2( 0 , 150 ) , + ImGuiSetCond_Once ); + ImGui::Begin( "Input overrides" ); + + if ( soRoot_.subsections.empty( ) ) { + ImGui::Text( "No overrides have been defined." ); + } else { + for ( auto& section : soRoot_.subsections ) { + section->makeUI( true ); + } + } + + ImGui::End( ); +} + #if 0 void T_SyncManager::makeUI( ) { diff --git a/sync.hh b/sync.hh index f0e7ec1..f4386b4 100644 --- a/sync.hh +++ b/sync.hh @@ -1,6 +1,7 @@ #pragma once #include "filewatcher.hh" #include "utilities.hh" +#include "imgui_internal.h" #include #include @@ -168,17 +169,23 @@ using P_SyncOverrideSection = T_OwnPtr< T_SyncOverrideSection >; class A_SyncOverride { private: - T_String type_; + const T_String type_; + bool enabled_{ false }; protected: + ebcl::T_Buffer< char > title_; ebcl::T_Set< T_String > inputs_{ ebcl::UseTag< ebcl::ArrayBacked< 8 > >( ) }; T_AutoArray< uint32_t , 8 > inputPos_; - bool enabled_{ false }; - explicit A_SyncOverride( T_String type ) noexcept; + A_SyncOverride( T_String type , + T_String const& title ) noexcept; + + // Draw the UI for that specific override. + virtual void makeEditWidgets( ) noexcept = 0; public: + A_SyncOverride( ) = delete; virtual ~A_SyncOverride( ) = 0; T_String const& type( ) const noexcept @@ -194,21 +201,22 @@ class A_SyncOverride // the inputs have been added. virtual void setup( ) noexcept; - // Draw the UI for that specific override. - virtual void makeUI( ) noexcept = 0; + // Draw the title, enable button and editor. + virtual void makeUI( ) noexcept; }; // Overrides section struct T_SyncOverrideSection { + const T_String title; + const ebcl::T_Buffer< char > cTitle; bool open{ false }; - T_String title; T_Array< P_SyncOverrideSection > subsections; T_Array< P_SyncOverride > overrides; T_SyncOverrideSection( ) = delete; NO_COPY( T_SyncOverrideSection ); - DEF_MOVE( T_SyncOverrideSection ); + NO_MOVE( T_SyncOverrideSection ); explicit T_SyncOverrideSection( T_String title ) noexcept; @@ -276,7 +284,9 @@ struct T_SyncManager // Overrides public: - void registerOverride( ebcl::T_SRDInputRule rule ); + void registerOverrideRule( ebcl::T_SRDInputRule rule ); + void mergeOverrides( T_SyncOverrideSection& overrides ); + void makeOverridesWindow( ); // --------------------------------------------------------------------- // Update @@ -293,4 +303,5 @@ struct T_SyncManager T_Array< P_SyncCurveCache > curveCaches_; // Cache for curve segments ebcl::T_SRDParserDefs pdOverrides_; // Parser definitions for UI overrides ebcl::OP_SRDParserConfig pcOverrides_; // Parser configuration for UI overrides + T_SyncOverrideSection soRoot_; // Root for overrides }; diff --git a/syncoverrides.cc b/syncoverrides.cc new file mode 100644 index 0000000..3af87cf --- /dev/null +++ b/syncoverrides.cc @@ -0,0 +1,82 @@ +#include "externals.hh" +#include "globals.hh" +#include "syncoverrides.hh" + +using namespace sov; + +#define M_SETOPT_( FIELD , VAR ) \ + if ( FIELD ) { return false; } \ + FIELD = (VAR); \ + return true + + +/*= T_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( + const float v ) noexcept +{ + M_SETOPT_( min_ , v ); +} + +bool T_Float::setMax( + const float v ) noexcept +{ + M_SETOPT_( max_ , v ); +} + +bool T_Float::setStep( + const float v ) noexcept +{ + assert( v > 0 ); + M_SETOPT_( step_ , v ); +} + +bool T_Float::setDecimals( + const uint32_t n ) noexcept +{ + assert( n <= 100 ); + if ( decimals_ ) { + return false; + } + + T_StringBuilder sb; + sb << "%." << n << 'f' << '\0'; + assert( sb.size( ) < 12 ); + decimals_.setNew( ); + for ( auto i = 0u ; i < sb.size( ) ; i ++ ) { + decimals_->add( sb.data( )[ i ] ); + } + + return true; +} + +bool T_Float::setPower( + const float v ) noexcept +{ + assert( v > 0 ); + M_SETOPT_( power_ , v ); +} + +/*------------------------------------------------------------------------------*/ + +void T_Float::makeEditWidgets( ) noexcept +{ + 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 ]; + } +} diff --git a/syncoverrides.hh b/syncoverrides.hh new file mode 100644 index 0000000..fb4ae14 --- /dev/null +++ b/syncoverrides.hh @@ -0,0 +1,40 @@ +#pragma once +#include "sync.hh" + +namespace sov { + +/*= FLOATING POINT SLIDERS =====================================================*/ + +// Single float value +class T_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_; + + protected: + void makeEditWidgets( ) noexcept override; + + public: + T_Float( T_String const& input , + T_String const& title ) noexcept; + + bool setMin( const float v ) noexcept; + bool setMax( const float v ) noexcept; + bool setStep( const float v ) noexcept; + bool setDecimals( const uint32_t n ) noexcept; + bool setPower( const float v ) 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; } +}; + + +} // namespace