Merge "Clock font content (2/2)" into main
diff --git a/res/layout/clock_font_axis_name.xml b/res/layout/clock_font_axis_name.xml
deleted file mode 100644
index dd29c6b..0000000
--- a/res/layout/clock_font_axis_name.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2024 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/clock_axis_name"
- android:layout_width="@dimen/clock_font_axis_name_width"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical" />
\ No newline at end of file
diff --git a/res/layout/clock_font_axis_slider_row.xml b/res/layout/clock_font_axis_slider_row.xml
deleted file mode 100644
index cb663b4..0000000
--- a/res/layout/clock_font_axis_slider_row.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2024 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingVertical="@dimen/clock_axis_control_row_vertical_padding"
- android:orientation="horizontal">
- <include layout="@layout/clock_font_axis_name" />
-
- <SeekBar
- android:id="@+id/clock_axis_slider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:paddingStart="@dimen/clock_axis_control_padding_start"
- android:minHeight="@dimen/touch_target_min_height"
- android:thumb="@null"
- android:background="@null"
- android:splitTrack="false"
- android:progressDrawable="@drawable/saturation_progress_drawable" />
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/clock_font_axis_switch.xml b/res/layout/clock_font_axis_switch.xml
deleted file mode 100644
index 385d105..0000000
--- a/res/layout/clock_font_axis_switch.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2024 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<Switch xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/clock_axis_switch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/clock_axis_control_padding_start"
- style="@style/Switch.SettingsLib" />
\ No newline at end of file
diff --git a/res/layout/clock_font_axis_switch_row.xml b/res/layout/clock_font_axis_switch_row.xml
deleted file mode 100644
index 139e5e0..0000000
--- a/res/layout/clock_font_axis_switch_row.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2024 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingVertical="@dimen/clock_axis_control_row_vertical_padding"
- android:orientation="horizontal">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/clock_switch_one"
- android:orientation="horizontal">
-
- <include layout="@layout/clock_font_axis_name" />
- <include layout="@layout/clock_font_axis_switch" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/clock_switch_two"
- android:orientation="horizontal"
- android:visibility="gone">
-
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:src="@drawable/clock_font_switch_divider"
- android:layout_marginHorizontal="@dimen/clock_font_control_switch_padding_horizontal"
- android:layout_gravity="center_vertical"/>
-
- <include layout="@layout/clock_font_axis_name" />
- <include layout="@layout/clock_font_axis_switch" />
- </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/floating_sheet_clock.xml b/res/layout/floating_sheet_clock.xml
index cdaf3de..338cbf2 100644
--- a/res/layout/floating_sheet_clock.xml
+++ b/res/layout/floating_sheet_clock.xml
@@ -17,8 +17,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
android:paddingHorizontal="@dimen/floating_sheet_horizontal_padding"
android:orientation="vertical">
@@ -31,185 +29,66 @@
android:clipToPadding="false"
android:clipChildren="false">
- <androidx.constraintlayout.widget.ConstraintLayout
+ <include
+ layout="@layout/floating_sheet_clock_style_content"
android:id="@+id/clock_floating_sheet_style_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipToPadding="false"
- android:clipChildren="false">
+ android:layout_height="wrap_content" />
- <FrameLayout
- android:id="@+id/clock_style_list_container"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_title"
- android:layout_marginBottom="8dp"
- android:clipToPadding="false"
- android:clipChildren="false">
-
- <!--
- This is an invisible placeholder put in place so that the parent keeps its height
- stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
- the layout logic to keep the size of the preview container stable as well, which
- bodes well for setting up the SurfaceView for remote rendering without changing its
- size after the content is loaded into the RecyclerView.
-
- It's critical for any TextViews inside the included layout to have text.
- -->
- <include
- layout="@layout/clock_style_option"
- android:layout_width="@dimen/floating_sheet_clock_style_option_size"
- android:layout_height="@dimen/floating_sheet_clock_style_option_size"
- android:visibility="invisible" />
-
- <!--
- TODO (b/377528523): We intentionally disable over scroll mode since it will clip the
- edit icon when in over scroll.
- -->
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/clock_style_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:overScrollMode="never"
- android:clipChildren="false"
- android:clipToPadding="false"/>
- </FrameLayout>
-
- <TextView
- android:id="@+id/clock_style_clock_size_title"
- style="@style/CustomizationOptionEntryTitleTextStyle"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:text="@string/clock_size_large"
- android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
- android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
- app:layout_constraintTop_toBottomOf="@+id/clock_style_list_container"
- app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_description" />
-
- <TextView
- android:id="@+id/clock_style_clock_size_description"
- style="@style/CustomizationOptionEntrySubtitleTextStyle"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
- android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
- android:text="@string/clock_size_dynamic_description"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
- app:layout_constraintTop_toBottomOf="@+id/clock_style_clock_size_title"
- app:layout_constraintBottom_toBottomOf="parent" />
-
- <Switch
- android:id="@+id/clock_style_clock_size_switch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/floating_sheet_content_horizontal_padding"
- app:layout_constraintTop_toTopOf="@+id/clock_style_clock_size_title"
- app:layout_constraintBottom_toBottomOf="@+id/clock_style_clock_size_description"
- app:layout_constraintEnd_toEndOf="parent"
- style="@style/Switch.SettingsLib"
- tools:ignore="UseSwitchCompatOrMaterialXml" />
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <LinearLayout
+ <include
+ layout="@layout/floating_sheet_clock_color_content"
android:id="@+id/clock_floating_sheet_color_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:clipToPadding="false"
- android:clipChildren="false">
+ android:layout_height="wrap_content" />
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipToPadding="false"
- android:clipChildren="false"
- android:layout_marginBottom="12dp">
-
- <!--
- This is an invisible placeholder put in place so that the parent keeps its height
- stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
- the layout logic to keep the size of the preview container stable as well, which
- bodes well for setting up the SurfaceView for remote rendering without changing its
- size after the content is loaded into the RecyclerView.
-
- It's critical for any TextViews inside the included layout to have text.
- -->
- <include
- layout="@layout/color_option"
- android:layout_width="@dimen/option_item_size"
- android:layout_height="@dimen/option_item_size"
- android:visibility="invisible" />
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/clock_color_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false" />
- </FrameLayout>
-
- <SeekBar
- android:id="@+id/clock_color_slider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
- android:minHeight="@dimen/touch_target_min_height"
- android:thumb="@null"
- android:contentDescription="@string/accessibility_clock_slider_description"
- android:background="@null"
- android:progressDrawable="@drawable/saturation_progress_drawable"
- android:splitTrack="false" />
- </LinearLayout>
-
- <LinearLayout
+ <include
+ layout="@layout/floating_sheet_clock_font_content"
android:id="@+id/clock_floating_sheet_font_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
- android:orientation="vertical"
- android:clipToPadding="false"
- android:clipChildren="false">
-
- <!-- Populated dynamically w/ clock axis information -->
- </LinearLayout>
+ android:layout_height="wrap_content" />
</FrameLayout>
- <com.android.wallpaper.picker.customization.ui.view.FloatingToolbar
- android:id="@+id/floating_toolbar"
- android:layout_width="wrap_content"
+ <FrameLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginVertical="@dimen/floating_sheet_tab_toolbar_vertical_margin" />
+ android:layout_marginVertical="@dimen/floating_sheet_tab_toolbar_vertical_margin">
- <LinearLayout
- android:id="@+id/clock_font_toolbar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="@dimen/floating_sheet_tab_clock_font_toolbar_top_margin"
- android:layout_marginBottom="@dimen/floating_sheet_tab_clock_font_toolbar_bottom_margin">
-
- <ImageView
- android:id="@+id/clock_font_revert"
+ <!-- Invisible placeholder to make sure the view does not shrink in height when the floating
+ toolbar visibility is gone -->
+ <include
+ layout="@layout/floating_toolbar_tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/clock_font_revert"
- android:contentDescription="@string/clock_font_editor_revert" />
+ android:layout_marginVertical="@dimen/floating_tab_toolbar_padding_vertical"
+ android:visibility="invisible" />
- <ImageView
- android:id="@+id/clock_font_apply"
+ <com.android.wallpaper.picker.customization.ui.view.FloatingToolbar
+ android:id="@+id/floating_toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingStart="@dimen/clock_font_apply_padding_start"
- android:src="@drawable/clock_font_apply"
- android:contentDescription="@string/clock_font_editor_apply" />
- </LinearLayout>
+ android:layout_gravity="center" />
+
+ <LinearLayout
+ android:id="@+id/clock_font_toolbar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_gravity="center_horizontal">
+
+ <ImageView
+ android:id="@+id/clock_font_revert"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/clock_font_revert"
+ android:contentDescription="@string/clock_font_editor_revert" />
+
+ <ImageView
+ android:id="@+id/clock_font_apply"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/clock_font_apply_padding_start"
+ android:src="@drawable/clock_font_apply"
+ android:contentDescription="@string/clock_font_editor_apply" />
+ </LinearLayout>
+ </FrameLayout>
</LinearLayout>
diff --git a/res/layout/floating_sheet_clock_color_content.xml b/res/layout/floating_sheet_clock_color_content.xml
new file mode 100644
index 0000000..3f1ec8c
--- /dev/null
+++ b/res/layout/floating_sheet_clock_color_content.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:clipChildren="false"
+ android:layout_marginBottom="@dimen/floating_sheet_clock_color_option_list_bottom_margin">
+
+ <!--
+ This is an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
+ the layout logic to keep the size of the preview container stable as well, which
+ bodes well for setting up the SurfaceView for remote rendering without changing its
+ size after the content is loaded into the RecyclerView.
+
+ It's critical for any TextViews inside the included layout to have text.
+ -->
+ <include
+ layout="@layout/color_option"
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size"
+ android:visibility="invisible" />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/clock_color_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false" />
+ </FrameLayout>
+
+ <SeekBar
+ android:id="@+id/clock_color_slider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
+ android:minHeight="@dimen/touch_target_min_height"
+ android:thumb="@null"
+ android:contentDescription="@string/accessibility_clock_slider_description"
+ android:background="@null"
+ android:progressDrawable="@drawable/saturation_progress_drawable"
+ android:splitTrack="false" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/floating_sheet_clock_font_content.xml b/res/layout/floating_sheet_clock_font_content.xml
new file mode 100644
index 0000000..9c223a5
--- /dev/null
+++ b/res/layout/floating_sheet_clock_font_content.xml
@@ -0,0 +1,160 @@
+<?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:clipChildren="false"
+ android:clipToPadding="false"
+ android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding">
+
+ <TextView
+ android:id="@+id/clock_axis_slider_name1"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/barrier1"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_axis_slider1"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <SeekBar
+ android:id="@+id/clock_axis_slider1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/accessibility_min_height"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/barrier1"
+ app:layout_constraintStart_toEndOf="@+id/clock_axis_slider_name1"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:background="@null"
+ android:progressDrawable="@drawable/saturation_progress_drawable"
+ android:splitTrack="false"
+ android:thumb="@null" />
+
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/barrier1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:barrierDirection="bottom"
+ app:constraint_referenced_ids="clock_axis_slider1,clock_axis_slider_name1" />
+
+ <TextView
+ android:id="@+id/clock_axis_slider_name2"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier1"
+ app:layout_constraintBottom_toTopOf="@+id/barrier2"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_axis_slider2"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <SeekBar
+ android:id="@+id/clock_axis_slider2"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/accessibility_min_height"
+ app:layout_constraintTop_toBottomOf="@+id/barrier1"
+ app:layout_constraintBottom_toTopOf="@+id/barrier2"
+ app:layout_constraintStart_toEndOf="@+id/clock_axis_slider_name2"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
+ android:background="@null"
+ android:progressDrawable="@drawable/saturation_progress_drawable"
+ android:splitTrack="false"
+ android:thumb="@null" />
+
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/barrier2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:barrierDirection="bottom"
+ app:constraint_referenced_ids="clock_axis_slider2,clock_axis_slider_name2" />
+
+ <TextView
+ android:id="@+id/clock_axis_switch_name1"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <Switch
+ android:id="@+id/clock_axis_switch1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/clock_axis_switch_name1"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ android:layout_marginStart="@dimen/clock_axis_control_text_margin_end"
+ style="@style/Switch.SettingsLib" />
+
+ <ImageView
+ android:id="@+id/divider"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.5"
+ android:src="@drawable/clock_font_switch_divider"
+ android:importantForAccessibility="no" />
+
+ <TextView
+ android:id="@+id/clock_axis_switch_name2"
+ android:layout_width="@dimen/clock_font_axis_name_width"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_axis_switch2"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
+ android:lines="1"
+ android:ellipsize="end"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:text="@string/tab_placeholder_text" />
+
+ <Switch
+ android:id="@+id/clock_axis_switch2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@+id/barrier2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
+ style="@style/Switch.SettingsLib" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/layout/floating_sheet_clock_style_content.xml b/res/layout/floating_sheet_clock_style_content.xml
new file mode 100644
index 0000000..9054ec3
--- /dev/null
+++ b/res/layout/floating_sheet_clock_style_content.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <FrameLayout
+ android:id="@+id/clock_style_list_container"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_title"
+ android:layout_marginBottom="@dimen/floating_sheet_clock_style_option_list_margin_bottom"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <!--
+ This is an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
+ the layout logic to keep the size of the preview container stable as well, which
+ bodes well for setting up the SurfaceView for remote rendering without changing its
+ size after the content is loaded into the RecyclerView.
+
+ It's critical for any TextViews inside the included layout to have text.
+ -->
+ <include
+ layout="@layout/clock_style_option"
+ android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_size"
+ android:visibility="invisible" />
+
+ <!--
+ TODO (b/377528523): We intentionally disable over scroll mode since it will clip the
+ edit icon when in over scroll.
+ -->
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/clock_style_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:overScrollMode="never"
+ android:clipChildren="false"
+ android:clipToPadding="false"/>
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/clock_style_clock_size_title"
+ style="@style/CustomizationOptionEntryTitleTextStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/clock_size_large"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
+ android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
+ app:layout_constraintTop_toBottomOf="@+id/clock_style_list_container"
+ app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_description" />
+
+ <TextView
+ android:id="@+id/clock_style_clock_size_description"
+ style="@style/CustomizationOptionEntrySubtitleTextStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
+ android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
+ android:text="@string/clock_size_dynamic_description"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
+ app:layout_constraintTop_toBottomOf="@+id/clock_style_clock_size_title"
+ app:layout_constraintBottom_toBottomOf="parent" />
+
+ <Switch
+ android:id="@+id/clock_style_clock_size_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/floating_sheet_content_horizontal_padding"
+ app:layout_constraintTop_toTopOf="@+id/clock_style_clock_size_title"
+ app:layout_constraintBottom_toBottomOf="@+id/clock_style_clock_size_description"
+ app:layout_constraintEnd_toEndOf="parent"
+ style="@style/Switch.SettingsLib"
+ tools:ignore="UseSwitchCompatOrMaterialXml" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 9c5e84d..229815e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -187,18 +187,20 @@
<dimen name="floating_sheet_tab_clock_font_toolbar_bottom_margin">8dp</dimen>
<dimen name="floating_sheet_list_item_horizontal_space">4dp</dimen>
<dimen name="floating_sheet_list_item_vertical_space">4dp</dimen>
+ <dimen name="floating_sheet_clock_style_option_list_margin_bottom">8dp</dimen>
<dimen name="floating_sheet_clock_style_option_size">82dp</dimen>
<dimen name="floating_sheet_clock_edit_icon_size">48dp</dimen>
<dimen name="floating_sheet_clock_style_thumbnail_margin">12dp</dimen>
<dimen name="floating_sheet_clock_style_clock_size_text_margin_end">16dp</dimen>
+ <dimen name="floating_sheet_clock_color_option_list_bottom_margin">12dp</dimen>
<dimen name="floating_sheet_color_option_size">54dp</dimen>
<dimen name="floating_sheet_color_option_stroke_width">3dp</dimen>
<dimen name="customization_option_entry_shortcut_icon_size">20dp</dimen>
<!-- Clock font control dimensions -->
<dimen name="clock_font_axis_name_width">64dp</dimen>
- <dimen name="clock_axis_control_padding_start">16dp</dimen>
- <dimen name="clock_axis_control_row_vertical_padding">10dp</dimen>
- <dimen name="clock_font_control_switch_padding_horizontal">38dp</dimen>
+ <dimen name="clock_axis_control_text_margin_end">16dp</dimen>
+ <dimen name="clock_axis_control_slider_row_margin_vertical">10dp</dimen>
+ <dimen name="clock_axis_control_switch_row_margin_vertical">8dp</dimen>
<dimen name="clock_font_apply_padding_start">8dp</dimen>
</resources>
diff --git a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
index 5f982e2..e2b6217 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
@@ -16,19 +16,18 @@
package com.android.wallpaper.customization.ui.binder
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.Configuration
-import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.FrameLayout
import android.widget.ImageView
-import android.widget.LinearLayout
import android.widget.SeekBar
import android.widget.Switch
-import android.widget.TextView
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
@@ -42,10 +41,10 @@
import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
import com.android.customization.picker.common.ui.view.SingleRowListItemSpacing
import com.android.systemui.plugins.clocks.AxisType
-import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.systemui.plugins.clocks.ClockId
import com.android.themepicker.R
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK
+import com.android.wallpaper.customization.ui.view.ClockFontSliderViewHolder
+import com.android.wallpaper.customization.ui.view.ClockFontSwitchViewHolder
import com.android.wallpaper.customization.ui.viewmodel.ClockFloatingSheetHeightsViewModel
import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel
import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel.ClockStyleModel
@@ -57,7 +56,6 @@
import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter
import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter2
import java.lang.ref.WeakReference
-import kotlin.math.abs
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -71,8 +69,8 @@
private const val SLIDER_DISABLED_ALPHA = .3f
private const val ANIMATION_DURATION = 200L
- private val _clockFloatingSheetHeights: MutableStateFlow<ClockFloatingSheetHeightsViewModel?> =
- MutableStateFlow(null)
+ private val _clockFloatingSheetHeights: MutableStateFlow<ClockFloatingSheetHeightsViewModel> =
+ MutableStateFlow(ClockFloatingSheetHeightsViewModel())
private val clockFloatingSheetHeights: Flow<ClockFloatingSheetHeightsViewModel> =
_clockFloatingSheetHeights.asStateFlow().filterNotNull()
@@ -145,14 +143,14 @@
clockStyleContent.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
- if (clockStyleContent.height != 0) {
+ if (
+ clockStyleContent.height != 0 &&
+ _clockFloatingSheetHeights.value.clockStyleContentHeight == null
+ ) {
_clockFloatingSheetHeights.value =
- _clockFloatingSheetHeights.value?.copy(
+ _clockFloatingSheetHeights.value.copy(
clockStyleContentHeight = clockStyleContent.height
)
- ?: ClockFloatingSheetHeightsViewModel(
- clockStyleContentHeight = clockStyleContent.height
- )
clockStyleContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
@@ -162,14 +160,31 @@
clockColorContent.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
- if (clockColorContent.height != 0) {
+ if (
+ clockColorContent.height != 0 &&
+ _clockFloatingSheetHeights.value.clockColorContentHeight == null
+ ) {
_clockFloatingSheetHeights.value =
- _clockFloatingSheetHeights.value?.copy(
+ _clockFloatingSheetHeights.value.copy(
clockColorContentHeight = clockColorContent.height
)
- ?: ClockFloatingSheetHeightsViewModel(
- clockColorContentHeight = clockColorContent.height
- )
+ clockColorContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
+ }
+ }
+ }
+ )
+
+ clockFontContent.viewTreeObserver.addOnGlobalLayoutListener(
+ object : OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ if (
+ clockFontContent.height != 0 &&
+ _clockFloatingSheetHeights.value.clockFontContentHeight == null
+ ) {
+ _clockFloatingSheetHeights.value =
+ _clockFloatingSheetHeights.value.copy(
+ clockFontContentHeight = clockFontContent.height
+ )
clockColorContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
@@ -177,84 +192,70 @@
)
lifecycleOwner.lifecycleScope.launch {
+ var currentContent: View = clockStyleContent
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch { viewModel.tabs.collect { tabAdapter.submitList(it) } }
launch {
combine(clockFloatingSheetHeights, viewModel.selectedTab, ::Pair).collect {
(heights, selectedTab) ->
- val (clockStyleContentHeight, clockColorContentHeight) = heights
+ val (
+ clockStyleContentHeight,
+ clockColorContentHeight,
+ clockFontContentHeight) =
+ heights
clockStyleContentHeight ?: return@collect
clockColorContentHeight ?: return@collect
+ clockFontContentHeight ?: return@collect
- if (selectedTab == Tab.STYLE || selectedTab == Tab.COLOR) {
- val targetHeight =
- when (selectedTab) {
- Tab.STYLE -> clockStyleContentHeight
- Tab.COLOR -> clockColorContentHeight
- else -> 0
- } +
- view.resources.getDimensionPixelSize(
- R.dimen.floating_sheet_content_vertical_padding
- ) * 2
-
- ValueAnimator.ofInt(floatingSheetContainer.height, targetHeight)
- .apply {
- addUpdateListener { valueAnimator ->
- val value = valueAnimator.animatedValue as Int
- floatingSheetContainer.layoutParams =
- floatingSheetContainer.layoutParams.apply {
- height = value
- }
- }
- duration = ANIMATION_DURATION
+ val fromHeight = floatingSheetContainer.height
+ val toHeight =
+ when (selectedTab) {
+ Tab.STYLE -> clockStyleContentHeight
+ Tab.COLOR -> clockColorContentHeight
+ Tab.FONT -> clockFontContentHeight
+ } +
+ view.resources.getDimensionPixelSize(
+ R.dimen.floating_sheet_content_vertical_padding
+ ) * 2
+ // Start to animate the content height
+ ValueAnimator.ofInt(fromHeight, toHeight)
+ .apply {
+ addUpdateListener { valueAnimator ->
+ val value = valueAnimator.animatedValue as Int
+ floatingSheetContainer.layoutParams =
+ floatingSheetContainer.layoutParams.apply { height = value }
+ currentContent.alpha = getAlpha(fromHeight, toHeight, value)
}
- .start()
- } else if (selectedTab == Tab.FONT) {
- floatingSheetContainer.layoutParams =
- LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT,
- LinearLayout.LayoutParams.WRAP_CONTENT,
+ duration = ANIMATION_DURATION
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ clockStyleContent.isVisible = selectedTab == Tab.STYLE
+ clockStyleContent.alpha = 1f
+ clockColorContent.isVisible = selectedTab == Tab.COLOR
+ clockColorContent.alpha = 1f
+ clockFontContent.isVisible = selectedTab == Tab.FONT
+ clockFontContent.alpha = 1f
+ currentContent =
+ when (selectedTab) {
+ Tab.STYLE -> clockStyleContent
+ Tab.COLOR -> clockColorContent
+ Tab.FONT -> clockFontContent
+ }
+ // Also update the floating toolbar when the height
+ // animation ends.
+ tabs.isVisible = selectedTab != Tab.FONT
+ clockFontToolbar.isVisible = selectedTab == Tab.FONT
+ }
+ }
)
- }
-
- clockStyleContent.isVisible = selectedTab == Tab.STYLE
- clockColorContent.isVisible = selectedTab == Tab.COLOR
- clockFontContent.isVisible = selectedTab == Tab.FONT
-
- tabs.isVisible = selectedTab != Tab.FONT
- clockFontToolbar.isVisible = selectedTab == Tab.FONT
+ }
+ .start()
}
}
launch {
- var boundClockId: ClockId? = null
- var boundEditorViews = mapOf<String, Pair<View, ClockFontAxis>>()
- combine(viewModel.previewingClock, viewModel.previewingFontAxisMap, ::Pair)
- .collect { pair ->
- val (clock, fontAxisMap) = pair
-
- if (boundClockId != clock.clockId) {
- boundEditorViews =
- initClockFontEditor(clockFontContent, clock.fontAxes, viewModel)
- boundClockId = clock.clockId
- }
-
- for ((key, value) in fontAxisMap) {
- boundEditorViews[key]?.let { pair ->
- val (view, axis) = pair
- view.findViewById<Switch>(R.id.clock_axis_switch)?.apply {
- isChecked = abs(value - axis.maxValue) < 0.01f
- }
- view.findViewById<SeekBar>(R.id.clock_axis_slider)?.apply {
- setProgress(value.toInt(), false)
- }
- }
- }
- }
- }
-
- launch {
viewModel.clockStyleOptions.collect { styleOptions ->
clockStyleAdapter.setItems(styleOptions) {
var indexToFocus = styleOptions.indexOfFirst { it.isSelected.value }
@@ -308,78 +309,93 @@
}
}
}
+
+ bindClockFontContent(
+ clockFontContent = clockFontContent,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner,
+ )
}
- private fun initClockFontEditor(
- parent: ViewGroup,
- fontAxes: List<ClockFontAxis>,
+ private fun bindClockFontContent(
+ clockFontContent: View,
viewModel: ClockPickerViewModel,
- ): Map<String, Pair<View, ClockFontAxis>> {
- parent.removeAllViews()
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ val sliderViewList =
+ listOf(
+ ClockFontSliderViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_slider_name1),
+ slider = clockFontContent.requireViewById(R.id.clock_axis_slider1),
+ ),
+ ClockFontSliderViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_slider_name2),
+ slider = clockFontContent.requireViewById(R.id.clock_axis_slider2),
+ ),
+ )
+ val switchViewList =
+ listOf(
+ ClockFontSwitchViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_switch_name1),
+ switch = clockFontContent.requireViewById(R.id.clock_axis_switch1),
+ ),
+ ClockFontSwitchViewHolder(
+ name = clockFontContent.requireViewById(R.id.clock_axis_switch_name2),
+ switch = clockFontContent.requireViewById(R.id.clock_axis_switch2),
+ ),
+ )
+ val sliderViewMap: MutableMap<String, ClockFontSliderViewHolder> = mutableMapOf()
+ val switchViewMap: MutableMap<String, ClockFontSwitchViewHolder> = mutableMapOf()
- val inflater = LayoutInflater.from(parent.context)
- val axisMap = mutableMapOf<String, Pair<View, ClockFontAxis>>()
- var nextSwitch: View? = null
- for (axis in fontAxes) {
- val view =
- when (axis.type) {
- AxisType.Float -> {
- val id = R.layout.clock_font_axis_slider_row
- val row = inflater.inflate(id, parent, false)
- parent.addView(row)
- row
- }
- AxisType.Boolean ->
- nextSwitch?.also { nextSwitch = null }
- ?: run {
- val id = R.layout.clock_font_axis_switch_row
- val row = inflater.inflate(id, parent, false)
- parent.addView(row)
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.selectedClockFontAxes.filterNotNull().collect { fontAxes ->
+ // This data flow updates only when a new clock style is selected. We
+ // initiate the clock font content with regard to that clock style.
+ sliderViewMap.clear()
+ switchViewMap.clear()
- nextSwitch = row.requireViewById(R.id.clock_switch_two)
- row.requireViewById(R.id.clock_switch_one)
- }
- }
-
- view.visibility = View.VISIBLE
- axisMap[axis.key] = Pair(view, axis)
- view.contentDescription = axis.description
- view.requireViewById<TextView>(R.id.clock_axis_name).text = axis.name
-
- view.findViewById<Switch>(R.id.clock_axis_switch)?.apply {
- isChecked = abs(axis.currentValue - axis.maxValue) < 0.01f
- setOnCheckedChangeListener { v, _ ->
- val value = if (v.isChecked) axis.maxValue else axis.minValue
- viewModel.updatePreviewFontAxis(axis.key, value)
- }
- }
-
- view.findViewById<SeekBar>(R.id.clock_axis_slider)?.apply {
- setMax(axis.maxValue.toInt())
- setMin(axis.minValue.toInt())
- setProgress(axis.currentValue.toInt(), false)
-
- setOnSeekBarChangeListener(
- object : SeekBar.OnSeekBarChangeListener {
- override fun onProgressChanged(
- seekBar: SeekBar?,
- progress: Int,
- fromUser: Boolean,
- ) {
- if (fromUser) {
- viewModel.updatePreviewFontAxis(axis.key, progress.toFloat())
+ // Initiate the slider views
+ val floatAxisList = fontAxes.filter { it.type == AxisType.Float }
+ sliderViewList.forEachIndexed { i, viewHolder ->
+ val floatAxis = floatAxisList.getOrNull(i)
+ viewHolder.setIsVisible(floatAxis != null)
+ floatAxis?.let {
+ sliderViewMap[floatAxis.key] = viewHolder
+ viewHolder.initView(it) { value ->
+ viewModel.updatePreviewFontAxis(floatAxis.key, value)
+ }
}
}
- override fun onStartTrackingTouch(seekBar: SeekBar?) {}
-
- override fun onStopTrackingTouch(seekBar: SeekBar?) {}
+ // Initiate the switch views
+ val booleanAxisList = fontAxes.filter { it.type == AxisType.Boolean }
+ switchViewList.forEachIndexed { i, viewHolder ->
+ val booleanAxis = booleanAxisList.getOrNull(i)
+ viewHolder.setIsVisible(booleanAxis != null)
+ booleanAxis?.let {
+ switchViewMap[it.key] = viewHolder
+ viewHolder.initView(booleanAxis) { value ->
+ viewModel.updatePreviewFontAxis(booleanAxis.key, value)
+ }
+ }
+ }
}
- )
+ }
+
+ launch {
+ viewModel.previewingClockFontAxisMap.collect { axisMap ->
+ // This data flow updates when user configures the sliders and switches
+ // in the clock font content.
+ axisMap.forEach { (key, value) ->
+ sliderViewMap[key]?.setValue(value)
+ switchViewMap[key]?.setValue(value)
+ }
+ }
+ }
}
}
-
- return axisMap
}
private fun createClockStyleOptionItemAdapter(
@@ -456,4 +472,8 @@
)
}
}
+
+ // Alpha is 1 when current height is from height, and 0 when current height is to height.
+ private fun getAlpha(fromHeight: Int, toHeight: Int, currentHeight: Int): Float =
+ (1 - (currentHeight - fromHeight).toFloat() / (toHeight - fromHeight).toFloat())
}
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
index 6bdd6ce..c3d1b83 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
@@ -295,7 +295,7 @@
combine(
clockPickerViewModel.previewingSeedColor,
clockPickerViewModel.previewingClock,
- clockPickerViewModel.previewingFontAxisMap,
+ clockPickerViewModel.previewingClockFontAxisMap,
colorUpdateViewModel.systemColorsUpdated,
::Quadruple,
)
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
new file mode 100644
index 0000000..8bdf073
--- /dev/null
+++ b/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wallpaper.customization.ui.view
+
+import android.widget.SeekBar
+import android.widget.TextView
+import androidx.core.view.isInvisible
+import com.android.systemui.plugins.clocks.ClockFontAxis
+
+class ClockFontSliderViewHolder(val name: TextView, val slider: SeekBar) {
+
+ fun setIsVisible(isVisible: Boolean) {
+ name.isInvisible = !isVisible
+ slider.isInvisible = !isVisible
+ }
+
+ fun initView(clockFontAxis: ClockFontAxis, onFontAxisValueUpdated: (value: Float) -> Unit) {
+ name.text = clockFontAxis.name
+ slider.apply {
+ max = clockFontAxis.maxValue.toInt()
+ min = clockFontAxis.minValue.toInt()
+ progress = clockFontAxis.currentValue.toInt()
+ setOnSeekBarChangeListener(
+ object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(
+ seekBar: SeekBar?,
+ progress: Int,
+ fromUser: Boolean,
+ ) {
+ if (fromUser) {
+ onFontAxisValueUpdated.invoke(progress.toFloat())
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {}
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {}
+ }
+ )
+ }
+ }
+
+ fun setValue(value: Float) {
+ slider.progress = value.toInt()
+ }
+}
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
new file mode 100644
index 0000000..6eb374b
--- /dev/null
+++ b/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wallpaper.customization.ui.view
+
+import android.widget.Switch
+import android.widget.TextView
+import androidx.core.view.isVisible
+import com.android.systemui.plugins.clocks.ClockFontAxis
+import kotlin.math.abs
+
+class ClockFontSwitchViewHolder(val name: TextView, val switch: Switch) {
+
+ private var switchMaxValue: Float? = null
+
+ fun setIsVisible(isVisible: Boolean) {
+ name.isVisible = isVisible
+ switch.isVisible = isVisible
+ }
+
+ fun initView(clockFontAxis: ClockFontAxis, onFontAxisValueUpdated: (value: Float) -> Unit) {
+ switchMaxValue = clockFontAxis.maxValue
+ name.text = clockFontAxis.name
+ switch.apply {
+ isChecked = abs(clockFontAxis.currentValue - clockFontAxis.maxValue) < 0.01f
+ setOnCheckedChangeListener { v, _ ->
+ val value = if (v.isChecked) clockFontAxis.maxValue else clockFontAxis.minValue
+ onFontAxisValueUpdated.invoke(value)
+ }
+ }
+ }
+
+ fun setValue(value: Float) {
+ switchMaxValue?.let { switch.isChecked = abs(value - it) < 0.01f }
+ }
+}
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
index a39ee7d..249f862 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
@@ -19,4 +19,5 @@
data class ClockFloatingSheetHeightsViewModel(
val clockStyleContentHeight: Int? = null,
val clockColorContentHeight: Int? = null,
+ val clockFontContentHeight: Int? = null,
)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
index c0f0ba7..f415fa8 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
@@ -42,7 +42,6 @@
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
-import kotlin.collections.map
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -168,7 +167,7 @@
} else {
fun() {
overridingClock.value = this
- overrideFontAxisMap.value = null
+ overrideClockFontAxisMap.value = null
}
}
},
@@ -176,27 +175,33 @@
}
// Clock Font Axis Editor
- private val overrideFontAxisMap = MutableStateFlow<Map<String, Float>?>(null)
- private val isFontAxisMapEdited = overrideFontAxisMap.map { it != null }
- private val selectedClockFontAxes =
+ private val overrideClockFontAxisMap = MutableStateFlow<Map<String, Float>?>(null)
+ private val isFontAxisMapEdited = overrideClockFontAxisMap.map { it != null }
+ val selectedClockFontAxes =
previewingClock
- .map { clock -> clock.fontAxes.associate { it.key to it.currentValue } }
+ .map { clock -> clock.fontAxes }
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
- val previewingFontAxisMap =
- combine(overrideFontAxisMap, selectedClockFontAxes.filterNotNull()) {
- overrideAxes,
- selectedFontAxes ->
- selectedFontAxes.toMutableMap().let { mutableMap ->
- overrideAxes?.forEach { (key, value) -> mutableMap[key] = value }
+ private val selectedClockFontAxisMap =
+ selectedClockFontAxes
+ .filterNotNull()
+ .map { fontAxes -> fontAxes.associate { it.key to it.currentValue } }
+ .stateIn(viewModelScope, SharingStarted.Eagerly, null)
+ val previewingClockFontAxisMap =
+ combine(overrideClockFontAxisMap, selectedClockFontAxisMap.filterNotNull()) {
+ overrideAxisMap,
+ selectedAxisMap ->
+ overrideAxisMap?.let {
+ val mutableMap = selectedAxisMap.toMutableMap()
+ overrideAxisMap.forEach { (key, value) -> mutableMap[key] = value }
mutableMap.toMap()
- }
+ } ?: selectedAxisMap
}
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyMap())
fun updatePreviewFontAxis(key: String, value: Float) {
- val axisMap = (overrideFontAxisMap.value?.toMutableMap() ?: mutableMapOf())
+ val axisMap = (overrideClockFontAxisMap.value?.toMutableMap() ?: mutableMapOf())
axisMap[key] = value
- overrideFontAxisMap.value = axisMap.toMap()
+ overrideClockFontAxisMap.value = axisMap.toMap()
}
fun confirmFontAxes() {
@@ -204,7 +209,7 @@
}
fun cancelFontAxes() {
- overrideFontAxisMap.value = null
+ overrideClockFontAxisMap.value = null
_selectedTab.value = Tab.STYLE
}
@@ -421,7 +426,7 @@
previewingClockSize,
previewingClockColorId,
previewingSliderProgress,
- previewingFontAxisMap,
+ previewingClockFontAxisMap,
) { array ->
val isEdited = array[0] as Boolean
val clock = array[1] as ClockMetadataModel
@@ -456,7 +461,7 @@
overridingClockSize.value = null
overridingClockColorId.value = null
overridingSliderProgress.value = null
- overrideFontAxisMap.value = null
+ overrideClockFontAxisMap.value = null
_selectedTab.value = Tab.STYLE
}
diff --git a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
index 0a8aa53..76df409 100644
--- a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
+++ b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
@@ -207,13 +207,13 @@
@Test
fun previewingFontAxes_defaultWhenNoOverrides() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
}
@Test
fun previewingFontAxes_updateAxisChangesSetting() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
underTest.updatePreviewFontAxis("key", 100f)
@@ -225,7 +225,7 @@
@Test
fun previewingFontAxes_applyFontEditorExitsTab_keepsPreviewAxis() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
val selectedTab = collectLastValue(underTest.selectedTab)
// Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
@@ -251,7 +251,7 @@
@Test
fun previewingFontAxes_revertFontEditorExitsTab_revertsPreviewAxis() = runTest {
- val previewingFontAxes = collectLastValue(underTest.previewingFontAxisMap)
+ val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
val selectedTab = collectLastValue(underTest.selectedTab)
// Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions