Merge "Implementing keyboard indicator dialog" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
19f6c52f6f
12
packages/SystemUI/res/drawable/ic_keyboard_backlight.xml
Normal file
12
packages/SystemUI/res/drawable/ic_keyboard_backlight.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user