Skip to content

Commit

Permalink
Add width/height overrides for NestedArtboardLayout
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
philter and philter committed Aug 7, 2024
1 parent eb1e576 commit 9039350
Show file tree
Hide file tree
Showing 10 changed files with 500 additions and 88 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1131f30e6a45bee5c0561de3a35b19985bf46820
0dc0b435ffb0df61de0afcdc2cea0c69bb8fedd4
68 changes: 63 additions & 5 deletions dev/defs/nested_artboard_layout.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
1 change: 1 addition & 0 deletions include/rive/artboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class Artboard : public ArtboardBase, public CoreContext

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);
Expand Down
48 changes: 48 additions & 0 deletions include/rive/generated/core_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,18 @@ class CoreRegistry
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;
Expand Down Expand Up @@ -1219,6 +1231,12 @@ class CoreRegistry
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;
Expand Down Expand Up @@ -1798,6 +1816,14 @@ class CoreRegistry
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:
Expand Down Expand Up @@ -2165,6 +2191,10 @@ class CoreRegistry
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:
Expand Down Expand Up @@ -2524,6 +2554,10 @@ class CoreRegistry
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:
Expand Down Expand Up @@ -2701,6 +2735,8 @@ class CoreRegistry
case NodeBase::xArtboardPropertyKey:
case NodeBase::yPropertyKey:
case NodeBase::yArtboardPropertyKey:
case NestedArtboardLayoutBase::instanceWidthPropertyKey:
case NestedArtboardLayoutBase::instanceHeightPropertyKey:
case LayoutComponentStyleBase::gapHorizontalPropertyKey:
case LayoutComponentStyleBase::gapVerticalPropertyKey:
case LayoutComponentStyleBase::maxWidthPropertyKey:
Expand Down Expand Up @@ -2985,6 +3021,14 @@ class CoreRegistry
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:
Expand Down Expand Up @@ -3331,6 +3375,10 @@ class CoreRegistry
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:
Expand Down
126 changes: 126 additions & 0 deletions include/rive/generated/nested_artboard_layout_base.hpp
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -33,9 +35,133 @@ class NestedArtboardLayoutBase : public NestedArtboard

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

Expand Down
14 changes: 14 additions & 0 deletions include/rive/layout_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public
}

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; }
Expand Down Expand Up @@ -106,6 +112,14 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public
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)
{
Expand Down
16 changes: 16 additions & 0 deletions include/rive/nested_artboard_layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ class NestedArtboardLayout : public NestedArtboardLayoutBase
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

Expand Down
5 changes: 4 additions & 1 deletion src/artboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,10 @@ void Artboard::markLayoutDirty(LayoutComponent* layoutComponent)
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();
}
}

Expand Down
Loading

0 comments on commit 9039350

Please sign in to comment.