diff options
author | Tor Norbye <tnorbye@google.com> | 2012-03-20 11:50:57 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-04-03 07:55:09 -0700 |
commit | a7621238bf0202419677380ee3a268142358df83 (patch) | |
tree | 0bde7f60b2124e21ca825e1ac3ef9bad50426f9a /attribute_stats | |
parent | b0c819f896b3c579633849e3fa674a30e6978dd7 (diff) | |
download | sdk-a7621238bf0202419677380ee3a268142358df83.zip sdk-a7621238bf0202419677380ee3a268142358df83.tar.gz sdk-a7621238bf0202419677380ee3a268142358df83.tar.bz2 |
Add support for the WindowBuilder Property Sheet
The WindowBuilder propertysheet has been extracted and added as a
library in external/eclipse-windowbuilder/.
This changeset removes the old propertysheet code (which used the
builtin Eclipse property sheet page), and replaces it with the
WindowBuilder one, along with new code to aggregate the properties
into some categories, as well as tagging some of the properties as
advanced. (This was computed by running the same analysis scripts used
to produce the most-frequent attributes (sdk/attribute_stats) and
instead computing which attributes are used very infrequently or not
at all in some representative sample code.)
The WindowBuilder propertysheet gives us the following new features:
- Highlighting (bold) of important attributes
- Masking (and when included, shown in gray italic) of advanced
attributes
- "Complex" attributes with nesting, used to for example aggregate all
the layout parameters into a single node, and the margin layout
attributes within those
- Tooltips over the attribute names, not values, so they never obscure
content
In addition, this changeset adds custom implementations of properties,
property editors and property dialogs for the core Android property
types (XML strings, flags and booleans), which adds the following new
features:
- Preview rendering of color and image resources inline
- Display of -default- attributes (those not specified in XML) using
the layoutlib facility getDefaultProperties() to render the implied
attributes. For example, if you look at a Button, it will show you
that the implied value of "Text Color Link" is
"@android:color/holo_blue_light" even though it is not set.
NOTE: This only happens for attributes that were actually queried by
the widget during rendering. Attributes that are not used by the
widget have no (displayed) value. Thus, EditText-specific attributes
in a TextView are not shown when a non-EditText TextView is
selected.
- Evaluation of the attributes. In the above example, in addition to
showing @android:color/holo_blue_light, it will chase down the value
of this to for example render a blue square next to the value. For
drawables it will render a thumbnail, and for String resources it
will display the actual value in parentheses.
- Field completion in text fields, completing all resource strings
(@string, @android:string, etc), as well as flag values. Enum values
are chosen in a dropdown.
- Checkbox support for boolean values, allowing you to click through
the three values true, false and null.
- Our custom version of the Property Sheet Page allows you to
expand/collapse all properties, and it also has an option letting
you switch between Alphabetical Sort (where all attributes are in a
flat table, sorted alphabetically by property value), or
hierarchical sorted "by category". Currently the categories are
simply the defining views, plus 2 more (layout parameters and
deprecated attributes). When we get more metadata, it would be nice
to switch these to more logical categories, such as "text",
"scrolling", "focus", etc. (There is some preliminary support for
this in the code, but since the defining-view categories seem to
work better those are used instead right now.)
Change-Id: Ie4959a3a2c36c083dcc1ba19a70f24b33739fe2f
Diffstat (limited to 'attribute_stats')
-rw-r--r-- | attribute_stats/src/Analyzer.java | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/attribute_stats/src/Analyzer.java b/attribute_stats/src/Analyzer.java index a6bbb4a..8da53ea 100644 --- a/attribute_stats/src/Analyzer.java +++ b/attribute_stats/src/Analyzer.java @@ -34,8 +34,11 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -59,6 +62,7 @@ public class Analyzer { private List<File> mDirectories; private File mCurrentFile; + private boolean mListAdvanced; /** Map from view id to map from attribute to frequency count */ private Map<String, Map<String, Usage>> mFrequencies = @@ -74,9 +78,10 @@ public class Analyzer { private int mLayoutFileCount; private File mXmlMetadataFile; - private Analyzer(List<File> directories, File xmlMetadataFile) { + private Analyzer(List<File> directories, File xmlMetadataFile, boolean listAdvanced) { mDirectories = directories; mXmlMetadataFile = xmlMetadataFile; + mListAdvanced = listAdvanced; } public static void main(String[] args) { @@ -90,14 +95,21 @@ public class Analyzer { File metadataFile = null; List<File> directories = new ArrayList<File>(); + boolean listAdvanced = false; for (int i = 0, n = args.length; i < n; i++) { String arg = args[i]; + if (arg.equals("--list")) { + // List ALL encountered attributes + listAdvanced = true; + continue; + } + // The -metadata flag takes a pointer to an ADT extra-view-metadata.xml file // and attempts to insert topAttrs attributes into it (and saves it as same // file +.mod as an extension). This isn't listed on the usage flag because // it's pretty brittle and requires some manual fixups to the file afterwards. - if (arg.equals("-metadata")) { + if (arg.equals("--metadata")) { i++; File file = new File(args[i]); if (!file.exists()) { @@ -125,13 +137,18 @@ public class Analyzer { directories.add(directory); } - new Analyzer(directories, metadataFile).analyze(); + new Analyzer(directories, metadataFile, listAdvanced).analyze(); } private void analyze() { for (File directory : mDirectories) { scanDirectory(directory); } + + if (mListAdvanced) { + listAdvanced(); + } + printStatistics(); if (mXmlMetadataFile != null) { @@ -523,6 +540,69 @@ public class Analyzer { System.out.println("Done - wrote " + output.getPath()); } + //private File mPublicFile = new File(location, "data/res/values/public.xml"); + private File mPublicFile = new File("/Volumes/AndroidWork/git/frameworks/base/core/res/res/values/public.xml"); + + private void listAdvanced() { + Set<String> keys = new HashSet<String>(1000); + + // Merged usages across view types + Map<String, Usage> mergedUsages = new HashMap<String, Usage>(100); + + for (Entry<String,Map<String,Usage>> entry : mFrequencies.entrySet()) { + String view = entry.getKey(); + if (view.indexOf('.') != -1 && !view.startsWith("android.")) { + // Skip custom views etc + continue; + } + Map<String, Usage> map = entry.getValue(); + for (Usage usage : map.values()) { +// if (usage.count == 1) { +// System.out.println("Only found *one* usage of " + usage.attribute); +// } +// if (usage.count < 4) { +// System.out.println("Only found " + usage.count + " usage of " + usage.attribute); +// } + + String attribute = usage.attribute; + int index = attribute.indexOf(':'); + if (index == -1 || attribute.startsWith("android:")) { + Usage merged = mergedUsages.get(attribute); + if (merged == null) { + merged = new Usage(attribute); + merged.count = usage.count; + mergedUsages.put(attribute, merged); + } else { + merged.count += usage.count; + } + } + } + } + + for (Usage usage : mergedUsages.values()) { + String attribute = usage.attribute; + if (usage.count < 4) { + System.out.println("Only found " + usage.count + " usage of " + usage.attribute); + continue; + } + int index = attribute.indexOf(':'); + if (index != -1) { + attribute = attribute.substring(index + 1); // +1: skip ':' + } + keys.add(attribute); + } + + List<String> sorted = new ArrayList<String>(keys); + Collections.sort(sorted); + System.out.println("\nEncountered Attributes"); + System.out.println("-----------------------------"); + for (String attribute : sorted) { + System.out.println(attribute); + } + + System.out.println(); + } + private static class Usage implements Comparable<Usage> { public String attribute; public int count; @@ -539,6 +619,7 @@ public class Analyzer { count++; } + @Override public int compareTo(Usage o) { // Sort by decreasing frequency, then sort alphabetically int frequencyDelta = o.count - count; |