R6 Robot Teach Pendant

// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Rectangle {
    id: root

    required property R6BotViewModel mainViewModel
    property bool connected: false
    property bool executing: false

    signal jogJoint(int jointIndex, real delta)

    color: "transparent"

    // Speed profile settings
    property int selectedSpeedProfile: 1 // 0=Fine, 1=Normal, 2=Fast
    property list<real> jogIncrements: [0.02, 0.1, 0.2] // Radians for each speed profile
    property real currentJogIncrement: jogIncrements[selectedSpeedProfile]

    Item {
        anchors.fill: parent

        ColumnLayout {
            anchors.fill: parent
            spacing: 0

            Rectangle {
                Layout.fillWidth: true
                Layout.preferredHeight: 100
                color: Theme.card

                Rectangle {
                    anchors.bottom: parent.bottom
                    width: parent.width
                    height: 1
                    color: Theme.border
                }

                ColumnLayout {
                    anchors.fill: parent
                    anchors.margins: Theme.spacingMedium
                    spacing: 12

                    RowLayout {
                        spacing: 12

                        Label {
                            text: "⏱"
                            color: Theme.mutedForeground
                            font.pixelSize: 16
                        }

                        Label {
                            text: "SPEED PROFILE"
                            color: Theme.mutedForeground
                            font.pixelSize: 11
                            font.bold: true
                            font.letterSpacing: 1
                        }
                    }

                    RowLayout {
                        spacing: 8
                        Layout.fillWidth: true

                        Repeater {
                            model: ["Fine", "Normal", "Fast"]
                            Button {
                                id: speedBtn
                                Layout.fillWidth: true
                                property bool isActive: index === root.selectedSpeedProfile
                                text: modelData
                                flat: true
                                font.pixelSize: 12

                                background: Rectangle {
                                    color: speedBtn.isActive ? Theme.primary : "transparent"
                                    radius: Theme.radius
                                    border.width: 1
                                    border.color: speedBtn.isActive ? Theme.primary : Theme.border
                                }

                                contentItem: Label {
                                    text: speedBtn.text
                                    color: speedBtn.isActive ? Theme.primaryForeground : Theme.foreground
                                    horizontalAlignment: Text.AlignHCenter
                                    verticalAlignment: Text.AlignVCenter
                                    font: speedBtn.font
                                }

                                onClicked: {
                                    root.selectedSpeedProfile = index
                                    console.log("Speed profile changed to:",
                                                modelData, "Increment:",
                                                root.jogIncrements[index],
                                                "rad")
                                }
                            }
                        }
                    }
                }
            }

            // Joint Jog Grid
            ScrollView {
                Layout.fillWidth: true
                Layout.fillHeight: true
                clip: true
                contentWidth: availableWidth

                ScrollBar.vertical.policy: ScrollBar.AsNeeded
                ScrollBar.horizontal.policy: ScrollBar.AlwaysOff

                ColumnLayout {
                    width: parent.parent.width - 2 * Theme.spacingMedium
                    spacing: Theme.spacingMedium
                    x: Theme.spacingMedium
                    y: Theme.spacingMedium

                    Repeater {
                        model: root.mainViewModel.jointStates

                        Rectangle {
                            Layout.fillWidth: true
                            Layout.preferredHeight: 120
                            color: Theme.panel
                            radius: Theme.radius
                            border.width: 1
                            border.color: Theme.border

                            ColumnLayout {
                                anchors.fill: parent
                                anchors.margins: 12
                                spacing: 8

                                // Joint name and value
                                RowLayout {
                                    Layout.fillWidth: true

                                    Label {
                                        text: modelData.name
                                        color: Theme.foreground
                                        font.pixelSize: 14
                                        font.bold: true
                                    }

                                    Item {
                                        Layout.fillWidth: true
                                    }

                                    Label {
                                        property real position: modelData.position
                                        text: position.toFixed(3) + " rad"
                                        color: Theme.foreground
                                        font.family: Theme.monoFontFamily
                                        font.pixelSize: 12
                                    }
                                }

                                // Joint limit bar
                                Rectangle {
                                    Layout.fillWidth: true
                                    height: 6
                                    radius: 3
                                    color: Theme.muted

                                    Rectangle {
                                        property real position: modelData.position
                                        property real percentage: (position + Math.PI)
                                                                  / (2 * Math.PI)

                                        width: parent.width * percentage
                                        height: parent.height
                                        radius: parent.radius
                                        color: Theme.primary
                                    }
                                }

                                // Jog buttons
                                RowLayout {
                                    Layout.fillWidth: true
                                    spacing: 8

                                    Button {
                                        id: minusBtn
                                        Layout.preferredWidth: 60
                                        Layout.preferredHeight: 60
                                        enabled: root.connected
                                                && !root.executing

                                        background: Rectangle {
                                            color: minusBtn.pressed ? "#8B4FD8" : "#9B5FE8"
                                            radius: Theme.radius
                                            opacity: minusBtn.enabled ? 1.0 : 0.3
                                        }

                                        contentItem: Label {
                                            text: "−"
                                            color: "white"
                                            font.pixelSize: 24
                                            font.bold: true
                                            horizontalAlignment: Text.AlignHCenter
                                            verticalAlignment: Text.AlignVCenter
                                        }

                                        onPressed: root.jogJoint(
                                                       index,
                                                       -root.currentJogIncrement)
                                    }

                                    Item {
                                        Layout.fillWidth: true

                                        Label {
                                            anchors.centerIn: parent
                                            property real position: modelData.position
                                            property real percentage: ((position + Math.PI) / 6.28
                                                                       - 0.5) * 200
                                            text: percentage.toFixed(0) + "%"
                                            color: Theme.mutedForeground
                                            font.pixelSize: 12
                                        }
                                    }

                                    Button {
                                        id: plusBtn
                                        Layout.preferredWidth: 60
                                        Layout.preferredHeight: 60
                                        enabled: root.connected && !root.executing

                                        background: Rectangle {
                                            color: plusBtn.pressed ? Theme.primary : "#3BC9DB"
                                            radius: Theme.radius
                                            opacity: plusBtn.enabled ? 1.0 : 0.3
                                        }

                                        contentItem: Label {
                                            text: "+"
                                            color: Theme.primaryForeground
                                            font.pixelSize: 24
                                            font.bold: true
                                            horizontalAlignment: Text.AlignHCenter
                                            verticalAlignment: Text.AlignVCenter
                                        }

                                        onPressed: root.jogJoint(
                                                       index,
                                                       root.currentJogIncrement)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}