diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java | 856 |
1 files changed, 0 insertions, 856 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java deleted file mode 100644 index 5f2659ef2..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java +++ /dev/null @@ -1,856 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.editors.layout.gre; - -import static com.android.SdkConstants.ANDROID_URI; -import static com.android.SdkConstants.ATTR_ID; -import static com.android.SdkConstants.FQCN_BUTTON; -import static com.android.SdkConstants.FQCN_SPINNER; -import static com.android.SdkConstants.FQCN_TOGGLE_BUTTON; -import static com.android.SdkConstants.ID_PREFIX; -import static com.android.SdkConstants.NEW_ID_PREFIX; -import static com.android.SdkConstants.VIEW_FRAGMENT; -import static com.android.SdkConstants.VIEW_INCLUDE; - -import com.android.annotations.VisibleForTesting; -import com.android.ide.common.api.IViewMetadata.FillPreference; -import com.android.ide.common.api.Margins; -import com.android.ide.common.api.ResizePolicy; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors; -import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; -import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; -import com.android.resources.Density; -import com.android.utils.Pair; -import com.google.common.base.Splitter; -import com.google.common.io.Closeables; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; - -import java.io.BufferedInputStream; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -/** - * The {@link ViewMetadataRepository} contains additional metadata for Android view - * classes - */ -public class ViewMetadataRepository { - private static final String PREVIEW_CONFIG_FILENAME = "rendering-configs.xml"; //$NON-NLS-1$ - private static final String METADATA_FILENAME = "extra-view-metadata.xml"; //$NON-NLS-1$ - - /** Singleton instance */ - private static ViewMetadataRepository sInstance = new ViewMetadataRepository(); - - /** - * Returns the singleton instance - * - * @return the {@link ViewMetadataRepository} - */ - public static ViewMetadataRepository get() { - return sInstance; - } - - /** - * Ever increasing counter used to assign natural ordering numbers to views and - * categories - */ - private static int sNextOrdinal = 0; - - /** - * List of categories (which contain views); constructed lazily so use - * {@link #getCategories()} - */ - private List<CategoryData> mCategories; - - /** - * Map from class names to view data objects; constructed lazily so use - * {@link #getClassToView} - */ - private Map<String, ViewData> mClassToView; - - /** Hidden constructor: Create via factory {@link #get()} instead */ - private ViewMetadataRepository() { - } - - /** Returns a map from class fully qualified names to {@link ViewData} objects */ - private Map<String, ViewData> getClassToView() { - if (mClassToView == null) { - int initialSize = 75; - mClassToView = new HashMap<String, ViewData>(initialSize); - List<CategoryData> categories = getCategories(); - for (CategoryData category : categories) { - for (ViewData view : category) { - mClassToView.put(view.getFcqn(), view); - } - } - assert mClassToView.size() <= initialSize; - } - - return mClassToView; - } - - /** - * Returns an XML document containing rendering configurations for the various Android - * views. The FQN of each view can be obtained via the - * {@link #getFullClassName(Element)} method - * - * @return an XML document containing rendering elements - */ - public Document getRenderingConfigDoc() { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - Class<ViewMetadataRepository> clz = ViewMetadataRepository.class; - InputStream paletteStream = clz.getResourceAsStream(PREVIEW_CONFIG_FILENAME); - InputSource is = new InputSource(paletteStream); - try { - factory.setNamespaceAware(true); - factory.setValidating(false); - factory.setIgnoringComments(true); - DocumentBuilder builder = factory.newDocumentBuilder(); - return builder.parse(is); - } catch (Exception e) { - AdtPlugin.log(e, "Parsing palette file failed"); - return null; - } finally { - Closeables.closeQuietly(paletteStream); - } - } - - /** - * Returns a fully qualified class name for an element in the rendering document - * returned by {@link #getRenderingConfigDoc()} - * - * @param element the element to look up the fqcn for - * @return the fqcn of the view the element represents a preview for - */ - public String getFullClassName(Element element) { - // We don't use the element tag name, because in some cases we have - // an outer element to render some interesting inner element, such as a tab widget - // (which must be rendered inside a tab host). - // - // Therefore, we instead use the convention that the id is the fully qualified - // class name, with .'s replaced with _'s. - - // Special case: for tab host we aren't allowed to mess with the id - String id = element.getAttributeNS(ANDROID_URI, ATTR_ID); - - if ("@android:id/tabhost".equals(id)) { - // Special case to distinguish TabHost and TabWidget - NodeList children = element.getChildNodes(); - if (children.getLength() > 1 && (children.item(1) instanceof Element)) { - Element child = (Element) children.item(1); - String childId = child.getAttributeNS(ANDROID_URI, ATTR_ID); - if ("@+id/android_widget_TabWidget".equals(childId)) { - return "android.widget.TabWidget"; // TODO: Tab widget! - } - } - return "android.widget.TabHost"; // TODO: Tab widget! - } - - StringBuilder sb = new StringBuilder(); - int i = 0; - if (id.startsWith(NEW_ID_PREFIX)) { - i = NEW_ID_PREFIX.length(); - } else if (id.startsWith(ID_PREFIX)) { - i = ID_PREFIX.length(); - } - - for (; i < id.length(); i++) { - char c = id.charAt(i); - if (c == '_') { - sb.append('.'); - } else { - sb.append(c); - } - } - - return sb.toString(); - } - - /** Returns an ordered list of categories and views, parsed from a metadata file */ - @SuppressWarnings("resource") // streams passed to parser InputSource closed by parser - private List<CategoryData> getCategories() { - if (mCategories == null) { - mCategories = new ArrayList<CategoryData>(); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - Class<ViewMetadataRepository> clz = ViewMetadataRepository.class; - InputStream inputStream = clz.getResourceAsStream(METADATA_FILENAME); - InputSource is = new InputSource(new BufferedInputStream(inputStream)); - try { - factory.setNamespaceAware(true); - factory.setValidating(false); - factory.setIgnoringComments(true); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.parse(is); - Map<String, FillPreference> fillTypes = new HashMap<String, FillPreference>(); - for (FillPreference pref : FillPreference.values()) { - fillTypes.put(pref.toString().toLowerCase(Locale.US), pref); - } - - NodeList categoryNodes = document.getDocumentElement().getChildNodes(); - for (int i = 0, n = categoryNodes.getLength(); i < n; i++) { - Node node = categoryNodes.item(i); - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) node; - if (element.getNodeName().equals("category")) { //$NON-NLS-1$ - String name = element.getAttribute("name"); //$NON-NLS-1$ - CategoryData category = new CategoryData(name); - NodeList children = element.getChildNodes(); - for (int j = 0, m = children.getLength(); j < m; j++) { - Node childNode = children.item(j); - if (childNode.getNodeType() == Node.ELEMENT_NODE) { - Element child = (Element) childNode; - ViewData view = createViewData(fillTypes, child, - null, FillPreference.NONE, RenderMode.NORMAL, null); - category.addView(view); - } - } - mCategories.add(category); - } - } - } - } catch (Exception e) { - AdtPlugin.log(e, "Invalid palette metadata"); //$NON-NLS-1$ - } - } - - return mCategories; - } - - private ViewData createViewData(Map<String, FillPreference> fillTypes, - Element child, String defaultFqcn, FillPreference defaultFill, - RenderMode defaultRender, String defaultSize) { - String fqcn = child.getAttribute("class"); //$NON-NLS-1$ - if (fqcn.length() == 0) { - fqcn = defaultFqcn; - } - String fill = child.getAttribute("fill"); //$NON-NLS-1$ - FillPreference fillPreference = null; - if (fill.length() > 0) { - fillPreference = fillTypes.get(fill); - } - if (fillPreference == null) { - fillPreference = defaultFill; - } - String skip = child.getAttribute("skip"); //$NON-NLS-1$ - RenderMode renderMode = defaultRender; - String render = child.getAttribute("render"); //$NON-NLS-1$ - if (render.length() > 0) { - renderMode = RenderMode.get(render); - } - String displayName = child.getAttribute("name"); //$NON-NLS-1$ - if (displayName.length() == 0) { - displayName = null; - } - - String relatedTo = child.getAttribute("relatedTo"); //$NON-NLS-1$ - String topAttrs = child.getAttribute("topAttrs"); //$NON-NLS-1$ - String resize = child.getAttribute("resize"); //$NON-NLS-1$ - ViewData view = new ViewData(fqcn, displayName, fillPreference, - skip.length() == 0 ? false : Boolean.valueOf(skip), - renderMode, relatedTo, resize, topAttrs); - - String init = child.getAttribute("init"); //$NON-NLS-1$ - String icon = child.getAttribute("icon"); //$NON-NLS-1$ - - view.setInitString(init); - if (icon.length() > 0) { - view.setIconName(icon); - } - - // Nested variations? - if (child.hasChildNodes()) { - // Palette variations - NodeList childNodes = child.getChildNodes(); - for (int k = 0, kl = childNodes.getLength(); k < kl; k++) { - Node variationNode = childNodes.item(k); - if (variationNode.getNodeType() == Node.ELEMENT_NODE) { - Element variation = (Element) variationNode; - ViewData variationView = createViewData(fillTypes, variation, - fqcn, fillPreference, renderMode, resize); - view.addVariation(variationView); - } - } - } - - return view; - } - - /** - * Computes the palette entries for the given {@link AndroidTargetData}, looking up the - * available node descriptors, categorizing and sorting them. - * - * @param targetData the target data for which to compute palette entries - * @param alphabetical if true, sort all items in alphabetical order - * @param createCategories if true, organize the items into categories - * @return a list of pairs where each pair contains of the category label and an - * ordered list of elements to be included in that category - */ - public List<Pair<String, List<ViewElementDescriptor>>> getPaletteEntries( - AndroidTargetData targetData, boolean alphabetical, boolean createCategories) { - List<Pair<String, List<ViewElementDescriptor>>> result = - new ArrayList<Pair<String, List<ViewElementDescriptor>>>(); - - List<List<ViewElementDescriptor>> lists = new ArrayList<List<ViewElementDescriptor>>(2); - LayoutDescriptors layoutDescriptors = targetData.getLayoutDescriptors(); - lists.add(layoutDescriptors.getViewDescriptors()); - lists.add(layoutDescriptors.getLayoutDescriptors()); - - // First record map of FQCN to ViewElementDescriptor such that we can quickly - // determine if a particular palette entry is available - Map<String, ViewElementDescriptor> fqcnToDescriptor = - new HashMap<String, ViewElementDescriptor>(); - for (List<ViewElementDescriptor> list : lists) { - for (ViewElementDescriptor view : list) { - String fqcn = view.getFullClassName(); - if (fqcn == null) { - // <view> and <merge> tags etc - fqcn = view.getUiName(); - } - fqcnToDescriptor.put(fqcn, view); - } - } - - Set<ViewElementDescriptor> remaining = new HashSet<ViewElementDescriptor>( - layoutDescriptors.getViewDescriptors().size() - + layoutDescriptors.getLayoutDescriptors().size()); - remaining.addAll(layoutDescriptors.getViewDescriptors()); - remaining.addAll(layoutDescriptors.getLayoutDescriptors()); - - // Now iterate in palette metadata order over the items in the palette and include - // any that also appear as a descriptor - List<ViewElementDescriptor> categoryItems = new ArrayList<ViewElementDescriptor>(); - for (CategoryData category : getCategories()) { - if (createCategories) { - categoryItems = new ArrayList<ViewElementDescriptor>(); - } - for (ViewData view : category) { - String fqcn = view.getFcqn(); - ViewElementDescriptor descriptor = fqcnToDescriptor.get(fqcn); - if (descriptor != null) { - remaining.remove(descriptor); - if (view.getSkip()) { - continue; - } - - if (view.getDisplayName() != null || view.getInitString().length() > 0) { - categoryItems.add(new PaletteMetadataDescriptor(descriptor, - view.getDisplayName(), view.getInitString(), view.getIconName())); - } else { - categoryItems.add(descriptor); - } - - if (view.hasVariations()) { - for (ViewData variation : view.getVariations()) { - String init = variation.getInitString(); - String icon = variation.getIconName(); - ViewElementDescriptor desc = new PaletteMetadataDescriptor(descriptor, - variation.getDisplayName(), init, icon); - categoryItems.add(desc); - } - } - } - } - - if (createCategories && categoryItems.size() > 0) { - if (alphabetical) { - Collections.sort(categoryItems); - } - result.add(Pair.of(category.getName(), categoryItems)); - } - } - - if (remaining.size() > 0) { - List<ViewElementDescriptor> otherItems = - new ArrayList<ViewElementDescriptor>(remaining); - // Always sorted, we don't have a natural order for these unknowns - Collections.sort(otherItems); - if (createCategories) { - result.add(Pair.of("Other", otherItems)); - } else { - categoryItems.addAll(otherItems); - } - } - - if (!createCategories) { - if (alphabetical) { - Collections.sort(categoryItems); - } - result.add(Pair.of("Views", categoryItems)); - } - - return result; - } - - @VisibleForTesting - Collection<String> getAllFqcns() { - return getClassToView().keySet(); - } - - /** - * Metadata holder for a particular category - contains the name of the category, its - * ordinal (for natural/logical sorting order) and views contained in the category - */ - private static class CategoryData implements Iterable<ViewData>, Comparable<CategoryData> { - /** Category name */ - private final String mName; - /** Views included in this category */ - private final List<ViewData> mViews = new ArrayList<ViewData>(); - /** Natural ordering rank */ - private final int mOrdinal = sNextOrdinal++; - - /** Constructs a new category with the given name */ - private CategoryData(String name) { - super(); - mName = name; - } - - /** Adds a new view into this category */ - private void addView(ViewData view) { - mViews.add(view); - } - - private String getName() { - return mName; - } - - // Implements Iterable<ViewData> such that we can use for-each on the category to - // enumerate its views - @Override - public Iterator<ViewData> iterator() { - return mViews.iterator(); - } - - // Implements Comparable<CategoryData> such that categories can be naturally sorted - @Override - public int compareTo(CategoryData other) { - return mOrdinal - other.mOrdinal; - } - } - - /** Metadata holder for a view of a given fully qualified class name */ - private static class ViewData implements Comparable<ViewData> { - /** The fully qualified class name of the view */ - private final String mFqcn; - /** Fill preference of the view */ - private final FillPreference mFillPreference; - /** Skip this item in the palette? */ - private final boolean mSkip; - /** Must this item be rendered alone? skipped? etc */ - private final RenderMode mRenderMode; - /** Related views */ - private final String mRelatedTo; - /** The relative rank of the view for natural ordering */ - private final int mOrdinal = sNextOrdinal++; - /** List of optional variations */ - private List<ViewData> mVariations; - /** Display name. Can be null. */ - private String mDisplayName; - /** - * Optional initialization string - a comma separate set of name/value pairs to - * initialize the element with - */ - private String mInitString; - /** The name of an icon (known to the {@link IconFactory} to show for this view */ - private String mIconName; - /** The resize preference of this view */ - private String mResize; - /** The most commonly set attributes of this view */ - private String mTopAttrs; - - /** Constructs a new view data for the given class */ - private ViewData(String fqcn, String displayName, - FillPreference fillPreference, boolean skip, RenderMode renderMode, - String relatedTo, String resize, String topAttrs) { - super(); - mFqcn = fqcn; - mDisplayName = displayName; - mFillPreference = fillPreference; - mSkip = skip; - mRenderMode = renderMode; - mRelatedTo = relatedTo; - mResize = resize; - mTopAttrs = topAttrs; - } - - /** Returns the {@link FillPreference} for views of this type */ - private FillPreference getFillPreference() { - return mFillPreference; - } - - /** Fully qualified class name of views of this type */ - private String getFcqn() { - return mFqcn; - } - - private String getDisplayName() { - return mDisplayName; - } - - private String getResize() { - return mResize; - } - - // Implements Comparable<ViewData> such that views can be sorted naturally - @Override - public int compareTo(ViewData other) { - return mOrdinal - other.mOrdinal; - } - - public RenderMode getRenderMode() { - return mRenderMode; - } - - public boolean getSkip() { - return mSkip; - } - - public List<String> getRelatedTo() { - if (mRelatedTo == null || mRelatedTo.length() == 0) { - return Collections.emptyList(); - } else { - List<String> result = new ArrayList<String>(); - ViewMetadataRepository repository = ViewMetadataRepository.get(); - Map<String, ViewData> classToView = repository.getClassToView(); - - List<String> fqns = new ArrayList<String>(classToView.keySet()); - for (String basename : Splitter.on(',').split(mRelatedTo)) { - boolean found = false; - for (String fqcn : fqns) { - String suffix = '.' + basename; - if (fqcn.endsWith(suffix)) { - result.add(fqcn); - found = true; - break; - } - } - if (basename.equals(VIEW_FRAGMENT) || basename.equals(VIEW_INCLUDE)) { - result.add(basename); - } else { - assert found : basename; - } - } - - return result; - } - } - - public List<String> getTopAttributes() { - // "id" is a top attribute for all views, so it is not included in the XML, we just - // add it in dynamically here - if (mTopAttrs == null || mTopAttrs.length() == 0) { - return Collections.singletonList(ATTR_ID); - } else { - String[] split = mTopAttrs.split(","); //$NON-NLS-1$ - List<String> topAttributes = new ArrayList<String>(split.length + 1); - topAttributes.add(ATTR_ID); - for (int i = 0, n = split.length; i < n; i++) { - topAttributes.add(split[i]); - } - return Collections.<String>unmodifiableList(topAttributes); - } - } - - void addVariation(ViewData variation) { - if (mVariations == null) { - mVariations = new ArrayList<ViewData>(4); - } - mVariations.add(variation); - } - - List<ViewData> getVariations() { - return mVariations; - } - - boolean hasVariations() { - return mVariations != null && mVariations.size() > 0; - } - - private void setInitString(String initString) { - this.mInitString = initString; - } - - private String getInitString() { - return mInitString; - } - - private void setIconName(String iconName) { - this.mIconName = iconName; - } - - private String getIconName() { - return mIconName; - } - } - - /** - * Returns the {@link FillPreference} for classes with the given fully qualified class - * name - * - * @param fqcn the fully qualified class name of the view - * @return a suitable {@link FillPreference} for the given view type - */ - public FillPreference getFillPreference(String fqcn) { - ViewData view = getClassToView().get(fqcn); - if (view != null) { - return view.getFillPreference(); - } - - return FillPreference.NONE; - } - - /** - * Returns the {@link RenderMode} for classes with the given fully qualified class - * name - * - * @param fqcn the fully qualified class name - * @return the {@link RenderMode} to use for previews of the given view type - */ - public RenderMode getRenderMode(String fqcn) { - ViewData view = getClassToView().get(fqcn); - if (view != null) { - return view.getRenderMode(); - } - - return RenderMode.NORMAL; - } - - /** - * Returns the {@link ResizePolicy} for the given class. - * - * @param fqcn the fully qualified class name of the target widget - * @return the {@link ResizePolicy} for the widget, which will never be null (but may - * be the default of {@link ResizePolicy#full()} if no metadata is found for - * the given widget) - */ - public ResizePolicy getResizePolicy(String fqcn) { - ViewData view = getClassToView().get(fqcn); - if (view != null) { - String resize = view.getResize(); - if (resize != null && resize.length() > 0) { - if ("full".equals(resize)) { //$NON-NLS-1$ - return ResizePolicy.full(); - } else if ("none".equals(resize)) { //$NON-NLS-1$ - return ResizePolicy.none(); - } else if ("horizontal".equals(resize)) { //$NON-NLS-1$ - return ResizePolicy.horizontal(); - } else if ("vertical".equals(resize)) { //$NON-NLS-1$ - return ResizePolicy.vertical(); - } else if ("scaled".equals(resize)) { //$NON-NLS-1$ - return ResizePolicy.scaled(); - } else { - assert false : resize; - } - } - } - - return ResizePolicy.full(); - } - - /** - * Returns true if classes with the given fully qualified class name should be hidden - * or skipped from the palette - * - * @param fqcn the fully qualified class name - * @return true if views of the given type should be hidden from the palette - */ - public boolean getSkip(String fqcn) { - ViewData view = getClassToView().get(fqcn); - if (view != null) { - return view.getSkip(); - } - - return false; - } - - /** - * Returns a list of the top (most commonly set) attributes of the given - * view. - * - * @param fqcn the fully qualified class name - * @return a list, never null but possibly empty, of popular attribute names - * (not including a namespace prefix) - */ - public List<String> getTopAttributes(String fqcn) { - ViewData view = getClassToView().get(fqcn); - if (view != null) { - return view.getTopAttributes(); - } - - return Collections.singletonList(ATTR_ID); - } - - /** - * Returns a set of fully qualified names for views that are closely related to the - * given view - * - * @param fqcn the fully qualified class name - * @return a list, never null but possibly empty, of views that are related to the - * view of the given type - */ - public List<String> getRelatedTo(String fqcn) { - ViewData view = getClassToView().get(fqcn); - if (view != null) { - return view.getRelatedTo(); - } - - return Collections.emptyList(); - } - - /** Render mode for palette preview */ - public enum RenderMode { - /** - * Render previews, and it can be rendered as a sibling of many other views in a - * big linear layout - */ - NORMAL, - /** This view needs to be rendered alone */ - ALONE, - /** - * Skip this element; it doesn't work or does not produce any visible artifacts - * (such as the basic layouts) - */ - SKIP; - - /** - * Returns the {@link RenderMode} for the given render XML attribute - * value - * - * @param render the attribute value in the metadata XML file - * @return a corresponding {@link RenderMode}, never null - */ - public static RenderMode get(String render) { - if ("alone".equals(render)) { //$NON-NLS-1$ - return ALONE; - } else if ("skip".equals(render)) { //$NON-NLS-1$ - return SKIP; - } else { - return NORMAL; - } - } - } - - /** - * Are insets supported yet? This flag indicates whether the {@link #getInsets} method - * can return valid data, such that clients can avoid doing any work computing the - * current theme or density if there's no chance that valid insets will be returned - */ - public static final boolean INSETS_SUPPORTED = false; - - /** - * Returns the insets of widgets with the given fully qualified name, in the given - * theme and the given screen density. - * - * @param fqcn the fully qualified name of the view - * @param density the screen density - * @param theme the theme name - * @return the insets of the visual bounds relative to the view info bounds, or null - * if not known or if there are no insets - */ - public static Margins getInsets(String fqcn, Density density, String theme) { - if (INSETS_SUPPORTED) { - // Some sample data measured manually for common themes and widgets. - if (fqcn.equals(FQCN_BUTTON)) { - if (density == Density.HIGH) { - if (theme.startsWith(HOLO_PREFIX)) { - // Theme.Holo, Theme.Holo.Light, WVGA - return new Margins(5, 5, 5, 5); - } else { - // Theme.Light, WVGA - return new Margins(4, 4, 0, 7); - } - } else if (density == Density.MEDIUM) { - if (theme.startsWith(HOLO_PREFIX)) { - // Theme.Holo, Theme.Holo.Light, WVGA - return new Margins(3, 3, 3, 3); - } else { - // Theme.Light, HVGA - return new Margins(2, 2, 0, 4); - } - } else if (density == Density.LOW) { - if (theme.startsWith(HOLO_PREFIX)) { - // Theme.Holo, Theme.Holo.Light, QVGA - return new Margins(2, 2, 2, 2); - } else { - // Theme.Light, QVGA - return new Margins(1, 3, 0, 4); - } - } - } else if (fqcn.equals(FQCN_TOGGLE_BUTTON)) { - if (density == Density.HIGH) { - if (theme.startsWith(HOLO_PREFIX)) { - // Theme.Holo, Theme.Holo.Light, WVGA - return new Margins(5, 5, 5, 5); - } else { - // Theme.Light, WVGA - return new Margins(2, 2, 0, 5); - } - } else if (density == Density.MEDIUM) { - if (theme.startsWith(HOLO_PREFIX)) { - // Theme.Holo, Theme.Holo.Light, WVGA - return new Margins(3, 3, 3, 3); - } else { - // Theme.Light, HVGA - return new Margins(0, 1, 0, 3); - } - } else if (density == Density.LOW) { - if (theme.startsWith(HOLO_PREFIX)) { - // Theme.Holo, Theme.Holo.Light, QVGA - return new Margins(2, 2, 2, 2); - } else { - // Theme.Light, QVGA - return new Margins(2, 2, 0, 4); - } - } - } else if (fqcn.equals(FQCN_SPINNER)) { - if (density == Density.HIGH) { - if (!theme.startsWith(HOLO_PREFIX)) { - // Theme.Light, WVGA - return new Margins(3, 4, 2, 8); - } // Doesn't render on Holo! - } else if (density == Density.MEDIUM) { - if (!theme.startsWith(HOLO_PREFIX)) { - // Theme.Light, HVGA - return new Margins(1, 1, 0, 4); - } - } - } - } - - return null; - } - - private static final String HOLO_PREFIX = "Theme.Holo"; //$NON-NLS-1$ -} |