Label properties change triggers reshape
This commit is contained in:
parent
33256b6549
commit
fd7fbd4d87
2 changed files with 49 additions and 23 deletions
|
|
@ -57,6 +57,9 @@ namespace psemek::ui
|
||||||
|
|
||||||
struct shape const & shape() const override { return shape_; }
|
struct shape const & shape() const override { return shape_; }
|
||||||
void reshape(geom::box<float, 2> const & bbox) override;
|
void reshape(geom::box<float, 2> const & bbox) override;
|
||||||
|
|
||||||
|
geom::box<float, 2> size_constraints() const override;
|
||||||
|
|
||||||
void draw(painter & p) const override;
|
void draw(painter & p) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -75,9 +78,12 @@ namespace psemek::ui
|
||||||
{
|
{
|
||||||
struct font const * font = nullptr;
|
struct font const * font = nullptr;
|
||||||
std::vector<glyph> glyphs;
|
std::vector<glyph> glyphs;
|
||||||
|
geom::vector<float, 2> size{0.f, 0.f};
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable std::optional<cached_state> cached_state_;
|
mutable std::optional<cached_state> cached_state_;
|
||||||
|
|
||||||
|
void update_cached_state() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,43 +39,63 @@ namespace psemek::ui
|
||||||
cached_state_.reset();
|
cached_state_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> label::size_constraints() const
|
||||||
|
{
|
||||||
|
if (!cached_state_)
|
||||||
|
update_cached_state();
|
||||||
|
|
||||||
|
static float const inf = std::numeric_limits<float>::infinity();
|
||||||
|
return {{{cached_state_->size[0], inf}, {cached_state_->size[1], inf}}};
|
||||||
|
}
|
||||||
|
|
||||||
void label::draw(painter & p) const
|
void label::draw(painter & p) const
|
||||||
{
|
{
|
||||||
|
if (!cached_state_)
|
||||||
|
update_cached_state();
|
||||||
|
|
||||||
|
if (!cached_state_->font) return;
|
||||||
|
|
||||||
|
auto st = style();
|
||||||
|
if (!st) return;
|
||||||
|
|
||||||
|
for (auto & g : cached_state_->glyphs)
|
||||||
|
p.draw_glyph(*(cached_state_->font), g.character, g.position, st->text_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::on_state_changed()
|
||||||
|
{
|
||||||
|
cached_state_.reset();
|
||||||
|
post_reshape();
|
||||||
|
}
|
||||||
|
|
||||||
|
void label::update_cached_state() const
|
||||||
|
{
|
||||||
|
cached_state_ = cached_state{};
|
||||||
|
|
||||||
if (text_.empty()) return;
|
if (text_.empty()) return;
|
||||||
|
|
||||||
auto st = style();
|
auto st = style();
|
||||||
if (!st) return;
|
if (!st) return;
|
||||||
if (!st->font) return;
|
if (!st->font) return;
|
||||||
|
|
||||||
if (!cached_state_ || cached_state_->font != st->font.get())
|
cached_state_->font = st->font.get();
|
||||||
{
|
|
||||||
cached_state_ = cached_state{};
|
|
||||||
cached_state_->font = st->font.get();
|
|
||||||
|
|
||||||
shape_options opts;
|
shape_options opts;
|
||||||
opts.scale = st->text_scale;
|
opts.scale = st->text_scale;
|
||||||
cached_state_->glyphs = st->font->shape(text_, opts);
|
cached_state_->glyphs = st->font->shape(text_, opts);
|
||||||
|
|
||||||
geom::box<float, 2> bbox;
|
geom::box<float, 2> bbox;
|
||||||
for (auto const & g : cached_state_->glyphs)
|
for (auto const & g : cached_state_->glyphs)
|
||||||
bbox |= g.position;
|
bbox |= g.position;
|
||||||
|
|
||||||
geom::vector<float, 2> offset;
|
geom::vector<float, 2> offset;
|
||||||
offset[0] = shape_.box[0].center() - bbox[0].length() / 2.f;
|
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;
|
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)
|
for (auto & g : cached_state_->glyphs)
|
||||||
p.draw_glyph(*st->font, g.character, g.position, st->text_color);
|
g.position += offset;
|
||||||
}
|
|
||||||
|
|
||||||
void label::on_state_changed()
|
cached_state_->size = bbox.dimensions();
|
||||||
{
|
|
||||||
// TODO: changes should notify parent about content change
|
|
||||||
element::reshape();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue