Merge "Controls UI - Marquee + dynamic column count" into rvc-dev am: f241f95205
Change-Id: I237fd5f26f834c1f65ce5ca3397bd31721792f00
This commit is contained in:
@@ -40,29 +40,20 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.Control.Status"
|
||||
android:paddingTop="@dimen/control_padding_adjustment"
|
||||
android:paddingStart="@dimen/control_status_padding"
|
||||
android:clickable="false"
|
||||
android:clickable="true"
|
||||
android:focusable="false"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
android:marqueeRepeatLimit = "marquee_forever"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/icon"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_extra"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.Control.Status"
|
||||
android:paddingTop="@dimen/control_padding_adjustment"
|
||||
android:paddingStart="@dimen/control_status_padding"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/icon"
|
||||
app:layout_constraintStart_toEndOf="@+id/status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -67,9 +67,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginRight="@dimen/global_actions_grid_horizontal_padding"
|
||||
android:layout_marginLeft="@dimen/global_actions_grid_horizontal_padding"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.globalactions.MinHeightScrollView>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -31,4 +31,7 @@
|
||||
|
||||
<!-- orientation of the dead zone when touches have recently occurred elsewhere on screen -->
|
||||
<integer name="navigation_bar_deadzone_orientation">1</integer>
|
||||
|
||||
<!-- Max number of columns for quick controls area -->
|
||||
<integer name="controls_max_columns">4</integer>
|
||||
</resources>
|
||||
|
||||
@@ -30,5 +30,7 @@
|
||||
<dimen name="global_actions_grid_item_icon_side_margin">22dp</dimen>
|
||||
<dimen name="global_actions_grid_item_icon_bottom_margin">4dp</dimen>
|
||||
|
||||
<!-- Home Controls -->
|
||||
<dimen name="controls_list_side_margin">10dp</dimen>
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -26,5 +26,7 @@
|
||||
navigation_extra_key_width -->
|
||||
<dimen name="navigation_side_padding">40dip</dimen>
|
||||
|
||||
<!-- Home Controls -->
|
||||
<dimen name="controls_list_side_margin">12dp</dimen>
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -30,5 +30,7 @@
|
||||
<dimen name="global_actions_grid_item_icon_side_margin">22dp</dimen>
|
||||
<dimen name="global_actions_grid_item_icon_bottom_margin">4dp</dimen>
|
||||
|
||||
<!-- Home Controls -->
|
||||
<dimen name="controls_list_side_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -533,4 +533,12 @@
|
||||
This config value should contain the package name of that preferred application.
|
||||
-->
|
||||
<string translatable="false" name="config_controlsPreferredPackage"></string>
|
||||
|
||||
<!-- Max number of columns for quick controls area -->
|
||||
<integer name="controls_max_columns">2</integer>
|
||||
<!-- If the dp width of the available space is <= this value, potentially adjust the number
|
||||
of columns-->
|
||||
<integer name="controls_max_columns_adjust_below_width_dp">320</integer>
|
||||
<!-- If the config font scale is >= this value, potentially adjust the number of columns-->
|
||||
<item name="controls_max_columns_adjust_above_font_scale" translatable="false" format="float" type="dimen">1.25</item>
|
||||
</resources>
|
||||
|
||||
@@ -51,7 +51,6 @@ class ControlViewHolder(
|
||||
) {
|
||||
val icon: ImageView = layout.requireViewById(R.id.icon)
|
||||
val status: TextView = layout.requireViewById(R.id.status)
|
||||
val statusExtra: TextView = layout.requireViewById(R.id.status_extra)
|
||||
val title: TextView = layout.requireViewById(R.id.title)
|
||||
val subtitle: TextView = layout.requireViewById(R.id.subtitle)
|
||||
val context: Context = layout.getContext()
|
||||
@@ -65,6 +64,8 @@ class ControlViewHolder(
|
||||
val ld = layout.getBackground() as LayerDrawable
|
||||
ld.mutate()
|
||||
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) as ClipDrawable
|
||||
// needed for marquee to start
|
||||
status.setSelected(true)
|
||||
}
|
||||
|
||||
fun bindData(cws: ControlWithState) {
|
||||
@@ -103,8 +104,7 @@ class ControlViewHolder(
|
||||
|
||||
behavior?.bind(cws)
|
||||
|
||||
layout.setContentDescription(
|
||||
"${title.text} ${subtitle.text} ${status.text} ${statusExtra.text}")
|
||||
layout.setContentDescription("${title.text} ${subtitle.text} ${status.text}")
|
||||
}
|
||||
|
||||
fun actionResponse(@ControlAction.ResponseResult response: Int) {
|
||||
@@ -113,15 +113,12 @@ class ControlViewHolder(
|
||||
|
||||
fun setTransientStatus(tempStatus: String) {
|
||||
val previousText = status.getText()
|
||||
val previousTextExtra = statusExtra.getText()
|
||||
|
||||
cancelUpdate = uiExecutor.executeDelayed({
|
||||
status.setText(previousText)
|
||||
statusExtra.setText(previousTextExtra)
|
||||
}, UPDATE_DELAY_IN_MILLIS)
|
||||
|
||||
status.setText(tempStatus)
|
||||
statusExtra.setText("")
|
||||
}
|
||||
|
||||
fun action(action: ControlAction) {
|
||||
@@ -154,7 +151,6 @@ class ControlViewHolder(
|
||||
}
|
||||
|
||||
status.setTextColor(fg)
|
||||
statusExtra.setTextColor(fg)
|
||||
|
||||
icon.setImageDrawable(ri.icon)
|
||||
|
||||
|
||||
@@ -21,10 +21,12 @@ import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.service.controls.Control
|
||||
import android.service.controls.actions.ControlAction
|
||||
import android.util.TypedValue
|
||||
import android.util.Log
|
||||
import android.view.ContextThemeWrapper
|
||||
import android.view.LayoutInflater
|
||||
@@ -345,10 +347,12 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
val inflater = LayoutInflater.from(context)
|
||||
inflater.inflate(R.layout.controls_with_favorites, parent, true)
|
||||
|
||||
val maxColumns = findMaxColumns()
|
||||
|
||||
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
|
||||
var lastRow: ViewGroup = createRow(inflater, listView)
|
||||
selectedStructure.controls.forEach {
|
||||
if (lastRow.getChildCount() == 2) {
|
||||
if (lastRow.getChildCount() == maxColumns) {
|
||||
lastRow = createRow(inflater, listView)
|
||||
}
|
||||
val baseLayout = inflater.inflate(
|
||||
@@ -365,12 +369,40 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
controlViewsById.put(key, cvh)
|
||||
}
|
||||
|
||||
// add spacer if necessary to keep control size consistent
|
||||
if ((selectedStructure.controls.size % 2) == 1) {
|
||||
// add spacers if necessary to keep control size consistent
|
||||
var spacersToAdd = selectedStructure.controls.size % maxColumns
|
||||
while (spacersToAdd > 0) {
|
||||
lastRow.addView(Space(context), LinearLayout.LayoutParams(0, 0, 1f))
|
||||
spacersToAdd--
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For low-dp width screens that also employ an increased font scale, adjust the
|
||||
* number of columns. This helps prevent text truncation on these devices.
|
||||
*/
|
||||
private fun findMaxColumns(): Int {
|
||||
val res = context.resources
|
||||
var maxColumns = res.getInteger(R.integer.controls_max_columns)
|
||||
val maxColumnsAdjustWidth =
|
||||
res.getInteger(R.integer.controls_max_columns_adjust_below_width_dp)
|
||||
|
||||
val outValue = TypedValue()
|
||||
res.getValue(R.dimen.controls_max_columns_adjust_above_font_scale, outValue, true)
|
||||
val maxColumnsAdjustFontScale = outValue.getFloat()
|
||||
|
||||
val config = res.configuration
|
||||
val isPortrait = config.orientation == Configuration.ORIENTATION_PORTRAIT
|
||||
if (isPortrait &&
|
||||
config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED &&
|
||||
config.screenWidthDp <= maxColumnsAdjustWidth &&
|
||||
config.fontScale >= maxColumnsAdjustFontScale) {
|
||||
maxColumns--
|
||||
}
|
||||
|
||||
return maxColumns
|
||||
}
|
||||
|
||||
private fun loadPreference(structures: List<StructureInfo>): StructureInfo {
|
||||
if (structures.isEmpty()) return EMPTY_STRUCTURE
|
||||
|
||||
|
||||
@@ -47,9 +47,10 @@ class ToggleRangeBehavior : Behavior {
|
||||
lateinit var control: Control
|
||||
lateinit var cvh: ControlViewHolder
|
||||
lateinit var rangeTemplate: RangeTemplate
|
||||
lateinit var statusExtra: TextView
|
||||
lateinit var status: TextView
|
||||
lateinit var context: Context
|
||||
var currentStatusText: CharSequence = ""
|
||||
var currentRangeValue: String = ""
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_FORMAT = "%.1f"
|
||||
@@ -83,8 +84,8 @@ class ToggleRangeBehavior : Behavior {
|
||||
override fun bind(cws: ControlWithState) {
|
||||
this.control = cws.control!!
|
||||
|
||||
statusExtra = cvh.statusExtra
|
||||
status.setText(control.getStatusText())
|
||||
currentStatusText = control.getStatusText()
|
||||
status.setText(currentStatusText)
|
||||
|
||||
val ld = cvh.layout.getBackground() as LayerDrawable
|
||||
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
|
||||
@@ -96,7 +97,7 @@ class ToggleRangeBehavior : Behavior {
|
||||
val checked = template.isChecked()
|
||||
val currentRatio = rangeTemplate.getCurrentValue() /
|
||||
(rangeTemplate.getMaxValue() - rangeTemplate.getMinValue())
|
||||
updateRange(currentRatio, checked)
|
||||
updateRange(currentRatio, checked, /* isDragging */ false)
|
||||
|
||||
cvh.applyRenderInfo(checked)
|
||||
|
||||
@@ -147,7 +148,7 @@ class ToggleRangeBehavior : Behavior {
|
||||
AccessibilityNodeInfo.ACTION_ARGUMENT_PROGRESS_VALUE)
|
||||
val ratioDiff = (value - rangeTemplate.getCurrentValue()) /
|
||||
(rangeTemplate.getMaxValue() - rangeTemplate.getMinValue())
|
||||
updateRange(ratioDiff, template.isChecked())
|
||||
updateRange(ratioDiff, template.isChecked(), /* isDragging */ false)
|
||||
endUpdateRange()
|
||||
true
|
||||
}
|
||||
@@ -167,26 +168,27 @@ class ToggleRangeBehavior : Behavior {
|
||||
}
|
||||
|
||||
fun beginUpdateRange() {
|
||||
status.setVisibility(View.GONE)
|
||||
statusExtra.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources()
|
||||
status.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.control_status_expanded).toFloat())
|
||||
}
|
||||
|
||||
fun updateRange(ratioDiff: Float, checked: Boolean) {
|
||||
fun updateRange(ratioDiff: Float, checked: Boolean, isDragging: Boolean) {
|
||||
val changeAmount = if (checked) (MAX_LEVEL * ratioDiff).toInt() else MIN_LEVEL
|
||||
val newLevel = Math.max(MIN_LEVEL, Math.min(MAX_LEVEL, clipLayer.getLevel() + changeAmount))
|
||||
clipLayer.setLevel(newLevel)
|
||||
|
||||
if (checked) {
|
||||
val newValue = levelToRangeValue(clipLayer.getLevel())
|
||||
val formattedNewValue = format(rangeTemplate.getFormatString().toString(),
|
||||
currentRangeValue = format(rangeTemplate.getFormatString().toString(),
|
||||
DEFAULT_FORMAT, newValue)
|
||||
|
||||
statusExtra.setText(formattedNewValue)
|
||||
statusExtra.setVisibility(View.VISIBLE)
|
||||
val text = if (isDragging) {
|
||||
currentRangeValue
|
||||
} else {
|
||||
"$currentStatusText $currentRangeValue"
|
||||
}
|
||||
status.setText(text)
|
||||
} else {
|
||||
statusExtra.setText("")
|
||||
statusExtra.setVisibility(View.GONE)
|
||||
status.setText(currentStatusText)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,9 +212,9 @@ class ToggleRangeBehavior : Behavior {
|
||||
}
|
||||
|
||||
fun endUpdateRange() {
|
||||
statusExtra.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources()
|
||||
status.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.control_status_normal).toFloat())
|
||||
status.setVisibility(View.VISIBLE)
|
||||
status.setText("$currentStatusText $currentRangeValue")
|
||||
cvh.action(FloatAction(rangeTemplate.getTemplateId(),
|
||||
findNearestStep(levelToRangeValue(clipLayer.getLevel()))))
|
||||
}
|
||||
@@ -260,7 +262,8 @@ class ToggleRangeBehavior : Behavior {
|
||||
isDragging = true
|
||||
}
|
||||
|
||||
this@ToggleRangeBehavior.updateRange(-xDiff / v.getWidth(), true)
|
||||
this@ToggleRangeBehavior.updateRange(-xDiff / v.getWidth(),
|
||||
/* checked */ true, /* isDragging */ true)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user