Use shared_ptr instead of unique_ptr for ui elements

This commit is contained in:
Nikita Lisitsa 2021-02-25 14:42:35 +03:00
parent f8567851bd
commit d42e1b1bcb
11 changed files with 32 additions and 29 deletions

View file

@ -38,14 +38,14 @@ namespace psemek::ui
virtual void on_state_changed() {} virtual void on_state_changed() {}
void set_label(std::unique_ptr<struct label> label); void set_label(std::shared_ptr<struct label> label);
private: private:
state_t state_ = state_t::normal; state_t state_ = state_t::normal;
on_click_callback callback_; on_click_callback callback_;
std::unique_ptr<struct label> label_; std::shared_ptr<struct label> label_;
element * children_[1]{nullptr}; element * children_[1]{nullptr};
}; };

View file

@ -15,17 +15,17 @@ namespace psemek::ui
protected: protected:
std::size_t children_count() const { return children_.size(); } std::size_t children_count() const { return children_.size(); }
std::size_t add(std::unique_ptr<element> c); std::size_t add(std::shared_ptr<element> c);
void add(std::unique_ptr<element> c, std::size_t index); void add(std::shared_ptr<element> c, std::size_t index);
element * get(std::size_t index); element * get(std::size_t index);
std::optional<std::size_t> find(element * c); std::optional<std::size_t> find(element * c);
std::unique_ptr<element> remove(element * c); std::shared_ptr<element> remove(element * c);
std::unique_ptr<element> remove(std::size_t index); std::shared_ptr<element> remove(std::size_t index);
private: private:
std::vector<std::unique_ptr<element>> children_; std::vector<std::shared_ptr<element>> children_;
std::vector<element *> children_range_; std::vector<element *> children_range_;
}; };

View file

@ -13,7 +13,7 @@ namespace psemek::ui
controller(); controller();
~controller(); ~controller();
std::unique_ptr<element> set_root(std::unique_ptr<element> r); std::shared_ptr<element> set_root(std::shared_ptr<element> r);
element * root(); element * root();
void reshape(geom::box<float, 2> const & shape); void reshape(geom::box<float, 2> const & shape);

View file

@ -17,8 +17,8 @@ namespace psemek::ui
void set_style(std::shared_ptr<struct style> st); void set_style(std::shared_ptr<struct style> st);
std::shared_ptr<struct style> style() const; std::shared_ptr<struct style> style() const;
std::unique_ptr<button> make_button(std::string text); std::shared_ptr<button> make_button(std::string text);
std::unique_ptr<screen> make_screen(); std::shared_ptr<screen> make_screen();
private: private:
psemek_declare_pimpl psemek_declare_pimpl

View file

@ -9,10 +9,13 @@
#include <psemek/util/span.hpp> #include <psemek/util/span.hpp>
#include <memory>
namespace psemek::ui namespace psemek::ui
{ {
struct element struct element
: std::enable_shared_from_this<element>
{ {
virtual element * parent() const { return parent_; } virtual element * parent() const { return parent_; }
virtual void set_parent(element * parent) { parent_ = parent; } virtual void set_parent(element * parent) { parent_ = parent; }

View file

@ -25,9 +25,9 @@ namespace psemek::ui
floating, floating,
}; };
void add(std::unique_ptr<element> c, x_policy x, y_policy y); void add(std::shared_ptr<element> c, x_policy x, y_policy y);
void add(std::unique_ptr<element> c); void add(std::shared_ptr<element> c);
std::unique_ptr<element> remove(element * c); std::shared_ptr<element> remove(element * c);
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;

View file

@ -65,7 +65,7 @@ namespace psemek::ui
return false; return false;
} }
void button::set_label(std::unique_ptr<struct label> label) void button::set_label(std::shared_ptr<struct label> label)
{ {
label_ = std::move(label); label_ = std::move(label);
children_[0] = label_.get(); children_[0] = label_.get();

View file

@ -8,7 +8,7 @@ namespace psemek::ui
return children_range{children_range_.data(), children_range_.data() + children_range_.size()}; return children_range{children_range_.data(), children_range_.data() + children_range_.size()};
} }
std::size_t container::add(std::unique_ptr<element> c) std::size_t container::add(std::shared_ptr<element> c)
{ {
std::size_t index = 0; std::size_t index = 0;
while (index < children_.size() && children_[index]) ++index; while (index < children_.size() && children_[index]) ++index;
@ -16,7 +16,7 @@ namespace psemek::ui
return index; return index;
} }
void container::add(std::unique_ptr<element> c, std::size_t index) void container::add(std::shared_ptr<element> c, std::size_t index)
{ {
if (index >= children_.size()) if (index >= children_.size())
{ {
@ -45,14 +45,14 @@ namespace psemek::ui
return std::nullopt; return std::nullopt;
} }
std::unique_ptr<element> container::remove(element * c) std::shared_ptr<element> container::remove(element * c)
{ {
if (auto i = find(c)) if (auto i = find(c))
return remove(*i); return remove(*i);
return nullptr; return nullptr;
} }
std::unique_ptr<element> container::remove(std::size_t index) std::shared_ptr<element> container::remove(std::size_t index)
{ {
if (index >= children_.size()) if (index >= children_.size())
return nullptr; return nullptr;

View file

@ -12,7 +12,7 @@ namespace psemek::ui
struct controller::impl struct controller::impl
{ {
painter_impl painter; painter_impl painter;
std::unique_ptr<element> root; std::shared_ptr<element> root;
async::event_loop loop; async::event_loop loop;
geom::box<float, 2> shape{{{0.f, 0.f}, {0.f, 0.f}}}; geom::box<float, 2> shape{{{0.f, 0.f}, {0.f, 0.f}}};
@ -42,7 +42,7 @@ namespace psemek::ui
controller::~controller() = default; controller::~controller() = default;
std::unique_ptr<element> controller::set_root(std::unique_ptr<element> r) std::shared_ptr<element> controller::set_root(std::shared_ptr<element> r)
{ {
auto old = std::move(impl().root); auto old = std::move(impl().root);
impl().root = std::move(r); impl().root = std::move(r);

View file

@ -13,7 +13,7 @@ namespace psemek::ui
{ {
button_impl() button_impl()
{ {
set_label(std::make_unique<struct label>()); set_label(std::make_shared<struct label>());
label()->set_valign(label::valignment::center); label()->set_valign(label::valignment::center);
label()->set_halign(label::halignment::center); label()->set_halign(label::halignment::center);
label()->set_overflow(label::overflow_mode::drop); label()->set_overflow(label::overflow_mode::drop);
@ -69,9 +69,9 @@ namespace psemek::ui
impl(); impl();
template <typename T> template <typename T>
std::unique_ptr<T> create() std::shared_ptr<T> create()
{ {
auto r = std::make_unique<T>(); auto r = std::make_shared<T>();
r->set_style(style); r->set_style(style);
return r; return r;
} }
@ -97,7 +97,7 @@ namespace psemek::ui
return impl().style; return impl().style;
} }
std::unique_ptr<button> default_element_factory::make_button(std::string text) std::shared_ptr<button> default_element_factory::make_button(std::string text)
{ {
auto r = impl().create<button_impl>(); auto r = impl().create<button_impl>();
r->label()->set_text(std::move(text)); r->label()->set_text(std::move(text));
@ -105,9 +105,9 @@ namespace psemek::ui
return r; return r;
} }
std::unique_ptr<screen> default_element_factory::make_screen() std::shared_ptr<screen> default_element_factory::make_screen()
{ {
return std::make_unique<screen>(); return std::make_shared<screen>();
} }
} }

View file

@ -3,7 +3,7 @@
namespace psemek::ui namespace psemek::ui
{ {
void screen::add(std::unique_ptr<element> c, x_policy x, y_policy y) void screen::add(std::shared_ptr<element> c, x_policy x, y_policy y)
{ {
auto i = container::add(std::move(c)); auto i = container::add(std::move(c));
if (i >= policies_.size()) if (i >= policies_.size())
@ -11,12 +11,12 @@ namespace psemek::ui
policies_[i] = {x, y}; policies_[i] = {x, y};
} }
void screen::add(std::unique_ptr<element> c) void screen::add(std::shared_ptr<element> c)
{ {
add(std::move(c), x_policy::floating, y_policy::floating); add(std::move(c), x_policy::floating, y_policy::floating);
} }
std::unique_ptr<element> screen::remove(element * c) std::shared_ptr<element> screen::remove(element * c)
{ {
return container::remove(c); return container::remove(c);
} }