Add outline to tv pip menu arrows
In order to have an outline for the arrows, we draw them programmatically instead of in xml with vector drawables. This way, we can ensure that the Path for the drawable is the same as the Path for the ViewOutlineProvider. Bug: 220108601 Test: atest TvPipMenuController Test: flash and check arrows are visible over white background Change-Id: I965e9ac33f474012446b6f8096edf39d93a0c92e
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/tv_pip_menu_focus_border"
|
||||
android:pathData="M7,10l5,5 5,-5H7z"/>
|
||||
</vector>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/tv_pip_menu_focus_border"
|
||||
android:pathData="M14,7l-5,5 5,5V7z"/>
|
||||
</vector>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/tv_pip_menu_focus_border"
|
||||
android:pathData="M10,17l5,-5 -5,-5v10z"/>
|
||||
</vector>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/tv_pip_menu_focus_border"
|
||||
android:pathData="M7,14l5,-5 5,5H7z"/>
|
||||
</vector>
|
||||
@@ -104,9 +104,7 @@
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:alpha="0"
|
||||
android:contentDescription="@string/a11y_action_pip_move_up"
|
||||
android:elevation="@dimen/pip_menu_arrow_elevation"
|
||||
android:src="@drawable/pip_ic_move_up" />
|
||||
android:contentDescription="@string/a11y_action_pip_move_up"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tv_pip_menu_arrow_right"
|
||||
@@ -115,9 +113,7 @@
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:alpha="0"
|
||||
android:contentDescription="@string/a11y_action_pip_move_right"
|
||||
android:elevation="@dimen/pip_menu_arrow_elevation"
|
||||
android:src="@drawable/pip_ic_move_right" />
|
||||
android:contentDescription="@string/a11y_action_pip_move_right"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tv_pip_menu_arrow_down"
|
||||
@@ -126,9 +122,7 @@
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:alpha="0"
|
||||
android:contentDescription="@string/a11y_action_pip_move_down"
|
||||
android:elevation="@dimen/pip_menu_arrow_elevation"
|
||||
android:src="@drawable/pip_ic_move_down" />
|
||||
android:contentDescription="@string/a11y_action_pip_move_down"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tv_pip_menu_arrow_left"
|
||||
@@ -137,7 +131,5 @@
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:alpha="0"
|
||||
android:contentDescription="@string/a11y_action_pip_move_left"
|
||||
android:elevation="@dimen/pip_menu_arrow_elevation"
|
||||
android:src="@drawable/pip_ic_move_left" />
|
||||
android:contentDescription="@string/a11y_action_pip_move_left"/>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
<!-- outer space minus border width -->
|
||||
<dimen name="pip_menu_outer_space_frame">20dp</dimen>
|
||||
|
||||
<dimen name="pip_menu_arrow_size">24dp</dimen>
|
||||
<dimen name="pip_menu_arrow_elevation">5dp</dimen>
|
||||
<dimen name="pip_menu_arrow_size">12dp</dimen>
|
||||
<dimen name="pip_menu_arrow_elevation">1dp</dimen>
|
||||
|
||||
<dimen name="pip_menu_elevation_no_menu">1dp</dimen>
|
||||
<dimen name="pip_menu_elevation_move_menu">7dp</dimen>
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
<color name="tv_pip_menu_focus_border">#E8EAED</color>
|
||||
<color name="tv_pip_menu_dim_layer">#990E0E0F</color>
|
||||
<color name="tv_pip_menu_background">#1E232C</color>
|
||||
<!-- Normally, the arrow color would be the same as the focus border color. But due to
|
||||
optical illusion that looks too dark on the screen. That's why we define a separate
|
||||
(lighter) arrow color. -->
|
||||
<color name="tv_pip_menu_arrow_color">#F1F3F4</color>
|
||||
|
||||
<color name="tv_pip_edu_text">#99D2E3FC</color>
|
||||
<color name="tv_pip_edu_text_home_icon">#D2E3FC</color>
|
||||
|
||||
@@ -31,12 +31,19 @@ import static com.android.wm.shell.pip.tv.TvPipMenuController.MODE_MOVE_MENU;
|
||||
import static com.android.wm.shell.pip.tv.TvPipMenuController.MODE_NO_MENU;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.PathShape;
|
||||
import android.os.Handler;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
@@ -89,6 +96,8 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
|
||||
private final ImageView mArrowLeft;
|
||||
private final TvWindowMenuActionButton mA11yDoneButton;
|
||||
|
||||
private final int mArrowElevation;
|
||||
|
||||
private @TvPipMenuController.TvPipMenuMode int mCurrentMenuMode = MODE_NO_MENU;
|
||||
private final Rect mCurrentPipBounds = new Rect();
|
||||
private int mCurrentPipGravity;
|
||||
@@ -129,21 +138,70 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
|
||||
mArrowLeft = findViewById(R.id.tv_pip_menu_arrow_left);
|
||||
mA11yDoneButton = findViewById(R.id.tv_pip_menu_done_button);
|
||||
|
||||
mResizeAnimationDuration = context.getResources().getInteger(
|
||||
R.integer.config_pipResizeAnimationDuration);
|
||||
mPipMenuFadeAnimationDuration = context.getResources()
|
||||
.getInteger(R.integer.tv_window_menu_fade_animation_duration);
|
||||
final Resources res = context.getResources();
|
||||
mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration);
|
||||
mPipMenuFadeAnimationDuration =
|
||||
res.getInteger(R.integer.tv_window_menu_fade_animation_duration);
|
||||
mPipMenuOuterSpace = res.getDimensionPixelSize(R.dimen.pip_menu_outer_space);
|
||||
mPipMenuBorderWidth = res.getDimensionPixelSize(R.dimen.pip_menu_border_width);
|
||||
mArrowElevation = res.getDimensionPixelSize(R.dimen.pip_menu_arrow_elevation);
|
||||
|
||||
mPipMenuOuterSpace = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.pip_menu_outer_space);
|
||||
mPipMenuBorderWidth = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.pip_menu_border_width);
|
||||
initMoveArrows();
|
||||
|
||||
mEduTextDrawer = new TvPipMenuEduTextDrawer(mContext, mainHandler, mListener);
|
||||
((FrameLayout) findViewById(R.id.tv_pip_menu_edu_text_drawer_placeholder))
|
||||
.addView(mEduTextDrawer);
|
||||
}
|
||||
|
||||
private void initMoveArrows() {
|
||||
final int arrowSize =
|
||||
mContext.getResources().getDimensionPixelSize(R.dimen.pip_menu_arrow_size);
|
||||
final Path arrowPath = createArrowPath(arrowSize);
|
||||
|
||||
final ShapeDrawable arrowDrawable = new ShapeDrawable();
|
||||
arrowDrawable.setShape(new PathShape(arrowPath, arrowSize, arrowSize));
|
||||
arrowDrawable.setTint(mContext.getResources().getColor(R.color.tv_pip_menu_arrow_color));
|
||||
|
||||
final ViewOutlineProvider arrowOutlineProvider = new ViewOutlineProvider() {
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
outline.setPath(createArrowPath(view.getMeasuredHeight()));
|
||||
}
|
||||
};
|
||||
|
||||
initArrow(mArrowRight, arrowOutlineProvider, arrowDrawable, 0);
|
||||
initArrow(mArrowDown, arrowOutlineProvider, arrowDrawable, 90);
|
||||
initArrow(mArrowLeft, arrowOutlineProvider, arrowDrawable, 180);
|
||||
initArrow(mArrowUp, arrowOutlineProvider, arrowDrawable, 270);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Path for a movement arrow in the MODE_MOVE_MENU. The resulting Path is a simple
|
||||
* right-pointing triangle with its tip in the center of a size x size square:
|
||||
* _ _ _ _ _
|
||||
* |* |
|
||||
* |* * |
|
||||
* |* * |
|
||||
* |* * |
|
||||
* |* _ _ _ _|
|
||||
*
|
||||
*/
|
||||
private Path createArrowPath(int size) {
|
||||
final Path triangle = new Path();
|
||||
triangle.lineTo(0, size);
|
||||
triangle.lineTo(size / 2, size / 2);
|
||||
triangle.close();
|
||||
return triangle;
|
||||
}
|
||||
|
||||
private void initArrow(View v, ViewOutlineProvider arrowOutlineProvider, Drawable arrowDrawable,
|
||||
int rotation) {
|
||||
v.setOutlineProvider(arrowOutlineProvider);
|
||||
v.setBackground(arrowDrawable);
|
||||
v.setRotation(rotation);
|
||||
v.setElevation(mArrowElevation);
|
||||
}
|
||||
|
||||
void onPipTransitionToTargetBoundsStarted(Rect targetBounds) {
|
||||
if (targetBounds == null) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user