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 org.eclipse.swt.SWT;
     20 import org.eclipse.swt.graphics.Color;
     21 import org.eclipse.swt.graphics.Device;
     22 import org.eclipse.swt.graphics.GC;
     23 import org.eclipse.swt.graphics.Rectangle;
     24 
     25 import java.util.ArrayList;
     26 import java.util.Collection;
     27 import java.util.Collections;
     28 import java.util.List;
     29 
     30 /**
     31  * A {@link MarqueeGesture} is a gesture for swiping out a selection rectangle.
     32  * With a modifier key, items that intersect the rectangle can be toggled
     33  * instead of added to the new selection set.
     34  */
     35 public class MarqueeGesture extends Gesture {
     36     /** The {@link Overlay} drawn for the marquee. */
     37     private MarqueeOverlay mOverlay;
     38 
     39     /** The canvas associated with this gesture. */
     40     private LayoutCanvas mCanvas;
     41 
     42     /** A copy of the initial selection, when we're toggling the marquee. */
     43     private Collection<CanvasViewInfo> mInitialSelection;
     44 
     45     /**
     46      * Creates a new marquee selection (selection swiping).
     47      *
     48      * @param canvas The canvas where selection is performed.
     49      * @param toggle If true, toggle the membership of contained elements
     50      *            instead of adding it.
     51      */
     52     public MarqueeGesture(LayoutCanvas canvas, boolean toggle) {
     53         mCanvas = canvas;
     54 
     55         if (toggle) {
     56             List<SelectionItem> selection = canvas.getSelectionManager().getSelections();
     57             mInitialSelection = new ArrayList<CanvasViewInfo>(selection.size());
     58             for (SelectionItem item : selection) {
     59                 mInitialSelection.add(item.getViewInfo());
     60             }
     61         } else {
     62             mInitialSelection = Collections.emptySet();
     63         }
     64     }
     65 
     66     @Override
     67     public void update(ControlPoint pos) {
     68         if (mOverlay == null) {
     69             return;
     70         }
     71 
     72         int x = Math.min(pos.x, mStart.x);
     73         int y = Math.min(pos.y, mStart.y);
     74         int w = Math.abs(pos.x - mStart.x);
     75         int h = Math.abs(pos.y - mStart.y);
     76 
     77         mOverlay.updateSize(x, y, w, h);
     78 
     79         // Compute selection overlaps
     80         LayoutPoint topLeft = ControlPoint.create(mCanvas, x, y).toLayout();
     81         LayoutPoint bottomRight = ControlPoint.create(mCanvas, x + w, y + h).toLayout();
     82         mCanvas.getSelectionManager().selectWithin(topLeft, bottomRight, mInitialSelection);
     83     }
     84 
     85     @Override
     86     public List<Overlay> createOverlays() {
     87         mOverlay = new MarqueeOverlay();
     88         return Collections.<Overlay> singletonList(mOverlay);
     89     }
     90 
     91     /**
     92      * An {@link Overlay} for the {@link MarqueeGesture}; paints a selection
     93      * overlay rectangle matching the mouse coordinate delta between gesture
     94      * start and the current position.
     95      */
     96     private static class MarqueeOverlay extends Overlay {
     97         /** Rectangle border color. */
     98         private Color mStroke;
     99 
    100         /** Rectangle fill color. */
    101         private Color mFill;
    102 
    103         /** Current rectangle coordinates (in terms of control coordinates). */
    104         private Rectangle mRectangle = new Rectangle(0, 0, 0, 0);
    105 
    106         /** Alpha value of the fill. */
    107         private int mFillAlpha;
    108 
    109         /** Alpha value of the border. */
    110         private int mStrokeAlpha;
    111 
    112         /** Constructs a new {@link MarqueeOverlay}. */
    113         public MarqueeOverlay() {
    114         }
    115 
    116         /**
    117          * Updates the size of the marquee rectangle.
    118          *
    119          * @param x The top left corner of the rectangle, x coordinate.
    120          * @param y The top left corner of the rectangle, y coordinate.
    121          * @param w Rectangle width.
    122          * @param h Rectangle height.
    123          */
    124         public void updateSize(int x, int y, int w, int h) {
    125             mRectangle.x = x;
    126             mRectangle.y = y;
    127             mRectangle.width = w;
    128             mRectangle.height = h;
    129         }
    130 
    131         @Override
    132         public void create(Device device) {
    133             // TODO: Integrate DrawingStyles with this?
    134             mStroke = new Color(device, 255, 255, 255);
    135             mFill = new Color(device, 128, 128, 128);
    136             mFillAlpha = 64;
    137             mStrokeAlpha = 255;
    138         }
    139 
    140         @Override
    141         public void dispose() {
    142             mStroke.dispose();
    143             mFill.dispose();
    144         }
    145 
    146         @Override
    147         public void paint(GC gc) {
    148             if (mRectangle.width > 0 && mRectangle.height > 0) {
    149                 gc.setLineStyle(SWT.LINE_SOLID);
    150                 gc.setLineWidth(1);
    151                 gc.setForeground(mStroke);
    152                 gc.setBackground(mFill);
    153                 gc.setAlpha(mStrokeAlpha);
    154                 gc.drawRectangle(mRectangle);
    155                 gc.setAlpha(mFillAlpha);
    156                 gc.fillRectangle(mRectangle);
    157             }
    158         }
    159     }
    160 }
    161