Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split experiment #761

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import androidx.constraintlayout.core.state.helpers.ChainReference;
import androidx.constraintlayout.core.state.helpers.FlowReference;
import androidx.constraintlayout.core.state.helpers.GuidelineReference;
import androidx.constraintlayout.core.state.helpers.SplitReference;
import androidx.constraintlayout.core.widgets.ConstraintWidget;
import androidx.constraintlayout.core.widgets.Flow;

Expand Down Expand Up @@ -538,6 +539,12 @@ public static void parseJSON(String content, State state,
(CLObject) element
);
break;
case "Split":
parseSplitType(state,
elementName,
layoutVariables,
(CLObject) element);
break;
}
} else {
parseWidget(state, layoutVariables,
Expand Down Expand Up @@ -854,6 +861,45 @@ private static void parseChainType(String orientation,
}
}

private static void parseSplitType(State state,
String name,
LayoutVariables layoutVariables,
CLObject element) throws CLParsingException {

SplitReference split = state.getSplit(name);

for (String param : element.names()) {
switch (param) {
case "contains":
CLArray list = element.getArrayOrNull(param);
if (list != null) {
for (int j = 0; j < list.size(); j++) {

String elementNameReference = list.get(j).content();
ConstraintReference elementReference =
state.constraints(elementNameReference);
if (PARSER_DEBUG) {
System.out.println(
"Add REFERENCE "
+ "($elementNameReference = $elementReference) "
+ "TO BARRIER "
);
}
split.add(elementReference);
}
}
break;
case "orientation":
int orientation = element.get(param).getInt();
split.setOrientation(orientation);
break;
default:
ConstraintReference reference = state.constraints(name);
applyAttribute(state, layoutVariables, reference, element, param);
}
}
}

/**
* It's used to parse the Flow type of Helper with the following format:
* flowID: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import androidx.constraintlayout.core.state.helpers.FlowReference;
import androidx.constraintlayout.core.state.helpers.GuidelineReference;
import androidx.constraintlayout.core.state.helpers.HorizontalChainReference;
import androidx.constraintlayout.core.state.helpers.SplitReference;
import androidx.constraintlayout.core.state.helpers.VerticalChainReference;
import androidx.constraintlayout.core.widgets.ConstraintWidget;
import androidx.constraintlayout.core.widgets.ConstraintWidgetContainer;
Expand Down Expand Up @@ -93,6 +94,7 @@ public enum Helper {
LAYER,
HORIZONTAL_FLOW,
VERTICAL_FLOW,
SPLIT,
FLOW
}

Expand Down Expand Up @@ -324,6 +326,10 @@ public HelperReference helper(Object key, State.Helper type) {
reference = new FlowReference(this, type);
}
break;
case SPLIT: {
reference = new SplitReference(this, type);
}
break;
default: {
reference = new HelperReference(this, type);
}
Expand Down Expand Up @@ -368,6 +374,15 @@ public BarrierReference barrier(Object key, Direction direction) {
return (BarrierReference) reference.getFacade();
}

public SplitReference getSplit(Object key) {
ConstraintReference reference = constraints(key);
if (reference.getFacade() == null || !(reference.getFacade() instanceof SplitReference)) {
SplitReference flowReference = new SplitReference(this, Helper.SPLIT);
reference.setFacade(flowReference);
}
return (SplitReference) reference.getFacade();
}

/**
* Gets a reference to a Flow object. Creating it if needed.
* @param key id of the reference
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package androidx.constraintlayout.core.state.helpers;

import androidx.constraintlayout.core.state.HelperReference;
import androidx.constraintlayout.core.state.State;
import androidx.constraintlayout.core.utils.Split;
import androidx.constraintlayout.core.widgets.ConstraintWidget;
import androidx.constraintlayout.core.widgets.Flow;
import androidx.constraintlayout.core.widgets.HelperWidget;

public class SplitReference extends HelperReference {

public SplitReference(State state, State.Helper type) {
super(state, type);
}

protected Split mSplit;

protected ConstraintWidget mLeft;

protected ConstraintWidget mRight;

protected int mOrientation;

public ConstraintWidget getLeft() {
return mLeft;
}

public void setLeft(ConstraintWidget mLeft) {
this.mLeft = mLeft;
}

public ConstraintWidget getRight() {
return mRight;
}

public void setRight(ConstraintWidget mRight) {
this.mRight = mRight;
}

@Override
public HelperWidget getHelperWidget() {
if (mSplit == null) {
mSplit = new Split();
}
return mSplit;
}

@Override
public void setHelperWidget(HelperWidget widget) {
if (widget instanceof Flow) {
mSplit = (Split) widget;
} else {
mSplit = null;
}
}

public int getOrientation() {
return mOrientation;
}

public void setOrientation(int orientation) {
mOrientation = orientation;

}

@Override
public void apply() {
if (mLeft != null) {
mSplit.setFirst(mLeft);
}

if (mRight != null) {
mSplit.setSecond(mRight);
}

mSplit.setOrientation(mOrientation);

// General attributes of a widget
applyBase();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package androidx.constraintlayout.core.utils;

import androidx.constraintlayout.core.LinearSystem;
import androidx.constraintlayout.core.widgets.ConstraintWidget;
import androidx.constraintlayout.core.widgets.ConstraintWidgetContainer;
import androidx.constraintlayout.core.widgets.VirtualLayout;

public class Split extends VirtualLayout {

ConstraintWidget splitBar;

ConstraintWidget first;
ConstraintWidget second;
ConstraintWidgetContainer mContainer;
int orientation;

public Split() {
splitBar = new ConstraintWidget();
first = new ConstraintWidget();
second = new ConstraintWidget();
}

public void setFirst(ConstraintWidget a) {
first = a;
}

public void setSecond(ConstraintWidget b) {
second = b;
}

public void setSplitBar(ConstraintWidget splitBar) {
this.splitBar = splitBar;
}

public ConstraintWidget getFirst() {
return first;
}

public ConstraintWidget getSecond() {
return second;
}

public ConstraintWidget getSplitBar() {
return splitBar;
}

public ConstraintWidgetContainer getContainer() {
return mContainer;
}

public void setContainer(ConstraintWidgetContainer container) {
mContainer = container;
}

public int getOrientation() {
return orientation;
}

public void setOrientation(int orientation) {
this.orientation = orientation;
}

@Override
public void measure(int widthMode, int widthSize, int heightMode, int heightSize) {
super.measure(widthMode, widthSize, heightMode, heightSize);
for (int i = 0; i < mWidgetsCount; i++) {
if (i == 0) {
setFirst(mWidgets[i]);
} else if (i == 1) {
setSecond(mWidgets[i]);
} else if (i == 2) {
setSplitBar(mWidgets[i]);
}
}
splitBar.stringId = String.valueOf(splitBar.hashCode());
first.stringId = String.valueOf(first.hashCode());
second.stringId = String.valueOf(second.hashCode());
mContainer = (ConstraintWidgetContainer) getParent();
mContainer.add(splitBar);
}

@Override
public void addToSolver(LinearSystem system, boolean optimize) {
this.mTop.connect(getParent().mTop, 0);
this.mLeft.connect(getParent().mLeft, 0);
this.mRight.connect(getParent().mRight, 0);
this.mBottom.connect(getParent().mBottom, 0);

splitBar.mTop.connect(mTop, 0);
splitBar.mBottom.connect(mBottom, 0);
splitBar.mLeft.connect(mLeft, 0);
splitBar.mRight.connect(mRight, 0);

if (orientation == 0) {
first.mLeft.connect(mLeft, 0);
first.mRight.connect(splitBar.mLeft, 0);
first.mTop.connect(mTop, 0);
first.mBottom.connect(mBottom, 0);

second.mLeft.connect(splitBar.mRight, 0);
second.mRight.connect(mRight, 0);
second.mTop.connect(mTop, 0);
second.mBottom.connect(mBottom, 0);
} else {
first.mLeft.connect(mLeft, 0);
first.mRight.connect(mRight, 0);
first.mTop.connect(mTop, 0);
first.mBottom.connect(splitBar.mTop, 0);

second.mLeft.connect(mLeft, 0);
second.mRight.connect(mRight, 0);
second.mTop.connect(splitBar.mBottom, 0);
second.mBottom.connect(mBottom, 0);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import static org.junit.Assert.assertEquals;

import androidx.constraintlayout.core.utils.Split;
import androidx.constraintlayout.core.widgets.ConstraintAnchor;
import androidx.constraintlayout.core.widgets.ConstraintWidget;
import androidx.constraintlayout.core.widgets.ConstraintWidgetContainer;
Expand Down Expand Up @@ -230,4 +231,40 @@ public void didMeasures() {
System.out.println("A: " + a);
System.out.println("B: " + b);
}
@Test
public void testSplit() {
ConstraintWidgetContainer root = new ConstraintWidgetContainer(50, 50);
Split split = new Split();
split.setDebugName("split");

split.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_PARENT);
split.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_PARENT);
split.connect(ConstraintAnchor.Type.LEFT, root, ConstraintAnchor.Type.LEFT);
split.connect(ConstraintAnchor.Type.RIGHT, root, ConstraintAnchor.Type.RIGHT);
split.connect(ConstraintAnchor.Type.TOP, root, ConstraintAnchor.Type.TOP);
split.connect(ConstraintAnchor.Type.BOTTOM, root, ConstraintAnchor.Type.BOTTOM);
split.setOrientation(1);
root.add(split);
split.setContainer(root);
root.setMeasurer(new BasicMeasure.Measurer() {
@Override
public void measure(ConstraintWidget widget, BasicMeasure.Measure measure) {
measure.measuredWidth = widget.getWidth();
measure.measuredHeight = widget.getHeight();
}

@Override
public void didMeasures() {

}
});
root.setMeasurer(sMeasurer);
root.measure(Optimizer.OPTIMIZATION_NONE,
0, 0, 0, 0, 0, 0, 0, 0);
//root.layout();
System.out.println("root: " + root);
System.out.println("flow: " + split);
System.out.println("A: " + split.getFirst());
System.out.println("B: " + split.getSecond());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,36 @@ fun FlowBasicDemo6() {
}
}

// test adding constraints to parent
@Preview(group = "split")
@Composable
fun SplitDemo1() {
ConstraintLayout(
ConstraintSet("""
{
split: {
height: 'parent',
width: 'parent',
type: 'Split',
orientation: 0,
contains: ['btn1', 'btn2'],
},
btn1: {
height: 'spread',
width: 'spread',
}
}
""".trimIndent()),
modifier = Modifier.fillMaxSize()) {
val numArray = arrayOf("btn1", "btn2")
for (num in numArray) {
Button(
modifier = Modifier.layoutId(num),
onClick = {},
) {
Text(text = num)
}
}
}
}