1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.quickstep.util; 17 18 import static java.lang.annotation.RetentionPolicy.SOURCE; 19 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.graphics.Rect; 23 import android.support.annotation.AnyThread; 24 import android.support.annotation.IntDef; 25 26 import com.android.launcher3.DeviceProfile; 27 import com.android.launcher3.R; 28 29 import java.lang.annotation.Retention; 30 31 public class LayoutUtils { 32 33 private static final int MULTI_WINDOW_STRATEGY_HALF_SCREEN = 1; 34 private static final int MULTI_WINDOW_STRATEGY_DEVICE_PROFILE = 2; 35 36 @Retention(SOURCE) 37 @IntDef({MULTI_WINDOW_STRATEGY_HALF_SCREEN, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE}) 38 private @interface MultiWindowStrategy {} 39 40 public static void calculateLauncherTaskSize(Context context, DeviceProfile dp, Rect outRect) { 41 float extraSpace; 42 if (dp.isVerticalBarLayout()) { 43 extraSpace = 0; 44 } else { 45 extraSpace = dp.hotseatBarSizePx + dp.verticalDragHandleSizePx; 46 } 47 calculateTaskSize(context, dp, extraSpace, MULTI_WINDOW_STRATEGY_HALF_SCREEN, outRect); 48 } 49 50 public static void calculateFallbackTaskSize(Context context, DeviceProfile dp, Rect outRect) { 51 calculateTaskSize(context, dp, 0, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE, outRect); 52 } 53 54 @AnyThread 55 public static void calculateTaskSize(Context context, DeviceProfile dp, 56 float extraVerticalSpace, @MultiWindowStrategy int multiWindowStrategy, Rect outRect) { 57 float taskWidth, taskHeight, paddingHorz; 58 Resources res = context.getResources(); 59 Rect insets = dp.getInsets(); 60 61 if (dp.isMultiWindowMode) { 62 if (multiWindowStrategy == MULTI_WINDOW_STRATEGY_HALF_SCREEN) { 63 DeviceProfile fullDp = dp.getFullScreenProfile(); 64 // Use availableWidthPx and availableHeightPx instead of widthPx and heightPx to 65 // account for system insets 66 taskWidth = fullDp.availableWidthPx; 67 taskHeight = fullDp.availableHeightPx; 68 float halfDividerSize = res.getDimension(R.dimen.multi_window_task_divider_size) 69 / 2; 70 71 if (fullDp.isLandscape) { 72 taskWidth = taskWidth / 2 - halfDividerSize; 73 } else { 74 taskHeight = taskHeight / 2 - halfDividerSize; 75 } 76 } else { 77 // multiWindowStrategy == MULTI_WINDOW_STRATEGY_DEVICE_PROFILE 78 taskWidth = dp.widthPx; 79 taskHeight = dp.heightPx; 80 } 81 paddingHorz = res.getDimension(R.dimen.multi_window_task_card_horz_space); 82 } else { 83 taskWidth = dp.availableWidthPx; 84 taskHeight = dp.availableHeightPx; 85 paddingHorz = res.getDimension(dp.isVerticalBarLayout() 86 ? R.dimen.landscape_task_card_horz_space 87 : R.dimen.portrait_task_card_horz_space); 88 } 89 90 float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin); 91 float paddingVert = res.getDimension(R.dimen.task_card_vert_space); 92 93 // Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless 94 // we override the insets ourselves. 95 int launcherVisibleWidth = dp.widthPx - insets.left - insets.right; 96 int launcherVisibleHeight = dp.heightPx - insets.top - insets.bottom; 97 98 float availableHeight = launcherVisibleHeight 99 - topIconMargin - extraVerticalSpace - paddingVert; 100 float availableWidth = launcherVisibleWidth - paddingHorz; 101 102 float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight); 103 float outWidth = scale * taskWidth; 104 float outHeight = scale * taskHeight; 105 106 // Center in the visible space 107 float x = insets.left + (launcherVisibleWidth - outWidth) / 2; 108 float y = insets.top + Math.max(topIconMargin, 109 (launcherVisibleHeight - extraVerticalSpace - outHeight) / 2); 110 outRect.set(Math.round(x), Math.round(y), 111 Math.round(x + outWidth), Math.round(y + outHeight)); 112 } 113 } 114