From 5a64593219061dcd51ef59819a85807555252303 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 17 Feb 2022 18:55:00 +0300 Subject: [PATCH] Introduce ui::toggle_button - a button that can be turned on/off --- libs/ui/include/psemek/ui/element_factory.hpp | 4 ++ libs/ui/include/psemek/ui/toggle_button.hpp | 33 ++++++++++++++ libs/ui/source/element_factory.cpp | 35 +++++++++++++++ libs/ui/source/toggle_button.cpp | 44 +++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 libs/ui/include/psemek/ui/toggle_button.hpp create mode 100644 libs/ui/source/toggle_button.cpp diff --git a/libs/ui/include/psemek/ui/element_factory.hpp b/libs/ui/include/psemek/ui/element_factory.hpp index 9f8cf35a..1e9b0316 100644 --- a/libs/ui/include/psemek/ui/element_factory.hpp +++ b/libs/ui/include/psemek/ui/element_factory.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,9 @@ namespace psemek::ui virtual std::shared_ptr make_image_view(gfx::texture_view_2d image); virtual std::shared_ptr make_rich_image_view(std::shared_ptr image); virtual std::shared_ptr make_checkbox(bool value); + virtual std::shared_ptr make_toggle_button(); + virtual std::shared_ptr make_toggle_button(std::string text); + virtual std::shared_ptr make_toggle_button(gfx::texture_view_2d icon); virtual std::shared_ptr make_slider(); virtual std::shared_ptr make_spinbox(); // directions: diff --git a/libs/ui/include/psemek/ui/toggle_button.hpp b/libs/ui/include/psemek/ui/toggle_button.hpp new file mode 100644 index 00000000..73721626 --- /dev/null +++ b/libs/ui/include/psemek/ui/toggle_button.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +namespace psemek::ui +{ + + struct toggle_button + : checkbox + { + struct label * label() { return label_.get(); } + struct label const * label() const { return label_.get(); } + + struct image_view * icon() { return icon_.get(); } + struct image_view const * icon() const { return icon_.get(); } + + virtual void set_label(std::shared_ptr label); + virtual void set_icon(std::shared_ptr icon); + + children_range children() const override; + + ~toggle_button() override; + + private: + std::shared_ptr label_; + std::shared_ptr icon_; + element * children_[1]{nullptr}; + }; + + +} diff --git a/libs/ui/source/element_factory.cpp b/libs/ui/source/element_factory.cpp index 8c9d47d5..ad3dfe24 100644 --- a/libs/ui/source/element_factory.cpp +++ b/libs/ui/source/element_factory.cpp @@ -76,6 +76,41 @@ namespace psemek::ui return nullptr; } + std::shared_ptr element_factory::make_toggle_button() { return nullptr; } + + std::shared_ptr element_factory::make_toggle_button(std::string text) + { + auto b = make_toggle_button(); + if (b) + { + auto l = make_label(std::move(text)); + if (l) + { + l->set_valign(label::valignment::center); + l->set_halign(label::halignment::center); + l->set_overflow(label::overflow_mode::ellipsis); + b->set_label(l); + } + } + return b; + } + + std::shared_ptr element_factory::make_toggle_button(gfx::texture_view_2d icon) + { + auto b = make_toggle_button(); + if (b) + { + auto i = make_image_view(icon); + if (i) + { + i->set_downscale(false); + i->set_upscale(false); + b->set_icon(i); + } + } + return b; + } + std::shared_ptr element_factory::make_slider() { return nullptr; } std::shared_ptr element_factory::make_spinbox() { return nullptr; } diff --git a/libs/ui/source/toggle_button.cpp b/libs/ui/source/toggle_button.cpp new file mode 100644 index 00000000..1716c804 --- /dev/null +++ b/libs/ui/source/toggle_button.cpp @@ -0,0 +1,44 @@ +#include + +namespace psemek::ui +{ + + element::children_range toggle_button::children() const + { + return children_range{children_}; + } + + toggle_button::~toggle_button() + { + release_children(); + } + + void toggle_button::set_label(std::shared_ptr label) + { + if (icon()) + set_icon(nullptr); + + if (label_) label_->set_parent(nullptr); + + label_ = std::move(label); + children_[0] = label_.get(); + if (label_) label_->set_parent(this); + } + + void toggle_button::set_icon(std::shared_ptr icon) + { + if (label()) + set_label(nullptr); + + if (icon_) icon_->set_parent(nullptr); + + icon_ = std::move(icon); + children_[0] = icon_.get(); + if (icon_) + { + icon_->set_parent(this); + icon_->set_downscale(false); + } + } + +}