Align rounded corners beside divider bar with display and task bar

Use the same way to draw rounded corners beside divider bar with
display and task bar to make sure all rounded corners share the same
style.

Bug: 196272915
Test: atest WMShellUnitTests
Test: manul check the rounded corners rendered in proper position.
Change-Id: I566ef5233dc345e0229fd9637c3b05705ba35864
This commit is contained in:
Jerry Chang
2021-09-17 21:56:54 +08:00
parent c3409c0dfd
commit 8675afb2c4
9 changed files with 164 additions and 149 deletions

View File

@@ -1,30 +0,0 @@
<!--
~ Copyright (C) 2021 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/split_divider_corner_size"
android:height="@dimen/split_divider_corner_size"
android:viewportWidth="42"
android:viewportHeight="42">
<group android:pivotX="21"
android:pivotY="21"
android:rotation="180">
<path
android:fillColor="@color/split_divider_background"
android:pathData="m 0 0 c 8 0 16 8 16 16 h 10 c 0 -8 8 -16 16 -16 z" />
</group>
</vector>

View File

@@ -1,30 +0,0 @@
<!--
~ Copyright (C) 2021 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/split_divider_corner_size"
android:height="@dimen/split_divider_corner_size"
android:viewportWidth="42"
android:viewportHeight="42">
<group android:pivotX="21"
android:pivotY="21"
android:rotation="-90">
<path
android:fillColor="@color/split_divider_background"
android:pathData="m 0 0 c 8 0 16 8 16 16 h 10 c 0 -8 8 -16 16 -16 z" />
</group>
</vector>

View File

@@ -1,30 +0,0 @@
<!--
~ Copyright (C) 2021 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/split_divider_corner_size"
android:height="@dimen/split_divider_corner_size"
android:viewportWidth="42"
android:viewportHeight="42">
<group android:pivotX="21"
android:pivotY="21"
android:rotation="90">
<path
android:fillColor="@color/split_divider_background"
android:pathData="m 0 0 c 8 0 16 8 16 16 h 10 c 0 -8 8 -16 16 -16 z" />
</group>
</vector>

View File

@@ -1,26 +0,0 @@
<!--
~ Copyright (C) 2021 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/split_divider_corner_size"
android:height="@dimen/split_divider_corner_size"
android:viewportWidth="42"
android:viewportHeight="42">
<path
android:fillColor="@color/split_divider_background"
android:pathData="m 0 0 c 8 0 16 8 16 16 h 10 c 0 -8 8 -16 16 -16 z" />
</vector>

View File

@@ -24,20 +24,20 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<View style="@style/DockedDividerTopLeftRoundCorner"/>
<View
style="@style/DockedDividerBackground"
android:id="@+id/docked_divider_background"/>
<View style="@style/DockedDividerBottomRightRoundCorner"/>
<com.android.wm.shell.common.split.DividerHandleView
style="@style/DockedDividerHandle"
android:id="@+id/docked_divider_handle"
android:contentDescription="@string/accessibility_divider"
android:background="@null"/>
<com.android.wm.shell.common.split.DividerRoundedCorner
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</com.android.wm.shell.common.split.DividerView>

View File

@@ -28,20 +28,6 @@
<item name="android:layout_height">96dp</item>
</style>
<style name="DockedDividerTopLeftRoundCorner">
<item name="android:layout_gravity">center_horizontal|top</item>
<item name="android:background">@drawable/split_rounded_top</item>
<item name="android:layout_width">@dimen/split_divider_corner_size</item>
<item name="android:layout_height">@dimen/split_divider_corner_size</item>
</style>
<style name="DockedDividerBottomRightRoundCorner">
<item name="android:layout_gravity">center_horizontal|bottom</item>
<item name="android:background">@drawable/split_rounded_bottom</item>
<item name="android:layout_width">@dimen/split_divider_corner_size</item>
<item name="android:layout_height">@dimen/split_divider_corner_size</item>
</style>
<style name="DockedDividerMinimizedShadow">
<item name="android:layout_width">8dp</item>
<item name="android:layout_height">match_parent</item>

View File

@@ -37,20 +37,6 @@
<item name="android:background">@color/split_divider_background</item>
</style>
<style name="DockedDividerTopLeftRoundCorner">
<item name="android:layout_gravity">center_vertical|left</item>
<item name="android:background">@drawable/split_rounded_left</item>
<item name="android:layout_width">@dimen/split_divider_corner_size</item>
<item name="android:layout_height">@dimen/split_divider_corner_size</item>
</style>
<style name="DockedDividerBottomRightRoundCorner">
<item name="android:layout_gravity">center_vertical|right</item>
<item name="android:background">@drawable/split_rounded_right</item>
<item name="android:layout_width">@dimen/split_divider_corner_size</item>
<item name="android:layout_height">@dimen/split_divider_corner_size</item>
</style>
<style name="DockedDividerMinimizedShadow">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">8dp</item>

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.common.split;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT;
import static android.view.RoundedCorner.POSITION_BOTTOM_RIGHT;
import static android.view.RoundedCorner.POSITION_TOP_LEFT;
import static android.view.RoundedCorner.POSITION_TOP_RIGHT;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.RoundedCorner;
import android.view.View;
import androidx.annotation.Nullable;
import com.android.wm.shell.R;
/**
* Draws inverted rounded corners beside divider bar to keep splitting tasks cropped with proper
* rounded corners.
*/
public class DividerRoundedCorner extends View {
private final int mDividerWidth;
private final Paint mDividerBarBackground;
private final Point mStartPos = new Point();
private InvertedRoundedCornerDrawInfo mTopLeftCorner;
private InvertedRoundedCornerDrawInfo mTopRightCorner;
private InvertedRoundedCornerDrawInfo mBottomLeftCorner;
private InvertedRoundedCornerDrawInfo mBottomRightCorner;
public DividerRoundedCorner(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mDividerWidth = getResources().getDimensionPixelSize(R.dimen.split_divider_bar_width);
mDividerBarBackground = new Paint();
mDividerBarBackground.setColor(
getResources().getColor(R.color.split_divider_background, null));
mDividerBarBackground.setFlags(Paint.ANTI_ALIAS_FLAG);
mDividerBarBackground.setStyle(Paint.Style.FILL);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mTopLeftCorner = new InvertedRoundedCornerDrawInfo(POSITION_TOP_LEFT);
mTopRightCorner = new InvertedRoundedCornerDrawInfo(POSITION_TOP_RIGHT);
mBottomLeftCorner = new InvertedRoundedCornerDrawInfo(POSITION_BOTTOM_LEFT);
mBottomRightCorner = new InvertedRoundedCornerDrawInfo(POSITION_BOTTOM_RIGHT);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
mTopLeftCorner.calculateStartPos(mStartPos);
canvas.translate(mStartPos.x, mStartPos.y);
canvas.drawPath(mTopLeftCorner.mPath, mDividerBarBackground);
canvas.translate(-mStartPos.x, -mStartPos.y);
mTopRightCorner.calculateStartPos(mStartPos);
canvas.translate(mStartPos.x, mStartPos.y);
canvas.drawPath(mTopRightCorner.mPath, mDividerBarBackground);
canvas.translate(-mStartPos.x, -mStartPos.y);
mBottomLeftCorner.calculateStartPos(mStartPos);
canvas.translate(mStartPos.x, mStartPos.y);
canvas.drawPath(mBottomLeftCorner.mPath, mDividerBarBackground);
canvas.translate(-mStartPos.x, -mStartPos.y);
mBottomRightCorner.calculateStartPos(mStartPos);
canvas.translate(mStartPos.x, mStartPos.y);
canvas.drawPath(mBottomRightCorner.mPath, mDividerBarBackground);
canvas.restore();
}
@Override
public boolean hasOverlappingRendering() {
return false;
}
private boolean isLandscape() {
return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
}
/**
* Holds draw information of the inverted rounded corner at a specific position.
*
* @see {@link com.android.launcher3.taskbar.TaskbarDragLayer}
*/
private class InvertedRoundedCornerDrawInfo {
@RoundedCorner.Position
private final int mCornerPosition;
private final int mRadius;
private final Path mPath = new Path();
InvertedRoundedCornerDrawInfo(@RoundedCorner.Position int cornerPosition) {
mCornerPosition = cornerPosition;
final RoundedCorner roundedCorner = getDisplay().getRoundedCorner(cornerPosition);
mRadius = roundedCorner == null ? 0 : roundedCorner.getRadius();
// Starts with a filled square, and then subtracting out a circle from the appropriate
// corner.
final Path square = new Path();
square.addRect(0, 0, mRadius, mRadius, Path.Direction.CW);
final Path circle = new Path();
circle.addCircle(
isLeftCorner() ? mRadius : 0 /* x */,
isTopCorner() ? mRadius : 0 /* y */,
mRadius, Path.Direction.CW);
mPath.op(square, circle, Path.Op.DIFFERENCE);
}
private void calculateStartPos(Point outPos) {
if (isLandscape()) {
// Place left corner at the right side of the divider bar.
outPos.x = isLeftCorner()
? getWidth() / 2 + mDividerWidth / 2
: getWidth() / 2 - mDividerWidth / 2 - mRadius;
outPos.y = isTopCorner() ? 0 : getHeight() - mRadius;
} else {
outPos.x = isLeftCorner() ? 0 : getWidth() - mRadius;
// Place top corner at the bottom of the divider bar.
outPos.y = isTopCorner()
? getHeight() / 2 + mDividerWidth / 2
: getHeight() / 2 - mDividerWidth / 2 - mRadius;
}
}
private boolean isLeftCorner() {
return mCornerPosition == POSITION_TOP_LEFT || mCornerPosition == POSITION_BOTTOM_LEFT;
}
private boolean isTopCorner() {
return mCornerPosition == POSITION_TOP_LEFT || mCornerPosition == POSITION_TOP_RIGHT;
}
}
}

View File

@@ -24,7 +24,6 @@ import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Property;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.InsetsSource;
import android.view.InsetsState;