Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
ExtractStyle.java
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5package org.qtproject.qt.android;
6
7import android.annotation.SuppressLint;
8import android.content.Context;
9import android.content.res.ColorStateList;
10import android.content.res.Resources;
11import android.content.res.TypedArray;
12import android.content.res.XmlResourceParser;
13import android.graphics.Bitmap;
14import android.graphics.Bitmap.Config;
15import android.graphics.Canvas;
16import android.graphics.NinePatch;
17import android.graphics.Paint;
18import android.graphics.PorterDuff;
19import android.graphics.Rect;
20import android.graphics.drawable.AnimatedStateListDrawable;
21import android.graphics.drawable.AnimationDrawable;
22import android.graphics.drawable.BitmapDrawable;
23import android.graphics.drawable.ClipDrawable;
24import android.graphics.drawable.ColorDrawable;
25import android.graphics.drawable.Drawable;
26import android.graphics.drawable.GradientDrawable;
27import android.graphics.drawable.GradientDrawable.Orientation;
28import android.graphics.drawable.InsetDrawable;
29import android.graphics.drawable.LayerDrawable;
30import android.graphics.drawable.NinePatchDrawable;
31import android.graphics.drawable.RippleDrawable;
32import android.graphics.drawable.RotateDrawable;
33import android.graphics.drawable.ScaleDrawable;
34import android.graphics.drawable.StateListDrawable;
35import android.graphics.drawable.VectorDrawable;
36import android.os.Build;
37import android.os.Bundle;
38import android.util.AttributeSet;
39import android.util.Log;
40import android.util.TypedValue;
41import android.util.Xml;
42import android.view.ContextThemeWrapper;
43import android.view.inputmethod.EditorInfo;
44
45import org.json.JSONArray;
46import org.json.JSONException;
47import org.json.JSONObject;
48import org.xmlpull.v1.XmlPullParser;
49
50import java.io.File;
51import java.io.FileNotFoundException;
52import java.io.FileOutputStream;
53import java.io.IOException;
54import java.io.OutputStreamWriter;
55import java.lang.reflect.Field;
56import java.util.ArrayList;
57import java.util.Arrays;
58import java.util.HashMap;
59import java.util.Map;
60import java.util.Objects;
61
62
63public class ExtractStyle {
64
65 // This used to be retrieved from android.R.styleable.ViewDrawableStates field via reflection,
66 // but since the access to that is restricted, we need to have hard-coded here.
67 final int[] viewDrawableStatesState = new int[]{
68 android.R.attr.state_focused,
69 android.R.attr.state_window_focused,
70 android.R.attr.state_enabled,
71 android.R.attr.state_selected,
72 android.R.attr.state_pressed,
73 android.R.attr.state_activated,
74 android.R.attr.state_accelerated,
75 android.R.attr.state_hovered,
76 android.R.attr.state_drag_can_accept,
77 android.R.attr.state_drag_hovered
78 };
79 final int[] EMPTY_STATE_SET = {};
80 final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled};
81 final int[] FOCUSED_STATE_SET = {android.R.attr.state_focused};
82 final int[] SELECTED_STATE_SET = {android.R.attr.state_selected};
83 final int[] PRESSED_STATE_SET = {android.R.attr.state_pressed};
84 final int[] WINDOW_FOCUSED_STATE_SET = {android.R.attr.state_window_focused};
85 final int[] ENABLED_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, FOCUSED_STATE_SET);
86 final int[] ENABLED_SELECTED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, SELECTED_STATE_SET);
87 final int[] ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
88 final int[] FOCUSED_SELECTED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, SELECTED_STATE_SET);
89 final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
90 final int[] SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
91 final int[] ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
92 final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
93 final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
94 final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
95 final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
96 final int[] PRESSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
97 final int[] PRESSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, SELECTED_STATE_SET);
98 final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
99 final int[] PRESSED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, FOCUSED_STATE_SET);
100 final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
101 final int[] PRESSED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
102 final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
103 final int[] PRESSED_ENABLED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, ENABLED_STATE_SET);
104 final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
105 final int[] PRESSED_ENABLED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, SELECTED_STATE_SET);
106 final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
107 final int[] PRESSED_ENABLED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, FOCUSED_STATE_SET);
108 final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
109 final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
110 final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
111 final Resources.Theme m_theme;
112 final String m_extractPath;
113 final int defaultBackgroundColor;
114 final int defaultTextColor;
115 final boolean m_minimal;
116 final int[] DrawableStates = { android.R.attr.state_active, android.R.attr.state_checked,
117 android.R.attr.state_enabled, android.R.attr.state_focused,
118 android.R.attr.state_pressed, android.R.attr.state_selected,
119 android.R.attr.state_window_focused, 16908288, android.R.attr.state_multiline,
120 android.R.attr.state_activated, android.R.attr.state_accelerated};
121 final String[] DrawableStatesLabels = {"active", "checked", "enabled", "focused", "pressed",
122 "selected", "window_focused", "background", "multiline", "activated", "accelerated"};
123 final String[] DisableDrawableStatesLabels = {"inactive", "unchecked", "disabled",
124 "not_focused", "no_pressed", "unselected", "window_not_focused", "background",
125 "multiline", "activated", "accelerated"};
126 final String[] sScaleTypeArray = {
127 "MATRIX",
128 "FIT_XY",
129 "FIT_START",
130 "FIT_CENTER",
131 "FIT_END",
132 "CENTER",
133 "CENTER_CROP",
134 "CENTER_INSIDE"
135 };
136 Context m_context;
137 private final HashMap<String, DrawableCache> m_drawableCache = new HashMap<>();
138
139 private static final String EXTRACT_STYLE_KEY = "extract.android.style";
140 private static final String EXTRACT_STYLE_MINIMAL_KEY = "extract.android.style.option";
141
142 private static boolean m_missingNormalStyle = false;
143 private static boolean m_missingDarkStyle = false;
144 private static String m_stylePath = null;
145 private static boolean m_extractMinimal = false;
146
147 public static void setup(Bundle loaderParams) {
148 if (loaderParams.containsKey(EXTRACT_STYLE_KEY)) {
149 m_stylePath = loaderParams.getString(EXTRACT_STYLE_KEY);
150
151 boolean darkModeFileMissing = !(new File(m_stylePath + "darkUiMode/style.json").exists());
152 m_missingDarkStyle = Build.VERSION.SDK_INT > 28 && darkModeFileMissing;
153
154 m_missingNormalStyle = !(new File(m_stylePath + "style.json").exists());
155
156 m_extractMinimal = loaderParams.containsKey(EXTRACT_STYLE_MINIMAL_KEY) &&
157 loaderParams.getBoolean(EXTRACT_STYLE_MINIMAL_KEY);
158 }
159 }
160
161 public static void runIfNeeded(Context context, boolean extractDarkMode) {
162 if (m_stylePath == null)
163 return;
164 if (extractDarkMode) {
165 if (m_missingDarkStyle) {
166 new ExtractStyle(context, m_stylePath + "darkUiMode/", m_extractMinimal);
167 m_missingDarkStyle = false;
168 }
169 } else if (m_missingNormalStyle) {
170 new ExtractStyle(context, m_stylePath, m_extractMinimal);
171 m_missingNormalStyle = false;
172 }
173 }
174
175 public ExtractStyle(Context context, String extractPath, boolean minimal) {
176 m_minimal = minimal;
177 m_extractPath = extractPath + "/";
178 boolean dirCreated = new File(m_extractPath).mkdirs();
179 if (!dirCreated)
180 Log.w(QtNative.QtTAG, "Cannot create Android style directory.");
181 m_context = context;
182 m_theme = context.getTheme();
183 TypedArray array = m_theme.obtainStyledAttributes(new int[]{
184 android.R.attr.colorBackground,
185 android.R.attr.textColorPrimary,
186 android.R.attr.textColor
187 });
188 defaultBackgroundColor = array.getColor(0, 0);
189 int textColor = array.getColor(1, 0xFFFFFF);
190 if (textColor == 0xFFFFFF)
191 textColor = array.getColor(2, 0xFFFFFF);
192 defaultTextColor = textColor;
193 array.recycle();
194
195 try {
196 SimpleJsonWriter jsonWriter = new SimpleJsonWriter(m_extractPath + "style.json");
197 jsonWriter.beginObject();
198 try {
199 jsonWriter.name("defaultStyle").value(extractDefaultPalette());
200 extractWindow(jsonWriter);
201 jsonWriter.name("buttonStyle").value(extractTextAppearanceInformation(android.R.attr.buttonStyle, "QPushButton"));
202 jsonWriter.name("spinnerStyle").value(extractTextAppearanceInformation(android.R.attr.spinnerStyle, "QComboBox"));
203 extractProgressBar(jsonWriter, android.R.attr.progressBarStyleHorizontal, "progressBarStyleHorizontal", "QProgressBar");
204 extractProgressBar(jsonWriter, android.R.attr.progressBarStyleLarge, "progressBarStyleLarge", null);
205 extractProgressBar(jsonWriter, android.R.attr.progressBarStyleSmall, "progressBarStyleSmall", null);
206 extractProgressBar(jsonWriter, android.R.attr.progressBarStyle, "progressBarStyle", null);
207 extractAbsSeekBar(jsonWriter);
208 extractSwitch(jsonWriter);
209 extractCompoundButton(jsonWriter, android.R.attr.checkboxStyle, "checkboxStyle", "QCheckBox");
210 jsonWriter.name("editTextStyle").value(extractTextAppearanceInformation(android.R.attr.editTextStyle, "QLineEdit"));
211 extractCompoundButton(jsonWriter, android.R.attr.radioButtonStyle, "radioButtonStyle", "QRadioButton");
212 jsonWriter.name("textViewStyle").value(extractTextAppearanceInformation(android.R.attr.textViewStyle, "QWidget"));
213 jsonWriter.name("scrollViewStyle").value(extractTextAppearanceInformation(android.R.attr.scrollViewStyle, "QAbstractScrollArea"));
214 extractListView(jsonWriter);
215 jsonWriter.name("listSeparatorTextViewStyle").value(extractTextAppearanceInformation(android.R.attr.listSeparatorTextViewStyle, null));
216 extractItemsStyle(jsonWriter);
217 extractCompoundButton(jsonWriter, android.R.attr.buttonStyleToggle, "buttonStyleToggle", null);
218 extractCalendar(jsonWriter);
219 extractToolBar(jsonWriter);
220 jsonWriter.name("actionButtonStyle").value(extractTextAppearanceInformation(android.R.attr.actionButtonStyle, "QToolButton"));
221 jsonWriter.name("actionBarTabTextStyle").value(extractTextAppearanceInformation(android.R.attr.actionBarTabTextStyle, null));
222 jsonWriter.name("actionBarTabStyle").value(extractTextAppearanceInformation(android.R.attr.actionBarTabStyle, null));
223 jsonWriter.name("actionOverflowButtonStyle").value(extractImageViewInformation(android.R.attr.actionOverflowButtonStyle, null));
224 extractTabBar(jsonWriter);
225 } catch (Exception e) {
226 e.printStackTrace();
227 }
228 jsonWriter.endObject();
229 jsonWriter.close();
230 } catch (Exception e) {
231 e.printStackTrace();
232 }
233 }
234
235 native static int[] extractNativeChunkInfo20(long nativeChunk);
236
237 private int[] stateSetUnion(final int[] stateSet1, final int[] stateSet2) {
238 try {
239 final int stateSet1Length = stateSet1.length;
240 final int stateSet2Length = stateSet2.length;
241 final int[] newSet = new int[stateSet1Length + stateSet2Length];
242 int k = 0;
243 int i = 0;
244 int j = 0;
245 // This is a merge of the two input state sets and assumes that the
246 // input sets are sorted by the order imposed by ViewDrawableStates.
247 for (int viewState : viewDrawableStatesState) {
248 if (i < stateSet1Length && stateSet1[i] == viewState) {
249 newSet[k++] = viewState;
250 i++;
251 } else if (j < stateSet2Length && stateSet2[j] == viewState) {
252 newSet[k++] = viewState;
253 j++;
254 }
255 assert k <= 1 || (newSet[k - 1] > newSet[k - 2]);
256 }
257 return newSet;
258 } catch (Exception e) {
259 e.printStackTrace();
260 }
261 return null;
262 }
263
264 Field getAccessibleField(Class<?> clazz, String fieldName) {
265 try {
266 Field f = clazz.getDeclaredField(fieldName);
267 f.setAccessible(true);
268 return f;
269 } catch (Exception e) {
270 e.printStackTrace();
271 }
272 return null;
273 }
274
275 Field tryGetAccessibleField(Class<?> clazz, String fieldName) {
276 if (clazz == null)
277 return null;
278
279 try {
280 Field f = clazz.getDeclaredField(fieldName);
281 f.setAccessible(true);
282 return f;
283 } catch (Exception e) {
284 for (Class<?> c : clazz.getInterfaces()) {
285 Field f = tryGetAccessibleField(c, fieldName);
286 if (f != null)
287 return f;
288 }
289 }
290 return tryGetAccessibleField(clazz.getSuperclass(), fieldName);
291 }
292
293 JSONObject getColorStateList(ColorStateList colorList) {
294 JSONObject json = new JSONObject();
295 try {
296 json.put("EMPTY_STATE_SET", colorList.getColorForState(EMPTY_STATE_SET, 0));
297 json.put("WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(WINDOW_FOCUSED_STATE_SET, 0));
298 json.put("SELECTED_STATE_SET", colorList.getColorForState(SELECTED_STATE_SET, 0));
299 json.put("SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
300 json.put("FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_STATE_SET, 0));
301 json.put("FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
302 json.put("FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_STATE_SET, 0));
303 json.put("FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
304 json.put("ENABLED_STATE_SET", colorList.getColorForState(ENABLED_STATE_SET, 0));
305 json.put("ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_WINDOW_FOCUSED_STATE_SET, 0));
306 json.put("ENABLED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_STATE_SET, 0));
307 json.put("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
308 json.put("ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_STATE_SET, 0));
309 json.put("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
310 json.put("ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_STATE_SET, 0));
311 json.put("ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
312 json.put("PRESSED_STATE_SET", colorList.getColorForState(PRESSED_STATE_SET, 0));
313 json.put("PRESSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_WINDOW_FOCUSED_STATE_SET, 0));
314 json.put("PRESSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_STATE_SET, 0));
315 json.put("PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
316 json.put("PRESSED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_STATE_SET, 0));
317 json.put("PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
318 json.put("PRESSED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_STATE_SET, 0));
319 json.put("PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
320 json.put("PRESSED_ENABLED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_STATE_SET, 0));
321 json.put("PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET, 0));
322 json.put("PRESSED_ENABLED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_STATE_SET, 0));
323 json.put("PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
324 json.put("PRESSED_ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_STATE_SET, 0));
325 json.put("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
326 json.put("PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, 0));
327 json.put("PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
328 } catch (JSONException e) {
329 e.printStackTrace();
330 }
331
332 return json;
333 }
334
335 JSONObject getStatesList(int[] states) throws JSONException {
336 JSONObject json = new JSONObject();
337 for (int s : states) {
338 boolean found = false;
339 for (int d = 0; d < DrawableStates.length; d++) {
340 if (s == DrawableStates[d]) {
341 json.put(DrawableStatesLabels[d], true);
342 found = true;
343 break;
344 } else if (s == -DrawableStates[d]) {
345 json.put(DrawableStatesLabels[d], false);
346
347 found = true;
348 break;
349 }
350 }
351 if (!found) {
352 json.put("unhandled_state_" + s, s > 0);
353 }
354 }
355 return json;
356 }
357
358 String getStatesName(int[] states) {
359 StringBuilder statesName = new StringBuilder();
360 for (int s : states) {
361 boolean found = false;
362 for (int d = 0; d < DrawableStates.length; d++) {
363 if (s == DrawableStates[d]) {
364 if (statesName.length() > 0)
365 statesName.append("__");
366 statesName.append(DrawableStatesLabels[d]);
367 found = true;
368 break;
369 } else if (s == -DrawableStates[d]) {
370 if (statesName.length() > 0)
371 statesName.append("__");
372 statesName.append(DisableDrawableStatesLabels[d]);
373 found = true;
374 break;
375 }
376 }
377 if (!found) {
378 if (statesName.length() > 0)
379 statesName.append(";");
380 statesName.append(s);
381 }
382 }
383 if (statesName.length() > 0)
384 return statesName.toString();
385 return "empty";
386 }
387
388 private JSONObject getLayerDrawable(Object drawable, String filename) {
389 JSONObject json = new JSONObject();
390 LayerDrawable layers = (LayerDrawable) drawable;
391 final int nr = layers.getNumberOfLayers();
392 try {
393 JSONArray array = new JSONArray();
394 for (int i = 0; i < nr; i++) {
395 int id = layers.getId(i);
396 if (id == -1)
397 id = i;
398 JSONObject layerJsonObject = getDrawable(layers.getDrawable(i), filename + "__" + id, null);
399 layerJsonObject.put("id", id);
400 array.put(layerJsonObject);
401 }
402 json.put("type", "layer");
403 Rect padding = new Rect();
404 if (layers.getPadding(padding))
405 json.put("padding", getJsonRect(padding));
406 json.put("layers", array);
407 } catch (JSONException e) {
408 e.printStackTrace();
409 }
410 return json;
411 }
412
413 private JSONObject getStateListDrawable(Object drawable, String filename) {
414 JSONObject json = new JSONObject();
415 try {
416 StateListDrawable stateList = (StateListDrawable) drawable;
417 JSONArray array = new JSONArray();
418 final int numStates;
419 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)
420 numStates = (Integer) StateListDrawable.class.getMethod("getStateCount").invoke(stateList);
421 else
422 numStates = stateList.getStateCount();
423 for (int i = 0; i < numStates; i++) {
424 JSONObject stateJson = new JSONObject();
425 final Drawable d = (Drawable) StateListDrawable.class.getMethod("getStateDrawable", Integer.TYPE).invoke(stateList, i);
426 final int[] states = (int[]) StateListDrawable.class.getMethod("getStateSet", Integer.TYPE).invoke(stateList, i);
427 if (states != null)
428 stateJson.put("states", getStatesList(states));
429 stateJson.put("drawable", getDrawable(d, filename + "__" + (states != null ? getStatesName(states) : ("state_pos_" + i)), null));
430 array.put(stateJson);
431 }
432 json.put("type", "stateslist");
433 Rect padding = new Rect();
434 if (stateList.getPadding(padding))
435 json.put("padding", getJsonRect(padding));
436 json.put("stateslist", array);
437 } catch (Exception e) {
438 e.printStackTrace();
439 }
440 return json;
441 }
442
443 private JSONObject getGradientDrawable(GradientDrawable drawable) {
444 JSONObject json = new JSONObject();
445 try {
446 json.put("type", "gradient");
447 Object obj = drawable.getConstantState();
448 Class<?> gradientStateClass = obj.getClass();
449 json.put("shape", gradientStateClass.getField("mShape").getInt(obj));
450 json.put("gradient", gradientStateClass.getField("mGradient").getInt(obj));
451 GradientDrawable.Orientation orientation = (Orientation) gradientStateClass.getField("mOrientation").get(obj);
452 if (orientation != null)
453 json.put("orientation", orientation.name());
454 int[] intArray = (int[]) gradientStateClass.getField("mGradientColors").get(obj);
455 if (intArray != null)
456 json.put("colors", getJsonArray(intArray, 0, intArray.length));
457 json.put("positions", getJsonArray((float[]) gradientStateClass.getField("mPositions").get(obj)));
458 json.put("strokeWidth", gradientStateClass.getField("mStrokeWidth").getInt(obj));
459 json.put("strokeDashWidth", gradientStateClass.getField("mStrokeDashWidth").getFloat(obj));
460 json.put("strokeDashGap", gradientStateClass.getField("mStrokeDashGap").getFloat(obj));
461 json.put("radius", gradientStateClass.getField("mRadius").getFloat(obj));
462 float[] floatArray = (float[]) gradientStateClass.getField("mRadiusArray").get(obj);
463 if (floatArray != null)
464 json.put("radiusArray", getJsonArray(floatArray));
465 Rect rc = (Rect) gradientStateClass.getField("mPadding").get(obj);
466 if (rc != null)
467 json.put("padding", getJsonRect(rc));
468 json.put("width", gradientStateClass.getField("mWidth").getInt(obj));
469 json.put("height", gradientStateClass.getField("mHeight").getInt(obj));
470 json.put("innerRadiusRatio", gradientStateClass.getField("mInnerRadiusRatio").getFloat(obj));
471 json.put("thicknessRatio", gradientStateClass.getField("mThicknessRatio").getFloat(obj));
472 json.put("innerRadius", gradientStateClass.getField("mInnerRadius").getInt(obj));
473 json.put("thickness", gradientStateClass.getField("mThickness").getInt(obj));
474 } catch (Exception e) {
475 e.printStackTrace();
476 }
477 return json;
478 }
479
480 private JSONObject getRotateDrawable(RotateDrawable drawable, String filename) {
481 JSONObject json = new JSONObject();
482 try {
483 json.put("type", "rotate");
484 Object obj = drawable.getConstantState();
485 Class<?> rotateStateClass = obj.getClass();
486 json.put("drawable", getDrawable(drawable.getClass().getMethod("getDrawable").invoke(drawable), filename, null));
487 json.put("pivotX", getAccessibleField(rotateStateClass, "mPivotX").getFloat(obj));
488 json.put("pivotXRel", getAccessibleField(rotateStateClass, "mPivotXRel").getBoolean(obj));
489 json.put("pivotY", getAccessibleField(rotateStateClass, "mPivotY").getFloat(obj));
490 json.put("pivotYRel", getAccessibleField(rotateStateClass, "mPivotYRel").getBoolean(obj));
491 json.put("fromDegrees", getAccessibleField(rotateStateClass, "mFromDegrees").getFloat(obj));
492 json.put("toDegrees", getAccessibleField(rotateStateClass, "mToDegrees").getFloat(obj));
493 } catch (Exception e) {
494 e.printStackTrace();
495 }
496 return json;
497 }
498
499 private JSONObject getAnimationDrawable(AnimationDrawable drawable, String filename) {
500 JSONObject json = new JSONObject();
501 try {
502 json.put("type", "animation");
503 json.put("oneshot", drawable.isOneShot());
504 final int count = drawable.getNumberOfFrames();
505 JSONArray frames = new JSONArray();
506 for (int i = 0; i < count; ++i) {
507 JSONObject frame = new JSONObject();
508 frame.put("duration", drawable.getDuration(i));
509 frame.put("drawable", getDrawable(drawable.getFrame(i), filename + "__" + i, null));
510 frames.put(frame);
511 }
512 json.put("frames", frames);
513 } catch (Exception e) {
514 e.printStackTrace();
515 }
516 return json;
517 }
518
519 private JSONObject getJsonRect(Rect rect) throws JSONException {
520 JSONObject jsonRect = new JSONObject();
521 jsonRect.put("left", rect.left);
522 jsonRect.put("top", rect.top);
523 jsonRect.put("right", rect.right);
524 jsonRect.put("bottom", rect.bottom);
525 return jsonRect;
526
527 }
528
529 private JSONArray getJsonArray(int[] array, int pos, int len) {
530 JSONArray a = new JSONArray();
531 final int l = pos + len;
532 for (int i = pos; i < l; i++)
533 a.put(array[i]);
534 return a;
535 }
536
537 private JSONArray getJsonArray(float[] array) throws JSONException {
538 JSONArray a = new JSONArray();
539 if (array != null)
540 for (float val : array)
541 a.put(val);
542 return a;
543 }
544
545 private JSONObject getJsonChunkInfo(int[] chunkData) throws JSONException {
546 JSONObject jsonRect = new JSONObject();
547 if (chunkData == null)
548 return jsonRect;
549
550 jsonRect.put("xdivs", getJsonArray(chunkData, 3, chunkData[0]));
551 jsonRect.put("ydivs", getJsonArray(chunkData, 3 + chunkData[0], chunkData[1]));
552 jsonRect.put("colors", getJsonArray(chunkData, 3 + chunkData[0] + chunkData[1], chunkData[2]));
553 return jsonRect;
554 }
555
556 private JSONObject findPatchesMarings(Drawable d) throws JSONException, IllegalAccessException {
557 NinePatch np;
558 Field f = tryGetAccessibleField(NinePatchDrawable.class, "mNinePatch");
559 if (f != null) {
560 np = (NinePatch) f.get(d);
561 } else {
562 Object state = getAccessibleField(NinePatchDrawable.class, "mNinePatchState").get(d);
563 np = (NinePatch) getAccessibleField(Objects.requireNonNull(state).getClass(), "mNinePatch").get(state);
564 }
565 return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(Objects.requireNonNull(np).getClass(), "mNativeChunk").getLong(np)));
566 }
567
568 private JSONObject getRippleDrawable(Object drawable, String filename, Rect padding) {
569 JSONObject json = getLayerDrawable(drawable, filename);
570 JSONObject ripple = new JSONObject();
571 try {
572 Class<?> rippleDrawableClass = Class.forName("android.graphics.drawable.RippleDrawable");
573 final Object mState = getAccessibleField(rippleDrawableClass, "mState").get(drawable);
574 ripple.put("mask", getDrawable((Drawable) getAccessibleField(rippleDrawableClass, "mMask").get(drawable), filename, padding));
575 if (mState != null) {
576 ripple.put("maxRadius", getAccessibleField(mState.getClass(), "mMaxRadius").getInt(mState));
577 ColorStateList color = (ColorStateList) getAccessibleField(mState.getClass(), "mColor").get(mState);
578 if (color != null)
579 ripple.put("color", getColorStateList(color));
580 }
581 json.put("ripple", ripple);
582 } catch (Exception e) {
583 e.printStackTrace();
584 }
585 return json;
586 }
587
588 private HashMap<Long, Long> getStateTransitions(Object sa) throws Exception {
589 HashMap<Long, Long> transitions = new HashMap<>();
590 final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa);
591 long[] keys = (long[]) getAccessibleField(sa.getClass(), "mKeys").get(sa);
592 long[] values = (long[]) getAccessibleField(sa.getClass(), "mValues").get(sa);
593 for (int i = 0; i < sz; i++) {
594 if (keys != null && values != null)
595 transitions.put(keys[i], values[i]);
596 }
597 return transitions;
598 }
599
600 private HashMap<Integer, Integer> getStateIds(Object sa) throws Exception {
601 HashMap<Integer, Integer> states = new HashMap<>();
602 final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa);
603 int[] keys = (int[]) getAccessibleField(sa.getClass(), "mKeys").get(sa);
604 int[] values = (int[]) getAccessibleField(sa.getClass(), "mValues").get(sa);
605 for (int i = 0; i < sz; i++) {
606 if (keys != null && values != null)
607 states.put(keys[i], values[i]);
608 }
609 return states;
610 }
611
612 private int findStateIndex(int id, HashMap<Integer, Integer> stateIds) {
613 for (Map.Entry<Integer, Integer> s : stateIds.entrySet()) {
614 if (id == s.getValue())
615 return s.getKey();
616 }
617 return -1;
618 }
619
620 private JSONObject getAnimatedStateListDrawable(Object drawable, String filename) {
621 JSONObject json = getStateListDrawable(drawable, filename);
622 try {
623 Class<?> animatedStateListDrawableClass = Class.forName("android.graphics.drawable.AnimatedStateListDrawable");
624 Object state = getAccessibleField(animatedStateListDrawableClass, "mState").get(drawable);
625
626 if (state != null) {
627 Class<?> stateClass = state.getClass();
628 HashMap<Integer, Integer> stateIds = getStateIds(Objects.requireNonNull(getAccessibleField(stateClass, "mStateIds").get(state)));
629 HashMap<Long, Long> transitions = getStateTransitions(Objects.requireNonNull(getAccessibleField(stateClass, "mTransitions").get(state)));
630
631 for (Map.Entry<Long, Long> t : transitions.entrySet()) {
632 final int toState = findStateIndex(t.getKey().intValue(), stateIds);
633 final int fromState = findStateIndex((int) (t.getKey() >> 32), stateIds);
634
635 JSONObject transition = new JSONObject();
636 transition.put("from", fromState);
637 transition.put("to", toState);
638 transition.put("reverse", (t.getValue() >> 32) != 0);
639
640 JSONArray stateslist = json.getJSONArray("stateslist");
641 JSONObject stateobj = stateslist.getJSONObject(t.getValue().intValue());
642 stateobj.put("transition", transition);
643 }
644 }
645 } catch (Exception e) {
646 e.printStackTrace();
647 }
648 return json;
649 }
650
651 private JSONObject getVPath(Object path) throws Exception {
652 JSONObject json = new JSONObject();
653 final Class<?> pathClass = path.getClass();
654 json.put("type", "path");
655 json.put("name", tryGetAccessibleField(pathClass, "mPathName").get(path));
656 Object[] mNodes = (Object[]) tryGetAccessibleField(pathClass, "mNodes").get(path);
657 JSONArray nodes = new JSONArray();
658 if (mNodes != null) {
659 for (Object n : mNodes) {
660 JSONObject node = new JSONObject();
661 node.put("type", String.valueOf(getAccessibleField(n.getClass(), "mType").getChar(n)));
662 node.put("params", getJsonArray((float[]) getAccessibleField(n.getClass(), "mParams").get(n)));
663 nodes.put(node);
664 }
665 json.put("nodes", nodes);
666 }
667 json.put("isClip", (Boolean) pathClass.getMethod("isClipPath").invoke(path));
668
669 if (tryGetAccessibleField(pathClass, "mStrokeColor") == null)
670 return json; // not VFullPath
671
672 json.put("strokeColor", getAccessibleField(pathClass, "mStrokeColor").getInt(path));
673 json.put("strokeWidth", getAccessibleField(pathClass, "mStrokeWidth").getFloat(path));
674 json.put("fillColor", getAccessibleField(pathClass, "mFillColor").getInt(path));
675 json.put("strokeAlpha", getAccessibleField(pathClass, "mStrokeAlpha").getFloat(path));
676 json.put("fillRule", getAccessibleField(pathClass, "mFillRule").getInt(path));
677 json.put("fillAlpha", getAccessibleField(pathClass, "mFillAlpha").getFloat(path));
678 json.put("trimPathStart", getAccessibleField(pathClass, "mTrimPathStart").getFloat(path));
679 json.put("trimPathEnd", getAccessibleField(pathClass, "mTrimPathEnd").getFloat(path));
680 json.put("trimPathOffset", getAccessibleField(pathClass, "mTrimPathOffset").getFloat(path));
681 json.put("strokeLineCap", (Paint.Cap) getAccessibleField(pathClass, "mStrokeLineCap").get(path));
682 json.put("strokeLineJoin", (Paint.Join) getAccessibleField(pathClass, "mStrokeLineJoin").get(path));
683 json.put("strokeMiterlimit", getAccessibleField(pathClass, "mStrokeMiterlimit").getFloat(path));
684 return json;
685 }
686
687 @SuppressWarnings("unchecked")
688 private JSONObject getVGroup(Object group) throws Exception {
689 JSONObject json = new JSONObject();
690 json.put("type", "group");
691 final Class<?> groupClass = group.getClass();
692 json.put("name", getAccessibleField(groupClass, "mGroupName").get(group));
693 json.put("rotate", getAccessibleField(groupClass, "mRotate").getFloat(group));
694 json.put("pivotX", getAccessibleField(groupClass, "mPivotX").getFloat(group));
695 json.put("pivotY", getAccessibleField(groupClass, "mPivotY").getFloat(group));
696 json.put("scaleX", getAccessibleField(groupClass, "mScaleX").getFloat(group));
697 json.put("scaleY", getAccessibleField(groupClass, "mScaleY").getFloat(group));
698 json.put("translateX", getAccessibleField(groupClass, "mTranslateX").getFloat(group));
699 json.put("translateY", getAccessibleField(groupClass, "mTranslateY").getFloat(group));
700
701 ArrayList<Object> mChildren = (ArrayList<Object>) getAccessibleField(groupClass, "mChildren").get(group);
702 JSONArray children = new JSONArray();
703 if (mChildren != null) {
704 for (Object c : mChildren) {
705 if (groupClass.isInstance(c))
706 children.put(getVGroup(c));
707 else
708 children.put(getVPath(c));
709 }
710 json.put("children", children);
711 }
712 return json;
713 }
714
715 private JSONObject getVectorDrawable(Object drawable) {
716 JSONObject json = new JSONObject();
717 try {
718 json.put("type", "vector");
719 Class<?> vectorDrawableClass = Class.forName("android.graphics.drawable.VectorDrawable");
720 final Object state = getAccessibleField(vectorDrawableClass, "mVectorState").get(drawable);
721 final Class<?> stateClass = Objects.requireNonNull(state).getClass();
722 final ColorStateList mTint = (ColorStateList) getAccessibleField(stateClass, "mTint").get(state);
723 if (mTint != null) {
724 json.put("tintList", getColorStateList(mTint));
725 json.put("tintMode", (PorterDuff.Mode) getAccessibleField(stateClass, "mTintMode").get(state));
726 }
727 final Object mVPathRenderer = getAccessibleField(stateClass, "mVPathRenderer").get(state);
728 final Class<?> VPathRendererClass = Objects.requireNonNull(mVPathRenderer).getClass();
729 json.put("baseWidth", getAccessibleField(VPathRendererClass, "mBaseWidth").getFloat(mVPathRenderer));
730 json.put("baseHeight", getAccessibleField(VPathRendererClass, "mBaseHeight").getFloat(mVPathRenderer));
731 json.put("viewportWidth", getAccessibleField(VPathRendererClass, "mViewportWidth").getFloat(mVPathRenderer));
732 json.put("viewportHeight", getAccessibleField(VPathRendererClass, "mViewportHeight").getFloat(mVPathRenderer));
733 json.put("rootAlpha", getAccessibleField(VPathRendererClass, "mRootAlpha").getInt(mVPathRenderer));
734 json.put("rootName", getAccessibleField(VPathRendererClass, "mRootName").get(mVPathRenderer));
735 json.put("rootGroup", getVGroup(Objects.requireNonNull(getAccessibleField(VPathRendererClass, "mRootGroup").get(mVPathRenderer))));
736 } catch (Exception e) {
737 e.printStackTrace();
738 }
739 return json;
740 }
741
742 public JSONObject getDrawable(Object drawable, String filename, Rect padding) {
743 if (drawable == null || m_minimal)
744 return null;
745
746 DrawableCache dc = m_drawableCache.get(filename);
747 if (dc != null) {
748 if (dc.drawable.equals(drawable))
749 return dc.object;
750 else
751 Log.e(QtNative.QtTAG, "Different drawable objects points to the same file name \"" + filename + "\"");
752 }
753 JSONObject json = new JSONObject();
754 Bitmap bmp = null;
755 if (drawable instanceof Bitmap)
756 bmp = (Bitmap) drawable;
757 else {
758 if (drawable instanceof BitmapDrawable) {
759 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
760 bmp = bitmapDrawable.getBitmap();
761 try {
762 json.put("gravity", bitmapDrawable.getGravity());
763 json.put("tileModeX", bitmapDrawable.getTileModeX());
764 json.put("tileModeY", bitmapDrawable.getTileModeY());
765 json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable));
766 json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable));
767 json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable));
768 ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable);
769 if (tintList != null)
770 json.put("tintList", getColorStateList(tintList));
771 } catch (Exception e) {
772 e.printStackTrace();
773 }
774 } else {
775
776 if (drawable instanceof RippleDrawable)
777 return getRippleDrawable(drawable, filename, padding);
778
779 if (drawable instanceof AnimatedStateListDrawable)
780 return getAnimatedStateListDrawable(drawable, filename);
781
782 if (drawable instanceof VectorDrawable)
783 return getVectorDrawable(drawable);
784
785 if (drawable instanceof ScaleDrawable) {
786 return getDrawable(((ScaleDrawable) drawable).getDrawable(), filename, null);
787 }
788 if (drawable instanceof LayerDrawable) {
789 return getLayerDrawable(drawable, filename);
790 }
791 if (drawable instanceof StateListDrawable) {
792 return getStateListDrawable(drawable, filename);
793 }
794 if (drawable instanceof GradientDrawable) {
795 return getGradientDrawable((GradientDrawable) drawable);
796 }
797 if (drawable instanceof RotateDrawable) {
798 return getRotateDrawable((RotateDrawable) drawable, filename);
799 }
800 if (drawable instanceof AnimationDrawable) {
801 return getAnimationDrawable((AnimationDrawable) drawable, filename);
802 }
803 if (drawable instanceof ClipDrawable) {
804 try {
805 json.put("type", "clipDrawable");
806 Drawable.ConstantState dcs = ((ClipDrawable) drawable).getConstantState();
807 json.put("drawable", getDrawable(getAccessibleField(dcs.getClass(), "mDrawable").get(dcs), filename, null));
808 if (null != padding)
809 json.put("padding", getJsonRect(padding));
810 else {
811 Rect _padding = new Rect();
812 if (((Drawable) drawable).getPadding(_padding))
813 json.put("padding", getJsonRect(_padding));
814 }
815 } catch (Exception e) {
816 e.printStackTrace();
817 }
818 return json;
819 }
820 if (drawable instanceof ColorDrawable) {
821 bmp = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
822 Drawable d = (Drawable) drawable;
823 d.setBounds(0, 0, 1, 1);
824 d.draw(new Canvas(bmp));
825 try {
826 json.put("type", "color");
827 json.put("color", bmp.getPixel(0, 0));
828 if (null != padding)
829 json.put("padding", getJsonRect(padding));
830 else {
831 Rect _padding = new Rect();
832 if (d.getPadding(_padding))
833 json.put("padding", getJsonRect(_padding));
834 }
835 } catch (JSONException e) {
836 e.printStackTrace();
837 }
838 return json;
839 }
840 if (drawable instanceof InsetDrawable) {
841 try {
842 InsetDrawable d = (InsetDrawable) drawable;
843 Object mInsetStateObject = getAccessibleField(InsetDrawable.class, "mState").get(d);
844 Rect _padding = new Rect();
845 boolean hasPadding = d.getPadding(_padding);
846 return getDrawable(getAccessibleField(Objects.requireNonNull(mInsetStateObject).getClass(), "mDrawable").get(mInsetStateObject), filename, hasPadding ? _padding : null);
847 } catch (Exception e) {
848 e.printStackTrace();
849 }
850 } else {
851 Drawable d = (Drawable) drawable;
852 int w = d.getIntrinsicWidth();
853 int h = d.getIntrinsicHeight();
854 d.setLevel(10000);
855 if (w < 1 || h < 1) {
856 w = 100;
857 h = 100;
858 }
859 bmp = Bitmap.createBitmap(w, h, Config.ARGB_8888);
860 d.setBounds(0, 0, w, h);
861 d.draw(new Canvas(bmp));
862 if (drawable instanceof NinePatchDrawable) {
863 NinePatchDrawable npd = (NinePatchDrawable) drawable;
864 try {
865 json.put("type", "9patch");
866 json.put("drawable", getDrawable(bmp, filename, null));
867 if (padding != null)
868 json.put("padding", getJsonRect(padding));
869 else {
870 Rect _padding = new Rect();
871 if (npd.getPadding(_padding))
872 json.put("padding", getJsonRect(_padding));
873 }
874
875 json.put("chunkInfo", findPatchesMarings(d));
876 return json;
877 } catch (Exception e) {
878 e.printStackTrace();
879 }
880 }
881 }
882 }
883 }
884 FileOutputStream out;
885 try {
886 filename = m_extractPath + filename + ".png";
887 out = new FileOutputStream(filename);
888 if (bmp != null)
889 bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
890 out.close();
891 } catch (IOException e) {
892 e.printStackTrace();
893 }
894 try {
895 json.put("type", "image");
896 json.put("path", filename);
897 if (bmp != null) {
898 json.put("width", bmp.getWidth());
899 json.put("height", bmp.getHeight());
900 }
901 m_drawableCache.put(filename, new DrawableCache(json, drawable));
902 } catch (JSONException e) {
903 e.printStackTrace();
904 }
905 return json;
906 }
907
908 private TypedArray obtainStyledAttributes(int styleName, int[] attributes)
909 {
910 TypedValue typedValue = new TypedValue();
911 Context ctx = new ContextThemeWrapper(m_context, m_theme);
912 ctx.getTheme().resolveAttribute(styleName, typedValue, true);
913 return ctx.obtainStyledAttributes(typedValue.data, attributes);
914 }
915
916 private ArrayList<Integer> getArrayListFromIntArray(int[] attributes) {
917 ArrayList<Integer> sortedAttrs = new ArrayList<>();
918 for (int attr : attributes)
919 sortedAttrs.add(attr);
920 return sortedAttrs;
921 }
922
923 public void extractViewInformation(int styleName, JSONObject json, String qtClassName) {
924 extractViewInformation(styleName, json, qtClassName, null);
925 }
926
927 public void extractViewInformation(int styleName, JSONObject json, String qtClassName, AttributeSet attributeSet) {
928 try {
929 TypedValue typedValue = new TypedValue();
930 Context ctx = new ContextThemeWrapper(m_context, m_theme);
931 ctx.getTheme().resolveAttribute(styleName, typedValue, true);
932
933 int[] attributes = new int[]{
934 android.R.attr.digits,
935 android.R.attr.background,
936 android.R.attr.padding,
937 android.R.attr.paddingLeft,
938 android.R.attr.paddingTop,
939 android.R.attr.paddingRight,
940 android.R.attr.paddingBottom,
941 android.R.attr.scrollX,
942 android.R.attr.scrollY,
943 android.R.attr.id,
944 android.R.attr.tag,
945 android.R.attr.fitsSystemWindows,
946 android.R.attr.focusable,
947 android.R.attr.focusableInTouchMode,
948 android.R.attr.clickable,
949 android.R.attr.longClickable,
950 android.R.attr.saveEnabled,
951 android.R.attr.duplicateParentState,
952 android.R.attr.visibility,
953 android.R.attr.drawingCacheQuality,
954 android.R.attr.contentDescription,
955 android.R.attr.soundEffectsEnabled,
956 android.R.attr.hapticFeedbackEnabled,
957 android.R.attr.scrollbars,
958 android.R.attr.fadingEdge,
959 android.R.attr.scrollbarStyle,
960 android.R.attr.scrollbarFadeDuration,
961 android.R.attr.scrollbarDefaultDelayBeforeFade,
962 android.R.attr.scrollbarSize,
963 android.R.attr.scrollbarThumbHorizontal,
964 android.R.attr.scrollbarThumbVertical,
965 android.R.attr.scrollbarTrackHorizontal,
966 android.R.attr.scrollbarTrackVertical,
967 android.R.attr.isScrollContainer,
968 android.R.attr.keepScreenOn,
969 android.R.attr.filterTouchesWhenObscured,
970 android.R.attr.nextFocusLeft,
971 android.R.attr.nextFocusRight,
972 android.R.attr.nextFocusUp,
973 android.R.attr.nextFocusDown,
974 android.R.attr.minWidth,
975 android.R.attr.minHeight,
976 android.R.attr.onClick,
977 android.R.attr.overScrollMode,
978 android.R.attr.paddingStart,
979 android.R.attr.paddingEnd,
980 };
981
982 // The array must be sorted in ascending order, otherwise obtainStyledAttributes()
983 // might fail to find some attributes
984 Arrays.sort(attributes);
985 TypedArray array;
986 if (attributeSet != null)
987 array = m_theme.obtainStyledAttributes(attributeSet, attributes, styleName, 0);
988 else
989 array = obtainStyledAttributes(styleName, attributes);
990 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
991
992 if (null != qtClassName)
993 json.put("qtClass", qtClassName);
994
995 json.put("defaultBackgroundColor", defaultBackgroundColor);
996 json.put("defaultTextColorPrimary", defaultTextColor);
997 json.put("TextView_digits", array.getText(sortedAttrs.indexOf(android.R.attr.digits)));
998 json.put("View_background", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.background)), styleName + "_View_background", null));
999 json.put("View_padding", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.padding), -1));
1000 json.put("View_paddingLeft", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.paddingLeft), -1));
1001 json.put("View_paddingTop", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.paddingTop), -1));
1002 json.put("View_paddingRight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.paddingRight), -1));
1003 json.put("View_paddingBottom", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.paddingBottom), -1));
1004 json.put("View_paddingBottom", array.getDimensionPixelOffset(sortedAttrs.indexOf(android.R.attr.scrollX), 0));
1005 json.put("View_scrollY", array.getDimensionPixelOffset(sortedAttrs.indexOf(android.R.attr.scrollY), 0));
1006 json.put("View_id", array.getResourceId(sortedAttrs.indexOf(android.R.attr.id), -1));
1007 json.put("View_tag", array.getText(sortedAttrs.indexOf(android.R.attr.tag)));
1008 json.put("View_fitsSystemWindows", array.getBoolean(sortedAttrs.indexOf(android.R.attr.fitsSystemWindows), false));
1009 json.put("View_focusable", array.getBoolean(sortedAttrs.indexOf(android.R.attr.focusable), false));
1010 json.put("View_focusableInTouchMode", array.getBoolean(sortedAttrs.indexOf(android.R.attr.focusableInTouchMode), false));
1011 json.put("View_clickable", array.getBoolean(sortedAttrs.indexOf(android.R.attr.clickable), false));
1012 json.put("View_longClickable", array.getBoolean(sortedAttrs.indexOf(android.R.attr.longClickable), false));
1013 json.put("View_saveEnabled", array.getBoolean(sortedAttrs.indexOf(android.R.attr.saveEnabled), true));
1014 json.put("View_duplicateParentState", array.getBoolean(sortedAttrs.indexOf(android.R.attr.duplicateParentState), false));
1015 json.put("View_visibility", array.getInt(sortedAttrs.indexOf(android.R.attr.visibility), 0));
1016 json.put("View_drawingCacheQuality", array.getInt(sortedAttrs.indexOf(android.R.attr.drawingCacheQuality), 0));
1017 json.put("View_contentDescription", array.getString(sortedAttrs.indexOf(android.R.attr.contentDescription)));
1018 json.put("View_soundEffectsEnabled", array.getBoolean(sortedAttrs.indexOf(android.R.attr.soundEffectsEnabled), true));
1019 json.put("View_hapticFeedbackEnabled", array.getBoolean(sortedAttrs.indexOf(android.R.attr.hapticFeedbackEnabled), true));
1020 json.put("View_scrollbars", array.getInt(sortedAttrs.indexOf(android.R.attr.scrollbars), 0));
1021 json.put("View_fadingEdge", array.getInt(sortedAttrs.indexOf(android.R.attr.fadingEdge), 0));
1022 json.put("View_scrollbarStyle", array.getInt(sortedAttrs.indexOf(android.R.attr.scrollbarStyle), 0));
1023 json.put("View_scrollbarFadeDuration", array.getInt(sortedAttrs.indexOf(android.R.attr.scrollbarFadeDuration), 0));
1024 json.put("View_scrollbarDefaultDelayBeforeFade", array.getInt(sortedAttrs.indexOf(android.R.attr.scrollbarDefaultDelayBeforeFade), 0));
1025 json.put("View_scrollbarSize", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.scrollbarSize), -1));
1026 json.put("View_scrollbarThumbHorizontal", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.scrollbarThumbHorizontal)), styleName + "_View_scrollbarThumbHorizontal", null));
1027 json.put("View_scrollbarThumbVertical", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.scrollbarThumbVertical)), styleName + "_View_scrollbarThumbVertical", null));
1028 json.put("View_scrollbarTrackHorizontal", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.scrollbarTrackHorizontal)), styleName + "_View_scrollbarTrackHorizontal", null));
1029 json.put("View_scrollbarTrackVertical", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.scrollbarTrackVertical)), styleName + "_View_scrollbarTrackVertical", null));
1030 json.put("View_isScrollContainer", array.getBoolean(sortedAttrs.indexOf(android.R.attr.isScrollContainer), false));
1031 json.put("View_keepScreenOn", array.getBoolean(sortedAttrs.indexOf(android.R.attr.keepScreenOn), false));
1032 json.put("View_filterTouchesWhenObscured", array.getBoolean(sortedAttrs.indexOf(android.R.attr.filterTouchesWhenObscured), false));
1033 json.put("View_nextFocusLeft", array.getResourceId(sortedAttrs.indexOf(android.R.attr.nextFocusLeft), -1));
1034 json.put("View_nextFocusRight", array.getResourceId(sortedAttrs.indexOf(android.R.attr.nextFocusRight), -1));
1035 json.put("View_nextFocusUp", array.getResourceId(sortedAttrs.indexOf(android.R.attr.nextFocusUp), -1));
1036 json.put("View_nextFocusDown", array.getResourceId(sortedAttrs.indexOf(android.R.attr.nextFocusDown), -1));
1037 json.put("View_minWidth", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.minWidth), 0));
1038 json.put("View_minHeight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.minHeight), 0));
1039 json.put("View_onClick", array.getString(sortedAttrs.indexOf(android.R.attr.onClick)));
1040 json.put("View_overScrollMode", array.getInt(sortedAttrs.indexOf(android.R.attr.overScrollMode), 1));
1041 json.put("View_paddingStart", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.paddingStart), 0));
1042 json.put("View_paddingEnd", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.paddingEnd), 0));
1043 array.recycle();
1044 } catch (Exception e) {
1045 e.printStackTrace();
1046 }
1047 }
1048
1049 public JSONObject extractTextAppearance(int styleName)
1050 {
1051 return extractTextAppearance(styleName, false);
1052 }
1053
1054 @SuppressLint("ResourceType")
1055 public JSONObject extractTextAppearance(int styleName, boolean subStyle)
1056 {
1057 final int[] attributes = new int[]{
1058 android.R.attr.textSize,
1059 android.R.attr.textStyle,
1060 android.R.attr.textColor,
1061 android.R.attr.typeface,
1062 android.R.attr.textAllCaps,
1063 android.R.attr.textColorHint,
1064 android.R.attr.textColorLink,
1065 android.R.attr.textColorHighlight
1066 };
1067 Arrays.sort(attributes);
1068 TypedArray array;
1069 if (subStyle)
1070 array = m_theme.obtainStyledAttributes(styleName, attributes);
1071 else
1072 array = obtainStyledAttributes(styleName, attributes);
1073 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1074 JSONObject json = new JSONObject();
1075 try {
1076 int attr = sortedAttrs.indexOf(android.R.attr.textSize);
1077 if (array.hasValue(attr))
1078 json.put("TextAppearance_textSize", array.getDimensionPixelSize(attr, 15));
1079 attr = sortedAttrs.indexOf(android.R.attr.textStyle);
1080 if (array.hasValue(attr))
1081 json.put("TextAppearance_textStyle", array.getInt(attr, -1));
1082 ColorStateList color = array.getColorStateList(sortedAttrs.indexOf(android.R.attr.textColor));
1083 if (color != null)
1084 json.put("TextAppearance_textColor", getColorStateList(color));
1085 attr = sortedAttrs.indexOf(android.R.attr.typeface);
1086 if (array.hasValue(attr))
1087 json.put("TextAppearance_typeface", array.getInt(attr, -1));
1088 attr = sortedAttrs.indexOf(android.R.attr.textAllCaps);
1089 if (array.hasValue(attr))
1090 json.put("TextAppearance_textAllCaps", array.getBoolean(attr, false));
1091 color = array.getColorStateList(sortedAttrs.indexOf(android.R.attr.textColorHint));
1092 if (color != null)
1093 json.put("TextAppearance_textColorHint", getColorStateList(color));
1094 color = array.getColorStateList(sortedAttrs.indexOf(android.R.attr.textColorLink));
1095 if (color != null)
1096 json.put("TextAppearance_textColorLink", getColorStateList(color));
1097 attr = sortedAttrs.indexOf(android.R.attr.textColorHighlight);
1098 if (array.hasValue(attr))
1099 json.put("TextAppearance_textColorHighlight", array.getColor(attr, 0));
1100 array.recycle();
1101 } catch (Exception e) {
1102 e.printStackTrace();
1103 }
1104 return json;
1105 }
1106
1107 public JSONObject extractTextAppearanceInformation(int styleName, String qtClass, AttributeSet attributeSet) {
1108 return extractTextAppearanceInformation(styleName, qtClass, android.R.attr.textAppearance, attributeSet);
1109 }
1110
1111 public JSONObject extractTextAppearanceInformation(int styleName, String qtClass) {
1112 return extractTextAppearanceInformation(styleName, qtClass, android.R.attr.textAppearance, null);
1113 }
1114
1115 public JSONObject extractTextAppearanceInformation(int styleName, String qtClass, int textAppearance, AttributeSet attributeSet) {
1116 JSONObject json = new JSONObject();
1117 extractViewInformation(styleName, json, qtClass, attributeSet);
1118
1119 if (textAppearance == -1)
1120 textAppearance = android.R.attr.textAppearance;
1121
1122 try {
1123 TypedValue typedValue = new TypedValue();
1124 Context ctx = new ContextThemeWrapper(m_context, m_theme);
1125 ctx.getTheme().resolveAttribute(styleName, typedValue, true);
1126
1127 // Get textAppearance values
1128 int[] textAppearanceAttr = new int[]{textAppearance};
1129 TypedArray textAppearanceArray = ctx.obtainStyledAttributes(typedValue.data, textAppearanceAttr);
1130 int textAppearanceId = textAppearanceArray.getResourceId(0, -1);
1131 textAppearanceArray.recycle();
1132
1133 int textSize = 15;
1134 int styleIndex = -1;
1135 int typefaceIndex = -1;
1136 int textColorHighlight = 0;
1137 boolean allCaps = false;
1138
1139 if (textAppearanceId != -1) {
1140 int[] attributes = new int[]{
1141 android.R.attr.textSize,
1142 android.R.attr.textStyle,
1143 android.R.attr.typeface,
1144 android.R.attr.textAllCaps,
1145 android.R.attr.textColorHighlight
1146 };
1147 Arrays.sort(attributes);
1148 TypedArray array = m_theme.obtainStyledAttributes(textAppearanceId, attributes);
1149 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1150
1151 textSize = array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.textSize), 15);
1152 styleIndex = array.getInt(sortedAttrs.indexOf(android.R.attr.textStyle), -1);
1153 typefaceIndex = array.getInt(sortedAttrs.indexOf(android.R.attr.typeface), -1);
1154 textColorHighlight = array.getColor(sortedAttrs.indexOf(android.R.attr.textColorHighlight), 0);
1155 allCaps = array.getBoolean(sortedAttrs.indexOf(android.R.attr.textAllCaps), false);
1156 array.recycle();
1157 }
1158 // Get TextView values
1159 int[] attributes = new int[]{
1160 android.R.attr.editable,
1161 android.R.attr.inputMethod,
1162 android.R.attr.numeric,
1163 android.R.attr.digits,
1164 android.R.attr.phoneNumber,
1165 android.R.attr.autoText,
1166 android.R.attr.capitalize,
1167 android.R.attr.bufferType,
1168 android.R.attr.selectAllOnFocus,
1169 android.R.attr.autoLink,
1170 android.R.attr.linksClickable,
1171 android.R.attr.drawableLeft,
1172 android.R.attr.drawableTop,
1173 android.R.attr.drawableRight,
1174 android.R.attr.drawableBottom,
1175 android.R.attr.drawableStart,
1176 android.R.attr.drawableEnd,
1177 android.R.attr.maxLines,
1178 android.R.attr.drawablePadding,
1179 android.R.attr.textCursorDrawable,
1180 android.R.attr.maxHeight,
1181 android.R.attr.lines,
1182 android.R.attr.height,
1183 android.R.attr.minLines,
1184 android.R.attr.minHeight,
1185 android.R.attr.maxEms,
1186 android.R.attr.maxWidth,
1187 android.R.attr.ems,
1188 android.R.attr.width,
1189 android.R.attr.minEms,
1190 android.R.attr.minWidth,
1191 android.R.attr.gravity,
1192 android.R.attr.hint,
1193 android.R.attr.text,
1194 android.R.attr.scrollHorizontally,
1195 android.R.attr.singleLine,
1196 android.R.attr.ellipsize,
1197 android.R.attr.marqueeRepeatLimit,
1198 android.R.attr.includeFontPadding,
1199 android.R.attr.cursorVisible,
1200 android.R.attr.maxLength,
1201 android.R.attr.textScaleX,
1202 android.R.attr.freezesText,
1203 android.R.attr.shadowColor,
1204 android.R.attr.shadowDx,
1205 android.R.attr.shadowDy,
1206 android.R.attr.shadowRadius,
1207 android.R.attr.enabled,
1208 android.R.attr.textColorHighlight,
1209 android.R.attr.textColor,
1210 android.R.attr.textColorHint,
1211 android.R.attr.textColorLink,
1212 android.R.attr.textSize,
1213 android.R.attr.typeface,
1214 android.R.attr.textStyle,
1215 android.R.attr.password,
1216 android.R.attr.lineSpacingExtra,
1217 android.R.attr.lineSpacingMultiplier,
1218 android.R.attr.inputType,
1219 android.R.attr.imeOptions,
1220 android.R.attr.imeActionLabel,
1221 android.R.attr.imeActionId,
1222 android.R.attr.privateImeOptions,
1223 android.R.attr.textSelectHandleLeft,
1224 android.R.attr.textSelectHandleRight,
1225 android.R.attr.textSelectHandle,
1226 android.R.attr.textIsSelectable,
1227 android.R.attr.textAllCaps
1228 };
1229
1230 // The array must be sorted in ascending order, otherwise obtainStyledAttributes()
1231 // might fail to find some attributes
1232 Arrays.sort(attributes);
1233 TypedArray array = ctx.obtainStyledAttributes(typedValue.data, attributes);
1234 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1235
1236 textSize = array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.textSize), textSize);
1237 styleIndex = array.getInt(sortedAttrs.indexOf(android.R.attr.textStyle), styleIndex);
1238 typefaceIndex = array.getInt(sortedAttrs.indexOf(android.R.attr.typeface), typefaceIndex);
1239 textColorHighlight = array.getColor(sortedAttrs.indexOf(android.R.attr.textColorHighlight), textColorHighlight);
1240 allCaps = array.getBoolean(sortedAttrs.indexOf(android.R.attr.textAllCaps), allCaps);
1241
1242 ColorStateList textColor = array.getColorStateList(sortedAttrs.indexOf(android.R.attr.textColor));
1243 ColorStateList textColorHint = array.getColorStateList(sortedAttrs.indexOf(android.R.attr.textColorHint));
1244 ColorStateList textColorLink = array.getColorStateList(sortedAttrs.indexOf(android.R.attr.textColorLink));
1245
1246 json.put("TextAppearance_textSize", textSize);
1247 json.put("TextAppearance_textStyle", styleIndex);
1248 json.put("TextAppearance_typeface", typefaceIndex);
1249 json.put("TextAppearance_textColorHighlight", textColorHighlight);
1250 json.put("TextAppearance_textAllCaps", allCaps);
1251 if (textColor != null)
1252 json.put("TextAppearance_textColor", getColorStateList(textColor));
1253 if (textColorHint != null)
1254 json.put("TextAppearance_textColorHint", getColorStateList(textColorHint));
1255 if (textColorLink != null)
1256 json.put("TextAppearance_textColorLink", getColorStateList(textColorLink));
1257
1258 json.put("TextView_editable", array.getBoolean(sortedAttrs.indexOf(android.R.attr.editable), false));
1259 json.put("TextView_inputMethod", array.getText(sortedAttrs.indexOf(android.R.attr.inputMethod)));
1260 json.put("TextView_numeric", array.getInt(sortedAttrs.indexOf(android.R.attr.numeric), 0));
1261 json.put("TextView_digits", array.getText(sortedAttrs.indexOf(android.R.attr.digits)));
1262 json.put("TextView_phoneNumber", array.getBoolean(sortedAttrs.indexOf(android.R.attr.phoneNumber), false));
1263 json.put("TextView_autoText", array.getBoolean(sortedAttrs.indexOf(android.R.attr.autoText), false));
1264 json.put("TextView_capitalize", array.getInt(sortedAttrs.indexOf(android.R.attr.capitalize), -1));
1265 json.put("TextView_bufferType", array.getInt(sortedAttrs.indexOf(android.R.attr.bufferType), 0));
1266 json.put("TextView_selectAllOnFocus", array.getBoolean(sortedAttrs.indexOf(android.R.attr.selectAllOnFocus), false));
1267 json.put("TextView_autoLink", array.getInt(sortedAttrs.indexOf(android.R.attr.autoLink), 0));
1268 json.put("TextView_linksClickable", array.getBoolean(sortedAttrs.indexOf(android.R.attr.linksClickable), true));
1269 json.put("TextView_drawableLeft", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.drawableLeft)), styleName + "_TextView_drawableLeft", null));
1270 json.put("TextView_drawableTop", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.drawableTop)), styleName + "_TextView_drawableTop", null));
1271 json.put("TextView_drawableRight", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.drawableRight)), styleName + "_TextView_drawableRight", null));
1272 json.put("TextView_drawableBottom", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.drawableBottom)), styleName + "_TextView_drawableBottom", null));
1273 json.put("TextView_drawableStart", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.drawableStart)), styleName + "_TextView_drawableStart", null));
1274 json.put("TextView_drawableEnd", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.drawableEnd)), styleName + "_TextView_drawableEnd", null));
1275 json.put("TextView_maxLines", array.getInt(sortedAttrs.indexOf(android.R.attr.maxLines), -1));
1276 json.put("TextView_drawablePadding", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.drawablePadding), 0));
1277
1278 try {
1279 json.put("TextView_textCursorDrawable", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.textCursorDrawable)), styleName + "_TextView_textCursorDrawable", null));
1280 } catch (Exception e_) {
1281 json.put("TextView_textCursorDrawable", getDrawable(m_context.getResources().getDrawable(array.getResourceId(sortedAttrs.indexOf(android.R.attr.textCursorDrawable), 0), m_theme), styleName + "_TextView_textCursorDrawable", null));
1282 }
1283
1284 json.put("TextView_maxLines", array.getInt(sortedAttrs.indexOf(android.R.attr.maxLines), -1));
1285 json.put("TextView_maxHeight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.maxHeight), -1));
1286 json.put("TextView_lines", array.getInt(sortedAttrs.indexOf(android.R.attr.lines), -1));
1287 json.put("TextView_height", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.height), -1));
1288 json.put("TextView_minLines", array.getInt(sortedAttrs.indexOf(android.R.attr.minLines), -1));
1289 json.put("TextView_minHeight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.minHeight), -1));
1290 json.put("TextView_maxEms", array.getInt(sortedAttrs.indexOf(android.R.attr.maxEms), -1));
1291 json.put("TextView_maxWidth", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.maxWidth), -1));
1292 json.put("TextView_ems", array.getInt(sortedAttrs.indexOf(android.R.attr.ems), -1));
1293 json.put("TextView_width", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.width), -1));
1294 json.put("TextView_minEms", array.getInt(sortedAttrs.indexOf(android.R.attr.minEms), -1));
1295 json.put("TextView_minWidth", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.minWidth), -1));
1296 json.put("TextView_gravity", array.getInt(sortedAttrs.indexOf(android.R.attr.gravity), -1));
1297 json.put("TextView_hint", array.getText(sortedAttrs.indexOf(android.R.attr.hint)));
1298 json.put("TextView_text", array.getText(sortedAttrs.indexOf(android.R.attr.text)));
1299 json.put("TextView_scrollHorizontally", array.getBoolean(sortedAttrs.indexOf(android.R.attr.scrollHorizontally), false));
1300 json.put("TextView_singleLine", array.getBoolean(sortedAttrs.indexOf(android.R.attr.singleLine), false));
1301 json.put("TextView_ellipsize", array.getInt(sortedAttrs.indexOf(android.R.attr.ellipsize), -1));
1302 json.put("TextView_marqueeRepeatLimit", array.getInt(sortedAttrs.indexOf(android.R.attr.marqueeRepeatLimit), 3));
1303 json.put("TextView_includeFontPadding", array.getBoolean(sortedAttrs.indexOf(android.R.attr.includeFontPadding), true));
1304 json.put("TextView_cursorVisible", array.getBoolean(sortedAttrs.indexOf(android.R.attr.maxLength), true));
1305 json.put("TextView_maxLength", array.getInt(sortedAttrs.indexOf(android.R.attr.maxLength), -1));
1306 json.put("TextView_textScaleX", array.getFloat(sortedAttrs.indexOf(android.R.attr.textScaleX), 1.0f));
1307 json.put("TextView_freezesText", array.getBoolean(sortedAttrs.indexOf(android.R.attr.freezesText), false));
1308 json.put("TextView_shadowColor", array.getInt(sortedAttrs.indexOf(android.R.attr.shadowColor), 0));
1309 json.put("TextView_shadowDx", array.getFloat(sortedAttrs.indexOf(android.R.attr.shadowDx), 0));
1310 json.put("TextView_shadowDy", array.getFloat(sortedAttrs.indexOf(android.R.attr.shadowDy), 0));
1311 json.put("TextView_shadowRadius", array.getFloat(sortedAttrs.indexOf(android.R.attr.shadowRadius), 0));
1312 json.put("TextView_enabled", array.getBoolean(sortedAttrs.indexOf(android.R.attr.enabled), true));
1313 json.put("TextView_password", array.getBoolean(sortedAttrs.indexOf(android.R.attr.password), false));
1314 json.put("TextView_lineSpacingExtra", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.lineSpacingExtra), 0));
1315 json.put("TextView_lineSpacingMultiplier", array.getFloat(sortedAttrs.indexOf(android.R.attr.lineSpacingMultiplier), 1.0f));
1316 json.put("TextView_inputType", array.getInt(sortedAttrs.indexOf(android.R.attr.inputType), EditorInfo.TYPE_NULL));
1317 json.put("TextView_imeOptions", array.getInt(sortedAttrs.indexOf(android.R.attr.imeOptions), EditorInfo.IME_NULL));
1318 json.put("TextView_imeActionLabel", array.getText(sortedAttrs.indexOf(android.R.attr.imeActionLabel)));
1319 json.put("TextView_imeActionId", array.getInt(sortedAttrs.indexOf(android.R.attr.imeActionId), 0));
1320 json.put("TextView_privateImeOptions", array.getString(sortedAttrs.indexOf(android.R.attr.privateImeOptions)));
1321
1322 try {
1323 json.put("TextView_textSelectHandleLeft", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.textSelectHandleLeft)), styleName + "_TextView_textSelectHandleLeft", null));
1324 } catch (Exception _e) {
1325 json.put("TextView_textSelectHandleLeft", getDrawable(m_context.getResources().getDrawable(array.getResourceId(sortedAttrs.indexOf(android.R.attr.textSelectHandleLeft), 0), m_theme), styleName + "_TextView_textSelectHandleLeft", null));
1326 }
1327
1328 try {
1329 json.put("TextView_textSelectHandleRight", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.textSelectHandleRight)), styleName + "_TextView_textSelectHandleRight", null));
1330 } catch (Exception _e) {
1331 json.put("TextView_textSelectHandleRight", getDrawable(m_context.getResources().getDrawable(array.getResourceId(sortedAttrs.indexOf(android.R.attr.textSelectHandleRight), 0), m_theme), styleName + "_TextView_textSelectHandleRight", null));
1332 }
1333
1334 try {
1335 json.put("TextView_textSelectHandle", getDrawable(array.getDrawable(sortedAttrs.indexOf(android.R.attr.textSelectHandle)), styleName + "_TextView_textSelectHandle", null));
1336 } catch (Exception _e) {
1337 json.put("TextView_textSelectHandle", getDrawable(m_context.getResources().getDrawable(array.getResourceId(sortedAttrs.indexOf(android.R.attr.textSelectHandle), 0), m_theme), styleName + "_TextView_textSelectHandle", null));
1338 }
1339 json.put("TextView_textIsSelectable", array.getBoolean(sortedAttrs.indexOf(android.R.attr.textIsSelectable), false));
1340 array.recycle();
1341 } catch (Exception e) {
1342 e.printStackTrace();
1343 }
1344 return json;
1345 }
1346
1347 public JSONObject extractImageViewInformation(int styleName, String qtClassName) {
1348 JSONObject json = new JSONObject();
1349 try {
1350 extractViewInformation(styleName, json, qtClassName);
1351
1352 int[] attributes = new int[]{
1353 android.R.attr.src,
1354 android.R.attr.baselineAlignBottom,
1355 android.R.attr.adjustViewBounds,
1356 android.R.attr.maxWidth,
1357 android.R.attr.maxHeight,
1358 android.R.attr.scaleType,
1359 android.R.attr.cropToPadding,
1360 android.R.attr.tint
1361
1362 };
1363 Arrays.sort(attributes);
1364 TypedArray array = obtainStyledAttributes(styleName, attributes);
1365 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1366
1367 Drawable drawable = array.getDrawable(sortedAttrs.indexOf(android.R.attr.src));
1368 if (drawable != null)
1369 json.put("ImageView_src", getDrawable(drawable, styleName + "_ImageView_src", null));
1370
1371 json.put("ImageView_baselineAlignBottom", array.getBoolean(sortedAttrs.indexOf(android.R.attr.baselineAlignBottom), false));
1372 json.put("ImageView_adjustViewBounds", array.getBoolean(sortedAttrs.indexOf(android.R.attr.baselineAlignBottom), false));
1373 json.put("ImageView_maxWidth", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.maxWidth), Integer.MAX_VALUE));
1374 json.put("ImageView_maxHeight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.maxHeight), Integer.MAX_VALUE));
1375 int index = array.getInt(sortedAttrs.indexOf(android.R.attr.scaleType), -1);
1376 if (index >= 0)
1377 json.put("ImageView_scaleType", sScaleTypeArray[index]);
1378
1379 int tint = array.getInt(sortedAttrs.indexOf(android.R.attr.tint), 0);
1380 if (tint != 0)
1381 json.put("ImageView_tint", tint);
1382
1383 json.put("ImageView_cropToPadding", array.getBoolean(sortedAttrs.indexOf(android.R.attr.cropToPadding), false));
1384 array.recycle();
1385 } catch (Exception e) {
1386 e.printStackTrace();
1387 }
1388 return json;
1389 }
1390
1391 void extractCompoundButton(SimpleJsonWriter jsonWriter, int styleName, String className, String qtClass) {
1392 JSONObject json = extractTextAppearanceInformation(styleName, qtClass);
1393
1394 TypedValue typedValue = new TypedValue();
1395 Context ctx = new ContextThemeWrapper(m_context, m_theme);
1396 ctx.getTheme().resolveAttribute(styleName, typedValue, true);
1397 final int[] attributes = new int[]{android.R.attr.button};
1398 TypedArray array = ctx.obtainStyledAttributes(typedValue.data, attributes);
1399 Drawable drawable = array.getDrawable(0);
1400 array.recycle();
1401
1402 try {
1403 if (drawable != null)
1404 json.put("CompoundButton_button", getDrawable(drawable, styleName + "_CompoundButton_button", null));
1405 jsonWriter.name(className).value(json);
1406 } catch (Exception e) {
1407 e.printStackTrace();
1408 }
1409 }
1410
1411 void extractProgressBarInfo(JSONObject json, int styleName) {
1412 try {
1413 final int[] attributes = new int[]{
1414 android.R.attr.minWidth,
1415 android.R.attr.maxWidth,
1416 android.R.attr.minHeight,
1417 android.R.attr.maxHeight,
1418 android.R.attr.indeterminateDuration,
1419 android.R.attr.progressDrawable,
1420 android.R.attr.indeterminateDrawable
1421 };
1422
1423 // The array must be sorted in ascending order, otherwise obtainStyledAttributes()
1424 // might fail to find some attributes
1425 Arrays.sort(attributes);
1426 TypedArray array = obtainStyledAttributes(styleName, attributes);
1427 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1428
1429 json.put("ProgressBar_indeterminateDuration", array.getInt(sortedAttrs.indexOf(android.R.attr.indeterminateDuration), 4000));
1430 json.put("ProgressBar_minWidth", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.minWidth), 24));
1431 json.put("ProgressBar_maxWidth", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.maxWidth), 48));
1432 json.put("ProgressBar_minHeight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.minHeight), 24));
1433 json.put("ProgressBar_maxHeight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.maxHeight), 28));
1434 json.put("ProgressBar_progress_id", android.R.id.progress);
1435 json.put("ProgressBar_secondaryProgress_id", android.R.id.secondaryProgress);
1436
1437 Drawable drawable = array.getDrawable(sortedAttrs.indexOf(android.R.attr.progressDrawable));
1438 if (drawable != null)
1439 json.put("ProgressBar_progressDrawable", getDrawable(drawable,
1440 styleName + "_ProgressBar_progressDrawable", null));
1441
1442 drawable = array.getDrawable(sortedAttrs.indexOf(android.R.attr.indeterminateDrawable));
1443 if (drawable != null)
1444 json.put("ProgressBar_indeterminateDrawable", getDrawable(drawable,
1445 styleName + "_ProgressBar_indeterminateDrawable", null));
1446
1447 array.recycle();
1448 } catch (Exception e) {
1449 e.printStackTrace();
1450 }
1451 }
1452
1453 void extractProgressBar(SimpleJsonWriter writer, int styleName, String className, String qtClass) {
1454 JSONObject json = extractTextAppearanceInformation(android.R.attr.progressBarStyle, qtClass);
1455 try {
1456 extractProgressBarInfo(json, styleName);
1457 writer.name(className).value(json);
1458 } catch (Exception e) {
1459 e.printStackTrace();
1460 }
1461 }
1462
1463 void extractAbsSeekBar(SimpleJsonWriter jsonWriter) {
1464 JSONObject json = extractTextAppearanceInformation(android.R.attr.seekBarStyle, "QSlider");
1465 extractProgressBarInfo(json, android.R.attr.seekBarStyle);
1466 try {
1467 int[] attributes = new int[]{
1468 android.R.attr.thumb,
1469 android.R.attr.thumbOffset
1470 };
1471 Arrays.sort(attributes);
1472 TypedArray array = obtainStyledAttributes(android.R.attr.seekBarStyle, attributes);
1473 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1474
1475 Drawable d = array.getDrawable(sortedAttrs.indexOf(android.R.attr.thumb));
1476 if (d != null)
1477 json.put("SeekBar_thumb", getDrawable(d, android.R.attr.seekBarStyle + "_SeekBar_thumb", null));
1478 json.put("SeekBar_thumbOffset", array.getDimensionPixelOffset(sortedAttrs.indexOf(android.R.attr.thumbOffset), -1));
1479 array.recycle();
1480 jsonWriter.name("seekBarStyle").value(json);
1481 } catch (Exception e) {
1482 e.printStackTrace();
1483 }
1484 }
1485
1486 void extractSwitch(SimpleJsonWriter jsonWriter) {
1487 JSONObject json = new JSONObject();
1488 try {
1489 int[] attributes = new int[]{
1490 android.R.attr.thumb,
1491 android.R.attr.track,
1492 android.R.attr.switchTextAppearance,
1493 android.R.attr.textOn,
1494 android.R.attr.textOff,
1495 android.R.attr.switchMinWidth,
1496 android.R.attr.switchPadding,
1497 android.R.attr.thumbTextPadding,
1498 android.R.attr.showText,
1499 android.R.attr.splitTrack
1500 };
1501 Arrays.sort(attributes);
1502 TypedArray array = obtainStyledAttributes(android.R.attr.switchStyle, attributes);
1503 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1504
1505 Drawable thumb = array.getDrawable(sortedAttrs.indexOf(android.R.attr.thumb));
1506 if (thumb != null)
1507 json.put("Switch_thumb", getDrawable(thumb, android.R.attr.switchStyle + "_Switch_thumb", null));
1508
1509 Drawable track = array.getDrawable(sortedAttrs.indexOf(android.R.attr.track));
1510 if (track != null)
1511 json.put("Switch_track", getDrawable(track, android.R.attr.switchStyle + "_Switch_track", null));
1512
1513 json.put("Switch_textOn", array.getText(sortedAttrs.indexOf(android.R.attr.textOn)));
1514 json.put("Switch_textOff", array.getText(sortedAttrs.indexOf(android.R.attr.textOff)));
1515 json.put("Switch_switchMinWidth", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.switchMinWidth), 0));
1516 json.put("Switch_switchPadding", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.switchPadding), 0));
1517 json.put("Switch_thumbTextPadding", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.thumbTextPadding), 0));
1518 json.put("Switch_showText", array.getBoolean(sortedAttrs.indexOf(android.R.attr.showText), true));
1519 json.put("Switch_splitTrack", array.getBoolean(sortedAttrs.indexOf(android.R.attr.splitTrack), false));
1520
1521 // Get textAppearance values
1522 final int textAppearanceId = array.getResourceId(sortedAttrs.indexOf(android.R.attr.switchTextAppearance), -1);
1523 json.put("Switch_switchTextAppearance", extractTextAppearance(textAppearanceId, true));
1524
1525 array.recycle();
1526 jsonWriter.name("switchStyle").value(json);
1527 } catch (Exception e) {
1528 e.printStackTrace();
1529 }
1530 }
1531
1532 JSONObject extractCheckedTextView(String itemName) {
1533 JSONObject json = extractTextAppearanceInformation(android.R.attr.checkedTextViewStyle, itemName);
1534 try {
1535 int[] attributes = new int[]{
1536 android.R.attr.checkMark,
1537 };
1538
1539 Arrays.sort(attributes);
1540 TypedArray array = obtainStyledAttributes(android.R.attr.switchStyle, attributes);
1541 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1542
1543 Drawable drawable = array.getDrawable(sortedAttrs.indexOf(android.R.attr.checkMark));
1544 if (drawable != null)
1545 json.put("CheckedTextView_checkMark", getDrawable(drawable, itemName + "_CheckedTextView_checkMark", null));
1546 array.recycle();
1547 } catch (Exception e) {
1548 e.printStackTrace();
1549 }
1550 return json;
1551 }
1552
1553 private JSONObject extractItemStyle(int resourceId, String itemName)
1554 {
1555 try {
1556 XmlResourceParser parser = m_context.getResources().getLayout(resourceId);
1557 int type = parser.next();
1558 while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT)
1559 type = parser.next();
1560
1561 if (type != XmlPullParser.START_TAG)
1562 return null;
1563
1564 AttributeSet attributes = Xml.asAttributeSet(parser);
1565 String name = parser.getName();
1566 if (name.equals("TextView"))
1567 return extractTextAppearanceInformation(android.R.attr.textViewStyle, itemName, android.R.attr.textAppearanceListItem, attributes);
1568 else if (name.equals("CheckedTextView"))
1569 return extractCheckedTextView(itemName);
1570 } catch (Exception e) {
1571 e.printStackTrace();
1572 }
1573 return null;
1574 }
1575
1576 private void extractItemsStyle(SimpleJsonWriter jsonWriter) {
1577 try {
1578 JSONObject itemStyle = extractItemStyle(android.R.layout.simple_list_item_1, "simple_list_item");
1579 if (itemStyle != null)
1580 jsonWriter.name("simple_list_item").value(itemStyle);
1581 itemStyle = extractItemStyle(android.R.layout.simple_list_item_checked, "simple_list_item_checked");
1582 if (itemStyle != null)
1583 jsonWriter.name("simple_list_item_checked").value(itemStyle);
1584 itemStyle = extractItemStyle(android.R.layout.simple_list_item_multiple_choice, "simple_list_item_multiple_choice");
1585 if (itemStyle != null)
1586 jsonWriter.name("simple_list_item_multiple_choice").value(itemStyle);
1587 itemStyle = extractItemStyle(android.R.layout.simple_list_item_single_choice, "simple_list_item_single_choice");
1588 if (itemStyle != null)
1589 jsonWriter.name("simple_list_item_single_choice").value(itemStyle);
1590 itemStyle = extractItemStyle(android.R.layout.simple_spinner_item, "simple_spinner_item");
1591 if (itemStyle != null)
1592 jsonWriter.name("simple_spinner_item").value(itemStyle);
1593 itemStyle = extractItemStyle(android.R.layout.simple_spinner_dropdown_item, "simple_spinner_dropdown_item");
1594 if (itemStyle != null)
1595 jsonWriter.name("simple_spinner_dropdown_item").value(itemStyle);
1596 itemStyle = extractItemStyle(android.R.layout.simple_dropdown_item_1line, "simple_dropdown_item_1line");
1597 if (itemStyle != null)
1598 jsonWriter.name("simple_dropdown_item_1line").value(itemStyle);
1599 itemStyle = extractItemStyle(android.R.layout.simple_selectable_list_item, "simple_selectable_list_item");
1600 if (itemStyle != null)
1601 jsonWriter.name("simple_selectable_list_item").value(itemStyle);
1602 } catch (Exception e) {
1603 e.printStackTrace();
1604 }
1605 }
1606
1607 void extractListView(SimpleJsonWriter writer) {
1608 JSONObject json = extractTextAppearanceInformation(android.R.attr.listViewStyle, "QListView");
1609 try {
1610 int[] attributes = new int[]{
1611 android.R.attr.divider,
1612 android.R.attr.dividerHeight
1613 };
1614 Arrays.sort(attributes);
1615 TypedArray array = obtainStyledAttributes(android.R.attr.listViewStyle, attributes);
1616 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1617
1618 Drawable divider = array.getDrawable(sortedAttrs.indexOf(android.R.attr.divider));
1619 if (divider != null)
1620 json.put("ListView_divider", getDrawable(divider, android.R.attr.listViewStyle + "_ListView_divider", null));
1621
1622 json.put("ListView_dividerHeight", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.dividerHeight), 0));
1623
1624 array.recycle();
1625 writer.name("listViewStyle").value(json);
1626 } catch (Exception e) {
1627 e.printStackTrace();
1628 }
1629 }
1630
1631 void extractCalendar(SimpleJsonWriter writer) {
1632 JSONObject json = extractTextAppearanceInformation(android.R.attr.calendarViewStyle, "QCalendarWidget");
1633 try {
1634 int[] attributes = new int[]{
1635 android.R.attr.firstDayOfWeek,
1636 android.R.attr.focusedMonthDateColor,
1637 android.R.attr.selectedWeekBackgroundColor,
1638 android.R.attr.showWeekNumber,
1639 android.R.attr.shownWeekCount,
1640 android.R.attr.unfocusedMonthDateColor,
1641 android.R.attr.weekNumberColor,
1642 android.R.attr.weekSeparatorLineColor,
1643 android.R.attr.selectedDateVerticalBar,
1644 android.R.attr.dateTextAppearance,
1645 android.R.attr.weekDayTextAppearance
1646 };
1647 Arrays.sort(attributes);
1648 TypedArray array = obtainStyledAttributes(android.R.attr.calendarViewStyle, attributes);
1649 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1650
1651 Drawable d = array.getDrawable(sortedAttrs.indexOf(android.R.attr.selectedDateVerticalBar));
1652 if (d != null)
1653 json.put("CalendarView_selectedDateVerticalBar", getDrawable(d, android.R.attr.calendarViewStyle + "_CalendarView_selectedDateVerticalBar", null));
1654
1655 int textAppearanceId = array.getResourceId(sortedAttrs.indexOf(android.R.attr.dateTextAppearance), -1);
1656 json.put("CalendarView_dateTextAppearance", extractTextAppearance(textAppearanceId, true));
1657 textAppearanceId = array.getResourceId(sortedAttrs.indexOf(android.R.attr.weekDayTextAppearance), -1);
1658 json.put("CalendarView_weekDayTextAppearance", extractTextAppearance(textAppearanceId, true));
1659
1660
1661 json.put("CalendarView_firstDayOfWeek", array.getInt(sortedAttrs.indexOf(android.R.attr.firstDayOfWeek), 0));
1662 json.put("CalendarView_focusedMonthDateColor", array.getColor(sortedAttrs.indexOf(android.R.attr.focusedMonthDateColor), 0));
1663 json.put("CalendarView_selectedWeekBackgroundColor", array.getColor(sortedAttrs.indexOf(android.R.attr.selectedWeekBackgroundColor), 0));
1664 json.put("CalendarView_showWeekNumber", array.getBoolean(sortedAttrs.indexOf(android.R.attr.showWeekNumber), true));
1665 json.put("CalendarView_shownWeekCount", array.getInt(sortedAttrs.indexOf(android.R.attr.shownWeekCount), 6));
1666 json.put("CalendarView_unfocusedMonthDateColor", array.getColor(sortedAttrs.indexOf(android.R.attr.unfocusedMonthDateColor), 0));
1667 json.put("CalendarView_weekNumberColor", array.getColor(sortedAttrs.indexOf(android.R.attr.weekNumberColor), 0));
1668 json.put("CalendarView_weekSeparatorLineColor", array.getColor(sortedAttrs.indexOf(android.R.attr.weekSeparatorLineColor), 0));
1669 array.recycle();
1670 writer.name("calendarViewStyle").value(json);
1671 } catch (Exception e) {
1672 e.printStackTrace();
1673 }
1674 }
1675
1676 void extractToolBar(SimpleJsonWriter writer) {
1677 JSONObject json = extractTextAppearanceInformation(android.R.attr.toolbarStyle, "QToolBar");
1678 try {
1679 int[] attributes = new int[]{
1680 android.R.attr.background,
1681 android.R.attr.backgroundStacked,
1682 android.R.attr.backgroundSplit,
1683 android.R.attr.divider,
1684 android.R.attr.itemPadding
1685 };
1686 Arrays.sort(attributes);
1687 TypedArray array = obtainStyledAttributes(android.R.attr.toolbarStyle, attributes);
1688 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1689
1690 Drawable d = array.getDrawable(sortedAttrs.indexOf(android.R.attr.background));
1691 if (d != null)
1692 json.put("ActionBar_background", getDrawable(d, android.R.attr.toolbarStyle + "_ActionBar_background", null));
1693
1694 d = array.getDrawable(sortedAttrs.indexOf(android.R.attr.backgroundStacked));
1695 if (d != null)
1696 json.put("ActionBar_backgroundStacked", getDrawable(d, android.R.attr.toolbarStyle + "_ActionBar_backgroundStacked", null));
1697
1698 d = array.getDrawable(sortedAttrs.indexOf(android.R.attr.backgroundSplit));
1699 if (d != null)
1700 json.put("ActionBar_backgroundSplit", getDrawable(d, android.R.attr.toolbarStyle + "_ActionBar_backgroundSplit", null));
1701
1702 d = array.getDrawable(sortedAttrs.indexOf(android.R.attr.divider));
1703 if (d != null)
1704 json.put("ActionBar_divider", getDrawable(d, android.R.attr.toolbarStyle + "_ActionBar_divider", null));
1705
1706 json.put("ActionBar_itemPadding", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.itemPadding), 0));
1707
1708 array.recycle();
1709 writer.name("actionBarStyle").value(json);
1710 } catch (Exception e) {
1711 e.printStackTrace();
1712 }
1713 }
1714
1715 void extractTabBar(SimpleJsonWriter writer) {
1716 JSONObject json = extractTextAppearanceInformation(android.R.attr.actionBarTabBarStyle, "QTabBar");
1717 try {
1718 int[] attributes = new int[]{
1719 android.R.attr.showDividers,
1720 android.R.attr.dividerPadding,
1721 android.R.attr.divider
1722 };
1723 Arrays.sort(attributes);
1724 TypedArray array = obtainStyledAttributes(android.R.attr.actionBarTabStyle, attributes);
1725 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1726
1727 Drawable d = array.getDrawable(sortedAttrs.indexOf(android.R.attr.divider));
1728 if (d != null)
1729 json.put("LinearLayout_divider", getDrawable(d, android.R.attr.actionBarTabStyle + "_LinearLayout_divider", null));
1730 json.put("LinearLayout_showDividers", array.getInt(sortedAttrs.indexOf(android.R.attr.showDividers), 0));
1731 json.put("LinearLayout_dividerPadding", array.getDimensionPixelSize(sortedAttrs.indexOf(android.R.attr.dividerPadding), 0));
1732
1733 array.recycle();
1734 writer.name("actionBarTabBarStyle").value(json);
1735 } catch (Exception e) {
1736 e.printStackTrace();
1737 }
1738 }
1739
1740 private void extractWindow(SimpleJsonWriter writer) {
1741 JSONObject json = new JSONObject();
1742 try {
1743 int[] attributes = new int[]{
1744 android.R.attr.windowBackground,
1745 android.R.attr.windowFrame
1746 };
1747 Arrays.sort(attributes);
1748 TypedArray array = obtainStyledAttributes(android.R.attr.popupWindowStyle, attributes);
1749 ArrayList<Integer> sortedAttrs = getArrayListFromIntArray(attributes);
1750
1751 Drawable background = array.getDrawable(sortedAttrs.indexOf(android.R.attr.windowBackground));
1752 if (background != null)
1753 json.put("Window_windowBackground", getDrawable(background, android.R.attr.popupWindowStyle + "_Window_windowBackground", null));
1754
1755 Drawable frame = array.getDrawable(sortedAttrs.indexOf(android.R.attr.windowFrame));
1756 if (frame != null)
1757 json.put("Window_windowFrame", getDrawable(frame, android.R.attr.popupWindowStyle + "_Window_windowFrame", null));
1758 array.recycle();
1759 writer.name("windowStyle").value(json);
1760 } catch (Exception e) {
1761 e.printStackTrace();
1762 }
1763 }
1764
1765 private JSONObject extractDefaultPalette() {
1766 JSONObject json = extractTextAppearance(android.R.attr.textAppearance);
1767 try {
1768 json.put("defaultBackgroundColor", defaultBackgroundColor);
1769 json.put("defaultTextColorPrimary", defaultTextColor);
1770 } catch (Exception e) {
1771 e.printStackTrace();
1772 }
1773 return json;
1774 }
1775
1776 static class SimpleJsonWriter {
1777 private final OutputStreamWriter m_writer;
1778 private boolean m_addComma = false;
1779 private int m_indentLevel = 0;
1780
1781 public SimpleJsonWriter(String filePath) throws FileNotFoundException {
1782 m_writer = new OutputStreamWriter(new FileOutputStream(filePath));
1783 }
1784
1785 public void close() throws IOException {
1786 m_writer.close();
1787 }
1788
1789 private void writeIndent() throws IOException {
1790 m_writer.write(" ", 0, m_indentLevel);
1791 }
1792
1793 void beginObject() throws IOException {
1794 writeIndent();
1795 m_writer.write("{\n");
1796 ++m_indentLevel;
1797 m_addComma = false;
1798 }
1799
1800 void endObject() throws IOException {
1801 m_writer.write("\n");
1802 writeIndent();
1803 m_writer.write("}\n");
1804 --m_indentLevel;
1805 m_addComma = false;
1806 }
1807
1808 SimpleJsonWriter name(String name) throws IOException {
1809 if (m_addComma) {
1810 m_writer.write(",\n");
1811 }
1812 writeIndent();
1813 m_writer.write(JSONObject.quote(name) + ": ");
1814 m_addComma = true;
1815 return this;
1816 }
1817
1818 void value(JSONObject value) throws IOException {
1819 m_writer.write(value.toString());
1820 }
1821 }
1822
1823 static class DrawableCache {
1824 JSONObject object;
1825 Object drawable;
1826 public DrawableCache(JSONObject json, Object drawable) {
1827 object = json;
1828 this.drawable = drawable;
1829 }
1830 }
1831}
Definition main.cpp:8
void extractViewInformation(int styleName, JSONObject json, String qtClassName)
ExtractStyle(Context context, String extractPath, boolean minimal)
JSONObject extractTextAppearanceInformation(int styleName, String qtClass, int textAppearance, AttributeSet attributeSet)
JSONObject extractTextAppearanceInformation(int styleName, String qtClass, AttributeSet attributeSet)
JSONObject extractTextAppearance(int styleName)
JSONObject extractTextAppearanceInformation(int styleName, String qtClass)
JSONObject getDrawable(Object drawable, String filename, Rect padding)
static void runIfNeeded(Context context, boolean extractDarkMode)
JSONObject extractImageViewInformation(int styleName, String qtClassName)
static void setup(Bundle loaderParams)
void extractViewInformation(int styleName, JSONObject json, String qtClassName, AttributeSet attributeSet)
EGLContext ctx
double e
rect
[4]
else opt state
[0]
Orientation
Definition qnamespace.h:97
static void * context
#define assert
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
const EGLAttrib EGLOutputLayerEXT * layers
static QList< QNetworkInterfacePrivate * > getInterfaces(int sock, char *buf)
GLenum GLsizei GLsizei GLint * values
[15]
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLenum GLenum GLsizei count
GLuint object
[3]
GLfloat GLfloat f
GLenum type
GLboolean GLuint group
GLuint name
GLfloat n
GLfloat GLfloat GLfloat GLfloat h
GLhandleARB obj
[2]
const GLubyte * c
GLuint GLfloat * val
GLenum array
GLenum GLsizei len
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei const GLchar *const * path
GLdouble s
[6]
Definition qopenglext.h:235
GLuint * states
XID Drawable
static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
static int getInt(QDataStream &stream)
const char className[16]
[1]
Definition qwizard.cpp:100
QStringList keys
QTextStream out(stdout)
[7]
QFrame frame
[0]