From fc3c1edf7bbc3f7cb23e79520731d13ccc2da046 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 9 Apr 2015 18:48:21 -0700 Subject: Fixing folder focus logic > Folder items no longer remain in a linear order when a folder gets rearranged, and se we need to use createSparseMatrix instead of createFullArray. Also because of this we need to use getChildAt(x, y) instead of getChildAt(index) > Removing traces of AppsCustomizePage (all apps) from FocusHelper Change-Id: I9007f6b95cb823e27ef4a43ce725fda8ef1b7cf8 --- src/com/android/launcher3/FocusHelper.java | 155 ++++++++------------- .../launcher3/ShortcutAndWidgetContainer.java | 2 +- src/com/android/launcher3/util/FocusLogic.java | 74 +++++----- 3 files changed, 88 insertions(+), 143 deletions(-) diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java index 32ed98c17..c77d41657 100644 --- a/src/com/android/launcher3/FocusHelper.java +++ b/src/com/android/launcher3/FocusHelper.java @@ -16,14 +16,12 @@ package com.android.launcher3; -import android.content.res.Configuration; import android.util.Log; import android.view.KeyEvent; import android.view.SoundEffectConstants; import android.view.View; import android.view.ViewGroup; -import com.android.launcher3.FocusHelper.PagedViewKeyListener; import com.android.launcher3.util.FocusLogic; import com.android.launcher3.util.Thunk; @@ -52,14 +50,10 @@ public class FocusHelper { private static final String TAG = "FocusHelper"; private static final boolean DEBUG = false; - // - // Key code handling methods. - // - /** - * A keyboard listener for scrollable folders + * Handles key events in paged folder. */ - public static class PagedFolderKeyEventListener extends PagedViewKeyListener { + public static class PagedFolderKeyEventListener implements View.OnKeyListener { private final Folder mFolder; @@ -67,20 +61,6 @@ public class FocusHelper { mFolder = folder; } - @Override - public void handleNoopKey(int keyCode, View v) { - if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { - mFolder.mFolderName.requestFocus(); - playSoundEffect(keyCode, v); - } - } - } - - /** - * Handles key events in the all apps screen. - */ - public static class PagedViewKeyListener implements View.OnKeyListener { - @Override public boolean onKey(View v, int keyCode, KeyEvent e) { boolean consume = FocusLogic.shouldConsume(keyCode); @@ -88,21 +68,12 @@ public class FocusHelper { return consume; } if (DEBUG) { - Log.v(TAG, String.format("Handle ALL APPS and Folders keyevent=[%s].", + Log.v(TAG, String.format("Handle ALL Folders keyevent=[%s].", KeyEvent.keyCodeToString(keyCode))); } - // Initialize variables. - ViewGroup parentLayout; - ViewGroup itemContainer; - int countX; - int countY; - if (v.getParent() instanceof ShortcutAndWidgetContainer) { - itemContainer = (ViewGroup) v.getParent(); - parentLayout = (ViewGroup) itemContainer.getParent(); - countX = ((CellLayout) parentLayout).getCountX(); - countY = ((CellLayout) parentLayout).getCountY(); - } else { + + if (!(v.getParent() instanceof ShortcutAndWidgetContainer)) { if (LauncherAppState.isDogfoodBuild()) { throw new IllegalStateException("Parent of the focused item is not supported."); } else { @@ -110,15 +81,19 @@ public class FocusHelper { } } + // Initialize variables. + final ShortcutAndWidgetContainer itemContainer = (ShortcutAndWidgetContainer) v.getParent(); + final CellLayout cellLayout = (CellLayout) itemContainer.getParent(); + final int countX = cellLayout.getCountX(); + final int countY = cellLayout.getCountY(); + final int iconIndex = itemContainer.indexOfChild(v); - final PagedView container = (PagedView) parentLayout.getParent(); - final int pageIndex = container.indexToPage(container.indexOfChild(parentLayout)); - final int pageCount = container.getChildCount(); - ViewGroup newParent = null; - View child = null; - // TODO(hyunyoungs): this matrix is not applicable on the last page. - int[][] matrix = FocusLogic.createFullMatrix(countX, countY, true); + final FolderPagedView pagedView = (FolderPagedView) cellLayout.getParent(); + final int pageIndex = pagedView.indexOfChild(cellLayout); + final int pageCount = pagedView.getPageCount(); + + int[][] matrix = FocusLogic.createSparseMatrix(cellLayout); // Process focus. int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX, countY, matrix, iconIndex, pageIndex, pageCount); @@ -126,60 +101,55 @@ public class FocusHelper { handleNoopKey(keyCode, v); return consume; } + ShortcutAndWidgetContainer newParent = null; + View child = null; + switch (newIconIndex) { case FocusLogic.PREVIOUS_PAGE_RIGHT_COLUMN: - case FocusLogic.NEXT_PAGE_RIGHT_COLUMN: - int newPageIndex = pageIndex - 1; - if (newIconIndex == FocusLogic.NEXT_PAGE_RIGHT_COLUMN) { - newPageIndex = pageIndex + 1; - } - newParent = getAppsCustomizePage(container, newPageIndex); + case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN: + newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex - 1); if (newParent != null) { - int row = FocusLogic.findRow(matrix, iconIndex); - container.snapToPage(newPageIndex); - // no need to create a new matrix. - child = newParent.getChildAt(matrix[countX-1][row]); + int row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY; + pagedView.snapToPage(pageIndex - 1); + child = newParent.getChildAt( + ((newIconIndex == FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN) + ^ newParent.invertLayoutHorizontally()) ? 0 : countX - 1, row); } break; case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM: - newParent = getAppsCustomizePage(container, pageIndex - 1); + newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex - 1); if (newParent != null) { - container.snapToPage(pageIndex - 1); - child = newParent.getChildAt(0); + pagedView.snapToPage(pageIndex - 1); + child = newParent.getChildAt(0, 0); } break; case FocusLogic.PREVIOUS_PAGE_LAST_ITEM: - newParent = getAppsCustomizePage(container, pageIndex - 1); + newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex - 1); if (newParent != null) { - container.snapToPage(pageIndex - 1); - child = newParent.getChildAt(newParent.getChildCount() - 1); + pagedView.snapToPage(pageIndex - 1); + child = newParent.getChildAt(countX - 1, countY - 1); } break; case FocusLogic.NEXT_PAGE_FIRST_ITEM: - newParent = getAppsCustomizePage(container, pageIndex + 1); + newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex + 1); if (newParent != null) { - container.snapToPage(pageIndex + 1); - child = newParent.getChildAt(0); + pagedView.snapToPage(pageIndex + 1); + child = newParent.getChildAt(0, 0); } break; case FocusLogic.NEXT_PAGE_LEFT_COLUMN: - case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN: - newPageIndex = pageIndex + 1; - if (newIconIndex == FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN) { - newPageIndex = pageIndex -1; - } - newParent = getAppsCustomizePage(container, newPageIndex); + case FocusLogic.NEXT_PAGE_RIGHT_COLUMN: + newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex + 1); if (newParent != null) { - container.snapToPage(newPageIndex); - int row = FocusLogic.findRow(matrix, iconIndex); - child = newParent.getChildAt(matrix[0][row]); + pagedView.snapToPage(pageIndex + 1); + child = FocusLogic.getAdjacentChildInNextPage(newParent, v, newIconIndex); } break; case FocusLogic.CURRENT_PAGE_FIRST_ITEM: - child = container.getChildAt(0); + child = cellLayout.getChildAt(0, 0); break; case FocusLogic.CURRENT_PAGE_LAST_ITEM: - child = itemContainer.getChildAt(itemContainer.getChildCount() - 1); + child = pagedView.getLastItem(); break; default: // Go to some item on the current page. child = itemContainer.getChildAt(newIconIndex); @@ -194,7 +164,12 @@ public class FocusHelper { return consume; } - public void handleNoopKey(int keyCode, View v) { } + public void handleNoopKey(int keyCode, View v) { + if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + mFolder.mFolderName.requestFocus(); + playSoundEffect(keyCode, v); + } + } } /** @@ -226,7 +201,7 @@ public class FocusHelper { int pageCount = workspace.getChildCount(); int countX = -1; int countY = -1; - int iconIndex = findIndexOfView(hotseatParent, v); + int iconIndex = hotseatParent.indexOfChild(v); int iconRank = ((CellLayout.LayoutParams) hotseatLayout.getShortcutsAndWidgets() .getChildAt(iconIndex).getLayoutParams()).cellX; @@ -323,11 +298,12 @@ public class FocusHelper { final ViewGroup launcher = (ViewGroup) workspace.getParent(); final ViewGroup tabs = (ViewGroup) launcher.findViewById(R.id.search_drop_target_bar); final Hotseat hotseat = (Hotseat) launcher.findViewById(R.id.hotseat); - int pageIndex = workspace.indexOfChild(iconLayout); - int pageCount = workspace.getChildCount(); + + final int iconIndex = parent.indexOfChild(v); + final int pageIndex = workspace.indexOfChild(iconLayout); + final int pageCount = workspace.getChildCount(); int countX = iconLayout.getCountX(); int countY = iconLayout.getCountY(); - final int iconIndex = findIndexOfView(parent, v); CellLayout hotseatLayout = (CellLayout) hotseat.getChildAt(0); ShortcutAndWidgetContainer hotseatParent = hotseatLayout.getShortcutsAndWidgets(); @@ -368,10 +344,11 @@ public class FocusHelper { if (newIconIndex == FocusLogic.NEXT_PAGE_RIGHT_COLUMN) { newPageIndex = pageIndex + 1; } - int row = FocusLogic.findRow(matrix, iconIndex); + int row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY; parent = getCellLayoutChildrenForIndex(workspace, newPageIndex); workspace.snapToPage(newPageIndex); if (parent != null) { + workspace.snapToPage(newPageIndex); iconLayout = (CellLayout) parent.getParent(); matrix = FocusLogic.createSparseMatrix(iconLayout, iconLayout.getCountX(), row); @@ -402,9 +379,10 @@ public class FocusHelper { newPageIndex = pageIndex - 1; } workspace.snapToPage(newPageIndex); - row = FocusLogic.findRow(matrix, iconIndex); + row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY; parent = getCellLayoutChildrenForIndex(workspace, newPageIndex); if (parent != null) { + workspace.snapToPage(newPageIndex); iconLayout = (CellLayout) parent.getParent(); matrix = FocusLogic.createSparseMatrix(iconLayout, -1, row); newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX + 1, countY, matrix, @@ -439,18 +417,6 @@ public class FocusHelper { // Helper methods. // - /** - * Returns the Viewgroup containing page contents for the page at the index specified. - */ - @Thunk static ViewGroup getAppsCustomizePage(ViewGroup container, int index) { - ViewGroup page = (ViewGroup) ((PagedView) container).getPageAt(index); - if (page instanceof CellLayout) { - // There are two layers, a PagedViewCellLayout and PagedViewCellLayoutChildren - page = ((CellLayout) page).getShortcutsAndWidgets(); - } - return page; - } - /** * Private helper method to get the CellLayoutChildren given a CellLayout index. */ @@ -460,15 +426,6 @@ public class FocusHelper { return parent.getShortcutsAndWidgets(); } - private static int findIndexOfView(ViewGroup parent, View v) { - for (int i = 0; i < parent.getChildCount(); i++) { - if (v != null && v.equals(parent.getChildAt(i))) { - return i; - } - } - return -1; - } - /** * Helper method to be used for playing sound effects. */ diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java index ff0604540..15b617683 100644 --- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java +++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java @@ -177,7 +177,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup { child.measure(childWidthMeasureSpec, childheightMeasureSpec); } - private boolean invertLayoutHorizontally() { + public boolean invertLayoutHorizontally() { return mInvertIfRtl && isLayoutRtl(); } diff --git a/src/com/android/launcher3/util/FocusLogic.java b/src/com/android/launcher3/util/FocusLogic.java index 8a08a4e72..a84e7df03 100644 --- a/src/com/android/launcher3/util/FocusLogic.java +++ b/src/com/android/launcher3/util/FocusLogic.java @@ -18,11 +18,15 @@ package com.android.launcher3.util; import android.util.Log; import android.view.KeyEvent; +import android.view.View; import android.view.ViewGroup; import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.ShortcutAndWidgetContainer; + +import java.util.Arrays; /** * Calculates the next item that a {@link KeyEvent} should change the focus to. @@ -69,14 +73,11 @@ public class FocusLogic { * Returns true only if this utility class handles the key code. */ public static boolean shouldConsume(int keyCode) { - if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || + return (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_MOVE_HOME || keyCode == KeyEvent.KEYCODE_MOVE_END || keyCode == KeyEvent.KEYCODE_PAGE_UP || keyCode == KeyEvent.KEYCODE_PAGE_DOWN || - keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_FORWARD_DEL) { - return true; - } - return false; + keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_FORWARD_DEL); } public static int handleKeyEvent(int keyCode, int cntX, int cntY, int [][] map, @@ -138,33 +139,17 @@ public class FocusLogic { } /** - * Returns a matrix of size (m x n) that has been initialized with incremental index starting - * with 0 or a matrix where all the values are initialized to {@link #EMPTY}. + * Returns a matrix of size (m x n) that has been initialized with {@link #EMPTY}. * * @param m number of columns in the matrix * @param n number of rows in the matrix - * @param incrementOrder {@code true} if the matrix contents should increment in reading - * order with 0 indexing. {@code false} if each cell should be - * initialized to {@link #EMPTY}; */ // TODO: get rid of dynamic matrix creation. - public static int[][] createFullMatrix(int m, int n, boolean incrementOrder) { - DeviceProfile profile = LauncherAppState.getInstance().getDynamicGrid() - .getDeviceProfile(); + private static int[][] createFullMatrix(int m, int n) { int[][] matrix = new int [m][n]; for (int i=0; i < m;i++) { - for (int j=0; j < n; j++) { - if (incrementOrder) { - if (!profile.isLayoutRtl) { - matrix[i][j] = j * m + i; - } else { - matrix[i][j] = j * m + m - i -1; - } - } else { - matrix[i][j] = EMPTY; - } - } + Arrays.fill(matrix[i], EMPTY); } return matrix; } @@ -175,17 +160,18 @@ public class FocusLogic { */ // TODO: get rid of the dynamic matrix creation public static int[][] createSparseMatrix(CellLayout layout) { - ViewGroup parent = layout.getShortcutsAndWidgets(); + ShortcutAndWidgetContainer parent = layout.getShortcutsAndWidgets(); final int m = layout.getCountX(); final int n = layout.getCountY(); + final boolean invert = parent.invertLayoutHorizontally(); - int[][] matrix = createFullMatrix(m, n, false /* initialize to #EMPTY */); + int[][] matrix = createFullMatrix(m, n); // Iterate thru the children. for (int i = 0; i < parent.getChildCount(); i++ ) { int cx = ((CellLayout.LayoutParams) parent.getChildAt(i).getLayoutParams()).cellX; int cy = ((CellLayout.LayoutParams) parent.getChildAt(i).getLayoutParams()).cellY; - matrix[cx][cy] = i; + matrix[invert ? (m - cx - 1) : cx][cy] = i; } if (DEBUG) { printMatrix(matrix); @@ -213,7 +199,7 @@ public class FocusLogic { m = iconLayout.getCountX() + hotseatLayout.getCountX(); n = iconLayout.getCountY(); } - int[][] matrix = createFullMatrix(m, n, false /* set all cell to empty */); + int[][] matrix = createFullMatrix(m, n); // Iterate thru the children of the top parent. for (int i = 0; i < iconParent.getChildCount(); i++) { @@ -267,8 +253,7 @@ public class FocusLogic { ViewGroup iconParent = iconLayout.getShortcutsAndWidgets(); - int[][] matrix = createFullMatrix(iconLayout.getCountX() + 1, iconLayout.getCountY(), - false /* set all cell to empty */); + int[][] matrix = createFullMatrix(iconLayout.getCountX() + 1, iconLayout.getCountY()); // Iterate thru the children of the top parent. for (int i = 0; i < iconParent.getChildCount(); i++) { @@ -499,22 +484,25 @@ public class FocusLogic { } /** - * Figure out the location of the icon. - * + * @param edgeColumn the column of the new icon. either {@link #NEXT_PAGE_LEFT_COLUMN} or + * {@link #NEXT_PAGE_RIGHT_COLUMN} + * @return the view adjacent to {@param oldView} in the {@param nextPage}. */ - //TODO(hyunyoungs): this helper method should move to CellLayout class while removing the - // dynamic matrix creation all together. - public static int findRow(int[][] matrix, int iconIndex) { - int cntX = matrix.length; - int cntY = matrix[0].length; - - for (int i = 0; i < cntX; i++) { - for (int j = 0; j < cntY; j++) { - if (matrix[i][j] == iconIndex) { - return j; + public static View getAdjacentChildInNextPage( + ShortcutAndWidgetContainer nextPage, View oldView, int edgeColumn) { + final int newRow = ((CellLayout.LayoutParams) oldView.getLayoutParams()).cellY; + + int column = (edgeColumn == NEXT_PAGE_LEFT_COLUMN) ^ nextPage.invertLayoutHorizontally() + ? 0 : (((CellLayout) nextPage.getParent()).getCountX() - 1); + + for (; column >= 0; column--) { + for (int row = newRow; row >= 0; row--) { + View newView = nextPage.getChildAt(column, row); + if (newView != null) { + return newView; } } } - return -1; + return null; } } -- cgit v1.2.3