Files
DeltaruneQuickshell/Shell/Windows/QuickSettings/QuickSettingsApp.qml
2026-01-30 13:40:57 +02:00

207 lines
5.7 KiB
QML

import QtQuick
import Quickshell.Services.Pipewire
import "../.."
Item {
id: root
width: parent ? parent.width : 1280
height: parent ? parent.height : 820
focus: true
/* ------------------------------
PIXEL CONSTANTS (DO NOT TOUCH)
------------------------------ */
property int menuLeft: 64
property int menuTop: 140
property int lineHeight: 38 + 40 + 1
property int nameFontSize: 32
property int stateFontSize: 28
property int stateColumnX: 824
property int soulOffsetX: -36 - 32
property int soulOffsetY: -26
/* ------------------------------ */
property ShellStateManager manager: null
property int activeSelection: 0
property bool isSelected: false
function clamp(v, lo, hi) {
return Math.max(lo, Math.min(hi, v));
}
function wrapIndex(i) {
if (actions.length === 0)
return 0;
return (i + actions.length) % actions.length;
}
function currentAction() {
return actions.length > 0 ? actions[activeSelection] : null;
}
PwObjectTracker {
objects: [Pipewire.defaultAudioSink]
}
property var actions: [
{
name: "Master Volume",
arr: function (dir) {
const sink = Pipewire.defaultAudioSink;
if (!sink || !sink.audio)
return;
const step = 0.05;
sink.audio.muted = false;
sink.audio.volume = clamp(sink.audio.volume + dir * step, 0, 1);
},
getState: function () {
const sink = Pipewire.defaultAudioSink;
if (!sink || !sink.audio)
return "—";
return Math.round(sink.audio.volume * 100) + "%";
}
},
{
name: "Controls",
ent: function () {},
getState: function () {
console.log("deltarune tommorow");
return "";
}
}
]
Text {
text: "CONFIG"
font.family: "8bitoperator JVE"
font.pixelSize: 71
renderType: Text.NativeRendering
font.hintingPreference: Font.PreferNoHinting
smooth: false
antialiasing: false
anchors.horizontalCenter: parent.horizontalCenter
color: "#ffffff"
y: 32
}
Repeater {
model: root.actions
delegate: Item {
width: root.width
height: lineHeight
x: 0
y: menuTop + index * lineHeight
Image {
source: "./soul.png"
width: 36
height: 36
x: 182
y: 8 + 14
visible: root.activeSelection == index
}
Text {
x: 239
y: 0
text: modelData.name
font.family: "8bitoperator JVE"
font.pixelSize: 71
font.letterSpacing: 1
renderType: Text.NativeRendering
font.hintingPreference: Font.PreferNoHinting
smooth: false
antialiasing: false
color: (root.activeSelection == index && root.isSelected == true) ? "#fefe00" : "#ffffff"
}
// Option state
Text {
x: menuLeft + stateColumnX
y: 4
text: modelData.getState ? modelData.getState() : ""
font.family: "8bitoperator JVE"
font.pixelSize: 71
font.letterSpacing: 1
renderType: Text.NativeRendering
font.hintingPreference: Font.PreferNoHinting
smooth: false
antialiasing: false
color: (root.activeSelection == index && root.isSelected == true) ? "#fefe00" : "#ffffff"
}
}
}
/* ------------------------------
INPUT HANDLING
------------------------------ */
function handleKey(key) {
switch (key) {
case Qt.Key_Up:
if (root.isSelected === false)
activeSelection = wrapIndex(activeSelection - 1);
return true;
case Qt.Key_Down:
if (root.isSelected === false)
activeSelection = wrapIndex(activeSelection + 1);
return true;
case Qt.Key_Left:
{
const a = currentAction();
if (a && a.arr && root.isSelected === true)
a.arr(-1);
return true;
}
case Qt.Key_Right:
{
const a = currentAction();
if (a && a.arr && root.isSelected === true)
a.arr(1);
return true;
}
case Qt.Key_Z:
case Qt.Key_Return:
case Qt.Key_Enter:
{
const a = currentAction();
if (a && a.ent) {
a.ent();
} else {
root.isSelected = !root.isSelected;
}
return true;
}
case Qt.Key_X:
case Qt.Key_Shift:
case Qt.Key_Escape:
if (root.isSelected === true) {
root.isSelected = false;
} else {
if (manager && manager.closeQuickSettings) {
manager.closeQuickSettings();
}
}
return true;
}
return false;
}
Component.onCompleted: {
root.activeSelection = 0;
root.isSelected = false;
ShellInputManager.registerHandler("quickSettings", handleKey);
}
Component.onDestruction: {
ShellInputManager.unregisterHandler("quickSettings");
}
}