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 package androidx.constraintlayout.core.motion.key; 17 18 import androidx.constraintlayout.core.motion.CustomVariable; 19 import androidx.constraintlayout.core.motion.MotionWidget; 20 import androidx.constraintlayout.core.motion.utils.FloatRect; 21 import androidx.constraintlayout.core.motion.utils.SplineSet; 22 23 import java.util.HashMap; 24 import java.util.HashSet; 25 import java.util.Locale; 26 27 public class MotionKeyTrigger extends MotionKey { 28 private static final String TAG = "KeyTrigger"; 29 public static final String VIEW_TRANSITION_ON_CROSS = "viewTransitionOnCross"; 30 public static final String VIEW_TRANSITION_ON_POSITIVE_CROSS = "viewTransitionOnPositiveCross"; 31 public static final String VIEW_TRANSITION_ON_NEGATIVE_CROSS = "viewTransitionOnNegativeCross"; 32 public static final String POST_LAYOUT = "postLayout"; 33 public static final String TRIGGER_SLACK = "triggerSlack"; 34 public static final String TRIGGER_COLLISION_VIEW = "triggerCollisionView"; 35 public static final String TRIGGER_COLLISION_ID = "triggerCollisionId"; 36 public static final String TRIGGER_ID = "triggerID"; 37 public static final String POSITIVE_CROSS = "positiveCross"; 38 public static final String NEGATIVE_CROSS = "negativeCross"; 39 public static final String TRIGGER_RECEIVER = "triggerReceiver"; 40 public static final String CROSS = "CROSS"; 41 42 private int mCurveFit = -1; 43 private String mCross = null; 44 private int mTriggerReceiver = UNSET; 45 private String mNegativeCross = null; 46 private String mPositiveCross = null; 47 private int mTriggerID = UNSET; 48 private int mTriggerCollisionId = UNSET; 49 // TODO private MotionWidget mTriggerCollisionView = null; 50 float mTriggerSlack = .1f; 51 private boolean mFireCrossReset = true; 52 private boolean mFireNegativeReset = true; 53 private boolean mFirePositiveReset = true; 54 private float mFireThreshold = Float.NaN; 55 private float mFireLastPos; 56 private boolean mPostLayout = false; 57 int mViewTransitionOnNegativeCross = UNSET; 58 int mViewTransitionOnPositiveCross = UNSET; 59 int mViewTransitionOnCross = UNSET; 60 61 public static final int TYPE_VIEW_TRANSITION_ON_CROSS = 301; 62 public static final int TYPE_VIEW_TRANSITION_ON_POSITIVE_CROSS = 302; 63 public static final int TYPE_VIEW_TRANSITION_ON_NEGATIVE_CROSS = 303; 64 public static final int TYPE_POST_LAYOUT = 304; 65 public static final int TYPE_TRIGGER_SLACK = 305; 66 public static final int TYPE_TRIGGER_COLLISION_VIEW = 306; 67 public static final int TYPE_TRIGGER_COLLISION_ID = 307; 68 public static final int TYPE_TRIGGER_ID = 308; 69 public static final int TYPE_POSITIVE_CROSS = 309; 70 public static final int TYPE_NEGATIVE_CROSS = 310; 71 public static final int TYPE_TRIGGER_RECEIVER = 311; 72 public static final int TYPE_CROSS = 312; 73 74 FloatRect mCollisionRect = new FloatRect(); 75 FloatRect mTargetRect = new FloatRect(); 76 public static final int KEY_TYPE = 5; 77 78 { 79 mType = KEY_TYPE; 80 mCustom = new HashMap<>(); 81 } 82 83 @Override getAttributeNames(HashSet<String> attributes)84 public void getAttributeNames(HashSet<String> attributes) { 85 86 } 87 88 @Override addValues(HashMap<String, SplineSet> splines)89 public void addValues(HashMap<String, SplineSet> splines) { 90 91 } 92 93 @Override getId(String name)94 public int getId(String name) { 95 switch (name) { 96 case VIEW_TRANSITION_ON_CROSS: 97 return TYPE_VIEW_TRANSITION_ON_CROSS; 98 case VIEW_TRANSITION_ON_POSITIVE_CROSS: 99 return TYPE_VIEW_TRANSITION_ON_POSITIVE_CROSS; 100 case VIEW_TRANSITION_ON_NEGATIVE_CROSS: 101 return TYPE_VIEW_TRANSITION_ON_NEGATIVE_CROSS; 102 case POST_LAYOUT: 103 return TYPE_POST_LAYOUT; 104 case TRIGGER_SLACK: 105 return TYPE_TRIGGER_SLACK; 106 case TRIGGER_COLLISION_VIEW: 107 return TYPE_TRIGGER_COLLISION_VIEW; 108 case TRIGGER_COLLISION_ID: 109 return TYPE_TRIGGER_COLLISION_ID; 110 case TRIGGER_ID: 111 return TYPE_TRIGGER_ID; 112 case POSITIVE_CROSS: 113 return TYPE_POSITIVE_CROSS; 114 case NEGATIVE_CROSS: 115 return TYPE_NEGATIVE_CROSS; 116 case TRIGGER_RECEIVER: 117 return TYPE_TRIGGER_RECEIVER; 118 } 119 return -1; 120 } 121 122 // @TODO: add description 123 @Override copy(MotionKey src)124 public MotionKeyTrigger copy(MotionKey src) { 125 super.copy(src); 126 MotionKeyTrigger k = (MotionKeyTrigger) src; 127 mCurveFit = k.mCurveFit; 128 mCross = k.mCross; 129 mTriggerReceiver = k.mTriggerReceiver; 130 mNegativeCross = k.mNegativeCross; 131 mPositiveCross = k.mPositiveCross; 132 mTriggerID = k.mTriggerID; 133 mTriggerCollisionId = k.mTriggerCollisionId; 134 // TODO mTriggerCollisionView = k.mTriggerCollisionView; 135 mTriggerSlack = k.mTriggerSlack; 136 mFireCrossReset = k.mFireCrossReset; 137 mFireNegativeReset = k.mFireNegativeReset; 138 mFirePositiveReset = k.mFirePositiveReset; 139 mFireThreshold = k.mFireThreshold; 140 mFireLastPos = k.mFireLastPos; 141 mPostLayout = k.mPostLayout; 142 mCollisionRect = k.mCollisionRect; 143 mTargetRect = k.mTargetRect; 144 return this; 145 } 146 147 // @TODO: add description 148 @Override clone()149 public MotionKey clone() { 150 return new MotionKeyTrigger().copy(this); 151 } 152 153 @SuppressWarnings("unused") fireCustom(String str, MotionWidget widget)154 private void fireCustom(String str, MotionWidget widget) { 155 boolean callAll = str.length() == 1; 156 if (!callAll) { 157 str = str.substring(1).toLowerCase(Locale.ROOT); 158 } 159 for (String name : mCustom.keySet()) { 160 String lowerCase = name.toLowerCase(Locale.ROOT); 161 if (callAll || lowerCase.matches(str)) { 162 CustomVariable custom = mCustom.get(name); 163 if (custom != null) { 164 custom.applyToWidget(widget); 165 } 166 } 167 } 168 } 169 170 // @TODO: add description conditionallyFire(float position, MotionWidget child)171 public void conditionallyFire(float position, MotionWidget child) { 172 } 173 174 // @TODO: add description 175 @Override setValue(int type, int value)176 public boolean setValue(int type, int value) { 177 switch (type) { 178 case TriggerType.TYPE_TRIGGER_RECEIVER: 179 mTriggerReceiver = value; 180 break; 181 case TriggerType.TYPE_TRIGGER_ID: 182 mTriggerID = toInt(value); 183 break; 184 case TriggerType.TYPE_TRIGGER_COLLISION_ID: 185 mTriggerCollisionId = value; 186 break; 187 case TriggerType.TYPE_VIEW_TRANSITION_ON_NEGATIVE_CROSS: 188 mViewTransitionOnNegativeCross = value; 189 break; 190 case TriggerType.TYPE_VIEW_TRANSITION_ON_POSITIVE_CROSS: 191 mViewTransitionOnPositiveCross = value; 192 break; 193 194 case TriggerType.TYPE_VIEW_TRANSITION_ON_CROSS: 195 mViewTransitionOnCross = value; 196 break; 197 default: 198 return super.setValue(type, value); 199 } 200 return true; 201 } 202 203 // @TODO: add description 204 @Override setValue(int type, float value)205 public boolean setValue(int type, float value) { 206 switch (type) { 207 case TriggerType.TYPE_TRIGGER_SLACK: 208 mTriggerSlack = value; 209 break; 210 default: 211 return super.setValue(type, value); 212 } 213 return true; 214 } 215 216 // @TODO: add description 217 @Override setValue(int type, String value)218 public boolean setValue(int type, String value) { 219 switch (type) { 220 case TriggerType.TYPE_CROSS: 221 mCross = value; 222 break; 223 case TriggerType.TYPE_NEGATIVE_CROSS: 224 mNegativeCross = value; 225 break; 226 case TriggerType.TYPE_POSITIVE_CROSS: 227 mPositiveCross = value; 228 break; 229 // TODO 230 // case TRIGGER_COLLISION_VIEW: 231 // mTriggerCollisionView = (MotionWidget) value; 232 // break; 233 234 default: 235 236 return super.setValue(type, value); 237 } 238 return true; 239 } 240 241 // @TODO: add description 242 @Override setValue(int type, boolean value)243 public boolean setValue(int type, boolean value) { 244 switch (type) { 245 case TriggerType.TYPE_POST_LAYOUT: 246 mPostLayout = value; 247 break; 248 default: 249 return super.setValue(type, value); 250 } 251 return true; 252 } 253 254 255 } 256