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