1d5cd92b446e43e8de625142415f560ee54636317Tor Norbye/* 2d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Copyright (C) 2011 The Android Open Source Project 3d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * 4d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * you may not use this file except in compliance with the License. 6d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * You may obtain a copy of the License at 7d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * 8d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * http://www.eclipse.org/org/documents/epl-v10.php 9d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * 10d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Unless required by applicable law or agreed to in writing, software 11d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS, 12d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * See the License for the specific language governing permissions and 14d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * limitations under the License. 15d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 16d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 17d5cd92b446e43e8de625142415f560ee54636317Tor Norbyepackage com.android.ide.eclipse.adt.internal.editors.layout.gre; 18d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 1912d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ANDROID_URI; 2012d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ATTR_ID; 2112d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.FQCN_BUTTON; 2212d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.FQCN_SPINNER; 2312d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.FQCN_TOGGLE_BUTTON; 2412d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ID_PREFIX; 2512d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.NEW_ID_PREFIX; 2612d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.VIEW_FRAGMENT; 2712d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.VIEW_INCLUDE; 28d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 290757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbyeimport com.android.annotations.VisibleForTesting; 30d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport com.android.ide.common.api.IViewMetadata.FillPreference; 310595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbyeimport com.android.ide.common.api.Margins; 320595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbyeimport com.android.ide.common.api.ResizePolicy; 33d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport com.android.ide.eclipse.adt.AdtPlugin; 34e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbyeimport com.android.ide.eclipse.adt.internal.editors.IconFactory; 35d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors; 36d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; 37d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; 380595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbyeimport com.android.resources.Density; 3985e4a1a9dd133abb879ec211ce8dd385004edf22Xavier Ducrohetimport com.android.utils.Pair; 406cb5c7f7141a08fd355bb92c6a4153140400890bTor Norbyeimport com.google.common.base.Splitter; 41ec7301a7433cf89c399fa3c507afe8a147adbcbaTor Norbyeimport com.google.common.io.Closeables; 42d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 43d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport org.w3c.dom.Document; 44d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport org.w3c.dom.Element; 45d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport org.w3c.dom.Node; 46d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport org.w3c.dom.NodeList; 47d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport org.xml.sax.InputSource; 48d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 49d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.io.BufferedInputStream; 50d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.io.InputStream; 51d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.util.ArrayList; 520757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbyeimport java.util.Collection; 53d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.util.Collections; 54d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.util.HashMap; 55e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbyeimport java.util.HashSet; 56d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.util.Iterator; 57d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.util.List; 5818bce12c5916331971b2e8108f8485cc56b696d3Tor Norbyeimport java.util.Locale; 59d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport java.util.Map; 60e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbyeimport java.util.Set; 61d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 62d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport javax.xml.parsers.DocumentBuilder; 63d5cd92b446e43e8de625142415f560ee54636317Tor Norbyeimport javax.xml.parsers.DocumentBuilderFactory; 64d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 65d5cd92b446e43e8de625142415f560ee54636317Tor Norbye/** 66d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * The {@link ViewMetadataRepository} contains additional metadata for Android view 67d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * classes 68d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 69d5cd92b446e43e8de625142415f560ee54636317Tor Norbyepublic class ViewMetadataRepository { 700ac475d29f793079783f501126239ed6ce8aa31dTor Norbye private static final String PREVIEW_CONFIG_FILENAME = "rendering-configs.xml"; //$NON-NLS-1$ 710ac475d29f793079783f501126239ed6ce8aa31dTor Norbye private static final String METADATA_FILENAME = "extra-view-metadata.xml"; //$NON-NLS-1$ 720ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 73d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Singleton instance */ 74d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private static ViewMetadataRepository sInstance = new ViewMetadataRepository(); 75d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 76d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** 77d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Returns the singleton instance 78d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * 79d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * @return the {@link ViewMetadataRepository} 80d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 81d5cd92b446e43e8de625142415f560ee54636317Tor Norbye public static ViewMetadataRepository get() { 82d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return sInstance; 83d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 84d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 85d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** 86d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Ever increasing counter used to assign natural ordering numbers to views and 87d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * categories 88d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 89d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private static int sNextOrdinal = 0; 90d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 91d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** 92d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * List of categories (which contain views); constructed lazily so use 93d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * {@link #getCategories()} 94d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 95d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private List<CategoryData> mCategories; 96d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 97d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** 98d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Map from class names to view data objects; constructed lazily so use 99d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * {@link #getClassToView} 100d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 101d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private Map<String, ViewData> mClassToView; 102d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 103d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Hidden constructor: Create via factory {@link #get()} instead */ 104d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private ViewMetadataRepository() { 105d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 106d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 107d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Returns a map from class fully qualified names to {@link ViewData} objects */ 108d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private Map<String, ViewData> getClassToView() { 109d5cd92b446e43e8de625142415f560ee54636317Tor Norbye if (mClassToView == null) { 110d5cd92b446e43e8de625142415f560ee54636317Tor Norbye int initialSize = 75; 111d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mClassToView = new HashMap<String, ViewData>(initialSize); 112d5cd92b446e43e8de625142415f560ee54636317Tor Norbye List<CategoryData> categories = getCategories(); 113d5cd92b446e43e8de625142415f560ee54636317Tor Norbye for (CategoryData category : categories) { 114d5cd92b446e43e8de625142415f560ee54636317Tor Norbye for (ViewData view : category) { 115d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mClassToView.put(view.getFcqn(), view); 116d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 117d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 118d5cd92b446e43e8de625142415f560ee54636317Tor Norbye assert mClassToView.size() <= initialSize; 119d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 120d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 121d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mClassToView; 122d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 123d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 1240ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** 1250ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * Returns an XML document containing rendering configurations for the various Android 1260ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * views. The FQN of each view can be obtained via the 1270ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * {@link #getFullClassName(Element)} method 1280ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * 1290ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @return an XML document containing rendering elements 1300ac475d29f793079783f501126239ed6ce8aa31dTor Norbye */ 1310ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public Document getRenderingConfigDoc() { 1320ac475d29f793079783f501126239ed6ce8aa31dTor Norbye DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 1330ac475d29f793079783f501126239ed6ce8aa31dTor Norbye Class<ViewMetadataRepository> clz = ViewMetadataRepository.class; 1340ac475d29f793079783f501126239ed6ce8aa31dTor Norbye InputStream paletteStream = clz.getResourceAsStream(PREVIEW_CONFIG_FILENAME); 1350ac475d29f793079783f501126239ed6ce8aa31dTor Norbye InputSource is = new InputSource(paletteStream); 1360ac475d29f793079783f501126239ed6ce8aa31dTor Norbye try { 1370ac475d29f793079783f501126239ed6ce8aa31dTor Norbye factory.setNamespaceAware(true); 1380ac475d29f793079783f501126239ed6ce8aa31dTor Norbye factory.setValidating(false); 1396feca9ac5f8add768fef2bc2dc1382a68c158d42Tor Norbye factory.setIgnoringComments(true); 1400ac475d29f793079783f501126239ed6ce8aa31dTor Norbye DocumentBuilder builder = factory.newDocumentBuilder(); 1410ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return builder.parse(is); 1420ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } catch (Exception e) { 1430ac475d29f793079783f501126239ed6ce8aa31dTor Norbye AdtPlugin.log(e, "Parsing palette file failed"); 1440ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return null; 145ec7301a7433cf89c399fa3c507afe8a147adbcbaTor Norbye } finally { 146ec7301a7433cf89c399fa3c507afe8a147adbcbaTor Norbye Closeables.closeQuietly(paletteStream); 1470ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1480ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1490ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 1500ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** 1510ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * Returns a fully qualified class name for an element in the rendering document 1520ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * returned by {@link #getRenderingConfigDoc()} 1530ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * 1540ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @param element the element to look up the fqcn for 1550ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @return the fqcn of the view the element represents a preview for 1560ac475d29f793079783f501126239ed6ce8aa31dTor Norbye */ 1570ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public String getFullClassName(Element element) { 1580ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // We don't use the element tag name, because in some cases we have 1590ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // an outer element to render some interesting inner element, such as a tab widget 1600ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // (which must be rendered inside a tab host). 1610ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // 1620ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // Therefore, we instead use the convention that the id is the fully qualified 1630ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // class name, with .'s replaced with _'s. 1640ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 1650ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // Special case: for tab host we aren't allowed to mess with the id 1660ac475d29f793079783f501126239ed6ce8aa31dTor Norbye String id = element.getAttributeNS(ANDROID_URI, ATTR_ID); 1670ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 1680ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if ("@android:id/tabhost".equals(id)) { 1690ac475d29f793079783f501126239ed6ce8aa31dTor Norbye // Special case to distinguish TabHost and TabWidget 1700ac475d29f793079783f501126239ed6ce8aa31dTor Norbye NodeList children = element.getChildNodes(); 1710ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if (children.getLength() > 1 && (children.item(1) instanceof Element)) { 1720ac475d29f793079783f501126239ed6ce8aa31dTor Norbye Element child = (Element) children.item(1); 1730ac475d29f793079783f501126239ed6ce8aa31dTor Norbye String childId = child.getAttributeNS(ANDROID_URI, ATTR_ID); 1740ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if ("@+id/android_widget_TabWidget".equals(childId)) { 1750ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return "android.widget.TabWidget"; // TODO: Tab widget! 1760ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1770ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1780ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return "android.widget.TabHost"; // TODO: Tab widget! 1790ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1800ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 1810ac475d29f793079783f501126239ed6ce8aa31dTor Norbye StringBuilder sb = new StringBuilder(); 1820ac475d29f793079783f501126239ed6ce8aa31dTor Norbye int i = 0; 1830ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if (id.startsWith(NEW_ID_PREFIX)) { 1840ac475d29f793079783f501126239ed6ce8aa31dTor Norbye i = NEW_ID_PREFIX.length(); 1850ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } else if (id.startsWith(ID_PREFIX)) { 1860ac475d29f793079783f501126239ed6ce8aa31dTor Norbye i = ID_PREFIX.length(); 1870ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1880ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 1890ac475d29f793079783f501126239ed6ce8aa31dTor Norbye for (; i < id.length(); i++) { 1900ac475d29f793079783f501126239ed6ce8aa31dTor Norbye char c = id.charAt(i); 1910ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if (c == '_') { 1920ac475d29f793079783f501126239ed6ce8aa31dTor Norbye sb.append('.'); 1930ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } else { 1940ac475d29f793079783f501126239ed6ce8aa31dTor Norbye sb.append(c); 1950ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1960ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 1970ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 1980ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return sb.toString(); 1990ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 2000ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 201d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Returns an ordered list of categories and views, parsed from a metadata file */ 202c7df8d23830cc48f5741d44e2a978fc9ca52b003Tor Norbye @SuppressWarnings("resource") // streams passed to parser InputSource closed by parser 203d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private List<CategoryData> getCategories() { 204d5cd92b446e43e8de625142415f560ee54636317Tor Norbye if (mCategories == null) { 205d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mCategories = new ArrayList<CategoryData>(); 206d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 207d5cd92b446e43e8de625142415f560ee54636317Tor Norbye DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 2080ac475d29f793079783f501126239ed6ce8aa31dTor Norbye Class<ViewMetadataRepository> clz = ViewMetadataRepository.class; 2090ac475d29f793079783f501126239ed6ce8aa31dTor Norbye InputStream inputStream = clz.getResourceAsStream(METADATA_FILENAME); 210d5cd92b446e43e8de625142415f560ee54636317Tor Norbye InputSource is = new InputSource(new BufferedInputStream(inputStream)); 211d5cd92b446e43e8de625142415f560ee54636317Tor Norbye try { 212d5cd92b446e43e8de625142415f560ee54636317Tor Norbye factory.setNamespaceAware(true); 213d5cd92b446e43e8de625142415f560ee54636317Tor Norbye factory.setValidating(false); 2146feca9ac5f8add768fef2bc2dc1382a68c158d42Tor Norbye factory.setIgnoringComments(true); 215d5cd92b446e43e8de625142415f560ee54636317Tor Norbye DocumentBuilder builder = factory.newDocumentBuilder(); 216d5cd92b446e43e8de625142415f560ee54636317Tor Norbye Document document = builder.parse(is); 217d5cd92b446e43e8de625142415f560ee54636317Tor Norbye Map<String, FillPreference> fillTypes = new HashMap<String, FillPreference>(); 218d5cd92b446e43e8de625142415f560ee54636317Tor Norbye for (FillPreference pref : FillPreference.values()) { 21918bce12c5916331971b2e8108f8485cc56b696d3Tor Norbye fillTypes.put(pref.toString().toLowerCase(Locale.US), pref); 220d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 221d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 222d5cd92b446e43e8de625142415f560ee54636317Tor Norbye NodeList categoryNodes = document.getDocumentElement().getChildNodes(); 223d5cd92b446e43e8de625142415f560ee54636317Tor Norbye for (int i = 0, n = categoryNodes.getLength(); i < n; i++) { 224d5cd92b446e43e8de625142415f560ee54636317Tor Norbye Node node = categoryNodes.item(i); 225d5cd92b446e43e8de625142415f560ee54636317Tor Norbye if (node.getNodeType() == Node.ELEMENT_NODE) { 226d5cd92b446e43e8de625142415f560ee54636317Tor Norbye Element element = (Element) node; 227d5cd92b446e43e8de625142415f560ee54636317Tor Norbye if (element.getNodeName().equals("category")) { //$NON-NLS-1$ 228d5cd92b446e43e8de625142415f560ee54636317Tor Norbye String name = element.getAttribute("name"); //$NON-NLS-1$ 229d5cd92b446e43e8de625142415f560ee54636317Tor Norbye CategoryData category = new CategoryData(name); 230d5cd92b446e43e8de625142415f560ee54636317Tor Norbye NodeList children = element.getChildNodes(); 231d5cd92b446e43e8de625142415f560ee54636317Tor Norbye for (int j = 0, m = children.getLength(); j < m; j++) { 232d5cd92b446e43e8de625142415f560ee54636317Tor Norbye Node childNode = children.item(j); 233d5cd92b446e43e8de625142415f560ee54636317Tor Norbye if (childNode.getNodeType() == Node.ELEMENT_NODE) { 234d5cd92b446e43e8de625142415f560ee54636317Tor Norbye Element child = (Element) childNode; 235e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye ViewData view = createViewData(fillTypes, child, 236429ae88878cf781753d8261d350ad89fe5864169Tor Norbye null, FillPreference.NONE, RenderMode.NORMAL, null); 237d5cd92b446e43e8de625142415f560ee54636317Tor Norbye category.addView(view); 238d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 239d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 240d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mCategories.add(category); 241d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 242d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 243d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 244d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } catch (Exception e) { 245d5cd92b446e43e8de625142415f560ee54636317Tor Norbye AdtPlugin.log(e, "Invalid palette metadata"); //$NON-NLS-1$ 246d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 247d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 248d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 249d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mCategories; 250d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 251d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 252e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private ViewData createViewData(Map<String, FillPreference> fillTypes, 253e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Element child, String defaultFqcn, FillPreference defaultFill, 254429ae88878cf781753d8261d350ad89fe5864169Tor Norbye RenderMode defaultRender, String defaultSize) { 255e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String fqcn = child.getAttribute("class"); //$NON-NLS-1$ 256e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (fqcn.length() == 0) { 257e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye fqcn = defaultFqcn; 258e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 259e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String fill = child.getAttribute("fill"); //$NON-NLS-1$ 260e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye FillPreference fillPreference = null; 261e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (fill.length() > 0) { 262e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye fillPreference = fillTypes.get(fill); 263e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 264e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (fillPreference == null) { 265e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye fillPreference = defaultFill; 266e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 267e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String skip = child.getAttribute("skip"); //$NON-NLS-1$ 268e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye RenderMode renderMode = defaultRender; 269e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String render = child.getAttribute("render"); //$NON-NLS-1$ 270e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (render.length() > 0) { 271e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye renderMode = RenderMode.get(render); 272e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 273e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String displayName = child.getAttribute("name"); //$NON-NLS-1$ 274e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (displayName.length() == 0) { 275e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye displayName = null; 276e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 277429ae88878cf781753d8261d350ad89fe5864169Tor Norbye 278e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String relatedTo = child.getAttribute("relatedTo"); //$NON-NLS-1$ 279e287bc8580e19d72a911615475b353790cf000ebTor Norbye String topAttrs = child.getAttribute("topAttrs"); //$NON-NLS-1$ 280429ae88878cf781753d8261d350ad89fe5864169Tor Norbye String resize = child.getAttribute("resize"); //$NON-NLS-1$ 281e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye ViewData view = new ViewData(fqcn, displayName, fillPreference, 282e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye skip.length() == 0 ? false : Boolean.valueOf(skip), 283e287bc8580e19d72a911615475b353790cf000ebTor Norbye renderMode, relatedTo, resize, topAttrs); 284e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 285e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String init = child.getAttribute("init"); //$NON-NLS-1$ 286e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String icon = child.getAttribute("icon"); //$NON-NLS-1$ 287e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 288e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye view.setInitString(init); 289e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (icon.length() > 0) { 290e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye view.setIconName(icon); 291e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 292e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 293e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // Nested variations? 294e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (child.hasChildNodes()) { 295e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // Palette variations 296e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye NodeList childNodes = child.getChildNodes(); 297e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye for (int k = 0, kl = childNodes.getLength(); k < kl; k++) { 298e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Node variationNode = childNodes.item(k); 299e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (variationNode.getNodeType() == Node.ELEMENT_NODE) { 300e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Element variation = (Element) variationNode; 301e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye ViewData variationView = createViewData(fillTypes, variation, 302429ae88878cf781753d8261d350ad89fe5864169Tor Norbye fqcn, fillPreference, renderMode, resize); 303e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye view.addVariation(variationView); 304e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 305e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 306e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 307e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 308e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye return view; 309e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 310e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 311d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** 312d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Computes the palette entries for the given {@link AndroidTargetData}, looking up the 313d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * available node descriptors, categorizing and sorting them. 314d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * 315d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * @param targetData the target data for which to compute palette entries 3160ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @param alphabetical if true, sort all items in alphabetical order 3170ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @param createCategories if true, organize the items into categories 318d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * @return a list of pairs where each pair contains of the category label and an 319d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * ordered list of elements to be included in that category 320d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 321d5cd92b446e43e8de625142415f560ee54636317Tor Norbye public List<Pair<String, List<ViewElementDescriptor>>> getPaletteEntries( 3220ac475d29f793079783f501126239ed6ce8aa31dTor Norbye AndroidTargetData targetData, boolean alphabetical, boolean createCategories) { 323d5cd92b446e43e8de625142415f560ee54636317Tor Norbye List<Pair<String, List<ViewElementDescriptor>>> result = 324d5cd92b446e43e8de625142415f560ee54636317Tor Norbye new ArrayList<Pair<String, List<ViewElementDescriptor>>>(); 325d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 326d5cd92b446e43e8de625142415f560ee54636317Tor Norbye List<List<ViewElementDescriptor>> lists = new ArrayList<List<ViewElementDescriptor>>(2); 327d5cd92b446e43e8de625142415f560ee54636317Tor Norbye LayoutDescriptors layoutDescriptors = targetData.getLayoutDescriptors(); 328d5cd92b446e43e8de625142415f560ee54636317Tor Norbye lists.add(layoutDescriptors.getViewDescriptors()); 329d5cd92b446e43e8de625142415f560ee54636317Tor Norbye lists.add(layoutDescriptors.getLayoutDescriptors()); 330d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 331e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // First record map of FQCN to ViewElementDescriptor such that we can quickly 332e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // determine if a particular palette entry is available 333e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Map<String, ViewElementDescriptor> fqcnToDescriptor = 334e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye new HashMap<String, ViewElementDescriptor>(); 335d5cd92b446e43e8de625142415f560ee54636317Tor Norbye for (List<ViewElementDescriptor> list : lists) { 336d5cd92b446e43e8de625142415f560ee54636317Tor Norbye for (ViewElementDescriptor view : list) { 337e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String fqcn = view.getFullClassName(); 338e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (fqcn == null) { 339e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // <view> and <merge> tags etc 340e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye fqcn = view.getUiName(); 341d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 342e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye fqcnToDescriptor.put(fqcn, view); 343e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 344e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 345d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 346e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Set<ViewElementDescriptor> remaining = new HashSet<ViewElementDescriptor>( 347e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye layoutDescriptors.getViewDescriptors().size() 348e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye + layoutDescriptors.getLayoutDescriptors().size()); 349e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye remaining.addAll(layoutDescriptors.getViewDescriptors()); 350e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye remaining.addAll(layoutDescriptors.getLayoutDescriptors()); 351d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 352e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // Now iterate in palette metadata order over the items in the palette and include 353e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // any that also appear as a descriptor 354e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye List<ViewElementDescriptor> categoryItems = new ArrayList<ViewElementDescriptor>(); 355e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye for (CategoryData category : getCategories()) { 356e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (createCategories) { 357e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye categoryItems = new ArrayList<ViewElementDescriptor>(); 358e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 359e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye for (ViewData view : category) { 360e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String fqcn = view.getFcqn(); 361e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye ViewElementDescriptor descriptor = fqcnToDescriptor.get(fqcn); 362e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (descriptor != null) { 363ec22f92d53f4bb74313b91aa491acbfbbb6dc9ceTor Norbye remaining.remove(descriptor); 364ec22f92d53f4bb74313b91aa491acbfbbb6dc9ceTor Norbye if (view.getSkip()) { 365ec22f92d53f4bb74313b91aa491acbfbbb6dc9ceTor Norbye continue; 366ec22f92d53f4bb74313b91aa491acbfbbb6dc9ceTor Norbye } 367ec22f92d53f4bb74313b91aa491acbfbbb6dc9ceTor Norbye 368e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (view.getDisplayName() != null || view.getInitString().length() > 0) { 369e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye categoryItems.add(new PaletteMetadataDescriptor(descriptor, 370e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye view.getDisplayName(), view.getInitString(), view.getIconName())); 371e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } else { 372e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye categoryItems.add(descriptor); 373e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 374e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 375e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (view.hasVariations()) { 376e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye for (ViewData variation : view.getVariations()) { 377e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String init = variation.getInitString(); 378e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye String icon = variation.getIconName(); 379e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye ViewElementDescriptor desc = new PaletteMetadataDescriptor(descriptor, 380e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye variation.getDisplayName(), init, icon); 381e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye categoryItems.add(desc); 382e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 383e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 384e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 385d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 386d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 387e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (createCategories && categoryItems.size() > 0) { 388e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (alphabetical) { 389e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Collections.sort(categoryItems); 390e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 391e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye result.add(Pair.of(category.getName(), categoryItems)); 3920ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 3930ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 3940ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 395e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (remaining.size() > 0) { 396e287bc8580e19d72a911615475b353790cf000ebTor Norbye List<ViewElementDescriptor> otherItems = 397e287bc8580e19d72a911615475b353790cf000ebTor Norbye new ArrayList<ViewElementDescriptor>(remaining); 398e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye // Always sorted, we don't have a natural order for these unknowns 399e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Collections.sort(otherItems); 400e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (createCategories) { 401e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye result.add(Pair.of("Other", otherItems)); 402e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } else { 403e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye categoryItems.addAll(otherItems); 404d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 405e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 406d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 407e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (!createCategories) { 4080ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if (alphabetical) { 409e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye Collections.sort(categoryItems); 4100ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 411e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye result.add(Pair.of("Views", categoryItems)); 412d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 413d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 414d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return result; 415d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 416d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 4170757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye @VisibleForTesting 4180757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye Collection<String> getAllFqcns() { 4190757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye return getClassToView().keySet(); 4200757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 4210757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye 422d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** 423d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Metadata holder for a particular category - contains the name of the category, its 424d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * ordinal (for natural/logical sorting order) and views contained in the category 425d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 426d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private static class CategoryData implements Iterable<ViewData>, Comparable<CategoryData> { 427d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Category name */ 428d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private final String mName; 429d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Views included in this category */ 430d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private final List<ViewData> mViews = new ArrayList<ViewData>(); 431d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Natural ordering rank */ 432d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private final int mOrdinal = sNextOrdinal++; 433d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 434d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Constructs a new category with the given name */ 435d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private CategoryData(String name) { 436d5cd92b446e43e8de625142415f560ee54636317Tor Norbye super(); 437d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mName = name; 438d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 439d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 440d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Adds a new view into this category */ 441d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private void addView(ViewData view) { 442d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mViews.add(view); 443d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 444d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 445d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private String getName() { 446d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mName; 447d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 448d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 449d5cd92b446e43e8de625142415f560ee54636317Tor Norbye // Implements Iterable<ViewData> such that we can use for-each on the category to 450d5cd92b446e43e8de625142415f560ee54636317Tor Norbye // enumerate its views 451ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 452d5cd92b446e43e8de625142415f560ee54636317Tor Norbye public Iterator<ViewData> iterator() { 453d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mViews.iterator(); 454d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 455d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 456d5cd92b446e43e8de625142415f560ee54636317Tor Norbye // Implements Comparable<CategoryData> such that categories can be naturally sorted 457ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 458d5cd92b446e43e8de625142415f560ee54636317Tor Norbye public int compareTo(CategoryData other) { 459d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mOrdinal - other.mOrdinal; 460d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 461d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 462d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 463d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Metadata holder for a view of a given fully qualified class name */ 464d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private static class ViewData implements Comparable<ViewData> { 465d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** The fully qualified class name of the view */ 466d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private final String mFqcn; 467d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Fill preference of the view */ 468d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private final FillPreference mFillPreference; 4690ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** Skip this item in the palette? */ 4700ac475d29f793079783f501126239ed6ce8aa31dTor Norbye private final boolean mSkip; 4710ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** Must this item be rendered alone? skipped? etc */ 4720ac475d29f793079783f501126239ed6ce8aa31dTor Norbye private final RenderMode mRenderMode; 4730757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye /** Related views */ 4740757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye private final String mRelatedTo; 475d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** The relative rank of the view for natural ordering */ 476d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private final int mOrdinal = sNextOrdinal++; 477e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye /** List of optional variations */ 478e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private List<ViewData> mVariations; 479e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye /** Display name. Can be null. */ 480e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private String mDisplayName; 481e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye /** 482e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye * Optional initialization string - a comma separate set of name/value pairs to 483e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye * initialize the element with 484e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye */ 485e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private String mInitString; 486e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye /** The name of an icon (known to the {@link IconFactory} to show for this view */ 487e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private String mIconName; 488429ae88878cf781753d8261d350ad89fe5864169Tor Norbye /** The resize preference of this view */ 489429ae88878cf781753d8261d350ad89fe5864169Tor Norbye private String mResize; 490e287bc8580e19d72a911615475b353790cf000ebTor Norbye /** The most commonly set attributes of this view */ 491e287bc8580e19d72a911615475b353790cf000ebTor Norbye private String mTopAttrs; 492d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 493d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Constructs a new view data for the given class */ 494e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private ViewData(String fqcn, String displayName, 4950757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye FillPreference fillPreference, boolean skip, RenderMode renderMode, 496e287bc8580e19d72a911615475b353790cf000ebTor Norbye String relatedTo, String resize, String topAttrs) { 497d5cd92b446e43e8de625142415f560ee54636317Tor Norbye super(); 498d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mFqcn = fqcn; 499e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye mDisplayName = displayName; 500d5cd92b446e43e8de625142415f560ee54636317Tor Norbye mFillPreference = fillPreference; 5010ac475d29f793079783f501126239ed6ce8aa31dTor Norbye mSkip = skip; 5020ac475d29f793079783f501126239ed6ce8aa31dTor Norbye mRenderMode = renderMode; 5030757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye mRelatedTo = relatedTo; 504429ae88878cf781753d8261d350ad89fe5864169Tor Norbye mResize = resize; 505e287bc8580e19d72a911615475b353790cf000ebTor Norbye mTopAttrs = topAttrs; 506d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 507d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 508d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Returns the {@link FillPreference} for views of this type */ 509d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private FillPreference getFillPreference() { 510d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mFillPreference; 511d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 512d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 513d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** Fully qualified class name of views of this type */ 514d5cd92b446e43e8de625142415f560ee54636317Tor Norbye private String getFcqn() { 515d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mFqcn; 516d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 517d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 518e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private String getDisplayName() { 519e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye return mDisplayName; 520d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 521d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 522429ae88878cf781753d8261d350ad89fe5864169Tor Norbye private String getResize() { 523429ae88878cf781753d8261d350ad89fe5864169Tor Norbye return mResize; 524429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } 525429ae88878cf781753d8261d350ad89fe5864169Tor Norbye 526d5cd92b446e43e8de625142415f560ee54636317Tor Norbye // Implements Comparable<ViewData> such that views can be sorted naturally 527ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 528d5cd92b446e43e8de625142415f560ee54636317Tor Norbye public int compareTo(ViewData other) { 529d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return mOrdinal - other.mOrdinal; 530d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 5310ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 5320ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public RenderMode getRenderMode() { 5330ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return mRenderMode; 5340ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 5350ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 5360ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public boolean getSkip() { 5370ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return mSkip; 5380ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 5390757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye 5400757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye public List<String> getRelatedTo() { 5410757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye if (mRelatedTo == null || mRelatedTo.length() == 0) { 5420757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye return Collections.emptyList(); 5430757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } else { 5440757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye List<String> result = new ArrayList<String>(); 5450757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye ViewMetadataRepository repository = ViewMetadataRepository.get(); 5460757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye Map<String, ViewData> classToView = repository.getClassToView(); 5470757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye 5480757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye List<String> fqns = new ArrayList<String>(classToView.keySet()); 5496cb5c7f7141a08fd355bb92c6a4153140400890bTor Norbye for (String basename : Splitter.on(',').split(mRelatedTo)) { 5500757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye boolean found = false; 5510757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye for (String fqcn : fqns) { 5520757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye String suffix = '.' + basename; 5530757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye if (fqcn.endsWith(suffix)) { 5540757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye result.add(fqcn); 5550757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye found = true; 5560757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye break; 5570757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 5580757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 55947412b5c2252df2624e5ff4ad2f9054af86c5065Tor Norbye if (basename.equals(VIEW_FRAGMENT) || basename.equals(VIEW_INCLUDE)) { 56047412b5c2252df2624e5ff4ad2f9054af86c5065Tor Norbye result.add(basename); 56147412b5c2252df2624e5ff4ad2f9054af86c5065Tor Norbye } else { 56247412b5c2252df2624e5ff4ad2f9054af86c5065Tor Norbye assert found : basename; 56347412b5c2252df2624e5ff4ad2f9054af86c5065Tor Norbye } 5640757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 5650757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye 5660757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye return result; 5670757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 5680757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 569e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 570e287bc8580e19d72a911615475b353790cf000ebTor Norbye public List<String> getTopAttributes() { 571e287bc8580e19d72a911615475b353790cf000ebTor Norbye // "id" is a top attribute for all views, so it is not included in the XML, we just 572e287bc8580e19d72a911615475b353790cf000ebTor Norbye // add it in dynamically here 573e287bc8580e19d72a911615475b353790cf000ebTor Norbye if (mTopAttrs == null || mTopAttrs.length() == 0) { 574e287bc8580e19d72a911615475b353790cf000ebTor Norbye return Collections.singletonList(ATTR_ID); 575e287bc8580e19d72a911615475b353790cf000ebTor Norbye } else { 576e287bc8580e19d72a911615475b353790cf000ebTor Norbye String[] split = mTopAttrs.split(","); //$NON-NLS-1$ 577e287bc8580e19d72a911615475b353790cf000ebTor Norbye List<String> topAttributes = new ArrayList<String>(split.length + 1); 578e287bc8580e19d72a911615475b353790cf000ebTor Norbye topAttributes.add(ATTR_ID); 579e287bc8580e19d72a911615475b353790cf000ebTor Norbye for (int i = 0, n = split.length; i < n; i++) { 580e287bc8580e19d72a911615475b353790cf000ebTor Norbye topAttributes.add(split[i]); 581e287bc8580e19d72a911615475b353790cf000ebTor Norbye } 582e287bc8580e19d72a911615475b353790cf000ebTor Norbye return Collections.<String>unmodifiableList(topAttributes); 583e287bc8580e19d72a911615475b353790cf000ebTor Norbye } 584e287bc8580e19d72a911615475b353790cf000ebTor Norbye } 585e287bc8580e19d72a911615475b353790cf000ebTor Norbye 586e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye void addVariation(ViewData variation) { 587e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye if (mVariations == null) { 588e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye mVariations = new ArrayList<ViewData>(4); 589e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 590e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye mVariations.add(variation); 591e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 592e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 593e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye List<ViewData> getVariations() { 594e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye return mVariations; 595e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 596e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 597e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye boolean hasVariations() { 598e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye return mVariations != null && mVariations.size() > 0; 599e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 600e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 601e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private void setInitString(String initString) { 602e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye this.mInitString = initString; 603e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 604e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 605e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private String getInitString() { 606e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye return mInitString; 607e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 608e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 609e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private void setIconName(String iconName) { 610e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye this.mIconName = iconName; 611e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 612e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye 613e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye private String getIconName() { 614e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye return mIconName; 615e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye } 616d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 617d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 618d5cd92b446e43e8de625142415f560ee54636317Tor Norbye /** 619d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * Returns the {@link FillPreference} for classes with the given fully qualified class 620d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * name 621d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * 622d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * @param fqcn the fully qualified class name of the view 623d5cd92b446e43e8de625142415f560ee54636317Tor Norbye * @return a suitable {@link FillPreference} for the given view type 624d5cd92b446e43e8de625142415f560ee54636317Tor Norbye */ 625d5cd92b446e43e8de625142415f560ee54636317Tor Norbye public FillPreference getFillPreference(String fqcn) { 626d5cd92b446e43e8de625142415f560ee54636317Tor Norbye ViewData view = getClassToView().get(fqcn); 627d5cd92b446e43e8de625142415f560ee54636317Tor Norbye if (view != null) { 628d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return view.getFillPreference(); 629d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 630d5cd92b446e43e8de625142415f560ee54636317Tor Norbye 631d5cd92b446e43e8de625142415f560ee54636317Tor Norbye return FillPreference.NONE; 632d5cd92b446e43e8de625142415f560ee54636317Tor Norbye } 6330ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 6340ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** 6350ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * Returns the {@link RenderMode} for classes with the given fully qualified class 6360ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * name 6370ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * 6380ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @param fqcn the fully qualified class name 6390ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @return the {@link RenderMode} to use for previews of the given view type 6400ac475d29f793079783f501126239ed6ce8aa31dTor Norbye */ 6410ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public RenderMode getRenderMode(String fqcn) { 6420ac475d29f793079783f501126239ed6ce8aa31dTor Norbye ViewData view = getClassToView().get(fqcn); 6430ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if (view != null) { 6440ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return view.getRenderMode(); 6450ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 6460ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 647e7abbed2fe84c25bcd6d68cef4140963c10a1e5dTor Norbye return RenderMode.NORMAL; 6480ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 6490ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 6500ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** 651429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * Returns the {@link ResizePolicy} for the given class. 652429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * 653429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * @param fqcn the fully qualified class name of the target widget 654429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * @return the {@link ResizePolicy} for the widget, which will never be null (but may 655429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * be the default of {@link ResizePolicy#full()} if no metadata is found for 656429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * the given widget) 657429ae88878cf781753d8261d350ad89fe5864169Tor Norbye */ 658429ae88878cf781753d8261d350ad89fe5864169Tor Norbye public ResizePolicy getResizePolicy(String fqcn) { 659429ae88878cf781753d8261d350ad89fe5864169Tor Norbye ViewData view = getClassToView().get(fqcn); 660429ae88878cf781753d8261d350ad89fe5864169Tor Norbye if (view != null) { 661429ae88878cf781753d8261d350ad89fe5864169Tor Norbye String resize = view.getResize(); 662429ae88878cf781753d8261d350ad89fe5864169Tor Norbye if (resize != null && resize.length() > 0) { 663429ae88878cf781753d8261d350ad89fe5864169Tor Norbye if ("full".equals(resize)) { //$NON-NLS-1$ 664429ae88878cf781753d8261d350ad89fe5864169Tor Norbye return ResizePolicy.full(); 665429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } else if ("none".equals(resize)) { //$NON-NLS-1$ 666429ae88878cf781753d8261d350ad89fe5864169Tor Norbye return ResizePolicy.none(); 667429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } else if ("horizontal".equals(resize)) { //$NON-NLS-1$ 668429ae88878cf781753d8261d350ad89fe5864169Tor Norbye return ResizePolicy.horizontal(); 669429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } else if ("vertical".equals(resize)) { //$NON-NLS-1$ 670429ae88878cf781753d8261d350ad89fe5864169Tor Norbye return ResizePolicy.vertical(); 671429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } else if ("scaled".equals(resize)) { //$NON-NLS-1$ 672429ae88878cf781753d8261d350ad89fe5864169Tor Norbye return ResizePolicy.scaled(); 673429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } else { 674429ae88878cf781753d8261d350ad89fe5864169Tor Norbye assert false : resize; 675429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } 676429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } 677429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } 678429ae88878cf781753d8261d350ad89fe5864169Tor Norbye 679429ae88878cf781753d8261d350ad89fe5864169Tor Norbye return ResizePolicy.full(); 680429ae88878cf781753d8261d350ad89fe5864169Tor Norbye } 681429ae88878cf781753d8261d350ad89fe5864169Tor Norbye 682429ae88878cf781753d8261d350ad89fe5864169Tor Norbye /** 6830ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * Returns true if classes with the given fully qualified class name should be hidden 6840ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * or skipped from the palette 6850ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * 6860ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @param fqcn the fully qualified class name 6870ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * @return true if views of the given type should be hidden from the palette 6880ac475d29f793079783f501126239ed6ce8aa31dTor Norbye */ 6890ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public boolean getSkip(String fqcn) { 6900ac475d29f793079783f501126239ed6ce8aa31dTor Norbye ViewData view = getClassToView().get(fqcn); 6910ac475d29f793079783f501126239ed6ce8aa31dTor Norbye if (view != null) { 6920ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return view.getSkip(); 6930ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 6940ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 6950ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return false; 6960ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 6970ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 6980757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye /** 699e287bc8580e19d72a911615475b353790cf000ebTor Norbye * Returns a list of the top (most commonly set) attributes of the given 700e287bc8580e19d72a911615475b353790cf000ebTor Norbye * view. 701e287bc8580e19d72a911615475b353790cf000ebTor Norbye * 702e287bc8580e19d72a911615475b353790cf000ebTor Norbye * @param fqcn the fully qualified class name 703e287bc8580e19d72a911615475b353790cf000ebTor Norbye * @return a list, never null but possibly empty, of popular attribute names 704e287bc8580e19d72a911615475b353790cf000ebTor Norbye * (not including a namespace prefix) 705e287bc8580e19d72a911615475b353790cf000ebTor Norbye */ 706e287bc8580e19d72a911615475b353790cf000ebTor Norbye public List<String> getTopAttributes(String fqcn) { 707e287bc8580e19d72a911615475b353790cf000ebTor Norbye ViewData view = getClassToView().get(fqcn); 708e287bc8580e19d72a911615475b353790cf000ebTor Norbye if (view != null) { 709e287bc8580e19d72a911615475b353790cf000ebTor Norbye return view.getTopAttributes(); 710e287bc8580e19d72a911615475b353790cf000ebTor Norbye } 711e287bc8580e19d72a911615475b353790cf000ebTor Norbye 712e287bc8580e19d72a911615475b353790cf000ebTor Norbye return Collections.singletonList(ATTR_ID); 713e287bc8580e19d72a911615475b353790cf000ebTor Norbye } 714e287bc8580e19d72a911615475b353790cf000ebTor Norbye 715e287bc8580e19d72a911615475b353790cf000ebTor Norbye /** 7160757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye * Returns a set of fully qualified names for views that are closely related to the 7170757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye * given view 7180757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye * 7190757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye * @param fqcn the fully qualified class name 7200757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye * @return a list, never null but possibly empty, of views that are related to the 7210757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye * view of the given type 7220757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye */ 7230757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye public List<String> getRelatedTo(String fqcn) { 7240757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye ViewData view = getClassToView().get(fqcn); 7250757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye if (view != null) { 7260757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye return view.getRelatedTo(); 7270757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 7280757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye 7290757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye return Collections.emptyList(); 7300757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye } 7310757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye 7320ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** Render mode for palette preview */ 7330ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public enum RenderMode { 7340ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** 7350ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * Render previews, and it can be rendered as a sibling of many other views in a 7360ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * big linear layout 7370ac475d29f793079783f501126239ed6ce8aa31dTor Norbye */ 7380ac475d29f793079783f501126239ed6ce8aa31dTor Norbye NORMAL, 7390ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** This view needs to be rendered alone */ 7400ac475d29f793079783f501126239ed6ce8aa31dTor Norbye ALONE, 7410ac475d29f793079783f501126239ed6ce8aa31dTor Norbye /** 7420ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * Skip this element; it doesn't work or does not produce any visible artifacts 7430ac475d29f793079783f501126239ed6ce8aa31dTor Norbye * (such as the basic layouts) 7440ac475d29f793079783f501126239ed6ce8aa31dTor Norbye */ 7450ac475d29f793079783f501126239ed6ce8aa31dTor Norbye SKIP; 7460ac475d29f793079783f501126239ed6ce8aa31dTor Norbye 747e287bc8580e19d72a911615475b353790cf000ebTor Norbye /** 748e287bc8580e19d72a911615475b353790cf000ebTor Norbye * Returns the {@link RenderMode} for the given render XML attribute 749e287bc8580e19d72a911615475b353790cf000ebTor Norbye * value 750e287bc8580e19d72a911615475b353790cf000ebTor Norbye * 751e287bc8580e19d72a911615475b353790cf000ebTor Norbye * @param render the attribute value in the metadata XML file 752e287bc8580e19d72a911615475b353790cf000ebTor Norbye * @return a corresponding {@link RenderMode}, never null 753e287bc8580e19d72a911615475b353790cf000ebTor Norbye */ 7540ac475d29f793079783f501126239ed6ce8aa31dTor Norbye public static RenderMode get(String render) { 755e287bc8580e19d72a911615475b353790cf000ebTor Norbye if ("alone".equals(render)) { //$NON-NLS-1$ 7560ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return ALONE; 757e287bc8580e19d72a911615475b353790cf000ebTor Norbye } else if ("skip".equals(render)) { //$NON-NLS-1$ 7580ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return SKIP; 7590ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } else { 7600ac475d29f793079783f501126239ed6ce8aa31dTor Norbye return NORMAL; 7610ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 7620ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 7630ac475d29f793079783f501126239ed6ce8aa31dTor Norbye } 7640595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye 7650595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye /** 7660595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * Are insets supported yet? This flag indicates whether the {@link #getInsets} method 7670595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * can return valid data, such that clients can avoid doing any work computing the 7680595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * current theme or density if there's no chance that valid insets will be returned 7690595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye */ 7700595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye public static final boolean INSETS_SUPPORTED = false; 7710595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye 7720595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye /** 7730595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * Returns the insets of widgets with the given fully qualified name, in the given 7740595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * theme and the given screen density. 7750595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * 7760595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * @param fqcn the fully qualified name of the view 7770595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * @param density the screen density 7780595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * @param theme the theme name 7790595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * @return the insets of the visual bounds relative to the view info bounds, or null 7800595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye * if not known or if there are no insets 7810595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye */ 7820595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye public static Margins getInsets(String fqcn, Density density, String theme) { 7830595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (INSETS_SUPPORTED) { 7840595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Some sample data measured manually for common themes and widgets. 7850595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (fqcn.equals(FQCN_BUTTON)) { 7860595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (density == Density.HIGH) { 7870595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (theme.startsWith(HOLO_PREFIX)) { 7880595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Holo, Theme.Holo.Light, WVGA 7890595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(5, 5, 5, 5); 7900595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else { 7910595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, WVGA 7920595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(4, 4, 0, 7); 7930595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 7940595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else if (density == Density.MEDIUM) { 7950595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (theme.startsWith(HOLO_PREFIX)) { 7960595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Holo, Theme.Holo.Light, WVGA 7970595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(3, 3, 3, 3); 7980595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else { 7990595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, HVGA 8000595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(2, 2, 0, 4); 8010595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8020595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else if (density == Density.LOW) { 8030595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (theme.startsWith(HOLO_PREFIX)) { 8040595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Holo, Theme.Holo.Light, QVGA 8050595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(2, 2, 2, 2); 8060595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else { 8070595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, QVGA 8080595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(1, 3, 0, 4); 8090595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8100595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8110595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else if (fqcn.equals(FQCN_TOGGLE_BUTTON)) { 8120595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (density == Density.HIGH) { 8130595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (theme.startsWith(HOLO_PREFIX)) { 8140595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Holo, Theme.Holo.Light, WVGA 8150595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(5, 5, 5, 5); 8160595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else { 8170595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, WVGA 8180595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(2, 2, 0, 5); 8190595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8200595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else if (density == Density.MEDIUM) { 8210595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (theme.startsWith(HOLO_PREFIX)) { 8220595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Holo, Theme.Holo.Light, WVGA 8230595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(3, 3, 3, 3); 8240595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else { 8250595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, HVGA 8260595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(0, 1, 0, 3); 8270595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8280595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else if (density == Density.LOW) { 8290595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (theme.startsWith(HOLO_PREFIX)) { 8300595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Holo, Theme.Holo.Light, QVGA 8310595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(2, 2, 2, 2); 8320595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else { 8330595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, QVGA 8340595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(2, 2, 0, 4); 8350595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8360595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8370595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else if (fqcn.equals(FQCN_SPINNER)) { 8380595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (density == Density.HIGH) { 8390595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (!theme.startsWith(HOLO_PREFIX)) { 8400595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, WVGA 8410595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(3, 4, 2, 8); 8420595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } // Doesn't render on Holo! 8430595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } else if (density == Density.MEDIUM) { 8440595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye if (!theme.startsWith(HOLO_PREFIX)) { 8450595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye // Theme.Light, HVGA 8460595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return new Margins(1, 1, 0, 4); 8470595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8480595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8490595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8500595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8510595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye 8520595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye return null; 8530595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye } 8540595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye 8550595b4123048f53179b5c2c65cf88968ac488ad3Tor Norbye private static final String HOLO_PREFIX = "Theme.Holo"; //$NON-NLS-1$ 856d5cd92b446e43e8de625142415f560ee54636317Tor Norbye} 857