summaryrefslogtreecommitdiff
path: root/LibGUI
diff options
context:
space:
mode:
Diffstat (limited to 'LibGUI')
-rw-r--r--LibGUI/GButton.cpp28
-rw-r--r--LibGUI/GButton.h2
-rw-r--r--LibGUI/GWidget.cpp16
-rw-r--r--LibGUI/GWidget.h3
-rw-r--r--LibGUI/GWindow.cpp15
-rw-r--r--LibGUI/GWindow.h6
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;
};