1 /*
2  * Copyright (C) 2023 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  */
17 
18 package com.android.wallpaper.picker.customization.ui.section
19 
20 import android.annotation.SuppressLint
21 import android.content.Context
22 import android.text.TextUtils
23 import android.view.LayoutInflater
24 import android.view.View
25 import android.widget.LinearLayout
26 import com.android.wallpaper.R
27 import com.android.wallpaper.model.CustomizationSectionController
28 import com.android.wallpaper.picker.SectionView
29 import java.util.*
30 
31 /**
32  * A section controller that renders two sections that are connected.
33  *
34  * In portrait mode, they are rendered vertically; in landscape mode, side-by-side.
35  */
36 class ConnectedSectionController(
37     /** First section. */
38     private val firstSectionController: CustomizationSectionController<out SectionView>,
39     /** Second section. */
40     private val secondSectionController: CustomizationSectionController<out SectionView>,
41     /** Whether to flip the order of the child sections when laid out horizontally. */
42     private val reverseOrderWhenHorizontal: Boolean = false,
43 ) : CustomizationSectionController<ResponsiveLayoutSectionView> {
isAvailablenull44     override fun isAvailable(context: Context): Boolean {
45         return firstSectionController.isAvailable(context) ||
46             secondSectionController.isAvailable(context)
47     }
48 
49     @SuppressLint("InflateParams") // It's okay that we're inflating without a parent view.
createViewnull50     override fun createView(context: Context): ResponsiveLayoutSectionView {
51         val view =
52             LayoutInflater.from(context)
53                 .inflate(
54                     R.layout.responsive_section,
55                     null,
56                 ) as ResponsiveLayoutSectionView
57 
58         val isHorizontal = view.orientation == LinearLayout.HORIZONTAL
59         val flipViewOrder = reverseOrderWhenHorizontal && isHorizontal
60 
61         add(
62             parentView = view,
63             childController =
64                 if (flipViewOrder) {
65                     secondSectionController
66                 } else {
67                     firstSectionController
68                 },
69             isHorizontal = isHorizontal,
70             isFirst = true,
71         )
72         add(
73             parentView = view,
74             childController =
75                 if (flipViewOrder) {
76                     firstSectionController
77                 } else {
78                     secondSectionController
79                 },
80             isHorizontal = isHorizontal,
81             isFirst = false,
82         )
83 
84         return view
85     }
86 
addnull87     private fun add(
88         parentView: LinearLayout,
89         childController: CustomizationSectionController<out SectionView>,
90         isHorizontal: Boolean,
91         isFirst: Boolean,
92     ) {
93         val childView =
94             childController.createView(
95                 context = parentView.context,
96                 params =
97                     CustomizationSectionController.ViewCreationParams(
98                         isConnectedHorizontallyToOtherSections = isHorizontal,
99                     ),
100             )
101 
102         if (isHorizontal) {
103             // We want each child to stretch to fill an equal amount as the other children.
104             childView.layoutParams =
105                 LinearLayout.LayoutParams(
106                     /* width= */ 0,
107                     /* height= */ LinearLayout.LayoutParams.WRAP_CONTENT,
108                     /* weight= */ 1f,
109                 )
110 
111             val isLeftToRight =
112                 TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) ==
113                     View.LAYOUT_DIRECTION_LTR
114             childView.setBackgroundResource(
115                 if (isLeftToRight) {
116                     // In left-to-right layouts, the first item is on the left.
117                     if (isFirst) {
118                         R.drawable.leftmost_connected_section_background
119                     } else {
120                         R.drawable.rightmost_connected_section_background
121                     }
122                 } else {
123                     // In right-to-left layouts, the first item is on the right.
124                     if (isFirst) {
125                         R.drawable.rightmost_connected_section_background
126                     } else {
127                         R.drawable.leftmost_connected_section_background
128                     }
129                 }
130             )
131         }
132 
133         parentView.addView(childView)
134     }
135 }
136