Skip to content

Commit

Permalink
add a standard constraint chain syntax (#613)
Browse files Browse the repository at this point in the history
* fix desig time lockout of on click

* fix ConstraintLayout Compose chain

* add support for weights and margins

* resolve comments & clean up spaces

* resolve comments & clean up spaces

* resolve oscar comments
  • Loading branch information
jafu888 authored May 25, 2022
1 parent 3593174 commit eb5afdd
Show file tree
Hide file tree
Showing 96 changed files with 3,285 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,16 @@ public static void parseJSON(String content, State state,
case "barrier":
parseBarrier(state, elementName, (CLObject) element);
break;
case "vChain":
case "hChain":
parseChainType(
type,
state,
elementName,
layoutVariables,
(CLObject) element
);
break;
}
} else {
parseWidget(state, layoutVariables,
Expand Down Expand Up @@ -726,6 +736,110 @@ static void parseChain(int orientation, State state,
}
}

private static float toPix(State state, float dp){
return state.getDpToPixel().toPixels(dp);
}
/**
* Support parsing Chain in the following manner
* chainId : {
* type:'hChain' // or vChain
* contains: ['id1', 'id2', 'id3' ]
* contains: [['id', weight, marginL ,marginR], 'id2', 'id3' ]
* start: ['parent', 'start',0],
* end: ['parent', 'end',0],
* top: ['parent', 'top',0],
* bottom: ['parent', 'bottom',0],
* style: 'spread'
* }
* @throws CLParsingException
*/
private static void parseChainType(String orientation,
State state,
String chainName,
LayoutVariables margins,
CLObject object) throws CLParsingException {

ChainReference chain = (orientation.charAt(0) == 'h')
? state.horizontalChain() : state.verticalChain();
chain.setKey(chainName);

for (String params : object.names()) {
switch (params) {
case "contains":
CLElement refs = object.get(params);
if (!(refs instanceof CLArray) || ((CLArray) refs).size() < 1) {
System.err.println(
chainName + " contains should be an array \"" + refs.content()
+ "\"");
return;
}
for (int i = 0; i < ((CLArray) refs).size(); i++) {
CLElement chainElement = ((CLArray) refs).get(i);
if (chainElement instanceof CLArray) {
CLArray array = (CLArray) chainElement;
if (array.size() > 0) {
String id = array.get(0).content();
chain.add(id);
float weight = Float.NaN;
float preMargin = Float.NaN;
float postMargin = Float.NaN;
switch (array.size()) {
case 2: // sets only the weight
weight = array.getFloat(1);
break;
case 3: // sets the pre and post margin to the 2 arg
weight = array.getFloat(1);
postMargin = preMargin = toPix(state, array.getFloat(2));
break;
case 4: // sets the pre and post margin
weight = array.getFloat(1);
preMargin = toPix(state, array.getFloat(2));
postMargin = toPix(state, array.getFloat(3));
break;
}
chain.addChainElement(id, weight, preMargin, postMargin);
}
} else {
chain.add(chainElement.content());
}
}
break;
case "start":
case "end":
case "top":
case "bottom":
case "left":
case "right":
parseConstraint(state, margins, object, chain, params);
break;
case "style":

CLElement styleObject = object.get(params);
String styleValue;
if (styleObject instanceof CLArray && ((CLArray) styleObject).size() > 1) {
styleValue = ((CLArray) styleObject).getString(0);
float biasValue = ((CLArray) styleObject).getFloat(1);
chain.bias(biasValue);
} else {
styleValue = styleObject.content();
}
switch (styleValue) {
case "packed":
chain.style(State.Chain.PACKED);
break;
case "spread_inside":
chain.style(State.Chain.SPREAD_INSIDE);
break;
default:
chain.style(State.Chain.SPREAD);
break;
}

break;
}
}
}

static void parseGuideline(int orientation,
State state, CLArray helper) throws CLParsingException {
Expand All @@ -738,7 +852,6 @@ static void parseGuideline(int orientation,
parseGuidelineParams(orientation, state, guidelineId, (CLObject) params);
}


static void parseGuidelineParams(
int orientation,
State state,
Expand Down Expand Up @@ -980,10 +1093,8 @@ static void parseWidget(

}
}

}


static void parseCustomProperties(
CLObject element,
ConstraintReference reference,
Expand Down Expand Up @@ -1019,7 +1130,6 @@ private static int indexOf(String val, String... types) {
return -1;
}


/**
* parse the motion section of a constraint
* <pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@
import androidx.constraintlayout.core.state.HelperReference;
import androidx.constraintlayout.core.state.State;

import java.util.HashMap;

public class ChainReference extends HelperReference {

protected float mBias = 0.5f;
protected HashMap<String ,Float> mMapWeights;
protected HashMap<String,Float> mMapPreMargin;
protected HashMap<String,Float> mMapPostMargin;

protected State.Chain mStyle = State.Chain.SPREAD;

public ChainReference(State state, State.Helper type) {
Expand All @@ -40,6 +46,52 @@ public ChainReference style(State.Chain style) {
return this;
}

public void addChainElement(String id, float weight, float preMargin, float postMargin ) {
super.add(id);
if (!Float.isNaN(weight)) {
if (mMapWeights == null) {
mMapWeights = new HashMap<>();
}
mMapWeights.put(id, weight);
}
if (!Float.isNaN(preMargin)) {
if (mMapPreMargin == null) {
mMapPreMargin = new HashMap<>();
}
mMapPreMargin.put(id, preMargin);
}
if (!Float.isNaN(postMargin)) {
if (mMapPostMargin == null) {
mMapPostMargin = new HashMap<>();
}
mMapPostMargin.put(id, postMargin);
}
}

protected float getWeight(String id) {
if (mMapWeights == null) {
return -1;
}
if (mMapWeights.containsKey(id)) {
return mMapWeights.get(id);
}
return 1;
}

protected float getPostMargin(String id) {
if (mMapPostMargin != null && mMapPostMargin.containsKey(id)) {
return mMapPostMargin.get(id);
}
return 0;
}

protected float getPreMargin(String id) {
if (mMapPreMargin != null && mMapPreMargin.containsKey(id)) {
return mMapPreMargin.get(id);
}
return 0;
}

public float getBias() {
return mBias;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public void apply() {

for (Object key : mReferences) {
ConstraintReference reference = mState.constraints(key);

if (first == null) {
first = reference;
if (mStartToStart != null) {
Expand All @@ -55,13 +56,17 @@ public void apply() {
first.startToEnd(mLeftToRight).margin(mMarginLeft).marginGone(mMarginLeftGone);
} else {
// No constraint declared, default to Parent.
first.startToStart(State.PARENT);
String refKey = reference.getKey().toString();
first.startToStart(State.PARENT).margin(getPreMargin(refKey));
}
}
if (previous != null) {
previous.endToStart(reference.getKey());
reference.startToEnd(previous.getKey());
String preKey = previous.getKey().toString();
String refKey = reference.getKey().toString();
previous.endToStart(reference.getKey()).margin(getPostMargin(preKey));
reference.startToEnd(previous.getKey()).margin(getPreMargin(refKey));
}
reference.setHorizontalChainWeight(getWeight(key.toString()));
previous = reference;
}

Expand All @@ -78,7 +83,8 @@ public void apply() {
previous.endToEnd(mRightToRight).margin(mMarginRight).marginGone(mMarginRightGone);
} else {
// No constraint declared, default to Parent.
previous.endToEnd(State.PARENT);
String preKey = previous.getKey().toString();
previous.endToEnd(State.PARENT).margin(getPostMargin(preKey));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,17 @@ public void apply() {
first.topToBottom(mTopToBottom).margin(mMarginTop).marginGone(mMarginTopGone);
} else {
// No constraint declared, default to Parent.
first.topToTop(State.PARENT);
String refKey = reference.getKey().toString();
first.topToTop(State.PARENT).margin(getPreMargin(refKey));
}
}
if (previous != null) {
previous.bottomToTop(reference.getKey());
reference.topToBottom(previous.getKey());
String preKey = previous.getKey().toString();
String refKey = reference.getKey().toString();
previous.bottomToTop(reference.getKey()).margin(getPostMargin(preKey));
reference.topToBottom(previous.getKey()).margin(getPreMargin(refKey));
}
reference.setVerticalChainWeight(getWeight(key.toString()));
previous = reference;
}

Expand All @@ -68,7 +72,8 @@ public void apply() {
.marginGone(mMarginBottomGone);
} else {
// No constraint declared, default to Parent.
previous.bottomToBottom(State.PARENT);
String preKey = previous.getKey().toString();
previous.bottomToBottom(State.PARENT).margin(getPostMargin(preKey));
}
}

Expand Down
15 changes: 15 additions & 0 deletions demoProjects/ComposeConstraintLayoutDemo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
3 changes: 3 additions & 0 deletions demoProjects/ComposeConstraintLayoutDemo/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions demoProjects/ComposeConstraintLayoutDemo/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
64 changes: 64 additions & 0 deletions demoProjects/ComposeConstraintLayoutDemo/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}

android {
namespace 'androidx.demo.motiondemos'
compileSdk 32

defaultConfig {
applicationId "androidx.demo.motiondemos"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.1.1'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.1'
implementation 'androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha01'
implementation "androidx.compose.ui:ui:$compose_ui_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
implementation 'androidx.compose.material:material:1.1.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
}
Loading

0 comments on commit eb5afdd

Please sign in to comment.