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 package com.android.car.customization.tool.domain.menu
18 
19 import androidx.annotation.StringRes
20 import com.android.car.customization.tool.R
21 import com.android.car.customization.tool.domain.panel.OpenPanelAction
22 
23 /**
24  * The tool's visual menu.
25  *
26  * The menu has a tree structure and is composed of different [MenuItem] nodes.
27  * Only nodes of type [MenuItem.SubMenuNavigation] can have children and allow the user to navigate
28  * to sub menus.
29  *
30  * @property rootNode The root element of the menu.
31  * @property currentParentNode The parent of the current menu shown to the user. For example if
32  * [currentParentNode] is the same as [rootNode] then the first layer of sub menu is shown (e.g. the
33  * menu containing the items: RRO, Plugin, OEM Design Tokens).
34  */
35 internal data class Menu(
36     val rootNode: MenuItem.SubMenuNavigation,
37     val currentParentNode: MenuItem.SubMenuNavigation,
38 )
39 
40 /**
41  * The base for all visual items available in Menu.
42  *
43  * @property displayTextRes the string resource (and ID) of a MenuItem.
44  * @property isEnabled defines if an item is enabled, users can't interact with disabled items.
45  */
46 internal sealed class MenuItem(
47     @StringRes open val displayTextRes: Int,
48     open val isEnabled: Boolean,
49 ) {
50 
51     /**
52      * The menu item that allows to navigate up the menu.
53      *
54      * Apart from the main level (RRO, Plugins...) all the other sub menus will contain
55      * a UpNavigation item.
56      */
57     object UpNavigation : MenuItem(R.string.menu_back, isEnabled = true) {
58         val action: MenuAction = NavigateUpAction
59     }
60 
61     /**
62      * The menu item that allows to navigate down the menu tree.
63      *
64      * @property displayTextRes the string resource (and ID) of the item.
65      * @property subMenu the list of child nodes of this item.
66      */
67     data class SubMenuNavigation(
68         @StringRes override val displayTextRes: Int,
69         val subMenu: List<MenuItem>,
70     ) : MenuItem(displayTextRes, isEnabled = true) {
71 
72         val action: MenuAction = OpenSubMenuAction(displayTextRes)
73     }
74 
75     /**
76      * The menu item that represents a switch on the menu.
77      *
78      * @property displayTextRes the string resource (and ID) of the item.
79      * @property isEnabled defines if an item is enabled, users can't interact with disabled items.
80      * @property isChecked defines if the switch is checked or not.
81      * @property action [ToggleMenuAction] that will be triggered when the user taps on the Switch
82      */
83     data class Switch(
84         @StringRes override val displayTextRes: Int,
85         override val isEnabled: Boolean,
86         val isChecked: Boolean,
87         val action: ToggleMenuAction,
88     ) : MenuItem(displayTextRes, isEnabled)
89 
90     /**
91      * The menu item that represents a DropDown item on the menu.
92      *
93      * Tapping on the DropDown shows the options defined in the [items] property.
94      *
95      * @property displayTextRes the string resource (and ID) of the item.
96      * @property isEnabled defines if an item is enabled, users can't interact with disabled items.
97      * @property items contains a list of DropDown.Item that will be shown when the user taps on the
98      * DropDown.
99      */
100     data class DropDown(
101         @StringRes override val displayTextRes: Int,
102         override val isEnabled: Boolean,
103         val items: List<Item>,
104     ) : MenuItem(displayTextRes, isEnabled) {
105 
106         /**
107          * An item inside a DropDown popup list.
108          *
109          * @property title: the text on the item.
110          * @property isActive a boolean that define which is the active option from the list. Only one
111          * item should be active at any time.
112          * @property action the action that is triggered when the user taps on the item.
113          */
114         data class Item(
115             val title: String,
116             val isActive: Boolean = false,
117             val action: MenuAction,
118         )
119     }
120 
121     /**
122      * The menu item that has the responsibility of launching a [Panel]
123      *
124      * @property displayTextRes the string resource (and ID) of the item.
125      * @property isEnabled defines if an item is enabled, users can't interact with disabled items.
126      * @property action [OpenPanelAction] that opens a specific panel.
127      */
128     data class PanelLauncher(
129         @StringRes override val displayTextRes: Int,
130         override val isEnabled: Boolean = true,
131         val action: OpenPanelAction,
132     ) : MenuItem(displayTextRes, isEnabled)
133 }
134