Compare commits
No commits in common. "94c0be051be354b81f018e2dcf3feb07046f0c5b" and "1f04b5d1dcff73005635e4a2af57682d468e5938" have entirely different histories.
94c0be051b
...
1f04b5d1dc
11 changed files with 149 additions and 168 deletions
|
@ -17,7 +17,6 @@ void Button::set_text(std::string text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::on_init() {
|
void Button::on_init() {
|
||||||
set_background_border_radius(styles()->button_border_radius());
|
|
||||||
set_background_fill_color(styles()->button_normal_color());
|
set_background_fill_color(styles()->button_normal_color());
|
||||||
set_do_background_fill(true);
|
set_do_background_fill(true);
|
||||||
fit_text(m_text);
|
fit_text(m_text);
|
||||||
|
|
|
@ -11,9 +11,9 @@ void DocumentLayout::run() {
|
||||||
|
|
||||||
Point current_position { m_margin, m_margin };
|
Point current_position { m_margin, m_margin };
|
||||||
double largest_height_so_far = -1.0;
|
double largest_height_so_far = -1.0;
|
||||||
|
|
||||||
auto& children = m_target->children();
|
auto& children = m_target->children();
|
||||||
for (auto child : children) {
|
|
||||||
|
for (auto& child : children) {
|
||||||
if (child->absolute())
|
if (child->absolute())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,21 @@ enum class EventType {
|
||||||
|
|
||||||
MouseButton,
|
MouseButton,
|
||||||
MouseMove,
|
MouseMove,
|
||||||
RelayoutSubtree,
|
Reflow,
|
||||||
RepaintRect,
|
|
||||||
FocusUpdate,
|
FocusUpdate,
|
||||||
ActivationUpdate,
|
ActivationUpdate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ReflowType {
|
||||||
|
RepaintRect,
|
||||||
|
RelayoutRect
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ReflowGrouping {
|
||||||
|
Yes,
|
||||||
|
No
|
||||||
|
};
|
||||||
|
|
||||||
class Event {
|
class Event {
|
||||||
private:
|
private:
|
||||||
bool m_accepted { false };
|
bool m_accepted { false };
|
||||||
|
@ -63,36 +72,31 @@ public:
|
||||||
const char *name() { return "MouseMove"; }
|
const char *name() { return "MouseMove"; }
|
||||||
|
|
||||||
Point &point() { return m_point; }
|
Point &point() { return m_point; }
|
||||||
void set_point(Point point) { m_point = point; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RepaintRectEvent : public Event {
|
class ReflowEvent: public Event {
|
||||||
private:
|
private:
|
||||||
bool m_grouping { true };
|
ReflowType m_reflow_type;
|
||||||
|
ReflowGrouping m_grouping;
|
||||||
Box m_box;
|
Box m_box;
|
||||||
public:
|
public:
|
||||||
RepaintRectEvent(bool grouping, Box box)
|
ReflowEvent(ReflowType type, ReflowGrouping grouping, Box box)
|
||||||
: m_grouping(grouping)
|
: m_reflow_type(type)
|
||||||
|
, m_grouping(grouping)
|
||||||
, m_box(box) {}
|
, m_box(box) {}
|
||||||
|
|
||||||
EventType type() { return EventType::RepaintRect; }
|
EventType type() { return EventType::Reflow; }
|
||||||
const char *name() { return "RepaintRect"; }
|
const char *name() { return "Reflow"; }
|
||||||
|
|
||||||
bool grouping() { return m_grouping; }
|
ReflowType reflow_type() { return m_reflow_type; }
|
||||||
|
ReflowGrouping grouping() { return m_grouping; }
|
||||||
Box &box() { return m_box; }
|
Box &box() { return m_box; }
|
||||||
|
|
||||||
void set_grouping(bool grouping) { m_grouping = grouping; }
|
void set_grouping(ReflowGrouping grouping) { m_grouping = grouping; }
|
||||||
|
void set_reflow_type(ReflowType type) { m_reflow_type = type; }
|
||||||
void set_box(Box box) { m_box = box; }
|
void set_box(Box box) { m_box = box; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class RelayoutSubtreeEvent : public Event {
|
|
||||||
public:
|
|
||||||
RelayoutSubtreeEvent() {}
|
|
||||||
|
|
||||||
EventType type() { return EventType::RelayoutSubtree; }
|
|
||||||
const char *name() { return "RelayoutSubtree"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class FocusUpdateEvent : public Event {
|
class FocusUpdateEvent : public Event {
|
||||||
private:
|
private:
|
||||||
bool m_focus_status;
|
bool m_focus_status;
|
||||||
|
|
|
@ -10,8 +10,8 @@ void Painter::rounded_rectangle(Box &geometry, double border_radius) {
|
||||||
double aspect = 1.0;
|
double aspect = 1.0;
|
||||||
double radius = border_radius / aspect;
|
double radius = border_radius / aspect;
|
||||||
double degrees = M_PI / 180.0;
|
double degrees = M_PI / 180.0;
|
||||||
double x = geometry.x();
|
double x = 0;
|
||||||
double y = geometry.y();
|
double y = 0;
|
||||||
double w = geometry.width();
|
double w = geometry.width();
|
||||||
double h = geometry.height();
|
double h = geometry.height();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
private: \
|
private: \
|
||||||
type m_##name {__VA_ARGS__}; \
|
type m_##name {__VA_ARGS__}; \
|
||||||
public: \
|
public: \
|
||||||
void set_##name(type new_prop_value) { m_##name = new_prop_value; repaint(); } \
|
void set_##name(type new_prop_value) { m_##name = new_prop_value; wants_repaint(); } \
|
||||||
type name() { return m_##name; } \
|
type name() { return m_##name; } \
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -23,7 +23,7 @@ DEF_WIDGET_STYLE_PROP(button_text_color, RGB, m_text_color)
|
||||||
DEF_WIDGET_STYLE_PROP(button_normal_color, RGB, m_accent_color)
|
DEF_WIDGET_STYLE_PROP(button_normal_color, RGB, m_accent_color)
|
||||||
DEF_WIDGET_STYLE_PROP(button_focused_color, RGB, m_accent_color_darker)
|
DEF_WIDGET_STYLE_PROP(button_focused_color, RGB, m_accent_color_darker)
|
||||||
DEF_WIDGET_STYLE_PROP(button_active_color, RGB, m_accent_color_darkest)
|
DEF_WIDGET_STYLE_PROP(button_active_color, RGB, m_accent_color_darkest)
|
||||||
DEF_WIDGET_STYLE_PROP(button_border_radius, double, 6.0)
|
DEF_WIDGET_STYLE_PROP(button_border_radius, double, 8.0)
|
||||||
|
|
||||||
DEF_WIDGET_STYLE_PROP(label_text_color, RGB, m_text_color)
|
DEF_WIDGET_STYLE_PROP(label_text_color, RGB, m_text_color)
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
Window *window() { return m_window; }
|
Window *window() { return m_window; }
|
||||||
void set_window(Window *window) { m_window = window; }
|
void set_window(Window *window) { m_window = window; }
|
||||||
|
|
||||||
void repaint();
|
void wants_repaint();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
162
src/Widget.cpp
162
src/Widget.cpp
|
@ -9,14 +9,6 @@
|
||||||
|
|
||||||
namespace Raven {
|
namespace Raven {
|
||||||
|
|
||||||
Point Widget::window_relative() {
|
|
||||||
Point point = { 0, 0 };
|
|
||||||
for (Widget* parent = m_parent; parent; parent = parent->parent()) {
|
|
||||||
point.add(parent->current_geometry().x(), parent->current_geometry().y());
|
|
||||||
}
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::fit_text(std::string &text) {
|
void Widget::fit_text(std::string &text) {
|
||||||
if (!window())
|
if (!window())
|
||||||
return;
|
return;
|
||||||
|
@ -24,7 +16,7 @@ void Widget::fit_text(std::string &text) {
|
||||||
window()->painter().set_pango_font_description(styles()->controls_font_description());
|
window()->painter().set_pango_font_description(styles()->controls_font_description());
|
||||||
auto size = window()->painter().compute_text_size(current_geometry(), text);
|
auto size = window()->painter().compute_text_size(current_geometry(), text);
|
||||||
if (!resize(size)) {
|
if (!resize(size)) {
|
||||||
reflow();
|
wants_full_relayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +29,7 @@ bool Widget::resize(double width, double height) {
|
||||||
|
|
||||||
m_current_geometry.set_width(width);
|
m_current_geometry.set_width(width);
|
||||||
m_current_geometry.set_height(height);
|
m_current_geometry.set_height(height);
|
||||||
reflow();
|
wants_full_relayout();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +39,7 @@ void Widget::move_to(double x, double y) {
|
||||||
|
|
||||||
m_current_geometry.set_x(x);
|
m_current_geometry.set_x(x);
|
||||||
m_current_geometry.set_y(y);
|
m_current_geometry.set_y(y);
|
||||||
reflow();
|
wants_full_relayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::do_layout() {
|
void Widget::do_layout() {
|
||||||
|
@ -81,26 +73,36 @@ bool Widget::add_child(std::shared_ptr<Widget> child) {
|
||||||
// TODO?: what happens when the parent changes its window?
|
// TODO?: what happens when the parent changes its window?
|
||||||
child->set_window(m_window);
|
child->set_window(m_window);
|
||||||
|
|
||||||
reflow();
|
wants_full_relayout();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::remove_child(std::shared_ptr<Widget> child) {
|
void Widget::remove_child(std::shared_ptr<Widget> child) {
|
||||||
m_children.erase(std::remove(m_children.begin(), m_children.end(), child), m_children.end());
|
m_children.erase(std::remove(m_children.begin(), m_children.end(), child), m_children.end());
|
||||||
reflow();
|
wants_full_relayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::repaint() {
|
void Widget::wants_repaint() {
|
||||||
if (m_window)
|
if (m_window)
|
||||||
m_window->repaint(this);
|
m_window->reflow(this, ReflowType::RepaintRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::reflow() {
|
void Widget::wants_relayout() {
|
||||||
if (m_window)
|
if (m_window)
|
||||||
m_window->reflow();
|
m_window->reflow(this, ReflowType::RelayoutRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::handle_repaint_rect(RepaintRectEvent &event) {
|
void Widget::wants_full_repaint() {
|
||||||
|
if (m_window)
|
||||||
|
m_window->reflow(ReflowType::RepaintRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::wants_full_relayout() {
|
||||||
|
if (m_window)
|
||||||
|
m_window->reflow(ReflowType::RelayoutRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::handle_reflow(ReflowEvent &event) {
|
||||||
event.accept(); // immediately accept the event - we will do our own propagation logic
|
event.accept(); // immediately accept the event - we will do our own propagation logic
|
||||||
|
|
||||||
auto painter = m_window->painter();
|
auto painter = m_window->painter();
|
||||||
|
@ -110,40 +112,36 @@ void Widget::handle_repaint_rect(RepaintRectEvent &event) {
|
||||||
if (!event.box().contains_box(current_geometry()))
|
if (!event.box().contains_box(current_geometry()))
|
||||||
return; // widgets contain their children, thus we don't need to recurse further
|
return; // widgets contain their children, thus we don't need to recurse further
|
||||||
|
|
||||||
// using a "group" in cairo reduces flickering
|
|
||||||
bool should_end_paint_group = false;
|
bool should_end_paint_group = false;
|
||||||
if (event.grouping()) {
|
if (event.grouping() == ReflowGrouping::Yes) {
|
||||||
painter.begin_paint_group();
|
painter.begin_paint_group();
|
||||||
should_end_paint_group = true;
|
should_end_paint_group = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.reflow_type() == ReflowType::RelayoutRect) {
|
||||||
|
do_layout();
|
||||||
|
}
|
||||||
|
|
||||||
auto cr = painter.cairo();
|
auto cr = painter.cairo();
|
||||||
|
|
||||||
cr->save();
|
cr->save();
|
||||||
|
|
||||||
// clip this widget. this ensuers that the background fill or children won't overflow the bounds of it
|
cr->translate(current_geometry().x(), current_geometry().y());
|
||||||
painter.rounded_rectangle(m_current_geometry, m_background_border_radius);
|
painter.rounded_rectangle(m_current_geometry, m_background_border_radius);
|
||||||
cr->clip();
|
cr->clip();
|
||||||
|
|
||||||
// paint the background fill
|
|
||||||
// note that we're using the bounds of the paint event as the rectangle, this ensures that we dont draw over other widgets which won't be repainted.
|
|
||||||
if (m_do_background_fill) {
|
if (m_do_background_fill) {
|
||||||
painter.source_rgb(m_background_fill_color);
|
painter.source_rgb(m_background_fill_color);
|
||||||
painter.rounded_rectangle(event.box(), m_background_border_radius);
|
painter.rounded_rectangle(event.box(), m_background_border_radius);
|
||||||
cr->fill();
|
cr->fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate to the widget's position
|
|
||||||
// the origin of the painter is now the widget's origin
|
|
||||||
// this is because the position of children is relative to the origin of their parent
|
|
||||||
cr->translate(current_geometry().x(), current_geometry().y());
|
|
||||||
|
|
||||||
on_paint();
|
on_paint();
|
||||||
|
|
||||||
// convert the paint event's origin to our coordinate space because all positions of children are relative to the origin of their parent
|
Box box = event.box();
|
||||||
auto local_box = event.box().offset(-m_current_geometry.x(), -m_current_geometry.y());
|
for (auto& child : m_children) {
|
||||||
auto local_event = RepaintRectEvent(false, local_box);
|
// convert the invalidation rectangle to the child's coordinate space
|
||||||
for (auto child : m_children) {
|
auto local_rect = box.offset(child->current_geometry().x(), child->current_geometry().y());
|
||||||
|
auto local_event = ReflowEvent(event.reflow_type(), ReflowGrouping::No, local_rect);
|
||||||
child->dispatch_event(local_event);
|
child->dispatch_event(local_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,72 +152,68 @@ void Widget::handle_repaint_rect(RepaintRectEvent &event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::handle_relayout_subtree() {
|
|
||||||
do_layout();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::handle_mouse_move_event(MouseMoveEvent &event) {
|
void Widget::handle_mouse_move_event(MouseMoveEvent &event) {
|
||||||
event.accept(); // we will do our own propagation logic
|
event.accept(); // we will do our own propagation logic. TODO: remove automatic event propagation?
|
||||||
|
|
||||||
bool update_focus_to = true;
|
bool update_focus_to = true;
|
||||||
|
|
||||||
|
std::cout << "point: " << event.point().x() << ", " << event.point().y() << std::endl;
|
||||||
|
|
||||||
if (!m_current_geometry.contains_point(event.point())) {
|
if (!m_current_geometry.contains_point(event.point())) {
|
||||||
// we just became unfocused
|
// we just became unfocused
|
||||||
update_focus_to = false;
|
if (m_is_focused) {
|
||||||
}
|
update_focus_to = false;
|
||||||
|
} else {
|
||||||
on_mouse_move(event);
|
return;
|
||||||
|
|
||||||
if (m_is_focused != update_focus_to) {
|
|
||||||
m_is_focused = update_focus_to;
|
|
||||||
if (m_is_focused && m_window)
|
|
||||||
m_window->set_focused_widget(this);
|
|
||||||
|
|
||||||
auto focus_update_event = FocusUpdateEvent(update_focus_to);
|
|
||||||
on_focus_update(focus_update_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_consumes_hits) {
|
|
||||||
// translate the event's point to our coordinate space because the position of all children is relative to the origin of their parent
|
|
||||||
auto local_event = MouseMoveEvent(Point(
|
|
||||||
event.point().x() - m_current_geometry.x(),
|
|
||||||
event.point().y() - m_current_geometry.y()
|
|
||||||
));
|
|
||||||
for (auto child : m_children) {
|
|
||||||
child->dispatch_event(local_event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_is_focused == update_focus_to)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_is_focused = update_focus_to;
|
||||||
|
auto focus_update_event = FocusUpdateEvent(update_focus_to);
|
||||||
|
on_focus_update(focus_update_event);
|
||||||
|
on_mouse_move(event);
|
||||||
|
|
||||||
|
if (!m_consumes_hits) {
|
||||||
|
for (auto &c : children()) {
|
||||||
|
auto e = MouseMoveEvent {
|
||||||
|
Point {
|
||||||
|
event.point().x() - current_geometry().x(),
|
||||||
|
event.point().y() - current_geometry().y()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
c->dispatch_event(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_is_focused && m_window)
|
||||||
|
m_window->set_focused_widget(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::handle_mouse_button_event(MouseButtonEvent &event) {
|
void Widget::handle_mouse_button_event(MouseButtonEvent &event) {
|
||||||
event.accept(); // we will do our own propagation logic
|
|
||||||
|
|
||||||
bool update_activation_to = event.was_left_button_pressed();
|
bool update_activation_to = event.was_left_button_pressed();
|
||||||
|
|
||||||
if (!m_current_geometry.contains_point(event.point())) {
|
if (!m_current_geometry.contains_point(event.point())) {
|
||||||
|
event.accept();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_is_active == update_activation_to)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_is_active = update_activation_to;
|
||||||
|
auto activation_update_event = ActivationUpdateEvent(update_activation_to);
|
||||||
|
on_activation_update(activation_update_event);
|
||||||
|
|
||||||
on_mouse_button(event);
|
on_mouse_button(event);
|
||||||
|
|
||||||
if (m_is_active != update_activation_to) {
|
if (m_is_active && m_window)
|
||||||
m_is_active = update_activation_to;
|
m_window->set_active_widget(this);
|
||||||
if (m_is_active && m_window)
|
|
||||||
m_window->set_active_widget(this);
|
|
||||||
|
|
||||||
auto activation_update_event = ActivationUpdateEvent(update_activation_to);
|
if (m_consumes_hits)
|
||||||
on_activation_update(activation_update_event);
|
event.accept();
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_consumes_hits) {
|
|
||||||
// translate the event's point to our coordinate space because the position of all children is relative to the origin of their parent
|
|
||||||
auto local_event = MouseButtonEvent(event.was_left_button_pressed(), event.was_right_button_pressed(), Point(
|
|
||||||
event.point().x() - m_current_geometry.x(),
|
|
||||||
event.point().y() - m_current_geometry.y()
|
|
||||||
));
|
|
||||||
for (auto child : m_children) {
|
|
||||||
child->dispatch_event(local_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::dispatch_event(Event &event) {
|
void Widget::dispatch_event(Event &event) {
|
||||||
|
@ -237,12 +231,8 @@ void Widget::dispatch_event(Event &event) {
|
||||||
handle_mouse_button_event(reinterpret_cast<MouseButtonEvent&>(event));
|
handle_mouse_button_event(reinterpret_cast<MouseButtonEvent&>(event));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EventType::RepaintRect: {
|
case EventType::Reflow: {
|
||||||
handle_repaint_rect(reinterpret_cast<RepaintRectEvent&>(event));
|
handle_reflow(reinterpret_cast<ReflowEvent&>(event));
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EventType::RelayoutSubtree: {
|
|
||||||
handle_relayout_subtree();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* these events aren't handled here, as they won't be dispatched to us from other places */
|
/* these events aren't handled here, as they won't be dispatched to us from other places */
|
||||||
|
|
|
@ -59,14 +59,13 @@ public:
|
||||||
void remove_child(std::shared_ptr<Widget> child);
|
void remove_child(std::shared_ptr<Widget> child);
|
||||||
|
|
||||||
Box ¤t_geometry() { return m_current_geometry; }
|
Box ¤t_geometry() { return m_current_geometry; }
|
||||||
void set_current_geometry(Box current_geometry) { m_current_geometry = current_geometry; reflow(); }
|
void set_current_geometry(Box current_geometry) { m_current_geometry = current_geometry; wants_full_relayout(); }
|
||||||
void set_current_geometry(Box current_geometry, bool is_pure) { m_current_geometry = current_geometry; if (!is_pure) { reflow(); } }
|
void set_current_geometry(Box current_geometry, bool is_pure) { m_current_geometry = current_geometry; if (!is_pure) { wants_full_relayout(); } }
|
||||||
|
|
||||||
Point window_relative();
|
|
||||||
|
|
||||||
WidgetType type() { return m_type; }
|
WidgetType type() { return m_type; }
|
||||||
ControlWidgetType control_type() { return m_control_type; }
|
ControlWidgetType control_type() { return m_control_type; }
|
||||||
|
|
||||||
|
|
||||||
Widget *parent() { return m_parent; }
|
Widget *parent() { return m_parent; }
|
||||||
void set_parent(Widget *parent) { m_parent = parent; }
|
void set_parent(Widget *parent) { m_parent = parent; }
|
||||||
|
|
||||||
|
@ -122,12 +121,11 @@ protected:
|
||||||
virtual void on_activation_update(ActivationUpdateEvent &event) {}
|
virtual void on_activation_update(ActivationUpdateEvent &event) {}
|
||||||
virtual void on_paint() {}
|
virtual void on_paint() {}
|
||||||
|
|
||||||
void repaint();
|
void wants_full_repaint();
|
||||||
void reflow();
|
void wants_full_relayout();
|
||||||
private:
|
private:
|
||||||
void do_layout();
|
void do_layout();
|
||||||
void handle_repaint_rect(RepaintRectEvent &event);
|
void handle_reflow(ReflowEvent& event);
|
||||||
void handle_relayout_subtree();
|
|
||||||
void handle_mouse_move_event(MouseMoveEvent &event);
|
void handle_mouse_move_event(MouseMoveEvent &event);
|
||||||
void handle_mouse_button_event(MouseButtonEvent &event);
|
void handle_mouse_button_event(MouseButtonEvent &event);
|
||||||
|
|
||||||
|
|
|
@ -64,57 +64,55 @@ bool Window::dispatch_to_main_widget(Event &event) {
|
||||||
if (!m_main_widget)
|
if (!m_main_widget)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//std::cout << "Dispatched " << event.name() << " to main widget" << std::endl;
|
std::cout << "Dispatched " << event.name() << " to main widget" << std::endl;
|
||||||
|
|
||||||
m_main_widget->dispatch_event(event);
|
m_main_widget->dispatch_event(event);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::repaint(Box geometry) {
|
void Window::reflow(Widget *target, ReflowType type) {
|
||||||
m_did_repaint_during_batch = true;
|
if (type == ReflowType::RelayoutRect) {
|
||||||
|
m_did_relayout_during_batch = true;
|
||||||
|
} else if (type == ReflowType::RepaintRect) {
|
||||||
|
m_did_repaint_during_batch = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_is_batching) {
|
if (m_is_batching) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto event = RepaintRectEvent(true, geometry);
|
auto event = ReflowEvent(type, ReflowGrouping::Yes, target->current_geometry());
|
||||||
dispatch_to_main_widget(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::repaint(Widget *target) {
|
|
||||||
std::cout << target->window_relative().x() << ", " << target->window_relative().y() << std::endl;
|
|
||||||
repaint(target->current_geometry().offset(target->window_relative().x(), target->window_relative().y()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::repaint() {
|
|
||||||
repaint(m_current_geometry);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::relayout(Widget *target) {
|
|
||||||
m_did_relayout_during_batch = true;
|
|
||||||
|
|
||||||
if (m_is_batching) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto event = RelayoutSubtreeEvent();
|
|
||||||
target->dispatch_event(event);
|
target->dispatch_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::relayout() {
|
void Window::reflow(ReflowType type) {
|
||||||
m_did_relayout_during_batch = true;
|
if (type == ReflowType::RelayoutRect) {
|
||||||
|
m_did_relayout_during_batch = true;
|
||||||
|
} else if (type == ReflowType::RepaintRect) {
|
||||||
|
m_did_repaint_during_batch = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_is_batching) {
|
if (m_is_batching) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto event = RelayoutSubtreeEvent();
|
auto event = ReflowEvent(type, ReflowGrouping::Yes, m_current_geometry);
|
||||||
dispatch_to_main_widget(event);
|
dispatch_to_main_widget(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::reflow() {
|
void Window::reflow(Box &box, ReflowType type) {
|
||||||
relayout();
|
if (type == ReflowType::RelayoutRect) {
|
||||||
repaint();
|
m_did_relayout_during_batch = true;
|
||||||
|
} else if (type == ReflowType::RepaintRect) {
|
||||||
|
m_did_repaint_during_batch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_is_batching) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto event = ReflowEvent(type, ReflowGrouping::Yes, box);
|
||||||
|
dispatch_to_main_widget(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::start_batch() {
|
void Window::start_batch() {
|
||||||
|
@ -127,9 +125,9 @@ void Window::end_batch() {
|
||||||
if (m_is_batching) {
|
if (m_is_batching) {
|
||||||
m_is_batching = false;
|
m_is_batching = false;
|
||||||
if (m_did_relayout_during_batch) {
|
if (m_did_relayout_during_batch) {
|
||||||
reflow();
|
reflow(ReflowType::RelayoutRect);
|
||||||
} else if (m_did_repaint_during_batch) {
|
} else if (m_did_repaint_during_batch) {
|
||||||
repaint();
|
reflow(ReflowType::RelayoutRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +161,7 @@ void Window::run(bool block) {
|
||||||
}
|
}
|
||||||
case Expose: {
|
case Expose: {
|
||||||
if (e.xexpose.count == 0) {
|
if (e.xexpose.count == 0) {
|
||||||
reflow();
|
reflow(ReflowType::RelayoutRect);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,9 @@ public:
|
||||||
|
|
||||||
std::shared_ptr<TopLevelStyles> top_level_styles() { return m_top_level_styles; }
|
std::shared_ptr<TopLevelStyles> top_level_styles() { return m_top_level_styles; }
|
||||||
|
|
||||||
void repaint();
|
void reflow(Widget *target, ReflowType type);
|
||||||
void repaint(Box geometry);
|
void reflow(Box &box, ReflowType type);
|
||||||
void repaint(Widget *target);
|
void reflow(ReflowType type);
|
||||||
void relayout(Widget *target);
|
|
||||||
void relayout();
|
|
||||||
void reflow();
|
|
||||||
|
|
||||||
Box ¤t_geometry() { return m_current_geometry; }
|
Box ¤t_geometry() { return m_current_geometry; }
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Box.hpp"
|
#include "Box.hpp"
|
||||||
#include "Label.hpp"
|
#include "Label.hpp"
|
||||||
#include "Layout.hpp"
|
#include "Layout.hpp"
|
||||||
#include "RGB.hpp"
|
|
||||||
#include "src/DocumentLayout.hpp"
|
#include "src/DocumentLayout.hpp"
|
||||||
#include "src/Events.hpp"
|
#include "src/Events.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -18,13 +17,9 @@ int main() {
|
||||||
|
|
||||||
auto main_widget = window.set_main_widget<Raven::Widget>();
|
auto main_widget = window.set_main_widget<Raven::Widget>();
|
||||||
|
|
||||||
auto second_widget = main_widget->add<Raven::Widget>();
|
auto inner_widget = main_widget->add<Raven::Widget>();
|
||||||
second_widget->set_layout<Raven::DocumentLayout>(16.0);
|
|
||||||
second_widget->resize(800, 800);
|
|
||||||
|
|
||||||
auto inner_widget = second_widget->add<Raven::Widget>();
|
|
||||||
inner_widget->set_layout<Raven::DocumentLayout>(8.0);
|
inner_widget->set_layout<Raven::DocumentLayout>(8.0);
|
||||||
inner_widget->resize(600, 600);
|
inner_widget->resize(400, 400);
|
||||||
|
|
||||||
int number = 0;
|
int number = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue