blob: d49ff89eb940ac412d33a07706da88e49037fc27 [file] [log] [blame]
/*
* Copyright (C) 2018 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.quickstep.util;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import androidx.annotation.AnyThread;
import androidx.annotation.IntDef;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.quickstep.SysUINavigationMode;
import java.lang.annotation.Retention;
public class LayoutUtils {
private static final int MULTI_WINDOW_STRATEGY_HALF_SCREEN = 1;
private static final int MULTI_WINDOW_STRATEGY_DEVICE_PROFILE = 2;
@Retention(SOURCE)
@IntDef({MULTI_WINDOW_STRATEGY_HALF_SCREEN, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE})
private @interface MultiWindowStrategy {}
/**
* The height for the swipe up motion
*/
public static float getDefaultSwipeHeight(Context context, DeviceProfile dp) {
float swipeHeight = dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
if (SysUINavigationMode.getMode(context) == SysUINavigationMode.Mode.NO_BUTTON) {
swipeHeight -= dp.getInsets().bottom;
}
return swipeHeight;
}
public static void calculateLauncherTaskSize(Context context, DeviceProfile dp, Rect outRect) {
float extraSpace;
if (dp.isVerticalBarLayout()) {
extraSpace = 0;
} else {
Resources res = context.getResources();
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
//TODO: this needs to account for the swipe gesture height and accessibility
// UI when shown.
extraSpace = 0;
} else {
extraSpace = getDefaultSwipeHeight(context, dp) + dp.verticalDragHandleSizePx
+ res.getDimensionPixelSize(
R.dimen.dynamic_grid_hotseat_extra_vertical_size)
+ res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
}
}
calculateTaskSize(context, dp, extraSpace, MULTI_WINDOW_STRATEGY_HALF_SCREEN, outRect);
}
public static void calculateFallbackTaskSize(Context context, DeviceProfile dp, Rect outRect) {
calculateTaskSize(context, dp, 0, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE, outRect);
}
@AnyThread
public static void calculateTaskSize(Context context, DeviceProfile dp,
float extraVerticalSpace, @MultiWindowStrategy int multiWindowStrategy, Rect outRect) {
float taskWidth, taskHeight, paddingHorz;
Resources res = context.getResources();
Rect insets = dp.getInsets();
if (dp.isMultiWindowMode) {
if (multiWindowStrategy == MULTI_WINDOW_STRATEGY_HALF_SCREEN) {
DeviceProfile fullDp = dp.getFullScreenProfile();
// Use availableWidthPx and availableHeightPx instead of widthPx and heightPx to
// account for system insets
taskWidth = fullDp.availableWidthPx;
taskHeight = fullDp.availableHeightPx;
float halfDividerSize = res.getDimension(R.dimen.multi_window_task_divider_size)
/ 2;
if (fullDp.isLandscape) {
taskWidth = taskWidth / 2 - halfDividerSize;
} else {
taskHeight = taskHeight / 2 - halfDividerSize;
}
} else {
// multiWindowStrategy == MULTI_WINDOW_STRATEGY_DEVICE_PROFILE
taskWidth = dp.widthPx;
taskHeight = dp.heightPx;
}
paddingHorz = res.getDimension(R.dimen.multi_window_task_card_horz_space);
} else {
taskWidth = dp.availableWidthPx;
taskHeight = dp.availableHeightPx;
final int paddingResId;
if (dp.isVerticalBarLayout()) {
paddingResId = R.dimen.landscape_task_card_horz_space;
} else if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
} else {
paddingResId = R.dimen.portrait_task_card_horz_space;
}
paddingHorz = res.getDimension(paddingResId);
}
float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
float bottomMargin = thumbnailBottomMargin(res);
float paddingVert = res.getDimension(R.dimen.task_card_vert_space);
// Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
// we override the insets ourselves.
int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
int launcherVisibleHeight = dp.heightPx - insets.top - insets.bottom;
float availableHeight = launcherVisibleHeight
- topIconMargin - extraVerticalSpace - paddingVert - bottomMargin;
float availableWidth = launcherVisibleWidth - paddingHorz;
float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
float outWidth = scale * taskWidth;
float outHeight = scale * taskHeight;
// Center in the visible space
float x = insets.left + (launcherVisibleWidth - outWidth) / 2;
float y = insets.top + Math.max(topIconMargin,
(launcherVisibleHeight - extraVerticalSpace - outHeight) / 2);
outRect.set(Math.round(x), Math.round(y),
Math.round(x) + Math.round(outWidth), Math.round(y) + Math.round(outHeight));
}
public static int getShelfTrackingDistance(Context context, DeviceProfile dp) {
// Track the bottom of the window.
int shelfHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
int spaceBetweenShelfAndRecents = (int) context.getResources().getDimension(
R.dimen.task_card_vert_space);
return shelfHeight + spaceBetweenShelfAndRecents;
}
/**
* Get the margin that the task thumbnail view should use.
* @return the margin in pixels.
*/
public static int thumbnailBottomMargin(Resources resources) {
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
return resources.getDimensionPixelSize(R.dimen.overview_actions_height);
} else {
return 0;
}
}
}