1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-07 22:15:38 -05:00

plugins: add ColorSetting

This commit is contained in:
bbedward
2025-11-08 11:19:47 -05:00
parent 02c59636fc
commit 55776fd7cb
14 changed files with 481 additions and 120 deletions

View File

@@ -106,12 +106,13 @@ DankModal {
}
width: 680
height: 680
height: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 680
backgroundColor: Theme.surfaceContainer
cornerRadius: Theme.cornerRadius
borderColor: Theme.outlineMedium
borderWidth: 1
keepContentLoaded: true
allowStacking: true
onBackgroundClicked: hide()
@@ -122,6 +123,7 @@ DankModal {
property alias hexInput: hexInput
anchors.fill: parent
implicitHeight: mainColumn.implicitHeight
focus: true
Keys.onEscapePressed: event => {
@@ -130,7 +132,10 @@ DankModal {
}
Column {
anchors.fill: parent
id: mainColumn
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: Theme.spacingM
spacing: Theme.spacingM
@@ -444,103 +449,192 @@ DankModal {
}
}
Row {
Column {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Hex:")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
anchors.verticalCenter: parent.verticalCenter
}
Row {
width: parent.width
spacing: Theme.spacingM
DankTextField {
id: hexInput
width: 120
height: 38
text: root.currentColor.toString()
font.pixelSize: Theme.fontSizeMedium
textColor: {
if (text.length === 0) return Theme.surfaceText
const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/
return hexPattern.test(text) ? Theme.surfaceText : Theme.error
Column {
width: (parent.width - Theme.spacingM * 2) / 3
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Hex")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
font.weight: Font.Medium
}
Row {
width: parent.width
spacing: Theme.spacingXS
DankTextField {
id: hexInput
width: parent.width - 36
height: 36
text: root.currentColor.toString()
font.pixelSize: Theme.fontSizeMedium
textColor: {
if (text.length === 0) return Theme.surfaceText
const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/
return hexPattern.test(text) ? Theme.surfaceText : Theme.error
}
placeholderText: "#000000"
backgroundColor: Theme.surfaceHover
borderWidth: 1
focusedBorderWidth: 2
topPadding: Theme.spacingS
bottomPadding: Theme.spacingS
onAccepted: () => {
const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/
if (!hexPattern.test(text)) return
const color = Qt.color(text)
if (color) {
root.selectedColor = color
root.currentColor = color
root.updateFromColor(color)
}
}
}
DankActionButton {
iconName: "content_copy"
iconSize: Theme.iconSize - 6
iconColor: Theme.surfaceText
buttonSize: 36
anchors.verticalCenter: parent.verticalCenter
onClicked: () => {
root.copyColorToClipboard(hexInput.text)
}
}
}
}
placeholderText: "#000000"
backgroundColor: Theme.surfaceHover
borderWidth: 1
focusedBorderWidth: 2
topPadding: Theme.spacingS
bottomPadding: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
onAccepted: () => {
const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/
if (!hexPattern.test(text)) return
const color = Qt.color(text)
if (color) {
root.selectedColor = color
root.currentColor = color
root.updateFromColor(color)
Column {
width: (parent.width - Theme.spacingM * 2) / 3
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("RGB")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
font.weight: Font.Medium
}
Row {
width: parent.width
spacing: Theme.spacingXS
Rectangle {
width: parent.width - 36
height: 36
radius: Theme.cornerRadius
color: Theme.surfaceHover
border.color: Theme.outline
border.width: 1
StyledText {
anchors.centerIn: parent
text: {
const r = Math.round(root.currentColor.r * 255)
const g = Math.round(root.currentColor.g * 255)
const b = Math.round(root.currentColor.b * 255)
return `${r}, ${g}, ${b}`
}
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
}
}
DankActionButton {
iconName: "content_copy"
iconSize: Theme.iconSize - 6
iconColor: Theme.surfaceText
buttonSize: 36
anchors.verticalCenter: parent.verticalCenter
onClicked: () => {
const r = Math.round(root.currentColor.r * 255)
const g = Math.round(root.currentColor.g * 255)
const b = Math.round(root.currentColor.b * 255)
const rgbString = `rgb(${r}, ${g}, ${b})`
Quickshell.execDetached(["sh", "-c", `echo "${rgbString}" | wl-copy`])
ToastService.showInfo(`${rgbString} copied`)
}
}
}
}
Column {
width: (parent.width - Theme.spacingM * 2) / 3
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("HSV")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
font.weight: Font.Medium
}
Row {
width: parent.width
spacing: Theme.spacingXS
Rectangle {
width: parent.width - 36
height: 36
radius: Theme.cornerRadius
color: Theme.surfaceHover
border.color: Theme.outline
border.width: 1
StyledText {
anchors.centerIn: parent
text: {
const h = Math.round(root.hue * 360)
const s = Math.round(root.saturation * 100)
const v = Math.round(root.value * 100)
return `${h}°, ${s}%, ${v}%`
}
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
}
}
DankActionButton {
iconName: "content_copy"
iconSize: Theme.iconSize - 6
iconColor: Theme.surfaceText
buttonSize: 36
anchors.verticalCenter: parent.verticalCenter
onClicked: () => {
const h = Math.round(root.hue * 360)
const s = Math.round(root.saturation * 100)
const v = Math.round(root.value * 100)
const hsvString = `${h}, ${s}, ${v}`
Quickshell.execDetached(["sh", "-c", `echo "${hsvString}" | wl-copy`])
ToastService.showInfo(`HSV ${hsvString} copied`)
}
}
}
}
}
DankButton {
width: 80
buttonHeight: 36
text: I18n.tr("Apply")
backgroundColor: Theme.primary
textColor: Theme.background
anchors.verticalCenter: parent.verticalCenter
onClicked: {
const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/
if (!hexPattern.test(hexInput.text)) return
const color = Qt.color(hexInput.text)
if (color) {
root.currentColor = color
root.updateFromColor(color)
root.selectedColor = root.currentColor
root.colorSelected(root.currentColor)
SessionData.addRecentColor(root.currentColor)
root.hide()
}
}
}
Item {
width: parent.width - 460
height: 1
}
DankButton {
visible: root.onColorSelectedCallback !== null && root.onColorSelectedCallback !== undefined
width: 70
buttonHeight: 36
text: I18n.tr("Cancel")
backgroundColor: "transparent"
textColor: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
onClicked: root.hide()
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: "transparent"
border.color: Theme.surfaceVariantAlpha
border.width: 1
z: -1
}
}
DankButton {
width: 70
buttonHeight: 36
text: I18n.tr("Copy")
text: I18n.tr("Save")
backgroundColor: Theme.primary
textColor: Theme.background
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
onClicked: {
const colorString = root.currentColor.toString()
root.copyColorToClipboard(colorString)
SessionData.addRecentColor(root.currentColor)
root.colorSelected(root.currentColor)
root.hide()
}
}
}

View File

@@ -0,0 +1,103 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
Column {
id: root
required property string settingKey
required property string label
property string description: ""
property color defaultValue: Theme.primary
property color value: defaultValue
width: parent.width
spacing: Theme.spacingS
property bool isInitialized: false
function loadValue() {
const settings = findSettings()
if (settings && settings.pluginService) {
const loadedValue = settings.loadValue(settingKey, defaultValue)
value = loadedValue
isInitialized = true
}
}
Component.onCompleted: {
Qt.callLater(loadValue)
}
onValueChanged: {
if (!isInitialized) return
const settings = findSettings()
if (settings) {
settings.saveValue(settingKey, value)
}
}
function findSettings() {
let item = parent
while (item) {
if (item.saveValue !== undefined && item.loadValue !== undefined) {
return item
}
item = item.parent
}
return null
}
StyledText {
text: root.label
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: root.description
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
wrapMode: Text.WordWrap
visible: root.description !== ""
}
Row {
width: parent.width
spacing: Theme.spacingS
Rectangle {
width: 100
height: 36
radius: Theme.cornerRadius
color: root.value
border.color: Theme.outlineStrong
border.width: 2
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (PopoutService && PopoutService.colorPickerModal) {
PopoutService.colorPickerModal.selectedColor = root.value
PopoutService.colorPickerModal.pickerTitle = root.label
PopoutService.colorPickerModal.onColorSelectedCallback = function(selectedColor) {
root.value = selectedColor
}
PopoutService.colorPickerModal.show()
}
}
}
}
StyledText {
text: root.value.toString()
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
}

View File

@@ -0,0 +1,32 @@
import QtQuick
import qs.Common
import qs.Modules.Plugins
import qs.Widgets
PluginSettings {
id: root
pluginId: "colorDemo"
StyledText {
width: parent.width
text: "Color Demo Settings"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
}
StyledText {
width: parent.width
text: "Choose a custom color to display in the bar widget"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
}
ColorSetting {
settingKey: "customColor"
label: "Custom Color"
description: "Choose a custom color to display in the widget"
defaultValue: Theme.primary
}
}

View File

@@ -0,0 +1,57 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
import qs.Modules.Plugins
PluginComponent {
id: root
property color customColor: pluginData.customColor || Theme.primary
horizontalBarPill: Component {
Row {
spacing: Theme.spacingS
Rectangle {
width: 20
height: 20
radius: 4
color: root.customColor
border.color: Theme.outlineStrong
border.width: 1
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.customColor.toString()
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
}
verticalBarPill: Component {
Column {
spacing: Theme.spacingXS
Rectangle {
width: 20
height: 20
radius: 4
color: root.customColor
border.color: Theme.outlineStrong
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: root.customColor.toString()
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}

View File

@@ -0,0 +1,12 @@
{
"id": "colorDemo",
"name": "Color Demo",
"description": "Demonstrates color picker plugin setting",
"version": "1.0.0",
"author": "DMS",
"icon": "palette",
"type": "widget",
"component": "./ColorDemoWidget.qml",
"settings": "./ColorDemoSettings.qml",
"permissions": ["settings_read", "settings_write"]
}

View File

@@ -179,12 +179,6 @@
"reference": "Modules/AppDrawer/AppDrawerPopout.qml:190",
"comment": ""
},
{
"term": "Apply",
"context": "Apply",
"reference": "Modals/DankColorPickerModal.qml:491",
"comment": ""
},
{
"term": "Apply GTK Colors",
"context": "Apply GTK Colors",
@@ -602,7 +596,7 @@
{
"term": "Cancel",
"context": "Cancel",
"reference": "Modals/BluetoothPairingModal.qml:251, Modals/DankColorPickerModal.qml:518, Modals/PolkitAuthModal.qml:291, Modals/WifiPasswordModal.qml:494, Modals/FileBrowser/FileBrowserOverwriteDialog.qml:83, Modules/Settings/PluginBrowser.qml:627",
"reference": "Modals/BluetoothPairingModal.qml:251, Modals/PolkitAuthModal.qml:291, Modals/WifiPasswordModal.qml:494, Modals/FileBrowser/FileBrowserOverwriteDialog.qml:83, Modules/Settings/PluginBrowser.qml:627",
"comment": ""
},
{
@@ -893,12 +887,6 @@
"reference": "Modules/Toast.qml:17",
"comment": ""
},
{
"term": "Copy",
"context": "Copy",
"reference": "Modals/DankColorPickerModal.qml:537",
"comment": ""
},
{
"term": "Copy PID",
"context": "Copy PID",
@@ -1715,6 +1703,12 @@
"reference": "Modules/Settings/DockTab.qml:304",
"comment": ""
},
{
"term": "HSV",
"context": "HSV",
"reference": "Modals/DankColorPickerModal.qml:576",
"comment": ""
},
{
"term": "Health",
"context": "Health",
@@ -1728,9 +1722,9 @@
"comment": ""
},
{
"term": "Hex:",
"context": "Hex:",
"reference": "Modals/DankColorPickerModal.qml:452",
"term": "Hex",
"context": "Hex",
"reference": "Modals/DankColorPickerModal.qml:465",
"comment": ""
},
{
@@ -2114,7 +2108,7 @@
{
"term": "Material Colors",
"context": "Material Colors",
"reference": "Modals/DankColorPickerModal.qml:313",
"reference": "Modals/DankColorPickerModal.qml:318",
"comment": ""
},
{
@@ -2546,7 +2540,7 @@
{
"term": "Opacity",
"context": "Opacity",
"reference": "Modals/DankColorPickerModal.qml:415",
"reference": "Modals/DankColorPickerModal.qml:420",
"comment": ""
},
{
@@ -2903,6 +2897,12 @@
"reference": "Modules/Settings/DisplaysTab.qml:45",
"comment": ""
},
{
"term": "RGB",
"context": "RGB",
"reference": "Modals/DankColorPickerModal.qml:522",
"comment": ""
},
{
"term": "Rain Chance",
"context": "Rain Chance",
@@ -2924,7 +2924,7 @@
{
"term": "Recent Colors",
"context": "Recent Colors",
"reference": "Modals/DankColorPickerModal.qml:363",
"reference": "Modals/DankColorPickerModal.qml:368",
"comment": ""
},
{
@@ -3020,7 +3020,7 @@
{
"term": "Save",
"context": "Save",
"reference": "Modals/FileBrowser/FileBrowserSaveRow.qml:55, Modules/Notepad/NotepadTextEditor.qml:511, Modules/Notepad/Notepad.qml:480",
"reference": "Modals/DankColorPickerModal.qml:630, Modals/FileBrowser/FileBrowserSaveRow.qml:55, Modules/Notepad/NotepadTextEditor.qml:511, Modules/Notepad/Notepad.qml:480",
"comment": ""
},
{
@@ -3104,7 +3104,7 @@
{
"term": "Select a color from the palette or use custom sliders",
"context": "Select a color from the palette or use custom sliders",
"reference": "Modals/DankColorPickerModal.qml:153",
"reference": "Modals/DankColorPickerModal.qml:158",
"comment": ""
},
{

View File

@@ -875,12 +875,18 @@
"Group multiple windows of the same app together with a window count indicator": {
"Group multiple windows of the same app together with a window count indicator": "Raggruppa molteplici finestre della stessa app con un indicatore del numero di finestre"
},
"HSV": {
"HSV": ""
},
"Health": {
"Health": "Salute"
},
"Height to Edge Gap (Exclusive Zone)": {
"Height to Edge Gap (Exclusive Zone)": "Altezza Gap Angolo (Zona Esclusa)"
},
"Hex": {
"Hex": ""
},
"Hex:": {
"Hex:": "Hex:"
},
@@ -1481,6 +1487,9 @@
"Quick note-taking slideout panel": {
"Quick note-taking slideout panel": "Pannello scorrevole per la presa veloce di appunti"
},
"RGB": {
"RGB": ""
},
"Rain Chance": {
"Rain Chance": "Possibili Piogge"
},

View File

@@ -875,12 +875,18 @@
"Group multiple windows of the same app together with a window count indicator": {
"Group multiple windows of the same app together with a window count indicator": "同じアプリの複数のウィンドウをウィンドウ数インジケーターでグループ化します"
},
"HSV": {
"HSV": ""
},
"Health": {
"Health": "健康"
},
"Height to Edge Gap (Exclusive Zone)": {
"Height to Edge Gap (Exclusive Zone)": "エッジギャップまでの高さ(排他ゾーン)"
},
"Hex": {
"Hex": ""
},
"Hex:": {
"Hex:": "16進数:"
},
@@ -1481,6 +1487,9 @@
"Quick note-taking slideout panel": {
"Quick note-taking slideout panel": "クイックノート作成スライドアウトパネル"
},
"RGB": {
"RGB": ""
},
"Rain Chance": {
"Rain Chance": "降水確率"
},

View File

@@ -875,12 +875,18 @@
"Group multiple windows of the same app together with a window count indicator": {
"Group multiple windows of the same app together with a window count indicator": "Grupuj wiele okien tej samej aplikacji ze wskaźnikiem liczby okien"
},
"HSV": {
"HSV": ""
},
"Health": {
"Health": "Zdrowie"
},
"Height to Edge Gap (Exclusive Zone)": {
"Height to Edge Gap (Exclusive Zone)": "Odstęp od krawędzi (strefa wyłączności)"
},
"Hex": {
"Hex": ""
},
"Hex:": {
"Hex:": "Hex:"
},
@@ -1481,6 +1487,9 @@
"Quick note-taking slideout panel": {
"Quick note-taking slideout panel": "Wysuwany panel szybkiego sporządzania notatek"
},
"RGB": {
"RGB": ""
},
"Rain Chance": {
"Rain Chance": "Szansa na deszcz"
},

View File

@@ -875,12 +875,18 @@
"Group multiple windows of the same app together with a window count indicator": {
"Group multiple windows of the same app together with a window count indicator": "Agrupar múltiplas janelas do mesmo app com um indicador de número de janelas"
},
"HSV": {
"HSV": ""
},
"Health": {
"Health": "Saúde"
},
"Height to Edge Gap (Exclusive Zone)": {
"Height to Edge Gap (Exclusive Zone)": "Distância da Borda (Zona Exclusiva)"
},
"Hex": {
"Hex": ""
},
"Hex:": {
"Hex:": "Hex:"
},
@@ -1481,6 +1487,9 @@
"Quick note-taking slideout panel": {
"Quick note-taking slideout panel": "Painel deslizante para anotações rápidas"
},
"RGB": {
"RGB": ""
},
"Rain Chance": {
"Rain Chance": "Chance de Chuva"
},

View File

@@ -875,12 +875,18 @@
"Group multiple windows of the same app together with a window count indicator": {
"Group multiple windows of the same app together with a window count indicator": "Aynı uygulamanın birden fazla penceresini pencere sayısı göstergesi ile gruplayın"
},
"HSV": {
"HSV": ""
},
"Health": {
"Health": "Sağlık"
},
"Height to Edge Gap (Exclusive Zone)": {
"Height to Edge Gap (Exclusive Zone)": "Kenar Boşluğu Yüksekliği (Özel Bölge)"
},
"Hex": {
"Hex": ""
},
"Hex:": {
"Hex:": "Hex:"
},
@@ -1481,6 +1487,9 @@
"Quick note-taking slideout panel": {
"Quick note-taking slideout panel": "Hızlı not alma sürgü paneli"
},
"RGB": {
"RGB": ""
},
"Rain Chance": {
"Rain Chance": "Yağış İhtimali"
},

View File

@@ -875,12 +875,18 @@
"Group multiple windows of the same app together with a window count indicator": {
"Group multiple windows of the same app together with a window count indicator": "将同一应用的多个窗口合并显示,并标注窗口数量"
},
"HSV": {
"HSV": ""
},
"Health": {
"Health": "电池健康"
},
"Height to Edge Gap (Exclusive Zone)": {
"Height to Edge Gap (Exclusive Zone)": "与屏幕边缘的间距(独占区)"
},
"Hex": {
"Hex": ""
},
"Hex:": {
"Hex:": "十六进制颜色码:"
},
@@ -1481,6 +1487,9 @@
"Quick note-taking slideout panel": {
"Quick note-taking slideout panel": "便于快速记便签的侧边栏面板"
},
"RGB": {
"RGB": ""
},
"Rain Chance": {
"Rain Chance": "降雨概率"
},

View File

@@ -875,12 +875,18 @@
"Group multiple windows of the same app together with a window count indicator": {
"Group multiple windows of the same app together with a window count indicator": "將同一應用程式的多個視窗匯集在一起,並附帶視窗數量指示器"
},
"HSV": {
"HSV": ""
},
"Health": {
"Health": "健康狀態"
},
"Height to Edge Gap (Exclusive Zone)": {
"Height to Edge Gap (Exclusive Zone)": "邊緣間隙高度 (獨佔區域)"
},
"Hex": {
"Hex": ""
},
"Hex:": {
"Hex:": "色碼:"
},
@@ -1481,6 +1487,9 @@
"Quick note-taking slideout panel": {
"Quick note-taking slideout panel": "快速筆記滑出面板"
},
"RGB": {
"RGB": ""
},
"Rain Chance": {
"Rain Chance": "降雨機率"
},

View File

@@ -209,13 +209,6 @@
"reference": "",
"comment": ""
},
{
"term": "Apply",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Apply GTK Colors",
"translation": "",
@@ -1042,13 +1035,6 @@
"reference": "",
"comment": ""
},
{
"term": "Copy",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Copy PID",
"translation": "",
@@ -2001,6 +1987,13 @@
"reference": "",
"comment": ""
},
{
"term": "HSV",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Health",
"translation": "",
@@ -2016,7 +2009,7 @@
"comment": ""
},
{
"term": "Hex:",
"term": "Hex",
"translation": "",
"context": "",
"reference": "",
@@ -3387,6 +3380,13 @@
"reference": "",
"comment": ""
},
{
"term": "RGB",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Rain Chance",
"translation": "",