Files
Lawnchair/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt
T
Jon Miranda 1d7ac8b8a7 Remove padding from All Apps and Divider views.
Bug: 375661139
Test: confirmed with design team
Flag: EXEMPT bugfix
Change-Id: I0f9cce376d47918e69a65ed288f10143930ee3be
2024-11-21 09:21:57 -08:00

144 lines
5.7 KiB
Kotlin

/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.taskbar.customization
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color.TRANSPARENT
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import androidx.annotation.DimenRes
import androidx.annotation.DrawableRes
import com.android.launcher3.R
import com.android.launcher3.Utilities.dpToPx
import com.android.launcher3.config.FeatureFlags.enableTaskbarPinning
import com.android.launcher3.taskbar.TaskbarActivityContext
import com.android.launcher3.taskbar.TaskbarViewCallbacks
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.launcher3.views.ActivityContext
import com.android.launcher3.views.IconButtonView
import com.android.quickstep.DeviceConfigWrapper
import com.android.quickstep.util.ContextualSearchStateManager
/** Taskbar all apps button container for customizable taskbar. */
class TaskbarAllAppsButtonContainer
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
IconButtonView(context, attrs), TaskbarContainer {
private val activityContext: TaskbarActivityContext = ActivityContext.lookupContext(context)
private var allAppsTouchTriggered = false
private var allAppsTouchRunnable: Runnable? = null
private var allAppsButtonTouchDelayMs: Long = ViewConfiguration.getLongPressTimeout().toLong()
private lateinit var taskbarViewCallbacks: TaskbarViewCallbacks
override val spaceNeeded: Int
get() {
return dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat())
}
init {
contentDescription = context.getString(R.string.all_apps_button_label)
setUpIcon()
}
@SuppressLint("UseCompatLoadingForDrawables", "ResourceAsColor")
private fun setUpIcon() {
val drawable =
resources.getDrawable(
getAllAppsButton(activityContext.taskbarFeatureEvaluator.isTransient)
)
backgroundTintList = ColorStateList.valueOf(TRANSPARENT)
setIconDrawable(drawable)
setForegroundTint(activityContext.getColor(R.color.all_apps_button_color))
}
@SuppressLint("ClickableViewAccessibility")
fun setUpCallbacks(callbacks: TaskbarViewCallbacks) {
taskbarViewCallbacks = callbacks
setOnClickListener(this::onAllAppsButtonClick)
setOnLongClickListener(this::onAllAppsButtonLongClick)
setOnTouchListener(this::onAllAppsButtonTouch)
isHapticFeedbackEnabled =
taskbarViewCallbacks.isAllAppsButtonHapticFeedbackEnabled(mContext)
allAppsTouchRunnable = Runnable {
taskbarViewCallbacks.triggerAllAppsButtonLongClick()
allAppsTouchTriggered = true
}
val contextualSearchStateManager = ContextualSearchStateManager.INSTANCE[mContext]
if (
DeviceConfigWrapper.get().customLpaaThresholds &&
contextualSearchStateManager.lpnhDurationMillis.isPresent
) {
allAppsButtonTouchDelayMs = contextualSearchStateManager.lpnhDurationMillis.get()
}
}
@DrawableRes
private fun getAllAppsButton(isTransientTaskbar: Boolean): Int {
val shouldSelectTransientIcon =
isTransientTaskbar || (enableTaskbarPinning() && !activityContext.isThreeButtonNav)
return if (shouldSelectTransientIcon) R.drawable.ic_transient_taskbar_all_apps_search_button
else R.drawable.ic_taskbar_all_apps_search_button
}
@DimenRes
fun getAllAppsButtonTranslationXOffset(isTransientTaskbar: Boolean): Int {
return if (isTransientTaskbar) {
R.dimen.transient_taskbar_all_apps_button_translation_x_offset
} else {
R.dimen.taskbar_all_apps_search_button_translation_x_offset
}
}
private fun onAllAppsButtonTouch(view: View, ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
allAppsTouchTriggered = false
MAIN_EXECUTOR.handler.postDelayed(allAppsTouchRunnable!!, allAppsButtonTouchDelayMs)
}
MotionEvent.ACTION_UP,
MotionEvent.ACTION_CANCEL -> cancelAllAppsButtonTouch()
}
return false
}
private fun cancelAllAppsButtonTouch() {
MAIN_EXECUTOR.handler.removeCallbacks(allAppsTouchRunnable!!)
// ACTION_UP is first triggered, then click listener / long-click listener is triggered on
// the next frame, so we need to post twice and delay the reset.
this.post { this.post { allAppsTouchTriggered = false } }
}
private fun onAllAppsButtonClick(view: View) {
if (!allAppsTouchTriggered) {
taskbarViewCallbacks.triggerAllAppsButtonClick(view)
}
}
// Handle long click from Switch Access and Voice Access
private fun onAllAppsButtonLongClick(view: View): Boolean {
if (!MAIN_EXECUTOR.handler.hasCallbacks(allAppsTouchRunnable!!) && !allAppsTouchTriggered) {
taskbarViewCallbacks.triggerAllAppsButtonLongClick()
}
return true
}
}