Fix layout shape hug in CPP
Diffs=
35a52873c Fix layout shape hug in CPP (#7770)
Co-authored-by: Philip Chung <philterdesign@gmail.com>
diff --git a/.rive_head b/.rive_head
index 17eacd6..db3938f 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-949c70600a6c30bfe3ef6e59685235407af1a323
+35a52873cf0adabbda2670673762a36c91822e96
diff --git a/include/rive/shapes/parametric_path.hpp b/include/rive/shapes/parametric_path.hpp
index 477b9e2..a7469fe 100644
--- a/include/rive/shapes/parametric_path.hpp
+++ b/include/rive/shapes/parametric_path.hpp
@@ -12,6 +12,7 @@
float height,
LayoutMeasureMode heightMode) override;
void controlSize(Vec2D size) override;
+ void markPathDirty(bool sendToLayout = true) override;
protected:
void widthChanged() override;
diff --git a/include/rive/shapes/path.hpp b/include/rive/shapes/path.hpp
index 59cc59b..0984138 100644
--- a/include/rive/shapes/path.hpp
+++ b/include/rive/shapes/path.hpp
@@ -58,7 +58,7 @@
bool canDeferPathUpdate();
void addVertex(PathVertex* vertex);
- virtual void markPathDirty();
+ virtual void markPathDirty(bool sendToLayout = true);
virtual bool isPathClosed() const { return true; }
void onDirty(ComponentDirt dirt) override;
inline bool isHidden() const { return (pathFlags() & 0x1) == 0x1; }
diff --git a/include/rive/shapes/points_path.hpp b/include/rive/shapes/points_path.hpp
index fd91881..743bf9c 100644
--- a/include/rive/shapes/points_path.hpp
+++ b/include/rive/shapes/points_path.hpp
@@ -10,7 +10,7 @@
bool isPathClosed() const override { return isClosed(); }
void buildDependencies() override;
void update(ComponentDirt value) override;
- void markPathDirty() override;
+ void markPathDirty(bool sendToLayout = true) override;
void markSkinDirty() override;
const Mat2D& pathTransform() const override;
};
diff --git a/include/rive/shapes/shape.hpp b/include/rive/shapes/shape.hpp
index e55f794..cfb2d26 100644
--- a/include/rive/shapes/shape.hpp
+++ b/include/rive/shapes/shape.hpp
@@ -69,6 +69,10 @@
AABB computeWorldBounds(const Mat2D* xform = nullptr) const;
AABB computeLocalBounds() const;
+ Vec2D measureLayout(float width,
+ LayoutMeasureMode widthMode,
+ float height,
+ LayoutMeasureMode heightMode) override;
};
} // namespace rive
diff --git a/src/shapes/parametric_path.cpp b/src/shapes/parametric_path.cpp
index b854cdf..aa39cf3 100644
--- a/src/shapes/parametric_path.cpp
+++ b/src/shapes/parametric_path.cpp
@@ -1,5 +1,8 @@
+#include "rive/layout_component.hpp"
#include "rive/math/aabb.hpp"
+#include "rive/node.hpp"
#include "rive/shapes/parametric_path.hpp"
+#include "rive/shapes/shape.hpp"
using namespace rive;
@@ -8,32 +11,13 @@
float height,
LayoutMeasureMode heightMode)
{
- float measuredWidth, measuredHeight;
- switch (widthMode)
- {
- case LayoutMeasureMode::atMost:
- measuredWidth = std::max(ParametricPath::width(), width);
- break;
- case LayoutMeasureMode::exactly:
- measuredWidth = width;
- break;
- case LayoutMeasureMode::undefined:
- measuredWidth = ParametricPath::width();
- break;
- }
- switch (heightMode)
- {
- case LayoutMeasureMode::atMost:
- measuredHeight = std::max(ParametricPath::height(), height);
- break;
- case LayoutMeasureMode::exactly:
- measuredHeight = height;
- break;
- case LayoutMeasureMode::undefined:
- measuredHeight = ParametricPath::height();
- break;
- }
- return Vec2D(measuredWidth, measuredHeight);
+ return Vec2D(
+ std::min(
+ (widthMode == LayoutMeasureMode::undefined ? std::numeric_limits<float>::max() : width),
+ ParametricPath::width()),
+ std::min((heightMode == LayoutMeasureMode::undefined ? std::numeric_limits<float>::max()
+ : height),
+ ParametricPath::height()));
}
void ParametricPath::controlSize(Vec2D size)
@@ -41,6 +25,35 @@
width(size.x);
height(size.y);
markWorldTransformDirty();
+ markPathDirty(false);
+}
+
+void ParametricPath::markPathDirty(bool sendToLayout)
+{
+ Super::markPathDirty();
+#ifdef WITH_RIVE_LAYOUT
+ if (sendToLayout)
+ {
+ for (ContainerComponent* p = parent(); p != nullptr; p = p->parent())
+ {
+ if (p->is<LayoutComponent>())
+ {
+ p->as<LayoutComponent>()->markLayoutNodeDirty();
+ break;
+ }
+ // If we're in a group we break out because objects in groups do
+ // not affect nor are affected by parent LayoutComponents
+ if (p->is<Node>())
+ {
+ if (p->is<Shape>() && p->as<Shape>() == shape())
+ {
+ continue;
+ }
+ break;
+ }
+ }
+ }
+#endif
}
void ParametricPath::widthChanged() { markPathDirty(); }
diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp
index f5898fe..44784db 100644
--- a/src/shapes/path.cpp
+++ b/src/shapes/path.cpp
@@ -228,7 +228,7 @@
}
}
-void Path::markPathDirty()
+void Path::markPathDirty(bool sendToLayout)
{
addDirt(ComponentDirt::Path);
if (m_Shape != nullptr)
diff --git a/src/shapes/points_path.cpp b/src/shapes/points_path.cpp
index a23b0ca..5795357 100644
--- a/src/shapes/points_path.cpp
+++ b/src/shapes/points_path.cpp
@@ -37,7 +37,7 @@
Super::update(value);
}
-void PointsPath::markPathDirty()
+void PointsPath::markPathDirty(bool sendToLayout)
{
if (skin() != nullptr)
{
diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp
index d69648b..68ccf59 100644
--- a/src/shapes/shape.cpp
+++ b/src/shapes/shape.cpp
@@ -302,4 +302,18 @@
const Mat2D& world = worldTransform();
Mat2D inverseWorld = world.invertOrIdentity();
return computeWorldBounds(&inverseWorld);
+}
+
+Vec2D Shape::measureLayout(float width,
+ LayoutMeasureMode widthMode,
+ float height,
+ LayoutMeasureMode heightMode)
+{
+ Vec2D size = Vec2D();
+ for (auto path : m_Paths)
+ {
+ Vec2D measured = path->measureLayout(width, widthMode, height, heightMode);
+ size = Vec2D(std::max(size.x, measured.x), std::max(size.y, measured.y));
+ }
+ return size;
}
\ No newline at end of file