100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato/* 200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Copyright (C) 2008 The Android Open Source Project 300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * you may not use this file except in compliance with the License. 600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * You may obtain a copy of the License at 700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 1000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Unless required by applicable law or agreed to in writing, software 1100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 1200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * See the License for the specific language governing permissions and 1400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * limitations under the License. 1500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 1600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 17fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevpackage com.android.launcher3.dragndrop; 1800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 19d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshevimport android.animation.Animator; 20d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshevimport android.animation.AnimatorListenerAdapter; 21fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport android.animation.FloatArrayEvaluator; 22a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.animation.ValueAnimator; 23a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.animation.ValueAnimator.AnimatorUpdateListener; 2442e28092b336bf89bee94c61e2cd327e1d8ec882Sunny Goyalimport android.annotation.SuppressLint; 2500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap; 2600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Canvas; 27fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport android.graphics.ColorMatrix; 28fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport android.graphics.ColorMatrixColorFilter; 2900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Paint; 30b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chungimport android.graphics.Point; 31e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohenimport android.graphics.Rect; 3200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.View; 33a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.view.animation.DecelerateInterpolator; 34fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev 35fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Launcher; 36fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.LauncherAnimUtils; 37ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickhamimport com.android.launcher3.R; 386c82867a7ea3a95a19d6cec7d1fe164d234d2cb6Tony Wickhamimport com.android.launcher3.util.Themes; 39091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 40fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev 41fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport java.util.Arrays; 42fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 43a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroypublic class DragView extends View { 44a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public static final int COLOR_CHANGE_DURATION = 120; 45a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public static final int VIEW_ZOOM_DURATION = 150; 46fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 47091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static float sDragAlpha = 1f; 487bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 4900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private Bitmap mBitmap; 50ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen private Bitmap mCrossFadeBitmap; 51316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk Paint mPaint; 52c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda private final int mBlurSizeOutline; 53d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final int mRegistrationX; 54d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final int mRegistrationY; 55ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham private final float mInitialScale; 56ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham private final int[] mTempLoc = new int[2]; 5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 58b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung private Point mDragVisualizeOffset = null; 59e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen private Rect mDragRegion = null; 60d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final DragLayer mDragLayer; 6142e28092b336bf89bee94c61e2cd327e1d8ec882Sunny Goyal @Thunk final DragController mDragController; 62fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen private boolean mHasDrawn = false; 63091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk float mCrossFadeProgress = 0f; 64456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev private boolean mAnimationCancelled = false; 65a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 66a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy ValueAnimator mAnim; 67eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // The intrinsic icon scale factor is the scale factor for a drag icon over the workspace 68eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // size. This is ignored for non-icons. 69eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung private float mIntrinsicIconScale = 1f; 7000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 71316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk float[] mCurrentFilter; 72fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal private ValueAnimator mFilterAnimator; 73fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 74a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mLastTouchX; 75a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mLastTouchY; 76a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mAnimatedShiftX; 77a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mAnimatedShiftY; 78a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 7900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 8000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Construct the drag view. 8100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * <p> 8200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * The registration point is the point inside our view that the touch events should 8300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * be centered upon. 848dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param launcher The Launcher instance 8500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param bitmap The view that we're dragging around. We scale it up when we draw it. 8600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationX The x coordinate of the registration point. 8700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationY The y coordinate of the registration point. 8800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 89157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY, 90157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal final float initialScale, final float finalScaleDps) { 918dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen super(launcher); 928dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDragLayer = launcher.getDragLayer(); 93d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mDragController = launcher.getDragController(); 9400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 95157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal final float scale = (bitmap.getWidth() + finalScaleDps) / bitmap.getWidth(); 96a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 97307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen // Set the initial scale to avoid any jumps 98307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen setScaleX(initialScale); 99307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen setScaleY(initialScale); 100307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen 101a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy // Animate the view into the correct position 102cda3bfb2e1d89ad872558dd0a82ae79ca6fe41eaJon Miranda mAnim = LauncherAnimUtils.ofFloat(0f, 1f); 103a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnim.setDuration(VIEW_ZOOM_DURATION); 104a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mAnim.addUpdateListener(new AnimatorUpdateListener() { 105a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy @Override 106a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy public void onAnimationUpdate(ValueAnimator animation) { 107a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy final float value = (Float) animation.getAnimatedValue(); 108a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 10972d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung setScaleX(initialScale + (value * (scale - initialScale))); 11072d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung setScaleY(initialScale + (value * (scale - initialScale))); 111867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung if (sDragAlpha != 1f) { 112867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung setAlpha(sDragAlpha * value + (1f - value)); 113867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung } 114a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 115a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy if (getParent() == null) { 116a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy animation.cancel(); 117a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy } 118a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy } 119a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy }); 12000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 121d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mAnim.addListener(new AnimatorListenerAdapter() { 122d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev @Override 123d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public void onAnimationEnd(Animator animation) { 124456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev if (!mAnimationCancelled) { 125456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev mDragController.onDragViewAnimationEnd(); 126456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev } 127d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 128d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev }); 129d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 130157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal mBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()); 131157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal setDragRegion(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight())); 13200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 13300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // The point in our scaled bitmap that the touch events are located 134a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mRegistrationX = registrationX; 135a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mRegistrationY = registrationY; 13662bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy 137ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mInitialScale = initialScale; 138ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham 13962bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass 14062bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 14162bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy measure(ms, ms); 1426cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); 14375deaf3d8f369bd13ea59ec3740324a5cfeb3099Sunny Goyal 144c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda mBlurSizeOutline = getResources().getDimensionPixelSize(R.dimen.blur_size_medium_outline); 145c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda 146a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal setElevation(getResources().getDimension(R.dimen.drag_elevation)); 14762bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy } 14862bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy 149eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung /** Sets the scale of the view over the normal workspace icon size. */ 150eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public void setIntrinsicIconScaleFactor(float scale) { 151eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung mIntrinsicIconScale = scale; 152eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 153eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 154eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public float getIntrinsicIconScaleFactor() { 155eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung return mIntrinsicIconScale; 156eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 157eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 158a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionLeft() { 159e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.left; 160a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 161a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 162a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionTop() { 163e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.top; 164a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 165a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 166a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionWidth() { 167e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.width(); 168a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 169a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 170a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionHeight() { 171e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.height(); 172e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen } 173e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen 174b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung public void setDragVisualizeOffset(Point p) { 175b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung mDragVisualizeOffset = p; 176b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung } 177b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung 178b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung public Point getDragVisualizeOffset() { 179b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung return mDragVisualizeOffset; 180b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung } 181b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung 182e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen public void setDragRegion(Rect r) { 183e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen mDragRegion = r; 184e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen } 185e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen 186e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen public Rect getDragRegion() { 187e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion; 188a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 189a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 19000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato @Override 19100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 192eebd92496e2fbfbd81ea871862a681929101ba06Joe Onorato setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight()); 19300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 19400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 195d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev // Draws drag shadow for system DND. 19642e28092b336bf89bee94c61e2cd327e1d8ec882Sunny Goyal @SuppressLint("WrongCall") 197d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public void drawDragShadow(Canvas canvas) { 198d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); 199d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev canvas.scale(getScaleX(), getScaleY()); 200d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev onDraw(canvas); 201d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev canvas.restoreToCount(saveCount); 202d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 203d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 204d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev // Provides drag shadow metrics for system DND. 205d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public void provideDragShadowMetrics(Point size, Point touch) { 206d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev size.set((int)(mBitmap.getWidth() * getScaleX()), (int)(mBitmap.getHeight() * getScaleY())); 207d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 20837bd006b73b4399ba10bb46e7f57a56b2e133e86Vadim Tryshev final float xGrowth = mBitmap.getWidth() * (getScaleX() - 1); 20937bd006b73b4399ba10bb46e7f57a56b2e133e86Vadim Tryshev final float yGrowth = mBitmap.getHeight() * (getScaleY() - 1); 2109430ff23c8a1127341e73b285e901a5cb9f1b5f7Vadim Tryshev touch.set( 2119430ff23c8a1127341e73b285e901a5cb9f1b5f7Vadim Tryshev mRegistrationX + (int)Math.round(xGrowth / 2), 2129430ff23c8a1127341e73b285e901a5cb9f1b5f7Vadim Tryshev mRegistrationY + (int)Math.round(yGrowth / 2)); 213d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 214d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 21500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato @Override 21600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onDraw(Canvas canvas) { 217fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mHasDrawn = true; 218ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null; 219ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen if (crossFade) { 220ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255; 221ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mPaint.setAlpha(alpha); 222ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 22300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); 224ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen if (crossFade) { 225ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mPaint.setAlpha((int) (255 * mCrossFadeProgress)); 226d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); 227ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth(); 228ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight(); 229ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen canvas.scale(sX, sY); 230ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint); 231d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev canvas.restoreToCount(saveCount); 232ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 233ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 234ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 235ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void setCrossFadeBitmap(Bitmap crossFadeBitmap) { 236ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mCrossFadeBitmap = crossFadeBitmap; 237ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 238ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 239ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void crossFade(int duration) { 240cda3bfb2e1d89ad872558dd0a82ae79ca6fe41eaJon Miranda ValueAnimator va = LauncherAnimUtils.ofFloat(0f, 1f); 241ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.setDuration(duration); 242ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.setInterpolator(new DecelerateInterpolator(1.5f)); 243ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.addUpdateListener(new AnimatorUpdateListener() { 244ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 245ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 246ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mCrossFadeProgress = animation.getAnimatedFraction(); 2475d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal invalidate(); 248ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 249ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen }); 250ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.start(); 25100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 25200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 25361967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung public void setColor(int color) { 2546cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka if (mPaint == null) { 2556cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); 2566cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka } 25761967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung if (color != 0) { 258fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal ColorMatrix m1 = new ColorMatrix(); 259fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal m1.setSaturation(0); 260fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 261fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal ColorMatrix m2 = new ColorMatrix(); 2626c82867a7ea3a95a19d6cec7d1fe164d234d2cb6Tony Wickham Themes.setColorScaleOnMatrix(color, m2); 263fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal m1.postConcat(m2); 264fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 265a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal animateFilterTo(m1.getArray()); 26661967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung } else { 267a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal if (mCurrentFilter == null) { 268fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mPaint.setColorFilter(null); 269fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal invalidate(); 270fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } else { 271fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal animateFilterTo(new ColorMatrix().getArray()); 272fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 27361967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung } 274fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 275fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 276fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal private void animateFilterTo(float[] targetFilter) { 277fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal float[] oldFilter = mCurrentFilter == null ? new ColorMatrix().getArray() : mCurrentFilter; 278fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mCurrentFilter = Arrays.copyOf(oldFilter, oldFilter.length); 279fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 280fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal if (mFilterAnimator != null) { 281fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.cancel(); 282fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 283fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator = ValueAnimator.ofObject(new FloatArrayEvaluator(mCurrentFilter), 284fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal oldFilter, targetFilter); 285fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.setDuration(COLOR_CHANGE_DURATION); 286fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.addUpdateListener(new AnimatorUpdateListener() { 287fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 288fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal @Override 289fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal public void onAnimationUpdate(ValueAnimator animation) { 290fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mPaint.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter)); 291fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal invalidate(); 292fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 293fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal }); 294fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.start(); 29500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 29600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 297fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen public boolean hasDrawn() { 298fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen return mHasDrawn; 299fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen } 300fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 3013e8f811f31a2275e778244427271f77f4116c08bAdam Cohen @Override 3023e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void setAlpha(float alpha) { 3033e8f811f31a2275e778244427271f77f4116c08bAdam Cohen super.setAlpha(alpha); 3043e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mPaint.setAlpha((int) (255 * alpha)); 3053e8f811f31a2275e778244427271f77f4116c08bAdam Cohen invalidate(); 3063e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 3073e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 30800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 30900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Create a window containing this view and show it. 31000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 3118dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchX the x coordinate the user touched in DragLayer coordinates 3128dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchY the y coordinate the user touched in DragLayer coordinates 31300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 3148dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void show(int touchX, int touchY) { 3158dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDragLayer.addView(this); 316043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 317043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Start the pick-up animation 3188dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0); 3198dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.width = mBitmap.getWidth(); 3208dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.height = mBitmap.getHeight(); 3218dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.customPosition = true; 3228dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen setLayoutParams(lp); 323a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal move(touchX, touchY); 324ca99383daef92fed673de22126875cb485be494fMichael Jurka // Post the animation to skip other expensive work happening on the first frame 325ca99383daef92fed673de22126875cb485be494fMichael Jurka post(new Runnable() { 326a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham public void run() { 327a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham mAnim.start(); 328a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham } 329a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham }); 33000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 331716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 3327bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void cancelAnimation() { 333456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev mAnimationCancelled = true; 3347bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mAnim != null && mAnim.isRunning()) { 3357bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mAnim.cancel(); 3367bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 3377bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 3387bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 33900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 34000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Move the window containing this view. 34100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 3428dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchX the x coordinate the user touched in DragLayer coordinates 3438dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchY the y coordinate the user touched in DragLayer coordinates 34400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 3451bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham public void move(int touchX, int touchY) { 346a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mLastTouchX = touchX; 347a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mLastTouchY = touchY; 348a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 349a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 350a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 351ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) { 352ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mTempLoc[0] = toTouchX - mRegistrationX; 353ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mTempLoc[1] = toTouchY - mRegistrationY; 354ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mDragLayer.animateViewIntoPosition(this, mTempLoc, 1f, mInitialScale, mInitialScale, 355ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham DragLayer.ANIMATION_END_DISAPPEAR, onCompleteRunnable, duration); 356ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham } 357ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham 358a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public void animateShift(final int shiftX, final int shiftY) { 359a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal if (mAnim.isStarted()) { 360a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal return; 361a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 362a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftX = shiftX; 363a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftY = shiftY; 364a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 365a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnim.addUpdateListener(new AnimatorUpdateListener() { 366a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal @Override 367a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public void onAnimationUpdate(ValueAnimator animation) { 368a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal float fraction = 1 - animation.getAnimatedFraction(); 369a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftX = (int) (fraction * shiftX); 370a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftY = (int) (fraction * shiftY); 371a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 372a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 373a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal }); 374a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 375a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 376a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private void applyTranslation() { 377a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal setTranslationX(mLastTouchX - mRegistrationX + mAnimatedShiftX); 378a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal setTranslationY(mLastTouchY - mRegistrationY + mAnimatedShiftY); 37900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 38000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 3811bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham public void remove() { 3827bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (getParent() != null) { 3837bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDragLayer.removeView(DragView.this); 3847bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 3856f13342ffd3f968de9ff86b988621cc91d94adffPatrick Dubroy } 3863a644ed1ce12554fcdf5c499e959bda986d10551Sunny Goyal 387c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda public int getBlurSizeOutline() { 388c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda return mBlurSizeOutline; 389c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda } 390dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal 391dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal public float getInitialScale() { 392dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal return mInitialScale; 393dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal } 39400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato} 395