Controls UI - Move 'add controls' to popup menu

Add a new popup menu for add/edit/settings. Start with just
add. Change colors of the popup background to match specs. Hide drop
down structure switching if there's only 1 option

Bug: 151142664
Test: visual

Change-Id: I3077d2eda020e8f1ddd03eda343b062f90ee412b
This commit is contained in:
Matt Pietal
2020-03-20 12:58:54 -04:00
parent 5562d464c6
commit 5ebb7feff6
7 changed files with 144 additions and 21 deletions

View File

@@ -0,0 +1,24 @@
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

View File

@@ -0,0 +1,23 @@
<!--
~ Copyright (C) 2019 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Control.MenuItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="24dp"
android:layout_gravity="start" />

View File

@@ -17,7 +17,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp">
android:padding="8dp">
<LinearLayout
android:orientation="horizontal"

View File

@@ -51,6 +51,18 @@
android:layout_gravity="center" />
</LinearLayout>
<ImageView
android:id="@+id/controls_more"
android:src="@drawable/ic_more_vert"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:layout_marginEnd="@dimen/controls_list_side_margin"
android:tint="@color/control_more_vert"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout

View File

@@ -225,6 +225,7 @@
<color name="control_default_background">@color/GM2_grey_900</color>
<color name="control_list_popup_background">@*android:color/background_floating_material_dark</color>
<color name="control_spinner_dropdown">@*android:color/foreground_material_dark</color>
<color name="control_more_vert">@*android:color/foreground_material_dark</color>
<color name="control_enabled_light_background">@color/GM2_yellow_200</color>
<color name="control_enabled_thermo_heat_background">@color/GM2_red_200</color>
<color name="control_enabled_thermo_cool_background">@color/GM2_blue_200</color>

View File

@@ -659,6 +659,13 @@
<style name="Control" />
<style name="Control.MenuItem">
<item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
<item name="android:textSize">@dimen/control_text_size</item>
<item name="android:textColor">@color/control_primary_text</item>
<item name="android:singleLine">true</item>
</style>
<style name="Control.Spinner">
<item name="android:textSize">@dimen/control_header_text_size</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
@@ -696,7 +703,7 @@
<item name="android:overlapAnchor">true</item>
<!-- used to override dark/light theming -->
<item name="*android:colorPopupBackground">@color/control_list_popup_background</item>
<item name="*android:colorPopupBackground">@color/GM2_grey_900</item>
</style>
<style name="TextAppearance.ControlSetup">

View File

@@ -29,6 +29,7 @@ import android.util.Log
import android.view.ContextThemeWrapper
import android.view.LayoutInflater
import android.view.View
import android.view.View.MeasureSpec
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.AdapterView
@@ -210,6 +211,63 @@ class ControlsUiControllerImpl @Inject constructor (
createListView()
createDropDown(items)
createMenu()
}
private fun createPopup(): ListPopupWindow {
return ListPopupWindow(
ContextThemeWrapper(context, R.style.Control_ListPopupWindow)).apply {
setWindowLayoutType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
setModal(true)
}
}
private fun createMenu() {
val items = arrayOf(
context.resources.getString(R.string.controls_menu_add)
)
var adapter = ArrayAdapter<String>(context, R.layout.controls_more_item, items)
val anchor = parent.requireViewById<ImageView>(R.id.controls_more)
anchor.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
popup = createPopup().apply {
setAnchorView(anchor)
setAdapter(adapter)
setOnItemClickListener(object : AdapterView.OnItemClickListener {
override fun onItemClick(
parent: AdapterView<*>,
view: View,
pos: Int,
id: Long
) {
when (pos) {
// 0: Add Control
0 -> launchSelectorActivityListener(view.context)(parent)
else -> Log.w(ControlsUiController.TAG,
"Unsupported index ($pos) on 'more' menu selection")
}
dismiss()
}
})
// need to call show() first in order to construct the listView
show()
var width = 0
getListView()?.apply {
// width should be between [.5, .9] of screen
val parentWidth = this@ControlsUiControllerImpl.parent.getWidth()
val widthSpec = MeasureSpec.makeMeasureSpec(
(parentWidth * 0.9).toInt(), MeasureSpec.AT_MOST)
val child = adapter.getView(0, null, this)
child.measure(widthSpec, MeasureSpec.UNSPECIFIED)
width = Math.max(child.getMeasuredWidth(), (parentWidth * 0.5).toInt())
}
setWidth(width)
setHorizontalOffset(-width + anchor.getWidth())
show()
}
}
})
}
private fun createDropDown(items: List<SelectionItem>) {
@@ -224,7 +282,7 @@ class ControlsUiControllerImpl @Inject constructor (
val selectionItem = findSelectionItem(selectedStructure, itemsWithStructure) ?: items[0]
var adapter = ItemAdapter(context, R.layout.controls_spinner_item).apply {
addAll(itemsWithStructure + addControlsItem)
addAll(itemsWithStructure)
}
/*
@@ -232,7 +290,7 @@ class ControlsUiControllerImpl @Inject constructor (
* for this dialog. Use a textView with the ListPopupWindow to achieve
* a similar effect
*/
parent.requireViewById<TextView>(R.id.app_or_structure_spinner).apply {
val spinner = parent.requireViewById<TextView>(R.id.app_or_structure_spinner).apply {
setText(selectionItem.getTitle())
// override the default color on the dropdown drawable
(getBackground() as LayerDrawable).getDrawable(1)
@@ -242,16 +300,18 @@ class ControlsUiControllerImpl @Inject constructor (
setContentDescription(selectionItem.getTitle())
setImageDrawable(selectionItem.icon)
}
if (itemsWithStructure.size == 1) {
spinner.setBackground(null)
return
}
val anchor = parent.requireViewById<ViewGroup>(R.id.controls_header)
anchor.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
popup = ListPopupWindow(
ContextThemeWrapper(context, R.style.Control_ListPopupWindow))
popup?.apply {
setWindowLayoutType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
popup = createPopup().apply {
setAnchorView(anchor)
setAdapter(adapter)
setModal(true)
setOnItemClickListener(object : AdapterView.OnItemClickListener {
override fun onItemClick(
parent: AdapterView<*>,
@@ -329,19 +389,15 @@ class ControlsUiControllerImpl @Inject constructor (
}
private fun switchAppOrStructure(item: SelectionItem) {
if (item == addControlsItem) {
launchSelectorActivityListener(context)(parent)
} else {
val newSelection = allStructures.first {
it.structure == item.structure && it.componentName == item.componentName
}
val newSelection = allStructures.first {
it.structure == item.structure && it.componentName == item.componentName
}
if (newSelection != selectedStructure) {
selectedStructure = newSelection
updatePreferences(selectedStructure)
controlsListingController.get().removeCallback(listingCallback)
reload(parent)
}
if (newSelection != selectedStructure) {
selectedStructure = newSelection
updatePreferences(selectedStructure)
controlsListingController.get().removeCallback(listingCallback)
reload(parent)
}
}