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