Home | History | Annotate | Download | only in gle2
      1 /*
      2  * Copyright (C) 2011 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.ide.common.api.Margins;
     20 import com.android.ide.common.api.Rect;
     21 import com.android.ide.common.api.ResizePolicy;
     22 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionHandle.Position;
     23 import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy;
     24 
     25 import java.util.ArrayList;
     26 import java.util.Collections;
     27 import java.util.Iterator;
     28 import java.util.List;
     29 
     30 /**
     31  * The {@link SelectionHandles} of a {@link SelectionItem} are the set of
     32  * {@link SelectionHandle} objects (possibly empty, for non-resizable objects) the user
     33  * can manipulate to resize a widget.
     34  */
     35 public class SelectionHandles implements Iterable<SelectionHandle> {
     36     private final SelectionItem mItem;
     37     private List<SelectionHandle> mHandles;
     38 
     39     /**
     40      * Constructs a new {@link SelectionHandles} object for the given {link
     41      * {@link SelectionItem}
     42      * @param item the item to create {@link SelectionHandles} for
     43      */
     44     public SelectionHandles(SelectionItem item) {
     45         mItem = item;
     46 
     47         createHandles(item.getCanvas());
     48     }
     49 
     50     /**
     51      * Find a specific {@link SelectionHandle} from this set of {@link SelectionHandles},
     52      * which is within the given distance (in layout coordinates) from the center of the
     53      * {@link SelectionHandle}.
     54      *
     55      * @param point the mouse position (in layout coordinates) to test
     56      * @param distance the maximum distance from the handle center to accept
     57      * @return a {@link SelectionHandle} under the point, or null if not found
     58      */
     59     public SelectionHandle findHandle(LayoutPoint point, int distance) {
     60         for (SelectionHandle handle : mHandles) {
     61             if (handle.contains(point, distance)) {
     62                 return handle;
     63             }
     64         }
     65 
     66         return null;
     67     }
     68 
     69     /**
     70      * Create the {@link SelectionHandle} objects for the selection item, according to its
     71      * {@link ResizePolicy}.
     72      */
     73     private void createHandles(LayoutCanvas canvas) {
     74         NodeProxy selectedNode = mItem.getNode();
     75         Rect r = selectedNode.getBounds();
     76         if (!r.isValid()) {
     77             mHandles = Collections.emptyList();
     78             return;
     79         }
     80 
     81         ResizePolicy resizability = mItem.getResizePolicy();
     82         if (resizability.isResizable()) {
     83             mHandles = new ArrayList<SelectionHandle>(8);
     84             boolean left = resizability.leftAllowed();
     85             boolean right = resizability.rightAllowed();
     86             boolean top = resizability.topAllowed();
     87             boolean bottom = resizability.bottomAllowed();
     88             int x1 = r.x;
     89             int y1 = r.y;
     90             int w = r.w;
     91             int h = r.h;
     92             int x2 = x1 + w;
     93             int y2 = y1 + h;
     94 
     95             Margins insets = canvas.getInsets(mItem.getNode().getFqcn());
     96             if (insets != null) {
     97                 x1 += insets.left;
     98                 x2 -= insets.right;
     99                 y1 += insets.top;
    100                 y2 -= insets.bottom;
    101             }
    102 
    103             int mx = (x1 + x2) / 2;
    104             int my = (y1 + y2) / 2;
    105 
    106             if (left) {
    107                 mHandles.add(new SelectionHandle(x1, my, Position.LEFT_MIDDLE));
    108                 if (top) {
    109                     mHandles.add(new SelectionHandle(x1, y1, Position.TOP_LEFT));
    110                 }
    111                 if (bottom) {
    112                     mHandles.add(new SelectionHandle(x1, y2, Position.BOTTOM_LEFT));
    113                 }
    114             }
    115             if (right) {
    116                 mHandles.add(new SelectionHandle(x2, my, Position.RIGHT_MIDDLE));
    117                 if (top) {
    118                     mHandles.add(new SelectionHandle(x2, y1, Position.TOP_RIGHT));
    119                 }
    120                 if (bottom) {
    121                     mHandles.add(new SelectionHandle(x2, y2, Position.BOTTOM_RIGHT));
    122                 }
    123             }
    124             if (top) {
    125                 mHandles.add(new SelectionHandle(mx, y1, Position.TOP_MIDDLE));
    126             }
    127             if (bottom) {
    128                 mHandles.add(new SelectionHandle(mx, y2, Position.BOTTOM_MIDDLE));
    129             }
    130         } else {
    131             mHandles = Collections.emptyList();
    132         }
    133     }
    134 
    135     // Implements Iterable<SelectionHandle>
    136     @Override
    137     public Iterator<SelectionHandle> iterator() {
    138         return mHandles.iterator();
    139     }
    140 }
    141