Merge "Fix paired icon placement in landscape/seascape" into tm-dev

This commit is contained in:
Jeremy Sim
2022-03-22 00:17:43 +00:00
committed by Android (Google) Code Review
6 changed files with 146 additions and 17 deletions
@@ -271,7 +271,8 @@ public class GroupedTaskView extends TaskView {
getPagedOrientationHandler().setSplitIconParams(mIconView, mIconView2,
taskIconHeight, mSnapshotView.getMeasuredWidth(), mSnapshotView.getMeasuredHeight(),
isRtl, deviceProfile, mSplitBoundsConfig);
getMeasuredHeight(), getMeasuredWidth(), isRtl, deviceProfile,
mSplitBoundsConfig);
}
private void updateSecondaryDwbPlacement() {
@@ -16,6 +16,7 @@
package com.android.launcher3.touch;
import static android.view.Gravity.BOTTOM;
import static android.view.Gravity.CENTER_VERTICAL;
import static android.view.Gravity.END;
import static android.view.Gravity.START;
@@ -468,18 +469,42 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
@Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
FrameLayout.LayoutParams secondaryIconParams =
new FrameLayout.LayoutParams(primaryIconParams);
primaryIconParams.gravity = CENTER_VERTICAL | (isRtl ? START : END);
// We calculate the "midpoint" of the thumbnail area, and place the icons there.
// This is the place where the thumbnail area splits by default, in a near-50/50 split.
// It is usually not exactly 50/50, due to insets/screen cutouts.
int fullscreenInsetThickness = deviceProfile.getInsets().top;
int fullscreenMidpointFromBottom = ((deviceProfile.heightPx - fullscreenInsetThickness)
/ 2);
float midpointFromBottomPct = (float) fullscreenMidpointFromBottom / deviceProfile.heightPx;
float insetPct = (float) fullscreenInsetThickness / deviceProfile.heightPx;
int spaceAboveSnapshots = deviceProfile.overviewTaskThumbnailTopMarginPx;
int overviewThumbnailAreaThickness = groupedTaskViewHeight - spaceAboveSnapshots;
int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness * midpointFromBottomPct);
int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
primaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
secondaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
primaryIconView.setTranslationX(0);
primaryIconView.setTranslationY(-(taskIconHeight / 2f));
secondaryIconParams.gravity = CENTER_VERTICAL | (isRtl ? START : END);
secondaryIconView.setTranslationX(0);
secondaryIconView.setTranslationY(taskIconHeight / 2f);
if (splitConfig.initiatedFromSeascape) {
// if the split was initiated from seascape,
// the task on the right (secondary) is slightly larger
primaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset);
secondaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset
+ taskIconHeight);
} else {
// if not,
// the task on the left (primary) is slightly larger
primaryIconView.setTranslationY(-bottomToMidpointOffset);
secondaryIconView.setTranslationY(-bottomToMidpointOffset + taskIconHeight);
}
primaryIconView.setLayoutParams(primaryIconParams);
secondaryIconView.setLayoutParams(secondaryIconParams);
@@ -146,7 +146,8 @@ public interface PagedOrientationHandler {
int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig);
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
DeviceProfile deviceProfile, StagedSplitBounds splitConfig);
/*
* The following two methods try to center the TaskMenuView in landscape by finding the center
@@ -18,6 +18,7 @@ package com.android.launcher3.touch;
import static android.view.Gravity.BOTTOM;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.Gravity.END;
import static android.view.Gravity.START;
import static android.view.Gravity.TOP;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -565,18 +566,70 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
@Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
FrameLayout.LayoutParams secondaryIconParams =
new FrameLayout.LayoutParams(primaryIconParams);
primaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
// shifts icon half a width left (height is used conveniently here since icons are square)
primaryIconView.setTranslationX(-(taskIconHeight / 2f));
if (deviceProfile.isLandscape) {
// We calculate the "midpoint" of the thumbnail area, and place the icons there.
// This is the place where the thumbnail area splits by default, in a near-50/50 split.
// It is usually not exactly 50/50, due to insets/screen cutouts.
int fullscreenInsetThickness = deviceProfile.isSeascape()
? deviceProfile.getInsets().right
: deviceProfile.getInsets().left;
int fullscreenMidpointFromBottom = ((deviceProfile.widthPx
- fullscreenInsetThickness) / 2);
float midpointFromBottomPct = (float) fullscreenMidpointFromBottom
/ deviceProfile.widthPx;
float insetPct = (float) fullscreenInsetThickness / deviceProfile.widthPx;
int spaceAboveSnapshots = 0;
int overviewThumbnailAreaThickness = groupedTaskViewWidth - spaceAboveSnapshots;
int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness
* midpointFromBottomPct);
int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
if (deviceProfile.isSeascape()) {
primaryIconParams.gravity = TOP | (isRtl ? END : START);
secondaryIconParams.gravity = TOP | (isRtl ? END : START);
if (splitConfig.initiatedFromSeascape) {
// if the split was initiated from seascape,
// the task on the right (secondary) is slightly larger
primaryIconView.setTranslationX(bottomToMidpointOffset - taskIconHeight);
secondaryIconView.setTranslationX(bottomToMidpointOffset);
} else {
// if not,
// the task on the left (primary) is slightly larger
primaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset
- taskIconHeight);
secondaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset);
}
} else {
primaryIconParams.gravity = TOP | (isRtl ? START : END);
secondaryIconParams.gravity = TOP | (isRtl ? START : END);
if (!splitConfig.initiatedFromSeascape) {
// if the split was initiated from landscape,
// the task on the left (primary) is slightly larger
primaryIconView.setTranslationX(-bottomToMidpointOffset);
secondaryIconView.setTranslationX(-bottomToMidpointOffset + taskIconHeight);
} else {
// if not,
// the task on the right (secondary) is slightly larger
primaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset);
secondaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset
+ taskIconHeight);
}
}
} else {
primaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
// shifts icon half a width left (height is used here since icons are square)
primaryIconView.setTranslationX(-(taskIconHeight / 2f));
secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
secondaryIconView.setTranslationX(taskIconHeight / 2f);
}
primaryIconView.setTranslationY(0);
secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
secondaryIconView.setTranslationX(taskIconHeight / 2f);
secondaryIconView.setTranslationY(0);
primaryIconView.setLayoutParams(primaryIconParams);
@@ -178,16 +178,46 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
@Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
super.setSplitIconParams(primaryIconView, secondaryIconView, taskIconHeight,
primarySnapshotWidth, primarySnapshotHeight, isRtl, deviceProfile, splitConfig);
primarySnapshotWidth, primarySnapshotHeight, groupedTaskViewHeight,
groupedTaskViewWidth, isRtl, deviceProfile, splitConfig);
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
FrameLayout.LayoutParams secondaryIconParams =
(FrameLayout.LayoutParams) secondaryIconView.getLayoutParams();
primaryIconParams.gravity = CENTER_VERTICAL | (isRtl ? END : START);
secondaryIconParams.gravity = CENTER_VERTICAL | (isRtl ? END : START);
// We calculate the "midpoint" of the thumbnail area, and place the icons there.
// This is the place where the thumbnail area splits by default, in a near-50/50 split.
// It is usually not exactly 50/50, due to insets/screen cutouts.
int fullscreenInsetThickness = deviceProfile.getInsets().top;
int fullscreenMidpointFromBottom = ((deviceProfile.heightPx
- fullscreenInsetThickness) / 2);
float midpointFromBottomPct = (float) fullscreenMidpointFromBottom / deviceProfile.heightPx;
float insetPct = (float) fullscreenInsetThickness / deviceProfile.heightPx;
int spaceAboveSnapshots = deviceProfile.overviewTaskThumbnailTopMarginPx;
int overviewThumbnailAreaThickness = groupedTaskViewHeight - spaceAboveSnapshots;
int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness * midpointFromBottomPct);
int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
primaryIconParams.gravity = BOTTOM | (isRtl ? END : START);
secondaryIconParams.gravity = BOTTOM | (isRtl ? END : START);
primaryIconView.setTranslationX(0);
secondaryIconView.setTranslationX(0);
if (splitConfig.initiatedFromSeascape) {
// if the split was initiated from seascape,
// the task on the right (secondary) is slightly larger
primaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset);
secondaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset
+ taskIconHeight);
} else {
// if not,
// the task on the left (primary) is slightly larger
primaryIconView.setTranslationY(-bottomToMidpointOffset);
secondaryIconView.setTranslationY(-bottomToMidpointOffset + taskIconHeight);
}
primaryIconView.setLayoutParams(primaryIconParams);
secondaryIconView.setLayoutParams(secondaryIconParams);
}
@@ -113,6 +113,14 @@ public final class SplitConfigurationOptions {
* the bounds were originally in
*/
public final boolean appsStackedVertically;
/**
* If {@code true}, that means at the time of creation of this object, the phone was in
* seascape orientation. This is important on devices with insets, because they do not split
* evenly -- one of the insets must be slightly larger to account for the inset.
* From landscape, it is the leftTop task that expands slightly.
* From seascape, it is the rightBottom task that expands slightly.
*/
public final boolean initiatedFromSeascape;
public final int leftTopTaskId;
public final int rightBottomTaskId;
@@ -128,11 +136,22 @@ public final class SplitConfigurationOptions {
this.visualDividerBounds = new Rect(leftTopBounds.left, leftTopBounds.bottom,
leftTopBounds.right, rightBottomBounds.top);
appsStackedVertically = true;
initiatedFromSeascape = false;
} else {
// horizontal apps, vertical divider
this.visualDividerBounds = new Rect(leftTopBounds.right, leftTopBounds.top,
rightBottomBounds.left, leftTopBounds.bottom);
appsStackedVertically = false;
// The following check is unreliable on devices without insets
// (initiatedFromSeascape will always be set to false.) This happens to be OK for
// all our current uses, but should be refactored.
// TODO: Create a more reliable check, or refactor how splitting works on devices
// with insets.
if (rightBottomBounds.width() > leftTopBounds.width()) {
initiatedFromSeascape = true;
} else {
initiatedFromSeascape = false;
}
}
leftTaskPercent = this.leftTopBounds.width() / (float) rightBottomBounds.right;