From 5e436b546362439b8358c9c98dca364bef775e38 Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Thu, 12 May 2022 17:05:16 +0300 Subject: [PATCH] replace the separate layout and repaint events with a single "reflow" event --- src/Events.hpp | 41 ++++++++++++++++++++++++----------------- src/Widget.cpp | 40 ++++++++++++++++++++-------------------- src/Widget.hpp | 4 ++-- src/Window.cpp | 9 ++++----- 4 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/Events.hpp b/src/Events.hpp index 8140130..e399ac1 100644 --- a/src/Events.hpp +++ b/src/Events.hpp @@ -11,10 +11,20 @@ enum class EventType { MouseButton, MouseMove, - WidgetRepaintRequested, + Reflow, FocusUpdate, ActivationUpdate, - WidgetRelayoutRequestedEvent +}; + +enum class ReflowType { + RepaintSubtree, + RelayoutSubtree, + RepaintSelf +}; + +enum class ReflowGrouping { + Yes, + No }; class Event { @@ -65,26 +75,23 @@ public: Point &point() { return m_point; } }; -class WidgetRepaintRequestedEvent : public Event { +class ReflowEvent: public Event { private: - bool m_should_do_group { false }; + ReflowType m_reflow_type; + ReflowGrouping m_reflow_grouping; public: - WidgetRepaintRequestedEvent(bool should_do_group) - : m_should_do_group(should_do_group) {} + ReflowEvent(ReflowType type, ReflowGrouping grouping) + : m_reflow_type(type) + , m_reflow_grouping(grouping) {} - EventType type() { return EventType::WidgetRepaintRequested; } - const char *name() { return "WidgetRepaintRequested"; } + EventType type() { return EventType::Reflow; } + const char *name() { return "Reflow"; } - bool should_do_group() { return m_should_do_group; } - void set_should_do_group(bool should_do_group) { m_should_do_group = should_do_group; } -}; + ReflowType reflow_type() { return m_reflow_type; } + ReflowGrouping reflow_grouping() { return m_reflow_grouping; } -class WidgetRelayoutRequestedEvent : public Event { -public: - WidgetRelayoutRequestedEvent() {} - - EventType type() { return EventType::WidgetRelayoutRequestedEvent; } - const char *name() { return "WidgetRelayoutRequestedEvent"; } + void set_reflow_grouping(ReflowGrouping reflow_grouping) { m_reflow_grouping = reflow_grouping; } + void set_reflow_type(ReflowType reflow_type) { m_reflow_type = reflow_type; } }; class FocusUpdateEvent : public Event { diff --git a/src/Widget.cpp b/src/Widget.cpp index d3277c7..69de66c 100644 --- a/src/Widget.cpp +++ b/src/Widget.cpp @@ -31,10 +31,8 @@ void Widget::move_to(double x, double y) { } void Widget::do_layout() { - if (m_layout) { + if (m_layout) m_layout->run(); - wants_repaint(); // TODO: should relayout really repaint as well? - } } void Widget::set_layout(std::shared_ptr layout) { @@ -114,7 +112,7 @@ void Widget::wants_full_relayout() { m_window->dispatch_full_relayout(); } -void Widget::handle_repaint(WidgetRepaintRequestedEvent &event) { +void Widget::handle_reflow(ReflowEvent &event) { // immediately accept the event - we will do our own propagation logic event.accept(); @@ -122,29 +120,35 @@ void Widget::handle_repaint(WidgetRepaintRequestedEvent &event) { return; auto painter = m_window->painter(); - if (!painter.can_paint()) return; auto cr = painter.cairo(); - auto event_should_do_group = event.should_do_group(); + auto grouping = event.reflow_grouping(); + auto type = event.reflow_type(); - if (event_should_do_group) { + if (grouping == ReflowGrouping::Yes) { painter.begin_paint_group(); } + if (type == ReflowType::RelayoutSubtree) { + do_layout(); + } + cr->save(); on_paint(); cr->restore(); - // we will propagate this event to all of our children, except it will have - // should_do_group set to false - event.set_should_do_group(false); - for (auto& child : m_children) { - child->dispatch_event(event); + if (type != ReflowType::RepaintSelf) { + // we will propagate this event to all of our children, except it will have + // should_do_group set to false + event.set_reflow_grouping(ReflowGrouping::No); + for (auto& child : m_children) { + child->dispatch_event(event); + } } - if (event_should_do_group) { + if (grouping == ReflowGrouping::Yes) { painter.end_paint_group(); } } @@ -207,12 +211,8 @@ void Widget::dispatch_event(Event &event) { handle_mouse_button_event(reinterpret_cast(event)); break; } - case EventType::WidgetRepaintRequested: { - handle_repaint(reinterpret_cast(event)); - break; - } - case EventType::WidgetRelayoutRequestedEvent: { - do_layout(); + case EventType::Reflow: { + handle_reflow(reinterpret_cast(event)); break; } /* these events aren't handled here, as they won't be dispatched to us from other places */ @@ -236,4 +236,4 @@ void Widget::on_init() { set_did_init(true); } -} \ No newline at end of file +} diff --git a/src/Widget.hpp b/src/Widget.hpp index 7d36dd1..3792677 100644 --- a/src/Widget.hpp +++ b/src/Widget.hpp @@ -132,9 +132,9 @@ private: void wants_full_repaint(); void wants_full_relayout(); void do_layout(); - void handle_repaint(WidgetRepaintRequestedEvent& event); + void handle_reflow(ReflowEvent& event); void handle_mouse_move_event(MouseMoveEvent &event); void handle_mouse_button_event(MouseButtonEvent &event); }; -} \ No newline at end of file +} diff --git a/src/Window.cpp b/src/Window.cpp index b4a64d9..f417bcb 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -61,12 +61,12 @@ bool Window::spawn_window() { } void Window::widget_repaint(Widget *target) { - auto event = WidgetRepaintRequestedEvent(true); + auto event = ReflowEvent(ReflowType::RepaintSubtree, ReflowGrouping::Yes); target->dispatch_event(event); } void Window::widget_relayout(Widget *target) { - auto event = WidgetRelayoutRequestedEvent(); + auto event = ReflowEvent(ReflowType::RelayoutSubtree, ReflowGrouping::Yes); target->dispatch_event(event); } @@ -79,12 +79,12 @@ bool Window::dispatch_to_main_widget(Event &event) { } bool Window::dispatch_full_repaint() { - auto event = WidgetRepaintRequestedEvent(true); + auto event = ReflowEvent(ReflowType::RepaintSubtree, ReflowGrouping::Yes); return dispatch_to_main_widget(event); } bool Window::dispatch_full_relayout() { - auto event = WidgetRelayoutRequestedEvent(); + auto event = ReflowEvent(ReflowType::RelayoutSubtree, ReflowGrouping::Yes); return dispatch_to_main_widget(event); } @@ -118,7 +118,6 @@ void Window::run(bool block) { } case Expose: { if (e.xexpose.count == 0) { - // TODO: hack // might run into issues with other X implementations... :( dispatch_full_repaint(); }