diff options
-rw-r--r-- | res/values/config.xml | 1 | ||||
-rw-r--r-- | res/values/strings.xml | 19 | ||||
-rw-r--r-- | src/com/android/launcher3/CellLayout.java | 17 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherAccessibilityDelegate.java | 99 |
4 files changed, 135 insertions, 1 deletions
diff --git a/res/values/config.xml b/res/values/config.xml index 6ef863532..84ccef10c 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -102,4 +102,5 @@ <item type="id" name="action_move_to_workspace" /> <item type="id" name="action_move_screen_backwards" /> <item type="id" name="action_move_screen_forwards" /> + <item type="id" name="action_resize" /> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index 1681fc626..59625841b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -252,4 +252,23 @@ <!-- Accessibility confirmation when a screen was moved [DO NOT TRANSLATE] --> <string name="screen_moved">Screen moved</string> + + <!-- Accessibility action to resize a widget [DO NOT TRANSLATE] --> + <string name="action_resize">Resize</string> + + <!-- Accessibility action to increase width of a widget [DO NOT TRANSLATE] --> + <string name="action_increase_width">Increase width</string> + + <!-- Accessibility action to increase height of a widget [DO NOT TRANSLATE] --> + <string name="action_increase_height">Increase height</string> + + <!-- Accessibility action to decrease width of a widget [DO NOT TRANSLATE] --> + <string name="action_decrease_width">Decrease width</string> + + <!-- Accessibility action to decrease height of a widget [DO NOT TRANSLATE] --> + <string name="action_decrease_height">Decrease height</string> + + <!-- Accessibility confirmation for widget resize [DO NOT TRANSLATE]--> + <string name="widget_resized">Widget resized to width <xliff:g id="number" example="2">%1$s</xliff:g> height <xliff:g id="number" example="1">%2$s</xliff:g></string> + </resources> diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 65c67025f..72eabf177 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -3051,4 +3051,21 @@ public class CellLayout extends ViewGroup { public boolean findVacantCell(int spanX, int spanY, int[] outXY) { return Utilities.findVacantCell(outXY, spanX, spanY, mCountX, mCountY, mOccupied); } + + public boolean isRegionVacant(int x, int y, int spanX, int spanY) { + int x2 = x + spanX - 1; + int y2 = y + spanY - 1; + if (x < 0 || y < 0 || x2 >= mCountX || y2 >= mCountY) { + return false; + } + for (int i = x; i <= x2; i++) { + for (int j = y; j <= y2; j++) { + if (mOccupied[i][j]) { + return false; + } + } + } + + return true; + } } diff --git a/src/com/android/launcher3/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/LauncherAccessibilityDelegate.java index 8a9a0508c..3992e6390 100644 --- a/src/com/android/launcher3/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/LauncherAccessibilityDelegate.java @@ -1,6 +1,9 @@ package com.android.launcher3; import android.annotation.TargetApi; +import android.app.AlertDialog; +import android.appwidget.AppWidgetProviderInfo; +import android.content.DialogInterface; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; @@ -28,6 +31,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { private static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace; private static final int MOVE = R.id.action_move; private static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace; + private static final int RESIZE = R.id.action_resize; public enum DragType { ICON, @@ -62,6 +66,8 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { launcher.getText(R.string.action_move))); mActions.put(MOVE_TO_WORKSPACE, new AccessibilityAction(MOVE_TO_WORKSPACE, launcher.getText(R.string.action_move_to_workspace))); + mActions.put(RESIZE, new AccessibilityAction(RESIZE, + launcher.getText(R.string.action_resize))); } @Override @@ -87,6 +93,10 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { if (item.container >= 0) { info.addAction(mActions.get(MOVE_TO_WORKSPACE)); + } else if (item instanceof LauncherAppWidgetInfo) { + if (!getSupportedResizeActions(host, (LauncherAppWidgetInfo) item).isEmpty()) { + info.addAction(mActions.get(RESIZE)); + } } } if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) { info.addAction(mActions.get(ADD_TO_WORKSPACE)); @@ -102,7 +112,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { return super.performAccessibilityAction(host, action, args); } - public boolean performAction(View host, final ItemInfo item, int action) { + public boolean performAction(final View host, final ItemInfo item, int action) { if (action == REMOVE) { if (DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host)) { announceConfirmation(R.string.item_removed); @@ -167,10 +177,97 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { announceConfirmation(R.string.item_moved); } }); + } else if (action == RESIZE) { + final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item; + final ArrayList<Integer> actions = getSupportedResizeActions(host, info); + CharSequence[] labels = new CharSequence[actions.size()]; + for (int i = 0; i < actions.size(); i++) { + labels[i] = mLauncher.getText(actions.get(i)); + } + + new AlertDialog.Builder(mLauncher) + .setTitle(R.string.action_resize) + .setItems(labels, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + performResizeAction(actions.get(which), host, info); + dialog.dismiss(); + } + }) + .show(); } return false; } + private ArrayList<Integer> getSupportedResizeActions(View host, LauncherAppWidgetInfo info) { + AppWidgetProviderInfo providerInfo = ((LauncherAppWidgetHostView) host).getAppWidgetInfo(); + ArrayList<Integer> actions = new ArrayList<>(); + + CellLayout layout = (CellLayout) host.getParent().getParent(); + if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) { + if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) || + layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) { + actions.add(R.string.action_increase_width); + } + + if (info.spanX > info.minSpanX && info.spanX > 1) { + actions.add(R.string.action_decrease_width); + } + } + + if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) { + if (layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1) || + layout.isRegionVacant(info.cellX, info.cellY - 1, info.spanX, 1)) { + actions.add(R.string.action_increase_height); + } + + if (info.spanY > info.minSpanY && info.spanY > 1) { + actions.add(R.string.action_decrease_height); + } + } + return actions; + } + + private void performResizeAction(int action, View host, LauncherAppWidgetInfo info) { + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) host.getLayoutParams(); + CellLayout layout = (CellLayout) host.getParent().getParent(); + layout.markCellsAsUnoccupiedForView(host); + + if (action == R.string.action_increase_width) { + if (((host.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) + && layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) + || !layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY)) { + lp.cellX --; + info.cellX --; + } + lp.cellHSpan ++; + info.spanX ++; + } else if (action == R.string.action_decrease_width) { + lp.cellHSpan --; + info.spanX --; + } else if (action == R.string.action_increase_height) { + if (!layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1)) { + lp.cellY --; + info.cellY --; + } + lp.cellVSpan ++; + info.spanY ++; + } else if (action == R.string.action_decrease_height) { + lp.cellVSpan --; + info.spanY --; + } + + layout.markCellsAsOccupiedForView(host); + Rect sizeRange = new Rect(); + AppWidgetResizeFrame.getWidgetSizeRanges(mLauncher, info.spanX, info.spanY, sizeRange); + ((LauncherAppWidgetHostView) host).updateAppWidgetSize(null, + sizeRange.left, sizeRange.top, sizeRange.right, sizeRange.bottom); + host.requestLayout(); + LauncherModel.updateItemInDatabase(mLauncher, info); + announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY)); + } + @Thunk void announceConfirmation(int resId) { announceConfirmation(mLauncher.getResources().getString(resId)); } |