From 662154f390b13759619140cbf7e8f3aad19a00f7 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Thu, 15 Jan 2026 14:30:43 +0100 Subject: [PATCH] NTagFilter: created TemplateSubTab: use NTagFilter AvailableSubTab: use NTagFilter --- .../Tabs/ColorScheme/TemplatesSubTab.qml | 36 ++------------ .../Settings/Tabs/Plugins/AvailableSubTab.qml | 45 +++++------------ Widgets/NTagFilter.qml | 48 +++++++++++++++++++ 3 files changed, 65 insertions(+), 64 deletions(-) create mode 100644 Widgets/NTagFilter.qml diff --git a/Modules/Panels/Settings/Tabs/ColorScheme/TemplatesSubTab.qml b/Modules/Panels/Settings/Tabs/ColorScheme/TemplatesSubTab.qml index 21895c99a..34eb6ecbe 100644 --- a/Modules/Panels/Settings/Tabs/ColorScheme/TemplatesSubTab.qml +++ b/Modules/Panels/Settings/Tabs/ColorScheme/TemplatesSubTab.qml @@ -173,41 +173,13 @@ ColumnLayout { } // Category filter chips - NCollapsible { - Layout.fillWidth: true + NTagFilter { + tags: root.availableCategories + selectedTag: root.selectedCategory + onSelectedTagChanged: root.selectedCategory = selectedTag label: I18n.tr("panels.color-scheme.templates-filter-label") description: I18n.tr("panels.color-scheme.templates-filter-description") expanded: true - contentSpacing: Style.marginXS - - Flow { - Layout.fillWidth: true - spacing: Style.marginXS - flow: Flow.LeftToRight - - Repeater { - model: [""].concat(root.availableCategories) - - delegate: NButton { - text: { - if (modelData === "") - return I18n.tr("launcher.categories.all"); - // Special case for UI to keep it uppercase - if (modelData === "system") - return "System"; - // Capitalize first letter for others - return modelData.charAt(0).toUpperCase() + modelData.slice(1); - } - backgroundColor: root.selectedCategory === modelData ? Color.mPrimary : Color.mSurfaceVariant - textColor: root.selectedCategory === modelData ? Color.mOnPrimary : Color.mOnSurfaceVariant - onClicked: root.selectedCategory = modelData - fontSize: Style.fontSizeS - iconSize: Style.fontSizeS - fontWeight: Style.fontWeightSemiBold - buttonRadius: Style.iRadiusM - } - } - } } // Search/filter input row diff --git a/Modules/Panels/Settings/Tabs/Plugins/AvailableSubTab.qml b/Modules/Panels/Settings/Tabs/Plugins/AvailableSubTab.qml index 00b7817ee..6f1ffaddc 100644 --- a/Modules/Panels/Settings/Tabs/Plugins/AvailableSubTab.qml +++ b/Modules/Panels/Settings/Tabs/Plugins/AvailableSubTab.qml @@ -17,7 +17,7 @@ ColumnLayout { property int availablePluginsRefreshCounter: 0 // Pseudo tags for filtering by download status - readonly property var pseudoTags: ["", "downloaded", "notDownloaded"] + readonly property var pseudoTags: ["downloaded", "notDownloaded"] readonly property var availableTags: { // Reference counter to force re-evaluation @@ -44,41 +44,22 @@ ColumnLayout { } // Tag filter chips in collapsible - NCollapsible { - Layout.fillWidth: true + NTagFilter { + tags: root.pseudoTags.concat(root.availableTags) + selectedTag: root.selectedTag + onSelectedTagChanged: root.selectedTag = selectedTag label: I18n.tr("panels.plugins.filter-tags-label") description: I18n.tr("panels.plugins.filter-tags-description") expanded: true - contentSpacing: Style.marginXS - Flow { - Layout.fillWidth: true - spacing: Style.marginXS - flow: Flow.LeftToRight - - Repeater { - id: tagRepeater - model: root.pseudoTags.concat(root.availableTags) - - delegate: NButton { - text: { - if (modelData === "") - return I18n.tr("launcher.categories.all"); - if (modelData === "downloaded") - return I18n.tr("panels.plugins.filter-downloaded"); - if (modelData === "notDownloaded") - return I18n.tr("panels.plugins.filter-not-downloaded"); - return modelData; - } - backgroundColor: root.selectedTag === modelData ? Color.mPrimary : Color.mSurfaceVariant - textColor: root.selectedTag === modelData ? Color.mOnPrimary : Color.mOnSurfaceVariant - onClicked: root.selectedTag = modelData - fontSize: Style.fontSizeS - iconSize: Style.fontSizeS - fontWeight: Style.fontWeightSemiBold - buttonRadius: Style.iRadiusM - } - } + formatTag: function (tag) { + if (tag === "") + return I18n.tr("launcher.categories.all"); + if (tag === "downloaded") + return I18n.tr("panels.plugins.filter-downloaded"); + if (tag === "notDownloaded") + return I18n.tr("panels.plugins.filter-not-downloaded"); + return tag; } } diff --git a/Widgets/NTagFilter.qml b/Widgets/NTagFilter.qml new file mode 100644 index 000000000..d2515ac68 --- /dev/null +++ b/Widgets/NTagFilter.qml @@ -0,0 +1,48 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import qs.Commons +import qs.Widgets + +NCollapsible { + id: root + + // Public API + property var tags: [] // Array of tag strings + property string selectedTag: "" + property alias label: root.label + property alias description: root.description + property alias expanded: root.expanded + + // Formatting function for tag display (optional override) + property var formatTag: function (tag) { + if (tag === "") + return I18n.tr("launcher.categories.all"); + // Default: capitalize first letter + return tag.charAt(0).toUpperCase() + tag.slice(1); + } + + Layout.fillWidth: true + contentSpacing: Style.marginXS + + Flow { + Layout.fillWidth: true + spacing: Style.marginXS + flow: Flow.LeftToRight + + Repeater { + model: [""].concat(root.tags) + + delegate: NButton { + text: root.formatTag(modelData) + backgroundColor: root.selectedTag === modelData ? Color.mPrimary : Color.mSurfaceVariant + textColor: root.selectedTag === modelData ? Color.mOnPrimary : Color.mOnSurfaceVariant + onClicked: root.selectedTag = modelData + fontSize: Style.fontSizeS + iconSize: Style.fontSizeS + fontWeight: Style.fontWeightSemiBold + buttonRadius: Style.iRadiusM + } + } + } +}