diff --git a/Modules/Bar/Widgets/CustomButton.qml b/Modules/Bar/Widgets/CustomButton.qml index 42fa154..1b9462d 100644 --- a/Modules/Bar/Widgets/CustomButton.qml +++ b/Modules/Bar/Widgets/CustomButton.qml @@ -1,19 +1,21 @@ import QtQuick import QtQuick.Layouts +import Quickshell import qs.Commons import qs.Services import qs.Widgets NIconButton { id: root - + // Widget properties passed from Bar.qml property var screen property real scaling: 1.0 + property string barSection: "" property int sectionWidgetIndex: -1 property int sectionWidgetsCount: 0 - + // Get user settings from Settings data property var widgetSettings: { var section = barSection.replace("Section", "").toLowerCase() @@ -25,19 +27,15 @@ NIconButton { } return {} } - + // Use settings or defaults from BarWidgetRegistry property string userIcon: widgetSettings.icon || BarWidgetRegistry.widgetMetadata["CustomButton"].icon property string userExecute: widgetSettings.execute || BarWidgetRegistry.widgetMetadata["CustomButton"].execute - + icon: userIcon tooltipText: userExecute ? `Execute: ${userExecute}` : "Custom Button - Configure in settings" - - colorBg: Color.transparent - colorFg: Color.mOnSurface - colorBgHover: Color.applyOpacity(Color.mPrimary, "20") - colorFgHover: Color.mPrimary - + opacity: userExecute ? Style.opacityFull : Style.opacityMedium + onClicked: { if (userExecute) { // Execute the user's command @@ -47,11 +45,8 @@ NIconButton { Logger.warn("CustomButton", "No command configured for this button") } } - - // Visual feedback when no command is set - opacity: userExecute ? 1.0 : 0.6 - + Component.onCompleted: { Logger.log("CustomButton", `Initialized with icon: ${userIcon}, command: ${userExecute}`) } -} \ No newline at end of file +} diff --git a/Widgets/NSectionEditor.qml b/Modules/SettingsPanel/Extras/BarSectionEditor.qml similarity index 59% rename from Widgets/NSectionEditor.qml rename to Modules/SettingsPanel/Extras/BarSectionEditor.qml index db4cdb6..0f4767a 100644 --- a/Widgets/NSectionEditor.qml +++ b/Modules/SettingsPanel/Extras/BarSectionEditor.qml @@ -37,207 +37,29 @@ NBox { // Generate widget color from name checksum function getWidgetColor(widget) { const totalSum = JSON.stringify(widget).split('').reduce((acc, character) => { - return acc + character.charCodeAt(0) - }, 0) + return acc + character.charCodeAt(0) + }, 0) switch (totalSum % 10) { - case 0: - return Color.mPrimary - case 1: - return Color.mSecondary - case 2: - return Color.mTertiary - case 3: - return Color.mError - case 4: - return Color.mOnSurface - case 5: - return Qt.darker(Color.mPrimary, 1.3) - case 6: - return Qt.darker(Color.mSecondary, 1.3) - case 7: - return Qt.darker(Color.mTertiary, 1.3) - case 8: - return Qt.darker(Color.mError, 1.3) - case 9: - return Qt.darker(Color.mOnSurface, 1.3) - } - } - - // Widget Settings Dialog Component - Component { - id: widgetSettingsDialog - - Popup { - id: settingsPopup - - property int widgetIndex: -1 - property var widgetData: null - property string widgetId: "" - - // Center popup in parent - x: (parent.width - width) * 0.5 - y: (parent.height - height) * 0.5 - - width: 400 * scaling - height: content.implicitHeight + padding * 2 - padding: Style.marginL * scaling - modal: true - - background: Rectangle { - id: bgRect - color: Color.mSurface - radius: Style.radiusL * scaling - border.color: Color.mPrimary - border.width: Style.borderM * scaling - } - - - - ColumnLayout { - id: content - width: parent.width - spacing: Style.marginM * scaling - - // Title - RowLayout { - Layout.fillWidth: true - - NText { - text: "Widget Settings: " + settingsPopup.widgetId - font.pointSize: Style.fontSizeL * scaling - font.weight: Style.fontWeightBold - color: Color.mPrimary - Layout.fillWidth: true - } - - NIconButton { - icon: "close" - colorBg: Color.transparent - colorFg: Color.mOnSurface - colorBgHover: Color.applyOpacity(Color.mError, "20") - colorFgHover: Color.mError - onClicked: settingsPopup.close() - } - } - - // Separator - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 1 - color: Color.mOutline - } - - // Settings based on widget type - Loader { - id: settingsLoader - Layout.fillWidth: true - sourceComponent: { - if (settingsPopup.widgetId === "CustomButton") { - return customButtonSettings - } - // Add more widget settings components here as needed - return null - } - } - - // Action buttons - RowLayout { - Layout.fillWidth: true - Layout.topMargin: Style.marginM * scaling - - Item { - Layout.fillWidth: true - } - - NButton { - text: "Cancel" - outlined: true - onClicked: settingsPopup.close() - } - - NButton { - text: "Save" - onClicked: { - if (settingsLoader.item && settingsLoader.item.saveSettings) { - var newSettings = settingsLoader.item.saveSettings() - root.updateWidgetSettings(sectionId, settingsPopup.widgetIndex, newSettings) - settingsPopup.close() - } - } - } - } - } - - // CustomButton settings component - Component { - id: customButtonSettings - - ColumnLayout { - spacing: Style.marginM * scaling - - property alias iconField: iconInput - property alias executeField: executeInput - - function saveSettings() { - var settings = Object.assign({}, settingsPopup.widgetData) - settings.icon = iconInput.text - settings.execute = executeInput.text - return settings - } - - // Icon setting - ColumnLayout { - Layout.fillWidth: true - spacing: Style.marginXS * scaling - - NText { - text: "Icon Name" - font.pointSize: Style.fontSizeS * scaling - color: Color.mOnSurfaceVariant - } - - NTextInput{ - id: iconInput - Layout.fillWidth: true - //placeholder: "Enter icon name (e.g., favorite, home, settings)" - text: settingsPopup.widgetData.icon || "" - } - - NText { - text: "Use Material Icon names from the icon set" - font.pointSize: Style.fontSizeXS * scaling - color: Color.applyOpacity(Color.mOnSurfaceVariant, "80") - } - } - - // Execute command setting - ColumnLayout { - Layout.fillWidth: true - spacing: Style.marginXS * scaling - - NText { - text: "Execute Command" - font.pointSize: Style.fontSizeS * scaling - color: Color.mOnSurfaceVariant - } - - NTextInput { - id: executeInput - Layout.fillWidth: true - //placeholder: "Enter command to execute (e.g., firefox, code, terminal)" - text: settingsPopup.widgetData.execute || "" - } - - NText { - text: "Command or application to run when clicked" - font.pointSize: Style.fontSizeXS * scaling - color: Color.applyOpacity(Color.mOnSurfaceVariant, "80") - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - } - } - } + case 0: + return Color.mPrimary + case 1: + return Color.mSecondary + case 2: + return Color.mTertiary + case 3: + return Color.mError + case 4: + return Color.mOnSurface + case 5: + return Qt.darker(Color.mPrimary, 1.3) + case 6: + return Qt.darker(Color.mSecondary, 1.3) + case 7: + return Qt.darker(Color.mTertiary, 1.3) + case 8: + return Qt.darker(Color.mError, 1.3) + case 9: + return Qt.darker(Color.mOnSurface, 1.3) } } @@ -301,7 +123,6 @@ NBox { spacing: Style.marginS * scaling flow: Flow.LeftToRight - Repeater { model: widgetModel delegate: Rectangle { @@ -363,18 +184,25 @@ NBox { colorFgHover: Color.mOnPrimary onClicked: { // Open widget settings dialog - var dialog = widgetSettingsDialog.createObject(root, { - widgetIndex: index, - widgetData: modelData, - widgetId: modelData.id, - parent: Overlay.overlay - }) + var dialog = Qt.createComponent("BarWidgetSettingsDialog.qml").createObject(root, { + "widgetIndex": index, + "widgetData": modelData, + "widgetId": modelData.id, + "parent": Overlay.overlay + }) + // }) + + // var dialog = widgetSettingsDialog.createObject(root, { + // widgetIndex: index, + // widgetData: modelData, + // widgetId: modelData.id, + // parent: Overlay.overlay + // }) dialog.open() } } } - NIconButton { icon: "close" sizeRatio: 0.6 @@ -402,20 +230,20 @@ NBox { const buttonsWidth = 45 * scaling const buttonsHeight = 20 * scaling - if (mouseX >= buttonsX && mouseX <= buttonsX + buttonsWidth - && mouseY >= buttonsY && mouseY <= buttonsY + buttonsHeight) { + if (mouseX >= buttonsX && mouseX <= buttonsX + buttonsWidth && mouseY >= buttonsY + && mouseY <= buttonsY + buttonsHeight) { // Click is on the buttons, don't start drag mouse.accepted = false return } - //Logger.log("NSectionEditor", `Started dragging widget: ${modelData.id} at index ${index}`) + //Logger.log("BarSectionEditor", `Started dragging widget: ${modelData.id} at index ${index}`) // Bring to front when starting drag widgetItem.z = 1000 } onReleased: { - //Logger.log("NSectionEditor", `Released widget: ${modelData.id} at index ${index}`) + //Logger.log("BarSectionEditor", `Released widget: ${modelData.id} at index ${index}`) // Reset z-index when drag ends widgetItem.z = 0 @@ -478,16 +306,16 @@ NBox { radius: Style.radiusS * scaling } - onEntered: function (drag) {//Logger.log("NSectionEditor", "Entered start drop zone") + onEntered: function (drag) {//Logger.log("BarSectionEditor", "Entered start drop zone") } onDropped: function (drop) { - //Logger.log("NSectionEditor", "Dropped on start zone") + //Logger.log("BarSectionEditor", "Dropped on start zone") if (drop.source && drop.source.widgetIndex !== undefined) { const fromIndex = drop.source.widgetIndex const toIndex = 0 // Insert at the beginning if (fromIndex !== toIndex) { - //Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to beginning`) + //Logger.log("BarSectionEditor", `Dropped widget from index ${fromIndex} to beginning`) reorderWidget(sectionId, fromIndex, toIndex) } } @@ -512,16 +340,16 @@ NBox { radius: Style.radiusS * scaling } - onEntered: function (drag) {//Logger.log("NSectionEditor", "Entered end drop zone") + onEntered: function (drag) {//Logger.log("BarSectionEditor", "Entered end drop zone") } onDropped: function (drop) { - //Logger.log("NSectionEditor", "Dropped on end zone") + //Logger.log("BarSectionEditor", "Dropped on end zone") if (drop.source && drop.source.widgetIndex !== undefined) { const fromIndex = drop.source.widgetIndex const toIndex = widgetModel.length // Insert at the end if (fromIndex !== toIndex) { - //Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to end`) + //Logger.log("BarSectionEditor", `Dropped widget from index ${fromIndex} to end`) reorderWidget(sectionId, fromIndex, toIndex) } } diff --git a/Modules/SettingsPanel/Extras/BarWidgetSettingsDialog.qml b/Modules/SettingsPanel/Extras/BarWidgetSettingsDialog.qml new file mode 100644 index 0000000..956beda --- /dev/null +++ b/Modules/SettingsPanel/Extras/BarWidgetSettingsDialog.qml @@ -0,0 +1,147 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Effects +import QtQuick.Layouts +import qs.Commons +import qs.Widgets +import qs.Services + +// Widget Settings Dialog Component +Popup { + id: settingsPopup + + property int widgetIndex: -1 + property var widgetData: null + property string widgetId: "" + + // Center popup in parent + x: (parent.width - width) * 0.5 + y: (parent.height - height) * 0.5 + + width: 400 * scaling + height: content.implicitHeight + padding * 2 + padding: Style.marginL * scaling + modal: true + + background: Rectangle { + id: bgRect + color: Color.mSurface + radius: Style.radiusL * scaling + border.color: Color.mPrimary + border.width: Style.borderM * scaling + } + + ColumnLayout { + id: content + width: parent.width + spacing: Style.marginM * scaling + + // Title + RowLayout { + Layout.fillWidth: true + + NText { + text: "Widget Settings: " + settingsPopup.widgetId + font.pointSize: Style.fontSizeL * scaling + font.weight: Style.fontWeightBold + color: Color.mPrimary + Layout.fillWidth: true + } + + NIconButton { + icon: "close" + colorBg: Color.transparent + colorFg: Color.mOnSurface + colorBgHover: Color.applyOpacity(Color.mError, "20") + colorFgHover: Color.mError + onClicked: settingsPopup.close() + } + } + + // Separator + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 1 + color: Color.mOutline + } + + // Settings based on widget type + Loader { + id: settingsLoader + Layout.fillWidth: true + sourceComponent: { + if (settingsPopup.widgetId === "CustomButton") { + return customButtonSettings + } + // Add more widget settings components here as needed + return null + } + } + + // Action buttons + RowLayout { + Layout.fillWidth: true + Layout.topMargin: Style.marginM * scaling + + Item { + Layout.fillWidth: true + } + + NButton { + text: "Cancel" + outlined: true + onClicked: settingsPopup.close() + } + + NButton { + text: "Save" + onClicked: { + if (settingsLoader.item && settingsLoader.item.saveSettings) { + var newSettings = settingsLoader.item.saveSettings() + root.updateWidgetSettings(sectionId, settingsPopup.widgetIndex, newSettings) + settingsPopup.close() + } + } + } + } + } + + // CustomButton settings component + Component { + id: customButtonSettings + + ColumnLayout { + spacing: Style.marginM * scaling + + property alias iconField: iconInput + property alias executeField: executeInput + + function saveSettings() { + var settings = Object.assign({}, settingsPopup.widgetData) + settings.icon = iconInput.text + settings.execute = executeInput.text + return settings + } + + // Icon setting + NTextInput { + id: iconInput + Layout.fillWidth: true + label: "Icon Name" + description: "Use Material Icon names from the icon set" + text: settingsPopup.widgetData.icon || "" + placeholderText: "Enter icon name (e.g., favorite, home, settings)" + } + + // Execute command setting + NTextInput { + id: executeInput + Layout.fillWidth: true + label: "Execute Command" + description: "Command or application to run when clicked" + text: settingsPopup.widgetData.execute || "" + placeholderText: "Enter command to execute (app or custom script)" + } + } + } +} diff --git a/Modules/SettingsPanel/Tabs/BarTab.qml b/Modules/SettingsPanel/Tabs/BarTab.qml index 6a76022..949ae04 100644 --- a/Modules/SettingsPanel/Tabs/BarTab.qml +++ b/Modules/SettingsPanel/Tabs/BarTab.qml @@ -4,6 +4,7 @@ import QtQuick.Layouts import qs.Commons import qs.Services import qs.Widgets +import qs.Modules.SettingsPanel.Extras ColumnLayout { id: root @@ -157,7 +158,7 @@ ColumnLayout { spacing: Style.marginM * scaling // Left Section - NSectionEditor { + BarSectionEditor { sectionName: "Left" sectionId: "left" widgetModel: Settings.data.bar.widgets.left @@ -169,7 +170,7 @@ ColumnLayout { } // Center Section - NSectionEditor { + BarSectionEditor { sectionName: "Center" sectionId: "center" widgetModel: Settings.data.bar.widgets.center @@ -181,7 +182,7 @@ ColumnLayout { } // Right Section - NSectionEditor { + BarSectionEditor { sectionName: "Right" sectionId: "right" widgetModel: Settings.data.bar.widgets.right diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index f99ebe6..155b583 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -35,13 +35,12 @@ Singleton { }) property var widgetMetadata: ({ - "CustomButton": { - allowUserSettings: true, - icon: "favorite", - execute: "" - }, - }) - + "CustomButton": { + "allowUserSettings": true, + "icon": "favorite", + "execute": "" + } + }) // Component definitions - these are loaded once at startup property Component activeWindowComponent: Component { diff --git a/Widgets/NTextInput.qml b/Widgets/NTextInput.qml index 829c92a..1e54a51 100644 --- a/Widgets/NTextInput.qml +++ b/Widgets/NTextInput.qml @@ -39,10 +39,13 @@ ColumnLayout { // Container Rectangle { id: frame - implicitWidth: parent.width - implicitHeight: Style.baseWidgetSize * 1.1 * scaling + + Layout.fillWidth: true Layout.minimumWidth: 80 * scaling Layout.maximumWidth: root.inputMaxWidth + + implicitWidth: parent.width + implicitHeight: Style.baseWidgetSize * 1.1 * scaling radius: Style.radiusM * scaling color: Color.mSurface border.color: Color.mOutline