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 "Point.hpp"
#include <iostream>
namespace Raven {
@ -28,4 +29,30 @@ bool Box::contains_box(const Box &other) const {
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_width {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:
Box() {}
Box(double x, double y, double width, double height)
@ -21,20 +26,35 @@ public:
}
Box max_geometry();
double x() { return m_x; }
double y() { return m_y; }
double width() { return m_width; }
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 y() const { return m_y; }
double width() const { return m_width; }
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_y(double y) { m_y = y; }
void set_width(double width) { m_width = width; }
void set_height(double height) { m_height = height; }
void set_width(double width);
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(const Point &point) const;

View file

@ -26,12 +26,16 @@ void Button::update_color() {
}
void Button::on_paint() {
auto painter = window()->painter();
do_generic_paint();
auto painter = window()->painter();
auto text_color = styles()->button_text_color();
auto max_geometry = current_geometry().max_geometry();
painter.source_rgb(text_color);
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();
}

View file

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

View file

@ -1,6 +1,7 @@
#include "Label.hpp"
#include "Window.hpp"
#include "pango/pango-layout.h"
#include <iostream>
namespace Raven {
@ -14,12 +15,16 @@ void Label::on_init() {
}
void Label::on_paint() {
do_generic_paint();
auto painter = window()->painter();
auto text_color = styles()->label_text_color();
auto text_geometry = current_geometry().max_geometry();
painter.source_rgb(text_color);
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();
}

View file

@ -39,22 +39,27 @@ bool Painter::text(Point &where, std::string &text) {
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)
return false;
return {-1,-1};
PangoLayout *layout = pango_cairo_create_layout(m_cairo->cobj());
int font_width;
int font_height;
int pango_width;
int pango_height;
pango_layout_set_font_description(layout, m_pango_font_description);
pango_layout_set_width(layout, pango_units_from_double(geometry.width()));
pango_layout_set_height(layout, pango_units_from_double(geometry.height()));
if (geometry.width() > 0)
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_text(layout, text.c_str(), -1);
pango_layout_get_pixel_size(layout, &font_width, &font_height);
pango_layout_get_size(layout, &pango_width, &pango_height);
double x = -1;
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);
return true;
return {pango_units_to_double(pango_width), pango_units_to_double(pango_height)};
}
void Painter::source_rgb(RGB &source_rgb) {

View file

@ -29,7 +29,7 @@ public:
void rounded_rectangle(Box &geometry, double border_radius);
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; }

View file

@ -9,6 +9,27 @@
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() {
if (m_layout) {
m_layout->run();
@ -112,8 +133,6 @@ void Widget::handle_repaint(WidgetRepaintRequestedEvent &event) {
painter.begin_paint_group();
}
do_generic_paint();
cr->save();
on_paint();
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, 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; }
bool add_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_focus_update(FocusUpdateEvent &event) {}
virtual void on_activation_update(ActivationUpdateEvent &event) {}
virtual void on_paint() {}
virtual void on_paint() { do_generic_paint(); }
void do_generic_paint();
private:
void wants_full_repaint();
void wants_full_relayout();
void do_layout();
void handle_repaint(WidgetRepaintRequestedEvent& event);
void do_generic_paint();
void handle_mouse_move_event(MouseMoveEvent &event);
void handle_mouse_button_event(MouseButtonEvent &event);
};

View file

@ -22,10 +22,6 @@ int main() {
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 = [&]() {
number++;
label->set_text(std::to_string(number));