1d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenpackage com.android.launcher2; 2d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 3d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.animation.AnimatorSet; 4d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.animation.ObjectAnimator; 5d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.animation.PropertyValuesHolder; 6d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.animation.ValueAnimator; 7d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener; 80cf2a7c3eeb75cbd532b011524140a4b963f2c93Adam Cohenimport android.appwidget.AppWidgetHostView; 9d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.appwidget.AppWidgetProviderInfo; 10d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.content.Context; 110cf2a7c3eeb75cbd532b011524140a4b963f2c93Adam Cohenimport android.graphics.Rect; 12d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.view.Gravity; 13d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.widget.FrameLayout; 14d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport android.widget.ImageView; 15d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 16d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenimport com.android.launcher.R; 17d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 18d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohenpublic class AppWidgetResizeFrame extends FrameLayout { 19d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private LauncherAppWidgetHostView mWidgetView; 20d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private CellLayout mCellLayout; 216788269814a678af976dfc7d6135993e172ce586Adam Cohen private DragLayer mDragLayer; 226788269814a678af976dfc7d6135993e172ce586Adam Cohen private Workspace mWorkspace; 23d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private ImageView mLeftHandle; 24d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private ImageView mRightHandle; 251b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen private ImageView mTopHandle; 26d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private ImageView mBottomHandle; 27d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 28d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private boolean mLeftBorderActive; 29d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private boolean mRightBorderActive; 30d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private boolean mTopBorderActive; 31d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private boolean mBottomBorderActive; 32d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 3337b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen private int mWidgetPaddingLeft; 3437b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen private int mWidgetPaddingRight; 3537b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen private int mWidgetPaddingTop; 3637b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen private int mWidgetPaddingBottom; 3737b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen 38d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mBaselineWidth; 39d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mBaselineHeight; 40d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mBaselineX; 41d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mBaselineY; 42d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mResizeMode; 433cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen 44d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mRunningHInc; 45d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mRunningVInc; 46d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mMinHSpan; 47d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mMinVSpan; 48d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mDeltaX; 49d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen private int mDeltaY; 50bebf042666cffe52039b875a549a582abd78a431Adam Cohen private int mDeltaXAddOn; 51bebf042666cffe52039b875a549a582abd78a431Adam Cohen private int mDeltaYAddOn; 521b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen 533cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen private int mBackgroundPadding; 543cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen private int mTouchTargetWidth; 55d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 564459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen private int mTopTouchRegionAdjustment = 0; 574459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen private int mBottomTouchRegionAdjustment = 0; 584459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen 59bebf042666cffe52039b875a549a582abd78a431Adam Cohen int[] mDirectionVector = new int[2]; 60e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen int[] mLastDirectionVector = new int[2]; 61d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 62d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen final int SNAP_DURATION = 150; 633cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen final int BACKGROUND_PADDING = 24; 64e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen final float DIMMED_HANDLE_ALPHA = 0f; 65e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen final float RESIZE_THRESHOLD = 0.66f; 66d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 679e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen private static Rect mTmpRect = new Rect(); 689e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen 691b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen public static final int LEFT = 0; 701b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen public static final int TOP = 1; 711b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen public static final int RIGHT = 2; 721b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen public static final int BOTTOM = 3; 731b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen 74cbf47e38e24cc0d63b4bd3f345c050216f06f404Adam Cohen private Launcher mLauncher; 75cbf47e38e24cc0d63b4bd3f345c050216f06f404Adam Cohen 763a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka public AppWidgetResizeFrame(Context context, 776788269814a678af976dfc7d6135993e172ce586Adam Cohen LauncherAppWidgetHostView widgetView, CellLayout cellLayout, DragLayer dragLayer) { 78d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 79d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen super(context); 80cbf47e38e24cc0d63b4bd3f345c050216f06f404Adam Cohen mLauncher = (Launcher) context; 81d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mCellLayout = cellLayout; 82d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mWidgetView = widgetView; 8327c09b05d3ed2a4ce9d53140216aba998727a569Adam Cohen mResizeMode = widgetView.getAppWidgetInfo().resizeMode; 846788269814a678af976dfc7d6135993e172ce586Adam Cohen mDragLayer = dragLayer; 856788269814a678af976dfc7d6135993e172ce586Adam Cohen mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace); 863cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen 87d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen final AppWidgetProviderInfo info = widgetView.getAppWidgetInfo(); 882f093b6ad185967c129781526060288e983bc58aAdam Cohen int[] result = Launcher.getMinSpanForWidget(mLauncher, info); 89d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mMinHSpan = result[0]; 90d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mMinVSpan = result[1]; 91d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 923cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen setBackgroundResource(R.drawable.widget_resize_frame_holo); 93d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen setPadding(0, 0, 0, 0); 94d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 95d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen LayoutParams lp; 96d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mLeftHandle = new ImageView(context); 973cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mLeftHandle.setImageResource(R.drawable.widget_resize_handle_left); 98d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 99cc11f742586b57c576026b7756a46209fe793ea1Fabrice Di Meglio Gravity.START | Gravity.CENTER_VERTICAL); 100d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen addView(mLeftHandle, lp); 101d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 102d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mRightHandle = new ImageView(context); 1033cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mRightHandle.setImageResource(R.drawable.widget_resize_handle_right); 104d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 105cc11f742586b57c576026b7756a46209fe793ea1Fabrice Di Meglio Gravity.END | Gravity.CENTER_VERTICAL); 106d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen addView(mRightHandle, lp); 107d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 108d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mTopHandle = new ImageView(context); 1093cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mTopHandle.setImageResource(R.drawable.widget_resize_handle_top); 110d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 111d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen Gravity.CENTER_HORIZONTAL | Gravity.TOP); 112d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen addView(mTopHandle, lp); 113d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 114d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mBottomHandle = new ImageView(context); 1153cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mBottomHandle.setImageResource(R.drawable.widget_resize_handle_bottom); 116d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 117d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); 118d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen addView(mBottomHandle, lp); 119d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 1200cf2a7c3eeb75cbd532b011524140a4b963f2c93Adam Cohen Rect p = AppWidgetHostView.getDefaultPaddingForWidget(context, 1210cf2a7c3eeb75cbd532b011524140a4b963f2c93Adam Cohen widgetView.getAppWidgetInfo().provider, null); 12282ebbd2a2f9ae5cb0a9d47f2f3a4293e4d0292d7Adam Cohen mWidgetPaddingLeft = p.left; 12382ebbd2a2f9ae5cb0a9d47f2f3a4293e4d0292d7Adam Cohen mWidgetPaddingTop = p.top; 12482ebbd2a2f9ae5cb0a9d47f2f3a4293e4d0292d7Adam Cohen mWidgetPaddingRight = p.right; 12582ebbd2a2f9ae5cb0a9d47f2f3a4293e4d0292d7Adam Cohen mWidgetPaddingBottom = p.bottom; 12637b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen 127d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) { 128d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mTopHandle.setVisibility(GONE); 129d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mBottomHandle.setVisibility(GONE); 130d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mResizeMode == AppWidgetProviderInfo.RESIZE_VERTICAL) { 131d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mLeftHandle.setVisibility(GONE); 132d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mRightHandle.setVisibility(GONE); 1333cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen } 1343cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen 135cbf47e38e24cc0d63b4bd3f345c050216f06f404Adam Cohen final float density = mLauncher.getResources().getDisplayMetrics().density; 1363cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mBackgroundPadding = (int) Math.ceil(density * BACKGROUND_PADDING); 1373cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mTouchTargetWidth = 2 * mBackgroundPadding; 138bebf042666cffe52039b875a549a582abd78a431Adam Cohen 139bebf042666cffe52039b875a549a582abd78a431Adam Cohen // When we create the resize frame, we first mark all cells as unoccupied. The appropriate 140bebf042666cffe52039b875a549a582abd78a431Adam Cohen // cells (same if not resized, or different) will be marked as occupied when the resize 141bebf042666cffe52039b875a549a582abd78a431Adam Cohen // frame is dismissed. 142bebf042666cffe52039b875a549a582abd78a431Adam Cohen mCellLayout.markCellsAsUnoccupiedForView(mWidgetView); 143d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 144d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 145d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen public boolean beginResizeIfPointInRegion(int x, int y) { 146d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen boolean horizontalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0; 147d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen boolean verticalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0; 1484459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen 1493cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mLeftBorderActive = (x < mTouchTargetWidth) && horizontalActive; 1503cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mRightBorderActive = (x > getWidth() - mTouchTargetWidth) && horizontalActive; 1514459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen mTopBorderActive = (y < mTouchTargetWidth + mTopTouchRegionAdjustment) && verticalActive; 1524459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen mBottomBorderActive = (y > getHeight() - mTouchTargetWidth + mBottomTouchRegionAdjustment) 1534459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen && verticalActive; 154d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 155d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen boolean anyBordersActive = mLeftBorderActive || mRightBorderActive 156d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen || mTopBorderActive || mBottomBorderActive; 157d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 158d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mBaselineWidth = getMeasuredWidth(); 159d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mBaselineHeight = getMeasuredHeight(); 160d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mBaselineX = getLeft(); 161d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mBaselineY = getTop(); 162d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 163d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (anyBordersActive) { 1643cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mLeftHandle.setAlpha(mLeftBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA); 1653cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mRightHandle.setAlpha(mRightBorderActive ? 1.0f :DIMMED_HANDLE_ALPHA); 1663cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mTopHandle.setAlpha(mTopBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA); 1673cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mBottomHandle.setAlpha(mBottomBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA); 168d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 169d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen return anyBordersActive; 170d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 171d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 1721b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen /** 1731b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen * Here we bound the deltas such that the frame cannot be stretched beyond the extents 1741b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen * of the CellLayout, and such that the frame's borders can't cross. 1751b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen */ 176d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen public void updateDeltas(int deltaX, int deltaY) { 177d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mLeftBorderActive) { 178d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mDeltaX = Math.max(-mBaselineX, deltaX); 1793cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mDeltaX = Math.min(mBaselineWidth - 2 * mTouchTargetWidth, mDeltaX); 180d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mRightBorderActive) { 1816788269814a678af976dfc7d6135993e172ce586Adam Cohen mDeltaX = Math.min(mDragLayer.getWidth() - (mBaselineX + mBaselineWidth), deltaX); 1823cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mDeltaX = Math.max(-mBaselineWidth + 2 * mTouchTargetWidth, mDeltaX); 183d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 184d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 185d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mTopBorderActive) { 186d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mDeltaY = Math.max(-mBaselineY, deltaY); 1873cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mDeltaY = Math.min(mBaselineHeight - 2 * mTouchTargetWidth, mDeltaY); 188d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mBottomBorderActive) { 1896788269814a678af976dfc7d6135993e172ce586Adam Cohen mDeltaY = Math.min(mDragLayer.getHeight() - (mBaselineY + mBaselineHeight), deltaY); 1903cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen mDeltaY = Math.max(-mBaselineHeight + 2 * mTouchTargetWidth, mDeltaY); 191d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 192d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 193d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 194bebf042666cffe52039b875a549a582abd78a431Adam Cohen public void visualizeResizeForDelta(int deltaX, int deltaY) { 195bebf042666cffe52039b875a549a582abd78a431Adam Cohen visualizeResizeForDelta(deltaX, deltaY, false); 196bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 197bebf042666cffe52039b875a549a582abd78a431Adam Cohen 1981b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen /** 1991b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen * Based on the deltas, we resize the frame, and, if needed, we resize the widget. 2001b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen */ 201bebf042666cffe52039b875a549a582abd78a431Adam Cohen private void visualizeResizeForDelta(int deltaX, int deltaY, boolean onDismiss) { 202d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen updateDeltas(deltaX, deltaY); 2036788269814a678af976dfc7d6135993e172ce586Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 2046788269814a678af976dfc7d6135993e172ce586Adam Cohen 205d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mLeftBorderActive) { 206d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.x = mBaselineX + mDeltaX; 207d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.width = mBaselineWidth - mDeltaX; 208d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mRightBorderActive) { 209d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.width = mBaselineWidth + mDeltaX; 210d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 211d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 212d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mTopBorderActive) { 213d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.y = mBaselineY + mDeltaY; 214d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.height = mBaselineHeight - mDeltaY; 215d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mBottomBorderActive) { 216d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.height = mBaselineHeight + mDeltaY; 217d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 218d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 219bebf042666cffe52039b875a549a582abd78a431Adam Cohen resizeWidgetIfNeeded(onDismiss); 220d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen requestLayout(); 221d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 222d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 2231b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen /** 2241b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen * Based on the current deltas, we determine if and how to resize the widget. 2251b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen */ 226bebf042666cffe52039b875a549a582abd78a431Adam Cohen private void resizeWidgetIfNeeded(boolean onDismiss) { 227d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap(); 228d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap(); 229d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 230bebf042666cffe52039b875a549a582abd78a431Adam Cohen int deltaX = mDeltaX + mDeltaXAddOn; 231bebf042666cffe52039b875a549a582abd78a431Adam Cohen int deltaY = mDeltaY + mDeltaYAddOn; 232bebf042666cffe52039b875a549a582abd78a431Adam Cohen 233bebf042666cffe52039b875a549a582abd78a431Adam Cohen float hSpanIncF = 1.0f * deltaX / xThreshold - mRunningHInc; 234bebf042666cffe52039b875a549a582abd78a431Adam Cohen float vSpanIncF = 1.0f * deltaY / yThreshold - mRunningVInc; 235e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen 236e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen int hSpanInc = 0; 237e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen int vSpanInc = 0; 238d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen int cellXInc = 0; 239d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen int cellYInc = 0; 240d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 241bebf042666cffe52039b875a549a582abd78a431Adam Cohen int countX = mCellLayout.getCountX(); 242bebf042666cffe52039b875a549a582abd78a431Adam Cohen int countY = mCellLayout.getCountY(); 243bebf042666cffe52039b875a549a582abd78a431Adam Cohen 244e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen if (Math.abs(hSpanIncF) > RESIZE_THRESHOLD) { 245e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen hSpanInc = Math.round(hSpanIncF); 246e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen } 247e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen if (Math.abs(vSpanIncF) > RESIZE_THRESHOLD) { 248e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen vSpanInc = Math.round(vSpanIncF); 249e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen } 250e4b7729b9d6343b4e7e0905e117e5ac469727cbeAdam Cohen 251bebf042666cffe52039b875a549a582abd78a431Adam Cohen if (!onDismiss && (hSpanInc == 0 && vSpanInc == 0)) return; 252d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 253d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 254d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams(); 2551b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen 256bebf042666cffe52039b875a549a582abd78a431Adam Cohen int spanX = lp.cellHSpan; 257bebf042666cffe52039b875a549a582abd78a431Adam Cohen int spanY = lp.cellVSpan; 258bebf042666cffe52039b875a549a582abd78a431Adam Cohen int cellX = lp.useTmpCoords ? lp.tmpCellX : lp.cellX; 259bebf042666cffe52039b875a549a582abd78a431Adam Cohen int cellY = lp.useTmpCoords ? lp.tmpCellY : lp.cellY; 260bebf042666cffe52039b875a549a582abd78a431Adam Cohen 261bebf042666cffe52039b875a549a582abd78a431Adam Cohen int hSpanDelta = 0; 262bebf042666cffe52039b875a549a582abd78a431Adam Cohen int vSpanDelta = 0; 263bebf042666cffe52039b875a549a582abd78a431Adam Cohen 2641b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen // For each border, we bound the resizing based on the minimum width, and the maximum 2651b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen // expandability. 266d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mLeftBorderActive) { 267bebf042666cffe52039b875a549a582abd78a431Adam Cohen cellXInc = Math.max(-cellX, hSpanInc); 268d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen cellXInc = Math.min(lp.cellHSpan - mMinHSpan, cellXInc); 269d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen hSpanInc *= -1; 270bebf042666cffe52039b875a549a582abd78a431Adam Cohen hSpanInc = Math.min(cellX, hSpanInc); 271d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc); 272bebf042666cffe52039b875a549a582abd78a431Adam Cohen hSpanDelta = -hSpanInc; 273bebf042666cffe52039b875a549a582abd78a431Adam Cohen 274d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mRightBorderActive) { 275bebf042666cffe52039b875a549a582abd78a431Adam Cohen hSpanInc = Math.min(countX - (cellX + spanX), hSpanInc); 276d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc); 277bebf042666cffe52039b875a549a582abd78a431Adam Cohen hSpanDelta = hSpanInc; 278d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 279d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 280d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mTopBorderActive) { 281bebf042666cffe52039b875a549a582abd78a431Adam Cohen cellYInc = Math.max(-cellY, vSpanInc); 282d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen cellYInc = Math.min(lp.cellVSpan - mMinVSpan, cellYInc); 283d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen vSpanInc *= -1; 284bebf042666cffe52039b875a549a582abd78a431Adam Cohen vSpanInc = Math.min(cellY, vSpanInc); 285d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc); 286bebf042666cffe52039b875a549a582abd78a431Adam Cohen vSpanDelta = -vSpanInc; 287d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mBottomBorderActive) { 288bebf042666cffe52039b875a549a582abd78a431Adam Cohen vSpanInc = Math.min(countY - (cellY + spanY), vSpanInc); 289d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc); 290bebf042666cffe52039b875a549a582abd78a431Adam Cohen vSpanDelta = vSpanInc; 291d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 292d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 293bebf042666cffe52039b875a549a582abd78a431Adam Cohen mDirectionVector[0] = 0; 294bebf042666cffe52039b875a549a582abd78a431Adam Cohen mDirectionVector[1] = 0; 295d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen // Update the widget's dimensions and position according to the deltas computed above 296d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mLeftBorderActive || mRightBorderActive) { 297bebf042666cffe52039b875a549a582abd78a431Adam Cohen spanX += hSpanInc; 298bebf042666cffe52039b875a549a582abd78a431Adam Cohen cellX += cellXInc; 299e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen if (hSpanDelta != 0) { 300e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen mDirectionVector[0] = mLeftBorderActive ? -1 : 1; 301e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen } 302d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 303d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 304d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mTopBorderActive || mBottomBorderActive) { 305bebf042666cffe52039b875a549a582abd78a431Adam Cohen spanY += vSpanInc; 306bebf042666cffe52039b875a549a582abd78a431Adam Cohen cellY += cellYInc; 307e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen if (vSpanDelta != 0) { 308e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen mDirectionVector[1] = mTopBorderActive ? -1 : 1; 309e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen } 310d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 311d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 312bebf042666cffe52039b875a549a582abd78a431Adam Cohen if (!onDismiss && vSpanDelta == 0 && hSpanDelta == 0) return; 313bebf042666cffe52039b875a549a582abd78a431Adam Cohen 314e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen // We always want the final commit to match the feedback, so we make sure to use the 315e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen // last used direction vector when committing the resize / reorder. 316e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen if (onDismiss) { 317e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen mDirectionVector[0] = mLastDirectionVector[0]; 318e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen mDirectionVector[1] = mLastDirectionVector[1]; 319e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen } else { 320e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen mLastDirectionVector[0] = mDirectionVector[0]; 321e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen mLastDirectionVector[1] = mDirectionVector[1]; 322e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen } 323e0489500d2a2cf410cb3cb687cbc59e966d7084eAdam Cohen 324bebf042666cffe52039b875a549a582abd78a431Adam Cohen if (mCellLayout.createAreaForResize(cellX, cellY, spanX, spanY, mWidgetView, 325bebf042666cffe52039b875a549a582abd78a431Adam Cohen mDirectionVector, onDismiss)) { 326bebf042666cffe52039b875a549a582abd78a431Adam Cohen lp.tmpCellX = cellX; 327bebf042666cffe52039b875a549a582abd78a431Adam Cohen lp.tmpCellY = cellY; 328bebf042666cffe52039b875a549a582abd78a431Adam Cohen lp.cellHSpan = spanX; 329bebf042666cffe52039b875a549a582abd78a431Adam Cohen lp.cellVSpan = spanY; 330bebf042666cffe52039b875a549a582abd78a431Adam Cohen mRunningVInc += vSpanDelta; 331bebf042666cffe52039b875a549a582abd78a431Adam Cohen mRunningHInc += hSpanDelta; 332a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen if (!onDismiss) { 333a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen updateWidgetSizeRanges(mWidgetView, mLauncher, spanX, spanY); 334a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen } 335bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 3366788269814a678af976dfc7d6135993e172ce586Adam Cohen mWidgetView.requestLayout(); 337d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 338d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 339a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Launcher launcher, 340a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int spanX, int spanY) { 3419e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen 3429e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen getWidgetSizeRanges(launcher, spanX, spanY, mTmpRect); 3439e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen widgetView.updateAppWidgetSize(null, mTmpRect.left, mTmpRect.top, 3449e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen mTmpRect.right, mTmpRect.bottom); 3459e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen } 3469e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen 3479e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen static Rect getWidgetSizeRanges(Launcher launcher, int spanX, int spanY, Rect rect) { 3489e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen if (rect == null) { 3499e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen rect = new Rect(); 3509e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen } 351a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen Rect landMetrics = Workspace.getCellLayoutMetrics(launcher, CellLayout.LANDSCAPE); 352a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen Rect portMetrics = Workspace.getCellLayoutMetrics(launcher, CellLayout.PORTRAIT); 353a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen final float density = launcher.getResources().getDisplayMetrics().density; 354a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen 355a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen // Compute landscape size 356a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int cellWidth = landMetrics.left; 357a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int cellHeight = landMetrics.top; 358a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int widthGap = landMetrics.right; 359a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int heightGap = landMetrics.bottom; 360a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int landWidth = (int) ((spanX * cellWidth + (spanX - 1) * widthGap) / density); 361a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int landHeight = (int) ((spanY * cellHeight + (spanY - 1) * heightGap) / density); 362a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen 363a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen // Compute portrait size 364a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen cellWidth = portMetrics.left; 365a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen cellHeight = portMetrics.top; 366a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen widthGap = portMetrics.right; 367a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen heightGap = portMetrics.bottom; 368a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int portWidth = (int) ((spanX * cellWidth + (spanX - 1) * widthGap) / density); 369a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen int portHeight = (int) ((spanY * cellHeight + (spanY - 1) * heightGap) / density); 3709e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen rect.set(portWidth, landHeight, landWidth, portHeight); 3719e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen return rect; 372a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen } 373a897f397e553826f327d853d5728d0e1d24513a6Adam Cohen 3741b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen /** 3751b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen * This is the final step of the resize. Here we save the new widget size and position 3761b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen * to LauncherModel and animate the resize frame. 3771b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen */ 378bebf042666cffe52039b875a549a582abd78a431Adam Cohen public void commitResize() { 379bebf042666cffe52039b875a549a582abd78a431Adam Cohen resizeWidgetIfNeeded(true); 380bebf042666cffe52039b875a549a582abd78a431Adam Cohen requestLayout(); 381bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 382d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 383bebf042666cffe52039b875a549a582abd78a431Adam Cohen public void onTouchUp() { 384bebf042666cffe52039b875a549a582abd78a431Adam Cohen int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap(); 385bebf042666cffe52039b875a549a582abd78a431Adam Cohen int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap(); 386bebf042666cffe52039b875a549a582abd78a431Adam Cohen 387bebf042666cffe52039b875a549a582abd78a431Adam Cohen mDeltaXAddOn = mRunningHInc * xThreshold; 388bebf042666cffe52039b875a549a582abd78a431Adam Cohen mDeltaYAddOn = mRunningVInc * yThreshold; 389bebf042666cffe52039b875a549a582abd78a431Adam Cohen mDeltaX = 0; 390bebf042666cffe52039b875a549a582abd78a431Adam Cohen mDeltaY = 0; 391d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 392d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen post(new Runnable() { 393bebf042666cffe52039b875a549a582abd78a431Adam Cohen @Override 394d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen public void run() { 395d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen snapToWidget(true); 396d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 397d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen }); 398d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 399d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 400d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen public void snapToWidget(boolean animate) { 4016788269814a678af976dfc7d6135993e172ce586Adam Cohen final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 4026a0393666a75b4cd352ac73a027d9cbcc539f6c2Craig Mautner int xOffset = mCellLayout.getLeft() + mCellLayout.getPaddingLeft() 4036a0393666a75b4cd352ac73a027d9cbcc539f6c2Craig Mautner + mDragLayer.getPaddingLeft() - mWorkspace.getScrollX(); 4046a0393666a75b4cd352ac73a027d9cbcc539f6c2Craig Mautner int yOffset = mCellLayout.getTop() + mCellLayout.getPaddingTop() 4056a0393666a75b4cd352ac73a027d9cbcc539f6c2Craig Mautner + mDragLayer.getPaddingTop() - mWorkspace.getScrollY(); 406d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 40737b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding - mWidgetPaddingLeft - 40837b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen mWidgetPaddingRight; 40937b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen int newHeight = mWidgetView.getHeight() + 2 * mBackgroundPadding - mWidgetPaddingTop - 41037b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen mWidgetPaddingBottom; 41137b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen 41237b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen int newX = mWidgetView.getLeft() - mBackgroundPadding + xOffset + mWidgetPaddingLeft; 41337b59ff9aa601d75392341e45d61bbb5c408439fAdam Cohen int newY = mWidgetView.getTop() - mBackgroundPadding + yOffset + mWidgetPaddingTop; 4143cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen 4154459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen // We need to make sure the frame's touchable regions lie fully within the bounds of the 4164459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen // DragLayer. We allow the actual handles to be clipped, but we shift the touch regions 4174459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen // down accordingly to provide a proper touch target. 4183cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen if (newY < 0) { 4194459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen // In this case we shift the touch region down to start at the top of the DragLayer 4204459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen mTopTouchRegionAdjustment = -newY; 4214459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen } else { 4224459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen mTopTouchRegionAdjustment = 0; 4233cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen } 4246788269814a678af976dfc7d6135993e172ce586Adam Cohen if (newY + newHeight > mDragLayer.getHeight()) { 4254459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen // In this case we shift the touch region up to end at the bottom of the DragLayer 4264459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen mBottomTouchRegionAdjustment = -(newY + newHeight - mDragLayer.getHeight()); 4274459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen } else { 4284459d6b4db75c49f25ac6a43925a8ea212113218Adam Cohen mBottomTouchRegionAdjustment = 0; 4293cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen } 4303cba722d4745b29a47ebc6a472dd921e5c9d7367Adam Cohen 431d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (!animate) { 432d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.width = newWidth; 433d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.height = newHeight; 434d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.x = newX; 435d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen lp.y = newY; 436d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mLeftHandle.setAlpha(1.0f); 437d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mRightHandle.setAlpha(1.0f); 438d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mTopHandle.setAlpha(1.0f); 439d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen mBottomHandle.setAlpha(1.0f); 440d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen requestLayout(); 441d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else { 442d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", lp.width, newWidth); 4431b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", lp.height, 4441b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen newHeight); 445d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", lp.x, newX); 446d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", lp.y, newY); 447f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka ObjectAnimator oa = 448f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka LauncherAnimUtils.ofPropertyValuesHolder(lp, this, width, height, x, y); 4492ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka ObjectAnimator leftOa = LauncherAnimUtils.ofFloat(mLeftHandle, "alpha", 1.0f); 4502ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka ObjectAnimator rightOa = LauncherAnimUtils.ofFloat(mRightHandle, "alpha", 1.0f); 4512ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka ObjectAnimator topOa = LauncherAnimUtils.ofFloat(mTopHandle, "alpha", 1.0f); 4522ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka ObjectAnimator bottomOa = LauncherAnimUtils.ofFloat(mBottomHandle, "alpha", 1.0f); 453d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen oa.addUpdateListener(new AnimatorUpdateListener() { 454d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 455d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen requestLayout(); 456d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 457d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen }); 4582ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka AnimatorSet set = LauncherAnimUtils.createAnimatorSet(); 459d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen if (mResizeMode == AppWidgetProviderInfo.RESIZE_VERTICAL) { 460d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen set.playTogether(oa, topOa, bottomOa); 461d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) { 462d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen set.playTogether(oa, leftOa, rightOa); 463d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } else { 464d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen set.playTogether(oa, leftOa, rightOa, topOa, bottomOa); 465d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 466d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 467d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen set.setDuration(SNAP_DURATION); 468d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen set.start(); 469d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 470d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 471d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen} 472