blob: 084287080859961a3b293ce830119e0748420404 [file] [log] [blame]
Catherine Liang68e0a822023-01-26 20:22:58 +00001/*
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
18package com.android.customization.picker.color.ui.binder
19
20import android.graphics.BlendMode
21import android.graphics.BlendModeColorFilter
22import android.view.LayoutInflater
23import android.view.View
24import android.widget.ImageView
25import android.widget.LinearLayout
26import androidx.core.view.isVisible
27import androidx.lifecycle.Lifecycle
28import androidx.lifecycle.LifecycleOwner
29import androidx.lifecycle.lifecycleScope
30import androidx.lifecycle.repeatOnLifecycle
31import com.android.customization.picker.color.ui.viewmodel.ColorOptionViewModel
32import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
33import com.android.wallpaper.R
34import kotlinx.coroutines.launch
35
36object ColorSectionViewBinder {
37
38 /**
39 * Binds view with view-model for color picker section. The view should include a linear layout
40 * with id [R.id.color_section_option_container]
41 */
42 @JvmStatic
43 fun bind(
44 view: View,
45 viewModel: ColorPickerViewModel,
46 lifecycleOwner: LifecycleOwner,
47 navigationOnClick: (View) -> Unit,
48 isConnectedHorizontallyToOtherSections: Boolean = false,
49 ) {
50 val optionContainer: LinearLayout =
51 view.requireViewById(R.id.color_section_option_container)
52 val moreColorsButton: View = view.requireViewById(R.id.more_colors)
53 if (isConnectedHorizontallyToOtherSections) {
54 moreColorsButton.isVisible = true
55 moreColorsButton.setOnClickListener(navigationOnClick)
56 } else {
57 moreColorsButton.isVisible = false
58 }
59 lifecycleOwner.lifecycleScope.launch {
60 lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
61 launch {
62 viewModel.colorSectionOptions.collect { colorOptions ->
63 setOptions(
64 options = colorOptions,
65 view = optionContainer,
66 addOverflowOption = !isConnectedHorizontallyToOtherSections,
67 overflowOnClick = navigationOnClick
68 )
69 }
70 }
71 }
72 }
73 }
74
75 fun setOptions(
76 options: List<ColorOptionViewModel>,
77 view: LinearLayout,
78 addOverflowOption: Boolean = false,
79 overflowOnClick: (View) -> Unit = {}
80 ) {
81 view.removeAllViews()
82 // Color option slot size is the minimum between the color option size and the view column
83 // count. When having an overflow option, a slot is reserved for the overflow option.
84 val colorOptionSlotSize =
85 (if (addOverflowOption) {
86 minOf(view.weightSum.toInt() - 1, options.size)
87 } else {
88 minOf(view.weightSum.toInt(), options.size)
89 })
90 .let { if (it < 0) 0 else it }
91 options.subList(0, colorOptionSlotSize).forEach { item ->
92 val itemView =
93 LayoutInflater.from(view.context)
94 .inflate(R.layout.color_option_no_background, view, false)
95
96 val color0View: ImageView = itemView.requireViewById(R.id.color_preview_0)
97 val color1View: ImageView = itemView.requireViewById(R.id.color_preview_1)
98 val color2View: ImageView = itemView.requireViewById(R.id.color_preview_2)
99 val color3View: ImageView = itemView.requireViewById(R.id.color_preview_3)
100 color0View.drawable.colorFilter = BlendModeColorFilter(item.color0, BlendMode.SRC)
101 color1View.drawable.colorFilter = BlendModeColorFilter(item.color1, BlendMode.SRC)
102 color2View.drawable.colorFilter = BlendModeColorFilter(item.color2, BlendMode.SRC)
103 color3View.drawable.colorFilter = BlendModeColorFilter(item.color3, BlendMode.SRC)
104
105 val optionSelectedView = itemView.findViewById<ImageView>(R.id.option_selected)
106 optionSelectedView.isVisible = item.isSelected
107
108 itemView.setOnClickListener(
109 if (item.onClick != null) {
110 View.OnClickListener { item.onClick.invoke() }
111 } else {
112 null
113 }
114 )
115 view.addView(itemView)
116 }
117 // add overflow option
118 if (addOverflowOption) {
119 val itemView =
120 LayoutInflater.from(view.context)
121 .inflate(R.layout.color_option_overflow_no_background, view, false)
122 itemView.setOnClickListener(overflowOnClick)
123 view.addView(itemView)
124 }
125 }
126}