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