1 /*
2  * Copyright (C) 2020 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 com.android.wm.shell.animation
18 
19 import android.graphics.Rect
20 import android.graphics.RectF
21 import androidx.dynamicanimation.animation.FloatPropertyCompat
22 
23 /**
24  * Helpful extra properties to use with the [PhysicsAnimator]. These allow you to animate objects
25  * such as [Rect] and [RectF].
26  *
27  * There are additional, more basic properties available in [DynamicAnimation].
28  */
29 class FloatProperties {
30     companion object {
31         /**
32          * Represents the x-coordinate of a [Rect]. Typically used to animate moving a Rect
33          * horizontally.
34          *
35          * This property's getter returns [Rect.left], and its setter uses [Rect.offsetTo], which
36          * sets [Rect.left] to the new value and offsets [Rect.right] so that the width of the Rect
37          * does not change.
38          */
39         @JvmField
40         val RECT_X = object : FloatPropertyCompat<Rect>("RectX") {
41             override fun setValue(rect: Rect?, value: Float) {
42                 rect?.offsetTo(value.toInt(), rect.top)
43             }
44 
45             override fun getValue(rect: Rect?): Float {
46                 return rect?.left?.toFloat() ?: -Float.MAX_VALUE
47             }
48         }
49 
50         /**
51          * Represents the y-coordinate of a [Rect]. Typically used to animate moving a Rect
52          * vertically.
53          *
54          * This property's getter returns [Rect.top], and its setter uses [Rect.offsetTo], which
55          * sets [Rect.top] to the new value and offsets [Rect.bottom] so that the height of the Rect
56          * does not change.
57          */
58         @JvmField
59         val RECT_Y = object : FloatPropertyCompat<Rect>("RectY") {
60             override fun setValue(rect: Rect?, value: Float) {
61                 rect?.offsetTo(rect.left, value.toInt())
62             }
63 
64             override fun getValue(rect: Rect?): Float {
65                 return rect?.top?.toFloat() ?: -Float.MAX_VALUE
66             }
67         }
68 
69         /**
70          * Represents the width of a [Rect]. Typically used to animate resizing a Rect horizontally.
71          *
72          * This property's getter returns [Rect.width], and its setter changes the value of
73          * [Rect.right] by adding the animated width value to [Rect.left].
74          */
75         @JvmField
76         val RECT_WIDTH = object : FloatPropertyCompat<Rect>("RectWidth") {
77             override fun getValue(rect: Rect): Float {
78                 return rect.width().toFloat()
79             }
80 
81             override fun setValue(rect: Rect, value: Float) {
82                 rect.right = rect.left + value.toInt()
83             }
84         }
85 
86         /**
87          * Represents the height of a [Rect]. Typically used to animate resizing a Rect vertically.
88          *
89          * This property's getter returns [Rect.height], and its setter changes the value of
90          * [Rect.bottom] by adding the animated height value to [Rect.top].
91          */
92         @JvmField
93         val RECT_HEIGHT = object : FloatPropertyCompat<Rect>("RectHeight") {
94             override fun getValue(rect: Rect): Float {
95                 return rect.height().toFloat()
96             }
97 
98             override fun setValue(rect: Rect, value: Float) {
99                 rect.bottom = rect.top + value.toInt()
100             }
101         }
102 
103         /**
104          * Represents the x-coordinate of a [RectF]. Typically used to animate moving a RectF
105          * horizontally.
106          *
107          * This property's getter returns [RectF.left], and its setter uses [RectF.offsetTo], which
108          * sets [RectF.left] to the new value and offsets [RectF.right] so that the width of the
109          * RectF does not change.
110          */
111         @JvmField
112         val RECTF_X = object : FloatPropertyCompat<RectF>("RectFX") {
113             override fun setValue(rect: RectF?, value: Float) {
114                 rect?.offsetTo(value, rect.top)
115             }
116 
117             override fun getValue(rect: RectF?): Float {
118                 return rect?.left ?: -Float.MAX_VALUE
119             }
120         }
121 
122         /**
123          * Represents the y-coordinate of a [RectF]. Typically used to animate moving a RectF
124          * vertically.
125          *
126          * This property's getter returns [RectF.top], and its setter uses [RectF.offsetTo], which
127          * sets [RectF.top] to the new value and offsets [RectF.bottom] so that the height of the
128          * RectF does not change.
129          */
130         @JvmField
131         val RECTF_Y = object : FloatPropertyCompat<RectF>("RectFY") {
132             override fun setValue(rect: RectF?, value: Float) {
133                 rect?.offsetTo(rect.left, value)
134             }
135 
136             override fun getValue(rect: RectF?): Float {
137                 return rect?.top ?: -Float.MAX_VALUE
138             }
139         }
140     }
141 }