replace the separate layout and repaint events with a single "reflow"
event
This commit is contained in:
parent
e52bbce5e0
commit
5e436b5463
4 changed files with 50 additions and 44 deletions
|
@ -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 {
|
||||
|
|
|
@ -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> 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<MouseButtonEvent&>(event));
|
||||
break;
|
||||
}
|
||||
case EventType::WidgetRepaintRequested: {
|
||||
handle_repaint(reinterpret_cast<WidgetRepaintRequestedEvent&>(event));
|
||||
break;
|
||||
}
|
||||
case EventType::WidgetRelayoutRequestedEvent: {
|
||||
do_layout();
|
||||
case EventType::Reflow: {
|
||||
handle_reflow(reinterpret_cast<ReflowEvent&>(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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue