respect slotted widget rectangle extents in boxlayout

currently thinking of a way to make unslotted widgets respect minimum
and maximum extents.
This commit is contained in:
hippoz 2022-07-09 20:19:09 +03:00
parent 3ab3e74cd1
commit 1ceb227165
No known key found for this signature in database
GPG key ID: 7C52899193467641
9 changed files with 50 additions and 154 deletions

View file

@ -1,23 +1,27 @@
project('raven', 'cpp') project(
'raven',
'cpp',
default_options : ['cpp_std=c++17']
)
cairomm_dep = dependency('cairomm-1.0') cairomm_dep = dependency('cairomm-1.0')
pangocairo_dep = dependency('pangocairo') pangocairo_dep = dependency('pangocairo')
xlib_dep = dependency('x11') xlib_dep = dependency('x11')
executable( executable(
'ravenapp', 'ravenapp',
'./src/Box.cpp', './src/Box.cpp',
'./src/Styles.cpp', './src/Styles.cpp',
'./src/Painter.cpp', './src/Painter.cpp',
'./src/Window.cpp', './src/Window.cpp',
'./src/Widget.cpp', './src/Widget.cpp',
'./src/ScrollContainer.cpp', './src/ScrollContainer.cpp',
'./src/Button.cpp', './src/Button.cpp',
'./src/DocumentLayout.cpp', './src/DocumentLayout.cpp',
'./src/HorizontalBoxLayout.cpp', './src/RowLayout.cpp',
'./src/VerticalBoxLayout.cpp', './src/ColumnLayout.cpp',
'./src/BoxLayout.cpp', './src/BoxLayout.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

@ -69,4 +69,10 @@ Box Box::max_geometry() {
return Box{ m_x, m_y, max_width, max_height }; return Box{ m_x, m_y, max_width, max_height };
} }
Box Box::min_geometry() {
auto min_width = m_min_width == -1 ? m_width : m_min_width;
auto min_height = m_min_height == -1 ? m_height : m_min_height;
return Box{ m_x, m_y, min_width, min_height };
}
} }

View file

@ -32,6 +32,7 @@ public:
} }
Box max_geometry(); Box max_geometry();
Box min_geometry();
double x() { return m_x; } double x() { return m_x; }
double y() { return m_y; } double y() { return m_y; }

View file

@ -3,6 +3,7 @@
#include "Widget.hpp" #include "Widget.hpp"
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include <algorithm>
namespace Raven { namespace Raven {
@ -24,16 +25,31 @@ void BoxLayout::run() {
unslotted_widgets++; unslotted_widgets++;
} else { } else {
Slot *slot = &m_slots[i]; Slot *slot = &m_slots[i];
auto child = m_target->children()[i];
if (m_direction == Direction::Horizontal) { if (m_direction == Direction::Horizontal) {
if (slot->type == SlotType::Percent) { if (slot->type == SlotType::Percent) {
slot->pixel = (free_space.width() / 100.0) * slot->percent; slot->pixel = ((free_space.width() / 100.0) * slot->percent);
} }
if (child->rect().max_width() != -1 && slot->pixel > child->rect().max_width()) {
slot->pixel = child->rect().max_width();
}
if (child->rect().min_width() != -1 && slot->pixel < child->rect().min_width()) {
slot->pixel = child->rect().min_width();
}
free_space.set_width(free_space.width() - slot->pixel); free_space.set_width(free_space.width() - slot->pixel);
} else { } else {
if (slot->type == SlotType::Percent) { if (slot->type == SlotType::Percent) {
slot->pixel = (free_space.height() / 100.0) * slot->percent; slot->pixel = ((free_space.height() / 100.0) * slot->percent);
} }
if (child->rect().max_height() != -1 && slot->pixel > child->rect().max_height()) {
slot->pixel = child->rect().max_height();
}
if (child->rect().min_height() != -1 && slot->pixel < child->rect().min_height()) {
slot->pixel = child->rect().min_height();
}
free_space.set_height(free_space.height() - slot->pixel); free_space.set_height(free_space.height() - slot->pixel);
} }
} }

View file

@ -1,39 +0,0 @@
#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

@ -1,27 +0,0 @@
#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

@ -1,39 +0,0 @@
#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);
}
}

View file

@ -1,27 +0,0 @@
#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

@ -10,10 +10,8 @@
#include "Events.hpp" #include "Events.hpp"
#include "src/BoxLayout.hpp" #include "src/BoxLayout.hpp"
#include "src/Box.hpp" #include "src/Box.hpp"
#include "src/HorizontalBoxLayout.hpp"
#include "src/ScrollContainer.hpp" #include "src/ScrollContainer.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>
@ -28,14 +26,17 @@ int main() {
auto top_bar = main_widget->add<Raven::Widget>(); auto top_bar = main_widget->add<Raven::Widget>();
top_bar->set_style(&Raven::accent_widget_style); top_bar->set_style(&Raven::accent_widget_style);
top_bar->set_layout<Raven::BoxLayout>(Raven::Direction::Horizontal); auto top_layout = top_bar->set_layout<Raven::BoxLayout>(Raven::Direction::Horizontal);
top_layout->slot_percent(50);
top_layout->slot_percent(100);
auto scroll_container = main_widget->add<Raven::ScrollContainer>(); auto scroll_container = main_widget->add<Raven::ScrollContainer>();
auto container_widget = scroll_container->make_target(); auto container_widget = scroll_container->make_target();
container_widget->set_layout<Raven::BoxLayout>(Raven::Direction::Vertical); container_widget->set_layout<Raven::BoxLayout>(Raven::Direction::Vertical);
container_widget->resize(400, 400); container_widget->resize(400, 400);
auto new_button = top_bar->add<Raven::Button>("add"); auto new_button = top_bar->add<Raven::Button>("add");
new_button->rect().set_max_width(50);
new_button->on_click = [container_widget]() { new_button->on_click = [container_widget]() {
auto button = container_widget->add<Raven::Button>("button"); auto button = container_widget->add<Raven::Button>("button");
button->on_click = [button]() { button->on_click = [button]() {