Home | History | Annotate | Download | only in uimodel
      1 /*
      2  * Copyright (C) 2008 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 
     17 package com.android.ide.eclipse.adt.internal.editors.layout.uimodel;
     18 
     19 import static com.android.ide.common.layout.LayoutConstants.FQCN_FRAME_LAYOUT;
     20 
     21 import com.android.ide.common.layout.LayoutConstants;
     22 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
     23 import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
     24 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
     25 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
     26 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
     27 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
     28 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
     29 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
     30 import com.android.sdklib.IAndroidTarget;
     31 import com.android.sdklib.SdkConstants;
     32 
     33 import org.eclipse.core.resources.IProject;
     34 
     35 /**
     36  * Specialized version of {@link UiElementNode} for the {@link ViewElementDescriptor}s.
     37  */
     38 public class UiViewElementNode extends UiElementNode {
     39 
     40     /** An AttributeDescriptor array that depends on the current UiParent. */
     41     private AttributeDescriptor[] mCachedAttributeDescriptors;
     42 
     43     public UiViewElementNode(ViewElementDescriptor elementDescriptor) {
     44         super(elementDescriptor);
     45     }
     46 
     47     /**
     48      * Returns an AttributeDescriptor array that depends on the current UiParent.
     49      * <p/>
     50      * The array merges both "direct" attributes with the descriptor layout attributes.
     51      * The array instance is cached and cleared if the UiParent is changed.
     52      */
     53     @Override
     54     public AttributeDescriptor[] getAttributeDescriptors() {
     55         if (mCachedAttributeDescriptors != null) {
     56             return mCachedAttributeDescriptors;
     57         }
     58 
     59         UiElementNode ui_parent = getUiParent();
     60         AttributeDescriptor[] direct_attrs = super.getAttributeDescriptors();
     61         mCachedAttributeDescriptors = direct_attrs;
     62 
     63         AttributeDescriptor[] layout_attrs = null;
     64         boolean need_xmlns = false;
     65 
     66         if (ui_parent instanceof UiDocumentNode) {
     67             // Limitation: right now the layout behaves as if everything was
     68             // owned by a FrameLayout.
     69             // TODO replace by something user-configurable.
     70 
     71             IProject project = getEditor().getProject();
     72             if (project != null) {
     73                 Sdk currentSdk = Sdk.getCurrent();
     74                 if (currentSdk != null) {
     75                     IAndroidTarget target = currentSdk.getTarget(project);
     76                     if (target != null) {
     77                         AndroidTargetData data = currentSdk.getTargetData(target);
     78                         if (data != null) {
     79                             LayoutDescriptors descriptors = data.getLayoutDescriptors();
     80                             ViewElementDescriptor desc =
     81                                 descriptors.findDescriptorByClass(FQCN_FRAME_LAYOUT);
     82                             if (desc != null) {
     83                                 layout_attrs = desc.getLayoutAttributes();
     84                                 need_xmlns = true;
     85                             }
     86                         }
     87                     }
     88                 }
     89             }
     90         } else if (ui_parent instanceof UiViewElementNode) {
     91             layout_attrs =
     92                 ((ViewElementDescriptor) ui_parent.getDescriptor()).getLayoutAttributes();
     93         }
     94 
     95         if (layout_attrs == null || layout_attrs.length == 0) {
     96             return mCachedAttributeDescriptors;
     97         }
     98 
     99         mCachedAttributeDescriptors =
    100             new AttributeDescriptor[direct_attrs.length +
    101                                     layout_attrs.length +
    102                                     (need_xmlns ? 1 : 0)];
    103         System.arraycopy(direct_attrs, 0,
    104                 mCachedAttributeDescriptors, 0,
    105                 direct_attrs.length);
    106         System.arraycopy(layout_attrs, 0,
    107                 mCachedAttributeDescriptors, direct_attrs.length,
    108                 layout_attrs.length);
    109         if (need_xmlns) {
    110             AttributeDescriptor desc = new XmlnsAttributeDescriptor(
    111                     LayoutConstants.ANDROID_NS_NAME,
    112                     SdkConstants.NS_RESOURCES);
    113             mCachedAttributeDescriptors[direct_attrs.length + layout_attrs.length] = desc;
    114         }
    115 
    116         return mCachedAttributeDescriptors;
    117     }
    118 
    119     /**
    120      * Sets the parent of this UI node.
    121      * <p/>
    122      * Also removes the cached AttributeDescriptor array that depends on the current UiParent.
    123      */
    124     @Override
    125     protected void setUiParent(UiElementNode parent) {
    126         super.setUiParent(parent);
    127         mCachedAttributeDescriptors = null;
    128     }
    129 }
    130