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:
parent
3ab3e74cd1
commit
1ceb227165
9 changed files with 50 additions and 154 deletions
36
meson.build
36
meson.build
|
@ -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]
|
||||||
)
|
)
|
||||||
|
|
|
@ -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 };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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]() {
|
||||||
|
|
Loading…
Reference in a new issue