diff options
Diffstat (limited to 'LibGUI')
-rw-r--r-- | LibGUI/GButton.cpp | 28 | ||||
-rw-r--r-- | LibGUI/GButton.h | 2 | ||||
-rw-r--r-- | LibGUI/GWidget.cpp | 16 | ||||
-rw-r--r-- | LibGUI/GWidget.h | 3 | ||||
-rw-r--r-- | LibGUI/GWindow.cpp | 15 | ||||
-rw-r--r-- | LibGUI/GWindow.h | 6 |
6 files changed, 63 insertions, 7 deletions
diff --git a/LibGUI/GButton.cpp b/LibGUI/GButton.cpp index cee19019d0..3fd616da0f 100644 --- a/LibGUI/GButton.cpp +++ b/LibGUI/GButton.cpp @@ -65,12 +65,24 @@ void GButton::paint_event(GPaintEvent&) } } +void GButton::mousemove_event(GMouseEvent& event) +{ + if (m_tracking_cursor) { + bool being_pressed = rect().contains(event.position()); + if (being_pressed != m_being_pressed) { + m_being_pressed = being_pressed; + update(); + } + } + GWidget::mousemove_event(event); +} + void GButton::mousedown_event(GMouseEvent& event) { dbgprintf("Button::mouseDownEvent: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button()); - m_being_pressed = true; - + m_tracking_cursor = true; + set_global_cursor_tracking(true); update(); GWidget::mousedown_event(event); } @@ -78,13 +90,15 @@ void GButton::mousedown_event(GMouseEvent& event) void GButton::mouseup_event(GMouseEvent& event) { dbgprintf("Button::mouseUpEvent: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button()); - + bool was_being_pressed = m_being_pressed; m_being_pressed = false; - + m_tracking_cursor = false; + set_global_cursor_tracking(false); update(); GWidget::mouseup_event(event); - - if (on_click) - on_click(*this); + if (was_being_pressed) { + if (on_click) + on_click(*this); + } } diff --git a/LibGUI/GButton.h b/LibGUI/GButton.h index 606311aac0..b5164ca26e 100644 --- a/LibGUI/GButton.h +++ b/LibGUI/GButton.h @@ -18,10 +18,12 @@ private: virtual void paint_event(GPaintEvent&) override; virtual void mousedown_event(GMouseEvent&) override; virtual void mouseup_event(GMouseEvent&) override; + virtual void mousemove_event(GMouseEvent&) override; virtual const char* class_name() const override { return "GButton"; } String m_caption; bool m_being_pressed { false }; + bool m_tracking_cursor { false }; }; diff --git a/LibGUI/GWidget.cpp b/LibGUI/GWidget.cpp index e2b77e33ec..8695fcda74 100644 --- a/LibGUI/GWidget.cpp +++ b/LibGUI/GWidget.cpp @@ -170,3 +170,19 @@ void GWidget::set_font(RetainPtr<Font>&& font) else m_font = move(font); } + +void GWidget::set_global_cursor_tracking(bool enabled) +{ + auto* win = window(); + if (!win) + return; + win->set_global_cursor_tracking_widget(enabled ? this : nullptr); +} + +bool GWidget::global_cursor_tracking() const +{ + auto* win = window(); + if (!win) + return false; + return win->global_cursor_tracking_widget() == this; +} diff --git a/LibGUI/GWidget.h b/LibGUI/GWidget.h index 15f3e1556c..afa10c370b 100644 --- a/LibGUI/GWidget.h +++ b/LibGUI/GWidget.h @@ -88,6 +88,9 @@ public: const Font& font() const { return *m_font; } void set_font(RetainPtr<Font>&&); + void set_global_cursor_tracking(bool); + bool global_cursor_tracking() const; + private: GWindow* m_window { nullptr }; diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index b6de4a7511..9aff94b40a 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -72,6 +72,13 @@ void GWindow::set_rect(const Rect& a_rect) void GWindow::event(GEvent& event) { if (event.is_mouse_event()) { + if (m_global_cursor_tracking_widget) { + // FIXME: This won't work for widgets-within-widgets. + auto& mouse_event = static_cast<GMouseEvent&>(event); + Point local_point { mouse_event.x() - m_global_cursor_tracking_widget->relative_rect().x(), mouse_event.y() - m_global_cursor_tracking_widget->relative_rect().y() }; + auto local_event = make<GMouseEvent>(event.type(), local_point, mouse_event.buttons(), mouse_event.button()); + m_global_cursor_tracking_widget->event(*local_event); + } if (!m_main_widget) return; auto& mouse_event = static_cast<GMouseEvent&>(event); @@ -158,3 +165,11 @@ void GWindow::set_focused_widget(GWidget* widget) m_focused_widget->update(); } } + +void GWindow::set_global_cursor_tracking_widget(GWidget* widget) +{ + if (widget == m_global_cursor_tracking_widget.ptr()) + return; + m_global_cursor_tracking_widget = widget ? widget->makeWeakPtr() : nullptr; + gui_set_global_cursor_tracking_enabled(m_window_id, widget != nullptr); +} diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h index a958207f08..7a53e8a8db 100644 --- a/LibGUI/GWindow.h +++ b/LibGUI/GWindow.h @@ -4,6 +4,7 @@ #include <SharedGraphics/Rect.h> #include <SharedGraphics/GraphicsBitmap.h> #include <AK/AKString.h> +#include <AK/WeakPtr.h> class GWidget; @@ -48,11 +49,16 @@ public: void update(const Rect& = Rect()); + void set_global_cursor_tracking_widget(GWidget*); + GWidget* global_cursor_tracking_widget() { return m_global_cursor_tracking_widget.ptr(); } + const GWidget* global_cursor_tracking_widget() const { return m_global_cursor_tracking_widget.ptr(); } + private: RetainPtr<GraphicsBitmap> m_backing; int m_window_id { -1 }; bool m_is_active { false }; GWidget* m_main_widget { nullptr }; GWidget* m_focused_widget { nullptr }; + WeakPtr<GWidget> m_global_cursor_tracking_widget; }; |