Home | History | Annotate | Download | only in util
      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