1358 lines
50 KiB
QML
1358 lines
50 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import ".."
|
|
import qs.components
|
|
import qs.components.controls
|
|
import qs.components.effects
|
|
import qs.components.containers
|
|
import qs.services
|
|
import qs.config
|
|
import qs.utils
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
import QtQuick.Layouts
|
|
|
|
RowLayout {
|
|
id: root
|
|
|
|
required property Session session
|
|
|
|
property bool showDebugInfo: false
|
|
|
|
// Bar Behavior
|
|
property bool persistent: true
|
|
property bool showOnHover: true
|
|
property int dragThreshold: 20
|
|
|
|
// Status Icons
|
|
property bool showAudio: true
|
|
property bool showMicrophone: true
|
|
property bool showKbLayout: false
|
|
property bool showNetwork: true
|
|
property bool showBluetooth: true
|
|
property bool showBattery: true
|
|
property bool showLockStatus: true
|
|
|
|
// Tray Settings
|
|
property bool trayBackground: false
|
|
property bool trayCompact: false
|
|
property bool trayRecolour: false
|
|
|
|
// Workspaces
|
|
property int workspacesShown: 5
|
|
property bool workspacesActiveIndicator: true
|
|
property bool workspacesOccupiedBg: false
|
|
property bool workspacesShowWindows: false
|
|
property bool workspacesPerMonitor: true
|
|
|
|
anchors.fill: parent
|
|
|
|
spacing: 0
|
|
|
|
FileView {
|
|
id: configFile
|
|
|
|
path: `${Paths.config}/shell.json`
|
|
watchChanges: true
|
|
|
|
onLoaded: {
|
|
try {
|
|
const config = JSON.parse(text());
|
|
updateFromConfig(config);
|
|
} catch (e) {
|
|
console.error("Failed to parse config:", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateFromConfig(config) {
|
|
// Update clock toggle
|
|
if (config.bar && config.bar.clock) {
|
|
clockShowIconSwitch.checked = config.bar.clock.showIcon !== false;
|
|
}
|
|
|
|
// Update entries
|
|
if (config.bar && config.bar.entries) {
|
|
entriesModel.clear();
|
|
for (const entry of config.bar.entries) {
|
|
entriesModel.append({
|
|
id: entry.id,
|
|
enabled: entry.enabled !== false
|
|
});
|
|
}
|
|
}
|
|
|
|
// Update bar behavior
|
|
if (config.bar) {
|
|
root.persistent = config.bar.persistent !== false;
|
|
root.showOnHover = config.bar.showOnHover !== false;
|
|
root.dragThreshold = config.bar.dragThreshold || 20;
|
|
}
|
|
|
|
// Update status icons
|
|
if (config.bar && config.bar.status) {
|
|
root.showAudio = config.bar.status.showAudio !== false;
|
|
root.showMicrophone = config.bar.status.showMicrophone !== false;
|
|
root.showKbLayout = config.bar.status.showKbLayout === true;
|
|
root.showNetwork = config.bar.status.showNetwork !== false;
|
|
root.showBluetooth = config.bar.status.showBluetooth !== false;
|
|
root.showBattery = config.bar.status.showBattery !== false;
|
|
root.showLockStatus = config.bar.status.showLockStatus !== false;
|
|
}
|
|
|
|
// Update tray settings
|
|
if (config.bar && config.bar.tray) {
|
|
root.trayBackground = config.bar.tray.background === true;
|
|
root.trayCompact = config.bar.tray.compact === true;
|
|
root.trayRecolour = config.bar.tray.recolour === true;
|
|
}
|
|
|
|
// Update workspaces
|
|
if (config.bar && config.bar.workspaces) {
|
|
root.workspacesShown = config.bar.workspaces.shown || 5;
|
|
root.workspacesActiveIndicator = config.bar.workspaces.activeIndicator !== false;
|
|
root.workspacesOccupiedBg = config.bar.workspaces.occupiedBg === true;
|
|
root.workspacesShowWindows = config.bar.workspaces.showWindows === true;
|
|
root.workspacesPerMonitor = config.bar.workspaces.perMonitorWorkspaces !== false;
|
|
}
|
|
}
|
|
|
|
function saveConfig(entryIndex, entryEnabled) {
|
|
if (!configFile.loaded) {
|
|
root.lastSaveStatus = "Error: Config file not loaded yet";
|
|
root.debugInfo = "Config file not loaded yet, cannot save";
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const config = JSON.parse(configFile.text());
|
|
|
|
// Ensure bar object exists
|
|
if (!config.bar) config.bar = {};
|
|
|
|
// Update clock setting
|
|
if (!config.bar.clock) config.bar.clock = {};
|
|
config.bar.clock.showIcon = clockShowIconSwitch.checked;
|
|
|
|
// Update bar behavior
|
|
config.bar.persistent = root.persistent;
|
|
config.bar.showOnHover = root.showOnHover;
|
|
config.bar.dragThreshold = root.dragThreshold;
|
|
|
|
// Update status icons
|
|
if (!config.bar.status) config.bar.status = {};
|
|
config.bar.status.showAudio = root.showAudio;
|
|
config.bar.status.showMicrophone = root.showMicrophone;
|
|
config.bar.status.showKbLayout = root.showKbLayout;
|
|
config.bar.status.showNetwork = root.showNetwork;
|
|
config.bar.status.showBluetooth = root.showBluetooth;
|
|
config.bar.status.showBattery = root.showBattery;
|
|
config.bar.status.showLockStatus = root.showLockStatus;
|
|
|
|
// Update tray settings
|
|
if (!config.bar.tray) config.bar.tray = {};
|
|
config.bar.tray.background = root.trayBackground;
|
|
config.bar.tray.compact = root.trayCompact;
|
|
config.bar.tray.recolour = root.trayRecolour;
|
|
|
|
// Update workspaces
|
|
if (!config.bar.workspaces) config.bar.workspaces = {};
|
|
config.bar.workspaces.shown = root.workspacesShown;
|
|
config.bar.workspaces.activeIndicator = root.workspacesActiveIndicator;
|
|
config.bar.workspaces.occupiedBg = root.workspacesOccupiedBg;
|
|
config.bar.workspaces.showWindows = root.workspacesShowWindows;
|
|
config.bar.workspaces.perMonitorWorkspaces = root.workspacesPerMonitor;
|
|
|
|
// Update entries from the model (same approach as clock - use provided value if available)
|
|
if (!config.bar.entries) config.bar.entries = [];
|
|
config.bar.entries = [];
|
|
|
|
let debugInfo = `saveConfig called\n`;
|
|
debugInfo += `entryIndex: ${entryIndex}\n`;
|
|
debugInfo += `entryEnabled: ${entryEnabled}\n`;
|
|
debugInfo += `entriesModel.count: ${entriesModel.count}\n\n`;
|
|
|
|
for (let i = 0; i < entriesModel.count; i++) {
|
|
const entry = entriesModel.get(i);
|
|
// If this is the entry being updated, use the provided value (same as clock toggle reads from switch)
|
|
// Otherwise use the value from the model
|
|
let enabled = entry.enabled;
|
|
if (entryIndex !== undefined && i === entryIndex) {
|
|
enabled = entryEnabled;
|
|
debugInfo += `Entry ${i} (${entry.id}): Using provided value = ${entryEnabled}\n`;
|
|
} else {
|
|
debugInfo += `Entry ${i} (${entry.id}): Using model value = ${entry.enabled}\n`;
|
|
}
|
|
config.bar.entries.push({
|
|
id: entry.id,
|
|
enabled: enabled
|
|
});
|
|
}
|
|
|
|
debugInfo += `\nFinal entries array:\n${JSON.stringify(config.bar.entries, null, 2)}\n`;
|
|
root.debugInfo = debugInfo;
|
|
|
|
// Write back to file using setText (same simple approach that worked for clock)
|
|
const jsonString = JSON.stringify(config, null, 4);
|
|
configFile.setText(jsonString);
|
|
root.lastSaveStatus = `Saved! Entries count: ${config.bar.entries.length}`;
|
|
} catch (e) {
|
|
root.lastSaveStatus = `Error: ${e.message}`;
|
|
root.debugInfo = `Failed to save config:\n${e.message}\n${e.stack}`;
|
|
}
|
|
}
|
|
|
|
ListModel {
|
|
id: entriesModel
|
|
}
|
|
|
|
// Debug info
|
|
property string debugInfo: ""
|
|
property string lastSaveStatus: ""
|
|
|
|
function collapseAllSections(exceptSection) {
|
|
if (exceptSection !== clockSection) clockSection.expanded = false;
|
|
if (exceptSection !== barBehaviorSection) barBehaviorSection.expanded = false;
|
|
if (exceptSection !== statusIconsSection) statusIconsSection.expanded = false;
|
|
if (exceptSection !== traySettingsSection) traySettingsSection.expanded = false;
|
|
if (exceptSection !== workspacesSection) workspacesSection.expanded = false;
|
|
}
|
|
|
|
Item {
|
|
Layout.preferredWidth: Math.floor(parent.width * 0.4)
|
|
Layout.minimumWidth: 420
|
|
Layout.fillHeight: true
|
|
|
|
StyledFlickable {
|
|
id: sidebarFlickable
|
|
anchors.fill: parent
|
|
flickableDirection: Flickable.VerticalFlick
|
|
contentHeight: sidebarLayout.implicitHeight + Appearance.padding.large * 2
|
|
|
|
StyledScrollBar.vertical: StyledScrollBar {
|
|
flickable: sidebarFlickable
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: sidebarLayout
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
|
anchors.leftMargin: Appearance.padding.large
|
|
anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2
|
|
|
|
spacing: Appearance.spacing.small
|
|
|
|
RowLayout {
|
|
spacing: Appearance.spacing.smaller
|
|
|
|
StyledText {
|
|
text: qsTr("Settings")
|
|
font.pointSize: Appearance.font.size.large
|
|
font.weight: 500
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: clockSection
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: clockSectionHeader.implicitHeight
|
|
property bool expanded: false
|
|
|
|
ColumnLayout {
|
|
id: clockSectionHeader
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
spacing: Appearance.spacing.small
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Appearance.spacing.small
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
text: qsTr("Clock")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
MaterialIcon {
|
|
text: "expand_more"
|
|
rotation: clockSection.expanded ? 180 : 0
|
|
color: Colours.palette.m3onSurface
|
|
Behavior on rotation {
|
|
Anim {}
|
|
}
|
|
}
|
|
}
|
|
|
|
StateLayer {
|
|
anchors.fill: parent
|
|
anchors.leftMargin: -Appearance.padding.normal
|
|
anchors.rightMargin: -Appearance.padding.normal
|
|
function onClicked(): void {
|
|
const wasExpanded = clockSection.expanded;
|
|
root.collapseAllSections(clockSection);
|
|
clockSection.expanded = !wasExpanded;
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
visible: clockSection.expanded
|
|
text: qsTr("Clock display settings")
|
|
color: Colours.palette.m3outline
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
Layout.fillWidth: true
|
|
visible: clockSection.expanded
|
|
implicitHeight: clockSection.expanded ? clockRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: clockRow
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show clock icon")
|
|
}
|
|
|
|
StyledSwitch {
|
|
id: clockShowIconSwitch
|
|
checked: true
|
|
onToggled: {
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: barBehaviorSection
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: barBehaviorSectionHeader.implicitHeight
|
|
property bool expanded: false
|
|
|
|
ColumnLayout {
|
|
id: barBehaviorSectionHeader
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
spacing: Appearance.spacing.small
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Appearance.spacing.small
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
text: qsTr("Bar Behavior")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
MaterialIcon {
|
|
text: "expand_more"
|
|
rotation: barBehaviorSection.expanded ? 180 : 0
|
|
color: Colours.palette.m3onSurface
|
|
Behavior on rotation {
|
|
Anim {}
|
|
}
|
|
}
|
|
}
|
|
|
|
StateLayer {
|
|
anchors.fill: parent
|
|
anchors.leftMargin: -Appearance.padding.normal
|
|
anchors.rightMargin: -Appearance.padding.normal
|
|
function onClicked(): void {
|
|
const wasExpanded = barBehaviorSection.expanded;
|
|
root.collapseAllSections(barBehaviorSection);
|
|
barBehaviorSection.expanded = !wasExpanded;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: barBehaviorSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: barBehaviorSection.expanded ? persistentRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: persistentRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Persistent")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.persistent
|
|
onToggled: {
|
|
root.persistent = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: barBehaviorSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: barBehaviorSection.expanded ? showOnHoverRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showOnHoverRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show on hover")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showOnHover
|
|
onToggled: {
|
|
root.showOnHover = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: barBehaviorSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: barBehaviorSection.expanded ? dragThresholdRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: dragThresholdRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Drag threshold")
|
|
}
|
|
|
|
CustomSpinBox {
|
|
min: 0
|
|
max: 100
|
|
value: root.dragThreshold
|
|
onValueModified: value => {
|
|
root.dragThreshold = value;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: statusIconsSection
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: statusIconsSectionHeader.implicitHeight
|
|
property bool expanded: false
|
|
|
|
ColumnLayout {
|
|
id: statusIconsSectionHeader
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
spacing: Appearance.spacing.small
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Appearance.spacing.small
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
text: qsTr("Status Icons")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
MaterialIcon {
|
|
text: "expand_more"
|
|
rotation: statusIconsSection.expanded ? 180 : 0
|
|
color: Colours.palette.m3onSurface
|
|
Behavior on rotation {
|
|
Anim {}
|
|
}
|
|
}
|
|
}
|
|
|
|
StateLayer {
|
|
anchors.fill: parent
|
|
anchors.leftMargin: -Appearance.padding.normal
|
|
anchors.rightMargin: -Appearance.padding.normal
|
|
function onClicked(): void {
|
|
const wasExpanded = statusIconsSection.expanded;
|
|
root.collapseAllSections(statusIconsSection);
|
|
statusIconsSection.expanded = !wasExpanded;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: statusIconsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: statusIconsSection.expanded ? showAudioRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showAudioRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show audio")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showAudio
|
|
onToggled: {
|
|
root.showAudio = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: statusIconsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: statusIconsSection.expanded ? showMicrophoneRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showMicrophoneRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show microphone")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showMicrophone
|
|
onToggled: {
|
|
root.showMicrophone = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: statusIconsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: statusIconsSection.expanded ? showKbLayoutRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showKbLayoutRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show keyboard layout")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showKbLayout
|
|
onToggled: {
|
|
root.showKbLayout = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: statusIconsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: statusIconsSection.expanded ? showNetworkRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showNetworkRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show network")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showNetwork
|
|
onToggled: {
|
|
root.showNetwork = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: statusIconsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: statusIconsSection.expanded ? showBluetoothRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showBluetoothRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show bluetooth")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showBluetooth
|
|
onToggled: {
|
|
root.showBluetooth = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: statusIconsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: statusIconsSection.expanded ? showBatteryRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showBatteryRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show battery")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showBattery
|
|
onToggled: {
|
|
root.showBattery = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: statusIconsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: statusIconsSection.expanded ? showLockStatusRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: showLockStatusRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show lock status")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.showLockStatus
|
|
onToggled: {
|
|
root.showLockStatus = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: traySettingsSection
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: traySettingsSectionHeader.implicitHeight
|
|
property bool expanded: false
|
|
|
|
ColumnLayout {
|
|
id: traySettingsSectionHeader
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
spacing: Appearance.spacing.small
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Appearance.spacing.small
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
text: qsTr("Tray Settings")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
MaterialIcon {
|
|
text: "expand_more"
|
|
rotation: traySettingsSection.expanded ? 180 : 0
|
|
color: Colours.palette.m3onSurface
|
|
Behavior on rotation {
|
|
Anim {}
|
|
}
|
|
}
|
|
}
|
|
|
|
StateLayer {
|
|
anchors.fill: parent
|
|
anchors.leftMargin: -Appearance.padding.normal
|
|
anchors.rightMargin: -Appearance.padding.normal
|
|
function onClicked(): void {
|
|
const wasExpanded = traySettingsSection.expanded;
|
|
root.collapseAllSections(traySettingsSection);
|
|
traySettingsSection.expanded = !wasExpanded;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: traySettingsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: traySettingsSection.expanded ? trayBackgroundRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: trayBackgroundRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Background")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.trayBackground
|
|
onToggled: {
|
|
root.trayBackground = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: traySettingsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: traySettingsSection.expanded ? trayCompactRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: trayCompactRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Compact")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.trayCompact
|
|
onToggled: {
|
|
root.trayCompact = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: traySettingsSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: traySettingsSection.expanded ? trayRecolourRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: trayRecolourRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Recolour")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.trayRecolour
|
|
onToggled: {
|
|
root.trayRecolour = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: workspacesSection
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: workspacesSectionHeader.implicitHeight
|
|
property bool expanded: false
|
|
|
|
ColumnLayout {
|
|
id: workspacesSectionHeader
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
spacing: Appearance.spacing.small
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Appearance.spacing.small
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
text: qsTr("Workspaces")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
MaterialIcon {
|
|
text: "expand_more"
|
|
rotation: workspacesSection.expanded ? 180 : 0
|
|
color: Colours.palette.m3onSurface
|
|
Behavior on rotation {
|
|
Anim {}
|
|
}
|
|
}
|
|
}
|
|
|
|
StateLayer {
|
|
anchors.fill: parent
|
|
anchors.leftMargin: -Appearance.padding.normal
|
|
anchors.rightMargin: -Appearance.padding.normal
|
|
function onClicked(): void {
|
|
const wasExpanded = workspacesSection.expanded;
|
|
root.collapseAllSections(workspacesSection);
|
|
workspacesSection.expanded = !wasExpanded;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: workspacesSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: workspacesSection.expanded ? workspacesShownRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: workspacesShownRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Shown")
|
|
}
|
|
|
|
CustomSpinBox {
|
|
min: 1
|
|
max: 20
|
|
value: root.workspacesShown
|
|
onValueModified: value => {
|
|
root.workspacesShown = value;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: workspacesSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: workspacesSection.expanded ? workspacesActiveIndicatorRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: workspacesActiveIndicatorRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Active indicator")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.workspacesActiveIndicator
|
|
onToggled: {
|
|
root.workspacesActiveIndicator = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: workspacesSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: workspacesSection.expanded ? workspacesOccupiedBgRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: workspacesOccupiedBgRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Occupied background")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.workspacesOccupiedBg
|
|
onToggled: {
|
|
root.workspacesOccupiedBg = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: workspacesSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: workspacesSection.expanded ? workspacesShowWindowsRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: workspacesShowWindowsRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show windows")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.workspacesShowWindows
|
|
onToggled: {
|
|
root.workspacesShowWindows = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
visible: workspacesSection.expanded
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.small / 2
|
|
implicitHeight: workspacesSection.expanded ? workspacesPerMonitorRow.implicitHeight + Appearance.padding.large * 2 : 0
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
RowLayout {
|
|
id: workspacesPerMonitorRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Per monitor workspaces")
|
|
}
|
|
|
|
StyledSwitch {
|
|
checked: root.workspacesPerMonitor
|
|
onToggled: {
|
|
root.workspacesPerMonitor = checked;
|
|
root.saveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
InnerBorder {
|
|
leftThickness: 0
|
|
rightThickness: Appearance.padding.normal / 2
|
|
}
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
|
|
StyledFlickable {
|
|
anchors.fill: parent
|
|
anchors.margins: Appearance.padding.large * 2
|
|
|
|
flickableDirection: Flickable.VerticalFlick
|
|
contentHeight: contentLayout.implicitHeight
|
|
|
|
StyledScrollBar.vertical: StyledScrollBar {
|
|
flickable: parent
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: contentLayout
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
|
|
spacing: Appearance.spacing.normal
|
|
|
|
MaterialIcon {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: "task_alt"
|
|
font.pointSize: Appearance.font.size.extraLarge * 3
|
|
font.bold: true
|
|
}
|
|
|
|
StyledText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: qsTr("Taskbar settings")
|
|
font.pointSize: Appearance.font.size.large
|
|
font.bold: true
|
|
}
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: qsTr("Clock")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
StyledText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: clockShowIconSwitch.checked ? qsTr("Clock icon enabled") : qsTr("Clock icon disabled")
|
|
color: Colours.palette.m3outline
|
|
}
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: qsTr("Taskbar Entries")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
StyledText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: qsTr("Configure which entries appear in the taskbar")
|
|
color: Colours.palette.m3outline
|
|
}
|
|
|
|
StyledRect {
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Appearance.spacing.large
|
|
implicitHeight: debugToggleRow.implicitHeight + Appearance.padding.large * 2
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
radius: Appearance.rounding.normal
|
|
|
|
RowLayout {
|
|
id: debugToggleRow
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.margins: Appearance.padding.large
|
|
spacing: Appearance.spacing.normal
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Show debug information")
|
|
font.pointSize: Appearance.font.size.normal
|
|
}
|
|
|
|
StyledSwitch {
|
|
id: showDebugInfoSwitch
|
|
checked: root.showDebugInfo
|
|
onToggled: {
|
|
root.showDebugInfo = checked;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.large
|
|
Layout.alignment: Qt.AlignHCenter
|
|
visible: root.showDebugInfo
|
|
text: qsTr("Debug Info")
|
|
font.pointSize: Appearance.font.size.larger
|
|
font.weight: 500
|
|
}
|
|
|
|
StyledRect {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 200
|
|
Layout.maximumHeight: 300
|
|
visible: root.showDebugInfo
|
|
|
|
radius: Appearance.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
clip: true
|
|
|
|
StyledFlickable {
|
|
id: debugFlickable
|
|
anchors.fill: parent
|
|
anchors.margins: Appearance.padding.normal
|
|
contentHeight: debugText.implicitHeight
|
|
clip: true
|
|
|
|
StyledScrollBar.vertical: StyledScrollBar {
|
|
flickable: debugFlickable
|
|
}
|
|
|
|
TextEdit {
|
|
id: debugText
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
width: parent.width
|
|
|
|
text: root.debugInfo || "No debug info yet"
|
|
font.pointSize: Appearance.font.size.small
|
|
color: Colours.palette.m3onSurface
|
|
wrapMode: TextEdit.Wrap
|
|
readOnly: true
|
|
selectByMouse: true
|
|
selectByKeyboard: true
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
Layout.topMargin: Appearance.spacing.small
|
|
Layout.alignment: Qt.AlignHCenter
|
|
visible: root.showDebugInfo
|
|
text: root.lastSaveStatus || ""
|
|
font.pointSize: Appearance.font.size.small
|
|
color: root.lastSaveStatus.includes("Error") ? Colours.palette.m3error : Colours.palette.m3primary
|
|
}
|
|
}
|
|
}
|
|
|
|
InnerBorder {
|
|
leftThickness: Appearance.padding.normal / 2
|
|
}
|
|
}
|
|
}
|