From f0ea4d3378be7b962c8e0bce2392df5e82491fb8 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 6 Jun 2011 14:27:16 -0700 Subject: Replacing AllApps/Customize in tablet UI with Apps/Customize. Change-Id: I11a296b25472e4bf298a468865b0dff29f500aaa --- src/com/android/launcher2/AllAppsPagedView.java | 1 - .../launcher2/ApplicationInfoDropTarget.java | 16 +- .../android/launcher2/AppsCustomizePagedView.java | 241 +++---- .../android/launcher2/AppsCustomizeTabHost.java | 37 +- src/com/android/launcher2/DeleteDropTarget.java | 2 +- src/com/android/launcher2/IconDropTarget.java | 2 +- src/com/android/launcher2/Launcher.java | 706 +++++---------------- src/com/android/launcher2/LauncherApplication.java | 5 - src/com/android/launcher2/PagedView.java | 56 +- src/com/android/launcher2/PagedViewCellLayout.java | 60 +- src/com/android/launcher2/PagedViewGridLayout.java | 17 +- src/com/android/launcher2/SearchDropTargetBar.java | 41 +- src/com/android/launcher2/Workspace.java | 167 +---- 13 files changed, 442 insertions(+), 909 deletions(-) (limited to 'src/com/android/launcher2') diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java index ae8b970fb..5c8812df3 100644 --- a/src/com/android/launcher2/AllAppsPagedView.java +++ b/src/com/android/launcher2/AllAppsPagedView.java @@ -208,7 +208,6 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All @Override public void setup(Launcher launcher, DragController dragController) { mLauncher = launcher; - mLauncher.setAllAppsPagedView(this); mDragController = dragController; } diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java index fa4663acf..4a9727dd5 100644 --- a/src/com/android/launcher2/ApplicationInfoDropTarget.java +++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java @@ -50,15 +50,13 @@ public class ApplicationInfoDropTarget extends IconDropTarget { int colour = getContext().getResources().getColor(R.color.info_target_hover_tint); mHoverPaint.setColorFilter(new PorterDuffColorFilter(colour, PorterDuff.Mode.SRC_ATOP)); - if (LauncherApplication.isScreenLarge()) { - // For the application info drop target, we just ignore the left padding since we don't want - // to overlap with the delete zone padding - int tb = getResources().getDimensionPixelSize( - R.dimen.delete_zone_vertical_drag_padding); - int lr = getResources().getDimensionPixelSize( - R.dimen.delete_zone_horizontal_drag_padding); - setDragPadding(tb, lr, tb, 0); - } + // For the application info drop target, we just ignore the left padding since we don't want + // to overlap with the delete zone padding + int tb = getResources().getDimensionPixelSize( + R.dimen.delete_zone_vertical_drag_padding); + int lr = getResources().getDimensionPixelSize( + R.dimen.delete_zone_horizontal_drag_padding); + setDragPadding(tb, lr, tb, 0); } public boolean acceptDrop(DragObject d) { diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java index 464bb44fb..dfdbce917 100644 --- a/src/com/android/launcher2/AppsCustomizePagedView.java +++ b/src/com/android/launcher2/AppsCustomizePagedView.java @@ -16,11 +16,8 @@ package com.android.launcher2; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; @@ -30,12 +27,13 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.Bitmap.Config; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; @@ -44,8 +42,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.LinearInterpolator; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; @@ -88,9 +84,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen private IconCache mIconCache; // Dimens + private Runnable mOnSizeChangedCallback; private int mContentWidth; private int mMaxWidgetSpan, mMinWidgetSpan; - private int mCellWidthGap, mCellHeightGap; + private int mWidgetWidthGap, mWidgetHeightGap; private int mWidgetCountX, mWidgetCountY; private final int mWidgetPreviewIconPaddedDimension; private final float sWidgetPreviewIconPaddingPercentage = 0.25f; @@ -120,23 +117,19 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, 0, 0); + // TODO-APPS_CUSTOMIZE: remove these unnecessary attrs after mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 6); mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4); a.recycle(); a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0); - mCellWidthGap = - a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellWidthGap, 10); - mCellHeightGap = - a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellHeightGap, 10); + mWidgetWidthGap = + a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellWidthGap, 0); + mWidgetHeightGap = + a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellHeightGap, 0); mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2); mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2); a.recycle(); - - // Create a dummy page that we can use to approximate the cell dimensions of widgets and - // the content width (to be used by our parent) - mWidgetSpacingLayout = new PagedViewCellLayout(context); - setupPage(mWidgetSpacingLayout); - mContentWidth = mWidgetSpacingLayout.getContentWidth(); + mWidgetSpacingLayout = new PagedViewCellLayout(getContext()); // The max widget span is the length N, such that NxN is the largest bounds that the widget // preview can be before applying the widget scaling @@ -160,6 +153,70 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f); } + @Override + protected void onWallpaperTap(android.view.MotionEvent ev) { + mLauncher.showWorkspace(true); + } + + /** + * This differs from isDataReady as this is the test done if isDataReady is not set. + */ + private boolean testDataReady() { + return !mApps.isEmpty() && !mWidgets.isEmpty(); + } + + protected void onDataReady(int width, int height) { + // Note that we transpose the counts in portrait so that we get a similar layout + boolean isLandscape = getResources().getConfiguration().orientation == + Configuration.ORIENTATION_LANDSCAPE; + int maxCellCountX = Integer.MAX_VALUE; + int maxCellCountY = Integer.MAX_VALUE; + if (LauncherApplication.isScreenLarge()) { + maxCellCountX = (isLandscape ? LauncherModel.getCellCountX() : + LauncherModel.getCellCountY()); + maxCellCountY = (isLandscape ? LauncherModel.getCellCountY() : + LauncherModel.getCellCountX()); + } + + // Now that the data is ready, we can calculate the content width, the number of cells to + // use for each page + mWidgetSpacingLayout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap); + mWidgetSpacingLayout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, + mPageLayoutPaddingRight, mPageLayoutPaddingBottom); + mWidgetSpacingLayout.calculateCellCount(width, height, maxCellCountX, maxCellCountY); + mCellCountX = mWidgetSpacingLayout.getCellCountX(); + mCellCountY = mWidgetSpacingLayout.getCellCountY(); + mWidgetCountX = Math.max(1, (int) Math.round(mCellCountX / 2f)); + mWidgetCountY = Math.max(1, (int) Math.round(mCellCountY / 3f)); + mContentWidth = mWidgetSpacingLayout.getContentWidth(); + + // Notify our parent so that we can synchronize the tab bar width to this page width + if (mOnSizeChangedCallback != null) { + mOnSizeChangedCallback.run(); + } + + invalidatePageData(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = MeasureSpec.getSize(heightMeasureSpec); + if (!isDataReady()) { + if (testDataReady()) { + setDataIsReady(); + setMeasuredDimension(width, height); + onDataReady(width, height); + } + } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + public void setOnSizeChangedCallback(Runnable r) { + mOnSizeChangedCallback = r; + } + /** Removes and returns the ResolveInfo with the specified ComponentName */ private ResolveInfo removeResolveInfoWithComponentName(List list, ComponentName cn) { @@ -179,108 +236,20 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen public void onPackagesUpdated() { // Get the list of widgets and shortcuts mWidgets.clear(); - mWidgets.addAll(AppWidgetManager.getInstance(mLauncher).getInstalledProviders()); + List widgets = + AppWidgetManager.getInstance(mLauncher).getInstalledProviders(); + Collections.sort(widgets, + new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager)); Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); - mWidgets.addAll(mPackageManager.queryIntentActivities(shortcutsIntent, 0)); - Collections.sort(mWidgets, + List shortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0); + Collections.sort(shortcuts, new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager)); - } - - /** - * Animates the given item onto the center of a home screen, and then scales the item to - * look as though it's disappearing onto that screen. - */ - private void animateItemOntoScreen(View dragView, - final CellLayout layout, final ItemInfo info) { - // On the phone, we only want to fade the widget preview out - float[] position = new float[2]; - position[0] = layout.getWidth() / 2; - position[1] = layout.getHeight() / 2; - - mLauncher.getWorkspace().mapPointFromChildToSelf(layout, position); - - int dragViewWidth = dragView.getMeasuredWidth(); - int dragViewHeight = dragView.getMeasuredHeight(); - float heightOffset = 0; - float widthOffset = 0; - - if (dragView instanceof ImageView) { - Drawable d = ((ImageView) dragView).getDrawable(); - int width = d.getIntrinsicWidth(); - int height = d.getIntrinsicHeight(); - - if ((1.0 * width / height) >= (1.0f * dragViewWidth) / dragViewHeight) { - float f = (dragViewWidth / (width * 1.0f)); - heightOffset = ANIMATION_SCALE * (dragViewHeight - f * height) / 2; - } else { - float f = (dragViewHeight / (height * 1.0f)); - widthOffset = ANIMATION_SCALE * (dragViewWidth - f * width) / 2; - } - } - final float toX = position[0] - dragView.getMeasuredWidth() / 2 + widthOffset; - final float toY = position[1] - dragView.getMeasuredHeight() / 2 + heightOffset; - - final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer); - final View dragCopy = dragLayer.createDragView(dragView); - dragCopy.setAlpha(1.0f); - - // Translate the item to the center of the appropriate home screen - animateIntoPosition(dragCopy, toX, toY, null); - - // The drop-onto-screen animation begins a bit later, but ends at the same time. - final int startDelay = TRANSLATE_ANIM_DURATION - DROP_ANIM_DURATION; - - // Scale down the icon and fade out the alpha - animateDropOntoScreen(dragCopy, info, DROP_ANIM_DURATION, startDelay); - } + mWidgets.addAll(widgets); + mWidgets.addAll(shortcuts); - /** - * Animation which scales the view down and animates its alpha, making it appear to disappear - * onto a home screen. - */ - private void animateDropOntoScreen( - final View view, final ItemInfo info, int duration, int delay) { - final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer); - final CellLayout layout = mLauncher.getWorkspace().getCurrentDropLayout(); - - ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, - PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f), - PropertyValuesHolder.ofFloat("scaleX", ANIMATION_SCALE), - PropertyValuesHolder.ofFloat("scaleY", ANIMATION_SCALE)); - anim.setInterpolator(new LinearInterpolator()); - if (delay > 0) { - anim.setStartDelay(delay); - } - anim.setDuration(duration); - anim.addListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - dragLayer.removeView(view); - mLauncher.addExternalItemToScreen(info, layout); - info.dropPos = null; - } - }); - anim.start(); - } - - /** - * Animates the x,y position of the view, and optionally execute a Runnable on animation end. - */ - private void animateIntoPosition( - View view, float toX, float toY, final Runnable endRunnable) { - ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, - PropertyValuesHolder.ofFloat("x", toX), - PropertyValuesHolder.ofFloat("y", toY)); - anim.setInterpolator(new DecelerateInterpolator(2.5f)); - anim.setDuration(TRANSLATE_ANIM_DURATION); - if (endRunnable != null) { - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - endRunnable.run(); - } - }); - } - anim.start(); + // The next layout pass will trigger data-ready if both widgets and apps are set, so request + // a layout to do this test and invalidate the page data when ready. + if (testDataReady()) requestLayout(); } @Override @@ -324,24 +293,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // Make a copy of the ApplicationInfo ApplicationInfo appInfo = new ApplicationInfo((ApplicationInfo) v.getTag()); - // Show the uninstall button if the app is uninstallable. - if ((appInfo.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) { - DeleteZone allAppsDeleteZone = (DeleteZone) - mLauncher.findViewById(R.id.all_apps_delete_zone); - allAppsDeleteZone.setDragAndDropEnabled(true); - - if ((appInfo.flags & ApplicationInfo.UPDATED_SYSTEM_APP_FLAG) != 0) { - allAppsDeleteZone.setText(R.string.delete_zone_label_all_apps_system_app); - } else { - allAppsDeleteZone.setText(R.string.delete_zone_label_all_apps); - } - } - - // Show the info button - ApplicationInfoDropTarget allAppsInfoButton = - (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target); - allAppsInfoButton.setDragAndDropEnabled(true); - // Compose the drag image (top compound drawable, index is 1) final TextView tv = (TextView) v; final Drawable icon = tv.getCompoundDrawables()[1]; @@ -542,6 +493,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen int y = index / mCellCountX; layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1)); } + + // Create the hardware layers + layout.allowHardwareLayerCreation(); + layout.createHardwareLayers(); } /* * Widgets PagedView implementation @@ -585,14 +540,11 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // We only need to make it wide enough so as not allow the preview to be scaled int expectedWidth = cellWidth; int expectedHeight = mWidgetPreviewIconPaddedDimension; - int offset = (int) (iconSize * sWidgetPreviewIconPaddingPercentage); // Render the icon Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888); Drawable icon = mIconCache.getFullResIcon(info, mPackageManager); - renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0, - mWidgetPreviewIconPaddedDimension, mWidgetPreviewIconPaddedDimension, 1f, 1f); - renderDrawableToBitmap(icon, preview, offset, offset, iconSize, iconSize, 1f, 1f); + renderDrawableToBitmap(icon, preview, 0, 0, iconSize, iconSize, 1f, 1f); FastBitmapDrawable iconDrawable = new FastBitmapDrawable(preview); iconDrawable.setBounds(0, 0, expectedWidth, expectedHeight); mWidgetPreviewCache.put(info, preview); @@ -706,9 +658,9 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen int numPages = (int) Math.ceil(mWidgets.size() / (float) numWidgetsPerPage); int offset = page * numWidgetsPerPage; int cellWidth = ((mWidgetSpacingLayout.getContentWidth() - mPageLayoutWidthGap - - ((mWidgetCountX - 1) * mCellWidthGap)) / mWidgetCountX); + - ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX); int cellHeight = ((mWidgetSpacingLayout.getContentHeight() - mPageLayoutHeightGap - - ((mWidgetCountY - 1) * mCellHeightGap)) / mWidgetCountY); + - ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY); for (int i = 0; i < Math.min(numWidgetsPerPage, mWidgets.size() - offset); ++i) { Object rawInfo = mWidgets.get(offset + i); PendingAddItemInfo createItemInfo = null; @@ -746,8 +698,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen int iy = i / mWidgetCountX; PagedViewGridLayout.LayoutParams lp = new PagedViewGridLayout.LayoutParams(cellWidth, cellHeight); - lp.leftMargin = (ix * cellWidth) + (ix * mCellWidthGap); - lp.topMargin = (iy * cellHeight) + (iy * mCellHeightGap); + lp.leftMargin = (ix * cellWidth) + (ix * mWidgetWidthGap); + lp.topMargin = (iy * cellHeight) + (iy * mWidgetHeightGap); layout.addView(widget, lp); } } @@ -836,7 +788,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen public void setApps(ArrayList list) { mApps = list; Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR); - invalidatePageData(); + + // The next layout pass will trigger data-ready if both widgets and apps are set, so request + // a layout to do this test and invalidate the page data when ready. + if (testDataReady()) requestLayout(); } private void addAppsWithoutInvalidate(ArrayList list) { // We add it in place, in alphabetical order diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java index e40524d3c..b5c6327a4 100644 --- a/src/com/android/launcher2/AppsCustomizeTabHost.java +++ b/src/com/android/launcher2/AppsCustomizeTabHost.java @@ -16,6 +16,7 @@ package com.android.launcher2; +import android.animation.Animator; import android.content.Context; import android.content.res.Resources; import android.util.AttributeSet; @@ -36,6 +37,7 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona private static final String WIDGETS_TAB_TAG = "WIDGETS"; private final LayoutInflater mLayoutInflater; + private ViewGroup mTabs; private AppsCustomizePagedView mAppsCustomizePane; public AppsCustomizeTabHost(Context context, AttributeSet attrs) { @@ -43,6 +45,9 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona mLayoutInflater = LayoutInflater.from(context); } + /** + * Convenience methods to select specific tabs + */ void selectAppsTab() { setCurrentTabByTag(APPS_TAB_TAG); } @@ -61,6 +66,7 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona final ViewGroup tabs = (ViewGroup) findViewById(com.android.internal.R.id.tabs); final AppsCustomizePagedView appsCustomizePane = (AppsCustomizePagedView) findViewById(R.id.apps_customize_pane_content); + mTabs = tabs; mAppsCustomizePane = appsCustomizePane; if (tabs == null || mAppsCustomizePane == null) throw new Resources.NotFoundException(); @@ -81,9 +87,18 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona tabView.setText(mContext.getString(R.string.widgets_tab_label)); addTab(newTabSpec(WIDGETS_TAB_TAG).setIndicator(tabView).setContent(contentFactory)); setOnTabChangedListener(this); + } - // Set the width of the tab bar to match the content (for now) - tabs.getLayoutParams().width = mAppsCustomizePane.getPageContentWidth(); + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + boolean remeasureTabWidth = (mTabs.getLayoutParams().width <= 0); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + // Set the width of the tab list to the content width + if (remeasureTabWidth) { + mTabs.getLayoutParams().width = mAppsCustomizePane.getPageContentWidth(); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } } @Override @@ -138,11 +153,21 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona /* LauncherTransitionable overrides */ @Override - public void onLauncherTransitionStart(android.animation.Animator animation) { - // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionStart(); + public void onLauncherTransitionStart(Animator animation) { + if (animation != null) { + // Turn on hardware layers for performance + setLayerType(LAYER_TYPE_HARDWARE, null); + + // force building the layer at the beginning of the animation, so you don't get a + // blip early in the animation + buildLayer(); + } } + @Override - public void onLauncherTransitionEnd(android.animation.Animator animation) { - // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionEnd(); + public void onLauncherTransitionEnd(Animator animation) { + if (animation != null) { + setLayerType(LAYER_TYPE_NONE, null); + } } } diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java index 4986a317f..a474c27e1 100644 --- a/src/com/android/launcher2/DeleteDropTarget.java +++ b/src/com/android/launcher2/DeleteDropTarget.java @@ -86,7 +86,7 @@ public class DeleteDropTarget extends IconDropTarget { boolean isVisible = true; boolean isUninstall = false; - // If we are dragging a widget from AppsCustomize , hide the delete target + // If we are dragging a widget from AppsCustomize, hide the delete target if (isAllAppsWidget(source, info)) { isVisible = false; } diff --git a/src/com/android/launcher2/IconDropTarget.java b/src/com/android/launcher2/IconDropTarget.java index a091f6c5d..202b38d9e 100644 --- a/src/com/android/launcher2/IconDropTarget.java +++ b/src/com/android/launcher2/IconDropTarget.java @@ -28,7 +28,7 @@ import android.widget.TextView; * Implements a DropTarget which allows applications to be dropped on it, * in order to launch the application info for that app. */ -public class IconDropTarget extends TextView implements DropTarget, DragController.DragListener { +public class IconDropTarget extends StrokedTextView implements DropTarget, DragController.DragListener { protected Launcher mLauncher; /** diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 6279b785e..7d2c74184 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -23,7 +23,6 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -40,12 +39,12 @@ import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.IntentFilter; import android.content.Intent.ShortcutIconResource; +import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; @@ -79,10 +78,9 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.Surface; import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.animation.DecelerateInterpolator; import android.view.inputmethod.InputMethodManager; @@ -91,7 +89,6 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupWindow; -import android.widget.TabHost; import android.widget.TextView; import android.widget.Toast; @@ -167,8 +164,7 @@ public final class Launcher extends Activity private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon"; /** The different states that Launcher can be in. */ - private enum State { WORKSPACE, APPS_CUSTOMIZE, ALL_APPS, CUSTOMIZE, - APPS_CUSTOMIZE_SPRING_LOADED }; + private enum State { WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED }; private State mState = State.WORKSPACE; private AnimatorSet mStateAnimation; @@ -198,22 +194,13 @@ public final class Launcher extends Activity private FolderInfo mFolderInfo; private DeleteZone mDeleteZone; - private HandleView mHandleView; + private ViewGroup mButtonCluster; + private View mAllAppsButton; private SearchDropTargetBar mSearchDeleteBar; - private AllAppsView mAllAppsGrid; private AppsCustomizeTabHost mAppsCustomizeTabHost; private AppsCustomizePagedView mAppsCustomizeContent; - private CustomizeTrayTabHost mHomeCustomizationDrawer; private boolean mAutoAdvanceRunning = false; - private ViewGroup mButtonCluster; - private View mAllAppsButton; - private View mDivider; - private View mConfigureButton; - - private AllAppsPagedView mAllAppsPagedView = null; - private CustomizePagedView mCustomizePagedView = null; - private Bundle mSavedState; private SpannableStringBuilder mDefaultKeySsb = null; @@ -287,13 +274,6 @@ public final class Launcher extends Activity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - if (LauncherApplication.isInPlaceRotationEnabled()) { - // hide the status bar (temporary until we get the status bar design figured out) - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); - } - LauncherApplication app = ((LauncherApplication)getApplication()); mModel = app.setLauncher(this); mIconCache = app.getIconCache(); @@ -312,12 +292,6 @@ public final class Launcher extends Activity loadHotseats(); checkForLocaleChange(); setContentView(R.layout.launcher); - mHomeCustomizationDrawer = (CustomizeTrayTabHost) findViewById(R.id.customization_drawer); - if (mHomeCustomizationDrawer != null) { - // share the same customization workspace across all the tabs - mCustomizePagedView = (CustomizePagedView) findViewById( - R.id.customization_drawer_tab_contents); - } setupViews(); registerContentObservers(); @@ -328,9 +302,6 @@ public final class Launcher extends Activity restoreState(mSavedState); // Update customization drawer _after_ restoring the states - if (mCustomizePagedView != null) { - mCustomizePagedView.update(); - } if (mAppsCustomizeContent != null) { mAppsCustomizeContent.onPackagesUpdated(); } @@ -351,19 +322,17 @@ public final class Launcher extends Activity registerReceiver(mCloseSystemDialogsReceiver, filter); // If we have a saved version of these external icons, we load them up immediately - if (LauncherApplication.isScreenLarge()) { - if (sGlobalSearchIcon == null || sVoiceSearchIcon == null || sAppMarketIcon == null) { - updateIconsAffectedByPackageManagerChanges(); - } - if (sGlobalSearchIcon != null) { - updateGlobalSearchIcon(sGlobalSearchIcon); - } - if (sVoiceSearchIcon != null) { - updateVoiceSearchIcon(sVoiceSearchIcon); - } - if (sAppMarketIcon != null) { - updateAppMarketIcon(sAppMarketIcon); - } + if (sGlobalSearchIcon == null || sVoiceSearchIcon == null || sAppMarketIcon == null) { + updateIconsAffectedByPackageManagerChanges(); + } + if (sGlobalSearchIcon != null) { + updateGlobalSearchIcon(sGlobalSearchIcon); + } + if (sVoiceSearchIcon != null) { + updateVoiceSearchIcon(sVoiceSearchIcon); + } + if (sAppMarketIcon != null) { + updateAppMarketIcon(sAppMarketIcon); } } @@ -721,9 +690,6 @@ public final class Launcher extends Activity public Object onRetainNonConfigurationInstance() { // Flag the loader to stop early before switching mModel.stopLoader(); - if (mAllAppsGrid != null) { - mAllAppsGrid.surrender(); - } if (mAppsCustomizeContent != null) { mAppsCustomizeContent.surrender(); } @@ -822,10 +788,8 @@ public final class Launcher extends Activity State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal())); - if (state == State.ALL_APPS || state == State.APPS_CUSTOMIZE) { + if (state == State.APPS_CUSTOMIZE) { showAllApps(false); - } else if (state == State.CUSTOMIZE) { - showCustomizationDrawer(false); } final int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1); @@ -849,38 +813,12 @@ public final class Launcher extends Activity mRestoring = true; } - // Restore the current AllApps drawer tab - if (mAllAppsGrid != null && mAllAppsGrid instanceof AllAppsTabbed) { - String curTab = savedState.getString("allapps_currentTab"); - if (curTab != null) { - AllAppsTabbed tabhost = (AllAppsTabbed) mAllAppsGrid; - tabhost.setCurrentTabByTag(curTab); - } - int curPage = savedState.getInt("allapps_currentPage", -1); - if (curPage > -1) { - mAllAppsPagedView.setRestorePage(curPage); - } - } - - // Restore the current customization drawer tab - if (mHomeCustomizationDrawer != null) { - String curTab = savedState.getString("customize_currentTab"); - if (curTab != null) { - // We set this directly so that there is no delay before the tab is set - mCustomizePagedView.setCustomizationFilter( - mHomeCustomizationDrawer.getCustomizeFilterForTabTag(curTab)); - mHomeCustomizationDrawer.setCurrentTabByTag(curTab); - } - - // Note: currently we do not restore the page for the customization tray because unlike - // AllApps, the page content can change drastically - } // Restore the AppsCustomize tab if (mAppsCustomizeTabHost != null) { String curTab = savedState.getString("apps_customize_currentTab"); if (curTab != null) { - // We set this directly so that there is no delay before the tab is set + // We set this directly so that there is no delay before the tab is set mAppsCustomizeContent.setContentType( mAppsCustomizeTabHost.getContentTypeForTabTag(curTab)); mAppsCustomizeTabHost.setCurrentTabByTag(curTab); @@ -909,67 +847,29 @@ public final class Launcher extends Activity mWorkspace.setup(this, dragController); mWorkspace.setWallpaperDimension(); - // Setup the different configurations - DeleteZone allAppsDeleteZone = null; - ApplicationInfoDropTarget allAppsInfoTarget = null; - if (LauncherApplication.isScreenLarge()) { - // Setup AllApps - mAllAppsGrid = (AllAppsView) mDragLayer.findViewById(R.id.all_apps_view); - mAllAppsGrid.setup(this, dragController); - // We don't want a hole punched in our window. - ((View) mAllAppsGrid).setWillNotDraw(false); - - // Setup Customize - mCustomizePagedView.setLauncher(this); - mCustomizePagedView.setDragController(dragController); - mCustomizePagedView.setAllAppsPagedView(mAllAppsPagedView); - - // Setup DeleteZone - mDeleteZone = (DeleteZone) mDragLayer.findViewById(R.id.delete_zone); - mDeleteZone.setLauncher(this); - mDeleteZone.setDragController(dragController); - - // Setup the top-right Apps/Customize buttons - mAllAppsButton = findViewById(R.id.all_apps_button); - mDivider = findViewById(R.id.all_apps_divider); - mConfigureButton = findViewById(R.id.configure_button); - mDeleteZone.setOverlappingViews(new View[] { mAllAppsButton, mDivider, - mConfigureButton }); - - // Setup the AllApps Delete toolbar button - allAppsDeleteZone = (DeleteZone) findViewById(R.id.all_apps_delete_zone); - allAppsDeleteZone.setLauncher(this); - allAppsDeleteZone.setDragController(dragController); - allAppsDeleteZone.setDragAndDropEnabled(false); - - // Setup the AllApps Info toolbar button - allAppsInfoTarget = (ApplicationInfoDropTarget) findViewById(R.id.all_apps_info_target); - allAppsInfoTarget.setLauncher(this); - allAppsInfoTarget.setDragAndDropEnabled(false); - - // Setup the AllApps Market toolbar button - View marketButton = findViewById(R.id.market_button); - allAppsInfoTarget.setOverlappingView(marketButton); - } else { - // Get the search/delete bar - mSearchDeleteBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar); - - // Setup AppsCustomize - mAppsCustomizeTabHost = (AppsCustomizeTabHost) - findViewById(R.id.apps_customize_pane); - mAppsCustomizeContent = (AppsCustomizePagedView) - mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content); - mAppsCustomizeContent.setup(this, dragController); - - // Setup AppsCustomize button - mHandleView = (HandleView) mDragLayer.findViewById(R.id.all_apps_button); - mHandleView.setLauncher(this); - mHandleView.setOnLongClickListener(this); - mHandleView.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - onClickAllAppsButton(v); - } - }); + // Get the search/delete bar + mSearchDeleteBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar); + + // Setup AppsCustomize + mAppsCustomizeTabHost = (AppsCustomizeTabHost) + findViewById(R.id.apps_customize_pane); + mAppsCustomizeContent = (AppsCustomizePagedView) + mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content); + mAppsCustomizeContent.setup(this, dragController); + + // Setup AppsCustomize button + mAllAppsButton = mDragLayer.findViewById(R.id.all_apps_button); + mAllAppsButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + onClickAllAppsButton(v); + } + }); + + if (!LauncherApplication.isScreenLarge()) { + // Setup AppsCustomize button on the phone + HandleView handleView = (HandleView) mAllAppsButton; + handleView.setLauncher(this); + handleView.setOnLongClickListener(this); // Setup Hotseat ImageView hotseatLeft = (ImageView) findViewById(R.id.hotseat_left); @@ -995,19 +895,21 @@ public final class Launcher extends Activity mNextView.setOnLongClickListener(this); } - // Setup keylistener for button cluster - mButtonCluster = (ViewGroup) findViewById(R.id.all_apps_button_cluster); - View.OnKeyListener listener = null; - if (LauncherApplication.isScreenLarge()) { - // For tablets, AllApps lives in the button bar at the top - listener = new ButtonBarKeyEventListener(); - } else { - // For phones, AppsCustomize lives in the "dock" at the bottom - listener = new DockKeyEventListener(); - } - int buttonCount = mButtonCluster.getChildCount(); - for (int i = 0; i < buttonCount; ++i) { - mButtonCluster.getChildAt(i).setOnKeyListener(listener); + if (!LauncherApplication.isScreenLarge()) { + // Setup keylistener for button cluster + mButtonCluster = (ViewGroup) findViewById(R.id.all_apps_button_cluster); + View.OnKeyListener listener = null; + if (LauncherApplication.isScreenLarge()) { + // For tablets, AllApps lives in the button bar at the top + listener = new ButtonBarKeyEventListener(); + } else { + // For phones, AppsCustomize lives in the "dock" at the bottom + listener = new DockKeyEventListener(); + } + int buttonCount = mButtonCluster.getChildCount(); + for (int i = 0; i < buttonCount; ++i) { + mButtonCluster.getChildAt(i).setOnKeyListener(listener); + } } // Setup the drag controller (the drop targets have to be added in reverse order) @@ -1015,40 +917,28 @@ public final class Launcher extends Activity dragController.setScrollView(mDragLayer); dragController.setMoveTarget(mWorkspace); dragController.addDropTarget(mWorkspace); - if (mDeleteZone != null) { - dragController.addDragListener(mDeleteZone); - dragController.addDropTarget(mDeleteZone); - } if (mSearchDeleteBar != null) { mSearchDeleteBar.setup(this, dragController); } - if (allAppsDeleteZone != null) { - dragController.addDragListener(allAppsDeleteZone); - dragController.addDropTarget(allAppsDeleteZone); - } - if (allAppsInfoTarget != null) { - dragController.addDragListener(allAppsInfoTarget); - dragController.addDropTarget(allAppsInfoTarget); - } } @SuppressWarnings({"UnusedDeclaration"}) public void previousScreen(View v) { - if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) { + if (mState != State.APPS_CUSTOMIZE) { mWorkspace.scrollLeft(); } } @SuppressWarnings({"UnusedDeclaration"}) public void nextScreen(View v) { - if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) { + if (mState != State.APPS_CUSTOMIZE) { mWorkspace.scrollRight(); } } @SuppressWarnings({"UnusedDeclaration"}) public void launchHotSeat(View v) { - if (mState == State.ALL_APPS) return; + if (mState == State.APPS_CUSTOMIZE) return; int index = -1; if (v.getId() == R.id.hotseat_left) { @@ -1246,9 +1136,6 @@ public final class Launcher extends Activity updateRunning(); // Reset AllApps to it's initial state - if (mAllAppsGrid != null) { - mAllAppsGrid.reset(); - } if (mAppsCustomizeContent != null) { mAppsCustomizeContent.reset(); } @@ -1421,9 +1308,6 @@ public final class Launcher extends Activity } // Reset AllApps to it's initial state - if (mAllAppsGrid != null) { - mAllAppsGrid.reset(); - } if (mAppsCustomizeContent != null) { mAppsCustomizeContent.reset(); } @@ -1466,22 +1350,6 @@ public final class Launcher extends Activity outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id); } - // Save the current AllApps drawer tab - if (mAllAppsGrid != null && mAllAppsGrid instanceof AllAppsTabbed) { - AllAppsTabbed tabhost = (AllAppsTabbed) mAllAppsGrid; - String currentTabTag = tabhost.getCurrentTabTag(); - if (currentTabTag != null) { - outState.putString("allapps_currentTab", currentTabTag); - outState.putInt("allapps_currentPage", mAllAppsPagedView.getCurrentPage()); - } - } - // Save the current customization drawer tab - if (mHomeCustomizationDrawer != null) { - String currentTabTag = mHomeCustomizationDrawer.getCurrentTabTag(); - if (currentTabTag != null) { - outState.putString("customize_currentTab", currentTabTag); - } - } // Save the current AppsCustomize tab if (mAppsCustomizeTabHost != null) { String currentTabTag = mAppsCustomizeTabHost.getCurrentTabTag(); @@ -1605,25 +1473,6 @@ public final class Launcher extends Activity public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - if (mAllAppsGrid != null) { - // If all apps is animating, don't show the menu, because we don't know - // which one to show. - if (mAllAppsGrid.isAnimating()) { - return false; - } - - // Only show the add and wallpaper options when we're not in all apps. - boolean visible = !mAllAppsGrid.isVisible(); - menu.setGroupVisible(MENU_GROUP_ADD, visible); - menu.setGroupVisible(MENU_GROUP_WALLPAPER, visible); - - // Disable add if the workspace is full. - if (visible) { - CellLayout layout = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage()); - menu.setGroupEnabled(MENU_GROUP_ADD, layout.existsEmptyCell()); - } - } - // TODO-APPS_CUSTOMIZE: Remove this for the phone UI at some point, along with all the menu // related code? if (mAppsCustomizeContent != null && mAppsCustomizeContent.isAnimating()) return false; @@ -1676,15 +1525,8 @@ public final class Launcher extends Activity } private void addItems() { - if (LauncherApplication.isScreenLarge()) { - // Animate the widget chooser up from the bottom of the screen - if (mState != State.CUSTOMIZE) { - showCustomizationDrawer(true); - } - } else { - showWorkspace(true); - showAddDialog(-1, -1); - } + showWorkspace(true); + showAddDialog(-1, -1); } private void resetAddInfo() { @@ -1883,7 +1725,7 @@ public final class Launcher extends Activity @Override public void onBackPressed() { - if (mState == State.ALL_APPS || mState == State.CUSTOMIZE || mState == State.APPS_CUSTOMIZE) { + if (mState == State.APPS_CUSTOMIZE) { showWorkspace(true); } else if (mWorkspace.getOpenFolder() != null) { closeFolder(); @@ -1966,8 +1808,8 @@ public final class Launcher extends Activity FolderIcon fi = (FolderIcon) v; handleFolderClick(fi); } - } else if (v == mHandleView) { - if (mState == State.ALL_APPS) { + } else if (v == mAllAppsButton) { + if (mState == State.APPS_CUSTOMIZE) { showWorkspace(true); } else { showAllApps(true); @@ -2159,21 +2001,21 @@ public final class Launcher extends Activity switch (v.getId()) { case R.id.previous_screen: - if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) { + if (mState != State.APPS_CUSTOMIZE) { mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); showPreviews(v); } return true; case R.id.next_screen: - if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) { + if (mState != State.APPS_CUSTOMIZE) { mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); showPreviews(v); } return true; case R.id.all_apps_button: - if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) { + if (mState != State.APPS_CUSTOMIZE) { mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); showPreviews(v); @@ -2357,10 +2199,6 @@ public final class Launcher extends Activity return mWorkspace; } - TabHost getCustomizationDrawer() { - return mHomeCustomizationDrawer; - } - @Override protected Dialog onCreateDialog(int id) { switch (id) { @@ -2509,116 +2347,20 @@ public final class Launcher extends Activity // Now a part of LauncherModel.Callbacks. Used to reorder loading steps. public boolean isAllAppsVisible() { - return (mState == State.ALL_APPS) || (mState == State.APPS_CUSTOMIZE); + return (mState == State.APPS_CUSTOMIZE); } // AllAppsView.Watcher public void zoomed(float zoom) { - // In XLarge view, we zoom down the workspace below all apps so it's still visible - if (zoom == 1.0f && !LauncherApplication.isScreenLarge()) { + if (zoom == 1.0f) { mWorkspace.setVisibility(View.GONE); } } - - private void showAndEnableToolbarButton(View button) { - button.setVisibility(View.VISIBLE); - } - - private void hideToolbarButton(View button) { - // We can't set it to GONE, otherwise the RelativeLayout gets screwed up - button.setVisibility(View.INVISIBLE); - button.setAlpha(0.0f); - } - - /** - * Helper function for showing or hiding a toolbar button, possibly animated. - * - * @param show If true, create an animation to the show the item. Otherwise, hide it. - * @param view The toolbar button to be animated - * @param seq A AnimatorSet that will be used to animate the transition. If null, the - * transition will not be animated. - */ - private void hideOrShowToolbarButton(boolean show, final View view, AnimatorSet seq) { - final boolean showing = show; - final boolean hiding = !show; - - final int duration = show ? - getResources().getInteger(R.integer.config_toolbarButtonFadeInTime) : - getResources().getInteger(R.integer.config_toolbarButtonFadeOutTime); - - if (seq != null) { - ValueAnimator anim = ValueAnimator.ofFloat(view.getAlpha(), show ? 1.0f : 0.0f); - anim.setDuration(duration); - anim.addUpdateListener(new AnimatorUpdateListener() { - public void onAnimationUpdate(ValueAnimator animation) { - view.setAlpha((Float) animation.getAnimatedValue()); - } - }); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - if (showing) showAndEnableToolbarButton(view); - } - @Override - public void onAnimationEnd(Animator animation) { - if (hiding) hideToolbarButton(view); - } - }); - seq.play(anim); - } else { - if (showing) { - showAndEnableToolbarButton(view); - view.setAlpha(1f); - } else { - hideToolbarButton(view); - } - } - } - - /** - * Show/hide the appropriate toolbar buttons for newState. - * If showSeq or hideSeq is null, the transition will be done immediately (not animated). - * - * @param newState The state that is being switched to - * @param showSeq AnimatorSet in which to put "show" animations, or null. - * @param hideSeq AnimatorSet in which to put "hide" animations, or null. - */ - private void hideAndShowToolbarButtons(State newState, AnimatorSet showSeq, AnimatorSet hideSeq) { - switch (newState) { - case WORKSPACE: - hideOrShowToolbarButton(true, mButtonCluster, showSeq); - if (mDeleteZone != null) { - mDeleteZone.setDragAndDropEnabled(true); - if (LauncherApplication.isScreenLarge()) { - mDeleteZone.setText( - getResources().getString(R.string.delete_zone_label_workspace)); - } - } - break; - case ALL_APPS: - case APPS_CUSTOMIZE: - hideOrShowToolbarButton(false, mButtonCluster, hideSeq); - if (mDeleteZone != null) { - mDeleteZone.setDragAndDropEnabled(false); - if (LauncherApplication.isScreenLarge()) { - mDeleteZone.setText( - getResources().getString(R.string.delete_zone_label_all_apps)); - } - } - break; - case CUSTOMIZE: - hideOrShowToolbarButton(false, mButtonCluster, hideSeq); - if (mDeleteZone != null) { - mDeleteZone.setDragAndDropEnabled(false); - } - break; - } - } /** * Helper method for the cameraZoomIn/cameraZoomOut animations * @param view The view being animated - * @param state The state that we are moving in or out of -- either ALL_APPS or CUSTOMIZE + * @param state The state that we are moving in or out of (eg. APPS_CUSTOMIZE) * @param scaleFactor The scale factor used for the zoom */ private void setPivotsForZoom(View view, State state, float scaleFactor) { @@ -2628,7 +2370,7 @@ public final class Launcher extends Activity // Set pivotY so that at the starting zoom factor, the view is partially // visible. Modifying initialHeightFactor changes how much of the view is // initially showing, and hence the perceived angle from which the view enters. - if (state == State.ALL_APPS || state == State.APPS_CUSTOMIZE) { + if (state == State.APPS_CUSTOMIZE) { final float initialHeightFactor = 0.175f; view.setPivotY((1 - initialHeightFactor) * height); } else { @@ -2641,57 +2383,30 @@ public final class Launcher extends Activity * Zoom the camera out from the workspace to reveal 'toView'. * Assumes that the view to show is anchored at either the very top or very bottom * of the screen. - * @param toState The state to zoom out to. Must be ALL_APPS or CUSTOMIZE. + * @param toState The state to zoom out to. Must be APPS_CUSTOMIZE. */ private void cameraZoomOut(State toState, boolean animated, boolean springLoaded) { final Resources res = getResources(); - final boolean toAllApps = (toState == State.ALL_APPS) - || (toState == State.APPS_CUSTOMIZE); - - final int duration = (toAllApps ? - res.getInteger(R.integer.config_appsCustomizeZoomInTime) : - res.getInteger(R.integer.config_customizeZoomInTime)); - final int fadeDuration = (toAllApps ? - res.getInteger(R.integer.config_appsCustomizeFadeInTime) : - res.getInteger(R.integer.config_customizeFadeInTime)); - - final float scale = toAllApps ? - (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor) : - (float) res.getInteger(R.integer.config_customizeZoomScaleFactor); - - View tmpView; - if (toAllApps) { - tmpView = (LauncherApplication.isScreenLarge()) - ? (View) mAllAppsGrid : mAppsCustomizeTabHost; - } else { - tmpView = mHomeCustomizationDrawer; - } - final View toView = tmpView; + + final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime); + final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime); + final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor); + final View toView = mAppsCustomizeTabHost; setPivotsForZoom(toView, toState, scale); - if (toAllApps) { - if (springLoaded) { - if (toState == State.APPS_CUSTOMIZE) { - // Shrink workspaces away if going back to AppsCustomize from spring loaded mode - mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated); - } else { - // Shrink workspaces to bottom if going back to AllApps from spring loaded mode - mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated); - } - } else { - // Shrink workspaces away if going to AllApps/AppsCustomize from workspace - mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated); - if (LauncherApplication.isScreenLarge()) { - // Everytime we launch into AllApps, we reset the successful drop flag which - // controls when it should hide/show the mini workspaces - mAllAppsPagedView.resetSuccessfulDropFlag(); - } + if (springLoaded) { + if (toState == State.APPS_CUSTOMIZE) { + // Shrink workspaces away if going back to AppsCustomize from spring loaded mode + mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated); + } else { + // Shrink workspaces to bottom if going back to AllApps from spring loaded mode + mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated); } } else { - // In Customize mode, shrink the workspaces to the top - mWorkspace.shrink(ShrinkState.TOP, animated); + // Shrink workspaces away if going to AllApps/AppsCustomize from workspace + mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated); } if (animated) { @@ -2705,19 +2420,17 @@ public final class Launcher extends Activity } }); - if (toAllApps) { - toView.setVisibility(View.VISIBLE); - toView.setFastAlpha(0f); - ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(fadeDuration); - alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f)); - alphaAnim.addUpdateListener(new LauncherAnimatorUpdateListener() { - public void onAnimationUpdate(float a, float b) { - // don't need to invalidate because we do so above - toView.setFastAlpha(a * 0f + b * 1f); - } - }); - alphaAnim.start(); - } + toView.setVisibility(View.VISIBLE); + toView.setFastAlpha(0f); + ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(fadeDuration); + alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f)); + alphaAnim.addUpdateListener(new LauncherAnimatorUpdateListener() { + public void onAnimationUpdate(float a, float b) { + // don't need to invalidate because we do so above + toView.setFastAlpha(a * 0f + b * 1f); + } + }); + alphaAnim.start(); if (toView instanceof LauncherTransitionable) { ((LauncherTransitionable) toView).onLauncherTransitionStart(scaleAnim); @@ -2730,9 +2443,6 @@ public final class Launcher extends Activity toView.setTranslationY(0.0f); toView.setVisibility(View.VISIBLE); toView.bringToFront(); - if (!toAllApps) { - toView.setFastAlpha(1.0f); - } } @Override public void onAnimationEnd(Animator animation) { @@ -2747,21 +2457,12 @@ public final class Launcher extends Activity } }); - AnimatorSet toolbarHideAnim = new AnimatorSet(); - AnimatorSet toolbarShowAnim = new AnimatorSet(); - hideAndShowToolbarButtons(toState, toolbarShowAnim, toolbarHideAnim); - // toView should appear right at the end of the workspace shrink animation final int startDelay = 0; if (mStateAnimation != null) mStateAnimation.cancel(); mStateAnimation = new AnimatorSet(); - mStateAnimation.playTogether(scaleAnim, toolbarHideAnim); mStateAnimation.play(scaleAnim).after(startDelay); - - // Show the new toolbar buttons just as the main animation is ending - final int fadeInTime = res.getInteger(R.integer.config_toolbarButtonFadeInTime); - mStateAnimation.play(toolbarShowAnim).after(duration + startDelay - fadeInTime); mStateAnimation.start(); } else { toView.setTranslationX(0.0f); @@ -2774,42 +2475,22 @@ public final class Launcher extends Activity ((LauncherTransitionable) toView).onLauncherTransitionStart(null); ((LauncherTransitionable) toView).onLauncherTransitionEnd(null); } - hideAndShowToolbarButtons(toState, null, null); } } /** * Zoom the camera back into the workspace, hiding 'fromView'. * This is the opposite of cameraZoomOut. - * @param fromState The current state (must be ALL_APPS or CUSTOMIZE). + * @param fromState The current state (must be APPS_CUSTOMIZE). * @param animated If true, the transition will be animated. */ private void cameraZoomIn(State fromState, boolean animated, boolean springLoaded) { Resources res = getResources(); - final boolean fromAllApps = (fromState == State.ALL_APPS) - || (fromState == State.APPS_CUSTOMIZE); - int duration = fromAllApps ? - res.getInteger(R.integer.config_appsCustomizeZoomOutTime) : - res.getInteger(R.integer.config_customizeZoomOutTime); - - final float scaleFactor = fromAllApps ? - (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor) : - (float) res.getInteger(R.integer.config_customizeZoomScaleFactor); - - View tmpView; - if (fromAllApps) { - tmpView = (LauncherApplication.isScreenLarge()) - ? (View) mAllAppsGrid : mAppsCustomizeTabHost; - } else { - tmpView = mHomeCustomizationDrawer; - } - final View fromView = tmpView; - - if (LauncherApplication.isScreenLarge()) { - mCustomizePagedView.endChoiceMode(); - mAllAppsPagedView.endChoiceMode(); - } + final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime); + final float scaleFactor = (float) + res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor); + final View fromView = mAppsCustomizeTabHost; setPivotsForZoom(fromView, fromState, scaleFactor); @@ -2854,18 +2535,7 @@ public final class Launcher extends Activity } }); - AnimatorSet toolbarHideAnim = new AnimatorSet(); - AnimatorSet toolbarShowAnim = new AnimatorSet(); - if (!springLoaded) { - hideAndShowToolbarButtons(State.WORKSPACE, toolbarShowAnim, toolbarHideAnim); - } - - mStateAnimation.playTogether(scaleAnim, toolbarHideAnim, alphaAnim); - - // Show the new toolbar buttons at the very end of the whole animation - final int fadeInTime = res.getInteger(R.integer.config_toolbarButtonFadeInTime); - final int unshrinkTime = res.getInteger(R.integer.config_workspaceUnshrinkTime); - mStateAnimation.play(toolbarShowAnim).after(unshrinkTime - fadeInTime); + mStateAnimation.playTogether(scaleAnim, alphaAnim); mStateAnimation.start(); } else { fromView.setVisibility(View.GONE); @@ -2873,9 +2543,6 @@ public final class Launcher extends Activity ((LauncherTransitionable) fromView).onLauncherTransitionStart(null); ((LauncherTransitionable) fromView).onLauncherTransitionEnd(null); } - if (!springLoaded) { - hideAndShowToolbarButtons(State.WORKSPACE, null, null); - } } } @@ -2891,10 +2558,8 @@ public final class Launcher extends Activity } else { mWorkspace.unshrink(animated); } - if (mState == State.ALL_APPS || mState == State.APPS_CUSTOMIZE) { + if (mState == State.APPS_CUSTOMIZE) { closeAllApps(animated); - } else if (mState == State.CUSTOMIZE) { - hideCustomizationDrawer(animated); } // Change the state *after* we've called all the transition code @@ -2915,40 +2580,67 @@ public final class Launcher extends Activity if (mState == State.APPS_CUSTOMIZE) { mState = State.APPS_CUSTOMIZE_SPRING_LOADED; cameraZoomIn(State.APPS_CUSTOMIZE, true, true); - } else { - // Do nothing } + // Otherwise, we are not in spring loaded mode, so don't do anything. } void exitSpringLoadedDragMode() { if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) { - mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_HIDDEN); + mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_VISIBLE); cameraZoomOut(State.APPS_CUSTOMIZE, true, true); mState = State.APPS_CUSTOMIZE; - } else { - // Do nothing + } + // Otherwise, we are not in spring loaded mode, so don't do anything. + } + + /** + * Shows the dock/hotseat area. + */ + void showDock(boolean animated) { + if (!LauncherApplication.isScreenLarge()) { + if (animated) { + int duration = mSearchDeleteBar.getTransitionInDuration(); + mButtonCluster.animate().alpha(1f).setDuration(duration); + mPreviousView.animate().alpha(1f).setDuration(duration); + mNextView.animate().alpha(1f).setDuration(duration); + } else { + mButtonCluster.setAlpha(1f); + mPreviousView.setAlpha(1f); + mNextView.setAlpha(1f); + } + } + } + + /** + * Hides the dock/hotseat area. + */ + void hideDock(boolean animated) { + if (!LauncherApplication.isScreenLarge()) { + if (animated) { + int duration = mSearchDeleteBar.getTransitionOutDuration(); + mButtonCluster.animate().alpha(0f).setDuration(duration); + mPreviousView.animate().alpha(0f).setDuration(duration); + mNextView.animate().alpha(0f).setDuration(duration); + } else { + mButtonCluster.setAlpha(0f); + mPreviousView.setAlpha(0f); + mNextView.setAlpha(0f); + } } } void showAllApps(boolean animated) { if (mState != State.WORKSPACE) return; - if (LauncherApplication.isScreenLarge()) { - cameraZoomOut(State.ALL_APPS, animated, false); - ((View) mAllAppsGrid).requestFocus(); - if (mDeleteZone != null) { - mDeleteZone.setVisibility(View.GONE); - } + cameraZoomOut(State.APPS_CUSTOMIZE, animated, false); + mAppsCustomizeTabHost.requestFocus(); - // Change the state *after* we've called all the transition code - mState = State.ALL_APPS; - } else { - cameraZoomOut(State.APPS_CUSTOMIZE, animated, false); - mAppsCustomizeTabHost.requestFocus(); + // Hide the search bar and dock + mSearchDeleteBar.hideSearchBar(animated); + hideDock(animated); - // Change the state *after* we've called all the transition code - mState = State.APPS_CUSTOMIZE; - } + // Change the state *after* we've called all the transition code + mState = State.APPS_CUSTOMIZE; // Pause the auto-advance of widgets until we are out of AllApps mUserPresent = false; @@ -2998,22 +2690,16 @@ public final class Launcher extends Activity * - From another workspace */ void closeAllApps(boolean animated) { - if (LauncherApplication.isScreenLarge()) { - if (mState == State.ALL_APPS) { - mWorkspace.setVisibility(View.VISIBLE); - cameraZoomIn(State.ALL_APPS, animated, false); + if (mState == State.APPS_CUSTOMIZE || mState == State.APPS_CUSTOMIZE_SPRING_LOADED) { + mWorkspace.setVisibility(View.VISIBLE); + cameraZoomIn(State.APPS_CUSTOMIZE, animated, false); - // Set focus to the AllApps button - findViewById(R.id.all_apps_button).requestFocus(); - } - } else { - if (mState == State.APPS_CUSTOMIZE || mState == State.APPS_CUSTOMIZE_SPRING_LOADED) { - mWorkspace.setVisibility(View.VISIBLE); - cameraZoomIn(State.APPS_CUSTOMIZE, animated, false); + // Show the search bar and dock + mSearchDeleteBar.showSearchBar(animated); + showDock(animated); - // Set focus to the AllApps button - findViewById(R.id.all_apps_button).requestFocus(); - } + // Set focus to the AppsCustomize button + findViewById(R.id.all_apps_button).requestFocus(); } } @@ -3025,32 +2711,6 @@ public final class Launcher extends Activity // TODO } - // Show the customization drawer (only exists in x-large configuration) - private void showCustomizationDrawer(boolean animated) { - if (mState != State.WORKSPACE) { - return; - } - - cameraZoomOut(State.CUSTOMIZE, animated, false); - - // Change the state *after* we've called all the transition code - mState = State.CUSTOMIZE; - - // Pause the auto-advance of widgets until we are out of Customization drawer - mUserPresent = false; - updateRunning(); - } - - // Hide the customization drawer (only exists in x-large configuration) - void hideCustomizationDrawer(boolean animated) { - if (mState == State.CUSTOMIZE) { - cameraZoomIn(State.CUSTOMIZE, animated, false); - - // Set focus to the customize button - findViewById(R.id.configure_button).requestFocus(); - } - } - /** * Add an item from all apps or customize onto the given workspace screen. * If layout is null, add to the current screen. @@ -3361,9 +3021,6 @@ public final class Launcher extends Activity } } - void setAllAppsPagedView(AllAppsPagedView view) { - mAllAppsPagedView = view; - } /** * Refreshes the shortcuts shown on the workspace. @@ -3518,15 +3175,6 @@ public final class Launcher extends Activity mSavedInstanceState = null; } - // Workaround a bug that occurs when rotating the device while the customization mode is - // open, we trigger a new layout on all the CellLayout children. - if (LauncherApplication.isScreenLarge() && (mState == State.CUSTOMIZE)) { - final int childCount = mWorkspace.getChildCount(); - for (int i = 0; i < childCount; ++i) { - mWorkspace.getChildAt(i).requestLayout(); - } - } - mWorkspaceLoading = false; // If we received the result of any pending adds while the loader was running (e.g. the @@ -3553,15 +3201,9 @@ public final class Launcher extends Activity * Implementation of the method from LauncherModel.Callbacks. */ public void bindAllApplications(ArrayList apps) { - if (mAllAppsGrid != null) { - mAllAppsGrid.setApps(apps); - } if (mAppsCustomizeContent != null) { mAppsCustomizeContent.setApps(apps); } - if (mCustomizePagedView != null) { - mCustomizePagedView.setApps(apps); - } updateIconsAffectedByPackageManagerChanges(); } @@ -3573,15 +3215,10 @@ public final class Launcher extends Activity public void bindAppsAdded(ArrayList apps) { setLoadOnResume(); removeDialog(DIALOG_CREATE_SHORTCUT); - if (mAllAppsGrid != null) { - mAllAppsGrid.addApps(apps); - } + if (mAppsCustomizeContent != null) { mAppsCustomizeContent.addApps(apps); } - if (mCustomizePagedView != null) { - mCustomizePagedView.addApps(apps); - } updateIconsAffectedByPackageManagerChanges(); } @@ -3596,15 +3233,10 @@ public final class Launcher extends Activity if (mWorkspace != null) { mWorkspace.updateShortcuts(apps); } - if (mAllAppsGrid != null) { - mAllAppsGrid.updateApps(apps); - } + if (mAppsCustomizeContent != null) { mAppsCustomizeContent.updateApps(apps); } - if (mCustomizePagedView != null) { - mCustomizePagedView.updateApps(apps); - } updateIconsAffectedByPackageManagerChanges(); } @@ -3618,15 +3250,10 @@ public final class Launcher extends Activity if (permanent) { mWorkspace.removeItems(apps); } - if (mAllAppsGrid != null) { - mAllAppsGrid.removeApps(apps); - } + if (mAppsCustomizeContent != null) { mAppsCustomizeContent.removeApps(apps); } - if (mCustomizePagedView != null) { - mCustomizePagedView.removeApps(apps); - } updateIconsAffectedByPackageManagerChanges(); } @@ -3634,10 +3261,7 @@ public final class Launcher extends Activity * A number of packages were updated. */ public void bindPackagesUpdated() { - // update the customization drawer contents - if (mCustomizePagedView != null) { - mCustomizePagedView.update(); - } + if (mAppsCustomizeContent != null) { mAppsCustomizeContent.onPackagesUpdated(); } @@ -3699,9 +3323,7 @@ public final class Launcher extends Activity Log.d(TAG, "mDesktopItems.size=" + mDesktopItems.size()); Log.d(TAG, "sFolders.size=" + sFolders.size()); mModel.dumpState(); - if (mAllAppsGrid != null) { - mAllAppsGrid.dumpState(); - } + if (mAppsCustomizeContent != null) { mAppsCustomizeContent.dumpState(); } diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java index 67573e083..68b164436 100644 --- a/src/com/android/launcher2/LauncherApplication.java +++ b/src/com/android/launcher2/LauncherApplication.java @@ -29,7 +29,6 @@ public class LauncherApplication extends Application { public IconCache mIconCache; private static boolean sIsScreenLarge; private static float sScreenDensity; - private static final boolean ENABLE_ROTATION = false; @Override public void onCreate() { @@ -98,10 +97,6 @@ public class LauncherApplication extends Application { return mModel; } - public static boolean isInPlaceRotationEnabled() { - return sIsScreenLarge && ENABLE_ROTATION; - } - public static boolean isScreenLarge() { return sIsScreenLarge; } diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java index 605f4b69f..d83db7435 100644 --- a/src/com/android/launcher2/PagedView.java +++ b/src/com/android/launcher2/PagedView.java @@ -77,7 +77,6 @@ public abstract class PagedView extends ViewGroup { protected int mCurrentPage; protected int mNextPage = INVALID_PAGE; - protected int mRestorePage = -1; protected int mMaxScrollX; protected Scroller mScroller; private VelocityTracker mVelocityTracker; @@ -112,7 +111,6 @@ public abstract class PagedView extends ViewGroup { protected int mPageLayoutPaddingRight; protected int mPageLayoutWidthGap; protected int mPageLayoutHeightGap; - protected int mPageLayoutMaxHeight; protected int mCellCountX = 0; protected int mCellCountY = 0; protected boolean mCenterPagesVertically; @@ -161,6 +159,9 @@ public abstract class PagedView extends ViewGroup { protected boolean mIsPageMoving = false; + // All syncs and layout passes are deferred until data is ready. + protected boolean mIsDataReady = false; + public interface PageSwitchListener { void onPageSwitch(View newPage, int newPageIndex); } @@ -192,8 +193,6 @@ public abstract class PagedView extends ViewGroup { R.styleable.PagedView_pageLayoutWidthGap, -1); mPageLayoutHeightGap = a.getDimensionPixelSize( R.styleable.PagedView_pageLayoutHeightGap, -1); - mPageLayoutMaxHeight = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutMaxHeight, -1); a.recycle(); setHapticFeedbackEnabled(false); @@ -223,6 +222,17 @@ public abstract class PagedView extends ViewGroup { } } + /** + * Called by subclasses to mark that data is ready, and that we can begin loading and laying + * out pages. + */ + protected void setDataIsReady() { + mIsDataReady = true; + } + protected boolean isDataReady() { + return mIsDataReady; + } + /** * Returns the index of the currently displayed page. * @@ -244,10 +254,6 @@ public abstract class PagedView extends ViewGroup { return getWidth(); } - public int getTouchState() { - return mTouchState; - } - /** * Updates the scroll of the current page immediately to its final scroll position. We use this * in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of @@ -376,6 +382,11 @@ public abstract class PagedView extends ViewGroup { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (!mIsDataReady) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + return; + } + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); final int widthSize = MeasureSpec.getSize(widthMeasureSpec); if (widthMode != MeasureSpec.EXACTLY) { @@ -393,9 +404,6 @@ public abstract class PagedView extends ViewGroup { final int verticalPadding = mPaddingTop + mPaddingBottom; - if (mPageLayoutMaxHeight != -1) { - heightSize = Math.min(mPageLayoutMaxHeight, heightSize); - } // The children are given the same width and height as the workspace // unless they were set to WRAP_CONTENT @@ -489,6 +497,10 @@ public abstract class PagedView extends ViewGroup { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (!mIsDataReady) { + return; + } + if (DEBUG) Log.d(TAG, "PagedView.onLayout()"); if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) { setHorizontalScrollBarEnabled(false); @@ -560,10 +572,14 @@ public abstract class PagedView extends ViewGroup { if (distanceFromScreenCenter > 0) { if (i > 0) { d += getScaledMeasuredWidth(getChildAt(i - 1)) / 2; + } else { + continue; } } else { if (i < childCount - 1) { d += getScaledMeasuredWidth(getChildAt(i + 1)) / 2; + } else { + continue; } } d += mPageSpacing; @@ -839,7 +855,6 @@ public abstract class PagedView extends ViewGroup { } case MotionEvent.ACTION_UP: - onWallpaperTap(ev); case MotionEvent.ACTION_CANCEL: mTouchState = TOUCH_STATE_REST; mAllowLongPress = false; @@ -1176,8 +1191,7 @@ public abstract class PagedView extends ViewGroup { } } - protected void onWallpaperTap(MotionEvent ev) { - } + protected void onWallpaperTap(MotionEvent ev) {} @Override public void requestChildFocus(View child, View focused) { @@ -1537,10 +1551,6 @@ public abstract class PagedView extends ViewGroup { } } - public void setRestorePage(int restorePage) { - mRestorePage = restorePage; - } - /** * 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 @@ -1568,6 +1578,10 @@ public abstract class PagedView extends ViewGroup { } protected void invalidatePageData() { + if (!mIsDataReady) { + return; + } + if (mContentIsRefreshable) { // Update all the pages syncPages(); @@ -1579,12 +1593,6 @@ public abstract class PagedView extends ViewGroup { mDirtyPageContent.add(true); } - // Use the restore page if necessary - if (mRestorePage > -1) { - mCurrentPage = mRestorePage; - mRestorePage = -1; - } - // Load any pages that are necessary for the current window of views loadAssociatedPages(mCurrentPage); mDirtyPageAlpha = true; diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java index 901ac2680..d7f8784a5 100644 --- a/src/com/android/launcher2/PagedViewCellLayout.java +++ b/src/com/android/launcher2/PagedViewCellLayout.java @@ -40,6 +40,7 @@ public class PagedViewCellLayout extends ViewGroup implements Page { private int mCellHeight; private int mWidthGap; private int mHeightGap; + private float mPeekWidth; protected PagedViewCellLayoutChildren mChildren; private PagedViewCellLayoutChildren mHolographicChildren; private boolean mAllowHardwareLayerCreation = false; @@ -62,6 +63,7 @@ public class PagedViewCellLayout extends ViewGroup implements Page { Resources resources = context.getResources(); mCellWidth = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_width); mCellHeight = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_height); + mPeekWidth = resources.getDimensionPixelSize(R.dimen.apps_customize_peek_width); mCellCountX = LauncherModel.getCellCountX(); mCellCountY = LauncherModel.getCellCountY(); mWidthGap = mHeightGap = -1; @@ -229,11 +231,11 @@ public class PagedViewCellLayout extends ViewGroup implements Page { int vSpaceLeft = heightSpecSize - mPaddingTop - mPaddingBottom - (cellHeight * mCellCountY); - int heightGap = vSpaceLeft / numHeightGaps; + int heightGap = (numHeightGaps <= 0) ? 0 : (vSpaceLeft / numHeightGaps); int hSpaceLeft = widthSpecSize - mPaddingLeft - mPaddingRight - (cellWidth * mCellCountX); - int widthGap = hSpaceLeft / numWidthGaps; + int widthGap = (numWidthGaps <= 0) ? 0 : (hSpaceLeft / numWidthGaps); // center it around the min gaps int minGap = Math.min(widthGap, heightGap); @@ -271,15 +273,7 @@ public class PagedViewCellLayout extends ViewGroup implements Page { } int getContentWidth() { - if (LauncherApplication.isScreenLarge()) { - // Return the distance from the left edge of the content of the leftmost icon to - // the right edge of the content of the rightmost icon - - // icons are centered within cells, find out how much padding that accounts for - return getWidthBeforeFirstLayout() - (mCellWidth - Utilities.getIconContentSize()); - } else { - return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight; - } + return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight; } int getContentHeight() { @@ -308,7 +302,20 @@ public class PagedViewCellLayout extends ViewGroup implements Page { @Override public boolean onTouchEvent(MotionEvent event) { - return super.onTouchEvent(event) || true; + boolean result = super.onTouchEvent(event); + int count = getPageChildCount(); + if (count > 0) { + // We only intercept the touch if we are tapping in empty space after the final row + View child = getChildOnPageAt(count - 1); + int bottom = child.getBottom(); + int numRows = (int) Math.ceil((float) getPageChildCount() / getCellCountX()); + if (numRows < getCellCountY()) { + // Add a little bit of buffer if there is room for another row + bottom += mCellHeight / 2; + } + result = result || (event.getY() < bottom); + } + return result; } public void enableCenteredContent(boolean enabled) { @@ -361,16 +368,37 @@ public class PagedViewCellLayout extends ViewGroup implements Page { * Estimates the number of cells that the specified width would take up. */ public int estimateCellHSpan(int width) { - // TODO: we need to take widthGap into effect - return (width + mCellWidth) / mCellWidth; + // The space for a page assuming that we want to show half of a column of the previous and + // next pages is the width - left padding (current & next page) - right padding (previous & + // current page) - half cell width (for previous and next pages) + int availWidth = (int) (width - (2 * mPaddingLeft + 2 * mPaddingRight) - (2 * mPeekWidth)); + + // We know that we have to fit N cells with N-1 width gaps, so we just juggle to solve for N + int n = Math.max(1, (availWidth + mWidthGap) / (mCellWidth + mWidthGap)); + + // We don't do anything fancy to determine if we squeeze another row in. + return n; } /** * Estimates the number of cells that the specified height would take up. */ public int estimateCellVSpan(int height) { - // TODO: we need to take heightGap into effect - return (height + mCellHeight) / mCellHeight; + // The space for a page is the height - top padding (current page) - bottom padding (current + // page) + int availHeight = height - (mPaddingTop + mPaddingBottom); + + // We know that we have to fit N cells with N-1 height gaps, so we juggle to solve for N + int n = Math.max(1, (availHeight + mHeightGap) / (mCellHeight + mHeightGap)); + + // We don't do anything fancy to determine if we squeeze another row in. + return n; + } + + public void calculateCellCount(int width, int height, int maxCellCountX, int maxCellCountY) { + mCellCountX = Math.min(maxCellCountX, estimateCellHSpan(width)); + mCellCountY = Math.min(maxCellCountY, estimateCellVSpan(height)); + requestLayout(); } /** diff --git a/src/com/android/launcher2/PagedViewGridLayout.java b/src/com/android/launcher2/PagedViewGridLayout.java index cedf71c5b..c6d39fd5f 100644 --- a/src/com/android/launcher2/PagedViewGridLayout.java +++ b/src/com/android/launcher2/PagedViewGridLayout.java @@ -59,14 +59,15 @@ public class PagedViewGridLayout extends FrameLayout implements Page { @Override public boolean onTouchEvent(MotionEvent event) { - // We eat up the touch events here, since the PagedView (which uses the same swiping - // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when - // the user is scrolling between pages. This means that if the pages themselves don't - // handle touch events, it gets forwarded up to PagedView itself, and it's own - // onTouchEvent() handling will prevent further intercept touch events from being called - // (it's the same view in that case). This is not ideal, but to prevent more changes, - // we just always mark the touch event as handled. - return super.onTouchEvent(event) || true; + boolean result = super.onTouchEvent(event); + int count = getPageChildCount(); + if (count > 0) { + // We only intercept the touch if we are tapping in empty space after the final row + View child = getChildOnPageAt(count - 1); + int bottom = child.getBottom(); + result = result || (event.getY() < bottom); + } + return result; } @Override diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java index 7a208b761..5ab28ea4a 100644 --- a/src/com/android/launcher2/SearchDropTargetBar.java +++ b/src/com/android/launcher2/SearchDropTargetBar.java @@ -33,8 +33,9 @@ import com.android.launcher.R; public class SearchDropTargetBar extends FrameLayout implements DragController.DragListener { private static final int sTransitionInDuration = 275; - private static final int sTransitionOutDuration = 200; + private static final int sTransitionOutDuration = 100; + private boolean mIsSearchBarHidden; private View mQSBSearchBar; private View mDropTargetBar; private IconDropTarget mInfoDropTarget; @@ -69,20 +70,54 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D mDeleteDropTarget = (IconDropTarget) mDropTargetBar.findViewById(R.id.delete_target); } + /* + * Shows and hides the search bar. + */ + public void showSearchBar(boolean animated) { + if (animated) { + mQSBSearchBar.animate().alpha(1f).setDuration(sTransitionInDuration); + } else { + mQSBSearchBar.setAlpha(1f); + } + mIsSearchBarHidden = false; + } + public void hideSearchBar(boolean animated) { + if (animated) { + mQSBSearchBar.animate().alpha(0f).setDuration(sTransitionOutDuration); + } else { + mQSBSearchBar.setAlpha(0f); + } + mIsSearchBarHidden = true; + } + + /* + * Gets various transition durations. + */ + public int getTransitionInDuration() { + return sTransitionInDuration; + } + public int getTransitionOutDuration() { + return sTransitionOutDuration; + } + /* * DragController.DragListener implementation */ @Override public void onDragStart(DragSource source, Object info, int dragAction) { // Animate out the QSB search bar, and animate in the drop target bar - mQSBSearchBar.animate().alpha(0f).setDuration(sTransitionOutDuration); mDropTargetBar.animate().alpha(1f).setDuration(sTransitionInDuration); + if (!mIsSearchBarHidden) { + mQSBSearchBar.animate().alpha(0f).setDuration(sTransitionOutDuration); + } } @Override public void onDragEnd() { // Restore the QSB search bar, and animate out the drop target bar mDropTargetBar.animate().alpha(0f).setDuration(sTransitionOutDuration); - mQSBSearchBar.animate().alpha(1f).setDuration(sTransitionInDuration); + if (!mIsSearchBarHidden) { + mQSBSearchBar.animate().alpha(1f).setDuration(sTransitionInDuration); + } } } diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 216c74ec6..b6e4f563d 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -106,17 +106,12 @@ public class Workspace extends SmoothPagedView private ValueAnimator mBackgroundFadeInAnimation; private ValueAnimator mBackgroundFadeOutAnimation; private Drawable mBackground; - private Drawable mCustomizeTrayBackground; boolean mDrawBackground = true; - private boolean mDrawCustomizeTrayBackground; private float mBackgroundAlpha = 0; private float mOverScrollMaxBackgroundAlpha = 0.0f; private int mOverScrollPageIndex = -1; - private View mCustomizationDrawer; - private View mCustomizationDrawerContent; - private int[] mCustomizationDrawerPos = new int[2]; - private float[] mCustomizationDrawerTransformedPos = new float[2]; + private final WallpaperManager mWallpaperManager; private IBinder mWindowToken; @@ -173,7 +168,7 @@ public class Workspace extends SmoothPagedView private boolean mIsInUnshrinkAnimation = false; private AnimatorListener mShrinkAnimationListener; private AnimatorListener mUnshrinkAnimationListener; - enum ShrinkState { TOP, SPRING_LOADED, MIDDLE, BOTTOM_HIDDEN, BOTTOM_VISIBLE }; + enum ShrinkState { SPRING_LOADED, MIDDLE, BOTTOM_HIDDEN, BOTTOM_VISIBLE }; private ShrinkState mShrinkState; private boolean mWaitingToShrink = false; private ShrinkState mWaitingToShrinkState; @@ -257,6 +252,9 @@ public class Workspace extends SmoothPagedView super(context, attrs, defStyle); mContentIsRefreshable = false; + // With workspace, data is available straight from the get-go + setDataIsReady(); + if (!LauncherApplication.isScreenLarge()) { mFadeInAdjacentScreens = false; } @@ -330,7 +328,6 @@ public class Workspace extends SmoothPagedView try { final Resources res = getResources(); mBackground = res.getDrawable(R.drawable.all_apps_bg_gradient); - mCustomizeTrayBackground = res.getDrawable(R.drawable.customize_bg_gradient); } catch (Resources.NotFoundException e) { // In this case, we will skip drawing background protection } @@ -345,8 +342,12 @@ public class Workspace extends SmoothPagedView public void onAnimationEnd(Animator animation) { mIsInUnshrinkAnimation = false; mSyncWallpaperOffsetWithScroll = true; - if (mShrinkState != ShrinkState.SPRING_LOADED) { - mDrawCustomizeTrayBackground = false; + if (mShrinkState == ShrinkState.SPRING_LOADED) { + View layout = null; + if (mLastDragView != null) { + layout = findMatchingPageForDragOver(mLastDragView, mLastDragOriginX, + mLastDragOriginY, mLastDragXOffset, mLastDragYOffset); + } } mWallpaperOffset.setOverrideHorizontalCatchupConstant(false); mAnimator = null; @@ -598,24 +599,6 @@ public class Workspace extends SmoothPagedView mYDown = ev.getY(); } - if (mIsSmall || mIsInUnshrinkAnimation) { - if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN) { - // Intercept this event so we can show the workspace in full view - // when it is clicked on and it is small - PagedView appsPane = null; - if (LauncherApplication.isScreenLarge()) { - appsPane = (PagedView) mLauncher.findViewById(R.id.all_apps_paged_view); - } else { - appsPane = (PagedView) mLauncher.findViewById(R.id.apps_customize_pane_content); - } - - if (appsPane != null) { - appsPane.onInterceptTouchEvent(ev); - } - return true; - } - return false; - } return super.onInterceptTouchEvent(ev); } @@ -1000,12 +983,6 @@ public class Workspace extends SmoothPagedView private void showBackgroundGradientForAllApps() { showBackgroundGradient(); - mDrawCustomizeTrayBackground = false; - } - - private void showBackgroundGradientForCustomizeTray() { - showBackgroundGradient(); - mDrawCustomizeTrayBackground = true; } private void showBackgroundGradient() { @@ -1169,12 +1146,6 @@ public class Workspace extends SmoothPagedView } }); } - - if (LauncherApplication.isInPlaceRotationEnabled()) { - // When the device is rotated, the scroll position of the current screen - // needs to be refreshed - setCurrentPage(getCurrentPage()); - } } public void showFolderAccept(FolderRingAnimator fra) { @@ -1195,33 +1166,10 @@ public class Workspace extends SmoothPagedView // Draw the background gradient if necessary if (mBackground != null && mBackgroundAlpha > 0.0f && mDrawBackground) { int alpha = (int) (mBackgroundAlpha * 255); - if (mDrawCustomizeTrayBackground) { - // Find out where to offset the gradient for the customization tray content - mCustomizationDrawer.getLocationOnScreen(mCustomizationDrawerPos); - final Matrix m = mCustomizationDrawer.getMatrix(); - mCustomizationDrawerTransformedPos[0] = 0.0f; - mCustomizationDrawerTransformedPos[1] = mCustomizationDrawerContent.getTop(); - m.mapPoints(mCustomizationDrawerTransformedPos); - - // Draw the bg glow behind the gradient - mCustomizeTrayBackground.setAlpha(alpha); - mCustomizeTrayBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(), - getMeasuredHeight()); - mCustomizeTrayBackground.draw(canvas); - - // Draw the bg gradient - final int offset = (int) (mCustomizationDrawerPos[1] + - mCustomizationDrawerTransformedPos[1]); - mBackground.setAlpha(alpha); - mBackground.setBounds(mScrollX, offset, mScrollX + getMeasuredWidth(), - offset + getMeasuredHeight()); - mBackground.draw(canvas); - } else { - mBackground.setAlpha(alpha); - mBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(), - getMeasuredHeight()); - mBackground.draw(canvas); - } + mBackground.setAlpha(alpha); + mBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(), + getMeasuredHeight()); + mBackground.draw(canvas); } // The folder outer / inner ring image(s) @@ -1401,39 +1349,6 @@ public class Workspace extends SmoothPagedView } } - @Override - public boolean onTouchEvent(MotionEvent ev) { - if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN) { - PagedView appsPane; - if (LauncherApplication.isScreenLarge()) { - appsPane = (PagedView) mLauncher.findViewById(R.id.all_apps_paged_view); - } else { - appsPane = (PagedView) mLauncher.findViewById(R.id.apps_customize_pane_content); - } - - if (appsPane != null) { - if (ev.getAction() == MotionEvent.ACTION_UP && - appsPane.getTouchState() == TOUCH_STATE_REST) { - - // Cancel any scrolling that is in progress. - if (!mScroller.isFinished()) { - mScroller.abortAnimation(); - } - setCurrentPage(mCurrentPage); - - if (mShrinkState == ShrinkState.BOTTOM_HIDDEN) { - mLauncher.showWorkspace(true); - } - appsPane.onTouchEvent(ev); - return true; - } else { - return appsPane.onTouchEvent(ev); - } - } - } - return super.onTouchEvent(ev); - } - protected void enableChildrenLayers(boolean enable) { for (int i = 0; i < getPageCount(); i++) { ((ViewGroup)getChildAt(i)).setChildrenLayersEnabled(enable); @@ -1488,18 +1403,6 @@ public class Workspace extends SmoothPagedView shrink(shrinkState, true); } - private int getCustomizeDrawerHeight() { - TabHost customizationDrawer = mLauncher.getCustomizationDrawer(); - int height = customizationDrawer.getHeight(); - TabWidget tabWidget = (TabWidget) - customizationDrawer.findViewById(com.android.internal.R.id.tabs); - if (tabWidget.getTabCount() > 0) { - TextView tabText = (TextView) tabWidget.getChildTabViewAt(0); - // subtract the empty space above the tab text - height -= ((tabWidget.getHeight() - tabText.getLineHeight())) / 2; - } - return height; - } // we use this to shrink the workspace for the all apps view and the customize view public void shrink(ShrinkState shrinkState, boolean animated) { @@ -1571,8 +1474,6 @@ public class Workspace extends SmoothPagedView } else if (shrinkState == ShrinkState.MIDDLE) { y = screenHeight / 2 - scaledPageHeight / 2; finalAlpha = 1.0f; - } else if (shrinkState == ShrinkState.TOP) { - y = (screenHeight - getCustomizeDrawerHeight() - scaledPageHeight) / 2; } int duration; @@ -1667,11 +1568,6 @@ public class Workspace extends SmoothPagedView if (enableWallpaperEffects) { switch (shrinkState) { // animating in - case TOP: - // customize - wallpaperOffset = 0.5f + offsetFromCenter; - mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.46f : 0.44f); - break; case MIDDLE: case SPRING_LOADED: wallpaperOffset = 0.5f; @@ -1740,11 +1636,7 @@ public class Workspace extends SmoothPagedView } setChildrenDrawnWithCacheEnabled(true); - if (shrinkState == ShrinkState.TOP) { - showBackgroundGradientForCustomizeTray(); - } else { - showBackgroundGradientForAllApps(); - } + showBackgroundGradientForAllApps(); } /* @@ -1826,14 +1718,10 @@ public class Workspace extends SmoothPagedView cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY)); } else { switch (state) { - case TOP: - cl.setIsDefaultDropTarget(i == mCurrentPage); case BOTTOM_HIDDEN: case BOTTOM_VISIBLE: case SPRING_LOADED: - if (state != ShrinkState.TOP) { - cl.setIsDefaultDropTarget(false); - } + cl.setIsDefaultDropTarget(false); if (!isDragHappening) { // even if a drag isn't happening, we don't want to show a screen as // accepting drops if it doesn't have at least one free cell @@ -2045,14 +1933,6 @@ public class Workspace extends SmoothPagedView if (enableWallpaperEffects) { switch (mShrinkState) { // animating out - case TOP: - // customize - if (animated) { - mWallpaperOffset.setHorizontalCatchupConstant(isLandscape ? 0.65f : 0.62f); - mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.65f : 0.62f); - mWallpaperOffset.setOverrideHorizontalCatchupConstant(true); - } - break; case MIDDLE: case SPRING_LOADED: if (animated) { @@ -2541,13 +2421,6 @@ public class Workspace extends SmoothPagedView if (d.dragSource != this) { final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1] }; - if (LauncherApplication.isScreenLarge() && (mIsSmall || mIsInUnshrinkAnimation) - && !mLauncher.isAllAppsVisible()) { - // When the workspace is shrunk and the drop comes from customize, don't actually - // add the item to the screen -- customize will do this itself - ((ItemInfo) d.dragInfo).dropPos = touchXY; - return; - } onDropExternal(touchXY, d.dragInfo, dropTargetLayout, false, d.dragView); } else if (mDragInfo != null) { final View cell = mDragInfo.cell; @@ -3367,12 +3240,6 @@ public class Workspace extends SmoothPagedView void setup(Launcher launcher, DragController dragController) { mLauncher = launcher; mSpringLoadedDragController = new SpringLoadedDragController(mLauncher); - - mCustomizationDrawer = mLauncher.findViewById(R.id.customization_drawer); - if (mCustomizationDrawer != null) { - mCustomizationDrawerContent = - mCustomizationDrawer.findViewById(com.android.internal.R.id.tabcontent); - } mDragController = dragController; } -- cgit v1.2.3