Merge "Lower the transition threshold for dropping on Workspace." into ub-launcher3-master
diff --git a/res/layout/folder_page.xml b/res/layout/folder_page.xml
new file mode 100644
index 0000000..084e8fd
--- /dev/null
+++ b/res/layout/folder_page.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.CellLayout
+ 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"
+ android:importantForAccessibility="no"
+ launcher:containerType="folder" />
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index 7bef889..f5b5bbf 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -20,5 +20,6 @@
android:id="@+id/layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_gravity="center" />
+ android:layout_gravity="center"
+ launcher:containerType="hotseat" />
</com.android.launcher3.Hotseat>
diff --git a/res/layout/workspace_screen.xml b/res/layout/workspace_screen.xml
index faf6885..94bdedb 100644
--- a/res/layout/workspace_screen.xml
+++ b/res/layout/workspace_screen.xml
@@ -19,4 +19,5 @@
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:hapticFeedbackEnabled="false" />
+ android:hapticFeedbackEnabled="false"
+ launcher:containerType="workspace" />
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 32bccb8..1e34c0f 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -112,4 +112,12 @@
<attr name="defaultLayoutId" format="reference" />
</declare-styleable>
+ <declare-styleable name="CellLayout">
+ <attr name="containerType" format="integer">
+ <enum name="workspace" value="0" />
+ <enum name="hotseat" value="1" />
+ <enum name="folder" value="2" />
+ </attr>
+ </declare-styleable>
+
</resources>
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 866d239..c0087c4 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -24,6 +24,7 @@
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.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.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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
// We make sure to end only after a full period
initDeltaX = 0;
initDeltaY = 0;
- initScale = getChildrenScale();
+ initScale = mChildScale;
repeating = true;
}
});
@@ -2081,8 +2087,8 @@
}
a = new LauncherViewPropertyAnimator(child)
- .scaleX(getChildrenScale())
- .scaleY(getChildrenScale())
+ .scaleX(mChildScale)
+ .scaleY(mChildScale)
.translationX(0)
.translationY(0)
.setDuration(REORDER_ANIMATION_DURATION);
@@ -2104,7 +2110,7 @@
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 @@
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);
}
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index eb1db1c..fbff4eb 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -30,6 +30,7 @@
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 @@
: 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.
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 5c96dde..3648fb7 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -113,12 +113,11 @@
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();
}
@@ -168,7 +167,7 @@
public boolean onInterceptTouchEvent(MotionEvent ev) {
// We don't want any clicks to go through to the hotseat unless the workspace is in
// the normal state or an accessible drag is in progress.
- return mLauncher.getWorkspace().workspaceInModalState() &&
+ return !mLauncher.getWorkspace().workspaceIconsCanBeDragged() &&
!mLauncher.getAccessibilityDelegate().isInAccessibleDrag();
}
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 46df0b2..46bc3b3 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -67,6 +69,7 @@
private static final String APP_SHORTCUT_TYPE_KEY = "isAppShortcut";
private static final String DEEPSHORTCUT_TYPE_KEY = "isDeepShortcut";
+ private static final String APP_WIDGET_TYPE_KEY = "isAppWidget";
private static final String USER_HANDLE_KEY = "userHandle";
// The set of shortcuts that are pending install
@@ -200,13 +203,17 @@
public static ShortcutInfo fromShortcutIntent(Context context, Intent data) {
PendingInstallShortcutInfo info = createPendingInfo(context, data);
- return info == null ? null : info.getShortcutInfo();
+ return info == null ? null : (ShortcutInfo) info.getItemInfo();
}
public static void queueShortcut(ShortcutInfoCompat info, Context context) {
queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, context), context);
}
+ public static void queueWidget(AppWidgetProviderInfo info, int widgetId, Context context) {
+ queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, widgetId, context), context);
+ }
+
public static HashSet<ShortcutKey> getPendingShortcuts(Context context) {
HashSet<ShortcutKey> result = new HashSet<>();
@@ -276,6 +283,7 @@
final LauncherActivityInfoCompat activityInfo;
final ShortcutInfoCompat shortcutInfo;
+ final AppWidgetProviderInfo providerInfo;
final Intent data;
final Context mContext;
@@ -287,25 +295,30 @@
* Initializes a PendingInstallShortcutInfo received from a different app.
*/
public PendingInstallShortcutInfo(Intent data, UserHandleCompat user, Context context) {
+ activityInfo = null;
+ shortcutInfo = null;
+ providerInfo = null;
+
this.data = data;
this.user = user;
mContext = context;
launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
- activityInfo = null;
- shortcutInfo = null;
+
}
/**
* Initializes a PendingInstallShortcutInfo to represent a launcher target.
*/
public PendingInstallShortcutInfo(LauncherActivityInfoCompat info, Context context) {
- this.data = null;
- mContext = context;
activityInfo = info;
shortcutInfo = null;
+ providerInfo = null;
+
+ data = null;
user = info.getUser();
+ mContext = context;
launchIntent = AppInfo.makeLaunchIntent(context, info, user);
label = info.getLabel().toString();
@@ -315,16 +328,36 @@
* Initializes a PendingInstallShortcutInfo to represent a launcher target.
*/
public PendingInstallShortcutInfo(ShortcutInfoCompat info, Context context) {
- this.data = null;
- shortcutInfo = info;
- mContext = context;
activityInfo = null;
+ shortcutInfo = info;
+ providerInfo = null;
+
+ data = null;
+ mContext = context;
user = info.getUserHandle();
launchIntent = info.makeIntent(context);
label = info.getShortLabel().toString();
}
+ /**
+ * Initializes a PendingInstallShortcutInfo to represent a launcher target.
+ */
+ public PendingInstallShortcutInfo(
+ AppWidgetProviderInfo info, int widgetId, Context context) {
+ activityInfo = null;
+ shortcutInfo = null;
+ providerInfo = info;
+
+ data = null;
+ mContext = context;
+ user = UserHandleCompat.fromUser(info.getProfile());
+
+ launchIntent = new Intent().setComponent(info.provider)
+ .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
+ label = info.label;
+ }
+
public String encodeToString() {
try {
if (activityInfo != null) {
@@ -347,6 +380,16 @@
.key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
.getSerialNumberForUser(user))
.endObject().toString();
+ } else if (providerInfo != null) {
+ // If it a launcher target, we only need component name, and user to
+ // recreate this.
+ return new JSONStringer()
+ .object()
+ .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
+ .key(APP_WIDGET_TYPE_KEY).value(true)
+ .key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
+ .getSerialNumberForUser(user))
+ .endObject().toString();
}
if (launchIntent.getAction() == null) {
@@ -388,11 +431,24 @@
}
}
- public ShortcutInfo getShortcutInfo() {
+ public ItemInfo getItemInfo() {
if (activityInfo != null) {
return new ShortcutInfo(activityInfo, mContext);
} else if (shortcutInfo != null) {
return new ShortcutInfo(shortcutInfo, mContext);
+ } else if (providerInfo != null) {
+ LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo
+ .fromProviderInfo(mContext, providerInfo);
+ LauncherAppWidgetInfo widgetInfo = new LauncherAppWidgetInfo(
+ launchIntent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0),
+ info.provider);
+ InvariantDeviceProfile idp = LauncherAppState.getInstance()
+ .getInvariantDeviceProfile();
+ widgetInfo.minSpanX = info.minSpanX;
+ widgetInfo.minSpanY = info.minSpanY;
+ widgetInfo.spanX = Math.min(info.spanX, idp.numColumns);
+ widgetInfo.spanY = Math.min(info.spanY, idp.numRows);
+ return widgetInfo;
} else {
return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data);
}
@@ -425,6 +481,16 @@
} else {
return new PendingInstallShortcutInfo(si.get(0), context);
}
+ } else if (decoder.optBoolean(APP_WIDGET_TYPE_KEY)) {
+ int widgetId = decoder.launcherIntent
+ .getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
+ AppWidgetProviderInfo info = AppWidgetManager.getInstance(context)
+ .getAppWidgetInfo(widgetId);
+ if (info == null || !info.provider.equals(decoder.launcherIntent.getComponent()) ||
+ !info.getProfile().equals(decoder.user.getUser())) {
+ return null;
+ }
+ return new PendingInstallShortcutInfo(info, widgetId, context);
}
Intent data = new Intent();
@@ -523,7 +589,7 @@
}
// Generate a shortcut info to add into the model
- installQueue.add(pendingInfo.getShortcutInfo());
+ installQueue.add(pendingInfo.getItemInfo());
}
return installQueue;
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 38545e2..1b0e5b3 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -85,6 +85,7 @@
*/
public int numHotseatIcons;
float hotseatIconSize;
+ public float hotseatScale;
int defaultLayoutId;
DeviceProfile landscapeProfile;
@@ -117,6 +118,8 @@
numHotseatIcons = hs;
hotseatIconSize = his;
defaultLayoutId = dlId;
+
+ hotseatScale = hotseatIconSize / iconSize;
}
@TargetApi(23)
@@ -158,6 +161,8 @@
// 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
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2f7a31f..9215024 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2808,6 +2808,7 @@
}
boolean isHotseatLayout(View layout) {
+ // TODO: Remove this method
return mHotseat != null && layout != null &&
(layout instanceof CellLayout) && (layout == mHotseat.getLayout());
}
@@ -3295,25 +3296,25 @@
* Implementation of the method from LauncherModel.Callbacks.
*/
@Override
- public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,
+ public void bindItems(final ArrayList<ItemInfo> items, final int start, final int end,
final boolean forceAnimateIcons) {
Runnable r = new Runnable() {
public void run() {
- bindItems(shortcuts, start, end, forceAnimateIcons);
+ bindItems(items, start, end, forceAnimateIcons);
}
};
if (waitUntilResume(r)) {
return;
}
- // Get the list of added shortcuts and intersect them with the set of shortcuts here
+ // Get the list of added items and intersect them with the set of items here
final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
final Collection<Animator> bounceAnims = new ArrayList<Animator>();
final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();
Workspace workspace = mWorkspace;
- long newShortcutsScreenId = -1;
+ long newItemsScreenId = -1;
for (int i = start; i < end; i++) {
- final ItemInfo item = shortcuts.get(i);
+ final ItemInfo item = items.get(i);
// Short circuit if we are loading dock items for a configuration which has no dock
if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
@@ -3325,15 +3326,33 @@
switch (item.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+ case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: {
ShortcutInfo info = (ShortcutInfo) item;
view = createShortcut(info);
break;
- case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
+ }
+ case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
view = FolderIcon.fromXml(R.layout.folder_icon, this,
(ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
(FolderInfo) item, mIconCache);
break;
+ }
+ case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: {
+ LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
+ if (mIsSafeModeEnabled) {
+ view = new PendingAppWidgetHostView(this, info, mIconCache, true);
+ } else {
+ LauncherAppWidgetProviderInfo providerInfo =
+ mAppWidgetManager.getLauncherAppWidgetInfo(info.appWidgetId);
+ if (providerInfo == null) {
+ deleteWidgetInfo(info);
+ continue;
+ }
+ view = mAppWidgetHost.createView(this, info.appWidgetId, providerInfo);
+ }
+ prepareAppWidget((AppWidgetHostView) view, info);
+ break;
+ }
default:
throw new RuntimeException("Invalid Item Type");
}
@@ -3364,22 +3383,22 @@
view.setScaleX(0f);
view.setScaleY(0f);
bounceAnims.add(createNewAppBounceAnimation(view, i));
- newShortcutsScreenId = item.screenId;
+ newItemsScreenId = item.screenId;
}
}
if (animateIcons) {
// Animate to the correct page
- if (newShortcutsScreenId > -1) {
+ if (newItemsScreenId > -1) {
long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());
- final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);
+ final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newItemsScreenId);
final Runnable startBounceAnimRunnable = new Runnable() {
public void run() {
anim.playTogether(bounceAnims);
anim.start();
}
};
- if (newShortcutsScreenId != currentScreenId) {
+ if (newItemsScreenId != currentScreenId) {
// We post the animation slightly delayed to prevent slowdowns
// when we are loading right after we return to launcher.
mWorkspace.postDelayed(new Runnable() {
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 342479f..6c73762 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -20,29 +20,19 @@
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 @@
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 @@
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) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 2d4af52..abd2c6c 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1168,7 +1168,7 @@
}
private boolean shouldConsumeTouch(View v) {
- return (workspaceInModalState() || !isFinishedSwitchingState())
+ return !workspaceIconsCanBeDragged()
|| (!workspaceInModalState() && indexOfChild(v) != mCurrentPage);
}
@@ -1835,6 +1835,11 @@
return mState != State.NORMAL;
}
+ /** Returns whether a drag should be allowed to be started from the current workspace state. */
+ public boolean workspaceIconsCanBeDragged() {
+ return mState == State.NORMAL || mState == State.SPRING_LOADED;
+ }
+
@Thunk void updateChildrenLayersEnabled(boolean force) {
boolean small = mState == State.OVERVIEW || mIsSwitchingState;
boolean enableChildrenLayers = force || small || mAnimatingViewIntoPlace || isPageInTransition();
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index c71307d..9a23aa8 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -57,7 +57,7 @@
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 @@
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);
}
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index e71c5e9..8aaeb9e 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -253,11 +253,9 @@
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);
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 97335cb..4cbb087 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -26,6 +26,7 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherModel.Callbacks;
@@ -60,8 +61,8 @@
}
Context context = app.getContext();
- final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>();
- final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
+ final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
+ final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<>();
// Get the list of workspace screens. We need to append to this list and
// can not use sBgWorkspaceScreens because loadWorkspace() may not have been
@@ -77,13 +78,14 @@
}
// Find appropriate space for the item.
- Pair<Long, int[]> coords = findSpaceForItem(
- app, dataModel, workspaceScreens, addedWorkspaceScreensFinal, 1, 1);
+ Pair<Long, int[]> coords = findSpaceForItem(app, dataModel, workspaceScreens,
+ addedWorkspaceScreensFinal, item.spanX, item.spanY);
long screenId = coords.first;
int[] cordinates = coords.second;
ItemInfo itemInfo;
- if (item instanceof ShortcutInfo || item instanceof FolderInfo) {
+ if (item instanceof ShortcutInfo || item instanceof FolderInfo ||
+ item instanceof LauncherAppWidgetInfo) {
itemInfo = item;
} else if (item instanceof AppInfo) {
itemInfo = ((AppInfo) item).makeShortcut();
@@ -95,23 +97,23 @@
addItemToDatabase(context, itemInfo, screenId, cordinates);
// Save the ShortcutInfo for binding in the workspace
- addedShortcutsFinal.add(itemInfo);
+ addedItemsFinal.add(itemInfo);
}
}
// Update the workspace screens
updateScreens(context, workspaceScreens);
- if (!addedShortcutsFinal.isEmpty()) {
+ if (!addedItemsFinal.isEmpty()) {
scheduleCallbackTask(new CallbackTask() {
@Override
public void execute(Callbacks callbacks) {
final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>();
final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>();
- if (!addedShortcutsFinal.isEmpty()) {
- ItemInfo info = addedShortcutsFinal.get(addedShortcutsFinal.size() - 1);
+ if (!addedItemsFinal.isEmpty()) {
+ ItemInfo info = addedItemsFinal.get(addedItemsFinal.size() - 1);
long lastScreenId = info.screenId;
- for (ItemInfo i : addedShortcutsFinal) {
+ for (ItemInfo i : addedItemsFinal) {
if (i.screenId == lastScreenId) {
addAnimated.add(i);
} else {
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 293585d..07f59a5 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -29,11 +29,9 @@
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 @@
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);