Make clock editor support blueprint clock view in new customization picker
Bug: 366519734
Test: manual test with flag on and off, observe clock on the correct
position
Flag: com.android.systemui.shared.new_customization_picker_ui
Change-Id: I350f640cf3cfc54fa9d34692d0850e4b83c7ceb0
diff --git a/res/layout/clock_host_view.xml b/res/layout/clock_host_view.xml
index 33cca01..d6f5275 100644
--- a/res/layout/clock_host_view.xml
+++ b/res/layout/clock_host_view.xml
@@ -13,7 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.customization.picker.clock.ui.view.ClockHostView2
+<com.android.customization.picker.clock.ui.view.ClockConstraintLayoutHostView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/clock_host_view"
android:importantForAccessibility="noHideDescendants"
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
index 99dfc26..764c671 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -41,10 +41,10 @@
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.ClockCarouselView
-import com.android.customization.picker.clock.ui.view.ClockHostView
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.binder.ColorOptionIconBinder
+import com.android.systemui.shared.Flags
import com.android.themepicker.R
import com.android.wallpaper.picker.common.ui.view.ItemSpacing
import com.android.wallpaper.picker.option.ui.binder.OptionItemBinder
@@ -64,7 +64,10 @@
clockViewFactory: ClockViewFactory,
lifecycleOwner: LifecycleOwner,
) {
- val clockHostView: ClockHostView = view.requireViewById(R.id.clock_host_view)
+ if (Flags.newCustomizationPickerUi()) {
+ return
+ }
+ val clockHostView: ViewGroup = view.requireViewById(R.id.clock_host_view)
val tabView: RecyclerView = view.requireViewById(R.id.tabs)
val tabAdapter = ClockSettingsTabAdapter()
tabView.adapter = tabAdapter
@@ -204,10 +207,11 @@
ClockSize.DYNAMIC -> clockViewFactory.getLargeView(clockId)
ClockSize.SMALL -> clockViewFactory.getSmallView(clockId)
}
- // The clock view might still be attached to an existing parent. Detach
- // before adding to another parent.
+ // The clock view might still be attached to an existing parent.
+ // Detach before adding to another parent.
(clockView.parent as? ViewGroup)?.removeView(clockView)
clockHostView.addView(clockView)
+
when (size) {
ClockSize.DYNAMIC -> {
// When clock size data flow emits clock size signal, we want
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockConstraintLayoutHostView.kt b/src/com/android/customization/picker/clock/ui/view/ClockConstraintLayoutHostView.kt
new file mode 100644
index 0000000..de5fbd5
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/ClockConstraintLayoutHostView.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.customization.picker.clock.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.view.View.MeasureSpec.EXACTLY
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.systemui.plugins.clocks.ClockController
+import com.android.wallpaper.util.ScreenSizeCalculator
+
+/**
+ * Parent view for the clock view. We will calculate the current display size and the preview size
+ * and scale down the clock view to fit in the preview.
+ */
+class ClockConstraintLayoutHostView(context: Context, attrs: AttributeSet?) :
+ ConstraintLayout(context, attrs) {
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
+ super.onMeasure(
+ MeasureSpec.makeMeasureSpec(screenSize.x, EXACTLY),
+ MeasureSpec.makeMeasureSpec(screenSize.y, EXACTLY),
+ )
+ val ratio = MeasureSpec.getSize(widthMeasureSpec) / screenSize.x.toFloat()
+ scaleX = ratio
+ scaleY = ratio
+ }
+
+ companion object {
+ fun addClockViews(
+ clockController: ClockController,
+ rootView: ClockConstraintLayoutHostView,
+ size: ClockSize,
+ ) {
+ clockController.let { clock ->
+ when (size) {
+ ClockSize.DYNAMIC -> {
+ clock.largeClock.layout.views.forEach {
+ if (it.parent != null) {
+ (it.parent as ViewGroup).removeView(it)
+ }
+ rootView.addView(it).apply { it.visibility = View.VISIBLE }
+ }
+ }
+
+ ClockSize.SMALL -> {
+ clock.smallClock.layout.views.forEach {
+ if (it.parent != null) {
+ (it.parent as ViewGroup).removeView(it)
+ }
+ rootView.addView(it).apply { it.visibility = View.VISIBLE }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt b/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
index 512fcd1..2db52f1 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
@@ -12,10 +12,7 @@
* same size of lockscreen to layout clock and scale down it to the size in picker carousel
* according to ratio of preview to LS
*/
-class ClockHostView(
- context: Context,
- attrs: AttributeSet?,
-) : FrameLayout(context, attrs) {
+class ClockHostView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
private var previewRatio: Float = 1F
set(value) {
if (field != value) {
@@ -41,15 +38,16 @@
parentWidthMeasureSpec: Int,
widthUsed: Int,
parentHeightMeasureSpec: Int,
- heightUsed: Int
+ heightUsed: Int,
) {
+
val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
super.measureChildWithMargins(
child,
MeasureSpec.makeMeasureSpec(screenSize.x, EXACTLY),
widthUsed,
MeasureSpec.makeMeasureSpec(screenSize.y, EXACTLY),
- heightUsed
+ heightUsed,
)
}
}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockHostView2.kt b/src/com/android/customization/picker/clock/ui/view/ClockHostView2.kt
deleted file mode 100644
index be2e53d..0000000
--- a/src/com/android/customization/picker/clock/ui/view/ClockHostView2.kt
+++ /dev/null
@@ -1,84 +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.customization.picker.clock.ui.view
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.View
-import android.view.View.MeasureSpec.EXACTLY
-import android.widget.FrameLayout
-import com.android.customization.picker.clock.shared.ClockSize
-import com.android.wallpaper.util.ScreenSizeCalculator
-
-/**
- * Parent view for the clock view. We will calculate the current display size and the preview size
- * and scale down the clock view to fit in the preview.
- */
-class ClockHostView2(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
-
- var clockSize: ClockSize = ClockSize.DYNAMIC
- set(value) {
- if (field != value) {
- field = value
- updatePivotAndScale()
- invalidate()
- }
- }
-
- override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
- super.onLayout(changed, left, top, right, bottom)
- updatePivotAndScale()
- }
-
- override fun measureChildWithMargins(
- child: View?,
- parentWidthMeasureSpec: Int,
- widthUsed: Int,
- parentHeightMeasureSpec: Int,
- heightUsed: Int,
- ) {
- val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
- super.measureChildWithMargins(
- child,
- MeasureSpec.makeMeasureSpec(screenSize.x, EXACTLY),
- widthUsed,
- MeasureSpec.makeMeasureSpec(screenSize.y, EXACTLY),
- heightUsed,
- )
- }
-
- private fun updatePivotAndScale() {
- when (clockSize) {
- ClockSize.DYNAMIC -> {
- resetPivot()
- }
- ClockSize.SMALL -> {
- pivotX = getCenteredHostViewPivotX(this)
- pivotY = 0F
- }
- }
- val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
- val ratio = measuredWidth / screenSize.x.toFloat()
- scaleX = ratio
- scaleY = ratio
- }
-
- companion object {
- fun getCenteredHostViewPivotX(hostView: View): Float {
- return if (hostView.isLayoutRtl) hostView.width.toFloat() else 0F
- }
- }
-}
diff --git a/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
index 6cb9acb..72b0f19 100644
--- a/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
@@ -28,6 +28,7 @@
import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockFontAxisSetting
import com.android.systemui.plugins.clocks.WeatherData
+import com.android.systemui.shared.Flags
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.wallpaper.util.ScreenSizeCalculator
import com.android.wallpaper.util.TimeUtils.TimeTicker
@@ -64,6 +65,7 @@
* configs, e.g. animation state, might change during the reuse of the clock view in the app.
*/
override fun getLargeView(clockId: String): View {
+ assert(!Flags.newCustomizationPickerUi())
return getController(clockId).largeClock.let {
it.animations.onPickerCarouselSwiping(1F)
it.view
@@ -75,6 +77,7 @@
* configs, e.g. translation X, might change during the reuse of the clock view in the app.
*/
override fun getSmallView(clockId: String): View {
+ assert(!Flags.newCustomizationPickerUi())
val smallClockFrame =
smallClockFrames[clockId]
?: createSmallClockFrame().also {
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
index db43f4b..32b28ad 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -97,11 +97,7 @@
) {
private val viewModel =
- ViewModelProvider(
- activity,
- clockCarouselViewModelFactory,
- )
- .get() as ClockCarouselViewModel
+ ViewModelProvider(activity, clockCarouselViewModelFactory).get() as ClockCarouselViewModel
private var clockColorAndSizeButton: View? = null
@@ -184,7 +180,7 @@
)
if (onAttachStateChangeListener != null) {
carouselView.carousel.removeOnAttachStateChangeListener(
- onAttachStateChangeListener,
+ onAttachStateChangeListener
)
}
}
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
index dd283c2..469db6d 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
@@ -16,10 +16,12 @@
package com.android.wallpaper.customization.ui.binder
+import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
@@ -27,10 +29,12 @@
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.customization.picker.clock.shared.ClockSize
-import com.android.customization.picker.clock.ui.view.ClockHostView2
+import com.android.customization.picker.clock.ui.view.ClockConstraintLayoutHostView
+import com.android.customization.picker.clock.ui.view.ClockConstraintLayoutHostView.Companion.addClockViews
import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.grid.ui.binder.GridIconViewBinder
import com.android.systemui.plugins.clocks.ClockFontAxisSetting
+import com.android.systemui.shared.Flags
import com.android.themepicker.R
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerHomeCustomizationOption
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption
@@ -231,12 +235,13 @@
}
override fun bindClockPreview(
+ context: Context,
clockHostView: View,
viewModel: CustomizationPickerViewModel2,
lifecycleOwner: LifecycleOwner,
clockViewFactory: ClockViewFactory,
) {
- clockHostView as ClockHostView2
+ clockHostView as ClockConstraintLayoutHostView
val clockPickerViewModel =
(viewModel.customizationOptionsViewModel as ThemePickerCustomizationOptionsViewModel)
.clockPickerViewModel
@@ -252,17 +257,36 @@
}
.collect { (clock, size) ->
clockHostView.removeAllViews()
- val clockView =
- when (size) {
- ClockSize.DYNAMIC ->
- clockViewFactory.getLargeView(clock.clockId)
- ClockSize.SMALL -> clockViewFactory.getSmallView(clock.clockId)
+ // For new customization picker, we should get views from clocklayout
+ if (Flags.newCustomizationPickerUi()) {
+ clockViewFactory.getController(clock.clockId).let { clockController
+ ->
+ addClockViews(clockController, clockHostView, size)
+ val cs = ConstraintSet()
+ clockController.largeClock.layout.applyPreviewConstraints(
+ context,
+ cs,
+ )
+ clockController.smallClock.layout.applyPreviewConstraints(
+ context,
+ cs,
+ )
+ cs.applyTo(clockHostView)
}
- // The clock view might still be attached to an existing parent. Detach
- // before adding to another parent.
- (clockView.parent as? ViewGroup)?.removeView(clockView)
- clockHostView.addView(clockView)
- clockHostView.clockSize = size
+ } else {
+ val clockView =
+ when (size) {
+ ClockSize.DYNAMIC ->
+ clockViewFactory.getLargeView(clock.clockId)
+ ClockSize.SMALL ->
+ clockViewFactory.getSmallView(clock.clockId)
+ }
+ // The clock view might still be attached to an existing parent.
+ // Detach
+ // before adding to another parent.
+ (clockView.parent as? ViewGroup)?.removeView(clockView)
+ clockHostView.addView(clockView)
+ }
}
}