Files
Button/qml/components/ColorPickerField.qml
T
2026-07-21 14:34:39 +03:00

169 lines
4.5 KiB
QML

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
RowLayout {
id: root
property string label: ""
property string hex: "#ffffff"
readonly property color swatchColor: hex
signal colorChanged(string hex)
readonly property var palette: [
"#000000", "#333333", "#666666", "#999999", "#cccccc", "#ffffff",
"#7b007b", "#00007b", "#4a0080", "#990099", "#cc00cc", "#ff66ff",
"#004400", "#006622", "#00aa44", "#00cc44", "#33ff66", "#aaffaa",
"#440000", "#881100", "#cc2200", "#ff4400", "#ff8844", "#ffcccc",
"#003366", "#0066cc", "#0088ff", "#44aaff", "#aaccff", "#ffff00",
"#ffaa00", "#884400"
]
function normalizeHex(s) {
if (!s)
return ""
s = String(s).trim()
if (s.charAt(0) !== "#")
s = "#" + s
if (/^#[0-9a-fA-F]{3}$/.test(s)) {
return ("#" + s.charAt(1) + s.charAt(1)
+ s.charAt(2) + s.charAt(2)
+ s.charAt(3) + s.charAt(3)).toLowerCase()
}
if (/^#[0-9a-fA-F]{6}$/.test(s))
return s.toLowerCase()
return ""
}
function pickColor(h) {
var n = normalizeHex(h)
if (!n)
return
hex = n
hexField.text = n
colorChanged(n)
}
Layout.fillWidth: true
spacing: 10
Text {
text: root.label
color: "#ffffff"
Layout.preferredWidth: 150
visible: root.label !== ""
}
Rectangle {
id: swatch
width: 36
height: 36
radius: 18
color: root.swatchColor
border.color: "#80ffffff"
border.width: 1
MouseArea {
anchors.fill: parent
onClicked: {
hexField.text = root.hex
pickerPopup.open()
}
}
}
Text {
Layout.fillWidth: true
text: root.hex
color: "#cccccc"
font.pixelSize: 12
elide: Text.ElideRight
}
Popup {
id: pickerPopup
modal: true
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
width: Math.min(300, root.width > 0 ? root.width : 300)
padding: 12
background: Rectangle {
color: "#161628"
radius: 6
border.color: "#80ffffff"
border.width: 1
}
contentItem: ColumnLayout {
spacing: 10
width: parent.width
Text {
Layout.fillWidth: true
text: root.label !== "" ? root.label : "Цвет"
color: "#ffffff"
font.pixelSize: 14
font.bold: true
}
GridLayout {
Layout.fillWidth: true
columns: 6
rowSpacing: 6
columnSpacing: 6
Repeater {
model: root.palette
delegate: Rectangle {
Layout.preferredWidth: 36
Layout.preferredHeight: 36
radius: 6
color: modelData
border.color: root.hex === modelData ? "#ffffff" : "#40ffffff"
border.width: root.hex === modelData ? 2 : 1
MouseArea {
anchors.fill: parent
onClicked: root.pickColor(modelData)
}
}
}
}
RowLayout {
Layout.fillWidth: true
spacing: 8
Text {
text: "#"
color: "#ffffff"
}
TextField {
id: hexField
Layout.fillWidth: true
placeholderText: "RRGGBB"
color: "#ffffff"
selectByMouse: true
onEditingFinished: root.pickColor(text)
}
Rectangle {
width: 32
height: 32
radius: 4
color: root.normalizeHex(hexField.text) || root.swatchColor
border.color: "#80ffffff"
border.width: 1
}
}
Button {
Layout.fillWidth: true
text: "Готово"
onClicked: pickerPopup.close()
}
}
}
}