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