Files
aiden-niri-noctalia/home/aiden/.config/noctalia/plugins/network-indicator/Settings.qml
T
2026-08-31 12:13:13 -05:00

402 lines
12 KiB
QML

import qs.Commons
import qs.Widgets
import qs.Services.System
import QtQuick
import QtQuick.Layouts
ColumnLayout {
id: root
property var pluginApi: null
property var cfg: pluginApi?.pluginSettings || ({})
property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({})
// ── Options ──
readonly property var slotOptions: [
{
key: "txIcon",
name: pluginApi?.tr("settings.slot.txIcon")
},
{
key: "rxIcon",
name: pluginApi?.tr("settings.slot.rxIcon")
},
{
key: "txSpeed",
name: pluginApi?.tr("settings.slot.txSpeed")
},
{
key: "rxSpeed",
name: pluginApi?.tr("settings.slot.rxSpeed")
},
{
key: "none",
name: pluginApi?.tr("settings.slot.none")
}
]
readonly property var layoutOptions: [
{
key: "horizontal",
name: pluginApi?.tr("settings.layout.horizontal")
},
{
key: "vertical",
name: pluginApi?.tr("settings.layout.vertical")
}
]
readonly property var iconNames: ["arrow", "arrow-bar", "arrow-big", "arrow-narrow", "caret", "chevron", "chevron-compact", "fold"]
// ── Edit state ──
property string editLayout: cfg.layout ?? defaults.layout
property var editSlots: cfg.slots ?? defaults.slots
property string editIconType: cfg.iconType ?? defaults.iconType
property int editByteThresholdActive: cfg.byteThresholdActive ?? defaults.byteThresholdActive
property real editFontSizeModifier: cfg.fontSizeModifier ?? defaults.fontSizeModifier
property real editIconSizeModifier: cfg.iconSizeModifier ?? defaults.iconSizeModifier
property real editPaddingLeft: cfg.paddingLeft ?? defaults.PaddingLeft
property real editPaddingRight: cfg.paddingRight ?? defaults.paddingRight
property real editColumnSpacing: cfg.columnSpacing ?? defaults.columnSpacing
property real editRowSpacing: cfg.rowSpacing ?? defaults.rowSpacing
property bool editUseCustomFont: cfg.useCustomFont ?? defaults.useCustomFonts
property string editCustomFontFamily: cfg.customFontFamily ?? defaults.customFontFamily
property bool editCustomFontBold: cfg.customFontBold ?? defaults.customFontBold
property bool editCustomFontItalic: cfg.customFontItalic ?? defaults.customFontItalic
property bool editUseCustomColors: cfg.useCustomColors ?? defaults.useCustomColors
property color editColorTx: editUseCustomColors && cfg.colorTx || Color.mSecondary
property color editColorRx: editUseCustomColors && cfg.colorRx || Color.mPrimary
property color editColorSilent: editUseCustomColors && cfg.colorSilent || Color.mSurfaceVariant
property color editColorText: editUseCustomColors && cfg.colorText || Color.mOnSurfaceVariant
// ── Helpers ──
readonly property bool isVerticalLayout: editLayout === "vertical"
function slotLabel(idx) {
if (root.isVerticalLayout) {
return ["Top Left", "Top Right", "Bottom Left", "Bottom Right"][idx];
}
return ["Left", "Center Left", "Center Right", "Right"][idx];
}
function updateSlot(index, value) {
let copy = root.editSlots.slice();
copy[index] = value;
root.editSlots = copy;
}
function toIntOr(defaultValue, text) {
const v = parseInt(String(text).trim(), 10);
return isNaN(v) ? defaultValue : v;
}
// ── Save ──
function saveSettings() {
if (!pluginApi || !pluginApi.pluginSettings) {
Logger.e("NetworkIndicator", "Cannot save: pluginApi or pluginSettings is null");
return;
}
const s = pluginApi.pluginSettings;
s.layout = root.editLayout;
s.slots = root.editSlots;
s.iconType = root.editIconType;
s.byteThresholdActive = root.editByteThresholdActive;
s.fontSizeModifier = root.editFontSizeModifier;
s.iconSizeModifier = root.editIconSizeModifier;
s.paddingLeft = root.editPaddingLeft;
s.paddingRight = root.editPaddingRight;
s.columnSpacing = root.editColumnSpacing;
s.rowSpacing = root.editRowSpacing;
s.useCustomFont = root.editUseCustomFont;
s.customFontFamily = root.editCustomFontFamily;
s.customFontBold = root.editCustomFontBold;
s.customFontItalic = root.editCustomFontItalic;
s.useCustomColors = root.editUseCustomColors;
if (root.editUseCustomColors) {
s.colorTx = root.editColorTx.toString();
s.colorRx = root.editColorRx.toString();
s.colorSilent = root.editColorSilent.toString();
s.colorText = root.editColorText.toString();
}
pluginApi.saveSettings();
Logger.i("NetworkIndicator", "Settings saved");
}
// ── UI ──
Layout.rightMargin: Style.marginL
spacing: Style.marginL
// ── Layout ──
NComboBox {
Layout.fillWidth: true
label: pluginApi?.tr("settings.layout.label")
description: pluginApi?.tr("settings.layout.desc")
currentKey: root.editLayout
model: root.layoutOptions
onSelected: key => root.editLayout = key
}
NDivider {
Layout.fillWidth: true
}
// ── Slot assignment ──
NLabel {
label: pluginApi?.tr("settings.slots.label")
description: pluginApi?.tr("settings.slots.desc")
}
Repeater {
model: 4
NComboBox {
Layout.fillWidth: true
label: root.slotLabel(index)
currentKey: root.editSlots[index] ?? "none"
model: root.slotOptions
onSelected: key => root.updateSlot(index, key)
}
}
NDivider {
Layout.fillWidth: true
}
// ── Icon style ──
NComboBox {
Layout.fillWidth: true
label: pluginApi?.tr("settings.iconType.label")
description: pluginApi?.tr("settings.iconType.desc")
currentKey: root.editIconType
model: root.iconNames.map(n => ({
key: n,
name: n
}))
onSelected: key => root.editIconType = key
}
// ── Activity threshold ──
NTextInput {
label: pluginApi?.tr("settings.byteThresholdActive.label")
description: pluginApi?.tr("settings.byteThresholdActive.desc")
placeholderText: root.editByteThresholdActive + " bytes"
text: String(root.editByteThresholdActive)
onTextChanged: root.editByteThresholdActive = root.toIntOr(0, text)
}
NDivider {
Layout.fillWidth: true
}
// ── Size modifiers ──
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginXXS
NLabel {
label: pluginApi?.tr("settings.fontSizeModifier.label")
description: pluginApi?.tr("settings.fontSizeModifier.desc")
}
NValueSlider {
Layout.fillWidth: true
from: 0.5
to: 1.5
stepSize: 0.05
text: root.editFontSizeModifier.toFixed(2)
value: root.editFontSizeModifier
onMoved: value => root.editFontSizeModifier = value
}
}
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginXXS
NLabel {
label: pluginApi?.tr("settings.iconSizeModifier.label")
description: pluginApi?.tr("settings.iconSizeModifier.desc")
}
NValueSlider {
Layout.fillWidth: true
from: 0.5
to: 1.5
stepSize: 0.05
text: root.editIconSizeModifier.toFixed(2)
value: root.editIconSizeModifier
onMoved: value => root.editIconSizeModifier = value
}
}
NDivider {
Layout.fillWidth: true
}
// ── Content padding ──
NTextInput {
label: pluginApi?.tr("settings.rowSpacing.label")
description: pluginApi?.tr("settings.rowSpacing.desc")
placeholderText: root.editRowSpacing + " px"
text: String(root.editRowSpacing)
onTextChanged: root.editRowSpacing = root.toIntOr(0, text)
}
NTextInput {
label: pluginApi?.tr("settings.columnSpacing.label")
description: pluginApi?.tr("settings.columnSpacing.desc")
placeholderText: root.editColumnSpacing + " px"
text: String(root.editColumnSpacing)
onTextChanged: root.editColumnSpacing = root.toIntOr(0, text)
}
NTextInput {
label: pluginApi?.tr("settings.paddingLeft.label")
description: pluginApi?.tr("settings.paddingLeft.desc")
placeholderText: root.editPaddingLeft + " px"
text: String(root.editPaddingLeft)
onTextChanged: root.editPaddingLeft = root.toIntOr(0, text)
}
NTextInput {
label: pluginApi?.tr("settings.paddingRight.label")
description: pluginApi?.tr("settings.paddingRight.desc")
placeholderText: root.editPaddingRight + " px"
text: String(root.editPaddingRight)
onTextChanged: root.editPaddingRight = root.toIntOr(0, text)
}
NDivider {
Layout.fillWidth: true
}
// ── Custom Font ──
NToggle {
checked: root.editUseCustomFont
defaultValue: defaults.useCustomFont ?? false
description: pluginApi?.tr("settings.useCustomFont.desc")
label: pluginApi?.tr("settings.useCustomFont.label")
onToggled: c => root.editUseCustomFont = c
}
ColumnLayout {
visible: root.editUseCustomFont
Layout.fillWidth: true
spacing: Style.marginL
NSearchableComboBox {
label: pluginApi?.tr("settings.customFontFamily.label")
description: pluginApi?.tr("settings.customFontFamily.desc")
model: FontService.availableFonts
currentKey: root.editCustomFontFamily || Qt.application.font.family
placeholder: pluginApi?.tr("settings.customFontFamily.placeholder")
searchPlaceholder: pluginApi?.tr("settings.customFontFamily.searchPlaceholder")
popupHeight: 420
onSelected: key => {
root.editCustomFontFamily = (key === Qt.application.font.family) ? "" : key;
}
}
NToggle {
checked: root.editCustomFontBold
defaultValue: defaults.customFontBold ?? false
description: pluginApi?.tr("settings.customFontBold.desc")
label: pluginApi?.tr("settings.customFontBold.label")
onToggled: c => root.editCustomFontBold = c
}
NToggle {
checked: root.editCustomFontItalic
defaultValue: defaults.customFontItalic ?? false
description: pluginApi?.tr("settings.customFontItalic.desc")
label: pluginApi?.tr("settings.customFontItalic.label")
onToggled: c => root.editCustomFontItalic = c
}
}
// ── Custom Colors ──
NToggle {
checked: root.editUseCustomColors
defaultValue: defaults.useCustomColors ?? false
description: pluginApi?.tr("settings.useCustomColors.desc")
label: pluginApi?.tr("settings.useCustomColors.label")
onToggled: c => root.editUseCustomColors = c
}
ColumnLayout {
visible: root.editUseCustomColors
RowLayout {
NLabel {
Layout.alignment: Qt.AlignTop
label: pluginApi?.tr("settings.colorTx.label")
description: pluginApi?.tr("settings.colorTx.desc")
}
NColorPicker {
selectedColor: root.editColorTx
onColorSelected: color => root.editColorTx = color
}
}
RowLayout {
NLabel {
Layout.alignment: Qt.AlignTop
label: pluginApi?.tr("settings.colorRx.label")
description: pluginApi?.tr("settings.colorRx.desc")
}
NColorPicker {
selectedColor: root.editColorRx
onColorSelected: color => root.editColorRx = color
}
}
RowLayout {
NLabel {
Layout.alignment: Qt.AlignTop
label: pluginApi?.tr("settings.colorSilent.label")
description: pluginApi?.tr("settings.colorSilent.desc")
}
NColorPicker {
selectedColor: root.editColorSilent
onColorSelected: color => root.editColorSilent = color
}
}
RowLayout {
NLabel {
Layout.alignment: Qt.AlignTop
label: pluginApi?.tr("settings.colorText.label")
description: pluginApi?.tr("settings.colorText.desc")
}
NColorPicker {
selectedColor: root.editColorText
onColorSelected: color => root.editColorText = color
}
}
}
}