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