Loading src/com/android/launcher3/DeviceProfile.java +65 −6 Original line number Diff line number Diff line Loading @@ -38,11 +38,13 @@ import android.util.SparseArray; import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.DevicePaddings.DevicePadding; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.IconNormalizer; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.uioverrides.ApiWrapper; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; Loading @@ -57,6 +59,9 @@ public class DeviceProfile { private static final int DEFAULT_DOT_SIZE = 100; private static final float ALL_APPS_TABLET_MAX_ROWS = 5.5f; public static final PointF DEFAULT_SCALE = new PointF(1.0f, 1.0f); public static final ViewScaleProvider DEFAULT_PROVIDER = itemInfo -> DEFAULT_SCALE; // Ratio of empty space, qsb should take up to appear visually centered. private final float mQsbCenterFactor; Loading Loading @@ -204,7 +209,7 @@ public class DeviceProfile { public int overviewGridSideMargin; // Widgets public final PointF appWidgetScale = new PointF(1.0f, 1.0f); private final ViewScaleProvider mViewScaleProvider; // Drop Target public int dropTargetBarSizePx; Loading Loading @@ -240,7 +245,8 @@ public class DeviceProfile { /** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */ DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds, SparseArray<DotRenderer> dotRendererCache, boolean isMultiWindowMode, boolean transposeLayoutWithOrientation, boolean useTwoPanels, boolean isGestureMode) { boolean transposeLayoutWithOrientation, boolean useTwoPanels, boolean isGestureMode, @NonNull final ViewScaleProvider viewScaleProvider) { this.inv = inv; this.isLandscape = windowBounds.isLandscape(); Loading Loading @@ -473,6 +479,8 @@ public class DeviceProfile { flingToDeleteThresholdVelocity = res.getDimensionPixelSize( R.dimen.drag_flingToDeleteMinVelocity); mViewScaleProvider = viewScaleProvider; // This is done last, after iconSizePx is calculated above. mDotRendererWorkSpace = createDotRenderer(iconSizePx, dotRendererCache); mDotRendererAllApps = createDotRenderer(allAppsIconSizePx, dotRendererCache); Loading Loading @@ -669,13 +677,18 @@ public class DeviceProfile { .setMultiWindowMode(true) .build(); profile.hideWorkspaceLabelsIfNotEnoughSpace(); // We use these scales to measure and layout the widgets using their full invariant profile // sizes and then draw them scaled and centered to fit in their multi-window mode cellspans. float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x; float appWidgetScaleY = (float) profile.getCellSize().y / getCellSize().y; profile.appWidgetScale.set(appWidgetScaleX, appWidgetScaleY); if (appWidgetScaleX != 1 || appWidgetScaleY != 1) { final PointF p = new PointF(appWidgetScaleX, appWidgetScaleY); profile = profile.toBuilder(context) .setViewScaleProvider(i -> p) .build(); } profile.hideWorkspaceLabelsIfNotEnoughSpace(); return profile; } Loading Loading @@ -1242,6 +1255,19 @@ public class DeviceProfile { + getOverviewActionsClaimedSpaceBelow(); } /** * Takes the View and return the scales of width and height depending on the DeviceProfile * specifications * * @param itemInfo The tag of the widget view * @return A PointF instance with the x set to be the scale of width, and y being the scale of * height */ @NonNull public PointF getAppWidgetScale(@Nullable final ItemInfo itemInfo) { return mViewScaleProvider.getScaleFromItemInfo(itemInfo); } /** * @return the bounds for which the open folders should be contained within */ Loading Loading @@ -1551,6 +1577,22 @@ public class DeviceProfile { } } /** * Handler that deals with ItemInfo of the views for the DeviceProfile */ @FunctionalInterface public interface ViewScaleProvider { /** * Get the scales from the view * * @param itemInfo The tag of the widget view * @return PointF instance containing the scale information, or null if using the default * app widget scale of this device profile. */ @NonNull PointF getScaleFromItemInfo(@Nullable ItemInfo itemInfo); } public static class Builder { private Context mContext; private InvariantDeviceProfile mInv; Loading @@ -1562,6 +1604,7 @@ public class DeviceProfile { private boolean mIsMultiWindowMode = false; private Boolean mTransposeLayoutWithOrientation; private Boolean mIsGestureMode; private ViewScaleProvider mViewScaleProvider = null; private SparseArray<DotRenderer> mDotRendererCache; Loading Loading @@ -1601,6 +1644,19 @@ public class DeviceProfile { return this; } /** * Set the viewScaleProvider for the builder * * @param viewScaleProvider The viewScaleProvider to be set for the * DeviceProfile * @return This builder */ @NonNull public Builder setViewScaleProvider(@Nullable ViewScaleProvider viewScaleProvider) { mViewScaleProvider = viewScaleProvider; return this; } public DeviceProfile build() { if (mWindowBounds == null) { throw new IllegalArgumentException("Window bounds not set"); Loading @@ -1614,9 +1670,12 @@ public class DeviceProfile { if (mDotRendererCache == null) { mDotRendererCache = new SparseArray<>(); } if (mViewScaleProvider == null) { mViewScaleProvider = DEFAULT_PROVIDER; } return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mDotRendererCache, mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels, mIsGestureMode); mIsGestureMode, mViewScaleProvider); } } Loading src/com/android/launcher3/ShortcutAndWidgetContainer.java +9 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.launcher3.CellLayout.WORKSPACE; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.view.MotionEvent; import android.view.View; Loading @@ -32,6 +33,7 @@ import android.view.ViewGroup; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.widget.NavigableAppWidgetHostView; Loading Loading @@ -109,8 +111,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. if (child instanceof NavigableAppWidgetHostView) { DeviceProfile profile = mActivity.getDeviceProfile(); ((NavigableAppWidgetHostView) child).getWidgetInset(profile, mTempRect); final PointF appWidgetScale = profile.getAppWidgetScale((ItemInfo) child.getTag()); lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, profile.appWidgetScale.x, profile.appWidgetScale.y, mBorderSpace, mTempRect); appWidgetScale.x, appWidgetScale.y, mBorderSpace, mTempRect); } else { lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, mBorderSpace, null); Loading @@ -133,8 +136,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. if (child instanceof NavigableAppWidgetHostView) { ((NavigableAppWidgetHostView) child).getWidgetInset(dp, mTempRect); final PointF appWidgetScale = dp.getAppWidgetScale((ItemInfo) child.getTag()); lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, dp.appWidgetScale.x, dp.appWidgetScale.y, mBorderSpace, mTempRect); appWidgetScale.x, appWidgetScale.y, mBorderSpace, mTempRect); } else { lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, mBorderSpace, null); Loading Loading @@ -187,8 +191,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. // Scale and center the widget to fit within its cells. DeviceProfile profile = mActivity.getDeviceProfile(); float scaleX = profile.appWidgetScale.x; float scaleY = profile.appWidgetScale.y; final PointF appWidgetScale = profile.getAppWidgetScale((ItemInfo) child.getTag()); float scaleX = appWidgetScale.x; float scaleY = appWidgetScale.y; nahv.setScaleToFit(Math.min(scaleX, scaleY)); nahv.setTranslationForCentering(-(lp.width - (lp.width * scaleX)) / 2.0f, Loading src/com/android/launcher3/Workspace.java +5 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Handler; Loading Loading @@ -369,7 +370,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T> float scale = 1; if (isWidget) { DeviceProfile profile = mLauncher.getDeviceProfile(); scale = Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y); final PointF appWidgetScale = profile.getAppWidgetScale(null); scale = Utilities.shrinkRect(r, appWidgetScale.x, appWidgetScale.y); } size[0] = r.width(); size[1] = r.height(); Loading Loading @@ -2884,7 +2886,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T> r.top -= widgetPadding.top; r.bottom += widgetPadding.bottom; } Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y); PointF appWidgetScale = profile.getAppWidgetScale(null); Utilities.shrinkRect(r, appWidgetScale.x, appWidgetScale.y); } mTempFXY[0] = r.left; Loading src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +50 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.View.VISIBLE; import static com.android.launcher3.DeviceProfile.DEFAULT_SCALE; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks; Loading @@ -36,6 +37,7 @@ import android.content.ContextWrapper; import android.content.Intent; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.ColorDrawable; Loading @@ -55,6 +57,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.widget.TextClock; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.BubbleTextView; Loading Loading @@ -100,6 +103,7 @@ import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.LocalColorExtractor; import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.custom.CustomWidgetManager; import com.android.launcher3.widget.util.WidgetSizes; import java.util.ArrayList; import java.util.Collections; Loading Loading @@ -173,6 +177,7 @@ public class LauncherPreviewRenderer extends ContextWrapper private final Context mContext; private final InvariantDeviceProfile mIdp; private final DeviceProfile mDp; private final DeviceProfile mDpOrig; private final Rect mInsets; private final WorkspaceItemInfo mWorkspaceItemInfo; private final LayoutInflater mHomeElementInflater; Loading @@ -192,7 +197,16 @@ public class LauncherPreviewRenderer extends ContextWrapper mUiHandler = new Handler(Looper.getMainLooper()); mContext = context; mIdp = idp; mDp = idp.getDeviceProfile(context).copy(context); mDp = idp.getDeviceProfile(context).toBuilder(context).setViewScaleProvider( this::getAppWidgetScale).build(); if (context instanceof PreviewContext) { Context tempContext = ((PreviewContext) context).getBaseContext(); mDpOrig = new InvariantDeviceProfile(tempContext, InvariantDeviceProfile .getCurrentGridName(tempContext)).getDeviceProfile(tempContext) .copy(tempContext); } else { mDpOrig = mDp; } WindowInsets currentWindowInsets = context.getSystemService(WindowManager.class) .getCurrentWindowMetrics().getWindowInsets(); Loading Loading @@ -390,6 +404,41 @@ public class LauncherPreviewRenderer extends ContextWrapper addInScreenFromBind(view, info); } @NonNull private PointF getAppWidgetScale(@Nullable ItemInfo itemInfo) { if (!(itemInfo instanceof LauncherAppWidgetInfo)) { return DEFAULT_SCALE; } LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) itemInfo; final Size launcherWidgetSize = mLauncherWidgetSpanInfo.get(info.appWidgetId); if (launcherWidgetSize == null) { return DEFAULT_SCALE; } final Size origSize = WidgetSizes.getWidgetSizePx(mDpOrig, launcherWidgetSize.getWidth(), launcherWidgetSize.getHeight()); final Size newSize = WidgetSizes.getWidgetSizePx(mDp, info.spanX, info.spanY); final Rect previewInset = new Rect(); final Rect origInset = new Rect(); // When the setup() is called for the LayoutParams, insets are added to the width // and height of the view. This is not accounted for in WidgetSizes and is handled // here. if (mDp.shouldInsetWidgets()) { previewInset.set(mDp.inv.defaultWidgetPadding); } else { previewInset.setEmpty(); } if (mDpOrig.shouldInsetWidgets()) { origInset.set(mDpOrig.inv.defaultWidgetPadding); } else { origInset.setEmpty(); } return new PointF((float) newSize.getWidth() / (origSize.getWidth() + origInset.left + origInset.right), (float) newSize.getHeight() / (origSize.getHeight() + origInset.top + origInset.bottom)); } private void inflateAndAddPredictedIcon(WorkspaceItemInfo info) { CellLayout screen = mWorkspaceScreens.get(info.screenId); View view = PredictedAppIconInflater.inflate(mHomeElementInflater, screen, info); Loading tests/src/com/android/launcher3/DeviceProfileBaseTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.graphics.PointF import android.graphics.Rect import android.util.SparseArray import androidx.test.core.app.ApplicationProvider import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER; import com.android.launcher3.util.DisplayController.Info import com.android.launcher3.util.WindowBounds import org.junit.Before Loading Loading @@ -61,7 +62,8 @@ abstract class DeviceProfileBaseTest { isMultiWindowMode, transposeLayoutWithOrientation, useTwoPanels, isGestureMode isGestureMode, DEFAULT_PROVIDER ) protected fun initializeVarsForPhone(isGestureMode: Boolean = true, Loading Loading
src/com/android/launcher3/DeviceProfile.java +65 −6 Original line number Diff line number Diff line Loading @@ -38,11 +38,13 @@ import android.util.SparseArray; import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.DevicePaddings.DevicePadding; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.IconNormalizer; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.uioverrides.ApiWrapper; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; Loading @@ -57,6 +59,9 @@ public class DeviceProfile { private static final int DEFAULT_DOT_SIZE = 100; private static final float ALL_APPS_TABLET_MAX_ROWS = 5.5f; public static final PointF DEFAULT_SCALE = new PointF(1.0f, 1.0f); public static final ViewScaleProvider DEFAULT_PROVIDER = itemInfo -> DEFAULT_SCALE; // Ratio of empty space, qsb should take up to appear visually centered. private final float mQsbCenterFactor; Loading Loading @@ -204,7 +209,7 @@ public class DeviceProfile { public int overviewGridSideMargin; // Widgets public final PointF appWidgetScale = new PointF(1.0f, 1.0f); private final ViewScaleProvider mViewScaleProvider; // Drop Target public int dropTargetBarSizePx; Loading Loading @@ -240,7 +245,8 @@ public class DeviceProfile { /** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */ DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds, SparseArray<DotRenderer> dotRendererCache, boolean isMultiWindowMode, boolean transposeLayoutWithOrientation, boolean useTwoPanels, boolean isGestureMode) { boolean transposeLayoutWithOrientation, boolean useTwoPanels, boolean isGestureMode, @NonNull final ViewScaleProvider viewScaleProvider) { this.inv = inv; this.isLandscape = windowBounds.isLandscape(); Loading Loading @@ -473,6 +479,8 @@ public class DeviceProfile { flingToDeleteThresholdVelocity = res.getDimensionPixelSize( R.dimen.drag_flingToDeleteMinVelocity); mViewScaleProvider = viewScaleProvider; // This is done last, after iconSizePx is calculated above. mDotRendererWorkSpace = createDotRenderer(iconSizePx, dotRendererCache); mDotRendererAllApps = createDotRenderer(allAppsIconSizePx, dotRendererCache); Loading Loading @@ -669,13 +677,18 @@ public class DeviceProfile { .setMultiWindowMode(true) .build(); profile.hideWorkspaceLabelsIfNotEnoughSpace(); // We use these scales to measure and layout the widgets using their full invariant profile // sizes and then draw them scaled and centered to fit in their multi-window mode cellspans. float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x; float appWidgetScaleY = (float) profile.getCellSize().y / getCellSize().y; profile.appWidgetScale.set(appWidgetScaleX, appWidgetScaleY); if (appWidgetScaleX != 1 || appWidgetScaleY != 1) { final PointF p = new PointF(appWidgetScaleX, appWidgetScaleY); profile = profile.toBuilder(context) .setViewScaleProvider(i -> p) .build(); } profile.hideWorkspaceLabelsIfNotEnoughSpace(); return profile; } Loading Loading @@ -1242,6 +1255,19 @@ public class DeviceProfile { + getOverviewActionsClaimedSpaceBelow(); } /** * Takes the View and return the scales of width and height depending on the DeviceProfile * specifications * * @param itemInfo The tag of the widget view * @return A PointF instance with the x set to be the scale of width, and y being the scale of * height */ @NonNull public PointF getAppWidgetScale(@Nullable final ItemInfo itemInfo) { return mViewScaleProvider.getScaleFromItemInfo(itemInfo); } /** * @return the bounds for which the open folders should be contained within */ Loading Loading @@ -1551,6 +1577,22 @@ public class DeviceProfile { } } /** * Handler that deals with ItemInfo of the views for the DeviceProfile */ @FunctionalInterface public interface ViewScaleProvider { /** * Get the scales from the view * * @param itemInfo The tag of the widget view * @return PointF instance containing the scale information, or null if using the default * app widget scale of this device profile. */ @NonNull PointF getScaleFromItemInfo(@Nullable ItemInfo itemInfo); } public static class Builder { private Context mContext; private InvariantDeviceProfile mInv; Loading @@ -1562,6 +1604,7 @@ public class DeviceProfile { private boolean mIsMultiWindowMode = false; private Boolean mTransposeLayoutWithOrientation; private Boolean mIsGestureMode; private ViewScaleProvider mViewScaleProvider = null; private SparseArray<DotRenderer> mDotRendererCache; Loading Loading @@ -1601,6 +1644,19 @@ public class DeviceProfile { return this; } /** * Set the viewScaleProvider for the builder * * @param viewScaleProvider The viewScaleProvider to be set for the * DeviceProfile * @return This builder */ @NonNull public Builder setViewScaleProvider(@Nullable ViewScaleProvider viewScaleProvider) { mViewScaleProvider = viewScaleProvider; return this; } public DeviceProfile build() { if (mWindowBounds == null) { throw new IllegalArgumentException("Window bounds not set"); Loading @@ -1614,9 +1670,12 @@ public class DeviceProfile { if (mDotRendererCache == null) { mDotRendererCache = new SparseArray<>(); } if (mViewScaleProvider == null) { mViewScaleProvider = DEFAULT_PROVIDER; } return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mDotRendererCache, mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels, mIsGestureMode); mIsGestureMode, mViewScaleProvider); } } Loading
src/com/android/launcher3/ShortcutAndWidgetContainer.java +9 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.launcher3.CellLayout.WORKSPACE; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.view.MotionEvent; import android.view.View; Loading @@ -32,6 +33,7 @@ import android.view.ViewGroup; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.widget.NavigableAppWidgetHostView; Loading Loading @@ -109,8 +111,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. if (child instanceof NavigableAppWidgetHostView) { DeviceProfile profile = mActivity.getDeviceProfile(); ((NavigableAppWidgetHostView) child).getWidgetInset(profile, mTempRect); final PointF appWidgetScale = profile.getAppWidgetScale((ItemInfo) child.getTag()); lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, profile.appWidgetScale.x, profile.appWidgetScale.y, mBorderSpace, mTempRect); appWidgetScale.x, appWidgetScale.y, mBorderSpace, mTempRect); } else { lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, mBorderSpace, null); Loading @@ -133,8 +136,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. if (child instanceof NavigableAppWidgetHostView) { ((NavigableAppWidgetHostView) child).getWidgetInset(dp, mTempRect); final PointF appWidgetScale = dp.getAppWidgetScale((ItemInfo) child.getTag()); lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, dp.appWidgetScale.x, dp.appWidgetScale.y, mBorderSpace, mTempRect); appWidgetScale.x, appWidgetScale.y, mBorderSpace, mTempRect); } else { lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, mBorderSpace, null); Loading Loading @@ -187,8 +191,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. // Scale and center the widget to fit within its cells. DeviceProfile profile = mActivity.getDeviceProfile(); float scaleX = profile.appWidgetScale.x; float scaleY = profile.appWidgetScale.y; final PointF appWidgetScale = profile.getAppWidgetScale((ItemInfo) child.getTag()); float scaleX = appWidgetScale.x; float scaleY = appWidgetScale.y; nahv.setScaleToFit(Math.min(scaleX, scaleY)); nahv.setTranslationForCentering(-(lp.width - (lp.width * scaleX)) / 2.0f, Loading
src/com/android/launcher3/Workspace.java +5 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Handler; Loading Loading @@ -369,7 +370,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T> float scale = 1; if (isWidget) { DeviceProfile profile = mLauncher.getDeviceProfile(); scale = Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y); final PointF appWidgetScale = profile.getAppWidgetScale(null); scale = Utilities.shrinkRect(r, appWidgetScale.x, appWidgetScale.y); } size[0] = r.width(); size[1] = r.height(); Loading Loading @@ -2884,7 +2886,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T> r.top -= widgetPadding.top; r.bottom += widgetPadding.bottom; } Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y); PointF appWidgetScale = profile.getAppWidgetScale(null); Utilities.shrinkRect(r, appWidgetScale.x, appWidgetScale.y); } mTempFXY[0] = r.left; Loading
src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +50 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.View.VISIBLE; import static com.android.launcher3.DeviceProfile.DEFAULT_SCALE; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks; Loading @@ -36,6 +37,7 @@ import android.content.ContextWrapper; import android.content.Intent; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.ColorDrawable; Loading @@ -55,6 +57,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.widget.TextClock; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.BubbleTextView; Loading Loading @@ -100,6 +103,7 @@ import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.LocalColorExtractor; import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.custom.CustomWidgetManager; import com.android.launcher3.widget.util.WidgetSizes; import java.util.ArrayList; import java.util.Collections; Loading Loading @@ -173,6 +177,7 @@ public class LauncherPreviewRenderer extends ContextWrapper private final Context mContext; private final InvariantDeviceProfile mIdp; private final DeviceProfile mDp; private final DeviceProfile mDpOrig; private final Rect mInsets; private final WorkspaceItemInfo mWorkspaceItemInfo; private final LayoutInflater mHomeElementInflater; Loading @@ -192,7 +197,16 @@ public class LauncherPreviewRenderer extends ContextWrapper mUiHandler = new Handler(Looper.getMainLooper()); mContext = context; mIdp = idp; mDp = idp.getDeviceProfile(context).copy(context); mDp = idp.getDeviceProfile(context).toBuilder(context).setViewScaleProvider( this::getAppWidgetScale).build(); if (context instanceof PreviewContext) { Context tempContext = ((PreviewContext) context).getBaseContext(); mDpOrig = new InvariantDeviceProfile(tempContext, InvariantDeviceProfile .getCurrentGridName(tempContext)).getDeviceProfile(tempContext) .copy(tempContext); } else { mDpOrig = mDp; } WindowInsets currentWindowInsets = context.getSystemService(WindowManager.class) .getCurrentWindowMetrics().getWindowInsets(); Loading Loading @@ -390,6 +404,41 @@ public class LauncherPreviewRenderer extends ContextWrapper addInScreenFromBind(view, info); } @NonNull private PointF getAppWidgetScale(@Nullable ItemInfo itemInfo) { if (!(itemInfo instanceof LauncherAppWidgetInfo)) { return DEFAULT_SCALE; } LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) itemInfo; final Size launcherWidgetSize = mLauncherWidgetSpanInfo.get(info.appWidgetId); if (launcherWidgetSize == null) { return DEFAULT_SCALE; } final Size origSize = WidgetSizes.getWidgetSizePx(mDpOrig, launcherWidgetSize.getWidth(), launcherWidgetSize.getHeight()); final Size newSize = WidgetSizes.getWidgetSizePx(mDp, info.spanX, info.spanY); final Rect previewInset = new Rect(); final Rect origInset = new Rect(); // When the setup() is called for the LayoutParams, insets are added to the width // and height of the view. This is not accounted for in WidgetSizes and is handled // here. if (mDp.shouldInsetWidgets()) { previewInset.set(mDp.inv.defaultWidgetPadding); } else { previewInset.setEmpty(); } if (mDpOrig.shouldInsetWidgets()) { origInset.set(mDpOrig.inv.defaultWidgetPadding); } else { origInset.setEmpty(); } return new PointF((float) newSize.getWidth() / (origSize.getWidth() + origInset.left + origInset.right), (float) newSize.getHeight() / (origSize.getHeight() + origInset.top + origInset.bottom)); } private void inflateAndAddPredictedIcon(WorkspaceItemInfo info) { CellLayout screen = mWorkspaceScreens.get(info.screenId); View view = PredictedAppIconInflater.inflate(mHomeElementInflater, screen, info); Loading
tests/src/com/android/launcher3/DeviceProfileBaseTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.graphics.PointF import android.graphics.Rect import android.util.SparseArray import androidx.test.core.app.ApplicationProvider import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER; import com.android.launcher3.util.DisplayController.Info import com.android.launcher3.util.WindowBounds import org.junit.Before Loading Loading @@ -61,7 +62,8 @@ abstract class DeviceProfileBaseTest { isMultiWindowMode, transposeLayoutWithOrientation, useTwoPanels, isGestureMode isGestureMode, DEFAULT_PROVIDER ) protected fun initializeVarsForPhone(isGestureMode: Boolean = true, Loading