From 395c34990f54b1cec2cee637d37a912815502037 Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 3 May 2026 17:19:31 +0200 Subject: [PATCH 1/6] implemented generic grid approach --- network-indicator/BarWidget.qml | 423 ++++++++++---------- network-indicator/Settings.qml | 656 +++++++++++++++++--------------- network-indicator/i18n/en.json | 118 +++--- network-indicator/manifest.json | 19 +- 4 files changed, 649 insertions(+), 567 deletions(-) diff --git a/network-indicator/BarWidget.qml b/network-indicator/BarWidget.qml index 691375072..5ed080e3b 100644 --- a/network-indicator/BarWidget.qml +++ b/network-indicator/BarWidget.qml @@ -7,222 +7,235 @@ import QtQuick.Layouts import Quickshell Item { - id: root - - property var pluginApi: null - - property ShellScreen screen - property string widgetId: "" - property string section: "" - property int sectionWidgetIndex: -1 - property int sectionWidgetsCount: 0 - - // ── Configuration ── - - property var cfg: pluginApi?.pluginSettings || ({}) - property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({}) - - property string arrowType: cfg.arrowType ?? defaults.arrowType - - property bool useCustomColors: cfg.useCustomColors ?? defaults.useCustomColors - property bool showNumbers: cfg.showNumbers ?? defaults.showNumbers - - property color colorSilent: root.useCustomColors && cfg.colorSilent || Color.mSurfaceVariant - property color colorTx: root.useCustomColors && cfg.colorTx || Color.mSecondary - property color colorRx: root.useCustomColors && cfg.colorRx || Color.mPrimary - property color colorText: root.useCustomColors && cfg.colorText || Color.mOnSurfaceVariant - - property int byteThresholdActive: cfg.byteThresholdActive ?? defaults.byteThresholdActive - property real fontSizeModifier: cfg.fontSizeModifier ?? defaults.fontSizeModifier - property real iconSizeModifier: cfg.iconSizeModifier ?? defaults.iconSizeModifier - property real spacingInbetween: cfg.spacingInbetween ?? defaults.spacingInbetween - property real contentMargin: cfg.contentMargin ?? defaults.contentMargin ?? Style.marginS - - property bool useCustomFont: cfg.useCustomFont ?? defaults.useCustomFont - property string customFontFamily: cfg.customFontFamily ?? defaults.customFontFamily - property bool customFontBold: cfg.customFontBold ?? defaults.customFontBold - property bool customFontItalic: cfg.customFontItalic ?? defaults.customFontItalic - - property bool horizontalNumbers: cfg.horizontalLayout ?? defaults.horizontalLayout - - readonly property string resolvedFontFamily: { - if (root.useCustomFont && root.customFontFamily) - return root.customFontFamily; - return Settings.data.ui.fontDefault; + id: root + + property var pluginApi: null + + property ShellScreen screen + property string widgetId: "" + property string section: "" + property int sectionWidgetIndex: -1 + property int sectionWidgetsCount: 0 + + property string txSpeed: (SystemStatService.formatSpeed(SystemStatService.txSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s").padStart(8, " ") + property string rxSpeed: (SystemStatService.formatSpeed(SystemStatService.rxSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s").padStart(8, " ") + + // ── Configuration ── + + property var cfg: pluginApi?.pluginSettings || ({}) + property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({}) + + property string iconType: cfg.iconType ?? defaults.iconType + property int byteThresholdActive: cfg.byteThresholdActive ?? defaults.byteThresholdActive + property string layout: cfg.layout ?? defaults.layout + property var slots: cfg.slots ?? defaults.slots + + property real fontSizeModifier: cfg.fontSizeModifier ?? defaults.fontSizeModifier + property real iconSizeModifier: cfg.iconSizeModifier ?? defaults.iconSizeModifier + + property real columnSpacing: cfg.columnSpacing ?? defaults.columnSpacing + property real rowSpacing: cfg.rowSpacing ?? defaults.rowSpacing + property real paddingLeft: cfg.paddingLeft ?? defaults.paddingLeft + property real paddingRight: cfg.paddingRight ?? defaults.paddingRight + + property bool useCustomColors: cfg.useCustomColors ?? defaults.useCustomColors + property color colorSilent: root.useCustomColors && cfg.colorSilent || Color.mSurfaceVariant + property color colorTx: root.useCustomColors && cfg.colorTx || Color.mSecondary + property color colorRx: root.useCustomColors && cfg.colorRx || Color.mPrimary + property color colorText: root.useCustomColors && cfg.colorText || Color.mOnSurfaceVariant + + property bool useCustomFont: cfg.useCustomFont ?? defaults.useCustomFont + property string customFontFamily: cfg.customFontFamily ?? defaults.customFontFamily + property bool customFontBold: cfg.customFontBold ?? defaults.customFontBold + property bool customFontItalic: cfg.customFontItalic ?? defaults.customFontItalic + + readonly property string resolvedFontFamily: { + if (root.useCustomFont && root.customFontFamily) + return root.customFontFamily; + return Settings.data.ui.fontDefault; + } + + readonly property int resolvedFontWeight: { + if (root.useCustomFont && root.customFontBold) + return Font.Bold; + return Style.fontWeightMedium; + } + + readonly property bool resolvedFontItalic: root.useCustomFont && root.customFontItalic + + // ── Widget ── + + property bool txActive: SystemStatService.txSpeed >= root.byteThresholdActive + property bool rxActive: SystemStatService.rxSpeed >= root.byteThresholdActive + + property string barPosition: Settings.data.bar.position || "top" + property string barDensity: Settings.data.bar.density || "compact" + property bool barIsSpacious: barDensity != "mini" + property bool barIsVertical: barPosition === "left" || barPosition === "right" + + readonly property real contentWidth: barIsVertical ? Style.capsuleHeight : content.implicitWidth + root.paddingLeft + root.paddingRight + readonly property real contentHeight: barIsVertical ? Math.round(content.implicitHeight + Style.marginM * 2) : Style.capsuleHeight + + implicitWidth: contentWidth + implicitHeight: contentHeight + + // Actual widget components + NIcon { + id: txIconElement + icon: root.iconType + "-up" + color: root.txActive ? root.colorTx : root.colorSilent + pointSize: Style.fontSizeL * root.iconSizeModifier + } + + NIcon { + id: rxIconElement + icon: root.iconType + "-down" + color: root.rxActive ? root.colorRx : root.colorSilent + pointSize: Style.fontSizeL * root.iconSizeModifier + } + + NText { + id: txSpeedElement + text: root.txSpeed + color: root.colorText + pointSize: Style.barFontSize * root.fontSizeModifier + font.family: root.resolvedFontFamily + font.weight: root.resolvedFontWeight + font.italic: root.resolvedFontItalic + } + + NText { + id: rxSpeedElement + text: root.rxSpeed + color: root.colorText + pointSize: Style.barFontSize * root.fontSizeModifier + font.family: root.resolvedFontFamily + font.weight: root.resolvedFontWeight + font.italic: root.resolvedFontItalic + } + + function getElement(name) { + switch (name) { + case "txIcon": + return txIconElement; + case "rxIcon": + return rxIconElement; + case "txSpeed": + return txSpeedElement; + case "rxSpeed": + return rxSpeedElement; + default: + return null; } - - readonly property int resolvedFontWeight: { - if (root.useCustomFont && root.customFontBold) - return Font.Bold; - return Style.fontWeightMedium; + } + + Item { + id: spacer0 + } + Item { + id: spacer1 + } + Item { + id: spacer2 + } + Item { + id: spacer3 + } + + readonly property var spacers: [spacer0, spacer1, spacer2, spacer3] + + Rectangle { + id: visualCapsule + x: Style.pixelAlignCenter(parent.width, width) + y: Style.pixelAlignCenter(parent.height, height) + width: root.contentWidth + height: root.contentHeight + color: Style.capsuleColor + radius: Style.radiusM + border.color: Style.capsuleBorderColor + border.width: Style.capsuleBorderWidth + + GridLayout { + id: content + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: root.paddingLeft + anchors.right: parent.right + anchors.rightMargin: root.paddingRight + + rows: root.layout === "horizontal" ? 1 : 2 + columns: root.layout === "horizontal" ? 4 : 2 + columnSpacing: root.columnSpacing + rowSpacing: root.rowSpacing } - - readonly property bool resolvedFontItalic: root.useCustomFont && root.customFontItalic - - readonly property bool numbersVisible: root.showNumbers && barIsSpacious && !barIsVertical - - property string barPosition: Settings.data.bar.position || "top" - property string barDensity: Settings.data.bar.density || "compact" - property bool barIsSpacious: barDensity != "mini" - property bool barIsVertical: barPosition === "left" || barPosition === "right" - - readonly property real contentWidth: barIsVertical ? Style.capsuleHeight : contentRow.implicitWidth + root.contentMargin * 2 - readonly property real contentHeight: barIsVertical ? Math.round(contentRow.implicitHeight + Style.marginM * 2) : Style.capsuleHeight - - implicitWidth: contentWidth - implicitHeight: contentHeight - - // ── Widget ── - - property string txSpeed: (SystemStatService.formatSpeed(SystemStatService.txSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s").padStart(8, " ") - property string rxSpeed: (SystemStatService.formatSpeed(SystemStatService.rxSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s").padStart(8, " ") - - Rectangle { - id: visualCapsule - x: Style.pixelAlignCenter(parent.width, width) - y: Style.pixelAlignCenter(parent.height, height) - width: root.contentWidth - height: root.contentHeight - color: Style.capsuleColor - radius: Style.radiusM - border.color: Style.capsuleBorderColor - border.width: Style.capsuleBorderWidth - - RowLayout { - id: contentRow - anchors.centerIn: parent - spacing: Style.marginS - - // Vertical layout: stacked values to the left - Column { - visible: root.numbersVisible && !root.horizontalNumbers - spacing: root.spacingInbetween - - NText { - horizontalAlignment: Text.AlignRight - text: root.txSpeed - color: root.colorText - pointSize: Style.barFontSize * root.fontSizeModifier - font.family: root.resolvedFontFamily - font.weight: root.resolvedFontWeight - font.italic: root.resolvedFontItalic - } - - NText { - horizontalAlignment: Text.AlignRight - text: root.rxSpeed - color: root.colorText - pointSize: Style.barFontSize * root.fontSizeModifier - font.family: root.resolvedFontFamily - font.weight: root.resolvedFontWeight - font.italic: root.resolvedFontItalic - } - } - - // Horizontal layout: TX value left - NText { - visible: root.numbersVisible && root.horizontalNumbers - horizontalAlignment: Text.AlignRight - text: root.rxSpeed - color: root.colorText - pointSize: Style.barFontSize * root.fontSizeModifier - font.family: root.resolvedFontFamily - font.weight: root.resolvedFontWeight - font.italic: root.resolvedFontItalic - } - - // Icons - Column { - spacing: -10.0 + root.spacingInbetween - - NIcon { - icon: arrowType + "-up" - color: SystemStatService.txSpeed >= root.byteThresholdActive ? root.colorTx : root.colorSilent - pointSize: Style.fontSizeL * root.iconSizeModifier - } - - NIcon { - icon: arrowType + "-down" - color: SystemStatService.rxSpeed >= root.byteThresholdActive ? root.colorRx : root.colorSilent - pointSize: Style.fontSizeL * root.iconSizeModifier - } - } - - // Horizontal layout: RX value right - NText { - visible: root.numbersVisible && root.horizontalNumbers - horizontalAlignment: Text.AlignLeft - text: root.txSpeed - color: root.colorText - pointSize: Style.barFontSize * root.fontSizeModifier - font.family: root.resolvedFontFamily - font.weight: root.resolvedFontWeight - font.italic: root.resolvedFontItalic - } - } + } + + function rebuildLayout() { + rxIconElement.parent = root; + rxIconElement.visible = false; + rxSpeedElement.parent = root; + rxSpeedElement.visible = false; + txIconElement.parent = root; + txIconElement.visible = false; + txSpeedElement.parent = root; + txSpeedElement.visible = false; + + for (let s of spacers) { + s.parent = root; + s.visible = false; } - // ── Interaction ── - - HoverHandler { - id: hoverHandler - onHoveredChanged: { - if (hovered) { - closeTimer.stop(); - hoverTimer.start(); - } else { - hoverTimer.stop(); - closeTimer.start(); - } - } + for (let idx = 0; idx < root.slots.length; idx++) { + const elem = root.getElement(root.slots[idx]); + if (elem) { + elem.parent = content; + elem.visible = true; + } else { + const s = spacers[idx]; + s.parent = content; + s.visible = true; + } } + } - Timer { - id: hoverTimer - interval: 500 - onTriggered: { - if (hoverHandler.hovered && root.pluginApi && !pluginApi.panelOpenScreen) - pluginApi.openPanel(root.screen, root); - } - } + onSlotsChanged: rebuildLayout() + onLayoutChanged: rebuildLayout() + Component.onCompleted: rebuildLayout() - Timer { - id: closeTimer - interval: 250 - onTriggered: { - if (!hoverHandler.hovered && root.pluginApi && pluginApi.panelOpenScreen) - pluginApi.togglePanel(root.screen, root); - } + // ── Interaction ── + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onPressed: mouse => { + if (mouse.button == Qt.LeftButton) + pluginApi.togglePanel(root.screen, root); + + if (mouse.button == Qt.RightButton) + PanelService.showContextMenu(contextMenu, root, screen); } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.RightButton + NPopupContextMenu { + id: contextMenu - onPressed: mouse => { - if (mouse.button == Qt.RightButton) - PanelService.showContextMenu(contextMenu, root, screen); - } + model: [ + { + "label": root.pluginApi?.tr("actions.widget-settings"), + "action": "widget-settings", + "icon": "settings" + }, + ] + + onTriggered: action => { + contextMenu.close(); + PanelService.closeContextMenu(screen); - NPopupContextMenu { - id: contextMenu - - model: [ - { - "label": root.pluginApi?.tr("actions.widget-settings"), - "action": "widget-settings", - "icon": "settings" - }, - ] - - onTriggered: action => { - contextMenu.close(); - PanelService.closeContextMenu(screen); - - if (action === "widget-settings") { - BarService.openPluginSettings(screen, pluginApi.manifest); - } - } + if (action === "widget-settings") { + BarService.openPluginSettings(screen, pluginApi.manifest); } + } } + } } diff --git a/network-indicator/Settings.qml b/network-indicator/Settings.qml index a230bd733..16d2e6fdb 100644 --- a/network-indicator/Settings.qml +++ b/network-indicator/Settings.qml @@ -5,347 +5,397 @@ import QtQuick import QtQuick.Layouts ColumnLayout { - id: root - - readonly property var iconNames: ["arrow", "arrow-bar", "arrow-big", "arrow-narrow", "caret", "chevron", "chevron-compact", "fold"] - - property var pluginApi: null - - property var cfg: pluginApi?.pluginSettings || ({}) - property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({}) - - property string editArrowType: cfg.arrowType ?? defaults.arrowType - property int editByteThresholdActive: cfg.byteThresholdActive ?? defaults.byteThresholdActive - property real editFontSizeModifier: cfg.fontSizeModifier ?? defaults.fontSizeModifier - property bool editHorizontalLayout: cfg.horizontalLayout ?? defaults.horizontalLayout ?? false - property real editIconSizeModifier: cfg.iconSizeModifier ?? defaults.iconSizeModifier - property bool editShowNumbers: cfg.showNumbers ?? defaults.showNumbers - property real editSpacingInbetween: cfg.spacingInbetween ?? defaults.spacingInbetween - property real editContentMargin: cfg.contentMargin ?? defaults.contentMargin ?? Style.marginS - - property bool editUseCustomFont: cfg.useCustomFont ?? defaults.useCustomFont ?? false - property string editCustomFontFamily: cfg.customFontFamily ?? defaults.customFontFamily ?? "" - property bool editCustomFontBold: cfg.customFontBold ?? defaults.customFontBold ?? false - property bool editCustomFontItalic: cfg.customFontItalic ?? defaults.customFontItalic ?? false - - property bool editUseCustomColors: cfg.useCustomColors ?? defaults.useCustomColors ?? false - property color editColorBackground: editUseCustomColors && cfg.colorBackground || Style.capsuleColor - property color editColorFont: editUseCustomColors && cfg.colorFont || Color.mOnSurface - property color editColorRx: editUseCustomColors && cfg.colorRx || Color.mPrimary - property color editColorSilent: editUseCustomColors && cfg.colorSilent || Color.mSurfaceVariant - property color editColorText: editUseCustomColors && cfg.colorText || Qt.alpha(Color.mOnSurfaceVariant, 0.3) - property color editColorTx: editUseCustomColors && cfg.colorTx || Color.mSecondary - - property string barPosition: Settings.data.bar.position || "top" - property string barDensity: Settings.data.bar.density || "compact" - property bool barIsSpacious: barDensity !== "mini" - property bool barIsVertical: barPosition === "left" || barPosition === "right" - - function toIntOr(defaultValue, text) { - const v = parseInt(String(text).trim(), 10); - return isNaN(v) ? defaultValue : v; + 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") } - - function saveSettings() { - if (!pluginApi || !pluginApi.pluginSettings) { - Logger.e("NetworkIndicator", "Cannot save: pluginApi or pluginSettings is null"); - return; - } - - pluginApi.pluginSettings.arrowType = root.editArrowType; - pluginApi.pluginSettings.byteThresholdActive = root.editByteThresholdActive; - pluginApi.pluginSettings.showNumbers = root.editShowNumbers; - pluginApi.pluginSettings.horizontalLayout = root.editHorizontalLayout; - pluginApi.pluginSettings.fontSizeModifier = root.editFontSizeModifier; - pluginApi.pluginSettings.iconSizeModifier = root.editIconSizeModifier; - pluginApi.pluginSettings.spacingInbetween = root.editSpacingInbetween; - pluginApi.pluginSettings.contentMargin = root.editContentMargin; - - pluginApi.pluginSettings.useCustomFont = root.editUseCustomFont; - pluginApi.pluginSettings.customFontFamily = root.editCustomFontFamily; - pluginApi.pluginSettings.customFontBold = root.editCustomFontBold; - pluginApi.pluginSettings.customFontItalic = root.editCustomFontItalic; - - pluginApi.pluginSettings.useCustomColors = root.editUseCustomColors; - if (root.editUseCustomColors) { - pluginApi.pluginSettings.colorSilent = root.editColorSilent.toString(); - pluginApi.pluginSettings.colorTx = root.editColorTx.toString(); - pluginApi.pluginSettings.colorRx = root.editColorRx.toString(); - pluginApi.pluginSettings.colorText = root.editColorText.toString(); - pluginApi.pluginSettings.colorFont = root.editColorFont.toString(); - pluginApi.pluginSettings.colorBackground = root.editColorBackground.toString(); - } - - pluginApi.saveSettings(); - Logger.i("NetworkIndicator", "Settings saved"); + ] + + readonly property var layoutOptions: [ + { + key: "horizontal", + name: pluginApi?.tr("settings.layout.horizontal") + }, + { + key: "vertical", + name: pluginApi?.tr("settings.layout.vertical") } + ] - Layout.rightMargin: Style.marginL - spacing: Style.marginL + readonly property var iconNames: ["arrow", "arrow-bar", "arrow-big", "arrow-narrow", "caret", "chevron", "chevron-compact", "fold"] - // ── Icon ── + // ── Edit state ── - NComboBox { - currentKey: root.editArrowType - description: root.pluginApi?.tr("settings.iconType.desc") - label: root.pluginApi?.tr("settings.iconType.label") - model: root.iconNames.map(n => ({ - key: n, - name: n - })) - - onSelected: key => root.editArrowType = key - } + 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 - NDivider { - Layout.fillWidth: true - } + 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 - // ── General ── + 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 - NToggle { - checked: root.editShowNumbers - defaultValue: defaults.showNumbers ?? true - description: root.pluginApi?.tr("settings.showNumbers.desc") - label: root.pluginApi?.tr("settings.showNumbers.label") - visible: root.barIsSpacious && !root.barIsVertical + 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 - onToggled: c => root.editShowNumbers = c - } + // ── Helpers ── - NToggle { - checked: root.editHorizontalLayout - defaultValue: defaults.horizontalLayout ?? false - description: root.pluginApi?.tr("settings.horizontalLayout.desc") - label: root.pluginApi?.tr("settings.horizontalLayout.label") - visible: root.barIsSpacious && !root.barIsVertical + readonly property bool isVerticalLayout: editLayout === "vertical" - onToggled: c => root.editHorizontalLayout = c + function slotLabel(idx) { + if (root.isVerticalLayout) { + return ["Top Left", "Top Right", "Bottom Left", "Bottom Right"][idx]; } - - NDivider { - Layout.fillWidth: true + 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; } - // ── Layout ── + const s = pluginApi.pluginSettings; - ColumnLayout { - Layout.fillWidth: true - spacing: Style.marginXXS + s.layout = root.editLayout; + s.slots = root.editSlots; + s.iconType = root.editIconType; + s.byteThresholdActive = root.editByteThresholdActive; - NLabel { - description: root.pluginApi?.tr("settings.contentMargin.desc") - label: root.pluginApi?.tr("settings.contentMargin.label") - } + s.fontSizeModifier = root.editFontSizeModifier; + s.iconSizeModifier = root.editIconSizeModifier; - NValueSlider { - Layout.fillWidth: true - from: 0 - stepSize: 1 - text: root.editContentMargin + "px" - to: 20 - value: root.editContentMargin + s.paddingLeft = root.editPaddingLeft; + s.paddingRight = root.editPaddingRight; + s.columnSpacing = root.editColumnSpacing; + s.rowSpacing = root.editRowSpacing; - onMoved: value => root.editContentMargin = value - } - } + s.useCustomFont = root.editUseCustomFont; + s.customFontFamily = root.editCustomFontFamily; + s.customFontBold = root.editCustomFontBold; + s.customFontItalic = root.editCustomFontItalic; - 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) + 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(); } - ColumnLayout { - Layout.fillWidth: true - spacing: Style.marginXXS - - NLabel { - description: root.pluginApi?.tr("settings.spacingInbetween.desc") - label: root.pluginApi?.tr("settings.spacingInbetween.label") - } - - NValueSlider { - Layout.fillWidth: true - from: -5 - stepSize: 1 - text: root.editSpacingInbetween.toFixed(0) - to: 5 - value: root.editSpacingInbetween - - onMoved: value => root.editSpacingInbetween = value - } - } + pluginApi.saveSettings(); + Logger.i("NetworkIndicator", "Settings saved"); + } - ColumnLayout { - Layout.fillWidth: true - spacing: Style.marginXXS - - NLabel { - description: root.pluginApi?.tr("settings.fontSizeModifier.desc") - label: root.pluginApi?.tr("settings.fontSizeModifier.label") - } - - NValueSlider { - Layout.fillWidth: true - from: 0.5 - stepSize: 0.05 - text: root.editFontSizeModifier.toFixed(2) - to: 1.5 - value: root.editFontSizeModifier - - onMoved: value => root.editFontSizeModifier = value - } - } + // ── UI ── - ColumnLayout { - Layout.fillWidth: true - spacing: Style.marginXXS - - NLabel { - description: root.pluginApi?.tr("settings.iconSizeModifier.desc") - label: root.pluginApi?.tr("settings.iconSizeModifier.label") - } - - NValueSlider { - Layout.fillWidth: true - from: 0.5 - stepSize: 0.05 - text: root.editIconSizeModifier.toFixed(2) - to: 1.5 - value: root.editIconSizeModifier - - onMoved: value => root.editIconSizeModifier = value - } - } + 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 + 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") } - // ── Font ── + 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 + } + } - NToggle { - checked: root.editUseCustomFont - defaultValue: defaults.useCustomFont ?? false - description: root.pluginApi?.tr("settings.useCustomFont.desc") - label: root.pluginApi?.tr("settings.useCustomFont.label") + ColumnLayout { + Layout.fillWidth: true + spacing: Style.marginXXS - onToggled: c => root.editUseCustomFont = c + NLabel { + label: pluginApi?.tr("settings.iconSizeModifier.label") + description: pluginApi?.tr("settings.iconSizeModifier.desc") } - ColumnLayout { - visible: root.editUseCustomFont - Layout.fillWidth: true - spacing: Style.marginL - - NSearchableComboBox { - label: root.pluginApi?.tr("settings.customFontFamily.label") - description: root.pluginApi?.tr("settings.customFontFamily.desc") - model: FontService.availableFonts - currentKey: root.editCustomFontFamily || Qt.application.font.family - placeholder: root.pluginApi?.tr("settings.customFontFamily.placeholder") - searchPlaceholder: root.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: root.pluginApi?.tr("settings.customFontBold.desc") - label: root.pluginApi?.tr("settings.customFontBold.label") - - onToggled: c => root.editCustomFontBold = c - } - - NToggle { - checked: root.editCustomFontItalic - defaultValue: defaults.customFontItalic ?? false - description: root.pluginApi?.tr("settings.customFontItalic.desc") - label: root.pluginApi?.tr("settings.customFontItalic.label") - - onToggled: c => root.editCustomFontItalic = c - } + 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 - NDivider { - Layout.fillWidth: true + 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; + } } - // ── Colors ── + 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.editUseCustomColors - defaultValue: defaults.useCustomColors ?? false - description: root.pluginApi?.tr("settings.useCustomColors.desc") - label: root.pluginApi?.tr("settings.useCustomColors.label") + 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 + } + } - onToggled: c => root.editUseCustomColors = c + 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 + } } - ColumnLayout { - visible: root.editUseCustomColors - - RowLayout { - NLabel { - Layout.alignment: Qt.AlignTop - description: root.pluginApi?.tr("settings.colorTx.desc") - label: root.pluginApi?.tr("settings.colorTx.label") - } - - NColorPicker { - selectedColor: root.editColorTx - - onColorSelected: color => root.editColorTx = color - } - } - - RowLayout { - NLabel { - Layout.alignment: Qt.AlignTop - description: root.pluginApi?.tr("settings.colorRx.desc") - label: root.pluginApi?.tr("settings.colorRx.label") - } - - NColorPicker { - selectedColor: root.editColorRx - - onColorSelected: color => root.editColorRx = color - } - } - - RowLayout { - NLabel { - Layout.alignment: Qt.AlignTop - description: root.pluginApi?.tr("settings.colorSilent.desc") - label: root.pluginApi?.tr("settings.colorSilent.label") - } - - NColorPicker { - selectedColor: root.editColorSilent - - onColorSelected: color => root.editColorSilent = color - } - } - - RowLayout { - NLabel { - Layout.alignment: Qt.AlignTop - description: root.pluginApi?.tr("settings.colorText.desc") - label: root.pluginApi?.tr("settings.colorText.label") - } - - NColorPicker { - selectedColor: root.editColorText - - onColorSelected: color => root.editColorText = 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 + } } + } } diff --git a/network-indicator/i18n/en.json b/network-indicator/i18n/en.json index 60a1265af..79ab996ba 100644 --- a/network-indicator/i18n/en.json +++ b/network-indicator/i18n/en.json @@ -3,75 +3,95 @@ "widget-settings": "Widget settings" }, "settings": { - "byteThresholdActive": { - "desc": "Set the activity threshold in bytes per second (B/s).", - "label": "Show Active Threshold" - }, - "colorRx": { - "desc": "Set the download (RX) icon color when above the threshold.", - "label": "RX Active" + "layout": { + "label": "Layout", + "desc": "Arrange cells in a row (horizontal) or a 2×2 grid (vertical).", + "horizontal": "Horizontal", + "vertical": "Vertical" + }, + "slots": { + "label": "Cell Assignment", + "desc": "Choose what each cell displays." + }, + "slot": { + "prefix": "Slot", + "row": "Row", + "col": "Col", + "txIcon": "TX Icon", + "rxIcon": "RX Icon", + "txSpeed": "TX Speed", + "rxSpeed": "RX Speed", + "none": "Empty" }, - "colorSilent": { - "desc": "Set the icon color when traffic is below the threshold.", - "label": "RX/TX Inactive" + "iconType": { + "label": "Icon Type", + "desc": "Choose the icon style used for the TX/RX indicators." }, - "colorText": { - "desc": "Set the text color used for both RX and TX values.", - "label": "Text" + "byteThresholdActive": { + "label": "Activity Threshold", + "desc": "Traffic below this value (B/s) is shown as inactive." }, - "colorTx": { - "desc": "Set the upload (TX) icon color when above the threshold.", - "label": "TX Active" + "fontSizeModifier": { + "label": "Font Size", + "desc": "Scale the text size relative to the default." }, - "contentMargin": { - "desc": "Horizontal padding on both sides of the widget content.", - "label": "Content Margin" + "iconSizeModifier": { + "label": "Icon Size", + "desc": "Scale the icon size relative to the default." }, - "customFontBold": { - "desc": "Render speed values in bold.", - "label": "Bold" + "useCustomFont": { + "label": "Custom Font", + "desc": "Override the default font for speed values." }, "customFontFamily": { - "desc": "Choose a font for the speed values.", "label": "Font", + "desc": "Choose a font for the speed values.", "placeholder": "Select a font", "searchPlaceholder": "Search fonts…" }, + "customFontBold": { + "label": "Bold", + "desc": "Render speed values in bold." + }, "customFontItalic": { - "desc": "Render speed values in italic.", - "label": "Italic" + "label": "Italic", + "desc": "Render speed values in italic." }, - "fontSizeModifier": { - "desc": "Scale the text size relative to the default.", - "label": "Font Size Modifier" + "useCustomColors": { + "label": "Custom Colors", + "desc": "Enable custom colors instead of theme defaults." }, - "horizontalLayout": { - "desc": "Place TX and RX values side by side instead of stacked.", - "label": "Horizontal Layout" + "colorTx": { + "label": "TX Active", + "desc": "Upload icon color when above the threshold." }, - "iconSizeModifier": { - "desc": "Scale the icon size relative to the default.", - "label": "Icon Size Modifier" + "colorRx": { + "label": "RX Active", + "desc": "Download icon color when above the threshold." }, - "iconType": { - "desc": "Choose the icon style used for the TX/RX indicators.", - "label": "Icon Type" + "colorSilent": { + "label": "Inactive", + "desc": "Icon color when traffic is below the threshold." + }, + "colorText": { + "label": "Text", + "desc": "Text color for speed values." }, - "showNumbers": { - "desc": "Display the current RX/TX speeds as numbers.", - "label": "Show Values" + "paddingLeft": { + "label": "Padding Left", + "desc": "Padding of the content on the left." }, - "spacingInbetween": { - "desc": "Adjust the spacing between RX/TX elements.", - "label": "Vertical Spacing" + "paddingRight": { + "label": "Padding Right", + "desc": "Padding of the content on the right." }, - "useCustomColors": { - "desc": "Enable custom colors instead of theme defaults.", - "label": "Custom Colors" + "columnSpacing": { + "label": "Column Spacing", + "desc": "Spacing between columns in grid layout." }, - "useCustomFont": { - "desc": "Override the default font for speed values.", - "label": "Custom Font" + "rowSpacing": { + "label": "Row Spacing", + "desc": "Spacing between rows in grid layout (obsolete in horizontal layout)." } } } diff --git a/network-indicator/manifest.json b/network-indicator/manifest.json index ba44311cb..a5b897983 100644 --- a/network-indicator/manifest.json +++ b/network-indicator/manifest.json @@ -1,17 +1,13 @@ { "id": "network-indicator", "name": "Network Indicator", - "version": "1.1.0", + "version": "1.1.1", "minNoctaliaVersion": "4.7.6", "author": "tonigineer", "license": "MIT", "repository": "https://github.com/noctalia-dev/noctalia-plugins", "description": "A `lively` network traffic indicator.", - "tags": [ - "Bar", - "Network", - "Indicator" - ], + "tags": ["Bar", "Network", "Indicator"], "entryPoints": { "barWidget": "BarWidget.qml", "panel": "Panel.qml", @@ -22,17 +18,20 @@ }, "metadata": { "defaultSettings": { - "arrowType": "caret", + "iconType": "caret", "byteThresholdActive": 5000, "fontSizeModifier": 0.75, "iconSizeModifier": 1.0, - "showNumbers": true, - "spacingInbetween": 0, "useCustomColors": false, "useCustomFont": false, "customFontBold": false, "customFontItalic": false, - "horizontalLayout": false + "columnSpacing": 0, + "rowSpacing": -8, + "paddingLeft": 5, + "paddingRight": 0, + "layout": "vertical", + "slots": ["txSpeed", "txIcon", "rxSpeed", "rxIcon"] } } } From 9ee298b70708c2a47fb7885e144f12bb4dd4ef3a Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 3 May 2026 18:39:48 +0200 Subject: [PATCH 2/6] panel reworked --- network-indicator/BarWidget.qml | 14 +- network-indicator/Panel.qml | 323 ++++++++++++++++++++++++-------- network-indicator/i18n/en.json | 9 +- 3 files changed, 259 insertions(+), 87 deletions(-) diff --git a/network-indicator/BarWidget.qml b/network-indicator/BarWidget.qml index 5ed080e3b..d7fd1e8f0 100644 --- a/network-indicator/BarWidget.qml +++ b/network-indicator/BarWidget.qml @@ -79,7 +79,6 @@ Item { implicitWidth: contentWidth implicitHeight: contentHeight - // Actual widget components NIcon { id: txIconElement icon: root.iconType + "-up" @@ -129,6 +128,8 @@ Item { } } + readonly property var spacers: [spacer0, spacer1, spacer2, spacer3] + Item { id: spacer0 } @@ -142,8 +143,6 @@ Item { id: spacer3 } - readonly property var spacers: [spacer0, spacer1, spacer2, spacer3] - Rectangle { id: visualCapsule x: Style.pixelAlignCenter(parent.width, width) @@ -221,6 +220,11 @@ Item { id: contextMenu model: [ + { + "label": root.pluginApi?.tr("actions.toggle-panel"), + "action": "toggle-panel", + "icon": "activity" + }, { "label": root.pluginApi?.tr("actions.widget-settings"), "action": "widget-settings", @@ -232,7 +236,9 @@ Item { contextMenu.close(); PanelService.closeContextMenu(screen); - if (action === "widget-settings") { + if (action === "toggle-panel") + pluginApi.togglePanel(root.screen, root); + else if (action === "widget-settings") { BarService.openPluginSettings(screen, pluginApi.manifest); } } diff --git a/network-indicator/Panel.qml b/network-indicator/Panel.qml index 1fbe98089..04ca9d328 100644 --- a/network-indicator/Panel.qml +++ b/network-indicator/Panel.qml @@ -1,103 +1,262 @@ +import QtQuick +import QtQuick.Layouts import qs.Commons -import qs.Modules.MainScreen import qs.Services.UI import qs.Services.System import qs.Widgets -import QtQuick -import QtQuick.Layouts Item { - id: root + id: root + + property var pluginApi: null + + readonly property var geometryPlaceholder: panelContainer + readonly property bool allowAttach: true + + property var cfg: pluginApi?.pluginSettings || ({}) + property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({}) + property string iconType: cfg.iconType ?? defaults.iconType ?? "arrow" - readonly property var geometryPlaceholder: panelContent - readonly property bool allowAttach: true + property real contentPreferredWidth: 400 * Style.uiScaleRatio + property real contentPreferredHeight: Math.min(contentColumn.implicitHeight + Style.marginL * 2, 600 * Style.uiScaleRatio) - property var pluginApi: null - property var cfg: pluginApi?.pluginSettings || ({}) - property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({}) - property string arrowType: cfg.arrowType ?? defaults.arrowType + property bool useCustomColors: cfg.useCustomColors ?? defaults.useCustomColors + property color colorTx: root.useCustomColors && cfg.colorTx || Color.mSecondary + property color colorRx: root.useCustomColors && cfg.colorRx || Color.mPrimary - property real contentPreferredWidth: 440 * Style.uiScaleRatio - property real contentPreferredHeight: panelContent.implicitHeight + Style.marginL * 2 + anchors.fill: parent + Component.onCompleted: { + if (pluginApi) + Logger.i("NetworkIndicator", "Panel initialized"); + } + + Rectangle { + id: panelContainer anchors.fill: parent + color: "transparent" + + ColumnLayout { + id: contentColumn + + anchors.fill: parent + anchors.margins: Style.marginL + spacing: Style.marginM + + // ── Header ── + + RowLayout { + Layout.fillWidth: true + spacing: Style.marginM + + NIcon { + icon: "activity" + pointSize: Style.fontSizeXL + color: Color.mPrimary + Layout.alignment: Qt.AlignVCenter + } + + NText { + text: root.pluginApi?.tr("panel.title") + pointSize: Style.fontSizeL + font.weight: Font.Bold + color: Color.mOnSurface + Layout.alignment: Qt.AlignVCenter + } + + Item { + Layout.fillWidth: true + } + + NIconButton { + icon: "settings" + tooltipText: root.pluginApi?.tr("actions.widget-settings") + onClicked: { + const screen = root.pluginApi?.panelOpenScreen; + if (screen) { + root.pluginApi.closePanel(screen); + Qt.callLater(() => BarService.openPluginSettings(screen, root.pluginApi.manifest)); + } + } + Layout.alignment: Qt.AlignVCenter + } - Component.onCompleted: { - if (pluginApi) { - Logger.i("NetworkIndicator", "Panel initialized"); + NIconButton { + icon: "close" + tooltipText: root.pluginApi?.tr("panel.close") + onClicked: { + const s = root.pluginApi?.panelOpenScreen; + if (s) + root.pluginApi.closePanel(s); + } + Layout.alignment: Qt.AlignVCenter } + } + + // ── Download (RX) ── + + NBox { + Layout.fillWidth: true + Layout.preferredHeight: rxGraph.implicitHeight + Style.marginS * 2 + + NetworkGraph { + id: rxGraph + anchors.fill: parent + anchors.margins: Style.marginS + + label: root.pluginApi?.tr("panel.download") + iconName: root.iconType + "-down" + accentColor: root.colorRx + history: SystemStatService.rxSpeedHistory + maxValue: SystemStatService.rxMaxSpeed + currentSpeed: SystemStatService.rxSpeed + } + } + + // ── Upload (TX) ── + + NBox { + Layout.fillWidth: true + Layout.preferredHeight: txGraph.implicitHeight + Style.marginS * 2 + + NetworkGraph { + id: txGraph + anchors.fill: parent + anchors.margins: Style.marginS + + label: root.pluginApi?.tr("panel.upload") ?? "" + iconName: root.iconType + "-up" + accentColor: root.colorTx + history: SystemStatService.txSpeedHistory + maxValue: SystemStatService.txMaxSpeed + currentSpeed: SystemStatService.txSpeed + } + } } + } - ColumnLayout { - id: panelContent + component NetworkGraph: ColumnLayout { + id: graphRoot + + required property string label + required property string iconName + required property color accentColor + required property var history + required property real maxValue + required property real currentSpeed + + function formatSpeed(bytesPerSec) { + return (SystemStatService.formatSpeed(bytesPerSec).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s"); + } + + spacing: Style.marginXS + + RowLayout { + Layout.fillWidth: true + spacing: Style.marginXS + + NIcon { + icon: graphRoot.iconName + pointSize: Style.fontSizeXS + color: graphRoot.accentColor + } + NText { + text: graphRoot.label + pointSize: Style.fontSizeXS + color: graphRoot.accentColor + font.weight: Font.Medium + } + + Item { + Layout.fillWidth: true + } + + NText { + text: graphRoot.formatSpeed(graphRoot.currentSpeed) + pointSize: Style.fontSizeXS + color: graphRoot.accentColor + font.family: Settings.data.ui.fontFixed + } + } + + Item { + Layout.fillWidth: true + implicitHeight: 120 * Style.uiScaleRatio + + Item { + id: graphArea anchors.fill: parent - anchors.margins: Style.marginL - - NBox { - Layout.fillWidth: true - Layout.preferredHeight: 90 * Style.uiScaleRatio - - ColumnLayout { - anchors.fill: parent - anchors.margins: Style.marginS - anchors.bottomMargin: Style.radiusM * 0.5 - spacing: Style.marginXS - - RowLayout { - Layout.fillWidth: true - spacing: Style.marginXS - - NIcon { - icon: arrowType + "-down" - pointSize: Style.fontSizeXS - color: Color.mPrimary - } - - NText { - text: (SystemStatService.formatSpeed(SystemStatService.rxSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s").padStart(8, " ") - pointSize: Style.fontSizeXS - color: Color.mPrimary - font.family: Settings.data.ui.fontFixed - Layout.rightMargin: Style.marginS - } - - NIcon { - icon: arrowType + "-up" - pointSize: Style.fontSizeXS - color: Color.mSecondary - } - - NText { - text: (SystemStatService.formatSpeed(SystemStatService.txSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s").padStart(8, " ") - pointSize: Style.fontSizeXS - color: Color.mSecondary - font.family: Settings.data.ui.fontFixed - } - - Item { - Layout.fillWidth: true - } - } - - NGraph { - Layout.fillWidth: true - Layout.fillHeight: true - values: SystemStatService.rxSpeedHistory - values2: SystemStatService.txSpeedHistory - minValue: 0 - maxValue: SystemStatService.rxMaxSpeed - minValue2: 0 - maxValue2: SystemStatService.txMaxSpeed - color: Color.mPrimary - color2: Color.mSecondary - strokeWidth: Math.max(1, Style.uiScaleRatio) - fill: true - fillOpacity: 0.15 - updateInterval: SystemStatService.networkIntervalMs - animateScale: true - } + + NGraph { + id: graph + anchors.fill: parent + values: graphRoot.history + minValue: 0 + maxValue: graphRoot.maxValue + color: graphRoot.accentColor + strokeWidth: Math.max(1, Style.uiScaleRatio) + fill: true + fillOpacity: 0.15 + updateInterval: SystemStatService.networkIntervalMs + animateScale: true + } + + MouseArea { + id: hover + anchors.fill: parent + hoverEnabled: true + + readonly property int idx: { + const n = graphRoot.history.length; + if (n < 2 || !containsMouse) + return -1; + return Math.max(0, Math.min(n - 1, Math.round(mouseX / width * (n - 1)))); + } + + readonly property real value: idx >= 0 ? (graphRoot.history[idx] ?? -1) : -1 + + Rectangle { + visible: hover.idx >= 0 + x: { + const n = graphRoot.history.length; + if (hover.idx < 0 || n < 2) + return 0; + return (hover.idx / (n - 1)) * parent.width - width / 2; + } + width: 1 + height: parent.height + color: Qt.alpha(Color.mOnSurface, 0.25) + + Rectangle { + readonly property string _label: { + if (hover.value < 0) + return ""; + return graphRoot.formatSpeed(hover.value); + } + + readonly property real posX: -implicitWidth / 2 + x: Math.max(-parent.x, Math.min(graphArea.width - parent.x - implicitWidth, posX)) + y: Style.marginXS + + implicitWidth: bubbleText.implicitWidth + Style.marginS * 2 + implicitHeight: bubbleText.implicitHeight + Style.marginXS * 2 + radius: Style.radiusS + color: Color.mSurfaceVariant + border.color: Qt.alpha(Color.mOnSurface, 0.15) + border.width: 1 + + NText { + id: bubbleText + anchors.centerIn: parent + text: parent._label + pointSize: Style.fontSizeXS + color: Color.mOnSurface + } } + } } + } } + } } diff --git a/network-indicator/i18n/en.json b/network-indicator/i18n/en.json index 79ab996ba..2711eca04 100644 --- a/network-indicator/i18n/en.json +++ b/network-indicator/i18n/en.json @@ -1,6 +1,13 @@ { "actions": { - "widget-settings": "Widget settings" + "widget-settings": "Widget settings", + "toggle-panel": "Toggle Monitor" + }, + "panel": { + "title": "Network Activity", + "close": "Close", + "download": "Download", + "upload": "Upload" }, "settings": { "layout": { From b3f5b86e87e76a5f1c605e703288555ec35e696f Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 3 May 2026 20:55:22 +0200 Subject: [PATCH 3/6] translations added --- network-indicator/Panel.qml | 108 +++++++++++++++++++++++++-- network-indicator/i18n/de.json | 118 ++++++++++++++++++------------ network-indicator/i18n/en.json | 7 +- network-indicator/i18n/es.json | 118 ++++++++++++++++++------------ network-indicator/i18n/fr.json | 118 ++++++++++++++++++------------ network-indicator/i18n/hu.json | 118 ++++++++++++++++++------------ network-indicator/i18n/it.json | 118 ++++++++++++++++++------------ network-indicator/i18n/ja.json | 118 ++++++++++++++++++------------ network-indicator/i18n/ku.json | 118 ++++++++++++++++++------------ network-indicator/i18n/nl.json | 118 ++++++++++++++++++------------ network-indicator/i18n/pl.json | 118 ++++++++++++++++++------------ network-indicator/i18n/pt.json | 118 ++++++++++++++++++------------ network-indicator/i18n/ru.json | 118 ++++++++++++++++++------------ network-indicator/i18n/tr.json | 118 ++++++++++++++++++------------ network-indicator/i18n/uk-UA.json | 118 ++++++++++++++++++------------ network-indicator/i18n/zh-CN.json | 118 ++++++++++++++++++------------ network-indicator/preview.png | Bin 62231 -> 76680 bytes 17 files changed, 1098 insertions(+), 669 deletions(-) diff --git a/network-indicator/Panel.qml b/network-indicator/Panel.qml index 04ca9d328..57d29fea8 100644 --- a/network-indicator/Panel.qml +++ b/network-indicator/Panel.qml @@ -68,6 +68,13 @@ Item { Layout.fillWidth: true } + NText { + text: `Interval ${(SystemStatService.networkIntervalMs / 1000)}s` + pointSize: Style.fontSizeXXS + color: Qt.alpha(Color.mOnSurface, 0.5) + Layout.alignment: Qt.AlignVCenter + } + NIconButton { icon: "settings" tooltipText: root.pluginApi?.tr("actions.widget-settings") @@ -124,7 +131,7 @@ Item { anchors.fill: parent anchors.margins: Style.marginS - label: root.pluginApi?.tr("panel.upload") ?? "" + label: root.pluginApi?.tr("panel.upload") iconName: root.iconType + "-up" accentColor: root.colorTx history: SystemStatService.txSpeedHistory @@ -149,8 +156,35 @@ Item { return (SystemStatService.formatSpeed(bytesPerSec).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s"); } + function timeAgo(idx) { + const n = graphRoot.history.length; + if (n < 2 || idx < 0) + return ""; + + const secsAgo = Math.round((n - 1 - idx) * SystemStatService.networkIntervalMs / 1000); + if (secsAgo < 60) + return secsAgo + "s ago"; + + const mins = Math.floor(secsAgo / 60); + const secs = secsAgo % 60; + return mins + "m " + secs + "s ago"; + } + + readonly property real yTickHigh: graphRoot.maxValue > 0 ? graphRoot.maxValue * 0.66 : 0 + readonly property real yTickLow: graphRoot.maxValue > 0 ? graphRoot.maxValue * 0.33 : 0 + readonly property real yAxisWidth: yAxisSizer.width + Style.marginXL + spacing: Style.marginXS + // Hidden text to measure the widest Y-axis label. + // TODO: find a better way. + NText { + id: yAxisSizer + visible: false + text: graphRoot.formatSpeed(graphRoot.yTickHigh) + pointSize: Style.fontSizeXS * 0.8 + } + RowLayout { Layout.fillWidth: true spacing: Style.marginXS @@ -190,7 +224,11 @@ Item { NGraph { id: graph - anchors.fill: parent + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: graphRoot.yAxisWidth values: graphRoot.history minValue: 0 maxValue: graphRoot.maxValue @@ -202,9 +240,65 @@ Item { animateScale: true } + // ── Y-axis scale ── + + Repeater { + model: [ + { + value: graphRoot.yTickHigh, + fraction: 0.66 + }, + { + value: graphRoot.yTickLow, + fraction: 0.33 + } + ] + + delegate: Item { + required property var modelData + anchors.left: parent.left + anchors.right: parent.right + y: graphArea.height * (1.0 - modelData.fraction) + visible: graphRoot.maxValue > 0 + + Rectangle { + id: horizontalLineYLabel + anchors.left: parent.left + anchors.right: yLabel.left + anchors.rightMargin: Style.marginXS + height: 1 + color: Qt.alpha(Color.mOnSurface, 0.08) + } + + Rectangle { + id: yLabel + anchors.right: parent.right + y: -height / 2 + implicitWidth: yLabelText.implicitWidth + Style.marginXS * 2 + implicitHeight: yLabelText.implicitHeight + 2 + radius: Style.radiusXS + color: Qt.alpha(graphRoot.accentColor, 0.10) + + NText { + id: yLabelText + anchors.centerIn: parent + text: graphRoot.formatSpeed(modelData.value) + pointSize: Style.fontSizeXS * 0.8 + color: Qt.alpha(graphRoot.accentColor, 0.7) + } + } + } + } + + // ── Hover ── + MouseArea { id: hover - anchors.fill: parent + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: graphRoot.yAxisWidth hoverEnabled: true readonly property int idx: { @@ -229,14 +323,16 @@ Item { color: Qt.alpha(Color.mOnSurface, 0.25) Rectangle { + readonly property real posX: -implicitWidth / 2 readonly property string _label: { if (hover.value < 0) return ""; - return graphRoot.formatSpeed(hover.value); + const speed = graphRoot.formatSpeed(hover.value); + const time = graphRoot.timeAgo(hover.idx); + return speed + (time ? " · " + time : ""); } - readonly property real posX: -implicitWidth / 2 - x: Math.max(-parent.x, Math.min(graphArea.width - parent.x - implicitWidth, posX)) + x: Math.max(-parent.x, Math.min(hover.width - parent.x - implicitWidth, posX)) y: Style.marginXS implicitWidth: bubbleText.implicitWidth + Style.marginS * 2 diff --git a/network-indicator/i18n/de.json b/network-indicator/i18n/de.json index 1f4bcda16..10ab4c51f 100644 --- a/network-indicator/i18n/de.json +++ b/network-indicator/i18n/de.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Widget-Einstellungen" + "widget-settings": "Widget-Einstellungen", + "toggle-panel": "Monitor umschalten" + }, + "panel": { + "title": "Netzwerkaktivität", + "close": "Schließen", + "download": "Download", + "upload": "Upload" }, "settings": { - "byteThresholdActive": { - "desc": "Aktivitätsschwellwert in Byte pro Sekunde (B/s) festlegen.", - "label": "Aktivitätsschwellwert anzeigen" - }, - "colorRx": { - "desc": "Symbolfarbe für Download (RX), wenn der Schwellwert überschritten ist.", - "label": "RX aktiv" + "layout": { + "label": "Layout", + "desc": "Zellen in einer Reihe (horizontal) oder in einem 2×2-Raster (vertikal) anordnen.", + "horizontal": "Horizontal", + "vertical": "Vertikal" + }, + "slots": { + "label": "Zellenbelegung", + "desc": "Wähle, was jede Zelle anzeigt. Keine Duplikate möglich. Z.\u00a0B. leere Zellen verwenden, um nur Symbole anzuzeigen." + }, + "slot": { + "txIcon": "TX-Symbol", + "rxIcon": "RX-Symbol", + "txSpeed": "TX-Geschwindigkeit", + "rxSpeed": "RX-Geschwindigkeit", + "none": "Leer" }, - "colorSilent": { - "desc": "Symbolfarbe, wenn der Datenverkehr unter dem Schwellwert liegt.", - "label": "RX/TX inaktiv" + "iconType": { + "desc": "Symbolstil für die TX/RX-Anzeigen auswählen.", + "label": "Symboltyp" }, - "colorText": { - "desc": "Textfarbe für RX- und TX-Werte festlegen.", - "label": "Text" + "byteThresholdActive": { + "desc": "Datenverkehr unter diesem Wert (B/s) wird als inaktiv angezeigt.", + "label": "Aktivitätsschwellwert" }, - "colorTx": { - "desc": "Symbolfarbe für Upload (TX), wenn der Schwellwert überschritten ist.", - "label": "TX aktiv" + "fontSizeModifier": { + "desc": "Schriftgröße relativ zum Standard skalieren.", + "label": "Schriftgröße" }, - "contentMargin": { - "desc": "Horizontaler Abstand auf beiden Seiten des Widget-Inhalts.", - "label": "Inhaltsrand" + "iconSizeModifier": { + "desc": "Symbolgröße relativ zum Standard skalieren.", + "label": "Symbolgröße" }, - "customFontBold": { - "desc": "Geschwindigkeitswerte fett darstellen.", - "label": "Fett" + "useCustomFont": { + "desc": "Standardschriftart für Geschwindigkeitswerte überschreiben.", + "label": "Eigene Schriftart" }, "customFontFamily": { "desc": "Schriftart für die Geschwindigkeitswerte wählen.", @@ -37,41 +53,49 @@ "placeholder": "Schriftart auswählen", "searchPlaceholder": "Schriften suchen…" }, + "customFontBold": { + "desc": "Geschwindigkeitswerte fett darstellen.", + "label": "Fett" + }, "customFontItalic": { "desc": "Geschwindigkeitswerte kursiv darstellen.", "label": "Kursiv" }, - "fontSizeModifier": { - "desc": "Schriftgröße relativ zum Standard skalieren.", - "label": "Schriftgrößen-Faktor" + "useCustomColors": { + "desc": "Eigene Farben statt der Standard-Themefarben verwenden.", + "label": "Eigene Farben" }, - "horizontalLayout": { - "desc": "TX- und RX-Werte nebeneinander statt übereinander anzeigen.", - "label": "Horizontales Layout" + "colorTx": { + "desc": "Symbolfarbe für Upload (TX), wenn der Schwellwert überschritten ist.", + "label": "TX aktiv" }, - "iconSizeModifier": { - "desc": "Symbolgröße relativ zum Standard skalieren.", - "label": "Symbolgrößen-Faktor" + "colorRx": { + "desc": "Symbolfarbe für Download (RX), wenn der Schwellwert überschritten ist.", + "label": "RX aktiv" }, - "iconType": { - "desc": "Symbolstil für die TX/RX-Anzeigen auswählen.", - "label": "Symboltyp" + "colorSilent": { + "desc": "Symbolfarbe, wenn der Datenverkehr unter dem Schwellwert liegt.", + "label": "Inaktiv" + }, + "colorText": { + "desc": "Textfarbe für Geschwindigkeitswerte.", + "label": "Text" }, - "showNumbers": { - "desc": "Aktuelle RX/TX-Geschwindigkeiten als Zahlen anzeigen.", - "label": "Werte anzeigen" + "paddingLeft": { + "label": "Abstand links", + "desc": "Innenabstand des Inhalts auf der linken Seite." }, - "spacingInbetween": { - "desc": "Den Abstand zwischen den RX/TX-Elementen anpassen.", - "label": "Vertikaler Abstand" + "paddingRight": { + "label": "Abstand rechts", + "desc": "Innenabstand des Inhalts auf der rechten Seite." }, - "useCustomColors": { - "desc": "Eigene Farben statt der Standard-Themefarben verwenden.", - "label": "Eigene Farben" + "columnSpacing": { + "label": "Spaltenabstand", + "desc": "Abstand zwischen Spalten im Rasterlayout." }, - "useCustomFont": { - "desc": "Standardschriftart für Geschwindigkeitswerte überschreiben.", - "label": "Eigene Schriftart" + "rowSpacing": { + "label": "Zeilenabstand", + "desc": "Abstand zwischen Zeilen im Rasterlayout (hat keine Wirkung im horizontalen Layout)." } } } diff --git a/network-indicator/i18n/en.json b/network-indicator/i18n/en.json index 2711eca04..b74166ab5 100644 --- a/network-indicator/i18n/en.json +++ b/network-indicator/i18n/en.json @@ -18,12 +18,9 @@ }, "slots": { "label": "Cell Assignment", - "desc": "Choose what each cell displays." + "desc": "Choose what each cell displays. No duplicates possible. E.g., use empty slots to only show icons." }, "slot": { - "prefix": "Slot", - "row": "Row", - "col": "Col", "txIcon": "TX Icon", "rxIcon": "RX Icon", "txSpeed": "TX Speed", @@ -98,7 +95,7 @@ }, "rowSpacing": { "label": "Row Spacing", - "desc": "Spacing between rows in grid layout (obsolete in horizontal layout)." + "desc": "Spacing between rows in grid layout (has no effect in horizontal layout)." } } } diff --git a/network-indicator/i18n/es.json b/network-indicator/i18n/es.json index c379e3b10..125883f64 100644 --- a/network-indicator/i18n/es.json +++ b/network-indicator/i18n/es.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Configuración del widget" + "widget-settings": "Configuración del widget", + "toggle-panel": "Alternar Monitor" + }, + "panel": { + "title": "Actividad de Red", + "close": "Cerrar", + "download": "Descarga", + "upload": "Subida" }, "settings": { - "byteThresholdActive": { - "desc": "Establecer el umbral de actividad en bytes por segundo (B/s).", - "label": "Mostrar umbral activo" + "layout": { + "label": "Diseño", + "desc": "Disponer las celdas en una fila (horizontal) o en una cuadrícula 2×2 (vertical).", + "horizontal": "Horizontal", + "vertical": "Vertical" + }, + "slots": { + "label": "Asignación de celdas", + "desc": "Elige qué muestra cada celda. No se permiten duplicados. P. ej., usa celdas vacías para mostrar solo iconos." + }, + "slot": { + "txIcon": "Icono TX", + "rxIcon": "Icono RX", + "txSpeed": "Velocidad TX", + "rxSpeed": "Velocidad RX", + "none": "Vacío" }, - "colorRx": { - "desc": "Establecer el color del icono de descarga (RX) cuando esté por encima del umbral.", - "label": "RX Activo" - }, - "colorSilent": { - "desc": "Establecer el color del icono cuando el tráfico esté por debajo del umbral.", - "label": "RX/TX Inactivo" + "iconType": { + "desc": "Elige el estilo de icono utilizado para los indicadores TX/RX.", + "label": "Tipo de icono" }, - "colorText": { - "desc": "Establecer el color del texto utilizado tanto para los valores RX como TX.", - "label": "Texto" + "byteThresholdActive": { + "desc": "El tráfico por debajo de este valor (B/s) se muestra como inactivo.", + "label": "Umbral de actividad" }, - "colorTx": { - "desc": "Establecer el color del icono de carga (TX) cuando esté por encima del umbral.", - "label": "TX Activo" + "fontSizeModifier": { + "desc": "Escalar el tamaño del texto en relación con el predeterminado.", + "label": "Tamaño de fuente" }, - "contentMargin": { - "desc": "Relleno horizontal en ambos lados del contenido del widget.", - "label": "Margen del contenido" + "iconSizeModifier": { + "desc": "Escalar el tamaño del icono en relación con el tamaño predeterminado.", + "label": "Tamaño del icono" }, - "customFontBold": { - "desc": "Mostrar los valores de velocidad en negrita.", - "label": "Negrita" + "useCustomFont": { + "desc": "Reemplazar la fuente predeterminada para los valores de velocidad.", + "label": "Fuente personalizada" }, "customFontFamily": { "desc": "Elegir una fuente para los valores de velocidad.", @@ -37,41 +53,49 @@ "placeholder": "Seleccionar fuente", "searchPlaceholder": "Buscar fuentes…" }, + "customFontBold": { + "desc": "Mostrar los valores de velocidad en negrita.", + "label": "Negrita" + }, "customFontItalic": { "desc": "Mostrar los valores de velocidad en cursiva.", "label": "Cursiva" }, - "fontSizeModifier": { - "desc": "Escalar el tamaño del texto en relación con el predeterminado.", - "label": "Modificador de tamaño de fuente" + "useCustomColors": { + "desc": "Activar colores personalizados en lugar de los predeterminados del tema.", + "label": "Colores personalizados" }, - "horizontalLayout": { - "desc": "Colocar los valores TX y RX uno al lado del otro en lugar de apilados.", - "label": "Diseño horizontal" + "colorTx": { + "desc": "Color del icono de subida (TX) cuando esté por encima del umbral.", + "label": "TX Activo" }, - "iconSizeModifier": { - "desc": "Escalar el tamaño del icono en relación con el tamaño predeterminado.", - "label": "Modificador del tamaño del icono" + "colorRx": { + "desc": "Color del icono de descarga (RX) cuando esté por encima del umbral.", + "label": "RX Activo" }, - "iconType": { - "desc": "Elige el estilo de icono utilizado para los indicadores TX/RX.", - "label": "Tipo de icono" + "colorSilent": { + "desc": "Color del icono cuando el tráfico esté por debajo del umbral.", + "label": "Inactivo" }, - "showNumbers": { - "desc": "Mostrar las velocidades actuales de RX/TX como números.", - "label": "Mostrar valores" + "colorText": { + "desc": "Color del texto para los valores de velocidad.", + "label": "Texto" }, - "spacingInbetween": { - "desc": "Ajustar el espaciado entre los elementos RX/TX.", - "label": "Espaciado vertical" + "paddingLeft": { + "label": "Relleno izquierdo", + "desc": "Relleno del contenido a la izquierda." }, - "useCustomColors": { - "desc": "Activar colores personalizados en lugar de los predeterminados del tema.", - "label": "Colores personalizados" + "paddingRight": { + "label": "Relleno derecho", + "desc": "Relleno del contenido a la derecha." }, - "useCustomFont": { - "desc": "Reemplazar la fuente predeterminada para los valores de velocidad.", - "label": "Fuente personalizada" + "columnSpacing": { + "label": "Espaciado de columnas", + "desc": "Espaciado entre columnas en el diseño de cuadrícula." + }, + "rowSpacing": { + "label": "Espaciado de filas", + "desc": "Espaciado entre filas en el diseño de cuadrícula (sin efecto en el diseño horizontal)." } } } diff --git a/network-indicator/i18n/fr.json b/network-indicator/i18n/fr.json index fe9d191c9..df155013c 100644 --- a/network-indicator/i18n/fr.json +++ b/network-indicator/i18n/fr.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Paramètres du widget" + "widget-settings": "Paramètres du widget", + "toggle-panel": "Basculer le moniteur" + }, + "panel": { + "title": "Activité réseau", + "close": "Fermer", + "download": "Téléchargement", + "upload": "Téléversement" }, "settings": { - "byteThresholdActive": { - "desc": "Définir le seuil d'activité en octets par seconde (o/s).", - "label": "Afficher le seuil actif" + "layout": { + "label": "Disposition", + "desc": "Disposer les cellules en ligne (horizontal) ou en grille 2×2 (vertical).", + "horizontal": "Horizontal", + "vertical": "Vertical" + }, + "slots": { + "label": "Affectation des cellules", + "desc": "Choisir ce que chaque cellule affiche. Pas de doublons possibles. Ex. : utiliser des cellules vides pour n'afficher que les icônes." + }, + "slot": { + "txIcon": "Icône TX", + "rxIcon": "Icône RX", + "txSpeed": "Vitesse TX", + "rxSpeed": "Vitesse RX", + "none": "Vide" }, - "colorRx": { - "desc": "Définir la couleur de l'icône de téléchargement (RX) lorsque la valeur est supérieure au seuil.", - "label": "RX Active" - }, - "colorSilent": { - "desc": "Définir la couleur de l'icône lorsque le trafic est inférieur au seuil.", - "label": "RX/TX Inactif" + "iconType": { + "desc": "Choisissez le style d'icône utilisé pour les indicateurs TX/RX.", + "label": "Type d'icône" }, - "colorText": { - "desc": "Définir la couleur du texte utilisée pour les valeurs RX et TX.", - "label": "Texte" + "byteThresholdActive": { + "desc": "Le trafic en dessous de cette valeur (o/s) est affiché comme inactif.", + "label": "Seuil d'activité" }, - "colorTx": { - "desc": "Définir la couleur de l'icône de téléversement (TX) lorsque le seuil est dépassé.", - "label": "TX Active" + "fontSizeModifier": { + "desc": "Mettre à l'échelle la taille du texte par rapport à la taille par défaut.", + "label": "Taille de police" }, - "contentMargin": { - "desc": "Marge horizontale des deux côtés du contenu du widget.", - "label": "Marge du contenu" + "iconSizeModifier": { + "desc": "Ajuster la taille de l'icône par rapport à la taille par défaut.", + "label": "Taille d'icône" }, - "customFontBold": { - "desc": "Afficher les valeurs de vitesse en gras.", - "label": "Gras" + "useCustomFont": { + "desc": "Remplacer la police par défaut pour les valeurs de vitesse.", + "label": "Police personnalisée" }, "customFontFamily": { "desc": "Choisir une police pour les valeurs de vitesse.", @@ -37,41 +53,49 @@ "placeholder": "Sélectionner une police", "searchPlaceholder": "Rechercher des polices…" }, + "customFontBold": { + "desc": "Afficher les valeurs de vitesse en gras.", + "label": "Gras" + }, "customFontItalic": { "desc": "Afficher les valeurs de vitesse en italique.", "label": "Italique" }, - "fontSizeModifier": { - "desc": "Mettre à l'échelle la taille du texte par rapport à la taille par défaut.", - "label": "Modificateur de taille de police" + "useCustomColors": { + "desc": "Activer les couleurs personnalisées au lieu des couleurs par défaut du thème.", + "label": "Couleurs personnalisées" }, - "horizontalLayout": { - "desc": "Afficher les valeurs TX et RX côte à côte au lieu de les empiler.", - "label": "Disposition horizontale" + "colorTx": { + "desc": "Couleur de l'icône de téléversement (TX) lorsque le seuil est dépassé.", + "label": "TX Active" }, - "iconSizeModifier": { - "desc": "Ajuster la taille de l'icône par rapport à la taille par défaut.", - "label": "Modificateur de taille d'icône" + "colorRx": { + "desc": "Couleur de l'icône de téléchargement (RX) lorsque la valeur est supérieure au seuil.", + "label": "RX Active" }, - "iconType": { - "desc": "Choisissez le style d'icône utilisé pour les indicateurs TX/RX.", - "label": "Type d'icône" + "colorSilent": { + "desc": "Couleur de l'icône lorsque le trafic est inférieur au seuil.", + "label": "Inactif" }, - "showNumbers": { - "desc": "Afficher les vitesses RX/TX actuelles sous forme de nombres.", - "label": "Afficher les valeurs" + "colorText": { + "desc": "Couleur du texte pour les valeurs de vitesse.", + "label": "Texte" }, - "spacingInbetween": { - "desc": "Ajuster l'espacement entre les éléments RX/TX.", - "label": "Espacement vertical" + "paddingLeft": { + "label": "Marge intérieure gauche", + "desc": "Marge intérieure du contenu à gauche." }, - "useCustomColors": { - "desc": "Activer les couleurs personnalisées au lieu des couleurs par défaut du thème.", - "label": "Couleurs personnalisées" + "paddingRight": { + "label": "Marge intérieure droite", + "desc": "Marge intérieure du contenu à droite." }, - "useCustomFont": { - "desc": "Remplacer la police par défaut pour les valeurs de vitesse.", - "label": "Police personnalisée" + "columnSpacing": { + "label": "Espacement des colonnes", + "desc": "Espacement entre les colonnes dans la disposition en grille." + }, + "rowSpacing": { + "label": "Espacement des lignes", + "desc": "Espacement entre les lignes dans la disposition en grille (sans effet en disposition horizontale)." } } } diff --git a/network-indicator/i18n/hu.json b/network-indicator/i18n/hu.json index 76f7f283d..a10e23473 100644 --- a/network-indicator/i18n/hu.json +++ b/network-indicator/i18n/hu.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Widget beállítások" + "widget-settings": "Widget beállítások", + "toggle-panel": "Monitor váltása" + }, + "panel": { + "title": "Hálózati aktivitás", + "close": "Bezárás", + "download": "Letöltés", + "upload": "Feltöltés" }, "settings": { - "byteThresholdActive": { - "desc": "Állítsa be az aktivitási küszöbértéket bájt/másodpercben (B/s).", - "label": "Aktív küszöbérték mutatása" + "layout": { + "label": "Elrendezés", + "desc": "Cellák elrendezése sorban (vízszintes) vagy 2×2-es rácsban (függőleges).", + "horizontal": "Vízszintes", + "vertical": "Függőleges" + }, + "slots": { + "label": "Cellák hozzárendelése", + "desc": "Válaszd ki, mit jelenítsen meg az egyes cellák. Duplikátumok nem lehetségesek. Pl. üres cellákkal csak ikonok jeleníthetők meg." + }, + "slot": { + "txIcon": "TX ikon", + "rxIcon": "RX ikon", + "txSpeed": "TX sebesség", + "rxSpeed": "RX sebesség", + "none": "Üres" }, - "colorRx": { - "desc": "Állítsa be a letöltés (RX) ikon színét, ha az meghaladja a küszöbértéket.", - "label": "RX Aktív" - }, - "colorSilent": { - "desc": "Állítsa be az ikon színét, ha a forgalom a küszöbérték alatt van.", - "label": "RX/TX inaktív" + "iconType": { + "desc": "Válaszd ki az TX/RX indikátorokhoz használt ikonkészletet.", + "label": "Ikon típusa" }, - "colorText": { - "desc": "Állítsa be az RX és TX értékekhez használt szövegszínt.", - "label": "Szöveg" + "byteThresholdActive": { + "desc": "Az e küszöbérték alatti forgalom (B/s) inaktívként jelenik meg.", + "label": "Aktivitási küszöbérték" }, - "colorTx": { - "desc": "Állítsa be a feltöltés (TX) ikon színét, ha a küszöbérték felett van.", - "label": "TX Aktív" + "fontSizeModifier": { + "desc": "A szövegméret skálázása az alapértelmezett mérethez képest.", + "label": "Betűméret" }, - "contentMargin": { - "desc": "Vízszetes padding a widget tartalma mindkét oldalán.", - "label": "Tartalom margó" + "iconSizeModifier": { + "desc": "Az ikonméret skálázása az alapértelmezett mérethez képest.", + "label": "Ikonméret" }, - "customFontBold": { - "desc": "Sebességértékek vastag betűvel.", - "label": "Vastag" + "useCustomFont": { + "desc": "Az alapértelmezett betűtípus felülírása a sebességértékekhez.", + "label": "Egyéni betűtípus" }, "customFontFamily": { "desc": "Válasszon betűtípust a sebességértékekhez.", @@ -37,41 +53,49 @@ "placeholder": "Betűtípus kiválasztása", "searchPlaceholder": "Betűtípusok keresése…" }, + "customFontBold": { + "desc": "Sebességértékek vastag betűvel.", + "label": "Vastag" + }, "customFontItalic": { "desc": "Sebességértékek dőlt betűvel.", "label": "Dőlt" }, - "fontSizeModifier": { - "desc": "A szövegméret skálázása az alapértelmezett mérethez képest.", - "label": "Betűméret módosító" + "useCustomColors": { + "desc": "Egyéni színek engedélyezése a téma alapértelmezett színei helyett.", + "label": "Egyéni színek" }, - "horizontalLayout": { - "desc": "TX és RX értékek egymás mellett, nem egymás alatt.", - "label": "Vízszintes elrendezés" + "colorTx": { + "desc": "Feltöltés (TX) ikon színe, ha a küszöbérték felett van.", + "label": "TX Aktív" }, - "iconSizeModifier": { - "desc": "Az ikonméret skálázása az alapértelmezett mérethez képest.", - "label": "Ikonméret módosító" + "colorRx": { + "desc": "Letöltés (RX) ikon színe, ha az meghaladja a küszöbértéket.", + "label": "RX Aktív" }, - "iconType": { - "desc": "Válaszd ki az TX/RX indikátorokhoz használt ikonkészletet.", - "label": "Ikon típusa" + "colorSilent": { + "desc": "Ikon színe, ha a forgalom a küszöbérték alatt van.", + "label": "Inaktív" }, - "showNumbers": { - "desc": "A pillanatnyi RX/TX sebességek megjelenítése számként.", - "label": "Értékek megjelenítése" + "colorText": { + "desc": "Szövegszín a sebességértékekhez.", + "label": "Szöveg" }, - "spacingInbetween": { - "desc": "Állítsa be a RX/TX elemek közötti távolságot.", - "label": "Függőleges térköz" + "paddingLeft": { + "label": "Bal oldali kitöltés", + "desc": "A tartalom kitöltése a bal oldalon." }, - "useCustomColors": { - "desc": "Egyéni színek engedélyezése a téma alapértelmezett színei helyett.", - "label": "Egyéni színek" + "paddingRight": { + "label": "Jobb oldali kitöltés", + "desc": "A tartalom kitöltése a jobb oldalon." }, - "useCustomFont": { - "desc": "Az alapértelmezett betűtípus felülírása a sebességértékekhez.", - "label": "Egyéni betűtípus" + "columnSpacing": { + "label": "Oszlopköz", + "desc": "Oszlopok közötti távolság a rácsos elrendezésben." + }, + "rowSpacing": { + "label": "Sorköz", + "desc": "Sorok közötti távolság a rácsos elrendezésben (nincs hatása vízszintes elrendezésben)." } } } diff --git a/network-indicator/i18n/it.json b/network-indicator/i18n/it.json index 23a4f54fc..6409c5e5e 100644 --- a/network-indicator/i18n/it.json +++ b/network-indicator/i18n/it.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Impostazioni widget" + "widget-settings": "Impostazioni widget", + "toggle-panel": "Mostra/nascondi Monitor" + }, + "panel": { + "title": "Attività di rete", + "close": "Chiudi", + "download": "Download", + "upload": "Upload" }, "settings": { - "byteThresholdActive": { - "desc": "Imposta la soglia di attività in byte al secondo (B/s).", - "label": "Mostra soglia attiva" + "layout": { + "label": "Layout", + "desc": "Disporre le celle in una riga (orizzontale) o in una griglia 2×2 (verticale).", + "horizontal": "Orizzontale", + "vertical": "Verticale" + }, + "slots": { + "label": "Assegnazione celle", + "desc": "Scegli cosa mostra ogni cella. Non sono possibili duplicati. Es.: usa celle vuote per mostrare solo le icone." + }, + "slot": { + "txIcon": "Icona TX", + "rxIcon": "Icona RX", + "txSpeed": "Velocità TX", + "rxSpeed": "Velocità RX", + "none": "Vuoto" }, - "colorRx": { - "desc": "Imposta il colore dell'icona di download (RX) quando sopra la soglia.", - "label": "RX Attivo" - }, - "colorSilent": { - "desc": "Imposta il colore dell'icona quando il traffico è sotto la soglia.", - "label": "RX/TX Inattivo" + "iconType": { + "desc": "Scegli lo stile dell'icona usata per gli indicatori TX/RX.", + "label": "Tipo icona" }, - "colorText": { - "desc": "Imposta il colore del testo utilizzato per i valori RX e TX.", - "label": "Testo" + "byteThresholdActive": { + "desc": "Il traffico sotto questo valore (B/s) viene mostrato come inattivo.", + "label": "Soglia di attività" }, - "colorTx": { - "desc": "Imposta il colore dell'icona di upload (TX) quando sopra la soglia.", - "label": "TX Attivo" + "fontSizeModifier": { + "desc": "Scala la dimensione del testo rispetto al valore predefinito.", + "label": "Dimensione font" }, - "contentMargin": { - "desc": "Padding orizzontale su entrambi i lati del contenuto del widget.", - "label": "Margine contenuto" + "iconSizeModifier": { + "desc": "Scala la dimensione dell'icona rispetto al valore predefinito.", + "label": "Dimensione icona" }, - "customFontBold": { - "desc": "Visualizza i valori di velocità in grassetto.", - "label": "Grassetto" + "useCustomFont": { + "desc": "Sovrascrivi il font predefinito per i valori di velocità.", + "label": "Font personalizzato" }, "customFontFamily": { "desc": "Scegli un font per i valori di velocità.", @@ -37,41 +53,49 @@ "placeholder": "Seleziona un font", "searchPlaceholder": "Cerca font…" }, + "customFontBold": { + "desc": "Visualizza i valori di velocità in grassetto.", + "label": "Grassetto" + }, "customFontItalic": { "desc": "Visualizza i valori di velocità in corsivo.", "label": "Corsivo" }, - "fontSizeModifier": { - "desc": "Scala la dimensione del testo rispetto al valore predefinito.", - "label": "Modificatore dimensione font" + "useCustomColors": { + "desc": "Attiva i colori personalizzati invece dei colori predefiniti del tema.", + "label": "Colori personalizzati" }, - "horizontalLayout": { - "desc": "Posiziona i valori TX e RX fianco a fianco invece che impilati.", - "label": "Layout orizzontale" + "colorTx": { + "desc": "Colore dell'icona di upload (TX) quando sopra la soglia.", + "label": "TX Attivo" }, - "iconSizeModifier": { - "desc": "Scala la dimensione dell'icona rispetto al valore predefinito.", - "label": "Modificatore dimensione icona" + "colorRx": { + "desc": "Colore dell'icona di download (RX) quando sopra la soglia.", + "label": "RX Attivo" }, - "iconType": { - "desc": "Scegli lo stile dell'icona usata per gli indicatori TX/RX.", - "label": "Tipo icona" + "colorSilent": { + "desc": "Colore dell'icona quando il traffico è sotto la soglia.", + "label": "Inattivo" }, - "showNumbers": { - "desc": "Visualizza le velocità RX/TX attuali come numeri.", - "label": "Mostra valori" + "colorText": { + "desc": "Colore del testo per i valori di velocità.", + "label": "Testo" }, - "spacingInbetween": { - "desc": "Regola lo spazio tra gli elementi RX/TX.", - "label": "Spaziatura verticale" + "paddingLeft": { + "label": "Padding sinistro", + "desc": "Padding del contenuto a sinistra." }, - "useCustomColors": { - "desc": "Attiva i colori personalizzati invece dei colori predefiniti del tema.", - "label": "Colori personalizzati" + "paddingRight": { + "label": "Padding destro", + "desc": "Padding del contenuto a destra." }, - "useCustomFont": { - "desc": "Sovrascrivi il font predefinito per i valori di velocità.", - "label": "Font personalizzato" + "columnSpacing": { + "label": "Spaziatura colonne", + "desc": "Spaziatura tra le colonne nel layout a griglia." + }, + "rowSpacing": { + "label": "Spaziatura righe", + "desc": "Spaziatura tra le righe nel layout a griglia (senza effetto nel layout orizzontale)." } } } diff --git a/network-indicator/i18n/ja.json b/network-indicator/i18n/ja.json index c70c454f3..fcbb86b71 100644 --- a/network-indicator/i18n/ja.json +++ b/network-indicator/i18n/ja.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "ウィジェット設定" + "widget-settings": "ウィジェット設定", + "toggle-panel": "モニターの切替" + }, + "panel": { + "title": "ネットワークアクティビティ", + "close": "閉じる", + "download": "ダウンロード", + "upload": "アップロード" }, "settings": { - "byteThresholdActive": { - "desc": "アクティビティの閾値をバイト毎秒 (B/s) で設定します。", - "label": "アクティブ閾値を表示" + "layout": { + "label": "レイアウト", + "desc": "セルを一列(水平)または2×2グリッド(垂直)に配置します。", + "horizontal": "水平", + "vertical": "垂直" + }, + "slots": { + "label": "セルの割り当て", + "desc": "各セルの表示内容を選択します。重複は不可。例:空のセルを使ってアイコンのみ表示。" + }, + "slot": { + "txIcon": "TXアイコン", + "rxIcon": "RXアイコン", + "txSpeed": "TX速度", + "rxSpeed": "RX速度", + "none": "空" }, - "colorRx": { - "desc": "閾値を超えた場合のダウンロード (RX) アイコンの色を設定します。", - "label": "RX アクティブ" - }, - "colorSilent": { - "desc": "トラフィックが閾値を下回った場合に、アイコンの色を設定します。", - "label": "RX/TX 非アクティブ" + "iconType": { + "desc": "TX/RXインジケーターに使用するアイコンのスタイルを選択してください。", + "label": "アイコンの種類" }, - "colorText": { - "desc": "RX と TX の両方の値に使用するテキストの色を設定します。", - "label": "テキスト" + "byteThresholdActive": { + "desc": "この値(B/s)未満のトラフィックは非アクティブとして表示されます。", + "label": "アクティビティ閾値" }, - "colorTx": { - "desc": "閾値を超えた場合のアップロード (TX) アイコンの色を設定します。", - "label": "TX アクティブ" + "fontSizeModifier": { + "desc": "テキストのサイズをデフォルトを基準に調整します。", + "label": "フォントサイズ" }, - "contentMargin": { - "desc": "ウィジェットコンテンツの両サイドの水平パディング。", - "label": "コンテンツマージン" + "iconSizeModifier": { + "desc": "デフォルトに対するアイコンのサイズを調整します。", + "label": "アイコンサイズ" }, - "customFontBold": { - "desc": "速度値を太字で表示。", - "label": "太字" + "useCustomFont": { + "desc": "速度値のデフォルトフォントを上書き。", + "label": "カスタムフォント" }, "customFontFamily": { "desc": "速度値に使用するフォントを選択してください。", @@ -37,41 +53,49 @@ "placeholder": "フォントを選択", "searchPlaceholder": "フォントを検索…" }, + "customFontBold": { + "desc": "速度値を太字で表示。", + "label": "太字" + }, "customFontItalic": { "desc": "速度値を斜体で表示。", "label": "斜体" }, - "fontSizeModifier": { - "desc": "テキストのサイズをデフォルトを基準に調整します。", - "label": "フォントサイズ変更" + "useCustomColors": { + "desc": "テーマのデフォルトの代わりにカスタムカラーを有効にする。", + "label": "カスタムカラー" }, - "horizontalLayout": { - "desc": "TXとRXの値を縦並びではなく横並びで表示。", - "label": "水平レイアウト" + "colorTx": { + "desc": "閾値を超えた場合のアップロード (TX) アイコンの色。", + "label": "TX アクティブ" }, - "iconSizeModifier": { - "desc": "デフォルトに対するアイコンのサイズを調整します。", - "label": "アイコンサイズ変更" + "colorRx": { + "desc": "閾値を超えた場合のダウンロード (RX) アイコンの色。", + "label": "RX アクティブ" }, - "iconType": { - "desc": "TX/RXインジケーターに使用するアイコンのスタイルを選択してください。", - "label": "アイコンの種類" + "colorSilent": { + "desc": "トラフィックが閾値を下回った場合のアイコンの色。", + "label": "非アクティブ" }, - "showNumbers": { - "desc": "現在のRX/TX速度を数値で表示。", - "label": "値を表示" + "colorText": { + "desc": "速度値のテキスト色。", + "label": "テキスト" }, - "spacingInbetween": { - "desc": "RX/TX要素間の間隔を調整してください。", - "label": "垂直間隔" + "paddingLeft": { + "label": "左パディング", + "desc": "コンテンツの左側のパディング。" }, - "useCustomColors": { - "desc": "テーマのデフォルトの代わりにカスタムカラーを有効にする。", - "label": "カスタムカラー" + "paddingRight": { + "label": "右パディング", + "desc": "コンテンツの右側のパディング。" }, - "useCustomFont": { - "desc": "速度値のデフォルトフォントを上書き。", - "label": "カスタムフォント" + "columnSpacing": { + "label": "列間隔", + "desc": "グリッドレイアウトでの列間の間隔。" + }, + "rowSpacing": { + "label": "行間隔", + "desc": "グリッドレイアウトでの行間の間隔(水平レイアウトでは効果なし)。" } } } diff --git a/network-indicator/i18n/ku.json b/network-indicator/i18n/ku.json index 2e8562adc..50b369bc2 100644 --- a/network-indicator/i18n/ku.json +++ b/network-indicator/i18n/ku.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Mîhengên widgetê" + "widget-settings": "Mîhengên widgetê", + "toggle-panel": "Monîtor veke/bigire" + }, + "panel": { + "title": "Çalakiya Torê", + "close": "Bigire", + "download": "Daxistin", + "upload": "Barkirin" }, "settings": { - "byteThresholdActive": { - "desc": "Sînorê çalakiyê bi bayt di duyemîn de (B/s) destnîşan bike.", - "label": "Derheqê Çalakîyê Nîşan Bide" - }, - "colorRx": { - "desc": "Rengê îkona daxistinê (RX) dema ku ji tixûbê derbas dibe, destnîşan bike.", - "label": "RX Çalak" + "layout": { + "label": "Sazmon", + "desc": "Hucreyan di rêzê de (asayî) an di torê 2×2 de (stûnî) bicîh bike.", + "horizontal": "Asayî", + "vertical": "Stûnî" + }, + "slots": { + "label": "Danîna Hucreyan", + "desc": "Hilbijêre ku her hucre çi nîşan bide. Dubare ne mumkin e. Mînak: ji bo tenê îkonan nîşan bidin hucreyan vala bihêle." + }, + "slot": { + "txIcon": "Îkona TX", + "rxIcon": "Îkona RX", + "txSpeed": "Leza TX", + "rxSpeed": "Leza RX", + "none": "Vala" }, - "colorSilent": { - "desc": "Îkon rengê dema trafîk ji binê tixûbê be, saz bike.", - "label": "RX/TX Neçalak" + "iconType": { + "desc": "Şêwaza îkonê ya ku ji bo nîşanderên TX/RX tê bikaranîn hilbijêre.", + "label": "Cureyê Îkonê" }, - "colorText": { - "desc": "Rengê nivîsê yê ku ji bo nirxên RX û TX tê bikaranîn, destnîşan bike.", - "label": "Nivîs" + "byteThresholdActive": { + "desc": "Trafîka li binê vê nirxê (B/s) wekî neçalak tê nîşandan.", + "label": "Sînorê Çalakiyê" }, - "colorTx": { - "desc": "Rengê îkona barkirinê (TX) dema ku ji tixûbê derbas dibe, destnîşan bike.", - "label": "TX Çalak" + "fontSizeModifier": { + "desc": "Mezinahiya nivîsê li gorî ya xwerû mezin bike.", + "label": "Mezinahiya Tîpan" }, - "contentMargin": { - "desc": "Peddinga asayî li her aliyê naveroka widgetê.", - "label": "Berkêşana Naverokê" + "iconSizeModifier": { + "desc": "Mezinahiya îkonê li gorî ya xwerû mezin bike.", + "label": "Mezinahiya Îkonê" }, - "customFontBold": { - "desc": "Nirxên lezê bi qalın ve bike.", - "label": "Qalın" + "useCustomFont": { + "desc": "Fontê xwerû ji bo nirxên lezê binpê bike.", + "label": "Fontê Xweser" }, "customFontFamily": { "desc": "Ji bo nirxên lezê fontek hilbijêre.", @@ -37,41 +53,49 @@ "placeholder": "Fontek hilbijêre", "searchPlaceholder": "Font lêgerîn…" }, + "customFontBold": { + "desc": "Nirxên lezê bi qalın ve bike.", + "label": "Qalın" + }, "customFontItalic": { "desc": "Nirxên lezê bi xwar ve bike.", "label": "Xwar" }, - "fontSizeModifier": { - "desc": "Mezinahiya nivîsê li gorî ya xwerû mezin bike.", - "label": "Guherînera Mezinahiya Tîpan" + "useCustomColors": { + "desc": "Rengên xweser li şûna rengên xwerû yên temayê çalak bike.", + "label": "Rengên Xweser" }, - "horizontalLayout": { - "desc": "Nirxên TX û RX li hev re biparêze, ne bi hev ve.", - "label": "Sazmona_ASAYÎ" + "colorTx": { + "desc": "Rengê îkona barkirinê (TX) dema ku ji tixûbê derbas dibe.", + "label": "TX Çalak" }, - "iconSizeModifier": { - "desc": "Mezinahiya îkonê li gorî ya xwerû mezin bike.", - "label": "Guherînerê Mezinahiya Îkonê" + "colorRx": { + "desc": "Rengê îkona daxistinê (RX) dema ku ji tixûbê derbas dibe.", + "label": "RX Çalak" }, - "iconType": { - "desc": "Şêwaza îkonê ya ku ji bo nîşanderên TX/RX tê bikaranîn hilbijêre.", - "label": "Cureyê Îkonê" + "colorSilent": { + "desc": "Rengê îkonê dema trafîk ji binê tixûbê be.", + "label": "Neçalak" + }, + "colorText": { + "desc": "Rengê nivîsê ji bo nirxên lezê.", + "label": "Nivîs" }, - "showNumbers": { - "desc": "Leza lezahenên RX/TX yên niha wekî hejmaran.", - "label": "Nîşan bide Nirxan" + "paddingLeft": { + "label": "Peddinga çepê", + "desc": "Peddinga naverokê li aliyê çepê." }, - "spacingInbetween": { - "desc": "Cihêtiya navbera elementên RX/TX eyar bike.", - "label": "Valahiya_Rastkirin" + "paddingRight": { + "label": "Peddinga rastê", + "desc": "Peddinga naverokê li aliyê rastê." }, - "useCustomColors": { - "desc": "Çalak bike rengên xwerû li şûna rengên xwerû yên temayê.", - "label": "Rengên Xweser" + "columnSpacing": { + "label": "Valahiya stûnan", + "desc": "Valahiya navbera stûnan di sazmona torê de." }, - "useCustomFont": { - "desc": "Fontê DEFAULT ji bo nirxên lezê binpê kirin.", - "label": "Fontê Xweser" + "rowSpacing": { + "label": "Valahiya rêzan", + "desc": "Valahiya navbera rêzan di sazmona torê de (di sazmona asayî de bêbandor e)." } } } diff --git a/network-indicator/i18n/nl.json b/network-indicator/i18n/nl.json index 560581f7a..423a540ad 100644 --- a/network-indicator/i18n/nl.json +++ b/network-indicator/i18n/nl.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Widget-instellingen" + "widget-settings": "Widget-instellingen", + "toggle-panel": "Monitor in-/uitschakelen" + }, + "panel": { + "title": "Netwerkactiviteit", + "close": "Sluiten", + "download": "Download", + "upload": "Upload" }, "settings": { - "byteThresholdActive": { - "desc": "Stel de activiteitsdrempel in bytes per seconde (B/s) in.", - "label": "Actieve drempel weergeven" + "layout": { + "label": "Lay-out", + "desc": "Cellen in een rij (horizontaal) of in een 2×2-raster (verticaal) rangschikken.", + "horizontal": "Horizontaal", + "vertical": "Verticaal" + }, + "slots": { + "label": "Celtoewijzing", + "desc": "Kies wat elke cel weergeeft. Geen duplicaten mogelijk. Gebruik bijv. lege cellen om alleen pictogrammen te tonen." + }, + "slot": { + "txIcon": "TX-pictogram", + "rxIcon": "RX-pictogram", + "txSpeed": "TX-snelheid", + "rxSpeed": "RX-snelheid", + "none": "Leeg" }, - "colorRx": { - "desc": "Stel de kleur van het download (RX) pictogram in wanneer deze boven de drempelwaarde ligt.", - "label": "RX Actief" - }, - "colorSilent": { - "desc": "Stel de pictogramkleur in wanneer het verkeer onder de drempelwaarde is.", - "label": "RX/TX Inactief" + "iconType": { + "desc": "Kies de pictogramstijl die gebruikt wordt voor de TX/RX-indicatoren.", + "label": "Icoontype" }, - "colorText": { - "desc": "Stel de tekstkleur in die gebruikt wordt voor zowel RX- als TX-waarden.", - "label": "Tekst" + "byteThresholdActive": { + "desc": "Verkeer onder deze waarde (B/s) wordt als inactief weergegeven.", + "label": "Activiteitsdrempel" }, - "colorTx": { - "desc": "Stel de kleur van het upload (TX) icoon in wanneer boven de drempelwaarde.", - "label": "TX Actief" + "fontSizeModifier": { + "desc": "Schaal de tekstgrootte ten opzichte van de standaard.", + "label": "Lettergrootte" }, - "contentMargin": { - "desc": "Horizontale padding aan beide zijden van de widget-inhoud.", - "label": "Inhoudmarge" + "iconSizeModifier": { + "desc": "Schaal de pictogramgrootte ten opzichte van de standaard.", + "label": "Icoongrootte" }, - "customFontBold": { - "desc": "Geef snelheidswaarden vetgedrukt weer.", - "label": "Vet" + "useCustomFont": { + "desc": "Overschrijf het standaard lettertype voor snelheidswaarden.", + "label": "Aangepast lettertype" }, "customFontFamily": { "desc": "Kies een lettertype voor de snelheidswaarden.", @@ -37,41 +53,49 @@ "placeholder": "Selecteer lettertype", "searchPlaceholder": "Lettertypen zoeken…" }, + "customFontBold": { + "desc": "Geef snelheidswaarden vetgedrukt weer.", + "label": "Vet" + }, "customFontItalic": { "desc": "Geef snelheidswaarden scheefgedrukt weer.", "label": "Schuin" }, - "fontSizeModifier": { - "desc": "Schaal de tekstgrootte ten opzichte van de standaard.", - "label": "Lettergrootte aanpassing" + "useCustomColors": { + "desc": "Schakel aangepaste kleuren in in plaats van de standaard themakleuren.", + "label": "Aangepaste kleuren" }, - "horizontalLayout": { - "desc": "Plaats TX en RX waarden naast elkaar in plaats van gestapeld.", - "label": "Horizontale lay-out" + "colorTx": { + "desc": "Kleur van het upload (TX) pictogram wanneer boven de drempelwaarde.", + "label": "TX Actief" }, - "iconSizeModifier": { - "desc": "Schaal de pictogramgrootte ten opzichte van de standaard.", - "label": "Icoongrootte aanpassing" + "colorRx": { + "desc": "Kleur van het download (RX) pictogram wanneer boven de drempelwaarde.", + "label": "RX Actief" }, - "iconType": { - "desc": "Kies de pictogramstijl die gebruikt wordt voor de TX/RX-indicatoren.", - "label": "Icoontype" + "colorSilent": { + "desc": "Pictogramkleur wanneer het verkeer onder de drempelwaarde is.", + "label": "Inactief" }, - "showNumbers": { - "desc": "Toon de huidige RX/TX snelheden als getallen.", - "label": "Waarden weergeven" + "colorText": { + "desc": "Tekstkleur voor snelheidswaarden.", + "label": "Tekst" }, - "spacingInbetween": { - "desc": "Pas de afstand tussen de RX/TX-elementen aan.", - "label": "Verticale afstand" + "paddingLeft": { + "label": "Padding links", + "desc": "Padding van de inhoud aan de linkerkant." }, - "useCustomColors": { - "desc": "Schakel aangepaste kleuren in in plaats van de standaard themakleuren.", - "label": "Aangepaste kleuren" + "paddingRight": { + "label": "Padding rechts", + "desc": "Padding van de inhoud aan de rechterkant." }, - "useCustomFont": { - "desc": "Overschrijf het standaard lettertype voor snelheidswaarden.", - "label": "Aangepast lettertype" + "columnSpacing": { + "label": "Kolomafstand", + "desc": "Afstand tussen kolommen in rasterlay-out." + }, + "rowSpacing": { + "label": "Rijafstand", + "desc": "Afstand tussen rijen in rasterlay-out (heeft geen effect in horizontale lay-out)." } } } diff --git a/network-indicator/i18n/pl.json b/network-indicator/i18n/pl.json index b0b68a865..dcd24acce 100644 --- a/network-indicator/i18n/pl.json +++ b/network-indicator/i18n/pl.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Ustawienia widgetu" + "widget-settings": "Ustawienia widgetu", + "toggle-panel": "Przełącz Monitor" + }, + "panel": { + "title": "Aktywność sieciowa", + "close": "Zamknij", + "download": "Pobieranie", + "upload": "Wysyłanie" }, "settings": { - "byteThresholdActive": { - "desc": "Ustaw próg aktywności w bajtach na sekundę (B/s).", - "label": "Pokaż Aktywny Próg" + "layout": { + "label": "Układ", + "desc": "Rozmieść komórki w rzędzie (poziomo) lub w siatce 2×2 (pionowo).", + "horizontal": "Poziomy", + "vertical": "Pionowy" + }, + "slots": { + "label": "Przypisanie komórek", + "desc": "Wybierz, co wyświetla każda komórka. Duplikaty nie są możliwe. Np. użyj pustych komórek, aby wyświetlać tylko ikony." + }, + "slot": { + "txIcon": "Ikona TX", + "rxIcon": "Ikona RX", + "txSpeed": "Prędkość TX", + "rxSpeed": "Prędkość RX", + "none": "Pusty" }, - "colorRx": { - "desc": "Ustaw kolor ikony pobierania (RX), gdy wartość przekroczy próg.", - "label": "RX Aktywny" - }, - "colorSilent": { - "desc": "Ustaw kolor ikony, gdy ruch jest poniżej progu.", - "label": "RX/TX Nieaktywne" + "iconType": { + "desc": "Wybierz styl ikony używany dla wskaźników TX/RX.", + "label": "Typ Ikony" }, - "colorText": { - "desc": "Ustaw kolor tekstu używany zarówno dla wartości RX, jak i TX.", - "label": "Tekst" + "byteThresholdActive": { + "desc": "Ruch poniżej tej wartości (B/s) jest wyświetlany jako nieaktywny.", + "label": "Próg aktywności" }, - "colorTx": { - "desc": "Ustaw kolor ikony wysyłania (TX), gdy przekroczony zostanie próg.", - "label": "TX Aktywny" + "fontSizeModifier": { + "desc": "Skaluj rozmiar tekstu względem domyślnego.", + "label": "Rozmiar czcionki" }, - "contentMargin": { - "desc": "Poziomy padding po obu stronach treści widgetu.", - "label": "Margines treści" + "iconSizeModifier": { + "desc": "Skaluj rozmiar ikony względem domyślnego.", + "label": "Rozmiar ikony" }, - "customFontBold": { - "desc": "Wyświetlaj wartości prędkości pogrubionym tekstem.", - "label": "Pogrubiony" + "useCustomFont": { + "desc": "Zastąp domyślną czcionkę dla wartości prędkości.", + "label": "Własna czcionka" }, "customFontFamily": { "desc": "Wybierz czcionkę dla wartości prędkości.", @@ -37,41 +53,49 @@ "placeholder": "Wybierz czcionkę", "searchPlaceholder": "Szukaj czcionek…" }, + "customFontBold": { + "desc": "Wyświetlaj wartości prędkości pogrubionym tekstem.", + "label": "Pogrubiony" + }, "customFontItalic": { "desc": "Wyświetlaj wartości prędkości kursywą.", "label": "Kursywa" }, - "fontSizeModifier": { - "desc": "Skaluj rozmiar tekstu względem domyślnego.", - "label": "Modyfikator rozmiaru czcionki" + "useCustomColors": { + "desc": "Włącz własne kolory zamiast domyślnych motywu.", + "label": "Własne kolory" }, - "horizontalLayout": { - "desc": "Umieść wartości TX i RX obok siebie zamiast jedna nad drugą.", - "label": "Układ poziomy" + "colorTx": { + "desc": "Kolor ikony wysyłania (TX), gdy przekroczony jest próg.", + "label": "TX Aktywny" }, - "iconSizeModifier": { - "desc": "Skaluj rozmiar ikony względem domyślnego.", - "label": "Modyfikator rozmiaru ikony" + "colorRx": { + "desc": "Kolor ikony pobierania (RX), gdy wartość przekroczy próg.", + "label": "RX Aktywny" }, - "iconType": { - "desc": "Wybierz styl ikony używany dla wskaźników TX/RX.", - "label": "Typ Ikony" + "colorSilent": { + "desc": "Kolor ikony, gdy ruch jest poniżej progu.", + "label": "Nieaktywne" }, - "showNumbers": { - "desc": "Wyświetlaj aktualne prędkości RX/TX jako liczby.", - "label": "Pokaż wartości" + "colorText": { + "desc": "Kolor tekstu dla wartości prędkości.", + "label": "Tekst" }, - "spacingInbetween": { - "desc": "Dostosuj odstępy między elementami RX/TX.", - "label": "Odstęp pionowy" + "paddingLeft": { + "label": "Padding lewy", + "desc": "Padding treści po lewej stronie." }, - "useCustomColors": { - "desc": "Włącz własne kolory zamiast domyślnych motywu.", - "label": "Własne kolory" + "paddingRight": { + "label": "Padding prawy", + "desc": "Padding treści po prawej stronie." }, - "useCustomFont": { - "desc": "Zastąp domyślną czcionkę dla wartości prędkości.", - "label": "Własna czcionka" + "columnSpacing": { + "label": "Odstęp kolumn", + "desc": "Odstęp między kolumnami w układzie siatki." + }, + "rowSpacing": { + "label": "Odstęp wierszy", + "desc": "Odstęp między wierszami w układzie siatki (bez efektu w układzie poziomym)." } } } diff --git a/network-indicator/i18n/pt.json b/network-indicator/i18n/pt.json index 551abdc50..ceefd199c 100644 --- a/network-indicator/i18n/pt.json +++ b/network-indicator/i18n/pt.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Configurações do widget" + "widget-settings": "Configurações do widget", + "toggle-panel": "Alternar Monitor" + }, + "panel": { + "title": "Atividade de Rede", + "close": "Fechar", + "download": "Download", + "upload": "Upload" }, "settings": { - "byteThresholdActive": { - "desc": "Defina o limite de atividade em bytes por segundo (B/s).", - "label": "Mostrar Limiar Ativo" + "layout": { + "label": "Layout", + "desc": "Organizar células em linha (horizontal) ou em grelha 2×2 (vertical).", + "horizontal": "Horizontal", + "vertical": "Vertical" + }, + "slots": { + "label": "Atribuição de células", + "desc": "Escolha o que cada célula exibe. Não são possíveis duplicados. Ex.: use células vazias para mostrar apenas ícones." + }, + "slot": { + "txIcon": "Ícone TX", + "rxIcon": "Ícone RX", + "txSpeed": "Velocidade TX", + "rxSpeed": "Velocidade RX", + "none": "Vazio" }, - "colorRx": { - "desc": "Defina a cor do ícone de download (RX) quando acima do limite.", - "label": "RX Ativo" - }, - "colorSilent": { - "desc": "Definir a cor do ícone quando o tráfego estiver abaixo do limite.", - "label": "RX/TX Inativo" + "iconType": { + "desc": "Escolha o estilo do ícone usado para os indicadores TX/RX.", + "label": "Tipo de Ícone" }, - "colorText": { - "desc": "Definir a cor do texto usada para os valores de RX e TX.", - "label": "Texto" + "byteThresholdActive": { + "desc": "Tráfego abaixo deste valor (B/s) é mostrado como inativo.", + "label": "Limiar de atividade" }, - "colorTx": { - "desc": "Definir a cor do ícone de upload (TX) quando acima do limite.", - "label": "TX Ativo" + "fontSizeModifier": { + "desc": "Ajustar o tamanho do texto em relação ao padrão.", + "label": "Tamanho da fonte" }, - "contentMargin": { - "desc": "Padding horizontal em ambos os lados do conteúdo do widget.", - "label": "Margem do conteúdo" + "iconSizeModifier": { + "desc": "Dimensionar o tamanho do ícone em relação ao padrão.", + "label": "Tamanho do ícone" }, - "customFontBold": { - "desc": "Renderizar valores de velocidade em negrito.", - "label": "Negrito" + "useCustomFont": { + "desc": "Substituir a fonte padrão para valores de velocidade.", + "label": "Fonte Personalizada" }, "customFontFamily": { "desc": "Escolha uma fonte para os valores de velocidade.", @@ -37,41 +53,49 @@ "placeholder": "Selecionar fonte", "searchPlaceholder": "Pesquisar fontes…" }, + "customFontBold": { + "desc": "Renderizar valores de velocidade em negrito.", + "label": "Negrito" + }, "customFontItalic": { "desc": "Renderizar valores de velocidade em itálico.", "label": "Itálico" }, - "fontSizeModifier": { - "desc": "Ajustar o tamanho do texto em relação ao padrão.", - "label": "Modificador de Tamanho da Fonte" + "useCustomColors": { + "desc": "Ativar cores personalizadas em vez das cores padrão do tema.", + "label": "Cores Personalizadas" }, - "horizontalLayout": { - "desc": "Colocar valores TX e RX lado a lado em vez de empilhados.", - "label": "Layout Horizontal" + "colorTx": { + "desc": "Cor do ícone de upload (TX) quando acima do limite.", + "label": "TX Ativo" }, - "iconSizeModifier": { - "desc": "Dimensionar o tamanho do ícone em relação ao padrão.", - "label": "Modificador de Tamanho do Ícone" + "colorRx": { + "desc": "Cor do ícone de download (RX) quando acima do limite.", + "label": "RX Ativo" }, - "iconType": { - "desc": "Escolha o estilo do ícone usado para os indicadores TX/RX.", - "label": "Tipo de Ícone" + "colorSilent": { + "desc": "Cor do ícone quando o tráfego estiver abaixo do limite.", + "label": "Inativo" }, - "showNumbers": { - "desc": "Exibir as velocidades atuais de RX/TX como números.", - "label": "Mostrar Valores" + "colorText": { + "desc": "Cor do texto para valores de velocidade.", + "label": "Texto" }, - "spacingInbetween": { - "desc": "Ajustar o espaçamento entre os elementos RX/TX.", - "label": "Espaçamento vertical" + "paddingLeft": { + "label": "Padding esquerdo", + "desc": "Padding do conteúdo à esquerda." }, - "useCustomColors": { - "desc": "Ativar cores personalizadas em vez das cores padrão do tema.", - "label": "Cores Personalizadas" + "paddingRight": { + "label": "Padding direito", + "desc": "Padding do conteúdo à direita." }, - "useCustomFont": { - "desc": "Substituir a fonte padrão para valores de velocidade.", - "label": "Fonte Personalizada" + "columnSpacing": { + "label": "Espaçamento de colunas", + "desc": "Espaçamento entre colunas no layout de grelha." + }, + "rowSpacing": { + "label": "Espaçamento de linhas", + "desc": "Espaçamento entre linhas no layout de grelha (sem efeito no layout horizontal)." } } } diff --git a/network-indicator/i18n/ru.json b/network-indicator/i18n/ru.json index 0a2e595cb..5bb865a59 100644 --- a/network-indicator/i18n/ru.json +++ b/network-indicator/i18n/ru.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Настройки виджета" + "widget-settings": "Настройки виджета", + "toggle-panel": "Переключить монитор" + }, + "panel": { + "title": "Сетевая активность", + "close": "Закрыть", + "download": "Загрузка", + "upload": "Отдача" }, "settings": { - "byteThresholdActive": { - "desc": "Установите порог активности в байтах в секунду (Б/с).", - "label": "Показать активный порог" + "layout": { + "label": "Раскладка", + "desc": "Расположить ячейки в ряд (горизонтально) или в сетку 2×2 (вертикально).", + "horizontal": "Горизонтальная", + "vertical": "Вертикальная" + }, + "slots": { + "label": "Назначение ячеек", + "desc": "Выберите, что отображает каждая ячейка. Дублирование невозможно. Напр., используйте пустые ячейки, чтобы показывать только значки." + }, + "slot": { + "txIcon": "Значок TX", + "rxIcon": "Значок RX", + "txSpeed": "Скорость TX", + "rxSpeed": "Скорость RX", + "none": "Пусто" }, - "colorRx": { - "desc": "Установите цвет значка загрузки (RX), когда он выше порогового значения.", - "label": "RX активен" - }, - "colorSilent": { - "desc": "Установите цвет значка, когда трафик ниже порогового значения.", - "label": "RX/TX неактивны" + "iconType": { + "desc": "Выберите стиль значков для индикаторов TX/RX.", + "label": "Тип значка" }, - "colorText": { - "desc": "Установите цвет текста для значений RX и TX.", - "label": "Текст" + "byteThresholdActive": { + "desc": "Трафик ниже этого значения (Б/с) отображается как неактивный.", + "label": "Порог активности" }, - "colorTx": { - "desc": "Установите цвет значка загрузки (TX) при превышении порогового значения.", - "label": "TX активен" + "fontSizeModifier": { + "desc": "Измените размер текста относительно размера по умолчанию.", + "label": "Размер шрифта" }, - "contentMargin": { - "desc": "Горизонтальный отступ по обеим сторонам содержимого виджета.", - "label": "Отступ содержимого" + "iconSizeModifier": { + "desc": "Измените размер значка относительно размера по умолчанию.", + "label": "Размер значка" }, - "customFontBold": { - "desc": "Отображать значения скорости жирным шрифтом.", - "label": "Жирный" + "useCustomFont": { + "desc": "Переопределите шрифт по умолчанию для значений скорости.", + "label": "Пользовательский шрифт" }, "customFontFamily": { "desc": "Выберите шрифт для значений скорости.", @@ -37,41 +53,49 @@ "placeholder": "Выбрать шрифт", "searchPlaceholder": "Поиск шрифтов…" }, + "customFontBold": { + "desc": "Отображать значения скорости жирным шрифтом.", + "label": "Жирный" + }, "customFontItalic": { "desc": "Отображать значения скорости курсивом.", "label": "Курсив" }, - "fontSizeModifier": { - "desc": "Измените размер текста относительно размера по умолчанию.", - "label": "Модификатор размера шрифта" + "useCustomColors": { + "desc": "Включите пользовательские цвета вместо цветов темы по умолчанию.", + "label": "Пользовательские цвета" }, - "horizontalLayout": { - "desc": "Разместите значения TX и RX рядом друг с другом, а не друг под другом.", - "label": "Горизонтальная раскладка" + "colorTx": { + "desc": "Цвет значка отдачи (TX) при превышении порогового значения.", + "label": "TX активен" }, - "iconSizeModifier": { - "desc": "Измените размер значка относительно размера по умолчанию.", - "label": "Модификатор размера значка" + "colorRx": { + "desc": "Цвет значка загрузки (RX), когда он выше порогового значения.", + "label": "RX активен" }, - "iconType": { - "desc": "Выберите стиль значков для индикаторов TX/RX.", - "label": "Тип значка" + "colorSilent": { + "desc": "Цвет значка, когда трафик ниже порогового значения.", + "label": "Неактивен" }, - "showNumbers": { - "desc": "Отображать текущие скорости RX/TX в виде чисел.", - "label": "Показать значения" + "colorText": { + "desc": "Цвет текста для значений скорости.", + "label": "Текст" }, - "spacingInbetween": { - "desc": "Отрегулируйте интервал между элементами RX/TX.", - "label": "Вертикальный интервал" + "paddingLeft": { + "label": "Отступ слева", + "desc": "Отступ содержимого слева." }, - "useCustomColors": { - "desc": "Включите пользовательские цвета вместо цветов темы по умолчанию.", - "label": "Пользовательские цвета" + "paddingRight": { + "label": "Отступ справа", + "desc": "Отступ содержимого справа." }, - "useCustomFont": { - "desc": "Переопределите шрифт по умолчанию для значений скорости.", - "label": "Пользовательский шрифт" + "columnSpacing": { + "label": "Расстояние между столбцами", + "desc": "Расстояние между столбцами в сеточной раскладке." + }, + "rowSpacing": { + "label": "Расстояние между строками", + "desc": "Расстояние между строками в сеточной раскладке (не действует в горизонтальной раскладке)." } } } diff --git a/network-indicator/i18n/tr.json b/network-indicator/i18n/tr.json index cfa3972f7..d5c923a49 100644 --- a/network-indicator/i18n/tr.json +++ b/network-indicator/i18n/tr.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Widget Ayarları" + "widget-settings": "Widget Ayarları", + "toggle-panel": "Monitörü Aç/Kapat" + }, + "panel": { + "title": "Ağ Etkinliği", + "close": "Kapat", + "download": "İndirme", + "upload": "Yükleme" }, "settings": { - "byteThresholdActive": { - "desc": "Etkinlik eşiğini saniye başına bayt (B/s) cinsinden ayarlayın.", - "label": "Aktif Eşiği Göster" + "layout": { + "label": "Düzen", + "desc": "Hücreleri bir satırda (yatay) veya 2×2 ızgarada (dikey) düzenle.", + "horizontal": "Yatay", + "vertical": "Dikey" + }, + "slots": { + "label": "Hücre Ataması", + "desc": "Her hücrenin ne göstereceğini seç. Yinelenenlere izin verilmez. Örn. yalnızca simgeleri göstermek için boş hücreler kullan." + }, + "slot": { + "txIcon": "TX Simgesi", + "rxIcon": "RX Simgesi", + "txSpeed": "TX Hızı", + "rxSpeed": "RX Hızı", + "none": "Boş" }, - "colorRx": { - "desc": "Eşiğin üzerindeyken indirme (RX) simge rengini ayarla.", - "label": "RX Aktif" - }, - "colorSilent": { - "desc": "Trafiğin eşiğin altında olduğu durumlarda simge rengini ayarla.", - "label": "RX/TX Etkin Değil" + "iconType": { + "desc": "TX/RX göstergeleri için kullanılan simge stilini seçin.", + "label": "Simge Türü" }, - "colorText": { - "desc": "RX ve TX değerleri için kullanılan metin rengini ayarla.", - "label": "Metin" + "byteThresholdActive": { + "desc": "Bu değerin altındaki trafik (B/s) etkin değil olarak gösterilir.", + "label": "Etkinlik Eşiği" }, - "colorTx": { - "desc": "Eşik değerinin üzerindeyken yükleme (TX) simge rengini ayarla.", - "label": "TX Aktif" + "fontSizeModifier": { + "desc": "Metin boyutunu varsayılana göre ölçekle.", + "label": "Yazı Boyutu" }, - "contentMargin": { - "desc": "Widget içeriğinin her iki tarafında yatay dolgu.", - "label": "İçerik Kenar Boşluğu" + "iconSizeModifier": { + "desc": "Simge boyutunu varsayılan değere göre ölçekle.", + "label": "Simge Boyutu" }, - "customFontBold": { - "desc": "Hız değerlerini kalın olarak oluştur.", - "label": "Kalın" + "useCustomFont": { + "desc": "Hız değerleri için varsayılan yazı tipini geçersiz kıl.", + "label": "Özel Yazı Tipi" }, "customFontFamily": { "desc": "Hız değerleri için bir yazı tipi seçin.", @@ -37,41 +53,49 @@ "placeholder": "Yazı tipi seçin", "searchPlaceholder": "Yazı tipleri ara…" }, + "customFontBold": { + "desc": "Hız değerlerini kalın olarak oluştur.", + "label": "Kalın" + }, "customFontItalic": { "desc": "Hız değerlerini italik olarak oluştur.", "label": "İtalik" }, - "fontSizeModifier": { - "desc": "Metin boyutunu varsayılana göre ölçekle.", - "label": "Yazı Boyutu Değiştirici" + "useCustomColors": { + "desc": "Tema varsayılanları yerine özel renkleri etkinleştir.", + "label": "Özel Renkler" }, - "horizontalLayout": { - "desc": "TX ve RX değerlerini üst üste yerine yan yana yerleştir.", - "label": "Yatay Düzen" + "colorTx": { + "desc": "Eşiğin üzerindeyken yükleme (TX) simge rengi.", + "label": "TX Aktif" }, - "iconSizeModifier": { - "desc": "Simge boyutunu varsayılan değere göre ölçekle.", - "label": "Simge Boyutu Değiştirici" + "colorRx": { + "desc": "Eşiğin üzerindeyken indirme (RX) simge rengi.", + "label": "RX Aktif" }, - "iconType": { - "desc": "TX/RX göstergeleri için kullanılan simge stilini seçin.", - "label": "Simge Türü" + "colorSilent": { + "desc": "Trafiğin eşiğin altında olduğu durumlarda simge rengi.", + "label": "Etkin Değil" }, - "showNumbers": { - "desc": "Mevcut RX/TX hızlarını sayı olarak görüntüle.", - "label": "Değerleri Göster" + "colorText": { + "desc": "Hız değerleri için metin rengi.", + "label": "Metin" }, - "spacingInbetween": { - "desc": "RX/TX öğeleri arasındaki boşluğu ayarlayın.", - "label": "Dikey Aralık" + "paddingLeft": { + "label": "Sol Dolgu", + "desc": "İçeriğin sol tarafındaki dolgu." }, - "useCustomColors": { - "desc": "Tema varsayılanları yerine özel renkleri etkinleştir.", - "label": "Özel Renkler" + "paddingRight": { + "label": "Sağ Dolgu", + "desc": "İçeriğin sağ tarafındaki dolgu." }, - "useCustomFont": { - "desc": "Hız değerleri için varsayılan yazı tipini geçersiz kıl.", - "label": "Özel Yazı Tipi" + "columnSpacing": { + "label": "Sütun Aralığı", + "desc": "Izgara düzeninde sütunlar arası boşluk." + }, + "rowSpacing": { + "label": "Satır Aralığı", + "desc": "Izgara düzeninde satırlar arası boşluk (yatay düzende etkisizdir)." } } } diff --git a/network-indicator/i18n/uk-UA.json b/network-indicator/i18n/uk-UA.json index b1f74be3c..f1910fcc5 100644 --- a/network-indicator/i18n/uk-UA.json +++ b/network-indicator/i18n/uk-UA.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "Налаштування віджета" + "widget-settings": "Налаштування віджета", + "toggle-panel": "Перемкнути монітор" + }, + "panel": { + "title": "Мережева активність", + "close": "Закрити", + "download": "Завантаження", + "upload": "Вивантаження" }, "settings": { - "byteThresholdActive": { - "desc": "Встановіть поріг активності в байтах на секунду (Б/с).", - "label": "Показати активний поріг" + "layout": { + "label": "Розташування", + "desc": "Розмістити комірки в ряд (горизонтально) або у сітку 2×2 (вертикально).", + "horizontal": "Горизонтальне", + "vertical": "Вертикальне" + }, + "slots": { + "label": "Призначення комірок", + "desc": "Оберіть, що відображає кожна комірка. Дублікати неможливі. Напр., використовуйте порожні комірки, щоб показувати лише іконки." + }, + "slot": { + "txIcon": "Іконка TX", + "rxIcon": "Іконка RX", + "txSpeed": "Швидкість TX", + "rxSpeed": "Швидкість RX", + "none": "Порожньо" }, - "colorRx": { - "desc": "Встановіть колір значка завантаження (RX), коли він перевищує поріг.", - "label": "RX активний" - }, - "colorSilent": { - "desc": "Встановіть колір значка, коли трафік нижче порогового значення.", - "label": "RX/TX неактивні" + "iconType": { + "desc": "Виберіть стиль іконок, що використовуються для індикаторів TX/RX.", + "label": "Тип іконки" }, - "colorText": { - "desc": "Встановіть колір тексту, який використовується для значень RX та TX.", - "label": "Текст" + "byteThresholdActive": { + "desc": "Трафік нижче цього значення (Б/с) відображається як неактивний.", + "label": "Поріг активності" }, - "colorTx": { - "desc": "Встановіть колір піктограми завантаження (TX), коли значення перевищує поріг.", - "label": "TX активний" + "fontSizeModifier": { + "desc": "Змінити розмір тексту відносно стандартного.", + "label": "Розмір шрифту" }, - "contentMargin": { - "desc": "Горизонтальний відступ з обох боків вмісту віджета.", - "label": "Відступ вмісту" + "iconSizeModifier": { + "desc": "Змінюйте розмір значка відносно стандартного.", + "label": "Розмір значка" }, - "customFontBold": { - "desc": "Відображати значення швидкості жирним шрифтом.", - "label": "Жирний" + "useCustomFont": { + "desc": "Перевизначити шрифт за замовчуванням для значень швидкості.", + "label": "Користувацький шрифт" }, "customFontFamily": { "desc": "Оберіть шрифт для значень швидкості.", @@ -37,41 +53,49 @@ "placeholder": "Обрати шрифт", "searchPlaceholder": "Пошук шрифтів…" }, + "customFontBold": { + "desc": "Відображати значення швидкості жирним шрифтом.", + "label": "Жирний" + }, "customFontItalic": { "desc": "Відображати значення швидкості курсивом.", "label": "Курсив" }, - "fontSizeModifier": { - "desc": "Змінити розмір тексту відносно стандартного.", - "label": "Модифікатор розміру шрифту" + "useCustomColors": { + "desc": "Увімкнути власні кольори замість кольорів теми за замовчуванням.", + "label": "Користувацькі кольори" }, - "horizontalLayout": { - "desc": "Розмістити значення TX та RX поруч, а не один під одним.", - "label": "Горизонтальне розташування" + "colorTx": { + "desc": "Колір піктограми вивантаження (TX), коли значення перевищує поріг.", + "label": "TX активний" }, - "iconSizeModifier": { - "desc": "Змінюйте розмір значка відносно стандартного.", - "label": "Модифікатор розміру значка" + "colorRx": { + "desc": "Колір значка завантаження (RX), коли він перевищує поріг.", + "label": "RX активний" }, - "iconType": { - "desc": "Виберіть стиль іконок, що використовуються для індикаторів TX/RX.", - "label": "Тип іконки" + "colorSilent": { + "desc": "Колір значка, коли трафік нижче порогового значення.", + "label": "Неактивний" }, - "showNumbers": { - "desc": "Показувати поточні швидкості RX/TX у вигляді чисел.", - "label": "Показати значення" + "colorText": { + "desc": "Колір тексту для значень швидкості.", + "label": "Текст" }, - "spacingInbetween": { - "desc": "Відрегулюйте інтервал між елементами RX/TX.", - "label": "Вертикальний інтервал" + "paddingLeft": { + "label": "Відступ зліва", + "desc": "Відступ вмісту зліва." }, - "useCustomColors": { - "desc": "Увімкнути власні кольори замість кольорів теми за замовчуванням.", - "label": "Користувацькі кольори" + "paddingRight": { + "label": "Відступ справа", + "desc": "Відступ вмісту справа." }, - "useCustomFont": { - "desc": "Перевизначити шрифт за замовчуванням для значень швидкості.", - "label": "Користувацький шрифт" + "columnSpacing": { + "label": "Відстань між стовпцями", + "desc": "Відстань між стовпцями у сітковому розташуванні." + }, + "rowSpacing": { + "label": "Відстань між рядками", + "desc": "Відстань між рядками у сітковому розташуванні (не діє у горизонтальному розташуванні)." } } } diff --git a/network-indicator/i18n/zh-CN.json b/network-indicator/i18n/zh-CN.json index 9e9e6e14c..6ba9f2add 100644 --- a/network-indicator/i18n/zh-CN.json +++ b/network-indicator/i18n/zh-CN.json @@ -1,35 +1,51 @@ { "actions": { - "widget-settings": "小组件设置" + "widget-settings": "小组件设置", + "toggle-panel": "切换监控面板" + }, + "panel": { + "title": "网络活动", + "close": "关闭", + "download": "下载", + "upload": "上传" }, "settings": { - "byteThresholdActive": { - "desc": "设置活动阈值,单位为字节/秒 (B/s)。", - "label": "显示活动阈值" + "layout": { + "label": "布局", + "desc": "将单元格排列为一行(水平)或 2×2 网格(垂直)。", + "horizontal": "水平", + "vertical": "垂直" + }, + "slots": { + "label": "单元格分配", + "desc": "选择每个单元格显示的内容。不可重复。例如,使用空单元格仅显示图标。" + }, + "slot": { + "txIcon": "TX 图标", + "rxIcon": "RX 图标", + "txSpeed": "TX 速度", + "rxSpeed": "RX 速度", + "none": "空" }, - "colorRx": { - "desc": "设置高于阈值时的下载(RX)图标颜色。", - "label": "RX 活跃" - }, - "colorSilent": { - "desc": "当流量低于阈值时,设置图标颜色。", - "label": "RX/TX 非活跃" + "iconType": { + "desc": "选择用于 TX/RX 指示器的图标样式。", + "label": "图标类型" }, - "colorText": { - "desc": "设置用于RX和TX值的文本颜色。", - "label": "文本" + "byteThresholdActive": { + "desc": "低于此值(B/s)的流量显示为非活跃。", + "label": "活动阈值" }, - "colorTx": { - "desc": "设置上传(TX)图标颜色,当高于阈值时。", - "label": "TX 活跃" + "fontSizeModifier": { + "desc": "相对于默认值缩放文本大小。", + "label": "字体大小" }, - "contentMargin": { - "desc": "小组件内容两侧的水平内边距。", - "label": "内容边距" + "iconSizeModifier": { + "desc": "相对于默认值缩放图标大小。", + "label": "图标大小" }, - "customFontBold": { - "desc": "以粗体显示速度值。", - "label": "粗体" + "useCustomFont": { + "desc": "覆盖速度值的默认字体。", + "label": "自定义字体" }, "customFontFamily": { "desc": "为速度值选择字体。", @@ -37,41 +53,49 @@ "placeholder": "选择字体", "searchPlaceholder": "搜索字体…" }, + "customFontBold": { + "desc": "以粗体显示速度值。", + "label": "粗体" + }, "customFontItalic": { "desc": "以斜体显示速度值。", "label": "斜体" }, - "fontSizeModifier": { - "desc": "相对于默认值缩放文本大小。", - "label": "字体大小调整" + "useCustomColors": { + "desc": "启用自定义颜色,而非主题默认颜色。", + "label": "自定义颜色" }, - "horizontalLayout": { - "desc": "将TX和RX值并排显示,而不是堆叠。", - "label": "水平布局" + "colorTx": { + "desc": "超过阈值时的上传(TX)图标颜色。", + "label": "TX 活跃" }, - "iconSizeModifier": { - "desc": "相对于默认值缩放图标大小。", - "label": "图标大小调整" + "colorRx": { + "desc": "超过阈值时的下载(RX)图标颜色。", + "label": "RX 活跃" }, - "iconType": { - "desc": "选择用于 TX/RX 指示器的图标样式。", - "label": "图标类型" + "colorSilent": { + "desc": "当流量低于阈值时的图标颜色。", + "label": "非活跃" }, - "showNumbers": { - "desc": "以数字形式显示当前的 RX/TX 速度。", - "label": "显示数值" + "colorText": { + "desc": "速度值的文本颜色。", + "label": "文本" }, - "spacingInbetween": { - "desc": "调整RX/TX元素之间的间距。", - "label": "垂直间距" + "paddingLeft": { + "label": "左内边距", + "desc": "内容左侧的内边距。" }, - "useCustomColors": { - "desc": "启用自定义颜色,而非主题默认颜色。", - "label": "自定义颜色" + "paddingRight": { + "label": "右内边距", + "desc": "内容右侧的内边距。" }, - "useCustomFont": { - "desc": "覆盖速度值的默认字体。", - "label": "自定义字体" + "columnSpacing": { + "label": "列间距", + "desc": "网格布局中列之间的间距。" + }, + "rowSpacing": { + "label": "行间距", + "desc": "网格布局中行之间的间距(在水平布局中无效)。" } } } diff --git a/network-indicator/preview.png b/network-indicator/preview.png index 3244cdc68c478a65f10f2d4b4c1608227bd9452b..de38727ffc7e2c17dbd013fb6f55d99ff115f2a9 100644 GIT binary patch literal 76680 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

FF4NKiYyi{g_3{E~ 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 Q*6uO8ZFP%i@*wVi0iYJo82|tP literal 62231 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 Date: Sun, 3 May 2026 21:11:07 +0200 Subject: [PATCH 4/6] readme updated --- network-indicator/README.md | 41 +++++++++++++++---------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/network-indicator/README.md b/network-indicator/README.md index 4ca37a9c9..775a9ce99 100644 --- a/network-indicator/README.md +++ b/network-indicator/README.md @@ -1,18 +1,14 @@ # NetworkIndicator Plugin for Noctalia -A compact Noctalia bar widget that displays current network upload (TX) and download (RX) activity, with optional live throughput values and a hover-activated graph panel. +A Noctalia bar widget that displays current network upload (TX) and download (RX) activity. Includes optional live throughput values and a hover-activated graph panel. ## Features -- **TX/RX Activity Indicators**: Separate icons for upload (TX) and download (RX). -- **Active/Idle Coloring**: Icons switch between "active" and "silent" colors based on a configurable traffic threshold. -- **Optional Throughput Values**: Displays formatted TX/RX speeds as text (shown only when the bar is spacious and horizontal). -- **Vertical and Horizontal Layouts**: Stack TX/RX values on the left of the arrows, or place them side by side with arrows centered in between. -- **Unit Formatting**: Automatically switches between KB/s and MB/s, or can be configured to always display MB/s. +- **TX/RX Activity Indicators**: Icons for TX and RX with active/idle coloring based on a configurable traffic threshold. +- **Vertical and Horizontal Layouts**: Configurable cell grid: arrange up to four cells (TX icon, RX icon, TX speed, RX speed) in a horizontal row or a 2×2 grid. Cells can be left empty to show only icons or only values. +- **Network Graph Panel**: Click on the widget to open a live graph panel showing recent RX and TX history. - **Custom Font**: Override the default font for speed values, with optional bold and italic styles. -- **Network Graph Panel**: Hover over the widget to open a live graph showing RX and TX history from the system monitor. -- **Theme Support**: Uses Noctalia theme colors by default, with optional custom colors. -- **Configurable Settings**: Provides a comprehensive set of user-adjustable options. +- **Theme Support**: Uses theme colors by default; all colors can be overridden individually. ## Installation @@ -20,25 +16,21 @@ This plugin is part of the `noctalia-plugins` repository. ## Configuration -Access the plugin settings in Noctalia to configure the following options: - -- **Icon Type**: Select the icon style used for TX/RX: `arrow`, `arrow-bar`, `arrow-big`, `arrow-narrow`, `caret`, `chevron`, `chevron-compact`, `fold`. -- **Show Values**: Display formatted TX/RX speeds as numbers. Automatically hidden on vertical bars and when using "mini" density. -- **Force Megabytes**: Always display values in MB/s instead of switching to KB/s at low traffic levels. -- **Horizontal Layout**: Place TX and RX values side by side instead of stacked. -- **Minimum Width**: Set a minimum width for the widget to prevent resizing when values change. -- **Content Margin**: Horizontal padding on both sides of the widget content. -- **Show Active Threshold**: Set the traffic threshold in bytes per second (B/s) above which TX/RX is considered "active". -- **Vertical Spacing**: Adjust the spacing between the TX and RX elements. -- **Font Size Modifier**: Scale the text size. -- **Icon Size Modifier**: Scale the icon size. -- **Custom Font**: Override the default font with any installed font, with bold and italic options. -- **Custom Colors**: When enabled, configure TX Active, RX Active, RX/TX Inactive, Text, Font, and Background colors. +Access settings through the widget's context menu. + +**Layout**: Choose between horizontal (single row) and vertical (2×2 grid) cell arrangement. +**Cell Assignment**: Assign what each cell displays. Duplicates are not allowed. Use empty cells to reduce the widget to just icons or just speed values. +**Icon Type**: Select the icon style for the TX/RX indicators (`arrow`, `arrow-bar`, `arrow-big`, `arrow-narrow`, `caret`, `chevron`, `chevron-compact`, `fold`). +**Activity Threshold**: Traffic below this value (B/s) is treated as inactive, and icons switch to the idle color. +**Font & Icon Size**: Scale text and icon sizes relative to the defaults. +**Custom Font**: Override the default font for speed values, with optional bold and italic. +**Custom Colors**: Override theme colors for TX active, RX active, inactive, and text individually. +**Spacing & Padding**: Adjust left/right padding, column spacing, and row spacing. ## Usage - Add the widget to your Noctalia bar. -- Hover over the widget to open the network graph panel. +- Left-click the widget to open the network graph panel. - Right-click the widget to access settings. - Configure the plugin settings as required. @@ -50,4 +42,3 @@ Access the plugin settings in Noctalia to configure the following options: - The widget reads `SystemStatService.txSpeed` and `SystemStatService.rxSpeed`; the polling interval is determined by that service. - The graph panel uses `SystemStatService.rxSpeedHistory` and `SystemStatService.txSpeedHistory` with `NGraph` from the Noctalia Shell. -- The panel opens on hover with a short delay and closes automatically when the cursor leaves the widget. From 9e837539f7cc1b8c86f65da12e25dfe502696d3b Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 3 May 2026 21:18:17 +0200 Subject: [PATCH 5/6] bumped up major version --- network-indicator/README.md | 1 + network-indicator/manifest.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/network-indicator/README.md b/network-indicator/README.md index 775a9ce99..72009a62e 100644 --- a/network-indicator/README.md +++ b/network-indicator/README.md @@ -42,3 +42,4 @@ Access settings through the widget's context menu. - The widget reads `SystemStatService.txSpeed` and `SystemStatService.rxSpeed`; the polling interval is determined by that service. - The graph panel uses `SystemStatService.rxSpeedHistory` and `SystemStatService.txSpeedHistory` with `NGraph` from the Noctalia Shell. +- Unfortunately, the update interval `SystemStatService.networkIntervalMs` is currently hardcoded to `3000` by Noctalia. diff --git a/network-indicator/manifest.json b/network-indicator/manifest.json index a5b897983..3cee05d13 100644 --- a/network-indicator/manifest.json +++ b/network-indicator/manifest.json @@ -1,7 +1,7 @@ { "id": "network-indicator", "name": "Network Indicator", - "version": "1.1.1", + "version": "2.0.0", "minNoctaliaVersion": "4.7.6", "author": "tonigineer", "license": "MIT", From 82a80fbca8ed5be9caf6d0bee725a6aa1bdc13ed Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 3 May 2026 22:05:34 +0200 Subject: [PATCH 6/6] pr check remark --- network-indicator/Panel.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network-indicator/Panel.qml b/network-indicator/Panel.qml index 57d29fea8..dee989fe6 100644 --- a/network-indicator/Panel.qml +++ b/network-indicator/Panel.qml @@ -318,7 +318,7 @@ Item { return 0; return (hover.idx / (n - 1)) * parent.width - width / 2; } - width: 1 + width: Style.borderS height: parent.height color: Qt.alpha(Color.mOnSurface, 0.25) @@ -340,7 +340,7 @@ Item { radius: Style.radiusS color: Color.mSurfaceVariant border.color: Qt.alpha(Color.mOnSurface, 0.15) - border.width: 1 + border.width: Style.borderS NText { id: bubbleText