- mark as const every pointer that can be const. - in implementation mark const args passed by value that are meant to be read-only. - wrap in a lambda complex initializations of (const) values. - argument passing: - pass by value arguments of cheap-to-copy types or meant to be copied anyway. - pass by (const) reference args not meant to outlive called function scope and not cheap-to-copy. - pass (const) pointers to (const) args when null is a valid option and pointed data aren't expected to outlive function scope. - use string_view for non-owned strings (not meant to outlive function scope). - use span for collection types like vector and arrays. - fancy pointers passing: - pass by value if a reference will be held: - pass by const reference if a reference _may_ be hell. - when no references are meant to be held: - dereference the pointer to pass the pointed data by reference if null is not an option. - pass the underlying raw pointer if null is an option. … and random subtle changes and fixes here and there that I forgot to mention.
76 lines
2.6 KiB
C++
76 lines
2.6 KiB
C++
#ifndef BWIDGETS_ALIGNED_LAYOUT_IMPL_HPP
|
|
#define BWIDGETS_ALIGNED_LAYOUT_IMPL_HPP
|
|
|
|
#include <basic_widgets/core/math.hpp>
|
|
#include <basic_widgets/w/aligned_layout.hpp>
|
|
#include <basic_widgets/w/base/layout_impl.hpp>
|
|
#include <basic_widgets/w/base/widget_impl.hpp>
|
|
|
|
namespace bwidgets
|
|
{
|
|
template<LayoutAlignment alignment>
|
|
class AlignedLayoutImpl final : public virtual AlignedLayout,
|
|
public virtual LayoutImpl,
|
|
public virtual WidgetImpl
|
|
{
|
|
public:
|
|
using LayoutImpl::LayoutImpl;
|
|
|
|
[[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};
|
|
}
|
|
|
|
private:
|
|
void _update_layout(const SDL_Rect& vp) override
|
|
{
|
|
if constexpr (alignment == LayoutAlignment::HORIZONTAL) {
|
|
const 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;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif
|