Merge "2D Recents: round task thumbnails properly." into nyc-mr2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
fb764b7035
@@ -15,5 +15,5 @@
|
|||||||
-->
|
-->
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<solid android:color="#61FFFFFF" />
|
<solid android:color="#61FFFFFF" />
|
||||||
<corners android:radius="8dp"/>
|
<corners android:radius="@dimen/recents_grid_task_view_rounded_corners_radius"/>
|
||||||
</shape>
|
</shape>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
<com.android.systemui.recents.views.TaskViewThumbnail
|
<com.android.systemui.recents.views.grid.GridTaskViewThumbnail
|
||||||
android:id="@+id/task_view_thumbnail"
|
android:id="@+id/task_view_thumbnail"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -22,5 +22,6 @@
|
|||||||
<dimen name="recents_grid_task_view_header_height">44dp</dimen>
|
<dimen name="recents_grid_task_view_header_height">44dp</dimen>
|
||||||
<dimen name="recents_grid_task_view_header_button_padding">8dp</dimen>
|
<dimen name="recents_grid_task_view_header_button_padding">8dp</dimen>
|
||||||
<dimen name="recents_grid_task_view_focused_frame_thickness">8dp</dimen>
|
<dimen name="recents_grid_task_view_focused_frame_thickness">8dp</dimen>
|
||||||
|
<dimen name="recents_grid_task_view_rounded_corners_radius">8dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.recents.Recents;
|
||||||
import com.android.systemui.recents.RecentsConfiguration;
|
import com.android.systemui.recents.RecentsConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,8 +91,10 @@ class FakeShadowDrawable extends Drawable {
|
|||||||
mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
|
mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
|
||||||
mCornerShadowPaint.setStyle(Paint.Style.FILL);
|
mCornerShadowPaint.setStyle(Paint.Style.FILL);
|
||||||
mCornerShadowPaint.setDither(true);
|
mCornerShadowPaint.setDither(true);
|
||||||
mCornerRadius = resources.getDimensionPixelSize(
|
mCornerRadius = Recents.getConfiguration().isGridEnabled ?
|
||||||
R.dimen.recents_task_view_rounded_corners_radius);
|
resources.getDimensionPixelSize(
|
||||||
|
R.dimen.recents_grid_task_view_rounded_corners_radius) :
|
||||||
|
resources.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
|
||||||
mCardBounds = new RectF();
|
mCardBounds = new RectF();
|
||||||
mEdgeShadowPaint = new Paint(mCornerShadowPaint);
|
mEdgeShadowPaint = new Paint(mCornerShadowPaint);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,8 +266,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
|
mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
|
||||||
mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
|
mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
|
||||||
mAnimationHelper = new TaskStackAnimationHelper(context, this);
|
mAnimationHelper = new TaskStackAnimationHelper(context, this);
|
||||||
mTaskCornerRadiusPx = res.getDimensionPixelSize(
|
mTaskCornerRadiusPx = Recents.getConfiguration().isGridEnabled ?
|
||||||
R.dimen.recents_task_view_rounded_corners_radius);
|
res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) :
|
||||||
|
res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
|
||||||
mDividerSize = ssp.getDockedDividerSize(context);
|
mDividerSize = ssp.getDockedDividerSize(context);
|
||||||
mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
|
mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
|
||||||
mDisplayRect = ssp.getDisplayRect();
|
mDisplayRect = ssp.getDisplayRect();
|
||||||
|
|||||||
@@ -201,7 +201,9 @@ public class TaskViewHeader extends FrameLayout
|
|||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
|
mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
|
||||||
mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
|
mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
|
||||||
mCornerRadius = res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
|
mCornerRadius = Recents.getConfiguration().isGridEnabled ?
|
||||||
|
res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) :
|
||||||
|
res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
|
||||||
mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
|
mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
|
||||||
mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
|
mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
|
||||||
mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
|
mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ public class TaskViewThumbnail extends View {
|
|||||||
|
|
||||||
// Drawing
|
// Drawing
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
private Rect mTaskViewRect = new Rect();
|
protected Rect mTaskViewRect = new Rect();
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
private Rect mThumbnailRect = new Rect();
|
protected Rect mThumbnailRect = new Rect();
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
private float mThumbnailScale;
|
protected float mThumbnailScale;
|
||||||
private float mFullscreenThumbnailScale;
|
private float mFullscreenThumbnailScale;
|
||||||
/** The height, in pixels, of the task view's title bar. */
|
/** The height, in pixels, of the task view's title bar. */
|
||||||
private int mTitleBarHeight;
|
private int mTitleBarHeight;
|
||||||
@@ -70,13 +70,13 @@ public class TaskViewThumbnail extends View {
|
|||||||
private boolean mOverlayHeaderOnThumbnailActionBar = true;
|
private boolean mOverlayHeaderOnThumbnailActionBar = true;
|
||||||
private ActivityManager.TaskThumbnailInfo mThumbnailInfo;
|
private ActivityManager.TaskThumbnailInfo mThumbnailInfo;
|
||||||
|
|
||||||
private int mCornerRadius;
|
protected int mCornerRadius;
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
private float mDimAlpha;
|
private float mDimAlpha;
|
||||||
private Matrix mScaleMatrix = new Matrix();
|
private Matrix mScaleMatrix = new Matrix();
|
||||||
private Paint mDrawPaint = new Paint();
|
protected Paint mDrawPaint = new Paint();
|
||||||
private Paint mBgFillPaint = new Paint();
|
protected Paint mBgFillPaint = new Paint();
|
||||||
private BitmapShader mBitmapShader;
|
protected BitmapShader mBitmapShader;
|
||||||
private LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0);
|
private LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0);
|
||||||
|
|
||||||
// Clip the top of the thumbnail against the opaque header bar that overlaps this view
|
// Clip the top of the thumbnail against the opaque header bar that overlaps this view
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.systemui.recents.views.grid;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.recents.views.TaskViewThumbnail;
|
||||||
|
|
||||||
|
public class GridTaskViewThumbnail extends TaskViewThumbnail {
|
||||||
|
|
||||||
|
private Path mThumbnailOutline;
|
||||||
|
private Path mRestBackgroundOutline;
|
||||||
|
private Path mFullBackgroundOutline;
|
||||||
|
// True if either this view's size or thumbnail scale has changed and mThumbnailOutline should
|
||||||
|
// be updated.
|
||||||
|
private boolean mUpdateThumbnailOutline = true;
|
||||||
|
|
||||||
|
public GridTaskViewThumbnail(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridTaskViewThumbnail(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridTaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
this(context, attrs, defStyleAttr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridTaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr,
|
||||||
|
int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
mCornerRadius = getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.recents_grid_task_view_rounded_corners_radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the task view frame changes, allowing us to move the contents of the header
|
||||||
|
* to match the frame changes.
|
||||||
|
*/
|
||||||
|
public void onTaskViewSizeChanged(int width, int height) {
|
||||||
|
mUpdateThumbnailOutline = true;
|
||||||
|
super.onTaskViewSizeChanged(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the scale of the bitmap relative to this view.
|
||||||
|
*/
|
||||||
|
public void updateThumbnailScale() {
|
||||||
|
mUpdateThumbnailOutline = true;
|
||||||
|
super.updateThumbnailScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateThumbnailOutline() {
|
||||||
|
final int titleHeight = getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.recents_grid_task_view_header_height);
|
||||||
|
final int viewWidth = mTaskViewRect.width();
|
||||||
|
final int viewHeight = mTaskViewRect.height() - titleHeight;
|
||||||
|
final int thumbnailWidth = Math.min(viewWidth,
|
||||||
|
(int) (mThumbnailRect.width() * mThumbnailScale));
|
||||||
|
final int thumbnailHeight = Math.min(viewHeight,
|
||||||
|
(int) (mThumbnailRect.height() * mThumbnailScale));
|
||||||
|
// Draw the thumbnail, we only round the bottom corners:
|
||||||
|
//
|
||||||
|
// outerLeft outerRight
|
||||||
|
// <-----------------------> mRestBackgroundOutline
|
||||||
|
// _________________________ (thumbnailWidth < viewWidth)
|
||||||
|
// |_______________________| outerTop A ____ B
|
||||||
|
// | | ↑ | |
|
||||||
|
// | | | | |
|
||||||
|
// | | | | |
|
||||||
|
// | | | | | C
|
||||||
|
// \_______________________/ ↓ |__/
|
||||||
|
// mCornerRadius outerBottom E D
|
||||||
|
//
|
||||||
|
// mRestBackgroundOutline (thumbnailHeight < viewHeight)
|
||||||
|
// A _________________________ B
|
||||||
|
// | | C
|
||||||
|
// F \_______________________/
|
||||||
|
// E D
|
||||||
|
final int outerLeft = 0;
|
||||||
|
final int outerTop = 0;
|
||||||
|
final int outerRight = outerLeft + thumbnailWidth;
|
||||||
|
final int outerBottom = outerTop + thumbnailHeight;
|
||||||
|
mThumbnailOutline = new Path();
|
||||||
|
mThumbnailOutline.moveTo(outerLeft, outerTop);
|
||||||
|
mThumbnailOutline.lineTo(outerRight, outerTop);
|
||||||
|
mThumbnailOutline.lineTo(outerRight, outerBottom - mCornerRadius);
|
||||||
|
mThumbnailOutline.arcTo(outerRight - 2 * mCornerRadius, outerBottom - 2 * mCornerRadius,
|
||||||
|
outerRight, outerBottom, 0, 90, false);
|
||||||
|
mThumbnailOutline.lineTo(outerLeft + mCornerRadius, outerBottom);
|
||||||
|
mThumbnailOutline.arcTo(outerLeft, outerBottom - 2 * mCornerRadius,
|
||||||
|
outerLeft + 2 * mCornerRadius, outerBottom, 90, 90, false);
|
||||||
|
mThumbnailOutline.lineTo(outerLeft, outerTop);
|
||||||
|
mThumbnailOutline.close();
|
||||||
|
|
||||||
|
if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
|
||||||
|
if (thumbnailWidth < viewWidth) {
|
||||||
|
final int l = Math.max(0, outerRight - mCornerRadius);
|
||||||
|
final int r = outerRight;
|
||||||
|
final int t = outerTop;
|
||||||
|
final int b = outerBottom;
|
||||||
|
mRestBackgroundOutline = new Path();
|
||||||
|
mRestBackgroundOutline.moveTo(l, t); // A
|
||||||
|
mRestBackgroundOutline.lineTo(r, t); // B
|
||||||
|
mRestBackgroundOutline.lineTo(r, b - mCornerRadius); // C
|
||||||
|
mRestBackgroundOutline.arcTo(r - 2 * mCornerRadius, b - 2 * mCornerRadius, r, b,
|
||||||
|
0, 90, false); // D
|
||||||
|
mRestBackgroundOutline.lineTo(l, b); // E
|
||||||
|
mRestBackgroundOutline.lineTo(l, t); // A
|
||||||
|
mRestBackgroundOutline.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
if (thumbnailHeight < viewHeight) {
|
||||||
|
final int l = outerLeft;
|
||||||
|
final int r = outerRight;
|
||||||
|
final int t = Math.max(0, thumbnailHeight - mCornerRadius);
|
||||||
|
final int b = outerBottom;
|
||||||
|
mRestBackgroundOutline = new Path();
|
||||||
|
mRestBackgroundOutline.moveTo(l, t); // A
|
||||||
|
mRestBackgroundOutline.lineTo(r, t); // B
|
||||||
|
mRestBackgroundOutline.lineTo(r, b - mCornerRadius); // C
|
||||||
|
mRestBackgroundOutline.arcTo(r - 2 * mCornerRadius, b - 2 * mCornerRadius, r, b,
|
||||||
|
0, 90, false); // D
|
||||||
|
mRestBackgroundOutline.lineTo(l + mCornerRadius, b); // E
|
||||||
|
mRestBackgroundOutline.arcTo(l, b - 2 * mCornerRadius, l + 2 * mCornerRadius, b,
|
||||||
|
90, 90, false); // F
|
||||||
|
mRestBackgroundOutline.lineTo(l, t); // A
|
||||||
|
mRestBackgroundOutline.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mFullBackgroundOutline = mThumbnailOutline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
final int titleHeight = getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.recents_grid_task_view_header_height);
|
||||||
|
final int viewWidth = mTaskViewRect.width();
|
||||||
|
final int viewHeight = mTaskViewRect.height() - titleHeight;
|
||||||
|
final int thumbnailWidth = Math.min(viewWidth,
|
||||||
|
(int) (mThumbnailRect.width() * mThumbnailScale));
|
||||||
|
final int thumbnailHeight = Math.min(viewHeight,
|
||||||
|
(int) (mThumbnailRect.height() * mThumbnailScale));
|
||||||
|
|
||||||
|
if (mUpdateThumbnailOutline) {
|
||||||
|
updateThumbnailOutline();
|
||||||
|
mUpdateThumbnailOutline = false;
|
||||||
|
}
|
||||||
|
if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
|
||||||
|
// Draw the background, there will be some small overdraw with the thumbnail
|
||||||
|
if (thumbnailWidth < viewWidth) {
|
||||||
|
// Portrait thumbnail on a landscape task view
|
||||||
|
canvas.drawPath(mRestBackgroundOutline, mBgFillPaint);
|
||||||
|
}
|
||||||
|
if (thumbnailHeight < viewHeight) {
|
||||||
|
// Landscape thumbnail on a portrait task view
|
||||||
|
canvas.drawPath(mRestBackgroundOutline, mBgFillPaint);
|
||||||
|
}
|
||||||
|
canvas.drawPath(mThumbnailOutline, mDrawPaint);
|
||||||
|
} else {
|
||||||
|
canvas.drawPath(mFullBackgroundOutline, mBgFillPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,11 +105,13 @@ public class TaskGridLayoutAlgorithm {
|
|||||||
if (maxTaskHeight >= maxTaskWidth / mAppAspectRatio + mTitleBarHeight) {
|
if (maxTaskHeight >= maxTaskWidth / mAppAspectRatio + mTitleBarHeight) {
|
||||||
// Width bound.
|
// Width bound.
|
||||||
taskWidth = maxTaskWidth;
|
taskWidth = maxTaskWidth;
|
||||||
taskHeight = (int) (maxTaskWidth / mAppAspectRatio + mTitleBarHeight);
|
// Here we should round the height to the nearest integer.
|
||||||
|
taskHeight = (int) (maxTaskWidth / mAppAspectRatio + mTitleBarHeight + 0.5);
|
||||||
} else {
|
} else {
|
||||||
// Height bound.
|
// Height bound.
|
||||||
taskHeight = maxTaskHeight;
|
taskHeight = maxTaskHeight;
|
||||||
taskWidth = (int) ((taskHeight - mTitleBarHeight) * mAppAspectRatio);
|
// Here we should round the width to the nearest integer.
|
||||||
|
taskWidth = (int) ((taskHeight - mTitleBarHeight) * mAppAspectRatio + 0.5);
|
||||||
}
|
}
|
||||||
size.set(0, 0, taskWidth, taskHeight);
|
size.set(0, 0, taskWidth, taskHeight);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user