OSDN Git Service

Add palette variations of widgets
authorTor Norbye <tnorbye@google.com>
Mon, 31 Jan 2011 04:52:05 +0000 (20:52 -0800)
committerTor Norbye <tnorbye@google.com>
Thu, 3 Mar 2011 21:49:57 +0000 (13:49 -0800)
This changeset adds new items to the palette which are just variations
of an existing widget but with different initial attributes. In
particular:

* Instead of just LinearLayout there are two versions of it:
   LinearLayout (Vertical) and LinearLayout (Horizontal)

* The ProgressBar has 3 variations: Large, Small, and Horizontal.  The
  horizontal ProgressBar looks like the SeekBar, without at thumb, so
  the SeekBar is moved next to the progress bar.

* There is a new palette category, "Text Fields", which contains a
  number of different initializations of the EditText's "inputType"
  attribute - for textual and numeric passwords, for names and e-mail
  and postal addresses, for phone numbers, for negative and decimal
  numbers, etc.

* Since LinearLayout is so common, the outline handles it specially to
  ensure that we show a horizontal or a vertical icon depending on the
  orientation attribute of the specific element rather than the
  generic descriptor icon.

There are various changes to the palette icon preview and drag preview
etc to handle these changes. In particular, the category
initialization code had to be rewritten to be able to handle
variations (since for example the text field appears in multiple
categories, so the old assumption that each view had an assigned
category was no longer true.)

This changeset also extracts a constant for the "android:" literal
used in many places in the code, and renames the existing "android"
namespace constant.

Change-Id: Ibbc3dbd34c551594421c3de034cdccea6a66eba0

23 files changed:
eclipse/plugins/com.android.ide.eclipse.adt/icons/SearchView.png
eclipse/plugins/com.android.ide.eclipse.adt/icons/VerticalLinearLayout.png [new file with mode: 0644]
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtils.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ElementDescriptor.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteControl.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PreviewIconFactory.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/PaletteMetadataDescriptor.java [new file with mode: 0644]
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/extra-view-metadata.xml
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/rendering-configs.xml
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractIncludeRefactoring.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java

index c41a2cd..2b45fc2 100644 (file)
Binary files a/eclipse/plugins/com.android.ide.eclipse.adt/icons/SearchView.png and b/eclipse/plugins/com.android.ide.eclipse.adt/icons/SearchView.png differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/icons/VerticalLinearLayout.png b/eclipse/plugins/com.android.ide.eclipse.adt/icons/VerticalLinearLayout.png
new file mode 100644 (file)
index 0000000..e03c16e
Binary files /dev/null and b/eclipse/plugins/com.android.ide.eclipse.adt/icons/VerticalLinearLayout.png differ
index 97da864..a148836 100644 (file)
@@ -41,6 +41,7 @@ public class LayoutConstants {
     public static final String TABLE_LAYOUT = "TableLayout";            //$NON-NLS-1$
     public static final String TABLE_ROW = "TableRow";                  //$NON-NLS-1$
     public static final String LIST_VIEW = "ListView";                  //$NON-NLS-1$
+    public static final String EDIT_TEXT = "EditText";                  //$NON-NLS-1$
     public static final String GALLERY = "Gallery";                     //$NON-NLS-1$
     public static final String GRID_VIEW = "GridView";                  //$NON-NLS-1$
     public static final String SCROLL_VIEW = "ScrollView";              //$NON-NLS-1$
@@ -134,7 +135,9 @@ public class LayoutConstants {
     public static final String GRAVITY_VALUE_FILL = "fill";                           //$NON-NLS-1$
 
     /** The default prefix used for the {@link #ANDROID_URI} name space */
-    public static final String ANDROID_NS_PREFIX = "android"; //$NON-NLS-1$
+    public static final String ANDROID_NS_NAME = "android"; //$NON-NLS-1$
+    /** The default prefix used for the {@link #ANDROID_URI} name space including the colon  */
+    public static final String ANDROID_NS_NAME_PREFIX = "android:"; //$NON-NLS-1$
 
     /**
      * Namespace for the Android resource XML, i.e.
index 1fea25a..97ed5a6 100644 (file)
@@ -21,6 +21,7 @@ import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_BELOW;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_HEIGHT;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_WIDTH;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_TEXT;
+import static com.android.ide.common.layout.LayoutConstants.EDIT_TEXT;
 import static com.android.ide.common.layout.LayoutConstants.EXPANDABLE_LIST_VIEW;
 import static com.android.ide.common.layout.LayoutConstants.FQCN_ADAPTER_VIEW;
 import static com.android.ide.common.layout.LayoutConstants.GALLERY;
@@ -677,49 +678,53 @@ public final class DescriptorsUtils {
      * <p/>
      * This does not override attributes which are not empty.
      */
-    public static void setDefaultLayoutAttributes(UiElementNode ui_node, boolean updateLayout) {
+    public static void setDefaultLayoutAttributes(UiElementNode node, boolean updateLayout) {
         // if this ui_node is a layout and we're adding it to a document, use match_parent for
         // both W/H. Otherwise default to wrap_layout.
-        boolean fill = ui_node.getDescriptor().hasChildren() &&
-                       ui_node.getUiParent() instanceof UiDocumentNode;
-        ui_node.setAttributeValue(
+        ElementDescriptor descriptor = node.getDescriptor();
+        boolean fill = descriptor.hasChildren() &&
+                       node.getUiParent() instanceof UiDocumentNode;
+        node.setAttributeValue(
                 ATTR_LAYOUT_WIDTH,
                 SdkConstants.NS_RESOURCES,
                 fill ? VALUE_FILL_PARENT : VALUE_WRAP_CONTENT,
                 false /* override */);
-        ui_node.setAttributeValue(
+        node.setAttributeValue(
                 ATTR_LAYOUT_HEIGHT,
                 SdkConstants.NS_RESOURCES,
                 fill ? VALUE_FILL_PARENT : VALUE_WRAP_CONTENT,
                 false /* override */);
 
-        String widget_id = getFreeWidgetId(ui_node);
-        if (widget_id != null) {
-            ui_node.setAttributeValue(
+        String freeId = getFreeWidgetId(node);
+        if (freeId != null) {
+            node.setAttributeValue(
                     ATTR_ID,
                     SdkConstants.NS_RESOURCES,
-                    widget_id,
+                    freeId,
                     false /* override */);
         }
 
-        String widget_type = ui_node.getDescriptor().getUiName();
-        ui_node.setAttributeValue(
+        // Don't set default text value into edit texts - they typically start out blank
+        if (!descriptor.getXmlLocalName().equals(EDIT_TEXT)) {
+            String type = descriptor.getUiName();
+            node.setAttributeValue(
                 ATTR_TEXT,
                 SdkConstants.NS_RESOURCES,
-                widget_type,
+                type,
                 false /*override*/);
+        }
 
         if (updateLayout) {
-            UiElementNode ui_parent = ui_node.getUiParent();
-            if (ui_parent != null &&
-                    ui_parent.getDescriptor().getXmlLocalName().equals(
+            UiElementNode parent = node.getUiParent();
+            if (parent != null &&
+                    parent.getDescriptor().getXmlLocalName().equals(
                             RELATIVE_LAYOUT)) {
-                UiElementNode ui_previous = ui_node.getUiPreviousSibling();
-                if (ui_previous != null) {
-                    String id = ui_previous.getAttributeValue(ATTR_ID);
+                UiElementNode previous = node.getUiPreviousSibling();
+                if (previous != null) {
+                    String id = previous.getAttributeValue(ATTR_ID);
                     if (id != null && id.length() > 0) {
                         id = id.replace("@+", "@");                     //$NON-NLS-1$ //$NON-NLS-2$
-                        ui_node.setAttributeValue(
+                        node.setAttributeValue(
                                 ATTR_LAYOUT_BELOW,
                                 SdkConstants.NS_RESOURCES,
                                 id,
index f4cb251..793ea14 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.ide.eclipse.adt.internal.editors.descriptors;
 
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME_PREFIX;
+
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.IconFactory;
 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
@@ -210,7 +212,7 @@ public class ElementDescriptor implements Comparable<ElementDescriptor> {
      */
     public final String getNamespace() {
         // For now we hard-code the prefix as being "android"
-        if (mXmlName.startsWith("android:")) { //$NON-NLs-1$
+        if (mXmlName.startsWith(ANDROID_NS_NAME_PREFIX)) {
             return SdkConstants.NS_RESOURCES;
         }
 
index d82774d..3c5cea4 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.ide.eclipse.adt.internal.editors.layout.configuration;
 
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME_PREFIX;
+
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.ide.common.sdk.LoadStatus;
@@ -1964,9 +1966,9 @@ public class ConfigurationComposite extends Composite {
                 }
 
                 // check for framework identifier.
-                if (parentStyle.startsWith("android:")) {
+                if (parentStyle.startsWith(ANDROID_NS_NAME_PREFIX)) {
                     frameworkStyle = true;
-                    parentStyle = parentStyle.substring("android:".length());
+                    parentStyle = parentStyle.substring(ANDROID_NS_NAME_PREFIX.length());
                 }
 
                 // at this point we could have the format style/<name>. we want only the name
index b1b7754..41b07b5 100644 (file)
@@ -47,13 +47,13 @@ import org.eclipse.swt.graphics.Image;
  *
  * @see ElementDescriptor
  */
-public final class ViewElementDescriptor extends ElementDescriptor {
+public class ViewElementDescriptor extends ElementDescriptor {
 
     /** The full class name (FQCN) of this view. */
-    private String mFullClassName;
+    private final String mFullClassName;
 
     /** The list of layout attributes. Can be empty but not null. */
-    private AttributeDescriptor[] mLayoutAttributes;
+    private final AttributeDescriptor[] mLayoutAttributes;
 
     /** The super-class descriptor. Can be null. */
     private ViewElementDescriptor mSuperClassDesc;
@@ -100,6 +100,7 @@ public final class ViewElementDescriptor extends ElementDescriptor {
     public ViewElementDescriptor(String xml_name, String fullClassName) {
         super(xml_name);
         mFullClassName = fullClassName;
+        mLayoutAttributes = null;
     }
 
     /**
index 01f153b..d29544d 100755 (executable)
@@ -1283,7 +1283,7 @@ public class LayoutCanvas extends Canvas {
 
                 // A root node requires the Android XMLNS
                 uiNew.setAttributeValue(
-                        LayoutConstants.ANDROID_NS_PREFIX,
+                        LayoutConstants.ANDROID_NS_NAME,
                         XmlnsAttributeDescriptor.XMLNS_URI,
                         SdkConstants.NS_RESOURCES,
                         true /*override*/);
index 21dff30..4323075 100755 (executable)
 package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
 
 import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_ORIENTATION;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_SRC;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_TEXT;
 import static com.android.ide.common.layout.LayoutConstants.DRAWABLE_PREFIX;
 import static com.android.ide.common.layout.LayoutConstants.LAYOUT_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.LINEAR_LAYOUT;
+import static com.android.ide.common.layout.LayoutConstants.VALUE_VERTICAL;
 import static org.eclipse.jface.viewers.StyledString.QUALIFIER_STYLER;
 
 import com.android.annotations.VisibleForTesting;
@@ -468,7 +471,20 @@ public class OutlinePage extends ContentOutlinePage
                 UiElementNode node = (UiElementNode) element;
                 ElementDescriptor desc = node.getDescriptor();
                 if (desc != null) {
-                    Image img = desc.getIcon();
+                    Image img = null;
+                    // Special case for the common case of vertical linear layouts:
+                    // show vertical linear icon (the default icon shows horizontal orientation)
+                    if (desc.getUiName().equals(LINEAR_LAYOUT)) {
+                        Element e = (Element) node.getXmlNode();
+                        if (VALUE_VERTICAL.equals(e.getAttributeNS(ANDROID_URI,
+                                ATTR_ORIENTATION))) {
+                            IconFactory factory = IconFactory.getInstance();
+                            img = factory.getIcon("VerticalLinearLayout"); //$NON-NLS-1$
+                        }
+                    }
+                    if (img == null) {
+                        img = desc.getIcon();
+                    }
                     if (img != null) {
                         if (node.hasError()) {
                             return new ErrorImageComposite(img).createImage();
index 5c48d49..9e090fd 100755 (executable)
@@ -40,6 +40,7 @@ import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Configu
 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
 import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeFactory;
 import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy;
+import com.android.ide.eclipse.adt.internal.editors.layout.gre.PaletteMetadataDescriptor;
 import com.android.ide.eclipse.adt.internal.editors.layout.gre.ViewMetadataRepository;
 import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
 import com.android.ide.eclipse.adt.internal.editors.ui.DecorComposite;
@@ -50,7 +51,6 @@ import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
 import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
 import com.android.util.Pair;
 
 import org.eclipse.jface.action.Action;
@@ -437,7 +437,14 @@ public class PaletteControl extends Composite {
             categoryToItems.put(category, categoryItems);
         }
 
-        if (expandedCategories == null && headers.size() > 0) {
+        // Set the categories to expand the first item if
+        //   (1) we don't have a previously selected category, or
+        //   (2) there's just one category anyway, or
+        //   (3) the set of categories have changed so our previously selected category
+        //       doesn't exist anymore (can happen when you toggle "Show Categories")
+        if ((expandedCategories == null && headers.size() > 0) || headers.size() == 1 ||
+                (expandedCategories != null && expandedCategories.size() >= 1
+                        && !headers.contains(expandedCategories.iterator().next()))) {
             // Expand the first category if we don't have a previous selection (e.g. refresh)
             expandedCategories = Collections.singleton(headers.get(0));
         }
@@ -649,6 +656,10 @@ public class PaletteControl extends Composite {
                     null   /* parentFqcn */,
                     bounds /* bounds */,
                     null   /* parentBounds */);
+            if (mDesc instanceof PaletteMetadataDescriptor) {
+                PaletteMetadataDescriptor pm = (PaletteMetadataDescriptor) mDesc;
+                pm.initializeNew(se);
+            }
             mElements = new SimpleElement[] { se };
 
             // Register this as the current dragged data
@@ -784,14 +795,20 @@ public class PaletteControl extends Composite {
             attr.setValue(ANDROID_URI);
             element.getAttributes().setNamedItemNS(attr);
 
-            element.setAttributeNS(SdkConstants.NS_RESOURCES,
+            element.setAttributeNS(ANDROID_URI,
                     ATTR_LAYOUT_WIDTH, VALUE_WRAP_CONTENT);
-            element.setAttributeNS(SdkConstants.NS_RESOURCES,
+            element.setAttributeNS(ANDROID_URI,
                     ATTR_LAYOUT_HEIGHT, VALUE_WRAP_CONTENT);
 
             // This doesn't apply to all, but doesn't seem to cause harm and makes for a
             // better experience with text-oriented views like buttons and texts
-            element.setAttributeNS(SdkConstants.NS_RESOURCES, ATTR_TEXT, mDesc.getUiName());
+            element.setAttributeNS(ANDROID_URI, ATTR_TEXT, mDesc.getUiName());
+
+            // Is this a palette variation?
+            if (mDesc instanceof PaletteMetadataDescriptor) {
+                PaletteMetadataDescriptor pm = (PaletteMetadataDescriptor) mDesc;
+                pm.initializeNew(element);
+            }
 
             document.appendChild(element);
 
index e8b4fba..f6db7da 100644 (file)
@@ -33,6 +33,7 @@ import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
+import com.android.ide.eclipse.adt.internal.editors.layout.gre.PaletteMetadataDescriptor;
 import com.android.ide.eclipse.adt.internal.editors.layout.gre.ViewMetadataRepository;
 import com.android.ide.eclipse.adt.internal.editors.layout.gre.ViewMetadataRepository.RenderMode;
 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
@@ -41,6 +42,7 @@ import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
 import com.android.util.Pair;
 
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.swt.graphics.RGB;
 import org.w3c.dom.Attr;
@@ -236,7 +238,7 @@ public class PreviewIconFactory {
                 // Important to get these sizes large enough for clients that don't support
                 // RenderMode.FULL_EXPAND such as 1.6
                 int width = 200;
-                int height = 2000;
+                int height = documentElement.getChildNodes().getLength() == 1 ? 400 : 1600;
                 Set<UiElementNode> expandNodes = Collections.<UiElementNode>emptySet();
                 RenderingMode renderingMode = RenderingMode.FULL_EXPAND;
 
@@ -309,6 +311,13 @@ public class PreviewIconFactory {
                             }
                         }
                     }
+                } else {
+                    if (session.getResult().getException() != null) {
+                        AdtPlugin.log(session.getResult().getException(),
+                                session.getResult().getErrorMessage());
+                    } else if (session.getResult().getErrorMessage() != null) {
+                        AdtPlugin.log(IStatus.WARNING, session.getResult().getErrorMessage());
+                    }
                 }
 
                 session.dispose();
@@ -488,6 +497,19 @@ public class PreviewIconFactory {
     }
 
     private String getFileName(ElementDescriptor descriptor) {
+        if (descriptor instanceof PaletteMetadataDescriptor) {
+            PaletteMetadataDescriptor pmd = (PaletteMetadataDescriptor) descriptor;
+            StringBuilder sb = new StringBuilder();
+            String name = pmd.getUiName();
+            // Strip out whitespace, parentheses, etc.
+            for (int i = 0, n = name.length(); i < n; i++) {
+                char c = name.charAt(i);
+                if (Character.isLetter(c)) {
+                    sb.append(c);
+                }
+            }
+            return sb.toString() + DOT_PNG;
+        }
         return descriptor.getUiName() + DOT_PNG;
     }
 
@@ -539,7 +561,7 @@ public class PreviewIconFactory {
             if (themeName.startsWith(themeNamePrefix)) {
                 themeName = themeName.substring(themeNamePrefix.length());
             }
-            String dirName = String.format("palette-preview-r10-%s-%s-%s", cleanup(targetName),
+            String dirName = String.format("palette-preview-r11-%s-%s-%s", cleanup(targetName),
                     cleanup(themeName), cleanup(mPalette.getCurrentDevice()));
             IPath dirPath = pluginState.append(dirName);
 
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/PaletteMetadataDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/PaletteMetadataDescriptor.java
new file mode 100644 (file)
index 0000000..287c5a8
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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.ide.common.layout.LayoutConstants.ANDROID_NS_NAME_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
+
+import com.android.ide.eclipse.adt.internal.editors.IconFactory;
+import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
+import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SimpleAttribute;
+import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SimpleElement;
+
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * Special version of {@link ViewElementDescriptor} which is initialized by the palette
+ * with specific metadata for how to instantiate particular variations of an existing
+ * {@link ViewElementDescriptor} with initial values.
+ */
+public class PaletteMetadataDescriptor extends ViewElementDescriptor {
+    private String mInitString;
+    private String mIconName;
+
+    public PaletteMetadataDescriptor(ViewElementDescriptor descriptor, String displayName,
+            String initString, String iconName) {
+        super(descriptor.getXmlName(),
+                displayName,
+                descriptor.getFullClassName(),
+                descriptor.getTooltip(),
+                descriptor.getSdkUrl(),
+                descriptor.getAttributes(),
+                descriptor.getLayoutAttributes(),
+                descriptor.getChildren(), descriptor.getMandatory() == Mandatory.MANDATORY);
+        mInitString = initString;
+        mIconName = iconName;
+    }
+
+    /**
+     * Returns a String which contains a comma separated list of name=value tokens,
+     * where the name can start with "android:" to indicate a property in the android namespace,
+     * or no prefix for plain attributes.
+     *
+     * @return the initialization string, which can be empty but never null
+     */
+    public String getInitializedAttributes() {
+        return mInitString != null ? mInitString : ""; //$NON-NLS-1$
+    }
+
+    @Override
+    public Image getIcon() {
+        if (mIconName != null) {
+            IconFactory factory = IconFactory.getInstance();
+            Image icon = factory.getIcon(mIconName);
+            if (icon != null) {
+                return icon;
+            }
+        }
+
+        return super.getIcon();
+    }
+
+    /**
+     * Initializes a new {@link SimpleElement} with the palette initialization
+     * configuration
+     *
+     * @param element the new element to initialize
+     */
+    public void initializeNew(SimpleElement element) {
+        initializeNew(element, null);
+    }
+
+    /**
+     * Initializes a new {@link Element} with the palette initialization configuration
+     *
+     * @param element the new element to initialize
+     */
+    public void initializeNew(Element element) {
+        initializeNew(null, element);
+    }
+
+    private void initializeNew(SimpleElement simpleElement, Element domElement) {
+        String initializedAttributes = mInitString;
+        if (initializedAttributes != null && initializedAttributes.length() > 0) {
+            for (String s : initializedAttributes.split(",")) { //$NON-NLS-1$
+                String[] nameValue = s.split("="); //$NON-NLS-1$
+                String name = nameValue[0];
+                String value = nameValue[1];
+                String nameSpace = ""; //$NON-NLS-1$
+                if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
+                    name = name.substring(ANDROID_NS_NAME_PREFIX.length());
+                    nameSpace = ANDROID_URI;
+                }
+
+                if (simpleElement != null) {
+                    SimpleAttribute attr = new SimpleAttribute(nameSpace, name, value);
+                    simpleElement.addAttribute(attr);
+                }
+
+                if (domElement != null) {
+                    domElement.setAttributeNS(nameSpace, name, value);
+                }
+            }
+        }
+    }
+}
index 567f5d5..cf6acba 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.android.ide.eclipse.adt.internal.editors.layout.gre;
 
-import static com.android.ide.common.api.IViewMetadata.FillPreference.NONE;
 import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
 import static com.android.ide.common.layout.LayoutConstants.ID_PREFIX;
@@ -25,6 +24,7 @@ import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX;
 import com.android.annotations.VisibleForTesting;
 import com.android.ide.common.api.IViewMetadata.FillPreference;
 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;
@@ -41,12 +41,12 @@ import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
+import java.util.Set;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -149,9 +149,7 @@ public class ViewMetadataRepository {
         // 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)) {
@@ -220,29 +218,11 @@ public class ViewMetadataRepository {
                                 Node childNode = children.item(j);
                                 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                                     Element child = (Element) childNode;
-                                    String fqcn = child.getAttribute("class"); //$NON-NLS-1$
-                                    String fill = child.getAttribute("fill"); //$NON-NLS-1$
-                                    FillPreference fillPreference = null;
-                                    if (fill.length() > 0) {
-                                        fillPreference = fillTypes.get(fill);
-                                    }
-                                    if (fillPreference == null) {
-                                        fillPreference = NONE;
-                                    }
-                                    String skip = child.getAttribute("skip"); //$NON-NLS-1$
-                                    RenderMode mode = RenderMode.NORMAL;
-                                    String render = child.getAttribute("render"); //$NON-NLS-1$
-                                    if (render.length() > 0) {
-                                        mode = RenderMode.get(render);
-                                    }
-                                    String relatedTo = child.getAttribute("relatedTo"); //$NON-NLS-1$
-                                    ViewData view = new ViewData(category, fqcn, fillPreference,
-                                            skip.length() == 0 ? false : Boolean.valueOf(skip),
-                                            mode, relatedTo);
+                                    ViewData view = createViewData(fillTypes, child,
+                                            null, FillPreference.NONE, RenderMode.NORMAL);
                                     category.addView(view);
                                 }
                             }
-
                             mCategories.add(category);
                         }
                     }
@@ -255,6 +235,62 @@ public class ViewMetadataRepository {
         return mCategories;
     }
 
+    private ViewData createViewData(Map<String, FillPreference> fillTypes,
+            Element child, String defaultFqcn, FillPreference defaultFill,
+            RenderMode defaultRender) {
+        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$
+        ViewData view = new ViewData(fqcn, displayName, fillPreference,
+                skip.length() == 0 ? false : Boolean.valueOf(skip),
+                renderMode, relatedTo);
+
+        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);
+                    view.addVariation(variationView);
+                }
+            }
+        }
+
+        return view;
+    }
+
     /**
      * Computes the palette entries for the given {@link AndroidTargetData}, looking up the
      * available node descriptors, categorizing and sorting them.
@@ -270,103 +306,87 @@ public class ViewMetadataRepository {
         List<Pair<String, List<ViewElementDescriptor>>> result =
             new ArrayList<Pair<String, List<ViewElementDescriptor>>>();
 
-        final Map<String, ViewData> viewMap = getClassToView();
-        Map<CategoryData, List<ViewElementDescriptor>> categories =
-            new TreeMap<CategoryData, List<ViewElementDescriptor>>();
-
-        // Locate the "Other" category
-        CategoryData other = null;
-        for (CategoryData category : getCategories()) {
-            if (category.getViewCount() == 0) {
-                other = category;
-                break;
-            }
-        }
-
         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) {
-                ViewData viewData = getClassToView().get(view.getFullClassName());
-                CategoryData category = other;
-                if (viewData != null) {
-                    if (viewData.getSkip()) {
-                        continue;
-                    }
-                    category = viewData.getCategory();
+                String fqcn = view.getFullClassName();
+                if (fqcn == null) {
+                    // <view> and <merge> tags etc
+                    fqcn = view.getUiName();
                 }
+                fqcnToDescriptor.put(fqcn, view);
+            }
+        }
 
-                List<ViewElementDescriptor> viewList = categories.get(category);
-                if (viewList == null) {
-                    viewList = new ArrayList<ViewElementDescriptor>();
-                    categories.put(category, viewList);
-                }
-                viewList.add(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) {
+                    if (view.getDisplayName() != null || view.getInitString().length() > 0) {
+                        categoryItems.add(new PaletteMetadataDescriptor(descriptor,
+                                view.getDisplayName(), view.getInitString(), view.getIconName()));
+                    } else {
+                        categoryItems.add(descriptor);
+                    }
+                    remaining.remove(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) {
-            // Squash all categories into a single one, "Views"
-            Map<CategoryData, List<ViewElementDescriptor>> singleCategory =
-                new HashMap<CategoryData, List<ViewElementDescriptor>>();
-            List<ViewElementDescriptor> items = new ArrayList<ViewElementDescriptor>(100);
-            for (Map.Entry<CategoryData, List<ViewElementDescriptor>> entry : categories.entrySet()) {
-                items.addAll(entry.getValue());
+            if (createCategories && categoryItems.size() > 0) {
+                if (alphabetical) {
+                    Collections.sort(categoryItems);
+                }
+                result.add(Pair.of(category.getName(), categoryItems));
             }
-            singleCategory.put(new CategoryData("Views"), items);
-            categories = singleCategory;
         }
 
-        for (Map.Entry<CategoryData, List<ViewElementDescriptor>> entry : categories.entrySet()) {
-            String name = entry.getKey().getName();
-            List<ViewElementDescriptor> items = entry.getValue();
-            if (items == null) {
-                continue; // empty category
+        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);
             }
+        }
 
-            // Natural sort of the descriptors
+        if (!createCategories) {
             if (alphabetical) {
-                Collections.sort(items);
-            } else {
-                Collections.sort(items, new Comparator<ViewElementDescriptor>() {
-                    public int compare(ViewElementDescriptor v1, ViewElementDescriptor v2) {
-                        String fqcn1 = v1.getFullClassName();
-                        String fqcn2 = v2.getFullClassName();
-                        if (fqcn1 == null) {
-                            // <view> and <merge> tags etc
-                            fqcn1 = v1.getUiName();
-                        }
-                        if (fqcn2 == null) {
-                            fqcn2 = v2.getUiName();
-                        }
-                        ViewData d1 = viewMap.get(fqcn1);
-                        ViewData d2 = viewMap.get(fqcn2);
-
-                        // Use natural sorting order of the view data
-                        // Sort unknown views to the end (and alphabetically among themselves)
-                        if (d1 != null) {
-                            if (d2 != null) {
-                                return d1.getOrdinal() - d2.getOrdinal();
-                            } else {
-                                return 1;
-                            }
-                        } else {
-                            if (d2 == null) {
-                                return v1.getUiName().compareTo(v2.getUiName());
-                            } else {
-                                return -1;
-                            }
-                        }
-                    }
-                });
+                Collections.sort(categoryItems);
             }
-
-
-            result.add(Pair.of(name, items));
+            result.add(Pair.of("Views", categoryItems));
         }
 
         return result;
@@ -404,10 +424,6 @@ public class ViewMetadataRepository {
             return mName;
         }
 
-        public int getViewCount() {
-            return mViews.size();
-        }
-
         // Implements Iterable<ViewData> such that we can use for-each on the category to
         // enumerate its views
         public Iterator<ViewData> iterator() {
@@ -426,8 +442,6 @@ public class ViewMetadataRepository {
         private final String mFqcn;
         /** Fill preference of the view */
         private final FillPreference mFillPreference;
-        /** The category that the view belongs to */
-        private final CategoryData mCategory;
         /** Skip this item in the palette? */
         private final boolean mSkip;
         /** Must this item be rendered alone? skipped? etc */
@@ -436,25 +450,31 @@ public class ViewMetadataRepository {
         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;
 
         /** Constructs a new view data for the given class */
-        private ViewData(CategoryData category, String fqcn,
+        private ViewData(String fqcn, String displayName,
                 FillPreference fillPreference, boolean skip, RenderMode renderMode,
                 String relatedTo) {
             super();
-            mCategory = category;
             mFqcn = fqcn;
+            mDisplayName = displayName;
             mFillPreference = fillPreference;
             mSkip = skip;
             mRenderMode = renderMode;
             mRelatedTo = relatedTo;
         }
 
-        /** Returns the category for views of this type */
-        private CategoryData getCategory() {
-            return mCategory;
-        }
-
         /** Returns the {@link FillPreference} for views of this type */
         private FillPreference getFillPreference() {
             return mFillPreference;
@@ -465,9 +485,8 @@ public class ViewMetadataRepository {
             return mFqcn;
         }
 
-        /** Relative rank of this view type */
-        private int getOrdinal() {
-            return mOrdinal;
+        private String getDisplayName() {
+            return mDisplayName;
         }
 
         // Implements Comparable<ViewData> such that views can be sorted naturally
@@ -509,6 +528,37 @@ public class ViewMetadataRepository {
                 return result;
             }
         }
+
+        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;
+        }
     }
 
     /**
@@ -540,7 +590,7 @@ public class ViewMetadataRepository {
             return view.getRenderMode();
         }
 
-        return RenderMode.ALONE;
+        return RenderMode.NORMAL;
     }
 
     /**
index 262f63d..96e9a01 100644 (file)
 <!ATTLIST category name CDATA #IMPLIED>
 <!--- Each view is identified by its full class name and has various
       other attributes such as a fill preference  -->
-<!ELEMENT view EMPTY>
+<!ELEMENT view (view)*>
 <!ATTLIST view
-    class CDATA #REQUIRED
+    class CDATA #IMPLIED
+    name CDATA #IMPLIED
+    init CDATA #IMPLIED
+    icon CDATA #IMPLIED
     relatedTo CDATA #IMPLIED
     skip (true|false) "false"
     render (alone|skip|normal) "normal"
             class="android.widget.Button"
             relatedTo="ImageButton" />
         <view
-            class="android.widget.CheckBox"
-            relatedTo="RadioButton,ToggleButton,CheckedTextView" />
-        <view
             class="android.widget.ToggleButton"
             relatedTo="CheckBox" />
         <view
+            class="android.widget.CheckBox"
+            relatedTo="RadioButton,ToggleButton,CheckedTextView" />
+        <view
             class="android.widget.RadioButton"
             relatedTo="CheckBox,ToggleButton" />
         <view
             relatedTo="Spinner,TextView,AutoCompleteTextView,MultiAutoCompleteTextView"
             fill="width_in_vertical" />
         <view
-            class="android.widget.AutoCompleteTextView"
-            relatedTo="EditText,MultiAutoCompleteTextView"
-            fill="width_in_vertical" />
+            class="android.widget.ProgressBar"
+            relatedTo="SeekBar"
+            name="ProgressBar (Large)"
+            init="style=?android:attr/progressBarStyleLarge">
+            <view
+                name="ProgressBar (Normal)"
+                init="" />
+            <view
+                name="ProgressBar (Small)"
+                init="style=?android:attr/progressBarStyleSmall" />
+            <view
+                name="ProgressBar (Horizontal)"
+                init="style=?android:attr/progressBarStyleHorizontal" />
+        </view>
         <view
-            class="android.widget.MultiAutoCompleteTextView"
-            relatedTo="EditText,AutoCompleteTextView"
+            class="android.widget.SeekBar"
+            relatedTo="ProgressBar"
             fill="width_in_vertical" />
         <view
-            class="android.widget.ProgressBar"
-            relatedTo="SeekBar" />
-        <view
             class="android.widget.QuickContactBadge" />
         <view
             class="android.widget.RadioGroup" />
         <view
             class="android.widget.RatingBar" />
+    </category>
+    <category
+        name="Text Fields">
         <view
-            class="android.widget.SeekBar"
-            relatedTo="ProgressBar"
+            class="android.widget.EditText"
+            name="Plain Text"
+            init=""
+            relatedTo="Spinner,TextView,AutoCompleteTextView,MultiAutoCompleteTextView"
+            fill="width_in_vertical">
+            <view
+                name="Person Name"
+                init="android:inputType=textPersonName" />
+            <view
+                name="Password"
+                init="android:inputType=textPassword" />
+            <view
+                name="Password (Numeric)"
+                init="android:inputType=numberPassword" />
+            <view
+                name="E-mail"
+                init="android:inputType=textEmailAddress" />
+            <view
+                name="Phone"
+                init="android:inputType=phone" />
+            <view
+                name="Postal Address"
+                init="android:inputType=textPostalAddress" />
+            <view
+                name="Multiline Text"
+                init="android:inputType=textMultiLine" />
+            <view
+                name="Time"
+                init="android:inputType=time" />
+            <view
+                name="Date"
+                init="android:inputType=date" />
+            <view
+                name="Number"
+                init="android:inputType=number" />
+            <view
+                name="Number (Signed)"
+                init="android:inputType=numberSigned" />
+            <view
+                name="Number (Decimal)"
+                init="android:inputType=numberDecimal" />
+        </view>
+        <view
+            class="android.widget.AutoCompleteTextView"
+            fill="width_in_vertical" />
+        <view
+            class="android.widget.MultiAutoCompleteTextView"
             fill="width_in_vertical" />
     </category>
     <category
         name="Layouts">
         <view
             class="android.widget.LinearLayout"
+            name="LinearLayout (Vertical)"
+            init="android:orientation=vertical"
+            icon="VerticalLinearLayout"
             fill="opposite"
-            render="skip" />
+            render="skip">
+            <view
+                name="LinearLayout (Horizontal)" />
+        </view>
         <view
             class="android.widget.RelativeLayout"
             fill="opposite"
         <!--  This is the catch-all category which contains unknown views if we encounter any -->
     </category>
     <!--  TODO: Add-ons? -->
-</metadata>
\ No newline at end of file
+</metadata>
index 9c99644..3eaac16 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-    Default configuration for various views to be rendered 
+    Default configuration for various views to be rendered
     TODO: Remove views that don't have custom configuration
     TODO: Parameterize the custom width (200dip) in the below?
 -->
         android:text="EditText"
         android:layout_width="200dip">
     </EditText>
+
+    <EditText
+        android:id="@+id/PlainText"
+        android:text="abc"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/Password"
+        android:inputType="textPassword"
+        android:text="••••••••"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <!-- android:inputType="numberPassword" not used here to allow digits in preview only -->
+    <EditText
+        android:id="@+id/PasswordNumeric"
+        android:text="1•••2•••3"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/PersonName"
+        android:inputType="textPersonName"
+        android:text="Firstname Lastname"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/Phone"
+        android:inputType="phone"
+        android:text="(555) 0100"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/PostalAddress"
+        android:inputType="textPostalAddress"
+        android:text="Address"
+        android:layout_width="200dip"
+        android:layout_height="100dip">
+    </EditText>
+
+    <EditText
+        android:id="@+id/MultilineText"
+        android:inputType="textMultiLine"
+        android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor"
+        android:layout_width="200dip"
+        android:layout_height="100dip">
+    </EditText>
+
+    <EditText
+        android:id="@+id/Date"
+        android:inputType="date"
+        android:text="1/1/2011"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/Time"
+        android:inputType="time"
+        android:text="12:00am"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/Email"
+        android:inputType="textEmailAddress"
+        android:text="user@domain"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/Number"
+        android:inputType="number"
+        android:text="42"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/NumberSigned"
+        android:inputType="numberSigned"
+        android:text="-42"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
+    <EditText
+        android:id="@+id/NumberDecimal"
+        android:inputType="numberDecimal"
+        android:text="42.0"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content">
+    </EditText>
+
     <ImageButton
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:id="@+id/android_widget_MultiAutoCompleteTextView">
     </MultiAutoCompleteTextView>
     <ProgressBar
-        android:id="@+id/android_widget_ProgressBar"
+        android:id="@+id/android_widget_ProgressBarNormal"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content">
     </ProgressBar>
+    <ProgressBar
+        android:id="@+id/android_widget_ProgressBarHorizontal"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content"
+        android:progress="30"
+        style="?android:attr/progressBarStyleHorizontal">
+    </ProgressBar>
+    <ProgressBar
+        android:id="@+id/android_widget_ProgressBarLarge"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="?android:attr/progressBarStyleLarge">
+    </ProgressBar>
+    <ProgressBar
+        android:id="@+id/android_widget_ProgressBarSmall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="?android:attr/progressBarStyleSmall">
+    </ProgressBar>
     <QuickContactBadge
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
index cb2a25c..d5921bf 100644 (file)
@@ -15,7 +15,7 @@
  */
 package com.android.ide.eclipse.adt.internal.editors.layout.refactoring;
 
-import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME;
 import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_HEIGHT;
@@ -350,7 +350,7 @@ public class ExtractIncludeRefactoring extends VisualRefactoring {
         namespaceDeclarations = sb.toString();
 
         if (androidNsPrefix == null) {
-            androidNsPrefix = ANDROID_NS_PREFIX;
+            androidNsPrefix = ANDROID_NS_NAME;
         }
 
         if (namespaceDeclarations.length() == 0) {
index e496b7a..3cce3b3 100644 (file)
@@ -15,7 +15,7 @@
  */
 package com.android.ide.eclipse.adt.internal.editors.layout.refactoring;
 
-import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME;
 import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
 import static com.android.ide.common.layout.LayoutConstants.ANDROID_WIDGET_PREFIX;
 import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
@@ -521,7 +521,7 @@ public abstract class VisualRefactoring extends Refactoring {
             }
 
             if (mAndroidNamespacePrefix == null) {
-                mAndroidNamespacePrefix = ANDROID_NS_PREFIX;
+                mAndroidNamespacePrefix = ANDROID_NS_NAME;
             }
         }
 
index f4b10b7..60b5662 100644 (file)
@@ -112,7 +112,7 @@ public class UiViewElementNode extends UiElementNode {
                 layout_attrs.length);
         if (need_xmlns) {
             AttributeDescriptor desc = new XmlnsAttributeDescriptor(
-                    LayoutConstants.ANDROID_NS_PREFIX,
+                    LayoutConstants.ANDROID_NS_NAME,
                     SdkConstants.NS_RESOURCES);
             mCachedAttributeDescriptors[direct_attrs.length + layout_attrs.length] = desc;
         }
index a84c743..f093a9b 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.android.ide.eclipse.adt.internal.editors.menu.descriptors;
 
-import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME;
 
 import com.android.ide.common.resources.platform.DeclareStyleableInfo;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
@@ -122,7 +122,7 @@ public final class MenuDescriptors implements IDescriptorProvider {
                 new ElementDescriptor[] { top_item }, // childrenElements,
                 false /* mandatory */);
 
-        XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(ANDROID_NS_PREFIX,
+        XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(ANDROID_NS_NAME,
                 SdkConstants.NS_RESOURCES);
 
         updateElement(mDescriptor, styleMap, "Menu", xmlns); //$NON-NLS-1$
index 01d4e4e..1a66cdb 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.android.ide.eclipse.adt.internal.editors.uimodel;
 
-import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME;
 import static com.android.ide.common.layout.LayoutConstants.ID_PREFIX;
 import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX;
 import static com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor.XMLNS;
@@ -1592,7 +1592,7 @@ public class UiElementNode implements IPropertySource {
         // We need to make sure the prefix is not one that was declared in the scope
         // visited above. Use a default namespace prefix "android" for the Android resource
         // NS and use "ns" for all other custom namespaces.
-        String prefix = NS_RESOURCES.equals(nsUri) ? ANDROID_NS_PREFIX : "ns"; //$NON-NLS-1$
+        String prefix = NS_RESOURCES.equals(nsUri) ? ANDROID_NS_NAME : "ns"; //$NON-NLS-1$
         String base = prefix;
         for (int i = 1; visited.contains(prefix); i++) {
             prefix = base + Integer.toString(i);
index cdb0c9a..c8e5720 100644 (file)
@@ -140,7 +140,7 @@ public class UiListAttributeNode extends UiAbstractTextAttributeNode {
         // FrameworkResourceManager expects a specific prefix for the attribute.
         String nsPrefix = "";
         if (SdkConstants.NS_RESOURCES.equals(descriptor.getNamespaceUri())) {
-            nsPrefix = LayoutConstants.ANDROID_NS_PREFIX + ':';
+            nsPrefix = LayoutConstants.ANDROID_NS_NAME + ':';
         } else if (XmlnsAttributeDescriptor.XMLNS_URI.equals(descriptor.getNamespaceUri())) {
             nsPrefix = XmlnsAttributeDescriptor.XMLNS_COLON;
         }
index 43c8fcd..b10d69b 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.ide.eclipse.adt.internal.editors.uimodel;
 
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME_PREFIX;
+
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
@@ -200,7 +202,7 @@ public class UiResourceAttributeNode extends UiTextAttributeNode {
         UiElementNode uiNode = getUiParent();
         AndroidXmlEditor editor = uiNode.getEditor();
 
-        if (prefix == null || prefix.indexOf("android:") < 0) {                 //$NON-NLS-1$
+        if (prefix == null || !prefix.contains(ANDROID_NS_NAME_PREFIX)) {
             IProject project = editor.getProject();
             if (project != null) {
                 // get the resource repository for this project and the system resources.
@@ -257,7 +259,7 @@ public class UiResourceAttributeNode extends UiTextAttributeNode {
                 }
 
                 if (isSystem) {
-                    sb.append("android:");                                  //$NON-NLS-1$
+                    sb.append(ANDROID_NS_NAME_PREFIX);
                 }
 
                 sb.append(typeName).append('/');
index b807aa1..bc74d57 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.android.ide.eclipse.adt.internal.editors.xml.descriptors;
 
-import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME;
 
 import com.android.ide.common.resources.platform.AttributeInfo;
 import com.android.ide.common.resources.platform.DeclareStyleableInfo;
@@ -134,7 +134,7 @@ public final class XmlDescriptors implements IDescriptorProvider {
             ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
 
         XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
-                ANDROID_NS_PREFIX,
+                ANDROID_NS_NAME,
                 SdkConstants.NS_RESOURCES);
 
         ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);