From fd7fbd4d87bf6136b6a3efabfc9ff7751ba3e073 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 25 Feb 2021 15:15:42 +0300 Subject: [PATCH] Label properties change triggers reshape --- libs/ui/include/psemek/ui/label.hpp | 6 +++ libs/ui/source/label.cpp | 66 +++++++++++++++++++---------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/libs/ui/include/psemek/ui/label.hpp b/libs/ui/include/psemek/ui/label.hpp index 0485ef32..2b077bad 100644 --- a/libs/ui/include/psemek/ui/label.hpp +++ b/libs/ui/include/psemek/ui/label.hpp @@ -57,6 +57,9 @@ namespace psemek::ui struct shape const & shape() const override { return shape_; } void reshape(geom::box const & bbox) override; + + geom::box size_constraints() const override; + void draw(painter & p) const override; protected: @@ -75,9 +78,12 @@ namespace psemek::ui { struct font const * font = nullptr; std::vector glyphs; + geom::vector size{0.f, 0.f}; }; mutable std::optional cached_state_; + + void update_cached_state() const; }; } diff --git a/libs/ui/source/label.cpp b/libs/ui/source/label.cpp index 36de8d35..c77f2099 100644 --- a/libs/ui/source/label.cpp +++ b/libs/ui/source/label.cpp @@ -39,43 +39,63 @@ namespace psemek::ui cached_state_.reset(); } + geom::box label::size_constraints() const + { + if (!cached_state_) + update_cached_state(); + + static float const inf = std::numeric_limits::infinity(); + return {{{cached_state_->size[0], inf}, {cached_state_->size[1], inf}}}; + } + 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; 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(); + cached_state_->font = st->font.get(); - shape_options opts; - opts.scale = st->text_scale; - cached_state_->glyphs = st->font->shape(text_, opts); + shape_options opts; + opts.scale = st->text_scale; + cached_state_->glyphs = st->font->shape(text_, opts); - geom::box bbox; - for (auto const & g : cached_state_->glyphs) - bbox |= g.position; + geom::box bbox; + for (auto const & g : cached_state_->glyphs) + bbox |= g.position; - geom::vector 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; - } + geom::vector 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) - p.draw_glyph(*st->font, g.character, g.position, st->text_color); - } + g.position += offset; - void label::on_state_changed() - { - // TODO: changes should notify parent about content change - element::reshape(); + cached_state_->size = bbox.dimensions(); } }