summaryrefslogtreecommitdiff
path: root/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt')
-rw-r--r--src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
new file mode 100644
index 00000000..66d92513
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2023 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.customization.picker.clock.ui.binder
+
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.SeekBar
+import androidx.core.view.isInvisible
+import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.customization.picker.clock.ui.adapter.ClockSettingsTabAdapter
+import com.android.customization.picker.clock.ui.view.ClockSizeRadioButtonGroup
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
+import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
+import com.android.customization.picker.color.ui.adapter.ColorOptionAdapter
+import com.android.customization.picker.common.ui.view.ItemSpacing
+import com.android.wallpaper.R
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.launch
+
+/** Bind between the clock settings screen and its view model. */
+object ClockSettingsBinder {
+ fun bind(
+ view: View,
+ viewModel: ClockSettingsViewModel,
+ clockViewFactory: ClockViewFactory,
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ val clockHostView: FrameLayout = view.requireViewById(R.id.clock_host_view)
+
+ val tabView: RecyclerView = view.requireViewById(R.id.tabs)
+ val tabAdapter = ClockSettingsTabAdapter()
+ tabView.adapter = tabAdapter
+ tabView.layoutManager = LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ tabView.addItemDecoration(ItemSpacing(ItemSpacing.TAB_ITEM_SPACING_DP))
+
+ val colorOptionContainerView: RecyclerView = view.requireViewById(R.id.color_options)
+ val colorOptionAdapter = ColorOptionAdapter()
+ colorOptionContainerView.adapter = colorOptionAdapter
+ colorOptionContainerView.layoutManager =
+ LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ colorOptionContainerView.addItemDecoration(ItemSpacing(ItemSpacing.ITEM_SPACING_DP))
+
+ val slider: SeekBar = view.requireViewById(R.id.slider)
+ slider.setOnSeekBarChangeListener(
+ object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(p0: SeekBar?, progress: Int, fromUser: Boolean) {
+ if (fromUser) {
+ viewModel.onSliderProgressChanged(progress)
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ seekBar?.progress?.let { viewModel.onSliderProgressStop(it) }
+ }
+ }
+ )
+
+ val sizeOptions =
+ view.requireViewById<ClockSizeRadioButtonGroup>(R.id.clock_size_radio_button_group)
+ sizeOptions.onRadioButtonClickListener =
+ object : ClockSizeRadioButtonGroup.OnRadioButtonClickListener {
+ override fun onClick(size: ClockSize) {
+ viewModel.setClockSize(size)
+ }
+ }
+
+ val colorOptionContainer = view.requireViewById<View>(R.id.color_picker_container)
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.selectedClockId
+ .mapNotNull { it }
+ .collect { clockId ->
+ val clockView = clockViewFactory.getView(clockId)
+ (clockView.parent as? ViewGroup)?.removeView(clockView)
+ clockHostView.removeAllViews()
+ clockHostView.addView(clockView)
+ }
+ }
+
+ launch {
+ viewModel.seedColor.collect { seedColor ->
+ viewModel.selectedClockId.value?.let { selectedClockId ->
+ clockViewFactory.updateColor(selectedClockId, seedColor)
+ }
+ }
+ }
+
+ launch { viewModel.tabs.collect { tabAdapter.setItems(it) } }
+
+ launch {
+ viewModel.selectedTab.collect { tab ->
+ when (tab) {
+ ClockSettingsViewModel.Tab.COLOR -> {
+ colorOptionContainer.isVisible = true
+ sizeOptions.isInvisible = true
+ }
+ ClockSettingsViewModel.Tab.SIZE -> {
+ colorOptionContainer.isInvisible = true
+ sizeOptions.isVisible = true
+ }
+ }
+ }
+ }
+
+ launch {
+ viewModel.colorOptions.collect { colorOptions ->
+ colorOptionAdapter.setItems(colorOptions)
+ }
+ }
+
+ launch {
+ viewModel.selectedColorOptionPosition.collect { selectedPosition ->
+ if (selectedPosition != -1) {
+ // We use "post" because we need to give the adapter item a pass to
+ // update the view.
+ colorOptionContainerView.post {
+ colorOptionContainerView.smoothScrollToPosition(selectedPosition)
+ }
+ }
+ }
+ }
+
+ launch {
+ viewModel.selectedClockSize.collect { size ->
+ when (size) {
+ ClockSize.DYNAMIC -> {
+ sizeOptions.radioButtonDynamic.isChecked = true
+ sizeOptions.radioButtonSmall.isChecked = false
+ }
+ ClockSize.SMALL -> {
+ sizeOptions.radioButtonDynamic.isChecked = false
+ sizeOptions.radioButtonSmall.isChecked = true
+ }
+ }
+ }
+ }
+
+ launch {
+ viewModel.sliderProgress.collect { progress ->
+ slider.setProgress(progress, true)
+ }
+ }
+
+ launch {
+ viewModel.isSliderEnabled.collect { isEnabled -> slider.isEnabled = isEnabled }
+ }
+ }
+ }
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ clockViewFactory.registerTimeTicker()
+ }
+ // When paused
+ clockViewFactory.unregisterTimeTicker()
+ }
+ }
+}