Merge "Fix stop point for physics in landscape."
diff --git a/src/com/android/launcher2/AllApps3D.java b/src/com/android/launcher2/AllApps3D.java
index d977885..6d0655e 100644
--- a/src/com/android/launcher2/AllApps3D.java
+++ b/src/com/android/launcher2/AllApps3D.java
@@ -120,7 +120,6 @@
private boolean mAnimateNextZoom;
private float mNextZoom;
private float mZoom;
- private float mPosX;
private float mVelocity;
private AAMessage mMessageProc;
@@ -128,6 +127,8 @@
private int mRowsPerPage;
private boolean mSurrendered;
+ private int mRestoreFocusIndex = -1;
+
@SuppressWarnings({"UnusedDeclaration"})
static class Defines {
public static final int ALLOC_PARAMS = 0;
@@ -306,8 +307,7 @@
if (mRollo.mState.iconCount > 0) {
if (mLastSelection == SELECTION_ICONS) {
int selection = mLastSelectedIcon;
- final int firstIcon = Math.round(mPosX) *
- mColumnsPerPage;
+ final int firstIcon = Math.round(mRollo.mScrollPos) * mColumnsPerPage;
if (selection < 0 || // No selection
selection < firstIcon || // off the top of the screen
selection >= mRollo.mState.iconCount || // past last icon
@@ -361,8 +361,7 @@
if (!mArrowNavigation && mRollo.mState.iconCount > 0) {
// Select the first icon when we gain keyboard focus
mArrowNavigation = true;
- mRollo.selectIcon(Math.round(mPosX) * mColumnsPerPage,
- SELECTED_FOCUSED);
+ mRollo.selectIcon(Math.round(mRollo.mScrollPos) * mColumnsPerPage, SELECTED_FOCUSED);
mRollo.mState.save();
}
}
@@ -394,16 +393,18 @@
}
if (iconCount > 0) {
+ final boolean isPortrait = getWidth() < getHeight();
+
mArrowNavigation = true;
int currentSelection = mRollo.mState.selectedIconIndex;
- int currentTopRow = Math.round(mPosX);
+ int currentTopRow = Math.round(mRollo.mScrollPos);
// The column of the current selection, in the range 0..COLUMNS_PER_PAGE_PORTRAIT-1
final int currentPageCol = currentSelection % mColumnsPerPage;
// The row of the current selection, in the range 0..ROWS_PER_PAGE_PORTRAIT-1
- final int currentPageRow = (currentSelection - (currentTopRow* mColumnsPerPage))
+ final int currentPageRow = (currentSelection - (currentTopRow * mColumnsPerPage))
/ mRowsPerPage;
int newSelection = currentSelection;
@@ -411,26 +412,30 @@
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
if (mLastSelection == SELECTION_HOME) {
- mRollo.setHomeSelected(SELECTED_NONE);
- int lastRowCount = iconCount % mColumnsPerPage;
- if (lastRowCount == 0) {
- lastRowCount = mColumnsPerPage;
- }
- newSelection = iconCount - lastRowCount + (mColumnsPerPage / 2);
- if (newSelection >= iconCount) {
- newSelection = iconCount-1;
- }
- int target = (newSelection / mColumnsPerPage)
- - (mRowsPerPage - 1);
- if (target < 0) {
- target = 0;
- }
- if (currentTopRow != target) {
- mRollo.moveTo(target);
+ if (isPortrait) {
+ mRollo.setHomeSelected(SELECTED_NONE);
+ int lastRowCount = iconCount % mColumnsPerPage;
+ if (lastRowCount == 0) {
+ lastRowCount = mColumnsPerPage;
+ }
+ newSelection = iconCount - lastRowCount + (mColumnsPerPage / 2);
+ if (newSelection >= iconCount) {
+ newSelection = iconCount-1;
+ }
+ int target = (newSelection / mColumnsPerPage) - (mRowsPerPage - 1);
+ if (target < 0) {
+ target = 0;
+ }
+ if (currentTopRow != target) {
+ mRollo.moveTo(target);
+ }
}
} else {
if (currentPageRow > 0) {
newSelection = currentSelection - mColumnsPerPage;
+ if (currentTopRow > newSelection / mColumnsPerPage) {
+ mRollo.moveTo(newSelection / mColumnsPerPage);
+ }
} else if (currentTopRow > 0) {
newSelection = currentSelection - mColumnsPerPage;
mRollo.moveTo(newSelection / mColumnsPerPage);
@@ -460,10 +465,9 @@
newSelection = iconCount - 1;
}
if (currentPageRow >= mRowsPerPage - 1) {
- mRollo.moveTo((newSelection / mColumnsPerPage) -
- mRowsPerPage + 1);
+ mRollo.moveTo((newSelection / mColumnsPerPage) - mRowsPerPage + 1);
}
- } else {
+ } else if (isPortrait) {
newSelection = -1;
mRollo.setHomeSelected(SELECTED_FOCUSED);
}
@@ -476,12 +480,20 @@
if (currentPageCol > 0) {
newSelection = currentSelection - 1;
}
+ } else if (!isPortrait) {
+ newSelection = ((int) (mRollo.mScrollPos) * mColumnsPerPage) +
+ (mRowsPerPage / 2 * mColumnsPerPage) + mColumnsPerPage - 1;
+ mRollo.setHomeSelected(SELECTED_NONE);
}
handled = true;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (mLastSelection != SELECTION_HOME) {
- if ((currentPageCol < mColumnsPerPage - 1) &&
+ if (!isPortrait && (currentPageCol == mColumnsPerPage - 1 ||
+ currentSelection == iconCount - 1)) {
+ newSelection = -1;
+ mRollo.setHomeSelected(SELECTED_FOCUSED);
+ } else if ((currentPageCol < mColumnsPerPage - 1) &&
(currentSelection < iconCount - 1)) {
newSelection = currentSelection + 1;
}
@@ -538,7 +550,7 @@
mRollo.clearSelectedIcon();
} else {
mDownIconIndex = mCurrentIconIndex
- = mRollo.selectIcon(x, y, mPosX, SELECTED_PRESSED);
+ = mRollo.selectIcon(x, y, SELECTED_PRESSED);
if (mDownIconIndex < 0) {
// if nothing was selected, no long press.
cancelLongPress();
@@ -567,7 +579,7 @@
if (!mStartedScrolling && slop < mSlop) {
// don't update anything so when we do start scrolling
// below, we get the right delta.
- mCurrentIconIndex = mRollo.chooseTappedIcon(x, y, mPosX);
+ mCurrentIconIndex = mRollo.chooseTappedIcon(x, y);
if (mDownIconIndex != mCurrentIconIndex) {
// If a different icon is selected, don't allow it to be picked up.
// This handles off-axis dragging.
@@ -757,6 +769,13 @@
if (mRollo != null && reload) {
mRollo.setApps(list);
}
+
+ if (hasFocus() && mRestoreFocusIndex != -1) {
+ mRollo.selectIcon(mRestoreFocusIndex, SELECTED_FOCUSED);
+ mRollo.mState.save();
+ mRestoreFocusIndex = -1;
+ }
+
mLocks &= ~LOCK_ICONS_PENDING;
}
@@ -856,7 +875,7 @@
class AAMessage extends RenderScript.RSMessage {
public void run() {
- mPosX = ((float)mData[0]) / (1 << 16);
+ mRollo.mScrollPos = ((float)mData[0]) / (1 << 16);
mVelocity = ((float)mData[1]) / (1 << 16);
mZoom = ((float)mData[2]) / (1 << 16);
mZoomDirty = false;
@@ -905,6 +924,8 @@
private Bitmap mSelectionBitmap;
private Canvas mSelectionCanvas;
+
+ private float mScrollPos;
Params mParams;
State mState;
@@ -923,7 +944,7 @@
private boolean checkClickOK() {
return (Math.abs(mAllApps.mVelocity) < 0.4f) &&
- (Math.abs(mAllApps.mPosX - Math.round(mAllApps.mPosX)) < 0.4f);
+ (Math.abs(mScrollPos - Math.round(mScrollPos)) < 0.4f);
}
void pause() {
@@ -1239,8 +1260,10 @@
}
private void setZoom(float zoom, boolean animate) {
- mRollo.clearSelectedIcon();
- mRollo.setHomeSelected(SELECTED_NONE);
+ if (animate) {
+ mRollo.clearSelectedIcon();
+ mRollo.setHomeSelected(SELECTED_NONE);
+ }
if (zoom > 0.001f) {
mRollo.mState.zoomTarget = zoom;
} else {
@@ -1396,7 +1419,9 @@
mInvokeMoveTo.execute();
}
- int chooseTappedIcon(int x, int y, float pos) {
+ int chooseTappedIcon(int x, int y) {
+ float pos = mScrollPos;
+
// Adjust for scroll position if not zero.
y += (pos - ((int)pos)) * (mTouchYBorders[1] - mTouchYBorders[0]);
@@ -1421,7 +1446,7 @@
return -1;
}
- int index = (((int)pos) * columnsCount) + (row * columnsCount) + col;
+ int index = (((int) pos) * columnsCount) + (row * columnsCount) + col;
if (index >= mState.iconCount) {
return -1;
@@ -1435,8 +1460,8 @@
*
* @return the index of the icon that was selected.
*/
- int selectIcon(int x, int y, float pos, int pressed) {
- final int index = chooseTappedIcon(x, y, pos);
+ int selectIcon(int x, int y, int pressed) {
+ final int index = chooseTappedIcon(x, y);
selectIcon(index, pressed);
return index;
}
@@ -1450,6 +1475,9 @@
void selectIcon(int index, int pressed) {
final ArrayList<ApplicationInfo> appsList = mAllApps.mAllAppsList;
if (appsList == null || index < 0 || index >= appsList.size()) {
+ if (mAllApps != null) {
+ mAllApps.mRestoreFocusIndex = index;
+ }
mState.selectedIconIndex = -1;
if (mAllApps.mLastSelection == SELECTION_ICONS) {
mAllApps.mLastSelection = SELECTION_NONE;
@@ -1560,7 +1588,7 @@
Log.d(TAG, "mZoomDirty=" + mZoomDirty);
Log.d(TAG, "mAnimateNextZoom=" + mAnimateNextZoom);
Log.d(TAG, "mZoom=" + mZoom);
- Log.d(TAG, "mPosX=" + mPosX);
+ Log.d(TAG, "mScrollPos=" + mRollo.mScrollPos);
Log.d(TAG, "mVelocity=" + mVelocity);
Log.d(TAG, "mMessageProc=" + mMessageProc);
if (mRollo != null) {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index f7cb749..1f48f5f 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -551,9 +551,9 @@
mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view);
mAllAppsGrid.setLauncher(this);
mAllAppsGrid.setDragController(dragController);
- ((View)mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.
+ ((View) mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.
// Manage focusability manually since this thing is always visible
- ((View)mAllAppsGrid).setFocusable(false);
+ ((View) mAllAppsGrid).setFocusable(false);
mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
final Workspace workspace = mWorkspace;
@@ -1707,8 +1707,8 @@
void showAllApps(boolean animated) {
mAllAppsGrid.zoom(1.0f, animated);
- ((View)mAllAppsGrid).setFocusable(true);
- ((View)mAllAppsGrid).requestFocus();
+ ((View) mAllAppsGrid).setFocusable(true);
+ ((View) mAllAppsGrid).requestFocus();
// TODO: fade these two too
mDeleteZone.setVisibility(View.GONE);
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 6560c5d..c6813c3 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -624,15 +624,21 @@
/**
* Gets the callbacks object. If we've been stopped, or if the launcher object
- * has somehow been garbage collected, return null instead.
+ * has somehow been garbage collected, return null instead. Pass in the Callbacks
+ * object that was around when the deferred message was scheduled, and if there's
+ * a new Callbacks object around then also return null. This will save us from
+ * calling onto it with data that will be ignored.
*/
- Callbacks tryGetCallbacks() {
+ Callbacks tryGetCallbacks(Callbacks oldCallbacks) {
synchronized (mLock) {
if (mStopped) {
return null;
}
final Callbacks callbacks = mCallbacks.get();
+ if (callbacks != oldCallbacks) {
+ return null;
+ }
if (callbacks == null) {
Log.w(TAG, "no mCallbacks");
return null;
@@ -897,8 +903,8 @@
// Don't use these two variables in any of the callback runnables.
// Otherwise we hold a reference to them.
- Callbacks callbacks = mCallbacks.get();
- if (callbacks == null) {
+ final Callbacks oldCallbacks = mCallbacks.get();
+ if (oldCallbacks == null) {
// This launcher has exited and nobody bothered to tell us. Just bail.
Log.w(TAG, "LoaderThread running with no launcher");
return;
@@ -908,7 +914,7 @@
// Tell the workspace that we're about to start firing items at it
mHandler.post(new Runnable() {
public void run() {
- Callbacks callbacks = tryGetCallbacks();
+ Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.startBinding();
}
@@ -921,7 +927,7 @@
final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i);
mHandler.post(new Runnable() {
public void run() {
- Callbacks callbacks = tryGetCallbacks();
+ Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindItems(mItems, start, start+chunkSize);
}
@@ -930,7 +936,7 @@
}
mHandler.post(new Runnable() {
public void run() {
- Callbacks callbacks = tryGetCallbacks();
+ Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindFolders(mFolders);
}
@@ -949,7 +955,7 @@
// but since getCurrentScreen() just returns the int, we should be okay. This
// is just a hint for the order, and if it's wrong, we'll be okay.
// TODO: instead, we should have that push the current screen into here.
- final int currentScreen = callbacks.getCurrentWorkspaceScreen();
+ final int currentScreen = oldCallbacks.getCurrentWorkspaceScreen();
N = mAppWidgets.size();
// once for the current screen
for (int i=0; i<N; i++) {
@@ -957,7 +963,7 @@
if (widget.screen == currentScreen) {
mHandler.post(new Runnable() {
public void run() {
- Callbacks callbacks = tryGetCallbacks();
+ Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindAppWidget(widget);
}
@@ -971,7 +977,7 @@
if (widget.screen != currentScreen) {
mHandler.post(new Runnable() {
public void run() {
- Callbacks callbacks = tryGetCallbacks();
+ Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindAppWidget(widget);
}
@@ -982,7 +988,7 @@
// Tell the workspace that we're done.
mHandler.post(new Runnable() {
public void run() {
- Callbacks callbacks = tryGetCallbacks();
+ Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.finishBindingItems();
}
@@ -1006,7 +1012,7 @@
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- final Callbacks callbacks = tryGetCallbacks();
+ final Callbacks callbacks = mCallbacks.get();
if (callbacks == null) {
return;
}
@@ -1042,12 +1048,13 @@
= (ArrayList<ApplicationInfo>) mAllAppsList.data.clone();
// We're adding this now, so clear out this so we don't re-send them.
mAllAppsList.added = new ArrayList<ApplicationInfo>();
+ final Callbacks old = mCallbacks.get();
mHandler.post(new Runnable() {
public void run() {
final long t = SystemClock.uptimeMillis();
final int count = results.size();
- Callbacks callbacks = tryGetCallbacks();
+ Callbacks callbacks = tryGetCallbacks(old);
if (callbacks != null) {
callbacks.bindAllApplications(results);
}
@@ -1195,14 +1202,14 @@
} else {
info.customIcon = true;
}
- info.setIcon(icon);
break;
default:
- info.setIcon(getFallbackIcon());
+ icon = getFallbackIcon();
info.usingFallbackIcon = true;
info.customIcon = false;
break;
}
+ info.setIcon(icon);
return info;
}