diff options
author | Chirayu Desai <chirayudesai1@gmail.com> | 2012-08-02 12:23:05 +0530 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2012-11-19 01:06:35 +0000 |
commit | 7dcb25f19af1b09f958de211f3506042fb4407ff (patch) | |
tree | edf2c2a38e9bca2953159d3f0fdad4ebf675ae51 /src/com/cyanogenmod/trebuchet/FolderIcon.java | |
parent | 348075fe8c42124911854777a8f932aec7ad2cd2 (diff) | |
download | android_packages_apps_Trebuchet-7dcb25f19af1b09f958de211f3506042fb4407ff.tar.gz android_packages_apps_Trebuchet-7dcb25f19af1b09f958de211f3506042fb4407ff.tar.bz2 android_packages_apps_Trebuchet-7dcb25f19af1b09f958de211f3506042fb4407ff.zip |
Rename Launcher to Trebuchet
Launcher2 is now Trebuchet
application_name removed from localized strings and made un-translatable
com.android.launcher is now com.cyanogenmod.trebuchet
Diffstat (limited to 'src/com/cyanogenmod/trebuchet/FolderIcon.java')
-rw-r--r-- | src/com/cyanogenmod/trebuchet/FolderIcon.java | 665 |
1 files changed, 665 insertions, 0 deletions
diff --git a/src/com/cyanogenmod/trebuchet/FolderIcon.java b/src/com/cyanogenmod/trebuchet/FolderIcon.java new file mode 100644 index 000000000..55aa19237 --- /dev/null +++ b/src/com/cyanogenmod/trebuchet/FolderIcon.java @@ -0,0 +1,665 @@ +/* + * 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.cyanogenmod.trebuchet; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.cyanogenmod.trebuchet.R; +import com.cyanogenmod.trebuchet.DropTarget.DragObject; +import com.cyanogenmod.trebuchet.FolderInfo.FolderListener; + +import java.util.ArrayList; + +/** + * An icon that can appear on in the workspace representing an {@link UserFolder}. + */ +public class FolderIcon extends LinearLayout implements FolderListener { + private Launcher mLauncher; + private Folder mFolder; + private FolderInfo mInfo; + private static boolean sStaticValuesDirty = true; + + private CheckLongPressHelper mLongPressHelper; + + // The number of icons to display in the + private static final int NUM_ITEMS_IN_PREVIEW = 3; + private static final int CONSUMPTION_ANIMATION_DURATION = 100; + private static final int DROP_IN_ANIMATION_DURATION = 400; + private static final int INITIAL_ITEM_ANIMATION_DURATION = 350; + private static final int FINAL_ITEM_ANIMATION_DURATION = 200; + + // The degree to which the inner ring grows when accepting drop + private static final float INNER_RING_GROWTH_FACTOR = 0.15f; + + // The degree to which the outer ring is scaled in its natural state + private static final float OUTER_RING_GROWTH_FACTOR = 0.3f; + + // The amount of vertical spread between items in the stack [0...1] + private static final float PERSPECTIVE_SHIFT_FACTOR = 0.24f; + + // The degree to which the item in the back of the stack is scaled [0...1] + // (0 means it's not scaled at all, 1 means it's scaled to nothing) + private static final float PERSPECTIVE_SCALE_FACTOR = 0.35f; + + public static Drawable sSharedFolderLeaveBehind = null; + + private ImageView mPreviewBackground; + private BubbleTextView mFolderName; + + FolderRingAnimator mFolderRingAnimator = null; + + // These variables are all associated with the drawing of the preview; they are stored + // as member variables for shared usage and to avoid computation on each frame + private int mIntrinsicIconSize; + private float mBaselineIconScale; + private int mBaselineIconSize; + private int mAvailableSpaceInPreview; + private int mTotalWidth = -1; + private int mPreviewOffsetX; + private int mPreviewOffsetY; + private float mMaxPerspectiveShift; + boolean mAnimating = false; + + private PreviewItemDrawingParams mParams = new PreviewItemDrawingParams(0, 0, 0, 0); + private PreviewItemDrawingParams mAnimParams = new PreviewItemDrawingParams(0, 0, 0, 0); + private ArrayList<ShortcutInfo> mHiddenItems = new ArrayList<ShortcutInfo>(); + + public FolderIcon(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public FolderIcon(Context context) { + super(context); + init(); + } + + private void init() { + mLongPressHelper = new CheckLongPressHelper(this); + } + + public boolean isDropEnabled() { + final ViewGroup cellLayoutChildren = (ViewGroup) getParent(); + final ViewGroup cellLayout = (ViewGroup) cellLayoutChildren.getParent(); + final Workspace workspace = (Workspace) cellLayout.getParent(); + return !workspace.isSmall(); + } + + static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, + FolderInfo folderInfo, IconCache iconCache) { + @SuppressWarnings("all") // suppress dead code warning + final boolean error = INITIAL_ITEM_ANIMATION_DURATION >= DROP_IN_ANIMATION_DURATION; + if (error) { + throw new IllegalStateException("DROP_IN_ANIMATION_DURATION must be greater than " + + "INITIAL_ITEM_ANIMATION_DURATION, as sequencing of adding first two items " + + "is dependent on this"); + } + + FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false); + + icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name); + icon.mFolderName.setText(folderInfo.title); + icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background); + + icon.setTag(folderInfo); + icon.setOnClickListener(launcher); + icon.mInfo = folderInfo; + icon.mLauncher = launcher; + icon.setContentDescription(String.format(launcher.getString(R.string.folder_name_format), + folderInfo.title)); + Folder folder = Folder.fromXml(launcher); + folder.setDragController(launcher.getDragController()); + folder.setFolderIcon(icon); + folder.bind(folderInfo); + icon.mFolder = folder; + + icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon); + folderInfo.addListener(icon); + + return icon; + } + + @Override + protected Parcelable onSaveInstanceState() { + sStaticValuesDirty = true; + return super.onSaveInstanceState(); + } + + public static class FolderRingAnimator { + public int mCellX; + public int mCellY; + private CellLayout mCellLayout; + public float mOuterRingSize; + public float mInnerRingSize; + public FolderIcon mFolderIcon = null; + public Drawable mOuterRingDrawable = null; + public Drawable mInnerRingDrawable = null; + public static Drawable sSharedOuterRingDrawable = null; + public static Drawable sSharedInnerRingDrawable = null; + public static int sPreviewSize = -1; + public static int sPreviewPadding = -1; + + private ValueAnimator mAcceptAnimator; + private ValueAnimator mNeutralAnimator; + + public FolderRingAnimator(Launcher launcher, FolderIcon folderIcon) { + mFolderIcon = folderIcon; + Resources res = launcher.getResources(); + mOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo); + mInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo); + + // We need to reload the static values when configuration changes in case they are + // different in another configuration + if (sStaticValuesDirty) { + sPreviewSize = res.getDimensionPixelSize(R.dimen.folder_preview_size); + sPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding); + sSharedOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo); + sSharedInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo); + sSharedFolderLeaveBehind = res.getDrawable(R.drawable.portal_ring_rest); + sStaticValuesDirty = false; + } + } + + public void animateToAcceptState() { + if (mNeutralAnimator != null) { + mNeutralAnimator.cancel(); + } + mAcceptAnimator = LauncherAnimUtils.ofFloat(0f, 1f); + mAcceptAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION); + + final int previewSize = sPreviewSize; + mAcceptAnimator.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + final float percent = (Float) animation.getAnimatedValue(); + mOuterRingSize = (1 + percent * OUTER_RING_GROWTH_FACTOR) * previewSize; + mInnerRingSize = (1 + percent * INNER_RING_GROWTH_FACTOR) * previewSize; + if (mCellLayout != null) { + mCellLayout.invalidate(); + } + } + }); + mAcceptAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + if (mFolderIcon != null) { + mFolderIcon.mPreviewBackground.setVisibility(INVISIBLE); + } + } + }); + mAcceptAnimator.start(); + } + + public void animateToNaturalState() { + if (mAcceptAnimator != null) { + mAcceptAnimator.cancel(); + } + mNeutralAnimator = LauncherAnimUtils.ofFloat(0f, 1f); + mNeutralAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION); + + final int previewSize = sPreviewSize; + mNeutralAnimator.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + final float percent = (Float) animation.getAnimatedValue(); + mOuterRingSize = (1 + (1 - percent) * OUTER_RING_GROWTH_FACTOR) * previewSize; + mInnerRingSize = (1 + (1 - percent) * INNER_RING_GROWTH_FACTOR) * previewSize; + if (mCellLayout != null) { + mCellLayout.invalidate(); + } + } + }); + mNeutralAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (mCellLayout != null) { + mCellLayout.hideFolderAccept(FolderRingAnimator.this); + } + if (mFolderIcon != null) { + mFolderIcon.mPreviewBackground.setVisibility(VISIBLE); + } + } + }); + mNeutralAnimator.start(); + } + + // Location is expressed in window coordinates + public void getCell(int[] loc) { + loc[0] = mCellX; + loc[1] = mCellY; + } + + // Location is expressed in window coordinates + public void setCell(int x, int y) { + mCellX = x; + mCellY = y; + } + + public void setCellLayout(CellLayout layout) { + mCellLayout = layout; + } + + public float getOuterRingSize() { + return mOuterRingSize; + } + + public float getInnerRingSize() { + return mInnerRingSize; + } + } + + Folder getFolder() { + return mFolder; + } + + FolderInfo getFolderInfo() { + return mInfo; + } + + private boolean willAcceptItem(ItemInfo item) { + final int itemType = item.itemType; + return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || + itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && + !mFolder.isFull() && item != mInfo && !mInfo.opened); + } + + public boolean acceptDrop(Object dragInfo) { + final ItemInfo item = (ItemInfo) dragInfo; + return !mFolder.isDestroyed() && willAcceptItem(item); + } + + public void addItem(ShortcutInfo item) { + mInfo.add(item); + } + + public void onDragEnter(Object dragInfo) { + if (mFolder.isDestroyed() || !willAcceptItem((ItemInfo) dragInfo)) return; + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); + CellLayout layout = (CellLayout) getParent().getParent(); + mFolderRingAnimator.setCell(lp.cellX, lp.cellY); + mFolderRingAnimator.setCellLayout(layout); + mFolderRingAnimator.animateToAcceptState(); + layout.showFolderAccept(mFolderRingAnimator); + } + + public void onDragOver(Object dragInfo) { + } + + public void performCreateAnimation(final ShortcutInfo destInfo, final View destView, + final ShortcutInfo srcInfo, final DragView srcView, Rect dstRect, + float scaleRelativeToDragLayer, Runnable postAnimationRunnable) { + + // These correspond two the drawable and view that the icon was dropped _onto_ + Drawable animateDrawable = ((TextView) destView).getCompoundDrawables()[1]; + computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), + destView.getMeasuredWidth()); + + // This will animate the first item from it's position as an icon into its + // position as the first item in the preview + animateFirstItem(animateDrawable, INITIAL_ITEM_ANIMATION_DURATION, false, null); + addItem(destInfo); + + // This will animate the dragView (srcView) into the new folder + onDrop(srcInfo, srcView, dstRect, scaleRelativeToDragLayer, 1, postAnimationRunnable, null); + } + + public void performDestroyAnimation(final View finalView, Runnable onCompleteRunnable) { + Drawable animateDrawable = ((TextView) finalView).getCompoundDrawables()[1]; + computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), + finalView.getMeasuredWidth()); + + // This will animate the first item from it's position as an icon into its + // position as the first item in the preview + animateFirstItem(animateDrawable, FINAL_ITEM_ANIMATION_DURATION, true, + onCompleteRunnable); + } + + public void onDragExit(Object dragInfo) { + onDragExit(); + } + + public void onDragExit() { + mFolderRingAnimator.animateToNaturalState(); + } + + private void onDrop(final ShortcutInfo item, DragView animateView, Rect finalRect, + float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable, + DragObject d) { + item.cellX = -1; + item.cellY = -1; + + // Typically, the animateView corresponds to the DragView; however, if this is being done + // after a configuration activity (ie. for a Shortcut being dragged from AllApps) we + // will not have a view to animate + if (animateView != null) { + DragLayer dragLayer = mLauncher.getDragLayer(); + Rect from = new Rect(); + dragLayer.getViewRectRelativeToSelf(animateView, from); + Rect to = finalRect; + if (to == null) { + to = new Rect(); + Workspace workspace = mLauncher.getWorkspace(); + // Set cellLayout and this to it's final state to compute final animation locations + workspace.setFinalTransitionTransform((CellLayout) getParent().getParent()); + float scaleX = getScaleX(); + float scaleY = getScaleY(); + setScaleX(1.0f); + setScaleY(1.0f); + scaleRelativeToDragLayer = dragLayer.getDescendantRectRelativeToSelf(this, to); + // Finished computing final animation locations, restore current state + setScaleX(scaleX); + setScaleY(scaleY); + workspace.resetTransitionTransform((CellLayout) getParent().getParent()); + } + + int[] center = new int[2]; + float scale = getLocalCenterForIndex(index, center); + center[0] = (int) Math.round(scaleRelativeToDragLayer * center[0]); + center[1] = (int) Math.round(scaleRelativeToDragLayer * center[1]); + + to.offset(center[0] - animateView.getMeasuredWidth() / 2, + center[1] - animateView.getMeasuredHeight() / 2); + + float finalAlpha = index < NUM_ITEMS_IN_PREVIEW ? 0.5f : 0f; + + float finalScale = scale * scaleRelativeToDragLayer; + dragLayer.animateView(animateView, from, to, finalAlpha, + 1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION, + new DecelerateInterpolator(2), new AccelerateInterpolator(2), + postAnimationRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null); + addItem(item); + mHiddenItems.add(item); + postDelayed(new Runnable() { + public void run() { + mHiddenItems.remove(item); + invalidate(); + } + }, DROP_IN_ANIMATION_DURATION); + } else { + addItem(item); + } + } + + public void onDrop(DragObject d) { + ShortcutInfo item; + if (d.dragInfo instanceof ApplicationInfo) { + // Came from all apps -- make a copy + item = ((ApplicationInfo) d.dragInfo).makeShortcut(); + } else { + item = (ShortcutInfo) d.dragInfo; + } + mFolder.notifyDrop(); + onDrop(item, d.dragView, null, 1.0f, mInfo.contents.size(), d.postAnimationRunnable, d); + } + + public DropTarget getDropTargetDelegate(DragObject d) { + return null; + } + + private void computePreviewDrawingParams(int drawableSize, int totalSize) { + if (mIntrinsicIconSize != drawableSize || mTotalWidth != totalSize) { + mIntrinsicIconSize = drawableSize; + mTotalWidth = totalSize; + + final int previewSize = FolderRingAnimator.sPreviewSize; + final int previewPadding = FolderRingAnimator.sPreviewPadding; + + mAvailableSpaceInPreview = (previewSize - 2 * previewPadding); + // cos(45) = 0.707 + ~= 0.1) = 0.8f + int adjustedAvailableSpace = (int) ((mAvailableSpaceInPreview / 2) * (1 + 0.8f)); + + int unscaledHeight = (int) (mIntrinsicIconSize * (1 + PERSPECTIVE_SHIFT_FACTOR)); + mBaselineIconScale = (1.0f * adjustedAvailableSpace / unscaledHeight); + + mBaselineIconSize = (int) (mIntrinsicIconSize * mBaselineIconScale); + mMaxPerspectiveShift = mBaselineIconSize * PERSPECTIVE_SHIFT_FACTOR; + + mPreviewOffsetX = (mTotalWidth - mAvailableSpaceInPreview) / 2; + mPreviewOffsetY = previewPadding; + } + } + + private void computePreviewDrawingParams(Drawable d) { + computePreviewDrawingParams(d.getIntrinsicWidth(), getMeasuredWidth()); + } + + class PreviewItemDrawingParams { + PreviewItemDrawingParams(float transX, float transY, float scale, int overlayAlpha) { + this.transX = transX; + this.transY = transY; + this.scale = scale; + this.overlayAlpha = overlayAlpha; + } + float transX; + float transY; + float scale; + int overlayAlpha; + Drawable drawable; + } + + private float getLocalCenterForIndex(int index, int[] center) { + mParams = computePreviewItemDrawingParams(Math.min(NUM_ITEMS_IN_PREVIEW, index), mParams); + + mParams.transX += mPreviewOffsetX; + mParams.transY += mPreviewOffsetY; + float offsetX = mParams.transX + (mParams.scale * mIntrinsicIconSize) / 2; + float offsetY = mParams.transY + (mParams.scale * mIntrinsicIconSize) / 2; + + center[0] = (int) Math.round(offsetX); + center[1] = (int) Math.round(offsetY); + return mParams.scale; + } + + private PreviewItemDrawingParams computePreviewItemDrawingParams(int index, + PreviewItemDrawingParams params) { + index = NUM_ITEMS_IN_PREVIEW - index - 1; + float r = (index * 1.0f) / (NUM_ITEMS_IN_PREVIEW - 1); + float scale = (1 - PERSPECTIVE_SCALE_FACTOR * (1 - r)); + + float offset = (1 - r) * mMaxPerspectiveShift; + float scaledSize = scale * mBaselineIconSize; + float scaleOffsetCorrection = (1 - scale) * mBaselineIconSize; + + // We want to imagine our coordinates from the bottom left, growing up and to the + // right. This is natural for the x-axis, but for the y-axis, we have to invert things. + float transY = mAvailableSpaceInPreview - (offset + scaledSize + scaleOffsetCorrection); + float transX = offset + scaleOffsetCorrection; + float totalScale = mBaselineIconScale * scale; + final int overlayAlpha = (int) (80 * (1 - r)); + + if (params == null) { + params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha); + } else { + params.transX = transX; + params.transY = transY; + params.scale = totalScale; + params.overlayAlpha = overlayAlpha; + } + return params; + } + + private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params) { + canvas.save(); + canvas.translate(params.transX + mPreviewOffsetX, params.transY + mPreviewOffsetY); + canvas.scale(params.scale, params.scale); + Drawable d = params.drawable; + + if (d != null) { + d.setBounds(0, 0, mIntrinsicIconSize, mIntrinsicIconSize); + d.setFilterBitmap(true); + d.setColorFilter(Color.argb(params.overlayAlpha, 0, 0, 0), PorterDuff.Mode.SRC_ATOP); + d.draw(canvas); + d.clearColorFilter(); + d.setFilterBitmap(false); + } + canvas.restore(); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + + if (mFolder == null) return; + if (mFolder.getItemCount() == 0 && !mAnimating) return; + + ArrayList<View> items = mFolder.getItemsInReadingOrder(false); + Drawable d; + TextView v; + + // Update our drawing parameters if necessary + if (mAnimating) { + computePreviewDrawingParams(mAnimParams.drawable); + } else { + v = (TextView) items.get(0); + d = v.getCompoundDrawables()[1]; + computePreviewDrawingParams(d); + } + + int nItemsInPreview = Math.min(items.size(), NUM_ITEMS_IN_PREVIEW); + if (!mAnimating) { + for (int i = nItemsInPreview - 1; i >= 0; i--) { + v = (TextView) items.get(i); + if (!mHiddenItems.contains(v.getTag())) { + d = v.getCompoundDrawables()[1]; + mParams = computePreviewItemDrawingParams(i, mParams); + mParams.drawable = d; + drawPreviewItem(canvas, mParams); + } + } + } else { + drawPreviewItem(canvas, mAnimParams); + } + } + + private void animateFirstItem(final Drawable d, int duration, final boolean reverse, + final Runnable onCompleteRunnable) { + final PreviewItemDrawingParams finalParams = computePreviewItemDrawingParams(0, null); + + final float scale0 = 1.0f; + final float transX0 = (mAvailableSpaceInPreview - d.getIntrinsicWidth()) / 2; + final float transY0 = (mAvailableSpaceInPreview - d.getIntrinsicHeight()) / 2; + mAnimParams.drawable = d; + + ValueAnimator va = LauncherAnimUtils.ofFloat(0f, 1.0f); + va.addUpdateListener(new AnimatorUpdateListener(){ + public void onAnimationUpdate(ValueAnimator animation) { + float progress = (Float) animation.getAnimatedValue(); + if (reverse) { + progress = 1 - progress; + mPreviewBackground.setAlpha(progress); + } + + mAnimParams.transX = transX0 + progress * (finalParams.transX - transX0); + mAnimParams.transY = transY0 + progress * (finalParams.transY - transY0); + mAnimParams.scale = scale0 + progress * (finalParams.scale - scale0); + invalidate(); + } + }); + va.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + mAnimating = true; + } + @Override + public void onAnimationEnd(Animator animation) { + mAnimating = false; + if (onCompleteRunnable != null) { + onCompleteRunnable.run(); + } + } + }); + va.setDuration(duration); + va.start(); + } + + public void setTextVisible(boolean visible) { + if (visible) { + mFolderName.setVisibility(VISIBLE); + } else { + mFolderName.setVisibility(INVISIBLE); + } + } + + public boolean getTextVisible() { + return mFolderName.getVisibility() == VISIBLE; + } + + public void onItemsChanged() { + invalidate(); + requestLayout(); + } + + public void onAdd(ShortcutInfo item) { + invalidate(); + requestLayout(); + } + + public void onRemove(ShortcutInfo item) { + invalidate(); + requestLayout(); + } + + public void onTitleChanged(CharSequence title) { + mFolderName.setText(title.toString()); + setContentDescription(String.format(getContext().getString(R.string.folder_name_format), + title)); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // Call the superclass onTouchEvent first, because sometimes it changes the state to + // isPressed() on an ACTION_UP + boolean result = super.onTouchEvent(event); + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mLongPressHelper.postCheckForLongPress(); + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + mLongPressHelper.cancelLongPress(); + break; + } + return result; + } + + @Override + public void cancelLongPress() { + super.cancelLongPress(); + + mLongPressHelper.cancelLongPress(); + } +} |