| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Eclipse Public License, Version 1.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.eclipse.org/org/documents/epl-v10.php |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.ide.eclipse.adt.internal.editors.layout.gle2; |
| |
| import com.android.ide.common.api.Margins; |
| import com.android.ide.common.api.Rect; |
| import com.android.ide.common.api.ResizePolicy; |
| import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionHandle.Position; |
| import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| /** |
| * The {@link SelectionHandles} of a {@link SelectionItem} are the set of |
| * {@link SelectionHandle} objects (possibly empty, for non-resizable objects) the user |
| * can manipulate to resize a widget. |
| */ |
| public class SelectionHandles implements Iterable<SelectionHandle> { |
| private final SelectionItem mItem; |
| private List<SelectionHandle> mHandles; |
| |
| /** |
| * Constructs a new {@link SelectionHandles} object for the given {link |
| * {@link SelectionItem} |
| * @param item the item to create {@link SelectionHandles} for |
| */ |
| public SelectionHandles(SelectionItem item) { |
| mItem = item; |
| |
| createHandles(item.getCanvas()); |
| } |
| |
| /** |
| * Find a specific {@link SelectionHandle} from this set of {@link SelectionHandles}, |
| * which is within the given distance (in layout coordinates) from the center of the |
| * {@link SelectionHandle}. |
| * |
| * @param point the mouse position (in layout coordinates) to test |
| * @param distance the maximum distance from the handle center to accept |
| * @return a {@link SelectionHandle} under the point, or null if not found |
| */ |
| public SelectionHandle findHandle(LayoutPoint point, int distance) { |
| for (SelectionHandle handle : mHandles) { |
| if (handle.contains(point, distance)) { |
| return handle; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Create the {@link SelectionHandle} objects for the selection item, according to its |
| * {@link ResizePolicy}. |
| */ |
| private void createHandles(LayoutCanvas canvas) { |
| NodeProxy selectedNode = mItem.getNode(); |
| Rect r = selectedNode.getBounds(); |
| if (!r.isValid()) { |
| mHandles = Collections.emptyList(); |
| return; |
| } |
| |
| ResizePolicy resizability = mItem.getResizePolicy(); |
| if (resizability.isResizable()) { |
| mHandles = new ArrayList<SelectionHandle>(8); |
| boolean left = resizability.leftAllowed(); |
| boolean right = resizability.rightAllowed(); |
| boolean top = resizability.topAllowed(); |
| boolean bottom = resizability.bottomAllowed(); |
| int x1 = r.x; |
| int y1 = r.y; |
| int w = r.w; |
| int h = r.h; |
| int x2 = x1 + w; |
| int y2 = y1 + h; |
| |
| Margins insets = canvas.getInsets(mItem.getNode().getFqcn()); |
| if (insets != null) { |
| x1 += insets.left; |
| x2 -= insets.right; |
| y1 += insets.top; |
| y2 -= insets.bottom; |
| } |
| |
| int mx = (x1 + x2) / 2; |
| int my = (y1 + y2) / 2; |
| |
| if (left) { |
| mHandles.add(new SelectionHandle(x1, my, Position.LEFT_MIDDLE)); |
| if (top) { |
| mHandles.add(new SelectionHandle(x1, y1, Position.TOP_LEFT)); |
| } |
| if (bottom) { |
| mHandles.add(new SelectionHandle(x1, y2, Position.BOTTOM_LEFT)); |
| } |
| } |
| if (right) { |
| mHandles.add(new SelectionHandle(x2, my, Position.RIGHT_MIDDLE)); |
| if (top) { |
| mHandles.add(new SelectionHandle(x2, y1, Position.TOP_RIGHT)); |
| } |
| if (bottom) { |
| mHandles.add(new SelectionHandle(x2, y2, Position.BOTTOM_RIGHT)); |
| } |
| } |
| if (top) { |
| mHandles.add(new SelectionHandle(mx, y1, Position.TOP_MIDDLE)); |
| } |
| if (bottom) { |
| mHandles.add(new SelectionHandle(mx, y2, Position.BOTTOM_MIDDLE)); |
| } |
| } else { |
| mHandles = Collections.emptyList(); |
| } |
| } |
| |
| // Implements Iterable<SelectionHandle> |
| @Override |
| public Iterator<SelectionHandle> iterator() { |
| return mHandles.iterator(); |
| } |
| } |