Merge "Defining various modes for CellLayout: Workspace, Hotseat & Folder" into ub-launcher3-master

This commit is contained in:
Sunny Goyal
2016-12-12 20:45:17 +00:00
committed by Android (Google) Code Review
13 changed files with 114 additions and 91 deletions
+45 -39
View File
@@ -24,6 +24,7 @@ import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -35,6 +36,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Parcelable;
import android.support.annotation.IntDef;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
@@ -60,6 +62,8 @@ import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.ParcelableSparseArray;
import com.android.launcher3.util.Thunk;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -145,8 +149,16 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
private TimeInterpolator mEaseOutInterpolator;
private ShortcutAndWidgetContainer mShortcutsAndWidgets;
private boolean mIsHotseat = false;
private float mHotseatScale = 1f;
@Retention(RetentionPolicy.SOURCE)
@IntDef({WORKSPACE, HOTSEAT, FOLDER})
public @interface ContainerType{}
public static final int WORKSPACE = 0;
public static final int HOTSEAT = 1;
public static final int FOLDER = 2;
@ContainerType private final int mContainerType;
private final float mChildScale;
public static final int MODE_SHOW_REORDER_HINT = 0;
public static final int MODE_DRAG_OVER = 1;
@@ -158,7 +170,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
private static final float REORDER_PREVIEW_MAGNITUDE = 0.12f;
private static final int REORDER_ANIMATION_DURATION = 150;
@Thunk float mReorderPreviewAnimationMagnitude;
@Thunk final float mReorderPreviewAnimationMagnitude;
private ArrayList<View> mIntersectingViews = new ArrayList<View>();
private Rect mOccupiedRect = new Rect();
@@ -184,6 +196,9 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
public CellLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
mContainerType = a.getInteger(R.styleable.CellLayout_containerType, WORKSPACE);
a.recycle();
// A ViewGroup usually does not draw, but CellLayout needs to draw a rectangle to show
// the user where a dragged item will land when dropped.
@@ -207,9 +222,10 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
mFolderLeaveBehind.delegateCellX = -1;
mFolderLeaveBehind.delegateCellY = -1;
mChildScale = mContainerType == HOTSEAT ? grid.inv.hotseatScale : 1f;
setAlwaysDrawnWithCacheEnabled(false);
final Resources res = getResources();
mHotseatScale = (float) grid.hotseatIconSizePx / grid.iconSizePx;
mBackground = (TransitionDrawable) res.getDrawable(
FeatureFlags.LAUNCHER3_LEGACY_WORKSPACE_DND ? R.drawable.bg_screenpanel
@@ -217,8 +233,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
mBackground.setCallback(this);
mBackground.setAlpha((int) (mBackgroundAlpha * 255));
mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE *
grid.iconSizePx);
mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * grid.iconSizePx);
// Initialize the data structures used for the drag visualization.
mEaseOutInterpolator = new DecelerateInterpolator(2.5f); // Quint ease out
@@ -276,7 +291,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
mDragOutlineAnims[i] = anim;
}
mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context);
mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context, mContainerType);
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
@@ -355,10 +370,6 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
mShortcutsAndWidgets.buildLayer();
}
public float getChildrenScale() {
return mIsHotseat ? mHotseatScale : 1.0f;
}
public void setCellDimensions(int width, int height) {
mFixedCellWidth = mCellWidth = width;
mFixedCellHeight = mCellHeight = height;
@@ -603,15 +614,8 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
return mCountY;
}
public void setIsHotseat(boolean isHotseat) {
mIsHotseat = isHotseat;
mShortcutsAndWidgets.setContainerType(isHotseat
? ShortcutAndWidgetContainer.HOTSEAT
: ShortcutAndWidgetContainer.DEFAULT);
}
public boolean isHotseat() {
return mIsHotseat;
public boolean acceptsWidget() {
return mContainerType == WORKSPACE;
}
public boolean addViewToCellLayout(View child, int index, int childId, LayoutParams params,
@@ -621,11 +625,11 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
// Hotseat icons - remove text
if (child instanceof BubbleTextView) {
BubbleTextView bubbleChild = (BubbleTextView) child;
bubbleChild.setTextVisibility(!mIsHotseat);
bubbleChild.setTextVisibility(mContainerType != HOTSEAT);
}
child.setScaleX(getChildrenScale());
child.setScaleY(getChildrenScale());
child.setScaleX(mChildScale);
child.setScaleY(mChildScale);
// Generate an id for each view, this assumes we have at most 256x256 cells
// per workspace screen
@@ -1061,24 +1065,26 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
r.set(left, top, left + dragOutline.getWidth(), top + dragOutline.getHeight());
}
Utilities.scaleRectAboutCenter(r, getChildrenScale());
Utilities.scaleRectAboutCenter(r, mChildScale);
mDragOutlineAnims[mDragOutlineCurrent].setTag(dragOutline);
mDragOutlineAnims[mDragOutlineCurrent].animateIn();
if (dragObject.stateAnnouncer != null) {
String msg;
if (isHotseat()) {
msg = getContext().getString(R.string.move_to_hotseat_position,
Math.max(cellX, cellY) + 1);
} else {
msg = getContext().getString(R.string.move_to_empty_cell,
cellY + 1, cellX + 1);
}
dragObject.stateAnnouncer.announce(msg);
dragObject.stateAnnouncer.announce(getItemMoveDescription(cellX, cellY));
}
}
}
public String getItemMoveDescription(int cellX, int cellY) {
if (mContainerType == HOTSEAT) {
return getContext().getString(R.string.move_to_hotseat_position,
Math.max(cellX, cellY) + 1);
} else {
return getContext().getString(R.string.move_to_empty_cell,
cellY + 1, cellX + 1);
}
}
public void clearDragOutlines() {
final int oldIndex = mDragOutlineCurrent;
mDragOutlineAnims[oldIndex].animateOut();
@@ -2011,7 +2017,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
this.mode = mode;
initDeltaX = child.getTranslationX();
initDeltaY = child.getTranslationY();
finalScale = getChildrenScale() - 4.0f / child.getWidth();
finalScale = mChildScale - 4.0f / child.getWidth();
initScale = child.getScaleX();
this.child = child;
}
@@ -2061,7 +2067,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
// We make sure to end only after a full period
initDeltaX = 0;
initDeltaY = 0;
initScale = getChildrenScale();
initScale = mChildScale;
repeating = true;
}
});
@@ -2081,8 +2087,8 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
}
a = new LauncherViewPropertyAnimator(child)
.scaleX(getChildrenScale())
.scaleY(getChildrenScale())
.scaleX(mChildScale)
.scaleY(mChildScale)
.translationX(0)
.translationY(0)
.setDuration(REORDER_ANIMATION_DURATION);
@@ -2104,7 +2110,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
long screenId = mLauncher.getWorkspace().getIdForScreen(this);
int container = Favorites.CONTAINER_DESKTOP;
if (mLauncher.isHotseatLayout(this)) {
if (mContainerType == HOTSEAT) {
screenId = -1;
container = Favorites.CONTAINER_HOTSEAT;
}
@@ -2127,7 +2133,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
info.spanY = lp.cellVSpan;
if (requiresDbUpdate) {
LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId,
LauncherModel.modifyItemInDatabase(getContext(), info, container, screenId,
info.cellX, info.cellY, info.spanX, info.spanY);
}
}
@@ -30,6 +30,7 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.config.FeatureFlags;
import java.util.ArrayList;
@@ -620,6 +621,19 @@ public class DeviceProfile {
: Math.max(widthPx, heightPx);
}
public int getCellHeight(@ContainerType int containerType) {
switch (containerType) {
case CellLayout.WORKSPACE:
return cellHeightPx;
case CellLayout.FOLDER:
return folderCellHeightPx;
case CellLayout.HOTSEAT:
return hotseatCellHeightPx;
default:
// ??
return 0;
}
}
/**
* @return the left/right paddings for all containers.
+3 -4
View File
@@ -113,12 +113,11 @@ public class Hotseat extends FrameLayout
super.onFinishInflate();
DeviceProfile grid = mLauncher.getDeviceProfile();
mContent = (CellLayout) findViewById(R.id.layout);
if (grid.isLandscape && !grid.isLargeTablet) {
mContent.setGridSize(1, (int) grid.inv.numHotseatIcons);
if (grid.isVerticalBarLayout()) {
mContent.setGridSize(1, grid.inv.numHotseatIcons);
} else {
mContent.setGridSize((int) grid.inv.numHotseatIcons, 1);
mContent.setGridSize(grid.inv.numHotseatIcons, 1);
}
mContent.setIsHotseat(true);
resetLayout();
}
@@ -85,6 +85,7 @@ public class InvariantDeviceProfile {
*/
public int numHotseatIcons;
float hotseatIconSize;
public float hotseatScale;
int defaultLayoutId;
DeviceProfile landscapeProfile;
@@ -117,6 +118,8 @@ public class InvariantDeviceProfile {
numHotseatIcons = hs;
hotseatIconSize = his;
defaultLayoutId = dlId;
hotseatScale = hotseatIconSize / iconSize;
}
@TargetApi(23)
@@ -158,6 +161,8 @@ public class InvariantDeviceProfile {
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, dm);
hotseatScale = hotseatIconSize / iconSize;
Point realSize = new Point();
display.getRealSize(realSize);
// The real size never changes. smallSide and largeSide will remain the
+1
View File
@@ -2808,6 +2808,7 @@ public class Launcher extends Activity
}
boolean isHotseatLayout(View layout) {
// TODO: Remove this method
return mHotseat != null && layout != null &&
(layout instanceof CellLayout) && (layout == mHotseat.getLayout());
}
@@ -20,29 +20,19 @@ import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.support.annotation.IntDef;
import android.view.View;
import android.view.ViewGroup;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.android.launcher3.CellLayout.ContainerType;
public class ShortcutAndWidgetContainer extends ViewGroup {
static final String TAG = "ShortcutAndWidgetContainer";
@Retention(RetentionPolicy.SOURCE)
@IntDef({DEFAULT, HOTSEAT, FOLDER})
public @interface ContainerType{}
public static final int DEFAULT = 0;
public static final int HOTSEAT = 1;
public static final int FOLDER = 2;
private int mContainerType = DEFAULT;
// These are temporary variables to prevent having to allocate a new object just to
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
private final int[] mTmpCellXY = new int[2];
@ContainerType private final int mContainerType;
private final WallpaperManager mWallpaperManager;
private int mCellWidth;
@@ -51,13 +41,13 @@ public class ShortcutAndWidgetContainer extends ViewGroup {
private int mCountX;
private Launcher mLauncher;
private boolean mInvertIfRtl = false;
public ShortcutAndWidgetContainer(Context context) {
public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
super(context);
mLauncher = Launcher.getLauncher(context);
mWallpaperManager = WallpaperManager.getInstance(context);
mContainerType = containerType;
}
public void setCellDimensions(int cellWidth, int cellHeight, int countX, int countY) {
@@ -105,19 +95,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup {
mInvertIfRtl = invert;
}
public void setContainerType(@ContainerType int containerType) {
mContainerType = containerType;
}
int getCellContentHeight() {
final DeviceProfile grid = mLauncher.getDeviceProfile();
int cellContentHeight = grid.cellHeightPx;
if (mContainerType == HOTSEAT) {
cellContentHeight = grid.hotseatCellHeightPx;
} else if (mContainerType == FOLDER) {
cellContentHeight = grid.folderCellHeightPx;
}
return Math.min(getMeasuredHeight(), cellContentHeight);
return Math.min(getMeasuredHeight(),
mLauncher.getDeviceProfile().getCellHeight(mContainerType));
}
public void measureChild(View child) {
@@ -57,7 +57,7 @@ public class WorkspaceAccessibilityHelper extends DragAndDropAccessibilityDelega
int y = id / mCountX;
LauncherAccessibilityDelegate.DragInfo dragInfo = mDelegate.getDragInfo();
if (dragInfo.dragType == DragType.WIDGET && mView.isHotseat()) {
if (dragInfo.dragType == DragType.WIDGET && !mView.acceptsWidget()) {
return INVALID_POSITION;
}
@@ -161,11 +161,7 @@ public class WorkspaceAccessibilityHelper extends DragAndDropAccessibilityDelega
View child = mView.getChildAt(x, y);
if (child == null || child == dragInfo.item) {
if (mView.isHotseat()) {
return mContext.getString(R.string.move_to_hotseat_position, id + 1);
} else {
return mContext.getString(R.string.move_to_empty_cell, y + 1, x + 1);
}
return mView.getItemMoveDescription(x, y);
} else {
return getDescriptionForDropOver(child, mContext);
}
@@ -253,11 +253,9 @@ public class FolderPagedView extends PagedView {
private CellLayout createAndAddNewPage() {
DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
CellLayout page = new CellLayout(getContext());
CellLayout page = (CellLayout) mInflater.inflate(R.layout.folder_page, this, false);
page.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx);
page.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
page.getShortcutsAndWidgets().setContainerType(ShortcutAndWidgetContainer.FOLDER);
page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
page.setInvertIfRtl(true);
page.setGridSize(mGridCountX, mGridCountY);
@@ -29,11 +29,9 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.R;
import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.StylusEventHelper;
import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.WidgetPreviewLoader.PreviewLoadRequest;
@@ -182,14 +180,6 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
ensurePreview();
}
public int getActualItemWidth() {
ItemInfo info = (ItemInfo) getTag();
int[] size = getPreviewSize();
int cellWidth = mLauncher.getDeviceProfile().cellWidthPx;
return Math.min(size[0], info.spanX * cellWidth);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean handled = super.onTouchEvent(ev);