1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.constraintlayout.compose 18 19 import androidx.compose.runtime.Immutable 20 import androidx.compose.ui.layout.Measurable 21 import androidx.constraintlayout.core.parser.CLKey 22 import androidx.constraintlayout.core.parser.CLParser 23 import androidx.constraintlayout.core.parser.CLParsingException 24 import androidx.constraintlayout.core.state.ConstraintSetParser 25 import androidx.constraintlayout.core.state.Transition 26 import org.intellij.lang.annotations.Language 27 28 @Immutable 29 internal class JSONConstraintSet( 30 @Language("json5") content: String, 31 @Language("json5") overrideVariables: String? = null, 32 override val extendFrom: ConstraintSet? = null 33 ) : EditableJSONLayout(content), DerivedConstraintSet { 34 private val overridedVariables = HashMap<String, Float>() 35 private val overrideVariables = overrideVariables 36 private var _isDirty = true 37 38 init { 39 initialization() 40 } 41 equalsnull42 override fun equals(other: Any?): Boolean { 43 if (other is JSONConstraintSet) { 44 return this.getCurrentContent() == other.getCurrentContent() 45 } 46 return false 47 } 48 isDirtynull49 override fun isDirty(measurables: List<Measurable>): Boolean { 50 return _isDirty 51 } 52 53 // Only called by MotionLayout in MotionMeasurer applyTonull54 override fun applyTo(transition: Transition, type: Int) { 55 val layoutVariables = ConstraintSetParser.LayoutVariables() 56 applyLayoutVariables(layoutVariables) 57 ConstraintSetParser.parseJSON(getCurrentContent(), transition, type) 58 } 59 emitDesignElementsnull60 fun emitDesignElements(designElements: ArrayList<ConstraintSetParser.DesignElement>) { 61 try { 62 designElements.clear() 63 ConstraintSetParser.parseDesignElementsJSON(getCurrentContent(), designElements) 64 } catch (e: Exception) { 65 // nothing (content might be invalid, sent by live edit) 66 } 67 } 68 69 // Called by both MotionLayout & ConstraintLayout measurers applyToStatenull70 override fun applyToState(state: State) { 71 val layoutVariables = ConstraintSetParser.LayoutVariables() 72 applyLayoutVariables(layoutVariables) 73 // TODO: Need to better handle half parsed JSON and/or incorrect states. 74 try { 75 ConstraintSetParser.parseJSON(getCurrentContent(), state, layoutVariables) 76 _isDirty = false 77 } catch (e: Exception) { 78 // nothing (content might be invalid, sent by live edit) 79 _isDirty = true 80 } 81 } 82 onNewContentnull83 override fun onNewContent(content: String) { 84 super.onNewContent(content) 85 _isDirty = true 86 } 87 overridenull88 override fun override(name: String, value: Float): ConstraintSet { 89 overridedVariables[name] = value 90 return this 91 } 92 applyLayoutVariablesnull93 private fun applyLayoutVariables(layoutVariables: ConstraintSetParser.LayoutVariables) { 94 if (overrideVariables != null) { 95 try { 96 val variables = CLParser.parse(overrideVariables) 97 for (i in 0 until variables.size()) { 98 val key = variables[i] as CLKey 99 val variable = key.value.float 100 // TODO: allow arbitrary override, not just float values 101 layoutVariables.putOverride(key.content(), variable) 102 } 103 } catch (e: CLParsingException) { 104 System.err.println("exception: " + e) 105 } 106 } 107 for (name in overridedVariables.keys) { 108 layoutVariables.putOverride(name, overridedVariables[name]!!) 109 } 110 } 111 resetForcedProgressnull112 override fun resetForcedProgress() { 113 // Nothing for ConstraintSet 114 } 115 getForcedProgressnull116 override fun getForcedProgress(): Float { 117 // Nothing for ConstraintSet 118 return 0f 119 } 120 onNewProgressnull121 override fun onNewProgress(progress: Float) { 122 // Nothing for ConstraintSet 123 } 124 } 125