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.WRAP_CONTENT 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 /** Layoutter for rendering task bar in large screen, both in 3-button and gesture nav mode. */ 31 class TaskbarNavLayoutter( 32 resources: Resources, 33 navBarContainer: LinearLayout, 34 endContextualContainer: ViewGroup, 35 startContextualContainer: ViewGroup, 36 imeSwitcher: ImageView?, 37 a11yButton: ImageView?, 38 space: Space? 39 ) : 40 AbstractNavButtonLayoutter( 41 resources, 42 navBarContainer, 43 endContextualContainer, 44 startContextualContainer, 45 imeSwitcher, 46 a11yButton, 47 space 48 ) { 49 layoutButtonsnull50 override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { 51 // Add spacing after the end of the last nav button 52 var navMarginEnd = 53 resources.getDimension(context.deviceProfile.inv.inlineNavButtonsEndSpacing).toInt() 54 55 val cutout = context.display.cutout 56 val bottomRect = cutout?.boundingRectBottom 57 if (bottomRect != null && !bottomRect.isEmpty) { 58 navMarginEnd = bottomRect.width() 59 } 60 61 val contextualWidth = endContextualContainer.width 62 // If contextual buttons are showing, we check if the end margin is enough for the 63 // contextual button to be showing - if not, move the nav buttons over a smidge 64 if (isA11yButtonPersistent && navMarginEnd < contextualWidth) { 65 // Additional spacing, eat up half of space between last icon and nav button 66 navMarginEnd += resources.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2 67 } 68 69 val navButtonParams = 70 FrameLayout.LayoutParams( 71 FrameLayout.LayoutParams.WRAP_CONTENT, 72 ViewGroup.LayoutParams.MATCH_PARENT 73 ) 74 navButtonParams.apply { 75 gravity = Gravity.END or Gravity.CENTER_VERTICAL 76 marginEnd = navMarginEnd 77 } 78 navButtonContainer.orientation = LinearLayout.HORIZONTAL 79 navButtonContainer.layoutParams = navButtonParams 80 81 // Add the spaces in between the nav buttons 82 val spaceInBetween = resources.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween) 83 for (i in 0 until navButtonContainer.childCount) { 84 val navButton = navButtonContainer.getChildAt(i) 85 val buttonLayoutParams = navButton.layoutParams as LinearLayout.LayoutParams 86 buttonLayoutParams.weight = 0f 87 when (i) { 88 0 -> { 89 buttonLayoutParams.marginEnd = spaceInBetween / 2 90 } 91 navButtonContainer.childCount - 1 -> { 92 buttonLayoutParams.marginStart = spaceInBetween / 2 93 } 94 else -> { 95 buttonLayoutParams.marginStart = spaceInBetween / 2 96 buttonLayoutParams.marginEnd = spaceInBetween / 2 97 } 98 } 99 } 100 101 endContextualContainer.removeAllViews() 102 startContextualContainer.removeAllViews() 103 104 if (!context.deviceProfile.isGestureMode) { 105 val contextualMargin = 106 resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_padding) 107 repositionContextualContainer(endContextualContainer, WRAP_CONTENT, 0, 0, Gravity.END) 108 repositionContextualContainer( 109 startContextualContainer, 110 WRAP_CONTENT, 111 contextualMargin, 112 contextualMargin, 113 Gravity.START 114 ) 115 116 if (imeSwitcher != null) { 117 val imeStartMargin = 118 resources.getDimensionPixelSize( 119 R.dimen.taskbar_ime_switcher_button_margin_start 120 ) 121 startContextualContainer.addView(imeSwitcher) 122 val imeSwitcherButtonParams = 123 FrameLayout.LayoutParams( 124 FrameLayout.LayoutParams.MATCH_PARENT, 125 ViewGroup.LayoutParams.MATCH_PARENT 126 ) 127 imeSwitcherButtonParams.apply { 128 marginStart = imeStartMargin 129 gravity = Gravity.CENTER_VERTICAL 130 } 131 imeSwitcher.layoutParams = imeSwitcherButtonParams 132 } 133 if (a11yButton != null) { 134 endContextualContainer.addView(a11yButton) 135 a11yButton.layoutParams = getParamsToCenterView() 136 } 137 } 138 } 139 } 140