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 package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
17 
18 import org.eclipse.swt.SWT;
19 
20 /**
21  * A selection handle is a small rectangle on the border of a selected view which lets you
22  * change the size of the view by dragging it.
23  */
24 public class SelectionHandle {
25     /**
26      * Size of the selection handle radius, in control coordinates. Note that this isn't
27      * necessarily a <b>circular</b> radius; in the case of a rectangular handle, the
28      * width and the height are both equal to this radius.
29      * Note also that this radius is in <b>control</b> coordinates, whereas the rest
30      * of the class operates in layout coordinates. This is because we do not want the
31      * selection handles to grow or shrink along with the screen zoom; they are always
32      * at the given pixel size in the control.
33      */
34     public final static int PIXEL_RADIUS = 3;
35 
36     /**
37      * Extra number of pixels to look beyond the actual radius of the selection handle
38      * when matching mouse positions to handles
39      */
40     public final static int PIXEL_MARGIN = 2;
41 
42     /** The position of the handle in the selection rectangle */
43     enum Position {
44         TOP_MIDDLE(SWT.CURSOR_SIZEN),
45         TOP_RIGHT(SWT.CURSOR_SIZENE),
46         RIGHT_MIDDLE(SWT.CURSOR_SIZEE),
47         BOTTOM_RIGHT(SWT.CURSOR_SIZESE),
48         BOTTOM_MIDDLE(SWT.CURSOR_SIZES),
49         BOTTOM_LEFT(SWT.CURSOR_SIZESW),
50         LEFT_MIDDLE(SWT.CURSOR_SIZEW),
51         TOP_LEFT(SWT.CURSOR_SIZENW);
52 
53         /** Corresponding SWT cursor value */
54         private int mSwtCursor;
55 
Position(int swtCursor)56         private Position(int swtCursor) {
57             mSwtCursor = swtCursor;
58         }
59 
getCursorType()60         private int getCursorType() {
61             return mSwtCursor;
62         }
63 
64         /** Is the {@link SelectionHandle} somewhere on the left edge? */
isLeft()65         boolean isLeft() {
66             return this == TOP_LEFT || this == LEFT_MIDDLE || this == BOTTOM_LEFT;
67         }
68 
69         /** Is the {@link SelectionHandle} somewhere on the right edge? */
isRight()70         boolean isRight() {
71             return this == TOP_RIGHT || this == RIGHT_MIDDLE || this == BOTTOM_RIGHT;
72         }
73 
74         /** Is the {@link SelectionHandle} somewhere on the top edge? */
isTop()75         boolean isTop() {
76             return this == TOP_LEFT || this == TOP_MIDDLE || this == TOP_RIGHT;
77         }
78 
79         /** Is the {@link SelectionHandle} somewhere on the bottom edge? */
isBottom()80         boolean isBottom() {
81             return this == BOTTOM_LEFT || this == BOTTOM_MIDDLE || this == BOTTOM_RIGHT;
82         }
83     };
84 
85     /** The x coordinate of the center of the selection handle */
86     public final int centerX;
87     /** The y coordinate of the center of the selection handle */
88     public final int centerY;
89     /** The position of the handle in the selection rectangle */
90     private final Position mPosition;
91 
92     /**
93      * Constructs a new {@link SelectionHandle} at the given layout coordinate
94      * corresponding to a handle at the given {@link Position}.
95      *
96      * @param centerX the x coordinate of the center of the selection handle
97      * @param centerY y coordinate of the center of the selection handle
98      * @param position the position of the handle in the selection rectangle
99      */
SelectionHandle(int centerX, int centerY, Position position)100     public SelectionHandle(int centerX, int centerY, Position position) {
101         mPosition = position;
102         this.centerX = centerX;
103         this.centerY = centerY;
104     }
105 
106     /**
107      * Determines whether the given {@link LayoutPoint} is within the given distance in
108      * layout coordinates. The distance should incorporate at least the equivalent
109      * distance to the control coordinate space {@link #PIXEL_RADIUS}, but usually with a
110      * few extra pixels added in to make the corners easier to target.
111      *
112      * @param point the mouse position in layout coordinates
113      * @param distance the distance from the center of the handle to check whether the
114      *            point fits within
115      * @return true if the given point is within the given distance of this handle
116      */
contains(LayoutPoint point, int distance)117     public boolean contains(LayoutPoint point, int distance) {
118         return (point.x >= centerX - distance
119               && point.x <= centerX + distance
120               && point.y >= centerY - distance
121               && point.y <= centerY + distance);
122     }
123 
124     /**
125      * Returns the position of the handle in the selection rectangle
126      *
127      * @return the position of the handle in the selection rectangle
128      */
getPosition()129     public Position getPosition() {
130         return mPosition;
131     }
132 
133     /**
134      * Returns the SWT cursor type to use for this selection handle
135      *
136      * @return the position of the handle in the selection rectangle
137      */
getSwtCursorType()138     public int getSwtCursorType() {
139         return mPosition.getCursorType();
140     }
141 }
142