Label implementation wip

This commit is contained in:
Nikita Lisitsa 2021-02-25 11:42:47 +03:00
parent f106299dd9
commit 69bd546848
5 changed files with 72 additions and 2 deletions

View file

@ -19,6 +19,7 @@ struct ui_example
{
auto style = std::make_shared<ui::style>();
style->font = ui::make_default_9x12_font();
style->text_scale = 2;
element_factory.set_style(style);
auto screen = element_factory.make_screen();

View file

@ -1,6 +1,7 @@
#pragma once
#include <psemek/ui/element.hpp>
#include <psemek/ui/box_shape.hpp>
#include <string>
#include <string_view>
@ -54,6 +55,10 @@ namespace psemek::ui
virtual void set_overflow(overflow_mode value);
virtual overflow_mode overflow() const { return overflow_; }
struct shape const & shape() const override { return shape_; }
void reshape(geom::box<float, 2> const & bbox) override;
void draw(painter & p) const override;
protected:
virtual void on_state_changed();
@ -63,6 +68,16 @@ namespace psemek::ui
valignment valign_;
multiline_mode multiline_;
overflow_mode overflow_;
box_shape shape_;
struct cached_state
{
struct font const * font = nullptr;
std::vector<glyph> glyphs;
};
mutable std::optional<cached_state> cached_state_;
};
}

View file

@ -19,7 +19,11 @@ namespace psemek::ui
geom::vector<int, 2> shadow_offset{1, 1};
gfx::color_rgba shadow_color{0, 0, 0, 255};
int inner_margin = 5;
int outer_margin = 10;
gfx::color_rgba text_color{0, 0, 0, 255};
int text_scale = 1;
std::shared_ptr<struct font> font;
};

View file

@ -14,6 +14,10 @@ namespace psemek::ui
button_impl()
{
set_label(std::make_unique<struct label>());
label()->set_valign(label::valignment::center);
label()->set_halign(label::halignment::center);
label()->set_overflow(label::overflow_mode::drop);
label()->set_multiline(label::multiline_mode::none);
}
struct shape const & shape() const override
@ -24,6 +28,8 @@ namespace psemek::ui
void reshape(geom::box<float, 2> const & bbox) override
{
shape_.box = bbox;
auto s = style();
if (s && label()) label()->reshape(geom::shrink(bbox, 1.f * (s->border_width + s->inner_margin)));
}
void draw(painter & p) const override
@ -95,6 +101,7 @@ namespace psemek::ui
{
auto r = impl().create<button_impl>();
r->label()->set_text(std::move(text));
r->label()->set_style(impl().style);
return r;
}

View file

@ -3,8 +3,6 @@
namespace psemek::ui
{
// TODO: changes should notify parent about content change
void label::set_text(std::string text)
{
text_ = std::move(text);
@ -35,4 +33,49 @@ namespace psemek::ui
on_state_changed();
}
void label::reshape(geom::box<float, 2> const & bbox)
{
shape_.box = bbox;
cached_state_.reset();
}
void label::draw(painter & p) const
{
if (text_.empty()) return;
auto st = style();
if (!st) return;
if (!st->font) return;
if (!cached_state_ || cached_state_->font != st->font.get())
{
cached_state_ = cached_state{};
cached_state_->font = st->font.get();
shape_options opts;
opts.scale = st->text_scale;
cached_state_->glyphs = st->font->shape(text_, opts);
geom::box<float, 2> bbox;
for (auto const & g : cached_state_->glyphs)
bbox |= g.position;
geom::vector<float, 2> offset;
offset[0] = shape_.box[0].center() - bbox[0].length() / 2.f;
offset[1] = shape_.box[1].center() - st->text_scale * st->font->size()[1] / 2.f;
for (auto & g : cached_state_->glyphs)
g.position += offset;
}
for (auto & g : cached_state_->glyphs)
p.draw_rect(g.position, st->text_color);
}
void label::on_state_changed()
{
// TODO: changes should notify parent about content change
element::reshape();
}
}