aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionHandle.java
blob: c2db2431c7762b9d8396bce425356f5b85ea3e39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * 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 org.eclipse.swt.SWT;

/**
 * A selection handle is a small rectangle on the border of a selected view which lets you
 * change the size of the view by dragging it.
 */
public class SelectionHandle {
    /**
     * Size of the selection handle radius, in control coordinates. Note that this isn't
     * necessarily a <b>circular</b> radius; in the case of a rectangular handle, the
     * width and the height are both equal to this radius.
     * Note also that this radius is in <b>control</b> coordinates, whereas the rest
     * of the class operates in layout coordinates. This is because we do not want the
     * selection handles to grow or shrink along with the screen zoom; they are always
     * at the given pixel size in the control.
     */
    public final static int PIXEL_RADIUS = 3;

    /**
     * Extra number of pixels to look beyond the actual radius of the selection handle
     * when matching mouse positions to handles
     */
    public final static int PIXEL_MARGIN = 2;

    /** The position of the handle in the selection rectangle */
    enum Position {
        TOP_MIDDLE(SWT.CURSOR_SIZEN),
        TOP_RIGHT(SWT.CURSOR_SIZENE),
        RIGHT_MIDDLE(SWT.CURSOR_SIZEE),
        BOTTOM_RIGHT(SWT.CURSOR_SIZESE),
        BOTTOM_MIDDLE(SWT.CURSOR_SIZES),
        BOTTOM_LEFT(SWT.CURSOR_SIZESW),
        LEFT_MIDDLE(SWT.CURSOR_SIZEW),
        TOP_LEFT(SWT.CURSOR_SIZENW);

        /** Corresponding SWT cursor value */
        private int mSwtCursor;

        private Position(int swtCursor) {
            mSwtCursor = swtCursor;
        }

        private int getCursorType() {
            return mSwtCursor;
        }

        /** Is the {@link SelectionHandle} somewhere on the left edge? */
        boolean isLeft() {
            return this == TOP_LEFT || this == LEFT_MIDDLE || this == BOTTOM_LEFT;
        }

        /** Is the {@link SelectionHandle} somewhere on the right edge? */
        boolean isRight() {
            return this == TOP_RIGHT || this == RIGHT_MIDDLE || this == BOTTOM_RIGHT;
        }

        /** Is the {@link SelectionHandle} somewhere on the top edge? */
        boolean isTop() {
            return this == TOP_LEFT || this == TOP_MIDDLE || this == TOP_RIGHT;
        }

        /** Is the {@link SelectionHandle} somewhere on the bottom edge? */
        boolean isBottom() {
            return this == BOTTOM_LEFT || this == BOTTOM_MIDDLE || this == BOTTOM_RIGHT;
        }
    };

    /** The x coordinate of the center of the selection handle */
    public final int centerX;
    /** The y coordinate of the center of the selection handle */
    public final int centerY;
    /** The position of the handle in the selection rectangle */
    private final Position mPosition;

    /**
     * Constructs a new {@link SelectionHandle} at the given layout coordinate
     * corresponding to a handle at the given {@link Position}.
     *
     * @param centerX the x coordinate of the center of the selection handle
     * @param centerY y coordinate of the center of the selection handle
     * @param position the position of the handle in the selection rectangle
     */
    public SelectionHandle(int centerX, int centerY, Position position) {
        mPosition = position;
        this.centerX = centerX;
        this.centerY = centerY;
    }

    /**
     * Determines whether the given {@link LayoutPoint} is within the given distance in
     * layout coordinates. The distance should incorporate at least the equivalent
     * distance to the control coordinate space {@link #PIXEL_RADIUS}, but usually with a
     * few extra pixels added in to make the corners easier to target.
     *
     * @param point the mouse position in layout coordinates
     * @param distance the distance from the center of the handle to check whether the
     *            point fits within
     * @return true if the given point is within the given distance of this handle
     */
    public boolean contains(LayoutPoint point, int distance) {
        return (point.x >= centerX - distance
              && point.x <= centerX + distance
              && point.y >= centerY - distance
              && point.y <= centerY + distance);
    }

    /**
     * Returns the position of the handle in the selection rectangle
     *
     * @return the position of the handle in the selection rectangle
     */
    public Position getPosition() {
        return mPosition;
    }

    /**
     * Returns the SWT cursor type to use for this selection handle
     *
     * @return the position of the handle in the selection rectangle
     */
    public int getSwtCursorType() {
        return mPosition.getCursorType();
    }
}