Merge "Added changes for a custom banner" into main
diff --git a/res/drawable/ic_font_size_filled_24px.xml b/res/drawable/ic_font_size_filled_24px.xml
new file mode 100644
index 0000000..b37e8e6
--- /dev/null
+++ b/res/drawable/ic_font_size_filled_24px.xml
@@ -0,0 +1,27 @@
+<?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="M560,800L560,280L360,280L360,160L880,160L880,280L680,280L680,800L560,800ZM200,800L200,480L80,480L80,360L440,360L440,480L320,480L320,800L200,800Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/layout/clock_style_option.xml b/res/layout/clock_style_option.xml
index fa20706..c59a9d4 100644
--- a/res/layout/clock_style_option.xml
+++ b/res/layout/clock_style_option.xml
@@ -14,57 +14,25 @@
limitations under the License.
-->
<!-- Content description is set programmatically on the parent FrameLayout -->
-<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"
+<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"
android:clipToPadding="false"
android:clipChildren="false">
<com.android.wallpaper.picker.option.ui.view.OptionItemBackground
android:id="@id/background"
- 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" />
+ android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_size"
+ android:layout_gravity="center"
+ android:importantForAccessibility="no" />
<ImageView
android:id="@+id/foreground"
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:layout_gravity="center"
android:src="@drawable/ic_clock_24px" />
-
- <FrameLayout
- 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"
- app:layout_constraintEnd_toEndOf="@+id/background"
- app:layout_constraintTop_toTopOf="@+id/background" >
- <ImageView
- android:id="@+id/edit_icon_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/edit_icon_background"
- android:importantForAccessibility="no" />
-
- <ImageView
- android:id="@+id/edit_icon_foreground"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/edit_icon_foreground"
- android:importantForAccessibility="no" />
- </FrameLayout>
-
-
-</androidx.constraintlayout.widget.ConstraintLayout>
+</FrameLayout>
diff --git a/res/layout/floating_sheet_clock.xml b/res/layout/floating_sheet_clock.xml
index 6b757be..2e98b4f 100644
--- a/res/layout/floating_sheet_clock.xml
+++ b/res/layout/floating_sheet_clock.xml
@@ -41,8 +41,8 @@
android:layout_height="wrap_content" />
<include
- layout="@layout/floating_sheet_clock_font_content"
- android:id="@+id/clock_floating_sheet_font_content"
+ layout="@layout/floating_sheet_clock_size_content"
+ android:id="@+id/clock_floating_sheet_size_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
@@ -66,28 +66,5 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_font_content.xml b/res/layout/floating_sheet_clock_font_content.xml
deleted file mode 100644
index ba6c70c..0000000
--- a/res/layout/floating_sheet_clock_font_content.xml
+++ /dev/null
@@ -1,159 +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.
- -->
-
-<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" />
-
- <com.google.android.material.slider.Slider
- 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"
- app:trackHeight="@dimen/slider_track_height"
- app:thumbHeight="@dimen/slider_thumb_height"
- android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-
- <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" />
-
- <com.google.android.material.slider.Slider
- 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"
- app:trackHeight="@dimen/slider_track_height"
- app:thumbHeight="@dimen/slider_thumb_height"
- android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-
- <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" />
-
- <com.google.android.material.materialswitch.MaterialSwitch
- 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"
- android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-
- <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" />
-
- <com.google.android.material.materialswitch.MaterialSwitch
- 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"
- android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/layout/floating_sheet_clock_size_content.xml b/res/layout/floating_sheet_clock_size_content.xml
new file mode 100644
index 0000000..e6c41f2
--- /dev/null
+++ b/res/layout/floating_sheet_clock_size_content.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2025 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:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <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="parent"
+ 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_large_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" />
+
+ <com.google.android.material.materialswitch.MaterialSwitch
+ 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"
+ android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/floating_sheet_clock_style_content.xml b/res/layout/floating_sheet_clock_style_content.xml
index 0339e26..259f376 100644
--- a/res/layout/floating_sheet_clock_style_content.xml
+++ b/res/layout/floating_sheet_clock_style_content.xml
@@ -13,26 +13,18 @@
~ 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"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:orientation="vertical"
+ android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
android:clipToPadding="false"
android:clipChildren="false">
<FrameLayout
- android:id="@+id/clock_style_list_container"
- android:layout_width="0dp"
+ android:layout_width="match_parent"
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">
@@ -47,8 +39,8 @@
-->
<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:layout_width="@dimen/floating_sheet_clock_style_option_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_size"
android:visibility="invisible" />
<androidx.recyclerview.widget.RecyclerView
@@ -59,40 +51,18 @@
android:clipToPadding="false"/>
</FrameLayout>
- <TextView
- android:id="@+id/clock_style_clock_size_title"
- style="@style/CustomizationOptionEntryTitleTextStyle"
- android:layout_width="0dp"
+ <com.google.android.material.slider.Slider
+ android:id="@+id/clock_axis_preset_slider"
+ android:layout_width="match_parent"
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_large_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" />
-
- <com.google.android.material.materialswitch.MaterialSwitch
- 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"
+ android:minHeight="@dimen/accessibility_min_height"
+ android:layout_marginTop="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:valueFrom="0.0"
+ android:valueTo="100.0"
+ android:stepSize="10.0"
+ app:trackHeight="@dimen/slider_track_height"
+ app:thumbHeight="@dimen/slider_thumb_height"
+ app:labelBehavior="gone"
android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-</androidx.constraintlayout.widget.ConstraintLayout>
+</LinearLayout>
+
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d335636..531523b 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -182,8 +182,6 @@
<!-- 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>
@@ -191,14 +189,10 @@
<dimen name="floating_sheet_list_item_horizontal_space">4dp</dimen>
<dimen name="floating_sheet_grid_list_item_horizontal_space">10dp</dimen>
<dimen name="floating_sheet_list_item_vertical_space">4dp</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_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_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_color_option_size">54dp</dimen>
<dimen name="floating_sheet_color_option_stroke_width">3dp</dimen>
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
index fa71fc2..feebf43 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
@@ -52,7 +52,7 @@
suspend fun setClockSize(size: ClockSize)
- suspend fun setClockFontAxes(axisSettings: ClockAxisStyle)
+ suspend fun setClockAxisStyle(axisStyle: ClockAxisStyle)
fun isReactiveToTone(clockId: ClockId): Boolean?
}
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
index 9342ab5..fd0cd11 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -22,8 +22,8 @@
import androidx.annotation.IntRange
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.systemui.plugins.clocks.AxisPresetConfig
import com.android.systemui.plugins.clocks.ClockAxisStyle
-import com.android.systemui.plugins.clocks.ClockFontAxis
import com.android.systemui.plugins.clocks.ClockId
import com.android.systemui.plugins.clocks.ClockMetadata
import com.android.systemui.shared.clocks.ClockRegistry
@@ -73,7 +73,7 @@
description = clockConfig.description,
thumbnail = clockConfig.thumbnail,
isReactiveToTone = clockConfig.isReactiveToTone,
- fontAxes = clockConfig.axes,
+ axisPresetConfig = clockConfig.presetConfig,
)
} else {
null
@@ -85,6 +85,10 @@
val listener =
object : ClockRegistry.ClockChangeListener {
+ override fun onCurrentClockChanged() {
+ send()
+ }
+
override fun onAvailableClocksChanged() {
send()
}
@@ -119,7 +123,7 @@
description = it.description,
thumbnail = it.thumbnail,
isReactiveToTone = it.isReactiveToTone,
- fontAxes = it.axes,
+ axisPresetConfig = it.presetConfig,
selectedColorId = metadata?.getSelectedColorId(),
colorTone =
metadata?.getColorTone()
@@ -191,9 +195,9 @@
)
}
- override suspend fun setClockFontAxes(axisSettings: ClockAxisStyle) {
+ override suspend fun setClockAxisStyle(axisStyle: ClockAxisStyle) {
registry.mutateSetting { oldSettings ->
- val newSettings = oldSettings.copy(axes = axisSettings)
+ val newSettings = oldSettings.copy(axes = axisStyle)
newSettings.metadata = oldSettings.metadata
newSettings
}
@@ -224,7 +228,7 @@
description: String,
thumbnail: Drawable,
isReactiveToTone: Boolean,
- fontAxes: List<ClockFontAxis>,
+ axisPresetConfig: AxisPresetConfig?,
selectedColorId: String? = null,
@IntRange(from = 0, to = 100) colorTone: Int = 0,
@ColorInt seedColor: Int? = null,
@@ -235,7 +239,7 @@
description = description,
thumbnail = thumbnail,
isReactiveToTone = isReactiveToTone,
- fontAxes = fontAxes,
+ axisPresetConfig = axisPresetConfig,
selectedColorId = selectedColorId,
colorToneProgress = colorTone,
seedColor = seedColor,
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
index acff6e8..b962652 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
@@ -61,9 +61,7 @@
val seedColor: Flow<Int?> = repository.selectedClock.map { clock -> clock.seedColor }
val axisSettings: Flow<ClockAxisStyle?> =
- repository.selectedClock.map { clock ->
- if (clock.fontAxes.isEmpty()) null else ClockAxisStyle(clock.fontAxes)
- }
+ repository.selectedClock.map { it.axisPresetConfig?.current?.style }
val selectedClockSize: Flow<ClockSize> = repository.selectedClockSize
@@ -136,7 +134,7 @@
)
}
clockSnapshotModel.clockId?.let { repository.setSelectedClock(it) }
- clockSnapshotModel.axisSettings?.let { repository.setClockFontAxes(it) }
+ clockSnapshotModel.axisSettings?.let { repository.setClockAxisStyle(it) }
}
private suspend fun storeCurrentClockOption(clockSnapshotModel: ClockSnapshotModel) {
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt
index 41e82eb..62e6d16 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt
@@ -60,7 +60,7 @@
seedColor = repository.selectedClock.map { clock -> clock.seedColor }.firstOrNull(),
axisSettings =
repository.selectedClock
- .map { clock -> ClockAxisStyle(clock.fontAxes) }
+ .map { clock -> clock.axisPresetConfig?.current?.style ?: ClockAxisStyle() }
.firstOrNull(),
)
return snapshot(originalOption)
@@ -97,7 +97,7 @@
)
}
optionToRestore.clockId?.let { repository.setSelectedClock(it) }
- optionToRestore.axisSettings?.let { repository.setClockFontAxes(it) }
+ optionToRestore.axisSettings?.let { repository.setClockAxisStyle(it) }
}
}
diff --git a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
index 8414960..c2274a7 100644
--- a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
+++ b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
@@ -20,7 +20,7 @@
import android.graphics.drawable.Drawable
import androidx.annotation.ColorInt
import androidx.annotation.IntRange
-import com.android.systemui.plugins.clocks.ClockFontAxis
+import com.android.systemui.plugins.clocks.AxisPresetConfig
/** Model for clock metadata. */
data class ClockMetadataModel(
@@ -29,7 +29,7 @@
val description: String,
val thumbnail: Drawable,
val isReactiveToTone: Boolean,
- val fontAxes: List<ClockFontAxis>,
+ val axisPresetConfig: AxisPresetConfig?, // Null indicates the preset list should be disabled.
val selectedColorId: String?,
@IntRange(from = 0, to = 100) val colorToneProgress: Int,
@ColorInt val seedColor: Int?,
diff --git a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
index 09a55e9..275b25a 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
@@ -25,7 +25,6 @@
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver.OnGlobalLayoutListener
-import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.core.graphics.drawable.DrawableCompat
@@ -42,13 +41,9 @@
import com.android.customization.picker.color.ui.view.ColorOptionIconView2
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.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
import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel.Tab
import com.android.wallpaper.customization.ui.viewmodel.ThemePickerCustomizationOptionsViewModel
@@ -60,6 +55,7 @@
import com.google.android.material.materialswitch.MaterialSwitch
import com.google.android.material.slider.LabelFormatter
import com.google.android.material.slider.Slider
+import com.google.android.material.slider.Slider.OnSliderTouchListener
import java.lang.ref.WeakReference
import kotlin.math.roundToInt
import kotlinx.coroutines.DisposableHandle
@@ -90,7 +86,7 @@
val appContext = view.context.applicationContext
val isFloatingSheetActive = { optionsViewModel.selectedOption.value == CLOCK }
- val tabs = view.requireViewById<FloatingToolbar>(R.id.floating_toolbar)
+ val tabs: FloatingToolbar = view.requireViewById(R.id.floating_toolbar)
val tabContainer =
tabs.findViewById<ViewGroup>(com.android.wallpaper.R.id.floating_toolbar_tab_container)
ColorUpdateBinder.bind(
@@ -108,8 +104,8 @@
)
.also { tabs.setAdapter(it) }
- val floatingSheetContainer =
- view.requireViewById<ViewGroup>(R.id.floating_sheet_content_container)
+ val floatingSheetContainer: ViewGroup =
+ view.requireViewById(R.id.floating_sheet_content_container)
ColorUpdateBinder.bind(
setColor = { color ->
DrawableCompat.setTint(
@@ -123,9 +119,7 @@
)
// Clock style
- val clockStyleContent = view.requireViewById<View>(R.id.clock_floating_sheet_style_content)
- val clockSizeSwitch =
- clockStyleContent.requireViewById<MaterialSwitch>(R.id.clock_style_clock_size_switch)
+ val clockStyleContent: View = view.requireViewById(R.id.clock_floating_sheet_style_content)
val isClockStyleActive = {
isFloatingSheetActive() && viewModel.selectedTab.value == Tab.STYLE
}
@@ -135,66 +129,14 @@
shouldAnimateColor = isClockStyleActive,
lifecycleOwner = lifecycleOwner,
)
- val clockStyleList =
- view.requireViewById<RecyclerView>(R.id.clock_style_list).apply {
- initStyleList(appContext, clockStyleAdapter)
- }
- ColorUpdateBinder.bind(
- setColor = { color ->
- clockStyleContent
- .requireViewById<TextView>(R.id.clock_style_clock_size_title)
- .setTextColor(color)
- },
- color = colorUpdateViewModel.colorOnSurface,
- shouldAnimate = isClockStyleActive,
- lifecycleOwner = lifecycleOwner,
- )
- ColorUpdateBinder.bind(
- setColor = { color ->
- clockStyleContent
- .requireViewById<TextView>(R.id.clock_style_clock_size_description)
- .setTextColor(color)
- },
- color = colorUpdateViewModel.colorOnSurfaceVariant,
- shouldAnimate = isClockStyleActive,
- lifecycleOwner = lifecycleOwner,
- )
-
- // Clock font editor
- val clockFontContent =
- view.requireViewById<ViewGroup>(R.id.clock_floating_sheet_font_content)
- val clockFontToolbar = view.requireViewById<ViewGroup>(R.id.clock_font_toolbar)
- clockFontToolbar.requireViewById<View>(R.id.clock_font_revert).setOnClickListener {
- viewModel.cancelFontAxes()
- }
- clockFontToolbar.requireViewById<View>(R.id.clock_font_apply).setOnClickListener {
- viewModel.confirmFontAxes()
- }
- val isClockFontActive = {
- isFloatingSheetActive() && viewModel.selectedTab.value == Tab.FONT
- }
- ColorUpdateBinder.bind(
- setColor = { color ->
- clockFontContent
- .requireViewById<TextView>(R.id.clock_axis_slider_name1)
- .setTextColor(color)
- clockFontContent
- .requireViewById<TextView>(R.id.clock_axis_slider_name2)
- .setTextColor(color)
- clockFontContent
- .requireViewById<TextView>(R.id.clock_axis_switch_name1)
- .setTextColor(color)
- clockFontContent
- .requireViewById<TextView>(R.id.clock_axis_switch_name2)
- .setTextColor(color)
- },
- color = colorUpdateViewModel.colorOnSurface,
- shouldAnimate = isClockFontActive,
- lifecycleOwner = lifecycleOwner,
- )
+ val clockStyleList: RecyclerView = view.requireViewById(R.id.clock_style_list)
+ clockStyleList.initStyleList(appContext, clockStyleAdapter)
+ val axisPresetSlider: Slider =
+ clockStyleContent.requireViewById(R.id.clock_axis_preset_slider)
// Clock color
- val clockColorContent = view.requireViewById<View>(R.id.clock_floating_sheet_color_content)
+ val clockColorContent: View = view.requireViewById(R.id.clock_floating_sheet_color_content)
+
val clockColorAdapter =
createClockColorOptionItemAdapter(
uiMode = view.resources.configuration.uiMode,
@@ -202,21 +144,19 @@
shouldAnimateColor = isFloatingSheetActive,
lifecycleOwner = lifecycleOwner,
)
- val clockColorList =
- view.requireViewById<RecyclerView>(R.id.clock_color_list).apply {
- adapter = clockColorAdapter
- layoutManager =
- LinearLayoutManager(appContext, LinearLayoutManager.HORIZONTAL, false)
- }
- val clockColorSlider: Slider =
- view.requireViewById<Slider>(R.id.clock_color_slider).also {
- SliderColorBinder.bind(
- slider = it,
- colorUpdateViewModel = colorUpdateViewModel,
- shouldAnimateColor = isFloatingSheetActive,
- lifecycleOwner = lifecycleOwner,
- )
- }
+ val clockColorList: RecyclerView = view.requireViewById(R.id.clock_color_list)
+ clockColorList.adapter = clockColorAdapter
+ clockColorList.layoutManager =
+ LinearLayoutManager(appContext, LinearLayoutManager.HORIZONTAL, false)
+
+ val clockColorSlider: Slider = view.requireViewById(R.id.clock_color_slider)
+ SliderColorBinder.bind(
+ slider = clockColorSlider,
+ colorUpdateViewModel = colorUpdateViewModel,
+ shouldAnimateColor = isFloatingSheetActive,
+ lifecycleOwner = lifecycleOwner,
+ )
+
clockColorSlider.apply {
valueFrom = ClockMetadataModel.MIN_COLOR_TONE_PROGRESS.toFloat()
valueTo = ClockMetadataModel.MAX_COLOR_TONE_PROGRESS.toFloat()
@@ -251,16 +191,44 @@
lifecycleOwner = lifecycleOwner,
)
+ // Clock size
+ val clockSizeContent: View = view.requireViewById(R.id.clock_floating_sheet_size_content)
+ val clockSizeSwitch: MaterialSwitch =
+ clockSizeContent.requireViewById(R.id.clock_style_clock_size_switch)
+ ColorUpdateBinder.bind(
+ setColor = { color ->
+ clockSizeContent
+ .requireViewById<TextView>(R.id.clock_style_clock_size_title)
+ .setTextColor(color)
+ },
+ color = colorUpdateViewModel.colorOnSurface,
+ shouldAnimate = isClockStyleActive,
+ lifecycleOwner = lifecycleOwner,
+ )
+ ColorUpdateBinder.bind(
+ setColor = { color ->
+ clockSizeContent
+ .requireViewById<TextView>(R.id.clock_style_clock_size_description)
+ .setTextColor(color)
+ },
+ color = colorUpdateViewModel.colorOnSurfaceVariant,
+ shouldAnimate = isClockStyleActive,
+ lifecycleOwner = lifecycleOwner,
+ )
+
clockStyleContent.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (
clockStyleContent.height != 0 &&
+ axisPresetSlider.height != 0 &&
+ _clockFloatingSheetHeights.value.axisPresetSliderHeight == null &&
_clockFloatingSheetHeights.value.clockStyleContentHeight == null
) {
_clockFloatingSheetHeights.value =
_clockFloatingSheetHeights.value.copy(
- clockStyleContentHeight = clockStyleContent.height
+ clockStyleContentHeight = clockStyleContent.height,
+ axisPresetSliderHeight = axisPresetSlider.height,
)
clockStyleContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
@@ -285,82 +253,100 @@
}
)
- clockFontContent.viewTreeObserver.addOnGlobalLayoutListener(
+ clockSizeContent.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (
- clockFontContent.height != 0 &&
- _clockFloatingSheetHeights.value.clockFontContentHeight == null
+ clockSizeContent.height != 0 &&
+ _clockFloatingSheetHeights.value.clockSizeContentHeight == null
) {
_clockFloatingSheetHeights.value =
_clockFloatingSheetHeights.value.copy(
- clockFontContentHeight = clockFontContent.height
+ clockSizeContentHeight = clockSizeContent.height
)
- clockColorContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
+ clockSizeContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
}
)
lifecycleOwner.lifecycleScope.launch {
- var currentContent: View = clockStyleContent
+ var currentTab: Tab = Tab.STYLE
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch { viewModel.tabs.collect { tabAdapter.submitList(it) } }
launch {
- combine(clockFloatingSheetHeights, viewModel.selectedTab, ::Pair).collect {
- (heights, selectedTab) ->
- val (
- clockStyleContentHeight,
- clockColorContentHeight,
- clockFontContentHeight) =
- heights
- clockStyleContentHeight ?: return@collect
- clockColorContentHeight ?: return@collect
- clockFontContentHeight ?: return@collect
+ combine(
+ clockFloatingSheetHeights,
+ viewModel.selectedTab,
+ viewModel.shouldShowPresetSlider,
+ ::Triple,
+ )
+ .collect { (heights, selectedTab, shouldShowPresetSlider) ->
+ val (
+ clockStyleContentHeight,
+ clockColorContentHeight,
+ clockSizeContentHeight,
+ axisPresetSliderHeight) =
+ heights
+ clockStyleContentHeight ?: return@collect
+ clockColorContentHeight ?: return@collect
+ clockSizeContentHeight ?: return@collect
+ axisPresetSliderHeight ?: return@collect
- 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)
+ val fromHeight = floatingSheetContainer.height
+ val toHeight =
+ when (selectedTab) {
+ Tab.STYLE ->
+ if (shouldShowPresetSlider) clockStyleContentHeight
+ else clockStyleContentHeight - axisPresetSliderHeight
+ Tab.COLOR -> clockColorContentHeight
+ Tab.SIZE -> clockSizeContentHeight
}
- 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
+ val currentContent: View =
+ when (currentTab) {
+ Tab.STYLE -> clockStyleContent
+ Tab.COLOR -> clockColorContent
+ Tab.SIZE -> clockSizeContent
+ }
+ val shouldCurrentContentFadeOut = currentTab != selectedTab
+ // 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
+ }
+ if (shouldCurrentContentFadeOut) {
+ currentContent.alpha =
+ getAlpha(fromHeight, toHeight, value)
}
}
- )
- }
- .start()
- }
+ 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
+ clockSizeContent.isVisible = selectedTab == Tab.SIZE
+ clockSizeContent.alpha = 1f
+ }
+ }
+ )
+ }
+ .start()
+ currentTab = selectedTab
+ }
+ }
+
+ launch {
+ viewModel.shouldShowPresetSlider.collect { axisPresetSlider.isVisible = it }
}
launch {
@@ -429,120 +415,30 @@
}
}
}
- }
- }
- bindClockFontContent(
- clockFontContent = clockFontContent,
- viewModel = viewModel,
- colorUpdateViewModel = colorUpdateViewModel,
- shouldAnimateColor = isClockFontActive,
- lifecycleOwner = lifecycleOwner,
- )
- }
-
- private fun bindClockFontContent(
- clockFontContent: View,
- viewModel: ClockPickerViewModel,
- colorUpdateViewModel: ColorUpdateViewModel,
- shouldAnimateColor: () -> Boolean,
- lifecycleOwner: LifecycleOwner,
- ) {
- val slider1 =
- clockFontContent.requireViewById<Slider>(R.id.clock_axis_slider1).also {
- SliderColorBinder.bind(
- slider = it,
- colorUpdateViewModel = colorUpdateViewModel,
- shouldAnimateColor = shouldAnimateColor,
- lifecycleOwner = lifecycleOwner,
- )
- }
- val slider2 =
- clockFontContent.requireViewById<Slider>(R.id.clock_axis_slider2).also {
- SliderColorBinder.bind(
- slider = it,
- colorUpdateViewModel = colorUpdateViewModel,
- shouldAnimateColor = shouldAnimateColor,
- lifecycleOwner = lifecycleOwner,
- )
- }
- val sliderViewList =
- listOf(
- ClockFontSliderViewHolder(
- name = clockFontContent.requireViewById(R.id.clock_axis_slider_name1),
- slider = slider1,
- ),
- ClockFontSliderViewHolder(
- name = clockFontContent.requireViewById(R.id.clock_axis_slider_name2),
- slider = 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()
-
- lifecycleOwner.lifecycleScope.launch {
- lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
- viewModel.previewingClockFontAxes.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()
+ viewModel.axisPresetsSliderViewModel.collect {
+ val axisPresetsSliderViewModel = it ?: return@collect
+ axisPresetSlider.valueFrom = axisPresetsSliderViewModel.valueFrom
+ axisPresetSlider.valueTo = axisPresetsSliderViewModel.valueTo
+ axisPresetSlider.stepSize = axisPresetsSliderViewModel.stepSize
+ axisPresetSlider.clearOnSliderTouchListeners()
+ axisPresetSlider.addOnSliderTouchListener(
+ object : OnSliderTouchListener {
+ override fun onStartTrackingTouch(slider: Slider) {}
- // 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 onStopTrackingTouch(slider: Slider) {
+ axisPresetsSliderViewModel.onSliderStopTrackingTouch(
+ slider.value
+ )
}
}
- }
-
- // 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(
- clockFontAxis = booleanAxis,
- onFontAxisValueUpdated = { value ->
- viewModel.updatePreviewFontAxis(booleanAxis.key, value)
- },
- colorUpdateViewModel = colorUpdateViewModel,
- shouldAnimateColor = shouldAnimateColor,
- lifecycleOwner = lifecycleOwner,
- )
- }
- }
+ )
}
}
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)
- }
- }
+ viewModel.axisPresetsSliderSelectedValue.collect { axisPresetSlider.value = it }
}
}
}
@@ -560,29 +456,7 @@
view
.findViewById<ImageView>(R.id.foreground)
?.setImageDrawable(styleModel.thumbnail)
- val job =
- lifecycleOwner.lifecycleScope.launch {
- lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
- styleModel.showEditButton.collect {
- view.findViewById<FrameLayout>(R.id.edit_icon)?.isVisible = it
- }
- }
- }
- val binding =
- ColorUpdateBinder.bind(
- setColor = { color ->
- view.findViewById<ImageView>(R.id.edit_icon_background)?.drawable?.let {
- DrawableCompat.setTint(DrawableCompat.wrap(it), color)
- }
- },
- color = colorUpdateViewModel.colorOnPrimaryFixedVariant,
- shouldAnimate = shouldAnimateColor,
- lifecycleOwner = lifecycleOwner,
- )
- return@OptionItemAdapter2 DisposableHandle {
- job.cancel()
- binding.destroy()
- }
+ return@OptionItemAdapter2 null
},
colorUpdateViewModel = WeakReference(colorUpdateViewModel),
shouldAnimateColor = shouldAnimateColor,
@@ -616,10 +490,8 @@
layoutResourceId = R.layout.color_option2,
lifecycleOwner = lifecycleOwner,
bindPayload = { itemView: View, colorIcon: ColorOptionIconViewModel ->
- val colorOptionIconView =
- itemView.requireViewById<ColorOptionIconView2>(
- com.android.wallpaper.R.id.background
- )
+ val colorOptionIconView: ColorOptionIconView2 =
+ itemView.requireViewById(com.android.wallpaper.R.id.background)
val night = uiMode and UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES
val binding =
ColorOptionIconBinder2.bind(
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
index 5736e0e..09bb692 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
@@ -81,6 +81,7 @@
navigateToMoreLockScreenSettingsActivity: () -> Unit,
navigateToColorContrastSettingsActivity: () -> Unit,
navigateToLockScreenNotificationsSettingsActivity: () -> Unit,
+ navigateToPackThemeActivity: () -> Unit,
) {
defaultCustomizationOptionsBinder.bind(
view,
@@ -93,6 +94,7 @@
navigateToMoreLockScreenSettingsActivity,
navigateToColorContrastSettingsActivity,
navigateToLockScreenNotificationsSettingsActivity,
+ navigateToPackThemeActivity,
)
val isComposeRefactorEnabled = BaseFlags.get().isComposeRefactorEnabled()
@@ -179,15 +181,18 @@
var optionPackThemeIconLock: ImageView? = null
if (BaseFlags.get().isPackThemeEnabled()) {
- val optionPackThemeHome: View =
+ val optionPackThemeHome =
homeScreenCustomizationOptionEntries
.first { it.first == ThemePickerHomeCustomizationOption.PACK_THEME }
.second
+ optionPackThemeHome.setOnClickListener { navigateToPackThemeActivity.invoke() }
optionPackThemeIconHome = optionPackThemeHome.requireViewById(R.id.option_entry_icon)
- val optionPackThemeLock: View =
- homeScreenCustomizationOptionEntries
+
+ val optionPackThemeLock =
+ lockScreenCustomizationOptionEntries
.first { it.first == ThemePickerHomeCustomizationOption.PACK_THEME }
.second
+ optionPackThemeLock.setOnClickListener { navigateToPackThemeActivity.invoke() }
optionPackThemeIconLock = optionPackThemeLock.requireViewById(R.id.option_entry_icon)
}
@@ -416,6 +421,7 @@
override fun bindClockPreview(
context: Context,
clockHostView: View,
+ clockFaceClickDelegateView: View,
viewModel: CustomizationPickerViewModel2,
colorUpdateViewModel: ColorUpdateViewModel,
lifecycleOwner: LifecycleOwner,
@@ -486,20 +492,38 @@
combine(
clockPickerViewModel.previewingSeedColor,
clockPickerViewModel.previewingClock,
- clockPickerViewModel.previewingClockFontAxisMap,
+ clockPickerViewModel.previewingClockPresetIndexedStyle,
colorUpdateViewModel.systemColorsUpdated,
::Quadruple,
)
.collect { quadruple ->
- val (color, clock, axisMap, _) = quadruple
+ val (color, clock, clockPresetIndexedStyle, _) = quadruple
clockViewFactory.updateColor(clock.clockId, color)
- clockViewFactory.updateFontAxes(clock.clockId, ClockAxisStyle(axisMap))
+ clockViewFactory.updateFontAxes(
+ clock.clockId,
+ clockPresetIndexedStyle?.style ?: ClockAxisStyle(),
+ )
}
}
launch {
viewModel.lockPreviewAnimateToAlpha.collect { clockHostView.animateToAlpha(it) }
}
+
+ launch {
+ combine(
+ viewModel.customizationOptionsViewModel.selectedOption,
+ clockPickerViewModel.onClockFaceClicked,
+ ::Pair,
+ )
+ .collect { (selectedOption, onClockFaceClicked) ->
+ clockFaceClickDelegateView.isVisible =
+ selectedOption == ThemePickerLockCustomizationOption.CLOCK
+ clockFaceClickDelegateView.setOnClickListener {
+ onClockFaceClicked.invoke()
+ }
+ }
+ }
}
}
}
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
index cb4ab57..f818ff8 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
@@ -16,8 +16,6 @@
package com.android.wallpaper.customization.ui.binder
-import android.animation.ValueAnimator
-import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.Button
import android.widget.FrameLayout
import android.widget.Toolbar
@@ -35,7 +33,6 @@
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.SHORTCUTS
import com.android.wallpaper.customization.ui.viewmodel.ThemePickerCustomizationOptionsViewModel
-import com.android.wallpaper.customization.ui.viewmodel.ToolbarHeightsViewModel
import com.android.wallpaper.picker.customization.ui.binder.ColorUpdateBinder
import com.android.wallpaper.picker.customization.ui.binder.DefaultToolbarBinder
import com.android.wallpaper.picker.customization.ui.binder.ToolbarBinder
@@ -43,7 +40,6 @@
import com.android.wallpaper.picker.customization.ui.viewmodel.CustomizationOptionsViewModel
import javax.inject.Inject
import javax.inject.Singleton
-import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
@@ -61,8 +57,6 @@
lifecycleOwner: LifecycleOwner,
onNavBack: () -> Unit,
) {
- val toolbarHeights: MutableStateFlow<ToolbarHeightsViewModel?> = MutableStateFlow(null)
-
defaultToolbarBinder.bind(
navButton,
toolbar,
@@ -79,45 +73,6 @@
)
}
- navButton.viewTreeObserver.addOnGlobalLayoutListener(
- object : OnGlobalLayoutListener {
- override fun onGlobalLayout() {
- if (navButton.height != 0) {
- toolbarHeights.value =
- toolbarHeights.value?.copy(navButtonHeight = navButton.height)
- ?: ToolbarHeightsViewModel(navButtonHeight = navButton.height)
- }
- navButton.viewTreeObserver.removeOnGlobalLayoutListener(this)
- }
- }
- )
-
- toolbar.viewTreeObserver.addOnGlobalLayoutListener(
- object : OnGlobalLayoutListener {
- override fun onGlobalLayout() {
- if (toolbar.height != 0) {
- toolbarHeights.value =
- toolbarHeights.value?.copy(toolbarHeight = toolbar.height)
- ?: ToolbarHeightsViewModel(toolbarHeight = toolbar.height)
- }
- navButton.viewTreeObserver.removeOnGlobalLayoutListener(this)
- }
- }
- )
-
- applyButton.viewTreeObserver.addOnGlobalLayoutListener(
- object : OnGlobalLayoutListener {
- override fun onGlobalLayout() {
- if (applyButton.height != 0) {
- toolbarHeights.value =
- toolbarHeights.value?.copy(applyButtonHeight = applyButton.height)
- ?: ToolbarHeightsViewModel(applyButtonHeight = applyButton.height)
- }
- applyButton.viewTreeObserver.removeOnGlobalLayoutListener(this)
- }
- }
- )
-
ColorUpdateBinder.bind(
setColor = { color ->
DrawableCompat.setTint(DrawableCompat.wrap(applyButton.background), color)
@@ -177,53 +132,6 @@
toolbar.title = toolbar.resources.getString(stringResId)
}
}
-
- launch {
- combine(toolbarHeights, viewModel.isToolbarCollapsed, ::Pair).collect {
- (toolbarHeights, isToolbarCollapsed) ->
- val (navButtonHeight, toolbarHeight, applyButtonHeight) =
- toolbarHeights ?: return@collect
- navButtonHeight ?: return@collect
- toolbarHeight ?: return@collect
- applyButtonHeight ?: return@collect
-
- val navButtonToHeight = if (isToolbarCollapsed) 0 else navButtonHeight
- val toolbarToHeight = if (isToolbarCollapsed) 0 else toolbarHeight
- val applyButtonToHeight = if (isToolbarCollapsed) 0 else applyButtonHeight
- ValueAnimator.ofInt(navButton.height, navButtonToHeight)
- .apply {
- addUpdateListener { valueAnimator ->
- val value = valueAnimator.animatedValue as Int
- navButton.layoutParams =
- navButton.layoutParams.apply { height = value }
- }
- duration = ANIMATION_DURATION
- }
- .start()
-
- ValueAnimator.ofInt(toolbar.height, toolbarToHeight)
- .apply {
- addUpdateListener { valueAnimator ->
- val value = valueAnimator.animatedValue as Int
- toolbar.layoutParams =
- toolbar.layoutParams.apply { height = value }
- }
- duration = ANIMATION_DURATION
- }
- .start()
-
- ValueAnimator.ofInt(applyButton.height, applyButtonToHeight)
- .apply {
- addUpdateListener { valueAnimator ->
- val value = valueAnimator.animatedValue as Int
- applyButton.layoutParams =
- applyButton.layoutParams.apply { height = value }
- }
- duration = ANIMATION_DURATION
- }
- .start()
- }
- }
}
}
}
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
deleted file mode 100644
index fb14342..0000000
--- a/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.TextView
-import androidx.core.view.isInvisible
-import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.google.android.material.slider.LabelFormatter
-import com.google.android.material.slider.Slider
-
-class ClockFontSliderViewHolder(val name: TextView, val slider: Slider) {
-
- fun setIsVisible(isVisible: Boolean) {
- name.isInvisible = !isVisible
- slider.isInvisible = !isVisible
- }
-
- fun initView(clockFontAxis: ClockFontAxis, onFontAxisValueUpdated: (value: Float) -> Unit) {
- name.text = clockFontAxis.name
- slider.apply {
- valueFrom = clockFontAxis.minValue
- valueTo = clockFontAxis.maxValue
- value = clockFontAxis.currentValue
- labelBehavior = LabelFormatter.LABEL_GONE
- addOnChangeListener { _, value, fromUser ->
- if (fromUser) {
- onFontAxisValueUpdated.invoke(value)
- }
- }
- }
- }
-
- fun setValue(value: Float) {
- slider.value = value
- }
-}
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
deleted file mode 100644
index fcf70d3..0000000
--- a/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.TextView
-import androidx.core.view.isVisible
-import androidx.lifecycle.LifecycleOwner
-import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.wallpaper.customization.ui.binder.SwitchColorBinder
-import com.android.wallpaper.picker.customization.ui.viewmodel.ColorUpdateViewModel
-import com.google.android.material.materialswitch.MaterialSwitch
-import kotlin.math.abs
-
-class ClockFontSwitchViewHolder(val name: TextView, val switch: MaterialSwitch) {
-
- private var switchMaxValue: Float? = null
-
- fun setIsVisible(isVisible: Boolean) {
- name.isVisible = isVisible
- switch.isVisible = isVisible
- }
-
- fun initView(
- clockFontAxis: ClockFontAxis,
- onFontAxisValueUpdated: (value: Float) -> Unit,
- colorUpdateViewModel: ColorUpdateViewModel,
- shouldAnimateColor: () -> Boolean,
- lifecycleOwner: LifecycleOwner,
- ) {
- switchMaxValue = clockFontAxis.maxValue
- name.text = clockFontAxis.name
- switch.apply {
- isChecked = abs(clockFontAxis.currentValue - clockFontAxis.maxValue) < 0.01f
- var binding: SwitchColorBinder.Binding =
- SwitchColorBinder.bind(
- switch = switch,
- isChecked = isChecked,
- colorUpdateViewModel = colorUpdateViewModel,
- shouldAnimateColor = shouldAnimateColor,
- lifecycleOwner = lifecycleOwner,
- )
- setOnCheckedChangeListener { v, _ ->
- binding.destroy()
- binding =
- SwitchColorBinder.bind(
- switch = switch,
- isChecked = v.isChecked,
- colorUpdateViewModel = colorUpdateViewModel,
- shouldAnimateColor = shouldAnimateColor,
- lifecycleOwner = lifecycleOwner,
- )
- 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/ClockAxisPresetSliderViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockAxisPresetSliderViewModel.kt
new file mode 100644
index 0000000..d11044a
--- /dev/null
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockAxisPresetSliderViewModel.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 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.viewmodel
+
+/** Data class representing [com.google.android.material.slider]'s configuration. */
+data class ClockAxisPresetSliderViewModel(
+ val valueFrom: Float,
+ val valueTo: Float,
+ val stepSize: Float,
+ val onSliderStopTrackingTouch: (value: Float) -> Unit,
+)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
index 249f862..fcfec5f 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
@@ -19,5 +19,6 @@
data class ClockFloatingSheetHeightsViewModel(
val clockStyleContentHeight: Int? = null,
val clockColorContentHeight: Int? = null,
- val clockFontContentHeight: Int? = null,
+ val clockSizeContentHeight: Int? = null,
+ val axisPresetSliderHeight: 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 dca361f..cff9e08 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
@@ -28,6 +28,8 @@
import com.android.customization.picker.clock.ui.viewmodel.ClockColorViewModel
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor2
import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
+import com.android.systemui.plugins.clocks.AxisPresetConfig
+import com.android.systemui.plugins.clocks.AxisPresetConfig.IndexedStyle
import com.android.systemui.plugins.clocks.ClockAxisStyle
import com.android.themepicker.R
import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
@@ -40,6 +42,7 @@
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -74,7 +77,7 @@
enum class Tab {
STYLE,
COLOR,
- FONT,
+ SIZE,
}
private val colorMap = ClockColorViewModel.getPresetColorMap(context.resources)
@@ -92,9 +95,9 @@
contentDescription = Text.Resource(R.string.clock_style),
),
text = context.getString(R.string.clock_style),
- isSelected = it == Tab.STYLE || it == Tab.FONT,
+ isSelected = it == Tab.STYLE,
onClick =
- if (it == Tab.STYLE || it == Tab.FONT) null
+ if (it == Tab.STYLE) null
else {
{ _selectedTab.value = Tab.STYLE }
},
@@ -113,29 +116,41 @@
{ _selectedTab.value = Tab.COLOR }
},
),
+ FloatingToolbarTabViewModel(
+ icon =
+ Icon.Resource(
+ res = R.drawable.ic_font_size_filled_24px,
+ contentDescription = Text.Resource(R.string.clock_size),
+ ),
+ text = context.getString(R.string.clock_size),
+ isSelected = it == Tab.SIZE,
+ onClick =
+ if (it == Tab.SIZE) null
+ else {
+ { _selectedTab.value = Tab.SIZE }
+ },
+ ),
)
}
// Clock style
private val overridingClock = MutableStateFlow<ClockMetadataModel?>(null)
- private val isClockEdited =
- combine(overridingClock, clockPickerInteractor.selectedClock) {
- overridingClock,
- selectedClock ->
- overridingClock != null && overridingClock.clockId != selectedClock.clockId
- }
val selectedClock = clockPickerInteractor.selectedClock
val previewingClock =
combine(overridingClock, selectedClock) { overridingClock, selectedClock ->
(overridingClock ?: selectedClock)
}
.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
+ private val isClockEdited =
+ combine(overridingClock, selectedClock) { overridingClock, selectedClock ->
+ overridingClock != null && overridingClock.clockId != selectedClock.clockId
+ }
suspend fun getIsShadeLayoutWide() = clockPickerInteractor.getIsShadeLayoutWide()
suspend fun getUdfpsLocation() = clockPickerInteractor.getUdfpsLocation()
- data class ClockStyleModel(val thumbnail: Drawable, val showEditButton: StateFlow<Boolean>)
+ data class ClockStyleModel(val thumbnail: Drawable)
@OptIn(ExperimentalCoroutinesApi::class)
val clockStyleOptions: StateFlow<List<OptionItemViewModel2<ClockStyleModel>>> =
@@ -143,7 +158,7 @@
.mapLatest { allClocks ->
// Delay to avoid the case that the full list of clocks is not initiated.
delay(CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
- val allClockMap = allClocks.groupBy { it.fontAxes.isNotEmpty() }
+ val allClockMap = allClocks.groupBy { it.axisPresetConfig != null }
buildList {
allClockMap[true]?.map { add(it.toOption(resources)) }
allClockMap[false]?.map { add(it.toOption(resources)) }
@@ -155,83 +170,107 @@
.flowOn(backgroundDispatcher.limitedParallelism(1))
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
+ // Clock font presets
+ private val overridingClockPresetIndexedStyle: MutableStateFlow<IndexedStyle?> =
+ MutableStateFlow(null)
+ private val selectedClockPresetIndexedStyle: Flow<IndexedStyle?> =
+ previewingClock
+ .map { it.axisPresetConfig?.current }
+ .shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
+ val previewingClockPresetIndexedStyle: Flow<IndexedStyle?> =
+ combine(overridingClockPresetIndexedStyle, selectedClockPresetIndexedStyle) {
+ overridingClockPresetIndexedStyle,
+ selectedClockPresetIndexedStyle ->
+ overridingClockPresetIndexedStyle ?: selectedClockPresetIndexedStyle
+ }
+ private val isClockAxisStyleEdited: Flow<Boolean> =
+ combine(overridingClockPresetIndexedStyle, selectedClockPresetIndexedStyle) {
+ overridingClockPresetIndexedStyle,
+ selectedClockPresetIndexedStyle ->
+ overridingClockPresetIndexedStyle != null &&
+ (overridingClockPresetIndexedStyle.style != selectedClockPresetIndexedStyle?.style)
+ }
+
+ private val groups: Flow<List<AxisPresetConfig.Group>?> =
+ previewingClock.map { it.axisPresetConfig?.groups }
+ private val previewingClockPresetGroupIndex: Flow<Int> =
+ previewingClockPresetIndexedStyle.map { it?.groupIndex ?: 0 }.distinctUntilChanged()
+ val shouldShowPresetSlider: Flow<Boolean> = previewingClock.map { it.axisPresetConfig != null }
+ val axisPresetsSliderViewModel: Flow<ClockAxisPresetSliderViewModel?> =
+ combine(groups, previewingClockPresetGroupIndex) { groups, previewingClockPresetGroupIndex
+ ->
+ if (groups.isNullOrEmpty()) {
+ null
+ } else {
+ val group = groups[previewingClockPresetGroupIndex]
+ ClockAxisPresetSliderViewModel(
+ valueFrom = 0F,
+ valueTo = (group.presets.size - 1).toFloat(),
+ stepSize = 1F,
+ onSliderStopTrackingTouch = { value ->
+ val presetIndex = value.roundToInt()
+ overridingClockPresetIndexedStyle.value =
+ IndexedStyle(
+ groupIndex = previewingClockPresetGroupIndex,
+ presetIndex = presetIndex,
+ style = group.presets[presetIndex],
+ )
+ },
+ )
+ }
+ }
+ val axisPresetsSliderSelectedValue: Flow<Float> =
+ previewingClockPresetIndexedStyle.map { it?.presetIndex?.toFloat() }.filterNotNull()
+ val onClockFaceClicked: Flow<() -> Unit> =
+ combine(groups, previewingClockPresetIndexedStyle) { groups, previewingIndexedStyle ->
+ if (groups.isNullOrEmpty()) {
+ {}
+ } else {
+ val groupCount = groups.size
+ if (groupCount == 1) {
+ {}
+ } else {
+ val currentGroupIndex = previewingIndexedStyle?.groupIndex ?: 0
+ val nextGroupIndex = (currentGroupIndex + 1) % groupCount
+ val nextPresetIndex = previewingIndexedStyle?.presetIndex ?: (groupCount / 2)
+ val nextGroup = groups[nextGroupIndex]
+ {
+ overridingClockPresetIndexedStyle.value =
+ IndexedStyle(
+ groupIndex = nextGroupIndex,
+ presetIndex = nextPresetIndex,
+ style = nextGroup.presets[nextPresetIndex],
+ )
+ }
+ }
+ }
+ }
+
private suspend fun ClockMetadataModel.toOption(
resources: Resources
): 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 OptionItemViewModel2<ClockStyleModel>(
key = MutableStateFlow(clockId) as StateFlow<String>,
- payload = ClockStyleModel(thumbnail = thumbnail, showEditButton = showEditButton),
+ payload = ClockStyleModel(thumbnail = thumbnail),
text = Text.Loaded(contentDescription),
isTextUserVisible = false,
isSelected = isSelectedFlow,
onClicked =
isSelectedFlow.map { isSelected ->
- if (isSelected && isEditable) {
- fun() {
- _selectedTab.value = Tab.FONT
- }
+ if (isSelected) {
+ null
} else {
fun() {
overridingClock.value = this
- overrideClockFontAxisMap.value = emptyMap()
}
}
},
)
}
- // Clock font axis
- private val overrideClockFontAxisMap = MutableStateFlow<Map<String, Float>>(emptyMap())
- val previewingClockFontAxes =
- previewingClock
- .map { clock -> clock.fontAxes }
- .shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
- private val selectedClockFontAxisMap =
- selectedClock
- .map { clock -> clock.fontAxes.associate { it.key to it.currentValue } }
- .shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
- private val isFontAxisMapEdited =
- combine(overrideClockFontAxisMap, selectedClockFontAxisMap) {
- overrideClockFontAxisMap,
- selectedClockFontAxisMap ->
- !overrideClockFontAxisMap.all { (key, value) -> selectedClockFontAxisMap[key] == value }
- }
- val previewingClockFontAxisMap =
- combine(overrideClockFontAxisMap, selectedClockFontAxisMap.filterNotNull()) {
- overrideAxisMap,
- selectedAxisMap ->
- if (overrideAxisMap.isEmpty()) {
- selectedAxisMap
- } else {
- overrideAxisMap.let {
- val mutableMap = selectedAxisMap.toMutableMap()
- overrideAxisMap.forEach { (key, value) -> mutableMap[key] = value }
- mutableMap.toMap()
- }
- }
- }
- .stateIn(viewModelScope, SharingStarted.Eagerly, emptyMap())
-
- fun updatePreviewFontAxis(key: String, value: Float) {
- val axisMap = overrideClockFontAxisMap.value.toMutableMap()
- axisMap[key] = value
- overrideClockFontAxisMap.value = axisMap.toMap()
- }
-
- fun confirmFontAxes() {
- _selectedTab.value = Tab.STYLE
- }
-
- fun cancelFontAxes() {
- overrideClockFontAxisMap.value = emptyMap()
- _selectedTab.value = Tab.STYLE
- }
-
// Clock size
private val overridingClockSize = MutableStateFlow<ClockSize?>(null)
private val isClockSizeEdited =
@@ -415,18 +454,18 @@
private val isEdited =
combine(
isClockEdited,
- isFontAxisMapEdited,
+ isClockAxisStyleEdited,
isClockSizeEdited,
isClockColorIdEdited,
isSliderProgressEdited,
) {
isClockEdited,
- isFontAxisMapEdited,
+ isClockAxisStyleEdited,
isClockSizeEdited,
isClockColorEdited,
isSliderProgressEdited ->
isClockEdited ||
- isFontAxisMapEdited ||
+ isClockAxisStyleEdited ||
isClockSizeEdited ||
isClockColorEdited ||
isSliderProgressEdited
@@ -440,7 +479,7 @@
previewingClockSize,
previewingClockColorId,
previewingSliderProgress,
- previewingClockFontAxisMap,
+ previewingClockPresetIndexedStyle,
) { array ->
val onApplyClicked: Boolean = array[0] as Boolean
val isEdited: Boolean = array[1] as Boolean
@@ -448,7 +487,8 @@
val size: ClockSize = array[3] as ClockSize
val previewingColorId: String = array[4] as String
val previewProgress: Int = array[5] as Int
- val axisMap: Map<String, Float> = array[6] as Map<String, Float>
+ val clockAxisStyle: ClockAxisStyle =
+ (array[6] as? IndexedStyle)?.style ?: ClockAxisStyle()
if (isEdited && !onApplyClicked) {
{
this.onApplyClicked.value = true
@@ -464,7 +504,7 @@
colorTone = it.getColorTone(previewProgress),
)
},
- axisSettings = ClockAxisStyle(axisMap),
+ axisSettings = clockAxisStyle,
)
}
} else {
@@ -477,7 +517,7 @@
overridingClockSize.value = null
overridingClockColorId.value = null
overridingSliderProgress.value = null
- overrideClockFontAxisMap.value = emptyMap()
+ overridingClockPresetIndexedStyle.value = null
_selectedTab.value = Tab.STYLE
onApplyClicked.value = false
}
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
index 95f55c0..9414cc7 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
@@ -32,7 +32,6 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
@@ -77,16 +76,6 @@
defaultCustomizationOptionsViewModel.discardChangesDialogViewModel
override fun handleBackPressed(): Boolean {
-
- if (
- defaultCustomizationOptionsViewModel.selectedOption.value ==
- ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK &&
- clockPickerViewModel.selectedTab.value == ClockPickerViewModel.Tab.FONT
- ) {
- clockPickerViewModel.cancelFontAxes()
- return true
- }
-
if (isApplyButtonEnabled.value) {
defaultCustomizationOptionsViewModel.showDiscardChangesDialogViewModel()
return true
@@ -212,14 +201,6 @@
val isApplyButtonVisible: Flow<Boolean> = selectedOption.map { it != null }
- val isToolbarCollapsed: Flow<Boolean> =
- combine(selectedOption, clockPickerViewModel.selectedTab) { selectedOption, selectedTab ->
- selectedOption ==
- ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK &&
- selectedTab == ClockPickerViewModel.Tab.FONT
- }
- .distinctUntilChanged()
-
@ViewModelScoped
@AssistedFactory
interface Factory : CustomizationOptionsViewModelFactory {
diff --git a/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt b/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
index fd2c801..7728218 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
@@ -22,16 +22,16 @@
import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository.Companion.fakeClocks
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.systemui.plugins.clocks.AxisPresetConfig
+import com.android.systemui.plugins.clocks.AxisPresetConfig.Group
import com.android.systemui.plugins.clocks.AxisType
import com.android.systemui.plugins.clocks.ClockAxisStyle
import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge
import com.android.systemui.plugins.clocks.ClockId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.update
/** By default [FakeClockPickerRepository] uses [fakeClocks]. */
open class FakeClockPickerRepository(clocks: List<ClockMetadataModel> = fakeClocks) :
@@ -43,16 +43,16 @@
private val colorTone: MutableStateFlow<Int> =
MutableStateFlow(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS)
@ColorInt private val seedColor: MutableStateFlow<Int?> = MutableStateFlow(null)
- private val fontAxes: MutableStateFlow<List<ClockFontAxis>> =
- MutableStateFlow(listOf(buildFakeAxis(0)))
+ private val clockListFlow: MutableStateFlow<List<ClockMetadataModel>> =
+ MutableStateFlow(fakeClocks)
override val selectedClock: Flow<ClockMetadataModel> =
- combine(selectedClockId, selectedColorId, colorTone, seedColor, fontAxes) {
+ combine(clockListFlow, selectedClockId, selectedColorId, colorTone, seedColor) {
+ clockList,
selectedClockId,
selectedColor,
colorTone,
- seedColor,
- fontAxes ->
- val selectedClock = fakeClocks.find { clock -> clock.clockId == selectedClockId }
+ seedColor ->
+ val selectedClock = clockList.find { clock -> clock.clockId == selectedClockId }
checkNotNull(selectedClock)
ClockMetadataModel(
clockId = selectedClock.clockId,
@@ -60,7 +60,7 @@
description = "description",
thumbnail = ColorDrawable(0),
isReactiveToTone = selectedClock.isReactiveToTone,
- fontAxes = fontAxes,
+ axisPresetConfig = selectedClock.axisPresetConfig,
selectedColorId = selectedColor,
colorToneProgress = colorTone,
seedColor = seedColor,
@@ -88,16 +88,31 @@
_selectedClockSize.value = size
}
- override suspend fun setClockFontAxes(axisSettings: ClockAxisStyle) {
- fontAxes.update { fontAxes -> fontAxes.merge(axisSettings) }
+ override suspend fun setClockAxisStyle(axisStyle: ClockAxisStyle) {
+ val clockList = clockListFlow.value
+ val newClockList = clockList.toMutableList()
+ for ((index, clock) in clockList.withIndex()) {
+ val presetConfig = clock.axisPresetConfig
+ val style = presetConfig?.findStyle(axisStyle)
+ if (presetConfig != null && style != null) {
+ newClockList[index] =
+ clock.copy(axisPresetConfig = presetConfig.copy(current = style))
+ }
+ }
+
+ clockListFlow.value = newClockList.toList()
}
override fun isReactiveToTone(clockId: ClockId): Boolean? = true
companion object {
- fun buildFakeAxis(i: Int): ClockFontAxis {
+ fun buildFakeClockAxisStyle(i: Int): ClockAxisStyle {
+ return ClockAxisStyle(listOf(buildFakeAxis(i)))
+ }
+
+ private fun buildFakeAxis(i: Int): ClockFontAxis {
return ClockFontAxis(
- key = "key",
+ key = "key#$i",
type = AxisType.Float,
maxValue = 0f,
minValue = 1000f,
@@ -107,10 +122,36 @@
)
}
+ private val fakeClockAxisStyle0 = ClockAxisStyle(listOf(buildFakeAxis(0)))
+ val fakeClockAxisStyle1 = ClockAxisStyle(listOf(buildFakeAxis(1)))
+ private val fakeClockAxisStyle2 = ClockAxisStyle(listOf(buildFakeAxis(2)))
+ private val fakeClockAxisStyle3 = ClockAxisStyle(listOf(buildFakeAxis(3)))
+ private val fakeAxisPresetConfig: AxisPresetConfig =
+ AxisPresetConfig(
+ groups =
+ listOf(
+ AxisPresetConfig.Group(
+ presets = listOf(fakeClockAxisStyle0, fakeClockAxisStyle1),
+ icon = ColorDrawable(Color.BLUE),
+ ),
+ AxisPresetConfig.Group(
+ presets = listOf(fakeClockAxisStyle2, fakeClockAxisStyle3),
+ icon = ColorDrawable(Color.YELLOW),
+ ),
+ ),
+ current =
+ AxisPresetConfig.IndexedStyle(
+ groupIndex = 0,
+ presetIndex = 0,
+ style = fakeClockAxisStyle0,
+ ),
+ )
+
const val CLOCK_ID_0 = "clock0"
const val CLOCK_ID_1 = "clock1"
const val CLOCK_ID_2 = "clock2"
const val CLOCK_ID_3 = "clock3"
+
val fakeClocks =
listOf(
ClockMetadataModel(
@@ -119,7 +160,7 @@
"description0",
ColorDrawable(0),
true,
- listOf(buildFakeAxis(0)),
+ fakeAxisPresetConfig,
null,
50,
null,
@@ -130,7 +171,7 @@
"description1",
ColorDrawable(0),
true,
- listOf(buildFakeAxis(1)),
+ null,
null,
50,
null,
@@ -141,7 +182,7 @@
"description2",
ColorDrawable(0),
true,
- listOf(buildFakeAxis(2)),
+ null,
null,
50,
null,
@@ -152,7 +193,7 @@
"description3",
ColorDrawable(0),
false,
- listOf(buildFakeAxis(3)),
+ null,
null,
50,
null,
diff --git a/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt b/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
index 484d810..67c2e46 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
@@ -3,7 +3,6 @@
import androidx.test.filters.SmallTest
import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
import com.android.customization.picker.clock.shared.ClockSize
-import com.android.systemui.plugins.clocks.ClockAxisStyle
import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
import com.android.wallpaper.picker.customization.data.repository.CustomizationRuntimeValuesRepository
import com.android.wallpaper.testing.FakeSnapshotStore
@@ -89,7 +88,7 @@
@Test
fun setFontAxisSettings() = runTest {
val axisSettings = collectLastValue(underTest.axisSettings)
- val fakeSettings = ClockAxisStyle(listOf(FakeClockPickerRepository.buildFakeAxis(10)))
+ val fakeSettings = FakeClockPickerRepository.fakeClockAxisStyle1
underTest.setClockFontAxes(fakeSettings)
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
index 0386c85..07d7cbf 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -60,7 +60,7 @@
description = "description",
thumbnail = ColorDrawable(0),
isReactiveToTone = true,
- fontAxes = listOf(),
+ axisPresetConfig = null,
selectedColorId = null,
colorToneProgress = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
seedColor = null,
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 482af7e..132133e 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
@@ -28,6 +28,7 @@
import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
import com.android.customization.picker.color.data.repository.FakeColorPickerRepository2
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor2
+import com.android.systemui.plugins.clocks.AxisPresetConfig.IndexedStyle
import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
import com.android.themepicker.R
import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel.Tab
@@ -114,48 +115,13 @@
Dispatchers.resetMain()
}
- @Test
- fun selectedTab_whenClickOnTabStyle() = runTest {
- val tabs = collectLastValue(underTest.tabs)
- val selectedTab = collectLastValue(underTest.selectedTab)
-
- tabs()?.get(0)?.onClick?.invoke()
-
- assertThat(selectedTab()).isEqualTo(Tab.STYLE)
- }
-
- @Test
- fun selectedTab_whenClickOnTabColor() = runTest {
- val tabs = collectLastValue(underTest.tabs)
- val selectedTab = collectLastValue(underTest.selectedTab)
-
- tabs()?.get(1)?.onClick?.invoke()
-
- assertThat(selectedTab()).isEqualTo(Tab.COLOR)
- }
-
- @Test
- fun selectedTab_fontEditorWhenClickSelectedClock() = runTest {
- val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
- val selectedTab = collectLastValue(underTest.selectedTab)
- // Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
- advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
- assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-
- val firstClock = clockStyleOptions()!![0]
- val onClicked = collectLastValue(firstClock.onClicked)
- if (!firstClock.isSelected.value) onClicked()?.invoke()
- onClicked()?.invoke()
-
- assertThat(selectedTab()).isEqualTo(Tab.FONT)
- }
-
+ //// Tabs
@Test
fun tabs_whenInitialState() = runTest {
val tabs = collectLastValue(underTest.tabs)
val resultTabs = checkNotNull(tabs())
- assertThat(resultTabs).hasSize(2)
+ assertThat(resultTabs).hasSize(3)
resultTabs.forEachIndexed { index, floatingToolbarTabViewModel ->
when (index) {
0 -> {
@@ -184,6 +150,19 @@
isOnClickNull = false,
)
}
+ 2 -> {
+ assertFloatingToolbarTabViewModel(
+ viewModel = floatingToolbarTabViewModel,
+ icon =
+ Icon.Resource(
+ res = R.drawable.ic_font_size_filled_24px,
+ contentDescription = Text.Resource(R.string.clock_size),
+ ),
+ text = context.getString(R.string.clock_size),
+ isSelected = false,
+ isOnClickNull = false,
+ )
+ }
}
}
}
@@ -207,6 +186,37 @@
}
@Test
+ fun selectedTab_whenClickOnTabStyle() = runTest {
+ val tabs = collectLastValue(underTest.tabs)
+ val selectedTab = collectLastValue(underTest.selectedTab)
+
+ tabs()?.get(0)?.onClick?.invoke()
+
+ assertThat(selectedTab()).isEqualTo(Tab.STYLE)
+ }
+
+ @Test
+ fun selectedTab_whenClickOnTabColor() = runTest {
+ val tabs = collectLastValue(underTest.tabs)
+ val selectedTab = collectLastValue(underTest.selectedTab)
+
+ tabs()?.get(1)?.onClick?.invoke()
+
+ assertThat(selectedTab()).isEqualTo(Tab.COLOR)
+ }
+
+ @Test
+ fun selectedTab_whenClickOnTabSize() = runTest {
+ val tabs = collectLastValue(underTest.tabs)
+ val selectedTab = collectLastValue(underTest.selectedTab)
+
+ tabs()?.get(2)?.onClick?.invoke()
+
+ assertThat(selectedTab()).isEqualTo(Tab.SIZE)
+ }
+
+ //// Clock style
+ @Test
fun selectedClock_whenClickOnStyleOptions() = runTest {
val selectedClock = collectLastValue(underTest.selectedClock)
@@ -241,7 +251,7 @@
val option1OnClicked = collectLastValue(clockStyleOptions()!![1].onClicked)
assertThat(option0IsSelected()).isTrue()
- assertThat(option0OnClicked()).isNotNull()
+ assertThat(option0OnClicked()).isNull()
option1OnClicked()?.invoke()
// Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockColorOptions
@@ -249,9 +259,117 @@
assertThat(option0IsSelected()).isFalse()
assertThat(option1IsSelected()).isTrue()
- assertThat(option1OnClicked()).isNotNull()
+ assertThat(option1OnClicked()).isNull()
}
+ //// Clock font
+ @Test
+ fun previewingClockPresetIndexedStyle_whenInitialState() = runTest {
+ val previewingClockPresetIndexedStyle =
+ collectLastValue(underTest.previewingClockPresetIndexedStyle)
+
+ assertThat(previewingClockPresetIndexedStyle())
+ .isEqualTo(FakeClockPickerRepository.fakeClocks[0].axisPresetConfig?.current)
+ }
+
+ @Test
+ fun previewingClockPresetIndexedStyle_whenClickOnSliderStep() = runTest {
+ val previewingClockPresetIndexedStyle =
+ collectLastValue(underTest.previewingClockPresetIndexedStyle)
+ val axisPresetsSliderViewModel = collectLastValue(underTest.axisPresetsSliderViewModel)
+ val onSlierStopTrackingTouch = axisPresetsSliderViewModel()?.onSliderStopTrackingTouch
+ checkNotNull(onSlierStopTrackingTouch)
+
+ onSlierStopTrackingTouch.invoke(1F)
+
+ assertThat(previewingClockPresetIndexedStyle())
+ .isEqualTo(
+ IndexedStyle(
+ groupIndex = 0,
+ presetIndex = 1,
+ style = FakeClockPickerRepository.fakeClockAxisStyle1,
+ )
+ )
+ }
+
+ @Test
+ fun shouldShowPresetSlider_true_whenDefault() = runTest {
+ val shouldShowPresetSlider = collectLastValue(underTest.shouldShowPresetSlider)
+
+ assertThat(shouldShowPresetSlider()).isTrue()
+ }
+
+ @Test
+ fun shouldShowPresetSlider_false_whenSelectClockWithNullAxisPresetConfig() = runTest {
+ val shouldShowPresetSlider = collectLastValue(underTest.shouldShowPresetSlider)
+ val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
+ // Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
+ advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+ val onClockOption1Clicked =
+ clockStyleOptions()?.get(1)?.onClicked?.let { collectLastValue(it) }
+ checkNotNull(onClockOption1Clicked)
+
+ onClockOption1Clicked()?.invoke()
+
+ assertThat(shouldShowPresetSlider()).isFalse()
+ }
+
+ @Test
+ fun axisPresetsSliderViewModel_initialState() = runTest {
+ val axisPresetsSliderViewModel = collectLastValue(underTest.axisPresetsSliderViewModel)
+
+ val expectedPresetSize =
+ FakeClockPickerRepository.fakeClocks[0].axisPresetConfig?.groups?.get(0)?.presets?.size
+ checkNotNull(expectedPresetSize)
+ val resultAxisPresetsSliderViewModel = axisPresetsSliderViewModel()
+ assertThat(resultAxisPresetsSliderViewModel?.valueFrom).isEqualTo(0F)
+ assertThat(resultAxisPresetsSliderViewModel?.valueTo)
+ .isEqualTo((expectedPresetSize - 1).toFloat())
+ assertThat(resultAxisPresetsSliderViewModel?.stepSize).isEqualTo(1F)
+ }
+
+ @Test
+ fun axisPresetsSliderSelectedValue_update_whenClickOnSliderStep() = runTest {
+ val axisPresetsSliderSelectedValue =
+ collectLastValue(underTest.axisPresetsSliderSelectedValue)
+ val axisPresetsSliderViewModel = collectLastValue(underTest.axisPresetsSliderViewModel)
+ val onSlierStopTrackingTouch = axisPresetsSliderViewModel()?.onSliderStopTrackingTouch
+ checkNotNull(onSlierStopTrackingTouch)
+
+ onSlierStopTrackingTouch.invoke(1F)
+
+ val expectedResult =
+ FakeClockPickerRepository.fakeClocks[0]
+ .axisPresetConfig
+ ?.groups
+ ?.get(0)
+ ?.presets
+ ?.get(1)
+ checkNotNull(expectedResult)
+ assertThat(axisPresetsSliderSelectedValue()).isEqualTo(1F)
+ }
+
+ @Test
+ fun previewingClockPresetIndexedStyle_whenOnClockFaceClicked() = runTest {
+ val previewingClockPresetIndexedStyle =
+ collectLastValue(underTest.previewingClockPresetIndexedStyle)
+ val onClockFaceClicked = collectLastValue(underTest.onClockFaceClicked)
+
+ onClockFaceClicked()?.invoke()
+
+ val expectedResult =
+ FakeClockPickerRepository.fakeClocks[0]
+ .axisPresetConfig
+ ?.groups
+ ?.get(1)
+ ?.presets
+ ?.get(0)
+ checkNotNull(expectedResult)
+ assertThat(previewingClockPresetIndexedStyle())
+ .isEqualTo(IndexedStyle(groupIndex = 1, presetIndex = 0, style = expectedResult))
+ }
+
+ //// Clock size
@Test
fun previewingClockSize_whenCallingOnClockSizeSwitchChecked() = runTest {
val previewingClockSize = collectLastValue(underTest.previewingClockSize)
@@ -265,76 +383,7 @@
assertThat(previewingClockSize()).isEqualTo(ClockSize.SMALL)
}
- @Test
- fun previewingFontAxes_defaultWhenNoOverrides() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
- }
-
- @Test
- fun previewingFontAxes_updateAxisChangesSetting() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
-
- underTest.updatePreviewFontAxis("key", 100f)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
-
- underTest.updatePreviewFontAxis("extra", 10f)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f, "extra" to 10f))
- }
-
- @Test
- fun previewingFontAxes_applyFontEditorExitsTab_keepsPreviewAxis() = runTest {
- 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
- advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
- assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-
- val firstClock = clockStyleOptions()!![0]
- val onClicked = collectLastValue(firstClock.onClicked)
- if (!firstClock.isSelected.value) onClicked()?.invoke()
- onClicked()?.invoke()
- underTest.updatePreviewFontAxis("key", 100f)
-
- assertThat(selectedTab()).isEqualTo(Tab.FONT)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
-
- underTest.confirmFontAxes()
-
- assertThat(selectedTab()).isEqualTo(Tab.STYLE)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
- }
-
- @Test
- fun previewingFontAxes_revertFontEditorExitsTab_revertsPreviewAxis() = runTest {
- 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
- advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
- assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-
- val firstClock = clockStyleOptions()!![0]
- val onClicked = collectLastValue(firstClock.onClicked)
- if (!firstClock.isSelected.value) onClicked()?.invoke()
- onClicked()?.invoke()
- underTest.updatePreviewFontAxis("key", 100f)
-
- assertThat(selectedTab()).isEqualTo(Tab.FONT)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
-
- underTest.cancelFontAxes()
-
- assertThat(selectedTab()).isEqualTo(Tab.STYLE)
- assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
- }
-
+ //// Clock color
@Test
fun sliderProgress_whenOnSliderProgressChanged() = runTest {
val sliderProgress = collectLastValue(underTest.previewingSliderProgress)
@@ -488,25 +537,6 @@
}
@Test
- fun apply_notNullWhenFontAxisChanged() = runTest {
- val onApply = collectLastValue(underTest.onApply)
-
- underTest.updatePreviewFontAxis("key", 100f)
-
- assertThat(onApply()).isNotNull()
- }
-
- @Test
- fun apply_nullAfterApplyingFontAxis() = runTest {
- val onApply = collectLastValue(underTest.onApply)
-
- underTest.updatePreviewFontAxis("key", 100f)
- onApply()?.invoke()
-
- assertThat(onApply()).isNull()
- }
-
- @Test
fun apply_notNullWhenClockSizeChanged() = runTest {
val onApply = collectLastValue(underTest.onApply)
val onClockSizeSwitchCheckedChange =