From 6a1c134cf30d1bfd64c418cc921b1685cd432328 Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Mon, 20 Apr 2020 02:16:14 +0200 Subject: [PATCH] [UI] Capture mouse. --- src/xenia/ui/imgui_drawer.cc | 42 +++++++++++++++++++++++++++--------- src/xenia/ui/window.h | 3 +++ src/xenia/ui/window_gtk.h | 4 ++++ src/xenia/ui/window_win.cc | 15 +++++++++++++ src/xenia/ui/window_win.h | 3 +++ 5 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/xenia/ui/imgui_drawer.cc b/src/xenia/ui/imgui_drawer.cc index 4e58774a5..184aa5837 100644 --- a/src/xenia/ui/imgui_drawer.cc +++ b/src/xenia/ui/imgui_drawer.cc @@ -268,16 +268,27 @@ void ImGuiDrawer::OnKeyChar(KeyEvent* e) { void ImGuiDrawer::OnMouseDown(MouseEvent* e) { auto& io = GetIO(); io.MousePos = ImVec2(float(e->x()), float(e->y())); + int button = -1; switch (e->button()) { case xe::ui::MouseEvent::Button::kLeft: { - io.MouseDown[0] = true; - } break; + button = 0; + break; + } case xe::ui::MouseEvent::Button::kRight: { - io.MouseDown[1] = true; - } break; + button = 1; + break; + } default: { // Ignored. - } break; + break; + } + } + + if (button >= 0 && button < std::size(io.MouseDown)) { + if (!ImGui::IsAnyMouseDown()) { + window_->CaptureMouse(); + } + io.MouseDown[button] = true; } } @@ -289,16 +300,27 @@ void ImGuiDrawer::OnMouseMove(MouseEvent* e) { void ImGuiDrawer::OnMouseUp(MouseEvent* e) { auto& io = GetIO(); io.MousePos = ImVec2(float(e->x()), float(e->y())); + int button = -1; switch (e->button()) { case xe::ui::MouseEvent::Button::kLeft: { - io.MouseDown[0] = false; - } break; + button = 0; + break; + } case xe::ui::MouseEvent::Button::kRight: { - io.MouseDown[1] = false; - } break; + button = 1; + break; + } default: { // Ignored. - } break; + break; + } + } + + if (button >= 0 && button < std::size(io.MouseDown)) { + io.MouseDown[button] = false; + if (!ImGui::IsAnyMouseDown()) { + window_->ReleaseMouse(); + } } } diff --git a/src/xenia/ui/window.h b/src/xenia/ui/window.h index 4814dee0c..e1e48e2a0 100644 --- a/src/xenia/ui/window.h +++ b/src/xenia/ui/window.h @@ -59,6 +59,9 @@ class Window { virtual bool SetIcon(const void* buffer, size_t size) = 0; void ResetIcon() { SetIcon(nullptr, 0); } + virtual bool CaptureMouse() = 0; + virtual bool ReleaseMouse() = 0; + virtual bool is_fullscreen() const { return false; } virtual void ToggleFullscreen(bool fullscreen) {} diff --git a/src/xenia/ui/window_gtk.h b/src/xenia/ui/window_gtk.h index af842cf15..b0b56f70d 100644 --- a/src/xenia/ui/window_gtk.h +++ b/src/xenia/ui/window_gtk.h @@ -42,6 +42,10 @@ class GTKWindow : public Window { bool SetIcon(const void* buffer, size_t size) override; + // This seems to happen implicitly compared to Windows. + bool CaptureMouse() override { return true; }; + bool ReleaseMouse() override { return true; }; + bool is_fullscreen() const override; void ToggleFullscreen(bool fullscreen) override; diff --git a/src/xenia/ui/window_win.cc b/src/xenia/ui/window_win.cc index beaea0e26..2e60d2e42 100644 --- a/src/xenia/ui/window_win.cc +++ b/src/xenia/ui/window_win.cc @@ -236,6 +236,21 @@ bool Win32Window::SetIcon(const void* buffer, size_t size) { return false; } +bool Win32Window::CaptureMouse() { + if (GetCapture() != nullptr) { + return false; + } + SetCapture(hwnd_); + return true; +} + +bool Win32Window::ReleaseMouse() { + if (GetCapture() != hwnd_) { + return false; + } + return ReleaseCapture() != 0; +} + bool Win32Window::is_fullscreen() const { return fullscreen_; } // https://blogs.msdn.microsoft.com/oldnewthing/20131017-00/?p=2903 diff --git a/src/xenia/ui/window_win.h b/src/xenia/ui/window_win.h index dc8868431..da638afdc 100644 --- a/src/xenia/ui/window_win.h +++ b/src/xenia/ui/window_win.h @@ -38,6 +38,9 @@ class Win32Window : public Window { bool SetIcon(const void* buffer, size_t size) override; + bool CaptureMouse() override; + bool ReleaseMouse() override; + bool is_fullscreen() const override; void ToggleFullscreen(bool fullscreen) override;