// Copyright (C) 2026 Danilo M. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. import QtQuick import "../.." import "../../island" // One row per scene: its name and a field holding its glyph. Paste an icon // from the Nerd Fonts cheat sheet; an empty field falls back to the generic. Column { id: page spacing: 6 // Bumped on discard/save so the rows are rebuilt. A TextInput breaks its // text binding on user edit, so without this a Discard would leave the // discarded glyph on screen. property int rev: 0 Connections { target: SceneIcons function onReset() { page.rev++ } } readonly property var rows: { const out = []; const add = n => { if (!out.some(r => r.name === n)) out.push({ name: n, rev: page.rev }); }; for (const n in SceneIcons.map.scenes) add(n); for (const n of Obs.scenes) add(n); return out; } function glyphOf(name) { const d = SceneIcons.draft; if (d && d.scenes) return d.scenes[name] ?? ""; return SceneIcons.map.scenes[name] ?? ""; } function genericGlyph() { const d = SceneIcons.draft; return d ? (d.generic ?? "") : SceneIcons.map.generic; } Text { width: parent.width wrapMode: Text.Wrap text: "Paste an icon from the Nerd Fonts cheat sheet. An empty field falls back to the default for unmapped scenes." color: Theme.subtext font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } } Repeater { model: page.rows delegate: Item { id: row required property var modelData objectName: modelData.name width: page.width height: 40 Text { anchors { left: parent.left; right: field.left; rightMargin: 10; verticalCenter: parent.verticalCenter } elide: Text.ElideRight text: row.modelData.name color: Theme.text font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } } Rectangle { id: field anchors { right: parent.right; verticalCenter: parent.verticalCenter } width: 64 height: 34 radius: 8 color: Theme.surface border.width: 1 border.color: field.invalid ? Theme.red : Qt.alpha(Theme.text, 0.15) readonly property string value: page.glyphOf(row.modelData.name) readonly property bool invalid: value !== "" && !SceneIcons.validGlyph(value) TextInput { anchors.fill: parent horizontalAlignment: TextInput.AlignHCenter verticalAlignment: TextInput.AlignVCenter selectByMouse: true text: field.value color: Theme.text font { family: Theme.iconFamily; pixelSize: Theme.fontSize + 4 } onTextEdited: SceneIcons.editScene(row.modelData.name, text) } } } } Item { width: parent.width height: 40 Text { anchors { left: parent.left; right: gfield.left; rightMargin: 10; verticalCenter: parent.verticalCenter } elide: Text.ElideRight text: "Default for unmapped scenes" color: Theme.text font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } } Rectangle { id: gfield anchors { right: parent.right; verticalCenter: parent.verticalCenter } width: 64 height: 34 radius: 8 color: Theme.surface border.width: 1 border.color: gfield.invalid ? Theme.red : Qt.alpha(Theme.text, 0.15) readonly property string value: page.genericGlyph() readonly property bool invalid: value !== "" && !SceneIcons.validGlyph(value) TextInput { anchors.fill: parent horizontalAlignment: TextInput.AlignHCenter verticalAlignment: TextInput.AlignVCenter selectByMouse: true text: gfield.value color: Theme.text font { family: Theme.iconFamily; pixelSize: Theme.fontSize + 4 } onTextEdited: SceneIcons.editGeneric(text) } } } }