/*SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>SPDX-License-Identifier: GPL-2.0-or-later*/import QtQuickimport QtQuick.Windowimport QtQuick.Layoutsimport QtQuick.Shapesimport QtQuick.Controls as QQC2import org.kde.kirigami as Kirigamiimport org.kde.plasma.tablet.kcmQQC2.ApplicationWindow {id: rootrequired property var devicerequired property var tabletEventsproperty CalibrationTool tool: CalibrationTool {onFinished: matrix => {tool.setCalibrationMatrix(device, matrix);}}property real currentPenToolX: -1property real currentPenToolY: -1title: i18nc("@title", "Pen Calibration")onWidthChanged: tool.width = widthonHeightChanged: tool.height = heightHoverHandler {cursorShape: Qt.BlankCursoracceptedDevices: PointerDevice.Stylus}Connections {target: tabletEventsfunction onToolDown(hardware_serial_hi: int, hardware_serial_lo: int, x: real, y: real): void {const centerX = root.width / 2;const centerY = root.height / 2;let targetItem = null;if (x < centerX && y < centerY) {targetItem = topLeftAnchor;} else if (x < centerX && y > centerY) {targetItem = bottomLeftAnchor;} else if (x > centerX && y < centerY) {targetItem = topRightAnchor;} else {targetItem = bottomRightAnchor;}// Calculate the distance between the item and the pointconst distance = Math.sqrt(Math.pow(x - targetItem.x, 2) + Math.pow(y - targetItem.y, 2));// Ensure that large distances are culled because they are probably not clicking on the targetif (distance > 100) {return;}if (tool.finishedCalibration) {root.currentPenToolX = x;root.currentPenToolY = y;} else {tool.calibrate(x, y, targetItem.positionX, targetItem.positionY);}}function onToolUp(hardware_serial_hi: int, hardware_serial_lo: int, x: real, y: real): void {root.currentPenToolX = -1;root.currentPenToolY = -1;}}ColumnLayout {anchors.centerIn: parentspacing: Kirigami.Units.largeSpacingQQC2.Label {horizontalAlignment: Text.AlignHCentertext: tool.finishedCalibration? xi18nc("@info", "Calibration is completed and saved.<nl/><nl/>Refine the calibration further or close the window."): xi18nc("@info", "Tap the center of each target.<nl/><nl/>Aim for the point where the stylus tip lands, and ignore the cursor position on the screen.")}QQC2.Button {visible: tool.finishedCalibrationtext: i18nc("@action:button", "Refine Existing Calibration")icon.name: "edit-redo"onClicked: tool.reset()Layout.alignment: Qt.AlignHCenter}QQC2.Button {text: i18nc("@action:button", "Calibrate from Scratch")icon.name: "kt-restore-defaults"focus: truevisible: tool.finishedCalibrationonClicked: {tool.restoreDefaults(root.device);tool.reset();}Layout.alignment: Qt.AlignHCenter}QQC2.Button {text: tool.finishedCalibration ? i18nc("@action:button", "Close") : i18nc("@action:button", "Cancel")icon.name: "dialog-cancel"onClicked: root.close()Layout.alignment: Qt.AlignHCenter}}component Target: QQC2.ToolButton {readonly property real positionX: test.Kirigami.ScenePosition.xreadonly property real positionY: test.Kirigami.ScenePosition.yicon.name: "crosshairs"focusPolicy: Qt.NoFocushoverEnabled: falseHoverHandler {cursorShape: Qt.BlankCursoracceptedDevices: PointerDevice.Stylus}down: {const isX = root.currentPenToolX >= Kirigami.ScenePosition.x && root.currentPenToolX <= Kirigami.ScenePosition.x + width;const isY = root.currentPenToolY >= Kirigami.ScenePosition.y && root.currentPenToolY <= Kirigami.ScenePosition.y + height;return isX && isY;}Item {id: testanchors.centerIn: parent}}component TargetPath: Shape {required property real sourceXrequired property real sourceYrequired property real targetXrequired property real targetYKirigami.Theme.colorSet: Kirigami.Theme.HeaderKirigami.Theme.inherit: falseShapePath {strokeWidth: 1strokeColor: Qt.lighter(Kirigami.Theme.backgroundColor, 1.5)startX: sourceX; startY: sourceYPathLine { x: targetX; y: targetY }}}component PairTargetPath: Item {required property var anchorvisible: anchor.visibleTargetPath {sourceX: anchor.positionXsourceY: 0targetX: anchor.positionXtargetY: root.height}TargetPath {sourceX: 0sourceY: anchor.positionYtargetX: root.widthtargetY: anchor.positionY}}Target {id: topLeftAnchorvisible: tool.finishedCalibration || tool.currentTarget === 0anchors {left: parent.leftleftMargin: Kirigami.Units.gridUnit * 4top: parent.toptopMargin: Kirigami.Units.gridUnit * 4}}PairTargetPath {anchor: topLeftAnchor}Target {id: topRightAnchorvisible: tool.finishedCalibration || tool.currentTarget === 1anchors {right: parent.rightrightMargin: Kirigami.Units.gridUnit * 4top: parent.toptopMargin: Kirigami.Units.gridUnit * 4}}PairTargetPath {anchor: topRightAnchor}Target {id: bottomLeftAnchorvisible: tool.finishedCalibration || tool.currentTarget === 2anchors {left: parent.leftleftMargin: Kirigami.Units.gridUnit * 4bottom: parent.bottombottomMargin: Kirigami.Units.gridUnit * 4}}PairTargetPath {anchor: bottomLeftAnchor}Target {id: bottomRightAnchorvisible: tool.finishedCalibration || tool.currentTarget === 3anchors {right: parent.rightrightMargin: Kirigami.Units.gridUnit * 4bottom: parent.bottombottomMargin: Kirigami.Units.gridUnit * 4}}PairTargetPath {anchor: bottomRightAnchor}}