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.Gravity 21 import android.view.ViewGroup 22 import android.view.ViewGroup.LayoutParams.MATCH_PARENT 23 import android.widget.FrameLayout 24 import android.widget.ImageView 25 import android.widget.LinearLayout 26 import android.widget.Space 27 import com.android.launcher3.R 28 import com.android.launcher3.taskbar.TaskbarActivityContext 29 30 open class PhoneLandscapeNavLayoutter( 31 resources: Resources, 32 navBarContainer: LinearLayout, 33 endContextualContainer: ViewGroup, 34 startContextualContainer: ViewGroup, 35 imeSwitcher: ImageView?, 36 a11yButton: ImageView?, 37 space: Space? 38 ) : 39 AbstractNavButtonLayoutter( 40 resources, 41 navBarContainer, 42 endContextualContainer, 43 startContextualContainer, 44 imeSwitcher, 45 a11yButton, 46 space 47 ) { 48 layoutButtonsnull49 override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { 50 val totalHeight = context.deviceProfile.heightPx 51 val homeButtonHeight = 52 resources.getDimensionPixelSize(R.dimen.taskbar_phone_home_button_size) 53 val roundedCornerContentMargin = 54 resources.getDimensionPixelSize(R.dimen.taskbar_phone_rounded_corner_content_margin) 55 val contentPadding = resources.getDimensionPixelSize(R.dimen.taskbar_phone_content_padding) 56 val contentWidth = totalHeight - roundedCornerContentMargin * 2 - contentPadding * 2 57 58 // left:back:space(reserved for home):overview:right = 0.25:0.5:1:0.5:0.25 59 val contextualButtonHeight = contentWidth / (0.25f + 0.5f + 1f + 0.5f + 0.25f) * 0.25f 60 val sideButtonHeight = contextualButtonHeight * 2 61 val navButtonContainerHeight = contentWidth - contextualButtonHeight * 2 62 63 val navContainerParams = 64 FrameLayout.LayoutParams(MATCH_PARENT, navButtonContainerHeight.toInt()) 65 navContainerParams.apply { 66 topMargin = 67 (contextualButtonHeight + contentPadding + roundedCornerContentMargin).toInt() 68 bottomMargin = 69 (contextualButtonHeight + contentPadding + roundedCornerContentMargin).toInt() 70 marginEnd = 0 71 marginStart = 0 72 } 73 74 // Ensure order of buttons is correct 75 navButtonContainer.removeAllViews() 76 navButtonContainer.orientation = LinearLayout.VERTICAL 77 78 addThreeButtons() 79 80 navButtonContainer.layoutParams = navContainerParams 81 navButtonContainer.gravity = Gravity.CENTER 82 83 // Add the spaces in between the nav buttons 84 val spaceInBetween = 85 (navButtonContainerHeight - homeButtonHeight - sideButtonHeight * 2) / 2.0f 86 for (i in 0 until navButtonContainer.childCount) { 87 val navButton = navButtonContainer.getChildAt(i) 88 val buttonLayoutParams = navButton.layoutParams as LinearLayout.LayoutParams 89 val margin = (spaceInBetween / 2).toInt() 90 when (i) { 91 0 -> { 92 // First button 93 buttonLayoutParams.bottomMargin = margin 94 buttonLayoutParams.height = sideButtonHeight.toInt() 95 } 96 navButtonContainer.childCount - 1 -> { 97 // Last button 98 buttonLayoutParams.topMargin = margin 99 buttonLayoutParams.height = sideButtonHeight.toInt() 100 } 101 else -> { 102 // other buttons 103 buttonLayoutParams.topMargin = margin 104 buttonLayoutParams.bottomMargin = margin 105 buttonLayoutParams.height = homeButtonHeight 106 } 107 } 108 } 109 110 repositionContextualButtons(contextualButtonHeight.toInt()) 111 } 112 addThreeButtonsnull113 open fun addThreeButtons() { 114 // Swap recents and back button 115 navButtonContainer.addView(recentsButton) 116 navButtonContainer.addView(homeButton) 117 navButtonContainer.addView(backButton) 118 } 119 repositionContextualButtonsnull120 open fun repositionContextualButtons(buttonSize: Int) { 121 endContextualContainer.removeAllViews() 122 startContextualContainer.removeAllViews() 123 124 val roundedCornerContentMargin = 125 resources.getDimensionPixelSize(R.dimen.taskbar_phone_rounded_corner_content_margin) 126 val contentPadding = resources.getDimensionPixelSize(R.dimen.taskbar_phone_content_padding) 127 repositionContextualContainer( 128 startContextualContainer, 129 buttonSize, 130 roundedCornerContentMargin + contentPadding, 131 0, 132 Gravity.TOP 133 ) 134 repositionContextualContainer( 135 endContextualContainer, 136 buttonSize, 137 0, 138 roundedCornerContentMargin + contentPadding, 139 Gravity.BOTTOM 140 ) 141 142 if (imeSwitcher != null) { 143 startContextualContainer.addView(imeSwitcher) 144 imeSwitcher.layoutParams = getParamsToCenterView() 145 } 146 if (a11yButton != null) { 147 startContextualContainer.addView(a11yButton) 148 a11yButton.layoutParams = getParamsToCenterView() 149 } 150 endContextualContainer.addView(space, MATCH_PARENT, MATCH_PARENT) 151 } 152 repositionContextualContainernull153 override fun repositionContextualContainer( 154 contextualContainer: ViewGroup, 155 buttonSize: Int, 156 barAxisMarginTop: Int, 157 barAxisMarginBottom: Int, 158 gravity: Int 159 ) { 160 val contextualContainerParams = FrameLayout.LayoutParams(MATCH_PARENT, buttonSize) 161 contextualContainerParams.apply { 162 marginStart = 0 163 marginEnd = 0 164 topMargin = barAxisMarginTop 165 bottomMargin = barAxisMarginBottom 166 } 167 contextualContainerParams.gravity = gravity or Gravity.CENTER_HORIZONTAL 168 contextualContainer.layoutParams = contextualContainerParams 169 } 170 } 171