diff options
author | Winson Chung <winsonc@google.com> | 2010-08-20 14:49:25 -0700 |
---|---|---|
committer | Winson Chung <winsonc@google.com> | 2010-09-02 11:35:48 -0700 |
commit | 5f2aa4efeeb8b0133d891715d71553138d9f9ca7 (patch) | |
tree | 9d34aadf9e1b94db2edbb2e09aa96a9d1f02c840 /src/com/android | |
parent | 12815f5ac09055ba6a3cd04a14f3bc9d2e537a25 (diff) | |
download | packages_apps_trebuchet-5f2aa4efeeb8b0133d891715d71553138d9f9ca7.zip packages_apps_trebuchet-5f2aa4efeeb8b0133d891715d71553138d9f9ca7.tar.gz packages_apps_trebuchet-5f2aa4efeeb8b0133d891715d71553138d9f9ca7.tar.bz2 |
Adding single/multi selection mode to AllAppsPagedView (action bar disabled).
Also adding check to prevent scrolling mode from continuing on touch down.
Change-Id: I744f2c1f6bc659219145b52b15a7ea176853ec7c
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/launcher2/AllAppsPagedView.java | 112 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedView.java | 71 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedViewIcon.java | 68 |
3 files changed, 232 insertions, 19 deletions
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java index a673304..0aa7724 100644 --- a/src/com/android/launcher2/AllAppsPagedView.java +++ b/src/com/android/launcher2/AllAppsPagedView.java @@ -22,10 +22,15 @@ import java.util.Collections; import android.content.ComponentName; import android.content.Context; import android.content.res.TypedArray; +import android.graphics.Rect; import android.util.AttributeSet; +import android.view.ActionMode; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.animation.AnimationUtils; +import android.widget.Checkable; import android.widget.TextView; import com.android.launcher.R; @@ -35,7 +40,8 @@ import com.android.launcher.R; * with all of the user's applications. */ public class AllAppsPagedView extends PagedView - implements AllAppsView, View.OnClickListener, View.OnLongClickListener, DragSource { + implements AllAppsView, View.OnClickListener, View.OnLongClickListener, DragSource, + DropTarget, ActionMode.Callback { private static final String TAG = "AllAppsPagedView"; private static final boolean DEBUG = false; @@ -127,6 +133,8 @@ public class AllAppsPagedView extends PagedView if (!isVisible()) { setVisibility(View.GONE); mZoom = 0.0f; + + endChoiceMode(); } else { mZoom = 1.0f; } @@ -138,7 +146,7 @@ public class AllAppsPagedView extends PagedView private int getChildIndexForGrandChild(View v) { final int childCount = getChildCount(); for (int i = 0; i < childCount; ++i) { - PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); + final PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); if (layout.indexOfChild(v) > -1) { return i; } @@ -148,6 +156,22 @@ public class AllAppsPagedView extends PagedView @Override public void onClick(View v) { + // if we are already in a choice mode, then just change the selection + if (v instanceof Checkable) { + if (!isChoiceMode(CHOICE_MODE_NONE)) { + if (isChoiceMode(CHOICE_MODE_SINGLE)) { + // reset all the previously checked items if in single selection mode + resetCheckedGrandchildren(); + } + + // then toggle this one + Checkable c = (Checkable) v; + c.toggle(); + return; + } + } + + // otherwise continue and launch the application int childIndex = getChildIndexForGrandChild(v); if (childIndex == getCurrentPage()) { final ApplicationInfo app = (ApplicationInfo) v.getTag(); @@ -159,6 +183,8 @@ public class AllAppsPagedView extends PagedView mLauncher.startActivitySafely(app.intent, app); } }); + + endChoiceMode(); } } @@ -168,6 +194,24 @@ public class AllAppsPagedView extends PagedView return false; } + /* Uncomment this to enable selection mode with the action bar + + // start the choice mode, and select the item that was long-pressed + if (isChoiceMode(CHOICE_MODE_NONE)) { + startChoiceMode(CHOICE_MODE_SINGLE, this); + } + + if (v instanceof Checkable) { + // In preparation for drag, we always reset the checked grand children regardless of + // what choice mode we are in + resetCheckedGrandchildren(); + + // Toggle the selection on the dragged app + Checkable c = (Checkable) v; + c.toggle(); + } + */ + ApplicationInfo app = (ApplicationInfo) v.getTag(); app = new ApplicationInfo(app); @@ -177,7 +221,10 @@ public class AllAppsPagedView extends PagedView @Override public void onDropCompleted(View target, boolean success) { - // do nothing + // close the choice action mode if we have a proper drop + if (target != this) { + endChoiceMode(); + } } @Override @@ -341,4 +388,63 @@ public class AllAppsPagedView extends PagedView params.cellY = index / mCellCountX; } } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + mDragController.addDropTarget(this); + + // REST TO BE IMPLEMENTED BY PAT + mode.setTitle("Customization title goes here"); + return true; + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return true; + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + mDragController.removeDropTarget(this); + endChoiceMode(); + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + // TO BE IMPLEMENTED BY PAT + // get the checked grandchild, and handle the action here + return false; + } + + /* + * We don't actually use AllAppsPagedView as a drop target... it's only used to intercept a drop + * to the workspace. + */ + @Override + public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, + DragView dragView, Object dragInfo) { + return false; + } + @Override + public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset, + DragView dragView, Object dragInfo, Rect recycle) { + return null; + } + @Override + public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, + int yOffset, DragView dragView, Object dragInfo) { + return null; + } + @Override + public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, + DragView dragView, Object dragInfo) {} + @Override + public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, + DragView dragView, Object dragInfo) {} + @Override + public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, + DragView dragView, Object dragInfo) {} + @Override + public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, + DragView dragView, Object dragInfo) {} } diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java index 5052a59..8e0203b 100644 --- a/src/com/android/launcher2/PagedView.java +++ b/src/com/android/launcher2/PagedView.java @@ -19,7 +19,6 @@ package com.android.launcher2; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; - import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -27,6 +26,8 @@ import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; +import android.util.Log; +import android.view.ActionMode; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; @@ -36,6 +37,7 @@ import android.view.ViewParent; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; +import android.widget.Checkable; import android.widget.Scroller; import com.android.launcher.R; @@ -51,6 +53,7 @@ public abstract class PagedView extends ViewGroup { // the min drag distance for a fling to register, to prevent random page shifts private static final int MIN_LENGTH_FOR_FLING = 50; + private static final int PAGE_SNAP_ANIMATION_DURATION = 1000; protected static final float NANOTIME_DIV = 1000000000.0f; // the velocity at which a fling gesture will cause us to snap to the next page @@ -96,6 +99,14 @@ public abstract class PagedView extends ViewGroup { private ArrayList<Boolean> mDirtyPageContent; private boolean mDirtyPageAlpha; + // choice modes + protected static final int CHOICE_MODE_NONE = 0; + protected static final int CHOICE_MODE_SINGLE = 1; + // Multiple selection mode is not supported by all Launcher actions atm + protected static final int CHOICE_MODE_MULTIPLE = 2; + private int mChoiceMode; + private ActionMode mActionMode; + protected PagedViewIconCache mPageViewIconCache; // If true, syncPages and syncPageItems will be called to refresh pages @@ -153,6 +164,7 @@ public abstract class PagedView extends ViewGroup { public PagedView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + mChoiceMode = CHOICE_MODE_NONE; setHapticFeedbackEnabled(false); init(); @@ -530,7 +542,14 @@ public abstract class PagedView extends ViewGroup { * otherwise don't. mScroller.isFinished should be false when * being flinged. */ - mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING; + final int xDist = (mScroller.getFinalX() - mScroller.getCurrX()); + final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop); + if (finishedScrolling) { + mTouchState = TOUCH_STATE_REST; + mScroller.abortAnimation(); + } else { + mTouchState = TOUCH_STATE_SCROLLING; + } // check if this can be the beginning of a tap on the side of the pages // to scroll the current page @@ -819,7 +838,7 @@ public abstract class PagedView extends ViewGroup { minDistanceFromScreenCenterIndex = i; } } - snapToPage(minDistanceFromScreenCenterIndex, 1000); + snapToPage(minDistanceFromScreenCenterIndex, PAGE_SNAP_ANIMATION_DURATION); } protected void snapToPageWithVelocity(int whichPage, int velocity) { @@ -829,7 +848,7 @@ public abstract class PagedView extends ViewGroup { } protected void snapToPage(int whichPage) { - snapToPage(whichPage, 1000); + snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION); } protected void snapToPage(int whichPage, int duration) { @@ -982,6 +1001,50 @@ public abstract class PagedView extends ViewGroup { } } + protected void startChoiceMode(int mode, ActionMode.Callback callback) { + // StartActionMode may call through toendChoiceMode, so we should do this first + mActionMode = startActionMode(callback); + mChoiceMode = mode; + } + + protected void endChoiceMode() { + if (!isChoiceMode(CHOICE_MODE_NONE)) { + mActionMode.finish(); + mActionMode = null; + mChoiceMode = CHOICE_MODE_NONE; + resetCheckedGrandchildren(); + } + } + + protected boolean isChoiceMode(int mode) { + return mChoiceMode == mode; + } + + protected ArrayList<Checkable> getCheckedGrandchildren() { + ArrayList<Checkable> checked = new ArrayList<Checkable>(); + final int childCount = getChildCount(); + for (int i = 0; i < childCount; ++i) { + final PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); + final int grandChildCount = layout.getChildCount(); + for (int j = 0; j < grandChildCount; ++j) { + final View v = layout.getChildAt(j); + if (v instanceof Checkable) { + checked.add((Checkable) v); + } + } + } + return checked; + } + + protected void resetCheckedGrandchildren() { + // loop through children, and set all of their children to _not_ be checked + final ArrayList<Checkable> checked = getCheckedGrandchildren(); + for (int i = 0; i < checked.size(); ++i) { + final Checkable c = checked.get(i); + c.setChecked(false); + } + } + /** * This method is called ONLY to synchronize the number of pages that the paged view has. * To actually fill the pages with information, implement syncPageItems() below. It is diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java index e227569..b8cc206 100644 --- a/src/com/android/launcher2/PagedViewIcon.java +++ b/src/com/android/launcher2/PagedViewIcon.java @@ -40,17 +40,19 @@ import android.widget.TextView; import com.android.launcher2.PagedView.PagedViewIconCache; class HolographicOutlineHelper { + private float mDensity; private final Paint mHolographicPaint = new Paint(); private final Paint mBlurPaint = new Paint(); private final Paint mErasePaint = new Paint(); - private static final Matrix mIdentity = new Matrix(); - private static final float STROKE_WIDTH = 6.0f; + private static final Matrix mIdentity = new Matrix();; private static final float BLUR_FACTOR = 3.5f; + public static final float DEFAULT_STROKE_WIDTH = 6.0f; public static final int HOLOGRAPHIC_BLUE = 0xFF6699FF; - public static final int HOLOGRAPHIC_GREEN = 0xFF66FF66; + public static final int HOLOGRAPHIC_GREEN = 0xFF51E633; HolographicOutlineHelper(float density) { + mDensity = density; mHolographicPaint.setColor(HOLOGRAPHIC_BLUE); mHolographicPaint.setFilterBitmap(true); mHolographicPaint.setAntiAlias(true); @@ -101,13 +103,14 @@ class HolographicOutlineHelper { /** * Applies an outline to whatever is currently drawn in the specified bitmap. */ - void applyOutline(Bitmap srcDst, Canvas srcDstCanvas, PointF offset) { + void applyOutline(Bitmap srcDst, Canvas srcDstCanvas, float strokeWidth, PointF offset) { + strokeWidth *= mDensity; Bitmap mask = srcDst.extractAlpha(); Matrix m = new Matrix(); final int width = srcDst.getWidth(); final int height = srcDst.getHeight(); - float xScale = STROKE_WIDTH*2.0f/width; - float yScale = STROKE_WIDTH*2.0f/height; + float xScale = strokeWidth*2.0f/width; + float yScale = strokeWidth*2.0f/height; m.preScale(1+xScale, 1+yScale, (width / 2.0f) + offset.x, (height / 2.0f) + offset.y); @@ -138,6 +141,7 @@ public class PagedViewIcon extends TextView implements Checkable { // holographic outline private final Paint mPaint = new Paint(); private static HolographicOutlineHelper sHolographicOutlineHelper; + private Bitmap mCheckedOutline; private Bitmap mHolographicOutline; private Canvas mHolographicOutlineCanvas; private boolean mIsHolographicUpdatePass; @@ -207,6 +211,13 @@ public class PagedViewIcon extends TextView implements Checkable { super.setAlpha(viewAlpha); } + public void invalidateCheckedImage() { + if (mCheckedOutline != null) { + mCheckedOutline.recycle(); + mCheckedOutline = null; + } + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); @@ -229,10 +240,11 @@ public class PagedViewIcon extends TextView implements Checkable { draw(mHolographicOutlineCanvas); sHolographicOutlineHelper.setColor(HolographicOutlineHelper.HOLOGRAPHIC_BLUE); sHolographicOutlineHelper.applyOutline(mHolographicOutline, mHolographicOutlineCanvas, - offset); + HolographicOutlineHelper.DEFAULT_STROKE_WIDTH, offset); sHolographicOutlineHelper.applyBlur(mHolographicOutline, mHolographicOutlineCanvas); mIsHolographicUpdatePass = false; mIconCache.addOutline(mIconCacheKey, mHolographicOutline); + mHolographicOutlineCanvas = null; } } @@ -254,9 +266,17 @@ public class PagedViewIcon extends TextView implements Checkable { } } - if (!mIsHolographicUpdatePass && mHolographicOutline != null && mHolographicAlpha > 0) { - mPaint.setAlpha(mHolographicAlpha); - canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint); + // draw any blended overlays + if (!mIsHolographicUpdatePass) { + if (mCheckedOutline == null) { + if (mHolographicOutline != null && mHolographicAlpha > 0) { + mPaint.setAlpha(mHolographicAlpha); + canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint); + } + } else { + mPaint.setAlpha(255); + canvas.drawBitmap(mCheckedOutline, 0, 0, mPaint); + } } } @@ -267,8 +287,32 @@ public class PagedViewIcon extends TextView implements Checkable { @Override public void setChecked(boolean checked) { - mIsChecked = checked; - invalidate(); + if (mIsChecked != checked) { + mIsChecked = checked; + + if (mIsChecked) { + final PointF offset = new PointF(0, + -(getCompoundPaddingBottom() + getCompoundPaddingTop())/2.0f); + + // set a flag to indicate that we are going to draw the view at full alpha with the text + // clipped for the generation of the holographic icon + mIsHolographicUpdatePass = true; + mCheckedOutline = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), + Bitmap.Config.ARGB_8888); + mHolographicOutlineCanvas = new Canvas(mCheckedOutline); + mHolographicOutlineCanvas.concat(getMatrix()); + draw(mHolographicOutlineCanvas); + sHolographicOutlineHelper.setColor(HolographicOutlineHelper.HOLOGRAPHIC_GREEN); + sHolographicOutlineHelper.applyOutline(mCheckedOutline, mHolographicOutlineCanvas, + HolographicOutlineHelper.DEFAULT_STROKE_WIDTH + 1.0f, offset); + mIsHolographicUpdatePass = false; + mHolographicOutlineCanvas = null; + } else { + invalidateCheckedImage(); + } + + invalidate(); + } } @Override |