Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5da3fc5 authored by George Lin's avatar George Lin
Browse files

Bind preset slider

Bind preset slider to enable the clock customization.

Test: Manually tested. See bug.
Bug: 395647577
Flag: com.android.systemui.shared.new_customization_picker_ui
Change-Id: Ia7ccf6f08b428146977735c136e145914dd05876
parent c2b404cb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -87,6 +87,10 @@ constructor(

                val listener =
                    object : ClockRegistry.ClockChangeListener {
                        override fun onCurrentClockChanged() {
                            send()
                        }

                        override fun onAvailableClocksChanged() {
                            send()
                        }
+26 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter2
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
@@ -414,6 +415,31 @@ object ClockFloatingSheetBinder {
                        }
                    }
                }

                launch {
                    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) {}

                                override fun onStopTrackingTouch(slider: Slider) {
                                    axisPresetsSliderViewModel.onSliderStopTrackingTouch(
                                        slider.value
                                    )
                                }
                            }
                        )
                    }
                }

                launch {
                    viewModel.axisPresetsSliderSelectedValue.collect { axisPresetSlider.value = it }
                }
            }
        }
    }
+6 −3
Original line number Diff line number Diff line
@@ -486,14 +486,17 @@ constructor(private val defaultCustomizationOptionsBinder: DefaultCustomizationO
                    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(),
                            )
                        }
                }

+25 −0
Original line number Diff line number Diff line
/*
 * 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,
)
+90 −51
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import com.android.customization.picker.clock.shared.model.ClockMetadataModel
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.AssistedFactory
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
@@ -51,6 +54,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
@@ -131,18 +135,16 @@ constructor(

    // 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()

@@ -168,7 +170,81 @@ constructor(
            .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
@@ -195,44 +271,6 @@ constructor(
        )
    }

    // 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) {
                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()
    }

    // Clock size
    private val overridingClockSize = MutableStateFlow<ClockSize?>(null)
    private val isClockSizeEdited =
@@ -416,18 +454,18 @@ constructor(
    private val isEdited =
        combine(
            isClockEdited,
            isFontAxisMapEdited,
            isClockAxisStyleEdited,
            isClockSizeEdited,
            isClockColorIdEdited,
            isSliderProgressEdited,
        ) {
            isClockEdited,
            isFontAxisMapEdited,
            isClockAxisStyleEdited,
            isClockSizeEdited,
            isClockColorEdited,
            isSliderProgressEdited ->
            isClockEdited ||
                isFontAxisMapEdited ||
                isClockAxisStyleEdited ||
                isClockSizeEdited ||
                isClockColorEdited ||
                isSliderProgressEdited
@@ -441,7 +479,7 @@ constructor(
            previewingClockSize,
            previewingClockColorId,
            previewingSliderProgress,
            previewingClockFontAxisMap,
            previewingClockPresetIndexedStyle,
        ) { array ->
            val onApplyClicked: Boolean = array[0] as Boolean
            val isEdited: Boolean = array[1] as Boolean
@@ -449,7 +487,8 @@ constructor(
            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
@@ -465,7 +504,7 @@ constructor(
                                    colorTone = it.getColorTone(previewProgress),
                                )
                            },
                        axisSettings = ClockAxisStyle(axisMap),
                        axisSettings = clockAxisStyle,
                    )
                }
            } else {
@@ -478,7 +517,7 @@ constructor(
        overridingClockSize.value = null
        overridingClockColorId.value = null
        overridingSliderProgress.value = null
        overrideClockFontAxisMap.value = emptyMap()
        overridingClockPresetIndexedStyle.value = null
        _selectedTab.value = Tab.STYLE
        onApplyClicked.value = false
    }