43 state()->component_instance = std::nullopt;
56 std::string
name() const final {
57 return std::string{refl::type_name<T>};
65 auto dim = c->get()->get_dimensional_relations();
66 auto cx = get_value(dim.x);
67 auto cy = get_value(dim.y);
68 auto mx = get_value(dim.margin_left);
69 auto my = get_value(dim.margin_top);
70 auto px = get_value(dim.padding_left);
71 auto py = get_value(dim.padding_top);
73 if (
nullptr != found) {
94 .margin_top = s.
margin.top,
95 .margin_bottom = s.
margin.bottom,
96 .margin_left = s.
margin.left,
97 .margin_right = s.
margin.right,
99 .padding_bottom = s.
padding.bottom,
100 .padding_left = s.
padding.left,
101 .padding_right = s.
padding.right
110 using style_t =
typename T::style_t;
111 const auto& ti = refl::type_info::from<style_t>();
121 void dismount() final {
130 state()->component_instance = std::nullopt;
133 bool update_with(std::shared_ptr<component_base_t> other)
final {
134 ZoneScopedN(
"Update With");
135 auto other_component = std::dynamic_pointer_cast<component_t>(other);
136 if (!other_component) {
138 }(
"Attempted to update component of type ({}) with type ({})", this->
name(), other->name());
143 if (not refl::deep_eq(props(), other_component->props())) {
144 props() = other_component->props();
147 if (not(*as_attrs() == *(other_component->as_attrs()))) {
148 as_attrs()->update_with(*(other_component->as_attrs()));
152 if (
style_data->update_override_with(other_component->style_data->style_override_data)) {
156 if (update_fields(other_component)) {
163 std::shared_ptr<component_state_t> create_state_instance() final {
164 std::shared_ptr<component_state_t>
state;
165 if constexpr (
requires {
new typename T::state_t{std::declval<typename T::props_t*>()}; }) {
166 state = std::shared_ptr<component_state_t>{
167 new typename T::state_t(
static_cast<typename T::props_t*
>(
get_props()))
170 state = std::shared_ptr<component_state_t>{
new typename T::state_t()};
174 using EVH =
typename T::event_handler_t;
175 if (EVH::handles_text_input) {
185 T&
tag(
const std::unordered_set<std::string>& tags) {
186 for (
const auto&
tag: tags) {
189 return *
dynamic_cast<T*
>(
this);
192 T&
tag(
const std::string& tag_) {
194 return *
dynamic_cast<T*
>(
this);
197 T&
untag(
const std::unordered_set<std::string>& tags) {
198 for (
const auto&
tag: tags) {
201 return *
dynamic_cast<T*
>(
this);
206 return *
dynamic_cast<T*
>(
this);
211 return *
dynamic_cast<T*
>(
this);
215 template <
typename Fun>
218 self_so.set_style_transform(std::forward<Fun>(transform_func));
222 self_so.clear_style_transform();
235 return (
dynamic_cast<T*
>(
this)->props);
238 bool update_fields(std::shared_ptr<component_t>& other) {
240 [&]<std::size_t... I>(std::index_sequence<I...>) {
241 (update_field<I>(dirty, other), ...);
242 }(std::make_index_sequence<refl::field_count<T>>());
246 template <std::
size_t I>
247 void update_field(
bool& dirty, std::shared_ptr<component_t>& other_) {
248 auto other = std::dynamic_pointer_cast<T>(other_);
249 using field = refl::field<T, I>;
250 using field_type =
typename field::type;
252 if constexpr (packtl::is_type<fabric::wiring::signal, field_type>::value) {
253 auto& this_signal = field::from_instance(*
dynamic_cast<T*
>(
this));
254 auto& other_signal = field::from_instance(*other);
256 if (this_signal != other_signal) {
257 this_signal = other_signal;
268export template <
typename,
typename =
void>
271export template <
typename T>