1 /*
2  * Copyright (C) 2014 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 android.graphics;
18 
19 import com.android.layoutlib.bridge.impl.DelegateManager;
20 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
21 
22 import libcore.util.NativeAllocationRegistry_Delegate;
23 
24 /**
25  * Delegate implementing the native methods of {@link RenderNode}
26  * <p/>
27  * Through the layoutlib_create tool, some native methods of RenderNode have been replaced by calls
28  * to methods of the same name in this delegate class.
29  *
30  * @see DelegateManager
31  */
32 public class RenderNode_Delegate {
33 
34 
35     // ---- delegate manager ----
36     private static final DelegateManager<RenderNode_Delegate> sManager =
37             new DelegateManager<RenderNode_Delegate>(RenderNode_Delegate.class);
38     private static long sFinalizer = -1;
39 
40     private float mLift;
41     private float mTranslationX;
42     private float mTranslationY;
43     private float mTranslationZ;
44     private float mRotation;
45     private float mScaleX = 1;
46     private float mScaleY = 1;
47     private float mPivotX;
48     private float mPivotY;
49     private boolean mPivotExplicitlySet;
50     private int mLeft;
51     private int mRight;
52     private int mTop;
53     private int mBottom;
54     @SuppressWarnings("UnusedDeclaration")
55     private String mName;
56 
57     @LayoutlibDelegate
nCreate(String name)58     /*package*/ static long nCreate(String name) {
59         RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate();
60         renderNodeDelegate.mName = name;
61         return sManager.addNewDelegate(renderNodeDelegate);
62     }
63 
64     @LayoutlibDelegate
nGetNativeFinalizer()65     /*package*/ static long nGetNativeFinalizer() {
66         synchronized (RenderNode_Delegate.class) {
67             if (sFinalizer == -1) {
68                 sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
69             }
70         }
71         return sFinalizer;
72     }
73 
74     @LayoutlibDelegate
nSetElevation(long renderNode, float lift)75     /*package*/ static boolean nSetElevation(long renderNode, float lift) {
76         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
77         if (delegate != null && delegate.mLift != lift) {
78             delegate.mLift = lift;
79             return true;
80         }
81         return false;
82     }
83 
84     @LayoutlibDelegate
nGetElevation(long renderNode)85     /*package*/ static float nGetElevation(long renderNode) {
86         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
87         if (delegate != null) {
88             return delegate.mLift;
89         }
90         return 0f;
91     }
92 
93     @LayoutlibDelegate
nSetTranslationX(long renderNode, float translationX)94     /*package*/ static boolean nSetTranslationX(long renderNode, float translationX) {
95         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
96         if (delegate != null && delegate.mTranslationX != translationX) {
97             delegate.mTranslationX = translationX;
98             return true;
99         }
100         return false;
101     }
102 
103     @LayoutlibDelegate
nGetTranslationX(long renderNode)104     /*package*/ static float nGetTranslationX(long renderNode) {
105         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
106         if (delegate != null) {
107             return delegate.mTranslationX;
108         }
109         return 0f;
110     }
111 
112     @LayoutlibDelegate
nSetTranslationY(long renderNode, float translationY)113     /*package*/ static boolean nSetTranslationY(long renderNode, float translationY) {
114         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
115         if (delegate != null && delegate.mTranslationY != translationY) {
116             delegate.mTranslationY = translationY;
117             return true;
118         }
119         return false;
120     }
121 
122     @LayoutlibDelegate
nGetTranslationY(long renderNode)123     /*package*/ static float nGetTranslationY(long renderNode) {
124         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
125         if (delegate != null) {
126             return delegate.mTranslationY;
127         }
128         return 0f;
129     }
130 
131     @LayoutlibDelegate
nSetTranslationZ(long renderNode, float translationZ)132     /*package*/ static boolean nSetTranslationZ(long renderNode, float translationZ) {
133         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
134         if (delegate != null && delegate.mTranslationZ != translationZ) {
135             delegate.mTranslationZ = translationZ;
136             return true;
137         }
138         return false;
139     }
140 
141     @LayoutlibDelegate
nGetTranslationZ(long renderNode)142     /*package*/ static float nGetTranslationZ(long renderNode) {
143         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
144         if (delegate != null) {
145             return delegate.mTranslationZ;
146         }
147         return 0f;
148     }
149 
150     @LayoutlibDelegate
nSetRotation(long renderNode, float rotation)151     /*package*/ static boolean nSetRotation(long renderNode, float rotation) {
152         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
153         if (delegate != null && delegate.mRotation != rotation) {
154             delegate.mRotation = rotation;
155             return true;
156         }
157         return false;
158     }
159 
160     @LayoutlibDelegate
nGetRotation(long renderNode)161     /*package*/ static float nGetRotation(long renderNode) {
162         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
163         if (delegate != null) {
164             return delegate.mRotation;
165         }
166         return 0f;
167     }
168 
169     @LayoutlibDelegate
getMatrix(RenderNode renderNode, Matrix outMatrix)170     /*package*/ static void getMatrix(RenderNode renderNode, Matrix outMatrix) {
171         outMatrix.reset();
172         if (renderNode != null) {
173             float rotation = renderNode.getRotationZ();
174             float translationX = renderNode.getTranslationX();
175             float translationY = renderNode.getTranslationY();
176             float pivotX = renderNode.getPivotX();
177             float pivotY = renderNode.getPivotY();
178             float scaleX = renderNode.getScaleX();
179             float scaleY = renderNode.getScaleY();
180 
181             outMatrix.setTranslate(translationX, translationY);
182             outMatrix.preRotate(rotation, pivotX, pivotY);
183             outMatrix.preScale(scaleX, scaleY, pivotX, pivotY);
184         }
185     }
186 
187     @LayoutlibDelegate
nSetLeft(long renderNode, int left)188     /*package*/ static boolean nSetLeft(long renderNode, int left) {
189         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
190         if (delegate != null && delegate.mLeft != left) {
191             delegate.mLeft = left;
192             return true;
193         }
194         return false;
195     }
196 
197     @LayoutlibDelegate
nSetTop(long renderNode, int top)198     /*package*/ static boolean nSetTop(long renderNode, int top) {
199         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
200         if (delegate != null && delegate.mTop != top) {
201             delegate.mTop = top;
202             return true;
203         }
204         return false;
205     }
206 
207     @LayoutlibDelegate
nSetRight(long renderNode, int right)208     /*package*/ static boolean nSetRight(long renderNode, int right) {
209         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
210         if (delegate != null && delegate.mRight != right) {
211             delegate.mRight = right;
212             return true;
213         }
214         return false;
215     }
216 
217     @LayoutlibDelegate
nSetBottom(long renderNode, int bottom)218     /*package*/ static boolean nSetBottom(long renderNode, int bottom) {
219         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
220         if (delegate != null && delegate.mBottom != bottom) {
221             delegate.mBottom = bottom;
222             return true;
223         }
224         return false;
225     }
226 
227     @LayoutlibDelegate
nSetLeftTopRightBottom(long renderNode, int left, int top, int right, int bottom)228     /*package*/ static boolean nSetLeftTopRightBottom(long renderNode, int left, int top, int right,
229             int bottom) {
230         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
231         if (delegate != null && (delegate.mLeft != left || delegate.mTop != top || delegate
232                 .mRight != right || delegate.mBottom != bottom)) {
233             delegate.mLeft = left;
234             delegate.mTop = top;
235             delegate.mRight = right;
236             delegate.mBottom = bottom;
237             return true;
238         }
239         return false;
240     }
241 
242     @LayoutlibDelegate
nIsPivotExplicitlySet(long renderNode)243     /*package*/ static boolean nIsPivotExplicitlySet(long renderNode) {
244         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
245         return delegate != null && delegate.mPivotExplicitlySet;
246     }
247 
248     @LayoutlibDelegate
nSetPivotX(long renderNode, float pivotX)249     /*package*/ static boolean nSetPivotX(long renderNode, float pivotX) {
250         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
251         if (delegate != null) {
252             delegate.mPivotX = pivotX;
253             delegate.mPivotExplicitlySet = true;
254             return true;
255         }
256         return false;
257     }
258 
259     @LayoutlibDelegate
nGetPivotX(long renderNode)260     /*package*/ static float nGetPivotX(long renderNode) {
261         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
262         if (delegate != null) {
263             if (delegate.mPivotExplicitlySet) {
264                 return delegate.mPivotX;
265             } else {
266                 return (delegate.mRight - delegate.mLeft) / 2.0f;
267             }
268         }
269         return 0f;
270     }
271 
272     @LayoutlibDelegate
nSetPivotY(long renderNode, float pivotY)273     /*package*/ static boolean nSetPivotY(long renderNode, float pivotY) {
274         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
275         if (delegate != null) {
276             delegate.mPivotY = pivotY;
277             delegate.mPivotExplicitlySet = true;
278             return true;
279         }
280         return false;
281     }
282 
283     @LayoutlibDelegate
nGetPivotY(long renderNode)284     /*package*/ static float nGetPivotY(long renderNode) {
285         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
286         if (delegate != null) {
287             if (delegate.mPivotExplicitlySet) {
288                 return delegate.mPivotY;
289             } else {
290                 return (delegate.mBottom - delegate.mTop) / 2.0f;
291             }
292         }
293         return 0f;
294     }
295 
296     @LayoutlibDelegate
nSetScaleX(long renderNode, float scaleX)297     /*package*/ static boolean nSetScaleX(long renderNode, float scaleX) {
298         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
299         if (delegate != null && delegate.mScaleX != scaleX) {
300             delegate.mScaleX = scaleX;
301             return true;
302         }
303         return false;
304     }
305 
306     @LayoutlibDelegate
nGetScaleX(long renderNode)307     /*package*/ static float nGetScaleX(long renderNode) {
308         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
309         if (delegate != null) {
310             return delegate.mScaleX;
311         }
312         return 0f;
313     }
314 
315     @LayoutlibDelegate
nSetScaleY(long renderNode, float scaleY)316     /*package*/ static boolean nSetScaleY(long renderNode, float scaleY) {
317         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
318         if (delegate != null && delegate.mScaleY != scaleY) {
319             delegate.mScaleY = scaleY;
320             return true;
321         }
322         return false;
323     }
324 
325     @LayoutlibDelegate
nGetScaleY(long renderNode)326     /*package*/ static float nGetScaleY(long renderNode) {
327         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
328         if (delegate != null) {
329             return delegate.mScaleY;
330         }
331         return 0f;
332     }
333 }
334