Merge "Added dependencies in ThemePicker for packagenotifier" into main
diff --git a/res/drawable/ic_clock_filled_24px.xml b/res/drawable/ic_clock_filled_24px.xml
new file mode 100644
index 0000000..0d587d7
--- /dev/null
+++ b/res/drawable/ic_clock_filled_24px.xml
@@ -0,0 +1,18 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal">
+ <path android:fillColor="@android:color/white" android:pathData="M612,668L668,612L520,464L520,280L440,280L440,496L612,668ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_style_filled_24px.xml b/res/drawable/ic_style_filled_24px.xml
deleted file mode 100644
index 0b9ec32..0000000
--- a/res/drawable/ic_style_filled_24px.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ 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.
- ~
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal">
- <path android:fillColor="@android:color/white" android:pathData="M159,792L125,778Q94,765 83.5,733Q73,701 87,670L159,514L159,792ZM319,880Q286,880 262.5,856.5Q239,833 239,800L239,560L345,854Q348,861 351,867.5Q354,874 359,880L319,880ZM525,876Q493,888 463,873Q433,858 421,826L243,338Q231,306 245,275.5Q259,245 291,234L593,124Q625,112 655,127Q685,142 697,174L875,662Q887,694 873,724.5Q859,755 827,766L525,876ZM439,400Q456,400 467.5,388.5Q479,377 479,360Q479,343 467.5,331.5Q456,320 439,320Q422,320 410.5,331.5Q399,343 399,360Q399,377 410.5,388.5Q422,400 439,400Z"/>
-</vector>
\ No newline at end of file
diff --git a/res/layout/clock_font_axis_name.xml b/res/layout/clock_font_axis_name.xml
deleted file mode 100644
index dd29c6b..0000000
--- a/res/layout/clock_font_axis_name.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ 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.
- -->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/clock_axis_name"
- android:layout_width="@dimen/clock_font_axis_name_width"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical" />
\ No newline at end of file
diff --git a/res/layout/clock_font_axis_slider_row.xml b/res/layout/clock_font_axis_slider_row.xml
deleted file mode 100644
index cb663b4..0000000
--- a/res/layout/clock_font_axis_slider_row.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ 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.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingVertical="@dimen/clock_axis_control_row_vertical_padding"
- android:orientation="horizontal">
- <include layout="@layout/clock_font_axis_name" />
-
- <SeekBar
- android:id="@+id/clock_axis_slider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:paddingStart="@dimen/clock_axis_control_padding_start"
- android:minHeight="@dimen/touch_target_min_height"
- android:thumb="@null"
- android:background="@null"
- android:splitTrack="false"
- android:progressDrawable="@drawable/saturation_progress_drawable" />
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/clock_font_axis_switch.xml b/res/layout/clock_font_axis_switch.xml
deleted file mode 100644
index 385d105..0000000
--- a/res/layout/clock_font_axis_switch.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ 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.
- -->
-
-<Switch xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/clock_axis_switch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/clock_axis_control_padding_start"
- style="@style/Switch.SettingsLib" />
\ No newline at end of file
diff --git a/res/layout/clock_font_axis_switch_row.xml b/res/layout/clock_font_axis_switch_row.xml
deleted file mode 100644
index 139e5e0..0000000
--- a/res/layout/clock_font_axis_switch_row.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ 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.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingVertical="@dimen/clock_axis_control_row_vertical_padding"
- android:orientation="horizontal">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/clock_switch_one"
- android:orientation="horizontal">
-
- <include layout="@layout/clock_font_axis_name" />
- <include layout="@layout/clock_font_axis_switch" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/clock_switch_two"
- android:orientation="horizontal"
- android:visibility="gone">
-
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:src="@drawable/clock_font_switch_divider"
- android:layout_marginHorizontal="@dimen/clock_font_control_switch_padding_horizontal"
- android:layout_gravity="center_vertical"/>
-
- <include layout="@layout/clock_font_axis_name" />
- <include layout="@layout/clock_font_axis_switch" />
- </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/clock_style_option.xml b/res/layout/clock_style_option.xml
index 27fe597..e251c4a 100644
--- a/res/layout/clock_style_option.xml
+++ b/res/layout/clock_style_option.xml
@@ -14,47 +14,43 @@
limitations under the License.
-->
<!-- Content description is set programmatically on the parent FrameLayout -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/floating_sheet_clock_style_option_size"
- android:layout_height="@dimen/floating_sheet_clock_style_option_size"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/floating_sheet_clock_style_option_width"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_height"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:clipToPadding="false"
android:clipChildren="false">
- <ImageView
- android:id="@id/selection_border"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/option_item_border"
- android:alpha="0"
- android:importantForAccessibility="no" />
-
- <ImageView
+ <com.android.wallpaper.picker.option.ui.view.OptionItemBackground
android:id="@id/background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/option_item_background"
- android:importantForAccessibility="no" />
+ android:layout_width="@dimen/floating_sheet_clock_style_option_background_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_background_size"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:importantForAccessibility="no"
+ android:layout_gravity="bottom" />
- <FrameLayout
+
+ <ImageView
android:id="@+id/foreground"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_width="@dimen/floating_sheet_clock_style_option_thumbnail_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_thumbnail_size"
+ android:layout_marginBottom="@dimen/floating_sheet_clock_style_thumbnail_margin_bottom"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:src="@drawable/ic_clock_24px" />
- <ImageView
- android:id="@+id/clock_icon"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="@dimen/floating_sheet_clock_style_thumbnail_margin"
- android:src="@drawable/ic_clock_24px" />
-
- <ImageView
- android:id="@+id/edit_icon"
- android:layout_width="@dimen/floating_sheet_clock_edit_icon_size"
- android:layout_height="@dimen/floating_sheet_clock_edit_icon_size"
- android:layout_marginTop="-16dp"
- android:layout_marginLeft="50dp"
- android:src="@drawable/edit_icon"/>
-
- </FrameLayout>
-</FrameLayout>
+ <ImageView
+ android:id="@+id/edit_icon"
+ android:layout_width="@dimen/floating_sheet_clock_edit_icon_size"
+ android:layout_height="@dimen/floating_sheet_clock_edit_icon_size"
+ android:layout_marginTop="@dimen/floating_sheet_clock_edit_icon_margin"
+ android:layout_marginEnd="@dimen/floating_sheet_clock_edit_icon_margin"
+ android:src="@drawable/edit_icon"
+ app:layout_constraintEnd_toEndOf="@+id/background"
+ app:layout_constraintTop_toTopOf="@+id/background"
+ android:importantForAccessibility="no" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/clock_style_option2.xml b/res/layout/clock_style_option2.xml
deleted file mode 100644
index 8bb60d1..0000000
--- a/res/layout/clock_style_option2.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- 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.
--->
-<!-- Content description is set programmatically on the parent FrameLayout -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:clipToPadding="false"
- android:clipChildren="false">
-
- <com.android.wallpaper.picker.option.ui.view.OptionItemBackground
- android:id="@id/background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:importantForAccessibility="no" />
-
- <ImageView
- android:id="@+id/foreground"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="@dimen/floating_sheet_clock_style_thumbnail_margin"
- android:src="@drawable/ic_clock_24px" />
-
- <ImageView
- android:id="@+id/edit_icon"
- android:layout_width="@dimen/floating_sheet_clock_edit_icon_size"
- android:layout_height="@dimen/floating_sheet_clock_edit_icon_size"
- android:layout_marginTop="-16dp"
- android:layout_marginStart="50dp"
- android:src="@drawable/edit_icon"
- android:importantForAccessibility="no" />
-</FrameLayout>
-
diff --git a/res/layout/customization_option_entry_clock.xml b/res/layout/customization_option_entry_clock.xml
index c302965..f677a1e 100644
--- a/res/layout/customization_option_entry_clock.xml
+++ b/res/layout/customization_option_entry_clock.xml
@@ -30,18 +30,24 @@
android:text="@string/clock_title"
android:layout_marginEnd="@dimen/customization_option_entry_text_margin_end"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/option_entry_clock_icon"
+ app:layout_constraintEnd_toStartOf="@+id/option_entry_clock_icon_container"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<FrameLayout
- android:id="@+id/option_entry_clock_icon"
+ android:id="@+id/option_entry_clock_icon_container"
android:layout_width="@dimen/customization_option_entry_icon_size"
android:layout_height="@dimen/customization_option_entry_icon_size"
- android:orientation="horizontal"
android:background="@drawable/customization_option_entry_icon_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent" />
+ app:layout_constraintBottom_toBottomOf="parent">
+
+ <ImageView
+ android:id="@+id/option_entry_clock_icon"
+ android:layout_width="@dimen/customization_option_entry_clock_icon_size"
+ android:layout_height="@dimen/customization_option_entry_clock_icon_size"
+ android:layout_gravity="center"/>
+ </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/floating_sheet_clock.xml b/res/layout/floating_sheet_clock.xml
index cdaf3de..93cf24b 100644
--- a/res/layout/floating_sheet_clock.xml
+++ b/res/layout/floating_sheet_clock.xml
@@ -17,8 +17,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
android:paddingHorizontal="@dimen/floating_sheet_horizontal_padding"
android:orientation="vertical">
@@ -26,190 +24,70 @@
android:id="@+id/clock_floating_sheet_content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
android:background="@drawable/floating_sheet_content_background"
android:clipToPadding="false"
android:clipChildren="false">
- <androidx.constraintlayout.widget.ConstraintLayout
+ <include
+ layout="@layout/floating_sheet_clock_style_content"
android:id="@+id/clock_floating_sheet_style_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipToPadding="false"
- android:clipChildren="false">
+ android:layout_height="wrap_content" />
- <FrameLayout
- android:id="@+id/clock_style_list_container"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_title"
- android:layout_marginBottom="8dp"
- android:clipToPadding="false"
- android:clipChildren="false">
-
- <!--
- This is an invisible placeholder put in place so that the parent keeps its height
- stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
- the layout logic to keep the size of the preview container stable as well, which
- bodes well for setting up the SurfaceView for remote rendering without changing its
- size after the content is loaded into the RecyclerView.
-
- It's critical for any TextViews inside the included layout to have text.
- -->
- <include
- layout="@layout/clock_style_option"
- android:layout_width="@dimen/floating_sheet_clock_style_option_size"
- android:layout_height="@dimen/floating_sheet_clock_style_option_size"
- android:visibility="invisible" />
-
- <!--
- TODO (b/377528523): We intentionally disable over scroll mode since it will clip the
- edit icon when in over scroll.
- -->
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/clock_style_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:overScrollMode="never"
- android:clipChildren="false"
- android:clipToPadding="false"/>
- </FrameLayout>
-
- <TextView
- android:id="@+id/clock_style_clock_size_title"
- style="@style/CustomizationOptionEntryTitleTextStyle"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:text="@string/clock_size_large"
- android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
- android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
- app:layout_constraintTop_toBottomOf="@+id/clock_style_list_container"
- app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_description" />
-
- <TextView
- android:id="@+id/clock_style_clock_size_description"
- style="@style/CustomizationOptionEntrySubtitleTextStyle"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
- android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
- android:text="@string/clock_size_dynamic_description"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
- app:layout_constraintTop_toBottomOf="@+id/clock_style_clock_size_title"
- app:layout_constraintBottom_toBottomOf="parent" />
-
- <Switch
- android:id="@+id/clock_style_clock_size_switch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/floating_sheet_content_horizontal_padding"
- app:layout_constraintTop_toTopOf="@+id/clock_style_clock_size_title"
- app:layout_constraintBottom_toBottomOf="@+id/clock_style_clock_size_description"
- app:layout_constraintEnd_toEndOf="parent"
- style="@style/Switch.SettingsLib"
- tools:ignore="UseSwitchCompatOrMaterialXml" />
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <LinearLayout
+ <include
+ layout="@layout/floating_sheet_clock_color_content"
android:id="@+id/clock_floating_sheet_color_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:clipToPadding="false"
- android:clipChildren="false">
+ android:layout_height="wrap_content" />
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipToPadding="false"
- android:clipChildren="false"
- android:layout_marginBottom="12dp">
-
- <!--
- This is an invisible placeholder put in place so that the parent keeps its height
- stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
- the layout logic to keep the size of the preview container stable as well, which
- bodes well for setting up the SurfaceView for remote rendering without changing its
- size after the content is loaded into the RecyclerView.
-
- It's critical for any TextViews inside the included layout to have text.
- -->
- <include
- layout="@layout/color_option"
- android:layout_width="@dimen/option_item_size"
- android:layout_height="@dimen/option_item_size"
- android:visibility="invisible" />
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/clock_color_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false" />
- </FrameLayout>
-
- <SeekBar
- android:id="@+id/clock_color_slider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
- android:minHeight="@dimen/touch_target_min_height"
- android:thumb="@null"
- android:contentDescription="@string/accessibility_clock_slider_description"
- android:background="@null"
- android:progressDrawable="@drawable/saturation_progress_drawable"
- android:splitTrack="false" />
- </LinearLayout>
-
- <LinearLayout
+ <include
+ layout="@layout/floating_sheet_clock_font_content"
android:id="@+id/clock_floating_sheet_font_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
- android:orientation="vertical"
- android:clipToPadding="false"
- android:clipChildren="false">
-
- <!-- Populated dynamically w/ clock axis information -->
- </LinearLayout>
+ android:layout_height="wrap_content" />
</FrameLayout>
- <com.android.wallpaper.picker.customization.ui.view.FloatingToolbar
- android:id="@+id/floating_toolbar"
- android:layout_width="wrap_content"
+ <FrameLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginVertical="@dimen/floating_sheet_tab_toolbar_vertical_margin" />
+ android:layout_marginVertical="@dimen/floating_sheet_tab_toolbar_vertical_margin">
- <LinearLayout
- android:id="@+id/clock_font_toolbar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="@dimen/floating_sheet_tab_clock_font_toolbar_top_margin"
- android:layout_marginBottom="@dimen/floating_sheet_tab_clock_font_toolbar_bottom_margin">
-
- <ImageView
- android:id="@+id/clock_font_revert"
+ <!-- Invisible placeholder to make sure the view does not shrink in height when the floating
+ toolbar visibility is gone -->
+ <include
+ layout="@layout/floating_toolbar_tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/clock_font_revert"
- android:contentDescription="@string/clock_font_editor_revert" />
+ android:layout_marginVertical="@dimen/floating_tab_toolbar_padding_vertical"
+ android:visibility="invisible" />
- <ImageView
- android:id="@+id/clock_font_apply"
+ <com.android.wallpaper.picker.customization.ui.view.FloatingToolbar
+ android:id="@+id/floating_toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingStart="@dimen/clock_font_apply_padding_start"
- android:src="@drawable/clock_font_apply"
- android:contentDescription="@string/clock_font_editor_apply" />
- </LinearLayout>
+ android:layout_gravity="center" />
+
+ <LinearLayout
+ android:id="@+id/clock_font_toolbar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_gravity="center_horizontal">
+
+ <ImageView
+ android:id="@+id/clock_font_revert"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/clock_font_revert"
+ android:contentDescription="@string/clock_font_editor_revert" />
+
+ <ImageView
+ android:id="@+id/clock_font_apply"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/clock_font_apply_padding_start"
+ android:src="@drawable/clock_font_apply"
+ android:contentDescription="@string/clock_font_editor_apply" />
+ </LinearLayout>
+ </FrameLayout>
</LinearLayout>
diff --git a/res/layout/floating_sheet_clock_color_content.xml b/res/layout/floating_sheet_clock_color_content.xml
new file mode 100644
index 0000000..fd218c6
--- /dev/null
+++ b/res/layout/floating_sheet_clock_color_content.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
+ android:orientation="vertical"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ android:layout_marginBottom="@dimen/floating_sheet_clock_color_option_list_bottom_margin">
+
+ <!--
+ This is an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
+ the layout logic to keep the size of the preview container stable as well, which
+ bodes well for setting up the SurfaceView for remote rendering without changing its
+ size after the content is loaded into the RecyclerView.
+
+ It's critical for any TextViews inside the included layout to have text.
+ -->
+ <include
+ layout="@layout/color_option"
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size"
+ android:visibility="invisible" />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/clock_color_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false" />
+ </FrameLayout>
+
+ <SeekBar
+ android:id="@+id/clock_color_slider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
+ android:minHeight="@dimen/touch_target_min_height"
+ android:thumb="@null"
+ android:contentDescription="@string/accessibility_clock_slider_description"
+ android:background="@null"
+ android:progressDrawable="@drawable/saturation_progress_drawable"
+ android:splitTrack="false" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/floating_sheet_clock_font_content.xml b/res/layout/floating_sheet_clock_font_content.xml
new file mode 100644
index 0000000..3ce65e4
--- /dev/null
+++ b/res/layout/floating_sheet_clock_font_content.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/clock_floating_sheet_font_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
+ android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <TextView
+ android:id="@+id/clock_axis_slider_name1"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/barrier1"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_axis_slider1"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <SeekBar
+ android:id="@+id/clock_axis_slider1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/accessibility_min_height"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/barrier1"
+ app:layout_constraintStart_toEndOf="@+id/clock_axis_slider_name1"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:background="@null"
+ android:progressDrawable="@drawable/saturation_progress_drawable"
+ android:splitTrack="false"
+ android:thumb="@null" />
+
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/barrier1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:barrierDirection="bottom"
+ app:constraint_referenced_ids="clock_axis_slider1,clock_axis_slider_name1" />
+
+ <TextView
+ android:id="@+id/clock_axis_slider_name2"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier1"
+ app:layout_constraintBottom_toTopOf="@+id/barrier2"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_axis_slider2"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <SeekBar
+ android:id="@+id/clock_axis_slider2"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/accessibility_min_height"
+ app:layout_constraintTop_toBottomOf="@+id/barrier1"
+ app:layout_constraintBottom_toTopOf="@+id/barrier2"
+ app:layout_constraintStart_toEndOf="@+id/clock_axis_slider_name2"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:background="@null"
+ android:progressDrawable="@drawable/saturation_progress_drawable"
+ android:splitTrack="false"
+ android:thumb="@null" />
+
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/barrier2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:barrierDirection="bottom"
+ app:constraint_referenced_ids="clock_axis_slider2,clock_axis_slider_name2" />
+
+ <TextView
+ android:id="@+id/clock_axis_switch_name1"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <Switch
+ android:id="@+id/clock_axis_switch1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/clock_axis_switch_name1"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ android:layout_marginStart="@dimen/clock_axis_control_text_margin_end"
+ style="@style/Switch.SettingsLib" />
+
+ <ImageView
+ android:id="@+id/divider"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.5"
+ android:src="@drawable/clock_font_switch_divider"
+ android:importantForAccessibility="no" />
+
+ <TextView
+ android:id="@+id/clock_axis_switch_name2"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_axis_switch2"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <Switch
+ android:id="@+id/clock_axis_switch2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ style="@style/Switch.SettingsLib" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/layout/floating_sheet_clock_style_content.xml b/res/layout/floating_sheet_clock_style_content.xml
new file mode 100644
index 0000000..5b39776
--- /dev/null
+++ b/res/layout/floating_sheet_clock_style_content.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/floating_sheet_clock_style_content_top_padding"
+ android:paddingBottom="@dimen/floating_sheet_clock_style_content_bottom_padding"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <FrameLayout
+ android:id="@+id/clock_style_list_container"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_title"
+ android:layout_marginBottom="@dimen/floating_sheet_clock_style_option_list_margin_bottom"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <!--
+ This is an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
+ the layout logic to keep the size of the preview container stable as well, which
+ bodes well for setting up the SurfaceView for remote rendering without changing its
+ size after the content is loaded into the RecyclerView.
+
+ It's critical for any TextViews inside the included layout to have text.
+ -->
+ <include
+ layout="@layout/clock_style_option"
+ android:layout_width="@dimen/floating_sheet_clock_style_option_width"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_height"
+ android:visibility="invisible" />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/clock_style_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"/>
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/clock_style_clock_size_title"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/clock_size_large"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
+ android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
+ app:layout_constraintTop_toBottomOf="@+id/clock_style_list_container"
+ app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_description" />
+
+ <TextView
+ android:id="@+id/clock_style_clock_size_description"
+ style="@style/CustomizationOptionEntrySubtitleTextStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
+ android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
+ android:text="@string/clock_size_dynamic_description"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
+ app:layout_constraintTop_toBottomOf="@+id/clock_style_clock_size_title"
+ app:layout_constraintBottom_toBottomOf="parent" />
+
+ <Switch
+ android:id="@+id/clock_style_clock_size_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/floating_sheet_content_horizontal_padding"
+ app:layout_constraintTop_toTopOf="@+id/clock_style_clock_size_title"
+ app:layout_constraintBottom_toBottomOf="@+id/clock_style_clock_size_description"
+ app:layout_constraintEnd_toEndOf="parent"
+ style="@style/Switch.SettingsLib"
+ tools:ignore="UseSwitchCompatOrMaterialXml" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 9c5e84d..fab8357 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -181,24 +181,33 @@
<!-- Floating sheet dimensions -->
<dimen name="floating_sheet_content_vertical_padding">20dp</dimen>
<dimen name="floating_sheet_content_horizontal_padding">20dp</dimen>
+ <dimen name="floating_sheet_clock_style_content_top_padding">2dp</dimen>
+ <dimen name="floating_sheet_clock_style_content_bottom_padding">20dp</dimen>
<dimen name="floating_sheet_horizontal_padding">16dp</dimen>
<dimen name="floating_sheet_tab_toolbar_vertical_margin">8dp</dimen>
<dimen name="floating_sheet_tab_clock_font_toolbar_top_margin">16dp</dimen>
<dimen name="floating_sheet_tab_clock_font_toolbar_bottom_margin">8dp</dimen>
<dimen name="floating_sheet_list_item_horizontal_space">4dp</dimen>
<dimen name="floating_sheet_list_item_vertical_space">4dp</dimen>
- <dimen name="floating_sheet_clock_style_option_size">82dp</dimen>
+ <dimen name="floating_sheet_clock_style_option_list_margin_bottom">8dp</dimen>
+ <dimen name="floating_sheet_clock_style_option_width">80dp</dimen>
+ <dimen name="floating_sheet_clock_style_option_height">98dp</dimen>
+ <dimen name="floating_sheet_clock_style_option_background_size">80dp</dimen>
+ <dimen name="floating_sheet_clock_style_option_thumbnail_size">56dp</dimen>
<dimen name="floating_sheet_clock_edit_icon_size">48dp</dimen>
- <dimen name="floating_sheet_clock_style_thumbnail_margin">12dp</dimen>
+ <dimen name="floating_sheet_clock_edit_icon_margin">-18dp</dimen>
+ <dimen name="floating_sheet_clock_style_thumbnail_margin_bottom">12dp</dimen>
<dimen name="floating_sheet_clock_style_clock_size_text_margin_end">16dp</dimen>
+ <dimen name="floating_sheet_clock_color_option_list_bottom_margin">12dp</dimen>
<dimen name="floating_sheet_color_option_size">54dp</dimen>
<dimen name="floating_sheet_color_option_stroke_width">3dp</dimen>
<dimen name="customization_option_entry_shortcut_icon_size">20dp</dimen>
+ <dimen name="customization_option_entry_clock_icon_size">44dp</dimen>
<!-- Clock font control dimensions -->
<dimen name="clock_font_axis_name_width">64dp</dimen>
- <dimen name="clock_axis_control_padding_start">16dp</dimen>
- <dimen name="clock_axis_control_row_vertical_padding">10dp</dimen>
- <dimen name="clock_font_control_switch_padding_horizontal">38dp</dimen>
+ <dimen name="clock_axis_control_text_margin_end">16dp</dimen>
+ <dimen name="clock_axis_control_slider_row_margin_vertical">10dp</dimen>
+ <dimen name="clock_axis_control_switch_row_margin_vertical">8dp</dimen>
<dimen name="clock_font_apply_padding_start">8dp</dimen>
</resources>
diff --git a/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
index 72b0f19..73ebb0f 100644
--- a/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
@@ -79,7 +79,10 @@
override fun getSmallView(clockId: String): View {
assert(!Flags.newCustomizationPickerUi())
val smallClockFrame =
- smallClockFrames[clockId]
+ smallClockFrames[clockId]?.apply {
+ (layoutParams as FrameLayout.LayoutParams).topMargin = getSmallClockTopMargin()
+ (layoutParams as FrameLayout.LayoutParams).marginStart = getSmallClockStartPadding()
+ }
?: createSmallClockFrame().also {
it.addView(getController(clockId).smallClock.view)
smallClockFrames[clockId] = it
@@ -114,7 +117,10 @@
private fun getSmallClockStartPadding() =
appContext.resources.getDimensionPixelSize(
com.android.systemui.customization.R.dimen.clock_padding_start
- )
+ ) +
+ appContext.resources.getDimensionPixelSize(
+ com.android.systemui.customization.R.dimen.status_view_margin_horizontal
+ )
override fun updateColorForAllClocks(@ColorInt seedColor: Int?) {
clockControllers.values.forEach {
diff --git a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
index 5f982e2..86b2d78 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
@@ -16,19 +16,18 @@
package com.android.wallpaper.customization.ui.binder
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.Configuration
-import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.FrameLayout
import android.widget.ImageView
-import android.widget.LinearLayout
import android.widget.SeekBar
import android.widget.Switch
-import android.widget.TextView
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
@@ -42,10 +41,10 @@
import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
import com.android.customization.picker.common.ui.view.SingleRowListItemSpacing
import com.android.systemui.plugins.clocks.AxisType
-import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.systemui.plugins.clocks.ClockId
import com.android.themepicker.R
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK
+import com.android.wallpaper.customization.ui.view.ClockFontSliderViewHolder
+import com.android.wallpaper.customization.ui.view.ClockFontSwitchViewHolder
import com.android.wallpaper.customization.ui.viewmodel.ClockFloatingSheetHeightsViewModel
import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel
import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel.ClockStyleModel
@@ -57,7 +56,6 @@
import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter
import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter2
import java.lang.ref.WeakReference
-import kotlin.math.abs
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -71,8 +69,8 @@
private const val SLIDER_DISABLED_ALPHA = .3f
private const val ANIMATION_DURATION = 200L
- private val _clockFloatingSheetHeights: MutableStateFlow<ClockFloatingSheetHeightsViewModel?> =
- MutableStateFlow(null)
+ private val _clockFloatingSheetHeights: MutableStateFlow<ClockFloatingSheetHeightsViewModel> =
+ MutableStateFlow(ClockFloatingSheetHeightsViewModel())
private val clockFloatingSheetHeights: Flow<ClockFloatingSheetHeightsViewModel> =
_clockFloatingSheetHeights.asStateFlow().filterNotNull()
@@ -145,14 +143,14 @@
clockStyleContent.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
- if (clockStyleContent.height != 0) {
+ if (
+ clockStyleContent.height != 0 &&
+ _clockFloatingSheetHeights.value.clockStyleContentHeight == null
+ ) {
_clockFloatingSheetHeights.value =
- _clockFloatingSheetHeights.value?.copy(
+ _clockFloatingSheetHeights.value.copy(
clockStyleContentHeight = clockStyleContent.height
)
- ?: ClockFloatingSheetHeightsViewModel(
- clockStyleContentHeight = clockStyleContent.height
- )
clockStyleContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
@@ -162,14 +160,31 @@
clockColorContent.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
- if (clockColorContent.height != 0) {
+ if (
+ clockColorContent.height != 0 &&
+ _clockFloatingSheetHeights.value.clockColorContentHeight == null
+ ) {
_clockFloatingSheetHeights.value =
- _clockFloatingSheetHeights.value?.copy(
+ _clockFloatingSheetHeights.value.copy(
clockColorContentHeight = clockColorContent.height
)
- ?: ClockFloatingSheetHeightsViewModel(
- clockColorContentHeight = clockColorContent.height
- )
+ clockColorContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
+ }
+ }
+ }
+ )
+
+ clockFontContent.viewTreeObserver.addOnGlobalLayoutListener(
+ object : OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ if (
+ clockFontContent.height != 0 &&
+ _clockFloatingSheetHeights.value.clockFontContentHeight == null
+ ) {
+ _clockFloatingSheetHeights.value =
+ _clockFloatingSheetHeights.value.copy(
+ clockFontContentHeight = clockFontContent.height
+ )
clockColorContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
@@ -177,84 +192,67 @@
)
lifecycleOwner.lifecycleScope.launch {
+ var currentContent: View = clockStyleContent
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch { viewModel.tabs.collect { tabAdapter.submitList(it) } }
launch {
combine(clockFloatingSheetHeights, viewModel.selectedTab, ::Pair).collect {
(heights, selectedTab) ->
- val (clockStyleContentHeight, clockColorContentHeight) = heights
+ val (
+ clockStyleContentHeight,
+ clockColorContentHeight,
+ clockFontContentHeight) =
+ heights
clockStyleContentHeight ?: return@collect
clockColorContentHeight ?: return@collect
+ clockFontContentHeight ?: return@collect
- if (selectedTab == Tab.STYLE || selectedTab == Tab.COLOR) {
- val targetHeight =
- when (selectedTab) {
- Tab.STYLE -> clockStyleContentHeight
- Tab.COLOR -> clockColorContentHeight
- else -> 0
- } +
- view.resources.getDimensionPixelSize(
- R.dimen.floating_sheet_content_vertical_padding
- ) * 2
-
- ValueAnimator.ofInt(floatingSheetContainer.height, targetHeight)
- .apply {
- addUpdateListener { valueAnimator ->
- val value = valueAnimator.animatedValue as Int
- floatingSheetContainer.layoutParams =
- floatingSheetContainer.layoutParams.apply {
- height = value
- }
- }
- duration = ANIMATION_DURATION
+ val fromHeight = floatingSheetContainer.height
+ val toHeight =
+ when (selectedTab) {
+ Tab.STYLE -> clockStyleContentHeight
+ Tab.COLOR -> clockColorContentHeight
+ Tab.FONT -> clockFontContentHeight
+ }
+ // Start to animate the content height
+ ValueAnimator.ofInt(fromHeight, toHeight)
+ .apply {
+ addUpdateListener { valueAnimator ->
+ val value = valueAnimator.animatedValue as Int
+ floatingSheetContainer.layoutParams =
+ floatingSheetContainer.layoutParams.apply { height = value }
+ currentContent.alpha = getAlpha(fromHeight, toHeight, value)
}
- .start()
- } else if (selectedTab == Tab.FONT) {
- floatingSheetContainer.layoutParams =
- LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT,
- LinearLayout.LayoutParams.WRAP_CONTENT,
+ duration = ANIMATION_DURATION
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ clockStyleContent.isVisible = selectedTab == Tab.STYLE
+ clockStyleContent.alpha = 1f
+ clockColorContent.isVisible = selectedTab == Tab.COLOR
+ clockColorContent.alpha = 1f
+ clockFontContent.isVisible = selectedTab == Tab.FONT
+ clockFontContent.alpha = 1f
+ currentContent =
+ when (selectedTab) {
+ Tab.STYLE -> clockStyleContent
+ Tab.COLOR -> clockColorContent
+ Tab.FONT -> clockFontContent
+ }
+ // Also update the floating toolbar when the height
+ // animation ends.
+ tabs.isVisible = selectedTab != Tab.FONT
+ clockFontToolbar.isVisible = selectedTab == Tab.FONT
+ }
+ }
)
- }
-
- clockStyleContent.isVisible = selectedTab == Tab.STYLE
- clockColorContent.isVisible = selectedTab == Tab.COLOR
- clockFontContent.isVisible = selectedTab == Tab.FONT
-
- tabs.isVisible = selectedTab != Tab.FONT
- clockFontToolbar.isVisible = selectedTab == Tab.FONT
+ }
+ .start()
}
}
launch {
- var boundClockId: ClockId? = null
- var boundEditorViews = mapOf<String, Pair<View, ClockFontAxis>>()
- combine(viewModel.previewingClock, viewModel.previewingFontAxisMap, ::Pair)
- .collect { pair ->
- val (clock, fontAxisMap) = pair
-
- if (boundClockId != clock.clockId) {
- boundEditorViews =
- initClockFontEditor(clockFontContent, clock.fontAxes, viewModel)
- boundClockId = clock.clockId
- }
-
- for ((key, value) in fontAxisMap) {
- boundEditorViews[key]?.let { pair ->
- val (view, axis) = pair
- view.findViewById<Switch>(R.id.clock_axis_switch)?.apply {
- isChecked = abs(value - axis.maxValue) < 0.01f
- }
- view.findViewById<SeekBar>(R.id.clock_axis_slider)?.apply {
- setProgress(value.toInt(), false)
- }
- }
- }
- }
- }
-
- launch {
viewModel.clockStyleOptions.collect { styleOptions ->
clockStyleAdapter.setItems(styleOptions) {
var indexToFocus = styleOptions.indexOfFirst { it.isSelected.value }
@@ -308,85 +306,100 @@
}
}
}
+
+ bindClockFontContent(
+ clockFontContent = clockFontContent,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner,
+ )
}
- private fun initClockFontEditor(
- parent: ViewGroup,
- fontAxes: List<ClockFontAxis>,
+ private fun bindClockFontContent(
+ clockFontContent: View,
viewModel: ClockPickerViewModel,
- ): Map<String, Pair<View, ClockFontAxis>> {
- parent.removeAllViews()
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ val sliderViewList =
+ listOf(
+ ClockFontSliderViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_slider_name1),
+ slider = clockFontContent.requireViewById(R.id.clock_axis_slider1),
+ ),
+ ClockFontSliderViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_slider_name2),
+ slider = clockFontContent.requireViewById(R.id.clock_axis_slider2),
+ ),
+ )
+ val switchViewList =
+ listOf(
+ ClockFontSwitchViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_switch_name1),
+ switch = clockFontContent.requireViewById(R.id.clock_axis_switch1),
+ ),
+ ClockFontSwitchViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_switch_name2),
+ switch = clockFontContent.requireViewById(R.id.clock_axis_switch2),
+ ),
+ )
+ val sliderViewMap: MutableMap<String, ClockFontSliderViewHolder> = mutableMapOf()
+ val switchViewMap: MutableMap<String, ClockFontSwitchViewHolder> = mutableMapOf()
- val inflater = LayoutInflater.from(parent.context)
- val axisMap = mutableMapOf<String, Pair<View, ClockFontAxis>>()
- var nextSwitch: View? = null
- for (axis in fontAxes) {
- val view =
- when (axis.type) {
- AxisType.Float -> {
- val id = R.layout.clock_font_axis_slider_row
- val row = inflater.inflate(id, parent, false)
- parent.addView(row)
- row
- }
- AxisType.Boolean ->
- nextSwitch?.also { nextSwitch = null }
- ?: run {
- val id = R.layout.clock_font_axis_switch_row
- val row = inflater.inflate(id, parent, false)
- parent.addView(row)
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.selectedClockFontAxes.filterNotNull().collect { fontAxes ->
+ // This data flow updates only when a new clock style is selected. We
+ // initiate the clock font content with regard to that clock style.
+ sliderViewMap.clear()
+ switchViewMap.clear()
- nextSwitch = row.requireViewById(R.id.clock_switch_two)
- row.requireViewById(R.id.clock_switch_one)
- }
- }
-
- view.visibility = View.VISIBLE
- axisMap[axis.key] = Pair(view, axis)
- view.contentDescription = axis.description
- view.requireViewById<TextView>(R.id.clock_axis_name).text = axis.name
-
- view.findViewById<Switch>(R.id.clock_axis_switch)?.apply {
- isChecked = abs(axis.currentValue - axis.maxValue) < 0.01f
- setOnCheckedChangeListener { v, _ ->
- val value = if (v.isChecked) axis.maxValue else axis.minValue
- viewModel.updatePreviewFontAxis(axis.key, value)
- }
- }
-
- view.findViewById<SeekBar>(R.id.clock_axis_slider)?.apply {
- setMax(axis.maxValue.toInt())
- setMin(axis.minValue.toInt())
- setProgress(axis.currentValue.toInt(), false)
-
- setOnSeekBarChangeListener(
- object : SeekBar.OnSeekBarChangeListener {
- override fun onProgressChanged(
- seekBar: SeekBar?,
- progress: Int,
- fromUser: Boolean,
- ) {
- if (fromUser) {
- viewModel.updatePreviewFontAxis(axis.key, progress.toFloat())
+ // Initiate the slider views
+ val floatAxisList = fontAxes.filter { it.type == AxisType.Float }
+ sliderViewList.forEachIndexed { i, viewHolder ->
+ val floatAxis = floatAxisList.getOrNull(i)
+ viewHolder.setIsVisible(floatAxis != null)
+ floatAxis?.let {
+ sliderViewMap[floatAxis.key] = viewHolder
+ viewHolder.initView(it) { value ->
+ viewModel.updatePreviewFontAxis(floatAxis.key, value)
+ }
}
}
- override fun onStartTrackingTouch(seekBar: SeekBar?) {}
-
- override fun onStopTrackingTouch(seekBar: SeekBar?) {}
+ // Initiate the switch views
+ val booleanAxisList = fontAxes.filter { it.type == AxisType.Boolean }
+ switchViewList.forEachIndexed { i, viewHolder ->
+ val booleanAxis = booleanAxisList.getOrNull(i)
+ viewHolder.setIsVisible(booleanAxis != null)
+ booleanAxis?.let {
+ switchViewMap[it.key] = viewHolder
+ viewHolder.initView(booleanAxis) { value ->
+ viewModel.updatePreviewFontAxis(booleanAxis.key, value)
+ }
+ }
+ }
}
- )
+ }
+
+ launch {
+ viewModel.previewingClockFontAxisMap.collect { axisMap ->
+ // This data flow updates when user configures the sliders and switches
+ // in the clock font content.
+ axisMap.forEach { (key, value) ->
+ sliderViewMap[key]?.setValue(value)
+ switchViewMap[key]?.setValue(value)
+ }
+ }
+ }
}
}
-
- return axisMap
}
private fun createClockStyleOptionItemAdapter(
lifecycleOwner: LifecycleOwner
): OptionItemAdapter2<ClockStyleModel> =
OptionItemAdapter2(
- layoutResourceId = R.layout.clock_style_option2,
+ layoutResourceId = R.layout.clock_style_option,
lifecycleOwner = lifecycleOwner,
bindPayload = { view: View, styleModel: ClockStyleModel ->
view
@@ -456,4 +469,8 @@
)
}
}
+
+ // Alpha is 1 when current height is from height, and 0 when current height is to height.
+ private fun getAlpha(fromHeight: Int, toHeight: Int, currentHeight: Int): Float =
+ (1 - (currentHeight - fromHeight).toFloat() / (toHeight - fromHeight).toFloat())
}
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
index 6bdd6ce..2936b1c 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
@@ -85,6 +85,7 @@
lockScreenCustomizationOptionEntries
.find { it.first == ThemePickerLockCustomizationOption.CLOCK }
?.second
+ val optionClockIcon = optionClock?.findViewById<ImageView>(R.id.option_entry_clock_icon)
val optionShortcut =
lockScreenCustomizationOptionEntries
@@ -128,6 +129,12 @@
}
launch {
+ optionsViewModel.clockPickerViewModel.selectedClock.collect {
+ optionClockIcon?.setImageDrawable(it.thumbnail)
+ }
+ }
+
+ launch {
optionsViewModel.onCustomizeShortcutClicked.collect {
optionShortcut?.setOnClickListener { _ -> it?.invoke() }
}
@@ -295,7 +302,7 @@
combine(
clockPickerViewModel.previewingSeedColor,
clockPickerViewModel.previewingClock,
- clockPickerViewModel.previewingFontAxisMap,
+ clockPickerViewModel.previewingClockFontAxisMap,
colorUpdateViewModel.systemColorsUpdated,
::Quadruple,
)
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
index 357f131..5ea757e 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
@@ -21,11 +21,13 @@
import android.widget.Button
import android.widget.FrameLayout
import android.widget.Toolbar
+import androidx.core.graphics.ColorUtils
import androidx.core.view.isInvisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import com.android.wallpaper.R
import com.android.wallpaper.customization.ui.viewmodel.ThemePickerCustomizationOptionsViewModel
import com.android.wallpaper.customization.ui.viewmodel.ToolbarHeightsViewModel
import com.android.wallpaper.picker.customization.ui.binder.DefaultToolbarBinder
@@ -109,6 +111,14 @@
}
)
+ val applyButtonTextColorEnabled =
+ applyButton.resources.getColor(R.color.system_on_primary, null)
+ val applyButtonTextColorDisabled =
+ ColorUtils.setAlphaComponent(
+ applyButton.resources.getColor(R.color.system_on_surface, null),
+ 97,
+ ) // 97 for 38% transparent
+
lifecycleOwner.lifecycleScope.launch {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
@@ -117,9 +127,18 @@
}
}
- launch { viewModel.isOnApplyVisible.collect { applyButton.isInvisible = !it } }
+ launch { viewModel.isApplyButtonVisible.collect { applyButton.isInvisible = !it } }
- launch { viewModel.isOnApplyEnabled.collect { applyButton.isEnabled = it } }
+ launch {
+ viewModel.isApplyButtonEnabled.collect {
+ applyButton.isEnabled = it
+ applyButton.background.alpha =
+ if (it) 255 else 31 // 255 for 100%, 31 for 12% transparent,
+ applyButton.setTextColor(
+ if (it) applyButtonTextColorEnabled else applyButtonTextColorDisabled
+ )
+ }
+ }
launch {
combine(toolbarHeights, viewModel.isToolbarCollapsed, ::Pair).collect {
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
new file mode 100644
index 0000000..8bdf073
--- /dev/null
+++ b/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.wallpaper.customization.ui.view
+
+import android.widget.SeekBar
+import android.widget.TextView
+import androidx.core.view.isInvisible
+import com.android.systemui.plugins.clocks.ClockFontAxis
+
+class ClockFontSliderViewHolder(val name: TextView, val slider: SeekBar) {
+
+ fun setIsVisible(isVisible: Boolean) {
+ name.isInvisible = !isVisible
+ slider.isInvisible = !isVisible
+ }
+
+ fun initView(clockFontAxis: ClockFontAxis, onFontAxisValueUpdated: (value: Float) -> Unit) {
+ name.text = clockFontAxis.name
+ slider.apply {
+ max = clockFontAxis.maxValue.toInt()
+ min = clockFontAxis.minValue.toInt()
+ progress = clockFontAxis.currentValue.toInt()
+ setOnSeekBarChangeListener(
+ object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(
+ seekBar: SeekBar?,
+ progress: Int,
+ fromUser: Boolean,
+ ) {
+ if (fromUser) {
+ onFontAxisValueUpdated.invoke(progress.toFloat())
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {}
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {}
+ }
+ )
+ }
+ }
+
+ fun setValue(value: Float) {
+ slider.progress = value.toInt()
+ }
+}
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
new file mode 100644
index 0000000..6eb374b
--- /dev/null
+++ b/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.wallpaper.customization.ui.view
+
+import android.widget.Switch
+import android.widget.TextView
+import androidx.core.view.isVisible
+import com.android.systemui.plugins.clocks.ClockFontAxis
+import kotlin.math.abs
+
+class ClockFontSwitchViewHolder(val name: TextView, val switch: Switch) {
+
+ private var switchMaxValue: Float? = null
+
+ fun setIsVisible(isVisible: Boolean) {
+ name.isVisible = isVisible
+ switch.isVisible = isVisible
+ }
+
+ fun initView(clockFontAxis: ClockFontAxis, onFontAxisValueUpdated: (value: Float) -> Unit) {
+ switchMaxValue = clockFontAxis.maxValue
+ name.text = clockFontAxis.name
+ switch.apply {
+ isChecked = abs(clockFontAxis.currentValue - clockFontAxis.maxValue) < 0.01f
+ setOnCheckedChangeListener { v, _ ->
+ val value = if (v.isChecked) clockFontAxis.maxValue else clockFontAxis.minValue
+ onFontAxisValueUpdated.invoke(value)
+ }
+ }
+ }
+
+ fun setValue(value: Float) {
+ switchMaxValue?.let { switch.isChecked = abs(value - it) < 0.01f }
+ }
+}
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
index a39ee7d..249f862 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
@@ -19,4 +19,5 @@
data class ClockFloatingSheetHeightsViewModel(
val clockStyleContentHeight: Int? = null,
val clockColorContentHeight: Int? = null,
+ val clockFontContentHeight: Int? = null,
)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
index da3e65c..6ca773b 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
@@ -36,12 +36,12 @@
import com.android.wallpaper.picker.customization.ui.viewmodel.FloatingToolbarTabViewModel
import com.android.wallpaper.picker.di.modules.BackgroundDispatcher
import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
-import kotlin.collections.map
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -88,7 +88,7 @@
listOf(
FloatingToolbarTabViewModel(
Icon.Resource(
- res = R.drawable.ic_style_filled_24px,
+ res = R.drawable.ic_clock_filled_24px,
contentDescription = Text.Resource(R.string.clock_style),
),
context.getString(R.string.clock_style),
@@ -117,17 +117,16 @@
selectedClock ->
overridingClock != null && overridingClock.clockId != selectedClock.clockId
}
+ val selectedClock = clockPickerInteractor.selectedClock
val previewingClock =
- combine(overridingClock, clockPickerInteractor.selectedClock) {
- overridingClock,
- selectedClock ->
+ combine(overridingClock, selectedClock) { overridingClock, selectedClock ->
overridingClock ?: selectedClock
}
data class ClockStyleModel(val thumbnail: Drawable, val showEditButton: StateFlow<Boolean>)
@OptIn(ExperimentalCoroutinesApi::class)
- val clockStyleOptions: StateFlow<List<OptionItemViewModel<ClockStyleModel>>> =
+ val clockStyleOptions: StateFlow<List<OptionItemViewModel2<ClockStyleModel>>> =
clockPickerInteractor.allClocks
.mapLatest { allClocks ->
// Delay to avoid the case that the full list of clocks is not initiated.
@@ -146,13 +145,13 @@
private suspend fun ClockMetadataModel.toOption(
resources: Resources
- ): OptionItemViewModel<ClockStyleModel> {
+ ): OptionItemViewModel2<ClockStyleModel> {
val isSelectedFlow = previewingClock.map { it.clockId == clockId }.stateIn(viewModelScope)
val isEditable = fontAxes.isNotEmpty()
val showEditButton = isSelectedFlow.map { it && isEditable }.stateIn(viewModelScope)
val contentDescription =
resources.getString(R.string.select_clock_action_description, description)
- return OptionItemViewModel<ClockStyleModel>(
+ return OptionItemViewModel2<ClockStyleModel>(
key = MutableStateFlow(clockId) as StateFlow<String>,
payload = ClockStyleModel(thumbnail = thumbnail, showEditButton = showEditButton),
text = Text.Loaded(contentDescription),
@@ -167,7 +166,7 @@
} else {
fun() {
overridingClock.value = this
- overrideFontAxisMap.value = null
+ overrideClockFontAxisMap.value = null
}
}
},
@@ -175,27 +174,33 @@
}
// Clock Font Axis Editor
- private val overrideFontAxisMap = MutableStateFlow<Map<String, Float>?>(null)
- private val isFontAxisMapEdited = overrideFontAxisMap.map { it != null }
- private val selectedClockFontAxes =
+ private val overrideClockFontAxisMap = MutableStateFlow<Map<String, Float>?>(null)
+ private val isFontAxisMapEdited = overrideClockFontAxisMap.map { it != null }
+ val selectedClockFontAxes =
previewingClock
- .map { clock -> clock.fontAxes.associate { it.key to it.currentValue } }
+ .map { clock -> clock.fontAxes }
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
- val previewingFontAxisMap =
- combine(overrideFontAxisMap, selectedClockFontAxes.filterNotNull()) {
- overrideAxes,
- selectedFontAxes ->
- selectedFontAxes.toMutableMap().let { mutableMap ->
- overrideAxes?.forEach { (key, value) -> mutableMap[key] = value }
+ private val selectedClockFontAxisMap =
+ selectedClockFontAxes
+ .filterNotNull()
+ .map { fontAxes -> fontAxes.associate { it.key to it.currentValue } }
+ .stateIn(viewModelScope, SharingStarted.Eagerly, null)
+ val previewingClockFontAxisMap =
+ combine(overrideClockFontAxisMap, selectedClockFontAxisMap.filterNotNull()) {
+ overrideAxisMap,
+ selectedAxisMap ->
+ overrideAxisMap?.let {
+ val mutableMap = selectedAxisMap.toMutableMap()
+ overrideAxisMap.forEach { (key, value) -> mutableMap[key] = value }
mutableMap.toMap()
- }
+ } ?: selectedAxisMap
}
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyMap())
fun updatePreviewFontAxis(key: String, value: Float) {
- val axisMap = (overrideFontAxisMap.value?.toMutableMap() ?: mutableMapOf())
+ val axisMap = (overrideClockFontAxisMap.value?.toMutableMap() ?: mutableMapOf())
axisMap[key] = value
- overrideFontAxisMap.value = axisMap.toMap()
+ overrideClockFontAxisMap.value = axisMap.toMap()
}
fun confirmFontAxes() {
@@ -203,7 +208,7 @@
}
fun cancelFontAxes() {
- overrideFontAxisMap.value = null
+ overrideClockFontAxisMap.value = null
_selectedTab.value = Tab.STYLE
}
@@ -420,7 +425,7 @@
previewingClockSize,
previewingClockColorId,
previewingSliderProgress,
- previewingFontAxisMap,
+ previewingClockFontAxisMap,
) { array ->
val isEdited = array[0] as Boolean
val clock = array[1] as ClockMetadataModel
@@ -455,7 +460,7 @@
overridingClockSize.value = null
overridingClockColorId.value = null
overridingSliderProgress.value = null
- overrideFontAxisMap.value = null
+ overrideClockFontAxisMap.value = null
_selectedTab.value = Tab.STYLE
}
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2.kt
index 26e7867..e7efebd 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2.kt
@@ -27,7 +27,7 @@
import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
import com.android.wallpaper.picker.customization.ui.viewmodel.FloatingToolbarTabViewModel
-import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -109,7 +109,7 @@
/** The list of all color options mapped by their color type */
private val allColorOptions:
- Flow<Map<ColorType, List<OptionItemViewModel<ColorOptionIconViewModel>>>> =
+ Flow<Map<ColorType, List<OptionItemViewModel2<ColorOptionIconViewModel>>>> =
interactor.colorOptions.map { colorOptions ->
colorOptions
.map { colorOptionEntry ->
@@ -128,7 +128,7 @@
?: colorOptionModel.isSelected
}
.stateIn(viewModelScope)
- OptionItemViewModel<ColorOptionIconViewModel>(
+ OptionItemViewModel2<ColorOptionIconViewModel>(
key = MutableStateFlow(colorOptionModel.key) as StateFlow<String>,
payload =
ColorOptionIconViewModel(
@@ -188,9 +188,9 @@
}
/** The list of all available color options for the selected Color Type. */
- val colorOptions: Flow<List<OptionItemViewModel<ColorOptionIconViewModel>>> =
+ val colorOptions: Flow<List<OptionItemViewModel2<ColorOptionIconViewModel>>> =
combine(allColorOptions, selectedColorTypeTabId) {
- allColorOptions: Map<ColorType, List<OptionItemViewModel<ColorOptionIconViewModel>>>,
+ allColorOptions: Map<ColorType, List<OptionItemViewModel2<ColorOptionIconViewModel>>>,
selectedColorTypeIdOrNull ->
val selectedColorTypeId = selectedColorTypeIdOrNull ?: ColorType.WALLPAPER_COLOR
allColorOptions[selectedColorTypeId]!!
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt b/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt
index fd94b78..fd04580 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt
@@ -36,6 +36,7 @@
import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
import com.android.wallpaper.picker.customization.ui.viewmodel.FloatingToolbarTabViewModel
import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -174,7 +175,7 @@
.shareIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(), replay = 1)
/** The list of all available quick affordances for the selected slot. */
- val quickAffordances: Flow<List<OptionItemViewModel<Icon>>> =
+ val quickAffordances: Flow<List<OptionItemViewModel2<Icon>>> =
quickAffordanceInteractor.affordances.map { affordances ->
val isNoneSelected =
combine(selectedSlotId, previewingQuickAffordances, selectedAffordanceIds) {
@@ -219,7 +220,7 @@
} ?: selectedAffordanceIds.contains(affordance.id)
}
.stateIn(viewModelScope)
- OptionItemViewModel<Icon>(
+ OptionItemViewModel2<Icon>(
key =
selectedSlotId
.map { slotId -> "$slotId::${affordance.id}" }
@@ -374,8 +375,8 @@
slotId: StateFlow<String>,
isSelected: StateFlow<Boolean>,
onSelected: Flow<(() -> Unit)?>,
- ): OptionItemViewModel<Icon> {
- return OptionItemViewModel<Icon>(
+ ): OptionItemViewModel2<Icon> {
+ return OptionItemViewModel2<Icon>(
key = slotId.map { "$it::none" }.stateIn(viewModelScope),
payload = Icon.Resource(res = R.drawable.link_off, contentDescription = null),
text = Text.Resource(res = R.string.keyguard_affordance_none),
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
index 54ae132..62a96fe 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
@@ -62,6 +62,16 @@
override val selectedOption = defaultCustomizationOptionsViewModel.selectedOption
override fun handleBackPressed(): Boolean {
+
+ if (
+ defaultCustomizationOptionsViewModel.selectedOption.value ==
+ ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK &&
+ clockPickerViewModel.selectedTab.value == ClockPickerViewModel.Tab.FONT
+ ) {
+ clockPickerViewModel.cancelFontAxes()
+ return true
+ }
+
val isBackPressedHandled = defaultCustomizationOptionsViewModel.handleBackPressed()
if (isBackPressedHandled) {
@@ -168,9 +178,9 @@
}
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
- val isOnApplyEnabled: Flow<Boolean> = onApplyButtonClicked.map { it != null }
+ val isApplyButtonEnabled: Flow<Boolean> = onApplyButtonClicked.map { it != null }
- val isOnApplyVisible: Flow<Boolean> = selectedOption.map { it != null }
+ val isApplyButtonVisible: Flow<Boolean> = selectedOption.map { it != null }
val isToolbarCollapsed: Flow<Boolean> =
combine(selectedOption, clockPickerViewModel.selectedTab) { selectedOption, selectedTab ->
diff --git a/tests/robotests/src/com/android/customization/picker/mode/ui/viewmodel/DarkModeViewModelTest.kt b/tests/robotests/src/com/android/customization/picker/mode/ui/viewmodel/DarkModeViewModelTest.kt
index 4078803..fbd56bc 100644
--- a/tests/robotests/src/com/android/customization/picker/mode/ui/viewmodel/DarkModeViewModelTest.kt
+++ b/tests/robotests/src/com/android/customization/picker/mode/ui/viewmodel/DarkModeViewModelTest.kt
@@ -91,16 +91,19 @@
testScope.runTest {
uiModeManager.setNightModeActivated(false)
darkModeRepository.refreshIsDarkModeActivated()
+ val getOverridingIsDarkMode = collectLastValue(darkModeViewModel.overridingIsDarkMode)
val getPreviewingIsDarkMode = collectLastValue(darkModeViewModel.previewingIsDarkMode)
val getToggleDarkMode = collectLastValue(darkModeViewModel.toggleDarkMode)
assertThat(getPreviewingIsDarkMode()).isFalse()
getToggleDarkMode()?.invoke()
+ assertThat(getOverridingIsDarkMode()).isTrue()
assertThat(getPreviewingIsDarkMode()).isTrue()
getToggleDarkMode()?.invoke()
+ assertThat(getOverridingIsDarkMode()).isNull()
assertThat(getPreviewingIsDarkMode()).isFalse()
}
}
diff --git a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
index 0a8aa53..76df409 100644
--- a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
+++ b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
@@ -207,13 +207,13 @@
@Test
fun previewingFontAxes_defaultWhenNoOverrides() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
}
@Test
fun previewingFontAxes_updateAxisChangesSetting() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
underTest.updatePreviewFontAxis("key", 100f)
@@ -225,7 +225,7 @@
@Test
fun previewingFontAxes_applyFontEditorExitsTab_keepsPreviewAxis() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
val selectedTab = collectLastValue(underTest.selectedTab)
// Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
@@ -251,7 +251,7 @@
@Test
fun previewingFontAxes_revertFontEditorExitsTab_revertsPreviewAxis() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
val selectedTab = collectLastValue(underTest.selectedTab)
// Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
diff --git a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2Test.kt b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2Test.kt
index a4d0ba0..421d8a0 100644
--- a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2Test.kt
+++ b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ColorPickerViewModel2Test.kt
@@ -29,7 +29,7 @@
import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
import com.android.systemui.monet.Style
import com.android.wallpaper.picker.customization.ui.viewmodel.FloatingToolbarTabViewModel
-import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
import com.android.wallpaper.testing.FakeSnapshotStore
import com.android.wallpaper.testing.collectLastValue
import com.google.common.truth.Truth.assertThat
@@ -205,7 +205,7 @@
/** Simulates a user selecting the affordance at the given index, if that is clickable. */
private fun TestScope.selectColorOption(
- colorOptions: () -> List<OptionItemViewModel<ColorOptionIconViewModel>>?,
+ colorOptions: () -> List<OptionItemViewModel2<ColorOptionIconViewModel>>?,
index: Int,
) {
val onClickedFlow = colorOptions()?.get(index)?.onClicked
@@ -235,7 +235,7 @@
*/
private fun TestScope.assertPickerUiState(
colorTypes: List<FloatingToolbarTabViewModel>?,
- colorOptions: List<OptionItemViewModel<ColorOptionIconViewModel>>?,
+ colorOptions: List<OptionItemViewModel2<ColorOptionIconViewModel>>?,
selectedColorTypeText: String,
selectedColorOptionIndex: Int,
) {
@@ -260,7 +260,7 @@
* -1 stands for no color option should be selected
*/
private fun TestScope.assertColorOptionUiState(
- colorOptions: List<OptionItemViewModel<ColorOptionIconViewModel>>?,
+ colorOptions: List<OptionItemViewModel2<ColorOptionIconViewModel>>?,
selectedColorOptionIndex: Int,
) {
var foundSelectedColorOption = false
diff --git a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt
index b6f249e..a7efc45 100644
--- a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt
+++ b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt
@@ -30,7 +30,7 @@
import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
import com.android.wallpaper.picker.customization.ui.viewmodel.FloatingToolbarTabViewModel
-import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
import com.android.wallpaper.testing.collectLastValue
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
@@ -149,7 +149,7 @@
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
FakeCustomizationProviderClient.AFFORDANCE_1,
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
- FakeCustomizationProviderClient.AFFORDANCE_2
+ FakeCustomizationProviderClient.AFFORDANCE_2,
)
)
@@ -203,7 +203,7 @@
icon =
Icon.Loaded(
FakeCustomizationProviderClient.ICON_1,
- Text.Loaded("Right shortcut")
+ Text.Loaded("Right shortcut"),
),
text = "Right shortcut",
isSelected = true,
@@ -399,7 +399,7 @@
private fun assertQuickAffordance(
testScope: TestScope,
- quickAffordance: OptionItemViewModel<Icon>?,
+ quickAffordance: OptionItemViewModel2<Icon>?,
key: String,
icon: Icon,
text: Text,