make aligned layout orientation a template parameter.

This commit is contained in:
Andrea Blankenstijn 2021-08-14 11:20:26 +02:00
parent 718af15b07
commit 280575a0e2
4 changed files with 63 additions and 72 deletions

View File

@ -47,11 +47,11 @@ void run_example(
std::make_shared<bwidgets::Renderer>(win(), -1, SDL_RENDERER_ACCELERATED);
renderer->blend_mode(SDL_BLENDMODE_BLEND);
bwidgets::AlignedLayout layout(bwidgets::AlignedLayout::Alignment::HORIZONTAL);
bwidgets::AlignedLayout<bwidgets::LayoutAlignment::HORIZONTAL> layout;
for (auto x = 0; x < w; x++) {
auto col = std::make_unique<bwidgets::AlignedLayout>(
bwidgets::AlignedLayout::Alignment::VERTICAL);
auto col = std::make_unique<
bwidgets::AlignedLayout<bwidgets::LayoutAlignment::VERTICAL>>();
for (auto y = 0; y < h; y++) {
auto widget = std::make_unique<W>();
setup(widget.get(), font, x, y);

View File

@ -1,25 +1,51 @@
#ifndef BWIDGETS_ALIGNED_LAYOUT_HPP
#define BWIDGETS_ALIGNED_LAYOUT_HPP
#include <basic_widgets/core/math.hpp>
#include <basic_widgets/w/base/layout.hpp>
namespace bwidgets
{
enum struct LayoutAlignment
{
HORIZONTAL,
VERTICAL
};
template<LayoutAlignment alignment>
class AlignedLayout final : public Layout
{
private:
void _update_layout(const SDL_Rect&) override;
void _update_layout(const SDL_Rect& vp) override
{
if constexpr (alignment == LayoutAlignment::HORIZONTAL) {
int widget_width =
(vp.w - ((int)_widgets.size() + 1) * margins.w) / (int)_widgets.size();
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++) {
const auto& w {_widgets[i]};
w->viewport({vp.x + margins.w + (int)i * (widget_width + margins.w),
vp.y + center_line(vp.h, w->size().h), widget_width,
w->size().h});
}
}
else {
int offset = 0;
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++) {
const auto& w {_widgets[i]};
w->viewport({
vp.x,
vp.y + ((int)i + 1) * margins.h + offset,
vp.w,
w->size().h,
});
offset += w->size().h;
}
}
}
public:
enum struct Alignment
{
HORIZONTAL,
VERTICAL
} alignment;
AlignedLayout(Alignment align, Widget* p = nullptr) noexcept
: Layout(p), alignment(align)
{}
AlignedLayout(Widget* p = nullptr) noexcept : Layout(p) {}
AlignedLayout(const AlignedLayout&) = delete;
AlignedLayout(AlignedLayout&&) = delete;
@ -27,7 +53,30 @@ namespace bwidgets
auto operator=(const AlignedLayout&) = delete;
auto operator=(AlignedLayout&&) = delete;
[[nodiscard]] auto size() const noexcept -> Size override;
[[nodiscard]] auto size() const noexcept -> Size override
{
Size min_size {0, 0};
if constexpr (alignment == LayoutAlignment::HORIZONTAL) {
for (const auto& w : _widgets) {
if (w->size().w > min_size.w) min_size.w = w->size().w;
if (w->size().h > min_size.h) min_size.h = w->size().h;
}
return {(int)_widgets.size() * min_size.w
+ ((int)_widgets.size() + 1) * margins.w,
min_size.h + 2 * margins.h};
}
for (const auto& w : _widgets) {
if (w->size().w > min_size.w) min_size.w = w->size().w;
min_size.h += w->size().h;
}
return {min_size.w + 2 * margins.w,
min_size.h + ((int)_widgets.size() + 1) * margins.h};
}
};
}

View File

@ -25,7 +25,6 @@ libbasic_widgets = static_library('basic_widgets',
'src/core/font.cpp',
'src/core/renderer.cpp',
'src/core/texture.cpp',
'src/w/aligned_layout.cpp',
'src/w/base/layout.cpp',
'src/w/base/widget.cpp',
'src/w/button.cpp',

View File

@ -1,57 +0,0 @@
#include <basic_widgets/core/math.hpp>
#include <basic_widgets/w/aligned_layout.hpp>
using namespace bwidgets;
auto AlignedLayout::size() const noexcept -> Size
{
Size min_size {0, 0};
if (alignment == Alignment::HORIZONTAL) {
for (const auto& w : _widgets) {
if (w->size().w > min_size.w) min_size.w = w->size().w;
if (w->size().h > min_size.h) min_size.h = w->size().h;
}
return {(int)_widgets.size() * min_size.w
+ ((int)_widgets.size() + 1) * margins.w,
min_size.h + 2 * margins.h};
}
for (const auto& w : _widgets) {
if (w->size().w > min_size.w) min_size.w = w->size().w;
min_size.h += w->size().h;
}
return {min_size.w + 2 * margins.w,
min_size.h + ((int)_widgets.size() + 1) * margins.h};
}
void AlignedLayout::_update_layout(const SDL_Rect& vp)
{
if (alignment == Alignment::HORIZONTAL) {
int widget_width =
(vp.w - ((int)_widgets.size() + 1) * margins.w) / (int)_widgets.size();
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++) {
const auto& w {_widgets[i]};
w->viewport({vp.x + margins.w + (int)i * (widget_width + margins.w),
vp.y + center_line(vp.h, w->size().h), widget_width,
w->size().h});
}
}
else {
int offset = 0;
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++) {
const auto& w {_widgets[i]};
w->viewport({
vp.x,
vp.y + ((int)i + 1) * margins.h + offset,
vp.w,
w->size().h,
});
offset += w->size().h;
}
}
}