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