add sizing based on text size

This commit is contained in:
hippoz 2022-05-08 19:31:31 +03:00
parent 1aec5d3e44
commit 5d672e9eec
Signed by: hippoz
GPG key ID: 7C52899193467641
10 changed files with 103 additions and 21 deletions

View file

@ -1,5 +1,6 @@
#include "Box.hpp" #include "Box.hpp"
#include "Point.hpp" #include "Point.hpp"
#include <iostream>
namespace Raven { namespace Raven {
@ -28,4 +29,30 @@ bool Box::contains_box(const Box &other) const {
return boxes_overlap; return boxes_overlap;
} }
void Box::set_width(double width) {
if (m_max_width != -1 && width > m_max_width) {
m_width = m_max_width;
} else if (m_min_width != -1 && width < m_min_width) {
m_width = m_min_width;
} else {
m_width = width;
}
}
void Box::set_height(double height) {
if (m_max_height != -1 && height > m_max_height) {
m_height = m_max_height;
} else if (m_min_height != -1 && height < m_min_height) {
m_height = m_min_height;
} else {
m_height = height;
}
}
Box Box::max_geometry() {
auto max_width = m_max_width == -1 ? m_width : m_max_width;
auto max_height = m_max_height == -1 ? m_height : m_max_height;
return Box{ m_x, m_y, max_width, max_height };
}
} }

View file

@ -10,6 +10,11 @@ private:
double m_y {0}; double m_y {0};
double m_width {0}; double m_width {0};
double m_height {0}; double m_height {0};
double m_max_width {-1};
double m_max_height {-1};
double m_min_width {-1};
double m_min_height {-1};
public: public:
Box() {} Box() {}
Box(double x, double y, double width, double height) Box(double x, double y, double width, double height)
@ -21,20 +26,35 @@ public:
} }
Box max_geometry();
double x() { return m_x; } double x() { return m_x; }
double y() { return m_y; } double y() { return m_y; }
double width() { return m_width; } double width() { return m_width; }
double height() { return m_height; } double height() { return m_height; }
double min_width() { return m_min_width; }
double min_height() { return m_min_height; }
double max_width() { return m_max_width; }
double max_height() { return m_max_height; }
double x() const { return m_x; } double x() const { return m_x; }
double y() const { return m_y; } double y() const { return m_y; }
double width() const { return m_width; } double width() const { return m_width; }
double height() const { return m_height; } double height() const { return m_height; }
double min_width() const { return m_min_width; }
double min_height() const { return m_min_height; }
double max_width() const { return m_max_width; }
double max_height() const { return m_max_height; }
void set_x(double x) { m_x = x; } void set_x(double x) { m_x = x; }
void set_y(double y) { m_y = y; } void set_y(double y) { m_y = y; }
void set_width(double width) { m_width = width; } void set_width(double width);
void set_height(double height) { m_height = height; } void set_height(double height);
void set_max_width(double max_width) { m_max_width = max_width; set_width(m_width); }
void set_max_height(double max_height) { m_max_height = max_height; set_height(m_height); }
void set_min_width(double min_width) { m_min_width = min_width; set_width(m_width); }
void set_min_height(double min_height) { m_min_height = min_height; set_height(m_height); }
bool contains_point(double x, double y) const; bool contains_point(double x, double y) const;
bool contains_point(const Point &point) const; bool contains_point(const Point &point) const;

View file

@ -26,12 +26,16 @@ void Button::update_color() {
} }
void Button::on_paint() { void Button::on_paint() {
auto painter = window()->painter(); do_generic_paint();
auto painter = window()->painter();
auto text_color = styles()->button_text_color(); auto text_color = styles()->button_text_color();
auto max_geometry = current_geometry().max_geometry();
painter.source_rgb(text_color); painter.source_rgb(text_color);
painter.set_pango_font_description(styles()->controls_font_description()); painter.set_pango_font_description(styles()->controls_font_description());
painter.text(current_geometry(), m_text, PaintTextAlign::Center, PANGO_ELLIPSIZE_END); auto point = painter.text(max_geometry, m_text, PaintTextAlign::Center, PANGO_ELLIPSIZE_END);
resize(point);
painter.fill(); painter.fill();
} }

View file

@ -1,6 +1,7 @@
#include "DocumentLayout.hpp" #include "DocumentLayout.hpp"
#include "Point.hpp" #include "Point.hpp"
#include "Widget.hpp" #include "Widget.hpp"
#include <iostream>
namespace Raven { namespace Raven {
@ -21,8 +22,8 @@ void DocumentLayout::run() {
if (c->current_geometry().height() > row_largest_height) { if (c->current_geometry().height() > row_largest_height) {
row_largest_height = c->current_geometry().height(); row_largest_height = c->current_geometry().height();
} }
auto new_geometry = Box{ point.x(), point.y(), c->current_geometry().width(), c->current_geometry().height() }; c->current_geometry().set_x(point.x());
c->set_current_geometry(std::move(new_geometry), true); c->current_geometry().set_y(point.y());
point.add(c->current_geometry().width() + m_margin, 0); point.add(c->current_geometry().width() + m_margin, 0);
} }
} }

View file

@ -1,6 +1,7 @@
#include "Label.hpp" #include "Label.hpp"
#include "Window.hpp" #include "Window.hpp"
#include "pango/pango-layout.h" #include "pango/pango-layout.h"
#include <iostream>
namespace Raven { namespace Raven {
@ -14,12 +15,16 @@ void Label::on_init() {
} }
void Label::on_paint() { void Label::on_paint() {
do_generic_paint();
auto painter = window()->painter(); auto painter = window()->painter();
auto text_color = styles()->label_text_color(); auto text_color = styles()->label_text_color();
auto text_geometry = current_geometry().max_geometry();
painter.source_rgb(text_color); painter.source_rgb(text_color);
painter.set_pango_font_description(styles()->controls_font_description()); painter.set_pango_font_description(styles()->controls_font_description());
painter.text(current_geometry(), m_text, PaintTextAlign::Left, PANGO_ELLIPSIZE_NONE); auto point = painter.text(text_geometry, m_text, PaintTextAlign::Left, PANGO_ELLIPSIZE_NONE);
resize(point);
painter.fill(); painter.fill();
} }

View file

@ -39,22 +39,27 @@ bool Painter::text(Point &where, std::string &text) {
return true; return true;
} }
bool Painter::text(Box &geometry, std::string &text, PaintTextAlign align, PangoEllipsizeMode ellipsize) { Point Painter::text(Box &geometry, std::string &text, PaintTextAlign align, PangoEllipsizeMode ellipsize) {
if (m_pango_font_description == nullptr) if (m_pango_font_description == nullptr)
return false; return {-1,-1};
PangoLayout *layout = pango_cairo_create_layout(m_cairo->cobj()); PangoLayout *layout = pango_cairo_create_layout(m_cairo->cobj());
int font_width; int font_width;
int font_height; int font_height;
int pango_width;
int pango_height;
pango_layout_set_font_description(layout, m_pango_font_description); pango_layout_set_font_description(layout, m_pango_font_description);
pango_layout_set_width(layout, pango_units_from_double(geometry.width())); if (geometry.width() > 0)
pango_layout_set_height(layout, pango_units_from_double(geometry.height())); pango_layout_set_width(layout, pango_units_from_double(geometry.width()));
if (geometry.height() > 0)
pango_layout_set_height(layout, pango_units_from_double(geometry.height()));
pango_layout_set_ellipsize(layout, ellipsize); pango_layout_set_ellipsize(layout, ellipsize);
pango_layout_set_text(layout, text.c_str(), -1); pango_layout_set_text(layout, text.c_str(), -1);
pango_layout_get_pixel_size(layout, &font_width, &font_height); pango_layout_get_pixel_size(layout, &font_width, &font_height);
pango_layout_get_size(layout, &pango_width, &pango_height);
double x = -1; double x = -1;
double y = geometry.y() + ((geometry.height() - font_height) / 2); double y = geometry.y() + ((geometry.height() - font_height) / 2);
@ -70,7 +75,7 @@ bool Painter::text(Box &geometry, std::string &text, PaintTextAlign align, Pango
g_object_unref(layout); g_object_unref(layout);
return true; return {pango_units_to_double(pango_width), pango_units_to_double(pango_height)};
} }
void Painter::source_rgb(RGB &source_rgb) { void Painter::source_rgb(RGB &source_rgb) {

View file

@ -29,7 +29,7 @@ public:
void rounded_rectangle(Box &geometry, double border_radius); void rounded_rectangle(Box &geometry, double border_radius);
bool text(Point &where, std::string &text); bool text(Point &where, std::string &text);
bool text(Box &geometry, std::string &text, PaintTextAlign align, PangoEllipsizeMode ellipsize); Point text(Box &geometry, std::string &text, PaintTextAlign align, PangoEllipsizeMode ellipsize);
bool can_paint() { if (m_cairo) return true; else return false; } bool can_paint() { if (m_cairo) return true; else return false; }

View file

@ -9,6 +9,27 @@
namespace Raven { namespace Raven {
void Widget::resize(double width, double height) {
if (m_current_geometry.width() == width && m_current_geometry.height() == height)
return;
if (width < 0 || height < 0)
return;
m_current_geometry.set_width(width);
m_current_geometry.set_height(height);
wants_full_relayout();
}
void Widget::move_to(double x, double y) {
if (m_current_geometry.x() == x && m_current_geometry.y() == y)
return;
m_current_geometry.set_x(x);
m_current_geometry.set_y(y);
wants_full_relayout();
}
void Widget::do_layout() { void Widget::do_layout() {
if (m_layout) { if (m_layout) {
m_layout->run(); m_layout->run();
@ -112,8 +133,6 @@ void Widget::handle_repaint(WidgetRepaintRequestedEvent &event) {
painter.begin_paint_group(); painter.begin_paint_group();
} }
do_generic_paint();
cr->save(); cr->save();
on_paint(); on_paint();
cr->restore(); cr->restore();

View file

@ -59,6 +59,10 @@ public:
void set_current_geometry(Box current_geometry) { m_current_geometry = current_geometry; wants_full_relayout(); } 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) { wants_full_relayout(); } } void set_current_geometry(Box current_geometry, bool is_pure) { m_current_geometry = current_geometry; if (!is_pure) { wants_full_relayout(); } }
void move_to(double x, double y);
void resize(double width, double height);
void resize(Point &point) { resize(point.x(), point.y()); }
std::vector<std::shared_ptr<Widget>> &children() { return m_children; } std::vector<std::shared_ptr<Widget>> &children() { return m_children; }
bool add_child(std::shared_ptr<Widget> child); bool add_child(std::shared_ptr<Widget> child);
void remove_child(std::shared_ptr<Widget> child); void remove_child(std::shared_ptr<Widget> child);
@ -118,13 +122,14 @@ protected:
virtual void on_mouse_move(MouseMoveEvent &event) {} virtual void on_mouse_move(MouseMoveEvent &event) {}
virtual void on_focus_update(FocusUpdateEvent &event) {} virtual void on_focus_update(FocusUpdateEvent &event) {}
virtual void on_activation_update(ActivationUpdateEvent &event) {} virtual void on_activation_update(ActivationUpdateEvent &event) {}
virtual void on_paint() {} virtual void on_paint() { do_generic_paint(); }
void do_generic_paint();
private: private:
void wants_full_repaint(); void wants_full_repaint();
void wants_full_relayout(); void wants_full_relayout();
void do_layout(); void do_layout();
void handle_repaint(WidgetRepaintRequestedEvent& event); void handle_repaint(WidgetRepaintRequestedEvent& event);
void do_generic_paint();
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);
}; };

View file

@ -22,10 +22,6 @@ int main() {
window.spawn_window(); window.spawn_window();
add_button->set_current_geometry(Raven::Box(0, 0, 100, 30));
subtract_button->set_current_geometry(Raven::Box(0, 0, 100, 30));
label->set_current_geometry(Raven::Box(0, 0, 100, 20));
add_button->on_click = [&]() { add_button->on_click = [&]() {
number++; number++;
label->set_text(std::to_string(number)); label->set_text(std::to_string(number));