DiagramDesigner/PropertyEditor/resources/Qml/ValueEditor/BoolBox.qml

185 lines
5.1 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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