diff --git a/Makefile b/Makefile index bf47db7..5a41ccb 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ COMMON = \ ui-actions.cc \ ui-app.cc \ ui-colorgrading.cc \ + ui-demo.cc \ ui-dialogs.cc \ ui-imgui-sdl.cc \ ui-odbg.cc \ @@ -50,7 +51,6 @@ COMMON = \ # END COMMON DEMO = \ - demo.cc \ main.cc \ # END DEMO diff --git a/c-opcomp.cc b/c-opcomp.cc index 2c3f53b..6000455 100644 --- a/c-opcomp.cc +++ b/c-opcomp.cc @@ -3,7 +3,7 @@ #include "c-opcomp.hh" #include -#define INVASIVE_TRACES +//#define INVASIVE_TRACES using namespace ebcl; using namespace ops; diff --git a/main.cc b/main.cc index 5a83d59..e5db8ba 100644 --- a/main.cc +++ b/main.cc @@ -1,5 +1,4 @@ #include "externals.hh" -#include "demo.hh" #include "common.hh" #include "c-sync.hh" @@ -7,6 +6,7 @@ #include "ui.hh" #include "ui-app.hh" +#include "ui-demo.hh" #include "ui-imgui-sdl.hh" #include "ui-odbg.hh" #include "ui-opemu.hh" @@ -31,9 +31,6 @@ struct T_Main private: bool done = false; - bool capture = false; - ImVec2 mouseInitial; - ImVec2 mouseMove; uint32_t stopResize = 0; ImVec2 prevSize; @@ -44,7 +41,6 @@ struct T_Main void initDemo( ); void startIteration( ); - void handleCapture( ); void makeUI( ); void render( ); }; @@ -53,15 +49,16 @@ struct T_Main T_Main::T_Main( ) { - Common::Init( ); UI::Init( ); prevSize = ImVec2( -1 , -1 ); } void T_Main::mainLoop( ) { + auto& m( UI::Main( ) ); auto& p( UI::Profiler( ) ); - while ( !done ) { + while ( !m.exiting( ) ) { + // Check whether there's a resize in progress auto const& dspSize( ImGui::GetIO( ).DisplaySize ); if ( prevSize.x != dspSize.x || prevSize.y != dspSize.y ) { const auto doit( prevSize.x > 0 ); @@ -71,6 +68,8 @@ void T_Main::mainLoop( ) } } + // If there was a resize and some time has passed, + // re-initialise the demo. bool needInit( !demo ); if ( stopResize > 0 ) { stopResize --; @@ -81,26 +80,31 @@ void T_Main::mainLoop( ) if ( needInit ) { initDemo( ); } + #warning FIXME remove this if ( !sequencer ) { sequencer.setNew( ); } + // Update file watcher and shaders Common::Watcher( ).check( ); UI::Shaders( ).update( ); + // Display glFinish( ); p.startFrame( ); p.start( "Full frame" ); - startIteration( ); - if ( !done ) { - handleCapture( ); + m.handleEvents( ); + + if ( !m.exiting( ) ) { makeUI( ); render( ); - p.end( "Full frame" ); - UI::Main( ).swap( ); - p.endFrame( ); + m.render( ); } + + p.end( "Full frame" ); + m.swap( ); + p.endFrame( ); } } @@ -108,7 +112,6 @@ T_Main::~T_Main( ) { demo.clear( ); UI::Shutdown( ); - Common::Shutdown( ); } /*----------------------------------------------------------------------------*/ @@ -130,83 +133,6 @@ void T_Main::initDemo( ) } } -void T_Main::startIteration( ) -{ - SDL_Event event; - mouseMove = ImVec2( ); - while ( SDL_PollEvent( &event ) ) { - ImGui_ImplSdl_ProcessEvent( &event ); - if ( event.type == SDL_QUIT ) { - done = true; - return; - } - - if ( capture && event.type == SDL_MOUSEMOTION ) { - mouseMove.x += event.motion.xrel; - mouseMove.y += event.motion.yrel; - } - } - - UI::Main( ).startFrame( capture , mouseInitial ); - ImGui::GetIO( ).MouseDrawCursor = true; -} - -void T_Main::handleCapture( ) -{ - using namespace ImGui; - auto const& io( GetIO( ) ); - const T_MouseButtons mb( ([]() {; - T_MouseButtons mb; - if ( IsMouseDown( 0 ) ) { - mb |= E_MouseButton::LEFT; - } - if ( IsMouseDown( 1 ) ) { - mb |= E_MouseButton::RIGHT; - } - if ( IsMouseDown( 2 ) ) { - mb |= E_MouseButton::MIDDLE; - } - return mb; - })() ); - const T_KeyboardModifiers kb( ([&io]() { - T_KeyboardModifiers kb; - if ( io.KeyCtrl ) { - kb |= E_KeyboardModifier::CTRL; - } - if ( io.KeyShift ) { - kb |= E_KeyboardModifier::SHIFT; - } - if ( io.KeyAlt ) { - kb |= E_KeyboardModifier::ALT; - } - return kb; - })() ); - const bool appCanGrab( !( ImGui::IsMouseHoveringAnyWindow( ) - || io.WantCaptureMouse - || io.WantCaptureKeyboard ) ); - - if ( capture && !mb ) { - capture = false; - CaptureMouseFromApp( false ); - SDL_SetRelativeMouseMode( SDL_FALSE ); - UI::Main( ).warpMouse( mouseInitial ); - SetMouseCursor( ImGuiMouseCursor_Arrow ); - } else if ( capture ) { - SetMouseCursor( ImGuiMouseCursor_Move ); - UI::Sync( ).handleDragAndDrop( mouseMove , kb , mb ); - } else if ( appCanGrab && mb ) { - capture = true; - mouseInitial = GetMousePos( ); - CaptureMouseFromApp( true ); - SDL_SetRelativeMouseMode( SDL_TRUE ); - SetMouseCursor( ImGuiMouseCursor_Move ); - } - - if ( ( appCanGrab || capture ) && io.MouseWheel ) { - UI::Sync( ).handleWheel( io.MouseWheel , kb , mb ); - } -} - void T_Main::makeUI( ) { using namespace ImGui; @@ -276,13 +202,6 @@ void T_Main::render( ) glClearColor( 0 , 0 , 0 , 1 ); glClear( GL_COLOR_BUFFER_BIT ); } - - UI::Main( ).handleDialogs( ); - glUseProgram( 0 ); - glBindProgramPipeline( 0 ); - UI::Textures( ).reset( ); - glClearColor( 0 , 0 , 0 , 1 ); - ImGui::Render( ); } diff --git a/ui-app.cc b/ui-app.cc index 5b0d3f8..8e8e493 100644 --- a/ui-app.cc +++ b/ui-app.cc @@ -1,6 +1,8 @@ #include "externals.hh" +#include "ui.hh" #include "ui-app.hh" #include "ui-imgui-sdl.hh" +#include "ui-texture.hh" #include @@ -29,18 +31,18 @@ T_UIApp::T_UIApp( ) SDL_DisplayMode current; SDL_GetCurrentDisplayMode( 0 , ¤t ); - window = SDL_CreateWindow( "DEMO", + window_ = SDL_CreateWindow( "DEMO", SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED , 1280 , 720 , SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE ); - gl = SDL_GL_CreateContext( window ); + gl_ = SDL_GL_CreateContext( window_ ); glewInit( ); if ( !GLEW_VERSION_4_5 ) { fprintf( stderr , "OpenGL 4.5 required\n" ); exit( 1 ); } - ImGui_ImplSdl_Init( window ); + ImGui_ImplSdl_Init( window_ ); using namespace ImGui; StyleColorsDark( ); @@ -76,8 +78,8 @@ T_UIApp::T_UIApp( ) T_UIApp::~T_UIApp( ) { ImGui_ImplSdl_Shutdown( ); - SDL_GL_DeleteContext( gl ); - SDL_DestroyWindow( window ); + SDL_GL_DeleteContext( gl_ ); + SDL_DestroyWindow( window_ ); SDL_Quit( ); } @@ -105,22 +107,100 @@ void T_UIApp::actionButton( } } -void T_UIApp::startFrame( - const bool capture , - ImVec2 const& mouseInitial ) const +void T_UIApp::handleEvents( ) noexcept { - ImGui_ImplSdl_NewFrame( window , capture , mouseInitial ); + SDL_Event event; + mMove_ = ImVec2( ); + while ( SDL_PollEvent( &event ) ) { + ImGui_ImplSdl_ProcessEvent( &event ); + if ( event.type == SDL_QUIT ) { +#warning FIXME request confirmation + exiting_ = true; + return; + } + + if ( mCapture_ && event.type == SDL_MOUSEMOTION ) { + mMove_.x += event.motion.xrel; + mMove_.y += event.motion.yrel; + } + } + + ImGui_ImplSdl_NewFrame( window_ , mCapture_ , mInitial_ ); + ImGui::GetIO( ).MouseDrawCursor = true; + handleMouseCapture( ); } -void T_UIApp::warpMouse( - ImVec2 const& pos ) const +void T_UIApp::handleMouseCapture( ) noexcept { - SDL_WarpMouseInWindow( window , pos.x , pos.y ); + using namespace ImGui; + auto const& io( GetIO( ) ); + const T_MouseButtons mb( ([]() {; + T_MouseButtons mb; + if ( IsMouseDown( 0 ) ) { + mb |= E_MouseButton::LEFT; + } + if ( IsMouseDown( 1 ) ) { + mb |= E_MouseButton::RIGHT; + } + if ( IsMouseDown( 2 ) ) { + mb |= E_MouseButton::MIDDLE; + } + return mb; + })() ); + const T_KeyboardModifiers kb( ([&io]() { + T_KeyboardModifiers kb; + if ( io.KeyCtrl ) { + kb |= E_KeyboardModifier::CTRL; + } + if ( io.KeyShift ) { + kb |= E_KeyboardModifier::SHIFT; + } + if ( io.KeyAlt ) { + kb |= E_KeyboardModifier::ALT; + } + return kb; + })() ); + const bool appCanGrab( !( ImGui::IsMouseHoveringAnyWindow( ) + || io.WantCaptureMouse + || io.WantCaptureKeyboard ) ); + + if ( mCapture_ && !( mb && mDelegate_ ) ) { + mCapture_ = false; + CaptureMouseFromApp( false ); + SDL_SetRelativeMouseMode( SDL_FALSE ); + SDL_WarpMouseInWindow( window_ , mInitial_.x , mInitial_.y ); + SetMouseCursor( ImGuiMouseCursor_Arrow ); + + } else if ( mCapture_ && mDelegate_ ) { + SetMouseCursor( ImGuiMouseCursor_Move ); + mDelegate_->handleDragAndDrop( mMove_ , kb , mb ); + + } else if ( appCanGrab && mb && mDelegate_ ) { + mCapture_ = true; + mInitial_ = GetMousePos( ); + CaptureMouseFromApp( true ); + SDL_SetRelativeMouseMode( SDL_TRUE ); + SetMouseCursor( ImGuiMouseCursor_Move ); + } + + if ( ( appCanGrab || mCapture_ ) && io.MouseWheel && mDelegate_ ) { + mDelegate_->handleWheel( io.MouseWheel , kb , mb ); + } } -void T_UIApp::swap( ) const +void T_UIApp::render( ) noexcept { - SDL_GL_SwapWindow( window ); + handleDialogs( ); + glUseProgram( 0 ); + glBindProgramPipeline( 0 ); + UI::Textures( ).reset( ); + glClearColor( 0 , 0 , 0 , 1 ); + ImGui::Render( ); +} + +void T_UIApp::swap( ) const noexcept +{ + SDL_GL_SwapWindow( window_ ); } void T_UIApp::handleDialogs( ) noexcept diff --git a/ui-app.hh b/ui-app.hh index 2517000..1594f42 100644 --- a/ui-app.hh +++ b/ui-app.hh @@ -51,22 +51,49 @@ struct T_UIApp //---------------------------------------------------------------------- - void startFrame( const bool capture , - ImVec2 const& mouseInitial ) const; - void warpMouse( ImVec2 const& pos ) const; + void handleEvents( ) noexcept; - void swap( ) const; - void handleDialogs( ) noexcept; + void setMouseDelegate( A_MouseCtrl* const delegate ) noexcept + { mDelegate_ = delegate; } + void clearMouseDelegate( ) noexcept + { mDelegate_ = nullptr; } + + bool exiting( ) const noexcept + { return exiting_; } + + //---------------------------------------------------------------------- + + void render( ) noexcept; + void swap( ) const noexcept; private: - SDL_Window * window; - SDL_GLContext gl; + // Window and GL context + SDL_Window* window_; + SDL_GLContext gl_; + + // Fonts ImFont* defaultFont_; ImFont* smallFont_; + + // Do we need to quit? + bool exiting_{ false }; + + // Mouse capture + bool mCapture_{ false }; + ImVec2 mInitial_{ 0 , 0 }; + ImVec2 mMove_{ 0 , 0 }; + A_MouseCtrl* mDelegate_; + + // Stack of modal dialogs T_AutoArray< P_ModalDialog , 8 > modals_; + + // Actions and keyboard shortcuts T_ObjectTable< T_String , T_UIAction > actions_{ []( T_UIAction const& a ) -> T_String { return a.id; } }; + + void handleMouseCapture( ) noexcept; + void handleDialogs( ) noexcept; }; diff --git a/demo.cc b/ui-demo.cc similarity index 98% rename from demo.cc rename to ui-demo.cc index 6ebdc22..0eda5c8 100644 --- a/demo.cc +++ b/ui-demo.cc @@ -1,10 +1,10 @@ #include "externals.hh" -#include "demo.hh" #include "common.hh" #include "c-opcomp.hh" #include "c-sync.hh" +#include "ui-demo.hh" #include "ui-opemu.hh" #include "ui-rendertarget.hh" diff --git a/demo.hh b/ui-demo.hh similarity index 100% rename from demo.hh rename to ui-demo.hh diff --git a/ui-sync.cc b/ui-sync.cc index 7cbf9d9..1b2a64e 100644 --- a/ui-sync.cc +++ b/ui-sync.cc @@ -64,6 +64,11 @@ T_UISync::T_UISync( ) addui( "cam" , sov::UICamera ); } +T_UISync::~T_UISync( ) +{ + UI::Main( ).clearMouseDelegate( ); +} + /*----------------------------------------------------------------------------*/ namespace { @@ -170,6 +175,22 @@ void T_UISync::makeOverridesWindow( ) /*----------------------------------------------------------------------------*/ +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 , diff --git a/ui-sync.hh b/ui-sync.hh index 55466d7..525559a 100644 --- a/ui-sync.hh +++ b/ui-sync.hh @@ -11,6 +11,7 @@ class T_UISync : public A_MouseCtrl void( A_SyncOverride& , uint32_t& , T_StringBuilder& ) >; T_UISync( ); + ~T_UISync( ); bool& overridesWindowEnabled( ) noexcept { return ovWindow_; } @@ -21,17 +22,8 @@ class T_UISync : public A_MouseCtrl //---------------------------------------------------------------------- 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{ }; - } + P_MouseCtrl delegate ) noexcept; + void clearMouseDelegate( ) noexcept; bool isCurrentDelegate( T_String const& delegate ) noexcept { return mouseDelegateName_ == delegate; } diff --git a/ui.cc b/ui.cc index 75d6ff4..434f7ae 100644 --- a/ui.cc +++ b/ui.cc @@ -1,4 +1,5 @@ #include "externals.hh" +#include "common.hh" #include "ui.hh" #include "ui-app.hh" #include "ui-odbg.hh" @@ -28,12 +29,14 @@ std::aligned_storage_t< sizeof( UIData_ ) , alignof( UIData_ ) > Instance_; void UI::Init( ) noexcept { + Common::Init( ); new ((char*)&Instance_) UIData_( ); } void UI::Shutdown( ) noexcept { ((UIData_*)(char*)&Instance_)->~UIData_( ); + Common::Shutdown( ); } /*----------------------------------------------------------------------------*/