make aligned layout orientation a template parameter.
This commit is contained in:
parent
718af15b07
commit
280575a0e2
4 changed files with 63 additions and 72 deletions
|
@ -47,11 +47,11 @@ void run_example(
|
||||||
std::make_shared<bwidgets::Renderer>(win(), -1, SDL_RENDERER_ACCELERATED);
|
std::make_shared<bwidgets::Renderer>(win(), -1, SDL_RENDERER_ACCELERATED);
|
||||||
renderer->blend_mode(SDL_BLENDMODE_BLEND);
|
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++) {
|
for (auto x = 0; x < w; x++) {
|
||||||
auto col = std::make_unique<bwidgets::AlignedLayout>(
|
auto col = std::make_unique<
|
||||||
bwidgets::AlignedLayout::Alignment::VERTICAL);
|
bwidgets::AlignedLayout<bwidgets::LayoutAlignment::VERTICAL>>();
|
||||||
for (auto y = 0; y < h; y++) {
|
for (auto y = 0; y < h; y++) {
|
||||||
auto widget = std::make_unique<W>();
|
auto widget = std::make_unique<W>();
|
||||||
setup(widget.get(), font, x, y);
|
setup(widget.get(), font, x, y);
|
||||||
|
|
|
@ -1,25 +1,51 @@
|
||||||
#ifndef BWIDGETS_ALIGNED_LAYOUT_HPP
|
#ifndef BWIDGETS_ALIGNED_LAYOUT_HPP
|
||||||
#define BWIDGETS_ALIGNED_LAYOUT_HPP
|
#define BWIDGETS_ALIGNED_LAYOUT_HPP
|
||||||
|
|
||||||
|
#include <basic_widgets/core/math.hpp>
|
||||||
#include <basic_widgets/w/base/layout.hpp>
|
#include <basic_widgets/w/base/layout.hpp>
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
|
enum struct LayoutAlignment
|
||||||
|
{
|
||||||
|
HORIZONTAL,
|
||||||
|
VERTICAL
|
||||||
|
};
|
||||||
|
|
||||||
|
template<LayoutAlignment alignment>
|
||||||
class AlignedLayout final : public Layout
|
class AlignedLayout final : public Layout
|
||||||
{
|
{
|
||||||
private:
|
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:
|
public:
|
||||||
enum struct Alignment
|
AlignedLayout(Widget* p = nullptr) noexcept : Layout(p) {}
|
||||||
{
|
|
||||||
HORIZONTAL,
|
|
||||||
VERTICAL
|
|
||||||
} alignment;
|
|
||||||
|
|
||||||
AlignedLayout(Alignment align, Widget* p = nullptr) noexcept
|
|
||||||
: Layout(p), alignment(align)
|
|
||||||
{}
|
|
||||||
|
|
||||||
AlignedLayout(const AlignedLayout&) = delete;
|
AlignedLayout(const AlignedLayout&) = delete;
|
||||||
AlignedLayout(AlignedLayout&&) = delete;
|
AlignedLayout(AlignedLayout&&) = delete;
|
||||||
|
@ -27,7 +53,30 @@ namespace bwidgets
|
||||||
auto operator=(const AlignedLayout&) = delete;
|
auto operator=(const AlignedLayout&) = delete;
|
||||||
auto operator=(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};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ libbasic_widgets = static_library('basic_widgets',
|
||||||
'src/core/font.cpp',
|
'src/core/font.cpp',
|
||||||
'src/core/renderer.cpp',
|
'src/core/renderer.cpp',
|
||||||
'src/core/texture.cpp',
|
'src/core/texture.cpp',
|
||||||
'src/w/aligned_layout.cpp',
|
|
||||||
'src/w/base/layout.cpp',
|
'src/w/base/layout.cpp',
|
||||||
'src/w/base/widget.cpp',
|
'src/w/base/widget.cpp',
|
||||||
'src/w/button.cpp',
|
'src/w/button.cpp',
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue