• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.IViewRule;
20 import com.android.ide.common.api.Rect;
21 
22 
23 /**
24  * This singleton is used to keep track of drag'n'drops initiated within this
25  * session of Eclipse. A drag can be initiated from a palette or from a canvas
26  * and its content is an Android View fully-qualified class name.
27  * <p/>
28  * Overall this is a workaround: the issue is that the drag'n'drop SWT API does not
29  * allow us to know the transfered data during the initial drag -- only when the
30  * data is dropped do we know what it is about (and to be more exact there is a workaround
31  * to do just that which works on Windows but not on Linux/Mac SWT).
32  * <p/>
33  * In the GLE we'd like to adjust drag feedback to the data being actually dropped.
34  * The singleton instance of this class will be used to track the data currently dragged
35  * off a canvas or its palette and then set back to null when the drag'n'drop is finished.
36  * <p/>
37  * Note that when a drag starts in one instance of Eclipse and the dragOver/drop is done
38  * in a <em>separate</em> instance of Eclipse, the dragged FQCN won't be registered here
39  * and will be null.
40  */
41 final class GlobalCanvasDragInfo {
42 
43     private static final GlobalCanvasDragInfo sInstance = new GlobalCanvasDragInfo();
44 
45     private SimpleElement[] mCurrentElements = null;
46     private SelectionItem[] mCurrentSelection;
47     private Object mSourceCanvas = null;
48     private Runnable mRemoveSourceHandler;
49     private Rect mDragBounds;
50     private int mDragBaseline = -1;
51 
52     /** Private constructor. Use {@link #getInstance()} to retrieve the singleton. */
GlobalCanvasDragInfo()53     private GlobalCanvasDragInfo() {
54         // pass
55     }
56 
57     /** Returns the singleton instance. */
getInstance()58     public static GlobalCanvasDragInfo getInstance() {
59         return sInstance;
60     }
61 
62     /**
63      * Registers the XML elements being dragged.
64      *
65      * @param elements The elements being dragged
66      * @param selection The selection (which can be null, for example when the
67      *            user drags from the palette)
68      * @param sourceCanvas An object representing the source we are dragging
69      *            from (used for identity comparisons only)
70      * @param removeSourceHandler A runnable (or null) which can clean up the
71      *            source. It should only be invoked if the drag operation is a
72      *            move, not a copy.
73      */
startDrag(SimpleElement[] elements, SelectionItem[] selection, Object sourceCanvas, Runnable removeSourceHandler)74     public void startDrag(SimpleElement[] elements, SelectionItem[] selection,
75             Object sourceCanvas, Runnable removeSourceHandler) {
76         mCurrentElements = elements;
77         mCurrentSelection = selection;
78         mSourceCanvas = sourceCanvas;
79         mRemoveSourceHandler = removeSourceHandler;
80     }
81 
82     /** Unregisters elements being dragged. */
stopDrag()83     public void stopDrag() {
84         mCurrentElements = null;
85         mCurrentSelection = null;
86         mSourceCanvas = null;
87         mRemoveSourceHandler = null;
88         mDragBounds = null;
89     }
90 
isDragging()91     public boolean isDragging() {
92         return mCurrentElements != null;
93     }
94 
95     /** Returns the elements being dragged. */
getCurrentElements()96     public SimpleElement[] getCurrentElements() {
97         return mCurrentElements;
98     }
99 
100     /** Returns the selection originally dragged.
101      * Can be null if the drag did not start in a canvas.
102      */
getCurrentSelection()103     public SelectionItem[] getCurrentSelection() {
104         return mCurrentSelection;
105     }
106 
107     /**
108      * Returns the object that call {@link #startDrag(SimpleElement[], SelectionItem[], Object)}.
109      * Can be null.
110      * This is not meant to access the object indirectly, it is just meant to compare if the
111      * source and the destination of the drag'n'drop are the same, so object identity
112      * is all what matters.
113      */
getSourceCanvas()114     public Object getSourceCanvas() {
115         return mSourceCanvas;
116     }
117 
118     /**
119      * Removes source of the drag. This should only be called when the drag and
120      * drop operation is a move (not a copy).
121      */
removeSource()122     public void removeSource() {
123         if (mRemoveSourceHandler != null) {
124             mRemoveSourceHandler.run();
125             mRemoveSourceHandler = null;
126         }
127     }
128 
129     /**
130      * Get the bounds of the drag, relative to the starting mouse position. For example,
131      * if you have a rectangular view of size 100x80, and you start dragging at position
132      * (15,20) from the top left corner of this rectangle, then the drag bounds would be
133      * (-15,-20, 100x80).
134      * <p>
135      * NOTE: The coordinate units will be in SWT/control pixels, not Android view pixels.
136      * In other words, they are affected by the canvas zoom: If you zoom the view and the
137      * bounds of a view grow, the drag bounds will be larger.
138      *
139      * @return the drag bounds, or null if there are no bounds for the current drag
140      */
getDragBounds()141     public Rect getDragBounds() {
142         return mDragBounds;
143     }
144 
145     /**
146      * Set the bounds of the drag, relative to the starting mouse position. See
147      * {@link #getDragBounds()} for details on the semantics of the drag bounds.
148      *
149      * @param dragBounds the new drag bounds, or null if there are no drag bounds
150      */
setDragBounds(Rect dragBounds)151     public void setDragBounds(Rect dragBounds) {
152         mDragBounds = dragBounds;
153     }
154 
155     /**
156      * Returns the baseline of the drag, or -1 if not applicable
157      *
158      * @return the current SWT modifier key mask as an {@link IViewRule} modifier mask
159      */
getDragBaseline()160     public int getDragBaseline() {
161         return mDragBaseline;
162     }
163 
164     /**
165      * Sets the baseline of the drag
166      *
167      * @param baseline the new baseline
168      */
setDragBaseline(int baseline)169     public void setDragBaseline(int baseline) {
170         mDragBaseline = baseline;
171     }
172 }
173