From cbbfbcf671d0f523ece0a9d29673d625b6667608 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Fri, 22 Aug 2025 21:01:00 +0200 Subject: [PATCH] Add NWidgetCard, fix some BarTab things --- Modules/SettingsPanel/Tabs/BarTab.qml | 398 ++------------------------ Widgets/NWidgetCard.qml | 158 ++++++++++ 2 files changed, 182 insertions(+), 374 deletions(-) create mode 100644 Widgets/NWidgetCard.qml diff --git a/Modules/SettingsPanel/Tabs/BarTab.qml b/Modules/SettingsPanel/Tabs/BarTab.qml index c751dcb..3209637 100644 --- a/Modules/SettingsPanel/Tabs/BarTab.qml +++ b/Modules/SettingsPanel/Tabs/BarTab.qml @@ -162,386 +162,36 @@ ColumnLayout { spacing: Style.marginM * scaling // Left Section - NCard { - Layout.fillWidth: true - Layout.minimumHeight: { - var widgetCount = Settings.data.bar.widgets.left.length - if (widgetCount === 0) - return 140 * scaling - - var availableWidth = scrollView.availableWidth - (Style.marginM * scaling * 2) // Card margins - var avgWidgetWidth = 150 * scaling // Estimated widget width including spacing - var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth)) - var rows = Math.ceil(widgetCount / widgetsPerRow) - - // Header (50) + spacing (20) + (rows * widget height) + (rows-1 * spacing) + bottom margin (20) - return (50 + 20 + (rows * 48) + ((rows - 1) * Style.marginS) + 20) * scaling - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: Style.marginM * scaling - spacing: Style.marginM * scaling - - RowLayout { - Layout.fillWidth: true - - NText { - text: "Left Section" - font.pointSize: Style.fontSizeL * scaling - font.weight: Style.fontWeightBold - color: Color.mOnSurface - } - - Item { - Layout.fillWidth: true - } - - NComboBox { - id: leftComboBox - width: 120 * scaling - model: availableWidgets - label: "" - description: "" - placeholder: "Add widget to left section" - onSelected: key => { - addWidgetToSection(key, "left") - } - } - } - - Flow { - id: leftWidgetsFlow - Layout.fillWidth: true - Layout.fillHeight: true - Layout.minimumHeight: 65 * scaling - spacing: Style.marginS * scaling - flow: Flow.LeftToRight - - Repeater { - model: Settings.data.bar.widgets.left - delegate: Rectangle { - width: widgetContent.implicitWidth + 16 * scaling - height: 48 * scaling - radius: Style.radiusS * scaling - color: Color.mPrimary - border.color: Color.mOutline - border.width: Math.max(1, Style.borderS * scaling) - - RowLayout { - id: widgetContent - anchors.centerIn: parent - spacing: Style.marginXS * scaling - - NIconButton { - icon: "chevron_left" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - enabled: index > 0 - onClicked: { - if (index > 0) { - reorderWidgetInSection("left", index, index - 1) - } - } - } - - NText { - text: modelData - font.pointSize: Style.fontSizeS * scaling - color: Color.mOnPrimary - horizontalAlignment: Text.AlignHCenter - } - - NIconButton { - icon: "chevron_right" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - enabled: index < Settings.data.bar.widgets.left.length - 1 - onClicked: { - if (index < Settings.data.bar.widgets.left.length - 1) { - reorderWidgetInSection("left", index, index + 1) - } - } - } - - NIconButton { - icon: "close" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - onClicked: { - removeWidgetFromSection("left", index) - } - } - } - } - } - } - } + NWidgetCard { + sectionName: "Left" + widgetModel: Settings.data.bar.widgets.left + availableWidgets: availableWidgets + scrollView: scrollView + onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section) + onRemoveWidget: (section, index) => removeWidgetFromSection(section, index) + onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex) } // Center Section - NCard { - Layout.fillWidth: true - Layout.minimumHeight: { - var widgetCount = Settings.data.bar.widgets.center.length - if (widgetCount === 0) - return 140 * scaling - - var availableWidth = scrollView.availableWidth - (Style.marginM * scaling * 2) // Card margins - var avgWidgetWidth = 150 * scaling // Estimated widget width including spacing - var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth)) - var rows = Math.ceil(widgetCount / widgetsPerRow) - - // Header (50) + spacing (20) + (rows * widget height) + (rows-1 * spacing) + bottom margin (20) - return (50 + 20 + (rows * 48) + ((rows - 1) * Style.marginS) + 20) * scaling - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: Style.marginM * scaling - spacing: Style.marginM * scaling - - RowLayout { - Layout.fillWidth: true - - NText { - text: "Center Section" - font.pointSize: Style.fontSizeL * scaling - font.weight: Style.fontWeightBold - color: Color.mOnSurface - } - - Item { - Layout.fillWidth: true - } - - NComboBox { - id: centerComboBox - width: 120 * scaling - model: availableWidgets - label: "" - description: "" - placeholder: "Add widget to center section" - onSelected: key => { - addWidgetToSection(key, "center") - reset() // Reset selection - } - } - } - - Flow { - id: centerWidgetsFlow - Layout.fillWidth: true - Layout.fillHeight: true - Layout.minimumHeight: 65 * scaling - spacing: Style.marginS * scaling - flow: Flow.LeftToRight - - Repeater { - model: Settings.data.bar.widgets.center - delegate: Rectangle { - width: widgetContent.implicitWidth + 16 * scaling - height: 48 * scaling - radius: Style.radiusS * scaling - color: Color.mPrimary - border.color: Color.mOutline - border.width: Math.max(1, Style.borderS * scaling) - - RowLayout { - id: widgetContent - anchors.centerIn: parent - spacing: Style.marginXS * scaling - - NIconButton { - icon: "chevron_left" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - enabled: index > 0 - onClicked: { - if (index > 0) { - reorderWidgetInSection("center", index, index - 1) - } - } - } - - NText { - text: modelData - font.pointSize: Style.fontSizeS * scaling - color: Color.mOnPrimary - horizontalAlignment: Text.AlignHCenter - } - - NIconButton { - icon: "chevron_right" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - enabled: index < Settings.data.bar.widgets.center.length - 1 - onClicked: { - if (index < Settings.data.bar.widgets.center.length - 1) { - reorderWidgetInSection("center", index, index + 1) - } - } - } - - NIconButton { - icon: "close" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - onClicked: { - removeWidgetFromSection("center", index) - } - } - } - } - } - } - } + NWidgetCard { + sectionName: "Center" + widgetModel: Settings.data.bar.widgets.center + availableWidgets: availableWidgets + scrollView: scrollView + onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section) + onRemoveWidget: (section, index) => removeWidgetFromSection(section, index) + onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex) } // Right Section - NCard { - Layout.fillWidth: true - Layout.minimumHeight: { - var widgetCount = Settings.data.bar.widgets.right.length - if (widgetCount === 0) - return 140 * scaling - - var availableWidth = scrollView.availableWidth - (Style.marginM * scaling * 2) // Card margins - var avgWidgetWidth = 150 * scaling // Estimated widget width including spacing - var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth)) - var rows = Math.ceil(widgetCount / widgetsPerRow) - - // Header (50) + spacing (20) + (rows * widget height) + (rows-1 * spacing) + bottom margin (20) - return (50 + 20 + (rows * 48) + ((rows - 1) * Style.marginS) + 20) * scaling - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: Style.marginM * scaling - spacing: Style.marginM * scaling - - RowLayout { - Layout.fillWidth: true - - NText { - text: "Right Section" - font.pointSize: Style.fontSizeL * scaling - font.weight: Style.fontWeightBold - color: Color.mOnSurface - } - - Item { - Layout.fillWidth: true - } - - NComboBox { - id: rightComboBox - width: 120 * scaling - model: availableWidgets - label: "" - description: "" - placeholder: "Add widget to right section" - onSelected: key => { - addWidgetToSection(key, "right") - reset() // Reset selection - } - } - } - - Flow { - id: rightWidgetsFlow - Layout.fillWidth: true - Layout.fillHeight: true - Layout.minimumHeight: 65 * scaling - spacing: Style.marginS * scaling - flow: Flow.LeftToRight - - Repeater { - model: Settings.data.bar.widgets.right - delegate: Rectangle { - width: widgetContent.implicitWidth + 16 * scaling - height: 48 * scaling - radius: Style.radiusS * scaling - color: Color.mPrimary - border.color: Color.mOutline - border.width: Math.max(1, Style.borderS * scaling) - - RowLayout { - id: widgetContent - anchors.centerIn: parent - spacing: Style.marginXS * scaling - - NIconButton { - icon: "chevron_left" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - enabled: index > 0 - onClicked: { - if (index > 0) { - reorderWidgetInSection("right", index, index - 1) - } - } - } - - NText { - text: modelData - font.pointSize: Style.fontSizeS * scaling - color: Color.mOnPrimary - horizontalAlignment: Text.AlignHCenter - } - - NIconButton { - icon: "chevron_right" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - enabled: index < Settings.data.bar.widgets.right.length - 1 - onClicked: { - if (index < Settings.data.bar.widgets.right.length - 1) { - reorderWidgetInSection("right", index, index + 1) - } - } - } - - NIconButton { - icon: "close" - size: 20 * scaling - colorBg: Color.applyOpacity(Color.mOnPrimary, "20") - colorFg: Color.mOnPrimary - colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") - colorFgHover: Color.mOnPrimary - onClicked: { - removeWidgetFromSection("right", index) - } - } - } - } - } - } - } + NWidgetCard { + sectionName: "Right" + widgetModel: Settings.data.bar.widgets.right + availableWidgets: availableWidgets + scrollView: scrollView + onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section) + onRemoveWidget: (section, index) => removeWidgetFromSection(section, index) + onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex) } } } diff --git a/Widgets/NWidgetCard.qml b/Widgets/NWidgetCard.qml new file mode 100644 index 0000000..2808465 --- /dev/null +++ b/Widgets/NWidgetCard.qml @@ -0,0 +1,158 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import qs.Commons +import qs.Widgets + +NCard { + id: root + + property string sectionName: "" + property var widgetModel: [] + property var availableWidgets: [] + property var scrollView: null + + signal addWidget(string widgetName, string section) + signal removeWidget(string section, int index) + signal reorderWidget(string section, int fromIndex, int toIndex) + + Layout.fillWidth: true + Layout.minimumHeight: { + var widgetCount = widgetModel.length + if (widgetCount === 0) + return 140 * scaling + + var availableWidth = scrollView ? scrollView.availableWidth - (Style.marginM * scaling * 2) : 400 * scaling + var avgWidgetWidth = 150 * scaling + var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth)) + var rows = Math.ceil(widgetCount / widgetsPerRow) + + return (50 + 20 + (rows * 48) + ((rows - 1) * Style.marginS) + 20) * scaling + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: Style.marginM * scaling + spacing: Style.marginM * scaling + + RowLayout { + Layout.fillWidth: true + + NText { + text: sectionName + " Section" + font.pointSize: Style.fontSizeL * scaling + font.weight: Style.fontWeightBold + color: Color.mOnSurface + Layout.alignment: Qt.AlignVCenter + } + + Item { + Layout.fillWidth: true + } + + NComboBox { + id: comboBox + width: 120 * scaling + model: availableWidgets + label: "" + description: "" + placeholder: "Add widget to " + sectionName.toLowerCase() + " section" + onSelected: key => { + comboBox.selectedKey = key + } + } + + NIconButton { + icon: "add" + size: 24 * scaling + colorBg: Color.mPrimary + colorFg: Color.mOnPrimary + colorBgHover: Color.mPrimaryContainer + colorFgHover: Color.mOnPrimaryContainer + enabled: comboBox.selectedKey !== "" + Layout.alignment: Qt.AlignVCenter + onClicked: { + if (comboBox.selectedKey !== "") { + addWidget(comboBox.selectedKey, sectionName.toLowerCase()) + comboBox.reset() + } + } + } + } + + Flow { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.minimumHeight: 65 * scaling + spacing: Style.marginS * scaling + flow: Flow.LeftToRight + + Repeater { + model: widgetModel + delegate: Rectangle { + width: widgetContent.implicitWidth + 16 * scaling + height: 48 * scaling + radius: Style.radiusS * scaling + color: Color.mPrimary + border.color: Color.mOutline + border.width: Math.max(1, Style.borderS * scaling) + + RowLayout { + id: widgetContent + anchors.centerIn: parent + spacing: Style.marginXS * scaling + + NIconButton { + icon: "chevron_left" + size: 20 * scaling + colorBg: Color.applyOpacity(Color.mOnPrimary, "20") + colorFg: Color.mOnPrimary + colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") + colorFgHover: Color.mOnPrimary + enabled: index > 0 + onClicked: { + if (index > 0) { + reorderWidget(sectionName.toLowerCase(), index, index - 1) + } + } + } + + NText { + text: modelData + font.pointSize: Style.fontSizeS * scaling + color: Color.mOnPrimary + horizontalAlignment: Text.AlignHCenter + } + + NIconButton { + icon: "chevron_right" + size: 20 * scaling + colorBg: Color.applyOpacity(Color.mOnPrimary, "20") + colorFg: Color.mOnPrimary + colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") + colorFgHover: Color.mOnPrimary + enabled: index < widgetModel.length - 1 + onClicked: { + if (index < widgetModel.length - 1) { + reorderWidget(sectionName.toLowerCase(), index, index + 1) + } + } + } + + NIconButton { + icon: "close" + size: 20 * scaling + colorBg: Color.applyOpacity(Color.mOnPrimary, "20") + colorFg: Color.mOnPrimary + colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40") + colorFgHover: Color.mOnPrimary + onClicked: { + removeWidget(sectionName.toLowerCase(), index) + } + } + } + } + } + } + } +}