1 /* 2 * Copyright (C) 2009 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.gle2; 18 19 import com.android.annotations.NonNull; 20 import com.android.annotations.Nullable; 21 import com.android.ide.common.api.ResizePolicy; 22 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate; 23 import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy; 24 import com.android.ide.eclipse.adt.internal.editors.layout.gre.ViewMetadataRepository; 25 import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; 26 27 import org.eclipse.swt.graphics.Rectangle; 28 import org.w3c.dom.Node; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 /** 34 * Represents one selection in {@link LayoutCanvas}. 35 */ 36 class SelectionItem { 37 38 /** The associated {@link LayoutCanvas} */ 39 private LayoutCanvas mCanvas; 40 41 /** Current selected view info. Can be null. */ 42 private final CanvasViewInfo mCanvasViewInfo; 43 44 /** Current selection border rectangle. Null when mCanvasViewInfo is null . */ 45 private final Rectangle mRect; 46 47 /** The node proxy for drawing the selection. Null when mCanvasViewInfo is null. */ 48 private final NodeProxy mNodeProxy; 49 50 /** The resize policy for this selection item */ 51 private ResizePolicy mResizePolicy; 52 53 /** The selection handles for this item */ 54 private SelectionHandles mHandles; 55 56 /** 57 * Creates a new {@link SelectionItem} object. 58 * @param canvas the associated canvas 59 * @param canvasViewInfo The view info being selected. Must not be null. 60 */ SelectionItem(LayoutCanvas canvas, CanvasViewInfo canvasViewInfo)61 public SelectionItem(LayoutCanvas canvas, CanvasViewInfo canvasViewInfo) { 62 assert canvasViewInfo != null; 63 64 mCanvas = canvas; 65 mCanvasViewInfo = canvasViewInfo; 66 67 if (canvasViewInfo == null) { 68 mRect = null; 69 mNodeProxy = null; 70 } else { 71 Rectangle r = canvasViewInfo.getSelectionRect(); 72 mRect = new Rectangle(r.x, r.y, r.width, r.height); 73 mNodeProxy = mCanvas.getNodeFactory().create(canvasViewInfo); 74 } 75 } 76 77 /** 78 * Returns true when this selection item represents the root, the top level 79 * layout element in the editor. 80 * 81 * @return True if and only if this element is at the root of the hierarchy 82 */ isRoot()83 public boolean isRoot() { 84 return mCanvasViewInfo.isRoot(); 85 } 86 87 /** 88 * Returns true if this item represents a widget that should not be manipulated by the 89 * user. 90 * 91 * @return True if this widget should not be manipulated directly by the user 92 */ isHidden()93 public boolean isHidden() { 94 return mCanvasViewInfo.isHidden(); 95 } 96 97 /** 98 * Returns the selected view info. Cannot be null. 99 * 100 * @return the selected view info. Cannot be null. 101 */ 102 @NonNull getViewInfo()103 public CanvasViewInfo getViewInfo() { 104 return mCanvasViewInfo; 105 } 106 107 /** 108 * Returns the selected node. 109 * 110 * @return the selected node, or null 111 */ 112 @Nullable getUiNode()113 public UiViewElementNode getUiNode() { 114 return mCanvasViewInfo.getUiViewNode(); 115 } 116 117 /** 118 * Returns the selection border rectangle. Cannot be null. 119 * 120 * @return the selection border rectangle, never null 121 */ getRect()122 public Rectangle getRect() { 123 return mRect; 124 } 125 126 /** Returns the node associated with this selection (may be null) */ 127 @Nullable getNode()128 NodeProxy getNode() { 129 return mNodeProxy; 130 } 131 132 /** Returns the canvas associated with this selection (never null) */ 133 @NonNull getCanvas()134 LayoutCanvas getCanvas() { 135 return mCanvas; 136 } 137 138 //---- 139 140 /** 141 * Gets the XML text from the given selection for a text transfer. 142 * The returned string can be empty but not null. 143 */ 144 @NonNull getAsText(LayoutCanvas canvas, List<SelectionItem> selection)145 static String getAsText(LayoutCanvas canvas, List<SelectionItem> selection) { 146 StringBuilder sb = new StringBuilder(); 147 148 LayoutEditorDelegate layoutEditorDelegate = canvas.getEditorDelegate(); 149 for (SelectionItem cs : selection) { 150 CanvasViewInfo vi = cs.getViewInfo(); 151 UiViewElementNode key = vi.getUiViewNode(); 152 Node node = key.getXmlNode(); 153 String t = layoutEditorDelegate.getEditor().getXmlText(node); 154 if (t != null) { 155 if (sb.length() > 0) { 156 sb.append('\n'); 157 } 158 sb.append(t); 159 } 160 } 161 162 return sb.toString(); 163 } 164 165 /** 166 * Returns elements representing the given selection of canvas items. 167 * 168 * @param items Items to wrap in elements 169 * @return An array of wrapper elements. Never null. 170 */ 171 @NonNull getAsElements(@onNull List<SelectionItem> items)172 static SimpleElement[] getAsElements(@NonNull List<SelectionItem> items) { 173 return getAsElements(items, null); 174 } 175 176 /** 177 * Returns elements representing the given selection of canvas items. 178 * 179 * @param items Items to wrap in elements 180 * @param primary The primary selected item which should be listed first 181 * @return An array of wrapper elements. Never null. 182 */ 183 @NonNull getAsElements( @onNull List<SelectionItem> items, @Nullable SelectionItem primary)184 static SimpleElement[] getAsElements( 185 @NonNull List<SelectionItem> items, 186 @Nullable SelectionItem primary) { 187 List<SimpleElement> elements = new ArrayList<SimpleElement>(); 188 189 if (primary != null) { 190 CanvasViewInfo vi = primary.getViewInfo(); 191 SimpleElement e = vi.toSimpleElement(); 192 e.setSelectionItem(primary); 193 elements.add(e); 194 } 195 196 for (SelectionItem cs : items) { 197 if (cs == primary) { 198 // Already handled 199 continue; 200 } 201 202 CanvasViewInfo vi = cs.getViewInfo(); 203 SimpleElement e = vi.toSimpleElement(); 204 e.setSelectionItem(cs); 205 elements.add(e); 206 } 207 208 return elements.toArray(new SimpleElement[elements.size()]); 209 } 210 211 /** 212 * Returns true if this selection item is a layout 213 * 214 * @return true if this selection item is a layout 215 */ isLayout()216 public boolean isLayout() { 217 UiViewElementNode node = mCanvasViewInfo.getUiViewNode(); 218 if (node != null) { 219 return node.getDescriptor().hasChildren(); 220 } else { 221 return false; 222 } 223 } 224 225 /** 226 * Returns the {@link SelectionHandles} for this {@link SelectionItem}. Never null. 227 * 228 * @return the {@link SelectionHandles} for this {@link SelectionItem}, never null 229 */ 230 @NonNull getSelectionHandles()231 public SelectionHandles getSelectionHandles() { 232 if (mHandles == null) { 233 mHandles = new SelectionHandles(this); 234 } 235 236 return mHandles; 237 } 238 239 /** 240 * Returns the {@link ResizePolicy} for this item 241 * 242 * @return the {@link ResizePolicy} for this item, never null 243 */ 244 @NonNull getResizePolicy()245 public ResizePolicy getResizePolicy() { 246 if (mResizePolicy == null && mNodeProxy != null) { 247 mResizePolicy = ViewMetadataRepository.get().getResizePolicy(mNodeProxy.getFqcn()); 248 } 249 250 return mResizePolicy; 251 } 252 } 253