From 21b28e705b37b900fa7896afbaa387be72206dfa Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 6 Jan 2022 19:09:09 +0100 Subject: [PATCH] GUI fixes --- src/client/component/gui.cpp | 91 +++++++++++++++++++++++++++--------- src/client/component/gui.hpp | 2 +- 2 files changed, 69 insertions(+), 24 deletions(-) diff --git a/src/client/component/gui.cpp b/src/client/component/gui.cpp index abe49432..81a93f9e 100644 --- a/src/client/component/gui.cpp +++ b/src/client/component/gui.cpp @@ -19,8 +19,23 @@ namespace gui namespace { - utils::concurrency::container>> on_frame_callbacks; - utils::concurrency::container> notifications; + struct frame_callback + { + std::function callback; + bool always; + }; + + struct event + { + HWND hWnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; + }; + + utils::concurrency::container> on_frame_callbacks; + utils::concurrency::container> notifications; + utils::concurrency::container> event_queue; ID3D11Device* device; ID3D11DeviceContext* device_context; @@ -38,13 +53,29 @@ namespace gui initialized = true; } + void run_event_queue() + { + event_queue.access([](std::vector& queue) + { + for (const auto& event : queue) + { + ImGui_ImplWin32_WndProcHandler(event.hWnd, event.msg, event.wParam, event.lParam); + } + + queue.clear(); + }); + } + void new_gui_frame() { + ImGui::GetIO().MouseDrawCursor = toggled; + *game::keyCatchers |= 0x10 * toggled; + ImGui_ImplDX11_NewFrame(); ImGui_ImplWin32_NewFrame(); - ImGui::NewFrame(); + run_event_queue(); - *game::keyCatchers |= 0x10; + ImGui::NewFrame(); } void end_gui_frame() @@ -65,15 +96,15 @@ namespace gui ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoMove; - notifications.access([](std::vector& notifications_) + notifications.access([](std::deque& notifications_) { auto index = 0; - for (auto i = notifications_.begin(); i != notifications_.end(); ++i) + for (auto i = notifications_.begin(); i != notifications_.end();) { const auto now = std::chrono::high_resolution_clock::now(); if (now - i->creation_time >= i->duration) { - notifications_.erase(i--); + i = notifications_.erase(i); continue; } @@ -91,7 +122,8 @@ namespace gui ImGui::End(); - index++; + ++i; + ++index; } }); } @@ -101,18 +133,22 @@ namespace gui ImGui::Checkbox(name.data(), &enabled_menus[menu]); } - void gui_draw() + void run_frame_callbacks() { - show_notifications(); - - on_frame_callbacks.access([](std::vector>& callbacks) + on_frame_callbacks.access([](std::vector& callbacks) { for (const auto& callback : callbacks) { - callback(); + if (callback.always || toggled) + { + callback.callback(); + } } }); + } + void draw_main_menu_bar() + { if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("Windows")) @@ -121,6 +157,7 @@ namespace gui menu_checkbox("Entity list", "entity_list"); menu_checkbox("Console", "console"); menu_checkbox("Script console", "script_console"); + menu_checkbox("Debug", "debug"); ImGui::EndMenu(); } @@ -135,11 +172,10 @@ namespace gui { initialize_gui_context(); } - - if (toggled) + else { new_gui_frame(); - gui_draw(); + run_frame_callbacks(); end_gui_frame(); } } @@ -178,9 +214,12 @@ namespace gui utils::hook::detour wnd_proc_hook; LRESULT wnd_proc_stub(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (wParam != VK_ESCAPE && toggled && ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + if (wParam != VK_ESCAPE && toggled) { - return TRUE; + event_queue.access([hWnd, msg, wParam, lParam](std::vector& queue) + { + queue.push_back({hWnd, msg, wParam, lParam}); + }); } return wnd_proc_hook.invoke(hWnd, msg, wParam, lParam); @@ -214,11 +253,11 @@ namespace gui return !toggled; } - void on_frame(const std::function& callback) + void on_frame(const std::function& callback, bool always) { - on_frame_callbacks.access([callback](std::vector>& callbacks) + on_frame_callbacks.access([always, callback](std::vector& callbacks) { - callbacks.push_back(callback); + callbacks.push_back({callback, always}); }); } @@ -235,9 +274,9 @@ namespace gui notification.duration = duration; notification.creation_time = std::chrono::high_resolution_clock::now(); - notifications.access([notification](std::vector& notifications_) + notifications.access([notification](std::deque& notifications_) { - notifications_.insert(notifications_.begin(), notification); + notifications_.push_front(notification); }); } @@ -264,6 +303,12 @@ namespace gui { utils::hook::jump(0x7A14C4_b, utils::hook::assemble(dxgi_swap_chain_present_stub), true); wnd_proc_hook.create(0x650F10_b, wnd_proc_stub); + + on_frame([]() + { + show_notifications(); + draw_main_menu_bar(); + }); } void pre_destroy() override diff --git a/src/client/component/gui.hpp b/src/client/component/gui.hpp index 0665215b..ad8b3aee 100644 --- a/src/client/component/gui.hpp +++ b/src/client/component/gui.hpp @@ -16,7 +16,7 @@ namespace gui bool gui_char_event(const int local_client_num, const int key); bool gui_mouse_event(const int local_client_num, int x, int y); - void on_frame(const std::function& callback); + void on_frame(const std::function& callback, bool always = false); bool is_menu_open(const std::string& name); void notification(const std::string& title, const std::string& text, const std::chrono::milliseconds duration = 3s); void copy_to_clipboard(const std::string& text);