UI - Refactoring progress

(see previous log message)
This commit is contained in:
Emmanuel BENOîT 2017-11-23 22:44:20 +01:00
parent b5a5a5298c
commit 942b6f239a
21 changed files with 905 additions and 704 deletions

View file

@ -38,10 +38,14 @@ COMMON = \
opcomp.cc \
opmgr.cc \
\
ui.cc \
ui-actions.cc \
ui-colorgrading.cc \
ui-dialogs.cc \
ui-imgui-sdl.cc \
ui-overrides.cc \
ui-sequencer.cc \
ui-sync.cc \
ui-utilities.cc \
# END COMMON
@ -49,7 +53,6 @@ DEMO = \
demo.cc \
main.cc \
opemu.cc \
ui-sequencer.cc \
# END DEMO
PARSERCHECK = \

View file

@ -2,24 +2,16 @@
#include "globals.hh"
#include "filewatcher.hh"
#include "odbg.hh"
#include "opcomp.hh"
#include "ops.hh"
#include "profiling.hh"
#include "shaders.hh"
#include "sync.hh"
#include "texture.hh"
#include "undo.hh"
#include "window.hh"
T_OwnPtr< T_FilesWatcher > Globals::watcher_;
T_OwnPtr< T_Window > Globals::window_;
T_OwnPtr< T_Profiler > Globals::profiler_;
T_OwnPtr< T_SyncManager > Globals::sync_;
T_OwnPtr< T_TextureManager > Globals::textures_;
T_OwnPtr< T_ShaderManager > Globals::shaders_;
T_OwnPtr< T_OutputDebugger > Globals::odbg_;
T_OwnPtr< T_ScriptManager > Globals::ops_;
T_OwnPtr< T_UndoManager > Globals::undo_;
@ -27,12 +19,8 @@ T_OwnPtr< T_UndoManager > Globals::undo_;
void Globals::Init( )
{
watcher_ = NewOwned< T_FilesWatcher >( );
window_ = NewOwned< T_Window >( );
profiler_ = NewOwned< T_Profiler >( );
sync_ = NewOwned< T_SyncManager >( );
textures_ = NewOwned< T_TextureManager >( );
shaders_ = NewOwned< T_ShaderManager >( );
odbg_ = NewOwned< T_OutputDebugger >( );
ops_ = NewOwned< T_ScriptManager >( );
undo_ = NewOwned< T_UndoManager >( );
}
@ -41,11 +29,7 @@ void Globals::Shutdown( )
{
undo_.clear( );
ops_.clear( );
odbg_.clear( );
shaders_.clear( );
textures_.clear( );
sync_.clear( );
profiler_.clear( );
window_.clear( );
watcher_.clear( );
}

View file

@ -4,12 +4,8 @@
#endif
struct T_Window;
struct T_FilesWatcher;
struct T_Profiler;
struct T_TextureManager;
struct T_ShaderManager;
struct T_OutputDebugger;
struct T_SyncManager;
struct T_ScriptManager;
class T_UndoManager;
@ -21,23 +17,15 @@ struct Globals
static void Shutdown( );
static T_FilesWatcher& Watcher( ) { return *watcher_; }
static T_Window& Window( ) { return *window_; }
static T_Profiler& Profiler( ) { return *profiler_; }
static T_SyncManager& Sync( ) { return *sync_; }
static T_TextureManager& Textures( ) { return *textures_; }
static T_ShaderManager& Shaders( ) { return *shaders_; }
static T_OutputDebugger& ODbg( ) { return *odbg_; }
static T_ScriptManager& Ops( ) { return *ops_; }
static T_UndoManager& Undo( ) { return *undo_; }
private:
static T_OwnPtr< T_FilesWatcher > watcher_;
static T_OwnPtr< T_Window > window_;
static T_OwnPtr< T_Profiler > profiler_;
static T_OwnPtr< T_SyncManager > sync_;
static T_OwnPtr< T_ShaderManager > shaders_;
static T_OwnPtr< T_TextureManager > textures_;
static T_OwnPtr< T_OutputDebugger > odbg_;
static T_OwnPtr< T_ScriptManager > ops_;
static T_OwnPtr< T_UndoManager > undo_;
};

80
main.cc
View file

@ -9,7 +9,9 @@
#include "opemu.hh"
#include "rendertarget.hh"
#include "sync.hh"
#include "ui.hh"
#include "ui-sequencer.hh"
#include "ui-sync.hh"
#include "ui-utilities.hh"
#include "undo.hh"
@ -50,46 +52,8 @@ struct T_Main
T_Main::T_Main( )
{
Globals::Init( );
UI::Init( );
prevSize = ImVec2( -1 , -1 );
// FIXME: should be somewhere else
T_UIAction saveCurves{ "Save curves" , []() {
if ( Globals::Sync( ).curvesFileChanged( ) ) {
Globals::Window( ).msgbox(
"Curves file changed" ,
"The file containing the curves has been modified "
"on the disk. These changes will be overwritten. "
"Do you want to continue?" ,
[]( auto b ) {
if ( b == T_MessageBox::BT_YES ) {
Globals::Sync( ).saveCurves( );
}
} , { T_MessageBox::BT_YES , T_MessageBox::BT_NO } );
} else {
Globals::Sync( ).saveCurves( );
}
} };
saveCurves.setEnabledCheck( []() { return Globals::Sync( ).curvesModified( ); } )
.setIcon( ICON_FA_FLOPPY_O )
.setShortcut( T_KeyboardShortcut{ 's' , E_KeyboardModifier::CTRL } );
Globals::Window( ).addAction( std::move( saveCurves ) );
T_UIAction reloadCurves{ "Reload curves" , []() {
Globals::Window( ).msgbox(
"Reload curves?" ,
"Changes you made to the curves will be lost. Do you "
"want to continue?" ,
[]( auto b ) {
if ( b == T_MessageBox::BT_YES ) {
Globals::Sync( ).loadCurves( );
}
} , { T_MessageBox::BT_YES , T_MessageBox::BT_NO } );
} };
reloadCurves.setEnabledCheck( []() { return Globals::Sync( ).curvesModified( ); } )
.setIcon( ICON_FA_DOWNLOAD )
.setShortcut( T_KeyboardShortcut{ 'r' ,
{ E_KeyboardModifier::CTRL , E_KeyboardModifier::SHIFT } } );
Globals::Window( ).addAction( std::move( reloadCurves ) );
}
void T_Main::mainLoop( )
@ -121,7 +85,7 @@ void T_Main::mainLoop( )
}
Globals::Watcher( ).check( );
Globals::Shaders( ).update( );
UI::Shaders( ).update( );
glFinish( );
p.startFrame( );
@ -132,7 +96,7 @@ void T_Main::mainLoop( )
makeUI( );
render( );
p.end( "Full frame" );
Globals::Window( ).swap( );
UI::Window( ).swap( );
p.endFrame( );
}
}
@ -141,6 +105,7 @@ void T_Main::mainLoop( )
T_Main::~T_Main( )
{
demo.clear( );
UI::Shutdown( );
Globals::Shutdown( );
}
@ -180,7 +145,7 @@ void T_Main::startIteration( )
}
}
Globals::Window( ).startFrame( capture , mouseInitial );
UI::Window( ).startFrame( capture , mouseInitial );
ImGui::GetIO( ).MouseDrawCursor = true;
}
@ -222,11 +187,11 @@ void T_Main::handleCapture( )
capture = false;
CaptureMouseFromApp( false );
SDL_SetRelativeMouseMode( SDL_FALSE );
Globals::Window( ).warpMouse( mouseInitial );
UI::Window( ).warpMouse( mouseInitial );
SetMouseCursor( ImGuiMouseCursor_Arrow );
} else if ( capture ) {
SetMouseCursor( ImGuiMouseCursor_Move );
Globals::Sync( ).handleDragAndDrop( mouseMove , kb , mb );
UI::Sync( ).handleDragAndDrop( mouseMove , kb , mb );
} else if ( appCanGrab && mb ) {
capture = true;
mouseInitial = GetMousePos( );
@ -236,7 +201,7 @@ void T_Main::handleCapture( )
}
if ( ( appCanGrab || capture ) && io.MouseWheel ) {
Globals::Sync( ).handleWheel( io.MouseWheel , kb , mb );
UI::Sync( ).handleWheel( io.MouseWheel , kb , mb );
}
}
@ -244,12 +209,11 @@ void T_Main::makeUI( )
{
using namespace ImGui;
auto& undo( Globals::Undo( ) );
auto& sync( Globals::Sync( ) );
bool eSequencer{ sequencer };
if ( BeginMainMenuBar( ) ) {
if ( BeginMenu( "File" ) ) {
Globals::Window( ).actionMenu( "Save curves" );
Globals::Window( ).actionMenu( "Reload curves" );
UI::Window( ).actionMenu( "Save curves" );
UI::Window( ).actionMenu( "Reload curves" );
Separator( );
if ( MenuItem( "Undo" , "C-z" , false , undo.canUndo( ) ) ) {
undo.undo( );
@ -265,14 +229,14 @@ void T_Main::makeUI( )
}
if ( BeginMenu( "Views" ) ) {
MenuItemCheckbox( "Input overrides" ,
&sync.overridesWindowEnabled( ) );
&UI::Sync( ).overridesWindowEnabled( ) );
MenuItemCheckbox( "Output debugger" ,
&Globals::ODbg( ).uiEnabled( ) );
&UI::ODbg( ).uiEnabled( ) );
MenuItemCheckbox( "Profiler" ,
&Globals::Profiler( ).uiEnabled( ) );
MenuItemCheckbox( "Sequencer" , &eSequencer );
MenuItemCheckbox( "Shaders" ,
&Globals::Shaders( ).uiEnabled( ) );
&UI::Shaders( ).uiEnabled( ) );
EndMenu( );
}
EndMainMenuBar( );
@ -285,9 +249,9 @@ void T_Main::makeUI( )
}
Globals::Profiler( ).makeUI( );
Globals::ODbg( ).makeUI( );
Globals::Shaders( ).makeUI( );
Globals::Sync( ).makeOverridesWindow( );
UI::ODbg( ).makeUI( );
UI::Shaders( ).makeUI( );
UI::Sync( ).makeOverridesWindow( );
if ( sequencer && !sequencer->display( ) ) {
sequencer.clear( );
}
@ -300,8 +264,8 @@ void T_Main::render( )
Globals::Profiler( ).start( "Debug" );
T_Rendertarget::MainOutput( );
if ( Globals::ODbg( ).isActive( ) ) {
Globals::ODbg( ).debugOutput( );
if ( UI::ODbg( ).isActive( ) ) {
UI::ODbg( ).debugOutput( );
}
glFinish( ); Globals::Profiler( ).end( "Debug" );
@ -311,10 +275,10 @@ void T_Main::render( )
glClear( GL_COLOR_BUFFER_BIT );
}
Globals::Window( ).handleDialogs( );
UI::Window( ).handleDialogs( );
glUseProgram( 0 );
glBindProgramPipeline( 0 );
Globals::Textures( ).reset( );
UI::Textures( ).reset( );
glClearColor( 0 , 0 , 0 , 1 );
ImGui::Render( );
}

View file

@ -1,6 +1,6 @@
#include "externals.hh"
#include "odbg.hh"
#include "globals.hh"
#include "ui.hh"
namespace {
@ -108,7 +108,7 @@ void T_OutputDebugger::debugOutput( )
return;
}
auto& tm( Globals::Textures( ) );
auto& tm( UI::Textures( ) );
glBindTextureUnit( 0 , info.id );
glBindSampler( 0 , tm.sampler( "nearest-border" )->id( ) );
@ -138,7 +138,7 @@ void T_OutputDebugger::registerSubmode(
sb << shader << ".glsl" << '\0';
submodes_[ int( mode ) ].add( T_Submode_{
name ,
Globals::Shaders( ).pipeline({
UI::Shaders( ).pipeline({
"fullscreen.v.glsl" , sb.data( ) }) ,
setup
} );

View file

@ -1,6 +1,7 @@
#include "externals.hh"
#include "opemu.hh"
#include "globals.hh"
#include "ui.hh"
#include "profiling.hh"
#include "rendertarget.hh"
#include "sync.hh"
@ -69,7 +70,7 @@ struct T_RunGuard
glUseProgram( 0 );
glBindProgramPipeline( 0 );
glBindFramebuffer( GL_FRAMEBUFFER , 0 );
Globals::Textures( ).reset( );
UI::Textures( ).reset( );
}
};
}
@ -436,7 +437,7 @@ void T_OpContext::run(
}
pipelines[ plIndex ] = NewOwned< T_ShaderPipeline >(
Globals::Shaders( ).pipeline( progNames , instr.args[ 0 ] + 1 ) );
UI::Shaders( ).pipeline( progNames , instr.args[ 0 ] + 1 ) );
break;
}
@ -446,7 +447,7 @@ void T_OpContext::run(
throw X_OpFailure{ instr , "invalid argument" };
}
programs.add( NewOwned< T_ShaderProgram >(
Globals::Shaders( ).program( program.progNames[ instr.args[ 0 ] ] ) ) );
UI::Shaders( ).program( program.progNames[ instr.args[ 0 ] ] ) ) );
wreg = programs.size( );
break;
}
@ -551,7 +552,7 @@ void T_OpContext::run(
throw X_OpFailure{ instr , "invalid sampler" };
}
Globals::Textures( ).bind( instr.args[ 0 ] ,
UI::Textures( ).bind( instr.args[ 0 ] ,
*textures[ svt - 1 ] , *samplers[ svs - 1 ] );
break;
}
@ -710,7 +711,7 @@ void T_OpContext::run(
if ( svt == 0 || svt > textures.size( ) || !textures[ svt - 1 ] ) {
throw X_OpFailure{ instr , "invalid texture" };
}
Globals::ODbg( ).registerTexture( *textures[ svt - 1 ] ,
UI::ODbg( ).registerTexture( *textures[ svt - 1 ] ,
E_ODbgMode( instr.args[ 0 ] ) ,
program.uiStrings[ instr.args[ 1 ] ] );
break;

View file

@ -1,6 +1,7 @@
#include "externals.hh"
#include "shaders.hh"
#include "globals.hh"
#include "ui.hh"
#include "ui-utilities.hh"
#include <ebcl/Sets.hh>
@ -214,14 +215,14 @@ T_ShaderProgram::T_ShaderProgram(
: id_( id )
{
if ( id_ ) {
Globals::Shaders( ).programs_[ id_ - 1 ].saReferences ++;
UI::Shaders( ).programs_[ id_ - 1 ].saReferences ++;
}
}
T_ShaderProgram::~T_ShaderProgram( )
{
if ( id_ ) {
Globals::Shaders( ).dereferenceProgram( id_ - 1 );
UI::Shaders( ).dereferenceProgram( id_ - 1 );
}
}
@ -230,11 +231,11 @@ T_ShaderProgram& T_ShaderProgram::operator=(
{
if ( this != &other ) {
if ( id_ ) {
Globals::Shaders( ).dereferenceProgram( id_ - 1 );
UI::Shaders( ).dereferenceProgram( id_ - 1 );
}
id_ = other.id_;
if ( id_ ) {
Globals::Shaders( ).programs_[ id_ - 1 ].saReferences ++;
UI::Shaders( ).programs_[ id_ - 1 ].saReferences ++;
}
}
return *this;
@ -245,7 +246,7 @@ T_ShaderProgram& T_ShaderProgram::operator=(
{
if ( this != &other ) {
if ( id_ ) {
Globals::Shaders( ).dereferenceProgram( id_ - 1 );
UI::Shaders( ).dereferenceProgram( id_ - 1 );
}
id_ = other.id_;
other.id_ = T_String{};
@ -255,7 +256,7 @@ T_ShaderProgram& T_ShaderProgram::operator=(
bool T_ShaderProgram::valid( ) const noexcept
{
return id_ && Globals::Shaders( ).programs_[ id_ - 1 ].id != 0;
return id_ && UI::Shaders( ).programs_[ id_ - 1 ].id != 0;
}
void T_ShaderProgram::enable( ) const
@ -264,7 +265,7 @@ void T_ShaderProgram::enable( ) const
return;
}
auto const& p( Globals::Shaders( ).programs_[ id_ - 1 ] );
auto const& p( UI::Shaders( ).programs_[ id_ - 1 ] );
if ( p.id ) {
glBindProgramPipeline( 0 );
glUseProgram( p.id );
@ -274,7 +275,7 @@ void T_ShaderProgram::enable( ) const
GLuint T_ShaderProgram::id( ) const
{
if ( id_ ) {
return Globals::Shaders( ).programs_[ id_ - 1 ].id;
return UI::Shaders( ).programs_[ id_ - 1 ].id;
} else {
return 0;
}
@ -283,7 +284,7 @@ GLuint T_ShaderProgram::id( ) const
T_Optional< E_ShaderType > T_ShaderProgram::type( ) const
{
if ( id_ ) {
return Globals::Shaders( ).programs_[ id_ - 1 ].code.type;
return UI::Shaders( ).programs_[ id_ - 1 ].code.type;
} else {
return {};
}
@ -292,7 +293,7 @@ T_Optional< E_ShaderType > T_ShaderProgram::type( ) const
T_String T_ShaderProgram::name( ) const
{
if ( id_ ) {
return Globals::Shaders( ).programs_[ id_ - 1 ].name;
return UI::Shaders( ).programs_[ id_ - 1 ].name;
} else {
return {};
}
@ -321,14 +322,14 @@ T_ShaderPipeline::T_ShaderPipeline( T_String id ) noexcept
: id_( std::move( id ) )
{
if ( id_ ) {
Globals::Shaders( ).pipelines_.get( id_ )->references ++;
UI::Shaders( ).pipelines_.get( id_ )->references ++;
}
}
T_ShaderPipeline::~T_ShaderPipeline( )
{
if ( id_ ) {
Globals::Shaders( ).dereferencePipeline( id_ );
UI::Shaders( ).dereferencePipeline( id_ );
}
}
@ -337,11 +338,11 @@ T_ShaderPipeline& T_ShaderPipeline::operator=(
{
if ( this != &other ) {
if ( id_ ) {
Globals::Shaders( ).dereferencePipeline( id_ );
UI::Shaders( ).dereferencePipeline( id_ );
}
id_ = other.id_;
if ( id_ ) {
Globals::Shaders( ).pipelines_.get( id_ )->references ++;
UI::Shaders( ).pipelines_.get( id_ )->references ++;
}
}
return *this;
@ -352,7 +353,7 @@ T_ShaderPipeline& T_ShaderPipeline::operator=(
{
if ( this != &other ) {
if ( id_ ) {
Globals::Shaders( ).dereferencePipeline( id_ );
UI::Shaders( ).dereferencePipeline( id_ );
}
id_ = other.id_;
other.id_ = T_String{};
@ -363,7 +364,7 @@ T_ShaderPipeline& T_ShaderPipeline::operator=(
bool T_ShaderPipeline::valid( ) const noexcept
{
return id_
&& Globals::Shaders( ).pipelines_.get( id_ )->id != 0;
&& UI::Shaders( ).pipelines_.get( id_ )->id != 0;
}
void T_ShaderPipeline::enable( ) const
@ -372,7 +373,7 @@ void T_ShaderPipeline::enable( ) const
return;
}
auto const* pl( Globals::Shaders( ).pipelines_.get( id_ ) );
auto const* pl( UI::Shaders( ).pipelines_.get( id_ ) );
if ( pl && pl->id ) {
glUseProgram( 0 );
glBindProgramPipeline( pl->id );
@ -382,7 +383,7 @@ void T_ShaderPipeline::enable( ) const
GLuint T_ShaderPipeline::id( ) const
{
if ( id_ ) {
return Globals::Shaders( ).pipelines_.get( id_ )->id;
return UI::Shaders( ).pipelines_.get( id_ )->id;
} else {
return 0;
}
@ -395,7 +396,7 @@ GLuint T_ShaderPipeline::program(
return 0;
}
auto const& sm( Globals::Shaders( ) );
auto const& sm( UI::Shaders( ) );
auto const& pl( *sm.pipelines_.get( id_ ) );
for ( auto const& pn : pl.programs ) {
auto const* pos( sm.programIndex_.get( pn ) );

123
sync.cc
View file

@ -10,18 +10,6 @@
#include <ebcl/SRDParser.hh>
using ebcl::T_SRDParserConfig;
namespace {
const std::map< std::string , T_SyncSegment::E_SegmentType > SegmentTypes_( ([] {
std::map< std::string , T_SyncSegment::E_SegmentType > t;
t.emplace( "linear" , T_SyncSegment::LINEAR );
t.emplace( "ramp" , T_SyncSegment::RAMP );
t.emplace( "smooth" , T_SyncSegment::SMOOTH );
return t;
})());
}
/*= SRD parser for the curves ================================================*/
@ -432,40 +420,6 @@ void A_SyncOverride::setup( ) noexcept
id_ = std::move( sb );
}
char const* A_SyncOverride::buildLabel(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
sb.clear( ) << "temp label " << counter << '\0';
counter ++;
return sb.data( );
}
void A_SyncOverride::makeUI(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
using namespace ImGui;
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( counter , sb );
PopItemWidth( );
Unindent( );
if ( !enabled_ ) {
PopItemFlag( );
PopStyleVar( );
}
}
/*= T_SyncOverrideSection ====================================================*/
@ -486,33 +440,6 @@ void T_SyncOverrideSection::merge(
}
}
void T_SyncOverrideSection::makeUI(
uint32_t& counter ,
T_StringBuilder& tempSb ,
const bool topLevel ) noexcept
{
const bool display( topLevel
? ImGui::CollapsingHeader( &cTitle[ 0 ] )
: ImGui::TreeNode( &cTitle[ 0 ] ) );
if ( !display ) {
return;
}
for ( auto& os : subsections ) {
os->makeUI( counter , tempSb );
}
if ( subsections.size( ) && overrides.size( ) ) {
ImGui::Separator( );
}
for ( auto& ov : overrides ) {
ov->makeUI( counter , tempSb );
}
if ( !topLevel ) {
ImGui::TreePop( );
}
}
T_SyncOverrideSection& T_SyncOverrideSection::section(
T_String const& name ) noexcept
{
@ -803,7 +730,6 @@ void T_SyncManager::updateValues( )
void T_SyncManager::clearOverrides( ) noexcept
{
mouseDelegate_ = nullptr;
soRoot_.subsections.clear( );
soRoot_.overrides.clear( );
soTable_.clear( );
@ -866,52 +792,3 @@ void T_SyncManager::visitOverrides(
{
soVisitor_.visitor.visit( &soRoot_ , visitor );
}
/*------------------------------------------------------------------------------*/
void T_SyncManager::makeOverridesWindow( )
{
if ( !ovWindow_ ) {
return;
}
using namespace ImGui;
auto const& dspSize( GetIO( ).DisplaySize );
SetNextWindowSize( ImVec2( dspSize.x * .25f , dspSize.y * .66f - 20 ) , ImGuiSetCond_Appearing );
SetNextWindowPos( ImVec2( 0 , 20 ) , ImGuiSetCond_Appearing );
Begin( "Input overrides" , &ovWindow_ ,
ImGuiWindowFlags_NoCollapse );
if ( soRoot_.subsections.empty( ) ) {
Text( "No overrides have been defined." );
} else {
T_StringBuilder temp;
uint32_t counter{ 0 };
for ( auto& section : soRoot_.subsections ) {
section->makeUI( counter , temp , true );
}
}
End( );
}
/*------------------------------------------------------------------------------*/
void T_SyncManager::handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
if ( mouseDelegate_ ) {
mouseDelegate_->handleDragAndDrop( move , modifiers , buttons );
}
}
void T_SyncManager::handleWheel(
const float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
if ( mouseDelegate_ ) {
mouseDelegate_->handleWheel( wheel , modifiers , buttons );
}
}

54
sync.hh
View file

@ -1,7 +1,6 @@
#pragma once
#include "filewatcher.hh"
#include "utilities.hh"
#include "ui-mousectrl.hh"
#include <ebcl/SRDParserConfig.hh>
#include <ebcl/Sets.hh>
@ -189,18 +188,6 @@ class A_SyncOverride
A_SyncOverride( char const* type ,
T_String const& title ) noexcept;
// Build a temporary label for use with ImGui. The label is valid
// until the next call to buildLabel(), as it is in fact stored
// in the string builder.
char const* buildLabel(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept;
// Draw the UI for that specific override.
virtual void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept = 0;
public:
A_SyncOverride( ) = delete;
virtual ~A_SyncOverride( ) = 0;
@ -208,9 +195,13 @@ class A_SyncOverride
T_String const& type( ) const noexcept
{ return type_; }
ebcl::T_Set< T_String > const& inputNames( ) const noexcept
auto const& inputNames( ) const noexcept
{ return inputs_; }
auto const& inputPositions( ) const noexcept
{ return inputPos_; }
bool& enabled( ) noexcept
{ return enabled_; }
bool enabled( ) const noexcept
{ return enabled_; }
@ -228,12 +219,6 @@ class A_SyncOverride
// the inputs have been added.
virtual void setup( ) noexcept;
// Draw the title, enable button and editor. The counter and temporary
// string builder are used to generate "fake" labels for ImGui.
virtual void makeUI(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept;
// Create a clone of the current override.
virtual T_OwnPtr< A_SyncOverride > clone( ) const noexcept = 0;
};
@ -288,7 +273,7 @@ struct T_SyncOverrideVisitor
// Synchronisation manager; handles all the synchronization data and makes it
// work together.
struct T_SyncManager : public virtual A_MouseCtrl
struct T_SyncManager
{
T_SyncManager( );
@ -391,30 +376,6 @@ struct T_SyncManager : public virtual A_MouseCtrl
void updateValues( );
// ---------------------------------------------------------------------
// User interface
bool& overridesWindowEnabled( ) noexcept
{ return ovWindow_; }
void makeOverridesWindow( );
void delegateMouse( A_MouseCtrl& delegate ) noexcept
{ mouseDelegate_ = &delegate; }
void clearMouseDelegate( ) noexcept
{ mouseDelegate_ = nullptr; }
bool isCurrentDelegate( A_MouseCtrl const& delegate ) noexcept
{ return mouseDelegate_ == &delegate; }
void handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
void handleWheel(
float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
// ---------------------------------------------------------------------
// Private data
@ -434,11 +395,8 @@ struct T_SyncManager : public virtual A_MouseCtrl
T_SyncCurves curves_; // Curves storage
T_Array< P_SyncCurveCache > curveCaches_; // Cache for curve segments
bool ovWindow_{ false }; // Overrides window
T_SyncOverrideSection soRoot_; // Root for overrides
T_SyncOverrideVisitor soVisitor_;
T_KeyValueTable< T_String , A_SyncOverride* > soTable_;
// Table of sync overrides, by ID
A_MouseCtrl* mouseDelegate_{ nullptr }; // Delegate for mouse actions
};

View file

@ -641,24 +641,6 @@ T_Float::T_Float(
inputs_.add( input );
}
void T_Float::makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
using namespace ImGui;
float v[ 1 ] = {
Globals::Sync( ).inputs( )[ inputPos_[ 0 ] ]
};
char const* const label( buildLabel( counter , sb ) );
const bool changed( slider( )
? SliderFloat( label , v , min( ) , max( ) , decimals( ) , power( ) )
: DragFloat( label , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) );
if ( changed ) {
Globals::Sync( ).inputs( )[ inputPos_[ 0 ] ] = v[ 0 ];
}
}
P_SyncOverride T_Float::clone( ) const noexcept
{
auto c{ NewOwned< T_Float >( inputs_[ 0 ] , &title_[ 0 ] ) };
@ -679,28 +661,6 @@ T_Float2::T_Float2(
inputs_.add( input1 );
}
void T_Float2::makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
using namespace ImGui;
auto& sinp( Globals::Sync( ).inputs( ) );
float 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( )
? SliderFloat2( label , v , min( ) , max( ) , decimals( ) , power( ) )
: DragFloat2( label , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 2 ; i ++ ) {
sinp[ inputPos_[ i ] ] = v[ i ];
}
}
}
P_SyncOverride T_Float2::clone( ) const noexcept
{
auto c{ NewOwned< T_Float2 >( inputs_[ 0 ] , inputs_[ 1 ] , &title_[ 0 ] ) };
@ -723,28 +683,6 @@ T_Float3::T_Float3(
inputs_.add( input2 );
}
void T_Float3::makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
using namespace ImGui;
auto& sinp( Globals::Sync( ).inputs( ) );
float 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( )
? SliderFloat3( label , v , min( ) , max( ) , decimals( ) , power( ) )
: DragFloat3( label , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
sinp[ inputPos_[ i ] ] = v[ i ];
}
}
}
P_SyncOverride T_Float3::clone( ) const noexcept
{
auto c{ NewOwned< T_Float3 >( inputs_[ 0 ] , inputs_[ 1 ] ,
@ -770,28 +708,6 @@ T_Float4::T_Float4(
inputs_.add( input3 );
}
void T_Float4::makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
using namespace ImGui;
auto& sinp( Globals::Sync( ).inputs( ) );
float 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( )
? SliderFloat4( label , v , min( ) , max( ) , decimals( ) , power( ) )
: DragFloat4( label , v , step( ) , min( ) , max( ) , decimals( ) , power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 4 ; i ++ ) {
sinp[ inputPos_[ i ] ] = v[ i ];
}
}
}
P_SyncOverride T_Float4::clone( ) const noexcept
{
auto c{ NewOwned< T_Float4 >( inputs_[ 0 ] , inputs_[ 1 ] ,
@ -838,24 +754,6 @@ T_Integer::T_Integer(
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 ];
}
}
P_SyncOverride T_Integer::clone( ) const noexcept
{
auto c{ NewOwned< T_Integer >( inputs_[ 0 ] , &title_[ 0 ] ) };
@ -876,28 +774,6 @@ T_Integer2::T_Integer2(
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 ];
}
}
}
P_SyncOverride T_Integer2::clone( ) const noexcept
{
auto c{ NewOwned< T_Integer2 >( inputs_[ 0 ] , inputs_[ 1 ] , &title_[ 0 ] ) };
@ -920,28 +796,6 @@ T_Integer3::T_Integer3(
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 ];
}
}
}
P_SyncOverride T_Integer3::clone( ) const noexcept
{
auto c{ NewOwned< T_Integer3 >( inputs_[ 0 ] , inputs_[ 1 ] ,
@ -967,28 +821,6 @@ T_Integer4::T_Integer4(
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 ];
}
}
}
P_SyncOverride T_Integer4::clone( ) const noexcept
{
auto c{ NewOwned< T_Integer4 >( inputs_[ 0 ] , inputs_[ 1 ] ,
@ -1012,30 +844,6 @@ T_ColorGrading::T_ColorGrading(
inputs_.add( iBlue );
}
void T_ColorGrading::makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
using namespace ImGui;
auto& sinp{ Globals::Sync( ).inputs( ) };
float v[ 3 ];
for ( auto i = 0 ; i < 3 ; i ++ ) {
v[ i ] = sinp[ inputPos_[ i ] ];
}
char const* const label{ buildLabel( counter , sb ) };
const bool changed{ ColorGradingControls(
label ,
&v[ 0 ] , &v[ 1 ] , &v[ 2 ] ,
base( ) , unit( ) ) };
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
sinp[ inputPos_[ i ] ] = v[ i ];
}
}
}
bool T_ColorGrading::setBase(
const float v ) noexcept
{
@ -1187,7 +995,7 @@ bool T_CamOverride::checkValidConfig( ) noexcept
/*------------------------------------------------------------------------------*/
T_CamOverride::E_SetState T_CamOverride::setVector(
T_Optional< T_VectorConfig_ >& vector ,
T_Optional< T_VectorConfig >& vector ,
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept
@ -1206,151 +1014,3 @@ T_CamOverride::E_SetState T_CamOverride::setVector(
inputs_.add( inZ );
return S_OK;
}
/*------------------------------------------------------------------------------*/
void T_CamOverride::makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
auto& sync( Globals::Sync( ) );
auto& sinp( sync.inputs( ) );
auto const& fc( *fovConfig_ );
if ( !enabled( ) || !prevEnabled_ ) {
// Set field of view / near plane
if ( fc.mode == FM_FOV ) {
camera_.fieldOfView( sinp[ inputPos_[ fc.inputIndex ] ] );
} else {
camera_.nearPlane( sinp[ inputPos_[ fc.inputIndex ] ] );
}
// Set camera parameters
const glm::vec3 lookAt{ vectorFromInputs( *target_ ) };
if ( camMode_ == CM_ANGLES ) {
const glm::vec3 angles{ vectorFromInputs( *angles_ ) };
const float distance{ sinp[ inputPos_[ *distance_ ] ] };
camera_.camera( lookAt , angles , distance );
} else {
const glm::vec3 position{ vectorFromInputs( *position_ ) };
const glm::vec3 up{ vectorFromInputs( *upVector_ ) };
camera_.camera( lookAt , position , up );
}
}
prevEnabled_ = enabled( );
// Draw UI
char const* const name( buildLabel( counter , sb ) );
bool mouseHandler{ sync.isCurrentDelegate( *this ) };
using namespace ImGui;
PushItemWidth( 0 ); // Compensate for -1
PushID( GetCurrentWindow( )->GetID( name ) );
const bool handlerChanged{ Checkbox( "Mouse control" , &mouseHandler ) };
Separator( );
const auto changes{ camera_.makeUI( ) };
PopID( );
PopItemWidth( );
if ( handlerChanged ) {
if ( mouseHandler ) {
sync.delegateMouse( *this );
} else {
sync.clearMouseDelegate( );
}
}
if ( changes & T_Camera::E_Changes::FOV ) {
if ( fc.mode == FM_FOV ) {
sinp[ inputPos_[ fc.inputIndex ] ] = camera_.fieldOfView( );
} else {
sinp[ inputPos_[ fc.inputIndex ] ] = camera_.nearPlane( );
}
}
if ( changes & T_Camera::E_Changes::MATRIX ) {
inputsFromVector( *target_ , camera_.lookAt( ) );
if ( camMode_ == CM_ANGLES ) {
inputsFromVector( *angles_ , camera_.angles( ) );
sinp[ inputPos_[ *distance_ ] ] = camera_.distance( );
} else {
inputsFromVector( *position_ , camera_.position( ) );
inputsFromVector( *upVector_ , camera_.upVector( ) );
}
}
}
glm::vec3 T_CamOverride::vectorFromInputs(
T_VectorConfig_ const& vc ) noexcept
{
auto& sinp( Globals::Sync( ).inputs( ) );
return glm::vec3{
sinp[ inputPos_[ vc.x ] ] ,
sinp[ inputPos_[ vc.y ] ] ,
sinp[ inputPos_[ vc.z ] ] };
}
void T_CamOverride::inputsFromVector(
T_VectorConfig_ const& vc ,
glm::vec3 const& v ) noexcept
{
auto& sinp( Globals::Sync( ).inputs( ) );
sinp[ inputPos_[ vc.x ] ] = v.x;
sinp[ inputPos_[ vc.y ] ] = v.y;
sinp[ inputPos_[ vc.z ] ] = v.z;
}
/*------------------------------------------------------------------------------*/
void T_CamOverride::handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
auto& sync( Globals::Sync( ) );
if ( !enabled( ) ) {
sync.clearMouseDelegate( );
return;
}
camera_.handleDragAndDrop( move , modifiers , buttons );
auto& sinp( sync.inputs( ) );
inputsFromVector( *target_ , camera_.lookAt( ) );
if ( camMode_ == CM_ANGLES ) {
inputsFromVector( *angles_ , camera_.angles( ) );
sinp[ inputPos_[ *distance_ ] ] = camera_.distance( );
} else {
inputsFromVector( *position_ , camera_.position( ) );
inputsFromVector( *upVector_ , camera_.upVector( ) );
}
}
void T_CamOverride::handleWheel(
const float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
auto& sync( Globals::Sync( ) );
if ( !enabled( ) ) {
sync.clearMouseDelegate( );
return;
}
camera_.handleWheel( wheel , modifiers , buttons );
auto& sinp( sync.inputs( ) );
if ( modifiers & E_KeyboardModifier::SHIFT ) {
auto const& fc( *fovConfig_ );
if ( fc.mode == FM_FOV ) {
sinp[ inputPos_[ fc.inputIndex ] ] = camera_.fieldOfView( );
} else {
sinp[ inputPos_[ fc.inputIndex ] ] = camera_.nearPlane( );
}
} else {
inputsFromVector( *target_ , camera_.lookAt( ) );
if ( camMode_ == CM_ANGLES ) {
inputsFromVector( *angles_ , camera_.angles( ) );
sinp[ inputPos_[ *distance_ ] ] = camera_.distance( );
} else {
inputsFromVector( *position_ , camera_.position( ) );
inputsFromVector( *upVector_ , camera_.upVector( ) );
}
}
}

View file

@ -53,10 +53,6 @@ class A_Float : public A_SyncOverride
// Single float values
class T_Float : public A_Float
{
protected:
void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept override;
public:
T_Float( T_String const& input ,
T_String const& title ) noexcept;
@ -67,10 +63,6 @@ class T_Float : public A_Float
// 2 float values
class T_Float2 : public A_Float
{
protected:
void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept override;
public:
T_Float2( T_String const& input0 ,
T_String const& input1 ,
@ -82,10 +74,6 @@ class T_Float2 : public A_Float
// 3 float values
class T_Float3 : public A_Float
{
protected:
void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept override;
public:
T_Float3( T_String const& input0 ,
T_String const& input1 ,
@ -98,10 +86,6 @@ class T_Float3 : public A_Float
// 4 float values
class T_Float4 : public A_Float
{
protected:
void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept override;
public:
T_Float4( T_String const& input0 ,
T_String const& input1 ,
@ -155,10 +139,6 @@ class A_Integer : public A_SyncOverride
// 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;
@ -169,10 +149,6 @@ class T_Integer : public A_Integer
// 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 ,
@ -184,10 +160,6 @@ class T_Integer2 : public A_Integer
// 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 ,
@ -200,10 +172,6 @@ class T_Integer3 : public A_Integer
// 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 ,
@ -223,11 +191,6 @@ class T_ColorGrading : public A_SyncOverride
T_Optional< float > base_;
T_Optional< float > unit_;
protected:
void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept override;
public:
T_ColorGrading( T_String const& iRed ,
T_String const& iGreen ,
@ -246,7 +209,7 @@ class T_ColorGrading : public A_SyncOverride
/*= CAMERA CONTROLS ============================================================*/
class T_CamOverride : public A_SyncOverride , public virtual A_MouseCtrl
class T_CamOverride : public A_SyncOverride
{
public:
enum E_SetState {
@ -255,57 +218,60 @@ class T_CamOverride : public A_SyncOverride , public virtual A_MouseCtrl
S_INPUTS , // Duplicate inputs
};
private:
enum E_CamMode_ {
enum E_CamMode {
CM_INVALID ,
CM_ANGLES ,
CM_VECTORS
};
enum E_FovMode_ {
enum E_FovMode {
FM_INVALID ,
FM_FOV ,
FM_NEARPLANE ,
};
struct T_FovConfig_
struct T_FovConfig
{
E_FovMode_ mode;
E_FovMode mode;
uint32_t inputIndex;
T_FovConfig_( E_FovMode_ mode , uint32_t idx ) noexcept
T_FovConfig( E_FovMode mode , uint32_t idx ) noexcept
: mode( mode ) , inputIndex( idx )
{ assert( mode != FM_INVALID ); }
};
struct T_VectorConfig_
struct T_VectorConfig
{
uint32_t x , y , z;
T_VectorConfig_( uint32_t x , uint32_t y , uint32_t z ) noexcept
T_VectorConfig( uint32_t x , uint32_t y ,
uint32_t z ) noexcept
: x(x),y(y),z(z)
{}
};
T_Optional< T_FovConfig_ > fovConfig_;
T_Optional< T_VectorConfig_ > target_;
private:
T_Optional< T_FovConfig > fovConfig_;
T_Optional< T_VectorConfig > target_;
T_Optional< T_VectorConfig_ > upVector_;
T_Optional< T_VectorConfig_ > position_;
T_Optional< T_VectorConfig > upVector_;
T_Optional< T_VectorConfig > position_;
T_Optional< T_VectorConfig_ > angles_;
T_Optional< T_VectorConfig > angles_;
T_Optional< uint32_t > distance_;
E_CamMode_ camMode_;
E_CamMode camMode_;
T_Camera camera_;
bool prevEnabled_{ false };
public:
T_CamOverride( T_String const& title ) noexcept;
P_SyncOverride clone( ) const noexcept override;
//----------------------------------------------------------------------
// Set configuration
E_SetState setFieldOfView(
T_String const& input ) noexcept;
E_SetState setNearPlane(
@ -332,44 +298,52 @@ class T_CamOverride : public A_SyncOverride , public virtual A_MouseCtrl
E_SetState setDistance(
T_String const& input ) noexcept;
//----------------------------------------------------------------------
// Check configuration
bool isFovConfigured( ) const noexcept
{ return fovConfig_; }
bool isTargetConfigured( ) const noexcept
{ return target_; }
bool checkValidConfig( ) noexcept;
//----------------------------------------------------------------------
// Read configuration
T_FovConfig const& fovConfig( ) const noexcept
{ return *fovConfig_; }
T_VectorConfig const& target( ) const noexcept
{ return *target_; }
E_CamMode mode( ) const noexcept
{ return camMode_; }
auto const& angles( ) const noexcept
{ return *angles_; }
auto const& distance( ) const noexcept
{ return *distance_; }
auto const& position( ) const noexcept
{ return *position_; }
auto const& up( ) const noexcept
{ return *upVector_; }
//----------------------------------------------------------------------
// State
T_Camera& camData( ) noexcept
{ return camera_; }
T_Camera const& camData( ) const noexcept
{ return camera_; }
void handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
void handleWheel(
float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
bool& prevEnabled( ) noexcept
{ return prevEnabled_; }
private:
E_SetState setVector(
T_Optional< T_VectorConfig_ >& vector ,
T_Optional< T_VectorConfig >& vector ,
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept;
protected:
void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept override;
private:
glm::vec3 vectorFromInputs(
T_VectorConfig_ const& inputs ) noexcept;
void inputsFromVector(
T_VectorConfig_ const& inputs ,
glm::vec3 const& vector ) noexcept;
};

View file

@ -1,6 +1,6 @@
#include "externals.hh"
#include "texture.hh"
#include "globals.hh"
#include "ui.hh"
#include "odbg.hh"
#include "ui-utilities.hh"
@ -84,7 +84,7 @@ T_Texture::T_Texture(
T_Texture::~T_Texture( )
{
if ( debugIndex_ != -1 ) {
auto& odbg( Globals::ODbg( ) );
auto& odbg( UI::ODbg( ) );
assert( odbg.outputs_[ debugIndex_ ].id == id_ );
assert( odbg.nRegistered_ > 0 );
odbg.outputs_[ debugIndex_ ].id = 0;

View file

@ -21,5 +21,6 @@ class A_MouseCtrl
T_MouseButtons buttons
) noexcept = 0;
};
using P_MouseCtrl = T_OwnPtr< A_MouseCtrl >;
inline A_MouseCtrl::~A_MouseCtrl() {}

426
ui-overrides.cc Normal file
View file

@ -0,0 +1,426 @@
#include "externals.hh"
#include "globals.hh"
#include "ui.hh"
#include "ui-colorgrading.hh"
#include "ui-overrides.hh"
#include "ui-sync.hh"
#include <imgui_internal.h>
namespace sov {
namespace {
char const* BuildLabel_(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
sb.clear( ) << "##temp label " << counter << '\0';
counter ++;
return sb.data( );
}
} // namespace <anon>
/*= FLOAT OVERRIDES ==========================================================*/
M_DECL_SOVUI( Float )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Float& >( ovp ) };
float v[ 1 ] = {
Globals::Sync( ).inputs( )[ ov.inputPositions( )[ 0 ] ]
};
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderFloat( label , v , ov.min( ) , ov.max( ) ,
ov.decimals( ) , ov.power( ) )
: DragFloat( label , v , ov.step( ) , ov.min( ) ,
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
Globals::Sync( ).inputs( )[ ov.inputPositions( )[ 0 ] ] = v[ 0 ];
}
}
M_DECL_SOVUI( Float2 )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Float2& >( ovp ) };
auto& sinp( Globals::Sync( ).inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
float v[ 2 ];
for ( auto i = 0 ; i < 2 ; i ++ ) {
v[ i ] = sinp[ ovip[ i ] ];
}
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderFloat2( label , v , ov.min( ) , ov.max( ) ,
ov.decimals( ) , ov.power( ) )
: DragFloat2( label , v , ov.step( ) , ov.min( ) ,
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 2 ; i ++ ) {
sinp[ ovip[ i ] ] = v[ i ];
}
}
}
M_DECL_SOVUI( Float3 )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Float3& >( ovp ) };
auto& sinp( Globals::Sync( ).inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
float v[ 3 ];
for ( auto i = 0 ; i < 3 ; i ++ ) {
v[ i ] = sinp[ ovip[ i ] ];
}
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderFloat3( label , v , ov.min( ) , ov.max( ) ,
ov.decimals( ) , ov.power( ) )
: DragFloat3( label , v , ov.step( ) , ov.min( ) ,
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
sinp[ ovip[ i ] ] = v[ i ];
}
}
}
M_DECL_SOVUI( Float4 )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Float4& >( ovp ) };
auto& sinp( Globals::Sync( ).inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
float v[ 4 ];
for ( auto i = 0 ; i < 4 ; i ++ ) {
v[ i ] = sinp[ ovip[ i ] ];
}
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderFloat4( label , v , ov.min( ) , ov.max( ) ,
ov.decimals( ) , ov.power( ) )
: DragFloat4( label , v , ov.step( ) , ov.min( ) ,
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 4 ; i ++ ) {
sinp[ ovip[ i ] ] = v[ i ];
}
}
}
/*= INTEGER OVERRIDES ========================================================*/
M_DECL_SOVUI( Integer )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Integer& >( ovp ) };
auto& sinp( Globals::Sync( ).inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
int32_t v[ 1 ] = {
int32_t( sinp[ ovip[ 0 ] ] )
};
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderInt( label , v , ov.min( ) , ov.max( ) )
: DragInt( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
sinp[ ovip[ 0 ] ] = v[ 0 ];
}
}
M_DECL_SOVUI( Integer2 )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Integer2& >( ovp ) };
auto& sinp( Globals::Sync( ).inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
int32_t v[ 2 ];
for ( auto i = 0 ; i < 2 ; i ++ ) {
v[ i ] = sinp[ ovip[ i ] ];
}
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderInt2( label , v , ov.min( ) , ov.max( ) )
: DragInt2( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 2 ; i ++ ) {
sinp[ ovip[ i ] ] = v[ i ];
}
}
}
M_DECL_SOVUI( Integer3 )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Integer3& >( ovp ) };
auto& sinp( Globals::Sync( ).inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
int32_t v[ 3 ];
for ( auto i = 0 ; i < 3 ; i ++ ) {
v[ i ] = sinp[ ovip[ i ] ];
}
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderInt3( label , v , ov.min( ) , ov.max( ) )
: DragInt3( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
sinp[ ovip[ i ] ] = v[ i ];
}
}
}
M_DECL_SOVUI( Integer4 )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_Integer4& >( ovp ) };
auto& sinp( Globals::Sync( ).inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
int32_t v[ 4 ];
for ( auto i = 0 ; i < 4 ; i ++ ) {
v[ i ] = sinp[ ovip[ i ] ];
}
char const* const label( BuildLabel_( counter , sb ) );
const bool changed( ov.slider( )
? SliderInt4( label , v , ov.min( ) , ov.max( ) )
: DragInt4( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 4 ; i ++ ) {
sinp[ ovip[ i ] ] = v[ i ];
}
}
}
/*= COLOR GRADING OVERRIDES ==================================================*/
M_DECL_SOVUI( ColorGrading )
{
using namespace ImGui;
auto& ov{ dynamic_cast< T_ColorGrading& >( ovp ) };
auto& sinp{ Globals::Sync( ).inputs( ) };
auto const& ovip{ ov.inputPositions( ) };
float v[ 3 ];
for ( auto i = 0 ; i < 3 ; i ++ ) {
v[ i ] = sinp[ ovip[ i ] ];
}
char const* const label{ BuildLabel_( counter , sb ) };
const bool changed{ ColorGradingControls(
label ,
&v[ 0 ] , &v[ 1 ] , &v[ 2 ] ,
ov.base( ) , ov.unit( ) ) };
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
sinp[ ovip[ i ] ] = v[ i ];
}
}
}
/*= CAMERA OVERRIDES =========================================================*/
namespace {
glm::vec3 VectorFromInputs_(
T_CamOverride::T_VectorConfig const& vc ,
T_AutoArray< uint32_t , 8 > const& ovip ) noexcept
{
auto& sinp( Globals::Sync( ).inputs( ) );
return glm::vec3{
sinp[ ovip[ vc.x ] ] ,
sinp[ ovip[ vc.y ] ] ,
sinp[ ovip[ vc.z ] ] };
}
void InputsFromVector_(
T_CamOverride::T_VectorConfig const& vc ,
T_AutoArray< uint32_t , 8 > const& ovip ,
glm::vec3 const& v ) noexcept
{
auto& sinp( Globals::Sync( ).inputs( ) );
sinp[ ovip[ vc.x ] ] = v.x;
sinp[ ovip[ vc.y ] ] = v.y;
sinp[ ovip[ vc.z ] ] = v.z;
}
/*------------------------------------------------------------------------------*/
struct T_MouseCam_ : public virtual A_MouseCtrl
{
T_Camera& camera;
T_CamOverride& ov;
T_MouseCam_( T_Camera& cam ,
T_CamOverride& ov ) noexcept
: camera( cam ) , ov( ov )
{ }
void handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
void handleWheel(
float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
};
/*------------------------------------------------------------------------------*/
void T_MouseCam_::handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
auto& sync( Globals::Sync( ) );
if ( !ov.enabled( ) ) {
UI::Sync( ).clearMouseDelegate( );
return;
}
camera.handleDragAndDrop( move , modifiers , buttons );
auto& sinp( sync.inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
InputsFromVector_( ov.target( ) , ovip , camera.lookAt( ) );
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
InputsFromVector_( ov.angles( ) , ovip , camera.angles( ) );
sinp[ ovip[ ov.distance( ) ] ] = camera.distance( );
} else {
InputsFromVector_( ov.position( ) , ovip , camera.position( ) );
InputsFromVector_( ov.up( ) , ovip , camera.upVector( ) );
}
}
void T_MouseCam_::handleWheel(
const float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
auto& sync( Globals::Sync( ) );
if ( !ov.enabled( ) ) {
UI::Sync( ).clearMouseDelegate( );
return;
}
camera.handleWheel( wheel , modifiers , buttons );
auto& sinp( sync.inputs( ) );
auto const& ovip{ ov.inputPositions( ) };
if ( modifiers & E_KeyboardModifier::SHIFT ) {
auto const& fc( ov.fovConfig( ) );
if ( fc.mode == T_CamOverride::FM_FOV ) {
sinp[ ovip[ fc.inputIndex ] ] = camera.fieldOfView( );
} else {
sinp[ ovip[ fc.inputIndex ] ] = camera.nearPlane( );
}
} else {
InputsFromVector_( ov.target( ) , ovip , camera.lookAt( ) );
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
InputsFromVector_( ov.angles( ) , ovip , camera.angles( ) );
sinp[ ovip[ ov.distance( ) ] ] = camera.distance( );
} else {
InputsFromVector_( ov.position( ) , ovip , camera.position( ) );
InputsFromVector_( ov.up( ) , ovip , camera.upVector( ) );
}
}
}
} // namespace <anon>
M_DECL_SOVUI( Camera )
{
auto& ov{ dynamic_cast< T_CamOverride& >( ovp ) };
auto& sync{ Globals::Sync( ) };
auto& sinp{ sync.inputs( ) };
auto& camera{ ov.camData( ) };
auto const& ovip{ ov.inputPositions( ) };
auto const& fc{ ov.fovConfig( ) };
if ( !ov.enabled( ) || !ov.prevEnabled( ) ) {
// Set field of view / near plane
if ( fc.mode == T_CamOverride::FM_FOV ) {
camera.fieldOfView( sinp[ ovip[ fc.inputIndex ] ] );
} else {
camera.nearPlane( sinp[ ovip[ fc.inputIndex ] ] );
}
// Set camera parameters
const glm::vec3 lookAt{ VectorFromInputs_(
ov.target( ) , ovip ) };
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
const glm::vec3 angles{ VectorFromInputs_(
ov.angles( ) , ovip ) };
const float distance{ sinp[ ovip[ ov.distance( ) ] ] };
camera.camera( lookAt , angles , distance );
} else {
const glm::vec3 position{ VectorFromInputs_(
ov.position( ) , ovip ) };
const glm::vec3 up{ VectorFromInputs_(
ov.up( ) , ovip ) };
camera.camera( lookAt , position , up );
}
}
ov.prevEnabled( ) = ov.enabled( );
// Draw UI
char const* const name( BuildLabel_( counter , sb ) );
auto& sui{ UI::Sync( ) };
bool mouseHandler{ sui.isCurrentDelegate( ov.id( ) ) };
using namespace ImGui;
PushItemWidth( 0 ); // Compensate for -1
PushID( GetCurrentWindow( )->GetID( name ) );
const bool handlerChanged{ Checkbox( "Mouse control" , &mouseHandler ) };
Separator( );
const auto changes{ camera.makeUI( ) };
PopID( );
PopItemWidth( );
if ( handlerChanged ) {
if ( mouseHandler ) {
sui.delegateMouse( ov.id( ) ,
NewOwned< T_MouseCam_ >( camera , ov ) );
} else {
sui.clearMouseDelegate( );
}
}
// Update values
if ( changes & T_Camera::E_Changes::FOV ) {
if ( fc.mode == T_CamOverride::FM_FOV ) {
sinp[ ovip[ fc.inputIndex ] ] = camera.fieldOfView( );
} else {
sinp[ ovip[ fc.inputIndex ] ] = camera.nearPlane( );
}
}
if ( changes & T_Camera::E_Changes::MATRIX ) {
InputsFromVector_( ov.target( ) , ovip , camera.lookAt( ) );
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
InputsFromVector_( ov.angles( ) , ovip , camera.angles( ) );
sinp[ ovip[ ov.distance( ) ] ] = camera.distance( );
} else {
InputsFromVector_( ov.position( ) , ovip , camera.position( ) );
InputsFromVector_( ov.up( ) , ovip , camera.upVector( ) );
}
}
}
} // namespace sov

25
ui-overrides.hh Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#include "syncoverrides.hh"
#define M_DECL_SOVUI(NAME) \
void UI##NAME( A_SyncOverride& ovp , \
uint32_t& counter , \
T_StringBuilder& sb ) noexcept
namespace sov {
M_DECL_SOVUI( Float );
M_DECL_SOVUI( Float2 );
M_DECL_SOVUI( Float3 );
M_DECL_SOVUI( Float4 );
M_DECL_SOVUI( Integer );
M_DECL_SOVUI( Integer2 );
M_DECL_SOVUI( Integer3 );
M_DECL_SOVUI( Integer4 );
M_DECL_SOVUI( ColorGrading );
M_DECL_SOVUI( Camera );
} // namespace sovui

View file

@ -4,6 +4,7 @@
#include "globals.hh"
#include "window.hh"
#include "syncedit.hh"
#include "ui.hh"
#include "ui-utilities.hh"
#define IMGUI_DEFINE_MATH_OPERATORS
@ -326,7 +327,7 @@ void T_SyncViewImpl_::displayToolbar( ) noexcept
ToolbarSeparator( );
if ( ToolbarButton( ICON_FA_CLOCK_O , BtSize , "Change duration and time units." ) ) {
Globals::Window( ).pushDialog( NewOwned< T_ChangeDurationDialog_ >(
UI::Window( ).pushDialog( NewOwned< T_ChangeDurationDialog_ >(
sync.durationUnits( ) , sync.durationUnitSize( ) ) );
}
@ -499,7 +500,7 @@ void T_SyncViewImpl_::sequencerHeader(
GetColorU32( ImVec4{ 1 , 1 , 1 , .5 } ) );
}
PushFont( Globals::Window( ).smallFont( ) );
PushFont( UI::Window( ).smallFont( ) );
PushStyleColor( ImGuiCol_Text , ColHeaderText );
auto pos{ startBarPos };
auto bar{ startBar };

191
ui-sync.cc Normal file
View file

@ -0,0 +1,191 @@
#include "externals.hh"
#include "globals.hh"
#include "ui.hh"
#include "ui-actions.hh"
#include "ui-overrides.hh"
#include "ui-sync.hh"
#include "ui-utilities.hh"
#include "window.hh"
/*= T_UISync =================================================================*/
T_UISync::T_UISync( )
{
UI::Window( ).newAction( "Save curves" , []() {
if ( Globals::Sync( ).curvesFileChanged( ) ) {
UI::Window( ).msgbox(
"Curves file changed" ,
"The file containing the curves has been modified "
"on the disk. These changes will be overwritten. "
"Do you want to continue?" ,
[]( auto b ) {
if ( b == T_MessageBox::BT_YES ) {
Globals::Sync( ).saveCurves( );
}
} , { T_MessageBox::BT_YES , T_MessageBox::BT_NO } );
} else {
Globals::Sync( ).saveCurves( );
}
} ).setEnabledCheck( []() {
return Globals::Sync( ).curvesModified( );
} ).setIcon( ICON_FA_FLOPPY_O )
.setShortcut( T_KeyboardShortcut{ 's' , E_KeyboardModifier::CTRL } );
//-----------------------------------------------------------------------------
UI::Window( ).newAction( "Reload curves" , []() {
UI::Window( ).msgbox(
"Reload curves?" ,
"Changes you made to the curves will be lost. Do you "
"want to continue?" ,
[]( auto b ) {
if ( b == T_MessageBox::BT_YES ) {
Globals::Sync( ).loadCurves( );
}
} , { T_MessageBox::BT_YES , T_MessageBox::BT_NO } );
} ).setEnabledCheck( []() {
return Globals::Sync( ).curvesModified( );
} ).setIcon( ICON_FA_DOWNLOAD )
.setShortcut( T_KeyboardShortcut{ 'r' ,
{ E_KeyboardModifier::CTRL , E_KeyboardModifier::SHIFT } } );
//-----------------------------------------------------------------------------
const auto addui{ [this]( char const* type , F_Override ov ) {
const bool ok{ sovuis_.add( T_String{ type } , std::move( ov ) ) };
assert( ok ); (void)ok;
} };
addui( "float" , sov::UIFloat );
addui( "float2" , sov::UIFloat2 );
addui( "float3" , sov::UIFloat3 );
addui( "float4" , sov::UIFloat4 );
addui( "int" , sov::UIInteger );
addui( "int2" , sov::UIInteger2 );
addui( "int3" , sov::UIInteger3 );
addui( "int4" , sov::UIInteger4 );
addui( "cg" , sov::UIColorGrading );
addui( "cam" , sov::UICamera );
}
/*----------------------------------------------------------------------------*/
namespace {
bool HandleOverrideSection_(
T_SyncOverrideSection& sos ,
bool exit ,
T_AutoArray< bool , 32 >& stack )
{
if ( exit ) {
assert( !stack.empty( ) );
if ( stack.last( ) && stack.size( ) > 1 ) {
ImGui::TreePop( );
}
stack.removeLast( );
return true;
}
const bool display( stack.empty( )
? ImGui::CollapsingHeader( &sos.cTitle[ 0 ] )
: ImGui::TreeNode( &sos.cTitle[ 0 ] ) );
stack.add( display );
return display;
}
void HandleOverride_(
A_SyncOverride& ov ,
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
using namespace ImGui;
bool& enabled{ ov.enabled( ) };
if ( Checkbox( &ov.title( )[ 0 ] , &enabled ) ) {
auto const& ipos( ov.inputPositions( ) );
Globals::Sync( ).setOverridesActive( ov.enabled( ) ,
ipos.size( ) , &ipos[ 0 ] );
}
if ( !enabled ) {
PushDisabled( );
}
Indent( );
PushItemWidth( -1 );
(UI::Sync( ).uiFor( ov ))( ov , counter , sb );
PopItemWidth( );
Unindent( );
if ( !enabled ) {
PopDisabled( );
}
}
} // namespace <anon>
T_UISync::F_Override T_UISync::uiFor(
A_SyncOverride& target ) const noexcept
{
auto const* const rv{ sovuis_.get( target.type( ) ) };
return rv ? *rv : []( A_SyncOverride& , uint32_t& , T_StringBuilder& ) {
ImGui::Text( "(missing UI)" );
};
}
void T_UISync::makeOverridesWindow( )
{
if ( !ovWindow_ ) {
return;
}
using namespace ImGui;
auto const& dspSize( GetIO( ).DisplaySize );
SetNextWindowSize( ImVec2( dspSize.x * .25f , dspSize.y * .66f - 20 ) , ImGuiSetCond_Appearing );
SetNextWindowPos( ImVec2( 0 , 20 ) , ImGuiSetCond_Appearing );
Begin( "Input overrides" , &ovWindow_ ,
ImGuiWindowFlags_NoCollapse );
T_StringBuilder temp;
uint32_t counter{ 0 };
T_AutoArray< bool , 32 > stack;
bool found{ false };
using T_Ove_ = T_SyncOverrideVisitor::T_Element;
Globals::Sync( ).visitOverrides( [&]( T_Ove_ element , bool exit ) {
// Display sections
if ( element.hasType< T_SyncOverrideSection* >( ) ) {
auto& sos( *element.value< T_SyncOverrideSection* >( ) );
if ( sos.title == "*root*" ) {
return true;
}
return HandleOverrideSection_( sos , exit , stack );
}
if ( exit ) {
HandleOverride_( *element.value< A_SyncOverride* >( ) ,
counter , temp );
found = true;
}
return true;
} );
if ( !found ) {
Text( "No overrides have been defined." );
}
End( );
}
/*----------------------------------------------------------------------------*/
void T_UISync::handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
if ( mouseDelegate_ ) {
mouseDelegate_->handleDragAndDrop( move , modifiers , buttons );
}
}
void T_UISync::handleWheel(
const float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
if ( mouseDelegate_ ) {
mouseDelegate_->handleWheel( wheel , modifiers , buttons );
}
}

55
ui-sync.hh Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#include "sync.hh"
#include "ui-mousectrl.hh"
class T_UISync : public A_MouseCtrl
{
public:
using F_Override = std::function<
void( A_SyncOverride& , uint32_t& , T_StringBuilder& ) >;
T_UISync( );
bool& overridesWindowEnabled( ) noexcept
{ return ovWindow_; }
void makeOverridesWindow( );
F_Override uiFor( A_SyncOverride& target ) const noexcept;
//----------------------------------------------------------------------
void delegateMouse( T_String const& id ,
P_MouseCtrl delegate ) noexcept
{
mouseDelegateName_ = id;
mouseDelegate_ = std::move( delegate );
}
void clearMouseDelegate( ) noexcept
{
mouseDelegateName_ = T_String{ };
mouseDelegate_ = P_MouseCtrl{ };
}
bool isCurrentDelegate( T_String const& delegate ) noexcept
{ return mouseDelegateName_ == delegate; }
//----------------------------------------------------------------------
void handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
void handleWheel(
float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept override;
private:
bool ovWindow_{ false };
T_String mouseDelegateName_{ };
T_OwnPtr< A_MouseCtrl > mouseDelegate_{ };
T_KeyValueTable< T_String , F_Override > sovuis_;
};

54
ui.cc Normal file
View file

@ -0,0 +1,54 @@
#include "externals.hh"
#include "odbg.hh"
#include "shaders.hh"
#include "texture.hh"
#include "ui.hh"
#include "ui-sync.hh"
#include "window.hh"
namespace {
struct UIData_
{
T_Window window;
T_TextureManager textures;
T_ShaderManager shaders;
T_OutputDebugger odbg;
T_UISync sync;
};
std::aligned_storage_t< sizeof( UIData_ ) , alignof( UIData_ ) > Instance_;
} // namespace <anon>
/*----------------------------------------------------------------------------*/
void UI::Init( ) noexcept
{
new ((char*)&Instance_) UIData_( );
}
void UI::Shutdown( ) noexcept
{
((UIData_*)(char*)&Instance_)->~UIData_( );
}
/*----------------------------------------------------------------------------*/
#define M_GET_( P ) ((UIData_*)(char*)&Instance_)->P
T_Window& UI::Window( ) noexcept
{ return M_GET_( window ); }
T_TextureManager& UI::Textures( ) noexcept
{ return M_GET_( textures ); }
T_ShaderManager& UI::Shaders( ) noexcept
{ return M_GET_( shaders ); }
T_OutputDebugger& UI::ODbg( ) noexcept
{ return M_GET_( odbg ); }
T_UISync& UI::Sync( ) noexcept
{ return M_GET_( sync ); }

29
ui.hh Normal file
View file

@ -0,0 +1,29 @@
#pragma once
#ifndef REAL_BUILD
# include "externals.hh"
#endif
struct T_Window;
struct T_TextureManager;
struct T_ShaderManager;
struct T_OutputDebugger;
struct T_UISync;
struct UI : public ebcl::A_PrivateImplementation
{
public:
static void Init( ) noexcept;
static void Shutdown( ) noexcept;
static T_Window& Window( ) noexcept;
static T_TextureManager& Textures( ) noexcept;
static T_ShaderManager& Shaders( ) noexcept;
static T_OutputDebugger& ODbg( ) noexcept;
static T_UISync& Sync( ) noexcept;
private:
UI( ) noexcept;
NO_COPY( UI );
NO_MOVE( UI );
};

View file

@ -33,6 +33,15 @@ struct T_Window
void actionMenu( T_String const& id ) const noexcept;
void actionButton( T_String const& id ) const noexcept;
template< typename... Args >
T_UIAction& newAction( Args&&... args )
{
T_UIAction a{ std::forward< Args >( args ) ... };
T_String id{ a.id };
addAction( std::move( a ) );
return *actions_.get( id );
}
//----------------------------------------------------------------------
ImFont* defaultFont( ) const noexcept