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() } } } }