Loading src/com/android/launcher3/AppWidgetResizeFrame.java +93 −20 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ package com.android.launcher3; import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT; import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH; import static com.android.launcher3.Utilities.ATLEAST_S; import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS; import static com.android.launcher3.views.BaseDragLayer.LAYOUT_X; import static com.android.launcher3.views.BaseDragLayer.LAYOUT_Y; Loading @@ -11,14 +13,19 @@ import android.animation.PropertyValuesHolder; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.Bundle; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import com.android.launcher3.accessibility.DragViewStateAnnouncer; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.util.FocusLogic; Loading Loading @@ -353,32 +360,98 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O public static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Launcher launcher, int spanX, int spanY) { getWidgetSizeRanges(launcher, spanX, spanY, sTmpRect); widgetView.updateAppWidgetSize(null, sTmpRect.left, sTmpRect.top, sTmpRect.right, sTmpRect.bottom); List<PointF> sizes = getWidgetSizes(launcher, spanX, spanY); if (ATLEAST_S) { widgetView.updateAppWidgetSize(new Bundle(), sizes); } else { Rect bounds = getMinMaxSizes(sizes, null /* outRect */); widgetView.updateAppWidgetSize(new Bundle(), bounds.left, bounds.top, bounds.right, bounds.bottom); } public static Rect getWidgetSizeRanges(Context context, int spanX, int spanY, Rect rect) { if (rect == null) { rect = new Rect(); } final float density = context.getResources().getDisplayMetrics().density; final Point[] cellSize = CELL_SIZE.get(context); private static PointF getWidgetSize(Context context, Point cellSize, int spanX, int spanY) { final float density = context.getResources().getDisplayMetrics().density; float hBorderSpacing = 0; float vBorderSpacing = 0; if (ENABLE_FOUR_COLUMNS.get()) { final int borderSpacing = context.getResources() .getDimensionPixelSize(R.dimen.dynamic_grid_cell_border_spacing); final float hBorderSpacing = (spanX - 1) * borderSpacing; final float vBorderSpacing = (spanY - 1) * borderSpacing; // Compute landscape size int landWidth = (int) (((spanX * cellSize[0].x) + hBorderSpacing) / density); int landHeight = (int) (((spanY * cellSize[0].y) + vBorderSpacing) / density); // Compute portrait size int portWidth = (int) (((spanX * cellSize[1].x) + hBorderSpacing) / density); int portHeight = (int) (((spanY * cellSize[1].y) + vBorderSpacing) / density); rect.set(portWidth, landHeight, landWidth, portHeight); return rect; hBorderSpacing = (spanX - 1) * borderSpacing; vBorderSpacing = (spanY - 1) * borderSpacing; } PointF widgetSize = new PointF(); widgetSize.x = ((spanX * cellSize.x) + hBorderSpacing) / density; widgetSize.y = ((spanY * cellSize.y) + vBorderSpacing) / density; return widgetSize; } /** Returns the actual widget size given its span. */ public static PointF getWidgetSize(Context context, int spanX, int spanY) { final Point[] cellSize = CELL_SIZE.get(context); if (isLandscape(context)) { return getWidgetSize(context, cellSize[0], spanX, spanY); } return getWidgetSize(context, cellSize[1], spanX, spanY); } /** Returns true if the screen is in landscape mode. */ private static boolean isLandscape(Context context) { return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; } /** Returns the list of sizes for a widget of given span, in dp. */ public static ArrayList<PointF> getWidgetSizes(Context context, int spanX, int spanY) { final Point[] cellSize = CELL_SIZE.get(context); PointF landSize = getWidgetSize(context, cellSize[0], spanX, spanY); PointF portSize = getWidgetSize(context, cellSize[1], spanX, spanY); ArrayList<PointF> sizes = new ArrayList<>(2); sizes.add(landSize); sizes.add(portSize); return sizes; } /** * Returns the min and max widths and heights given a list of sizes, in dp. * * @param sizes List of sizes to get the min/max from. * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If * null, a new rectangle will be allocated. * @return A rectangle with the left (resp. top) is used for the min width (resp. height) and * the right (resp. bottom) for the max. The returned rectangle is set with 0s if the list is * empty. */ public static Rect getMinMaxSizes(List<PointF> sizes, @Nullable Rect outRect) { if (outRect == null) { outRect = new Rect(); } if (sizes.isEmpty()) { outRect.set(0, 0, 0, 0); } else { PointF first = sizes.get(0); outRect.set((int) first.x, (int) first.y, (int) first.x, (int) first.y); for (int i = 1; i < sizes.size(); i++) { outRect.union((int) sizes.get(i).x, (int) sizes.get(i).y); } } return outRect; } /** * Returns the range of sizes a widget may be displayed, given its span. * * @param context Context in which the View is rendered. * @param spanX Width of the widget, in cells. * @param spanY Height of the widget, in cells. * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If * null, a new rectangle will be allocated. */ public static Rect getWidgetSizeRanges(Context context, int spanX, int spanY, @Nullable Rect outRect) { return getMinMaxSizes(getWidgetSizes(context, spanX, spanY), outRect); } @Override Loading src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +2 −4 Original line number Diff line number Diff line Loading @@ -357,10 +357,8 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme } 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); AppWidgetResizeFrame.updateWidgetSizeRanges(((LauncherAppWidgetHostView) host), mLauncher, info.spanX, info.spanY); host.requestLayout(); mLauncher.getModelWriter().updateItemInDatabase(info); announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY)); Loading src/com/android/launcher3/qsb/QsbContainerView.java +11 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.appwidget.AppWidgetManager.ACTION_APPWIDGET_BIND; import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID; import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_PROVIDER; import static com.android.launcher3.Utilities.ATLEAST_S; import android.app.Activity; import android.app.Fragment; import android.app.SearchManager; Loading @@ -30,6 +32,7 @@ import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.graphics.Rect; import android.os.Bundle; import android.provider.Settings; Loading @@ -50,6 +53,8 @@ import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.FragmentWithPreview; import java.util.ArrayList; /** * A frame layout which contains a QSB. This internally uses fragment to bind the view, which * allows it to contain the logic for {@link Fragment#startActivityForResult(Intent, int)}. Loading Loading @@ -294,12 +299,16 @@ public class QsbContainerView extends FrameLayout { InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext()); Bundle opts = new Bundle(); Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(getContext(), idp.numColumns, 1, null); ArrayList<PointF> sizes = AppWidgetResizeFrame .getWidgetSizes(getContext(), idp.numColumns, 1); Rect size = AppWidgetResizeFrame.getMinMaxSizes(sizes, null /* outRect */); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, size.left); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, size.top); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, size.right); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, size.bottom); if (ATLEAST_S) { opts.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, sizes); } return opts; } Loading src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +13 −2 Original line number Diff line number Diff line Loading @@ -16,9 +16,12 @@ package com.android.launcher3.widget; import static com.android.launcher3.Utilities.ATLEAST_S; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; import android.graphics.PointF; import android.os.Handler; import android.os.SystemClock; import android.util.SparseBooleanArray; Loading Loading @@ -70,8 +73,6 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView private boolean mIsAutoAdvanceRegistered; private Runnable mAutoAdvanceRunnable; public LauncherAppWidgetHostView(Context context) { super(context); mLauncher = Launcher.getLauncher(context); Loading Loading @@ -218,6 +219,16 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView mIsScrollable = checkScrollableRecursively(this); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (ATLEAST_S) { float density = getContext().getResources().getDisplayMetrics().density; setCurrentSize(new PointF(w / density, h / density)); } } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); Loading src/com/android/launcher3/widget/PendingAppWidgetHostView.java +8 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; Loading @@ -46,6 +47,8 @@ import com.android.launcher3.model.data.PackageItemInfo; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.util.Themes; import java.util.List; public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implements OnClickListener, ItemInfoUpdateReceiver { private static final float SETUP_ICON_SIZE_FACTOR = 2f / 5; Loading Loading @@ -108,6 +111,11 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView // No-op } @Override public void updateAppWidgetSize(Bundle newOptions, List<PointF> sizes) { // No-op } @Override protected View getDefaultView() { View defaultView = mInflater.inflate(R.layout.appwidget_not_ready, this, false); Loading Loading
src/com/android/launcher3/AppWidgetResizeFrame.java +93 −20 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ package com.android.launcher3; import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT; import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH; import static com.android.launcher3.Utilities.ATLEAST_S; import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS; import static com.android.launcher3.views.BaseDragLayer.LAYOUT_X; import static com.android.launcher3.views.BaseDragLayer.LAYOUT_Y; Loading @@ -11,14 +13,19 @@ import android.animation.PropertyValuesHolder; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.Bundle; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import com.android.launcher3.accessibility.DragViewStateAnnouncer; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.util.FocusLogic; Loading Loading @@ -353,32 +360,98 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O public static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Launcher launcher, int spanX, int spanY) { getWidgetSizeRanges(launcher, spanX, spanY, sTmpRect); widgetView.updateAppWidgetSize(null, sTmpRect.left, sTmpRect.top, sTmpRect.right, sTmpRect.bottom); List<PointF> sizes = getWidgetSizes(launcher, spanX, spanY); if (ATLEAST_S) { widgetView.updateAppWidgetSize(new Bundle(), sizes); } else { Rect bounds = getMinMaxSizes(sizes, null /* outRect */); widgetView.updateAppWidgetSize(new Bundle(), bounds.left, bounds.top, bounds.right, bounds.bottom); } public static Rect getWidgetSizeRanges(Context context, int spanX, int spanY, Rect rect) { if (rect == null) { rect = new Rect(); } final float density = context.getResources().getDisplayMetrics().density; final Point[] cellSize = CELL_SIZE.get(context); private static PointF getWidgetSize(Context context, Point cellSize, int spanX, int spanY) { final float density = context.getResources().getDisplayMetrics().density; float hBorderSpacing = 0; float vBorderSpacing = 0; if (ENABLE_FOUR_COLUMNS.get()) { final int borderSpacing = context.getResources() .getDimensionPixelSize(R.dimen.dynamic_grid_cell_border_spacing); final float hBorderSpacing = (spanX - 1) * borderSpacing; final float vBorderSpacing = (spanY - 1) * borderSpacing; // Compute landscape size int landWidth = (int) (((spanX * cellSize[0].x) + hBorderSpacing) / density); int landHeight = (int) (((spanY * cellSize[0].y) + vBorderSpacing) / density); // Compute portrait size int portWidth = (int) (((spanX * cellSize[1].x) + hBorderSpacing) / density); int portHeight = (int) (((spanY * cellSize[1].y) + vBorderSpacing) / density); rect.set(portWidth, landHeight, landWidth, portHeight); return rect; hBorderSpacing = (spanX - 1) * borderSpacing; vBorderSpacing = (spanY - 1) * borderSpacing; } PointF widgetSize = new PointF(); widgetSize.x = ((spanX * cellSize.x) + hBorderSpacing) / density; widgetSize.y = ((spanY * cellSize.y) + vBorderSpacing) / density; return widgetSize; } /** Returns the actual widget size given its span. */ public static PointF getWidgetSize(Context context, int spanX, int spanY) { final Point[] cellSize = CELL_SIZE.get(context); if (isLandscape(context)) { return getWidgetSize(context, cellSize[0], spanX, spanY); } return getWidgetSize(context, cellSize[1], spanX, spanY); } /** Returns true if the screen is in landscape mode. */ private static boolean isLandscape(Context context) { return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; } /** Returns the list of sizes for a widget of given span, in dp. */ public static ArrayList<PointF> getWidgetSizes(Context context, int spanX, int spanY) { final Point[] cellSize = CELL_SIZE.get(context); PointF landSize = getWidgetSize(context, cellSize[0], spanX, spanY); PointF portSize = getWidgetSize(context, cellSize[1], spanX, spanY); ArrayList<PointF> sizes = new ArrayList<>(2); sizes.add(landSize); sizes.add(portSize); return sizes; } /** * Returns the min and max widths and heights given a list of sizes, in dp. * * @param sizes List of sizes to get the min/max from. * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If * null, a new rectangle will be allocated. * @return A rectangle with the left (resp. top) is used for the min width (resp. height) and * the right (resp. bottom) for the max. The returned rectangle is set with 0s if the list is * empty. */ public static Rect getMinMaxSizes(List<PointF> sizes, @Nullable Rect outRect) { if (outRect == null) { outRect = new Rect(); } if (sizes.isEmpty()) { outRect.set(0, 0, 0, 0); } else { PointF first = sizes.get(0); outRect.set((int) first.x, (int) first.y, (int) first.x, (int) first.y); for (int i = 1; i < sizes.size(); i++) { outRect.union((int) sizes.get(i).x, (int) sizes.get(i).y); } } return outRect; } /** * Returns the range of sizes a widget may be displayed, given its span. * * @param context Context in which the View is rendered. * @param spanX Width of the widget, in cells. * @param spanY Height of the widget, in cells. * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If * null, a new rectangle will be allocated. */ public static Rect getWidgetSizeRanges(Context context, int spanX, int spanY, @Nullable Rect outRect) { return getMinMaxSizes(getWidgetSizes(context, spanX, spanY), outRect); } @Override Loading
src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +2 −4 Original line number Diff line number Diff line Loading @@ -357,10 +357,8 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme } 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); AppWidgetResizeFrame.updateWidgetSizeRanges(((LauncherAppWidgetHostView) host), mLauncher, info.spanX, info.spanY); host.requestLayout(); mLauncher.getModelWriter().updateItemInDatabase(info); announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY)); Loading
src/com/android/launcher3/qsb/QsbContainerView.java +11 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.appwidget.AppWidgetManager.ACTION_APPWIDGET_BIND; import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID; import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_PROVIDER; import static com.android.launcher3.Utilities.ATLEAST_S; import android.app.Activity; import android.app.Fragment; import android.app.SearchManager; Loading @@ -30,6 +32,7 @@ import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.graphics.Rect; import android.os.Bundle; import android.provider.Settings; Loading @@ -50,6 +53,8 @@ import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.FragmentWithPreview; import java.util.ArrayList; /** * A frame layout which contains a QSB. This internally uses fragment to bind the view, which * allows it to contain the logic for {@link Fragment#startActivityForResult(Intent, int)}. Loading Loading @@ -294,12 +299,16 @@ public class QsbContainerView extends FrameLayout { InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext()); Bundle opts = new Bundle(); Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(getContext(), idp.numColumns, 1, null); ArrayList<PointF> sizes = AppWidgetResizeFrame .getWidgetSizes(getContext(), idp.numColumns, 1); Rect size = AppWidgetResizeFrame.getMinMaxSizes(sizes, null /* outRect */); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, size.left); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, size.top); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, size.right); opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, size.bottom); if (ATLEAST_S) { opts.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, sizes); } return opts; } Loading
src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +13 −2 Original line number Diff line number Diff line Loading @@ -16,9 +16,12 @@ package com.android.launcher3.widget; import static com.android.launcher3.Utilities.ATLEAST_S; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; import android.graphics.PointF; import android.os.Handler; import android.os.SystemClock; import android.util.SparseBooleanArray; Loading Loading @@ -70,8 +73,6 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView private boolean mIsAutoAdvanceRegistered; private Runnable mAutoAdvanceRunnable; public LauncherAppWidgetHostView(Context context) { super(context); mLauncher = Launcher.getLauncher(context); Loading Loading @@ -218,6 +219,16 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView mIsScrollable = checkScrollableRecursively(this); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (ATLEAST_S) { float density = getContext().getResources().getDisplayMetrics().density; setCurrentSize(new PointF(w / density, h / density)); } } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); Loading
src/com/android/launcher3/widget/PendingAppWidgetHostView.java +8 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; Loading @@ -46,6 +47,8 @@ import com.android.launcher3.model.data.PackageItemInfo; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.util.Themes; import java.util.List; public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implements OnClickListener, ItemInfoUpdateReceiver { private static final float SETUP_ICON_SIZE_FACTOR = 2f / 5; Loading Loading @@ -108,6 +111,11 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView // No-op } @Override public void updateAppWidgetSize(Bundle newOptions, List<PointF> sizes) { // No-op } @Override protected View getDefaultView() { View defaultView = mInflater.inflate(R.layout.appwidget_not_ready, this, false); Loading