Compare commits

..

10 commits

12 changed files with 175 additions and 40 deletions

View file

@ -13,6 +13,8 @@ executable(
'./src/Widget.cpp', './src/Widget.cpp',
'./src/Button.cpp', './src/Button.cpp',
'./src/DocumentLayout.cpp', './src/DocumentLayout.cpp',
'./src/HorizontalBoxLayout.cpp',
'./src/VerticalBoxLayout.cpp',
'./src/Label.cpp', './src/Label.cpp',
'./src/main.cpp', './src/main.cpp',
dependencies : [cairomm_dep, xlib_dep, pangocairo_dep] dependencies : [cairomm_dep, xlib_dep, pangocairo_dep]

View file

@ -0,0 +1,39 @@
#include "HorizontalBoxLayout.hpp"
#include "Point.hpp"
#include "Widget.hpp"
namespace Raven {
void HorizontalBoxLayout::run() {
if (!m_target) {
return;
}
Point current_point { m_margin, m_margin };
double max_height_so_far = 0;
double requested_width = 0;
auto& children = m_target->children();
for (auto child : children) {
if (child->absolute()) {
continue;
}
if (child->rect().height() > max_height_so_far) {
max_height_so_far = child->rect().height();
}
requested_width += child->rect().width() + m_margin;
child->rect().set_x(current_point.x());
child->rect().set_y(current_point.y());
current_point.add(child->rect().width() + m_margin, 0);
}
m_target->rect().set_width(requested_width + m_margin);
m_target->rect().set_height(max_height_so_far + m_margin * 2);
}
}

View file

@ -0,0 +1,27 @@
#pragma once
#include "Layout.hpp"
namespace Raven {
class HorizontalBoxLayout : public Layout {
private:
double m_margin { 0.0 };
public:
HorizontalBoxLayout()
: Layout() {}
HorizontalBoxLayout(double margin)
: Layout()
, m_margin(margin) {}
void run();
double margin() { return m_margin; }
void set_margin(double margin) { m_margin = margin; run(); }
virtual ~HorizontalBoxLayout() {}
};
}

View file

@ -7,6 +7,11 @@
namespace Raven { namespace Raven {
void Painter::rounded_rectangle(Box &geometry, double border_radius) { void Painter::rounded_rectangle(Box &geometry, double border_radius) {
if (border_radius == 0.0) {
m_cairo->rectangle(geometry.x(), geometry.y(), geometry.width(), geometry.height());
return;
}
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;
@ -43,13 +48,11 @@ Point Painter::compute_text_size(Box &widget_geometry, std::string &text, PangoF
return { pango_units_to_double(font_width), pango_units_to_double(font_height) }; return { pango_units_to_double(font_width), pango_units_to_double(font_height) };
} }
Point Painter::text(Box &geometry, std::string &text, PaintTextAlign align, PangoEllipsizeMode ellipsize, PangoFontDescription *pango_font_description) { void Painter::text(Box &geometry, std::string &text, PaintTextAlign align, PangoEllipsizeMode ellipsize, PangoFontDescription *pango_font_description) {
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, pango_font_description); pango_layout_set_font_description(layout, pango_font_description);
if (geometry.width() > 0) if (geometry.width() > 0)
@ -60,7 +63,6 @@ Point Painter::text(Box &geometry, std::string &text, PaintTextAlign align, Pang
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 = 0; double x = 0;
double y = ((geometry.height() - font_height) / 2); double y = ((geometry.height() - font_height) / 2);
@ -69,12 +71,11 @@ Point Painter::text(Box &geometry, std::string &text, PaintTextAlign align, Pang
x = ((geometry.width() - font_width) / 2); x = ((geometry.width() - font_width) / 2);
} }
m_cairo->move_to(x, y); m_cairo->move_to(std::floor(x), std::floor(y));
pango_cairo_show_layout(m_cairo->cobj(), layout); pango_cairo_show_layout(m_cairo->cobj(), layout);
g_object_unref(layout); g_object_unref(layout);
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

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

View file

@ -36,13 +36,24 @@ GenericStyle default_widget_style {
false false
}; };
GenericStyle accent_widget_style {
pango_font_description_from_string("sans-serif"),
black6,
white2,
white2,
white2,
0.0,
true,
false
};
GenericStyle default_button_style { GenericStyle default_button_style {
pango_font_description_from_string("sans-serif"), pango_font_description_from_string("sans-serif"),
black6, black6,
white2, white2,
white1, white1,
white0, white0,
6.0, 5.0,
true, true,
true true
}; };

View file

@ -25,6 +25,7 @@ extern RGB accent1;
extern RGB accent2; extern RGB accent2;
extern GenericStyle default_widget_style; extern GenericStyle default_widget_style;
extern GenericStyle accent_widget_style;
extern GenericStyle default_button_style; extern GenericStyle default_button_style;
extern GenericStyle accent_button_style; extern GenericStyle accent_button_style;
extern GenericStyle default_label_style; extern GenericStyle default_label_style;

39
src/VerticalBoxLayout.cpp Normal file
View file

@ -0,0 +1,39 @@
#include "VerticalBoxLayout.hpp"
#include "Point.hpp"
#include "Widget.hpp"
namespace Raven {
void VerticalBoxLayout::run() {
if (!m_target) {
return;
}
Point current_point { m_margin, m_margin };
double max_width_so_far = 0;
double requested_height = 0;
auto& children = m_target->children();
for (auto child : children) {
if (child->absolute()) {
continue;
}
if (child->rect().width() > max_width_so_far) {
max_width_so_far = child->rect().height();
}
requested_height += child->rect().height() + m_margin;
child->rect().set_x(current_point.x());
child->rect().set_y(current_point.y());
current_point.add(0, child->rect().height() + m_margin);
}
m_target->rect().set_height(requested_height + m_margin);
m_target->rect().set_width(max_width_so_far + m_margin * 2);
}
}

27
src/VerticalBoxLayout.hpp Normal file
View file

@ -0,0 +1,27 @@
#pragma once
#include "Layout.hpp"
namespace Raven {
class VerticalBoxLayout : public Layout {
private:
double m_margin { 0.0 };
public:
VerticalBoxLayout()
: Layout() {}
VerticalBoxLayout(double margin)
: Layout()
, m_margin(margin) {}
void run();
double margin() { return m_margin; }
void set_margin(double margin) { m_margin = margin; run(); }
virtual ~VerticalBoxLayout() {}
};
}

View file

@ -22,9 +22,9 @@ void Widget::fit_text(std::string &text) {
return; return;
auto size = window()->painter().compute_text_size(rect(), text, style()->font_description()); auto size = window()->painter().compute_text_size(rect(), text, style()->font_description());
// always reflow, even if resize doesn't // always repaint, even if resize doesn't reflow
if (!resize(size)) { if (!resize(size)) {
reflow(); repaint();
} }
} }
@ -139,7 +139,7 @@ void Widget::handle_repaint_rect(RepaintRectEvent &event) {
} else { } else {
painter.source_rgb(m_style->background_norm()); painter.source_rgb(m_style->background_norm());
} }
painter.rounded_rectangle(event.box(), m_style->border_radius()); painter.rounded_rectangle(event.box(), 0.0);
cr->fill(); cr->fill();
} }

View file

@ -154,6 +154,10 @@ void Window::run(bool block) {
m_rect.set_height(e.xconfigure.height); m_rect.set_height(e.xconfigure.height);
// if we have a main widget, we are going to have to resize it as well // if we have a main widget, we are going to have to resize it as well
if (m_main_widget) { if (m_main_widget) {
m_main_widget->rect().set_max_height(m_rect.height());
m_main_widget->rect().set_max_width(m_rect.width());
m_main_widget->rect().set_min_height(m_rect.height());
m_main_widget->rect().set_min_width(m_rect.width());
m_main_widget->rect().set_width(m_rect.width()); m_main_widget->rect().set_width(m_rect.width());
m_main_widget->rect().set_height(m_rect.height()); m_main_widget->rect().set_height(m_rect.height());
} }

View file

@ -8,7 +8,9 @@
#include "RGB.hpp" #include "RGB.hpp"
#include "DocumentLayout.hpp" #include "DocumentLayout.hpp"
#include "Events.hpp" #include "Events.hpp"
#include "src/HorizontalBoxLayout.hpp"
#include "src/Styles.hpp" #include "src/Styles.hpp"
#include "src/VerticalBoxLayout.hpp"
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <string> #include <string>
@ -18,37 +20,19 @@ int main() {
window.spawn_window(); window.spawn_window();
auto main_widget = window.set_main_widget<Raven::Widget>(); auto main_widget = window.set_main_widget<Raven::Widget>();
main_widget->set_layout<Raven::DocumentLayout>(10.0); main_widget->set_layout<Raven::VerticalBoxLayout>(6.0);
auto second_widget = main_widget->add<Raven::Widget>(); for (int i = 0; i < 12; i++) {
second_widget->set_layout<Raven::DocumentLayout>(20.0); auto row = main_widget->add<Raven::Widget>();
second_widget->resize(800, 800); row->set_layout<Raven::HorizontalBoxLayout>(6.0);
for (int i = 0; i < 12; i++) {
auto button = row->add<Raven::Button>("0");
auto inner_widget = second_widget->add<Raven::Widget>(); button->on_click = [button]() {
inner_widget->set_layout<Raven::DocumentLayout>(8.0); int number = std::stoi(button->text());
inner_widget->resize(600, 600); button->set_text(std::to_string(++number));
};
int number = 0; }
for (int i = 0; i < 250; i++) {
auto button = inner_widget->add<Raven::Button>("click me");
button->set_style(&Raven::accent_button_style);
auto label = inner_widget->add<Raven::Label>("click one of the buttons!");
button->on_click = [&]() {
number += 10;
window.start_batch();
auto& children = inner_widget->children();
for (auto& child : children) {
if (child->type() == Raven::WidgetType::Button) {
std::static_pointer_cast<Raven::Button>(child)->set_text(std::to_string(number));
}
if (child->type() == Raven::WidgetType::Label) {
std::static_pointer_cast<Raven::Label>(child)->set_text(std::to_string(number));
}
}
window.end_batch();
};
} }
window.run(true); window.run(true);