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_PADDING;
import static com.android.ide.common.layout.LayoutConstants.VALUE_FILL_PARENT;
import static com.android.ide.common.layout.LayoutConstants.VALUE_MATCH_PARENT;
import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.ATTR_LAYOUT;
* This pull parser generates {@link ViewInfo}s which key is a {@link UiElementNode}.
*/
public class UiElementPullParser extends BasePullParser {
- private final static String ATTR_PADDING = "padding"; //$NON-NLS-1$
private final static Pattern FLOAT_PATTERN = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)"); //$NON-NLS-1$
private final int[] sIntOut = new int[1];
private final boolean mExplodedRendering;
private boolean mZeroAttributeIsPadding = false;
private boolean mIncreaseExistingPadding = false;
- private List<ViewElementDescriptor> mLayoutDescriptors;
+ private LayoutDescriptors mDescriptors;
private final Density mDensity;
private final float mXdpi;
// get the layout descriptor
IAndroidTarget target = Sdk.getCurrent().getTarget(project);
AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
- LayoutDescriptors descriptors = data.getLayoutDescriptors();
- mLayoutDescriptors = descriptors.getLayoutDescriptors();
+ mDescriptors = data.getLayoutDescriptors();
}
push(mRoot);
}
if (mExplodedRendering) {
// first get the node name
String xml = node.getDescriptor().getXmlLocalName();
- for (ViewElementDescriptor descriptor : mLayoutDescriptors) {
- if (xml.equals(descriptor.getXmlLocalName())) {
- NamedNodeMap attributes = node.getXmlNode().getAttributes();
- Node padding = attributes.getNamedItemNS(SdkConstants.NS_RESOURCES, "padding");
- if (padding == null) {
- // we'll return an extra padding
- mZeroAttributeIsPadding = true;
- } else {
- mIncreaseExistingPadding = true;
- }
-
- break;
+ ViewElementDescriptor descriptor = mDescriptors.findDescriptorByTag(xml);
+ if (descriptor != null) {
+ NamedNodeMap attributes = node.getXmlNode().getAttributes();
+ Node padding = attributes.getNamedItemNS(SdkConstants.NS_RESOURCES, ATTR_PADDING);
+ if (padding == null) {
+ // we'll return an extra padding
+ mZeroAttributeIsPadding = true;
+ } else {
+ mIncreaseExistingPadding = true;
}
}
}
import static com.android.ide.common.layout.LayoutConstants.ATTR_CLASS;
import static com.android.ide.common.layout.LayoutConstants.ATTR_NAME;
import static com.android.ide.common.layout.LayoutConstants.ATTR_TAG;
+import static com.android.ide.common.layout.LayoutConstants.FQCN_GESTURE_OVERLAY_VIEW;
import com.android.ide.common.api.IAttributeInfo.Format;
import com.android.ide.common.resources.platform.AttributeInfo;
import com.android.sdklib.SdkConstants;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/** The descriptor matching android.view.View. */
private ViewElementDescriptor mBaseViewDescriptor;
+ /** Map from view full class name to view descriptor */
+ private Map<String, ViewElementDescriptor> mFqcnToDescriptor =
+ // As of 3.1 there are 58 items in this map
+ new HashMap<String, ViewElementDescriptor>(80);
+
/** Returns the document descriptor. Contains all layouts and views linked together. */
public DocumentDescriptor getDescriptor() {
return mRootDescriptor;
*/
public ViewElementDescriptor getBaseViewDescriptor() {
if (mBaseViewDescriptor == null) {
- for (ElementDescriptor desc : mViewDescriptors) {
- if (desc instanceof ViewElementDescriptor) {
- ViewElementDescriptor viewDesc = (ViewElementDescriptor) desc;
- if (SdkConstants.CLASS_VIEW.equals(viewDesc.getFullClassName())) {
- mBaseViewDescriptor = viewDesc;
- break;
- }
- }
-
- }
+ mBaseViewDescriptor = findDescriptorByClass(SdkConstants.CLASS_VIEW);
}
return mBaseViewDescriptor;
}
for (ViewClassInfo info : views) {
ViewElementDescriptor desc = convertView(info, infoDescMap);
newViews.add(desc);
+ mFqcnToDescriptor.put(desc.getFullClassName(), desc);
}
}
for (ViewClassInfo info : layouts) {
ViewElementDescriptor desc = convertView(info, infoDescMap);
newLayouts.add(desc);
+ mFqcnToDescriptor.put(desc.getFullClassName(), desc);
}
}
// Find View and inherit all its layout attributes
- AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes(
- SdkConstants.CLASS_FRAMELAYOUT, newLayouts);
+ AttributeDescriptor[] frameLayoutAttrs = findViewLayoutAttributes(
+ SdkConstants.CLASS_FRAMELAYOUT);
if (target.getVersion().getApiLevel() >= 4) {
- ViewElementDescriptor fragmentTag = createFragment(viewLayoutAttribs, styleMap);
+ ViewElementDescriptor fragmentTag = createFragment(frameLayoutAttrs, styleMap);
newViews.add(fragmentTag);
}
layoutDesc.setChildren(newDescriptors);
}
+ // The gesture overlay descriptor is really a layout but not included in the layouts list
+ // so handle it specially
+ ViewElementDescriptor gestureView = findDescriptorByClass(FQCN_GESTURE_OVERLAY_VIEW);
+ if (gestureView != null) {
+ gestureView.setChildren(newDescriptors);
+ // Inherit layout attributes from FrameLayout
+ gestureView.setLayoutAttributes(frameLayoutAttrs);
+ }
+
fixSuperClasses(infoDescMap);
ViewElementDescriptor requestFocus = createRequestFocus();
// The <merge> tag can only be a root tag, so it is added at the end.
// It gets everything else as children but it is not made a child itself.
- ViewElementDescriptor mergeTag = createMerge(viewLayoutAttribs);
+ ViewElementDescriptor mergeTag = createMerge(frameLayoutAttrs);
mergeTag.setChildren(newDescriptors); // mergeTag makes a copy of the list
newDescriptors.add(mergeTag);
newLayouts.add(mergeTag);
private ViewElementDescriptor convertView(
ViewClassInfo info,
HashMap<ViewClassInfo, ViewElementDescriptor> infoDescMap) {
- String xml_name = info.getShortClassName();
+ String xmlName = info.getShortClassName();
+ String uiName = xmlName;
+ String fqcn = info.getFullClassName();
+ if (ViewElementDescriptor.viewNeedsPackage(fqcn)) {
+ xmlName = fqcn;
+ }
String tooltip = info.getJavaDoc();
ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
LayoutParamsInfo layoutParams = info.getLayoutData();
for(; layoutParams != null; layoutParams = layoutParams.getSuperClass()) {
- boolean need_separator = true;
- for (AttributeInfo attr_info : layoutParams.getAttributes()) {
+ boolean needSeparator = true;
+ for (AttributeInfo attrInfo : layoutParams.getAttributes()) {
if (DescriptorsUtils.containsAttribute(layoutAttributes,
- SdkConstants.NS_RESOURCES, attr_info)) {
+ SdkConstants.NS_RESOURCES, attrInfo)) {
continue;
}
- if (need_separator) {
+ if (needSeparator) {
String title;
if (layoutParams.getShortClassName().equals(
SdkConstants.CLASS_NAME_LAYOUTPARAMS)) {
layoutParams.getShortClassName());
}
layoutAttributes.add(new SeparatorAttributeDescriptor(title));
- need_separator = false;
+ needSeparator = false;
}
DescriptorsUtils.appendAttribute(layoutAttributes,
null, // elementName
SdkConstants.NS_RESOURCES,
- attr_info,
+ attrInfo,
false, // required
null /* overrides */);
}
}
- ViewElementDescriptor desc = new ViewElementDescriptor(xml_name,
- xml_name, // ui_name
- info.getFullClassName(),
+ ViewElementDescriptor desc = new ViewElementDescriptor(
+ xmlName,
+ uiName,
+ fqcn,
tooltip,
null, // sdk_url
attributes.toArray(new AttributeDescriptor[attributes.size()]),
* View descriptor and extract its layout attributes.
*/
private void insertInclude(List<ViewElementDescriptor> knownViews) {
- String xml_name = VIEW_INCLUDE;
+ String xmlName = VIEW_INCLUDE;
// Create the include custom attributes
ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
// Find View and inherit all its layout attributes
AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes(
- SdkConstants.CLASS_VIEW, knownViews);
+ SdkConstants.CLASS_VIEW);
// Create the include descriptor
- ViewElementDescriptor desc = new ViewElementDescriptor(xml_name, // xml_name
- xml_name, // ui_name
+ ViewElementDescriptor desc = new ViewElementDescriptor(xmlName,
+ xmlName, // ui_name
VIEW_INCLUDE, // "class name"; the GLE only treats this as an element tag
"Lets you statically include XML layouts inside other XML layouts.", // tooltip
null, // sdk_url
* @param viewLayoutAttribs The layout attributes to use for the new descriptor
*/
private ViewElementDescriptor createMerge(AttributeDescriptor[] viewLayoutAttribs) {
- String xml_name = VIEW_MERGE;
+ String xmlName = VIEW_MERGE;
// Create the include descriptor
- ViewElementDescriptor desc = new ViewElementDescriptor(xml_name, // xml_name
- xml_name, // ui_name
+ ViewElementDescriptor desc = new ViewElementDescriptor(xmlName,
+ xmlName, // ui_name
VIEW_MERGE, // "class name"; the GLE only treats this as an element tag
"A root tag useful for XML layouts inflated using a ViewStub.", // tooltip
null, // sdk_url
*/
private ViewElementDescriptor createFragment(AttributeDescriptor[] viewLayoutAttribs,
Map<String, DeclareStyleableInfo> styleMap) {
- String xml_name = VIEW_FRAGMENT;
+ String xmlName = VIEW_FRAGMENT;
final ViewElementDescriptor descriptor;
// First try to create the descriptor from metadata in attrs.xml:
// The above will only work on API 11 and up. However, fragments are *also* available
// on older platforms, via the fragment support library, so add in a manual
// entry if necessary.
- descriptor = new ViewElementDescriptor(xml_name, // xml_name
- xml_name, // ui_name
- xml_name, // "class name"; the GLE only treats this as an element tag
+ descriptor = new ViewElementDescriptor(xmlName,
+ xmlName, // ui_name
+ xmlName, // "class name"; the GLE only treats this as an element tag
fragmentTooltip,
sdkUrl,
new AttributeDescriptor[] {
* Creates and returns a new {@code <requestFocus>} descriptor.
*/
private ViewElementDescriptor createRequestFocus() {
- String xml_name = REQUEST_FOCUS;
+ String xmlName = REQUEST_FOCUS;
// Create the include descriptor
return new ViewElementDescriptor(
- xml_name, // xml_name
- xml_name, // ui_name
- xml_name, // "class name"; the GLE only treats this as an element tag
+ xmlName, // xml_name
+ xmlName, // ui_name
+ xmlName, // "class name"; the GLE only treats this as an element tag
"Requests focus for the parent element or one of its descendants", // tooltip
null, // sdk_url
null, // attributes
* Finds the descriptor and retrieves all its layout attributes.
*/
private AttributeDescriptor[] findViewLayoutAttributes(
- String viewFqcn,
- List<ViewElementDescriptor> knownViews) {
-
- for (ViewElementDescriptor viewDesc : knownViews) {
- if (viewFqcn.equals(viewDesc.getFullClassName())) {
- return viewDesc.getLayoutAttributes();
- }
+ String viewFqcn) {
+ ViewElementDescriptor viewDesc = findDescriptorByClass(viewFqcn);
+ if (viewDesc != null) {
+ return viewDesc.getLayoutAttributes();
}
return null;
}
}
}
+
+ /**
+ * Returns the {@link ViewElementDescriptor} with the given fully qualified class
+ * name, or null if not found. This is a quick map lookup.
+ *
+ * @param fqcn the fully qualified class name
+ * @return the corresponding {@link ViewElementDescriptor} or null
+ */
+ public ViewElementDescriptor findDescriptorByClass(String fqcn) {
+ return mFqcnToDescriptor.get(fqcn);
+ }
+
+ /**
+ * Returns the {@link ViewElementDescriptor} with the given XML tag name,
+ * which usually does not include the package (depending on the
+ * value of {@link ViewElementDescriptor#viewNeedsPackage(String)}).
+ *
+ * @param tag the XML tag name
+ * @return the corresponding {@link ViewElementDescriptor} or null
+ */
+ public ViewElementDescriptor findDescriptorByTag(String tag) {
+ // TODO: Consider whether we need to add a direct map lookup for this as well.
+ // Currently not done since this is not frequently needed (only needed for
+ // exploded rendering which was already performing list iteration.)
+ for (ViewElementDescriptor descriptor : mLayoutDescriptors) {
+ if (tag.equals(descriptor.getXmlLocalName())) {
+ return descriptor;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a collection of all the view class names, including layouts
+ *
+ * @return a collection of all the view class names, never null
+ */
+ public Collection<String> getAllViewClassNames() {
+ return mFqcnToDescriptor.keySet();
+ }
}
import static com.android.ide.common.layout.LayoutConstants.SCROLL_VIEW;
import static com.android.ide.common.layout.LayoutConstants.STRING_PREFIX;
import static com.android.ide.eclipse.adt.AdtConstants.ANDROID_PKG;
+import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor.viewNeedsPackage;
import static com.android.sdklib.SdkConstants.FD_GEN_SOURCES;
import com.android.ide.common.rendering.LayoutLibrary;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor;
+import com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ChangeFlags;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
-import com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.LayoutCreatorDialog;
+import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener;
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.editors.layout.gle2.IncludeFinder.Reference;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine;
import com.android.ide.eclipse.adt.internal.editors.ui.DecorComposite;
// is the same
labelClass),
actual,
- suggested.startsWith(ANDROID_PKG) ? suggestedBase : suggested
+ viewNeedsPackage(suggested) ? suggested : suggestedBase
);
addText(mErrorLabel, ", ");
}
}
private static Collection<String> getAndroidViewClassNames(IProject project) {
- List<String> classNames = new ArrayList<String>(100);
-
Sdk currentSdk = Sdk.getCurrent();
IAndroidTarget target = currentSdk.getTarget(project);
if (target != null) {
AndroidTargetData targetData = currentSdk.getTargetData(target);
LayoutDescriptors layoutDescriptors = targetData.getLayoutDescriptors();
-
- for (ViewElementDescriptor d : layoutDescriptors.getViewDescriptors()) {
- classNames.add(d.getFullClassName());
- }
- for (ViewElementDescriptor d : layoutDescriptors.getLayoutDescriptors()) {
- classNames.add(d.getFullClassName());
- }
+ return layoutDescriptors.getAllViewClassNames();
}
- return classNames;
+ return Collections.emptyList();
}
/** Add a normal line of text to the styled text widget. */