30 template <
typename Base>
50 base_type::set_destroying();
70 return std::is_base_of_v<i_layout, self_type>;
74 if constexpr (std::is_base_of_v<i_layout, self_type>)
75 return static_cast<const i_layout&
>(*
this);
81 if constexpr (std::is_base_of_v<i_layout, self_type>)
82 return static_cast<i_layout&
>(*
this);
88 return std::is_base_of_v<i_spacer, self_type>;
92 if constexpr (std::is_base_of_v<i_spacer, self_type>)
93 return static_cast<const i_spacer&
>(*
this);
99 if constexpr (std::is_base_of_v<i_spacer, self_type>)
100 return static_cast<i_spacer&
>(*
this);
106 return std::is_base_of_v<i_widget, self_type>;
110 if constexpr (std::is_base_of_v<i_widget, self_type>)
111 return static_cast<const i_widget&
>(*
this);
117 if constexpr (std::is_base_of_v<i_widget, self_type>)
118 return static_cast<i_widget&
>(*
this);
125 auto& self = as_layout_item();
126 if (self.has_parent_layout() && self.same_parent_widget_as(self.parent_layout()))
128 else if (self.is_layout() && self.has_parent_widget())
130 else if (self.is_widget() && self.as_widget().has_parent())
136 auto& self = as_layout_item();
137 if (self.has_parent_layout() && self.same_parent_widget_as(self.parent_layout()))
138 return self.parent_layout();
139 else if (self.is_layout() && self.has_parent_widget())
140 return self.parent_widget();
141 else if (self.is_widget() && self.as_widget().has_parent())
142 return self.as_widget().parent();
147 return const_cast<i_layout_item&
>(to_const(*this).parent_layout_item());
152 auto& self = as_layout_item();
153 if (!self.has_parent_widget())
168 auto& self = as_layout_item();
182 return const_cast<i_widget&
>(to_const(*this).layout_manager());
187 auto& self = as_layout_item();
188 if (self.has_parent_layout_item())
190 if (!self.is_widget() ||
191 (self.as_widget().has_parent_layout() && !self.as_widget().is_managing_layout()) || aAncestors)
192 self.parent_layout_item().update_layout(aDeferLayout, aAncestors);
196 if (debug::layoutItem ==
this)
200 if (self.is_widget() && (!aDeferLayout || self.as_widget().can_defer_layout()))
201 self.as_widget().layout_items(aDeferLayout);
202 else if (self.is_layout())
203 self.as_layout().invalidate(aDeferLayout);
210 auto& self = as_layout_item();
211 if (!self.is_widget())
220 if (!self.as_widget().is_root() || self.as_widget().root().is_nested())
222 if (self.as_widget().has_parent())
223 iOrigin = self.as_widget().position() + self.as_widget().parent().origin();
225 iOrigin = self.as_widget().position();
239 auto& self = as_layout_item();
240 return (self.has_parent_layout_item() ? self.parent_layout_item().transformation(
true) : mat33::identity()) *
246 auto& self = as_layout_item();
247 return (self.has_parent_layout_item() ? self.parent_layout_item().transformation(
true) : mat33::identity()) *
249 static_cast<size>(Size) : Anchor_Size.evaluate_constraints());
266 return SizePolicy != std::nullopt;
271 if (debug::layoutItem ==
this)
274 if (SizePolicy != std::nullopt)
281 using i_geometry::set_size_policy;
282 void set_size_policy(
const optional_size_policy& aSizePolicy,
bool aUpdateLayout =
true)
override
284 if (SizePolicy != aSizePolicy)
287 if (debug::layoutItem ==
this)
288 service<debug::logger>() <<
neolib::logger::severity::Debug <<
typeid(*this).name() <<
"::set_size_policy(" << aSizePolicy <<
", " << aUpdateLayout <<
")" << endl;
290 SizePolicy = aSizePolicy;
297 return Weight != std::nullopt;
307 if (Weight != aWeight)
310 if (debug::layoutItem ==
this)
311 service<debug::logger>() <<
neolib::logger::severity::Debug <<
typeid(*this).name() <<
"::set_weight(" << aWeight <<
", " << aUpdateLayout <<
")" << endl;
313 Weight.assign(aWeight, aUpdateLayout);
320 return IdealSize != std::nullopt;
324 return Anchor_IdealSize.active();
331 else if (Anchor_IdealSize.active())
332 result = units_converter{ *
this }.from_device_units(Anchor_IdealSize.evaluate_constraints(aAvailableSpace));
335 scoped_query_ideal_size sqis;
339 if (debug::layoutItem ==
this)
347 if (IdealSize != newIdealSize)
350 if (debug::layoutItem ==
this)
351 service<debug::logger>() <<
neolib::logger::severity::Debug <<
typeid(*this).name() <<
"::set_ideal_size(" << aIdealSize <<
", " << aUpdateLayout <<
")" << endl;
353 IdealSize.assign(newIdealSize, aUpdateLayout);
360 return MinimumSize != std::nullopt;
364 return Anchor_MinimumSize.active();
371 else if (Anchor_MinimumSize.active())
372 result = units_converter{ *
this }.from_device_units(Anchor_MinimumSize.evaluate_constraints(aAvailableSpace));
376 if (debug::layoutItem ==
this)
384 if (MinimumSize != newMinimumSize)
387 if (debug::layoutItem ==
this)
388 service<debug::logger>() <<
neolib::logger::severity::Debug <<
typeid(*this).name() <<
"::set_minimum_size(" << aMinimumSize <<
", " << aUpdateLayout <<
")" << endl;
390 MinimumSize.assign(newMinimumSize, aUpdateLayout);
397 return MaximumSize != std::nullopt;
401 return Anchor_MaximumSize.active();
408 else if (Anchor_MaximumSize.active())
409 result = units_converter{ *
this }.from_device_units(Anchor_MaximumSize.evaluate_constraints(aAvailableSpace));
417 if (MaximumSize != newMaximumSize)
420 if (debug::layoutItem ==
this)
421 service<debug::logger>() <<
neolib::logger::severity::Debug <<
typeid(*this).name() <<
"::set_maximum_size(" << aMaximumSize <<
", " << aUpdateLayout <<
")" << endl;
423 MaximumSize.assign(newMaximumSize, aUpdateLayout);
444 if (debug::layoutItem ==
this)
445 service<debug::logger>() <<
neolib::logger::severity::Debug <<
typeid(*this).name() <<
"::set_fixed_size(" << aFixedSize <<
", " << aUpdateLayout <<
")" << endl;
447 FixedSize.assign(newFixedSize, aUpdateLayout);
454 return Transformation != std::nullopt;
458 if (!aCombineAncestorTransformations)
461 return *Transformation;
462 return mat33::identity();
476 if (Transformation != newTransformation)
479 if (debug::layoutItem ==
this)
480 service<debug::logger>() <<
neolib::logger::severity::Debug <<
typeid(*this).name() <<
"::set_transformation(" << aTransformation <<
", " << aUpdateLayout <<
")" << endl;
482 Transformation.assign(newTransformation, aUpdateLayout);
491 return Margin != std::nullopt;
500 if (Margin != newMargin)
509 return Border != std::nullopt;
527 return Padding != std::nullopt;
536 if (Padding != newPadding)
538 Padding = newPadding;
546 auto& self = as_layout_item();
547 if (!self.is_widget())
556 if (!self.as_widget().is_root() || self.as_widget().root().is_nested())
558 if (self.as_widget().has_parent())
561 return self.
as_widget().unconstrained_position();
576 auto& self = as_layout_item();
577 if (self.is_layout())
586 else if (self.is_widget())
600 if (debug::layoutItem ==
this)
603 auto& self = as_layout_item();
604 auto&
layout = (self.is_layout() ? self.as_layout() : self.as_widget().layout());
610 if (aRecalculate || !item.has_weight())
614 if (debug::layoutItem ==
this)
643 auto& lhsAnchor = base_type::anchor_to(aRhs, aLhsAnchor, aLhsFunction, aRhsAnchor, aRhsFunction);
644 AnchorUpdated.trigger(lhsAnchor);
653 i_layout_item& as_layout_item()
#define define_anchor(name)
#define define_anchor_ex(name, calculator_override)
static constexpr basic_size max_size()
virtual const i_widget & as_widget() const =0
virtual const i_widget & parent_widget() const =0
virtual void invalidate_combined_transformation()=0
size fixed_size(optional_size const &aAvailableSpace={}) const override
bool has_parent_layout_item() const final
void set_weight(optional_size const &aWeight, bool aUpdateLayout=true) override
bool is_spacer() const final
void set_minimum_size(optional_size const &aMinimumSize, bool aUpdateLayout=true) override
void set_fixed_size(optional_size const &aFixedSize, bool aUpdateLayout=true)
void layout_item_enabled(i_layout_item &aItem) override
i_widget & as_widget() override
bool has_maximum_size() const noexcept override
bool has_padding() const noexcept override
bool has_minimum_size() const noexcept override
define_property(property_category::soft_geometry, point, Position, position) define_property(property_category cache< point > iOrigin
neogfx::margin margin() const override
neogfx::border border() const override
bool is_maximum_size_constrained() const noexcept override
void set_border(optional_border const &aBorder, bool aUpdateLayout=true) override
bool is_layout() const final
point origin() const final
const i_layout_item & parent_layout_item() const final
void reset_origin() const final
void update_layout(bool aDeferLayout=true, bool aAncestors=false) final
void set_padding(optional_padding const &aPadding, bool aUpdateLayout=true) override
bool has_border() const noexcept override
size maximum_size(optional_size const &aAvailableSpace={}) const override
const i_widget & layout_manager() const final
void invalidate_combined_transformation() override
mat33 const & transformation(bool aCombineAncestorTransformations=false) const override
const i_layout & as_layout() const final
bool is_cache() const final
void set_position(const point &aPosition) override
bool is_widget() const override
size minimum_size(optional_size const &aAvailableSpace={}) const override
bool is_minimum_size_constrained() const noexcept override
void set_extents(const size &aExtents) override
bool has_margin() const noexcept override
void set_transformation(optional_mat33 const &aTransformation, bool aUpdateLayout=true) override
i_layout & as_layout() final
bool has_fixed_size() const noexcept override
point unconstrained_position() const override
void set_size_policy(const optional_size_policy &aSizePolicy, bool aUpdateLayout=true) override
bool has_weight() const noexcept override
const i_widget & as_widget() const override
bool has_ideal_size() const noexcept override
point unconstrained_origin() const override
i_spacer & as_spacer() final
bool has_transformation() const noexcept override
neogfx::size_policy size_policy() const override
point position() const final
void fix_weightings(bool aRecalculate=true) override
size ideal_size(optional_size const &aAvailableSpace={}) const override
const i_spacer & as_spacer() const final
i_widget & layout_manager() final
size weight() const override
void set_margin(optional_margin const &aMargin, bool aUpdateLayout=true) override
bool has_size_policy() const noexcept override
size extents() const final
void set_maximum_size(optional_size const &aMaximumSize, bool aUpdateLayout=true) override
void layout_item_disabled(i_layout_item &aItem) override
void set_id(const i_string &aId) final
neogfx::padding padding() const override
bool has_layout_manager() const final
i_anchor & anchor_to(i_anchorable &aRhs, i_string const &aLhsAnchor, anchor_constraint_function aLhsFunction, i_string const &aRhsAnchor, anchor_constraint_function aRhsFunction) override
void set_ideal_size(optional_size const &aIdealSize, bool aUpdateLayout=true) override
const i_string & id() const final
i_layout_item & parent_layout_item() final
bool is_ideal_size_constrained() const noexcept override
cache< mat33 > iCombinedTransformation
const i_layout_item & item_at(layout_item_index aIndex) const override
layout_item_index count() const override
vector2 to_device_units(const vector2 &aValue) const
vector2 from_device_units(const vector2 &aValue) const
optional< margin > optional_margin
anchor_constraint_function
optional< padding > optional_padding
uint32_t layout_item_index
size calculate_relative_weight(const i_layout &aLayout, const i_layout_item &aItem)
optional< size > optional_size
optional< border > optional_border
basic_point< coordinate > point
basic_size< coordinate > size
optional< mat33 > optional_mat33
#define define_event(name, declName,...)
#define define_property(category, type, name, calculator,...)