AntiClipSettings/qml/DeviceView.qml

417 lines
17 KiB
QML

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import AntiClipSettings 1.0
Item {
id: root
property alias enabled: shieldedRow.enabled
property int dargWidth: 12
property color openDoorAreaColor: "#0FF40D" // 绿色
property var openDoorAreaPoints: []
property int openDoorAreaWay: 0
property color shieldedAreaColor: "yellow"
property var shieldedAreaPoints: []
property bool shieldedAreaEnabled: false
property color antiClipAreaColor: "blue"
property var antiClipAreaPoints: []
property bool antiClipAreaEnabled: false
property int antiClipSensitivity: 1
property alias flip: flipSwitch.checked
property alias videoRotation: rotateComboBox.currentIndex
Item {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: controlBar.top
Image {
id: image
anchors.centerIn: parent
cache: false
fillMode: Image.PreserveAspectFit
source: "image://videoframe/"
property real aspectRatio: 16 / 9
width: Math.min(parent.width, parent.height * aspectRatio)
height: width / aspectRatio
enabled: root.enabled
Canvas {
id: canvas
anchors.fill: parent
onPaint: {
var ctx = canvas.getContext("2d")
ctx.clearRect(0, 0, canvas.width, canvas.height)
if(!root.enabled)return
if(openDoorAreaWay == DeviceConnection.FullArea){
ctx.strokeStyle = openDoorAreaColor
ctx.lineWidth = 8
ctx.strokeRect(0,0, canvas.width,
canvas.height)
} else if ((openDoorAreaWay>=DeviceConnection.Quadrangle) &&(openDoorAreaPoints.length > 0)) {
ctx.strokeStyle = openDoorAreaColor
ctx.lineWidth = 2
ctx.beginPath()
let point = scaledPoint(openDoorAreaPoints[0],
width, height)
ctx.moveTo(point.x, point.y)
for (var i = 1; i < openDoorAreaPoints.length; i++) {
point = scaledPoint(openDoorAreaPoints[i],
width, height)
ctx.lineTo(point.x, point.y)
}
ctx.closePath()
ctx.stroke()
}
if (antiClipAreaEnabled && (antiClipAreaPoints.length > 0)) {
ctx.strokeStyle = antiClipAreaColor
ctx.lineWidth = 2
ctx.beginPath()
let point = scaledPoint(antiClipAreaPoints[0],
width, height)
ctx.moveTo(point.x, point.y)
for (var i = 1; i < antiClipAreaPoints.length; i++) {
point = scaledPoint(antiClipAreaPoints[i],
width, height)
ctx.lineTo(point.x, point.y)
}
ctx.closePath()
ctx.stroke()
}
if (shieldedAreaEnabled &&(shieldedAreaPoints.length > 0)) {
ctx.lineWidth = 2
ctx.strokeStyle = shieldedAreaColor
let point0 = scaledPoint(shieldedAreaPoints[0],
width, height)
let point1 = scaledPoint(shieldedAreaPoints[1],
width, height)
let point2 = scaledPoint(shieldedAreaPoints[2],
width, height)
let point3 = scaledPoint(shieldedAreaPoints[3],
width, height)
ctx.strokeRect(point0.x, point0.y, point1.x - point0.x,
point1.y - point0.y)
ctx.strokeRect(point2.x, point2.y, point3.x - point2.x,
point3.y - point2.y)
}
}
}
Repeater {
id: repeater
visible: openDoorAreaWay>=DeviceConnection.Quadrangle
model: openDoorAreaPoints
delegate: Rectangle {
width: dargWidth
height: dargWidth
visible: root.enabled &&(openDoorAreaWay>=DeviceConnection.Quadrangle)
color: openDoorAreaColor
x: scaledPoint(modelData, canvas.width,
canvas.height).x - width / 2
y: scaledPoint(modelData, canvas.width,
canvas.height).y - height / 2
}
}
Repeater {
id: shieldedAreaRepeater
model: shieldedAreaPoints
visible: shieldedAreaEnabled
delegate: Rectangle {
width: dargWidth
height: dargWidth
visible: root.enabled && shieldedAreaEnabled
color: shieldedAreaColor
x: scaledPoint(modelData, canvas.width,
canvas.height).x - width / 2
y: scaledPoint(modelData, canvas.width,
canvas.height).y - height / 2
}
}
Repeater {
id: antiAreaRepeater
visible: antiClipAreaEnabled
model: antiClipAreaPoints
delegate: Rectangle {
visible: root.enabled && antiClipAreaEnabled
width: dargWidth
height: dargWidth
color: antiClipAreaColor
x: scaledPoint(modelData, canvas.width,
canvas.height).x - width / 2
y: scaledPoint(modelData, canvas.width,
canvas.height).y - height / 2
}
}
MouseArea {
anchors.fill: parent
enabled: root.enabled
property int draggedOpenDoorAreaPointIndex: -1
property int draggedShieldedAreaPointIndex: -1
property int draggedAntiAreaPointIndex: -1
onPressed: mouse => {
if(openDoorAreaWay == DeviceConnection.Quadrangle){
for (var i = 0; i < openDoorAreaPoints.length; i++) {
let point = scaledPoint(
openDoorAreaPoints[i], canvas.width,
canvas.height)
if (isInside(mouse.x, mouse.y, point)) {
draggedOpenDoorAreaPointIndex = i
break
}
}
}
if (draggedOpenDoorAreaPointIndex >= 0)
return
if(shieldedAreaEnabled){
for (let i = 0; i < shieldedAreaPoints.length; i++) {
let point = scaledPoint(
shieldedAreaPoints[i], canvas.width,
canvas.height)
if (isInside(mouse.x, mouse.y, point)) {
draggedShieldedAreaPointIndex = i
break
}
}
}
if (draggedShieldedAreaPointIndex >= 0)
return
if(antiClipAreaEnabled){
for (let i = 0; i < antiClipAreaPoints.length; i++) {
let point = scaledPoint(
antiClipAreaPoints[i], canvas.width,
canvas.height)
if (isInside(mouse.x, mouse.y, point)) {
draggedAntiAreaPointIndex = i
break
}
}
}
}
onReleased: {
if (draggedOpenDoorAreaPointIndex >= 0) {
App.updateOpenDoorAreaPoints(openDoorAreaPoints)
draggedOpenDoorAreaPointIndex = -1
}
if (draggedShieldedAreaPointIndex >= 0) {
App.updateShieldedAreaPoints(shieldedAreaPoints)
draggedShieldedAreaPointIndex = -1
}
if (draggedAntiAreaPointIndex >= 0) {
App.updateAntiClipAreaPoints(antiClipAreaPoints)
draggedAntiAreaPointIndex = -1
}
}
onPositionChanged: mouse => {
if ((mouse.x < 0) || (mouse.x > canvas.width) || (mouse.y < 0) || (mouse.y > canvas.height)) return
if (draggedOpenDoorAreaPointIndex >= 0) {
openDoorAreaPoints[draggedOpenDoorAreaPointIndex]
= standardPoint(Qt.point(mouse.x, mouse.y), canvas.width, canvas.height)
canvas.requestPaint()
repeater.model = openDoorAreaPoints
} else if (draggedShieldedAreaPointIndex >= 0) {
shieldedAreaPoints[draggedShieldedAreaPointIndex]
= standardPoint(Qt.point(mouse.x,
mouse.y),
canvas.width,
canvas.height)
canvas.requestPaint()
shieldedAreaRepeater.model = shieldedAreaPoints
} else if (draggedAntiAreaPointIndex >= 0) {
antiClipAreaPoints[draggedAntiAreaPointIndex]
= standardPoint(Qt.point(mouse.x,
mouse.y),
canvas.width,
canvas.height)
canvas.requestPaint()
antiAreaRepeater.model = antiClipAreaPoints
}
}
function isInside(x, y, point) {
let edge = dargWidth / 2
return x >= point.x - edge && x <= point.x + edge
&& y >= point.y - edge && y <= point.y + edge
}
}
}
}
GridLayout {
id: controlBar
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
columns: 4
Label { text: qsTr("图像: ") }
Row {
enabled: root.enabled
Layout.columnSpan: 3
Label {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("旋转")
}
Item {width: 10; height:10}
ComboBox {
id: rotateComboBox
model: ["0°","90°","180°","270°"]
onCurrentIndexChanged: {
App.currentDeviceRotation = rotateComboBox.currentIndex
}
}
Item {width: 70; height:10}
Label {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("翻转")
}
Item {width: 10; height:10}
Switch {
id: flipSwitch
onToggled: App.currentDeviceFlip=flipSwitch.checked
}
}
Label {
text: qsTr("开门区域: ")
}
Row {
enabled: root.enabled
Layout.columnSpan: 3
RadioButton {
text: "关闭"
checked: App.currentOpenDoorAreaWay ==DeviceConnection.Diabled
onToggled:{
App.currentOpenDoorAreaWay =DeviceConnection.Diabled
}
}
RadioButton {
text: "全区域"
checked: App.currentOpenDoorAreaWay ==DeviceConnection.FullArea
onToggled:{
App.currentOpenDoorAreaWay =DeviceConnection.FullArea
}
}
RadioButton {
text: "四边形"
checked: App.currentOpenDoorAreaWay ==DeviceConnection.Quadrangle
onToggled:{
App.currentOpenDoorAreaWay =DeviceConnection.Quadrangle
}
}
}
Label {text: qsTr("防夹区域: ")}
Row {
enabled: root.enabled
Layout.columnSpan: 1
RadioButton {
text: "关闭"
checked: !App.currentAntiClipAreaEnabled
onToggled: {
App.currentAntiClipAreaEnabled=false
}
}
RadioButton {
text: "四边形"
checked: App.currentAntiClipAreaEnabled
onToggled: {
App.currentAntiClipAreaEnabled=true
}
}
}
Label { text: qsTr("灵敏度: ")
Layout.alignment: Qt.AlignRight
}
ComboBox {
id: antiClipSensitivityComboBox
enabled: root.enabled
Layout.alignment: Qt.AlignLeft
model: [1,2,3,4,5]
currentIndex: root.antiClipSensitivity-1
onCurrentIndexChanged: {
App.currentAntiClipSensitivity = antiClipSensitivityComboBox.currentIndex+1
}
}
Label {text: qsTr("屏蔽区域: ")}
Row {
id: shieldedRow
RadioButton {
checked: !shieldedAreaEnabled
text: "关闭"
onToggled: {
App.currentShieldedAreaEnabled = false
}
}
RadioButton {
checked: shieldedAreaEnabled
text: "开启"
onToggled: {
App.currentShieldedAreaEnabled = true
}
}
}
}
// 转换为显示画点
function scaledPoint(point, width, height) {
let x = point.x * width / App.DeviceWidth
let y = point.y * height / App.DeviceHeight
return Qt.point(x, y)
}
// 转换为设备画点(640x360)
function standardPoint(point, width, height) {
let x = point.x * App.DeviceWidth / width
let y = point.y * App.DeviceHeight / height
return Qt.point(x, y)
}
onEnabledChanged: {
canvas.requestPaint()
if(!enabled){
image.source = "image://videoframe/black"
}
}
Connections {
target: App
function onNewVideoFrame() {
image.source = ""
image.source = "image://videoframe/"
}
function onCurrentOpenDoorAreaPointsChanged() {
canvas.requestPaint()
repeater.model = openDoorAreaPoints
}
function onCurrentShieldedAreaPointsChanged() {
shieldedAreaRepeater.model = shieldedAreaPoints
canvas.requestPaint()
}
function onCurrentAntiClipAreaPointsChanged() {
antiAreaRepeater.model = antiClipAreaPoints
canvas.requestPaint()
}
function onCurrentOpenDoorAreaWayChanged(){
canvas.requestPaint()
}
function onCurrentShieldedAreaEnabledChanged(){
canvas.requestPaint()
}
function onCurrentAntiClipAreaEnabledChanged(){
canvas.requestPaint()
}
}
}