From 655ec42ce50e18f2ce597901707057b5898e110a Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 7 Feb 2017 11:40:22 -0800 Subject: [PATCH] Added FolderIconPreviewVerifier class. This class verifies whether an item in a Foder is displayed in the FolderIcon preview, based on the item's rank. We use this class to determine which items in a Folder will be displayed in the preview. Bug: 35064148 Change-Id: Ia21bccbd95c348efeac62591ae3696a4c60b5339 --- src/com/android/launcher3/LauncherModel.java | 19 ++++-- .../folder/ClippedFolderIconLayoutRule.java | 20 ------ .../android/launcher3/folder/FolderIcon.java | 23 ++++++- .../folder/FolderIconPreviewVerifier.java | 64 ++++++++++++++++++ .../launcher3/folder/FolderPagedView.java | 65 ++++++++++++------- .../folder/StackFolderIconLayoutRule.java | 6 -- 6 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 src/com/android/launcher3/folder/FolderIconPreviewVerifier.java diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 8c90c2cb15..845fdbfebc 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -48,6 +48,7 @@ import com.android.launcher3.config.ProviderConfig; import com.android.launcher3.dynamicui.ExtractionUtils; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; +import com.android.launcher3.folder.FolderIconPreviewVerifier; import com.android.launcher3.graphics.LauncherIcons; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.AddWorkspaceItemsTask; @@ -1260,17 +1261,23 @@ public class LauncherModel extends BroadcastReceiver } } - // Sort all the folder items and make sure the first 3 items are high resolution. + FolderIconPreviewVerifier verifier = + new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile()); + // Sort the folder items and make sure all items in the preview are high resolution. for (FolderInfo folder : sBgDataModel.folders) { Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR); - int pos = 0; + verifier.setFolderInfo(folder); + + int numItemsInPreview = 0; for (ShortcutInfo info : folder.contents) { - if (info.usingLowResIcon && - info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { + if (info.usingLowResIcon + && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION + && verifier.isItemInPreview(info.rank)) { mIconCache.getTitleAndIcon(info, false); + numItemsInPreview++; } - pos ++; - if (pos >= FolderIcon.NUM_ITEMS_IN_PREVIEW) { + + if (numItemsInPreview >= FolderIcon.NUM_ITEMS_IN_PREVIEW) { break; } } diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java index 840fcf5fe1..194a62fe4e 100644 --- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java +++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java @@ -129,24 +129,4 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule public boolean clipToBackground() { return true; } - - @Override - public List getItemsToDisplay(Folder folder) { - List items = new ArrayList<>(folder.getItemsInReadingOrder()); - int numItems = items.size(); - if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION && numItems > MAX_NUM_ITEMS_IN_PREVIEW) { - // We match the icons in the preview with the layout of the opened folder (b/27944225), - // but we still need to figure out how we want to handle updating the preview when the - // upper left quadrant changes. - int appsPerRow = folder.mContent.getPageAt(0).getCountX(); - int appsToDelete = appsPerRow - MAX_NUM_ITEMS_PER_ROW; - - // We only display the upper left quadrant. - while (appsToDelete > 0) { - items.remove(MAX_NUM_ITEMS_PER_ROW); - appsToDelete--; - } - } - return items.subList(0, Math.min(numItems, MAX_NUM_ITEMS_IN_PREVIEW)); - } } diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index fce902e495..5ba2f79c48 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -121,6 +121,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { private float mSlop; + FolderIconPreviewVerifier mPreviewVerifier; private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0); private ArrayList mDrawingParams = new ArrayList(); private Drawable mReferenceDrawable = null; @@ -222,6 +223,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { private void setFolder(Folder folder) { mFolder = folder; + mPreviewVerifier = new FolderIconPreviewVerifier(mLauncher.getDeviceProfile().inv); updateItemDrawingParams(false); } @@ -933,8 +935,26 @@ public class FolderIcon extends FrameLayout implements FolderListener { return mFolderName.getVisibility() == VISIBLE; } + private List getItemsToDisplay() { + mPreviewVerifier.setFolderInfo(mFolder.getInfo()); + + List itemsToDisplay = new ArrayList<>(); + List allItems = mFolder.getItemsInReadingOrder(); + int numItems = allItems.size(); + for (int rank = 0; rank < numItems; ++rank) { + if (mPreviewVerifier.isItemInPreview(rank)) { + itemsToDisplay.add(allItems.get(rank)); + } + + if (itemsToDisplay.size() == FolderIcon.NUM_ITEMS_IN_PREVIEW) { + break; + } + } + return itemsToDisplay; + } + private void updateItemDrawingParams(boolean animate) { - List items = mPreviewLayoutRule.getItemsToDisplay(mFolder); + List items = getItemsToDisplay(); int nItemsInPreview = items.size(); int prevNumItems = mDrawingParams.size(); @@ -1120,6 +1140,5 @@ public class FolderIcon extends FrameLayout implements FolderListener { float scaleForItem(int index, int totalNumItems); int maxNumItems(); boolean clipToBackground(); - List getItemsToDisplay(Folder folder); } } diff --git a/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java new file mode 100644 index 0000000000..de962b021d --- /dev/null +++ b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.folder; + +import com.android.launcher3.FolderInfo; +import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.config.FeatureFlags; + +/** + * Verifies whether an item in a Folder is displayed in the FolderIcon preview. + */ +public class FolderIconPreviewVerifier { + + private final int mMaxGridCountX; + private final int mMaxGridCountY; + private final int mMaxItemsPerPage; + private final int[] mGridSize = new int[2]; + + private int mGridCountX; + private boolean mDisplayingUpperLeftQuadrant = false; + + public FolderIconPreviewVerifier(InvariantDeviceProfile profile) { + mMaxGridCountX = profile.numFolderColumns; + mMaxGridCountY = profile.numFolderRows; + mMaxItemsPerPage = mMaxGridCountX * mMaxGridCountY; + } + + public void setFolderInfo(FolderInfo info) { + int numItemsInFolder = info.contents.size(); + mDisplayingUpperLeftQuadrant = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION + && !FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON + && numItemsInFolder > FolderIcon.NUM_ITEMS_IN_PREVIEW; + + if (mDisplayingUpperLeftQuadrant) { + FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX, + mMaxGridCountY, mMaxItemsPerPage, mGridSize); + mGridCountX = mGridSize[0]; + } + } + + public boolean isItemInPreview(int rank) { + if (mDisplayingUpperLeftQuadrant) { + // Returns true iff the icon is in the 2x2 upper left quadrant of the Folder. + int col = rank % mGridCountX; + int row = rank / mGridCountX; + return col < 2 && row < 2; + } + return rank < FolderIcon.NUM_ITEMS_IN_PREVIEW; + } +} diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java index eecce183a6..f29fb9a05b 100644 --- a/src/com/android/launcher3/folder/FolderPagedView.java +++ b/src/com/android/launcher3/folder/FolderPagedView.java @@ -42,7 +42,6 @@ import com.android.launcher3.ShortcutAndWidgetContainer; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace.ItemOperator; -import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.keyboard.ViewGroupFocusHelper; import com.android.launcher3.pageindicators.PageIndicator; import com.android.launcher3.util.Themes; @@ -68,7 +67,7 @@ public class FolderPagedView extends PagedView { */ private static final float SCROLL_HINT_FRACTION = 0.07f; - private static final int[] sTempPosArray = new int[2]; + private static final int[] sTmpArray = new int[2]; public final boolean mIsRtl; @@ -120,40 +119,58 @@ public class FolderPagedView extends PagedView { } /** - * Sets up the grid size such that {@param count} items can fit in the grid. + * Calculates the grid size such that {@param count} items can fit in the grid. * The grid size is calculated such that countY <= countX and countX = ceil(sqrt(count)) while * maintaining the restrictions of {@link #mMaxCountX} & {@link #mMaxCountY}. */ - private void setupContentDimensions(int count) { - mAllocatedContentSize = count; + public static void calculateGridSize(int count, int countX, int countY, int maxCountX, + int maxCountY, int maxItemsPerPage, int[] out) { boolean done; - if (count >= mMaxItemsPerPage) { - mGridCountX = mMaxCountX; - mGridCountY = mMaxCountY; + int gridCountX = countX; + int gridCountY = countY; + + if (count >= maxItemsPerPage) { + gridCountX = maxCountX; + gridCountY = maxCountY; done = true; } else { done = false; } while (!done) { - int oldCountX = mGridCountX; - int oldCountY = mGridCountY; - if (mGridCountX * mGridCountY < count) { + int oldCountX = gridCountX; + int oldCountY = gridCountY; + if (gridCountX * gridCountY < count) { // Current grid is too small, expand it - if ((mGridCountX <= mGridCountY || mGridCountY == mMaxCountY) && mGridCountX < mMaxCountX) { - mGridCountX++; - } else if (mGridCountY < mMaxCountY) { - mGridCountY++; + if ((gridCountX <= gridCountY || gridCountY == maxCountY) + && gridCountX < maxCountX) { + gridCountX++; + } else if (gridCountY < maxCountY) { + gridCountY++; } - if (mGridCountY == 0) mGridCountY++; - } else if ((mGridCountY - 1) * mGridCountX >= count && mGridCountY >= mGridCountX) { - mGridCountY = Math.max(0, mGridCountY - 1); - } else if ((mGridCountX - 1) * mGridCountY >= count) { - mGridCountX = Math.max(0, mGridCountX - 1); + if (gridCountY == 0) gridCountY++; + } else if ((gridCountY - 1) * gridCountX >= count && gridCountY >= gridCountX) { + gridCountY = Math.max(0, gridCountY - 1); + } else if ((gridCountX - 1) * gridCountY >= count) { + gridCountX = Math.max(0, gridCountX - 1); } - done = mGridCountX == oldCountX && mGridCountY == oldCountY; + done = gridCountX == oldCountX && gridCountY == oldCountY; } + out[0] = gridCountX; + out[1] = gridCountY; + } + + /** + * Sets up the grid size such that {@param count} items can fit in the grid. + */ + public void setupContentDimensions(int count) { + mAllocatedContentSize = count; + calculateGridSize(count, mGridCountX, mGridCountY, mMaxCountX, mMaxCountY, mMaxItemsPerPage, + sTmpArray); + mGridCountX = sTmpArray[0]; + mGridCountY = sTmpArray[1]; + // Update grid size for (int i = getPageCount() - 1; i >= 0; i--) { getPageAt(i).setGridSize(mGridCountX, mGridCountY); @@ -400,12 +417,12 @@ public class FolderPagedView extends PagedView { public int findNearestArea(int pixelX, int pixelY) { int pageIndex = getNextPage(); CellLayout page = getPageAt(pageIndex); - page.findNearestArea(pixelX, pixelY, 1, 1, sTempPosArray); + page.findNearestArea(pixelX, pixelY, 1, 1, sTmpArray); if (mFolder.isLayoutRtl()) { - sTempPosArray[0] = page.getCountX() - sTempPosArray[0] - 1; + sTmpArray[0] = page.getCountX() - sTmpArray[0] - 1; } return Math.min(mAllocatedContentSize - 1, - pageIndex * mMaxItemsPerPage + sTempPosArray[1] * mGridCountX + sTempPosArray[0]); + pageIndex * mMaxItemsPerPage + sTmpArray[1] * mGridCountX + sTmpArray[0]); } public boolean isFull() { diff --git a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java index 297203ae20..1f4e648138 100644 --- a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java +++ b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java @@ -98,10 +98,4 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule { public boolean clipToBackground() { return false; } - - @Override - public List getItemsToDisplay(Folder folder) { - List items = folder.getItemsInReadingOrder(); - return items.subList(0, Math.min(items.size(), MAX_NUM_ITEMS_IN_PREVIEW)); - } }