diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/drawable/DrawableDescriptors.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/drawable/DrawableDescriptors.java | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/drawable/DrawableDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/drawable/DrawableDescriptors.java new file mode 100644 index 000000000..4858ac7c6 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/drawable/DrawableDescriptors.java @@ -0,0 +1,301 @@ +/* + * 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.drawable; + +import static com.android.SdkConstants.ANDROID_NS_NAME; +import static com.android.SdkConstants.ANDROID_URI; + +import com.android.ide.common.api.IAttributeInfo.Format; +import com.android.ide.common.resources.platform.AttributeInfo; +import com.android.ide.common.resources.platform.DeclareStyleableInfo; +import com.android.ide.eclipse.adt.internal.editors.animator.AnimatorDescriptors; +import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; +import com.android.ide.eclipse.adt.internal.editors.descriptors.ReferenceAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; +import com.android.resources.ResourceType; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Descriptors for /res/drawable files + */ +public class DrawableDescriptors implements IDescriptorProvider { + private static final String SDK_URL_BASE = + "http://d.android.com/guide/topics/resources/"; //$NON-NLS-1$ + + /** The root element descriptor */ + private ElementDescriptor mDescriptor; + /** The root element descriptors */ + private ElementDescriptor[] mRootDescriptors; + private Map<String, ElementDescriptor> nameToDescriptor; + + /** @return the root descriptor. */ + @Override + public ElementDescriptor getDescriptor() { + if (mDescriptor == null) { + mDescriptor = new ElementDescriptor("", getRootElementDescriptors()); //$NON-NLS-1$ + } + + return mDescriptor; + } + + @Override + public ElementDescriptor[] getRootElementDescriptors() { + return mRootDescriptors; + } + + /** + * Returns a descriptor for the given root tag name + * + * @param tag the tag name to look up a descriptor for + * @return a descriptor with the given tag name + */ + public ElementDescriptor getElementDescriptor(String tag) { + if (nameToDescriptor == null) { + nameToDescriptor = new HashMap<String, ElementDescriptor>(); + for (ElementDescriptor descriptor : getRootElementDescriptors()) { + nameToDescriptor.put(descriptor.getXmlName(), descriptor); + } + } + + ElementDescriptor descriptor = nameToDescriptor.get(tag); + if (descriptor == null) { + descriptor = getDescriptor(); + } + return descriptor; + } + + public synchronized void updateDescriptors(Map<String, DeclareStyleableInfo> styleMap) { + XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(ANDROID_NS_NAME, + ANDROID_URI); + List<ElementDescriptor> descriptors = new ArrayList<ElementDescriptor>(); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "animation-list", "Animation List", "AnimationDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An animation defined in XML that shows a sequence of images in " + + "order (like a film)", + SDK_URL_BASE + "animation-resource.html#Frame", + xmlns, null, true /*mandatory*/); + + /* For some reason, android.graphics.drawable.AnimatedRotateDrawable is marked with @hide + * so we should not register it and its attributes here. See issue #19248 for details. + AnimatorDescriptors.addElement(descriptors, styleMap, + "animated-rotate", "Animated Rotate", "AnimatedRotateDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + // Need docs + null, // tooltip + null, // sdk_url + xmlns, null, true); + */ + + AnimatorDescriptors.addElement(descriptors, styleMap, + "bitmap", "BitMap", "BitmapDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An XML bitmap is a resource defined in XML that points to a bitmap file. " + + "The effect is an alias for a raw bitmap file. The XML can " + + "specify additional properties for the bitmap such as " + + "dithering and tiling.", + SDK_URL_BASE + "drawable-resource.html#Bitmap", //$NON-NLS-1$ + xmlns, null, true /* mandatory */); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "clip", "Clip", "ClipDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An XML file that defines a drawable that clips another Drawable based on " + + "this Drawable's current level value.", + SDK_URL_BASE + "drawable-resource.html#Clip", //$NON-NLS-1$ + xmlns, null, true /*mandatory*/); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "color", "Color", "ColorDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "XML resource that carries a color value (a hexadecimal color)", + SDK_URL_BASE + "more-resources.html#Color", + xmlns, null, true /*mandatory*/); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "inset", "Inset", "InsetDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An XML file that defines a drawable that insets another drawable by a " + + "specified distance. This is useful when a View needs a background " + + "drawble that is smaller than the View's actual bounds.", + SDK_URL_BASE + "drawable-resource.html#Inset", //$NON-NLS-1$ + xmlns, null, true /*mandatory*/); + + // Layer list + + // An <item> in a <selector> or < + ElementDescriptor layerItem = AnimatorDescriptors.addElement(null, styleMap, + "item", "Item", "LayerDrawableItem", null, //$NON-NLS-1$ //$NON-NLS-3$ + "Defines a drawable to place in the layer drawable, in a position " + + "defined by its attributes. Must be a child of a <selector> " + + "element. Accepts child <bitmap> elements.", + SDK_URL_BASE + "drawable-resource.html#LayerList", //$NON-NLS-1$ + null, /* extra attribute */ + null, /* This is wrong -- we can now embed any above drawable + (but without xmlns as extra) */ + false /*mandatory*/); + ElementDescriptor[] layerChildren = layerItem != null + ? new ElementDescriptor[] { layerItem } : null; + + AnimatorDescriptors.addElement(descriptors, styleMap, + "layer-list", "Layer List", "LayerDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "A Drawable that manages an array of other Drawables. These are drawn in " + + "array order, so the element with the largest index is be drawn on top.", + SDK_URL_BASE + "drawable-resource.html#LayerList", //$NON-NLS-1$ + xmlns, + layerChildren, + true /*mandatory*/); + + // Level list children + ElementDescriptor levelListItem = AnimatorDescriptors.addElement(null, styleMap, + "item", "Item", "LevelListDrawableItem", null, //$NON-NLS-1$ //$NON-NLS-3$ + "Defines a drawable to use at a certain level.", + SDK_URL_BASE + "drawable-resource.html#LevelList", //$NON-NLS-1$ + null, /* extra attribute */ + null, /* no further children */ + // TODO: The inflation code seems to show that all drawables can be nested here! + false /*mandatory*/); + AnimatorDescriptors.addElement(descriptors, styleMap, + "level-list", "Level List", "LevelListDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An XML file that defines a drawable that manages a number of alternate " + + "Drawables, each assigned a maximum numerical value", + SDK_URL_BASE + "drawable-resource.html#LevelList", //$NON-NLS-1$ + xmlns, + levelListItem != null ? new ElementDescriptor[] { levelListItem } : null, + true /*mandatory*/); + + // Not yet supported + //addElement(descriptors, styleMap, "mipmap", "Mipmap", "MipmapDrawable", null, + // null /* tooltip */, + // null /* sdk_url */, + // xmlns, null, true /*mandatory*/); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "nine-patch", "Nine Patch", "NinePatchDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "A PNG file with stretchable regions to allow image resizing " + + "based on content (.9.png).", + SDK_URL_BASE + "drawable-resource.html#NinePatch", //$NON-NLS-1$ + xmlns, null, true /*mandatory*/); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "rotate", "Rotate", "RotateDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + // Need docs + null /* tooltip */, + null /* sdk_url */, + xmlns, null, true /*mandatory*/); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "scale", "Shape", "ScaleDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An XML file that defines a drawable that changes the size of another Drawable " + + "based on its current level value.", + SDK_URL_BASE + "drawable-resource.html#Scale", //$NON-NLS-1$ + xmlns, null, true /*mandatory*/); + + // Selector children + ElementDescriptor selectorItem = AnimatorDescriptors.addElement(null, styleMap, + "item", "Item", "DrawableStates", null, //$NON-NLS-1$ //$NON-NLS-3$ + "Defines a drawable to use during certain states, as described by " + + "its attributes. Must be a child of a <selector> element.", + SDK_URL_BASE + "drawable-resource.html#StateList", //$NON-NLS-1$ + new ReferenceAttributeDescriptor( + ResourceType.DRAWABLE, "drawable", ANDROID_URI, //$NON-NLS-1$ + new AttributeInfo("drawable", Format.REFERENCE_SET)) + .setTooltip("Reference to a drawable resource."), + null, /* This is wrong -- we can now embed any above drawable + (but without xmlns as extra) */ + false /*mandatory*/); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "selector", "Selector", "StateListDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An XML file that references different bitmap graphics for different states " + + "(for example, to use a different image when a button is pressed).", + SDK_URL_BASE + "drawable-resource.html#StateList", //$NON-NLS-1$ + xmlns, + selectorItem != null ? new ElementDescriptor[] { selectorItem } : null, + true /*mandatory*/); + + // Shape + // Shape children + List<ElementDescriptor> shapeChildren = new ArrayList<ElementDescriptor>(); + // Selector children + AnimatorDescriptors.addElement(shapeChildren, styleMap, + "size", "Size", "GradientDrawableSize", null, //$NON-NLS-1$ //$NON-NLS-3$ + null /* tooltip */, null /* sdk_url */, null /* extra attribute */, + null /* children */, false /* mandatory */); + AnimatorDescriptors.addElement(shapeChildren, styleMap, + "gradient", "Gradient", "GradientDrawableGradient", null, //$NON-NLS-1$ //$NON-NLS-3$ + null /* tooltip */, null /* sdk_url */, null /* extra attribute */, + null /* children */, false /* mandatory */); + AnimatorDescriptors.addElement(shapeChildren, styleMap, + "solid", "Solid", "GradientDrawableSolid", null, //$NON-NLS-1$ //$NON-NLS-3$ + null /* tooltip */, null /* sdk_url */, null /* extra attribute */, + null /* children */, false /* mandatory */); + AnimatorDescriptors.addElement(shapeChildren, styleMap, + "stroke", "Stroke", "GradientDrawableStroke", null, //$NON-NLS-1$ //$NON-NLS-3$ + null /* tooltip */, null /* sdk_url */, null /* extra attribute */, + null /* children */, false /* mandatory */); + AnimatorDescriptors.addElement(shapeChildren, styleMap, + "corners", "Corners", "DrawableCorners", null, //$NON-NLS-1$ //$NON-NLS-3$ + null /* tooltip */, null /* sdk_url */, null /* extra attribute */, + null /* children */, false /* mandatory */); + AnimatorDescriptors.addElement(shapeChildren, styleMap, + "padding", "Padding", "GradientDrawablePadding", null, //$NON-NLS-1$ //$NON-NLS-3$ + null /* tooltip */, null /* sdk_url */, null /* extra attribute */, + null /* children */, false /* mandatory */); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "shape", "Shape", //$NON-NLS-1$ + + // The documentation says that a <shape> element creates a ShapeDrawable, + // but ShapeDrawable isn't finished and the code currently creates + // a GradientDrawable. + //"ShapeDrawable", //$NON-NLS-1$ + "GradientDrawable", //$NON-NLS-1$ + + null, + "An XML file that defines a geometric shape, including colors and gradients.", + SDK_URL_BASE + "drawable-resource.html#Shape", //$NON-NLS-1$ + xmlns, + + // These are the GradientDrawable children, not the ShapeDrawable children + shapeChildren.toArray(new ElementDescriptor[shapeChildren.size()]), + true /*mandatory*/); + + AnimatorDescriptors.addElement(descriptors, styleMap, + "transition", "Transition", "TransitionDrawable", null, //$NON-NLS-1$ //$NON-NLS-3$ + "An XML file that defines a drawable that can cross-fade between two " + + "drawable resources. Each drawable is represented by an <item> " + + "element inside a single <transition> element. No more than two " + + "items are supported. To transition forward, call startTransition(). " + + "To transition backward, call reverseTransition().", + SDK_URL_BASE + "drawable-resource.html#Transition", //$NON-NLS-1$ + xmlns, + layerChildren, // children: a TransitionDrawable is a LayerDrawable + true /*mandatory*/); + + mRootDescriptors = descriptors.toArray(new ElementDescriptor[descriptors.size()]); + + // A <selector><item> can contain any of the top level drawables + if (selectorItem != null) { + selectorItem.setChildren(mRootDescriptors); + } + // Docs says it can accept <bitmap> but code comment suggests any is possible; + // test and either use this or just { bitmap } + if (layerItem != null) { + layerItem.setChildren(mRootDescriptors); + } + } +} |