Require glyph drawing from ui::renderer & implement ui::label component
This commit is contained in:
parent
ab50b4c323
commit
611dc959da
6 changed files with 110 additions and 4 deletions
|
|
@ -3,6 +3,6 @@ file(GLOB_RECURSE PSEMEK_UI_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "sour
|
|||
|
||||
psemek_add_library(psemek-ui ${PSEMEK_UI_HEADERS} ${PSEMEK_UI_SOURCES})
|
||||
target_include_directories(psemek-ui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(psemek-ui PUBLIC psemek-util psemek-react psemek-geom psemek-async psemek-app)
|
||||
target_link_libraries(psemek-ui PUBLIC psemek-util psemek-react psemek-geom psemek-fonts psemek-async psemek-app)
|
||||
|
||||
psemek_glob_tests(psemek-ui tests)
|
||||
|
|
|
|||
31
libs/ui/include/psemek/ui/impl/label_base.hpp
Normal file
31
libs/ui/include/psemek/ui/impl/label_base.hpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ui/label.hpp>
|
||||
#include <psemek/ui/impl/component.hpp>
|
||||
#include <psemek/react/source.hpp>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
struct label_base
|
||||
: component
|
||||
{
|
||||
label_base();
|
||||
|
||||
react::value<struct size_constraints> size_constraints() const override;
|
||||
|
||||
void draw(renderer & renderer) override;
|
||||
|
||||
void update(label const & value);
|
||||
|
||||
private:
|
||||
react::source<react::value<fonts::font *>> font_;
|
||||
react::source<react::value<std::vector<fonts::shaped_glyph>>> glyphs_;
|
||||
react::value<gfx::color_rgba> color_ = gfx::color_rgba{0, 0, 0, 255};
|
||||
react::value<halignment> halign_ = halignment::center;
|
||||
react::value<valignment> valign_ = valignment::center;
|
||||
react::value<geom::vector<float, 2>> size_;
|
||||
react::value<struct size_constraints> size_constraints_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/fonts/font_v2.hpp>
|
||||
#include <psemek/gfx/color.hpp>
|
||||
#include <psemek/geom/box.hpp>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
struct renderer
|
||||
{
|
||||
virtual void draw_glyph(fonts::texture_type const & texture, geom::box<float, 2> const & position, geom::box<float, 2> const & texcoord, gfx::color_rgba const & color) = 0;
|
||||
|
||||
virtual ~renderer() {}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ui/alignment.hpp>
|
||||
#include <psemek/fonts/font_v2.hpp>
|
||||
#include <psemek/gfx/color.hpp>
|
||||
#include <psemek/react/value.hpp>
|
||||
|
||||
#include <string>
|
||||
|
|
@ -11,9 +13,10 @@ namespace psemek::ui
|
|||
struct label
|
||||
{
|
||||
react::value<std::string> text = {};
|
||||
react::value<halignment> halign = {};
|
||||
react::value<valignment> valign = {};
|
||||
react::value<std::string> must_fit = {};
|
||||
react::value<fonts::font *> font = {};
|
||||
react::value<gfx::color_rgba> color = gfx::color_rgba{0, 0, 0, 255};
|
||||
react::value<halignment> halign = halignment::center;
|
||||
react::value<valignment> valign = valignment::center;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <psemek/ui/impl/extend_base.hpp>
|
||||
#include <psemek/ui/impl/move_base.hpp>
|
||||
#include <psemek/ui/impl/button_base.hpp>
|
||||
#include <psemek/ui/impl/label_base.hpp>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
|
@ -29,6 +30,7 @@ namespace psemek::ui::impl
|
|||
register_type<extend, impl::extend_base>();
|
||||
register_type<move, impl::move_base>();
|
||||
register_type<button, impl::button_base>();
|
||||
register_type<label, impl::label_base>();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
64
libs/ui/source/impl/label_base.cpp
Normal file
64
libs/ui/source/impl/label_base.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue