1429ae88878cf781753d8261d350ad89fe5864169Tor Norbye/*
2429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * Copyright (C) 2011 The Android Open Source Project
3429ae88878cf781753d8261d350ad89fe5864169Tor Norbye *
4429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * you may not use this file except in compliance with the License.
6429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * You may obtain a copy of the License at
7429ae88878cf781753d8261d350ad89fe5864169Tor Norbye *
8429ae88878cf781753d8261d350ad89fe5864169Tor Norbye *      http://www.eclipse.org/org/documents/epl-v10.php
9429ae88878cf781753d8261d350ad89fe5864169Tor Norbye *
10429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * Unless required by applicable law or agreed to in writing, software
11429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS,
12429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * See the License for the specific language governing permissions and
14429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * limitations under the License.
15429ae88878cf781753d8261d350ad89fe5864169Tor Norbye */
16429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
17429ae88878cf781753d8261d350ad89fe5864169Tor Norbyepackage com.android.ide.eclipse.adt.internal.editors.layout.gle2;
18429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
19429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport com.android.ide.common.api.DropFeedback;
20429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport com.android.ide.common.api.Rect;
21429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport com.android.ide.common.api.ResizePolicy;
2280d9301c2e874b29889c41adb0623666cf534fa0Tor Norbyeimport com.android.ide.common.api.SegmentType;
23429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionHandle.Position;
24429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy;
25429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine;
2685e4a1a9dd133abb879ec211ce8dd385004edf22Xavier Ducrohetimport com.android.utils.Pair;
27429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
2880d9301c2e874b29889c41adb0623666cf534fa0Tor Norbyeimport org.eclipse.swt.events.KeyEvent;
29429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport org.eclipse.swt.graphics.GC;
30429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
31429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport java.util.Collections;
32429ae88878cf781753d8261d350ad89fe5864169Tor Norbyeimport java.util.List;
33429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
34429ae88878cf781753d8261d350ad89fe5864169Tor Norbye/**
35429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * A {@link ResizeGesture} is a gesture for resizing a selected widget. It is initiated
36429ae88878cf781753d8261d350ad89fe5864169Tor Norbye * by a drag of a {@link SelectionHandle}.
37429ae88878cf781753d8261d350ad89fe5864169Tor Norbye */
38429ae88878cf781753d8261d350ad89fe5864169Tor Norbyepublic class ResizeGesture extends Gesture {
39429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    /** The {@link Overlay} drawn for the gesture feedback. */
40429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private ResizeOverlay mOverlay;
41429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
42429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    /** The canvas associated with this gesture. */
43429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private LayoutCanvas mCanvas;
44429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
45429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    /** The selection handle we're dragging to perform this resize */
46429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private SelectionHandle mHandle;
47429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
48429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private NodeProxy mParentNode;
49429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private NodeProxy mChildNode;
50429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private DropFeedback mFeedback;
51429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private ResizePolicy mResizePolicy;
5280d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    private SegmentType mHorizontalEdge;
5380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    private SegmentType mVerticalEdge;
54429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
55429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    /**
56429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * Creates a new marquee selection (selection swiping).
57429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     *
58429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * @param canvas The canvas where selection is performed.
59429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * @param item The selected item the handle corresponds to
60429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * @param handle The handle being dragged to perform the resize
61429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     */
62429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    public ResizeGesture(LayoutCanvas canvas, SelectionItem item, SelectionHandle handle) {
63429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mCanvas = canvas;
64429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mHandle = handle;
65429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
66429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mChildNode = item.getNode();
67429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mParentNode = (NodeProxy) mChildNode.getParent();
68429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mResizePolicy = item.getResizePolicy();
6980d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        mHorizontalEdge = getHorizontalEdgeType(mHandle);
7080d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        mVerticalEdge = getVerticalEdgeType(mHandle);
71429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    }
72429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
73429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    @Override
74429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    public void begin(ControlPoint pos, int startMask) {
75429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        super.begin(pos, startMask);
76429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
7780d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        mCanvas.getSelectionOverlay().setHidden(true);
7880d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye
79429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        RulesEngine rulesEngine = mCanvas.getRulesEngine();
80429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        Rect newBounds = getNewBounds(pos);
81bf9db3ba5053c8f22a07ee748b2cb41d374d8642Tor Norbye        ViewHierarchy viewHierarchy = mCanvas.getViewHierarchy();
82bf9db3ba5053c8f22a07ee748b2cb41d374d8642Tor Norbye        CanvasViewInfo childInfo = viewHierarchy.findViewInfoFor(mChildNode);
83bf9db3ba5053c8f22a07ee748b2cb41d374d8642Tor Norbye        CanvasViewInfo parentInfo = viewHierarchy.findViewInfoFor(mParentNode);
84bf9db3ba5053c8f22a07ee748b2cb41d374d8642Tor Norbye        Object childView = childInfo != null ? childInfo.getViewObject() : null;
85bf9db3ba5053c8f22a07ee748b2cb41d374d8642Tor Norbye        Object parentView = parentInfo != null ? parentInfo.getViewObject() : null;
8680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        mFeedback = rulesEngine.callOnResizeBegin(mChildNode, mParentNode, newBounds,
87bf9db3ba5053c8f22a07ee748b2cb41d374d8642Tor Norbye                mHorizontalEdge, mVerticalEdge, childView, parentView);
881c9f2f2274a757006035f1031cf3117c1cd7632eTor Norbye        update(pos);
89429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mCanvas.getGestureManager().updateMessage(mFeedback);
90429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    }
91429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
92429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    @Override
9380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    public boolean keyPressed(KeyEvent event) {
9480d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        update(mCanvas.getGestureManager().getCurrentControlPoint());
9580d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        mCanvas.redraw();
9680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        return true;
9780d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    }
9880d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye
9980d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    @Override
10080d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    public boolean keyReleased(KeyEvent event) {
10180d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        update(mCanvas.getGestureManager().getCurrentControlPoint());
10280d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        mCanvas.redraw();
10380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        return true;
10480d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    }
10580d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye
10680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    @Override
107429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    public void update(ControlPoint pos) {
108429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        super.update(pos);
109429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        RulesEngine rulesEngine = mCanvas.getRulesEngine();
110429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        Rect newBounds = getNewBounds(pos);
11180d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        int modifierMask = mCanvas.getGestureManager().getRuleModifierMask();
11280d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        rulesEngine.callOnResizeUpdate(mFeedback, mChildNode, mParentNode, newBounds,
11380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye                modifierMask);
114429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mCanvas.getGestureManager().updateMessage(mFeedback);
115429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    }
116429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
117429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    @Override
118429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    public void end(ControlPoint pos, boolean canceled) {
119429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        super.end(pos, canceled);
120429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
121429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        if (!canceled) {
122429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            RulesEngine rulesEngine = mCanvas.getRulesEngine();
123429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            Rect newBounds = getNewBounds(pos);
12480d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            rulesEngine.callOnResizeEnd(mFeedback, mChildNode, mParentNode, newBounds);
125429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        }
12680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye
12780d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        mCanvas.getSelectionOverlay().setHidden(false);
128429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    }
129429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
1308f6e2fc89af2a75e05608d9ee1c648171ea47d83Tor Norbye    @Override
1318f6e2fc89af2a75e05608d9ee1c648171ea47d83Tor Norbye    public Pair<Boolean, Boolean> getTooltipPosition() {
1328f6e2fc89af2a75e05608d9ee1c648171ea47d83Tor Norbye        return Pair.of(mHorizontalEdge != SegmentType.TOP, mVerticalEdge != SegmentType.LEFT);
1338f6e2fc89af2a75e05608d9ee1c648171ea47d83Tor Norbye    }
1348f6e2fc89af2a75e05608d9ee1c648171ea47d83Tor Norbye
135429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    /**
136429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * For the new mouse position, compute the resized bounds (the bounding rectangle that
137429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * the view should be resized to). This is not just a width or height, since in some
138429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * cases resizing will change the x/y position of the view as well (for example, in
139429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * RelativeLayout or in AbsoluteLayout).
140429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     */
141429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private Rect getNewBounds(ControlPoint pos) {
142429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        LayoutPoint p = pos.toLayout();
143429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        LayoutPoint start = mStart.toLayout();
144429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        Rect b = mChildNode.getBounds();
145429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        Position direction = mHandle.getPosition();
146429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
147429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        int x = b.x;
148429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        int y = b.y;
149429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        int w = b.w;
150429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        int h = b.h;
151429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        int deltaX = p.x - start.x;
152429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        int deltaY = p.y - start.y;
153429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
154429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        if (deltaX == 0 && deltaY == 0) {
155429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // No move - just use the existing bounds
156429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            return b;
157429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        }
158429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
159429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        if (mResizePolicy.isAspectPreserving() && w != 0 && h != 0) {
160429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            double aspectRatio = w / (double) h;
161429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int newW = Math.abs(b.w + (direction.isLeft() ? -deltaX : deltaX));
162429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int newH = Math.abs(b.h + (direction.isTop() ? -deltaY : deltaY));
163429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            double newAspectRatio = newW / (double) newH;
164429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            if (newH == 0 || newAspectRatio > aspectRatio) {
165429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                deltaY = (int) (deltaX / aspectRatio);
166429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            } else {
167429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                deltaX = (int) (deltaY * aspectRatio);
168429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            }
169429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        }
170429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        if (direction.isLeft()) {
171429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // The user is dragging the left edge, so the position is anchored on the
172429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // right.
173429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int x2 = b.x + b.w;
174429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int nx1 = b.x + deltaX;
175429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            if (nx1 <= x2) {
176429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                x = nx1;
177429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                w = x2 - x;
178429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            } else {
179429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                w = 0;
180429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                x = x2;
181429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            }
182429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        } else if (direction.isRight()) {
183429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // The user is dragging the right edge, so the position is anchored on the
184429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // left.
185429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int nx2 = b.x + b.w + deltaX;
186429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            if (nx2 >= b.x) {
187429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                w = nx2 - b.x;
188429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            } else {
189429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                w = 0;
190429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            }
191429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        } else {
192429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            assert direction == Position.BOTTOM_MIDDLE || direction == Position.TOP_MIDDLE;
193429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        }
194429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
195429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        if (direction.isTop()) {
196429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // The user is dragging the top edge, so the position is anchored on the
197429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // bottom.
198429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int y2 = b.y + b.h;
199429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int ny1 = b.y + deltaY;
200429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            if (ny1 < y2) {
201429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                y = ny1;
202429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                h = y2 - y;
203429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            } else {
204429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                h = 0;
205429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                y = y2;
206429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            }
207429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        } else if (direction.isBottom()) {
208429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // The user is dragging the bottom edge, so the position is anchored on the
209429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            // top.
210429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            int ny2 = b.y + b.h + deltaY;
211429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            if (ny2 >= b.y) {
212429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                h = ny2 - b.y;
213429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            } else {
214429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                h = 0;
215429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            }
216429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        } else {
217429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            assert direction == Position.LEFT_MIDDLE || direction == Position.RIGHT_MIDDLE;
218429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        }
219429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
220429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        return new Rect(x, y, w, h);
221429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    }
222429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
22380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    private static SegmentType getHorizontalEdgeType(SelectionHandle handle) {
22480d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        switch (handle.getPosition()) {
22580d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case BOTTOM_LEFT:
22680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case BOTTOM_RIGHT:
22780d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case BOTTOM_MIDDLE:
22880d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye                return SegmentType.BOTTOM;
22980d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case LEFT_MIDDLE:
23080d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case RIGHT_MIDDLE:
23180d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye                return null;
23280d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case TOP_LEFT:
23380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case TOP_MIDDLE:
23480d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case TOP_RIGHT:
23580d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye                return SegmentType.TOP;
23680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            default: assert false : handle.getPosition();
23780d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        }
23880d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        return null;
23980d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    }
24080d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye
24180d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    private static SegmentType getVerticalEdgeType(SelectionHandle handle) {
24280d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        switch (handle.getPosition()) {
24380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case TOP_LEFT:
24480d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case LEFT_MIDDLE:
24580d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case BOTTOM_LEFT:
24680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye                return SegmentType.LEFT;
24780d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case BOTTOM_MIDDLE:
24880d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case TOP_MIDDLE:
24980d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye                return null;
25080d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case TOP_RIGHT:
25180d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case RIGHT_MIDDLE:
25280d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            case BOTTOM_RIGHT:
25380d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye                return SegmentType.RIGHT;
25480d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye            default: assert false : handle.getPosition();
25580d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        }
25680d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye        return null;
25780d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye    }
25880d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye
25980d9301c2e874b29889c41adb0623666cf534fa0Tor Norbye
260429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    @Override
261429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    public List<Overlay> createOverlays() {
262429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        mOverlay = new ResizeOverlay();
263429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        return Collections.<Overlay> singletonList(mOverlay);
264429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    }
265429ae88878cf781753d8261d350ad89fe5864169Tor Norbye
266429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    /**
267429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * An {@link Overlay} to paint the resize feedback. This just delegates to the
268429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     * layout rule for the parent which is handling the resizing.
269429ae88878cf781753d8261d350ad89fe5864169Tor Norbye     */
270429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    private class ResizeOverlay extends Overlay {
271429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        @Override
272429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        public void paint(GC gc) {
273429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            if (mChildNode != null && mFeedback != null) {
274429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                RulesEngine rulesEngine = mCanvas.getRulesEngine();
275429ae88878cf781753d8261d350ad89fe5864169Tor Norbye                rulesEngine.callDropFeedbackPaint(mCanvas.getGcWrapper(), mChildNode, mFeedback);
276429ae88878cf781753d8261d350ad89fe5864169Tor Norbye            }
277429ae88878cf781753d8261d350ad89fe5864169Tor Norbye        }
278429ae88878cf781753d8261d350ad89fe5864169Tor Norbye    }
279429ae88878cf781753d8261d350ad89fe5864169Tor Norbye}
280