Home | History | Annotate | Download | only in launcher2
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
      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 
     18 package com.android.launcher2;
     19 
     20 import android.animation.ValueAnimator;
     21 import android.animation.ValueAnimator.AnimatorUpdateListener;
     22 import android.content.res.Resources;
     23 import android.graphics.Bitmap;
     24 import android.graphics.Canvas;
     25 import android.graphics.Matrix;
     26 import android.graphics.Paint;
     27 import android.graphics.Point;
     28 import android.graphics.Rect;
     29 import android.view.View;
     30 import android.view.animation.DecelerateInterpolator;
     31 
     32 import com.android.launcher.R;
     33 
     34 public class DragView extends View {
     35     private Bitmap mBitmap;
     36     private Paint mPaint;
     37     private int mRegistrationX;
     38     private int mRegistrationY;
     39 
     40     private Point mDragVisualizeOffset = null;
     41     private Rect mDragRegion = null;
     42     private DragLayer mDragLayer = null;
     43     private boolean mHasDrawn = false;
     44 
     45     ValueAnimator mAnim;
     46     private float mOffsetX = 0.0f;
     47     private float mOffsetY = 0.0f;
     48 
     49     private DragLayer.LayoutParams mLayoutParams;
     50 
     51     /**
     52      * Construct the drag view.
     53      * <p>
     54      * The registration point is the point inside our view that the touch events should
     55      * be centered upon.
     56      *
     57      * @param launcher The Launcher instance
     58      * @param bitmap The view that we're dragging around.  We scale it up when we draw it.
     59      * @param registrationX The x coordinate of the registration point.
     60      * @param registrationY The y coordinate of the registration point.
     61      */
     62     public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY,
     63             int left, int top, int width, int height) {
     64         super(launcher);
     65         mDragLayer = launcher.getDragLayer();
     66 
     67         final Resources res = getResources();
     68         final int dragScale = res.getInteger(R.integer.config_dragViewExtraPixels);
     69 
     70         Matrix scale = new Matrix();
     71         final float scaleFactor = (width + dragScale) / width;
     72         if (scaleFactor != 1.0f) {
     73             scale.setScale(scaleFactor, scaleFactor);
     74         }
     75 
     76         final int offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX);
     77         final int offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY);
     78 
     79         // Animate the view into the correct position
     80         mAnim = ValueAnimator.ofFloat(0.0f, 1.0f);
     81         mAnim.setDuration(110);
     82         mAnim.setInterpolator(new DecelerateInterpolator(2.5f));
     83         mAnim.addUpdateListener(new AnimatorUpdateListener() {
     84             @Override
     85             public void onAnimationUpdate(ValueAnimator animation) {
     86                 final float value = (Float) animation.getAnimatedValue();
     87 
     88                 final int deltaX = (int) ((value * offsetX) - mOffsetX);
     89                 final int deltaY = (int) ((value * offsetY) - mOffsetY);
     90 
     91                 mOffsetX += deltaX;
     92                 mOffsetY += deltaY;
     93 
     94                 if (getParent() == null) {
     95                     animation.cancel();
     96                 } else {
     97                     DragLayer.LayoutParams lp = mLayoutParams;
     98                     lp.x += deltaX;
     99                     lp.y += deltaY;
    100                     mDragLayer.requestLayout();
    101                 }
    102             }
    103         });
    104 
    105         mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true);
    106         setDragRegion(new Rect(0, 0, width, height));
    107 
    108         // The point in our scaled bitmap that the touch events are located
    109         mRegistrationX = registrationX;
    110         mRegistrationY = registrationY;
    111 
    112         // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass
    113         int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    114         measure(ms, ms);
    115     }
    116 
    117     public float getOffsetY() {
    118         return mOffsetY;
    119     }
    120 
    121     public int getDragRegionLeft() {
    122         return mDragRegion.left;
    123     }
    124 
    125     public int getDragRegionTop() {
    126         return mDragRegion.top;
    127     }
    128 
    129     public int getDragRegionWidth() {
    130         return mDragRegion.width();
    131     }
    132 
    133     public int getDragRegionHeight() {
    134         return mDragRegion.height();
    135     }
    136 
    137     public void setDragVisualizeOffset(Point p) {
    138         mDragVisualizeOffset = p;
    139     }
    140 
    141     public Point getDragVisualizeOffset() {
    142         return mDragVisualizeOffset;
    143     }
    144 
    145     public void setDragRegion(Rect r) {
    146         mDragRegion = r;
    147     }
    148 
    149     public Rect getDragRegion() {
    150         return mDragRegion;
    151     }
    152 
    153     @Override
    154     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    155         setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
    156     }
    157 
    158     @Override
    159     protected void onDraw(Canvas canvas) {
    160         if (false) {
    161             // for debugging
    162             Paint p = new Paint();
    163             p.setStyle(Paint.Style.FILL);
    164             p.setColor(0xaaffffff);
    165             canvas.drawRect(0, 0, getWidth(), getHeight(), p);
    166         }
    167 
    168         mHasDrawn = true;
    169         canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
    170     }
    171 
    172     public void setPaint(Paint paint) {
    173         mPaint = paint;
    174         invalidate();
    175     }
    176 
    177     public boolean hasDrawn() {
    178         return mHasDrawn;
    179     }
    180 
    181     @Override
    182     public void setAlpha(float alpha) {
    183         super.setAlpha(alpha);
    184         if (mPaint == null) {
    185             mPaint = new Paint();
    186         }
    187         mPaint.setAlpha((int) (255 * alpha));
    188         invalidate();
    189     }
    190 
    191     /**
    192      * Create a window containing this view and show it.
    193      *
    194      * @param windowToken obtained from v.getWindowToken() from one of your views
    195      * @param touchX the x coordinate the user touched in DragLayer coordinates
    196      * @param touchY the y coordinate the user touched in DragLayer coordinates
    197      */
    198     public void show(int touchX, int touchY) {
    199         mDragLayer.addView(this);
    200         DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0);
    201         lp.width = mBitmap.getWidth();
    202         lp.height = mBitmap.getHeight();
    203         lp.x = touchX - mRegistrationX;
    204         lp.y = touchY - mRegistrationY;
    205         lp.customPosition = true;
    206         setLayoutParams(lp);
    207         mLayoutParams = lp;
    208         mAnim.start();
    209     }
    210 
    211     /**
    212      * Move the window containing this view.
    213      *
    214      * @param touchX the x coordinate the user touched in DragLayer coordinates
    215      * @param touchY the y coordinate the user touched in DragLayer coordinates
    216      */
    217     void move(int touchX, int touchY) {
    218         DragLayer.LayoutParams lp = mLayoutParams;
    219         lp.x = touchX - mRegistrationX + (int) mOffsetX;
    220         lp.y = touchY - mRegistrationY + (int) mOffsetY;
    221         mDragLayer.requestLayout();
    222     }
    223 
    224     void remove() {
    225         post(new Runnable() {
    226             public void run() {
    227                 mDragLayer.removeView(DragView.this);
    228             }
    229         });
    230     }
    231 
    232     int[] getPosition(int[] result) {
    233         DragLayer.LayoutParams lp = mLayoutParams;
    234         if (result == null) result = new int[2];
    235         result[0] = lp.x;
    236         result[1] = lp.y;
    237         return result;
    238     }
    239 }
    240 
    241