From ba6c7ae28c0be2cbb128853dbe47ac1fe15bacda Mon Sep 17 00:00:00 2001 From: purian23 Date: Sat, 13 Sep 2025 22:02:48 -0400 Subject: [PATCH] feat: Implement Color Picker --- Modals/ColorPickerModal.qml | 37 +++++++++++++++++++++ Modules/Settings/TopBarTab.qml | 6 ++++ Modules/TopBar/ColorPicker.qml | 60 ++++++++++++++++++++++++++++++++++ Modules/TopBar/TopBar.qml | 22 +++++++++++-- shell.qml | 4 +++ 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 Modals/ColorPickerModal.qml create mode 100644 Modules/TopBar/ColorPicker.qml diff --git a/Modals/ColorPickerModal.qml b/Modals/ColorPickerModal.qml new file mode 100644 index 00000000..786622ea --- /dev/null +++ b/Modals/ColorPickerModal.qml @@ -0,0 +1,37 @@ +import QtQuick +import Qt.labs.platform +import Quickshell +import qs.Common +import qs.Services + +Item { + id: colorPickerModal + + signal colorSelected(color selectedColor) + + function show() { + colorDialog.open() + } + + function hide() { + colorDialog.close() + } + + function copyColorToClipboard(colorValue) { + Quickshell.execDetached(["sh", "-c", `echo "${colorValue}" | wl-copy`]) + ToastService.showInfo(`Color ${colorValue} copied to clipboard`) + console.log("Copied color to clipboard:", colorValue) + } + + ColorDialog { + id: colorDialog + title: "Color Picker - Select and copy color" + color: Theme.primary + + onAccepted: { + const colorString = color.toString() + copyColorToClipboard(colorString) + colorSelected(color) + } + } +} \ No newline at end of file diff --git a/Modules/Settings/TopBarTab.qml b/Modules/Settings/TopBarTab.qml index 8921d494..f6279176 100644 --- a/Modules/Settings/TopBarTab.qml +++ b/Modules/Settings/TopBarTab.qml @@ -157,6 +157,12 @@ Item { "description": "Quick access to notepad", "icon": "assignment", "enabled": true + }, { + "id": "colorPicker", + "text": "Color Picker", + "description": "Quick access to color picker", + "icon": "palette", + "enabled": true }] property var defaultLeftWidgets: [{ "id": "launcherButton", diff --git a/Modules/TopBar/ColorPicker.qml b/Modules/TopBar/ColorPicker.qml new file mode 100644 index 00000000..e2286772 --- /dev/null +++ b/Modules/TopBar/ColorPicker.qml @@ -0,0 +1,60 @@ +import QtQuick +import qs.Common +import qs.Widgets + +Rectangle { + id: root + + property bool isActive: false + property string section: "right" + property var popupTarget: null + property var parentScreen: null + property real widgetHeight: 30 + property real barHeight: 48 + readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) + + signal clicked() + + width: colorPickerIcon.width + horizontalPadding * 2 + height: widgetHeight + radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius + color: { + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = colorPickerArea.containsMouse || root.isActive ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); + } + + DankIcon { + id: colorPickerIcon + + anchors.centerIn: parent + name: "palette" + size: Theme.iconSize - 6 + color: colorPickerArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText + } + + MouseArea { + id: colorPickerArea + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + console.log("Color picker button clicked!") + root.colorPickerRequested(); + } + } + + // Signal to notify TopBar to open color picker + signal colorPickerRequested() + + Behavior on color { + ColorAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } +} \ No newline at end of file diff --git a/Modules/TopBar/TopBar.qml b/Modules/TopBar/TopBar.qml index e214b626..d8010881 100644 --- a/Modules/TopBar/TopBar.qml +++ b/Modules/TopBar/TopBar.qml @@ -21,7 +21,9 @@ PanelWindow { property var modelData property var notepadVariants: null - + + signal colorPickerRequested() + function getNotepadInstanceForScreen() { if (!notepadVariants || !notepadVariants.instances) return null @@ -370,7 +372,8 @@ PanelWindow { "network_speed_monitor": networkComponent, "keyboard_layout_name": keyboardLayoutNameComponent, "vpn": vpnComponent, - "notepadButton": notepadButtonComponent + "notepadButton": notepadButtonComponent, + "colorPicker": colorPickerComponent }) function getWidgetComponent(widgetId) { @@ -999,9 +1002,24 @@ PanelWindow { } } } + + Component { + id: colorPickerComponent + + ColorPicker { + widgetHeight: root.widgetHeight + barHeight: root.effectiveBarHeight + section: topBarContent.getWidgetSection(parent) || "right" + parentScreen: root.screen + onColorPickerRequested: { + root.colorPickerRequested() + } + } + } } } } } } + } diff --git a/shell.qml b/shell.qml index ed3e871f..d62f5d36 100644 --- a/shell.qml +++ b/shell.qml @@ -48,6 +48,7 @@ ShellRoot { delegate: TopBar { modelData: item notepadVariants: notepadSlideoutVariants + onColorPickerRequested: colorPickerModal.show() } } @@ -258,6 +259,9 @@ ShellRoot { NotificationModal { id: notificationModal } + ColorPickerModal { + id: colorPickerModal + } LazyLoader { id: processListModalLoader