1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.wallpaper.picker.preview.ui.view
17 
18 import android.content.Context
19 import android.graphics.Point
20 import android.util.AttributeSet
21 import androidx.viewpager.widget.ViewPager
22 import com.android.wallpaper.R
23 import com.android.wallpaper.config.BaseFlags
24 import com.android.wallpaper.model.wallpaper.DeviceDisplayType
25 
26 /**
27  * This view pager sizes itself to be the exact height required by its content views:
28  * [DualDisplayAspectRatioLayout]. This is required because the actual heights of
29  * [DualDisplayAspectRatioLayout] are determined after the their parent ViewPager is rendered. This
30  * prevents the ViewPager from sizing itself to wrap its contents.
31  */
32 class DualPreviewViewPager
33 @JvmOverloads
34 constructor(context: Context, attrs: AttributeSet? = null /* attrs */) : ViewPager(context, attrs) {
35     private var previewDisplaySizes: Map<DeviceDisplayType, Point>? = null
36 
onMeasurenull37     override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
38         if (previewDisplaySizes == null || BaseFlags.get().isNewPickerUi()) {
39             super.onMeasure(widthMeasureSpec, heightMeasureSpec)
40             return
41         }
42 
43         val parentWidth =
44             this.measuredWidth -
45                 context.resources.let {
46                     it.getDimension(R.dimen.small_dual_preview_edge_space) * 2 -
47                         it.getDimension(R.dimen.small_preview_inter_preview_margin) * 3
48                 }
49 
50         val smallDisplayAspectRatio =
51             getPreviewDisplaySize(DeviceDisplayType.FOLDED).let { it.x.toFloat() / it.y }
52 
53         val largeDisplayAspectRatio =
54             getPreviewDisplaySize(DeviceDisplayType.UNFOLDED).let { it.x.toFloat() / it.y }
55 
56         val viewPagerHeight = parentWidth / (largeDisplayAspectRatio + smallDisplayAspectRatio)
57 
58         super.onMeasure(
59             widthMeasureSpec,
60             MeasureSpec.makeMeasureSpec(
61                 viewPagerHeight.toInt(),
62                 MeasureSpec.EXACTLY,
63             )
64         )
65     }
66 
setDisplaySizesnull67     fun setDisplaySizes(displaySizes: Map<DeviceDisplayType, Point>) {
68         previewDisplaySizes = displaySizes
69     }
70 
71     /**
72      * Gets the display size for a [DualDisplayAspectRatioLayout.Companion.PreviewView].
73      *
74      * Outside this class we should get display size via
75      * [DualDisplayAspectRatioLayout.getPreviewDisplaySize].
76      */
getPreviewDisplaySizenull77     private fun getPreviewDisplaySize(display: DeviceDisplayType): Point {
78         return checkNotNull(previewDisplaySizes?.get(display))
79     }
80 }
81