UI overhaul

* Use menus instead of a silly window with checkboxes
* Windows can be closed, cannot be collapsed
* Left side windows have more vertical space
* Specific window for the sequencer
This commit is contained in:
Emmanuel BENOîT 2017-11-19 10:21:08 +01:00
parent f16ff2ec2e
commit 2c97f3a52e
11 changed files with 167 additions and 169 deletions

10
demo.cc
View file

@ -28,15 +28,7 @@ void T_Demo::render( )
} }
auto& sync( Globals::Sync( ) ); auto& sync( Globals::Sync( ) );
if ( playing ) { sync.updateTime( );
const float time = SDL_GetTicks( ) * 1e-3;
if ( playingPrevious ) {
sync.timeDelta( time - lastFrame );
playing = !sync.finished( );
}
lastFrame = time;
}
playingPrevious = playing;
if ( context && !context->aborted ) { if ( context && !context->aborted ) {
try { try {

View file

@ -32,8 +32,6 @@ struct T_Demo
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
bool playing = false;
private: private:
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
@ -41,8 +39,5 @@ struct T_Demo
T_OwnPtr< ops::T_OpProgram > program; T_OwnPtr< ops::T_OpProgram > program;
T_OwnPtr< ops::T_OpContext > context; T_OwnPtr< ops::T_OpContext > context;
bool playingPrevious = false;
float lastFrame;
bool runInit( ops::T_OpProgram& program ); bool runInit( ops::T_OpProgram& program );
}; };

View file

@ -444,6 +444,8 @@
) )
) )
) )
# FIXME: overrides for vignette
# FIXME: overrides for color grading
) )
) )

51
main.cc
View file

@ -178,42 +178,35 @@ void T_Main::handleCapture( )
void T_Main::makeUI( ) void T_Main::makeUI( )
{ {
ImGui::SetNextWindowSize( ImVec2( 300 , 150 ) , using namespace ImGui;
ImGuiSetCond_Once ); if ( BeginMainMenuBar( ) ) {
ImGui::SetNextWindowPos( ImVec2( ) , ImGuiSetCond_Once ); if ( BeginMenu( "File" ) ) {
ImGui::Begin( "Tools" ); if ( MenuItem( "Quit" ) ) {
done = true;
ImGui::Checkbox( "Output debugger" , &Globals::ODbg( ).uiEnabled( ) ); }
ImGui::Checkbox( "Profiler" , &Globals::Profiler( ).uiEnabled( ) ); EndMenu( );
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( ) );
const float duration( sync.duration( ) );
float time( sync.time( ) );
if ( ImGui::SliderFloat( "" , &time , 0 , duration , "%.1fs" ) ) {
sync.setTime( time );
demo->playing = demo->playing && ! sync.finished( );
} }
ImGui::SameLine( ); if ( BeginMenu( "Views" ) ) {
if ( ImGui::Button( demo->playing ? "Stop" : "Play" ) ) { MenuItemCheckbox( "Input overrides" ,
demo->playing = !demo->playing; &Globals::Sync( ).overridesWindowEnabled( ) );
MenuItemCheckbox( "Output debugger" ,
&Globals::ODbg( ).uiEnabled( ) );
MenuItemCheckbox( "Profiler" ,
&Globals::Profiler( ).uiEnabled( ) );
MenuItemCheckbox( "Sequencer" ,
&Globals::Sync( ).sequencerWindowEnabled( ) );
MenuItemCheckbox( "Shaders" ,
&Globals::Shaders( ).uiEnabled( ) );
EndMenu( );
} }
EndMainMenuBar( );
} }
ImGui::End( );
Globals::Profiler( ).makeUI( ); Globals::Profiler( ).makeUI( );
Globals::ODbg( ).makeUI( ); Globals::ODbg( ).makeUI( );
Globals::Shaders( ).makeUI( ); Globals::Shaders( ).makeUI( );
if ( lol ) { Globals::Sync( ).makeOverridesWindow( );
Globals::Sync( ).makeOverridesWindow( ); Globals::Sync( ).makeSequencerWindow( );
}
} }
void T_Main::render( ) void T_Main::render( )

22
odbg.cc
View file

@ -41,12 +41,12 @@ void T_OutputDebugger::makeUI( )
if ( !enabled_ ) { if ( !enabled_ ) {
return; return;
} }
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
ImGui::SetNextWindowSize( ImVec2( 300 , dspSize.y - 300 ) , using namespace ImGui;
ImGuiSetCond_Once ); auto const& dspSize( GetIO( ).DisplaySize );
ImGui::SetNextWindowPos( ImVec2( 0 , 150 ) , SetNextWindowSize( ImVec2( 300 , dspSize.y - 170 ) , ImGuiSetCond_Appearing );
ImGuiSetCond_Once ); SetNextWindowPos( ImVec2( 0 , 20 ) , ImGuiSetCond_Appearing );
ImGui::Begin( "Output debugger" ); Begin( "Output debugger" , &enabled_ , ImGuiWindowFlags_NoCollapse );
// Main selector // Main selector
if ( selectorItems_ == nullptr ) { if ( selectorItems_ == nullptr ) {
@ -60,11 +60,11 @@ void T_OutputDebugger::makeUI( )
} }
} }
assert( csi != -1 ); assert( csi != -1 );
if ( ImGui::Combo( "Output" , &csi , selectorItems_ ) ) { if ( Combo( "Output" , &csi , selectorItems_ ) ) {
selected_ = selectorMapping_[ csi ]; selected_ = selectorMapping_[ csi ];
} }
if ( selected_ == -1 ) { if ( selected_ == -1 ) {
ImGui::End( ); End( );
return; return;
} }
@ -77,13 +77,13 @@ void T_OutputDebugger::makeUI( )
ptr += 1 + snprintf( ptr , sizeof( lodCombo ) - ( ptr - lodCombo ) , "%d" , i ); ptr += 1 + snprintf( ptr , sizeof( lodCombo ) - ( ptr - lodCombo ) , "%d" , i );
} }
*ptr = 0; *ptr = 0;
ImGui::Combo( "Level" , &t.lod , lodCombo ); Combo( "Level" , &t.lod , lodCombo );
} }
// Submode selector // Submode selector
ImGui::Combo( "Display" , &t.submode , smCombo_[ int( t.mode ) ] ); Combo( "Display" , &t.submode , smCombo_[ int( t.mode ) ] );
ImGui::End( ); End( );
} }
void T_OutputDebugger::registerTexture( void T_OutputDebugger::registerTexture(

View file

@ -119,10 +119,10 @@ void T_Profiler::makeUI( )
auto const& dspSize( ImGui::GetIO( ).DisplaySize ); auto const& dspSize( ImGui::GetIO( ).DisplaySize );
ImGui::SetNextWindowSize( ImVec2( dspSize.x , 150 ) , ImGui::SetNextWindowSize( ImVec2( dspSize.x , 150 ) ,
ImGuiSetCond_Once ); ImGuiSetCond_Appearing );
ImGui::SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , ImGui::SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) ,
ImGuiSetCond_Once ); ImGuiSetCond_Appearing );
ImGui::Begin( "Profiler" ); ImGui::Begin( "Profiler" , &uiEnabled_ , ImGuiWindowFlags_NoCollapse );
ImGui::BeginChild( "left" , ImVec2( 180 , 0 ) , true ); ImGui::BeginChild( "left" , ImVec2( 180 , 0 ) , true );
float angle( 0 ); float angle( 0 );

View file

@ -1111,12 +1111,11 @@ void T_ShaderManager::makeUI( )
return; return;
} }
auto const& dspSize( ImGui::GetIO( ).DisplaySize ); using namespace ImGui;
ImGui::SetNextWindowSize( ImVec2( dspSize.x , 150 ) , auto const& dspSize( GetIO( ).DisplaySize );
ImGuiSetCond_Once ); SetNextWindowSize( ImVec2( dspSize.x , 150 ) , ImGuiSetCond_Appearing );
ImGui::SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , ImGuiSetCond_Appearing );
ImGuiSetCond_Once ); Begin( "Shaders" , &uiEnabled_ , ImGuiWindowFlags_NoCollapse );
ImGui::Begin( "Shaders" );
const auto n( std::count_if( programs_.begin( ) , programs_.end( ) , const auto n( std::count_if( programs_.begin( ) , programs_.end( ) ,
[]( auto const& p ) { []( auto const& p ) {
@ -1149,40 +1148,40 @@ void T_ShaderManager::makeUI( )
const auto nErrors( program.code.errors.size( ) ); const auto nErrors( program.code.errors.size( ) );
const bool open( nErrors const bool open( nErrors
? ImGui::TreeNodeEx( &program , ImGuiTreeNodeFlags_OpenOnArrow ? TreeNodeEx( &program , ImGuiTreeNodeFlags_OpenOnArrow
| ImGuiTreeNodeFlags_OpenOnDoubleClick , "%s" , | ImGuiTreeNodeFlags_OpenOnDoubleClick , "%s" ,
program.name.toOSString( ).data( ) ) program.name.toOSString( ).data( ) )
: false ); : false );
if ( !nErrors ) { if ( !nErrors ) {
ImGui::Text( "%s" , program.name.toOSString( ).data( ) ); Text( "%s" , program.name.toOSString( ).data( ) );
} }
ImGui::SameLine( 400 ); SameLine( 400 );
ImGui::Text( "Usage: %u" , program.plReferences.size( ) + program.saReferences ); Text( "Usage: %u" , program.plReferences.size( ) + program.saReferences );
ImGui::SameLine( 550 ); SameLine( 550 );
if ( program.code.errors.empty( ) ) { if ( program.code.errors.empty( ) ) {
ImGui::PushStyleColor( ImGuiCol_Text , ImVec4( .6 , 1 , .6 , 1 ) ); PushStyleColor( ImGuiCol_Text , ImVec4( .6 , 1 , .6 , 1 ) );
ImGui::Text( "No errors" ); Text( "No errors" );
} else { } else {
ImGui::PushStyleColor( ImGuiCol_Text , ImVec4( 1 , .6 , .6 , 1 ) ); PushStyleColor( ImGuiCol_Text , ImVec4( 1 , .6 , .6 , 1 ) );
ImGui::Text( "%u error%s" , nErrors , nErrors > 1 ? "s" : "" ); Text( "%u error%s" , nErrors , nErrors > 1 ? "s" : "" );
} }
ImGui::PopStyleColor( ); PopStyleColor( );
if ( open ) { if ( open ) {
for ( auto const& err : program.code.errors ) { for ( auto const& err : program.code.errors ) {
ImGui::NewLine( ); NewLine( );
ImGui::SameLine( 50 ); SameLine( 50 );
ImGui::Text( "%s" , err.source.toOSString( ).data( ) ); Text( "%s" , err.source.toOSString( ).data( ) );
ImGui::SameLine( 250 ); SameLine( 250 );
ImGui::Text( "line %d" , err.line ); Text( "line %d" , err.line );
ImGui::SameLine( 370 ); SameLine( 370 );
ImGui::Text( "%s" , err.error.toOSString( ).data( ) ); Text( "%s" , err.error.toOSString( ).data( ) );
} }
ImGui::TreePop( ); TreePop( );
} }
} }
ImGui::End( ); End( );
} }

148
sync.cc
View file

@ -540,6 +540,19 @@ void T_SyncManager::setTime(
updateValues( ); updateValues( );
} }
void T_SyncManager::updateTime( ) noexcept
{
if ( playing_ ) {
const float time( SDL_GetTicks( ) * 1e-3 );
if ( playingPrevious_ ) {
timeDelta( time - lastFrame_ );
playing_ = !finished( );
}
lastFrame_ = time;
}
playingPrevious_ = playing_;
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void T_SyncManager::checkCurveFile( ) void T_SyncManager::checkCurveFile( )
@ -674,28 +687,6 @@ void T_SyncManager::mergeOverrides(
); );
} }
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 {
T_StringBuilder temp;
uint32_t counter{ 0 };
for ( auto& section : soRoot_.subsections ) {
section->makeUI( counter , temp , true );
}
}
ImGui::End( );
}
void T_SyncManager::setOverridesActive( void T_SyncManager::setOverridesActive(
const bool active , const bool active ,
const uint32_t n , const uint32_t n ,
@ -716,76 +707,61 @@ void T_SyncManager::setOverridesActive(
} }
} }
#if 0 /*------------------------------------------------------------------------------*/
void T_SyncManager::makeUI( )
{
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
if ( wOverrides ) { void T_SyncManager::makeSequencerWindow( )
ImGui::SetNextWindowSize( ImVec2( 300 , dspSize.y - 300 ) , {
ImGuiSetCond_Once ); if ( !tmWindow_ ) {
ImGui::SetNextWindowPos( ImVec2( 0 , 150 ) , return;
ImGuiSetCond_Once );
ImGui::Begin( "Input overrides" );
displayOvSections( uiRoot , true );
ImGui::End( );
} }
if ( wCurves ) {
ImGui::SetNextWindowSize( ImVec2( dspSize.x , 150 ) , using namespace ImGui;
ImGuiSetCond_Once ); auto const& dspSize( GetIO( ).DisplaySize );
ImGui::SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , SetNextWindowSize( ImVec2( dspSize.x , 150 ) , ImGuiSetCond_Appearing );
ImGuiSetCond_Once ); SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , ImGuiSetCond_Appearing );
ImGui::Begin( "Curve editor" ); Begin( "Sequencer" , &tmWindow_ , ImGuiWindowFlags_NoCollapse );
// XXX contents
ImGui::End( ); PushID( "playing" );
if ( Button( playing_ ? "Stop" : "Play" ) ) {
playing_ = !playing_;
} }
PopID( );
const float d( duration( ) );
float tm( time( ) );
SameLine( );
PushID( "sequencer" );
PushItemWidth( -1 );
if ( SliderFloat( "" , &tm , 0 , d , "%.1fs" ) ) {
setTime( tm );
playing_ = playing_ && !finished( );
}
PopItemWidth( );
PopID( );
End( );
} }
void T_SyncManager::displayOvSections( void T_SyncManager::makeOverridesWindow( )
T_SyncUISections& sections ,
const bool topLevel )
{ {
for ( auto& s : sections ) { if ( !ovWindow_ ) {
const bool display( topLevel return;
? ImGui::CollapsingHeader( s->title.c_str( ) ) }
: ImGui::TreeNode( s->title.c_str( ) ) );
if ( !display ) { using namespace ImGui;
continue; auto const& dspSize( GetIO( ).DisplaySize );
} SetNextWindowSize( ImVec2( 300 , dspSize.y - 170 ) , ImGuiSetCond_Appearing );
displayOvSections( s->subsections ); SetNextWindowPos( ImVec2( 0 , 20 ) , ImGuiSetCond_Appearing );
if ( s->subsections.size( ) && s->overrides.size( ) ) { Begin( "Input overrides" , &ovWindow_ ,
ImGui::Separator( ); ImGuiWindowFlags_NoCollapse );
}
displayOvControls( s->overrides ); if ( soRoot_.subsections.empty( ) ) {
if ( !topLevel ) { Text( "No overrides have been defined." );
ImGui::TreePop( ); } else {
T_StringBuilder temp;
uint32_t counter{ 0 };
for ( auto& section : soRoot_.subsections ) {
section->makeUI( counter , temp , true );
} }
} }
End( );
} }
void T_SyncManager::displayOvControls(
T_SyncUIOverrides& overrides )
{
for ( auto& o : overrides ) {
// XXX enable override checkbox should be selected and disabled
// if there is no curve
const bool changed( ImGui::Checkbox( "" , &o->enabled ) );
if ( changed ) {
// XXX mark the inputs as coming from the UI / the curves
}
ImGui::SameLine( );
switch ( o->type ) {
case T_SyncUIOverride::FLOAT:
case T_SyncUIOverride::VEC2:
case T_SyncUIOverride::VEC3:
case T_SyncUIOverride::VEC4:
case T_SyncUIOverride::INT:
case T_SyncUIOverride::COLOR:
case T_SyncUIOverride::COLOR_GRADING:
case T_SyncUIOverride::CAMERA:
break;
}
}
}
#endif

20
sync.hh
View file

@ -291,8 +291,11 @@ struct T_SyncManager
float time( ) const noexcept float time( ) const noexcept
{ return time_.time; } { return time_.time; }
bool playing( ) const noexcept
{ return playing_; }
bool finished( ) const noexcept bool finished( ) const noexcept
{ return time_.time >= time_.duration( ); } { return time_.time >= time_.duration( ); }
void updateTime( ) noexcept;
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Value access // Value access
@ -327,7 +330,6 @@ struct T_SyncManager
public: public:
void clearOverrides( ) noexcept; void clearOverrides( ) noexcept;
void mergeOverrides( T_SyncOverrideSection& overrides ); void mergeOverrides( T_SyncOverrideSection& overrides );
void makeOverridesWindow( );
// Mark a bunch of inputs as overridden / not overridden // Mark a bunch of inputs as overridden / not overridden
void setOverridesActive( bool active , void setOverridesActive( bool active ,
@ -340,12 +342,28 @@ struct T_SyncManager
void updateCurveCaches( ); void updateCurveCaches( );
void updateValues( ); void updateValues( );
// ---------------------------------------------------------------------
// User interface
bool& sequencerWindowEnabled( ) noexcept
{ return tmWindow_; }
void makeSequencerWindow( );
bool& overridesWindowEnabled( ) noexcept
{ return ovWindow_; }
void makeOverridesWindow( );
private: private:
ebcl::T_SRDParserConfig pConfig_; // Parser config for curves ebcl::T_SRDParserConfig pConfig_; // Parser config for curves
P_WatchedFiles watcher_; // Curves file watcher P_WatchedFiles watcher_; // Curves file watcher
T_SyncTime time_; // Duration/time information T_SyncTime time_; // Duration/time information
bool playing_{ false }; // Is it playing?
bool playingPrevious_{ false }; // Was it playing before?
float lastFrame_{ 0 }; // Time of last frame
T_SyncValues values_; // Value storage T_SyncValues values_; // Value storage
T_SyncCurves curves_; // Curves storage T_SyncCurves curves_; // Curves storage
bool tmWindow_{ false }; // Sequencer window
T_Array< P_SyncCurveCache > curveCaches_; // Cache for curve segments T_Array< P_SyncCurveCache > curveCaches_; // Cache for curve segments
bool ovWindow_{ false }; // Overrides window
T_SyncOverrideSection soRoot_; // Root for overrides T_SyncOverrideSection soRoot_; // Root for overrides
}; };

View file

@ -69,3 +69,16 @@ T_String GetParentPath(
free( rp ); free( rp );
return rv; return rv;
} }
/*------------------------------------------------------------------------------*/
bool ImGui::MenuItemCheckbox(
char const* name ,
bool* checked )
{
bool rv{ MenuItem( name , "" , *checked , true ) };
if ( rv ) {
*checked = !*checked;
}
return rv;
}

View file

@ -76,3 +76,13 @@ std::string GetAbsolutePath(
// Get the absolute parent path for a (possibly relative) path // Get the absolute parent path for a (possibly relative) path
std::string GetParentPath( std::string GetParentPath(
std::string const& path ); std::string const& path );
/*----------------------------------------------------------------------------*/
namespace ImGui {
bool MenuItemCheckbox(
char const* name ,
bool* checked );
} // namespace ImGui