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.content.Context;
     21 import android.content.res.TypedArray;
     22 import android.graphics.Bitmap;
     23 import android.graphics.Canvas;
     24 import android.graphics.Matrix;
     25 import android.graphics.Paint;
     26 import android.graphics.PixelFormat;
     27 import android.graphics.Point;
     28 import android.os.IBinder;
     29 import android.util.AttributeSet;
     30 import android.util.Log;
     31 import android.view.Gravity;
     32 import android.view.View;
     33 import android.view.ViewGroup;
     34 import android.view.KeyEvent;
     35 import android.view.WindowManager;
     36 import android.view.WindowManagerImpl;
     37 
     38 public class DragView extends View implements TweenCallback {
     39     // Number of pixels to add to the dragged item for scaling.  Should be even for pixel alignment.
     40     private static final int DRAG_SCALE = 40;
     41 
     42     private Bitmap mBitmap;
     43     private Paint mPaint;
     44     private int mRegistrationX;
     45     private int mRegistrationY;
     46 
     47     SymmetricalLinearTween mTween;
     48     private float mScale;
     49     private float mAnimationScale = 1.0f;
     50 
     51     private WindowManager.LayoutParams mLayoutParams;
     52     private WindowManager mWindowManager;
     53 
     54     /**
     55      * Construct the drag view.
     56      * <p>
     57      * The registration point is the point inside our view that the touch events should
     58      * be centered upon.
     59      *
     60      * @param context A context
     61      * @param bitmap The view that we're dragging around.  We scale it up when we draw it.
     62      * @param registrationX The x coordinate of the registration point.
     63      * @param registrationY The y coordinate of the registration point.
     64      */
     65     public DragView(Context context, Bitmap bitmap, int registrationX, int registrationY,
     66             int left, int top, int width, int height) {
     67         super(context);
     68 
     69         mWindowManager = WindowManagerImpl.getDefault();
     70 
     71         mTween = new SymmetricalLinearTween(false, 110 /*ms duration*/, this);
     72 
     73         Matrix scale = new Matrix();
     74         float scaleFactor = width;
     75         scaleFactor = mScale = (scaleFactor + DRAG_SCALE) / scaleFactor;
     76         scale.setScale(scaleFactor, scaleFactor);
     77 
     78         mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true);
     79 
     80         // The point in our scaled bitmap that the touch events are located
     81         mRegistrationX = registrationX + (DRAG_SCALE / 2);
     82         mRegistrationY = registrationY + (DRAG_SCALE / 2);
     83     }
     84 
     85     @Override
     86     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     87         setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
     88     }
     89 
     90     @Override
     91     protected void onDraw(Canvas canvas) {
     92         if (false) {
     93             // for debugging
     94             Paint p = new Paint();
     95             p.setStyle(Paint.Style.FILL);
     96             p.setColor(0xaaffffff);
     97             canvas.drawRect(0, 0, getWidth(), getHeight(), p);
     98         }
     99         float scale = mAnimationScale;
    100         if (scale < 0.999f) { // allow for some float error
    101             float width = mBitmap.getWidth();
    102             float offset = (width-(width*scale))/2;
    103             canvas.translate(offset, offset);
    104             canvas.scale(scale, scale);
    105         }
    106         canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
    107     }
    108 
    109     @Override
    110     protected void onDetachedFromWindow() {
    111         super.onDetachedFromWindow();
    112         mBitmap.recycle();
    113     }
    114 
    115     public void onTweenValueChanged(float value, float oldValue) {
    116         mAnimationScale = (1.0f+((mScale-1.0f)*value))/mScale;
    117         invalidate();
    118     }
    119 
    120     public void onTweenStarted() {
    121     }
    122 
    123     public void onTweenFinished() {
    124     }
    125 
    126     public void setPaint(Paint paint) {
    127         mPaint = paint;
    128         invalidate();
    129     }
    130 
    131     /**
    132      * Create a window containing this view and show it.
    133      *
    134      * @param windowToken obtained from v.getWindowToken() from one of your views
    135      * @param touchX the x coordinate the user touched in screen coordinates
    136      * @param touchY the y coordinate the user touched in screen coordinates
    137      */
    138     public void show(IBinder windowToken, int touchX, int touchY) {
    139         WindowManager.LayoutParams lp;
    140         int pixelFormat;
    141 
    142         pixelFormat = PixelFormat.TRANSLUCENT;
    143 
    144         lp = new WindowManager.LayoutParams(
    145                 ViewGroup.LayoutParams.WRAP_CONTENT,
    146                 ViewGroup.LayoutParams.WRAP_CONTENT,
    147                 touchX-mRegistrationX, touchY-mRegistrationY,
    148                 WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
    149                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
    150                     | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
    151                     /*| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM*/,
    152                 pixelFormat);
    153 //        lp.token = mStatusBarView.getWindowToken();
    154         lp.gravity = Gravity.LEFT | Gravity.TOP;
    155         lp.token = windowToken;
    156         lp.setTitle("DragView");
    157         mLayoutParams = lp;
    158 
    159         mWindowManager.addView(this, lp);
    160 
    161         mAnimationScale = 1.0f/mScale;
    162         mTween.start(true);
    163     }
    164 
    165     /**
    166      * Move the window containing this view.
    167      *
    168      * @param touchX the x coordinate the user touched in screen coordinates
    169      * @param touchY the y coordinate the user touched in screen coordinates
    170      */
    171     void move(int touchX, int touchY) {
    172         WindowManager.LayoutParams lp = mLayoutParams;
    173         lp.x = touchX - mRegistrationX;
    174         lp.y = touchY - mRegistrationY;
    175         mWindowManager.updateViewLayout(this, lp);
    176     }
    177 
    178     void remove() {
    179         mWindowManager.removeView(this);
    180     }
    181 }
    182 
    183