1 /* 2 * Copyright (C) 2022 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 17 package com.android.launcher3.taskbar.navbutton 18 19 import android.content.res.Resources 20 import android.view.Surface.ROTATION_90 21 import android.view.Surface.Rotation 22 import android.view.ViewGroup 23 import android.widget.FrameLayout 24 import android.widget.LinearLayout 25 import com.android.launcher3.DeviceProfile 26 import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.* 27 import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.Companion 28 import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter 29 30 /** 31 * Select the correct layout for nav buttons 32 * 33 * Since layouts are done dynamically for the nav buttons on Taskbar, this class returns a 34 * corresponding [NavButtonLayoutter] via [Companion.getUiLayoutter] that can help position the 35 * buttons based on the current [DeviceProfile] 36 */ 37 class NavButtonLayoutFactory { 38 companion object { 39 /** 40 * Get the correct instance of [NavButtonLayoutter] 41 * 42 * No layouts supported for configurations where: 43 * * taskbar isn't showing AND 44 * * the device is not in [phoneMode] OR 45 * * phone is showing 46 * * device is using gesture navigation 47 * 48 * @param navButtonsView ViewGroup that contains start, end, nav button ViewGroups 49 * @param isKidsMode no-op when taskbar is hidden/not showing 50 * @param isInSetup no-op when taskbar is hidden/not showing 51 * @param phoneMode refers to the device using the taskbar window on phones 52 * @param isThreeButtonNav are no-ops when taskbar is present/showing 53 */ getUiLayoutternull54 fun getUiLayoutter( 55 deviceProfile: DeviceProfile, 56 navButtonsView: FrameLayout, 57 resources: Resources, 58 isKidsMode: Boolean, 59 isInSetup: Boolean, 60 isThreeButtonNav: Boolean, 61 phoneMode: Boolean, 62 @Rotation surfaceRotation: Int 63 ): NavButtonLayoutter { 64 val navButtonContainer = navButtonsView.findViewById<LinearLayout>(ID_END_NAV_BUTTONS) 65 val endContextualContainer = 66 navButtonsView.findViewById<ViewGroup>(ID_END_CONTEXTUAL_BUTTONS) 67 val startContextualContainer = 68 navButtonsView.findViewById<ViewGroup>(ID_START_CONTEXTUAL_BUTTONS) 69 val isPhoneNavMode = phoneMode && isThreeButtonNav 70 val isPhoneGestureMode = phoneMode && !isThreeButtonNav 71 return when { 72 isPhoneNavMode -> { 73 if (!deviceProfile.isLandscape) { 74 PhonePortraitNavLayoutter( 75 resources, 76 navButtonContainer, 77 endContextualContainer, 78 startContextualContainer 79 ) 80 } else if (surfaceRotation == ROTATION_90) { 81 PhoneLandscapeNavLayoutter( 82 resources, 83 navButtonContainer, 84 endContextualContainer, 85 startContextualContainer 86 ) 87 } else { 88 PhoneSeascapeNavLayoutter( 89 resources, 90 navButtonContainer, 91 endContextualContainer, 92 startContextualContainer 93 ) 94 } 95 } 96 isPhoneGestureMode ->{ 97 PhoneGestureLayoutter( 98 resources, 99 navButtonContainer, 100 endContextualContainer, 101 startContextualContainer 102 ) 103 } 104 deviceProfile.isTaskbarPresent -> { 105 return when { 106 isInSetup -> { 107 SetupNavLayoutter( 108 resources, 109 navButtonContainer, 110 endContextualContainer, 111 startContextualContainer 112 ) 113 } 114 isKidsMode -> { 115 KidsNavLayoutter( 116 resources, 117 navButtonContainer, 118 endContextualContainer, 119 startContextualContainer 120 ) 121 } 122 else -> 123 TaskbarNavLayoutter( 124 resources, 125 navButtonContainer, 126 endContextualContainer, 127 startContextualContainer 128 ) 129 } 130 } 131 else -> error("No layoutter found") 132 } 133 } 134 } 135 136 /** Lays out and provides access to the home, recents, and back buttons for various mischief */ 137 interface NavButtonLayoutter { layoutButtonsnull138 fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) 139 } 140 } 141