1+ /*
2+ * Copyright 2025 Lambda
3+ *
4+ * This program is free software: you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation, either version 3 of the License, or
7+ * (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+ package com.lambda.config.settings.collections
19+
20+ import com.google.gson.JsonElement
21+ import com.google.gson.reflect.TypeToken
22+ import com.lambda.Lambda.gson
23+ import com.lambda.gui.dsl.ImGuiBuilder
24+ import imgui.flag.ImGuiSelectableFlags.DontClosePopups
25+
26+ /* *
27+ * @see [com.lambda.config.settings.collections.CollectionSettings]
28+ * @see [com.lambda.config.Configurable]
29+ */
30+ class ClassCollectionSetting <T : Any >(
31+ override var name : String ,
32+ private val immutableCollection : Collection <T >,
33+ defaultValue : MutableCollection <T >,
34+ description : String ,
35+ visibility : () -> Boolean ,
36+ ) : CollectionSetting<T>(
37+ name,
38+ immutableCollection,
39+ defaultValue,
40+ TypeToken .getParameterized(Collection ::class.java, Any ::class.java).type,
41+ description,
42+ visibility,
43+ ) {
44+ override fun ImGuiBuilder.buildLayout () {
45+ combo(" ##$name " , " $name : ${value.size} item(s)" ) {
46+ immutableCollection
47+ .forEach {
48+ val isSelected = value.contains(it)
49+
50+ selectable(
51+ label = it.className,
52+ selected = isSelected,
53+ flags = DontClosePopups ,
54+ ) {
55+ if (isSelected) value.remove(it)
56+ else value.add(it)
57+ }
58+ }
59+ }
60+ }
61+
62+ val Any .className: String get() = this ::class .java.name
63+ .substringAfter(" ${this ::class .java.packageName} ." )
64+ .replace(' $' , ' .' )
65+
66+ // When serializing the list to json we do not want to serialize the elements' classes, but their stringified representation.
67+ // If we do serialize the classes we'll run into missing type adapters errors by Gson.
68+ // This is intended behaviour. If you wish your collection settings to display something else then you must extend this class.
69+ override fun toJson (): JsonElement = gson.toJsonTree(value.map { it.className })
70+
71+ override fun loadFromJson (serialized : JsonElement ) {
72+ val strList = gson.fromJson<MutableList <String >>(serialized, type)
73+ .mapNotNull { str -> immutableCollection.find { it.className == str } }
74+ .toMutableList()
75+
76+ value = strList
77+ }
78+ }
0 commit comments