diff options
author | crupest <crupest@outlook.com> | 2020-12-01 23:20:01 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-12-01 23:20:01 +0800 |
commit | 0fb7a0e0b2b9e04ca414b1e47c69cc854c79831b (patch) | |
tree | 46d7f93e96bca49b0ec114c5595567b9bbcec6e3 /include | |
parent | 4fcf336d15fe246259ee18ccc99808d80e69c455 (diff) | |
download | cru-0fb7a0e0b2b9e04ca414b1e47c69cc854c79831b.tar.gz cru-0fb7a0e0b2b9e04ca414b1e47c69cc854c79831b.tar.bz2 cru-0fb7a0e0b2b9e04ca414b1e47c69cc854c79831b.zip |
...
Diffstat (limited to 'include')
-rw-r--r-- | include/cru/common/HandlerRegistry.hpp | 86 | ||||
-rw-r--r-- | include/cru/ui/controls/Button.hpp | 12 | ||||
-rw-r--r-- | include/cru/ui/controls/IClickableControl.hpp | 12 | ||||
-rw-r--r-- | include/cru/ui/helper/Styler.hpp | 47 | ||||
-rw-r--r-- | include/cru/ui/style/Styler.hpp | 0 | ||||
-rw-r--r-- | include/cru/ui/style/Trigger.hpp | 75 |
6 files changed, 184 insertions, 48 deletions
diff --git a/include/cru/common/HandlerRegistry.hpp b/include/cru/common/HandlerRegistry.hpp new file mode 100644 index 00000000..bd74a9e0 --- /dev/null +++ b/include/cru/common/HandlerRegistry.hpp @@ -0,0 +1,86 @@ +#pragma once +#include "Base.hpp" + +#include <algorithm> +#include <functional> +#include <utility> +#include <vector> + +namespace cru { + +template <typename T> +class HandlerRegistryIterator { + public: + using RawIterator = + typename std::vector<std::pair<int, std::function<T>>>::const_iterator; + + explicit HandlerRegistryIterator(RawIterator raw) : raw_(std::move(raw)) {} + + CRU_DELETE_COPY(HandlerRegistryIterator) + CRU_DELETE_MOVE(HandlerRegistryIterator) + + ~HandlerRegistryIterator() = default; + + const std::function<T>& operator*() const { return raw_->second; } + const std::function<T>* operator->() const { return &raw_->second; } + + HandlerRegistryIterator& operator++() { + ++raw_; + return *this; + } + + HandlerRegistryIterator operator++(int) { + auto c = *this; + this->operator++(); + return c; + } + + bool operator==(const HandlerRegistryIterator<T>& other) const { + return this->raw_ == other.raw_; + } + + bool operator!=(const HandlerRegistryIterator<T>& other) const { + return !this->operator==(other); + } + + private: + RawIterator raw_; +}; + +template <typename T> +class HandlerRegistry final { + public: + HandlerRegistry() = default; + CRU_DEFAULT_COPY(HandlerRegistry) + CRU_DEFAULT_MOVE(HandlerRegistry) + ~HandlerRegistry() = default; + + public: + int AddHandler(std::function<T> handler) { + auto id = current_id_++; + handler_list_.push_back({id, std::move(handler)}); + } + + void RemoveHandler(int id) { + auto result = std::find_if(handler_list_.cbegin(), handler_list_.cend(), + [id](const std::pair<int, std::function<T>>& d) { + return d.first == id; + }); + if (result != handler_list_.cend()) { + handler_list_.erase(result); + } + } + + HandlerRegistryIterator<T> begin() const { + return HandlerRegistryIterator<T>(handler_list_.begin()); + } + + HandlerRegistryIterator<T> end() const { + return HandlerRegistryIterator<T>(handler_list_.begin()); + } + + private: + int current_id_ = 1; + std::vector<std::pair<int, std::function<T>>> handler_list_; +}; +} // namespace cru diff --git a/include/cru/ui/controls/Button.hpp b/include/cru/ui/controls/Button.hpp index 5619ec89..0d2f4898 100644 --- a/include/cru/ui/controls/Button.hpp +++ b/include/cru/ui/controls/Button.hpp @@ -2,9 +2,11 @@ #include "ContentControl.hpp" #include "../helper/ClickDetector.hpp" +#include "IClickableControl.hpp" +#include "cru/common/Event.hpp" namespace cru::ui::controls { -class Button : public ContentControl { +class Button : public ContentControl, public virtual IClickableControl { public: static constexpr std::u16string_view control_type = u"Button"; @@ -25,6 +27,14 @@ class Button : public ContentControl { render::RenderObject* GetRenderObject() const override; public: + helper::ClickState GetClickState() override { + return click_detector_.GetState(); + } + + IEvent<helper::ClickState>* ClickStateChangeEvent() override { + return click_detector_.StateChangeEvent(); + } + const ButtonStyle& GetStyle() const { return style_; } void SetStyle(ButtonStyle style); diff --git a/include/cru/ui/controls/IClickableControl.hpp b/include/cru/ui/controls/IClickableControl.hpp new file mode 100644 index 00000000..aa7f13ab --- /dev/null +++ b/include/cru/ui/controls/IClickableControl.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "Base.hpp" + +#include "cru/common/Event.hpp" +#include "cru/ui/helper/ClickDetector.hpp" + +namespace cru::ui::controls { +struct IClickableControl : virtual Interface { + virtual helper::ClickState GetClickState() = 0; + virtual IEvent<helper::ClickState>* ClickStateChangeEvent() = 0; +}; +} // namespace cru::ui::controls diff --git a/include/cru/ui/helper/Styler.hpp b/include/cru/ui/helper/Styler.hpp deleted file mode 100644 index ed8bfbdc..00000000 --- a/include/cru/ui/helper/Styler.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include "cru/common/Base.hpp" -#include "cru/common/Event.hpp" -#include "cru/ui/Base.hpp" -#include "cru/ui/helper/ClickDetector.hpp" -#include "gsl/pointers" - -#include <memory> - -namespace cru::ui::helper { -struct ControlStyleState { - ClickState click_state; - bool focus; -}; - -class Styler : public Object { - public: - // You could provide your click detector. Otherwise a new one will be created. - explicit Styler(gsl::not_null<controls::Control*> control, - ClickDetector* click_detector = nullptr); - - CRU_DELETE_COPY(Styler) - CRU_DELETE_MOVE(Styler) - - ~Styler(); - - public: - gsl::not_null<controls::Control*> GetControl() const { return control_; } - gsl::not_null<ClickDetector*> GetClickDetector() const { - return click_detector_; - } - - IEvent<ControlStyleState>* StateChangeEvent() { return &state_change_event_; } - - private: - void RaiseStateChangeEvent(); - - private: - gsl::not_null<controls::Control*> control_; - std::unique_ptr<ClickDetector> managed_click_detector_; - gsl::not_null<ClickDetector*> click_detector_; - - Event<ControlStyleState> state_change_event_; - - EventRevokerListGuard event_guard_; -}; -} // namespace cru::ui::helper diff --git a/include/cru/ui/style/Styler.hpp b/include/cru/ui/style/Styler.hpp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/include/cru/ui/style/Styler.hpp diff --git a/include/cru/ui/style/Trigger.hpp b/include/cru/ui/style/Trigger.hpp new file mode 100644 index 00000000..ab012a3e --- /dev/null +++ b/include/cru/ui/style/Trigger.hpp @@ -0,0 +1,75 @@ +#pragma once +#include "../Base.hpp" +#include "cru/common/Base.hpp" +#include "cru/common/Event.hpp" +#include "cru/ui/controls/IClickableControl.hpp" +#include "cru/ui/helper/ClickDetector.hpp" + +#include <utility> +#include <vector> + +namespace cru::ui::style { +class Trigger { + public: + virtual ~Trigger() = default; + + bool GetState() const { return current_; } + IEvent<bool>* ChangeEvent() { return &change_event_; } + + protected: + void Raise(bool value); + + private: + bool current_ = false; + Event<bool> change_event_; + + protected: + EventRevokerListGuard guard_; +}; + +class CompoundTrigger : public Trigger { + public: + explicit CompoundTrigger(std::vector<Trigger*> triggers); + + const std::vector<Trigger*>& GetTriggers() const { return triggers_; } + + protected: + virtual bool CalculateState(const std::vector<Trigger*>& triggers) const = 0; + + private: + std::vector<Trigger*> triggers_; +}; + +class AndTrigger : public CompoundTrigger { + public: + using CompoundTrigger::CompoundTrigger; + + protected: + bool CalculateState(const std::vector<Trigger*>& triggers) const override; +}; + +class OrTrigger : public CompoundTrigger { + public: + using CompoundTrigger::CompoundTrigger; + + protected: + bool CalculateState(const std::vector<Trigger*>& triggers) const override; +}; + +class FocusTrigger : public Trigger { + public: + FocusTrigger(controls::Control* control, bool has_focus); + + private: + bool has_focus_; +}; + +class ClickStateTrigger : public Trigger { + public: + ClickStateTrigger(controls::IClickableControl* control, + helper::ClickState click_state); + + private: + helper::ClickState click_state_; +}; +} // namespace cru::ui::style |