summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Roard <nicolasroard@google.com>2018-06-03 23:16:28 -0700
committerNicolas Roard <nicolasroard@google.com>2018-06-03 23:23:23 -0700
commit81464d089d5912582e7df5f7a8c0ed468992630f (patch)
tree1da6df48757a1938c7310b89419ba552949cf40b
parentefb9f6ddf518048b621b33c56788f3f1090884a2 (diff)
downloadsherpa-81464d089d5912582e7df5f7a8c0ed468992630f.tar.gz
Fix ratio resolution
Fixes: 77991323 Test: added checks 187,188,189,190,191,192,193 added AdvancedChainTest:testChainLastGone() added RatioTest:testSimpleWrapRatio() RatioTest:testSimpleWrapRatio2() RatioTest:testNestedRatio() Change-Id: If1cc56456e3bae905d37153d44e6f8b71ea99d27
-rw-r--r--solver/src/main/java/android/support/constraint/solver/widgets/Chain.java13
-rw-r--r--solver/src/main/java/android/support/constraint/solver/widgets/ConstraintWidget.java36
-rw-r--r--solver/src/test/java/android/support/constraint/solver/AdvancedChainTest.java53
-rw-r--r--solver/src/test/java/android/support/constraint/solver/RatioTest.java109
4 files changed, 190 insertions, 21 deletions
diff --git a/solver/src/main/java/android/support/constraint/solver/widgets/Chain.java b/solver/src/main/java/android/support/constraint/solver/widgets/Chain.java
index 9fef62b..b2e8c1e 100644
--- a/solver/src/main/java/android/support/constraint/solver/widgets/Chain.java
+++ b/solver/src/main/java/android/support/constraint/solver/widgets/Chain.java
@@ -150,7 +150,10 @@ class Chain {
}
ConstraintAnchor begin = widget.mListAnchors[offset];
- int strength = SolverVariable.STRENGTH_LOW;
+ int strength = SolverVariable.STRENGTH_HIGHEST;
+ if (isWrapContent || isChainPacked) {
+ strength = SolverVariable.STRENGTH_LOW;
+ }
int margin = begin.getMargin();
if (begin.mTarget != null && widget != first) {
@@ -333,7 +336,7 @@ class Chain {
if (next != null) {
beginNextAnchor = next.mListAnchors[offset];
beginNext = beginNextAnchor.mSolverVariable;
- beginNextTarget = beginNextAnchor.mTarget != null ? beginNextAnchor.mTarget.mSolverVariable : null;
+ beginNextTarget = widget.mListAnchors[offset + 1].mSolverVariable;
} else {
beginNextAnchor = last.mListAnchors[offset + 1].mTarget;
if (beginNextAnchor != null) {
@@ -430,12 +433,16 @@ class Chain {
}
- // final centering
+ // final centering, necessary if the chain is smaller than the available space...
if ((isChainSpread || isChainSpreadInside) && firstVisibleWidget != null) {
ConstraintAnchor begin = firstVisibleWidget.mListAnchors[offset];
ConstraintAnchor end = lastVisibleWidget.mListAnchors[offset + 1];
SolverVariable beginTarget = begin.mTarget != null ? begin.mTarget.mSolverVariable : null;
SolverVariable endTarget = end.mTarget != null ? end.mTarget.mSolverVariable : null;
+ if (last != lastVisibleWidget) {
+ ConstraintAnchor realEnd = last.mListAnchors[offset + 1];
+ endTarget = realEnd.mTarget != null ? realEnd.mTarget.mSolverVariable : null;
+ }
if (firstVisibleWidget == lastVisibleWidget) {
begin = firstVisibleWidget.mListAnchors[offset];
end = firstVisibleWidget.mListAnchors[offset + 1];
diff --git a/solver/src/main/java/android/support/constraint/solver/widgets/ConstraintWidget.java b/solver/src/main/java/android/support/constraint/solver/widgets/ConstraintWidget.java
index 85aa836..09b8dc7 100644
--- a/solver/src/main/java/android/support/constraint/solver/widgets/ConstraintWidget.java
+++ b/solver/src/main/java/android/support/constraint/solver/widgets/ConstraintWidget.java
@@ -2240,12 +2240,25 @@ public class ConstraintWidget {
if (mDimensionRatio > 0 && mVisibility != GONE) {
useRatio = true;
if (mListDimensionBehaviors[DIMENSION_HORIZONTAL] == DimensionBehaviour.MATCH_CONSTRAINT
- && mListDimensionBehaviors[DIMENSION_VERTICAL] == DimensionBehaviour.MATCH_CONSTRAINT) {
+ && mMatchConstraintDefaultWidth == MATCH_CONSTRAINT_SPREAD) {
+ mMatchConstraintDefaultWidth = MATCH_CONSTRAINT_RATIO;
+ }
+ if (mListDimensionBehaviors[DIMENSION_VERTICAL] == DimensionBehaviour.MATCH_CONSTRAINT
+ && mMatchConstraintDefaultHeight == MATCH_CONSTRAINT_SPREAD) {
+ mMatchConstraintDefaultHeight = MATCH_CONSTRAINT_RATIO;
+ }
+
+ if (mListDimensionBehaviors[DIMENSION_HORIZONTAL] == DimensionBehaviour.MATCH_CONSTRAINT
+ && mListDimensionBehaviors[DIMENSION_VERTICAL] == DimensionBehaviour.MATCH_CONSTRAINT
+ && mMatchConstraintDefaultWidth == MATCH_CONSTRAINT_RATIO
+ && mMatchConstraintDefaultHeight == MATCH_CONSTRAINT_RATIO) {
setupDimensionRatio(horizontalParentWrapContent, verticalParentWrapContent, horizontalDimensionFixed, verticalDimensionFixed);
- } else if (mListDimensionBehaviors[DIMENSION_HORIZONTAL] == DimensionBehaviour.MATCH_CONSTRAINT) {
+ } else if (mListDimensionBehaviors[DIMENSION_HORIZONTAL] == DimensionBehaviour.MATCH_CONSTRAINT
+ && mMatchConstraintDefaultWidth == MATCH_CONSTRAINT_RATIO) {
mResolvedDimensionRatioSide = HORIZONTAL;
width = (int) (mResolvedDimensionRatio * mHeight);
- } else if (mListDimensionBehaviors[DIMENSION_VERTICAL] == DimensionBehaviour.MATCH_CONSTRAINT) {
+ } else if (mListDimensionBehaviors[DIMENSION_VERTICAL] == DimensionBehaviour.MATCH_CONSTRAINT
+ && mMatchConstraintDefaultHeight == MATCH_CONSTRAINT_RATIO) {
mResolvedDimensionRatioSide = VERTICAL;
if (mDimensionRatioSide == UNKNOWN) {
// need to reverse the ratio as the parsing is done in horizontal mode
@@ -2342,13 +2355,6 @@ public class ConstraintWidget {
* @param verticalDimensionFixed true if this widget vertical dimension is fixed
*/
public void setupDimensionRatio(boolean hparentWrapContent, boolean vparentWrapContent, boolean horizontalDimensionFixed, boolean verticalDimensionFixed) {
- if (mMatchConstraintDefaultWidth == MATCH_CONSTRAINT_SPREAD) {
- mMatchConstraintDefaultWidth = MATCH_CONSTRAINT_RATIO;
- }
- if (mMatchConstraintDefaultHeight == MATCH_CONSTRAINT_SPREAD) {
- mMatchConstraintDefaultHeight = MATCH_CONSTRAINT_RATIO;
- }
-
if (mResolvedDimensionRatioSide == UNKNOWN) {
if (horizontalDimensionFixed && !verticalDimensionFixed) {
mResolvedDimensionRatioSide = HORIZONTAL;
@@ -2396,11 +2402,13 @@ public class ConstraintWidget {
} else if (mMatchConstraintMinWidth == 0 && mMatchConstraintMinHeight > 0) {
mResolvedDimensionRatio = 1 / mResolvedDimensionRatio;
mResolvedDimensionRatioSide = VERTICAL;
- } else {
- mResolvedDimensionRatio = 1 / mResolvedDimensionRatio;
- mResolvedDimensionRatioSide = VERTICAL;
}
}
+
+ if (mResolvedDimensionRatioSide == UNKNOWN && hparentWrapContent && vparentWrapContent) {
+ mResolvedDimensionRatio = 1 / mResolvedDimensionRatio;
+ mResolvedDimensionRatioSide = VERTICAL;
+ }
}
/**
@@ -2624,7 +2632,7 @@ public class ConstraintWidget {
applyCentering = true;
applyBoundsCheck = true;
int strength = SolverVariable.STRENGTH_HIGHEST;
- if (!useRatio) {
+ if (!useRatio && mResolvedDimensionRatioSide != UNKNOWN) {
// useRatio is true if the side we base ourselves on for the ratio is this one
// in that case, we need to have a stronger constraint.
strength = SolverVariable.STRENGTH_FIXED;
diff --git a/solver/src/test/java/android/support/constraint/solver/AdvancedChainTest.java b/solver/src/test/java/android/support/constraint/solver/AdvancedChainTest.java
index a9715ec..20436bd 100644
--- a/solver/src/test/java/android/support/constraint/solver/AdvancedChainTest.java
+++ b/solver/src/test/java/android/support/constraint/solver/AdvancedChainTest.java
@@ -30,6 +30,59 @@ import static org.testng.Assert.assertEquals;
public class AdvancedChainTest {
@Test
+ public void testChainLastGone() {
+ ConstraintWidgetContainer root = new ConstraintWidgetContainer(0, 0, 800, 800);
+ ConstraintWidget A = new ConstraintWidget(100, 20);
+ ConstraintWidget B = new ConstraintWidget(100, 20);
+ ConstraintWidget C = new ConstraintWidget(100, 20);
+ ConstraintWidget D = new ConstraintWidget(100, 20);
+ root.setDebugSolverName(root.getSystem(), "root");
+ A.setDebugSolverName(root.getSystem(), "A");
+ B.setDebugSolverName(root.getSystem(), "B");
+ C.setDebugSolverName(root.getSystem(), "C");
+ D.setDebugSolverName(root.getSystem(), "D");
+ root.add(A);
+ root.add(B);
+ root.add(C);
+ root.add(D);
+
+ A.connect(Type.LEFT, root, Type.LEFT, 0);
+ A.connect(Type.RIGHT, root, Type.RIGHT, 0);
+
+ B.connect(Type.LEFT, root, Type.LEFT, 0);
+ B.connect(Type.RIGHT, root, Type.RIGHT, 0);
+
+ C.connect(Type.LEFT, root, Type.LEFT, 0);
+ C.connect(Type.RIGHT, root, Type.RIGHT, 0);
+
+ D.connect(Type.LEFT, root, Type.LEFT, 0);
+ D.connect(Type.RIGHT, root, Type.RIGHT, 0);
+
+ A.connect(Type.TOP, root, Type.TOP, 0);
+ A.connect(Type.BOTTOM, B, Type.TOP, 0);
+ B.connect(Type.TOP, A, Type.BOTTOM, 0);
+ B.connect(Type.BOTTOM, C, Type.TOP, 0);
+ C.connect(Type.TOP, B, Type.BOTTOM, 0);
+ C.connect(Type.BOTTOM, D, Type.TOP, 0);
+ D.connect(Type.TOP, C, Type.BOTTOM, 0);
+ D.connect(Type.BOTTOM, root, Type.BOTTOM, 0);
+
+ B.setVisibility(ConstraintWidget.GONE);
+ D.setVisibility(ConstraintWidget.GONE);
+
+ root.setOptimizationLevel(Optimizer.OPTIMIZATION_NONE);
+ root.layout();
+
+ System.out.println("A: " + A);
+ System.out.println("B: " + B);
+ System.out.println("C: " + C);
+ System.out.println("D: " + D);
+
+ assertEquals(A.getTop(), 253);
+ assertEquals(C.getTop(), 527);
+ }
+
+ @Test
public void testRatioChainGone() {
ConstraintWidgetContainer root = new ConstraintWidgetContainer(0, 0, 800, 800);
ConstraintWidget A = new ConstraintWidget(100, 20);
diff --git a/solver/src/test/java/android/support/constraint/solver/RatioTest.java b/solver/src/test/java/android/support/constraint/solver/RatioTest.java
index 6b474aa..9cc284b 100644
--- a/solver/src/test/java/android/support/constraint/solver/RatioTest.java
+++ b/solver/src/test/java/android/support/constraint/solver/RatioTest.java
@@ -25,6 +25,107 @@ import static org.testng.Assert.assertEquals;
public class RatioTest {
+
+ @Test
+ public void testSimpleWrapRatio() {
+ ConstraintWidgetContainer root = new ConstraintWidgetContainer(0, 0, 1000, 1000);
+ ConstraintWidget A = new ConstraintWidget(100, 20);
+ root.setDebugName("root");
+ root.add(A);
+ A.setDebugName("A");
+
+ A.connect(ConstraintAnchor.Type.LEFT, root, ConstraintAnchor.Type.LEFT);
+ A.connect(ConstraintAnchor.Type.RIGHT, root, ConstraintAnchor.Type.RIGHT);
+ A.connect(ConstraintAnchor.Type.TOP, root, ConstraintAnchor.Type.TOP);
+ A.connect(ConstraintAnchor.Type.BOTTOM, root, ConstraintAnchor.Type.BOTTOM);
+
+
+ A.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+ A.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+
+ A.setDimensionRatio("1:1");
+ root.setOptimizationLevel(Optimizer.OPTIMIZATION_NONE);
+ root.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.WRAP_CONTENT);
+ root.layout();
+
+ System.out.println("a) root: " + root + " A: " + A);
+ assertEquals(root.getWidth(), 1000);
+ assertEquals(root.getHeight(), 1000);
+ assertEquals(A.getWidth(), 1000);
+ assertEquals(A.getHeight(), 1000);
+ }
+
+ @Test
+ public void testSimpleWrapRatio2() {
+ ConstraintWidgetContainer root = new ConstraintWidgetContainer(0, 0, 1000, 1000);
+ ConstraintWidget A = new ConstraintWidget(100, 20);
+ root.setDebugName("root");
+ root.add(A);
+ A.setDebugName("A");
+
+ A.connect(ConstraintAnchor.Type.LEFT, root, ConstraintAnchor.Type.LEFT);
+ A.connect(ConstraintAnchor.Type.RIGHT, root, ConstraintAnchor.Type.RIGHT);
+ A.connect(ConstraintAnchor.Type.TOP, root, ConstraintAnchor.Type.TOP);
+ A.connect(ConstraintAnchor.Type.BOTTOM, root, ConstraintAnchor.Type.BOTTOM);
+
+
+ A.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+ A.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+
+ A.setDimensionRatio("1:1");
+ root.setOptimizationLevel(Optimizer.OPTIMIZATION_NONE);
+ root.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.WRAP_CONTENT);
+ root.layout();
+
+ System.out.println("a) root: " + root + " A: " + A);
+ assertEquals(root.getWidth(), 1000);
+ assertEquals(root.getHeight(), 1000);
+ assertEquals(A.getWidth(), 1000);
+ assertEquals(A.getHeight(), 1000);
+ }
+
+ @Test
+ public void testNestedRatio() {
+ ConstraintWidgetContainer root = new ConstraintWidgetContainer(0, 0, 1000, 1000);
+ ConstraintWidget A = new ConstraintWidget(100, 20);
+ ConstraintWidget B = new ConstraintWidget(100, 20);
+ root.setDebugName("root");
+ A.setDebugName("A");
+ B.setDebugName("B");
+ root.add(A);
+ root.add(B);
+ A.connect(ConstraintAnchor.Type.LEFT, root, ConstraintAnchor.Type.LEFT);
+ A.connect(ConstraintAnchor.Type.RIGHT, root, ConstraintAnchor.Type.RIGHT);
+ A.connect(ConstraintAnchor.Type.TOP, root, ConstraintAnchor.Type.TOP);
+ A.connect(ConstraintAnchor.Type.BOTTOM, B, ConstraintAnchor.Type.TOP);
+
+ B.connect(ConstraintAnchor.Type.LEFT, A, ConstraintAnchor.Type.LEFT);
+ B.connect(ConstraintAnchor.Type.RIGHT, A, ConstraintAnchor.Type.RIGHT);
+ B.connect(ConstraintAnchor.Type.TOP, A, ConstraintAnchor.Type.BOTTOM);
+ B.connect(ConstraintAnchor.Type.BOTTOM, root, ConstraintAnchor.Type.BOTTOM);
+
+ A.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+ A.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+ B.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+ B.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
+
+ A.setDimensionRatio("1:1");
+ B.setDimensionRatio("1:1");
+
+ root.setOptimizationLevel(Optimizer.OPTIMIZATION_NONE);
+ root.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.WRAP_CONTENT);
+ root.layout();
+
+ System.out.println("a) root: " + root + " A: " + A + " B: " + B);
+ assertEquals(root.getWidth(), 500);
+ assertEquals(A.getWidth(), 500);
+ assertEquals(B.getWidth(), 500);
+ assertEquals(root.getHeight(), 1000);
+ assertEquals(A.getHeight(), 500);
+ assertEquals(B.getHeight(), 500);
+ }
+
+
@Test
public void testBasicCenter() {
ConstraintWidgetContainer root = new ConstraintWidgetContainer(0, 0, 1000, 600);
@@ -180,18 +281,18 @@ public class RatioTest {
root.layout();
System.out.println("a) root: " + root + " A: " + A);
int w = (int) (0.7 * root.getWidth());
- assertEquals(A.getLeft(), (root.getWidth() - w) / 2);
- assertEquals(A.getTop(), (root.getHeight() - w) / 2);
assertEquals(A.getWidth(), w);
assertEquals(A.getHeight(), w);
+ assertEquals(A.getLeft(), (root.getWidth() - w) / 2);
+ assertEquals(A.getTop(), (root.getHeight() - w) / 2);
root.setOptimizationLevel(Optimizer.OPTIMIZATION_STANDARD);
root.layout();
System.out.println("b) root: " + root + " A: " + A);
- assertEquals(A.getLeft(), (root.getWidth() - w) / 2);
- assertEquals(A.getTop(), (root.getHeight() - w) / 2);
assertEquals(A.getWidth(), w);
assertEquals(A.getHeight(), w);
+ assertEquals(A.getLeft(), (root.getWidth() - w) / 2);
+ assertEquals(A.getTop(), (root.getHeight() - w) / 2);
}
@Test