DO NOT MERGE - Port 2D recents implementation from master to nyc-mr2
am: bf8e290376
Change-Id: I7b05418dc2d03da33e862cf67dbcd1d08cb1b899
This commit is contained in:
35
packages/SystemUI/res/layout/recents_grid_task_view.xml
Normal file
35
packages/SystemUI/res/layout/recents_grid_task_view.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2016 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.
|
||||||
|
-->
|
||||||
|
<com.android.systemui.recents.views.grid.GridTaskView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:focusable="true">
|
||||||
|
<com.android.systemui.recents.views.TaskViewThumbnail
|
||||||
|
android:id="@+id/task_view_thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<include layout="@layout/recents_task_view_header" />
|
||||||
|
|
||||||
|
<!-- TODO: Move this into a view stub -->
|
||||||
|
<include layout="@layout/recents_task_view_lock_to_app"/>
|
||||||
|
|
||||||
|
<!-- The incompatible app toast -->
|
||||||
|
<include layout="@layout/recents_task_view_incompatible_app_toast"/>
|
||||||
|
</com.android.systemui.recents.views.grid.GridTaskView>
|
||||||
|
|
||||||
|
|
||||||
@@ -26,35 +26,10 @@
|
|||||||
<include layout="@layout/recents_task_view_header" />
|
<include layout="@layout/recents_task_view_header" />
|
||||||
|
|
||||||
<!-- TODO: Move this into a view stub -->
|
<!-- TODO: Move this into a view stub -->
|
||||||
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
|
<include layout="@layout/recents_task_view_lock_to_app"/>
|
||||||
android:id="@+id/lock_to_app_fab"
|
|
||||||
android:layout_width="@dimen/recents_lock_to_app_size"
|
|
||||||
android:layout_height="@dimen/recents_lock_to_app_size"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:layout_marginEnd="15dp"
|
|
||||||
android:layout_marginBottom="15dp"
|
|
||||||
android:translationZ="4dp"
|
|
||||||
android:contentDescription="@string/recents_lock_to_app_button_label"
|
|
||||||
android:background="@drawable/recents_lock_to_task_button_bg"
|
|
||||||
android:visibility="invisible"
|
|
||||||
android:alpha="0">
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/recents_lock_to_app_icon_size"
|
|
||||||
android:layout_height="@dimen/recents_lock_to_app_icon_size"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:src="@drawable/recents_lock_to_app_pin" />
|
|
||||||
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
|
|
||||||
|
|
||||||
<!-- The incompatible app toast -->
|
<!-- The incompatible app toast -->
|
||||||
<ViewStub android:id="@+id/incompatible_app_toast_stub"
|
<include layout="@layout/recents_task_view_incompatible_app_toast"/>
|
||||||
android:inflatedId="@+id/incompatible_app_toast"
|
|
||||||
android:layout="@*android:layout/transient_notification"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="top|center_horizontal"
|
|
||||||
android:layout_marginTop="48dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp" />
|
|
||||||
</com.android.systemui.recents.views.TaskView>
|
</com.android.systemui.recents.views.TaskView>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2016 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.
|
||||||
|
-->
|
||||||
|
<ViewStub
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/incompatible_app_toast_stub"
|
||||||
|
android:inflatedId="@+id/incompatible_app_toast"
|
||||||
|
android:layout="@*android:layout/transient_notification"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top|center_horizontal"
|
||||||
|
android:layout_marginTop="48dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp" />
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2016 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.
|
||||||
|
-->
|
||||||
|
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/lock_to_app_fab"
|
||||||
|
android:layout_width="@dimen/recents_lock_to_app_size"
|
||||||
|
android:layout_height="@dimen/recents_lock_to_app_size"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_marginEnd="15dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:translationZ="4dp"
|
||||||
|
android:contentDescription="@string/recents_lock_to_app_button_label"
|
||||||
|
android:background="@drawable/recents_lock_to_task_button_bg"
|
||||||
|
android:visibility="invisible"
|
||||||
|
android:alpha="0">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="@dimen/recents_lock_to_app_icon_size"
|
||||||
|
android:layout_height="@dimen/recents_lock_to_app_icon_size"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/recents_lock_to_app_pin" />
|
||||||
|
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
|
||||||
25
packages/SystemUI/res/values/dimens_grid.xml
Normal file
25
packages/SystemUI/res/values/dimens_grid.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
* Copyright (c) 2016, 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<dimen name="recents_grid_padding_left_right">32dp</dimen>
|
||||||
|
<dimen name="recents_grid_padding_top_bottom">150dp</dimen>
|
||||||
|
<dimen name="recents_grid_padding_task_view">20dp</dimen>
|
||||||
|
<dimen name="recents_grid_task_view_header_height">44dp</dimen>
|
||||||
|
<dimen name="recents_grid_task_view_header_button_padding">8dp</dimen>
|
||||||
|
</resources>
|
||||||
|
|
||||||
@@ -207,8 +207,6 @@ public class Recents extends SystemUI
|
|||||||
getSystemService(Context.UI_MODE_SERVICE);
|
getSystemService(Context.UI_MODE_SERVICE);
|
||||||
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
|
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
|
||||||
mImpl = new RecentsTvImpl(mContext);
|
mImpl = new RecentsTvImpl(mContext);
|
||||||
} else if (SystemProperties.getBoolean("ro.recents.grid", false) == true) {
|
|
||||||
mImpl = new RecentsGridImpl(mContext);
|
|
||||||
} else {
|
} else {
|
||||||
mImpl = new RecentsImpl(mContext);
|
mImpl = new RecentsImpl(mContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.content.Context;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
import android.os.SystemProperties;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||||
|
|
||||||
@@ -58,6 +59,10 @@ public class RecentsConfiguration {
|
|||||||
public boolean fakeShadows;
|
public boolean fakeShadows;
|
||||||
public int svelteLevel;
|
public int svelteLevel;
|
||||||
|
|
||||||
|
// Whether this product supports Grid-based Recents. If this is field is set to true, then
|
||||||
|
// Recents will layout task views in a grid mode when there's enough space in the screen.
|
||||||
|
public boolean isGridEnabled;
|
||||||
|
|
||||||
public RecentsConfiguration(Context context) {
|
public RecentsConfiguration(Context context) {
|
||||||
// Load only resources that can not change after the first load either through developer
|
// Load only resources that can not change after the first load either through developer
|
||||||
// settings or via multi window
|
// settings or via multi window
|
||||||
@@ -66,6 +71,7 @@ public class RecentsConfiguration {
|
|||||||
Resources res = appContext.getResources();
|
Resources res = appContext.getResources();
|
||||||
fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows);
|
fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows);
|
||||||
svelteLevel = res.getInteger(R.integer.recents_svelte_level);
|
svelteLevel = res.getInteger(R.integer.recents_svelte_level);
|
||||||
|
isGridEnabled = SystemProperties.getBoolean("ro.recents.grid", false);
|
||||||
|
|
||||||
float screenDensity = context.getResources().getDisplayMetrics().density;
|
float screenDensity = context.getResources().getDisplayMetrics().density;
|
||||||
smallestWidth = ssp.getDeviceSmallestWidth();
|
smallestWidth = ssp.getDeviceSmallestWidth();
|
||||||
|
|||||||
@@ -180,10 +180,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
|||||||
ssp.registerTaskStackListener(mTaskStackListener);
|
ssp.registerTaskStackListener(mTaskStackListener);
|
||||||
|
|
||||||
// Initialize the static configuration resources
|
// Initialize the static configuration resources
|
||||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
|
||||||
mDummyStackView = new TaskStackView(mContext);
|
mDummyStackView = new TaskStackView(mContext);
|
||||||
mHeaderBar = (TaskViewHeader) inflater.inflate(R.layout.recents_task_view_header,
|
|
||||||
null, false);
|
|
||||||
reloadResources();
|
reloadResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,14 +201,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
|||||||
Resources res = mContext.getResources();
|
Resources res = mContext.getResources();
|
||||||
reloadResources();
|
reloadResources();
|
||||||
mDummyStackView.reloadOnConfigurationChange();
|
mDummyStackView.reloadOnConfigurationChange();
|
||||||
// Update the header bar direction directly as it is not attached to anything and does not
|
|
||||||
// layout except in updateHeaderBarLayout()
|
|
||||||
mHeaderBar.setLayoutDirection(res.getConfiguration().getLayoutDirection());
|
|
||||||
mHeaderBar.onConfigurationChanged();
|
|
||||||
mHeaderBar.forceLayout();
|
|
||||||
mHeaderBar.measure(
|
|
||||||
MeasureSpec.makeMeasureSpec(mHeaderBar.getMeasuredWidth(), MeasureSpec.EXACTLY),
|
|
||||||
MeasureSpec.makeMeasureSpec(mHeaderBar.getMeasuredHeight(), MeasureSpec.EXACTLY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -582,7 +571,13 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
|||||||
R.dimen.recents_task_view_header_height,
|
R.dimen.recents_task_view_header_height,
|
||||||
R.dimen.recents_task_view_header_height_tablet_land,
|
R.dimen.recents_task_view_header_height_tablet_land,
|
||||||
R.dimen.recents_task_view_header_height,
|
R.dimen.recents_task_view_header_height,
|
||||||
R.dimen.recents_task_view_header_height_tablet_land);
|
R.dimen.recents_task_view_header_height_tablet_land,
|
||||||
|
R.dimen.recents_grid_task_view_header_height);
|
||||||
|
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||||
|
mHeaderBar = (TaskViewHeader) inflater.inflate(R.layout.recents_task_view_header,
|
||||||
|
null, false);
|
||||||
|
mHeaderBar.setLayoutDirection(res.getConfiguration().getLayoutDirection());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -721,7 +716,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
|||||||
if (task.isFreeformTask()) {
|
if (task.isFreeformTask()) {
|
||||||
mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
|
mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
|
||||||
stackScroller.getStackScroll(), mTmpTransform, null,
|
stackScroller.getStackScroll(), mTmpTransform, null,
|
||||||
windowOverrideRect);
|
windowOverrideRect, false /* useGridLayout */);
|
||||||
Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform,
|
Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform,
|
||||||
mThumbTransitionBitmapCache);
|
mThumbTransitionBitmapCache);
|
||||||
Rect toTaskRect = new Rect();
|
Rect toTaskRect = new Rect();
|
||||||
@@ -771,7 +766,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
|||||||
stackView.updateLayoutAlgorithm(true /* boundScroll */);
|
stackView.updateLayoutAlgorithm(true /* boundScroll */);
|
||||||
stackView.updateToInitialState();
|
stackView.updateToInitialState();
|
||||||
stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
|
stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
|
||||||
stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect);
|
stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect,
|
||||||
|
Recents.getConfiguration().isGridEnabled);
|
||||||
return mTmpTransform;
|
return mTmpTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,14 +79,15 @@ public class Utilities {
|
|||||||
public static final Rect EMPTY_RECT = new Rect();
|
public static final Rect EMPTY_RECT = new Rect();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the first parent walking up the view hierarchy that has the given class type.
|
* @return the first parent walking up the view hierarchy that has the given class type (or
|
||||||
|
* a subclass).
|
||||||
*
|
*
|
||||||
* @param parentClass must be a class derived from {@link View}
|
* @param parentClass must be a class derived from {@link View}
|
||||||
*/
|
*/
|
||||||
public static <T extends View> T findParent(View v, Class<T> parentClass) {
|
public static <T extends View> T findParent(View v, Class<T> parentClass) {
|
||||||
ViewParent parent = v.getParent();
|
ViewParent parent = v.getParent();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
if (parent.getClass().equals(parentClass)) {
|
if (parentClass.isAssignableFrom(parent.getClass())) {
|
||||||
return (T) parent;
|
return (T) parent;
|
||||||
}
|
}
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
|
|||||||
@@ -849,6 +849,24 @@ public class TaskStack {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the task in stack tasks which should be launched next if Recents are toggled
|
||||||
|
* again, or null if there is no task to be launched.
|
||||||
|
*/
|
||||||
|
public Task getNextLaunchTarget() {
|
||||||
|
int taskCount = getTaskCount();
|
||||||
|
if (taskCount == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int launchTaskIndex = indexOfStackTask(getLaunchTarget());
|
||||||
|
if (launchTaskIndex != -1) {
|
||||||
|
launchTaskIndex = Math.max(0, launchTaskIndex - 1);
|
||||||
|
} else {
|
||||||
|
launchTaskIndex = getTaskCount() - 1;
|
||||||
|
}
|
||||||
|
return getStackTasks().get(launchTaskIndex);
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the index of this task in this current task stack */
|
/** Returns the index of this task in this current task stack */
|
||||||
public int indexOfStackTask(Task t) {
|
public int indexOfStackTask(Task t) {
|
||||||
return mStackTaskList.indexOf(t);
|
return mStackTaskList.indexOf(t);
|
||||||
|
|||||||
@@ -30,17 +30,17 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
|
|||||||
private static final float MIN_ALPHA = 0.1f;
|
private static final float MIN_ALPHA = 0.1f;
|
||||||
private static final float MAX_ALPHA = 0.8f;
|
private static final float MAX_ALPHA = 0.8f;
|
||||||
|
|
||||||
View mSourceView;
|
protected View mSourceView;
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
Rect mClipRect = new Rect();
|
protected Rect mClipRect = new Rect();
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
Rect mClipBounds = new Rect();
|
protected Rect mClipBounds = new Rect();
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
Rect mLastClipBounds = new Rect();
|
protected Rect mLastClipBounds = new Rect();
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
int mCornerRadius;
|
protected int mCornerRadius;
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
float mAlpha = 1f;
|
protected float mAlpha = 1f;
|
||||||
|
|
||||||
public AnimateableViewBounds(View source, int cornerRadius) {
|
public AnimateableViewBounds(View source, int cornerRadius) {
|
||||||
mSourceView = source;
|
mSourceView = source;
|
||||||
@@ -110,7 +110,7 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
|
|||||||
return mClipRect.bottom;
|
return mClipRect.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateClipBounds() {
|
protected void updateClipBounds() {
|
||||||
mClipBounds.set(Math.max(0, mClipRect.left), Math.max(0, mClipRect.top),
|
mClipBounds.set(Math.max(0, mClipRect.left), Math.max(0, mClipRect.top),
|
||||||
mSourceView.getWidth() - Math.max(0, mClipRect.right),
|
mSourceView.getWidth() - Math.max(0, mClipRect.right),
|
||||||
mSourceView.getHeight() - Math.max(0, mClipRect.bottom));
|
mSourceView.getHeight() - Math.max(0, mClipRect.bottom));
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ public class RecentsView extends FrameLayout {
|
|||||||
private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 134;
|
private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 134;
|
||||||
private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
|
private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
|
||||||
|
|
||||||
private TaskStack mStack;
|
|
||||||
private TaskStackView mTaskStackView;
|
private TaskStackView mTaskStackView;
|
||||||
private TextView mStackActionButton;
|
private TextView mStackActionButton;
|
||||||
private TextView mEmptyView;
|
private TextView mEmptyView;
|
||||||
@@ -195,7 +194,6 @@ public class RecentsView extends FrameLayout {
|
|||||||
* Called from RecentsActivity when the task stack is updated.
|
* Called from RecentsActivity when the task stack is updated.
|
||||||
*/
|
*/
|
||||||
public void updateStack(TaskStack stack, boolean setStackViewTasks) {
|
public void updateStack(TaskStack stack, boolean setStackViewTasks) {
|
||||||
mStack = stack;
|
|
||||||
if (setStackViewTasks) {
|
if (setStackViewTasks) {
|
||||||
mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
|
mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
|
||||||
}
|
}
|
||||||
@@ -212,7 +210,7 @@ public class RecentsView extends FrameLayout {
|
|||||||
* Returns the current TaskStack.
|
* Returns the current TaskStack.
|
||||||
*/
|
*/
|
||||||
public TaskStack getStack() {
|
public TaskStack getStack() {
|
||||||
return mStack;
|
return mTaskStackView.getStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -251,8 +249,7 @@ public class RecentsView extends FrameLayout {
|
|||||||
/** Launches the task that recents was launched from if possible */
|
/** Launches the task that recents was launched from if possible */
|
||||||
public boolean launchPreviousTask() {
|
public boolean launchPreviousTask() {
|
||||||
if (mTaskStackView != null) {
|
if (mTaskStackView != null) {
|
||||||
TaskStack stack = mTaskStackView.getStack();
|
Task task = getStack().getLaunchTarget();
|
||||||
Task task = stack.getLaunchTarget();
|
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
TaskView taskView = mTaskStackView.getChildViewForTask(task);
|
TaskView taskView = mTaskStackView.getChildViewForTask(task);
|
||||||
EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null,
|
EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null,
|
||||||
@@ -340,7 +337,8 @@ public class RecentsView extends FrameLayout {
|
|||||||
|
|
||||||
if (RecentsDebugFlags.Static.EnableStackActionButton) {
|
if (RecentsDebugFlags.Static.EnableStackActionButton) {
|
||||||
// Measure the stack action button within the constraints of the space above the stack
|
// Measure the stack action button within the constraints of the space above the stack
|
||||||
Rect buttonBounds = mTaskStackView.mLayoutAlgorithm.mStackActionButtonRect;
|
Rect buttonBounds = mTaskStackView.mLayoutAlgorithm.getStackActionButtonRect(
|
||||||
|
mTaskStackView.useGridLayout());
|
||||||
measureChild(mStackActionButton,
|
measureChild(mStackActionButton,
|
||||||
MeasureSpec.makeMeasureSpec(buttonBounds.width(), MeasureSpec.AT_MOST),
|
MeasureSpec.makeMeasureSpec(buttonBounds.width(), MeasureSpec.AT_MOST),
|
||||||
MeasureSpec.makeMeasureSpec(buttonBounds.height(), MeasureSpec.AT_MOST));
|
MeasureSpec.makeMeasureSpec(buttonBounds.height(), MeasureSpec.AT_MOST));
|
||||||
@@ -437,8 +435,9 @@ public class RecentsView extends FrameLayout {
|
|||||||
|
|
||||||
public final void onBusEvent(LaunchTaskEvent event) {
|
public final void onBusEvent(LaunchTaskEvent event) {
|
||||||
mLastTaskLaunchedWasFreeform = event.task.isFreeformTask();
|
mLastTaskLaunchedWasFreeform = event.task.isFreeformTask();
|
||||||
mTransitionHelper.launchTaskFromRecents(mStack, event.task, mTaskStackView, event.taskView,
|
mTransitionHelper.launchTaskFromRecents(getStack(), event.task, mTaskStackView,
|
||||||
event.screenPinningRequested, event.targetTaskBounds, event.targetTaskStack);
|
event.taskView, event.screenPinningRequested, event.targetTaskBounds,
|
||||||
|
event.targetTaskStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
|
public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
|
||||||
@@ -514,8 +513,7 @@ public class RecentsView extends FrameLayout {
|
|||||||
EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
|
EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
|
||||||
// Remove the task and don't bother relaying out, as all the tasks will be
|
// Remove the task and don't bother relaying out, as all the tasks will be
|
||||||
// relaid out when the stack changes on the multiwindow change event
|
// relaid out when the stack changes on the multiwindow change event
|
||||||
mTaskStackView.getStack().removeTask(event.task, null,
|
getStack().removeTask(event.task, null, true /* fromDockGesture */);
|
||||||
true /* fromDockGesture */);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -536,7 +534,7 @@ public class RecentsView extends FrameLayout {
|
|||||||
MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
|
MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
|
||||||
event.task.getTopComponent().flattenToShortString());
|
event.task.getTopComponent().flattenToShortString());
|
||||||
} else {
|
} else {
|
||||||
EventBus.getDefault().send(new DragEndCancelledEvent(mStack, event.task,
|
EventBus.getDefault().send(new DragEndCancelledEvent(getStack(), event.task,
|
||||||
event.taskView));
|
event.taskView));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -598,7 +596,7 @@ public class RecentsView extends FrameLayout {
|
|||||||
public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
|
public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
|
||||||
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
|
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
|
||||||
if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
|
if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
|
||||||
&& mStack.getTaskCount() > 0) {
|
&& getStack().getTaskCount() > 0) {
|
||||||
animateBackgroundScrim(1f,
|
animateBackgroundScrim(1f,
|
||||||
TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
|
TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
|
||||||
}
|
}
|
||||||
@@ -775,7 +773,8 @@ public class RecentsView extends FrameLayout {
|
|||||||
* @return the bounds of the stack action button.
|
* @return the bounds of the stack action button.
|
||||||
*/
|
*/
|
||||||
private Rect getStackActionButtonBoundsFromStackLayout() {
|
private Rect getStackActionButtonBoundsFromStackLayout() {
|
||||||
Rect actionButtonRect = new Rect(mTaskStackView.mLayoutAlgorithm.mStackActionButtonRect);
|
Rect actionButtonRect = new Rect(mTaskStackView.mLayoutAlgorithm.getStackActionButtonRect(
|
||||||
|
mTaskStackView.useGridLayout()));
|
||||||
int left = isLayoutRtl()
|
int left = isLayoutRtl()
|
||||||
? actionButtonRect.left - mStackActionButton.getPaddingLeft()
|
? actionButtonRect.left - mStackActionButton.getPaddingLeft()
|
||||||
: actionButtonRect.right + mStackActionButton.getPaddingRight()
|
: actionButtonRect.right + mStackActionButton.getPaddingRight()
|
||||||
@@ -797,8 +796,8 @@ public class RecentsView extends FrameLayout {
|
|||||||
writer.print(" [0x"); writer.print(id); writer.print("]");
|
writer.print(" [0x"); writer.print(id); writer.print("]");
|
||||||
writer.println();
|
writer.println();
|
||||||
|
|
||||||
if (mStack != null) {
|
if (getStack() != null) {
|
||||||
mStack.dump(innerPrefix, writer);
|
getStack().dump(innerPrefix, writer);
|
||||||
}
|
}
|
||||||
if (mTaskStackView != null) {
|
if (mTaskStackView != null) {
|
||||||
mTaskStackView.dump(innerPrefix, writer);
|
mTaskStackView.dump(innerPrefix, writer);
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ public class TaskStackAnimationHelper {
|
|||||||
|
|
||||||
// Get the current transform for the task, which will be used to position it offscreen
|
// Get the current transform for the task, which will be used to position it offscreen
|
||||||
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
|
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
|
||||||
null);
|
null, mStackView.useGridLayout());
|
||||||
|
|
||||||
if (hideTask) {
|
if (hideTask) {
|
||||||
tv.setVisibility(View.INVISIBLE);
|
tv.setVisibility(View.INVISIBLE);
|
||||||
@@ -230,7 +230,7 @@ public class TaskStackAnimationHelper {
|
|||||||
// Get the current transform for the task, which will be updated to the final transform
|
// Get the current transform for the task, which will be updated to the final transform
|
||||||
// to animate to depending on how recents was invoked
|
// to animate to depending on how recents was invoked
|
||||||
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
|
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
|
||||||
null);
|
null, mStackView.useGridLayout());
|
||||||
|
|
||||||
if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
|
if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
|
||||||
if (task.isLaunchTarget) {
|
if (task.isLaunchTarget) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import com.android.systemui.recents.misc.SystemServicesProxy;
|
|||||||
import com.android.systemui.recents.misc.Utilities;
|
import com.android.systemui.recents.misc.Utilities;
|
||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
|
import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@@ -240,14 +241,14 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
// This is the current system insets
|
// This is the current system insets
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
public Rect mSystemInsets = new Rect();
|
public Rect mSystemInsets = new Rect();
|
||||||
// This is the bounds of the stack action above the stack rect
|
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
|
||||||
public Rect mStackActionButtonRect = new Rect();
|
|
||||||
|
|
||||||
// The visible ranges when the stack is focused and unfocused
|
// The visible ranges when the stack is focused and unfocused
|
||||||
private Range mUnfocusedRange;
|
private Range mUnfocusedRange;
|
||||||
private Range mFocusedRange;
|
private Range mFocusedRange;
|
||||||
|
|
||||||
|
// This is the bounds of the stack action above the stack rect
|
||||||
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
|
private Rect mStackActionButtonRect = new Rect();
|
||||||
// The base top margin for the stack from the system insets
|
// The base top margin for the stack from the system insets
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
private int mBaseTopMargin;
|
private int mBaseTopMargin;
|
||||||
@@ -326,7 +327,7 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
int mMinTranslationZ;
|
int mMinTranslationZ;
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
int mMaxTranslationZ;
|
public int mMaxTranslationZ;
|
||||||
|
|
||||||
// Optimization, allows for quick lookup of task -> index
|
// Optimization, allows for quick lookup of task -> index
|
||||||
private SparseIntArray mTaskIndexMap = new SparseIntArray();
|
private SparseIntArray mTaskIndexMap = new SparseIntArray();
|
||||||
@@ -334,6 +335,7 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
|
|
||||||
// The freeform workspace layout
|
// The freeform workspace layout
|
||||||
FreeformWorkspaceLayoutAlgorithm mFreeformLayoutAlgorithm;
|
FreeformWorkspaceLayoutAlgorithm mFreeformLayoutAlgorithm;
|
||||||
|
TaskGridLayoutAlgorithm mTaskGridLayoutAlgorithm;
|
||||||
|
|
||||||
// The transform to place TaskViews at the front and back of the stack respectively
|
// The transform to place TaskViews at the front and back of the stack respectively
|
||||||
TaskViewTransform mBackOfStackTransform = new TaskViewTransform();
|
TaskViewTransform mBackOfStackTransform = new TaskViewTransform();
|
||||||
@@ -344,19 +346,7 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
mContext = context;
|
mContext = context;
|
||||||
mCb = cb;
|
mCb = cb;
|
||||||
mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
|
mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
|
||||||
mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
|
mTaskGridLayoutAlgorithm = new TaskGridLayoutAlgorithm(context);
|
||||||
mBaseTopMargin = getDimensionForDevice(context,
|
|
||||||
R.dimen.recents_layout_top_margin_phone,
|
|
||||||
R.dimen.recents_layout_top_margin_tablet,
|
|
||||||
R.dimen.recents_layout_top_margin_tablet_xlarge);
|
|
||||||
mBaseSideMargin = getDimensionForDevice(context,
|
|
||||||
R.dimen.recents_layout_side_margin_phone,
|
|
||||||
R.dimen.recents_layout_side_margin_tablet,
|
|
||||||
R.dimen.recents_layout_side_margin_tablet_xlarge);
|
|
||||||
mBaseBottomMargin = res.getDimensionPixelSize(R.dimen.recents_layout_bottom_margin);
|
|
||||||
mFreeformStackGap =
|
|
||||||
res.getDimensionPixelSize(R.dimen.recents_freeform_layout_bottom_margin);
|
|
||||||
|
|
||||||
reloadOnConfigurationChange(context);
|
reloadOnConfigurationChange(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,6 +371,7 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
R.dimen.recents_layout_initial_top_offset_tablet,
|
R.dimen.recents_layout_initial_top_offset_tablet,
|
||||||
R.dimen.recents_layout_initial_top_offset_tablet,
|
R.dimen.recents_layout_initial_top_offset_tablet,
|
||||||
R.dimen.recents_layout_initial_top_offset_tablet,
|
R.dimen.recents_layout_initial_top_offset_tablet,
|
||||||
|
R.dimen.recents_layout_initial_top_offset_tablet,
|
||||||
R.dimen.recents_layout_initial_top_offset_tablet);
|
R.dimen.recents_layout_initial_top_offset_tablet);
|
||||||
mBaseInitialBottomOffset = getDimensionForDevice(context,
|
mBaseInitialBottomOffset = getDimensionForDevice(context,
|
||||||
R.dimen.recents_layout_initial_bottom_offset_phone_port,
|
R.dimen.recents_layout_initial_bottom_offset_phone_port,
|
||||||
@@ -388,8 +379,24 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
R.dimen.recents_layout_initial_bottom_offset_tablet,
|
R.dimen.recents_layout_initial_bottom_offset_tablet,
|
||||||
R.dimen.recents_layout_initial_bottom_offset_tablet,
|
R.dimen.recents_layout_initial_bottom_offset_tablet,
|
||||||
R.dimen.recents_layout_initial_bottom_offset_tablet,
|
R.dimen.recents_layout_initial_bottom_offset_tablet,
|
||||||
|
R.dimen.recents_layout_initial_bottom_offset_tablet,
|
||||||
R.dimen.recents_layout_initial_bottom_offset_tablet);
|
R.dimen.recents_layout_initial_bottom_offset_tablet);
|
||||||
mFreeformLayoutAlgorithm.reloadOnConfigurationChange(context);
|
mFreeformLayoutAlgorithm.reloadOnConfigurationChange(context);
|
||||||
|
mTaskGridLayoutAlgorithm.reloadOnConfigurationChange(context);
|
||||||
|
mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
|
||||||
|
mBaseTopMargin = getDimensionForDevice(context,
|
||||||
|
R.dimen.recents_layout_top_margin_phone,
|
||||||
|
R.dimen.recents_layout_top_margin_tablet,
|
||||||
|
R.dimen.recents_layout_top_margin_tablet_xlarge,
|
||||||
|
R.dimen.recents_layout_top_margin_tablet);
|
||||||
|
mBaseSideMargin = getDimensionForDevice(context,
|
||||||
|
R.dimen.recents_layout_side_margin_phone,
|
||||||
|
R.dimen.recents_layout_side_margin_tablet,
|
||||||
|
R.dimen.recents_layout_side_margin_tablet_xlarge,
|
||||||
|
R.dimen.recents_layout_side_margin_tablet);
|
||||||
|
mBaseBottomMargin = res.getDimensionPixelSize(R.dimen.recents_layout_bottom_margin);
|
||||||
|
mFreeformStackGap =
|
||||||
|
res.getDimensionPixelSize(R.dimen.recents_freeform_layout_bottom_margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -406,6 +413,7 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
public boolean setSystemInsets(Rect systemInsets) {
|
public boolean setSystemInsets(Rect systemInsets) {
|
||||||
boolean changed = !mSystemInsets.equals(systemInsets);
|
boolean changed = !mSystemInsets.equals(systemInsets);
|
||||||
mSystemInsets.set(systemInsets);
|
mSystemInsets.set(systemInsets);
|
||||||
|
mTaskGridLayoutAlgorithm.setSystemInsets(systemInsets);
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,6 +479,9 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
|
|
||||||
updateFrontBackTransforms();
|
updateFrontBackTransforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize the grid layout
|
||||||
|
mTaskGridLayoutAlgorithm.initialize(displayRect, windowRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -722,6 +733,11 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Rect getStackActionButtonRect(boolean useGridLayout) {
|
||||||
|
return useGridLayout
|
||||||
|
? mTaskGridLayoutAlgorithm.getStackActionButtonRect() : mStackActionButtonRect;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the TaskViewTransform that would put the task just off the back of the stack.
|
* Returns the TaskViewTransform that would put the task just off the back of the stack.
|
||||||
*/
|
*/
|
||||||
@@ -826,24 +842,30 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
* is what the view is measured and laid out with.
|
* is what the view is measured and laid out with.
|
||||||
*/
|
*/
|
||||||
public TaskViewTransform getStackTransform(Task task, float stackScroll,
|
public TaskViewTransform getStackTransform(Task task, float stackScroll,
|
||||||
TaskViewTransform transformOut, TaskViewTransform frontTransform) {
|
TaskViewTransform transformOut, TaskViewTransform frontTransform,
|
||||||
|
boolean useGridLayout) {
|
||||||
return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
|
return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
|
||||||
false /* forceUpdate */, false /* ignoreTaskOverrides */);
|
false /* forceUpdate */, false /* ignoreTaskOverrides */, useGridLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskViewTransform getStackTransform(Task task, float stackScroll,
|
public TaskViewTransform getStackTransform(Task task, float stackScroll,
|
||||||
TaskViewTransform transformOut, TaskViewTransform frontTransform,
|
TaskViewTransform transformOut, TaskViewTransform frontTransform,
|
||||||
boolean ignoreTaskOverrides) {
|
boolean ignoreTaskOverrides, boolean useGridLayout) {
|
||||||
return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
|
return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
|
||||||
false /* forceUpdate */, ignoreTaskOverrides);
|
false /* forceUpdate */, ignoreTaskOverrides, useGridLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskViewTransform getStackTransform(Task task, float stackScroll, int focusState,
|
public TaskViewTransform getStackTransform(Task task, float stackScroll, int focusState,
|
||||||
TaskViewTransform transformOut, TaskViewTransform frontTransform, boolean forceUpdate,
|
TaskViewTransform transformOut, TaskViewTransform frontTransform, boolean forceUpdate,
|
||||||
boolean ignoreTaskOverrides) {
|
boolean ignoreTaskOverrides, boolean useGridLayout) {
|
||||||
if (mFreeformLayoutAlgorithm.isTransformAvailable(task, this)) {
|
if (mFreeformLayoutAlgorithm.isTransformAvailable(task, this)) {
|
||||||
mFreeformLayoutAlgorithm.getTransform(task, transformOut, this);
|
mFreeformLayoutAlgorithm.getTransform(task, transformOut, this);
|
||||||
return transformOut;
|
return transformOut;
|
||||||
|
} else if (useGridLayout) {
|
||||||
|
int taskIndex = mTaskIndexMap.get(task.key.id);
|
||||||
|
int taskCount = mTaskIndexMap.size();
|
||||||
|
mTaskGridLayoutAlgorithm.getTransform(taskIndex, taskCount, transformOut, this);
|
||||||
|
return transformOut;
|
||||||
} else {
|
} else {
|
||||||
// Return early if we have an invalid index
|
// Return early if we have an invalid index
|
||||||
int nonOverrideTaskProgress = mTaskIndexMap.get(task.key.id, -1);
|
int nonOverrideTaskProgress = mTaskIndexMap.get(task.key.id, -1);
|
||||||
@@ -865,10 +887,10 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
*/
|
*/
|
||||||
public TaskViewTransform getStackTransformScreenCoordinates(Task task, float stackScroll,
|
public TaskViewTransform getStackTransformScreenCoordinates(Task task, float stackScroll,
|
||||||
TaskViewTransform transformOut, TaskViewTransform frontTransform,
|
TaskViewTransform transformOut, TaskViewTransform frontTransform,
|
||||||
Rect windowOverrideRect) {
|
Rect windowOverrideRect, boolean useGridLayout) {
|
||||||
TaskViewTransform transform = getStackTransform(task, stackScroll, mFocusState,
|
TaskViewTransform transform = getStackTransform(task, stackScroll, mFocusState,
|
||||||
transformOut, frontTransform, true /* forceUpdate */,
|
transformOut, frontTransform, true /* forceUpdate */,
|
||||||
false /* ignoreTaskOverrides */);
|
false /* ignoreTaskOverrides */, useGridLayout);
|
||||||
return transformToScreenCoordinates(transform, windowOverrideRect);
|
return transformToScreenCoordinates(transform, windowOverrideRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1089,9 +1111,9 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
* Retrieves resources that are constant regardless of the current configuration of the device.
|
* Retrieves resources that are constant regardless of the current configuration of the device.
|
||||||
*/
|
*/
|
||||||
public static int getDimensionForDevice(Context ctx, int phoneResId,
|
public static int getDimensionForDevice(Context ctx, int phoneResId,
|
||||||
int tabletResId, int xlargeTabletResId) {
|
int tabletResId, int xlargeTabletResId, int gridLayoutResId) {
|
||||||
return getDimensionForDevice(ctx, phoneResId, phoneResId, tabletResId, tabletResId,
|
return getDimensionForDevice(ctx, phoneResId, phoneResId, tabletResId, tabletResId,
|
||||||
xlargeTabletResId, xlargeTabletResId);
|
xlargeTabletResId, xlargeTabletResId, gridLayoutResId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1099,12 +1121,14 @@ public class TaskStackLayoutAlgorithm {
|
|||||||
*/
|
*/
|
||||||
public static int getDimensionForDevice(Context ctx, int phonePortResId, int phoneLandResId,
|
public static int getDimensionForDevice(Context ctx, int phonePortResId, int phoneLandResId,
|
||||||
int tabletPortResId, int tabletLandResId, int xlargeTabletPortResId,
|
int tabletPortResId, int tabletLandResId, int xlargeTabletPortResId,
|
||||||
int xlargeTabletLandResId) {
|
int xlargeTabletLandResId, int gridLayoutResId) {
|
||||||
RecentsConfiguration config = Recents.getConfiguration();
|
RecentsConfiguration config = Recents.getConfiguration();
|
||||||
Resources res = ctx.getResources();
|
Resources res = ctx.getResources();
|
||||||
boolean isLandscape = Utilities.getAppConfiguration(ctx).orientation ==
|
boolean isLandscape = Utilities.getAppConfiguration(ctx).orientation ==
|
||||||
Configuration.ORIENTATION_LANDSCAPE;
|
Configuration.ORIENTATION_LANDSCAPE;
|
||||||
if (config.isXLargeScreen) {
|
if (config.isGridEnabled) {
|
||||||
|
return res.getDimensionPixelSize(gridLayoutResId);
|
||||||
|
} else if (config.isXLargeScreen) {
|
||||||
return res.getDimensionPixelSize(isLandscape
|
return res.getDimensionPixelSize(isLandscape
|
||||||
? xlargeTabletLandResId
|
? xlargeTabletLandResId
|
||||||
: xlargeTabletPortResId);
|
: xlargeTabletPortResId);
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ import com.android.systemui.recents.misc.Utilities;
|
|||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
|
|
||||||
|
import com.android.systemui.recents.views.grid.GridTaskView;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -158,6 +159,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
private int mTaskCornerRadiusPx;
|
private int mTaskCornerRadiusPx;
|
||||||
private int mDividerSize;
|
private int mDividerSize;
|
||||||
private int mStartTimerIndicatorDuration;
|
private int mStartTimerIndicatorDuration;
|
||||||
|
private boolean mDraggingOverDockState;
|
||||||
|
|
||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
private boolean mTaskViewsClipDirty = true;
|
private boolean mTaskViewsClipDirty = true;
|
||||||
@@ -279,6 +281,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
|
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||||
|
if (ssp.hasFreeformWorkspaceSupport()) {
|
||||||
|
setWillNotDraw(false);
|
||||||
|
}
|
||||||
|
|
||||||
mFreeformWorkspaceBackground = (GradientDrawable) getContext().getDrawable(
|
mFreeformWorkspaceBackground = (GradientDrawable) getContext().getDrawable(
|
||||||
R.drawable.recents_freeform_workspace_bg);
|
R.drawable.recents_freeform_workspace_bg);
|
||||||
@@ -496,13 +501,13 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
|
|
||||||
// Calculate the current and (if necessary) the target transform for the task
|
// Calculate the current and (if necessary) the target transform for the task
|
||||||
transform = mLayoutAlgorithm.getStackTransform(task, curStackScroll,
|
transform = mLayoutAlgorithm.getStackTransform(task, curStackScroll,
|
||||||
taskTransforms.get(i), frontTransform, ignoreTaskOverrides);
|
taskTransforms.get(i), frontTransform, ignoreTaskOverrides, useGridLayout());
|
||||||
if (useTargetStackScroll && !transform.visible) {
|
if (useTargetStackScroll && !transform.visible) {
|
||||||
// If we have a target stack scroll and the task is not currently visible, then we
|
// If we have a target stack scroll and the task is not currently visible, then we
|
||||||
// just update the transform at the new scroll
|
// just update the transform at the new scroll
|
||||||
// TODO: Optimize this
|
// TODO: Optimize this
|
||||||
transformAtTarget = mLayoutAlgorithm.getStackTransform(task,
|
transformAtTarget = mLayoutAlgorithm.getStackTransform(task, targetStackScroll,
|
||||||
targetStackScroll, new TaskViewTransform(), frontTransformAtTarget);
|
new TaskViewTransform(), frontTransformAtTarget, useGridLayout());
|
||||||
if (transformAtTarget.visible) {
|
if (transformAtTarget.visible) {
|
||||||
transform.copyFrom(transformAtTarget);
|
transform.copyFrom(transformAtTarget);
|
||||||
}
|
}
|
||||||
@@ -733,7 +738,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
} else {
|
} else {
|
||||||
mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(),
|
mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(),
|
||||||
focusState, transform, null, true /* forceUpdate */,
|
focusState, transform, null, true /* forceUpdate */,
|
||||||
false /* ignoreTaskOverrides */);
|
false /* ignoreTaskOverrides */, useGridLayout());
|
||||||
}
|
}
|
||||||
transform.visible = true;
|
transform.visible = true;
|
||||||
}
|
}
|
||||||
@@ -750,7 +755,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
Task task = tasks.get(i);
|
Task task = tasks.get(i);
|
||||||
TaskViewTransform transform = transformsOut.get(i);
|
TaskViewTransform transform = transformsOut.get(i);
|
||||||
mLayoutAlgorithm.getStackTransform(task, stackScroll, focusState, transform, null,
|
mLayoutAlgorithm.getStackTransform(task, stackScroll, focusState, transform, null,
|
||||||
true /* forceUpdate */, ignoreTaskOverrides);
|
true /* forceUpdate */, ignoreTaskOverrides, useGridLayout());
|
||||||
transform.visible = true;
|
transform.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -779,6 +784,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
* Updates the clip for each of the task views from back to front.
|
* Updates the clip for each of the task views from back to front.
|
||||||
*/
|
*/
|
||||||
private void clipTaskViews() {
|
private void clipTaskViews() {
|
||||||
|
// We never clip task views in grid layout
|
||||||
|
if (Recents.getConfiguration().isGridEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the clip on each task child
|
// Update the clip on each task child
|
||||||
List<TaskView> taskViews = getTaskViews();
|
List<TaskView> taskViews = getTaskViews();
|
||||||
TaskView tmpTv = null;
|
TaskView tmpTv = null;
|
||||||
@@ -1335,14 +1345,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
|
setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
|
||||||
false /* requestViewFocus */);
|
false /* requestViewFocus */);
|
||||||
}
|
}
|
||||||
|
updateStackActionButtonVisibility();
|
||||||
// Update the stack action button visibility
|
|
||||||
if (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
|
||||||
mStack.getTaskCount() > 0) {
|
|
||||||
EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
|
|
||||||
} else {
|
|
||||||
EventBus.getDefault().send(new HideStackActionButtonEvent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTouchPointInView(float x, float y, TaskView tv) {
|
public boolean isTouchPointInView(float x, float y, TaskView tv) {
|
||||||
@@ -1503,7 +1506,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskView createView(Context context) {
|
public TaskView createView(Context context) {
|
||||||
return (TaskView) mInflater.inflate(R.layout.recents_task_view, this, false);
|
if (Recents.getConfiguration().isGridEnabled) {
|
||||||
|
return (GridTaskView) mInflater.inflate(R.layout.recents_grid_task_view, this, false);
|
||||||
|
} else {
|
||||||
|
return (TaskView) mInflater.inflate(R.layout.recents_task_view, this, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1560,11 +1567,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
// Bind the task view to the new task
|
// Bind the task view to the new task
|
||||||
bindTaskView(tv, task);
|
bindTaskView(tv, task);
|
||||||
|
|
||||||
// If the doze trigger has already fired, then update the state for this task view
|
|
||||||
if (mUIDozeTrigger.isAsleep()) {
|
|
||||||
tv.setNoUserInteractionState();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the new state for this view, including the callbacks and view clipping
|
// Set the new state for this view, including the callbacks and view clipping
|
||||||
tv.setCallbacks(this);
|
tv.setCallbacks(this);
|
||||||
tv.setTouchEnabled(true);
|
tv.setTouchEnabled(true);
|
||||||
@@ -1594,6 +1596,12 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
// Rebind the task and request that this task's data be filled into the TaskView
|
// Rebind the task and request that this task's data be filled into the TaskView
|
||||||
tv.onTaskBound(task, mTouchExplorationEnabled, mDisplayOrientation, mDisplayRect);
|
tv.onTaskBound(task, mTouchExplorationEnabled, mDisplayOrientation, mDisplayRect);
|
||||||
|
|
||||||
|
// If the doze trigger has already fired, then update the state for this task view
|
||||||
|
if (mUIDozeTrigger.isAsleep() ||
|
||||||
|
Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
|
||||||
|
tv.setNoUserInteractionState();
|
||||||
|
}
|
||||||
|
|
||||||
// Load the task data
|
// Load the task data
|
||||||
Recents.getTaskLoader().loadTaskData(task);
|
Recents.getTaskLoader().loadTaskData(task);
|
||||||
}
|
}
|
||||||
@@ -1632,7 +1640,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
relayoutTaskViewsOnNextFrame(animation);
|
relayoutTaskViewsOnNextFrame(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEnterAnimationComplete) {
|
// In grid layout, the stack action button always remains visible.
|
||||||
|
if (mEnterAnimationComplete && !useGridLayout()) {
|
||||||
if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
||||||
curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
||||||
mStack.getTaskCount() > 0) {
|
mStack.getTaskCount() > 0) {
|
||||||
@@ -1679,17 +1688,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int launchTaskIndex = mStack.indexOfStackTask(mStack.getLaunchTarget());
|
final Task launchTask = mStack.getNextLaunchTarget();
|
||||||
if (launchTaskIndex != -1) {
|
if (launchTask != null) {
|
||||||
launchTaskIndex = Math.max(0, launchTaskIndex - 1);
|
|
||||||
} else {
|
|
||||||
launchTaskIndex = mStack.getTaskCount() - 1;
|
|
||||||
}
|
|
||||||
if (launchTaskIndex != -1) {
|
|
||||||
// Stop all animations
|
// Stop all animations
|
||||||
cancelAllTaskViewAnimations();
|
cancelAllTaskViewAnimations();
|
||||||
|
|
||||||
final Task launchTask = mStack.getStackTasks().get(launchTaskIndex);
|
|
||||||
float curScroll = mStackScroller.getStackScroll();
|
float curScroll = mStackScroller.getStackScroll();
|
||||||
float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(launchTask);
|
float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(launchTask);
|
||||||
float absScrollDiff = Math.abs(targetScroll - curScroll);
|
float absScrollDiff = Math.abs(targetScroll - curScroll);
|
||||||
@@ -1832,7 +1835,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
// Enlarge the dragged view slightly
|
// Enlarge the dragged view slightly
|
||||||
float finalScale = event.taskView.getScaleX() * DRAG_SCALE_FACTOR;
|
float finalScale = event.taskView.getScaleX() * DRAG_SCALE_FACTOR;
|
||||||
mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
|
mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
|
||||||
mTmpTransform, null);
|
mTmpTransform, null, useGridLayout());
|
||||||
mTmpTransform.scale = finalScale;
|
mTmpTransform.scale = finalScale;
|
||||||
mTmpTransform.translationZ = mLayoutAlgorithm.mMaxTranslationZ + 1;
|
mTmpTransform.translationZ = mLayoutAlgorithm.mMaxTranslationZ + 1;
|
||||||
mTmpTransform.dimAlpha = 0f;
|
mTmpTransform.dimAlpha = 0f;
|
||||||
@@ -1853,6 +1856,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
Interpolators.FAST_OUT_SLOW_IN);
|
Interpolators.FAST_OUT_SLOW_IN);
|
||||||
boolean ignoreTaskOverrides = false;
|
boolean ignoreTaskOverrides = false;
|
||||||
if (event.dropTarget instanceof TaskStack.DockState) {
|
if (event.dropTarget instanceof TaskStack.DockState) {
|
||||||
|
mDraggingOverDockState = true;
|
||||||
// Calculate the new task stack bounds that matches the window size that Recents will
|
// Calculate the new task stack bounds that matches the window size that Recents will
|
||||||
// have after the drop
|
// have after the drop
|
||||||
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
|
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
|
||||||
@@ -1872,6 +1876,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
updateLayoutAlgorithm(true /* boundScroll */);
|
updateLayoutAlgorithm(true /* boundScroll */);
|
||||||
ignoreTaskOverrides = true;
|
ignoreTaskOverrides = true;
|
||||||
} else {
|
} else {
|
||||||
|
mDraggingOverDockState = false;
|
||||||
// Restore the pre-drag task stack bounds, but ensure that we don't layout the dragging
|
// Restore the pre-drag task stack bounds, but ensure that we don't layout the dragging
|
||||||
// task view, so add it back to the ignore set after updating the layout
|
// task view, so add it back to the ignore set after updating the layout
|
||||||
removeIgnoreTask(event.task);
|
removeIgnoreTask(event.task);
|
||||||
@@ -1882,6 +1887,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void onBusEvent(final DragEndEvent event) {
|
public final void onBusEvent(final DragEndEvent event) {
|
||||||
|
mDraggingOverDockState = false;
|
||||||
// We don't handle drops on the dock regions
|
// We don't handle drops on the dock regions
|
||||||
if (event.dropTarget instanceof TaskStack.DockState) {
|
if (event.dropTarget instanceof TaskStack.DockState) {
|
||||||
// However, we do need to reset the overrides, since the last state of this task stack
|
// However, we do need to reset the overrides, since the last state of this task stack
|
||||||
@@ -1969,7 +1975,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Start the dozer to trigger to trigger any UI that shows after a timeout
|
// Start the dozer to trigger to trigger any UI that shows after a timeout
|
||||||
mUIDozeTrigger.startDozing();
|
if (!Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
|
||||||
|
mUIDozeTrigger.startDozing();
|
||||||
|
}
|
||||||
|
|
||||||
// Update the focused state here -- since we only set the focused task without
|
// Update the focused state here -- since we only set the focused task without
|
||||||
// requesting view focus in onFirstLayout(), actually request view focus and
|
// requesting view focus in onFirstLayout(), actually request view focus and
|
||||||
@@ -2049,6 +2057,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the Clear All button in case we're switching in or out of grid layout.
|
||||||
|
updateStackActionButtonVisibility();
|
||||||
|
|
||||||
// Trigger a new layout and update to the initial state if necessary
|
// Trigger a new layout and update to the initial state if necessary
|
||||||
if (event.fromMultiWindow) {
|
if (event.fromMultiWindow) {
|
||||||
mInitialState = INITIAL_STATE_UPDATE_LAYOUT_ONLY;
|
mInitialState = INITIAL_STATE_UPDATE_LAYOUT_ONLY;
|
||||||
@@ -2118,6 +2129,20 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether we should use the grid layout.
|
||||||
|
* We use the grid layout for Recents iff all the following is true:
|
||||||
|
* 1. Grid-mode is enabled.
|
||||||
|
* 2. The activity is not in multi-window mode.
|
||||||
|
* 3. The user is not dragging a task view over the dock state.
|
||||||
|
* @return True if we should use the grid layout.
|
||||||
|
*/
|
||||||
|
public boolean useGridLayout() {
|
||||||
|
return Recents.getConfiguration().isGridEnabled
|
||||||
|
&& !((RecentsActivity) mContext).isInMultiWindowMode()
|
||||||
|
&& !mDraggingOverDockState;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads current system flags related to accessibility and screen pinning.
|
* Reads current system flags related to accessibility and screen pinning.
|
||||||
*/
|
*/
|
||||||
@@ -2128,6 +2153,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
Settings.System.LOCK_TO_APP_ENABLED) != 0;
|
Settings.System.LOCK_TO_APP_ENABLED) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateStackActionButtonVisibility() {
|
||||||
|
// Always show the button in grid layout.
|
||||||
|
if (useGridLayout() ||
|
||||||
|
(mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
||||||
|
mStack.getTaskCount() > 0)) {
|
||||||
|
EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
|
||||||
|
} else {
|
||||||
|
EventBus.getDefault().send(new HideStackActionButtonEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void dump(String prefix, PrintWriter writer) {
|
public void dump(String prefix, PrintWriter writer) {
|
||||||
String innerPrefix = prefix + " ";
|
String innerPrefix = prefix + " ";
|
||||||
String id = Integer.toHexString(System.identityHashCode(this));
|
String id = Integer.toHexString(System.identityHashCode(this));
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
|
|||||||
private ArrayList<Animator> mTmpAnimators = new ArrayList<>();
|
private ArrayList<Animator> mTmpAnimators = new ArrayList<>();
|
||||||
|
|
||||||
@ViewDebug.ExportedProperty(deepExport=true, prefix="thumbnail_")
|
@ViewDebug.ExportedProperty(deepExport=true, prefix="thumbnail_")
|
||||||
TaskViewThumbnail mThumbnailView;
|
protected TaskViewThumbnail mThumbnailView;
|
||||||
@ViewDebug.ExportedProperty(deepExport=true, prefix="header_")
|
@ViewDebug.ExportedProperty(deepExport=true, prefix="header_")
|
||||||
TaskViewHeader mHeaderView;
|
TaskViewHeader mHeaderView;
|
||||||
private View mActionButtonView;
|
private View mActionButtonView;
|
||||||
@@ -176,8 +176,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
RecentsConfiguration config = Recents.getConfiguration();
|
RecentsConfiguration config = Recents.getConfiguration();
|
||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
mViewBounds = new AnimateableViewBounds(this, res.getDimensionPixelSize(
|
mViewBounds = createOutlineProvider();
|
||||||
R.dimen.recents_task_view_shadow_rounded_corners_radius));
|
|
||||||
if (config.fakeShadows) {
|
if (config.fakeShadows) {
|
||||||
setBackground(new FakeShadowDrawable(res, config));
|
setBackground(new FakeShadowDrawable(res, config));
|
||||||
}
|
}
|
||||||
@@ -194,7 +193,9 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
|
|||||||
* Called from RecentsActivity when it is relaunched.
|
* Called from RecentsActivity when it is relaunched.
|
||||||
*/
|
*/
|
||||||
void onReload(boolean isResumingFromVisible) {
|
void onReload(boolean isResumingFromVisible) {
|
||||||
resetNoUserInteractionState();
|
if (!Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
|
||||||
|
resetNoUserInteractionState();
|
||||||
|
}
|
||||||
if (!isResumingFromVisible) {
|
if (!isResumingFromVisible) {
|
||||||
resetViewProperties();
|
resetViewProperties();
|
||||||
}
|
}
|
||||||
@@ -205,6 +206,12 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
|
|||||||
return mTask;
|
return mTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create an outline provider to clip and outline the view */
|
||||||
|
protected AnimateableViewBounds createOutlineProvider() {
|
||||||
|
return new AnimateableViewBounds(this, mContext.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.recents_task_view_shadow_rounded_corners_radius));
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the view bounds. */
|
/** Returns the view bounds. */
|
||||||
AnimateableViewBounds getViewBounds() {
|
AnimateableViewBounds getViewBounds() {
|
||||||
return mViewBounds;
|
return mViewBounds;
|
||||||
@@ -232,7 +239,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
|
|||||||
/**
|
/**
|
||||||
* Update the task view when the configuration changes.
|
* Update the task view when the configuration changes.
|
||||||
*/
|
*/
|
||||||
void onConfigurationChanged() {
|
protected void onConfigurationChanged() {
|
||||||
mHeaderView.onConfigurationChanged();
|
mHeaderView.onConfigurationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,10 +673,16 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
|
|||||||
@Override
|
@Override
|
||||||
public boolean onLongClick(View v) {
|
public boolean onLongClick(View v) {
|
||||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||||
// Since we are clipping the view to the bounds, manually do the hit test
|
boolean inBounds = false;
|
||||||
Rect clipBounds = new Rect(mViewBounds.mClipBounds);
|
Rect clipBounds = new Rect(mViewBounds.mClipBounds);
|
||||||
clipBounds.scale(getScaleX());
|
if (!clipBounds.isEmpty()) {
|
||||||
boolean inBounds = clipBounds.contains(mDownTouchPos.x, mDownTouchPos.y);
|
// If we are clipping the view to the bounds, manually do the hit test.
|
||||||
|
clipBounds.scale(getScaleX());
|
||||||
|
inBounds = clipBounds.contains(mDownTouchPos.x, mDownTouchPos.y);
|
||||||
|
} else {
|
||||||
|
// Otherwise just make sure we're within the view's bounds.
|
||||||
|
inBounds = mDownTouchPos.x <= getWidth() && mDownTouchPos.y <= getHeight();
|
||||||
|
}
|
||||||
if (v == this && inBounds && !ssp.hasDockedTask()) {
|
if (v == this && inBounds && !ssp.hasDockedTask()) {
|
||||||
// Start listening for drag events
|
// Start listening for drag events
|
||||||
setClipViewInStack(false);
|
setClipViewInStack(false);
|
||||||
|
|||||||
@@ -290,14 +290,16 @@ public class TaskViewHeader extends FrameLayout
|
|||||||
R.dimen.recents_task_view_header_height,
|
R.dimen.recents_task_view_header_height,
|
||||||
R.dimen.recents_task_view_header_height_tablet_land,
|
R.dimen.recents_task_view_header_height_tablet_land,
|
||||||
R.dimen.recents_task_view_header_height,
|
R.dimen.recents_task_view_header_height,
|
||||||
R.dimen.recents_task_view_header_height_tablet_land);
|
R.dimen.recents_task_view_header_height_tablet_land,
|
||||||
|
R.dimen.recents_grid_task_view_header_height);
|
||||||
int headerButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
|
int headerButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
|
||||||
R.dimen.recents_task_view_header_button_padding,
|
R.dimen.recents_task_view_header_button_padding,
|
||||||
R.dimen.recents_task_view_header_button_padding,
|
R.dimen.recents_task_view_header_button_padding,
|
||||||
R.dimen.recents_task_view_header_button_padding,
|
R.dimen.recents_task_view_header_button_padding,
|
||||||
R.dimen.recents_task_view_header_button_padding_tablet_land,
|
R.dimen.recents_task_view_header_button_padding_tablet_land,
|
||||||
R.dimen.recents_task_view_header_button_padding,
|
R.dimen.recents_task_view_header_button_padding,
|
||||||
R.dimen.recents_task_view_header_button_padding_tablet_land);
|
R.dimen.recents_task_view_header_button_padding_tablet_land,
|
||||||
|
R.dimen.recents_grid_task_view_header_button_padding);
|
||||||
if (headerBarHeight != mHeaderBarHeight || headerButtonPadding != mHeaderButtonPadding) {
|
if (headerBarHeight != mHeaderBarHeight || headerButtonPadding != mHeaderButtonPadding) {
|
||||||
mHeaderBarHeight = headerBarHeight;
|
mHeaderBarHeight = headerBarHeight;
|
||||||
mHeaderButtonPadding = headerButtonPadding;
|
mHeaderButtonPadding = headerButtonPadding;
|
||||||
@@ -603,10 +605,7 @@ public class TaskViewHeader extends FrameLayout
|
|||||||
Constants.Metrics.DismissSourceHeaderButton);
|
Constants.Metrics.DismissSourceHeaderButton);
|
||||||
} else if (v == mMoveTaskButton) {
|
} else if (v == mMoveTaskButton) {
|
||||||
TaskView tv = Utilities.findParent(this, TaskView.class);
|
TaskView tv = Utilities.findParent(this, TaskView.class);
|
||||||
Rect bounds = mMoveTaskTargetStackId == FREEFORM_WORKSPACE_STACK_ID
|
EventBus.getDefault().send(new LaunchTaskEvent(tv, mTask, null,
|
||||||
? new Rect(mTaskViewRect)
|
|
||||||
: new Rect();
|
|
||||||
EventBus.getDefault().send(new LaunchTaskEvent(tv, mTask, bounds,
|
|
||||||
mMoveTaskTargetStackId, false));
|
mMoveTaskTargetStackId, false));
|
||||||
} else if (v == mAppInfoView) {
|
} else if (v == mAppInfoView) {
|
||||||
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
|
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ public class TaskViewThumbnail extends View {
|
|||||||
@ViewDebug.ExportedProperty(category="recents")
|
@ViewDebug.ExportedProperty(category="recents")
|
||||||
private float mThumbnailScale;
|
private float mThumbnailScale;
|
||||||
private float mFullscreenThumbnailScale;
|
private float mFullscreenThumbnailScale;
|
||||||
|
private boolean mSizeToFit = false;
|
||||||
|
private boolean mOverlayHeaderOnThumbnailActionBar = true;
|
||||||
private ActivityManager.TaskThumbnailInfo mThumbnailInfo;
|
private ActivityManager.TaskThumbnailInfo mThumbnailInfo;
|
||||||
|
|
||||||
private int mCornerRadius;
|
private int mCornerRadius;
|
||||||
@@ -133,10 +135,12 @@ public class TaskViewThumbnail extends View {
|
|||||||
(int) (mThumbnailRect.width() * mThumbnailScale));
|
(int) (mThumbnailRect.width() * mThumbnailScale));
|
||||||
int thumbnailHeight = Math.min(viewHeight,
|
int thumbnailHeight = Math.min(viewHeight,
|
||||||
(int) (mThumbnailRect.height() * mThumbnailScale));
|
(int) (mThumbnailRect.height() * mThumbnailScale));
|
||||||
|
|
||||||
if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
|
if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
|
||||||
int topOffset = mTaskBar != null
|
int topOffset = 0;
|
||||||
? mTaskBar.getHeight() - mCornerRadius
|
if (mTaskBar != null && mOverlayHeaderOnThumbnailActionBar) {
|
||||||
: 0;
|
topOffset = mTaskBar.getHeight() - mCornerRadius;
|
||||||
|
}
|
||||||
|
|
||||||
// Draw the background, there will be some small overdraw with the thumbnail
|
// Draw the background, there will be some small overdraw with the thumbnail
|
||||||
if (thumbnailWidth < viewWidth) {
|
if (thumbnailWidth < viewWidth) {
|
||||||
@@ -230,7 +234,7 @@ public class TaskViewThumbnail extends View {
|
|||||||
// If we haven't measured or the thumbnail is invalid, skip the thumbnail drawing
|
// If we haven't measured or the thumbnail is invalid, skip the thumbnail drawing
|
||||||
// and only draw the background color
|
// and only draw the background color
|
||||||
mThumbnailScale = 0f;
|
mThumbnailScale = 0f;
|
||||||
} else if (isStackTask) {
|
} else if (isStackTask && !mSizeToFit) {
|
||||||
float invThumbnailScale = 1f / mFullscreenThumbnailScale;
|
float invThumbnailScale = 1f / mFullscreenThumbnailScale;
|
||||||
if (mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT) {
|
if (mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
if (mThumbnailInfo.screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
|
if (mThumbnailInfo.screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
@@ -262,6 +266,19 @@ public class TaskViewThumbnail extends View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sets whether the thumbnail should be resized to fit the task view in all orientations. */
|
||||||
|
public void setSizeToFit(boolean flag) {
|
||||||
|
mSizeToFit = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the header should overlap (and hide) the action bar in the thumbnail, or
|
||||||
|
* be stacked just above it.
|
||||||
|
*/
|
||||||
|
public void setOverlayHeaderOnThumbnailActionBar(boolean flag) {
|
||||||
|
mOverlayHeaderOnThumbnailActionBar = flag;
|
||||||
|
}
|
||||||
|
|
||||||
/** Updates the clip rect based on the given task bar. */
|
/** Updates the clip rect based on the given task bar. */
|
||||||
void updateClipToTaskBar(View taskBar) {
|
void updateClipToTaskBar(View taskBar) {
|
||||||
mTaskBar = taskBar;
|
mTaskBar = taskBar;
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.view.View;
|
||||||
|
import com.android.systemui.recents.views.AnimateableViewBounds;
|
||||||
|
|
||||||
|
/* An outline provider for grid-based task views. */
|
||||||
|
class AnimateableGridViewBounds extends AnimateableViewBounds {
|
||||||
|
|
||||||
|
public AnimateableGridViewBounds(View source, int cornerRadius) {
|
||||||
|
super(source, cornerRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateClipBounds() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.util.AttributeSet;
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.recents.views.AnimateableViewBounds;
|
||||||
|
import com.android.systemui.recents.views.TaskView;
|
||||||
|
|
||||||
|
public class GridTaskView extends TaskView {
|
||||||
|
|
||||||
|
/** The height, in pixels, of the header view. */
|
||||||
|
private int mHeaderHeight;
|
||||||
|
|
||||||
|
public GridTaskView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridTaskView(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
this(context, attrs, defStyleAttr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridTaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
mHeaderHeight = context.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.recents_grid_task_view_header_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFinishInflate() {
|
||||||
|
super.onFinishInflate();
|
||||||
|
// Show the full thumbnail and don't overlap with the header.
|
||||||
|
mThumbnailView.setSizeToFit(true);
|
||||||
|
mThumbnailView.setOverlayHeaderOnThumbnailActionBar(false);
|
||||||
|
mThumbnailView.updateThumbnailScale();
|
||||||
|
mThumbnailView.setTranslationY(mHeaderHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AnimateableViewBounds createOutlineProvider() {
|
||||||
|
return new AnimateableGridViewBounds(this, mContext.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.recents_task_view_shadow_rounded_corners_radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onConfigurationChanged() {
|
||||||
|
super.onConfigurationChanged();
|
||||||
|
mHeaderHeight = mContext.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.recents_grid_task_view_header_height);
|
||||||
|
mThumbnailView.setTranslationY(mHeaderHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.content.res.Resources;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.recents.misc.Utilities;
|
||||||
|
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
|
||||||
|
import com.android.systemui.recents.views.TaskViewTransform;
|
||||||
|
|
||||||
|
public class TaskGridLayoutAlgorithm {
|
||||||
|
|
||||||
|
private final String TAG = "TaskGridLayoutAlgorithm";
|
||||||
|
private final int MAX_LAYOUT_TASK_COUNT = 8;
|
||||||
|
|
||||||
|
/** The horizontal padding around the whole recents view. */
|
||||||
|
private int mPaddingLeftRight;
|
||||||
|
/** The vertical padding around the whole recents view. */
|
||||||
|
private int mPaddingTopBottom;
|
||||||
|
/** The padding between task views. */
|
||||||
|
private int mPaddingTaskView;
|
||||||
|
|
||||||
|
private Rect mDisplayRect;
|
||||||
|
private Rect mWindowRect;
|
||||||
|
private Point mScreenSize = new Point();
|
||||||
|
|
||||||
|
private Rect mTaskGridRect;
|
||||||
|
|
||||||
|
/** The height, in pixels, of each task view's title bar. */
|
||||||
|
private int mTitleBarHeight;
|
||||||
|
|
||||||
|
/** The aspect ratio of each task thumbnail, without the title bar. */
|
||||||
|
private float mAppAspectRatio;
|
||||||
|
private Rect mSystemInsets = new Rect();
|
||||||
|
|
||||||
|
public TaskGridLayoutAlgorithm(Context context) {
|
||||||
|
reloadOnConfigurationChange(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reloadOnConfigurationChange(Context context) {
|
||||||
|
Resources res = context.getResources();
|
||||||
|
mPaddingLeftRight = res.getDimensionPixelSize(R.dimen.recents_grid_padding_left_right);
|
||||||
|
mPaddingTopBottom = res.getDimensionPixelSize(R.dimen.recents_grid_padding_top_bottom);
|
||||||
|
mPaddingTaskView = res.getDimensionPixelSize(R.dimen.recents_grid_padding_task_view);
|
||||||
|
|
||||||
|
mTaskGridRect = new Rect();
|
||||||
|
mTitleBarHeight = res.getDimensionPixelSize(R.dimen.recents_grid_task_view_header_height);
|
||||||
|
|
||||||
|
WindowManager windowManager = (WindowManager) context
|
||||||
|
.getSystemService(Context.WINDOW_SERVICE);
|
||||||
|
windowManager.getDefaultDisplay().getRealSize(mScreenSize);
|
||||||
|
|
||||||
|
updateAppAspectRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskViewTransform getTransform(int taskIndex, int taskCount,
|
||||||
|
TaskViewTransform transformOut, TaskStackLayoutAlgorithm stackLayout) {
|
||||||
|
|
||||||
|
int layoutTaskCount = Math.min(MAX_LAYOUT_TASK_COUNT, taskCount);
|
||||||
|
|
||||||
|
// We also need to invert the index in order to display the most recent tasks first.
|
||||||
|
int taskLayoutIndex = taskCount - taskIndex - 1;
|
||||||
|
|
||||||
|
int tasksPerLine = layoutTaskCount < 2 ? 1 : (
|
||||||
|
layoutTaskCount < 5 ? 2 : (
|
||||||
|
layoutTaskCount < 7 ? 3 : 4));
|
||||||
|
int lines = layoutTaskCount < 3 ? 1 : 2;
|
||||||
|
|
||||||
|
int taskWidth, taskHeight;
|
||||||
|
int maxTaskWidth = (mDisplayRect.width() - 2 * mPaddingLeftRight
|
||||||
|
- (tasksPerLine - 1) * mPaddingTaskView) / tasksPerLine;
|
||||||
|
int maxTaskHeight = (mDisplayRect.height() - 2 * mPaddingTopBottom
|
||||||
|
- (lines - 1) * mPaddingTaskView) / lines;
|
||||||
|
|
||||||
|
if (maxTaskHeight >= maxTaskWidth / mAppAspectRatio + mTitleBarHeight) {
|
||||||
|
// Width bound.
|
||||||
|
taskWidth = maxTaskWidth;
|
||||||
|
taskHeight = (int) (maxTaskWidth / mAppAspectRatio + mTitleBarHeight);
|
||||||
|
} else {
|
||||||
|
// Height bound.
|
||||||
|
taskHeight = maxTaskHeight;
|
||||||
|
taskWidth = (int) ((taskHeight - mTitleBarHeight) * mAppAspectRatio);
|
||||||
|
}
|
||||||
|
int emptySpaceX = mDisplayRect.width() - 2 * mPaddingLeftRight
|
||||||
|
- (tasksPerLine * taskWidth) - (tasksPerLine - 1) * mPaddingTaskView;
|
||||||
|
int emptySpaceY = mDisplayRect.height() - 2 * mPaddingTopBottom
|
||||||
|
- (lines * taskHeight) - (lines - 1) * mPaddingTaskView;
|
||||||
|
|
||||||
|
mTaskGridRect.set(0, 0, taskWidth, taskHeight);
|
||||||
|
|
||||||
|
int xIndex = taskLayoutIndex % tasksPerLine;
|
||||||
|
int yIndex = taskLayoutIndex / tasksPerLine;
|
||||||
|
int x = emptySpaceX / 2 + mPaddingLeftRight + (taskWidth + mPaddingTaskView) * xIndex;
|
||||||
|
int y = emptySpaceY / 2 + mPaddingTopBottom + (taskHeight + mPaddingTaskView) * yIndex;
|
||||||
|
float z = stackLayout.mMaxTranslationZ;
|
||||||
|
|
||||||
|
float dimAlpha = 0f;
|
||||||
|
float viewOutlineAlpha = 0f;
|
||||||
|
boolean isTaskViewVisible = (taskLayoutIndex < MAX_LAYOUT_TASK_COUNT);
|
||||||
|
|
||||||
|
// Fill out the transform
|
||||||
|
transformOut.scale = 1f;
|
||||||
|
transformOut.alpha = isTaskViewVisible ? 1f : 0f;
|
||||||
|
transformOut.translationZ = z;
|
||||||
|
transformOut.dimAlpha = dimAlpha;
|
||||||
|
transformOut.viewOutlineAlpha = viewOutlineAlpha;
|
||||||
|
transformOut.rect.set(mTaskGridRect);
|
||||||
|
transformOut.rect.offset(x, y);
|
||||||
|
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
|
||||||
|
// We only show the 8 most recent tasks.
|
||||||
|
transformOut.visible = isTaskViewVisible;
|
||||||
|
return transformOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(Rect displayRect, Rect windowRect) {
|
||||||
|
mDisplayRect = displayRect;
|
||||||
|
mWindowRect = windowRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSystemInsets(Rect systemInsets) {
|
||||||
|
mSystemInsets = systemInsets;
|
||||||
|
updateAppAspectRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAppAspectRatio() {
|
||||||
|
int usableWidth = mScreenSize.x - mSystemInsets.left - mSystemInsets.right;
|
||||||
|
int usableHeight = mScreenSize.y - mSystemInsets.top - mSystemInsets.bottom;
|
||||||
|
mAppAspectRatio = (float) usableWidth / (float) usableHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect getStackActionButtonRect() {
|
||||||
|
Rect buttonRect = new Rect(mDisplayRect);
|
||||||
|
buttonRect.right -= mPaddingLeftRight;
|
||||||
|
buttonRect.left += mPaddingLeftRight;
|
||||||
|
buttonRect.bottom = buttonRect.top + mPaddingTopBottom;
|
||||||
|
return buttonRect;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user