Merge "Implementing keyboard indicator dialog" into tm-qpr-dev

This commit is contained in:
Christian Göllner
2023-03-08 10:35:50 +00:00
committed by Android (Google) Code Review
5 changed files with 287 additions and 6 deletions

View File

@@ -0,0 +1,12 @@
<vector android:height="11dp" android:viewportHeight="12"
android:viewportWidth="22" android:width="20.166666dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0,0.5h22v11h-22z"/>
<path android:fillColor="#231F20" android:pathData="M6.397,9.908H0V11.5H6.397V9.908Z"/>
<path android:fillColor="#231F20" android:pathData="M14.199,9.908H7.801V11.5H14.199V9.908Z"/>
<path android:fillColor="#231F20" android:pathData="M11.858,0.5H10.142V6.434H11.858V0.5Z"/>
<path android:fillColor="#231F20" android:pathData="M8.348,7.129L3.885,2.975L3.823,2.932L2.668,4.003L2.621,4.046L7.084,8.2L7.146,8.243L8.301,7.172L8.348,7.129Z"/>
<path android:fillColor="#231F20" android:pathData="M18.224,2.975L18.177,2.932L13.653,7.129L14.807,8.2L14.854,8.243L19.379,4.046L18.224,2.975Z"/>
<path android:fillColor="#231F20" android:pathData="M22,9.908H15.603V11.5H22V9.908Z"/>
</group>
</vector>

View File

@@ -207,6 +207,11 @@
<color name="control_thumbnail_shadow_color">@*android:color/black</color>
<color name="controls_task_view_bg">#CC191C1D</color>
<!-- Keyboard backlight indicator-->
<color name="backlight_indicator_step_filled">#F6E388</color>
<color name="backlight_indicator_step_empty">#494740</color>
<color name="backlight_indicator_background">#32302A</color>
<!-- Docked misalignment message -->
<color name="misalignment_text_color">#F28B82</color>

View File

@@ -1653,6 +1653,19 @@
<dimen name="media_output_broadcast_info_summary_height">20dp</dimen>
<dimen name="media_output_broadcast_info_edit">18dp</dimen>
<!-- Keyboard backlight indicator-->
<dimen name="backlight_indicator_root_corner_radius">48dp</dimen>
<dimen name="backlight_indicator_root_vertical_padding">8dp</dimen>
<dimen name="backlight_indicator_root_horizontal_padding">4dp</dimen>
<dimen name="backlight_indicator_icon_width">22dp</dimen>
<dimen name="backlight_indicator_icon_height">11dp</dimen>
<dimen name="backlight_indicator_icon_left_margin">2dp</dimen>
<dimen name="backlight_indicator_step_width">52dp</dimen>
<dimen name="backlight_indicator_step_height">40dp</dimen>
<dimen name="backlight_indicator_step_horizontal_margin">4dp</dimen>
<dimen name="backlight_indicator_step_small_radius">4dp</dimen>
<dimen name="backlight_indicator_step_large_radius">48dp</dimen>
<!-- Broadcast dialog -->
<dimen name="broadcast_dialog_title_img_margin_top">18dp</dimen>
<dimen name="broadcast_dialog_title_text_size">24sp</dimen>

View File

@@ -46,8 +46,15 @@ constructor(
viewModel.dialogContent.collect { dialogViewModel ->
if (dialogViewModel != null) {
if (dialog == null) {
dialog = KeyboardBacklightDialog(context, dialogViewModel)
// pass viewModel and show
dialog =
KeyboardBacklightDialog(
context,
initialCurrentLevel = dialogViewModel.currentValue,
initialMaxLevel = dialogViewModel.maxValue
)
dialog?.show()
} else {
dialog?.updateState(dialogViewModel.currentValue, dialogViewModel.maxValue)
}
} else {
dialog?.dismiss()

View File

@@ -17,16 +17,260 @@
package com.android.systemui.keyboard.backlight.ui.view
import android.annotation.ColorInt
import android.app.Dialog
import android.content.Context
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.os.Bundle
import com.android.systemui.keyboard.backlight.ui.viewmodel.BacklightDialogContentViewModel
import android.view.Gravity
import android.view.Window
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.LinearLayout.LayoutParams
import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
import com.android.systemui.R
import com.android.systemui.util.children
class KeyboardBacklightDialog(context: Context, val viewModel: BacklightDialogContentViewModel) :
Dialog(context) {
class KeyboardBacklightDialog(
context: Context,
initialCurrentLevel: Int,
initialMaxLevel: Int,
) : Dialog(context) {
private data class RootProperties(
val cornerRadius: Float,
val verticalPadding: Int,
val horizontalPadding: Int,
)
private data class BacklightIconProperties(
val width: Int,
val height: Int,
val leftMargin: Int,
)
private data class StepViewProperties(
val width: Int,
val height: Int,
val horizontalMargin: Int,
val smallRadius: Float,
val largeRadius: Float,
)
private var currentLevel: Int = 0
private var maxLevel: Int = 0
private lateinit var rootView: LinearLayout
private var dialogBottomMargin = 208
private lateinit var rootProperties: RootProperties
private lateinit var iconProperties: BacklightIconProperties
private lateinit var stepProperties: StepViewProperties
@ColorInt var filledRectangleColor: Int = 0
@ColorInt var emptyRectangleColor: Int = 0
@ColorInt var backgroundColor: Int = 0
init {
currentLevel = initialCurrentLevel
maxLevel = initialMaxLevel
}
override fun onCreate(savedInstanceState: Bundle?) {
setUpWindowProperties(this)
setWindowTitle()
updateResources()
rootView = buildRootView()
setContentView(rootView)
super.onCreate(savedInstanceState)
// TODO(b/268650355) Implement the dialog
updateState(currentLevel, maxLevel, forceRefresh = true)
}
private fun updateResources() {
context.resources.apply {
filledRectangleColor = getColor(R.color.backlight_indicator_step_filled)
emptyRectangleColor = getColor(R.color.backlight_indicator_step_empty)
backgroundColor = getColor(R.color.backlight_indicator_background)
rootProperties =
RootProperties(
cornerRadius =
getDimensionPixelSize(R.dimen.backlight_indicator_root_corner_radius)
.toFloat(),
verticalPadding =
getDimensionPixelSize(R.dimen.backlight_indicator_root_vertical_padding),
horizontalPadding =
getDimensionPixelSize(R.dimen.backlight_indicator_root_horizontal_padding)
)
iconProperties =
BacklightIconProperties(
width = getDimensionPixelSize(R.dimen.backlight_indicator_icon_width),
height = getDimensionPixelSize(R.dimen.backlight_indicator_icon_height),
leftMargin =
getDimensionPixelSize(R.dimen.backlight_indicator_icon_left_margin),
)
stepProperties =
StepViewProperties(
width = getDimensionPixelSize(R.dimen.backlight_indicator_step_width),
height = getDimensionPixelSize(R.dimen.backlight_indicator_step_height),
horizontalMargin =
getDimensionPixelSize(R.dimen.backlight_indicator_step_horizontal_margin),
smallRadius =
getDimensionPixelSize(R.dimen.backlight_indicator_step_small_radius)
.toFloat(),
largeRadius =
getDimensionPixelSize(R.dimen.backlight_indicator_step_large_radius)
.toFloat(),
)
}
}
fun updateState(current: Int, max: Int, forceRefresh: Boolean = false) {
if (maxLevel != max || forceRefresh) {
maxLevel = max
rootView.removeAllViews()
buildStepViews().forEach { rootView.addView(it) }
}
currentLevel = current
updateLevel()
}
private fun updateLevel() {
rootView.children.forEachIndexed(
action = { index, v ->
val drawable = v.background as ShapeDrawable
if (index <= currentLevel) {
updateColor(drawable, filledRectangleColor)
} else {
updateColor(drawable, emptyRectangleColor)
}
}
)
}
private fun updateColor(drawable: ShapeDrawable, @ColorInt color: Int) {
if (drawable.paint.color != color) {
drawable.paint.color = color
drawable.invalidateSelf()
}
}
private fun buildRootView(): LinearLayout {
val linearLayout =
LinearLayout(context).apply {
orientation = LinearLayout.HORIZONTAL
layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
setPadding(
/* left= */ rootProperties.horizontalPadding,
/* top= */ rootProperties.verticalPadding,
/* right= */ rootProperties.horizontalPadding,
/* bottom= */ rootProperties.verticalPadding
)
}
val drawable =
ShapeDrawable(
RoundRectShape(
/* outerRadii= */ FloatArray(8) { rootProperties.cornerRadius },
/* inset= */ null,
/* innerRadii= */ null
)
)
drawable.paint.color = backgroundColor
linearLayout.background = drawable
return linearLayout
}
private fun buildStepViews(): List<FrameLayout> {
val stepViews = (0..maxLevel).map { i -> createStepViewAt(i) }
stepViews[0].addView(createBacklightIconView())
return stepViews
}
private fun createStepViewAt(i: Int): FrameLayout {
return FrameLayout(context).apply {
layoutParams =
FrameLayout.LayoutParams(stepProperties.width, stepProperties.height).apply {
setMargins(
/* left= */ stepProperties.horizontalMargin,
/* top= */ 0,
/* right= */ stepProperties.horizontalMargin,
/* bottom= */ 0
)
}
val drawable =
ShapeDrawable(
RoundRectShape(
/* outerRadii= */ radiiForIndex(i, maxLevel),
/* inset= */ null,
/* innerRadii= */ null
)
)
drawable.paint.color = emptyRectangleColor
background = drawable
}
}
private fun createBacklightIconView(): ImageView {
return ImageView(context).apply {
setImageResource(R.drawable.ic_keyboard_backlight)
layoutParams =
FrameLayout.LayoutParams(iconProperties.width, iconProperties.height).apply {
gravity = Gravity.CENTER
leftMargin = iconProperties.leftMargin
}
}
}
private fun setWindowTitle() {
val attrs = window.attributes
// TODO(b/271796169): check if title needs to be a translatable resource.
attrs.title = "KeyboardBacklightDialog"
attrs?.y = dialogBottomMargin
window.attributes = attrs
}
private fun setUpWindowProperties(dialog: Dialog) {
val window = dialog.window
window.requestFeature(Window.FEATURE_NO_TITLE) // otherwise fails while creating actionBar
window.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL)
window.addFlags(
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
)
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
window.setBackgroundDrawableResource(android.R.color.transparent)
window.setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL)
setCanceledOnTouchOutside(true)
}
private fun radiiForIndex(i: Int, last: Int): FloatArray {
val smallRadius = stepProperties.smallRadius
val largeRadius = stepProperties.largeRadius
return when (i) {
0 -> // left radii bigger
floatArrayOf(
largeRadius,
largeRadius,
smallRadius,
smallRadius,
smallRadius,
smallRadius,
largeRadius,
largeRadius
)
last -> // right radii bigger
floatArrayOf(
smallRadius,
smallRadius,
largeRadius,
largeRadius,
largeRadius,
largeRadius,
smallRadius,
smallRadius
)
else -> FloatArray(8) { smallRadius } // all radii equal
}
}
}