DragView.java revision 4a5fd100d743fcd9e51c2da36a9f9f542c5b5cdd
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; 254a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.content.pm.PackageManager; 2600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap; 2700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Canvas; 28fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport android.graphics.ColorMatrix; 29fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport android.graphics.ColorMatrixColorFilter; 304a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.graphics.Matrix; 3100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Paint; 324a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.graphics.Path; 33b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chungimport android.graphics.Point; 34e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohenimport android.graphics.Rect; 354a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.graphics.drawable.AdaptiveIconDrawable; 364a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.graphics.drawable.Drawable; 374a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.os.Handler; 384a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.os.Looper; 394a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.support.animation.DynamicAnimation; 404a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.support.animation.SpringAnimation; 414a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.support.animation.SpringForce; 4200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.View; 43a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.view.animation.DecelerateInterpolator; 444a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.widget.FrameLayout; 454a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.widget.ImageView; 46fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev 474a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.ItemInfo; 48fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Launcher; 49fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.LauncherAnimUtils; 504a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.LauncherModel; 514a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.LauncherSettings; 52ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickhamimport com.android.launcher3.R; 534a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.Utilities; 544a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.config.FeatureFlags; 556c82867a7ea3a95a19d6cec7d1fe164d234d2cb6Tony Wickhamimport com.android.launcher3.util.Themes; 56091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 57fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev 58fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport java.util.Arrays; 59fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 604a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT; 614a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 624a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songpublic class DragView extends FrameLayout { 63a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public static final int COLOR_CHANGE_DURATION = 120; 64a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public static final int VIEW_ZOOM_DURATION = 150; 65fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 66091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static float sDragAlpha = 1f; 677bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 6800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private Bitmap mBitmap; 69ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen private Bitmap mCrossFadeBitmap; 70316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk Paint mPaint; 71c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda private final int mBlurSizeOutline; 72d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final int mRegistrationX; 73d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final int mRegistrationY; 74ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham private final float mInitialScale; 75ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham private final int[] mTempLoc = new int[2]; 7600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 77b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung private Point mDragVisualizeOffset = null; 78e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen private Rect mDragRegion = null; 794a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final Launcher mLauncher; 80d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final DragLayer mDragLayer; 8142e28092b336bf89bee94c61e2cd327e1d8ec882Sunny Goyal @Thunk final DragController mDragController; 82fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen private boolean mHasDrawn = false; 83091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk float mCrossFadeProgress = 0f; 84456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev private boolean mAnimationCancelled = false; 85a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 86a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy ValueAnimator mAnim; 87eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // The intrinsic icon scale factor is the scale factor for a drag icon over the workspace 88eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // size. This is ignored for non-icons. 89eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung private float mIntrinsicIconScale = 1f; 9000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 91316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk float[] mCurrentFilter; 92fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal private ValueAnimator mFilterAnimator; 93fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 94a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mLastTouchX; 95a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mLastTouchY; 96a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mAnimatedShiftX; 97a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mAnimatedShiftY; 98a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 994a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song // Below variable only needed IF FeatureFlags.LAUNCHER3_SPRING_ICONS is {@code true} 1004a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private SpringAnimation mSpringX, mSpringY; 1014a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private ImageView mFgImageView, mBgImageView; 1024a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private Path mScaledMaskPath; 1034a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song // TODO: figure out if there is smarter way to retrieve these two constants below 1044a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final static float ADAPTIVE_ICON_SCALE = .731121626f; 1054a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final static float ADAPTIVE_ICON_MASK_SCALE = 1.165f; //1.185f; 1064a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 1074a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song // Following three values are fine tuned with motion ux designer 1084a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final static int STIFFNESS = 4000; 1094a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final static float DAMPENING_RATIO = 1f; 1104a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final static int PARALLAX_MAX_IN_DP = 8; 1114a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final int mDelta; 1124a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 11300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 11400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Construct the drag view. 11500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * <p> 11600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * The registration point is the point inside our view that the touch events should 11700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * be centered upon. 1188dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param launcher The Launcher instance 11900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param bitmap The view that we're dragging around. We scale it up when we draw it. 12000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationX The x coordinate of the registration point. 12100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationY The y coordinate of the registration point. 12200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 123157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY, 124157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal final float initialScale, final float finalScaleDps) { 1258dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen super(launcher); 1264a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mLauncher = launcher; 1278dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDragLayer = launcher.getDragLayer(); 128d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mDragController = launcher.getDragController(); 12900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 130157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal final float scale = (bitmap.getWidth() + finalScaleDps) / bitmap.getWidth(); 131a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 132307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen // Set the initial scale to avoid any jumps 133307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen setScaleX(initialScale); 134307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen setScaleY(initialScale); 135307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen 136a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy // Animate the view into the correct position 137cda3bfb2e1d89ad872558dd0a82ae79ca6fe41eaJon Miranda mAnim = LauncherAnimUtils.ofFloat(0f, 1f); 138a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnim.setDuration(VIEW_ZOOM_DURATION); 139a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mAnim.addUpdateListener(new AnimatorUpdateListener() { 140a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy @Override 141a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy public void onAnimationUpdate(ValueAnimator animation) { 142a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy final float value = (Float) animation.getAnimatedValue(); 143a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 14472d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung setScaleX(initialScale + (value * (scale - initialScale))); 14572d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung setScaleY(initialScale + (value * (scale - initialScale))); 146867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung if (sDragAlpha != 1f) { 147867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung setAlpha(sDragAlpha * value + (1f - value)); 148867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung } 149a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 150a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy if (getParent() == null) { 151a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy animation.cancel(); 152a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy } 153a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy } 154a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy }); 15500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 156d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mAnim.addListener(new AnimatorListenerAdapter() { 157d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev @Override 158d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public void onAnimationEnd(Animator animation) { 159456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev if (!mAnimationCancelled) { 160456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev mDragController.onDragViewAnimationEnd(); 161456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev } 162d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 163d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev }); 164d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 165157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal mBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()); 166157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal setDragRegion(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight())); 16700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 16800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // The point in our scaled bitmap that the touch events are located 169a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mRegistrationX = registrationX; 170a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mRegistrationY = registrationY; 17162bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy 172ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mInitialScale = initialScale; 173ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham 17462bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass 17562bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 17662bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy measure(ms, ms); 1776cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); 17875deaf3d8f369bd13ea59ec3740324a5cfeb3099Sunny Goyal 179c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda mBlurSizeOutline = getResources().getDimensionPixelSize(R.dimen.blur_size_medium_outline); 180a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal setElevation(getResources().getDimension(R.dimen.drag_elevation)); 1814a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song setWillNotDraw(false); 1824a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mDelta = (int)(getResources().getDisplayMetrics().density * PARALLAX_MAX_IN_DP); 1834a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 1844a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 1854a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song /** 1864a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song * Initialize {@code #mIconDrawable} only if the icon type is app icon (not shortcut or folder). 1874a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song */ 1884a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song public void setItemInfo(final ItemInfo info) { 1894a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song if (!(FeatureFlags.LAUNCHER3_SPRING_ICONS && Utilities.isAtLeastO())) { 1904a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song return; 1914a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 1924a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song if (!(info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION 1934a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)) { 1944a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song return; 1954a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 1964a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song // Load the adaptive icon on a background thread and add the view in ui thread. 1974a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song final Looper workerLooper = LauncherModel.getWorkerLooper(); 1984a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song new Handler(workerLooper).postAtFrontOfQueue(new Runnable() { 1994a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song @Override 2004a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song public void run() { 2014a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song PackageManager pm = (mLauncher).getPackageManager(); 2024a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song try { 2034a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song Drawable dr = pm.getActivityIcon(info.getTargetComponent()); 2044a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song if (dr instanceof AdaptiveIconDrawable) { 2054a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song int w = mBitmap.getWidth(); 2064a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song int h = mBitmap.getHeight(); 2074a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr; 2084a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song adaptiveIcon.setBounds(0, 0, w, h); 2094a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song setupMaskPath(adaptiveIcon); 2104a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mFgImageView = setupImageView(adaptiveIcon.getForeground()); 2114a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mBgImageView = setupImageView(adaptiveIcon.getBackground()); 2124a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mSpringX = setupSpringAnimation(-w/4, w/4, DynamicAnimation.TRANSLATION_X); 2134a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mSpringY = setupSpringAnimation(-h/4, h/4, DynamicAnimation.TRANSLATION_Y); 2144a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2154a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song new Handler(Looper.getMainLooper()).post(new Runnable() { 2164a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song @Override 2174a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song public void run() { 2184a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song addView(mBgImageView); 2194a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song addView(mFgImageView); 2204a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song setWillNotDraw(true); 2214a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2224a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song }); 2234a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2244a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } catch (PackageManager.NameNotFoundException e) { } 2254a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song }}); 2264a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2274a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2284a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private ImageView setupImageView(Drawable drawable) { 2294a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song FrameLayout.LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT); 2304a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song ImageView imageViewOut = new ImageView(getContext()); 2314a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song imageViewOut.setLayoutParams(params); 2324a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song imageViewOut.setScaleType(ImageView.ScaleType.CENTER); 2334a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song imageViewOut.setScaleX(ADAPTIVE_ICON_SCALE); 2344a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song imageViewOut.setScaleY(ADAPTIVE_ICON_SCALE); 2354a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song imageViewOut.setImageDrawable(drawable); 2364a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song return imageViewOut; 2374a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2384a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2394a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private SpringAnimation setupSpringAnimation(int minValue, int maxValue, 2404a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song DynamicAnimation.ViewProperty property) { 2414a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song SpringAnimation s = new SpringAnimation(mFgImageView, property, 0); 2424a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song s.setMinValue(minValue).setMaxValue(maxValue); 2434a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song s.setSpring(new SpringForce(0) 2444a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song .setDampingRatio(DAMPENING_RATIO) 2454a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song .setStiffness(STIFFNESS)); 2464a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song return s; 2474a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2484a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2494a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private void setupMaskPath(AdaptiveIconDrawable dr) { 2504a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song Matrix m = new Matrix(); 2514a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song m.setScale(ADAPTIVE_ICON_SCALE * ADAPTIVE_ICON_MASK_SCALE, 2524a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song ADAPTIVE_ICON_SCALE * ADAPTIVE_ICON_MASK_SCALE, 2534a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song dr.getBounds().centerX(), 2544a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song dr.getBounds().centerY()); 2554a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mScaledMaskPath = new Path(); 2564a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song dr.getIconMask().transform(m, mScaledMaskPath); 2574a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2584a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2594a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private void applySpring(int x, int y) { 2604a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song if (mSpringX == null || mSpringY == null) { 2614a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song return; 2624a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2634a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mSpringX.animateToFinalPosition(Utilities.boundToRange(x, -mDelta, mDelta)); 2644a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mSpringY.animateToFinalPosition(Utilities.boundToRange(y, -mDelta, mDelta)); 2654a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2664a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2674a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song @Override 2684a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 2694a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song int w = right - left; 2704a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song int h = bottom - top; 2714a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song for (int i = 0; i < getChildCount(); i++) { 2724a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song getChildAt(i).layout(-w / 4, -h / 4, w + w / 4, h + h / 4); 2734a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2744a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2754a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2764a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song @Override 2774a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 2784a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song int w = mBitmap.getWidth(); 2794a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song int h = mBitmap.getHeight(); 2804a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song setMeasuredDimension(w, h); 2814a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song for (int i = 0; i < getChildCount(); i++) { 2824a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song getChildAt(i).measure(w, h); 2834a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2844a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2854a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2864a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song @Override 2874a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song protected void dispatchDraw(Canvas canvas) { 2884a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song if (mScaledMaskPath != null) { 2894a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); 2904a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song canvas.clipPath(mScaledMaskPath); 2914a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2924a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song super.dispatchDraw(canvas); 29362bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy } 29462bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy 295eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung /** Sets the scale of the view over the normal workspace icon size. */ 296eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public void setIntrinsicIconScaleFactor(float scale) { 297eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung mIntrinsicIconScale = scale; 298eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 299eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 300eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public float getIntrinsicIconScaleFactor() { 301eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung return mIntrinsicIconScale; 302eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 303eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 304a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionLeft() { 305e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.left; 306a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 307a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 308a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionTop() { 309e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.top; 310a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 311a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 312a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionWidth() { 313e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.width(); 314a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 315a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 316a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionHeight() { 317e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.height(); 318e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen } 319e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen 320b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung public void setDragVisualizeOffset(Point p) { 321b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung mDragVisualizeOffset = p; 322b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung } 323b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung 324b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung public Point getDragVisualizeOffset() { 325b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung return mDragVisualizeOffset; 326b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung } 327b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung 328e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen public void setDragRegion(Rect r) { 329e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen mDragRegion = r; 330e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen } 331e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen 332e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen public Rect getDragRegion() { 333e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion; 334a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 335a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 336d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev // Draws drag shadow for system DND. 33742e28092b336bf89bee94c61e2cd327e1d8ec882Sunny Goyal @SuppressLint("WrongCall") 338d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public void drawDragShadow(Canvas canvas) { 339d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); 340d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev canvas.scale(getScaleX(), getScaleY()); 341d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev onDraw(canvas); 342d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev canvas.restoreToCount(saveCount); 343d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 344d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 345d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev // Provides drag shadow metrics for system DND. 346d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public void provideDragShadowMetrics(Point size, Point touch) { 347d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev size.set((int)(mBitmap.getWidth() * getScaleX()), (int)(mBitmap.getHeight() * getScaleY())); 348d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 34937bd006b73b4399ba10bb46e7f57a56b2e133e86Vadim Tryshev final float xGrowth = mBitmap.getWidth() * (getScaleX() - 1); 35037bd006b73b4399ba10bb46e7f57a56b2e133e86Vadim Tryshev final float yGrowth = mBitmap.getHeight() * (getScaleY() - 1); 3519430ff23c8a1127341e73b285e901a5cb9f1b5f7Vadim Tryshev touch.set( 3529430ff23c8a1127341e73b285e901a5cb9f1b5f7Vadim Tryshev mRegistrationX + (int)Math.round(xGrowth / 2), 3539430ff23c8a1127341e73b285e901a5cb9f1b5f7Vadim Tryshev mRegistrationY + (int)Math.round(yGrowth / 2)); 354d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 355d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 35600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato @Override 35700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onDraw(Canvas canvas) { 358fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mHasDrawn = true; 359ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null; 360ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen if (crossFade) { 361ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255; 362ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mPaint.setAlpha(alpha); 363ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 36400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); 365ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen if (crossFade) { 366ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mPaint.setAlpha((int) (255 * mCrossFadeProgress)); 367d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); 368ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth(); 369ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight(); 370ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen canvas.scale(sX, sY); 371ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint); 372d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev canvas.restoreToCount(saveCount); 373ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 374ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 375ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 376ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void setCrossFadeBitmap(Bitmap crossFadeBitmap) { 377ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mCrossFadeBitmap = crossFadeBitmap; 378ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 379ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 380ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void crossFade(int duration) { 381cda3bfb2e1d89ad872558dd0a82ae79ca6fe41eaJon Miranda ValueAnimator va = LauncherAnimUtils.ofFloat(0f, 1f); 382ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.setDuration(duration); 383ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.setInterpolator(new DecelerateInterpolator(1.5f)); 384ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.addUpdateListener(new AnimatorUpdateListener() { 385ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 386ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 387ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mCrossFadeProgress = animation.getAnimatedFraction(); 3885d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal invalidate(); 389ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 390ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen }); 391ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.start(); 39200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 39300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 39461967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung public void setColor(int color) { 3956cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka if (mPaint == null) { 3966cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); 3976cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka } 39861967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung if (color != 0) { 399fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal ColorMatrix m1 = new ColorMatrix(); 400fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal m1.setSaturation(0); 401fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 402fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal ColorMatrix m2 = new ColorMatrix(); 4036c82867a7ea3a95a19d6cec7d1fe164d234d2cb6Tony Wickham Themes.setColorScaleOnMatrix(color, m2); 404fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal m1.postConcat(m2); 405fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 406a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal animateFilterTo(m1.getArray()); 40761967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung } else { 408a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal if (mCurrentFilter == null) { 409fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mPaint.setColorFilter(null); 410fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal invalidate(); 411fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } else { 412fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal animateFilterTo(new ColorMatrix().getArray()); 413fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 41461967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung } 415fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 416fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 417fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal private void animateFilterTo(float[] targetFilter) { 418fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal float[] oldFilter = mCurrentFilter == null ? new ColorMatrix().getArray() : mCurrentFilter; 419fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mCurrentFilter = Arrays.copyOf(oldFilter, oldFilter.length); 420fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 421fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal if (mFilterAnimator != null) { 422fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.cancel(); 423fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 424fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator = ValueAnimator.ofObject(new FloatArrayEvaluator(mCurrentFilter), 425fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal oldFilter, targetFilter); 426fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.setDuration(COLOR_CHANGE_DURATION); 427fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.addUpdateListener(new AnimatorUpdateListener() { 428fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 429fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal @Override 430fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal public void onAnimationUpdate(ValueAnimator animation) { 431fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mPaint.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter)); 432fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal invalidate(); 433fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 434fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal }); 435fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.start(); 43600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 43700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 438fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen public boolean hasDrawn() { 439fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen return mHasDrawn; 440fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen } 441fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 4423e8f811f31a2275e778244427271f77f4116c08bAdam Cohen @Override 4433e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void setAlpha(float alpha) { 4443e8f811f31a2275e778244427271f77f4116c08bAdam Cohen super.setAlpha(alpha); 4453e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mPaint.setAlpha((int) (255 * alpha)); 4463e8f811f31a2275e778244427271f77f4116c08bAdam Cohen invalidate(); 4473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 4483e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 44900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 45000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Create a window containing this view and show it. 45100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 4528dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchX the x coordinate the user touched in DragLayer coordinates 4538dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchY the y coordinate the user touched in DragLayer coordinates 45400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 4558dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void show(int touchX, int touchY) { 4568dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDragLayer.addView(this); 457043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 458043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Start the pick-up animation 4598dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0); 4608dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.width = mBitmap.getWidth(); 4618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.height = mBitmap.getHeight(); 4628dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.customPosition = true; 4638dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen setLayoutParams(lp); 464a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal move(touchX, touchY); 465ca99383daef92fed673de22126875cb485be494fMichael Jurka // Post the animation to skip other expensive work happening on the first frame 466ca99383daef92fed673de22126875cb485be494fMichael Jurka post(new Runnable() { 467a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham public void run() { 468a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham mAnim.start(); 469a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham } 470a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham }); 47100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 472716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4737bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void cancelAnimation() { 474456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev mAnimationCancelled = true; 4757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mAnim != null && mAnim.isRunning()) { 4767bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mAnim.cancel(); 4777bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 4787bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 4797bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 48000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 48100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Move the window containing this view. 48200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 4838dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchX the x coordinate the user touched in DragLayer coordinates 4848dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchY the y coordinate the user touched in DragLayer coordinates 48500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 4861bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham public void move(int touchX, int touchY) { 4874a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0) { 4884a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song applySpring(mLastTouchX - touchX, mLastTouchY - touchY); 4894a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 490a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mLastTouchX = touchX; 491a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mLastTouchY = touchY; 492a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 493a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 494a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 495ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) { 496ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mTempLoc[0] = toTouchX - mRegistrationX; 497ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mTempLoc[1] = toTouchY - mRegistrationY; 498ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mDragLayer.animateViewIntoPosition(this, mTempLoc, 1f, mInitialScale, mInitialScale, 499ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham DragLayer.ANIMATION_END_DISAPPEAR, onCompleteRunnable, duration); 500ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham } 501ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham 502a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public void animateShift(final int shiftX, final int shiftY) { 503a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal if (mAnim.isStarted()) { 504a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal return; 505a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 506a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftX = shiftX; 507a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftY = shiftY; 508a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 509a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnim.addUpdateListener(new AnimatorUpdateListener() { 510a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal @Override 511a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public void onAnimationUpdate(ValueAnimator animation) { 512a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal float fraction = 1 - animation.getAnimatedFraction(); 513a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftX = (int) (fraction * shiftX); 514a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftY = (int) (fraction * shiftY); 515a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 516a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 517a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal }); 518a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 519a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 520a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private void applyTranslation() { 521a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal setTranslationX(mLastTouchX - mRegistrationX + mAnimatedShiftX); 522a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal setTranslationY(mLastTouchY - mRegistrationY + mAnimatedShiftY); 52300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 52400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 5251bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham public void remove() { 5267bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (getParent() != null) { 5277bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDragLayer.removeView(DragView.this); 5287bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 5296f13342ffd3f968de9ff86b988621cc91d94adffPatrick Dubroy } 5303a644ed1ce12554fcdf5c499e959bda986d10551Sunny Goyal 531c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda public int getBlurSizeOutline() { 532c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda return mBlurSizeOutline; 533c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda } 534dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal 535dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal public float getInitialScale() { 536dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal return mInitialScale; 537dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal } 53800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato} 539