Merge "Making drop target smaller in landscape."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index feba679..ace53ef 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -74,7 +74,8 @@
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
- android:theme="@style/Theme">
+ android:theme="@style/Theme"
+ android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
diff --git a/res/drawable-hdpi/portal_container_holo.9.png b/res/drawable-hdpi/portal_container_holo.9.png
index a2fbcb6..e2a1bd5 100644
--- a/res/drawable-hdpi/portal_container_holo.9.png
+++ b/res/drawable-hdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/portal_ring_inner_holo.png b/res/drawable-hdpi/portal_ring_inner_holo.png
index e671d1b..cd40594 100644
--- a/res/drawable-hdpi/portal_ring_inner_holo.png
+++ b/res/drawable-hdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/portal_ring_outer_holo.png b/res/drawable-hdpi/portal_ring_outer_holo.png
index 7aad607..1a66a44 100644
--- a/res/drawable-hdpi/portal_ring_outer_holo.png
+++ b/res/drawable-hdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-large-mdpi/portal_container_holo.9.png b/res/drawable-large-mdpi/portal_container_holo.9.png
new file mode 100644
index 0000000..7eef5d7
--- /dev/null
+++ b/res/drawable-large-mdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/portal_ring_inner_holo.png b/res/drawable-large-mdpi/portal_ring_inner_holo.png
new file mode 100644
index 0000000..c22224f
--- /dev/null
+++ b/res/drawable-large-mdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-large-mdpi/portal_ring_outer_holo.png b/res/drawable-large-mdpi/portal_ring_outer_holo.png
new file mode 100644
index 0000000..b94c948
--- /dev/null
+++ b/res/drawable-large-mdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/portal_container_holo.9.png b/res/drawable-mdpi/portal_container_holo.9.png
index d2f9b58..7eef5d7 100644
--- a/res/drawable-mdpi/portal_container_holo.9.png
+++ b/res/drawable-mdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/portal_ring_inner_holo.png b/res/drawable-mdpi/portal_ring_inner_holo.png
index dc0c041..9addb30 100644
--- a/res/drawable-mdpi/portal_ring_inner_holo.png
+++ b/res/drawable-mdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/portal_ring_outer_holo.png b/res/drawable-mdpi/portal_ring_outer_holo.png
index 5a7e740..6103869 100644
--- a/res/drawable-mdpi/portal_ring_outer_holo.png
+++ b/res/drawable-mdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 299095d..548a39e 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -49,7 +49,7 @@
android:paddingTop="@dimen/folder_content_name_gap"
android:paddingBottom="@dimen/folder_padding"
android:background="#00000000"
- android:hint="@string/default_folder_name"
+ android:hint="@string/folder_hint_text"
android:textSize="16sp"
android:textColor="#FFF"
android:gravity="center_horizontal"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d0e4749..2d41791 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -244,5 +244,5 @@
<string name="dream_name">Rocket Launcher</string>
<!-- Default folder title -->
- <string name="default_folder_name">Unnamed Folder</string>
+ <string name="folder_hint_text">Unnamed Folder</string>
</resources>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index e793363..5696b50 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -67,6 +67,11 @@
* The data needed to perform either of the custom AsyncTasks.
*/
class AsyncTaskPageData {
+ enum Type {
+ LoadWidgetPreviewData,
+ LoadHolographicIconsData
+ }
+
AsyncTaskPageData(int p, ArrayList<Object> l, ArrayList<Bitmap> si, AsyncTaskCallback bgR,
AsyncTaskCallback postR) {
page = p;
@@ -103,10 +108,11 @@
* A generic template for an async task used in AppsCustomize.
*/
class AppsCustomizeAsyncTask extends AsyncTask<AsyncTaskPageData, Void, AsyncTaskPageData> {
- AppsCustomizeAsyncTask(int p, AppsCustomizePagedView.ContentType t) {
+ AppsCustomizeAsyncTask(int p, AppsCustomizePagedView.ContentType t, AsyncTaskPageData.Type ty) {
page = p;
pageContentType = t;
threadPriority = Process.THREAD_PRIORITY_DEFAULT;
+ dataType = ty;
}
@Override
protected AsyncTaskPageData doInBackground(AsyncTaskPageData... params) {
@@ -129,6 +135,7 @@
}
// The page that this async task is associated with
+ AsyncTaskPageData.Type dataType;
int page;
AppsCustomizePagedView.ContentType pageContentType;
int threadPriority;
@@ -314,6 +321,7 @@
public void onPackagesUpdated() {
// Get the list of widgets and shortcuts
+ boolean wasEmpty = mWidgets.isEmpty() && mShortcuts.isEmpty();
mWidgets.clear();
mShortcuts.clear();
List<AppWidgetProviderInfo> widgets =
@@ -327,9 +335,13 @@
mWidgets.addAll(widgets);
mShortcuts.addAll(shortcuts);
- // The next layout pass will trigger data-ready if both widgets and apps are set, so request
- // a layout to do this test and invalidate the page data when ready.
- if (testDataReady()) requestLayout();
+ if (wasEmpty) {
+ // The next layout pass will trigger data-ready if both widgets and apps are set, so request
+ // a layout to do this test and invalidate the page data when ready.
+ if (testDataReady()) requestLayout();
+ } else {
+ invalidatePageData();
+ }
}
@Override
@@ -548,6 +560,7 @@
int startIndex = page * numCells;
int endIndex = Math.min(startIndex + numCells, mApps.size());
PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
+
layout.removeAllViewsOnPage();
ArrayList<Object> items = new ArrayList<Object>();
ArrayList<Bitmap> images = new ArrayList<Bitmap>();
@@ -604,7 +617,8 @@
while (iter.hasNext()) {
AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
int taskPage = task.page;
- if (taskPage < getAssociatedLowerPageBound(mCurrentPage) ||
+ if ((taskPage == page) ||
+ taskPage < getAssociatedLowerPageBound(mCurrentPage) ||
taskPage > getAssociatedUpperPageBound(mCurrentPage)) {
task.cancel(false);
iter.remove();
@@ -650,6 +664,7 @@
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
mRunningTasks.remove(task);
+ if (task.isCancelled()) return;
if (task.page > getPageCount()) return;
if (task.pageContentType != mContentType) return;
onSyncWidgetPageItems(data);
@@ -657,7 +672,8 @@
});
// Ensure that the task is appropriately prioritized and runs in parallel
- AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page, mContentType);
+ AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page, mContentType,
+ AsyncTaskPageData.Type.LoadWidgetPreviewData);
t.setThreadPriority(getThreadPriorityForPage(page));
t.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pageData);
mRunningTasks.add(t);
@@ -667,6 +683,18 @@
*/
private void prepareGenerateHoloOutlinesTask(int page, ArrayList<Object> items,
ArrayList<Bitmap> images) {
+ // Prune old tasks for this page
+ Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
+ while (iter.hasNext()) {
+ AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
+ int taskPage = task.page;
+ if ((taskPage == page) &&
+ (task.dataType == AsyncTaskPageData.Type.LoadHolographicIconsData)) {
+ task.cancel(false);
+ iter.remove();
+ }
+ }
+
AsyncTaskPageData pageData = new AsyncTaskPageData(page, items, images,
new AsyncTaskCallback() {
@Override
@@ -700,6 +728,7 @@
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
mRunningTasks.remove(task);
+ if (task.isCancelled()) return;
if (task.page > getPageCount()) return;
if (task.pageContentType != mContentType) return;
onHolographicPageItemsLoaded(data);
@@ -708,7 +737,8 @@
// Ensure that the outline task always runs in the background, serially
AppsCustomizeAsyncTask t =
- new AppsCustomizeAsyncTask(page, mContentType);
+ new AppsCustomizeAsyncTask(page, mContentType,
+ AsyncTaskPageData.Type.LoadHolographicIconsData);
t.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
t.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, pageData);
mRunningTasks.add(t);
@@ -939,12 +969,14 @@
if (layout instanceof PagedViewCellLayout) {
PagedViewCellLayout cl = (PagedViewCellLayout) layout;
int count = cl.getPageChildCount();
+ if (count != data.generatedImages.size()) return;
for (int i = 0; i < count; ++i) {
PagedViewIcon icon = (PagedViewIcon) cl.getChildOnPageAt(i);
icon.setHolographicOutline(data.generatedImages.get(i));
}
} else {
int count = layout.getChildCount();
+ if (count != data.generatedImages.size()) return;
for (int i = 0; i < count; ++i) {
View v = layout.getChildAt(i);
((PagedViewWidget) v).setHolographicOutline(data.generatedImages.get(i));
@@ -955,6 +987,15 @@
@Override
public void syncPages() {
removeAllViews();
+
+ // Remove all background asyc tasks if we are loading content anew
+ Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
+ while (iter.hasNext()) {
+ AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
+ task.cancel(false);
+ iter.remove();
+ }
+
switch (mContentType) {
case Applications:
syncAppsPages();
@@ -1037,8 +1078,8 @@
mApps = list;
Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
- // The next layout pass will trigger data-ready if both widgets and apps are set, so request
- // a layout to do this test and invalidate the page data when ready.
+ // The next layout pass will trigger data-ready if both widgets and apps are set, so
+ // request a layout to do this test and invalidate the page data when ready.
if (testDataReady()) requestLayout();
}
private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 8182b82..68e9edb 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -573,10 +573,6 @@
}
}
- public boolean getAcceptsDrops() {
- return mAcceptsDrops;
- }
-
@Override
public void removeAllViews() {
clearOccupiedCells();
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 0454430..80428fa 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -99,12 +99,14 @@
private Alarm mOnExitAlarm = new Alarm();
private TextView mFolderName;
private int mFolderNameHeight;
- private static String sDefaultFolderName;
private Rect mHitRect = new Rect();
private boolean mIsEditingName = false;
private InputMethodManager mInputMethodManager;
+ private static String sDefaultFolderName;
+ private static String sHintText;
+
/**
* Used to inflate the Workspace from XML.
*
@@ -128,6 +130,9 @@
if (sDefaultFolderName == null) {
sDefaultFolderName = res.getString(R.string.folder_name);
}
+ if (sHintText == null) {
+ sHintText = res.getString(R.string.folder_hint_text);
+ }
}
@Override
@@ -229,6 +234,7 @@
}
public void startEditingFolderName() {
+ mFolderName.setHint("");
mFolderName.setCursorVisible(true);
mIsEditingName = true;
}
@@ -239,6 +245,7 @@
}
public void doneEditingFolderName(boolean commit) {
+ mFolderName.setHint(sHintText);
mInfo.setTitle(mFolderName.getText());
LauncherModel.updateItemInDatabase(mLauncher, mInfo);
mFolderName.setCursorVisible(false);
@@ -321,11 +328,23 @@
void bind(FolderInfo info) {
mInfo = info;
ArrayList<ShortcutInfo> children = info.contents;
+ ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>();
setupContentForNumItems(children.size());
for (int i = 0; i < children.size(); i++) {
ShortcutInfo child = (ShortcutInfo) children.get(i);
- createAndAddShortcut(child);
+ if (!createAndAddShortcut(child)) {
+ overflow.add(child);
+ }
}
+
+ // If our folder has too many items we prune them from the list. This is an issue
+ // when upgrading from the old Folders implementation which could contain an unlimited
+ // number of items.
+ for (ShortcutInfo item: overflow) {
+ mInfo.remove(item);
+ LauncherModel.deleteItemFromDatabase(mLauncher, item);
+ }
+
mItemsInvalidated = true;
mInfo.addListener(this);
@@ -492,7 +511,7 @@
}
}
- protected void createAndAddShortcut(ShortcutInfo item) {
+ protected boolean createAndAddShortcut(ShortcutInfo item) {
final TextView textView =
(TextView) mInflater.inflate(R.layout.application_boxed, this, false);
textView.setCompoundDrawablesWithIntrinsicBounds(null,
@@ -503,10 +522,21 @@
textView.setOnClickListener(this);
textView.setOnLongClickListener(this);
+ // We need to check here to verify that the given item's location isn't already occupied
+ // by another item. If it is, we need to find the next available slot and assign
+ // it that position. This is an issue when upgrading from the old Folders implementation
+ // which could contain an unlimited number of items.
+ if (mContent.getChildAt(item.cellX, item.cellY) != null) {
+ if (!findAndSetEmptyCells(item)) {
+ return false;
+ }
+ }
+
CellLayout.LayoutParams lp =
new CellLayout.LayoutParams(item.cellX, item.cellY, item.spanX, item.spanY);
boolean insert = false;
mContent.addViewToCellLayout(textView, insert ? 0 : -1, (int)item.id, lp, true);
+ return true;
}
public void onDragEnter(DragObject d) {
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 7fa96fb..a4e162f 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -1417,9 +1417,6 @@
}
// Stop any scrolling, move to the current page right away
setCurrentPage((mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage);
- if (!mIsDragInProcess) {
- updateWhichPagesAcceptDrops(shrinkState);
- }
// Hide the scrollbar
hideScrollingIndicator(true);
@@ -1701,46 +1698,6 @@
private final ZoomOutInterpolator mZoomOutInterpolator = new ZoomOutInterpolator();
private final ZoomInInterpolator mZoomInInterpolator = new ZoomInInterpolator();
- private void updateWhichPagesAcceptDrops(ShrinkState state) {
- updateWhichPagesAcceptDropsHelper(state, false, 1, 1);
- }
-
- private void updateWhichPagesAcceptDropsDuringDrag(ShrinkState state, int spanX, int spanY) {
- updateWhichPagesAcceptDropsHelper(state, true, spanX, spanY);
- }
-
- private void updateWhichPagesAcceptDropsHelper(
- ShrinkState state, boolean isDragHappening, int spanX, int spanY) {
- final int screenCount = getChildCount();
- for (int i = 0; i < screenCount; i++) {
- CellLayout cl = (CellLayout) getChildAt(i);
- cl.setIsDragOccuring(isDragHappening);
- if (state == null) {
- // If we are not in a shrunken state, mark all cell layouts as droppable (if they
- // have the space)
- cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY));
- } else {
- switch (state) {
- case BOTTOM_HIDDEN:
- case BOTTOM_VISIBLE:
- case SPRING_LOADED:
- cl.setIsDefaultDropTarget(false);
- if (!isDragHappening) {
- // even if a drag isn't happening, we don't want to show a screen as
- // accepting drops if it doesn't have at least one free cell
- spanX = 1;
- spanY = 1;
- }
- // the page accepts drops if we can find at least one empty spot
- cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY));
- break;
- default:
- throw new RuntimeException("Unhandled ShrinkState " + state);
- }
- }
- }
- }
-
/*
*
* We call these methods (onDragStartedWithItemSpans/onDragStartedWithSize) whenever we
@@ -1776,8 +1733,6 @@
// The outline is used to visualize where the item will land if dropped
mDragOutline = createDragOutline(b, canvas, bitmapPadding, size[0], size[1]);
-
- updateWhichPagesAcceptDropsDuringDrag(mShrinkState, spanX, spanY);
}
// we call this method whenever a drag and drop in Launcher finishes, even if Workspace was
@@ -1789,7 +1744,6 @@
doDragExit(null);
}
mIsDragInProcess = false;
- updateWhichPagesAcceptDrops(mShrinkState);
}
// We call this when we trigger an unshrink by clicking on the CellLayout cl
@@ -2308,18 +2262,31 @@
* {@inheritDoc}
*/
public boolean acceptDrop(DragObject d) {
-
// If it's an external drop (e.g. from All Apps), check if it should be accepted
if (d.dragSource != this) {
// Don't accept the drop if we're not over a screen at time of drop
- if (mDragTargetLayout == null || !mDragTargetLayout.getAcceptsDrops()) {
+ if (mDragTargetLayout == null) {
return false;
}
+ mDragViewVisualCenter = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset,
+ d.dragView, mDragViewVisualCenter);
+
final CellLayout.CellInfo dragCellInfo = mDragInfo;
final int spanX = dragCellInfo == null ? 1 : dragCellInfo.spanX;
final int spanY = dragCellInfo == null ? 1 : dragCellInfo.spanY;
+ mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
+ (int) mDragViewVisualCenter[1], spanX, spanY, mDragTargetLayout, mTargetCell);
+
+ if (willCreateUserFolder((ItemInfo) d.dragInfo, mDragTargetLayout, mTargetCell, true)) {
+ return true;
+ }
+ if (willAddToExistingUserFolder((ItemInfo) d.dragInfo, mDragTargetLayout,
+ mTargetCell)) {
+ return true;
+ }
+
final View ignoreView = dragCellInfo == null ? null : dragCellInfo.cell;
// Don't accept the drop if there's no room for the item
@@ -2331,13 +2298,18 @@
return true;
}
- boolean willCreateUserFolder(ItemInfo info, View v, int[] targetCell) {
+ boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell,
+ boolean considerTimeout) {
+ View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
+
boolean hasntMoved = mDragInfo != null
&& (mDragInfo.cellX == targetCell[0] && mDragInfo.cellY == targetCell[1]);
- if (v == null || hasntMoved) return false;
+ if (dropOverView == null || hasntMoved || (considerTimeout && !mCreateUserFolderOnDrop)) {
+ return false;
+ }
- boolean aboveShortcut = (v.getTag() instanceof ShortcutInfo);
+ boolean aboveShortcut = (dropOverView.getTag() instanceof ShortcutInfo);
boolean willBecomeShortcut =
(info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT);
@@ -2345,6 +2317,17 @@
return (aboveShortcut && willBecomeShortcut);
}
+ boolean willAddToExistingUserFolder(Object dragInfo, CellLayout target, int[] targetCell) {
+ View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
+ if (dropOverView instanceof FolderIcon) {
+ FolderIcon fi = (FolderIcon) dropOverView;
+ if (fi.acceptDrop(dragInfo)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
boolean createUserFolderIfNecessary(View newView, CellLayout target,
int[] targetCell, boolean external) {
View v = target.getChildAt(targetCell[0], targetCell[1]);
@@ -2381,9 +2364,9 @@
return false;
}
- boolean addToExistingFolderIfNecessary(View newView, CellLayout target, int[] tagetCell,
+ boolean addToExistingFolderIfNecessary(View newView, CellLayout target, int[] targetCell,
Object dragInfo, boolean external) {
- View dropOverView = target.getChildAt(tagetCell[0], tagetCell[1]);
+ View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
if (dropOverView instanceof FolderIcon) {
FolderIcon fi = (FolderIcon) dropOverView;
if (fi.acceptDrop(dragInfo)) {
@@ -2402,7 +2385,6 @@
}
public void onDrop(DragObject d) {
-
mDragViewVisualCenter = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, d.dragView,
mDragViewVisualCenter);
@@ -2902,8 +2884,7 @@
// full screen (which is traditionally set to not accept drops) if they want
// to get to pages beyond the screen that is full.
boolean isInSpringLoadedMode = (mShrinkState == ShrinkState.SPRING_LOADED);
- boolean allowDragOver = (mDragTargetLayout != null) &&
- (mDragTargetLayout.getAcceptsDrops() || isInSpringLoadedMode);
+ boolean allowDragOver = (mDragTargetLayout != null);
if (allowDragOver) {
if (isInSpringLoadedMode) {
mSpringLoadedDragController.setAlarm(mDragTargetLayout);
@@ -2948,8 +2929,8 @@
final View dragOverView = mDragTargetLayout.getChildAt(mTargetCell[0],
mTargetCell[1]);
- boolean userFolderPending = willCreateUserFolder(info, dragOverView,
- mTargetCell);
+ boolean userFolderPending = willCreateUserFolder(info, mDragTargetLayout,
+ mTargetCell, false);
boolean isOverFolder = dragOverView instanceof FolderIcon;
if (dragOverView != mLastDragOverView) {
cancelFolderCreation();