From 3997a369ec44d3ff22c0434ed2b131bb9ea397e9 Mon Sep 17 00:00:00 2001 From: quadbyte Date: Tue, 12 Aug 2025 18:03:00 -0400 Subject: [PATCH] NComboBox now includes label + description still working on settings --- Modules/Settings/Tabs/Bar.qml | 78 ++++----- Modules/Settings/Tabs/General.qml | 5 +- Modules/Settings/Tabs/ScreenRecorder.qml | 213 ++++++----------------- Modules/Settings/Tabs/TimeWeather.qml | 2 +- Widgets/NComboBox.qml | 148 +++++++++------- 5 files changed, 177 insertions(+), 269 deletions(-) diff --git a/Modules/Settings/Tabs/Bar.qml b/Modules/Settings/Tabs/Bar.qml index bcac604..39f609a 100644 --- a/Modules/Settings/Tabs/Bar.qml +++ b/Modules/Settings/Tabs/Bar.qml @@ -29,7 +29,7 @@ ColumnLayout { } ColumnLayout { - spacing: Style.marginMedium * scaling + spacing: Style.marginLarge * scaling Layout.fillWidth: true NText { @@ -37,58 +37,50 @@ ColumnLayout { font.pointSize: Style.fontSizeXL * scaling font.weight: Style.fontWeightBold color: Colors.textPrimary - Layout.bottomMargin: Style.marginSmall * scaling } - // Elements section - ColumnLayout { - spacing: Style.marginSmall * scaling - Layout.fillWidth: true - Layout.topMargin: Style.marginSmall * scaling - - NToggle { - label: "Show Active Window" - description: "Display the title of the currently focused window below the bar" - value: Settings.data.bar.showActiveWindow - onToggled: function (newValue) { - Settings.data.bar.showActiveWindow = newValue - } + NToggle { + label: "Show Active Window" + description: "Display the title of the currently focused window below the bar" + value: Settings.data.bar.showActiveWindow + onToggled: function (newValue) { + Settings.data.bar.showActiveWindow = newValue } + } - NToggle { - label: "Show Active Window Icon" - description: "Display the icon of the currently focused window" - value: Settings.data.bar.showActiveWindowIcon - onToggled: function (newValue) { - Settings.data.bar.showActiveWindowIcon = newValue - } + NToggle { + label: "Show Active Window Icon" + description: "Display the icon of the currently focused window" + value: Settings.data.bar.showActiveWindowIcon + onToggled: function (newValue) { + Settings.data.bar.showActiveWindowIcon = newValue } + } - NToggle { - label: "Show System Info" - description: "Display system information (CPU, RAM, Temperature)" - value: Settings.data.bar.showSystemInfo - onToggled: function (newValue) { - Settings.data.bar.showSystemInfo = newValue - } + NToggle { + label: "Show System Info" + description: "Display system information (CPU, RAM, Temperature)" + value: Settings.data.bar.showSystemInfo + onToggled: function (newValue) { + Settings.data.bar.showSystemInfo = newValue } + } - NToggle { - label: "Show Taskbar" - description: "Display a taskbar showing currently open windows" - value: Settings.data.bar.showTaskbar - onToggled: function (newValue) { - Settings.data.bar.showTaskbar = newValue - } + NToggle { + label: "Show Taskbar" + description: "Display a taskbar showing currently open windows" + value: Settings.data.bar.showTaskbar + onToggled: function (newValue) { + Settings.data.bar.showTaskbar = newValue } + } - NToggle { - label: "Show Media" - description: "Display media controls and information" - value: Settings.data.bar.showMedia - onToggled: function (newValue) { - Settings.data.bar.showMedia = newValue - } + NToggle { + label: "Show Media" + description: "Display media controls and information" + value: Settings.data.bar.showMedia + onToggled: function (newValue) { + Settings.data.bar.showMedia = newValue } } } diff --git a/Modules/Settings/Tabs/General.qml b/Modules/Settings/Tabs/General.qml index f0ed6f0..343e4ef 100644 --- a/Modules/Settings/Tabs/General.qml +++ b/Modules/Settings/Tabs/General.qml @@ -29,7 +29,7 @@ ColumnLayout { } ColumnLayout { - spacing: Style.marginTiny * scaling + spacing: Style.marginLarge * scaling Layout.fillWidth: true NText { @@ -37,7 +37,6 @@ ColumnLayout { font.pointSize: Style.fontSizeXL * scaling font.weight: Style.fontWeightBold color: Colors.textPrimary - Layout.bottomMargin: Style.marginSmall * scaling } // Profile section @@ -92,7 +91,7 @@ ColumnLayout { } ColumnLayout { - spacing: Style.marginMedium * scaling + spacing: Style.marginLarge * scaling Layout.fillWidth: true NText { diff --git a/Modules/Settings/Tabs/ScreenRecorder.qml b/Modules/Settings/Tabs/ScreenRecorder.qml index f9346a8..68dc670 100644 --- a/Modules/Settings/Tabs/ScreenRecorder.qml +++ b/Modules/Settings/Tabs/ScreenRecorder.qml @@ -94,7 +94,7 @@ ColumnLayout { // Video Settings ColumnLayout { - spacing: Style.marginTiny * scaling + spacing: Style.marginLarge * scaling Layout.fillWidth: true NText { @@ -106,125 +106,50 @@ ColumnLayout { } // Frame Rate - ColumnLayout { - spacing: Style.marginSmall * scaling - Layout.fillWidth: true - Layout.topMargin: Style.marginSmall * scaling - - ColumnLayout { - spacing: Style.marginTiny * scaling - NText { - text: "Frame Rate" - font.weight: Style.fontWeightBold - color: Colors.textPrimary - } - - NText { - text: "Target frame rate for screen recordings (default: 60)" - font.pointSize: Style.fontSizeSmall * scaling - color: Colors.textSecondary - wrapMode: Text.WordWrap - } - } - NComboBox { - optionsKeys: ["30", "60", "120", "2Style.marginLarge * scaling0"] - optionsLabels: ["30 FPS", "60 FPS", "120 FPS", "2Style.marginLarge * scaling0 FPS"] - currentKey: Settings.data.screenRecorder.frameRate - onSelected: function (key) { - Settings.data.screenRecorder.frameRate = key - } + NComboBox { + label: "Frame Rate" + description: "Target frame rate for screen recordings (default: 60)" + optionsKeys: ["30", "60", "120", "240"] + optionsLabels: ["30 FPS", "60 FPS", "120 FPS", "240 FPS"] + currentKey: Settings.data.screenRecorder.frameRate + onSelected: function (key) { + Settings.data.screenRecorder.frameRate = key } } // Video Quality - ColumnLayout { - spacing: Style.marginSmall * scaling - Layout.fillWidth: true - Layout.topMargin: Style.marginSmall * scaling - - NText { - text: "Video Quality" - font.pointSize: 13 - font.weight: Style.fontWeightBold - color: Colors.textPrimary - } - - NText { - text: "Higher quality results in larger file sizes" - font.pointSize: 12 - color: Colors.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - NComboBox { - optionsKeys: ["medium", "high", "very_high", "ultra"] - optionsLabels: ["Medium", "High", "Very High", "Ultra"] - currentKey: Settings.data.screenRecorder.quality - onSelected: function (key) { - Settings.data.screenRecorder.quality = key - } + NComboBox { + label: "Video Quality" + description: "Higher quality results in larger file sizes" + optionsKeys: ["medium", "high", "very_high", "ultra"] + optionsLabels: ["Medium", "High", "Very High", "Ultra"] + currentKey: Settings.data.screenRecorder.quality + onSelected: function (key) { + Settings.data.screenRecorder.quality = key } } // Video Codec - ColumnLayout { - spacing: Style.marginTiny * scaling - Layout.fillWidth: true - Layout.topMargin: Style.marginSmall * scaling - - NText { - text: "Video Codec" - font.weight: Style.fontWeightBold - color: Colors.textPrimary - } - - NText { - text: "Different codecs offer different compression and compatibility" - font.pointSize: Style.fontSizeSmall * scaling - color: Colors.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - NComboBox { - optionsKeys: ["h264", "hevc", "av1", "vp8", "vp9"] - optionsLabels: ["H264", "HEVC", "AV1", "VP8", "VP9"] - currentKey: Settings.data.screenRecorder.videoCodec - onSelected: function (key) { - Settings.data.screenRecorder.videoCodec = key - } + NComboBox { + label: "Video Codec" + description: "Different codecs offer different compression and compatibility" + optionsKeys: ["h264", "hevc", "av1", "vp8", "vp9"] + optionsLabels: ["H264", "HEVC", "AV1", "VP8", "VP9"] + currentKey: Settings.data.screenRecorder.videoCodec + onSelected: function (key) { + Settings.data.screenRecorder.videoCodec = key } } // Color Range - ColumnLayout { - spacing: Style.marginSmall * scaling - Layout.fillWidth: true - Layout.topMargin: Style.marginSmall * scaling - - NText { - text: "Color Range" - - font.weight: Style.fontWeightBold - color: Colors.textPrimary - } - - NText { - text: "Limited is recommended for better compatibility" - font.pointSize: Style.fontSizeSmall * scaling - color: Colors.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - NComboBox { - optionsKeys: ["limited", "full"] - optionsLabels: ["Limited", "Full"] - currentKey: Settings.data.screenRecorder.colorRange - onSelected: function (key) { - Settings.data.screenRecorder.colorRange = key - } + NComboBox { + label: "Color Range" + description: "Limited is recommended for better compatibility" + optionsKeys: ["limited", "full"] + optionsLabels: ["Limited", "Full"] + currentKey: Settings.data.screenRecorder.colorRange + onSelected: function (key) { + Settings.data.screenRecorder.colorRange = key } } } @@ -237,7 +162,7 @@ ColumnLayout { // Audio Settings ColumnLayout { - spacing: Style.spacingTiny * scaling + spacing: Style.marginLarge * scaling Layout.fillWidth: true NText { @@ -249,64 +174,26 @@ ColumnLayout { } // Audio Source - ColumnLayout { - spacing: Style.marginSmall * scaling - Layout.fillWidth: true - Layout.topMargin: Style.marginSmall * scaling - - NText { - text: "Audio Source" - - font.weight: Style.fontWeightBold - color: Colors.textPrimary - } - - NText { - text: "Audio source to capture during recording" - font.pointSize: Style.fontSizeSmall * scaling - color: Colors.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - NComboBox { - optionsKeys: ["default_output", "default_input", "both"] - optionsLabels: ["System Audio", "Microphone", "System Audio + Microphone"] - currentKey: Settings.data.screenRecorder.audioSource - onSelected: function (key) { - Settings.data.screenRecorder.audioSource = key - } + NComboBox { + label: "Audio Source" + description: "Audio source to capture during recording" + optionsKeys: ["default_output", "default_input", "both"] + optionsLabels: ["System Audio", "Microphone", "System Audio + Microphone"] + currentKey: Settings.data.screenRecorder.audioSource + onSelected: function (key) { + Settings.data.screenRecorder.audioSource = key } } // Audio Codec - ColumnLayout { - spacing: Style.marginSmall * scaling - Layout.fillWidth: true - Layout.topMargin: Style.marginSmall * scaling - - NText { - text: "Audio Codec" - font.pointSize: 13 - font.weight: Style.fontWeightBold - color: Colors.textPrimary - } - - NText { - text: "Opus is recommended for best performance and smallest audio size" - font.pointSize: 12 - color: Colors.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - NComboBox { - optionsKeys: ["opus", "aac"] - optionsLabels: ["OPUS", "AAC"] - currentKey: Settings.data.screenRecorder.audioCodec - onSelected: function (key) { - Settings.data.screenRecorder.audioCodec = key - } + NComboBox { + label: "Audio Codec" + description: "Opus is recommended for best performance and smallest audio size" + optionsKeys: ["opus", "aac"] + optionsLabels: ["OPUS", "AAC"] + currentKey: Settings.data.screenRecorder.audioCodec + onSelected: function (key) { + Settings.data.screenRecorder.audioCodec = key } } } diff --git a/Modules/Settings/Tabs/TimeWeather.qml b/Modules/Settings/Tabs/TimeWeather.qml index 383eeba..e4e228c 100644 --- a/Modules/Settings/Tabs/TimeWeather.qml +++ b/Modules/Settings/Tabs/TimeWeather.qml @@ -64,7 +64,7 @@ ColumnLayout { // Time section ColumnLayout { - spacing: Style.marginMedium * scaling + spacing: Style.marginLarge * scaling Layout.fillWidth: true NText { diff --git a/Widgets/NComboBox.qml b/Widgets/NComboBox.qml index 0b27fa6..3be8183 100644 --- a/Widgets/NComboBox.qml +++ b/Widgets/NComboBox.qml @@ -4,99 +4,129 @@ import QtQuick.Layouts import qs.Services import qs.Widgets -ComboBox { +ColumnLayout { id: root readonly property real scaling: Scaling.scale(screen) readonly property real preferredHeight: Style.baseWidgetSize * 1.25 * scaling + property string label: "" + property string description: "" property list optionsKeys: [] property list optionsLabels: [] property string currentKey: '' signal selected(string key) + spacing: Style.marginSmall * scaling Layout.fillWidth: true - Layout.preferredHeight: height - model: optionsKeys - currentIndex: model.indexOf(currentKey) - onActivated: { - root.selected(model[currentIndex]) - } + ColumnLayout { + id: mainColumn + spacing: Style.marginTiniest * scaling + Layout.fillWidth: true - // Rounded background - background: Rectangle { - implicitWidth: 120 * scaling - implicitHeight: preferredHeight - color: Colors.surfaceVariant - border.color: root.activeFocus ? Colors.hover : Colors.outline - border.width: Math.max(1, Style.borderThin * scaling) - radius: Style.radiusMedium * scaling - } + NText { + text: label + font.pointSize: Style.fontSizeMedium * scaling + font.weight: Style.fontWeightBold + color: Colors.textPrimary + } - // Label (currently selected) - contentItem: NText { - leftPadding: Style.marginLarge * scaling - rightPadding: root.indicator.width + Style.marginLarge * scaling - font.pointSize: Style.fontSizeMedium * scaling - font.weight: Style.fontWeightBold - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - text: { - return root.optionsLabels[root.currentIndex] + NText { + text: description + font.pointSize: Style.fontSizeSmall * scaling + color: Colors.textSecondary + wrapMode: Text.WordWrap + Layout.fillWidth: true } } - // Drop down indicator - indicator: NText { - x: root.width - width - Style.marginMedium * scaling - y: root.topPadding + (root.availableHeight - height) / 2 - text: "arrow_drop_down" - font.family: "Material Symbols Outlined" - font.pointSize: Style.fontSizeXL * scaling - } + ComboBox { + id: combo - popup: Popup { - y: root.height - width: root.width - implicitHeight: Math.min(160 * scaling, contentItem.implicitHeight + Style.marginMedium * scaling * 2) - padding: Style.marginMedium * scaling + Layout.fillWidth: true + Layout.preferredHeight: height - contentItem: ListView { - clip: true - implicitHeight: contentHeight - model: root.popup.visible ? root.delegateModel : null - currentIndex: root.highlightedIndex - ScrollIndicator.vertical: ScrollIndicator {} + model: optionsKeys + currentIndex: model.indexOf(currentKey) + onActivated: { + root.selected(model[combo.currentIndex]) } + // Rounded background background: Rectangle { + implicitWidth: 120 * scaling + implicitHeight: preferredHeight color: Colors.surfaceVariant - border.color: Colors.outline + border.color: root.activeFocus ? Colors.hover : Colors.outline border.width: Math.max(1, Style.borderThin * scaling) radius: Style.radiusMedium * scaling } - } - - delegate: ItemDelegate { - width: root.width - highlighted: root.highlightedIndex === index + // Label (currently selected) contentItem: NText { - text: { - return root.optionsLabels[root.model.indexOf(modelData)] - } + leftPadding: Style.marginLarge * scaling + rightPadding: combo.indicator.width + Style.marginLarge * scaling font.pointSize: Style.fontSizeMedium * scaling - color: highlighted ? Colors.backgroundPrimary : Colors.textPrimary + font.weight: Style.fontWeightBold verticalAlignment: Text.AlignVCenter elide: Text.ElideRight + text: { + return root.optionsLabels[combo.currentIndex] + } } - background: Rectangle { - width: root.width - Style.marginMedium * scaling * 3 - color: highlighted ? Colors.hover : "transparent" - radius: Style.radiusSmall * scaling + // Drop down indicator + indicator: NText { + x: root.width - width - Style.marginMedium * scaling + y: root.topPadding + (root.availableHeight - height) / 2 + text: "arrow_drop_down" + font.family: "Material Symbols Outlined" + font.pointSize: Style.fontSizeXL * scaling + } + + popup: Popup { + y: root.height + width: root.width + implicitHeight: Math.min(160 * scaling, contentItem.implicitHeight + Style.marginMedium * scaling * 2) + padding: Style.marginMedium * scaling + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: combo.popup.visible ? combo.delegateModel : null + currentIndex: combo.highlightedIndex + ScrollIndicator.vertical: ScrollIndicator {} + } + + background: Rectangle { + color: Colors.surfaceVariant + border.color: Colors.outline + border.width: Math.max(1, Style.borderThin * scaling) + radius: Style.radiusMedium * scaling + } + } + + delegate: ItemDelegate { + width: root.width + highlighted: root.highlightedIndex === index + + contentItem: NText { + text: { + return root.optionsLabels[combo.model.indexOf(modelData)] + } + font.pointSize: Style.fontSizeMedium * scaling + color: highlighted ? Colors.backgroundPrimary : Colors.textPrimary + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + width: root.width - Style.marginMedium * scaling * 3 + color: highlighted ? Colors.hover : "transparent" + radius: Style.radiusSmall * scaling + } } } }