From d12857fc36879cddfaf2d0c7f607454ab7a96958 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 25 May 2019 13:40:57 +0200 Subject: [PATCH] LibGUI: Notify widgets when their enabled state changes. This is done by dispatching a (synchronous) "EnabledChange" event that can be picked up in change_event(). Use this event to kick widgets out of their "being pressed"-type modes if the user is interacting with them while the state is programmatically changed. --- LibGUI/GAbstractButton.cpp | 13 +++++++++++++ LibGUI/GAbstractButton.h | 1 + LibGUI/GEvent.h | 1 + LibGUI/GScrollBar.cpp | 9 +++++++++ LibGUI/GScrollBar.h | 1 + LibGUI/GSlider.cpp | 9 +++++++++ LibGUI/GSlider.h | 1 + LibGUI/GWidget.cpp | 8 ++++++++ LibGUI/GWidget.h | 1 + 9 files changed, 44 insertions(+) diff --git a/LibGUI/GAbstractButton.cpp b/LibGUI/GAbstractButton.cpp index d9f2b21c60..03f95e0e1d 100644 --- a/LibGUI/GAbstractButton.cpp +++ b/LibGUI/GAbstractButton.cpp @@ -124,3 +124,16 @@ void GAbstractButton::paint_text(GPainter& painter, const Rect& rect, const Font if (is_focused()) painter.draw_rect(clipped_rect.inflated(6, 4), Color(140, 140, 140)); } + +void GAbstractButton::change_event(GEvent& event) +{ + if (event.type() == GEvent::Type::EnabledChange) { + if (!is_enabled()) { + bool was_being_pressed = m_being_pressed; + m_being_pressed = false; + if (was_being_pressed) + update(); + } + } + GWidget::change_event(event); +} diff --git a/LibGUI/GAbstractButton.h b/LibGUI/GAbstractButton.h index 75627e5e0e..fdbb6a7a8c 100644 --- a/LibGUI/GAbstractButton.h +++ b/LibGUI/GAbstractButton.h @@ -37,6 +37,7 @@ protected: virtual void keydown_event(GKeyEvent&) override; virtual void enter_event(CEvent&) override; virtual void leave_event(CEvent&) override; + virtual void change_event(GEvent&) override; void paint_text(GPainter&, const Rect&, const Font&, TextAlignment); diff --git a/LibGUI/GEvent.h b/LibGUI/GEvent.h index 9a308f1072..bdb4c0e5d5 100644 --- a/LibGUI/GEvent.h +++ b/LibGUI/GEvent.h @@ -33,6 +33,7 @@ public: FocusOut, WindowCloseRequest, ContextMenu, + EnabledChange, __Begin_WM_Events, WM_WindowRemoved, diff --git a/LibGUI/GScrollBar.cpp b/LibGUI/GScrollBar.cpp index acad0ecdb9..bc932dd242 100644 --- a/LibGUI/GScrollBar.cpp +++ b/LibGUI/GScrollBar.cpp @@ -300,3 +300,12 @@ void GScrollBar::leave_event(CEvent&) update(); } } + +void GScrollBar::change_event(GEvent& event) +{ + if (event.type() == GEvent::Type::EnabledChange) { + if (!is_enabled()) + m_scrubbing = false; + } + return GWidget::change_event(event); +} diff --git a/LibGUI/GScrollBar.h b/LibGUI/GScrollBar.h index 659a2b09d2..cfc9fbc7a2 100644 --- a/LibGUI/GScrollBar.h +++ b/LibGUI/GScrollBar.h @@ -42,6 +42,7 @@ private: virtual void mouseup_event(GMouseEvent&) override; virtual void mousemove_event(GMouseEvent&) override; virtual void leave_event(CEvent&) override; + virtual void change_event(GEvent&) override; int button_size() const { return 16; } int button_width() const { return orientation() == Orientation::Vertical ? width() : button_size(); } diff --git a/LibGUI/GSlider.cpp b/LibGUI/GSlider.cpp index 28591c2942..ca532bf456 100644 --- a/LibGUI/GSlider.cpp +++ b/LibGUI/GSlider.cpp @@ -120,6 +120,15 @@ void GSlider::leave_event(CEvent& event) GWidget::leave_event(event); } +void GSlider::change_event(GEvent& event) +{ + if (event.type() == GEvent::Type::EnabledChange) { + if (!is_enabled())) + m_dragging = false; + } + GWidget::change_event(event); +} + void GSlider::set_knob_hovered(bool hovered) { if (m_knob_hovered == hovered) diff --git a/LibGUI/GSlider.h b/LibGUI/GSlider.h index ed93910cd5..fb0582d49e 100644 --- a/LibGUI/GSlider.h +++ b/LibGUI/GSlider.h @@ -32,6 +32,7 @@ protected: virtual void mousemove_event(GMouseEvent&) override; virtual void mouseup_event(GMouseEvent&) override; virtual void leave_event(CEvent&) override; + virtual void change_event(GEvent&) override; private: void set_knob_hovered(bool); diff --git a/LibGUI/GWidget.cpp b/LibGUI/GWidget.cpp index 55e31b7adf..506108ca02 100644 --- a/LibGUI/GWidget.cpp +++ b/LibGUI/GWidget.cpp @@ -94,6 +94,8 @@ void GWidget::event(CEvent& event) return handle_enter_event(event); case GEvent::Leave: return handle_leave_event(event); + case GEvent::EnabledChange: + return change_event(static_cast(event)); default: return CObject::event(event); } @@ -271,6 +273,10 @@ void GWidget::leave_event(CEvent&) { } +void GWidget::change_event(GEvent&) +{ +} + void GWidget::update() { if (rect().is_empty()) @@ -454,6 +460,8 @@ void GWidget::set_enabled(bool enabled) if (m_enabled == enabled) return; m_enabled = enabled; + GEvent e(GEvent::EnabledChange); + event(e); update(); } diff --git a/LibGUI/GWidget.h b/LibGUI/GWidget.h index 1d61cf28df..781e91a079 100644 --- a/LibGUI/GWidget.h +++ b/LibGUI/GWidget.h @@ -67,6 +67,7 @@ public: virtual void enter_event(CEvent&); virtual void leave_event(CEvent&); virtual void child_event(CChildEvent&) override; + virtual void change_event(GEvent&); // This is called after children have been painted. virtual void second_paint_event(GPaintEvent&);