From 3843720e063be0e7b577b65b143c88dd83725cf9 Mon Sep 17 00:00:00 2001 From: baiYue Date: Tue, 27 Jan 2026 20:35:16 +0800 Subject: [PATCH] add baseType QPoint/QRect/QSize/bool to lib propertyEditor --- PropertyEditor/resources.qrc | 4 + .../resources/Qml/ValueEditor/BoolBox.qml | 184 +++++++++ .../resources/Qml/ValueEditor/PointFBox.qml | 184 +++++++++ .../resources/Qml/ValueEditor/RectFBox.qml | 136 +++++++ .../resources/Qml/ValueEditor/SizeFBox.qml | 372 ++++++++++++++++++ .../src/QQuickDetailsViewBasicTypeEditor.cpp | 182 +++++++++ 6 files changed, 1062 insertions(+) create mode 100644 PropertyEditor/resources/Qml/ValueEditor/BoolBox.qml create mode 100644 PropertyEditor/resources/Qml/ValueEditor/PointFBox.qml create mode 100644 PropertyEditor/resources/Qml/ValueEditor/RectFBox.qml create mode 100644 PropertyEditor/resources/Qml/ValueEditor/SizeFBox.qml diff --git a/PropertyEditor/resources.qrc b/PropertyEditor/resources.qrc index 55b790d..0a0e6cc 100644 --- a/PropertyEditor/resources.qrc +++ b/PropertyEditor/resources.qrc @@ -23,5 +23,9 @@ resources/Qml/ValueEditor/FileSelector.qml resources/Qml/ValueEditor/LineTextBox.qml resources/Qml/ValueEditor/MultiLineTextBox.qml + resources/Qml/ValueEditor/PointFBox.qml + resources/Qml/ValueEditor/RectFBox.qml + resources/Qml/ValueEditor/SizeFBox.qml + resources/Qml/ValueEditor/BoolBox.qml diff --git a/PropertyEditor/resources/Qml/ValueEditor/BoolBox.qml b/PropertyEditor/resources/Qml/ValueEditor/BoolBox.qml new file mode 100644 index 0000000..828f24a --- /dev/null +++ b/PropertyEditor/resources/Qml/ValueEditor/BoolBox.qml @@ -0,0 +1,184 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Shapes + +Item { + id: control + + // 保持与框架一致的接口 + property var value: false + property int decimals: 0 + property string text: "Enabled" + property color textColor: "black" + property color checkedColor: "#2196F3" + property color uncheckedColor: "#cccccc" + property color checkedBoxColor: "white" + property color uncheckedBoxColor: "white" + property int boxSize: 16 + property int spacing: 8 + property int textSize: 12 + property alias font: label.font + + // 与框架一致的信号 + signal asValueChanged(value: var) + signal boolValueChanged(bool checked) // 辅助信号,避免与内置信号冲突 + + implicitHeight: Math.max(boxSize, label.implicitHeight) + implicitWidth: boxSize + spacing + label.implicitWidth + + function toggle() { + var newValue = !getBoolValue() + setValue(newValue) + } + + function setValue(newValue) { + var boolValue = getBoolValue() + var newBoolValue = toBool(newValue) + + if (boolValue !== newBoolValue) { + value = newBoolValue + boolValueChanged(newBoolValue) + asValueChanged(newBoolValue) + } + } + + function getBoolValue() { + return toBool(value) + } + + function toBool(value) { + if (typeof value === 'boolean') { + return value + } else if (typeof value === 'number') { + return value !== 0 + } else if (typeof value === 'string') { + var str = value.toString().toLowerCase() + return str === 'true' || str === '1' || str === 'on' + } + return false + } + + // 整个区域的点击事件 + MouseArea { + anchors.fill: parent + + onClicked: function(mouse) { + control.toggle() + mouse.accepted = true + } + } + + RowLayout { + anchors.fill: parent + spacing: control.spacing + + // 复选框 + Rectangle { + id: checkBox + width: control.boxSize + height: control.boxSize + radius: 3 + border.color: getBoolValue() ? control.checkedColor : control.uncheckedColor + border.width: 1 + color: getBoolValue() ? control.checkedColor : control.uncheckedBoxColor + + Layout.alignment: Qt.AlignVCenter + + // 勾选标记 + Shape { + anchors.centerIn: parent + width: 10 + height: 8 + visible: getBoolValue() + + ShapePath { + strokeColor: "transparent" + fillColor: control.checkedBoxColor + strokeWidth: 0 + + PathMove { x: 0; y: 4 } + PathLine { x: 4; y: 8 } + PathLine { x: 10; y: 0 } + PathLine { x: 9; y: 0 } + PathLine { x: 4; y: 7 } + PathLine { x: 1; y: 4 } + } + } + + // 悬停效果 + Rectangle { + anchors.fill: parent + radius: parent.radius + color: "transparent" + border.color: "#888888" + border.width: boxMouseArea.containsMouse ? 1 : 0 + opacity: boxMouseArea.containsMouse ? 0.3 : 0 + } + + // 复选框自身的点击事件 + MouseArea { + id: boxMouseArea + anchors.fill: parent + hoverEnabled: true + + onClicked: function(mouse) { + control.toggle() + mouse.accepted = true + } + } + } + + // 标签文本 + Label { + id: label + text: control.text + color: control.textColor + font.pixelSize: control.textSize + verticalAlignment: Text.AlignVCenter + + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + + // 鼠标悬停在文本上时的点击事件 + MouseArea { + anchors.fill: parent + + onClicked: function(mouse) { + control.toggle() + mouse.accepted = true + } + } + } + } + + // 键盘支持 + Keys.onPressed: function(event) { + if (event.key === Qt.Key_Space || event.key === Qt.Key_Return) { + control.toggle() + event.accepted = true + } + } + + // 聚焦支持 + activeFocusOnTab: true + + // 聚焦时的边框 + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: control.activeFocus ? "#2196F3" : "transparent" + border.width: 2 + radius: 2 + visible: control.activeFocus + } + + // 当value从外部改变时,更新显示 + onValueChanged: { + var boolValue = getBoolValue() + if (checkBox.border.color !== (boolValue ? control.checkedColor : control.uncheckedColor)) { + checkBox.border.color = boolValue ? control.checkedColor : control.uncheckedColor + checkBox.color = boolValue ? control.checkedColor : control.uncheckedBoxColor + } + } +} diff --git a/PropertyEditor/resources/Qml/ValueEditor/PointFBox.qml b/PropertyEditor/resources/Qml/ValueEditor/PointFBox.qml new file mode 100644 index 0000000..c323fbe --- /dev/null +++ b/PropertyEditor/resources/Qml/ValueEditor/PointFBox.qml @@ -0,0 +1,184 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: control + + property var value: Qt.point(0, 0) + property int decimals: 2 + implicitHeight: 25 + implicitWidth: 120 // 设置默认宽度 + + signal asValueChanged(value: var) + + function setValue(newValue: var) { + if (!control.value || + Math.abs(control.value.x - newValue.x) > 0.000001 || + Math.abs(control.value.y - newValue.y) > 0.000001) { + value = newValue + asValueChanged(value) + } + } + + RowLayout { + anchors.fill: parent + spacing: 4 // 减小间距 + + Label { + text: "X:" + Layout.alignment: Qt.AlignVCenter + font.pixelSize: 10 + } + + TextField { + id: xBox + Layout.preferredWidth: 60 // 减小宽度 + Layout.preferredHeight: 22 + Layout.alignment: Qt.AlignVCenter + text: control.value ? control.value.x.toFixed(control.decimals) : "0.00" + font.pixelSize: 10 + leftPadding: 4 + rightPadding: 4 + selectByMouse: true + + // 双击全选的处理 + MouseArea { + id: xMouseArea + anchors.fill: parent + propagateComposedEvents: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.IBeamCursor + + onDoubleClicked: function(mouse) { + parent.selectAll() + parent.forceActiveFocus() + mouse.accepted = true + } + + onClicked: function(mouse) { + // 单击时设置焦点但不全选 + parent.forceActiveFocus() + mouse.accepted = false + } + } + + onActiveFocusChanged: { + if (activeFocus) { + // 如果不是双击触发的焦点变化,就全选文本 + if (!xMouseArea.containsPress) { + selectAll() + } + } + } + + validator: DoubleValidator { + bottom: -999999 + top: 999999 + decimals: 2 + } + + background: Rectangle { + color: xBox.enabled ? "white" : "#f0f0f0" + border.color: xBox.activeFocus ? "#2196F3" : "#cccccc" + border.width: 1 + radius: 2 + } + + onEditingFinished: { + var xValue = parseFloat(text) + if (!isNaN(xValue) && control.value) { + control.setValue(Qt.point(xValue, control.value.y)) + } else { + xBox.text = control.value ? control.value.x.toFixed(control.decimals) : "0.00" + } + } + } + + Label { + text: "Y:" + Layout.alignment: Qt.AlignVCenter + font.pixelSize: 10 + } + + TextField { + id: yBox + Layout.preferredWidth: 60 + Layout.preferredHeight: 22 + Layout.alignment: Qt.AlignVCenter + text: control.value ? control.value.y.toFixed(control.decimals) : "0.00" + font.pixelSize: 10 + leftPadding: 4 + rightPadding: 4 + selectByMouse: true + + // 双击全选的处理 + MouseArea { + id: yMouseArea + anchors.fill: parent + propagateComposedEvents: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.IBeamCursor + + onDoubleClicked: function(mouse) { + parent.selectAll() + parent.forceActiveFocus() + mouse.accepted = true + } + + onClicked: function(mouse) { + // 单击时设置焦点但不全选 + parent.forceActiveFocus() + mouse.accepted = false + } + } + + onActiveFocusChanged: { + if (activeFocus) { + // 如果不是双击触发的焦点变化,就全选文本 + if (!yMouseArea.containsPress) { + selectAll() + } + } + } + + validator: DoubleValidator { + bottom: -999999 + top: 999999 + decimals: 2 + } + + background: Rectangle { + color: yBox.enabled ? "white" : "#f0f0f0" + border.color: yBox.activeFocus ? "#2196F3" : "#cccccc" + border.width: 1 + radius: 2 + } + + onEditingFinished: { + var yValue = parseFloat(text) + if (!isNaN(yValue) && control.value) { + control.setValue(Qt.point(control.value.x, yValue)) + } else { + yBox.text = control.value ? control.value.y.toFixed(control.decimals) : "0.00" + } + } + } + + Item { + Layout.fillWidth: true + } + } + + // 当value从外部改变时,更新输入框显示 + onValueChanged: { + if (value) { + if (!xBox.activeFocus) { + xBox.text = value.x.toFixed(decimals) + } + if (!yBox.activeFocus) { + yBox.text = value.y.toFixed(decimals) + } + } + } +} diff --git a/PropertyEditor/resources/Qml/ValueEditor/RectFBox.qml b/PropertyEditor/resources/Qml/ValueEditor/RectFBox.qml new file mode 100644 index 0000000..e194763 --- /dev/null +++ b/PropertyEditor/resources/Qml/ValueEditor/RectFBox.qml @@ -0,0 +1,136 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: control + + property var value: Qt.rect(0, 0, 0, 0) + property int decimals: 1 + implicitHeight: 25 + implicitWidth: 240 + + signal asValueChanged(value: var) + + function setValue(newValue) { + if (!control.value || + Math.abs(control.value.x - newValue.x) > 0.000001 || + Math.abs(control.value.y - newValue.y) > 0.000001 || + Math.abs(control.value.width - newValue.width) > 0.000001 || + Math.abs(control.value.height - newValue.height) > 0.000001) { + value = newValue + asValueChanged(value) + } + } + + RowLayout { + anchors.fill: parent + spacing: 2 + + Repeater { + id: repeater + model: [ + { label: "X", prop: "x", validator: [-999999, 999999] }, + { label: "Y", prop: "y", validator: [-999999, 999999] }, + { label: "W", prop: "width", validator: [0, 999999] }, + { label: "H", prop: "height", validator: [0, 999999] } + ] + + RowLayout { + id: inputRow + spacing: 2 + Layout.alignment: Qt.AlignVCenter + + property string propertyName: modelData.prop + property var textField: inputField + + Label { + text: modelData.label + ":" + font.pixelSize: 10 + } + + TextField { + id: inputField + Layout.preferredWidth: 60 + Layout.preferredHeight: 22 + text: control.value ? control.value[modelData.prop].toFixed(control.decimals) : "0.0" + font.pixelSize: 9 + padding: 2 + selectByMouse: true + + // 双击全选的处理 + MouseArea { + id: fieldMouseArea + anchors.fill: parent + propagateComposedEvents: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.IBeamCursor + + onDoubleClicked: function(mouse) { + parent.selectAll() + parent.forceActiveFocus() + mouse.accepted = true + } + + onClicked: function(mouse) { + // 单击时设置焦点但不全选 + parent.forceActiveFocus() + mouse.accepted = false + } + } + + onActiveFocusChanged: { + if (activeFocus) { + // 如果不是双击触发的焦点变化,就全选文本 + if (!fieldMouseArea.containsPress) { + selectAll() + } + } + } + + validator: DoubleValidator { + bottom: modelData.validator[0] + top: modelData.validator[1] + decimals: 2 + } + + background: Rectangle { + border.color: parent.activeFocus ? "#0066cc" : "#999999" + border.width: 1 + radius: 1 + } + + onEditingFinished: { + var val = parseFloat(text) + if (!isNaN(val) && control.value) { + var newRect = Qt.rect( + modelData.prop === "x" ? val : control.value.x, + modelData.prop === "y" ? val : control.value.y, + modelData.prop === "width" ? val : control.value.width, + modelData.prop === "height" ? val : control.value.height + ) + control.setValue(newRect) + } else { + text = control.value ? control.value[modelData.prop].toFixed(control.decimals) : "0.0" + } + } + } + } + } + + Item { Layout.fillWidth: true } + } + + onValueChanged: { + if (!value) return + + // 通过 Repeater 的 itemAt 方法安全访问 + var props = ["x", "y", "width", "height"] + for (var i = 0; i < props.length; i++) { + var item = repeater.itemAt(i) + if (item && item.textField && !item.textField.activeFocus) { + item.textField.text = value[props[i]].toFixed(decimals) + } + } + } +} diff --git a/PropertyEditor/resources/Qml/ValueEditor/SizeFBox.qml b/PropertyEditor/resources/Qml/ValueEditor/SizeFBox.qml new file mode 100644 index 0000000..ce347cc --- /dev/null +++ b/PropertyEditor/resources/Qml/ValueEditor/SizeFBox.qml @@ -0,0 +1,372 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: control + + // 属性定义 + property var value: Qt.size(0, 0) // QSizeF + property int decimals: 1 // 默认小数位为1 + property int precision: 2 // 精度,允许的小数位数 + + // 尺寸相关属性 + property real minWidth: 0 + property real maxWidth: 999999 + property real minHeight: 0 + property real maxHeight: 999999 + + // 步进增量 + property real widthStep: 1.0 + property real heightStep: 1.0 + + // 是否显示步进按钮 + property bool showSpinButtons: true + + implicitHeight: 25 + implicitWidth: showSpinButtons ? 140 : 120 + + // 信号 - 重命名避免与内置信号冲突 + signal asValueChanged(value: var) + signal sizeWidthChanged(width: real) // 改为 sizeWidthChanged + signal sizeHeightChanged(height: real) // 改为 sizeHeightChanged + + // 获取宽高 + function getWidth() { + return value ? value.width : 0 + } + + function getHeight() { + return value ? value.height : 0 + } + + // 设置值 + function setValue(newValue: var) { + if (!control.value || + Math.abs(control.value.width - newValue.width) > 0.000001 || + Math.abs(control.value.height - newValue.height) > 0.000001) { + + // 应用边界限制 + var limitedWidth = Math.max(minWidth, Math.min(maxWidth, newValue.width)) + var limitedHeight = Math.max(minHeight, Math.min(maxHeight, newValue.height)) + + // 保留精度 + limitedWidth = parseFloat(limitedWidth.toFixed(precision)) + limitedHeight = parseFloat(limitedHeight.toFixed(precision)) + + value = Qt.size(limitedWidth, limitedHeight) + asValueChanged(value) + } + } + + // 设置宽度 + function setWidth(width: real) { + if (control.value && Math.abs(control.value.width - width) > 0.000001) { + var limitedWidth = Math.max(minWidth, Math.min(maxWidth, width)) + limitedWidth = parseFloat(limitedWidth.toFixed(precision)) + control.setValue(Qt.size(limitedWidth, control.value.height)) + } + } + + // 设置高度 + function setHeight(height: real) { + if (control.value && Math.abs(control.value.height - height) > 0.000001) { + var limitedHeight = Math.max(minHeight, Math.min(maxHeight, height)) + limitedHeight = parseFloat(limitedHeight.toFixed(precision)) + control.setValue(Qt.size(control.value.width, limitedHeight)) + } + } + + // 步进增加/减少 + function stepWidth(positive: bool) { + if (!control.value) return + var step = positive ? widthStep : -widthStep + setWidth(getWidth() + step) + } + + function stepHeight(positive: bool) { + if (!control.value) return + var step = positive ? heightStep : -heightStep + setHeight(getHeight() + step) + } + + // UI布局 + RowLayout { + anchors.fill: parent + spacing: 4 + + // 宽度部分 + Label { + text: "W:" + Layout.alignment: Qt.AlignVCenter + font.pixelSize: 10 + } + + TextField { + id: widthBox + Layout.preferredWidth: 60 + Layout.preferredHeight: 22 + Layout.alignment: Qt.AlignVCenter + selectByMouse: true // 允许鼠标选择文本 + + text: control.value ? control.value.width.toFixed(control.decimals) : "0.0" + font.pixelSize: 10 + leftPadding: 4 + rightPadding: 4 + + // 双击全选的处理 + MouseArea { + id: widthMouseArea + anchors.fill: parent + propagateComposedEvents: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.IBeamCursor + + onDoubleClicked: function(mouse) { + parent.selectAll() + parent.forceActiveFocus() + mouse.accepted = true + } + + onClicked: function(mouse) { + // 单击时设置焦点但不全选 + parent.forceActiveFocus() + mouse.accepted = false + } + } + + onActiveFocusChanged: { + if (activeFocus) { + // 如果不是双击触发的焦点变化,就全选文本 + if (!widthMouseArea.containsPress) { + selectAll() + } + } + } + + // 验证器 + validator: DoubleValidator { + bottom: control.minWidth + top: control.maxWidth + decimals: control.precision + notation: DoubleValidator.StandardNotation + } + + background: Rectangle { + color: widthBox.enabled ? "white" : "#f0f0f0" + border.color: widthBox.activeFocus ? "#2196F3" : "#cccccc" + border.width: 1 + radius: 2 + } + + onEditingFinished: { + var num = parseFloat(text) + if (!isNaN(num) && control.value) { + control.setWidth(num) + } else { + // 恢复原值 + widthBox.text = control.value ? + control.value.width.toFixed(control.decimals) : + "0.0" + } + } + + // 键盘上下键调整 + Keys.onUpPressed: function(event) { + control.stepWidth(true) + event.accepted = true + } + + Keys.onDownPressed: function(event) { + control.stepWidth(false) + event.accepted = true + } + } + + // 宽度步进按钮 + Row { + visible: control.showSpinButtons + spacing: 0 + Layout.alignment: Qt.AlignVCenter + + Button { + width: 12 + height: 11 + text: "▲" + font.pixelSize: 6 + padding: 0 + onClicked: control.stepWidth(true) + + background: Rectangle { + color: parent.hovered ? "#e0e0e0" : "transparent" + border.color: "#cccccc" + border.width: 1 + radius: 2 + } + } + + Button { + width: 12 + height: 11 + text: "▼" + font.pixelSize: 6 + padding: 0 + onClicked: control.stepWidth(false) + + background: Rectangle { + color: parent.hovered ? "#e0e0e0" : "transparent" + border.color: "#cccccc" + border.width: 1 + radius: 2 + } + } + } + + // 高度部分 + Label { + text: "H:" + Layout.alignment: Qt.AlignVCenter + font.pixelSize: 10 + } + + TextField { + id: heightBox + Layout.preferredWidth: 60 + Layout.preferredHeight: 22 + Layout.alignment: Qt.AlignVCenter + selectByMouse: true // 允许鼠标选择文本 + + text: control.value ? control.value.height.toFixed(control.decimals) : "0.0" + font.pixelSize: 10 + leftPadding: 4 + rightPadding: 4 + + // 双击全选的处理 + MouseArea { + id: heightMouseArea + anchors.fill: parent + propagateComposedEvents: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.IBeamCursor + + onDoubleClicked: function(mouse) { + parent.selectAll() + parent.forceActiveFocus() + mouse.accepted = true + } + + onClicked: function(mouse) { + // 单击时设置焦点但不全选 + parent.forceActiveFocus() + mouse.accepted = false + } + } + + onActiveFocusChanged: { + if (activeFocus) { + // 如果不是双击触发的焦点变化,就全选文本 + if (!heightMouseArea.containsPress) { + selectAll() + } + } + } + + // 验证器 + validator: DoubleValidator { + bottom: control.minHeight + top: control.maxHeight + decimals: control.precision + notation: DoubleValidator.StandardNotation + } + + background: Rectangle { + color: heightBox.enabled ? "white" : "#f0f0f0" + border.color: heightBox.activeFocus ? "#2196F3" : "#cccccc" + border.width: 1 + radius: 2 + } + + onEditingFinished: { + var num = parseFloat(text) + if (!isNaN(num) && control.value) { + control.setHeight(num) + } else { + // 恢复原值 + heightBox.text = control.value ? + control.value.height.toFixed(control.decimals) : + "0.0" + } + } + + // 键盘上下键调整 + Keys.onUpPressed: function(event) { + control.stepHeight(true) + event.accepted = true + } + + Keys.onDownPressed: function(event) { + control.stepHeight(false) + event.accepted = true + } + } + + // 高度步进按钮 + Row { + visible: control.showSpinButtons + spacing: 0 + Layout.alignment: Qt.AlignVCenter + + Button { + width: 12 + height: 11 + text: "▲" + font.pixelSize: 6 + padding: 0 + onClicked: control.stepHeight(true) + + background: Rectangle { + color: parent.hovered ? "#e0e0e0" : "transparent" + border.color: "#cccccc" + border.width: 1 + radius: 2 + } + } + + Button { + width: 12 + height: 11 + text: "▼" + font.pixelSize: 6 + padding: 0 + onClicked: control.stepHeight(false) + + background: Rectangle { + color: parent.hovered ? "#e0e0e0" : "transparent" + border.color: "#cccccc" + border.width: 1 + radius: 2 + } + } + } + + Item { + Layout.fillWidth: true + } + } + + // 当value从外部改变时,更新输入框显示 + onValueChanged: { + if (value) { + if (!widthBox.activeFocus) { + widthBox.text = value.width.toFixed(decimals) + } + if (!heightBox.activeFocus) { + heightBox.text = value.height.toFixed(decimals) + } + + // 发出单独的宽高变化信号 + sizeWidthChanged(value.width) + sizeHeightChanged(value.height) + } + } +} diff --git a/PropertyEditor/source/src/QQuickDetailsViewBasicTypeEditor.cpp b/PropertyEditor/source/src/QQuickDetailsViewBasicTypeEditor.cpp index 4933e8a..727f6d2 100644 --- a/PropertyEditor/source/src/QQuickDetailsViewBasicTypeEditor.cpp +++ b/PropertyEditor/source/src/QQuickDetailsViewBasicTypeEditor.cpp @@ -162,6 +162,188 @@ void QQuickDetailsViewManager::RegisterBasicTypeEditor() { return valueEditor; }); + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { + QQmlEngine* engine = qmlEngine(parent); + QQmlContext* context = qmlContext(parent); + QQmlComponent comp(engine); + comp.setData(R"( + import QtQuick; + import QtQuick.Controls; + import "qrc:/resources/Qml/ValueEditor" + BoolBox{ + anchors.verticalCenter: parent.verticalCenter + width: parent.width + } + )", QUrl()); + QVariantMap initialProperties; + initialProperties["parent"] = QVariant::fromValue(parent); + auto valueEditor = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); + if (!comp.errors().isEmpty()) { + qDebug() << comp.errorString(); + } + valueEditor->setParentItem(parent); + valueEditor->setProperty("value", handle->getVar()); + connect(valueEditor, SIGNAL(asValueChanged(QVariant)), handle, SLOT(setVar(QVariant))); + connect(handle, SIGNAL(asRequestRollback(QVariant)), valueEditor, SLOT(setValue(QVariant))); + return valueEditor; + }); + + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { + QQmlEngine* engine = qmlEngine(parent); + QQmlContext* context = qmlContext(parent); + QQmlComponent comp(engine); + comp.setData(R"( + import QtQuick; + import QtQuick.Controls; + import "qrc:/resources/Qml/ValueEditor" + PointFBox{ + anchors.verticalCenter: parent.verticalCenter + width: parent.width + } + )", QUrl()); + QVariantMap initialProperties; + initialProperties["parent"] = QVariant::fromValue(parent); + auto valueEditor = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); + if (!comp.errors().isEmpty()) { + qDebug() << comp.errorString(); + } + valueEditor->setParentItem(parent); + valueEditor->setProperty("value", handle->getVar()); + connect(valueEditor, SIGNAL(asValueChanged(QVariant)), handle, SLOT(setVar(QVariant))); + connect(handle, SIGNAL(asRequestRollback(QVariant)), valueEditor, SLOT(setValue(QVariant))); + return valueEditor; + }); + + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { + QQmlEngine* engine = qmlEngine(parent); + QQmlContext* context = qmlContext(parent); + QQmlComponent comp(engine); + comp.setData(R"( + import QtQuick; + import QtQuick.Controls; + import "qrc:/resources/Qml/ValueEditor" + PointFBox{ + anchors.verticalCenter: parent.verticalCenter + width: parent.width + } + )", QUrl()); + QVariantMap initialProperties; + initialProperties["parent"] = QVariant::fromValue(parent); + auto valueEditor = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); + if (!comp.errors().isEmpty()) { + qDebug() << comp.errorString(); + } + valueEditor->setParentItem(parent); + valueEditor->setProperty("value", handle->getVar()); + connect(valueEditor, SIGNAL(asValueChanged(QVariant)), handle, SLOT(setVar(QVariant))); + connect(handle, SIGNAL(asRequestRollback(QVariant)), valueEditor, SLOT(setValue(QVariant))); + return valueEditor; + }); + + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { + QQmlEngine* engine = qmlEngine(parent); + QQmlContext* context = qmlContext(parent); + QQmlComponent comp(engine); + comp.setData(R"( + import QtQuick; + import QtQuick.Controls; + import "qrc:/resources/Qml/ValueEditor" + RectFBox{ + anchors.verticalCenter: parent.verticalCenter + width: parent.width + } + )", QUrl()); + QVariantMap initialProperties; + initialProperties["parent"] = QVariant::fromValue(parent); + auto valueEditor = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); + if (!comp.errors().isEmpty()) { + qDebug() << comp.errorString(); + } + valueEditor->setParentItem(parent); + valueEditor->setProperty("value", handle->getVar()); + connect(valueEditor, SIGNAL(asValueChanged(QVariant)), handle, SLOT(setVar(QVariant))); + connect(handle, SIGNAL(asRequestRollback(QVariant)), valueEditor, SLOT(setValue(QVariant))); + return valueEditor; + }); + + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { + QQmlEngine* engine = qmlEngine(parent); + QQmlContext* context = qmlContext(parent); + QQmlComponent comp(engine); + comp.setData(R"( + import QtQuick; + import QtQuick.Controls; + import "qrc:/resources/Qml/ValueEditor" + RectFBox{ + anchors.verticalCenter: parent.verticalCenter + width: parent.width + } + )", QUrl()); + QVariantMap initialProperties; + initialProperties["parent"] = QVariant::fromValue(parent); + auto valueEditor = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); + if (!comp.errors().isEmpty()) { + qDebug() << comp.errorString(); + } + valueEditor->setParentItem(parent); + valueEditor->setProperty("value", handle->getVar()); + connect(valueEditor, SIGNAL(asValueChanged(QVariant)), handle, SLOT(setVar(QVariant))); + connect(handle, SIGNAL(asRequestRollback(QVariant)), valueEditor, SLOT(setValue(QVariant))); + return valueEditor; + }); + + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { + QQmlEngine* engine = qmlEngine(parent); + QQmlContext* context = qmlContext(parent); + QQmlComponent comp(engine); + comp.setData(R"( + import QtQuick; + import QtQuick.Controls; + import "qrc:/resources/Qml/ValueEditor" + SizeFBox{ + anchors.verticalCenter: parent.verticalCenter + width: parent.width + } + )", QUrl()); + QVariantMap initialProperties; + initialProperties["parent"] = QVariant::fromValue(parent); + auto valueEditor = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); + if (!comp.errors().isEmpty()) { + qDebug() << comp.errorString(); + } + valueEditor->setParentItem(parent); + valueEditor->setProperty("value", handle->getVar()); + connect(valueEditor, SIGNAL(asValueChanged(QVariant)), handle, SLOT(setVar(QVariant))); + connect(handle, SIGNAL(asRequestRollback(QVariant)), valueEditor, SLOT(setValue(QVariant))); + return valueEditor; + }); + + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { + QQmlEngine* engine = qmlEngine(parent); + QQmlContext* context = qmlContext(parent); + QQmlComponent comp(engine); + comp.setData(R"( + import QtQuick; + import QtQuick.Controls; + import "qrc:/resources/Qml/ValueEditor" + SizeFBox{ + anchors.verticalCenter: parent.verticalCenter + width: parent.width + } + )", QUrl()); + QVariantMap initialProperties; + initialProperties["parent"] = QVariant::fromValue(parent); + auto valueEditor = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); + if (!comp.errors().isEmpty()) { + qDebug() << comp.errorString(); + } + valueEditor->setParentItem(parent); + valueEditor->setProperty("value", handle->getVar()); + connect(valueEditor, SIGNAL(asValueChanged(QVariant)), handle, SLOT(setVar(QVariant))); + connect(handle, SIGNAL(asRequestRollback(QVariant)), valueEditor, SLOT(setValue(QVariant))); + return valueEditor; + }); + registerTypeEditor(QMetaType::fromType(), [](QPropertyHandle* handle, QQuickItem* parent)->QQuickItem* { QQmlEngine* engine = qmlEngine(parent); QQmlContext* context = qmlContext(parent);