summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorMichael Jurka <mikejurka@google.com>2011-01-12 20:24:50 -0800
committerMichael Jurka <mikejurka@google.com>2011-01-13 22:30:59 -0800
commitc5b262ccf639fedac2aff5bb8238342f95396338 (patch)
tree63c4aa5cb378bf9746a700b663461465ff14bcb2 /src/com/android
parentf16e571330f030e445c4f7f63f55d093337ffd87 (diff)
downloadandroid_packages_apps_Trebuchet-c5b262ccf639fedac2aff5bb8238342f95396338.tar.gz
android_packages_apps_Trebuchet-c5b262ccf639fedac2aff5bb8238342f95396338.tar.bz2
android_packages_apps_Trebuchet-c5b262ccf639fedac2aff5bb8238342f95396338.zip
tweaking parallax effect
- adding vertical parallax when switching to all apps/customize mode - added effect to have parallax lag the rest of scrolling - adjusted the amount of horizontal/vertical parallax in both portrait and landscape modes Change-Id: I5ee778f78c1080337f642217bcf828b2392ddf70
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/launcher2/Launcher.java28
-rw-r--r--src/com/android/launcher2/PagedView.java8
-rw-r--r--src/com/android/launcher2/Workspace.java185
3 files changed, 183 insertions, 38 deletions
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index f43f31e93..e5d22996f 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -27,13 +27,13 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.SearchManager;
import android.app.StatusBarManager;
-import android.app.WallpaperManager;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
@@ -77,7 +77,6 @@ import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.method.TextKeyListener;
import android.util.Log;
-import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -309,7 +308,6 @@ public final class Launcher extends Activity
loadHotseats();
checkForLocaleChange();
- setWallpaperDimension();
setContentView(R.layout.launcher);
mHomeCustomizationDrawer = (TabHost) findViewById(R.id.customization_drawer);
if (mHomeCustomizationDrawer != null) {
@@ -547,18 +545,6 @@ public final class Launcher extends Activity
}
}
- private void setWallpaperDimension() {
- WallpaperManager wpm = (WallpaperManager)getSystemService(WALLPAPER_SERVICE);
-
- Display display = getWindowManager().getDefaultDisplay();
- boolean isPortrait = display.getWidth() < display.getHeight();
- // find width and height when in portrait mode
- final int width = isPortrait ? display.getWidth() : display.getHeight();
- final int height = isPortrait ? display.getHeight() : display.getWidth();
- wpm.suggestDesiredDimensions((int) (Math.max(width, height) * 1.5f),
- Math.max(width, height));
- }
-
// Note: This doesn't do all the client-id magic that BrowserProvider does
// in Browser. (http://b/2425179)
private Uri getDefaultBrowserUri() {
@@ -1002,6 +988,7 @@ public final class Launcher extends Activity
workspace.setOnLongClickListener(this);
workspace.setDragController(dragController);
workspace.setLauncher(this);
+ workspace.setWallpaperDimension();
deleteZone.setLauncher(this);
deleteZone.setDragController(dragController);
@@ -1426,8 +1413,10 @@ public final class Launcher extends Activity
}
if (!mWorkspace.isDefaultPageShowing()) {
// on the phone, we don't animate the change to the workspace if all apps is visible
- mWorkspace.moveToDefaultScreen(alreadyOnHome &&
- (LauncherApplication.isScreenXLarge() || mState != State.ALL_APPS));
+ boolean animate = alreadyOnHome &&
+ (LauncherApplication.isScreenXLarge() || mState != State.ALL_APPS);
+ mWorkspace.moveToDefaultScreen(animate);
+ if (!animate) mWorkspace.updateWallpaperOffsetImmediately();
}
showWorkspace(alreadyOnHome);
@@ -2747,6 +2736,8 @@ public final class Launcher extends Activity
toView.setVisibility(View.VISIBLE);
hideAndShowToolbarButtons(toState, null, null);
}
+ mWorkspace.setVerticalWallpaperOffset(toAllApps ?
+ Workspace.WallpaperVerticalOffset.TOP : Workspace.WallpaperVerticalOffset.BOTTOM);
}
/**
@@ -2821,6 +2812,7 @@ public final class Launcher extends Activity
hideAndShowToolbarButtons(State.WORKSPACE, null, null);
}
}
+ mWorkspace.setVerticalWallpaperOffset(Workspace.WallpaperVerticalOffset.MIDDLE);
}
/**
@@ -2898,6 +2890,8 @@ public final class Launcher extends Activity
toView.setVisibility(View.VISIBLE);
hideAndShowToolbarButtons(toState, null, null);
}
+ mWorkspace.setVerticalWallpaperOffset((toState == State.ALL_APPS) ?
+ Workspace.WallpaperVerticalOffset.TOP : Workspace.WallpaperVerticalOffset.BOTTOM);
}
void showAllApps(boolean animated) {
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 6c9aac1db..bb59678f6 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -888,6 +888,14 @@ public abstract class PagedView extends ViewGroup {
invalidate();
}
+ protected float maxOverScroll() {
+ // Using the formula in overScroll, assuming that f = 1.0 (which it should generally not
+ // exceed). Used to find out how much extra wallpaper we need for the overscroll effect
+ float f = 1.0f;
+ f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
+ return OVERSCROLL_DAMP_FACTOR * f;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Skip touch handling if there are no pages to swipe
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index a434eb35c..020f553d7 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -203,6 +203,17 @@ public class Workspace extends SmoothPagedView
private final Camera mCamera = new Camera();
private final float mTempFloat2[] = new float[2];
+ enum WallpaperVerticalOffset { TOP, MIDDLE, BOTTOM };
+ int mWallpaperWidth;
+ int mWallpaperHeight;
+ float mTargetHorizontalWallpaperOffset = 0.0f;
+ float mTargetVerticalWallpaperOffset = 0.5f;
+ float mHorizontalWallpaperOffset = 0.0f;
+ float mVerticalWallpaperOffset = 0.5f;
+ long mLastWallpaperOffsetUpdateTime;
+ boolean mWallpaperOffsetDirty;
+ boolean mUpdateWallpaperOffsetImmediately = false;
+
/**
* Used to inflate the Workspace from XML.
*
@@ -387,17 +398,6 @@ public class Workspace extends SmoothPagedView
}
/**
- * Sets the current screen.
- *
- * @param currentPage
- */
- @Override
- void setCurrentPage(int currentPage) {
- super.setCurrentPage(currentPage);
- updateWallpaperOffset();
- }
-
- /**
* Adds the specified child in the specified screen. The position and dimension of
* the child are defined by x, y, spanX and spanY.
*
@@ -558,23 +558,157 @@ public class Workspace extends SmoothPagedView
Launcher.setScreen(mCurrentPage);
};
- private void updateWallpaperOffset() {
+ // As a ratio of screen height, the total distance we want the parallax effect to span
+ // vertically
+ private float wallpaperTravelToScreenHeightRatio(int width, int height) {
+ return 1.1f;
+ }
+
+ // As a ratio of screen height, the total distance we want the parallax effect to span
+ // horizontally
+ private float wallpaperTravelToScreenWidthRatio(int width, int height) {
+ float aspectRatio = width / (float) height;
+
+ // At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width
+ // At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width
+ // We will use these two data points to extrapolate how much the wallpaper parallax effect
+ // to span (ie travel) at any aspect ratio:
+
+ final float ASPECT_RATIO_LANDSCAPE = 16/10f;
+ final float ASPECT_RATIO_PORTRAIT = 10/16f;
+ final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f;
+ final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f;
+
+ // To find out the desired width at different aspect ratios, we use the following two
+ // formulas, where the coefficient on x is the aspect ratio (width/height):
+ // (16/10)x + y = 1.5
+ // (10/16)x + y = 1.2
+ // We solve for x and y and end up with a final formula:
+ final float x =
+ (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
+ (ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT);
+ final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT;
+ return x * aspectRatio + y;
+ }
+
+ // The range of scroll values for Workspace
+ private int getScrollRange() {
+ return getChildOffset(getChildCount() - 1) - getChildOffset(0);
+ }
+
+ protected void setWallpaperDimension() {
+ WallpaperManager wpm =
+ (WallpaperManager) mLauncher.getSystemService(Context.WALLPAPER_SERVICE);
+
+ Display display = mLauncher.getWindowManager().getDefaultDisplay();
+ final int maxDim = Math.max(display.getWidth(), display.getHeight());
+ final int minDim = Math.min(display.getWidth(), display.getHeight());
+
+ // We need to ensure that there is enough extra space in the wallpaper for the intended
+ // parallax effects
+ mWallpaperWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
+ mWallpaperHeight = (int)(maxDim * wallpaperTravelToScreenHeightRatio(maxDim, minDim));
+ wpm.suggestDesiredDimensions(mWallpaperWidth, mWallpaperHeight);
+ }
+
+ public void setVerticalWallpaperOffset(WallpaperVerticalOffset offsetPosition) {
+ float offset = 0.5f;
+ Display display = mLauncher.getWindowManager().getDefaultDisplay();
+ int wallpaperTravelHeight = (int) (display.getHeight() *
+ wallpaperTravelToScreenHeightRatio(display.getWidth(), display.getHeight()));
+ float offsetFromCenter = (wallpaperTravelHeight / mWallpaperHeight) / 2f;
+ switch (offsetPosition) {
+ case TOP:
+ offset = 0.5f - offsetFromCenter;
+ break;
+ case MIDDLE:
+ offset = 0.5f;
+ break;
+ case BOTTOM:
+ offset = 0.5f + offsetFromCenter;
+ break;
+ }
+ mTargetVerticalWallpaperOffset = offset;
+ mWallpaperOffsetDirty = true;
+ }
+
+ private void updateHorizontalWallpaperOffset() {
if (LauncherApplication.isScreenXLarge()) {
- IBinder token = getWindowToken();
- int scrollRange = getChildOffset(getChildCount() - 1) - getChildOffset(0);
- if (token != null) {
- mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0);
- float offset = mScrollX / (float) scrollRange;
- mWallpaperManager.setWallpaperOffsets(getWindowToken(),
- Math.max(0.f, Math.min(offset, 1.0f)), 0);
- }
+ Display display = mLauncher.getWindowManager().getDefaultDisplay();
+ // The wallpaper travel width is how far, from left to right, the wallpaper will move
+ // at this orientation (for example, in portrait mode we don't move all the way to the
+ // edges of the wallpaper, or otherwise the parallax effect would be too strong)
+ int wallpaperTravelWidth = (int) (display.getWidth() *
+ wallpaperTravelToScreenWidthRatio(display.getWidth(), display.getHeight()));
+
+ // Account for overscroll: you only see the absolute edge of the wallpaper if
+ // you overscroll as far as you can in landscape mode
+ int overscrollOffset = (int) (maxOverScroll() * display.getWidth());
+ float overscrollRatio = overscrollOffset / (float) getScrollRange();
+ int scrollRangeWithOverscroll = getScrollRange() + 2 * overscrollOffset;
+
+ // Set wallpaper offset steps (1 / (number of screens - 1))
+ // We have 3 vertical offset states (centered, and then top/bottom aligned
+ // for all apps/customize)
+ mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 1.0f / (3 - 1));
+
+ float scrollProgress =
+ mScrollX / (float) scrollRangeWithOverscroll + overscrollRatio;
+ float offsetInDips = wallpaperTravelWidth * scrollProgress +
+ (mWallpaperWidth - wallpaperTravelWidth) / 2;
+ float offset = offsetInDips / (float) mWallpaperWidth;
+
+ mTargetHorizontalWallpaperOffset = Math.max(0f, Math.min(offset, 1.0f));
+ mWallpaperOffsetDirty = true;
+ }
+ }
+
+ public void updateWallpaperOffsetImmediately() {
+ mUpdateWallpaperOffsetImmediately = true;
+ }
+
+ private void updateWallpaperOffsets(boolean immediate) {
+ long currentTime = System.currentTimeMillis();
+ long millisecondsSinceLastUpdate = currentTime - mLastWallpaperOffsetUpdateTime;
+ millisecondsSinceLastUpdate = Math.min((long) (1000/30f), millisecondsSinceLastUpdate);
+ millisecondsSinceLastUpdate = Math.min(1L, millisecondsSinceLastUpdate);
+ final float PERCENT_TO_CATCH_UP_IN_100_MS_HORIZONTAL = 25f;
+ final float PERCENT_TO_CATCH_UP_IN_100_MS_VERTICAL = 25f;
+ final float UPDATE_THRESHOLD = 0.0001f;
+ float hOffsetDelta = mTargetHorizontalWallpaperOffset - mHorizontalWallpaperOffset;
+ float vOffsetDelta = mTargetVerticalWallpaperOffset - mVerticalWallpaperOffset;
+ boolean stopUpdating =
+ Math.abs(hOffsetDelta / mTargetHorizontalWallpaperOffset) < UPDATE_THRESHOLD &&
+ Math.abs(vOffsetDelta / mTargetVerticalWallpaperOffset) < UPDATE_THRESHOLD;
+
+ if (stopUpdating || immediate) {
+ mHorizontalWallpaperOffset = mTargetHorizontalWallpaperOffset;
+ mVerticalWallpaperOffset = mTargetVerticalWallpaperOffset;
+ } else {
+ float percentToCatchUpVertical =
+ millisecondsSinceLastUpdate / 100f * PERCENT_TO_CATCH_UP_IN_100_MS_VERTICAL;
+ float percentToCatchUpHorizontal =
+ millisecondsSinceLastUpdate / 100f * PERCENT_TO_CATCH_UP_IN_100_MS_HORIZONTAL;
+ mHorizontalWallpaperOffset += percentToCatchUpHorizontal * hOffsetDelta;
+ mVerticalWallpaperOffset +=
+ percentToCatchUpVertical * (mTargetVerticalWallpaperOffset - mVerticalWallpaperOffset);
}
+ IBinder token = getWindowToken();
+ if (token != null) {
+ mWallpaperManager.setWallpaperOffsets(getWindowToken(),
+ mHorizontalWallpaperOffset, mVerticalWallpaperOffset);
+ }
+ if (!stopUpdating && !immediate) {
+ invalidate();
+ mWallpaperOffsetDirty = true;
+ }
+ mLastWallpaperOffsetUpdateTime = System.currentTimeMillis();
}
@Override
public void computeScroll() {
super.computeScroll();
- updateWallpaperOffset();
+ updateHorizontalWallpaperOffset();
}
public void showOutlines() {
@@ -743,6 +877,9 @@ public class Workspace extends SmoothPagedView
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
+ mUpdateWallpaperOffsetImmediately = true;
+ }
super.onLayout(changed, left, top, right, bottom);
// if shrinkToBottom() is called on initialization, it has to be deferred
@@ -783,6 +920,12 @@ public class Workspace extends SmoothPagedView
@Override
protected void onDraw(Canvas canvas) {
+ if (mWallpaperOffsetDirty) {
+ updateWallpaperOffsets(mUpdateWallpaperOffsetImmediately);
+ mWallpaperOffsetDirty = false;
+ mUpdateWallpaperOffsetImmediately = false;
+ }
+
// Draw the background gradient if necessary
if (mBackground != null && mBackgroundAlpha > 0.0f) {
int alpha = (int) (mBackgroundAlpha * 255);