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