Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -417,13 +417,59 @@ fun parseWidget(
var value = layoutVariables.get(element[constraintName])
reference.rotationZ(value) // element.getDouble(constraintName).toFloat())
}
"custom" -> {
parseCustomProperties(state, layoutVariables, element, reference, constraintName)
}
else -> {
parseConstraint(state, layoutVariables, element, reference, constraintName)
}
}
}
}

private fun parseCustomProperties(
state: State,
layoutVariables: LayoutVariables,
element: JSONObject,
reference: ConstraintReference,
constraintName: String
) {
var json = element.optJSONObject(constraintName)
if (json == null) {
return
}
val properties = json.names() ?: return
(0 until properties.length()).forEach { i ->
val property = properties[i].toString()
val value = json[property]
if (value is Int) {
reference.addCustomFloat(property, value.toFloat())
} else if (value is Float) {
reference.addCustomFloat(property, value)
} else if (value is String) {
if (value.startsWith('#')) {
var r = 0f
var g = 0f
var b = 0f
var a = 1f
if (value.length == 7 || value.length == 9) {
var hr = Integer.valueOf(value.substring(1, 3), 16)
var hg = Integer.valueOf(value.substring(3, 5), 16)
var hb = Integer.valueOf(value.substring(5, 7), 16)
r = hr.toFloat() / 255f
g = hg.toFloat() / 255f
b = hb.toFloat() / 255f
}
if (value.length == 9) {
var ha = Integer.valueOf(value.substring(5, 7), 16)
a = ha.toFloat() / 255f
}
reference.addCustomColor(property, r, g, b, a)
}
}
}
}

private fun parseConstraint(
state: State,
layoutVariables: LayoutVariables,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.graphics.Matrix
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.LayoutScopeMarker
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
Expand All @@ -35,9 +36,7 @@ import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.layout.MultiMeasureLayout
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.*
import androidx.constraintlayout.core.state.Dimension
import androidx.constraintlayout.core.state.WidgetFrame
import androidx.constraintlayout.core.widgets.Optimizer
Expand All @@ -57,9 +56,10 @@ inline fun MotionLayout(
debug: EnumSet<MotionLayoutDebugFlags> = EnumSet.of(MotionLayoutDebugFlags.NONE),
modifier: Modifier = Modifier,
optimizationLevel: Int = Optimizer.OPTIMIZATION_STANDARD,
noinline content: @Composable () -> Unit
crossinline content: @Composable MotionLayoutScope.() -> Unit
) {
val measurer = remember { MotionMeasurer() }
val scope = remember { MotionLayoutScope(measurer) }
val progressState = remember { mutableStateOf(0f) }
SideEffect { progressState.value = progress }
val measurePolicy =
Expand All @@ -70,7 +70,7 @@ inline fun MotionLayout(
(MultiMeasureLayout(
modifier = modifier.semantics { designInfoProvider = measurer },
measurePolicy = measurePolicy,
content = content
content = { scope.content() }
))
with(measurer) {
drawDebug()
Expand All @@ -81,11 +81,78 @@ inline fun MotionLayout(
(MultiMeasureLayout(
modifier = modifier.semantics { designInfoProvider = measurer },
measurePolicy = measurePolicy,
content = content
content = { scope.content() }
))
}
}

@LayoutScopeMarker
class MotionLayoutScope @PublishedApi internal constructor(measurer: MotionMeasurer) {
private var myMeasurer = measurer

class MotionProperties internal constructor(id: String, tag: String?, measurer: MotionMeasurer) {
private var myId = id
private var myTag = null
private var myMeasurer = measurer

fun id() : String {
return myId
}

fun tag() : String? {
return myTag
}

fun color(name: String) : Color {
return myMeasurer.getCustomColor(myId, name)
}

fun float(name: String) : Float {
return myMeasurer.getCustomFloat(myId, name)
}

fun int(name: String): Int {
return myMeasurer.getCustomFloat(myId, name).toInt()
}

fun distance(name: String): Dp {
return myMeasurer.getCustomFloat(myId, name).dp
}

fun fontSize(name: String) : TextUnit {
return myMeasurer.getCustomFloat(myId, name).sp
}
}

fun motionProperties(id: String): MotionProperties {
return MotionProperties(id, null, myMeasurer)
}

fun motionProperties(id: String, tag: String): MotionProperties{
return MotionProperties(id, tag, myMeasurer)
}

fun motionColor(id: String, name: String): Color {
return myMeasurer.getCustomColor(id, name)
}

fun motionFloat(id: String, name: String): Float {
return myMeasurer.getCustomFloat(id, name)
}

fun motionInt(id: String, name: String): Int {
return myMeasurer.getCustomFloat(id, name).toInt()
}

fun motionDistance(id: String, name: String): Dp {
return myMeasurer.getCustomFloat(id, name).dp
}

fun motionFontSize(id: String, name: String): TextUnit {
return myMeasurer.getCustomFloat(id, name).sp
}
}

enum class MotionLayoutDebugFlags {
NONE,
SHOW_ALL
Expand Down Expand Up @@ -126,6 +193,8 @@ internal class MotionMeasurer : Measurer() {
var framesStart = ArrayList<WidgetFrame>()
var framesEnd = ArrayList<WidgetFrame>()

fun getProgress() : Float { return motionProgress }

private fun measureConstraintSet(optimizationLevel: Int, constraintSetStart: ConstraintSet,
measurables: List<Measurable>, constraints: Constraints
) {
Expand Down Expand Up @@ -329,6 +398,62 @@ internal class MotionMeasurer : Measurer() {
fun clear() {
frameCache.clear()
}

private fun interpolateColor(start: WidgetFrame.Color, end: WidgetFrame.Color, progress: Float) : Color {
if (progress < 0) {
return Color(start.r, start.g, start.b, start.a)
}
if (progress > 1) {
return Color(end.r, end.g, end.b, end.a)
}
val r = (1f - progress) * start.r + progress * (end.r)
val g = (1f - progress) * start.g + progress * (end.g)
val b = (1f - progress) * start.b + progress * (end.b)
return Color(r, g, b)
}

fun findChild(id: String) : Int {
if (root.children.size == 0) {
return -1
}
val ref = state.constraints(id)
val cw = ref.constraintWidget
var index = 0;
for (child in root.children) {
if (cw == child) {
return index
}
index++
}
return -1
}

fun getCustomColor(id: String, name: String): Color {
val index = findChild(id)
if (index == -1) {
return Color.Black
}
val startFrame = framesStart[index]
val endFrame = framesEnd[index]
val startColor = startFrame.getCustomColor(name)
val endColor = endFrame.getCustomColor(name)
if (startColor != null && endColor != null) {
return interpolateColor(startColor, endColor, motionProgress)
}
return Color.Black
}

fun getCustomFloat(id: String, name: String): Float {
val index = findChild(id)
if (index == -1) {
return 0f;
}
val startFrame = framesStart[index]
val endFrame = framesEnd[index]
val startFloat = startFrame.getCustomFloat(name)
val endFloat = endFrame.getCustomFloat(name)
return (1f - motionProgress) * startFloat + motionProgress * endFloat
}
}

private val DEBUG = false
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import androidx.constraintlayout.core.widgets.ConstraintWidget;

import java.util.ArrayList;
import java.util.HashMap;

import static androidx.constraintlayout.core.widgets.ConstraintWidget.HORIZONTAL;
import static androidx.constraintlayout.core.widgets.ConstraintWidget.VERTICAL;
Expand Down Expand Up @@ -113,6 +114,9 @@ public interface ConstraintReferenceFactory {
private Object mView;
private ConstraintWidget mConstraintWidget;

private HashMap<String, WidgetFrame.Color> mCustomColors = null;
private HashMap<String, Float> mCustomFloats = null;

public void setView(Object view) {
mView = view;
if (mConstraintWidget != null) {
Expand Down Expand Up @@ -355,6 +359,21 @@ public ConstraintReference baseline() {
return this;
}

public void addCustomColor(String name, float r, float g, float b, float a) {
WidgetFrame.Color color = new WidgetFrame.Color(r, g, b, a);
if (mCustomColors == null) {
mCustomColors = new HashMap<>();
}
mCustomColors.put(name, color);
}

public void addCustomFloat(String name, float value) {
if (mCustomFloats == null) {
mCustomFloats = new HashMap<>();
}
mCustomFloats.put(name, value);
}

private void dereference() {
mLeftToLeft = get(mLeftToLeft);
mLeftToRight = get(mLeftToRight);
Expand Down Expand Up @@ -835,5 +854,8 @@ public void apply() {
mConstraintWidget.frame.scaleX = mScaleX;
mConstraintWidget.frame.scaleY = mScaleY;
mConstraintWidget.frame.alpha = mAlpha;

mConstraintWidget.frame.mCustomFloats = mCustomFloats;
mConstraintWidget.frame.mCustomColors = mCustomColors;
}
}
Loading