Label implementation wip
This commit is contained in:
parent
f106299dd9
commit
69bd546848
5 changed files with 72 additions and 2 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue