64 lines
2 KiB
C++
64 lines
2 KiB
C++
#include <psemek/ui/impl/label_base.hpp>
|
|
#include <psemek/react/map.hpp>
|
|
#include <psemek/react/join.hpp>
|
|
|
|
namespace psemek::ui::impl
|
|
{
|
|
|
|
label_base::label_base()
|
|
: font_(react::value<fonts::font *>(nullptr))
|
|
, glyphs_(react::value<std::vector<fonts::shaped_glyph>>(std::vector<fonts::shaped_glyph>{}))
|
|
, size_(react::map([](std::vector<fonts::shaped_glyph> const & glyphs, fonts::font * font){
|
|
if (!font)
|
|
return geom::vector{0.f, 0.f};
|
|
geom::box<float, 2> bbox;
|
|
for (auto const & glyph : glyphs)
|
|
bbox |= glyph.position;
|
|
return geom::vector{bbox[0].length(), font->size()[1]};
|
|
}, react::join(glyphs_), react::join(font_)))
|
|
, size_constraints_(react::map([](geom::vector<float, 2> const & size){
|
|
geom::box<float, 2> result;
|
|
result[0].min = size[0];
|
|
result[0].max = size_constraints::infinity;
|
|
result[1].min = size[1];
|
|
result[1].max = size_constraints::infinity;
|
|
return impl::size_constraints{result};
|
|
}, size_))
|
|
{}
|
|
|
|
react::value<size_constraints> label_base::size_constraints() const
|
|
{
|
|
return size_constraints_;
|
|
}
|
|
|
|
void label_base::draw(renderer & renderer)
|
|
{
|
|
if (!glyphs_ || !*glyphs_)
|
|
return;
|
|
|
|
auto const size = *size_;
|
|
auto const shape = this->shape();
|
|
|
|
geom::vector<float, 2> origin;
|
|
origin[0] = std::round(geom::lerp(shape[0].min, shape[0].max - size[0], lerp_factor(*halign_)));
|
|
origin[1] = std::round(geom::lerp(shape[1].min, shape[1].max - size[1], lerp_factor(*valign_)));
|
|
origin[1] += std::round((size[1] + (**font_)->xheight()) / 2.f);
|
|
|
|
for (auto const & glyph : **glyphs_)
|
|
renderer.draw_glyph(*glyph.texture, glyph.position + origin, glyph.texcoords, *color_);
|
|
}
|
|
|
|
void label_base::update(label const & value)
|
|
{
|
|
font_.set(value.font);
|
|
glyphs_.set(react::map([](std::string const & str, fonts::font * font) -> std::vector<fonts::shaped_glyph> {
|
|
if (!font)
|
|
return {};
|
|
return font->shape(str, {});
|
|
}, value.text, value.font));
|
|
color_ = value.color;
|
|
halign_ = value.halign;
|
|
valign_ = value.valign;
|
|
}
|
|
|
|
}
|