diff --git a/main.cc b/main.cc index b30a724..34fe7ef 100644 --- a/main.cc +++ b/main.cc @@ -1,5 +1,7 @@ #include "externals.hh" +#define IMGUI_DEFINE_MATH_OPERATORS + #include "imgui_impl_sdl.h" #include "demo.hh" #include "globals.hh" @@ -176,6 +178,184 @@ void T_Main::handleCapture( ) } } +bool CGCModeButton_( + char const* const name , + const bool disabled ) +{ + using namespace ImGui; + if ( disabled ) { + PushItemFlag( ImGuiItemFlags_Disabled , true ); + PushStyleVar( ImGuiStyleVar_Alpha , GetStyle( ).Alpha * 0.5f ); + } + const bool rv( Button( name ) ); + if ( disabled ) { + PopItemFlag( ); + PopStyleVar( ); + } + return rv; +} + +bool CGCComponentBar_( + float* const value , + const float base , + const float unit , + const ImVec4 color , + char const* const label ) noexcept +{ + using namespace ImGui; + + const float BarWidth = 24.f; + const float BarHeight = 180.f; + const float fullWidth = CalcItemWidth( ); + const ImVec2 labelSize = CalcTextSize( label ); + const ImVec2 maxValueSize = CalcTextSize( "-9.99" ); + + // Compute bounding boxes + auto* const win( GetCurrentWindow( ) ); + const ImVec2 cPos( win->DC.CursorPos ); + const ImRect bbBar( cPos + ImVec2( ( fullWidth - BarWidth ) * .5f , 0 ) , + cPos + ImVec2( ( fullWidth + BarWidth ) * .5f , BarHeight ) ); + const ImRect bbLabel( cPos + ImVec2( 0 , BarHeight + 2 ) , + cPos + ImVec2( fullWidth , BarHeight + labelSize.y + 2 ) ); + const ImRect bbValue( ImVec2( cPos.x , bbLabel.Max.y + 2 ) , + bbLabel.Max + ImVec2( 0 , maxValueSize.y + 2 ) ); + const ImRect bbAll( cPos , bbValue.Max ); + auto& style( GetStyle( ) ); + auto id( win->GetID( label ) ); + ItemSize( bbAll , style.FramePadding.y ); + if ( !ItemAdd( bbAll , id ) ) { + return false; + } + + const bool tabFocus{ FocusableItemRegister( win , id ) }; + const bool hovered{ ItemHoverable( bbBar , id ) }; + auto* const ctx( GetCurrentContext( ) ); + if ( tabFocus || ( hovered && ctx->IO.MouseClicked[ 0 ] ) ) { + SetActiveID( id , win ); + FocusWindow( win ); + } + + float nValue{ *value }; + const bool active{ ctx->ActiveId == id }; + if ( active ) { + if ( ctx->IO.MouseDown[ 0 ] ) { + const float mPos{ ctx->IO.MousePos.y }; + const float clickPos{ 1.0f - ImClamp( + ( mPos - bbBar.Min.y - 1 ) / ( BarHeight - 2 ) , + 0.0f , 1.0f ) }; + nValue = base + unit * 2.f * clickPos; + } else { + ClearActiveID( ); + } + } else if ( hovered && ctx->IO.KeyCtrl && ctx->IO.MouseWheel != 0.f ) { + nValue += unit * .01f * ctx->IO.MouseWheel; + ctx->IO.MouseWheel = 0.f; + } + + //- DRAW --------------------------------------------------------------- + + auto* const dl( GetWindowDrawList( ) ); + const auto dispColor{ GetColorU32( ImVec4( + color.x * ( ( hovered || active ) ? 1.f : .5f ) , + color.y * ( ( hovered || active ) ? 1.f : .5f ) , + color.z * ( ( hovered || active ) ? 1.f : .5f ) , + 1 ) ) }; + + // Draw bar body + const ImU32 bgCol{ GetColorU32( + ( ctx->ActiveId == id || hovered ) + ? ImVec4( .25f , .25f , .25f , 1.f ) + : ImVec4( .1f , .1f , .1f , 1.f ) ) }; + const ImU32 fCol{ GetColorU32( + ( ctx->ActiveId == id || hovered ) + ? ImVec4( 1.f , 1.f , 1.f , 1.f ) + : ImVec4( 0.f , 0.f , 0.f , 1.f ) ) }; + dl->AddRectFilled( bbBar.Min , bbBar.Max , bgCol ); + dl->AddRect( bbBar.Min , bbBar.Max , fCol ); + + // Draw colored area on bar + const float val( std::max( base , std::min( unit * 2 , nValue ) ) ); + const float vy2( ( BarHeight - 2 ) * ( 1 - val / ( unit * 2 ) ) ); + dl->AddRectFilled( bbBar.Min + ImVec2( 1 , BarHeight * .5 ) , + bbBar.Min + ImVec2( BarWidth - 1 , 1 + vy2 ) , + dispColor ); + dl->AddLine( bbBar.Min + ImVec2( 1 , BarHeight * .5 ) , + bbBar.Min + ImVec2( BarWidth - 1 , BarHeight * .5 ) , + dispColor ); + + // Draw label & value + const char* tStart = &ctx->TempBuffer[ 0 ]; + const char* tEnd = tStart + ImFormatString( + ctx->TempBuffer, IM_ARRAYSIZE( ctx->TempBuffer ), + "%.2f" , *value ); + PushStyleColor( ImGuiCol_Text , dispColor ); + RenderTextClipped( bbLabel.Min , bbLabel.Max , + label , nullptr , nullptr , + ImVec2( .5f , .5f ) ); + RenderTextClipped( bbValue.Min , bbValue.Max , + tStart , tEnd , nullptr , + ImVec2( .5f , .5f ) ); + PopStyleColor( ); + + if ( nValue != *value ) { + *value = val; + return true; + } + return false; +} + +bool ColorGradingControls( + char const* const name , + float* const red , + float* const green , + float* const blue , + const float base = 0.f , + const float unit = 1.f ) noexcept +{ + using namespace ImGui; + assert( red && green && blue ); + assert( unit > 0.f && "invalid unit" ); + PushID( name ); + BeginGroup( ); + + ImGuiWindow* const window{ GetCurrentWindow() }; + ImGuiStorage* const storage{ window->DC.StateStorage }; + const bool wheelMode{ storage->GetBool( window->GetID( name ) ) }; + + // Mode selection + bool modeChanged{ false }; + modeChanged = CGCModeButton_( "Components" , !wheelMode ); + SameLine( ); + modeChanged = CGCModeButton_( "Color wheel" , wheelMode ) || modeChanged; + if ( modeChanged ) { + storage->SetBool( window->GetID( name ) , !wheelMode ); + } + + bool changed; + if ( wheelMode ^ modeChanged ) { + changed = false; +#warning implement the fuck + } else { + PushItemWidth( -1 ); + PushMultiItemsWidths( 3 ); + changed = CGCComponentBar_( red , base , unit , ImVec4( 1 , 0 , 0 , 0 ) , "R" ); + PopItemWidth( ); + SameLine( 0 , GetStyle( ).ItemInnerSpacing.x ); + changed = CGCComponentBar_( green , base , unit , ImVec4( 0 , 1 , 0 , 0 ) , "G" ) + || changed; + PopItemWidth( ); + SameLine( 0 , GetStyle( ).ItemInnerSpacing.x ); + changed = CGCComponentBar_( blue , base , unit , ImVec4( .3 , .3 , 1 , 0 ) , "B" ) + || changed; + PopItemWidth( ); + PopItemWidth( ); + } + + EndGroup( ); + PopID( ); + return changed; +} + void T_Main::makeUI( ) { using namespace ImGui; @@ -207,6 +387,17 @@ void T_Main::makeUI( ) Globals::Shaders( ).makeUI( ); Globals::Sync( ).makeOverridesWindow( ); Globals::Sync( ).makeSequencerWindow( ); + +#warning color grading widget test + static float cgRed = 1 , cgGreen = 1 , cgBlue = 1; + static float wtf[ 3 ] = { 0 , 0 , 0 }; + auto const& dspSize( GetIO( ).DisplaySize ); + SetNextWindowSize( ImVec2( 300 , 300 ) , ImGuiSetCond_Appearing ); + SetNextWindowPos( ImVec2( ( dspSize.x - 300 ) / 2 , (dspSize.y - 300)/2 ) , ImGuiSetCond_Appearing ); + Begin( "Test!" , nullptr , ImGuiWindowFlags_NoCollapse ); + ColorEdit3( "yo" , wtf ); + ColorGradingControls( "lolwut" , &cgRed , &cgGreen , &cgBlue ); + End( ); } void T_Main::render( )