1 /* 2 * Copyright (C) 2024 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 package com.android.internal.widget.remotecompose.core.operations.layout.modifiers; 17 18 import android.annotation.NonNull; 19 20 import com.android.internal.widget.remotecompose.core.Operation; 21 import com.android.internal.widget.remotecompose.core.RemoteContext; 22 import com.android.internal.widget.remotecompose.core.VariableSupport; 23 import com.android.internal.widget.remotecompose.core.operations.Utils; 24 import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; 25 26 /** Base class for dimension modifiers */ 27 public abstract class DimensionModifierOperation extends Operation 28 implements ModifierOperation, VariableSupport { 29 30 public enum Type { 31 EXACT, 32 FILL, 33 WRAP, 34 WEIGHT, 35 INTRINSIC_MIN, 36 INTRINSIC_MAX, 37 EXACT_DP; 38 39 @NonNull fromInt(int value)40 static Type fromInt(int value) { 41 switch (value) { 42 case 0: 43 return EXACT; 44 case 1: 45 return FILL; 46 case 2: 47 return WRAP; 48 case 3: 49 return WEIGHT; 50 case 4: 51 return INTRINSIC_MIN; 52 case 5: 53 return INTRINSIC_MAX; 54 case 6: 55 return EXACT_DP; 56 } 57 return EXACT; 58 } 59 } 60 61 @NonNull Type mType = Type.EXACT; 62 float mValue = Float.NaN; 63 float mOutValue = Float.NaN; 64 DimensionModifierOperation(@onNull Type type, float value)65 public DimensionModifierOperation(@NonNull Type type, float value) { 66 mType = type; 67 mOutValue = mValue = value; 68 } 69 DimensionModifierOperation(@onNull Type type)70 public DimensionModifierOperation(@NonNull Type type) { 71 this(type, Float.NaN); 72 } 73 DimensionModifierOperation(float value)74 public DimensionModifierOperation(float value) { 75 this(Type.EXACT, value); 76 } 77 78 @Override updateVariables(@onNull RemoteContext context)79 public void updateVariables(@NonNull RemoteContext context) { 80 if (mType == Type.EXACT) { 81 mOutValue = Float.isNaN(mValue) ? context.getFloat(Utils.idFromNan(mValue)) : mValue; 82 } 83 if (mType == Type.EXACT_DP) { 84 float pre = mOutValue; 85 mOutValue = Float.isNaN(mValue) ? context.getFloat(Utils.idFromNan(mValue)) : mValue; 86 mOutValue *= context.getDensity(); 87 if (pre != mOutValue) { 88 context.getDocument().getRootLayoutComponent().invalidateMeasure(); 89 } 90 } 91 } 92 93 @Override registerListening(@onNull RemoteContext context)94 public void registerListening(@NonNull RemoteContext context) { 95 if (mType == Type.EXACT) { 96 if (Float.isNaN(mValue)) { 97 context.listensTo(Utils.idFromNan(mValue), this); 98 } 99 } 100 if (mType == Type.EXACT_DP) { 101 if (Float.isNaN(mValue)) { 102 context.listensTo(Utils.idFromNan(mValue), this); 103 } 104 } 105 } 106 107 /** 108 * Returns true if the dimension is set using a weight 109 * 110 * @return true if using weight, false otherwise 111 */ hasWeight()112 public boolean hasWeight() { 113 return mType == Type.WEIGHT; 114 } 115 isWrap()116 public boolean isWrap() { 117 return mType == Type.WRAP; 118 } 119 isFill()120 public boolean isFill() { 121 return mType == Type.FILL; 122 } 123 isIntrinsicMin()124 public boolean isIntrinsicMin() { 125 return mType == Type.INTRINSIC_MIN; 126 } 127 isIntrinsicMax()128 public boolean isIntrinsicMax() { 129 return mType == Type.INTRINSIC_MAX; 130 } 131 getType()132 public @NonNull Type getType() { 133 return mType; 134 } 135 getValue()136 public float getValue() { 137 return mOutValue; 138 } 139 setValue(float value)140 public void setValue(float value) { 141 mOutValue = mValue = value; 142 } 143 144 /** 145 * Returns the serialized name for this operation 146 * 147 * @return the serialized name 148 */ 149 @NonNull serializedName()150 public String serializedName() { 151 return "DIMENSION"; 152 } 153 154 @Override serializeToString(int indent, @NonNull StringSerializer serializer)155 public void serializeToString(int indent, @NonNull StringSerializer serializer) { 156 if (mType == Type.EXACT) { 157 serializer.append(indent, serializedName() + " = " + mValue); 158 } 159 if (mType == Type.EXACT_DP) { 160 serializer.append(indent, serializedName() + " = " + mValue + " dp"); 161 } 162 } 163 164 @Override apply(@onNull RemoteContext context)165 public void apply(@NonNull RemoteContext context) {} 166 167 @NonNull 168 @Override deepToString(@onNull String indent)169 public String deepToString(@NonNull String indent) { 170 return (indent != null ? indent : "") + toString(); 171 } 172 173 @NonNull 174 @Override toString()175 public String toString() { 176 return "DimensionModifierOperation(" + mValue + ")"; 177 } 178 } 179