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.core.motion;
18 
19 import androidx.constraintlayout.core.motion.utils.TypedValues;
20 import androidx.constraintlayout.core.state.WidgetFrame;
21 import androidx.constraintlayout.core.widgets.ConstraintWidget;
22 
23 import java.util.Set;
24 
25 public class MotionWidget implements TypedValues {
26     WidgetFrame mWidgetFrame = new WidgetFrame();
27     Motion mMotion = new Motion();
28     PropertySet mPropertySet = new PropertySet();
29     private float mProgress;
30     float mTransitionPathRotate;
31 
32     public static final int VISIBILITY_MODE_NORMAL = 0;
33     public static final int VISIBILITY_MODE_IGNORE = 1;
34     @SuppressWarnings("unused") private static final int INTERNAL_MATCH_PARENT = -1;
35     @SuppressWarnings("unused") private static final int INTERNAL_WRAP_CONTENT = -2;
36     public static final int INVISIBLE = 0;
37     public static final int VISIBLE = 4;
38     @SuppressWarnings("unused") private static final int INTERNAL_MATCH_CONSTRAINT = -3;
39     @SuppressWarnings("unused") private static final int INTERNAL_WRAP_CONTENT_CONSTRAINED = -4;
40 
41     public static final int ROTATE_NONE = 0;
42     public static final int ROTATE_PORTRATE_OF_RIGHT = 1;
43     public static final int ROTATE_PORTRATE_OF_LEFT = 2;
44     public static final int ROTATE_RIGHT_OF_PORTRATE = 3;
45     public static final int ROTATE_LEFT_OF_PORTRATE = 4;
46     public static final int UNSET = -1;
47     public static final int MATCH_CONSTRAINT = 0;
48     public static final int PARENT_ID = 0;
49     public static final int FILL_PARENT = -1;
50     public static final int MATCH_PARENT = -1;
51     public static final int WRAP_CONTENT = -2;
52     public static final int GONE_UNSET = Integer.MIN_VALUE;
53     public static final int MATCH_CONSTRAINT_WRAP = ConstraintWidget.MATCH_CONSTRAINT_WRAP;
54 
55 
56     /**
57      *
58      */
59     public static class Motion {
60         public String mAnimateRelativeTo = null;
61         public int mAnimateCircleAngleTo = 0;
62         public String mTransitionEasing = null;
63         public int mPathMotionArc = UNSET;
64         public int mDrawPath = 0;
65         public float mMotionStagger = Float.NaN;
66         public int mPolarRelativeTo = UNSET;
67         public float mPathRotate = Float.NaN;
68         public float mQuantizeMotionPhase = Float.NaN;
69         public int mQuantizeMotionSteps = UNSET;
70         public String mQuantizeInterpolatorString = null;
71         public int mQuantizeInterpolatorType = INTERPOLATOR_UNDEFINED; // undefined
72         public int mQuantizeInterpolatorID = -1;
73         @SuppressWarnings("unused") private static final int INTERPOLATOR_REFERENCE_ID = -2;
74         @SuppressWarnings("unused") private static final int SPLINE_STRING = -1;
75         private static final int INTERPOLATOR_UNDEFINED = -3;
76     }
77 
78     public static class PropertySet {
79         public int visibility = VISIBLE;
80         public int mVisibilityMode = VISIBILITY_MODE_NORMAL;
81         public float alpha = 1;
82         public float mProgress = Float.NaN;
83     }
84 
MotionWidget()85     public MotionWidget() {
86 
87     }
88 
getParent()89     public MotionWidget getParent() {
90         return null;
91     }
92 
93     // @TODO: add description
findViewById(int mTransformPivotTarget)94     public MotionWidget findViewById(int mTransformPivotTarget) {
95         return null;
96     }
97 
setVisibility(int visibility)98     public void setVisibility(int visibility) {
99         mPropertySet.visibility = visibility;
100     }
101 
getName()102     public String getName() {
103         return mWidgetFrame.getId();
104     }
105 
106     // @TODO: add description
layout(int l, int t, int r, int b)107     public void layout(int l, int t, int r, int b) {
108         setBounds(l, t, r, b);
109     }
110 
111     // @TODO: add description
112     @Override
toString()113     public String toString() {
114         return mWidgetFrame.left + ", " + mWidgetFrame.top + ", "
115                 + mWidgetFrame.right + ", " + mWidgetFrame.bottom;
116     }
117 
118     // @TODO: add description
setBounds(int left, int top, int right, int bottom)119     public void setBounds(int left, int top, int right, int bottom) {
120         if (mWidgetFrame == null) {
121             mWidgetFrame = new WidgetFrame((ConstraintWidget) null);
122         }
123         mWidgetFrame.top = top;
124         mWidgetFrame.left = left;
125         mWidgetFrame.right = right;
126         mWidgetFrame.bottom = bottom;
127     }
128 
MotionWidget(WidgetFrame f)129     public MotionWidget(WidgetFrame f) {
130         mWidgetFrame = f;
131     }
132 
133     /**
134      * This populates the motion attributes from widgetFrame to the MotionWidget
135      */
updateMotion(TypedValues toUpdate)136     public void updateMotion(TypedValues toUpdate) {
137         if (mWidgetFrame.getMotionProperties() != null) {
138             mWidgetFrame.getMotionProperties().applyDelta(toUpdate);
139         }
140     }
141 
142     @Override
setValue(int id, int value)143     public boolean setValue(int id, int value) {
144         boolean set = setValueAttributes(id, value);
145         if (set) {
146             return true;
147         }
148         return setValueMotion(id, value);
149     }
150 
151     @Override
setValue(int id, float value)152     public boolean setValue(int id, float value) {
153         boolean set = setValueAttributes(id, value);
154         if (set) {
155             return true;
156         }
157         return setValueMotion(id, value);
158     }
159 
160     @Override
setValue(int id, String value)161     public boolean setValue(int id, String value) {
162         if (id == MotionType.TYPE_ANIMATE_RELATIVE_TO) {
163             mMotion.mAnimateRelativeTo = value;
164             return true;
165         }
166         return setValueMotion(id, value);
167     }
168 
169     @Override
setValue(int id, boolean value)170     public boolean setValue(int id, boolean value) {
171         return false;
172     }
173 
174     // @TODO: add description
setValueMotion(int id, int value)175     public boolean setValueMotion(int id, int value) {
176         switch (id) {
177             case MotionType.TYPE_ANIMATE_CIRCLEANGLE_TO:
178                 mMotion.mAnimateCircleAngleTo = value;
179                 break;
180             case MotionType.TYPE_PATHMOTION_ARC:
181                 mMotion.mPathMotionArc = value;
182                 break;
183             case MotionType.TYPE_DRAW_PATH:
184                 mMotion.mDrawPath = value;
185                 break;
186             case MotionType.TYPE_POLAR_RELATIVETO:
187                 mMotion.mPolarRelativeTo = value;
188                 break;
189             case MotionType.TYPE_QUANTIZE_MOTIONSTEPS:
190                 mMotion.mQuantizeMotionSteps = value;
191                 break;
192             case MotionType.TYPE_QUANTIZE_INTERPOLATOR_TYPE:
193                 mMotion.mQuantizeInterpolatorType = value;
194                 break; // undefined
195             case MotionType.TYPE_QUANTIZE_INTERPOLATOR_ID:
196                 mMotion.mQuantizeInterpolatorID = value;
197                 break;
198             default:
199                 return false;
200         }
201         return true;
202     }
203 
204     // @TODO: add description
setValueMotion(int id, String value)205     public boolean setValueMotion(int id, String value) {
206         switch (id) {
207 
208             case MotionType.TYPE_EASING:
209                 mMotion.mTransitionEasing = value;
210                 break;
211             case MotionType.TYPE_QUANTIZE_INTERPOLATOR:
212                 mMotion.mQuantizeInterpolatorString = value;
213                 break;
214             default:
215                 return false;
216         }
217         return true;
218     }
219 
220     // @TODO: add description
setValueMotion(int id, float value)221     public boolean setValueMotion(int id, float value) {
222         switch (id) {
223             case MotionType.TYPE_STAGGER:
224                 mMotion.mMotionStagger = value;
225                 break;
226             case MotionType.TYPE_PATH_ROTATE:
227                 mMotion.mPathRotate = value;
228                 break;
229             case MotionType.TYPE_QUANTIZE_MOTION_PHASE:
230                 mMotion.mQuantizeMotionPhase = value;
231                 break;
232             default:
233                 return false;
234         }
235         return true;
236     }
237 
238     /**
239      * Sets the attributes
240      */
setValueAttributes(int id, float value)241     public boolean setValueAttributes(int id, float value) {
242         switch (id) {
243             case AttributesType.TYPE_ALPHA:
244                 mWidgetFrame.alpha = value;
245                 break;
246             case AttributesType.TYPE_TRANSLATION_X:
247                 mWidgetFrame.translationX = value;
248                 break;
249             case AttributesType.TYPE_TRANSLATION_Y:
250                 mWidgetFrame.translationY = value;
251                 break;
252             case AttributesType.TYPE_TRANSLATION_Z:
253                 mWidgetFrame.translationZ = value;
254                 break;
255             case AttributesType.TYPE_ROTATION_X:
256                 mWidgetFrame.rotationX = value;
257                 break;
258             case AttributesType.TYPE_ROTATION_Y:
259                 mWidgetFrame.rotationY = value;
260                 break;
261             case AttributesType.TYPE_ROTATION_Z:
262                 mWidgetFrame.rotationZ = value;
263                 break;
264             case AttributesType.TYPE_SCALE_X:
265                 mWidgetFrame.scaleX = value;
266                 break;
267             case AttributesType.TYPE_SCALE_Y:
268                 mWidgetFrame.scaleY = value;
269                 break;
270             case AttributesType.TYPE_PIVOT_X:
271                 mWidgetFrame.pivotX = value;
272                 break;
273             case AttributesType.TYPE_PIVOT_Y:
274                 mWidgetFrame.pivotY = value;
275                 break;
276             case AttributesType.TYPE_PROGRESS:
277                 mProgress = value;
278                 break;
279             case AttributesType.TYPE_PATH_ROTATE:
280                 mTransitionPathRotate = value;
281                 break;
282             default:
283                 return false;
284         }
285         return true;
286     }
287 
288     /**
289      * Sets the attributes
290      */
getValueAttributes(int id)291     public float getValueAttributes(int id) {
292         switch (id) {
293             case AttributesType.TYPE_ALPHA:
294                 return mWidgetFrame.alpha;
295             case AttributesType.TYPE_TRANSLATION_X:
296                 return mWidgetFrame.translationX;
297             case AttributesType.TYPE_TRANSLATION_Y:
298                 return mWidgetFrame.translationY;
299             case AttributesType.TYPE_TRANSLATION_Z:
300                 return mWidgetFrame.translationZ;
301             case AttributesType.TYPE_ROTATION_X:
302                 return mWidgetFrame.rotationX;
303             case AttributesType.TYPE_ROTATION_Y:
304                 return mWidgetFrame.rotationY;
305             case AttributesType.TYPE_ROTATION_Z:
306                 return mWidgetFrame.rotationZ;
307             case AttributesType.TYPE_SCALE_X:
308                 return mWidgetFrame.scaleX;
309             case AttributesType.TYPE_SCALE_Y:
310                 return mWidgetFrame.scaleY;
311             case AttributesType.TYPE_PIVOT_X:
312                 return mWidgetFrame.pivotX;
313             case AttributesType.TYPE_PIVOT_Y:
314                 return mWidgetFrame.pivotY;
315             case AttributesType.TYPE_PROGRESS:
316                 return mProgress;
317             case AttributesType.TYPE_PATH_ROTATE:
318                 return mTransitionPathRotate;
319             default:
320                 return Float.NaN;
321         }
322 
323     }
324 
325     @Override
getId(String name)326     public int getId(String name) {
327         int ret = AttributesType.getId(name);
328         if (ret != -1) {
329             return ret;
330         }
331         return MotionType.getId(name);
332     }
333 
getTop()334     public int getTop() {
335         return mWidgetFrame.top;
336     }
337 
getLeft()338     public int getLeft() {
339         return mWidgetFrame.left;
340     }
341 
getBottom()342     public int getBottom() {
343         return mWidgetFrame.bottom;
344     }
345 
getRight()346     public int getRight() {
347         return mWidgetFrame.right;
348     }
349 
setPivotX(float px)350     public void setPivotX(float px) {
351         mWidgetFrame.pivotX = px;
352     }
353 
setPivotY(float py)354     public void setPivotY(float py) {
355         mWidgetFrame.pivotY = py;
356     }
357 
getRotationX()358     public float getRotationX() {
359         return mWidgetFrame.rotationX;
360     }
361 
setRotationX(float rotationX)362     public void setRotationX(float rotationX) {
363         mWidgetFrame.rotationX = rotationX;
364     }
365 
getRotationY()366     public float getRotationY() {
367         return mWidgetFrame.rotationY;
368     }
369 
setRotationY(float rotationY)370     public void setRotationY(float rotationY) {
371         mWidgetFrame.rotationY = rotationY;
372     }
373 
getRotationZ()374     public float getRotationZ() {
375         return mWidgetFrame.rotationZ;
376     }
377 
setRotationZ(float rotationZ)378     public void setRotationZ(float rotationZ) {
379         mWidgetFrame.rotationZ = rotationZ;
380     }
381 
getTranslationX()382     public float getTranslationX() {
383         return mWidgetFrame.translationX;
384     }
385 
setTranslationX(float translationX)386     public void setTranslationX(float translationX) {
387         mWidgetFrame.translationX = translationX;
388     }
389 
getTranslationY()390     public float getTranslationY() {
391         return mWidgetFrame.translationY;
392     }
393 
setTranslationY(float translationY)394     public void setTranslationY(float translationY) {
395         mWidgetFrame.translationY = translationY;
396     }
397 
setTranslationZ(float tz)398     public void setTranslationZ(float tz) {
399         mWidgetFrame.translationZ = tz;
400     }
401 
getTranslationZ()402     public float getTranslationZ() {
403         return mWidgetFrame.translationZ;
404     }
405 
getScaleX()406     public float getScaleX() {
407         return mWidgetFrame.scaleX;
408     }
409 
setScaleX(float scaleX)410     public void setScaleX(float scaleX) {
411         mWidgetFrame.scaleX = scaleX;
412     }
413 
getScaleY()414     public float getScaleY() {
415         return mWidgetFrame.scaleY;
416     }
417 
setScaleY(float scaleY)418     public void setScaleY(float scaleY) {
419         mWidgetFrame.scaleY = scaleY;
420     }
421 
getVisibility()422     public int getVisibility() {
423         return mPropertySet.visibility;
424     }
425 
getPivotX()426     public float getPivotX() {
427         return mWidgetFrame.pivotX;
428     }
429 
getPivotY()430     public float getPivotY() {
431         return mWidgetFrame.pivotY;
432     }
433 
getAlpha()434     public float getAlpha() {
435         return mWidgetFrame.alpha;
436     }
437 
getX()438     public int getX() {
439         return mWidgetFrame.left;
440     }
441 
getY()442     public int getY() {
443         return mWidgetFrame.top;
444     }
445 
getWidth()446     public int getWidth() {
447         return mWidgetFrame.right - mWidgetFrame.left;
448     }
449 
getHeight()450     public int getHeight() {
451         return mWidgetFrame.bottom - mWidgetFrame.top;
452     }
453 
getWidgetFrame()454     public WidgetFrame getWidgetFrame() {
455         return mWidgetFrame;
456     }
457 
getCustomAttributeNames()458     public Set<String> getCustomAttributeNames() {
459         return mWidgetFrame.getCustomAttributeNames();
460     }
461 
462     // @TODO: add description
setCustomAttribute(String name, int type, float value)463     public void setCustomAttribute(String name, int type, float value) {
464         mWidgetFrame.setCustomAttribute(name, type, value);
465     }
466 
467     // @TODO: add description
setCustomAttribute(String name, int type, int value)468     public void setCustomAttribute(String name, int type, int value) {
469         mWidgetFrame.setCustomAttribute(name, type, value);
470     }
471 
472     // @TODO: add description
setCustomAttribute(String name, int type, boolean value)473     public void setCustomAttribute(String name, int type, boolean value) {
474         mWidgetFrame.setCustomAttribute(name, type, value);
475     }
476 
477     // @TODO: add description
setCustomAttribute(String name, int type, String value)478     public void setCustomAttribute(String name, int type, String value) {
479         mWidgetFrame.setCustomAttribute(name, type, value);
480     }
481 
482     // @TODO: add description
getCustomAttribute(String name)483     public CustomVariable getCustomAttribute(String name) {
484         return mWidgetFrame.getCustomAttribute(name);
485     }
486 
487     // @TODO: add description
setInterpolatedValue(CustomAttribute attribute, float[] mCache)488     public void setInterpolatedValue(CustomAttribute attribute, float[] mCache) {
489         mWidgetFrame.setCustomAttribute(attribute.mName, TypedValues.Custom.TYPE_FLOAT, mCache[0]);
490     }
491 
492 }
493