1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.ide.eclipse.adt.internal.editors.animator;
17 
18 import static com.android.SdkConstants.ANDROID_NS_NAME;
19 import static com.android.SdkConstants.ANDROID_URI;
20 
21 import com.android.ide.common.resources.platform.DeclareStyleableInfo;
22 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
23 import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
24 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
25 import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
26 import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
27 
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 
33 /**
34  * Descriptors for /res/animator XML files.
35  */
36 public class AnimatorDescriptors implements IDescriptorProvider {
37     /** The root element descriptor */
38     private ElementDescriptor mDescriptor;
39     /** The root element descriptors */
40     private ElementDescriptor[] mRootDescriptors;
41     private Map<String, ElementDescriptor> nameToDescriptor;
42 
43     /** @return the root descriptor. */
44     @Override
getDescriptor()45     public ElementDescriptor getDescriptor() {
46         if (mDescriptor == null) {
47             mDescriptor = new ElementDescriptor("", getRootElementDescriptors()); //$NON-NLS-1$
48         }
49 
50         return mDescriptor;
51     }
52 
53     @Override
getRootElementDescriptors()54     public ElementDescriptor[] getRootElementDescriptors() {
55         return mRootDescriptors;
56     }
57 
getElementDescriptor(String rootTag)58     ElementDescriptor getElementDescriptor(String rootTag) {
59         if (nameToDescriptor == null) {
60             nameToDescriptor = new HashMap<String, ElementDescriptor>();
61             for (ElementDescriptor descriptor : getRootElementDescriptors()) {
62                 nameToDescriptor.put(descriptor.getXmlName(), descriptor);
63             }
64         }
65 
66         ElementDescriptor descriptor = nameToDescriptor.get(rootTag);
67         if (descriptor == null) {
68             descriptor = getDescriptor();
69         }
70         return descriptor;
71     }
72 
updateDescriptors(Map<String, DeclareStyleableInfo> styleMap)73     public synchronized void updateDescriptors(Map<String, DeclareStyleableInfo> styleMap) {
74         if (styleMap == null) {
75             return;
76         }
77 
78         XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(ANDROID_NS_NAME,
79                 ANDROID_URI);
80 
81         List<ElementDescriptor> descriptors = new ArrayList<ElementDescriptor>();
82 
83         String sdkUrl =
84             "http://developer.android.com/guide/topics/graphics/animation.html"; //$NON-NLS-1$
85 
86         ElementDescriptor set = addElement(descriptors, styleMap,
87                 "set", "Animator Set", "AnimatorSet", null, //$NON-NLS-1$ //$NON-NLS-3$
88                 null /* tooltip */, sdkUrl,
89                 xmlns, null, true /*mandatory*/);
90 
91         ElementDescriptor objectAnimator = addElement(descriptors, styleMap,
92                 "objectAnimator", "Object Animator", //$NON-NLS-1$
93                 "PropertyAnimator", "Animator", //$NON-NLS-1$ //$NON-NLS-2$
94                 null /* tooltip */, sdkUrl,
95                 xmlns, null, true /*mandatory*/);
96 
97         ElementDescriptor animator = addElement(descriptors, styleMap,
98                 "animator", "Animator", "Animator", null, //$NON-NLS-1$ //$NON-NLS-3$
99                 null /* tooltip */, sdkUrl,
100                 xmlns, null, true /*mandatory*/);
101 
102         mRootDescriptors = descriptors.toArray(new ElementDescriptor[descriptors.size()]);
103 
104         // Allow arbitrary nesting: the children of all of these element can include
105         // any of the others
106         if (objectAnimator != null) {
107             objectAnimator.setChildren(mRootDescriptors);
108         }
109         if (animator != null) {
110             animator.setChildren(mRootDescriptors);
111         }
112         if (set != null) {
113             set.setChildren(mRootDescriptors);
114         }
115     }
116 
117     /**
118      * Looks up the given style, and if found creates a new {@link ElementDescriptor}
119      * corresponding to the style. It can optionally take an extra style to merge in
120      * additional attributes from, and an extra attribute to add in as well. The new
121      * element, if it exists, can also be optionally added into a list.
122      *
123      * @param descriptors an optional list to add the element into, or null
124      * @param styleMap The map style => attributes from the attrs.xml file
125      * @param xmlName the XML tag name to use for the element
126      * @param uiName the UI name to display the element as
127      * @param styleName the name of the style which must exist for this style
128      * @param extraStyle an optional extra style to merge in attributes from, or null
129      * @param tooltip the tooltip or documentation for this element, or null
130      * @param sdkUrl an optional SDK url to display for the element, or null
131      * @param extraAttribute an extra attribute to add to the attributes list, or null
132      * @param childrenElements an array of children allowed by this element, or null
133      * @param mandatory if true, this element is mandatory
134      * @return a newly created element, or null if the style does not exist
135      */
addElement( List<ElementDescriptor> descriptors, Map<String, DeclareStyleableInfo> styleMap, String xmlName, String uiName, String styleName, String extraStyle, String tooltip, String sdkUrl, AttributeDescriptor extraAttribute, ElementDescriptor[] childrenElements, boolean mandatory)136     public static ElementDescriptor addElement(
137             List<ElementDescriptor> descriptors,
138             Map<String, DeclareStyleableInfo> styleMap,
139             String xmlName, String uiName, String styleName, String extraStyle,
140             String tooltip, String sdkUrl,
141             AttributeDescriptor extraAttribute,
142             ElementDescriptor[] childrenElements,
143             boolean mandatory) {
144         DeclareStyleableInfo style = styleMap.get(styleName);
145         if (style == null) {
146             return null;
147         }
148         ElementDescriptor element = new ElementDescriptor(xmlName, uiName, tooltip, sdkUrl,
149                 null, childrenElements, mandatory);
150 
151         ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>();
152 
153         DescriptorsUtils.appendAttributes(descs,
154                 null,   // elementName
155                 ANDROID_URI,
156                 style.getAttributes(),
157                 null,   // requiredAttributes
158                 null);  // overrides
159         element.setTooltip(style.getJavaDoc());
160 
161         if (extraStyle != null) {
162             style = styleMap.get(extraStyle);
163             if (style != null) {
164                 DescriptorsUtils.appendAttributes(descs,
165                         null,   // elementName
166                         ANDROID_URI,
167                         style.getAttributes(),
168                         null,   // requiredAttributes
169                         null);  // overrides
170             }
171         }
172 
173         if (extraAttribute != null) {
174             descs.add(extraAttribute);
175         }
176 
177         element.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()]));
178         if (descriptors != null) {
179             descriptors.add(element);
180         }
181 
182         return element;
183     }
184 }
185