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; 2403a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyalimport android.annotation.TargetApi; 25654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Songimport android.content.pm.LauncherActivityInfo; 2600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap; 2700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Canvas; 2803a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyalimport android.graphics.Color; 29fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport android.graphics.ColorMatrix; 30fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport android.graphics.ColorMatrixColorFilter; 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; 3603a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyalimport android.graphics.drawable.ColorDrawable; 374a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.graphics.drawable.Drawable; 38a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport android.graphics.drawable.InsetDrawable; 3903a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyalimport android.os.Build; 404a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.os.Handler; 414a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.os.Looper; 421a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyalimport android.support.animation.FloatPropertyCompat; 434a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.support.animation.SpringAnimation; 444a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport android.support.animation.SpringForce; 4500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.View; 46a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.view.animation.DecelerateInterpolator; 47fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev 48a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport com.android.launcher3.FastBitmapDrawable; 494a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.ItemInfo; 50fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Launcher; 51fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.LauncherAnimUtils; 52654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Songimport com.android.launcher3.LauncherAppState; 534a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.LauncherModel; 544a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.LauncherSettings; 55ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickhamimport com.android.launcher3.R; 564a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.Utilities; 57654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Songimport com.android.launcher3.compat.LauncherAppsCompat; 58a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport com.android.launcher3.compat.ShortcutConfigActivityInfo; 594a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Songimport com.android.launcher3.config.FeatureFlags; 6003a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyalimport com.android.launcher3.graphics.IconNormalizer; 61a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport com.android.launcher3.graphics.LauncherIcons; 62a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport com.android.launcher3.shortcuts.DeepShortcutManager; 63a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport com.android.launcher3.shortcuts.ShortcutInfoCompat; 64a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport com.android.launcher3.shortcuts.ShortcutKey; 656c82867a7ea3a95a19d6cec7d1fe164d234d2cb6Tony Wickhamimport com.android.launcher3.util.Themes; 66091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 67a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport com.android.launcher3.widget.PendingAddShortcutInfo; 68fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev 69fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyalimport java.util.Arrays; 70a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyalimport java.util.List; 71fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 721a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyalpublic class DragView extends View { 731a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private static final ColorMatrix sTempMatrix1 = new ColorMatrix(); 741a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private static final ColorMatrix sTempMatrix2 = new ColorMatrix(); 751a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 76a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public static final int COLOR_CHANGE_DURATION = 120; 77a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public static final int VIEW_ZOOM_DURATION = 150; 78fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 79091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static float sDragAlpha = 1f; 807bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 81e29897f503d54866fac279aa366922219d60b834Sunny Goyal private boolean mDrawBitmap = true; 8200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private Bitmap mBitmap; 83ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen private Bitmap mCrossFadeBitmap; 84316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk Paint mPaint; 85c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda private final int mBlurSizeOutline; 86d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final int mRegistrationX; 87d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final int mRegistrationY; 88ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham private final float mInitialScale; 89ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham private final int[] mTempLoc = new int[2]; 9000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 91b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung private Point mDragVisualizeOffset = null; 92e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen private Rect mDragRegion = null; 934a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private final Launcher mLauncher; 94d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev private final DragLayer mDragLayer; 9542e28092b336bf89bee94c61e2cd327e1d8ec882Sunny Goyal @Thunk final DragController mDragController; 96fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen private boolean mHasDrawn = false; 97091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk float mCrossFadeProgress = 0f; 98456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev private boolean mAnimationCancelled = false; 99a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 100a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy ValueAnimator mAnim; 101eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // The intrinsic icon scale factor is the scale factor for a drag icon over the workspace 102eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // size. This is ignored for non-icons. 103eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung private float mIntrinsicIconScale = 1f; 10400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 105316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk float[] mCurrentFilter; 106fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal private ValueAnimator mFilterAnimator; 107fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 108a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mLastTouchX; 109a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mLastTouchY; 110a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mAnimatedShiftX; 111a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private int mAnimatedShiftY; 112a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 1134a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song // Below variable only needed IF FeatureFlags.LAUNCHER3_SPRING_ICONS is {@code true} 1141a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private Drawable mBgSpringDrawable, mFgSpringDrawable; 1151a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private SpringFloatValue mTranslateX, mTranslateY; 1164a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song private Path mScaledMaskPath; 117654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song private Drawable mBadge; 1181a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private ColorMatrixColorFilter mBaseFilter; 1194a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 12000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 12100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Construct the drag view. 12200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * <p> 12300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * The registration point is the point inside our view that the touch events should 12400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * be centered upon. 1258dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param launcher The Launcher instance 12600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param bitmap The view that we're dragging around. We scale it up when we draw it. 12700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationX The x coordinate of the registration point. 12800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationY The y coordinate of the registration point. 12900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 130157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY, 131157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal final float initialScale, final float finalScaleDps) { 1328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen super(launcher); 1334a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song mLauncher = launcher; 1348dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDragLayer = launcher.getDragLayer(); 135d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mDragController = launcher.getDragController(); 13600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 13703a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal final float scale = (bitmap.getWidth() + finalScaleDps) / bitmap.getWidth(); 138a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 139307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen // Set the initial scale to avoid any jumps 140307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen setScaleX(initialScale); 141307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen setScaleY(initialScale); 142307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen 143a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy // Animate the view into the correct position 144cda3bfb2e1d89ad872558dd0a82ae79ca6fe41eaJon Miranda mAnim = LauncherAnimUtils.ofFloat(0f, 1f); 145a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnim.setDuration(VIEW_ZOOM_DURATION); 146a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mAnim.addUpdateListener(new AnimatorUpdateListener() { 147a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy @Override 148a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy public void onAnimationUpdate(ValueAnimator animation) { 149a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy final float value = (Float) animation.getAnimatedValue(); 150a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 15103a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal setScaleX(initialScale + (value * (scale - initialScale))); 15203a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal setScaleY(initialScale + (value * (scale - initialScale))); 153867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung if (sDragAlpha != 1f) { 154867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung setAlpha(sDragAlpha * value + (1f - value)); 155867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung } 156a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy 157a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy if (getParent() == null) { 158a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy animation.cancel(); 159a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy } 160a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy } 161a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy }); 16200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 163d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mAnim.addListener(new AnimatorListenerAdapter() { 164d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev @Override 165d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public void onAnimationEnd(Animator animation) { 166456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev if (!mAnimationCancelled) { 167456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev mDragController.onDragViewAnimationEnd(); 168456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev } 169d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 170d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev }); 171d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 172157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal mBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()); 173157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal setDragRegion(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight())); 17400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 17500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // The point in our scaled bitmap that the touch events are located 176a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mRegistrationX = registrationX; 177a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy mRegistrationY = registrationY; 17862bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy 179ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mInitialScale = initialScale; 180ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham 18162bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass 18262bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 18362bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy measure(ms, ms); 1846cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); 18575deaf3d8f369bd13ea59ec3740324a5cfeb3099Sunny Goyal 186c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda mBlurSizeOutline = getResources().getDimensionPixelSize(R.dimen.blur_size_medium_outline); 187a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal setElevation(getResources().getDimension(R.dimen.drag_elevation)); 1884a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 1894a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 1904a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song /** 191e29897f503d54866fac279aa366922219d60b834Sunny Goyal * Initialize {@code #mIconDrawable} if the item can be represented using 192e29897f503d54866fac279aa366922219d60b834Sunny Goyal * an {@link AdaptiveIconDrawable} or {@link FolderAdaptiveIcon}. 1934a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song */ 19403a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal @TargetApi(Build.VERSION_CODES.O) 1954a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song public void setItemInfo(final ItemInfo info) { 196e24cb63b811e2885a69e7df794e9972cdf5a57b9Hyunyoung Song if (!(FeatureFlags.LAUNCHER3_SPRING_ICONS && Utilities.ATLEAST_OREO)) { 1974a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song return; 1984a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 199a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && 200e29897f503d54866fac279aa366922219d60b834Sunny Goyal info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT && 201e29897f503d54866fac279aa366922219d60b834Sunny Goyal info.itemType != LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { 2024a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song return; 2034a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2044a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song // Load the adaptive icon on a background thread and add the view in ui thread. 2054a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song final Looper workerLooper = LauncherModel.getWorkerLooper(); 2064a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song new Handler(workerLooper).postAtFrontOfQueue(new Runnable() { 2074a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song @Override 2084a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song public void run() { 209654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song LauncherAppState appState = LauncherAppState.getInstance(mLauncher); 210a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal Object[] outObj = new Object[1]; 211e29897f503d54866fac279aa366922219d60b834Sunny Goyal final Drawable dr = getFullDrawable(info, appState, outObj); 212a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal 213654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song if (dr instanceof AdaptiveIconDrawable) { 214654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song int w = mBitmap.getWidth(); 215654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song int h = mBitmap.getHeight(); 2161a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal int blurMargin = (int) mLauncher.getResources() 2171a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal .getDimension(R.dimen.blur_size_medium_outline) / 2; 2181a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 2191a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal Rect bounds = new Rect(0, 0, w, h); 2201a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal bounds.inset(blurMargin, blurMargin); 2215be75795986da5229ec07ad8eec6a8cf0f7a19a3Sunny Goyal // Badge is applied after icon normalization so the bounds for badge should not 2225be75795986da5229ec07ad8eec6a8cf0f7a19a3Sunny Goyal // be scaled down due to icon normalization. 2235be75795986da5229ec07ad8eec6a8cf0f7a19a3Sunny Goyal Rect badgeBounds = new Rect(bounds); 2245be75795986da5229ec07ad8eec6a8cf0f7a19a3Sunny Goyal mBadge = getBadge(info, appState, outObj[0]); 2255be75795986da5229ec07ad8eec6a8cf0f7a19a3Sunny Goyal mBadge.setBounds(badgeBounds); 2265be75795986da5229ec07ad8eec6a8cf0f7a19a3Sunny Goyal 2271a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal Utilities.scaleRectAboutCenter(bounds, 2281a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal IconNormalizer.getInstance(mLauncher).getScale(dr, null, null, null)); 229654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr; 2301a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 2311a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal // Shrink very tiny bit so that the clip path is smaller than the original bitmap 2321a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal // that has anti aliased edges and shadows. 2331a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal Rect shrunkBounds = new Rect(bounds); 2341a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal Utilities.scaleRectAboutCenter(shrunkBounds, 0.98f); 2351a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal adaptiveIcon.setBounds(shrunkBounds); 2361a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal final Path mask = adaptiveIcon.getIconMask(); 2371a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 2381a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mTranslateX = new SpringFloatValue(DragView.this, 2391a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal w * AdaptiveIconDrawable.getExtraInsetFraction()); 2401a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mTranslateY = new SpringFloatValue(DragView.this, 2411a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal h * AdaptiveIconDrawable.getExtraInsetFraction()); 242654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song 2431a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal bounds.inset( 2441a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal (int) (-bounds.width() * AdaptiveIconDrawable.getExtraInsetFraction()), 2451a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal (int) (-bounds.height() * AdaptiveIconDrawable.getExtraInsetFraction()) 2461a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal ); 2471a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBgSpringDrawable = adaptiveIcon.getBackground(); 248746c6c36b656115076318c353418e3ecae303bbcTony Wickham if (mBgSpringDrawable == null) { 249746c6c36b656115076318c353418e3ecae303bbcTony Wickham mBgSpringDrawable = new ColorDrawable(Color.TRANSPARENT); 250746c6c36b656115076318c353418e3ecae303bbcTony Wickham } 2511a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBgSpringDrawable.setBounds(bounds); 2521a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mFgSpringDrawable = adaptiveIcon.getForeground(); 253746c6c36b656115076318c353418e3ecae303bbcTony Wickham if (mFgSpringDrawable == null) { 254746c6c36b656115076318c353418e3ecae303bbcTony Wickham mFgSpringDrawable = new ColorDrawable(Color.TRANSPARENT); 255746c6c36b656115076318c353418e3ecae303bbcTony Wickham } 2561a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mFgSpringDrawable.setBounds(bounds); 25703a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal 258654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song new Handler(Looper.getMainLooper()).post(new Runnable() { 259654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song @Override 260654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song public void run() { 26103a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal // Assign the variable on the UI thread to avoid race conditions. 26203a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal mScaledMaskPath = mask; 2632814112998042ccb5bda9501a5ae474f2b2832c6Sunny Goyal 264e29897f503d54866fac279aa366922219d60b834Sunny Goyal // Do not draw the background in case of folder as its translucent 265e29897f503d54866fac279aa366922219d60b834Sunny Goyal mDrawBitmap = !(dr instanceof FolderAdaptiveIcon); 266e29897f503d54866fac279aa366922219d60b834Sunny Goyal 2672814112998042ccb5bda9501a5ae474f2b2832c6Sunny Goyal if (info.isDisabled()) { 2682814112998042ccb5bda9501a5ae474f2b2832c6Sunny Goyal FastBitmapDrawable d = new FastBitmapDrawable(null); 2692814112998042ccb5bda9501a5ae474f2b2832c6Sunny Goyal d.setIsDisabled(true); 2701a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBaseFilter = (ColorMatrixColorFilter) d.getColorFilter(); 2712814112998042ccb5bda9501a5ae474f2b2832c6Sunny Goyal } 2721a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal updateColorFilter(); 273654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song } 274654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song }); 275654bf3141bc02604842659f34c15e0fb151a8eaeHyunyoung Song } 2764a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song }}); 2774a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 2784a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song 2791a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal @TargetApi(Build.VERSION_CODES.O) 2801a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private void updateColorFilter() { 2811a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal if (mCurrentFilter == null) { 2821a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mPaint.setColorFilter(null); 2831a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 2841a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal if (mScaledMaskPath != null) { 2851a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBgSpringDrawable.setColorFilter(mBaseFilter); 2861a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBgSpringDrawable.setColorFilter(mBaseFilter); 2871a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBadge.setColorFilter(mBaseFilter); 2881a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 2891a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } else { 2901a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal ColorMatrixColorFilter currentFilter = new ColorMatrixColorFilter(mCurrentFilter); 2911a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mPaint.setColorFilter(currentFilter); 2921a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 2931a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal if (mScaledMaskPath != null) { 2941a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal if (mBaseFilter != null) { 2951a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBaseFilter.getColorMatrix(sTempMatrix1); 2961a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal sTempMatrix2.set(mCurrentFilter); 2971a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal sTempMatrix1.postConcat(sTempMatrix2); 2981a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 2991a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal currentFilter = new ColorMatrixColorFilter(sTempMatrix1); 3001a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 3011a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 3021a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBgSpringDrawable.setColorFilter(currentFilter); 3031a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mFgSpringDrawable.setColorFilter(currentFilter); 3041a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBadge.setColorFilter(currentFilter); 3051a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 3061a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 3071a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 3081a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal invalidate(); 3091a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 3101a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 311a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal /** 312a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal * Returns the full drawable for {@param info}. 313a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal * @param outObj this is set to the internal data associated with {@param info}, 314a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal * eg {@link LauncherActivityInfo} or {@link ShortcutInfoCompat}. 315a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal */ 316a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal private Drawable getFullDrawable(ItemInfo info, LauncherAppState appState, Object[] outObj) { 317a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 318a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal LauncherActivityInfo activityInfo = LauncherAppsCompat.getInstance(mLauncher) 319a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal .resolveActivity(info.getIntent(), info.user); 320a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal outObj[0] = activityInfo; 321a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return (activityInfo != null) ? appState.getIconCache() 3221da138903bc8412615edacd7a447c6ffc25851d4Sunny Goyal .getFullResIcon(activityInfo, false) : null; 323a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { 324a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal if (info instanceof PendingAddShortcutInfo) { 325a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal ShortcutConfigActivityInfo activityInfo = 326a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal ((PendingAddShortcutInfo) info).activityInfo; 327a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal outObj[0] = activityInfo; 328a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return activityInfo.getFullResIcon(appState.getIconCache()); 329a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } 330a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal ShortcutKey key = ShortcutKey.fromItemInfo(info); 331a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal DeepShortcutManager sm = DeepShortcutManager.getInstance(mLauncher); 332a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal List<ShortcutInfoCompat> si = sm.queryForFullDetails( 333a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal key.componentName.getPackageName(), Arrays.asList(key.getId()), key.user); 334a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal if (si.isEmpty()) { 335a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return null; 336a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } else { 337a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal outObj[0] = si.get(0); 338a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return sm.getShortcutIconDrawable(si.get(0), 339a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal appState.getInvariantDeviceProfile().fillResIconDpi); 340a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } 341e29897f503d54866fac279aa366922219d60b834Sunny Goyal } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { 342e29897f503d54866fac279aa366922219d60b834Sunny Goyal FolderAdaptiveIcon icon = FolderAdaptiveIcon.createFolderAdaptiveIcon( 343e29897f503d54866fac279aa366922219d60b834Sunny Goyal mLauncher, info.id, new Point(mBitmap.getWidth(), mBitmap.getHeight())); 344e29897f503d54866fac279aa366922219d60b834Sunny Goyal if (icon == null) { 345e29897f503d54866fac279aa366922219d60b834Sunny Goyal return null; 346e29897f503d54866fac279aa366922219d60b834Sunny Goyal } 347e29897f503d54866fac279aa366922219d60b834Sunny Goyal outObj[0] = icon; 348e29897f503d54866fac279aa366922219d60b834Sunny Goyal return icon; 349a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } else { 350a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return null; 351a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } 352a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } 353a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal 354a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal /** 355a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal * For apps icons and shortcut icons that have badges, this method creates a drawable that can 356a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal * later on be rendered on top of the layers for the badges. For app icons, work profile badges 357a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal * can only be applied. For deep shortcuts, when dragged from the pop up container, there's no 358a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal * badge. When dragged from workspace or folder, it may contain app AND/OR work profile badge 359a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal **/ 360a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal 361a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal @TargetApi(Build.VERSION_CODES.O) 362a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal private Drawable getBadge(ItemInfo info, LauncherAppState appState, Object obj) { 363a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal int iconSize = appState.getInvariantDeviceProfile().iconBitmapSize; 364a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { 365a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal if (info.id == ItemInfo.NO_ID || !(obj instanceof ShortcutInfoCompat)) { 366a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal // The item is not yet added on home screen. 367a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return new FixedSizeEmptyDrawable(iconSize); 368a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } 369a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal ShortcutInfoCompat si = (ShortcutInfoCompat) obj; 370a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal Bitmap badge = LauncherIcons.getShortcutInfoBadge(si, appState.getIconCache()); 371a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal 372a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal float badgeSize = mLauncher.getResources().getDimension(R.dimen.profile_badge_size); 373a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal float insetFraction = (iconSize - badgeSize) / iconSize; 374a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return new InsetDrawable(new FastBitmapDrawable(badge), 375a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal insetFraction, insetFraction, 0, 0); 376e29897f503d54866fac279aa366922219d60b834Sunny Goyal } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { 377e29897f503d54866fac279aa366922219d60b834Sunny Goyal return ((FolderAdaptiveIcon) obj).getBadge(); 378a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } else { 379a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal return mLauncher.getPackageManager() 380a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal .getUserBadgedIcon(new FixedSizeEmptyDrawable(iconSize), info.user); 381a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } 382a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal } 383a2fde430b53c78255ea2cc87308897a06afb6723Sunny Goyal 3844a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song @Override 3854a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 3861a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight()); 38762bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy } 38862bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy 389eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung /** Sets the scale of the view over the normal workspace icon size. */ 390eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public void setIntrinsicIconScaleFactor(float scale) { 391eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung mIntrinsicIconScale = scale; 392eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 393eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 394eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public float getIntrinsicIconScaleFactor() { 395eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung return mIntrinsicIconScale; 396eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 397eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 398a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionLeft() { 399e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.left; 400a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 401a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 402a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionTop() { 403e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.top; 404a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 405a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 406a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionWidth() { 407e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.width(); 408a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 409a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 410a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka public int getDragRegionHeight() { 411e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion.height(); 412e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen } 413e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen 414b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung public void setDragVisualizeOffset(Point p) { 415b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung mDragVisualizeOffset = p; 416b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung } 417b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung 418b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung public Point getDragVisualizeOffset() { 419b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung return mDragVisualizeOffset; 420b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung } 421b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung 422e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen public void setDragRegion(Rect r) { 423e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen mDragRegion = r; 424e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen } 425e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen 426e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen public Rect getDragRegion() { 427e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen return mDragRegion; 428a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 429a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 43000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato @Override 43100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onDraw(Canvas canvas) { 432fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mHasDrawn = true; 433e29897f503d54866fac279aa366922219d60b834Sunny Goyal 434e29897f503d54866fac279aa366922219d60b834Sunny Goyal if (mDrawBitmap) { 435e29897f503d54866fac279aa366922219d60b834Sunny Goyal // Always draw the bitmap to mask anti aliasing due to clipPath 436e29897f503d54866fac279aa366922219d60b834Sunny Goyal boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null; 437e29897f503d54866fac279aa366922219d60b834Sunny Goyal if (crossFade) { 438e29897f503d54866fac279aa366922219d60b834Sunny Goyal int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255; 439e29897f503d54866fac279aa366922219d60b834Sunny Goyal mPaint.setAlpha(alpha); 440e29897f503d54866fac279aa366922219d60b834Sunny Goyal } 441e29897f503d54866fac279aa366922219d60b834Sunny Goyal canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); 442e29897f503d54866fac279aa366922219d60b834Sunny Goyal if (crossFade) { 443e29897f503d54866fac279aa366922219d60b834Sunny Goyal mPaint.setAlpha((int) (255 * mCrossFadeProgress)); 444e29897f503d54866fac279aa366922219d60b834Sunny Goyal final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); 445e29897f503d54866fac279aa366922219d60b834Sunny Goyal float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth(); 446e29897f503d54866fac279aa366922219d60b834Sunny Goyal float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight(); 447e29897f503d54866fac279aa366922219d60b834Sunny Goyal canvas.scale(sX, sY); 448e29897f503d54866fac279aa366922219d60b834Sunny Goyal canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint); 449e29897f503d54866fac279aa366922219d60b834Sunny Goyal canvas.restoreToCount(saveCount); 450e29897f503d54866fac279aa366922219d60b834Sunny Goyal } 451ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 4521a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 4531a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal if (mScaledMaskPath != null) { 4541a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal int cnt = canvas.save(); 4551a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal canvas.clipPath(mScaledMaskPath); 4561a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBgSpringDrawable.draw(canvas); 4571a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal canvas.translate(mTranslateX.mValue, mTranslateY.mValue); 4581a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mFgSpringDrawable.draw(canvas); 4591a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal canvas.restoreToCount(cnt); 4601a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mBadge.draw(canvas); 4611a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 462ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 463ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 464ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void setCrossFadeBitmap(Bitmap crossFadeBitmap) { 465ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mCrossFadeBitmap = crossFadeBitmap; 466ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 467ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 468ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void crossFade(int duration) { 469cda3bfb2e1d89ad872558dd0a82ae79ca6fe41eaJon Miranda ValueAnimator va = LauncherAnimUtils.ofFloat(0f, 1f); 470ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.setDuration(duration); 471ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.setInterpolator(new DecelerateInterpolator(1.5f)); 472ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.addUpdateListener(new AnimatorUpdateListener() { 473ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 474ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 475ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mCrossFadeProgress = animation.getAnimatedFraction(); 4765d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal invalidate(); 477ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 478ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen }); 479ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen va.start(); 48000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 48100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 48261967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung public void setColor(int color) { 4836cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka if (mPaint == null) { 4846cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); 4856cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka } 48661967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung if (color != 0) { 487fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal ColorMatrix m1 = new ColorMatrix(); 488fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal m1.setSaturation(0); 489fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 490fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal ColorMatrix m2 = new ColorMatrix(); 4916c82867a7ea3a95a19d6cec7d1fe164d234d2cb6Tony Wickham Themes.setColorScaleOnMatrix(color, m2); 492fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal m1.postConcat(m2); 493fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 494a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal animateFilterTo(m1.getArray()); 49561967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung } else { 496a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal if (mCurrentFilter == null) { 4971a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal updateColorFilter(); 498fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } else { 499fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal animateFilterTo(new ColorMatrix().getArray()); 500fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 50161967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung } 502fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 503fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 504fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal private void animateFilterTo(float[] targetFilter) { 505fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal float[] oldFilter = mCurrentFilter == null ? new ColorMatrix().getArray() : mCurrentFilter; 506fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mCurrentFilter = Arrays.copyOf(oldFilter, oldFilter.length); 507fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 508fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal if (mFilterAnimator != null) { 509fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.cancel(); 510fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 511fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator = ValueAnimator.ofObject(new FloatArrayEvaluator(mCurrentFilter), 512fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal oldFilter, targetFilter); 513fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.setDuration(COLOR_CHANGE_DURATION); 514fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.addUpdateListener(new AnimatorUpdateListener() { 515fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal 516fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal @Override 517fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal public void onAnimationUpdate(ValueAnimator animation) { 5181a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal updateColorFilter(); 519fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal } 520fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal }); 521fe0d1f2458e6a442613b070ae549124a4780e759Sunny Goyal mFilterAnimator.start(); 52200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 52300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 524fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen public boolean hasDrawn() { 525fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen return mHasDrawn; 526fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen } 527fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 5283e8f811f31a2275e778244427271f77f4116c08bAdam Cohen @Override 5293e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void setAlpha(float alpha) { 5303e8f811f31a2275e778244427271f77f4116c08bAdam Cohen super.setAlpha(alpha); 5313e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mPaint.setAlpha((int) (255 * alpha)); 5323e8f811f31a2275e778244427271f77f4116c08bAdam Cohen invalidate(); 5333e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 5343e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 53500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 53600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Create a window containing this view and show it. 53700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 5388dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchX the x coordinate the user touched in DragLayer coordinates 5398dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchY the y coordinate the user touched in DragLayer coordinates 54000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 5418dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void show(int touchX, int touchY) { 5428dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mDragLayer.addView(this); 543043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 544043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Start the pick-up animation 5458dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0); 5468dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.width = mBitmap.getWidth(); 5478dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.height = mBitmap.getHeight(); 5488dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen lp.customPosition = true; 5498dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen setLayoutParams(lp); 550a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal move(touchX, touchY); 551ca99383daef92fed673de22126875cb485be494fMichael Jurka // Post the animation to skip other expensive work happening on the first frame 552ca99383daef92fed673de22126875cb485be494fMichael Jurka post(new Runnable() { 553a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham public void run() { 554a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham mAnim.start(); 555a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham } 556a501d49a6a8b684bc83aa6b536f43247d75bacdfTony Wickham }); 55700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 558716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 5597bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void cancelAnimation() { 560456e87e1943ee4e779929f77a9cf11de7af3ec6aVadim Tryshev mAnimationCancelled = true; 5617bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mAnim != null && mAnim.isRunning()) { 5627bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mAnim.cancel(); 5637bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 5647bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 5657bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 56600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 56700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Move the window containing this view. 56800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 5698dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchX the x coordinate the user touched in DragLayer coordinates 5708dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param touchY the y coordinate the user touched in DragLayer coordinates 57100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 5721bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham public void move(int touchX, int touchY) { 5731a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0 5741a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal && mScaledMaskPath != null) { 5751a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mTranslateX.animateToPos(mLastTouchX - touchX); 5761a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mTranslateY.animateToPos(mLastTouchY - touchY); 5774a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song } 578a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mLastTouchX = touchX; 579a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mLastTouchY = touchY; 580a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 581a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 582a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 583ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) { 584ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mTempLoc[0] = toTouchX - mRegistrationX; 585ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mTempLoc[1] = toTouchY - mRegistrationY; 586ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham mDragLayer.animateViewIntoPosition(this, mTempLoc, 1f, mInitialScale, mInitialScale, 587ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham DragLayer.ANIMATION_END_DISAPPEAR, onCompleteRunnable, duration); 588ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham } 589ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham 590a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public void animateShift(final int shiftX, final int shiftY) { 591a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal if (mAnim.isStarted()) { 592a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal return; 593a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 594a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftX = shiftX; 595a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftY = shiftY; 596a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 597a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnim.addUpdateListener(new AnimatorUpdateListener() { 598a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal @Override 599a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal public void onAnimationUpdate(ValueAnimator animation) { 600a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal float fraction = 1 - animation.getAnimatedFraction(); 601a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftX = (int) (fraction * shiftX); 602a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal mAnimatedShiftY = (int) (fraction * shiftY); 603a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal applyTranslation(); 604a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 605a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal }); 606a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal } 607a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal 608a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal private void applyTranslation() { 609a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal setTranslationX(mLastTouchX - mRegistrationX + mAnimatedShiftX); 610a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal setTranslationY(mLastTouchY - mRegistrationY + mAnimatedShiftY); 61100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 61200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 6131bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham public void remove() { 6147bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (getParent() != null) { 6157bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDragLayer.removeView(DragView.this); 6167bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 6176f13342ffd3f968de9ff86b988621cc91d94adffPatrick Dubroy } 6183a644ed1ce12554fcdf5c499e959bda986d10551Sunny Goyal 619c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda public int getBlurSizeOutline() { 620c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda return mBlurSizeOutline; 621c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda } 622dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal 623dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal public float getInitialScale() { 624dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal return mInitialScale; 625dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal } 62603a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal 6271a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private static class SpringFloatValue { 6281a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 6291a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private static final FloatPropertyCompat<SpringFloatValue> VALUE = 6301a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal new FloatPropertyCompat<SpringFloatValue>("value") { 6311a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal @Override 6321a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal public float getValue(SpringFloatValue object) { 6331a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal return object.mValue; 6341a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 6351a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 6361a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal @Override 6371a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal public void setValue(SpringFloatValue object, float value) { 6381a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal object.mValue = value; 6391a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal object.mView.invalidate(); 6401a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 6411a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal }; 6421a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 6431a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal // Following three values are fine tuned with motion ux designer 6441a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private final static int STIFFNESS = 4000; 6451a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private final static float DAMPENING_RATIO = 1f; 6461a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private final static int PARALLAX_MAX_IN_DP = 8; 6471a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 6481a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private final View mView; 6491a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private final SpringAnimation mSpring; 6501a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private final float mDelta; 6511a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 6521a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal private float mValue; 6531a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 6541a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal public SpringFloatValue(View view, float range) { 6551a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mView = view; 6561a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mSpring = new SpringAnimation(this, VALUE, 0) 6571a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal .setMinValue(-range).setMaxValue(range) 6581a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal .setSpring(new SpringForce(0) 6591a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal .setDampingRatio(DAMPENING_RATIO) 6601a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal .setStiffness(STIFFNESS)); 6611a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mDelta = view.getResources().getDisplayMetrics().density * PARALLAX_MAX_IN_DP; 6621a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 6631a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 6641a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal public void animateToPos(float value) { 6651a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal mSpring.animateToFinalPosition(Utilities.boundToRange(value, -mDelta, mDelta)); 6661a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 6671a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal } 6681a56a5286c65bd56a5000001eed06b01d372c9a9Sunny Goyal 66903a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal private static class FixedSizeEmptyDrawable extends ColorDrawable { 67003a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal 67103a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal private final int mSize; 67203a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal 67303a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal public FixedSizeEmptyDrawable(int size) { 67403a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal super(Color.TRANSPARENT); 67503a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal mSize = size; 67603a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal } 67703a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal 67803a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal @Override 67903a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal public int getIntrinsicHeight() { 68003a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal return mSize; 68103a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal } 68203a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal 68303a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal @Override 68403a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal public int getIntrinsicWidth() { 68503a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal return mSize; 68603a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal } 68703a38a669cc01123858c309c5536c0c8d86bb831Sunny Goyal } 68800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato} 689