FileDocCategorySizeDatePackage
LayoutDescriptors.javaAPI DocAndroid 1.5 API13777Wed May 06 22:41:10 BST 2009com.android.ide.eclipse.editors.layout.descriptors

LayoutDescriptors

public final class LayoutDescriptors extends Object implements com.android.ide.eclipse.editors.descriptors.IDescriptorProvider
Complete description of the layout structure.

Fields Summary
public static final String
ID_ATTR
private com.android.ide.eclipse.editors.descriptors.DocumentDescriptor
mRootDescriptor
The document descriptor. Contains all layouts and views linked together.
private ArrayList
mLayoutDescriptors
The list of all known ViewLayout descriptors.
private List
mROLayoutDescriptors
Read-Only list of View Descriptors.
private ArrayList
mViewDescriptors
The list of all known View (not ViewLayout) descriptors.
private List
mROViewDescriptors
Read-Only list of View Descriptors.
Constructors Summary
Methods Summary
private com.android.ide.eclipse.editors.descriptors.ElementDescriptorconvertView(com.android.ide.eclipse.common.resources.ViewClassInfo info)
Creates an element descriptor from a given {@link ViewClassInfo}.

        String xml_name = info.getShortClassName();
        String tooltip = info.getJavaDoc();
        
        ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
        
        // All views and groups have an implicit "style" attribute which is a reference.
        AttributeInfo styleInfo = new DeclareStyleableInfo.AttributeInfo(
                "style",    //$NON-NLS-1$ xmlLocalName
                new DeclareStyleableInfo.AttributeInfo.Format[] {
                        DeclareStyleableInfo.AttributeInfo.Format.REFERENCE
                    });
        styleInfo.setJavaDoc("A reference to a custom style"); //tooltip
        DescriptorsUtils.appendAttribute(attributes,
                "style",    //$NON-NLS-1$
                null,       //nsUri
                styleInfo,
                false,      //required
                null);      // overrides
        
        // Process all View attributes
        DescriptorsUtils.appendAttributes(attributes,
                null, // elementName
                SdkConstants.NS_RESOURCES,
                info.getAttributes(),
                null, // requiredAttributes
                null /* overrides */);
        
        for (ViewClassInfo link = info.getSuperClass();
                link != null;
                link = link.getSuperClass()) {
            AttributeInfo[] attrList = link.getAttributes();
            if (attrList.length > 0) {
                attributes.add(new SeparatorAttributeDescriptor(
                        String.format("Attributes from %1$s", link.getShortClassName()))); 
                DescriptorsUtils.appendAttributes(attributes,
                        null, // elementName
                        SdkConstants.NS_RESOURCES,
                        attrList,
                        null, // requiredAttributes
                        null /* overrides */);
            }
        }

        // Process all LayoutParams attributes
        ArrayList<AttributeDescriptor> layoutAttributes = new ArrayList<AttributeDescriptor>();
        LayoutParamsInfo layoutParams = info.getLayoutData();

        for(; layoutParams != null; layoutParams = layoutParams.getSuperClass()) {
            boolean need_separator = true;
            for (AttributeInfo attr_info : layoutParams.getAttributes()) {
                if (DescriptorsUtils.containsAttribute(layoutAttributes,
                        SdkConstants.NS_RESOURCES, attr_info)) {
                    continue;
                }
                if (need_separator) {
                    String title;
                    if (layoutParams.getShortClassName().equals(
                            AndroidConstants.CLASS_NAME_LAYOUTPARAMS)) {
                        title = String.format("Layout Attributes from %1$s",
                                    layoutParams.getViewLayoutClass().getShortClassName());
                    } else {
                        title = String.format("Layout Attributes from %1$s (%2$s)",
                                layoutParams.getViewLayoutClass().getShortClassName(),
                                layoutParams.getShortClassName());
                    }
                    layoutAttributes.add(new SeparatorAttributeDescriptor(title));
                    need_separator = false;
                }
                DescriptorsUtils.appendAttribute(layoutAttributes,
                        null, // elementName
                        SdkConstants.NS_RESOURCES,
                        attr_info,
                        false, // required
                        null /* overrides */);
            }
        }

        return new ViewElementDescriptor(xml_name,
                xml_name, // ui_name
                info.getCanonicalClassName(),
                tooltip,
                null, // sdk_url
                attributes.toArray(new AttributeDescriptor[attributes.size()]),
                layoutAttributes.toArray(new AttributeDescriptor[layoutAttributes.size()]),
                null, // children
                false /* mandatory */);
    
private com.android.ide.eclipse.editors.descriptors.ElementDescriptorcreateMerge(java.util.ArrayList knownLayouts)
Creates and return a new descriptor.

param
knownLayouts A list of all known layout view descriptors, used to find the FrameLayout descriptor and extract its layout attributes.

        String xml_name = "merge";  //$NON-NLS-1$

        // Find View and inherit all its layout attributes
        AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes(
                AndroidConstants.CLASS_FRAMELAYOUT, knownLayouts);

        // Create the include descriptor
        ViewElementDescriptor desc = new ViewElementDescriptor(xml_name,  // xml_name
                xml_name, // ui_name
                null,     // canonical class name, we don't have one
                "A root tag useful for XML layouts inflated using a ViewStub.",  // tooltip
                null,  // sdk_url
                null,  // attributes
                viewLayoutAttribs,  // layout attributes
                null,  // children
                false  /* mandatory */);

        return desc;
    
private com.android.ide.eclipse.editors.descriptors.AttributeDescriptor[]findViewLayoutAttributes(java.lang.String viewFqcn, java.util.ArrayList knownViews)
Finds the descriptor and retrieves all its layout attributes.


        for (ElementDescriptor desc : knownViews) {
            if (desc instanceof ViewElementDescriptor) {
                ViewElementDescriptor viewDesc = (ViewElementDescriptor) desc;
                if (viewFqcn.equals(viewDesc.getCanonicalClassName())) {
                    return viewDesc.getLayoutAttributes();
                }
            }
        }
        
        return null;
    
public com.android.ide.eclipse.editors.descriptors.DocumentDescriptorgetDescriptor()

return
the document descriptor. Contains all layouts and views linked together.

    
                
       
        return mRootDescriptor;
    
public java.util.ListgetLayoutDescriptors()

return
The read-only list of all known ViewLayout descriptors.

        return mROLayoutDescriptors;
    
public com.android.ide.eclipse.editors.descriptors.ElementDescriptor[]getRootElementDescriptors()

        return mRootDescriptor.getChildren();
    
public java.util.ListgetViewDescriptors()

return
The read-only list of all known View (not ViewLayout) descriptors.

        return mROViewDescriptors;
    
private voidinsertInclude(java.util.ArrayList knownViews)
Creates a new descriptor and adds it to the list of view descriptors.

param
knownViews A list of view descriptors being populated. Also used to find the View descriptor and extract its layout attributes.

        String xml_name = "include";  //$NON-NLS-1$

        // Create the include custom attributes
        ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
        
        // Note that the "layout" attribute does NOT have the Android namespace
        DescriptorsUtils.appendAttribute(attributes,
                null, //elementXmlName
                null, //nsUri
                new AttributeInfo(
                        "layout",       //$NON-NLS-1$
                        new AttributeInfo.Format[] { AttributeInfo.Format.REFERENCE }
                        ),
                true,  //required
                null); //overrides

        DescriptorsUtils.appendAttribute(attributes,
                null, //elementXmlName
                SdkConstants.NS_RESOURCES, //nsUri
                new AttributeInfo(
                        "id",           //$NON-NLS-1$
                        new AttributeInfo.Format[] { AttributeInfo.Format.REFERENCE }
                        ),
                true,  //required
                null); //overrides

        // Find View and inherit all its layout attributes
        AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes(
                AndroidConstants.CLASS_VIEW, knownViews);

        // Create the include descriptor
        ViewElementDescriptor desc = new ViewElementDescriptor(xml_name,  // xml_name
                xml_name, // ui_name
                null,     // canonical class name, we don't have one
                "Lets you statically include XML layouts inside other XML layouts.",  // tooltip
                null, // sdk_url
                attributes.toArray(new AttributeDescriptor[attributes.size()]),
                viewLayoutAttribs,  // layout attributes
                null, // children
                false /* mandatory */);
        
        knownViews.add(desc);
    
public synchronized voidupdateDescriptors(com.android.ide.eclipse.common.resources.ViewClassInfo[] views, com.android.ide.eclipse.common.resources.ViewClassInfo[] layouts)
Updates the document descriptor.

It first computes the new children of the descriptor and then update them all at once.

TODO: differentiate groups from views in the tree UI? => rely on icons

param
views The list of views in the framework.
param
layouts The list of layouts in the framework.

        ArrayList<ElementDescriptor> newViews = new ArrayList<ElementDescriptor>();
        if (views != null) {
            for (ViewClassInfo info : views) {
                ElementDescriptor desc = convertView(info);
                newViews.add(desc);
            }
        }

        // Create <include> as a synthetic regular view.
        // Note: ViewStub is already described by attrs.xml
        insertInclude(newViews);

        ArrayList<ElementDescriptor> newLayouts = new ArrayList<ElementDescriptor>();
        if (layouts != null) {
            for (ViewClassInfo info : layouts) {
                ElementDescriptor desc = convertView(info);
                newLayouts.add(desc);
            }
        }

        ArrayList<ElementDescriptor> newDescriptors = new ArrayList<ElementDescriptor>();
        newDescriptors.addAll(newLayouts);
        newDescriptors.addAll(newViews);

        // Link all layouts to everything else here.. recursively
        for (ElementDescriptor layoutDesc : newLayouts) {
            layoutDesc.setChildren(newDescriptors);
        }

        // 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.
        ElementDescriptor mergeTag = createMerge(newLayouts);
        mergeTag.setChildren(newDescriptors);  // mergeTag makes a copy of the list
        newDescriptors.add(mergeTag);
        newLayouts.add(mergeTag);

        mViewDescriptors = newViews;
        mLayoutDescriptors  = newLayouts;
        mRootDescriptor.setChildren(newDescriptors);
        
        mROLayoutDescriptors = Collections.unmodifiableList(mLayoutDescriptors);
        mROViewDescriptors = Collections.unmodifiableList(mViewDescriptors);