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