2013-06-05 22:57:57 -04:00
|
|
|
package com.android.launcher3;
|
2011-02-18 19:25:06 -08:00
|
|
|
|
2015-08-19 17:55:02 -07:00
|
|
|
import com.android.launcher3.dragndrop.DragLayer;
|
|
|
|
|
|
2011-02-18 19:25:06 -08:00
|
|
|
import android.animation.AnimatorSet;
|
|
|
|
|
import android.animation.ObjectAnimator;
|
|
|
|
|
import android.animation.PropertyValuesHolder;
|
|
|
|
|
import android.animation.ValueAnimator;
|
|
|
|
|
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
2011-11-08 15:07:01 -08:00
|
|
|
import android.appwidget.AppWidgetHostView;
|
2011-02-18 19:25:06 -08:00
|
|
|
import android.appwidget.AppWidgetProviderInfo;
|
|
|
|
|
import android.content.Context;
|
2014-03-05 18:07:04 -08:00
|
|
|
import android.content.res.Resources;
|
2015-08-20 12:33:21 -07:00
|
|
|
import android.graphics.Point;
|
2011-11-08 15:07:01 -08:00
|
|
|
import android.graphics.Rect;
|
2011-02-18 19:25:06 -08:00
|
|
|
import android.view.Gravity;
|
|
|
|
|
import android.widget.FrameLayout;
|
|
|
|
|
import android.widget.ImageView;
|
|
|
|
|
|
|
|
|
|
public class AppWidgetResizeFrame extends FrameLayout {
|
2015-05-18 20:52:57 -07:00
|
|
|
private static final int SNAP_DURATION = 150;
|
|
|
|
|
private static final float DIMMED_HANDLE_ALPHA = 0f;
|
|
|
|
|
private static final float RESIZE_THRESHOLD = 0.66f;
|
|
|
|
|
|
2015-08-20 12:33:21 -07:00
|
|
|
private static final Rect sTmpRect = new Rect();
|
|
|
|
|
|
|
|
|
|
// Represents the cell size on the grid in the two orientations.
|
|
|
|
|
private static Point[] sCellSize;
|
2015-05-18 20:52:57 -07:00
|
|
|
|
|
|
|
|
private final Launcher mLauncher;
|
|
|
|
|
private final LauncherAppWidgetHostView mWidgetView;
|
|
|
|
|
private final CellLayout mCellLayout;
|
|
|
|
|
private final DragLayer mDragLayer;
|
|
|
|
|
|
|
|
|
|
private final ImageView mLeftHandle;
|
|
|
|
|
private final ImageView mRightHandle;
|
|
|
|
|
private final ImageView mTopHandle;
|
|
|
|
|
private final ImageView mBottomHandle;
|
|
|
|
|
|
|
|
|
|
private final Rect mWidgetPadding;
|
|
|
|
|
|
|
|
|
|
private final int mBackgroundPadding;
|
|
|
|
|
private final int mTouchTargetWidth;
|
|
|
|
|
|
|
|
|
|
private final int[] mDirectionVector = new int[2];
|
|
|
|
|
private final int[] mLastDirectionVector = new int[2];
|
|
|
|
|
private final int[] mTmpPt = new int[2];
|
2011-02-18 19:25:06 -08:00
|
|
|
|
|
|
|
|
private boolean mLeftBorderActive;
|
|
|
|
|
private boolean mRightBorderActive;
|
|
|
|
|
private boolean mTopBorderActive;
|
|
|
|
|
private boolean mBottomBorderActive;
|
|
|
|
|
|
|
|
|
|
private int mBaselineWidth;
|
|
|
|
|
private int mBaselineHeight;
|
|
|
|
|
private int mBaselineX;
|
|
|
|
|
private int mBaselineY;
|
|
|
|
|
private int mResizeMode;
|
2011-03-02 19:03:11 -08:00
|
|
|
|
2011-02-18 19:25:06 -08:00
|
|
|
private int mRunningHInc;
|
|
|
|
|
private int mRunningVInc;
|
|
|
|
|
private int mMinHSpan;
|
|
|
|
|
private int mMinVSpan;
|
|
|
|
|
private int mDeltaX;
|
|
|
|
|
private int mDeltaY;
|
2012-04-11 18:06:28 -07:00
|
|
|
private int mDeltaXAddOn;
|
|
|
|
|
private int mDeltaYAddOn;
|
2011-03-03 17:26:50 -08:00
|
|
|
|
2012-07-13 15:59:15 -07:00
|
|
|
private int mTopTouchRegionAdjustment = 0;
|
|
|
|
|
private int mBottomTouchRegionAdjustment = 0;
|
|
|
|
|
|
2012-04-13 14:44:29 -07:00
|
|
|
public AppWidgetResizeFrame(Context context,
|
2011-03-11 15:29:03 -08:00
|
|
|
LauncherAppWidgetHostView widgetView, CellLayout cellLayout, DragLayer dragLayer) {
|
2011-02-18 19:25:06 -08:00
|
|
|
|
|
|
|
|
super(context);
|
2011-09-16 17:32:37 -07:00
|
|
|
mLauncher = (Launcher) context;
|
2011-02-18 19:25:06 -08:00
|
|
|
mCellLayout = cellLayout;
|
|
|
|
|
mWidgetView = widgetView;
|
2014-03-05 18:07:04 -08:00
|
|
|
LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo)
|
|
|
|
|
widgetView.getAppWidgetInfo();
|
|
|
|
|
mResizeMode = info.resizeMode;
|
2011-03-11 15:29:03 -08:00
|
|
|
mDragLayer = dragLayer;
|
2011-03-02 19:03:11 -08:00
|
|
|
|
2015-08-03 13:05:01 -07:00
|
|
|
mMinHSpan = info.minSpanX;
|
|
|
|
|
mMinVSpan = info.minSpanY;
|
2011-02-18 19:25:06 -08:00
|
|
|
|
2015-05-18 20:52:57 -07:00
|
|
|
setBackgroundResource(R.drawable.widget_resize_shadow);
|
|
|
|
|
setForeground(getResources().getDrawable(R.drawable.widget_resize_frame));
|
2011-02-18 19:25:06 -08:00
|
|
|
setPadding(0, 0, 0, 0);
|
|
|
|
|
|
2015-05-18 20:52:57 -07:00
|
|
|
final int handleMargin = getResources().getDimensionPixelSize(R.dimen.widget_handle_margin);
|
2011-02-18 19:25:06 -08:00
|
|
|
LayoutParams lp;
|
|
|
|
|
mLeftHandle = new ImageView(context);
|
2015-05-18 20:52:57 -07:00
|
|
|
mLeftHandle.setImageResource(R.drawable.ic_widget_resize_handle);
|
|
|
|
|
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
|
2013-09-26 16:35:40 -07:00
|
|
|
Gravity.LEFT | Gravity.CENTER_VERTICAL);
|
2015-05-18 20:52:57 -07:00
|
|
|
lp.leftMargin = handleMargin;
|
2011-02-18 19:25:06 -08:00
|
|
|
addView(mLeftHandle, lp);
|
|
|
|
|
|
|
|
|
|
mRightHandle = new ImageView(context);
|
2015-05-18 20:52:57 -07:00
|
|
|
mRightHandle.setImageResource(R.drawable.ic_widget_resize_handle);
|
|
|
|
|
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
|
2013-09-26 16:35:40 -07:00
|
|
|
Gravity.RIGHT | Gravity.CENTER_VERTICAL);
|
2015-05-18 20:52:57 -07:00
|
|
|
lp.rightMargin = handleMargin;
|
2011-02-18 19:25:06 -08:00
|
|
|
addView(mRightHandle, lp);
|
|
|
|
|
|
|
|
|
|
mTopHandle = new ImageView(context);
|
2015-05-18 20:52:57 -07:00
|
|
|
mTopHandle.setImageResource(R.drawable.ic_widget_resize_handle);
|
|
|
|
|
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
|
2011-02-18 19:25:06 -08:00
|
|
|
Gravity.CENTER_HORIZONTAL | Gravity.TOP);
|
2015-05-18 20:52:57 -07:00
|
|
|
lp.topMargin = handleMargin;
|
2011-02-18 19:25:06 -08:00
|
|
|
addView(mTopHandle, lp);
|
|
|
|
|
|
|
|
|
|
mBottomHandle = new ImageView(context);
|
2015-05-18 20:52:57 -07:00
|
|
|
mBottomHandle.setImageResource(R.drawable.ic_widget_resize_handle);
|
|
|
|
|
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
|
2011-02-18 19:25:06 -08:00
|
|
|
Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
|
2015-05-18 20:52:57 -07:00
|
|
|
lp.bottomMargin = handleMargin;
|
2011-02-18 19:25:06 -08:00
|
|
|
addView(mBottomHandle, lp);
|
|
|
|
|
|
2014-03-05 18:07:04 -08:00
|
|
|
if (!info.isCustomWidget) {
|
2015-05-18 20:52:57 -07:00
|
|
|
mWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context,
|
2014-03-05 18:07:04 -08:00
|
|
|
widgetView.getAppWidgetInfo().provider, null);
|
|
|
|
|
} else {
|
|
|
|
|
Resources r = context.getResources();
|
|
|
|
|
int padding = r.getDimensionPixelSize(R.dimen.default_widget_padding);
|
2015-05-18 20:52:57 -07:00
|
|
|
mWidgetPadding = new Rect(padding, padding, padding, padding);
|
2014-03-05 18:07:04 -08:00
|
|
|
}
|
|
|
|
|
|
2011-02-18 19:25:06 -08:00
|
|
|
if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) {
|
|
|
|
|
mTopHandle.setVisibility(GONE);
|
|
|
|
|
mBottomHandle.setVisibility(GONE);
|
|
|
|
|
} else if (mResizeMode == AppWidgetProviderInfo.RESIZE_VERTICAL) {
|
|
|
|
|
mLeftHandle.setVisibility(GONE);
|
|
|
|
|
mRightHandle.setVisibility(GONE);
|
2011-03-02 19:03:11 -08:00
|
|
|
}
|
|
|
|
|
|
2015-05-18 20:52:57 -07:00
|
|
|
mBackgroundPadding = getResources()
|
|
|
|
|
.getDimensionPixelSize(R.dimen.resize_frame_background_padding);
|
2011-03-02 19:03:11 -08:00
|
|
|
mTouchTargetWidth = 2 * mBackgroundPadding;
|
2012-04-11 18:06:28 -07:00
|
|
|
|
|
|
|
|
// When we create the resize frame, we first mark all cells as unoccupied. The appropriate
|
|
|
|
|
// cells (same if not resized, or different) will be marked as occupied when the resize
|
|
|
|
|
// frame is dismissed.
|
|
|
|
|
mCellLayout.markCellsAsUnoccupiedForView(mWidgetView);
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean beginResizeIfPointInRegion(int x, int y) {
|
|
|
|
|
boolean horizontalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0;
|
|
|
|
|
boolean verticalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0;
|
2012-07-13 15:59:15 -07:00
|
|
|
|
2011-03-02 19:03:11 -08:00
|
|
|
mLeftBorderActive = (x < mTouchTargetWidth) && horizontalActive;
|
|
|
|
|
mRightBorderActive = (x > getWidth() - mTouchTargetWidth) && horizontalActive;
|
2012-07-13 15:59:15 -07:00
|
|
|
mTopBorderActive = (y < mTouchTargetWidth + mTopTouchRegionAdjustment) && verticalActive;
|
|
|
|
|
mBottomBorderActive = (y > getHeight() - mTouchTargetWidth + mBottomTouchRegionAdjustment)
|
|
|
|
|
&& verticalActive;
|
2011-02-18 19:25:06 -08:00
|
|
|
|
|
|
|
|
boolean anyBordersActive = mLeftBorderActive || mRightBorderActive
|
|
|
|
|
|| mTopBorderActive || mBottomBorderActive;
|
|
|
|
|
|
|
|
|
|
mBaselineWidth = getMeasuredWidth();
|
|
|
|
|
mBaselineHeight = getMeasuredHeight();
|
|
|
|
|
mBaselineX = getLeft();
|
|
|
|
|
mBaselineY = getTop();
|
|
|
|
|
|
|
|
|
|
if (anyBordersActive) {
|
2011-03-02 19:03:11 -08:00
|
|
|
mLeftHandle.setAlpha(mLeftBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA);
|
|
|
|
|
mRightHandle.setAlpha(mRightBorderActive ? 1.0f :DIMMED_HANDLE_ALPHA);
|
|
|
|
|
mTopHandle.setAlpha(mTopBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA);
|
|
|
|
|
mBottomHandle.setAlpha(mBottomBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA);
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
return anyBordersActive;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 17:26:50 -08:00
|
|
|
/**
|
|
|
|
|
* Here we bound the deltas such that the frame cannot be stretched beyond the extents
|
|
|
|
|
* of the CellLayout, and such that the frame's borders can't cross.
|
|
|
|
|
*/
|
2011-02-18 19:25:06 -08:00
|
|
|
public void updateDeltas(int deltaX, int deltaY) {
|
|
|
|
|
if (mLeftBorderActive) {
|
|
|
|
|
mDeltaX = Math.max(-mBaselineX, deltaX);
|
2011-03-02 19:03:11 -08:00
|
|
|
mDeltaX = Math.min(mBaselineWidth - 2 * mTouchTargetWidth, mDeltaX);
|
2011-02-18 19:25:06 -08:00
|
|
|
} else if (mRightBorderActive) {
|
2011-03-11 15:29:03 -08:00
|
|
|
mDeltaX = Math.min(mDragLayer.getWidth() - (mBaselineX + mBaselineWidth), deltaX);
|
2011-03-02 19:03:11 -08:00
|
|
|
mDeltaX = Math.max(-mBaselineWidth + 2 * mTouchTargetWidth, mDeltaX);
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mTopBorderActive) {
|
|
|
|
|
mDeltaY = Math.max(-mBaselineY, deltaY);
|
2011-03-02 19:03:11 -08:00
|
|
|
mDeltaY = Math.min(mBaselineHeight - 2 * mTouchTargetWidth, mDeltaY);
|
2011-02-18 19:25:06 -08:00
|
|
|
} else if (mBottomBorderActive) {
|
2011-03-11 15:29:03 -08:00
|
|
|
mDeltaY = Math.min(mDragLayer.getHeight() - (mBaselineY + mBaselineHeight), deltaY);
|
2011-03-02 19:03:11 -08:00
|
|
|
mDeltaY = Math.max(-mBaselineHeight + 2 * mTouchTargetWidth, mDeltaY);
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
public void visualizeResizeForDelta(int deltaX, int deltaY) {
|
|
|
|
|
visualizeResizeForDelta(deltaX, deltaY, false);
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 17:26:50 -08:00
|
|
|
/**
|
|
|
|
|
* Based on the deltas, we resize the frame, and, if needed, we resize the widget.
|
|
|
|
|
*/
|
2012-04-11 18:06:28 -07:00
|
|
|
private void visualizeResizeForDelta(int deltaX, int deltaY, boolean onDismiss) {
|
2011-02-18 19:25:06 -08:00
|
|
|
updateDeltas(deltaX, deltaY);
|
2011-03-11 15:29:03 -08:00
|
|
|
DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
|
|
|
|
|
|
2011-02-18 19:25:06 -08:00
|
|
|
if (mLeftBorderActive) {
|
|
|
|
|
lp.x = mBaselineX + mDeltaX;
|
|
|
|
|
lp.width = mBaselineWidth - mDeltaX;
|
|
|
|
|
} else if (mRightBorderActive) {
|
|
|
|
|
lp.width = mBaselineWidth + mDeltaX;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mTopBorderActive) {
|
|
|
|
|
lp.y = mBaselineY + mDeltaY;
|
|
|
|
|
lp.height = mBaselineHeight - mDeltaY;
|
|
|
|
|
} else if (mBottomBorderActive) {
|
|
|
|
|
lp.height = mBaselineHeight + mDeltaY;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
resizeWidgetIfNeeded(onDismiss);
|
2011-02-18 19:25:06 -08:00
|
|
|
requestLayout();
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 17:26:50 -08:00
|
|
|
/**
|
|
|
|
|
* Based on the current deltas, we determine if and how to resize the widget.
|
|
|
|
|
*/
|
2012-04-11 18:06:28 -07:00
|
|
|
private void resizeWidgetIfNeeded(boolean onDismiss) {
|
2011-02-18 19:25:06 -08:00
|
|
|
int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
|
|
|
|
|
int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
int deltaX = mDeltaX + mDeltaXAddOn;
|
|
|
|
|
int deltaY = mDeltaY + mDeltaYAddOn;
|
|
|
|
|
|
|
|
|
|
float hSpanIncF = 1.0f * deltaX / xThreshold - mRunningHInc;
|
|
|
|
|
float vSpanIncF = 1.0f * deltaY / yThreshold - mRunningVInc;
|
2011-03-08 18:35:52 -08:00
|
|
|
|
|
|
|
|
int hSpanInc = 0;
|
|
|
|
|
int vSpanInc = 0;
|
2011-02-18 19:25:06 -08:00
|
|
|
int cellXInc = 0;
|
|
|
|
|
int cellYInc = 0;
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
int countX = mCellLayout.getCountX();
|
|
|
|
|
int countY = mCellLayout.getCountY();
|
|
|
|
|
|
2011-03-08 18:35:52 -08:00
|
|
|
if (Math.abs(hSpanIncF) > RESIZE_THRESHOLD) {
|
|
|
|
|
hSpanInc = Math.round(hSpanIncF);
|
|
|
|
|
}
|
|
|
|
|
if (Math.abs(vSpanIncF) > RESIZE_THRESHOLD) {
|
|
|
|
|
vSpanInc = Math.round(vSpanIncF);
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
if (!onDismiss && (hSpanInc == 0 && vSpanInc == 0)) return;
|
2011-02-18 19:25:06 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams();
|
2011-03-03 17:26:50 -08:00
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
int spanX = lp.cellHSpan;
|
|
|
|
|
int spanY = lp.cellVSpan;
|
|
|
|
|
int cellX = lp.useTmpCoords ? lp.tmpCellX : lp.cellX;
|
|
|
|
|
int cellY = lp.useTmpCoords ? lp.tmpCellY : lp.cellY;
|
|
|
|
|
|
|
|
|
|
int hSpanDelta = 0;
|
|
|
|
|
int vSpanDelta = 0;
|
|
|
|
|
|
2011-03-03 17:26:50 -08:00
|
|
|
// For each border, we bound the resizing based on the minimum width, and the maximum
|
|
|
|
|
// expandability.
|
2011-02-18 19:25:06 -08:00
|
|
|
if (mLeftBorderActive) {
|
2012-04-11 18:06:28 -07:00
|
|
|
cellXInc = Math.max(-cellX, hSpanInc);
|
2011-02-18 19:25:06 -08:00
|
|
|
cellXInc = Math.min(lp.cellHSpan - mMinHSpan, cellXInc);
|
|
|
|
|
hSpanInc *= -1;
|
2012-04-11 18:06:28 -07:00
|
|
|
hSpanInc = Math.min(cellX, hSpanInc);
|
2011-02-18 19:25:06 -08:00
|
|
|
hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
|
2012-04-11 18:06:28 -07:00
|
|
|
hSpanDelta = -hSpanInc;
|
|
|
|
|
|
2011-02-18 19:25:06 -08:00
|
|
|
} else if (mRightBorderActive) {
|
2012-04-11 18:06:28 -07:00
|
|
|
hSpanInc = Math.min(countX - (cellX + spanX), hSpanInc);
|
2011-02-18 19:25:06 -08:00
|
|
|
hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
|
2012-04-11 18:06:28 -07:00
|
|
|
hSpanDelta = hSpanInc;
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mTopBorderActive) {
|
2012-04-11 18:06:28 -07:00
|
|
|
cellYInc = Math.max(-cellY, vSpanInc);
|
2011-02-18 19:25:06 -08:00
|
|
|
cellYInc = Math.min(lp.cellVSpan - mMinVSpan, cellYInc);
|
|
|
|
|
vSpanInc *= -1;
|
2012-04-11 18:06:28 -07:00
|
|
|
vSpanInc = Math.min(cellY, vSpanInc);
|
2011-02-18 19:25:06 -08:00
|
|
|
vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
|
2012-04-11 18:06:28 -07:00
|
|
|
vSpanDelta = -vSpanInc;
|
2011-02-18 19:25:06 -08:00
|
|
|
} else if (mBottomBorderActive) {
|
2012-04-11 18:06:28 -07:00
|
|
|
vSpanInc = Math.min(countY - (cellY + spanY), vSpanInc);
|
2011-02-18 19:25:06 -08:00
|
|
|
vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
|
2012-04-11 18:06:28 -07:00
|
|
|
vSpanDelta = vSpanInc;
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
mDirectionVector[0] = 0;
|
|
|
|
|
mDirectionVector[1] = 0;
|
2011-02-18 19:25:06 -08:00
|
|
|
// Update the widget's dimensions and position according to the deltas computed above
|
|
|
|
|
if (mLeftBorderActive || mRightBorderActive) {
|
2012-04-11 18:06:28 -07:00
|
|
|
spanX += hSpanInc;
|
|
|
|
|
cellX += cellXInc;
|
2012-08-27 15:18:53 -07:00
|
|
|
if (hSpanDelta != 0) {
|
|
|
|
|
mDirectionVector[0] = mLeftBorderActive ? -1 : 1;
|
|
|
|
|
}
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mTopBorderActive || mBottomBorderActive) {
|
2012-04-11 18:06:28 -07:00
|
|
|
spanY += vSpanInc;
|
|
|
|
|
cellY += cellYInc;
|
2012-08-27 15:18:53 -07:00
|
|
|
if (vSpanDelta != 0) {
|
|
|
|
|
mDirectionVector[1] = mTopBorderActive ? -1 : 1;
|
|
|
|
|
}
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
if (!onDismiss && vSpanDelta == 0 && hSpanDelta == 0) return;
|
|
|
|
|
|
2012-08-27 15:18:53 -07:00
|
|
|
// We always want the final commit to match the feedback, so we make sure to use the
|
|
|
|
|
// last used direction vector when committing the resize / reorder.
|
|
|
|
|
if (onDismiss) {
|
|
|
|
|
mDirectionVector[0] = mLastDirectionVector[0];
|
|
|
|
|
mDirectionVector[1] = mLastDirectionVector[1];
|
|
|
|
|
} else {
|
|
|
|
|
mLastDirectionVector[0] = mDirectionVector[0];
|
|
|
|
|
mLastDirectionVector[1] = mDirectionVector[1];
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
if (mCellLayout.createAreaForResize(cellX, cellY, spanX, spanY, mWidgetView,
|
|
|
|
|
mDirectionVector, onDismiss)) {
|
|
|
|
|
lp.tmpCellX = cellX;
|
|
|
|
|
lp.tmpCellY = cellY;
|
|
|
|
|
lp.cellHSpan = spanX;
|
|
|
|
|
lp.cellVSpan = spanY;
|
|
|
|
|
mRunningVInc += vSpanDelta;
|
|
|
|
|
mRunningHInc += hSpanDelta;
|
2012-04-27 18:12:05 -07:00
|
|
|
if (!onDismiss) {
|
|
|
|
|
updateWidgetSizeRanges(mWidgetView, mLauncher, spanX, spanY);
|
|
|
|
|
}
|
2012-04-11 18:06:28 -07:00
|
|
|
}
|
2011-03-11 15:29:03 -08:00
|
|
|
mWidgetView.requestLayout();
|
2011-02-18 19:25:06 -08:00
|
|
|
}
|
|
|
|
|
|
2012-04-27 18:12:05 -07:00
|
|
|
static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Launcher launcher,
|
|
|
|
|
int spanX, int spanY) {
|
2015-05-18 20:52:57 -07:00
|
|
|
getWidgetSizeRanges(launcher, spanX, spanY, sTmpRect);
|
|
|
|
|
widgetView.updateAppWidgetSize(null, sTmpRect.left, sTmpRect.top,
|
|
|
|
|
sTmpRect.right, sTmpRect.bottom);
|
2012-09-10 15:53:09 -07:00
|
|
|
}
|
|
|
|
|
|
2015-04-23 15:17:50 -07:00
|
|
|
public static Rect getWidgetSizeRanges(Launcher launcher, int spanX, int spanY, Rect rect) {
|
2015-08-20 12:33:21 -07:00
|
|
|
if (sCellSize == null) {
|
|
|
|
|
InvariantDeviceProfile inv = LauncherAppState.getInstance().getInvariantDeviceProfile();
|
|
|
|
|
|
|
|
|
|
// Initiate cell sizes.
|
|
|
|
|
sCellSize = new Point[2];
|
|
|
|
|
sCellSize[0] = inv.landscapeProfile.getCellSize();
|
|
|
|
|
sCellSize[1] = inv.portraitProfile.getCellSize();
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-10 15:53:09 -07:00
|
|
|
if (rect == null) {
|
|
|
|
|
rect = new Rect();
|
|
|
|
|
}
|
2012-04-27 18:12:05 -07:00
|
|
|
final float density = launcher.getResources().getDisplayMetrics().density;
|
|
|
|
|
|
|
|
|
|
// Compute landscape size
|
2015-08-20 12:33:21 -07:00
|
|
|
int landWidth = (int) ((spanX * sCellSize[0].x) / density);
|
|
|
|
|
int landHeight = (int) ((spanY * sCellSize[0].y) / density);
|
2012-04-27 18:12:05 -07:00
|
|
|
|
|
|
|
|
// Compute portrait size
|
2015-08-20 12:33:21 -07:00
|
|
|
int portWidth = (int) ((spanX * sCellSize[1].x) / density);
|
|
|
|
|
int portHeight = (int) ((spanY * sCellSize[1].y) / density);
|
2012-09-10 15:53:09 -07:00
|
|
|
rect.set(portWidth, landHeight, landWidth, portHeight);
|
|
|
|
|
return rect;
|
2012-04-27 18:12:05 -07:00
|
|
|
}
|
|
|
|
|
|
2011-03-03 17:26:50 -08:00
|
|
|
/**
|
|
|
|
|
* This is the final step of the resize. Here we save the new widget size and position
|
|
|
|
|
* to LauncherModel and animate the resize frame.
|
|
|
|
|
*/
|
2012-04-11 18:06:28 -07:00
|
|
|
public void commitResize() {
|
|
|
|
|
resizeWidgetIfNeeded(true);
|
|
|
|
|
requestLayout();
|
|
|
|
|
}
|
2011-02-18 19:25:06 -08:00
|
|
|
|
2012-04-11 18:06:28 -07:00
|
|
|
public void onTouchUp() {
|
|
|
|
|
int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
|
|
|
|
|
int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();
|
|
|
|
|
|
|
|
|
|
mDeltaXAddOn = mRunningHInc * xThreshold;
|
|
|
|
|
mDeltaYAddOn = mRunningVInc * yThreshold;
|
|
|
|
|
mDeltaX = 0;
|
|
|
|
|
mDeltaY = 0;
|
2011-02-18 19:25:06 -08:00
|
|
|
|
|
|
|
|
post(new Runnable() {
|
2012-04-11 18:06:28 -07:00
|
|
|
@Override
|
2011-02-18 19:25:06 -08:00
|
|
|
public void run() {
|
|
|
|
|
snapToWidget(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void snapToWidget(boolean animate) {
|
2011-03-11 15:29:03 -08:00
|
|
|
final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
|
2015-05-18 20:52:57 -07:00
|
|
|
int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding
|
|
|
|
|
- mWidgetPadding.left - mWidgetPadding.right;
|
|
|
|
|
int newHeight = mWidgetView.getHeight() + 2 * mBackgroundPadding
|
|
|
|
|
- mWidgetPadding.top - mWidgetPadding.bottom;
|
2011-06-13 17:13:42 -07:00
|
|
|
|
2013-07-09 15:32:37 -07:00
|
|
|
mTmpPt[0] = mWidgetView.getLeft();
|
|
|
|
|
mTmpPt[1] = mWidgetView.getTop();
|
|
|
|
|
mDragLayer.getDescendantCoordRelativeToSelf(mCellLayout.getShortcutsAndWidgets(), mTmpPt);
|
|
|
|
|
|
2015-05-18 20:52:57 -07:00
|
|
|
int newX = mTmpPt[0] - mBackgroundPadding + mWidgetPadding.left;
|
|
|
|
|
int newY = mTmpPt[1] - mBackgroundPadding + mWidgetPadding.top;
|
2011-03-02 19:03:11 -08:00
|
|
|
|
2015-05-18 20:52:57 -07:00
|
|
|
// We need to make sure the frame's touchable regions lie fully within the bounds of the
|
2012-07-13 15:59:15 -07:00
|
|
|
// DragLayer. We allow the actual handles to be clipped, but we shift the touch regions
|
|
|
|
|
// down accordingly to provide a proper touch target.
|
2011-03-02 19:03:11 -08:00
|
|
|
if (newY < 0) {
|
2012-07-13 15:59:15 -07:00
|
|
|
// In this case we shift the touch region down to start at the top of the DragLayer
|
|
|
|
|
mTopTouchRegionAdjustment = -newY;
|
|
|
|
|
} else {
|
|
|
|
|
mTopTouchRegionAdjustment = 0;
|
2011-03-02 19:03:11 -08:00
|
|
|
}
|
2011-03-11 15:29:03 -08:00
|
|
|
if (newY + newHeight > mDragLayer.getHeight()) {
|
2012-07-13 15:59:15 -07:00
|
|
|
// In this case we shift the touch region up to end at the bottom of the DragLayer
|
|
|
|
|
mBottomTouchRegionAdjustment = -(newY + newHeight - mDragLayer.getHeight());
|
|
|
|
|
} else {
|
|
|
|
|
mBottomTouchRegionAdjustment = 0;
|
2011-03-02 19:03:11 -08:00
|
|
|
}
|
|
|
|
|
|
2011-02-18 19:25:06 -08:00
|
|
|
if (!animate) {
|
|
|
|
|
lp.width = newWidth;
|
|
|
|
|
lp.height = newHeight;
|
|
|
|
|
lp.x = newX;
|
|
|
|
|
lp.y = newY;
|
|
|
|
|
mLeftHandle.setAlpha(1.0f);
|
|
|
|
|
mRightHandle.setAlpha(1.0f);
|
|
|
|
|
mTopHandle.setAlpha(1.0f);
|
|
|
|
|
mBottomHandle.setAlpha(1.0f);
|
|
|
|
|
requestLayout();
|
|
|
|
|
} else {
|
|
|
|
|
PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", lp.width, newWidth);
|
2011-03-03 17:26:50 -08:00
|
|
|
PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", lp.height,
|
|
|
|
|
newHeight);
|
2011-02-18 19:25:06 -08:00
|
|
|
PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", lp.x, newX);
|
|
|
|
|
PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", lp.y, newY);
|
2013-03-13 12:55:46 +01:00
|
|
|
ObjectAnimator oa =
|
|
|
|
|
LauncherAnimUtils.ofPropertyValuesHolder(lp, this, width, height, x, y);
|
2015-07-06 22:52:49 -07:00
|
|
|
ObjectAnimator leftOa = LauncherAnimUtils.ofFloat(mLeftHandle, ALPHA, 1.0f);
|
|
|
|
|
ObjectAnimator rightOa = LauncherAnimUtils.ofFloat(mRightHandle, ALPHA, 1.0f);
|
|
|
|
|
ObjectAnimator topOa = LauncherAnimUtils.ofFloat(mTopHandle, ALPHA, 1.0f);
|
|
|
|
|
ObjectAnimator bottomOa = LauncherAnimUtils.ofFloat(mBottomHandle, ALPHA, 1.0f);
|
2011-02-18 19:25:06 -08:00
|
|
|
oa.addUpdateListener(new AnimatorUpdateListener() {
|
|
|
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
|
|
|
requestLayout();
|
|
|
|
|
}
|
|
|
|
|
});
|
2012-06-18 12:52:28 -07:00
|
|
|
AnimatorSet set = LauncherAnimUtils.createAnimatorSet();
|
2011-02-18 19:25:06 -08:00
|
|
|
if (mResizeMode == AppWidgetProviderInfo.RESIZE_VERTICAL) {
|
|
|
|
|
set.playTogether(oa, topOa, bottomOa);
|
|
|
|
|
} else if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) {
|
|
|
|
|
set.playTogether(oa, leftOa, rightOa);
|
|
|
|
|
} else {
|
|
|
|
|
set.playTogether(oa, leftOa, rightOa, topOa, bottomOa);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set.setDuration(SNAP_DURATION);
|
|
|
|
|
set.start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|