am 4aed0267: Merge change 24695 into eclair

Merge commit '4aed02675d314697368e879781314f28507d5563'

* commit '4aed02675d314697368e879781314f28507d5563':
  Add the animation for when you enter the all apps view.
This commit is contained in:
Joe Onorato 2009-09-15 13:13:12 -07:00 committed by Android Git Automerger
commit 737f63dff8
8 changed files with 451 additions and 70 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -48,39 +48,29 @@
</com.android.launcher2.Workspace>
<LinearLayout
android:id="@+id/buttons"
android:layout_width="fill_parent"
android:layout_height="56dip"
android:layout_gravity="bottom"
<com.android.launcher2.HandleView
android:id="@+id/all_apps_button"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_bar_height"
android:layout_gravity="bottom|center_horizontal"
android:gravity="right"
>
android:focusable="true"
android:clickable="true"
<com.android.launcher2.HandleView
android:id="@+id/all_apps_button"
android:layout_width="@dimen/button_bar_height"
android:layout_height="@dimen/button_bar_height"
android:focusable="true"
android:clickable="true"
android:scaleType="center"
android:src="@drawable/all_apps_button"
launcher:direction="horizontal" />
</LinearLayout>
android:scaleType="center"
android:src="@drawable/all_apps_button"
launcher:direction="horizontal" />
<com.android.launcher2.DeleteZone
android:id="@+id/delete_zone"
android:layout_width="wrap_content"
android:layout_height="49dip"
android:layout_gravity="bottom|center_horizontal"
android:scaleType="center"
android:src="@drawable/ic_delete"
android:background="@drawable/delete_zone_selector"
android:layout_gravity="bottom|center_horizontal"
android:visibility="invisible"
launcher:direction="horizontal" />

View File

@ -34,6 +34,7 @@
#define STATE_SELECTED_ICON_TEXTURE 10
#define STATE_VISIBLE 11
#define STATE_ZOOM 12
// Drawing constants, should be parameters ======
#define VIEW_ANGLE 1.28700222f
@ -67,6 +68,8 @@ draw_page(int icon, int lastIcon, float centerAngle)
int row;
int col;
float scale = 1.0f - loadI32(ALLOC_STATE, STATE_ZOOM)/100000.0f;
float iconTextureWidth = ICON_WIDTH_PX / (float)ICON_TEXTURE_WIDTH_PX;
float iconTextureHeight = ICON_HEIGHT_PX / (float)ICON_TEXTURE_HEIGHT_PX;
@ -110,6 +113,7 @@ draw_page(int icon, int lastIcon, float centerAngle)
float centerX = sine * RADIUS;
float centerZ = cosine * RADIUS;
centerZ -= (7*scale);
float iconLeftX = centerX - (cosine * farIconTextureSize * .5);
float iconRightX = centerX + (cosine * farIconTextureSize * .5);
@ -133,15 +137,17 @@ draw_page(int icon, int lastIcon, float centerAngle)
iconLeftX, iconTextureBottom, iconLeftZ, 0.0f, 1.0f);
// label
float labelLeftX = centerX - farLabelWidth * 0.5f;
float labelRightX = centerX + farLabelWidth * 0.5f;
if (scale <= 1.04f) {
float labelLeftX = centerX - farLabelWidth * 0.5f;
float labelRightX = centerX + farLabelWidth * 0.5f;
bindTexture(NAMED_PF, 0, loadI32(ALLOC_LABEL_IDS, icon));
drawQuadTexCoords(
labelLeftX, labelTop, centerZ, 0.0f, 0.0f,
labelRightX, labelTop, centerZ, labelTextureWidth, 0.0f,
labelRightX, labelBottom, centerZ, labelTextureWidth, labelTextureHeight,
labelLeftX, labelBottom, centerZ, 0.0f, labelTextureHeight);
bindTexture(NAMED_PF, 0, loadI32(ALLOC_LABEL_IDS, icon));
drawQuadTexCoords(
labelLeftX, labelTop, centerZ, 0.0f, 0.0f,
labelRightX, labelTop, centerZ, labelTextureWidth, 0.0f,
labelRightX, labelBottom, centerZ, labelTextureWidth, labelTextureHeight,
labelLeftX, labelBottom, centerZ, 0.0f, labelTextureHeight);
}
angle += columnGutterAngle + iconWidthAngle;
icon++;
@ -269,6 +275,8 @@ main(int launchID)
scrollXPx = loadF(ALLOC_STATE, STATE_FLING_END_POS);
done = 1;
}
} else {
done = 1;
}
// Clamp

View File

@ -66,6 +66,7 @@ public class AllAppsView extends RSSurfaceView
private Launcher mLauncher;
private DragController mDragController;
private boolean mLocked = true;
private RenderScript mRS;
private RolloRS mRollo;
@ -163,12 +164,16 @@ public class AllAppsView extends RSSurfaceView
@Override
public boolean onTouchEvent(MotionEvent ev)
{
super.onTouchEvent(ev);
if (mRollo.mState.visible == 0) {
return false;
return true;
}
if (mLocked) {
return true;
}
super.onTouchEvent(ev);
mTouchHandler = mFlingHandler;
/*
int action = ev.getAction();
@ -287,15 +292,31 @@ public class AllAppsView extends RSSurfaceView
public void onDropCompleted(View target, boolean success) {
}
private static final int SCALE_SCALE = 100000;
public void show() {
mRollo.mState.read();
mRollo.mState.visible = 1;
mRollo.mState.zoom = SCALE_SCALE;
mRollo.mState.save();
}
public void hide(boolean animate) {
public void setScale(float amount) {
mRollo.mState.read();
if (amount > 0.001f) {
mRollo.mState.visible = 1;
mRollo.mState.zoom = (int)(SCALE_SCALE*amount);
} else {
mRollo.mState.visible = 0;
mRollo.mState.zoom = 0;
}
mRollo.mState.save();
}
public void hide() {
mRollo.mState.read();
mRollo.mState.visible = 0;
mRollo.mState.zoom = 0;
mRollo.mState.save();
}
@ -341,6 +362,7 @@ public class AllAppsView extends RSSurfaceView
}
mPageCount = countPages(list.size());
Log.d(TAG, "setApps mRollo=" + mRollo + " list=" + list);
mLocked = false;
}
private void invokeIcon(int index) {
@ -427,6 +449,7 @@ public class AllAppsView extends RSSurfaceView
@AllocationIndex(9) public int selectedIconIndex = -1;
@AllocationIndex(10) public int selectedIconTexture;
@AllocationIndex(11) public int visible;
@AllocationIndex(12) public int zoom;
}
public RolloRS() {

View File

@ -40,8 +40,17 @@ import android.widget.FrameLayout;
* A ViewGroup that coordinated dragging across its dscendants
*/
public class DragLayer extends FrameLayout {
private static final String TAG = "Launcher.DragLayer";
private static final int DRAG = 1;
private static final int SWIPE = 2;
private static final int BOTH = DRAG | SWIPE;
DragController mDragController;
SwipeController mSwipeController;
private int mAllowed = BOTH;
/**
* Used to create a new DragLayer from XML.
@ -57,6 +66,10 @@ public class DragLayer extends FrameLayout {
mDragController = controller;
}
public void setSwipeController(SwipeController controller) {
mSwipeController = controller;
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
@ -64,11 +77,47 @@ public class DragLayer extends FrameLayout {
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mDragController.onInterceptTouchEvent(ev);
boolean result = false;
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mAllowed = BOTH;
}
if ((mAllowed & DRAG) != 0) {
result = mDragController.onInterceptTouchEvent(ev);
if (result) {
mAllowed = DRAG;
}
}
if ((mAllowed & SWIPE) != 0) {
result = mSwipeController.onInterceptTouchEvent(ev);
if (result) {
mAllowed = SWIPE;
}
}
return result;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return mDragController.onTouchEvent(ev);
boolean result = false;
if ((mAllowed & DRAG) != 0) {
result = mDragController.onTouchEvent(ev);
if (result) {
mAllowed = DRAG;
}
}
if ((mAllowed & SWIPE) != 0) {
result = mSwipeController.onTouchEvent(ev);
if (result) {
mAllowed = SWIPE;
}
}
return result;
}
}

View File

@ -82,7 +82,8 @@ import java.io.DataInputStream;
* Default launcher application.
*/
public final class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks {
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
SwipeController.SwipeListener {
static final String LOG_TAG = "Launcher";
static final String TAG = LOG_TAG;
static final boolean LOGD = false;
@ -108,6 +109,10 @@ public final class Launcher extends Activity
private static final int REQUEST_PICK_LIVE_FOLDER = 8;
private static final int REQUEST_PICK_APPWIDGET = 9;
private static final int MODE_WORKSPACE = 0;
private static final int MODE_ALL_APPS = 1;
private static final int MODE_ALL_APPS_ZOOMED = 2;
static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
static final String EXTRA_CUSTOM_WIDGET = "custom_widget";
@ -158,6 +163,7 @@ public final class Launcher extends Activity
private LayoutInflater mInflater;
private DragController mDragController;
private SwipeController mSwipeController;
private Workspace mWorkspace;
private AppWidgetManager mAppWidgetManager;
@ -171,7 +177,8 @@ public final class Launcher extends Activity
private DeleteZone mDeleteZone;
private HandleView mHandleView;
private AllAppsView mAllAppsGrid;
private boolean mAllAppsVisible;
private boolean mAllAppsVisible; // if it's visible at all
private int mMode = MODE_WORKSPACE;
private Bundle mSavedState;
@ -515,13 +522,18 @@ public final class Launcher extends Activity
private void setupViews() {
mDragController = new DragController(this);
DragController dragController = mDragController;
mSwipeController = new SwipeController(this, this);
SwipeController swipeController = mSwipeController;
swipeController.setRange(-1, 0);
DragLayer dragLayer = (DragLayer) findViewById(R.id.drag_layer);
dragLayer.setDragController(dragController);
dragLayer.setSwipeController(swipeController);
mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view);
mAllAppsGrid.setLauncher(this);
mAllAppsGrid.setDragController(dragController);
mAllAppsGrid.setWillNotDraw(false); // We don't want a hole punched in our window.
mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
final Workspace workspace = mWorkspace;
@ -1422,6 +1434,7 @@ public final class Launcher extends Activity
}
if (mWorkspace.allowLongPress()) {
mSwipeController.cancelSwipe();
if (cellInfo.cell == null) {
if (cellInfo.valid) {
// User long pressed on empty space
@ -1607,7 +1620,7 @@ public final class Launcher extends Activity
void closeAllAppsDialog(boolean animated) {
if (mAllAppsVisible) {
Log.d(LOG_TAG, "closing all apps");
mAllAppsGrid.hide(animated);
mAllAppsGrid.hide();
mAllAppsVisible = false;
mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
mWorkspace.show();
@ -1743,6 +1756,89 @@ public final class Launcher extends Activity
}
}
/**
* Implementation of the method from SwipeController.SwipeListener.
*/
public void onStartSwipe() {
switch (mMode) {
case MODE_WORKSPACE:
mWorkspace.enableChildrenCache();
break;
case MODE_ALL_APPS:
break;
case MODE_ALL_APPS_ZOOMED:
break;
}
}
/**
* Implementation of the method from SwipeController.SwipeListener.
*
* @param amount The final value of the swipe (-1, 0 or 1)
*/
public void onFinishSwipe(int amount) {
switch (mMode) {
case MODE_WORKSPACE:
if (amount == -1) {
mWorkspace.clearChildrenCache();
mMode = MODE_ALL_APPS;
mSwipeController.setRange(0, 1);
}
break;
case MODE_ALL_APPS:
if (amount == 1) {
mWorkspace.clearChildrenCache();
mMode = MODE_WORKSPACE;
mSwipeController.setRange(-1, 0);
}
break;
case MODE_ALL_APPS_ZOOMED:
break;
}
}
/**
* Implementation of the method from SwipeController.SwipeListener.
*/
public void onSwipe(float amount) {
switch (mMode) {
case MODE_WORKSPACE:
// We can open the all apps view.
// 0 == workspace is showing
// -1 == all apps is showing
setWorkspaceAndAllAppsScale(-amount);
break;
case MODE_ALL_APPS:
// We can close it, or (someday) zoom it further
// 0 == all apps showing
// 1 == workspace is showing
setWorkspaceAndAllAppsScale(1-amount);
break;
}
}
/**
* Set the scale factor for the workspace and the all apps grid.
*
* @param amount A float between 0 and 1, where:
* 0 == workspace is showing and
* 1 == the all apps grid is showing.
*/
private void setWorkspaceAndAllAppsScale(float amount) {
//Log.d("setWorkspaceAndAllAppsScale", "setWorkspaceAndAllAppsScale amount=" + amount);
if (amount < 0.001f) {
amount = 0.0f;
}
if (amount > 0.999f) {
amount = 1.0f;
mWorkspace.setVisibility(View.INVISIBLE);
} else {
mWorkspace.setVisibility(View.VISIBLE);
}
mWorkspace.setScale(1-amount);
mAllAppsGrid.setScale(amount);
}
/**
* Implementation of the method from LauncherModel.Callbacks.
*/

View File

@ -0,0 +1,222 @@
/*
* Copyright (C) 2008 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.launcher2;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import java.util.ArrayList;
public class SwipeController {
private static final String TAG = "Launcher.SwipeController";
private static final int FRAME_DELAY = 1000 / 30;
private static final float DECAY_CONSTANT = 0.65f;
private static final float SPRING_CONSTANT = 0.0009f;
// configuration
private SwipeListener mListener;
private int mSlop;
private float mSwipeDistance;
// state
private VelocityTracker mVelocityTracker;
private boolean mCanceled;
private boolean mTracking;
private int mDownX;
private int mDownY;
private float mMinDest;
private float mMaxDest;
private long mFlingTime;
private long mLastTime;
private int mDirection;
private float mVelocity;
private float mDest;
private float mAmount;
public interface SwipeListener {
public void onStartSwipe();
public void onFinishSwipe(int amount);
public void onSwipe(float amount);
}
public SwipeController(Context context, SwipeListener listener) {
ViewConfiguration config = ViewConfiguration.get(context);
mSlop = config.getScaledTouchSlop();
DisplayMetrics display = context.getResources().getDisplayMetrics();
mSwipeDistance = display.heightPixels / 2; // one half of the screen
mListener = listener;
}
public void setRange(float min, float max) {
mMinDest = min;
mMaxDest = max;
}
public void cancelSwipe() {
mCanceled = true;
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
onTouchEvent(ev);
// After we return true, onIntercept doesn't get called any more, so this is
// a good place to do the callback.
if (mTracking) {
mListener.onStartSwipe();
}
return mTracking;
}
public boolean onTouchEvent(MotionEvent ev) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final int screenX = (int)ev.getRawX();
final int screenY = (int)ev.getRawY();
final int deltaX = screenX - mDownX;
final int deltaY = screenY - mDownY;
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Remember location of down touch
mCanceled = false;
mTracking = false;
mDownX = screenX;
mDownY = screenY;
break;
case MotionEvent.ACTION_MOVE:
if (!mCanceled && !mTracking) {
if (Math.abs(deltaX) > mSlop) {
mCanceled = true;
mTracking = false;
}
if (Math.abs(deltaY) > mSlop) {
mTracking = true;
}
}
if (mTracking && !mCanceled) {
track(screenY);
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (mTracking && !mCanceled) {
fling(screenY);
}
mVelocityTracker.recycle();
mVelocityTracker = null;
break;
}
return mTracking || mCanceled;
}
private float clamp(float v) {
if (v < mMinDest) {
return mMinDest;
} else if (v > mMaxDest) {
return mMaxDest;
} else {
return v;
}
}
/**
* Perform the callbacks.
*/
private void track(int screenY) {
mAmount = clamp((screenY - mDownY) / mSwipeDistance);
mListener.onSwipe(mAmount);
}
private void fling(int screenY) {
mVelocityTracker.computeCurrentVelocity(1);
mVelocity = mVelocityTracker.getYVelocity() / mSwipeDistance;
mDirection = mVelocity >= 0.0f ? 1 : -1;
mAmount = clamp((screenY-mDownY)/mSwipeDistance);
if (mAmount < 0) {
mDest = clamp(mVelocity < 0 ? -1.0f : 0.0f);
} else {
mDest = clamp(mVelocity < 0 ? 0.0f : 1.0f);
}
mFlingTime = SystemClock.uptimeMillis();
mLastTime = 0;
scheduleAnim();
}
private void scheduleAnim() {
boolean send = true;
if (mDirection > 0) {
if (mAmount > (mDest - 0.01f)) {
send = false;
}
} else {
if (mAmount < (mDest + 0.01f)) {
send = false;
}
}
if (send) {
mHandler.sendEmptyMessageDelayed(1, FRAME_DELAY);
} else {
mListener.onFinishSwipe((int)(mAmount >= 0 ? (mAmount+0.5f) : (mAmount-0.5f)));
}
}
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
long now = SystemClock.uptimeMillis();
final long t = now - mFlingTime;
final long dt = t - mLastTime;
mLastTime = t;
final float timeSlices = dt / (float)FRAME_DELAY;
float distance = mDest - mAmount;
mVelocity += timeSlices * mDirection * SPRING_CONSTANT * distance * distance / 2;
mVelocity *= (timeSlices * DECAY_CONSTANT);
mAmount += timeSlices * mVelocity;
mAmount += distance * timeSlices * 0.2f; // cheat
mListener.onSwipe(mAmount);
scheduleAnim();
}
};
}

View File

@ -46,8 +46,9 @@ import java.util.ArrayList;
* screen 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.
*/
public class Workspace extends ViewGroup implements DropTarget, DragSource, DragScroller,
TweenCallback {
public class Workspace extends ViewGroup implements DropTarget, DragSource, DragScroller {
private static final String TAG = "Launcher.Workspace";
private static final int INVALID_SCREEN = -1;
/**
@ -66,9 +67,6 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private SymmetricalLinearTween mTween;
private int mAlpha = 255;
/**
* CellInfo for the cell that is currently being dragged
*/
@ -150,8 +148,6 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mTween = new SymmetricalLinearTween(true, 250/*ms*/, this);
}
@Override
@ -486,12 +482,24 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
int restoreCount = 0;
// For the fade. If view gets setAlpha(), use that instead.
int alpha = mAlpha;
if (alpha < 255) {
float scale = mScale;
if (scale < 0.999f) {
int sx = mScrollX;
int alpha = (scale < 0.5f) ? (int)(255 * 2 * scale) : 255;
restoreCount = canvas.saveLayerAlpha(sx, 0, sx+getWidth(), getHeight(), alpha,
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
restore = true;
if (scale < 0.999f) {
int w = getWidth();
w += 2 * mCurrentScreen * w;
int h = getHeight();
canvas.translate(w/2, h/2);
canvas.scale(scale, scale);
canvas.translate(-w/2, -h/2);
}
}
// ViewGroup.dispatchDraw() supports many features we don't need:
@ -499,7 +507,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
// children, etc. The following implementation attempts to fast-track
// the drawing dispatch by drawing only what we know needs to be drawn.
boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;
boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN
&& scale > 0.999f;
// If we are not scrolling or flinging, draw only the current screen
if (fastDraw) {
drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());
@ -524,6 +533,12 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
}
}
private float mScale = 1.0f;
public void setScale(float scale) {
mScale = scale;
invalidate();
}
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mDragController.setWindowToken(getWindowToken());
@ -1335,31 +1350,9 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
}
void show() {
mTween.start(true);
setVisibility(VISIBLE);
}
void hide() {
mTween.start(false);
}
public void onTweenValueChanged(float value, float oldValue) {
mAlpha = (int)(255*value);
invalidate();
}
public void onTweenStarted() {
// TODO: This conflicts with the cache for drawing. Ref count instead?
// TODO: Don't cache all three.
enableChildrenCache();
}
public void onTweenFinished() {
// TODO: This conflicts with the cache for drawing. Ref count instead?
// TODO: Don't cache all three.
clearChildrenCache();
if (mAlpha == 0) {
setVisibility(GONE);
}
}
}