demotool/ui-sync.cc

227 lines
5.8 KiB
C++

#include "externals.hh"
#include "common.hh"
#include "ui.hh"
#include "ui-actions.hh"
#include "ui-app.hh"
#include "ui-overrides.hh"
#include "ui-sync.hh"
#include "ui-utilities.hh"
/*= T_UISync =================================================================*/
T_UISync::T_UISync( )
{
UI::Main( ).addAction( T_UIAction{ "Save curves" , []() {
if ( Common::Sync( ).curvesFileChanged( ) ) {
UI::Main( ).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 ) {
Common::Sync( ).saveCurves( );
}
} , { T_MessageBox::BT_YES , T_MessageBox::BT_NO } );
} else {
Common::Sync( ).saveCurves( );
}
} }.setEnabledCheck( []() {
return Common::Sync( ).curvesModified( );
} ).setIcon( ICON_FA_FLOPPY_O )
.setShortcut( T_KeyboardShortcut{ 's' , E_KeyboardModifier::CTRL } ) );
//-----------------------------------------------------------------------------
UI::Main( ).addAction( T_UIAction{ "Reload curves" , []() {
UI::Main( ).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 ) {
Common::Sync( ).loadCurves( );
}
} , { T_MessageBox::BT_YES , T_MessageBox::BT_NO } );
} }.setEnabledCheck( []() {
return Common::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 );
}
T_UISync::~T_UISync( )
{
UI::Main( ).clearMouseDelegate( );
}
/*----------------------------------------------------------------------------*/
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( ) );
Common::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;
Common::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::updateTime( ) noexcept
{
auto& s{ Common::Sync( ) };
if ( s.playing( ) ) {
const float time( SDL_GetTicks( ) * 1e-3f );
if ( playingPrevious_ ) {
s.timeDelta( time - lastFrame_ );
}
lastFrame_ = time;
}
playingPrevious_ = s.playing( );
}
/*----------------------------------------------------------------------------*/
void T_UISync::delegateMouse(
T_String const& id ,
P_MouseCtrl delegate ) noexcept
{
mouseDelegateName_ = id;
mouseDelegate_ = std::move( delegate );
UI::Main( ).setMouseDelegate( this );
}
void T_UISync::clearMouseDelegate( ) noexcept
{
mouseDelegateName_ = T_String{ };
mouseDelegate_ = P_MouseCtrl{ };
UI::Main( ).clearMouseDelegate( );
}
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 );
}
}