mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-02 08:56:55 +00:00
Merge "Simulating a split screen CellLayout using one CellLayout" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
726e9acea4
23
res/layout/workspace_screen_foldable.xml
Normal file
23
res/layout/workspace_screen_foldable.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2022 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.launcher3.MultipageCellLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:hapticFeedbackEnabled="false"
|
||||
launcher:containerType="workspace" />
|
||||
@@ -99,9 +99,9 @@ public class CellLayout extends ViewGroup {
|
||||
private Point mBorderSpace;
|
||||
|
||||
@ViewDebug.ExportedProperty(category = "launcher")
|
||||
private int mCountX;
|
||||
protected int mCountX;
|
||||
@ViewDebug.ExportedProperty(category = "launcher")
|
||||
private int mCountY;
|
||||
protected int mCountY;
|
||||
|
||||
private boolean mDropPending = false;
|
||||
|
||||
@@ -111,8 +111,8 @@ public class CellLayout extends ViewGroup {
|
||||
@Thunk final int[] mTempLocation = new int[2];
|
||||
final PointF mTmpPointF = new PointF();
|
||||
|
||||
private GridOccupancy mOccupied;
|
||||
private GridOccupancy mTmpOccupied;
|
||||
protected GridOccupancy mOccupied;
|
||||
protected GridOccupancy mTmpOccupied;
|
||||
|
||||
private OnTouchListener mInterceptTouchListener;
|
||||
|
||||
@@ -121,7 +121,7 @@ public class CellLayout extends ViewGroup {
|
||||
|
||||
private static final int[] BACKGROUND_STATE_ACTIVE = new int[] { android.R.attr.state_active };
|
||||
private static final int[] BACKGROUND_STATE_DEFAULT = EMPTY_STATE_SET;
|
||||
private final Drawable mBackground;
|
||||
protected final Drawable mBackground;
|
||||
|
||||
// These values allow a fixed measurement to be set on the CellLayout.
|
||||
private int mFixedWidth = -1;
|
||||
@@ -154,7 +154,7 @@ public class CellLayout extends ViewGroup {
|
||||
private int mGridVisualizationRoundingRadius;
|
||||
private float mGridAlpha = 0f;
|
||||
private int mGridColor = 0;
|
||||
private float mSpringLoadedProgress = 0f;
|
||||
protected float mSpringLoadedProgress = 0f;
|
||||
private float mScrollProgress = 0f;
|
||||
|
||||
// When a drag operation is in progress, holds the nearest cell to the touch point
|
||||
@@ -164,7 +164,7 @@ public class CellLayout extends ViewGroup {
|
||||
private boolean mDragging = false;
|
||||
|
||||
private final TimeInterpolator mEaseOutInterpolator;
|
||||
private final ShortcutAndWidgetContainer mShortcutsAndWidgets;
|
||||
protected final ShortcutAndWidgetContainer mShortcutsAndWidgets;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({WORKSPACE, HOTSEAT, FOLDER})
|
||||
@@ -565,7 +565,7 @@ public class CellLayout extends ViewGroup {
|
||||
return mSpringLoadedProgress;
|
||||
}
|
||||
|
||||
private void updateBgAlpha() {
|
||||
protected void updateBgAlpha() {
|
||||
mBackground.setAlpha((int) (mSpringLoadedProgress * 255));
|
||||
}
|
||||
|
||||
@@ -1662,7 +1662,7 @@ public class CellLayout extends ViewGroup {
|
||||
* @param spanY vertical cell span
|
||||
* @return the configuration that represents the found reorder
|
||||
*/
|
||||
private ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int minSpanX,
|
||||
ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int minSpanX,
|
||||
int minSpanY, int spanX, int spanY) {
|
||||
ItemConfiguration solution = new ItemConfiguration();
|
||||
int[] result = new int[2];
|
||||
@@ -2402,8 +2402,15 @@ public class CellLayout extends ViewGroup {
|
||||
return true;
|
||||
}
|
||||
|
||||
private ItemConfiguration findReorderSolution(int pixelX, int pixelY, int minSpanX, int minSpanY,
|
||||
int spanX, int spanY, int[] direction, View dragView, boolean decX,
|
||||
protected ItemConfiguration findReorderSolution(int pixelX, int pixelY, int minSpanX,
|
||||
int minSpanY, int spanX, int spanY, int[] direction, View dragView, boolean decX,
|
||||
ItemConfiguration solution) {
|
||||
return findReorderSolutionRecursive(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY,
|
||||
direction, dragView, decX, solution);
|
||||
}
|
||||
|
||||
protected ItemConfiguration findReorderSolutionRecursive(int pixelX, int pixelY, int minSpanX,
|
||||
int minSpanY, int spanX, int spanY, int[] direction, View dragView, boolean decX,
|
||||
ItemConfiguration solution) {
|
||||
// Copy the current state into the solution. This solution will be manipulated as necessary.
|
||||
copyCurrentStateToSolution(solution, false);
|
||||
@@ -2426,11 +2433,11 @@ public class CellLayout extends ViewGroup {
|
||||
// We try shrinking the widget down to size in an alternating pattern, shrink 1 in
|
||||
// x, then 1 in y etc.
|
||||
if (spanX > minSpanX && (minSpanY == spanY || decX)) {
|
||||
return findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX - 1, spanY,
|
||||
direction, dragView, false, solution);
|
||||
return findReorderSolutionRecursive(pixelX, pixelY, minSpanX, minSpanY, spanX - 1,
|
||||
spanY, direction, dragView, false, solution);
|
||||
} else if (spanY > minSpanY) {
|
||||
return findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY - 1,
|
||||
direction, dragView, true, solution);
|
||||
return findReorderSolutionRecursive(pixelX, pixelY, minSpanX, minSpanY, spanX,
|
||||
spanY - 1, direction, dragView, true, solution);
|
||||
}
|
||||
solution.isSolution = false;
|
||||
} else {
|
||||
@@ -2443,7 +2450,7 @@ public class CellLayout extends ViewGroup {
|
||||
return solution;
|
||||
}
|
||||
|
||||
private void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) {
|
||||
protected void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) {
|
||||
int childCount = mShortcutsAndWidgets.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = mShortcutsAndWidgets.getChildAt(i);
|
||||
@@ -2624,7 +2631,7 @@ public class CellLayout extends ViewGroup {
|
||||
return mItemPlacementDirty;
|
||||
}
|
||||
|
||||
private static class ItemConfiguration extends CellAndSpan {
|
||||
static class ItemConfiguration extends CellAndSpan {
|
||||
final ArrayMap<View, CellAndSpan> map = new ArrayMap<>();
|
||||
private final ArrayMap<View, CellAndSpan> savedMap = new ArrayMap<>();
|
||||
final ArrayList<View> sortedViews = new ArrayList<>();
|
||||
|
||||
@@ -44,6 +44,7 @@ import static com.android.launcher3.LauncherState.SPRING_LOADED;
|
||||
import static com.android.launcher3.Utilities.postAsyncCallback;
|
||||
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
|
||||
import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
|
||||
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
|
||||
import static com.android.launcher3.config.FeatureFlags.SHOW_DOT_PAGINATION;
|
||||
import static com.android.launcher3.logging.StatsLogManager.EventEnum;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||
@@ -138,6 +139,7 @@ import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.PropertyListBuilder;
|
||||
import com.android.launcher3.celllayout.CellPosMapper;
|
||||
import com.android.launcher3.celllayout.CellPosMapper.CellPos;
|
||||
import com.android.launcher3.celllayout.CellPosMapper.TwoPanelCellPosMapper;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dot.DotInfo;
|
||||
@@ -730,7 +732,11 @@ public class Launcher extends StatefulActivity<LauncherState>
|
||||
}
|
||||
|
||||
onDeviceProfileInitiated();
|
||||
mCellPosMapper = CellPosMapper.DEFAULT;
|
||||
if (FOLDABLE_SINGLE_PAGE.get() && mDeviceProfile.isTwoPanels) {
|
||||
mCellPosMapper = new TwoPanelCellPosMapper(mDeviceProfile.inv.numColumns);
|
||||
} else {
|
||||
mCellPosMapper = CellPosMapper.DEFAULT;
|
||||
}
|
||||
mModelWriter = mModel.getWriter(getDeviceProfile().isVerticalBarLayout(), true,
|
||||
mCellPosMapper, this);
|
||||
return true;
|
||||
|
||||
168
src/com/android/launcher3/MultipageCellLayout.java
Normal file
168
src/com/android/launcher3/MultipageCellLayout.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
|
||||
import com.android.launcher3.util.CellAndSpan;
|
||||
import com.android.launcher3.util.GridOccupancy;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* CellLayout that simulates a split in the middle for use in foldable devices.
|
||||
*/
|
||||
public class MultipageCellLayout extends CellLayout {
|
||||
|
||||
private final Drawable mLeftBackground;
|
||||
private final Drawable mRightBackground;
|
||||
|
||||
private View mSeam;
|
||||
|
||||
public MultipageCellLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public MultipageCellLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public MultipageCellLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mLeftBackground = getContext().getDrawable(R.drawable.bg_celllayout);
|
||||
mLeftBackground.setCallback(this);
|
||||
mLeftBackground.setAlpha(0);
|
||||
|
||||
mRightBackground = getContext().getDrawable(R.drawable.bg_celllayout);
|
||||
mRightBackground.setCallback(this);
|
||||
mRightBackground.setAlpha(0);
|
||||
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
|
||||
mCountX = deviceProfile.inv.numColumns * 2;
|
||||
mCountY = deviceProfile.inv.numRows;
|
||||
mSeam = new View(getContext());
|
||||
setGridSize(mCountX, mCountY);
|
||||
}
|
||||
|
||||
@Override
|
||||
ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int minSpanX, int minSpanY,
|
||||
int spanX, int spanY) {
|
||||
return simulateSeam(
|
||||
() -> super.closestEmptySpaceReorder(pixelX, pixelY, minSpanX, minSpanY, spanX,
|
||||
spanY));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemConfiguration findReorderSolution(int pixelX, int pixelY, int minSpanX,
|
||||
int minSpanY, int spanX, int spanY, int[] direction, View dragView, boolean decX,
|
||||
ItemConfiguration solution) {
|
||||
return simulateSeam(
|
||||
() -> super.findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY,
|
||||
direction, dragView, decX, solution));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemConfiguration dropInPlaceSolution(int pixelX, int pixelY, int spanX, int spanY,
|
||||
View dragView) {
|
||||
return simulateSeam(
|
||||
() -> super.dropInPlaceSolution(pixelX, pixelY, spanX, spanY, dragView));
|
||||
}
|
||||
|
||||
protected ItemConfiguration simulateSeam(Supplier<ItemConfiguration> f) {
|
||||
CellLayoutLayoutParams lp = new CellLayoutLayoutParams(mCountX / 2, 0, 1, mCountY);
|
||||
lp.canReorder = false;
|
||||
mCountX++;
|
||||
mShortcutsAndWidgets.addViewInLayout(mSeam, lp);
|
||||
GridOccupancy auxGrid = mOccupied;
|
||||
mOccupied = createGridOccupancy();
|
||||
mTmpOccupied = new GridOccupancy(mCountX, mCountY);
|
||||
|
||||
ItemConfiguration res = removeSeamFromSolution(f.get());
|
||||
|
||||
mCountX--;
|
||||
mShortcutsAndWidgets.removeViewInLayout(mSeam);
|
||||
mOccupied = auxGrid;
|
||||
mTmpOccupied = new GridOccupancy(mCountX, mCountY);
|
||||
return res;
|
||||
}
|
||||
|
||||
private ItemConfiguration removeSeamFromSolution(ItemConfiguration solution) {
|
||||
solution.map.forEach((view, cell) -> cell.cellX = cell.cellX > mCountX / 2
|
||||
? cell.cellX - 1 : cell.cellX);
|
||||
solution.cellX = solution.cellX > mCountX / 2 ? solution.cellX - 1 : solution.cellX;
|
||||
return solution;
|
||||
}
|
||||
|
||||
GridOccupancy createGridOccupancy() {
|
||||
GridOccupancy grid = new GridOccupancy(mCountX, mCountY);
|
||||
for (int i = 0; i < mShortcutsAndWidgets.getChildCount(); i++) {
|
||||
View view = mShortcutsAndWidgets.getChildAt(i);
|
||||
CellLayoutLayoutParams lp = (CellLayoutLayoutParams) view.getLayoutParams();
|
||||
int seamOffset = lp.getCellX() >= mCountX / 2 && lp.canReorder ? 1 : 0;
|
||||
grid.markCells(lp.getCellX() + seamOffset, lp.getCellY(), lp.cellHSpan, lp.cellVSpan,
|
||||
true);
|
||||
}
|
||||
return grid;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) {
|
||||
int childCount = mShortcutsAndWidgets.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = mShortcutsAndWidgets.getChildAt(i);
|
||||
CellLayoutLayoutParams lp = (CellLayoutLayoutParams) child.getLayoutParams();
|
||||
int seamOffset = lp.getCellX() >= mCountX / 2 && lp.canReorder ? 1 : 0;
|
||||
CellAndSpan c = new CellAndSpan(lp.getCellX() + seamOffset, lp.getCellY(), lp.cellHSpan,
|
||||
lp.cellVSpan);
|
||||
solution.add(child, c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mLeftBackground.getAlpha() > 0) {
|
||||
mLeftBackground.setState(mBackground.getState());
|
||||
mLeftBackground.draw(canvas);
|
||||
}
|
||||
if (mRightBackground.getAlpha() > 0) {
|
||||
mRightBackground.setState(mBackground.getState());
|
||||
mRightBackground.draw(canvas);
|
||||
}
|
||||
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateBgAlpha() {
|
||||
mLeftBackground.setAlpha((int) (mSpringLoadedProgress * 255));
|
||||
mRightBackground.setAlpha((int) (mSpringLoadedProgress * 255));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
Rect rect = mBackground.getBounds();
|
||||
mLeftBackground.setBounds(rect.left, rect.top, rect.right / 2 - 20, rect.bottom);
|
||||
mRightBackground.setBounds(rect.right / 2 + 20, rect.top, rect.right, rect.bottom);
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,18 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds view to Layout a new position and it does not trigger a layout request.
|
||||
* For more information check documentation for
|
||||
* {@code ViewGroup#addViewInLayout(View, int, LayoutParams, boolean)}
|
||||
*
|
||||
* @param child view to be added
|
||||
* @return true if the child was added, false otherwise
|
||||
*/
|
||||
public boolean addViewInLayout(View child, LayoutParams layoutParams) {
|
||||
return super.addViewInLayout(child, -1, layoutParams, true);
|
||||
}
|
||||
|
||||
public void setupLp(View child) {
|
||||
CellLayoutLayoutParams lp = (CellLayoutLayoutParams) child.getLayoutParams();
|
||||
if (child instanceof NavigableAppWidgetHostView) {
|
||||
|
||||
@@ -135,6 +135,7 @@ import java.util.stream.Collectors;
|
||||
* The workspace is a wide area with a wallpaper and a finite number of pages.
|
||||
* Each page contains a number of icons, folders or widgets the user can
|
||||
* interact with. A workspace is meant to be used with a fixed width only.
|
||||
*
|
||||
* @param <T> Class that extends View and PageIndicator
|
||||
*/
|
||||
public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
@@ -142,12 +143,16 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
DragController.DragListener, Insettable, StateHandler<LauncherState>,
|
||||
WorkspaceLayoutManager, LauncherBindableItemsContainer, LauncherOverlayCallbacks {
|
||||
|
||||
/** The value that {@link #mTransitionProgress} must be greater than for
|
||||
* {@link #transitionStateShouldAllowDrop()} to return true. */
|
||||
/**
|
||||
* The value that {@link #mTransitionProgress} must be greater than for
|
||||
* {@link #transitionStateShouldAllowDrop()} to return true.
|
||||
*/
|
||||
private static final float ALLOW_DROP_TRANSITION_PROGRESS = 0.25f;
|
||||
|
||||
/** The value that {@link #mTransitionProgress} must be greater than for
|
||||
* {@link #isFinishedSwitchingState()} ()} to return true. */
|
||||
/**
|
||||
* The value that {@link #mTransitionProgress} must be greater than for
|
||||
* {@link #isFinishedSwitchingState()} ()} to return true.
|
||||
*/
|
||||
private static final float FINISHED_SWITCHING_STATE_TRANSITION_PROGRESS = 0.5f;
|
||||
|
||||
private static final float SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE = 0.15f;
|
||||
@@ -161,16 +166,20 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
private final int mAllAppsIconSize;
|
||||
|
||||
private LayoutTransition mLayoutTransition;
|
||||
@Thunk final WallpaperManager mWallpaperManager;
|
||||
@Thunk
|
||||
final WallpaperManager mWallpaperManager;
|
||||
|
||||
protected ShortcutAndWidgetContainer mDragSourceInternal;
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
@Thunk public final IntSparseArrayMap<CellLayout> mWorkspaceScreens = new IntSparseArrayMap<>();
|
||||
@Thunk
|
||||
public final IntSparseArrayMap<CellLayout> mWorkspaceScreens = new IntSparseArrayMap<>();
|
||||
|
||||
@Thunk final IntArray mScreenOrder = new IntArray();
|
||||
@Thunk
|
||||
final IntArray mScreenOrder = new IntArray();
|
||||
|
||||
@Thunk boolean mDeferRemoveExtraEmptyScreen = false;
|
||||
@Thunk
|
||||
boolean mDeferRemoveExtraEmptyScreen = false;
|
||||
|
||||
/**
|
||||
* CellInfo for the cell that is currently being dragged
|
||||
@@ -180,14 +189,16 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
/**
|
||||
* Target drop area calculated during last acceptDrop call.
|
||||
*/
|
||||
@Thunk int[] mTargetCell = new int[2];
|
||||
@Thunk
|
||||
int[] mTargetCell = new int[2];
|
||||
private int mDragOverX = -1;
|
||||
private int mDragOverY = -1;
|
||||
|
||||
/**
|
||||
* The CellLayout that is currently being dragged over
|
||||
*/
|
||||
@Thunk CellLayout mDragTargetLayout = null;
|
||||
@Thunk
|
||||
CellLayout mDragTargetLayout = null;
|
||||
/**
|
||||
* The CellLayout that we will show as highlighted
|
||||
*/
|
||||
@@ -198,13 +209,16 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
*/
|
||||
private CellLayout mDropToLayout = null;
|
||||
|
||||
@Thunk final Launcher mLauncher;
|
||||
@Thunk DragController mDragController;
|
||||
@Thunk
|
||||
final Launcher mLauncher;
|
||||
@Thunk
|
||||
DragController mDragController;
|
||||
|
||||
protected final int[] mTempXY = new int[2];
|
||||
private final float[] mTempFXY = new float[2];
|
||||
private final Rect mTempRect = new Rect();
|
||||
@Thunk float[] mDragViewVisualCenter = new float[2];
|
||||
@Thunk
|
||||
float[] mDragViewVisualCenter = new float[2];
|
||||
|
||||
private SpringLoadedDragController mSpringLoadedDragController;
|
||||
|
||||
@@ -249,8 +263,10 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
private static final int DRAG_MODE_ADD_TO_FOLDER = 2;
|
||||
private static final int DRAG_MODE_REORDER = 3;
|
||||
protected int mDragMode = DRAG_MODE_NONE;
|
||||
@Thunk int mLastReorderX = -1;
|
||||
@Thunk int mLastReorderY = -1;
|
||||
@Thunk
|
||||
int mLastReorderX = -1;
|
||||
@Thunk
|
||||
int mLastReorderY = -1;
|
||||
|
||||
private SparseArray<Parcelable> mSavedStates;
|
||||
private final IntArray mRestoredPages = new IntArray();
|
||||
@@ -275,7 +291,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
* Used to inflate the Workspace from XML.
|
||||
*
|
||||
* @param context The application's context.
|
||||
* @param attrs The attributes set containing the Workspace's customization values.
|
||||
* @param attrs The attributes set containing the Workspace's customization values.
|
||||
*/
|
||||
public Workspace(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
@@ -284,8 +300,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
/**
|
||||
* Used to inflate the Workspace from XML.
|
||||
*
|
||||
* @param context The application's context.
|
||||
* @param attrs The attributes set containing the Workspace's customization values.
|
||||
* @param context The application's context.
|
||||
* @param attrs The attributes set containing the Workspace's customization values.
|
||||
* @param defStyle Unused.
|
||||
*/
|
||||
public Workspace(Context context, AttributeSet attrs, int defStyle) {
|
||||
@@ -421,7 +437,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
return mWallpaperOffset.wallpaperOffsetForScroll(pageScroll);
|
||||
}
|
||||
|
||||
/** Returns the number of pages used for the wallpaper parallax. */
|
||||
/**
|
||||
* Returns the number of pages used for the wallpaper parallax.
|
||||
*/
|
||||
public int getNumPagesForWallpaperParallax() {
|
||||
return mWallpaperOffset.getNumPagesForWallpaperParallax();
|
||||
}
|
||||
@@ -553,6 +571,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
void enableLayoutTransitions() {
|
||||
setLayoutTransition(mLayoutTransition);
|
||||
}
|
||||
|
||||
void disableLayoutTransitions() {
|
||||
setLayoutTransition(null);
|
||||
}
|
||||
@@ -644,8 +663,14 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
|
||||
// Inflate the cell layout, but do not add it automatically so that we can get the newly
|
||||
// created CellLayout.
|
||||
CellLayout newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
|
||||
CellLayout newScreen;
|
||||
if (FOLDABLE_SINGLE_PAGE.get() && isTwoPanelEnabled()) {
|
||||
newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.workspace_screen_foldable, this, false /* attachToRoot */);
|
||||
} else {
|
||||
newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.workspace_screen, this, false /* attachToRoot */);
|
||||
}
|
||||
|
||||
mWorkspaceScreens.put(screenId, newScreen);
|
||||
mScreenOrder.add(insertIndex, screenId);
|
||||
@@ -783,17 +808,17 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
* Empty page(s) from the end of mWorkspaceScreens will always be removed. The pages with
|
||||
* ID = Workspace.EXTRA_EMPTY_SCREEN_IDS will be removed if there are other non-empty pages.
|
||||
* If there are no more non-empty pages left, extra empty page(s) will either stay or get added.
|
||||
*
|
||||
* <p>
|
||||
* If stripEmptyScreens is true, all empty pages (not just the ones on the end) will be removed
|
||||
* from the Workspace, and if there are no more pages left then extra empty page(s) will be
|
||||
* added.
|
||||
*
|
||||
* <p>
|
||||
* The number of extra empty pages is equal to what getPanelCount() returns.
|
||||
*
|
||||
* <p>
|
||||
* After the method returns the possible pages are:
|
||||
* stripEmptyScreens = true : [non-empty pages, extra empty page(s) alone]
|
||||
* stripEmptyScreens = false : [non-empty pages, empty pages (not in the end),
|
||||
* extra empty page(s) alone]
|
||||
* extra empty page(s) alone]
|
||||
*/
|
||||
public void removeExtraEmptyScreenDelayed(
|
||||
int delay, boolean stripEmptyScreens, Runnable onComplete) {
|
||||
@@ -844,11 +869,11 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the extra empty pages then returns the screen ids of those new screens.
|
||||
* Usually there's only one extra empty screen, but when two panel home is enabled we commit
|
||||
* two extra screens.
|
||||
*
|
||||
* Returns an empty IntSet in case we cannot commit any new screens.
|
||||
* Commits the extra empty pages then returns the screen ids of those new screens.
|
||||
* Usually there's only one extra empty screen, but when two panel home is enabled we commit
|
||||
* two extra screens.
|
||||
* <p>
|
||||
* Returns an empty IntSet in case we cannot commit any new screens.
|
||||
*/
|
||||
public IntSet commitExtraEmptyScreens() {
|
||||
if (mLauncher.isWorkspaceLoading()) {
|
||||
@@ -869,7 +894,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
mScreenOrder.removeValue(emptyScreenId);
|
||||
|
||||
int newScreenId = LauncherSettings.Settings.call(getContext().getContentResolver(),
|
||||
LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
|
||||
LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
|
||||
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
|
||||
// Launcher database isn't aware of empty pages that are already bound, so we need to
|
||||
// skip those IDs manually.
|
||||
@@ -1058,8 +1083,10 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
return mIsSwitchingState;
|
||||
}
|
||||
|
||||
/** This differs from isSwitchingState in that we take into account how far the transition
|
||||
* has completed. */
|
||||
/**
|
||||
* This differs from isSwitchingState in that we take into account how far the transition
|
||||
* has completed.
|
||||
*/
|
||||
public boolean isFinishedSwitchingState() {
|
||||
return !mIsSwitchingState
|
||||
|| (mTransitionProgress > FINISHED_SWITCHING_STATE_TRANSITION_PROGRESS);
|
||||
@@ -1387,7 +1414,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
return mLauncher.isInState(SPRING_LOADED) || !workspaceInModalState();
|
||||
}
|
||||
|
||||
/** Returns whether a drag should be allowed to be started from the current workspace state. */
|
||||
/**
|
||||
* Returns whether a drag should be allowed to be started from the current workspace state.
|
||||
*/
|
||||
public boolean workspaceIconsCanBeDragged() {
|
||||
return mLauncher.getStateManager().getState().hasFlag(FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED);
|
||||
}
|
||||
@@ -1419,7 +1448,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
// In overview mode, make sure that the two side pages are visible.
|
||||
leftScreen = Utilities.boundToRange(getCurrentPage() - 1, 0, rightScreen);
|
||||
rightScreen = Utilities.boundToRange(getCurrentPage() + 1,
|
||||
leftScreen, getPageCount() - 1);
|
||||
leftScreen, getPageCount() - 1);
|
||||
}
|
||||
|
||||
if (leftScreen == rightScreen) {
|
||||
@@ -1621,7 +1650,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
if (draggableView != null) {
|
||||
draggableView.getSourceVisualDragBounds(dragRect);
|
||||
dragLayerY += dragRect.top;
|
||||
dragVisualizeOffset = new Point(- halfPadding, halfPadding);
|
||||
dragVisualizeOffset = new Point(-halfPadding, halfPadding);
|
||||
}
|
||||
|
||||
|
||||
@@ -1752,7 +1781,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
}
|
||||
|
||||
boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell,
|
||||
float distance, boolean considerTimeout) {
|
||||
float distance, boolean considerTimeout) {
|
||||
if (distance > target.getFolderCreationRadius(targetCell)) return false;
|
||||
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
|
||||
return willCreateUserFolder(info, dropOverView, considerTimeout);
|
||||
@@ -1788,12 +1817,13 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
}
|
||||
|
||||
boolean willAddToExistingUserFolder(ItemInfo dragInfo, CellLayout target, int[] targetCell,
|
||||
float distance) {
|
||||
float distance) {
|
||||
if (distance > target.getFolderCreationRadius(targetCell)) return false;
|
||||
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
|
||||
return willAddToExistingUserFolder(dragInfo, dropOverView);
|
||||
|
||||
}
|
||||
|
||||
boolean willAddToExistingUserFolder(ItemInfo dragInfo, View dropOverView) {
|
||||
if (dropOverView != null) {
|
||||
CellLayoutLayoutParams lp = (CellLayoutLayoutParams) dropOverView.getLayoutParams();
|
||||
@@ -1894,7 +1924,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareAccessibilityDrop() { }
|
||||
public void prepareAccessibilityDrop() {}
|
||||
|
||||
@Override
|
||||
public void onDrop(final DragObject d, DragOptions options) {
|
||||
@@ -1912,8 +1942,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
boolean resizeOnDrop = false;
|
||||
Runnable onCompleteRunnable = null;
|
||||
if (d.dragSource != this || mDragInfo == null) {
|
||||
final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0],
|
||||
(int) mDragViewVisualCenter[1] };
|
||||
final int[] touchXY = new int[]{(int) mDragViewVisualCenter[0],
|
||||
(int) mDragViewVisualCenter[1]};
|
||||
onDropExternal(touchXY, dropTargetLayout, d);
|
||||
} else {
|
||||
final View cell = mDragInfo.cell;
|
||||
@@ -2311,8 +2341,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
|
||||
/**
|
||||
* Updates the point in {@param xy} to point to the co-ordinate space of {@param layout}
|
||||
*
|
||||
* @param layout either hotseat of a page in workspace
|
||||
* @param xy the point location in workspace co-ordinate space
|
||||
* @param xy the point location in workspace co-ordinate space
|
||||
*/
|
||||
private void mapPointFromDropLayout(CellLayout layout, float[] xy) {
|
||||
if (mLauncher.isHotseatLayout(layout)) {
|
||||
@@ -2379,7 +2410,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
manageFolderFeedback(targetCellDistance, d);
|
||||
|
||||
boolean nearestDropOccupied = mDragTargetLayout.isNearestDropLocationOccupied((int)
|
||||
mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX,
|
||||
mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX,
|
||||
item.spanY, child, mTargetCell);
|
||||
|
||||
manageReorderOnDragOver(d, targetCellDistance, nearestDropOccupied, minSpanX, minSpanY,
|
||||
@@ -2400,11 +2431,15 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
ItemInfo item = d.dragInfo;
|
||||
final View child = (mDragInfo == null) ? null : mDragInfo.cell;
|
||||
if (!nearestDropOccupied) {
|
||||
int[] span = new int[2];
|
||||
mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
|
||||
(int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY,
|
||||
child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT);
|
||||
mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
|
||||
item.spanX, item.spanY, d);
|
||||
child, mTargetCell, span, CellLayout.MODE_SHOW_REORDER_HINT);
|
||||
mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1], span[0],
|
||||
span[1], d);
|
||||
nearestDropOccupied = mDragTargetLayout.isNearestDropLocationOccupied((int)
|
||||
mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX,
|
||||
item.spanY, child, mTargetCell);
|
||||
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
|
||||
&& (mLastReorderX != reorderX || mLastReorderY != reorderY)
|
||||
&& targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell, item.spanX,
|
||||
@@ -2423,6 +2458,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
mReorderAlarm.setAlarm(REORDER_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates {@link #mDragTargetLayout} and {@link #mDragOverlappingLayout}
|
||||
* based on the DragObject's position.
|
||||
@@ -2604,7 +2640,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
final View child;
|
||||
|
||||
public ReorderAlarmListener(float[] dragViewCenter, int minSpanX, int minSpanY, int spanX,
|
||||
int spanY, DragObject dragObject, View child) {
|
||||
int spanY, DragObject dragObject, View child) {
|
||||
this.dragViewCenter = dragViewCenter;
|
||||
this.minSpanX = minSpanX;
|
||||
this.minSpanY = minSpanY;
|
||||
@@ -2621,8 +2657,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
mTargetCell);
|
||||
|
||||
mTargetCell = mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
|
||||
(int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY,
|
||||
child, mTargetCell, resultSpan, CellLayout.MODE_DRAG_OVER);
|
||||
(int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY,
|
||||
child, mTargetCell, resultSpan, CellLayout.MODE_DRAG_OVER);
|
||||
|
||||
if (mTargetCell[0] < 0 || mTargetCell[1] < 0) {
|
||||
mDragTargetLayout.revertTempState();
|
||||
@@ -2646,7 +2682,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
* Drop an item that didn't originate on one of the workspace screens.
|
||||
* It may have come from Launcher (e.g. from all apps or customize), or it may have
|
||||
* come from another app altogether.
|
||||
*
|
||||
* <p>
|
||||
* NOTE: This can also be called when we are outside of a drag event, when we want
|
||||
* to add an item to one of the workspace screens.
|
||||
*/
|
||||
@@ -2688,7 +2724,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
|
||||
if (willCreateUserFolder(d.dragInfo, cellLayout, mTargetCell, distance, true)
|
||||
|| willAddToExistingUserFolder(
|
||||
d.dragInfo, cellLayout, mTargetCell, distance)) {
|
||||
d.dragInfo, cellLayout, mTargetCell, distance)) {
|
||||
findNearestVacantCell = false;
|
||||
}
|
||||
}
|
||||
@@ -2923,7 +2959,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
Drawable crossFadeDrawable = createWidgetDrawable(info, finalView);
|
||||
dragView.crossFadeContent(crossFadeDrawable, (int) (duration * 0.8f));
|
||||
} else if (isWidget && external) {
|
||||
scaleXY[0] = scaleXY[1] = Math.min(scaleXY[0], scaleXY[1]);
|
||||
scaleXY[0] = scaleXY[1] = Math.min(scaleXY[0], scaleXY[1]);
|
||||
}
|
||||
|
||||
DragLayer dragLayer = mLauncher.getDragLayer();
|
||||
@@ -2962,6 +2998,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
setScaleY(mStateTransitionAnimation.getFinalScale());
|
||||
}
|
||||
}
|
||||
|
||||
public void resetTransitionTransform() {
|
||||
if (isSwitchingState()) {
|
||||
setScaleX(mCurrentScale);
|
||||
@@ -2973,7 +3010,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
* Return the current CellInfo describing our current drag; this method exists
|
||||
* so that Launcher can sync this object with the correct info when the activity is created/
|
||||
* destroyed
|
||||
*
|
||||
*/
|
||||
public CellLayout.CellInfo getDragInfo() {
|
||||
return mDragInfo;
|
||||
@@ -2981,11 +3017,12 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
|
||||
/**
|
||||
* Calculate the nearest cell where the given object would be dropped.
|
||||
*
|
||||
* <p>
|
||||
* pixelX and pixelY should be in the coordinate system of layout
|
||||
*/
|
||||
@Thunk int[] findNearestArea(int pixelX, int pixelY,
|
||||
int spanX, int spanY, CellLayout layout, int[] recycle) {
|
||||
@Thunk
|
||||
int[] findNearestArea(int pixelX, int pixelY,
|
||||
int spanX, int spanY, CellLayout layout, int[] recycle) {
|
||||
return layout.findNearestAreaIgnoreOccupied(
|
||||
pixelX, pixelY, spanX, spanY, recycle);
|
||||
}
|
||||
@@ -3003,7 +3040,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
* Called at the end of a drag which originated on the workspace.
|
||||
*/
|
||||
public void onDropCompleted(final View target, final DragObject d,
|
||||
final boolean success) {
|
||||
final boolean success) {
|
||||
if (success) {
|
||||
if (target != this && mDragInfo != null) {
|
||||
removeWorkspaceItem(mDragInfo.cell);
|
||||
@@ -3050,6 +3087,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
|
||||
/**
|
||||
* Removed widget from workspace by appWidgetId
|
||||
*
|
||||
* @param appWidgetId
|
||||
*/
|
||||
public void removeWidget(int appWidgetId) {
|
||||
@@ -3256,6 +3294,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
|
||||
/**
|
||||
* Perform {param operator} over all the items in a given {param layout}.
|
||||
*
|
||||
* @return The first item that satisfies the operator or null.
|
||||
*/
|
||||
public View mapOverCellLayout(CellLayout layout, ItemOperator operator) {
|
||||
@@ -3310,10 +3349,10 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
/**
|
||||
* Remove workspace icons & widget information related to items in matcher.
|
||||
*
|
||||
* @param matcher the matcher generated by the caller.
|
||||
* @param matcher the matcher generated by the caller.
|
||||
*/
|
||||
public void persistRemoveItemsByMatcher(Predicate<ItemInfo> matcher,
|
||||
@Nullable final String reason) {
|
||||
@Nullable final String reason) {
|
||||
mLauncher.getModelWriter().deleteItemsFromDatabase(matcher, reason);
|
||||
removeItemsByMatcher(matcher);
|
||||
}
|
||||
@@ -3358,7 +3397,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
return mOverlayShown;
|
||||
}
|
||||
|
||||
/** Calls {@link #snapToPage(int)} on the {@link #DEFAULT_PAGE}, then requests focus on it. */
|
||||
/**
|
||||
* Calls {@link #snapToPage(int)} on the {@link #DEFAULT_PAGE}, then requests focus on it.
|
||||
*/
|
||||
public void moveToDefaultScreen() {
|
||||
int page = DEFAULT_PAGE;
|
||||
if (!workspaceInModalState() && getNextPage() != page) {
|
||||
@@ -3458,7 +3499,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
|
||||
private boolean mRefreshPending;
|
||||
|
||||
DeferredWidgetRefresh(ArrayList<LauncherAppWidgetInfo> infos,
|
||||
LauncherWidgetHolder holder) {
|
||||
LauncherWidgetHolder holder) {
|
||||
mInfos = infos;
|
||||
mWidgetHolder = holder;
|
||||
mHandler = mLauncher.mHandler;
|
||||
|
||||
@@ -81,4 +81,16 @@ public class GridOccupancy extends AbsGridOccupancy {
|
||||
public void clear() {
|
||||
markCells(0, 0, mCountX, mCountY, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder("Grid: \n");
|
||||
for (int y = 0; y < mCountY; y++) {
|
||||
for (int x = 0; x < mCountX; x++) {
|
||||
s.append(cells[x][y] ? 1 : 0).append(" ");
|
||||
}
|
||||
s.append("\n");
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user