#pragma once #include "StyleRule.hpp" #include "cru/common/Base.hpp" #include "cru/common/Event.hpp" #include namespace cru::ui::style { class StyleRuleSet : public Object { public: StyleRuleSet() = default; explicit StyleRuleSet(std::shared_ptr parent); CRU_DELETE_COPY(StyleRuleSet) CRU_DELETE_MOVE(StyleRuleSet) ~StyleRuleSet() override = default; public: std::shared_ptr GetParent() const { return parent_; } void SetParent(std::shared_ptr parent); gsl::index GetSize() const { return static_cast(rules_.size()); } const std::vector& GetRules() const { return rules_; } void AddStyleRule(StyleRule rule) { AddStyleRule(std::move(rule), GetSize()); } void AddStyleRule(StyleRule rule, gsl::index index); void RemoveStyleRule(gsl::index index, gsl::index count = 1); void Clear() { RemoveStyleRule(0, GetSize()); } void Set(const StyleRuleSet& other, bool set_parent = false); const StyleRule& operator[](gsl::index index) const { return rules_[index]; } // Triggered whenever a change happened to this (rule add or remove, parent // change ...). Subscribe to this and update style change listeners and style. IEvent* ChangeEvent() { return &change_event_; } private: void RaiseChangeEvent() { change_event_.Raise(nullptr); } private: Event change_event_; std::shared_ptr parent_ = nullptr; EventRevokerGuard parent_change_event_guard_; std::vector rules_; }; class StyleRuleSetBind { public: StyleRuleSetBind(controls::Control* control, std::shared_ptr ruleset); CRU_DELETE_COPY(StyleRuleSetBind) CRU_DELETE_MOVE(StyleRuleSetBind) ~StyleRuleSetBind() = default; private: void UpdateRuleSetChainCache(); void UpdateChangeListener(); void UpdateStyle(); private: controls::Control* control_; std::shared_ptr ruleset_; // child first, parent last. std::vector ruleset_chain_cache_; EventRevokerListGuard guard_; }; } // namespace cru::ui::style