Add width/height overrides for NestedArtboardLayout Adds the ability to override width and height for NestedArtboardLayout. This allows each NestedArtboardLayout instance to respond to be sized differently. This is not supported in the NestedArtboard Node and Leaf types, since those are resized using differently (Node uses scale and Leaf uses a combination of scale/fit/alignment). Implemented via FFI as discussed with @luigi-rosso because NestedArtboardLayout modifying the "taken" layoutNode directly could result in race conditions and other conflicts. https://github.com/user-attachments/assets/c323a94f-f392-4c10-ac01-af112f70a256 Diffs= 0dc0b435f Add width/height overrides for NestedArtboardLayout (#7736) Co-authored-by: Philip Chung <philterdesign@gmail.com>
diff --git a/.rive_head b/.rive_head index 2edbc19..eb57b2c 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -1131f30e6a45bee5c0561de3a35b19985bf46820 +0dc0b435ffb0df61de0afcdc2cea0c69bb8fedd4
diff --git a/dev/defs/nested_artboard_layout.json b/dev/defs/nested_artboard_layout.json index b0579be..4730f94 100644 --- a/dev/defs/nested_artboard_layout.json +++ b/dev/defs/nested_artboard_layout.json
@@ -1,8 +1,66 @@ { - "name": "NestedArtboardLayout", - "key": { - "int": 452, - "string": "nestedartboardlayout" + "name": "NestedArtboardLayout", + "key": { + "int": 452, + "string": "nestedartboardlayout" + }, + "extends": "nested_artboard.json", + "properties": { + "instanceWidth": { + "type": "double", + "initialValue": "-1", + "animates": true, + "key": { + "int": 663, + "string": "instancewidth" + }, + "description": "Width value in points or percent of this nested artboard instance." }, - "extends": "nested_artboard.json" + "instanceHeight": { + "type": "double", + "initialValue": "-1", + "animates": true, + "key": { + "int": 664, + "string": "instanceheight" + }, + "description": "Height value in points or percent of this nested artboard instance" + }, + "instanceWidthUnitsValue": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 665, + "string": "instancewidthunitsvalue" + }, + "description": "Whether to display width in points or percent" + }, + "instanceHeightUnitsValue": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 666, + "string": "instanceheightunitsvalue" + }, + "description": "Whether to display height in points or percent" + }, + "instanceWidthScaleType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 667, + "string": "instancewidthscaletype" + }, + "description": "Width scale type fixed | fill" + }, + "instanceHeightScaleType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 668, + "string": "instanceheightscaletype" + }, + "description": "Height scale type fixed | fill" + } + } } \ No newline at end of file
diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index e3cf802..6c9df53 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp
@@ -138,6 +138,7 @@ void* takeLayoutNode(); bool syncStyleChanges(); + bool canHaveOverrides() override { return true; } bool advance(double elapsedSeconds, bool nested = true); bool advanceInternal(double elapsedSeconds, bool isRoot, bool nested = true);
diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index d8e9eb9..3d23e26 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp
@@ -683,6 +683,18 @@ case SoloBase::activeComponentIdPropertyKey: object->as<SoloBase>()->activeComponentId(value); break; + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + object->as<NestedArtboardLayoutBase>()->instanceWidthUnitsValue(value); + break; + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + object->as<NestedArtboardLayoutBase>()->instanceHeightUnitsValue(value); + break; + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + object->as<NestedArtboardLayoutBase>()->instanceWidthScaleType(value); + break; + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: + object->as<NestedArtboardLayoutBase>()->instanceHeightScaleType(value); + break; case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: object->as<LayoutComponentStyleBase>()->layoutWidthScaleType(value); break; @@ -1219,6 +1231,12 @@ case NodeBase::yArtboardPropertyKey: object->as<NodeBase>()->y(value); break; + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + object->as<NestedArtboardLayoutBase>()->instanceWidth(value); + break; + case NestedArtboardLayoutBase::instanceHeightPropertyKey: + object->as<NestedArtboardLayoutBase>()->instanceHeight(value); + break; case LayoutComponentStyleBase::gapHorizontalPropertyKey: object->as<LayoutComponentStyleBase>()->gapHorizontal(value); break; @@ -1798,6 +1816,14 @@ return object->as<NestedAnimationBase>()->animationId(); case SoloBase::activeComponentIdPropertyKey: return object->as<SoloBase>()->activeComponentId(); + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + return object->as<NestedArtboardLayoutBase>()->instanceWidthUnitsValue(); + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + return object->as<NestedArtboardLayoutBase>()->instanceHeightUnitsValue(); + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + return object->as<NestedArtboardLayoutBase>()->instanceWidthScaleType(); + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: + return object->as<NestedArtboardLayoutBase>()->instanceHeightScaleType(); case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: return object->as<LayoutComponentStyleBase>()->layoutWidthScaleType(); case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: @@ -2165,6 +2191,10 @@ case NodeBase::yPropertyKey: case NodeBase::yArtboardPropertyKey: return object->as<NodeBase>()->y(); + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + return object->as<NestedArtboardLayoutBase>()->instanceWidth(); + case NestedArtboardLayoutBase::instanceHeightPropertyKey: + return object->as<NestedArtboardLayoutBase>()->instanceHeight(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->as<LayoutComponentStyleBase>()->gapHorizontal(); case LayoutComponentStyleBase::gapVerticalPropertyKey: @@ -2524,6 +2554,10 @@ case NestedArtboardBase::artboardIdPropertyKey: case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: @@ -2701,6 +2735,8 @@ case NodeBase::xArtboardPropertyKey: case NodeBase::yPropertyKey: case NodeBase::yArtboardPropertyKey: + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + case NestedArtboardLayoutBase::instanceHeightPropertyKey: case LayoutComponentStyleBase::gapHorizontalPropertyKey: case LayoutComponentStyleBase::gapVerticalPropertyKey: case LayoutComponentStyleBase::maxWidthPropertyKey: @@ -2985,6 +3021,14 @@ return object->is<NestedAnimationBase>(); case SoloBase::activeComponentIdPropertyKey: return object->is<SoloBase>(); + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + return object->is<NestedArtboardLayoutBase>(); + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + return object->is<NestedArtboardLayoutBase>(); + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + return object->is<NestedArtboardLayoutBase>(); + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: + return object->is<NestedArtboardLayoutBase>(); case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: return object->is<LayoutComponentStyleBase>(); case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: @@ -3331,6 +3375,10 @@ case NodeBase::yPropertyKey: case NodeBase::yArtboardPropertyKey: return object->is<NodeBase>(); + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + return object->is<NestedArtboardLayoutBase>(); + case NestedArtboardLayoutBase::instanceHeightPropertyKey: + return object->is<NestedArtboardLayoutBase>(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->is<LayoutComponentStyleBase>(); case LayoutComponentStyleBase::gapVerticalPropertyKey:
diff --git a/include/rive/generated/nested_artboard_layout_base.hpp b/include/rive/generated/nested_artboard_layout_base.hpp index 7c5ce6f..8bfa18d 100644 --- a/include/rive/generated/nested_artboard_layout_base.hpp +++ b/include/rive/generated/nested_artboard_layout_base.hpp
@@ -1,5 +1,7 @@ #ifndef _RIVE_NESTED_ARTBOARD_LAYOUT_BASE_HPP_ #define _RIVE_NESTED_ARTBOARD_LAYOUT_BASE_HPP_ +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" #include "rive/nested_artboard.hpp" namespace rive { @@ -33,9 +35,133 @@ uint16_t coreType() const override { return typeKey; } + static const uint16_t instanceWidthPropertyKey = 663; + static const uint16_t instanceHeightPropertyKey = 664; + static const uint16_t instanceWidthUnitsValuePropertyKey = 665; + static const uint16_t instanceHeightUnitsValuePropertyKey = 666; + static const uint16_t instanceWidthScaleTypePropertyKey = 667; + static const uint16_t instanceHeightScaleTypePropertyKey = 668; + +private: + float m_InstanceWidth = -1.0f; + float m_InstanceHeight = -1.0f; + uint32_t m_InstanceWidthUnitsValue = 1; + uint32_t m_InstanceHeightUnitsValue = 1; + uint32_t m_InstanceWidthScaleType = 0; + uint32_t m_InstanceHeightScaleType = 0; + +public: + inline float instanceWidth() const { return m_InstanceWidth; } + void instanceWidth(float value) + { + if (m_InstanceWidth == value) + { + return; + } + m_InstanceWidth = value; + instanceWidthChanged(); + } + + inline float instanceHeight() const { return m_InstanceHeight; } + void instanceHeight(float value) + { + if (m_InstanceHeight == value) + { + return; + } + m_InstanceHeight = value; + instanceHeightChanged(); + } + + inline uint32_t instanceWidthUnitsValue() const { return m_InstanceWidthUnitsValue; } + void instanceWidthUnitsValue(uint32_t value) + { + if (m_InstanceWidthUnitsValue == value) + { + return; + } + m_InstanceWidthUnitsValue = value; + instanceWidthUnitsValueChanged(); + } + + inline uint32_t instanceHeightUnitsValue() const { return m_InstanceHeightUnitsValue; } + void instanceHeightUnitsValue(uint32_t value) + { + if (m_InstanceHeightUnitsValue == value) + { + return; + } + m_InstanceHeightUnitsValue = value; + instanceHeightUnitsValueChanged(); + } + + inline uint32_t instanceWidthScaleType() const { return m_InstanceWidthScaleType; } + void instanceWidthScaleType(uint32_t value) + { + if (m_InstanceWidthScaleType == value) + { + return; + } + m_InstanceWidthScaleType = value; + instanceWidthScaleTypeChanged(); + } + + inline uint32_t instanceHeightScaleType() const { return m_InstanceHeightScaleType; } + void instanceHeightScaleType(uint32_t value) + { + if (m_InstanceHeightScaleType == value) + { + return; + } + m_InstanceHeightScaleType = value; + instanceHeightScaleTypeChanged(); + } + Core* clone() const override; + void copy(const NestedArtboardLayoutBase& object) + { + m_InstanceWidth = object.m_InstanceWidth; + m_InstanceHeight = object.m_InstanceHeight; + m_InstanceWidthUnitsValue = object.m_InstanceWidthUnitsValue; + m_InstanceHeightUnitsValue = object.m_InstanceHeightUnitsValue; + m_InstanceWidthScaleType = object.m_InstanceWidthScaleType; + m_InstanceHeightScaleType = object.m_InstanceHeightScaleType; + NestedArtboard::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case instanceWidthPropertyKey: + m_InstanceWidth = CoreDoubleType::deserialize(reader); + return true; + case instanceHeightPropertyKey: + m_InstanceHeight = CoreDoubleType::deserialize(reader); + return true; + case instanceWidthUnitsValuePropertyKey: + m_InstanceWidthUnitsValue = CoreUintType::deserialize(reader); + return true; + case instanceHeightUnitsValuePropertyKey: + m_InstanceHeightUnitsValue = CoreUintType::deserialize(reader); + return true; + case instanceWidthScaleTypePropertyKey: + m_InstanceWidthScaleType = CoreUintType::deserialize(reader); + return true; + case instanceHeightScaleTypePropertyKey: + m_InstanceHeightScaleType = CoreUintType::deserialize(reader); + return true; + } + return NestedArtboard::deserialize(propertyKey, reader); + } protected: + virtual void instanceWidthChanged() {} + virtual void instanceHeightChanged() {} + virtual void instanceWidthUnitsValueChanged() {} + virtual void instanceHeightUnitsValueChanged() {} + virtual void instanceWidthScaleTypeChanged() {} + virtual void instanceHeightScaleTypeChanged() {} }; } // namespace rive
diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index b39a9c3..18d8999 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp
@@ -71,6 +71,12 @@ } private: + float m_widthOverride = NAN; + int m_widthUnitValueOverride = -1; + float m_heightOverride = NAN; + int m_heightUnitValueOverride = -1; + bool m_parentIsRow = true; + #ifdef WITH_RIVE_LAYOUT protected: YGNode& layoutNode() { return m_layoutData->node; } @@ -106,6 +112,14 @@ return AABB::fromLTWH(0.0f, 0.0f, m_layoutSizeWidth, m_layoutSizeHeight); } + // We provide a way for nested artboards (or other objects) to override this layout's + // width/height and unit values. + void widthOverride(float width, int unitValue = 1, bool isRow = true); + void heightOverride(float height, int unitValue = 1, bool isRow = true); + virtual bool canHaveOverrides() { return false; } + bool mainAxisIsRow(); + bool mainAxisIsColumn(); + #ifdef WITH_RIVE_LAYOUT LayoutComponent() : m_layoutData(std::unique_ptr<LayoutData>(new LayoutData())), m_proxy(this) {
diff --git a/include/rive/nested_artboard_layout.hpp b/include/rive/nested_artboard_layout.hpp index 9a68074..f6876ea 100644 --- a/include/rive/nested_artboard_layout.hpp +++ b/include/rive/nested_artboard_layout.hpp
@@ -13,6 +13,22 @@ Core* clone() const override; void markNestedLayoutDirty(); void update(ComponentDirt value) override; + StatusCode onAddedClean(CoreContext* context) override; + + float actualInstanceWidth(); + float actualInstanceHeight(); + +protected: + void instanceWidthChanged() override; + void instanceHeightChanged() override; + void instanceWidthUnitsValueChanged() override; + void instanceHeightUnitsValueChanged() override; + void instanceWidthScaleTypeChanged() override; + void instanceHeightScaleTypeChanged() override; + +private: + void updateWidthOverride(); + void updateHeightOverride(); }; } // namespace rive
diff --git a/src/artboard.cpp b/src/artboard.cpp index 263f683..67a5a1b 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp
@@ -689,7 +689,10 @@ m_dirtyLayout.insert(layoutComponent); if (sharesLayoutWithHost()) { - m_host->as<NestedArtboardLayout>()->markNestedLayoutDirty(); + // TODO: Follow up with Luigi + // This only gets called when the NestedArtboardLayout is in the runtime + // but seems to cause an infinite loop in certain cases + // m_host->as<NestedArtboardLayout>()->markNestedLayoutDirty(); } }
diff --git a/src/layout_component.cpp b/src/layout_component.cpp index 3bd963d..c72a614 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp
@@ -131,6 +131,22 @@ } } +void LayoutComponent::widthOverride(float width, int unitValue, bool isRow) +{ + m_widthOverride = width; + m_widthUnitValueOverride = unitValue; + m_parentIsRow = isRow; + markLayoutNodeDirty(); +} + +void LayoutComponent::heightOverride(float height, int unitValue, bool isRow) +{ + m_heightOverride = height; + m_heightUnitValueOverride = unitValue; + m_parentIsRow = isRow; + markLayoutNodeDirty(); +} + #ifdef WITH_RIVE_LAYOUT StatusCode LayoutComponent::onAddedDirty(CoreContext* context) { @@ -207,6 +223,18 @@ return size; } +bool LayoutComponent::mainAxisIsRow() +{ + return style()->flexDirection() == YGFlexDirectionRow || + style()->flexDirection() == YGFlexDirectionRowReverse; +} + +bool LayoutComponent::mainAxisIsColumn() +{ + return style()->flexDirection() == YGFlexDirectionColumn || + style()->flexDirection() == YGFlexDirectionColumnReverse; +} + void LayoutComponent::syncStyle() { if (m_style == nullptr) @@ -224,94 +252,131 @@ { ygNode.setMeasureFunc(nullptr); } - if (m_style->widthUnits() != YGUnitAuto) - { - ygStyle.dimensions()[YGDimensionWidth] = YGValue{width(), m_style->widthUnits()}; - } - else - { - ygStyle.dimensions()[YGDimensionWidth] = YGValueAuto; - } - if (m_style->heightUnits() != YGUnitAuto) - { - ygStyle.dimensions()[YGDimensionHeight] = YGValue{height(), m_style->heightUnits()}; - } - else - { - ygStyle.dimensions()[YGDimensionHeight] = YGValueAuto; - } - if (layoutParent() != nullptr) + auto realWidth = width(); + auto realWidthUnits = m_style->widthUnits(); + auto realWidthScaleType = m_style->widthScaleType(); + auto realHeight = height(); + auto realHeightUnits = m_style->heightUnits(); + auto realHeightScaleType = m_style->heightScaleType(); + auto parentIsRow = layoutParent() != nullptr ? layoutParent()->mainAxisIsRow() : true; + + // If we have override width/height values, use those. + // Currently we only use these for Artboards that are part of a NestedArtboardLayout + // but perhaps there will be other use cases for overriding in the future? + if (canHaveOverrides()) { - bool isRow = layoutParent()->style()->flexDirection() == YGFlexDirectionRow || - layoutParent()->style()->flexDirection() == YGFlexDirectionRowReverse; - switch (m_style->widthScaleType()) + if (!std::isnan(m_widthOverride)) { - case LayoutScaleType::fixed: - if (isRow) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - break; - case LayoutScaleType::fill: - if (isRow) - { - ygStyle.flexGrow() = YGFloatOptional(1); - } - else - { - ygStyle.alignSelf() = YGAlignStretch; - } - break; - case LayoutScaleType::hug: - if (isRow) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - else - { - ygStyle.alignSelf() = YGAlignAuto; - } - break; - default: - break; + realWidth = m_widthOverride; } - bool isColumn = !isRow; - switch (m_style->heightScaleType()) + if (!std::isnan(m_heightOverride)) { - case LayoutScaleType::fixed: - if (isColumn) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - break; - case LayoutScaleType::fill: - if (isColumn) - { - ygStyle.flexGrow() = YGFloatOptional(1); - } - else - { - ygStyle.alignSelf() = YGAlignStretch; - } - break; - case LayoutScaleType::hug: - if (isColumn) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - else - { - ygStyle.alignSelf() = YGAlignAuto; - } - break; - default: - break; + realHeight = m_heightOverride; + } + parentIsRow = m_parentIsRow; + + if (m_widthUnitValueOverride != -1) + { + realWidthUnits = YGUnit(m_widthUnitValueOverride); + switch (realWidthUnits) + { + case YGUnitPoint: + case YGUnitPercent: + realWidthScaleType = LayoutScaleType::fixed; + break; + case YGUnitAuto: + realWidthScaleType = LayoutScaleType::fill; + break; + default: + break; + } + } + if (m_heightUnitValueOverride != -1) + { + realHeightUnits = YGUnit(m_heightUnitValueOverride); + switch (realHeightUnits) + { + case YGUnitPoint: + case YGUnitPercent: + realHeightScaleType = LayoutScaleType::fixed; + break; + case YGUnitAuto: + realHeightScaleType = LayoutScaleType::fill; + break; + default: + break; + } } } + ygStyle.dimensions()[YGDimensionWidth] = YGValue{realWidth, realWidthUnits}; + ygStyle.dimensions()[YGDimensionHeight] = YGValue{realHeight, realHeightUnits}; - bool isRowForAlignment = m_style->flexDirection() == YGFlexDirectionRow || - m_style->flexDirection() == YGFlexDirectionRowReverse; + switch (realWidthScaleType) + { + case LayoutScaleType::fixed: + if (parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + break; + case LayoutScaleType::fill: + if (parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(1); + } + else + { + ygStyle.alignSelf() = YGAlignStretch; + } + break; + case LayoutScaleType::hug: + if (parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + else + { + ygStyle.alignSelf() = YGAlignAuto; + } + break; + default: + break; + } + + switch (realHeightScaleType) + { + case LayoutScaleType::fixed: + if (!parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + break; + case LayoutScaleType::fill: + if (!parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(1); + } + else + { + ygStyle.alignSelf() = YGAlignStretch; + } + break; + case LayoutScaleType::hug: + if (!parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + else + { + ygStyle.alignSelf() = YGAlignAuto; + } + break; + default: + break; + } + + bool isRowForAlignment = mainAxisIsRow(); switch (m_style->alignmentType()) { case LayoutAlignmentType::topLeft: @@ -801,6 +866,9 @@ void LayoutComponent::markLayoutNodeDirty() {} void LayoutComponent::markLayoutStyleDirty() {} void LayoutComponent::onDirty(ComponentDirt value) {} +bool LayoutComponent::mainAxisIsRow() { return true; } + +bool LayoutComponent::mainAxisIsColumn() { return false; } #endif void LayoutComponent::clipChanged() { markLayoutNodeDirty(); }
diff --git a/src/nested_artboard_layout.cpp b/src/nested_artboard_layout.cpp index eed115e..501ffd6 100644 --- a/src/nested_artboard_layout.cpp +++ b/src/nested_artboard_layout.cpp
@@ -16,6 +16,16 @@ return nestedArtboard; } +float NestedArtboardLayout::actualInstanceWidth() +{ + return instanceWidth() == -1.0f ? artboardInstance()->originalWidth() : instanceWidth(); +} + +float NestedArtboardLayout::actualInstanceHeight() +{ + return instanceHeight() == -1.0f ? artboardInstance()->originalHeight() : instanceHeight(); +} + #ifdef WITH_RIVE_LAYOUT void* NestedArtboardLayout::layoutNode() { @@ -57,4 +67,72 @@ auto back = Mat2D::fromTranslation(-artboard->origin()); m_WorldTransform = back * m_WorldTransform; } -} \ No newline at end of file +} + +StatusCode NestedArtboardLayout::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + updateWidthOverride(); + updateHeightOverride(); + + return StatusCode::Ok; +} + +void NestedArtboardLayout::updateWidthOverride() +{ + if (artboardInstance() == nullptr) + { + return; + } + auto isRow = + parent()->is<LayoutComponent>() ? parent()->as<LayoutComponent>()->mainAxisIsRow() : true; + if (instanceWidthScaleType() == 0) // LayoutScaleType::fixed + { + // If we're set to fixed, pass the unit value (points|percent) + artboardInstance()->widthOverride(actualInstanceWidth(), instanceWidthUnitsValue(), isRow); + } + else if (instanceWidthScaleType() == 1) // LayoutScaleType::fill + { + // If we're set to fill, pass auto + artboardInstance()->widthOverride(actualInstanceWidth(), 3, isRow); + } +} + +void NestedArtboardLayout::updateHeightOverride() +{ + if (artboardInstance() == nullptr) + { + return; + } + auto isRow = + parent()->is<LayoutComponent>() ? parent()->as<LayoutComponent>()->mainAxisIsRow() : true; + if (instanceHeightScaleType() == 0) // LayoutScaleType::fixed + { + // If we're set to fixed, pass the unit value (points|percent) + artboardInstance()->heightOverride(actualInstanceHeight(), + instanceHeightUnitsValue(), + isRow); + } + else if (instanceHeightScaleType() == 1) // LayoutScaleType::fill + { + // If we're set to fill, pass auto + artboardInstance()->heightOverride(actualInstanceHeight(), 3, isRow); + } +} + +void NestedArtboardLayout::instanceWidthChanged() { updateWidthOverride(); } + +void NestedArtboardLayout::instanceHeightChanged() { updateHeightOverride(); } + +void NestedArtboardLayout::instanceWidthUnitsValueChanged() { updateWidthOverride(); } + +void NestedArtboardLayout::instanceHeightUnitsValueChanged() { updateHeightOverride(); } + +void NestedArtboardLayout::instanceWidthScaleTypeChanged() { updateWidthOverride(); } + +void NestedArtboardLayout::instanceHeightScaleTypeChanged() { updateHeightOverride(); } \ No newline at end of file