Canvas绘图

 

 

 

import QtQuick 2.15
import Room 1.0

Canvas {
    id: root
    antialiasing: true

    // 湿度水滴绘制半径
    property real humidityRadius: 10
    // 湿度偏移点
    property point humidityOffsetPoint: Qt.point(50, -135)
    // 湿度百分比
    property real humidityPercent: RoomManage.currRoom.humidity/100

    /**********************************************************************
     * 功能描述: 画室内华氏度
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintInsideText(ctx)
    {
        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        ctx.font = "25 300px Ubuntu"
        var insideTemp = String(RoomManage.currRoom.insideTemp)
        var obj = ctx.measureText(insideTemp)
        ctx.fillStyle = "white"
        ctx.beginPath()
        ctx.fillText(insideTemp, -obj.width/2, 120)
        ctx.font = "25 150px Ubuntu"
        ctx.beginPath()
        ctx.fillText("°", obj.width/2, 0)
        ctx.fill()
        ctx.restore()
    }

    /**********************************************************************
     * 功能描述: 画室内摄氏度
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintInsideCelsiusText(ctx)
    {
        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        ctx.font = "25 300px Ubuntu"
        var f = RoomManage.currRoom.insideTemp
        var c = parseFloat(f).toFixed(1)
        var integer = parseInt(c)
        var decimal = c - integer
        var insideTemp = String("%1").arg(integer)
        var obj = ctx.measureText(insideTemp)
        ctx.fillStyle = "white"
        ctx.beginPath()
        ctx.fillText(insideTemp, -obj.width/2, 120)
        insideTemp = String(".%1").arg(decimal*10)
        var obj1 = ctx.measureText(insideTemp)
        ctx.font = "25 80px Ubuntu"
        ctx.fillStyle = "white"
        ctx.beginPath()
        ctx.fillText(insideTemp, obj.width/2, 120)
        ctx.font = "25 150px Ubuntu"
        ctx.beginPath()
        ctx.fillText("°", obj.width/2, 0)
        ctx.fill()
        ctx.restore()
    }

    /**********************************************************************
     * 功能描述: 画湿度水滴百分比
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintHumidityPercent(ctx)
    {
        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        ctx.translate(humidityOffsetPoint.x, humidityOffsetPoint.y)
        ctx.strokeStyle = canvasJs.coolColor
        ctx.fillStyle = canvasJs.coolColor
        ctx.lineWidth = 1
        ctx.beginPath()
        ctx.arc(0, 0, humidityRadius, 0, Math.PI, false)
        ctx.lineTo(0, -humidityRadius*1.5)
        ctx.closePath()
        ctx.stroke()
        ctx.clip()
        ctx.beginPath()
        ctx.rect(-humidityRadius, -humidityRadius*1.5+(1-humidityPercent)*humidityRadius*2.5, humidityRadius*2, humidityRadius*2.5*humidityPercent)
        ctx.fill()

        ctx.restore()
    }

    Component.onCompleted: {
        canvasJs.center = Qt.point(width/2, (height+80)/2)
    }

    onVisibleChanged: {
        if (visible) {
            canvasJs.center = Qt.point(width/2, (height+80)/2)
            root.requestPaint()
        }
    }

    onPaint: {
        var ctx = getContext("2d")
        // 去除锯齿
        ctx.clearRect(0, 0, root.width, root.height);
        canvasJs.f_paintBkgColor(ctx)
        switch (RoomManage.currRoom.mode) {
            case RoomInfo.OffMode:
                break
            case RoomInfo.HeatMode:
                canvasJs.f_paintHeatArc(ctx)
                break
            case RoomInfo.CoolMode:
                canvasJs.f_paintCoolArc(ctx)
                break
            case RoomInfo.Heat_CoolMode:
            case RoomInfo.ScheduleIQMode:
                canvasJs.f_paintHeatArc(ctx)
                canvasJs.f_paintCoolArc(ctx)
                break
            default:
                break
        }

        canvasJs.f_paintYellowWedge(ctx)
        if (GlobalSetting.unit) {
            f_paintInsideText(ctx)
        } else {
            f_paintInsideCelsiusText(ctx)
        }

        f_paintHumidityPercent(ctx)
    }

    Connections {
        target: RoomManage.currRoom

        // 调整室内温度
        function onInsideTempChanged() {
            if (visible && RoomManage.roomIndex === 0) {
                canvasJs.suitAngle = canvasJs.f_tempToArcAngle(RoomManage.currRoom.insideTemp)
                root.requestPaint()
            }
        }

        // 调整室内湿度
        function onHumidityChanged() {
            if (visible && RoomManage.roomIndex === 0) {
                root.requestPaint()
            }
        }
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent

        property real pressX: 0

        onPressed: {
            mouseArea.pressX = mouse.x
        }

        onReleased: {
            if ((mouse.x - mouseArea.pressX) > 20) { // 向右滑
                if (RoomManage.roomIndex > 0) {
                    RoomManage.roomIndex -= 1
                }
            } else if ((mouse.x - mouseArea.pressX) < -20) { // 向左滑
                if (RoomManage.roomIndex < RoomManage.roomCount()-1) {
                    RoomManage.roomIndex += 1
                }
            }


        }
    }


    // 加热按钮
    Rectangle {
        visible: {
            switch (RoomManage.currRoom.mode) {
            case RoomInfo.CoolMode:
            case RoomInfo.OffMode:
                return false
            default:
                return true
            }
        }

        transform: Translate {
            x: canvasJs.center.x-canvasJs.btnWidth/2
            y: canvasJs.center.y-canvasJs.btnWidth/2
        }

        x: canvasJs.arcRadius*Math.cos(canvasJs.heatAngle*Math.PI/180)
        y: canvasJs.arcRadius*Math.sin(canvasJs.heatAngle*Math.PI/180)
        width: canvasJs.btnWidth
        height: width
        radius: width/2
        color: "white"

        Rectangle {
            anchors.centerIn: parent
            width: parent.width-10
            height: width
            radius: width/2
            border.width: 10
            border.color: canvasJs.heatColor
            color: "transparent"
        }

        MouseArea {
            anchors.fill: parent
            onPressed: {
                rootStackView.f_pushItem(roomParamAjdust, {btnStatus: 1})
            }
        }
    }

    // 制冷按钮
    Rectangle {
        visible: {
            switch (RoomManage.currRoom.mode) {
            case RoomInfo.HeatMode:
            case RoomInfo.OffMode:
                return false
            default:
                return true
            }
        }

        transform: Translate {
            x: canvasJs.center.x-canvasJs.btnWidth/2
            y: canvasJs.center.y-canvasJs.btnWidth/2
        }

        x: canvasJs.arcRadius*Math.cos(canvasJs.coolAngle*Math.PI/180)
        y: canvasJs.arcRadius*Math.sin(canvasJs.coolAngle*Math.PI/180)
        width: canvasJs.btnWidth
        height: width
        radius: width/2
        color: "white"
        Rectangle {
            anchors.centerIn: parent
            width: parent.width-10
            height: width
            radius: width/2
            border.width: 10
            border.color: canvasJs.coolColor
            color: "transparent"
        }

        MouseArea {
            anchors.fill: parent
            onPressed: {
                rootStackView.f_pushItem(roomParamAjdust, {btnStatus: 2})
            }
        }
    }

    // inside
    Text {
        id: insideText
        transform: Translate {
            x: canvasJs.center.x-insideText.width-30
            y: canvasJs.center.y-insideText.height-120
        }
        text: qsTr("inside")
        color: "white"
        font.pixelSize: 36
    }

    // 湿度
    Text {
        id: humidityText
        transform: Translate {
            x: canvasJs.center.x+75
            y: canvasJs.center.y-160
        }
        text: String("%1%").arg(RoomManage.currRoom.humidity)
        color: "white"
        font.pixelSize: 36
    }

    // 模式显示
    Row {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 65
        spacing: 20
        Image {
            y: 5
            source: switch (RoomManage.currRoom.mode) {
                        case RoomInfo.OffMode:
                            return "qrc:/img/off.png"
                        case RoomInfo.HeatMode:
                            return "qrc:/img/fire.png"
                        case RoomInfo.CoolMode:
                            return "qrc:/img/snow.png"
                        case RoomInfo.Heat_CoolMode:
                            return "qrc:/img/heat_cool.png"
                        case RoomInfo.ScheduleIQMode:
                            return "qrc:/img/schedule.png"
                        default:
                            return ""
                    }

            sourceSize: Qt.size(32, 32)
        }

        Text {
            text: switch (RoomManage.currRoom.mode) {
                    case RoomInfo.OffMode:
                        return qsTr("off")
                    case RoomInfo.HeatMode:
                        return qsTr("heat only")
                    case RoomInfo.CoolMode:
                        return qsTr("cool only")
                    case RoomInfo.Heat_CoolMode:
                        return qsTr("heat / cool")
                    case RoomInfo.ScheduleIQMode:
                        return qsTr("schedule IQ")
                    default:
                        return ""
                  }

            font.pixelSize: 36
            color: "white"
        }
    }

    // 模式选择
    Rectangle {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 10
        color: "#202020"
        width: modeText.width+40
        height: modeText.height+20
        radius: 10

        MouseArea {
            anchors.fill: parent
            onClicked: {
                rootStackView.f_pushItem(roomModeSel)
            }
        }

        Text {
            id: modeText
            anchors.centerIn: parent
            text: qsTr("modes/schedules")
            color: "white"
            font.pixelSize: 24
        }
    }
}
import QtQuick 2.15
import Room 1.0

Item {
    width: window.width
    height: window.height


    // 按钮设置状态 0: 起始状态 1:加热按钮设置中 2:制冷按钮设置中
    property int btnStatus: 0
    // 短刻度线Rect
    property rect shortMarkLineRect: Qt.rect(0, 0, 2, 16)
    // 长刻度线Rect
    property rect longMarkLineRect: Qt.rect(0, 0, 2, 32)



    Component.onCompleted: {
       canvasJs.center = Qt.point(root.width/2, (root.height+56)/2)
       popTimer.start()
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            rootStackView.f_pop()
        }
    }

    // 计时返回上一页
    Timer {
        id: popTimer
        interval: 5000
        running: false
        repeat: false
        onTriggered: {
            rootStackView.f_pop()
        }
    }

    /**********************************************************************
     * 功能描述: 画加热指示三角
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintHeatIndicateTriangle(ctx)
    {
        var points = [
            Qt.point(-canvasJs.arcLineW/2, 0),
            Qt.point(canvasJs.arcLineW/2, 0),
            Qt.point(0, -20),
        ]

        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        var triRadius = canvasJs.arcRadius+20
        var p = Qt.point(triRadius*Math.cos(canvasJs.heatAngle*Math.PI/180), triRadius*Math.sin(canvasJs.heatAngle*Math.PI/180))
        ctx.translate(p.x, p.y)
        ctx.rotate((canvasJs.heatAngle+90)*Math.PI/180)
        ctx.fillStyle = (btnStatus == 1 ? "white" : canvasJs.strokeBkgColor)
        ctx.beginPath()
        ctx.moveTo(points[0].x, points[0].y)
        ctx.lineTo(points[1].x, points[1].y)
        ctx.lineTo(points[2].x, points[2].y)
        ctx.fill()
        ctx.restore()
    }

    /**********************************************************************
     * 功能描述: 画制冷指示三角
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintCoolIndicateTriangle(ctx)
    {
        var points = [
            Qt.point(-canvasJs.arcLineW/2, 0),
            Qt.point(canvasJs.arcLineW/2, 0),
            Qt.point(0, -20),
        ]

        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        var triRadius = canvasJs.arcRadius+20
        var p = Qt.point(triRadius*Math.cos(canvasJs.coolAngle*Math.PI/180), triRadius*Math.sin(canvasJs.coolAngle*Math.PI/180))
        ctx.translate(p.x, p.y)
        ctx.rotate((canvasJs.coolAngle+90)*Math.PI/180)
        ctx.fillStyle = (btnStatus == 2 ? "white" : canvasJs.strokeBkgColor)
        ctx.beginPath()
        ctx.moveTo(points[0].x, points[0].y)
        ctx.lineTo(points[1].x, points[1].y)
        ctx.lineTo(points[2].x, points[2].y)
        ctx.fill()
        ctx.restore()
    }

    /**********************************************************************
     * 功能描述: 画室内华氏度
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintInsideText(ctx)
    {
        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        ctx.font = "25 300px Ubuntu"
        var angle = (btnStatus == 1 ? canvasJs.heatAngle : canvasJs.coolAngle)
        var insideTemp = String("%1").arg(canvasJs.f_arcAngleToTemp(angle))
        var obj = ctx.measureText(insideTemp)
        ctx.fillStyle = (btnStatus == 1 ? canvasJs.heatColor : canvasJs.coolColor)
        ctx.beginPath()
        ctx.fillText(insideTemp, -obj.width/2, 120)
        ctx.font = "25 150px Ubuntu"
        ctx.beginPath()
        ctx.fillText("°", obj.width/2, 0)
        ctx.fill()
        ctx.restore()
    }

    /**********************************************************************
     * 功能描述: 画度数文本
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintAngleText(ctx)
    {
        var span = 270/30
        // 画刻度度数
        ctx.fillStyle = "white"
        ctx.beginPath()
        var angleTextRadius = canvasJs.arcRadius+80
        var j = 0
        ctx.font = "24px Ubuntu"
        for (var i = canvasJs.heatStartAngle; i <= 360+canvasJs.coolStartAngle; i=i+span) {
            ctx.save()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            var p = Qt.point(angleTextRadius*Math.cos(i*Math.PI/180), angleTextRadius*Math.sin(i*Math.PI/180))
            ctx.translate(p.x, p.y)
            if (j % 5 == 0) {
                var str = String("%1°").arg(60+j)
                var obj = ctx.measureText(str)
                var k = i
                if (k > 0) {
                    k -=360
                }

                if ((RoomManage.currRoom.mode === RoomInfo.HeatMode && k !== canvasJs.heatAngle) ||
                    (RoomManage.currRoom.mode === RoomInfo.CoolMode && k !== canvasJs.coolAngle) ||
                    ((RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) &&
                     k !== canvasJs.heatAngle && k !== canvasJs.coolAngle)) {
                    ctx.fillText(str, -obj.width/2, 12)
                }
            }

            ctx.restore()
            j++
        }

        // 画锲子度数
        ctx.save()
        ctx.fillStyle = "yellow"
        ctx.beginPath()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        p = Qt.point(angleTextRadius*Math.cos(canvasJs.suitAngle*Math.PI/180), angleTextRadius*Math.sin(canvasJs.suitAngle*Math.PI/180))
        ctx.translate(p.x, p.y)
        str = String("%1°").arg(RoomManage.currRoom.insideTemp)
        obj = ctx.measureText(str)
        ctx.fillText(str, -obj.width/2, 12)
        ctx.restore()

        // 画加热按钮移动度数
        if (canvasJs.heatAngle !== canvasJs.suitAngle && (RoomManage.currRoom.mode !== RoomInfo.OffMode && RoomManage.currRoom.mode !== RoomInfo.CoolMode)) {
            ctx.save()
            ctx.fillStyle = canvasJs.heatColor
            ctx.beginPath()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            p = Qt.point(angleTextRadius*Math.cos(canvasJs.heatAngle*Math.PI/180), angleTextRadius*Math.sin(canvasJs.heatAngle*Math.PI/180))
            ctx.translate(p.x, p.y)
            if (canvasJs.heatAngle == canvasJs.coolStartAngle ||
                ((RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) && canvasJs.heatAngle === canvasJs.coolStartAngle-span*3)) {
                str = qsTr("max")
            } else if (Math.abs(canvasJs.heatAngle-canvasJs.heatStartAngle) < 0.001) {
                str = qsTr("min")
            } else {
                str = String("%1°").arg(canvasJs.f_arcAngleToTemp(canvasJs.heatAngle))
            }

            obj = ctx.measureText(str)
            ctx.fillText(str, -obj.width/2, 12)
            ctx.restore()
        }

        // 画制冷按钮移动度数
        if (canvasJs.coolAngle !== canvasJs.suitAngle && (RoomManage.currRoom.mode !== RoomInfo.OffMode && RoomManage.currRoom.mode !== RoomInfo.HeatMode)) {
            ctx.save()
            ctx.fillStyle = canvasJs.coolColor
            ctx.beginPath()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            p = Qt.point(angleTextRadius*Math.cos(canvasJs.coolAngle*Math.PI/180), angleTextRadius*Math.sin(canvasJs.coolAngle*Math.PI/180))
            ctx.translate(p.x, p.y)
            if (canvasJs.coolAngle == canvasJs.coolStartAngle) {
                str = qsTr("max")
            } else if (((RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) &&
                        canvasJs.coolAngle === canvasJs.heatStartAngle+span*3)||
                       (canvasJs.coolAngle == canvasJs.heatStartAngle)) {
                str = qsTr("min")
            } else {
                str = String("%1°").arg(canvasJs.f_arcAngleToTemp(canvasJs.coolAngle))
            }

            obj = ctx.measureText(str)
            ctx.fillText(str, -obj.width/2, 12)
            ctx.restore()
        }

        ctx.fill()
    }

    /**********************************************************************
     * 功能描述: 画室内摄氏度
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintInsideCelsiusText(ctx)
    {
        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        ctx.font = "25 300px Ubuntu"
        var angle = (btnStatus == 1 ? canvasJs.heatAngle : canvasJs.coolAngle)
        var insideTemp = String("%1").arg(canvasJs.f_arcAngleToTemp(angle))
        var c = parseFloat(insideTemp).toFixed(1)
        var integer = parseInt(c)
        var decimal = c - integer
        insideTemp = String(integer)
        var obj = ctx.measureText(insideTemp)
        ctx.fillStyle = (btnStatus == 1 ? canvasJs.heatColor : canvasJs.coolColor)
        ctx.beginPath()
        ctx.fillText(insideTemp, -obj.width/2, 120)
        insideTemp = String(".%1").arg(decimal*10)
        var obj1 = ctx.measureText(insideTemp)
        ctx.font = "25 80px Ubuntu"
        ctx.beginPath()
        ctx.fillText(insideTemp, obj.width/2, 120)
        ctx.font = "25 150px Ubuntu"
        ctx.beginPath()
        ctx.fillText("°", obj.width/2, 0)
        ctx.fill()
        ctx.restore()
    }

    /**********************************************************************
     * 功能描述: 画摄氏度数文本
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintCelsiusAngleText(ctx)
    {
        var span = 270/40
        // 画刻度度数
        ctx.fillStyle = "white"
        ctx.beginPath()
        var angleTextRadius = canvasJs.arcRadius+80
        var j = 0
        ctx.font = "24px Ubuntu"
        for (var i = canvasJs.heatStartAngle; i <= 360+canvasJs.coolStartAngle; i=i+span) {
            ctx.save()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            var p = Qt.point(angleTextRadius*Math.cos(i*Math.PI/180), angleTextRadius*Math.sin(i*Math.PI/180))
            ctx.translate(p.x, p.y)
            if (j % 10 == 0) {
                var str = String("%1°").arg(15+j*0.5)
                var obj = ctx.measureText(str)
                var k = i
                if (k > 0) {
                    k -=360
                }

                if ((RoomManage.currRoom.mode === RoomInfo.HeatMode && k !== canvasJs.heatAngle) ||
                    (RoomManage.currRoom.mode === RoomInfo.CoolMode && k !== canvasJs.coolAngle) ||
                    ((RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) &&
                     k !== canvasJs.heatAngle && k !== canvasJs.coolAngle)) {
                    ctx.fillText(str, -obj.width/2, 12)
                }
            }

            ctx.restore()
            j++
        }

        // 画锲子度数
        ctx.save()
        ctx.fillStyle = "yellow"
        ctx.beginPath()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        p = Qt.point(angleTextRadius*Math.cos(canvasJs.suitAngle*Math.PI/180), angleTextRadius*Math.sin(canvasJs.suitAngle*Math.PI/180))
        ctx.translate(p.x, p.y)
        str = String("%1°").arg(RoomManage.currRoom.insideTemp)
        obj = ctx.measureText(str)
        ctx.fillText(str, -obj.width/2, 12)
        ctx.restore()

        // 画加热按钮移动度数
        if (Math.abs(canvasJs.heatAngle-canvasJs.suitAngle) > 0.001 && (RoomManage.currRoom.mode !== RoomInfo.OffMode && RoomManage.currRoom.mode !== RoomInfo.CoolMode)) {
            ctx.save()
            ctx.fillStyle = canvasJs.heatColor
            ctx.beginPath()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            p = Qt.point(angleTextRadius*Math.cos(canvasJs.heatAngle*Math.PI/180), angleTextRadius*Math.sin(canvasJs.heatAngle*Math.PI/180))
            ctx.translate(p.x, p.y)

            var heatToStartAngle = canvasJs.heatStartAngle+(15.5-15)*span*2
            var coolToStartAngle = canvasJs.heatStartAngle+(30.5-15)*span*2

            if (Math.abs(canvasJs.heatAngle-coolToStartAngle) < 0.001) {
                str = qsTr("max")
            } else if (Math.abs(canvasJs.heatAngle-heatToStartAngle) < 0.001) {
                str = qsTr("min")
            } else {
                var c = canvasJs.f_arcAngleToTemp(canvasJs.heatAngle)
                if (c*10%10 == 0) { // 小数点后一位为0
                    c = parseInt(c)
                }

                str = String("%1°").arg(c)
            }

            obj = ctx.measureText(str)
            ctx.fillText(str, -obj.width/2, 12)
            ctx.restore()
        }

        // 画制冷按钮移动度数
        if (Math.abs(canvasJs.coolAngle-canvasJs.suitAngle) > 0.001 && (RoomManage.currRoom.mode !== RoomInfo.OffMode && RoomManage.currRoom.mode !== RoomInfo.HeatMode)) {
            ctx.save()
            ctx.fillStyle = canvasJs.coolColor
            ctx.beginPath()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            p = Qt.point(angleTextRadius*Math.cos(canvasJs.coolAngle*Math.PI/180), angleTextRadius*Math.sin(canvasJs.coolAngle*Math.PI/180))
            ctx.translate(p.x, p.y)

            heatToStartAngle = canvasJs.heatStartAngle+(17-15)*span*2
            coolToStartAngle = canvasJs.coolStartAngle+(32-35)*span*2

            if (Math.abs(canvasJs.coolAngle-coolToStartAngle) < 0.001) {
                str = qsTr("max")
            } else if (Math.abs(canvasJs.coolAngle-heatToStartAngle) < 0.001) {
                str = qsTr("min")
            } else {
                c = canvasJs.f_arcAngleToTemp(canvasJs.coolAngle)
                if (c*10%10 == 0) { // 小数点后一位为0
                    c = parseInt(c)
                }

                str = String("%1°").arg(c)
            }

            obj = ctx.measureText(str)
            ctx.fillText(str, -obj.width/2, 12)
            ctx.restore()
        }

        ctx.fill()
    }

    /**********************************************************************
     * 功能描述: 画刻度线
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintMark(ctx)
    {
        if (GlobalSetting.unit) {
            var span = 270/30   // 每个刻度间隔
        } else {
            span = 270/40
        }

        ctx.fillStyle = "white"
        ctx.beginPath()
        var makrLineRadius = canvasJs.arcRadius+40
        var j = 0
        for (var i = canvasJs.heatStartAngle; i <= 360+canvasJs.coolStartAngle; i=i+span) {
            ctx.save()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            var p = Qt.point(makrLineRadius*Math.cos(i*Math.PI/180), makrLineRadius*Math.sin(i*Math.PI/180))
            ctx.translate(p.x, p.y)
            ctx.rotate((i+90)*Math.PI/180)
            if (j % 5 == 0) {
                ctx.roundedRect(longMarkLineRect.x-longMarkLineRect.width/2,
                                longMarkLineRect.y-longMarkLineRect.height/2,
                                longMarkLineRect.width, longMarkLineRect.height,
                                longMarkLineRect.width/2, longMarkLineRect.width/2)
            } else {
                ctx.roundedRect(shortMarkLineRect.x-shortMarkLineRect.width/2,
                                shortMarkLineRect.y-shortMarkLineRect.height/2,
                                shortMarkLineRect.width, shortMarkLineRect.height,
                                shortMarkLineRect.width/2, shortMarkLineRect.width/2)
            }

            ctx.restore()
            j++
        }

        ctx.fill()
    }

    Connections {
        target: RoomManage.currRoom

        // 调整室内温度
        function onInsideTempChanged() {
            if (visible && RoomManage.roomIndex === 0) {
                canvasJs.suitAngle = canvasJs.f_tempToArcAngle(RoomManage.currRoom.insideTemp)
                root.requestPaint()
            }
        }
    }

    Canvas {
        id: root
        anchors.horizontalCenter: parent.horizontalCenter
        width: 780
        height: window.height
        antialiasing: true

        // mode
        Text {
             id: modeText
             transform: Translate {
                 x: canvasJs.center.x-modeText.width-30
                 y: canvasJs.center.y-modeText.height-120
             }
             text: {
                 switch (btnStatus) {
                 case 1:
                     return qsTr("heat-to")
                 case 2:
                    return qsTr("cool-to")
                 default:
                     return ""
                 }
             }

            color: "white"
            font.pixelSize: 36
        }

        onPaint: {
            var ctx = getContext("2d")
            // 去除锯齿
            ctx.clearRect(0, 0, root.width, root.height)
            canvasJs.f_paintBkgColor(ctx)
            switch (RoomManage.currRoom.mode) {
                case RoomInfo.HeatMode:
                    canvasJs.f_paintHeatArc(ctx)
                    f_paintHeatIndicateTriangle(ctx)
                    break
                case RoomInfo.CoolMode:
                    canvasJs.f_paintCoolArc(ctx)
                    f_paintCoolIndicateTriangle(ctx)
                    break
                case RoomInfo.Heat_CoolMode:
                case RoomInfo.ScheduleIQMode:
                    canvasJs.f_paintHeatArc(ctx)
                    f_paintHeatIndicateTriangle(ctx)
                    canvasJs.f_paintCoolArc(ctx)
                    f_paintCoolIndicateTriangle(ctx)
                    break
                default:
                    break
            }

            canvasJs.f_paintYellowWedge(ctx)
            if (GlobalSetting.unit) {
                f_paintInsideText(ctx)
                f_paintAngleText(ctx)
            } else {
                f_paintInsideCelsiusText(ctx)
                f_paintCelsiusAngleText(ctx)
            }

            f_paintMark(ctx)
        }

        // 加热按钮
        Rectangle {
            id: heatBtn
            visible: {
                switch (RoomManage.currRoom.mode) {
                case RoomInfo.CoolMode:
                case RoomInfo.OffMode:
                    return false
                default:
                    return true
                }
            }

            transform: Translate {
                x: canvasJs.center.x-canvasJs.btnWidth/2
                y: canvasJs.center.y-canvasJs.btnWidth/2
            }

            x: canvasJs.arcRadius*Math.cos(canvasJs.heatAngle*Math.PI/180)
            y: canvasJs.arcRadius*Math.sin(canvasJs.heatAngle*Math.PI/180)
            width: canvasJs.btnWidth
            height: width
            radius: width/2
            color: btnStatus == 2 ? "lightgray" : "white"

            MouseArea {
                anchors.fill: parent
                onPressed: {
                    btnStatus = 1
                    root.requestPaint()
                    popTimer.restart()
                }

                onReleased: {
                    canvasJs.f_setHeatToAndCoolToTemp()
                }

                onPositionChanged: {
                    if (btnStatus == 1) { // 移动当前加热按钮
                        if (GlobalSetting.unit) {
                            var span = 270/30   // 每个刻度间隔
                        } else {
                            span = 270/40
                        }

                        var p0 = mapToItem(root, mouse.x, mouse.y)
                        var p = Qt.point(p0.x-canvasJs.center.x, p0.y-canvasJs.center.y)
                        var angle = Math.atan2(p.y, p.x)*180/Math.PI
                        if (angle > 0) {   // x轴下半部角度转换为逆时针角度
                            angle = angle-360
                        }

                        // 限制滑动范围
                        if (angle < canvasJs.heatStartAngle && angle > canvasJs.coolStartAngle) {
                            return;
                        }

                        // 限制摄氏度范围
                        if (!GlobalSetting.unit) {
                            var heatToStartAngle = canvasJs.heatStartAngle+(15.5-15)*span*2
                            var coolToStartAngle = canvasJs.heatStartAngle+(30.5-15)*span*2
                            if (angle < heatToStartAngle || angle > coolToStartAngle) {
                                return
                            }
                        }

                        // 按刻度间隔滑动
                        if (angle >= canvasJs.heatStartAngle && angle <= 0) {
                            canvasJs.heatAngle = Math.round((angle-canvasJs.heatStartAngle)/span)*span+canvasJs.heatStartAngle
                        } else if (angle <= canvasJs.coolStartAngle) {
                            canvasJs.heatAngle = Math.round((angle+360-canvasJs.heatStartAngle)/span)*span+canvasJs.heatStartAngle-360
                        }

                        if (RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) {
                            // 加热按钮与制冷按钮相交
                            if (Math.abs(canvasJs.heatAngle-canvasJs.coolAngle) <= span*3 || (canvasJs.coolAngle+360-canvasJs.heatAngle) <= span*3) {
                                // 加热按钮coolStartAngle这边
                                if ((canvasJs.heatAngle > (canvasJs.coolStartAngle-span*3)) && (canvasJs.heatAngle < canvasJs.heatStartAngle)) {
                                    canvasJs.heatAngle = canvasJs.coolStartAngle-span*3
                                }

                                canvasJs.coolAngle = canvasJs.heatAngle+span*3
                                if (canvasJs.coolAngle > 0) {
                                    canvasJs.coolAngle -= 360
                                }
                            }
                        }

                        popTimer.restart()
                        root.requestPaint()
                    }
                }
            }

            Rectangle {
                anchors.centerIn: parent
                width: parent.width-10
                height: width
                radius: width/2
                border.width: 10
                border.color: btnStatus == 2 ? "gray" : canvasJs.heatColor
                color: "transparent"
            }
        }

        // 制冷按钮
        Rectangle {
            id: coolBtn
            visible: {
                switch (RoomManage.currRoom.mode) {
                case RoomInfo.HeatMode:
                case RoomInfo.OffMode:
                    return false
                default:
                    return true
                }
            }
             transform: Translate {
                 x: canvasJs.center.x-canvasJs.btnWidth/2
                 y: canvasJs.center.y-canvasJs.btnWidth/2
             }

             x: canvasJs.arcRadius*Math.cos(canvasJs.coolAngle*Math.PI/180)
             y: canvasJs.arcRadius*Math.sin(canvasJs.coolAngle*Math.PI/180)
             width: canvasJs.btnWidth
             height: width
             radius: width/2
             color: btnStatus == 1 ? "lightgray" : "white"

             Rectangle {
                 anchors.centerIn: parent
                 width: parent.width-10
                 height: width
                 radius: width/2
                 border.width: 10
                 border.color: btnStatus == 1 ? "gray" : canvasJs.coolColor
                 color: "transparent"
             }

             MouseArea {
                 anchors.fill: parent
                 onPressed: {
                     btnStatus = 2
                     root.requestPaint()
                     popTimer.restart()
                 }

                 onReleased: {
                     canvasJs.f_setHeatToAndCoolToTemp()
                 }

                 onPositionChanged: {
                     if (btnStatus == 2) { // 移动当前制冷按钮
                         if (GlobalSetting.unit) {
                             var span = 270/30   // 每个刻度间隔
                         } else {
                             span = 270/40
                         }

                         var p0 = mapToItem(root, mouse.x, mouse.y)
                         var p = Qt.point(p0.x-canvasJs.center.x, p0.y-canvasJs.center.y)
                         var angle = Math.atan2(p.y, p.x)*180/Math.PI
                         if (angle > 0) {   // x轴下半部角度转换为逆时针角度
                             angle = angle-360
                         }

                         // 限制滑动范围
                         if (angle < canvasJs.heatStartAngle && angle > canvasJs.coolStartAngle) {
                             return;
                         }

                         // 限制摄氏度范围
                         if (!GlobalSetting.unit) {
                             var heatToStartAngle = canvasJs.heatStartAngle+(17-15)*span*2
                             var coolToStartAngle = canvasJs.coolStartAngle+(32-35)*span*2
                             if (angle < heatToStartAngle && angle > coolToStartAngle) {
                                 return
                             }
                         }

                         // 按刻度间隔滑动
                         if (angle >= canvasJs.heatStartAngle && angle <= 0) {
                             canvasJs.coolAngle = Math.round((angle-canvasJs.heatStartAngle)/span)*span+canvasJs.heatStartAngle
                         } else if (angle <= canvasJs.coolStartAngle) {
                             canvasJs.coolAngle = Math.round((angle+360-canvasJs.heatStartAngle)/span)*span+canvasJs.heatStartAngle-360
                         }

                         if (RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) {
                             // 加热按钮与制冷按钮相交
                             if (Math.abs(canvasJs.heatAngle-canvasJs.coolAngle) <= span*3 || (canvasJs.coolAngle+360-canvasJs.heatAngle) <= span*3) {
                                 // 制冷按钮在heatStartAngle这边
                                if ((canvasJs.coolAngle < (canvasJs.heatStartAngle+span*3)) && canvasJs.coolAngle > canvasJs.coolStartAngle) {
                                    canvasJs.coolAngle = canvasJs.heatStartAngle+span*3
                                }

                                canvasJs.heatAngle = canvasJs.coolAngle-span*3
                                if (canvasJs.heatAngle < -360) {
                                    canvasJs.heatAngle += 360
                                }
                             }
                         }

                         popTimer.restart()
                         root.requestPaint()
                     }
                 }
             }
        }
    }

    // 减号
    Image {
        x: canvasJs.center.x-width/2
        y: canvasJs.center.y-height/2
        transform: Translate {
            x: -250
        }

        source: "qrc:/img/sub.png"
        sourceSize: Qt.size(128, 128)

        MouseArea {
            anchors.fill: parent
            onPressed: {
                if (GlobalSetting.unit) {
                    var span = 270/30   // 每个刻度间隔
                } else {
                    span = 270/40
                }

                if (btnStatus == 1) {
                    var angle = canvasJs.heatAngle-span
                    if ((angle+360) < 0) {
                        angle = angle+360
                    }

                    angle = parseFloat(angle).toFixed(2)
                    // 限制滑动范围
                    if (angle < canvasJs.heatStartAngle && angle > canvasJs.coolStartAngle) {
                        return;
                    }

                    // 限制摄氏度范围
                    if (!GlobalSetting.unit) {
                        var heatToStartAngle = canvasJs.heatStartAngle+(15.5-15)*span*2
                        var coolToStartAngle = canvasJs.heatStartAngle+(30.5-15)*span*2
                        if (angle < heatToStartAngle || angle > coolToStartAngle) {
                            return
                        }
                    }

                    canvasJs.heatAngle = angle
                } else if (btnStatus == 2) {
                    angle = canvasJs.coolAngle-span
                    if ((angle+360) < 0) {
                        angle = angle+360
                    }

                    angle = parseFloat(angle).toFixed(2)
                    // 限制滑动范围
                    if (angle < canvasJs.heatStartAngle && angle > canvasJs.coolStartAngle) {
                        return;
                    }

                    // 限制摄氏度范围
                    if (!GlobalSetting.unit) {
                        heatToStartAngle = canvasJs.heatStartAngle+(17-15)*span*2
                        coolToStartAngle = canvasJs.coolStartAngle+(32-35)*span*2
                        if (angle < heatToStartAngle && angle > coolToStartAngle) {
                            return
                        }
                    }

                    canvasJs.coolAngle = angle
                    if (RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) {
                        // 加热按钮与制冷按钮相交
                        if (Math.abs(canvasJs.heatAngle-canvasJs.coolAngle) <= span*3 || (canvasJs.coolAngle+360-canvasJs.heatAngle) <= span*3) {
                            // 制冷按钮在heatStartAngle这边
                           if ((canvasJs.coolAngle < (canvasJs.heatStartAngle+span*3)) && canvasJs.coolAngle > canvasJs.coolStartAngle) {
                               canvasJs.coolAngle = canvasJs.heatStartAngle+span*3
                           }

                           canvasJs.heatAngle = canvasJs.coolAngle-span*3
                           if (canvasJs.heatAngle < -360) {
                               canvasJs.heatAngle += 360
                           }
                        }
                    }
                }

                root.requestPaint()
                popTimer.restart()
            }

            onReleased: {
                canvasJs.f_setHeatToAndCoolToTemp()
            }
        }
    }

    // 加号
    Image {
        x: canvasJs.center.x-width/2
        y: canvasJs.center.y-height/2
        transform: Translate {
            x: 750
        }

        source: "qrc:/img/add.png"
        sourceSize: Qt.size(128, 128)

        MouseArea {
            anchors.fill: parent
            onPressed: {
                if (GlobalSetting.unit) {
                    var span = 270/30   // 每个刻度间隔
                } else {
                    span = 270/40
                }

                if (btnStatus == 1) {
                    var angle = canvasJs.heatAngle+span
                    if (angle > 0) {
                        angle = angle-360
                    }

                    angle = parseFloat(angle).toFixed(2)
                    // 限制滑动范围
                    if (angle < canvasJs.heatStartAngle && angle > canvasJs.coolStartAngle) {
                        return;
                    }

                    // 限制摄氏度范围
                    if (!GlobalSetting.unit) {
                        var heatToStartAngle = canvasJs.heatStartAngle+(15.5-15)*span*2
                        var coolToStartAngle = canvasJs.heatStartAngle+(30.5-15)*span*2
                        if (angle < heatToStartAngle || angle > coolToStartAngle) {
                            return
                        }
                    }

                    canvasJs.heatAngle = angle
                    if (RoomManage.currRoom.mode === RoomInfo.Heat_CoolMode || RoomManage.currRoom.mode === RoomInfo.ScheduleIQMode) {
                        // 加热按钮与制冷按钮相交
                        if (Math.abs(canvasJs.heatAngle-canvasJs.coolAngle) <= span*3 || (canvasJs.coolAngle+360-canvasJs.heatAngle) <= span*3) {
                            // 加热按钮coolStartAngle这边
                            if ((canvasJs.heatAngle > (canvasJs.coolStartAngle-span*3)) && (canvasJs.heatAngle < canvasJs.heatStartAngle)) {
                                canvasJs.heatAngle = canvasJs.coolStartAngle-span*3
                            }

                            canvasJs.coolAngle = canvasJs.heatAngle+span*3
                            if (canvasJs.coolAngle > 0) {
                                canvasJs.coolAngle -= 360
                            }
                        }
                    }
                } else if (btnStatus == 2) {
                    angle = canvasJs.coolAngle+span
                    if (angle > 0) {
                        angle = angle-360
                    }

                    angle = parseFloat(angle).toFixed(2)
                    // 限制滑动范围
                    if (angle < canvasJs.heatStartAngle && angle > canvasJs.coolStartAngle) {
                        return;
                    }

                    // 限制摄氏度范围
                    if (!GlobalSetting.unit) {
                        heatToStartAngle = canvasJs.heatStartAngle+(17-15)*span*2
                        coolToStartAngle = canvasJs.coolStartAngle+(32-35)*span*2
                        if (angle < heatToStartAngle && angle > coolToStartAngle) {
                            return
                        }
                    }

                    canvasJs.coolAngle = angle
                }

                root.requestPaint()
                popTimer.restart()
            }

            onReleased: {
                canvasJs.f_setHeatToAndCoolToTemp()
            }
        }
    }
}

import QtQuick 2.15
import Room 1.0

Item {
    width: window.width
    height: window.height

    Component.onCompleted: {
        canvasJs.center = Qt.point(root.width/2, (root.height+56)/2)
        popTimer.start()
    }

    // 分割线长度
    property real spliteLineLength: 130
    // 模式图片文字半径
    property real imgTextRadius: canvasJs.arcRadius+80
    // 由于静态文本渲染速度快于canvas,所以等canvas渲染完再显示
    property bool canvasRenderFinished: false

    /**********************************************************************
     * 功能描述: 画扇形分割线
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintSplitLine(ctx)
    {
        var points = [
            Qt.point(-0.5, 0),
            Qt.point(0.5, 0),
            Qt.point(0, -spliteLineLength)
        ]

        ctx.fillStyle = "white"
        var radius = canvasJs.arcRadius+canvasJs.arcLineW/2
        var spanAngle = (360+canvasJs.coolStartAngle-canvasJs.heatStartAngle)/5
        for (var i = 0; i < 6; ++i) {
            ctx.save()
            ctx.translate(canvasJs.center.x, canvasJs.center.y)
            var angle = canvasJs.heatStartAngle+i*spanAngle
            if (angle > 0) {
                angle -= 360
            }

            var p = Qt.point(radius*Math.cos(angle*Math.PI/180), radius*Math.sin(angle*Math.PI/180))
            ctx.translate(p.x, p.y)
            ctx.rotate((angle+90)*Math.PI/180)
            ctx.beginPath()
            ctx.moveTo(points[0].x, points[0].y)
            ctx.lineTo(points[1].x, points[1].y)
            ctx.lineTo(points[2].x, points[2].y)
            ctx.fill()
            ctx.restore()
        }
    }

    /**********************************************************************
     * 功能描述: 画圆弧扇形
     * 输入参数: ctx: 2d绘图上下文
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     ***********************************************************************/
    function f_paintArcPie(ctx)
    {
        var radius1 = canvasJs.arcRadius+canvasJs.arcLineW/2
        var radius2 = canvasJs.arcRadius+canvasJs.arcLineW/2+spliteLineLength
        ctx.save()
        ctx.translate(canvasJs.center.x, canvasJs.center.y)
        var spanAngle = (360+canvasJs.coolStartAngle-canvasJs.heatStartAngle)/5
        var startAngle = canvasJs.heatStartAngle+spanAngle*RoomManage.currRoom.mode
        if (startAngle > 0) {
            startAngle -= 360
        }

        var p1 = Qt.point(radius1*Math.cos((startAngle+spanAngle)*Math.PI/180), radius1*Math.sin((startAngle+spanAngle)*Math.PI/180))
        var p2 = Qt.point(radius2*Math.cos(startAngle*Math.PI/180), radius2*Math.sin(startAngle*Math.PI/180))
        ctx.fillStyle = canvasJs.strokeBkgColor
        ctx.beginPath()
        ctx.arc(0, 0, radius1, (startAngle+spanAngle)*Math.PI/180, startAngle*Math.PI/180, true)
        ctx.lineTo(p2.x, p2.y)
        ctx.arc(0, 0, radius2, startAngle*Math.PI/180, (startAngle+spanAngle)*Math.PI/180, false)
        ctx.lineTo(p1.x, p1.y)
        ctx.closePath()
        ctx.fill()
        ctx.restore()
    }

    MouseArea {
        id: mouseArea

        // 是否按压选择模式
        property bool isSelMode: false

        anchors.fill: parent
        onPressed: {
            popTimer.stop()
            var pToRoot = root.mapToItem(mouseArea, canvasJs.center.x, canvasJs.center.y)
            var len = Math.sqrt((Math.pow(mouse.x-pToRoot.x, 2)+Math.pow(mouse.y-pToRoot.y, 2)))
            // 鼠标点击区域判断
            if (len < canvasJs.arcRadius || len > canvasJs.arcRadius+canvasJs.arcLineW/2+spliteLineLength) {
                mouseArea.isSelMode = false
                return
            }

            var p = Qt.point(mouse.x-pToRoot.x, mouse.y-pToRoot.y)
            var angle = Math.atan2(p.y, p.x)*180/Math.PI
            if (angle > 0) {   // x轴下半部角度转换为逆时针角度
                angle = angle-360
            }

            var spanAngle = (360+canvasJs.coolStartAngle-canvasJs.heatStartAngle)/5
            for (var i = 0; i < RoomInfo.MaxValue; ++i) {
                var startAngle = canvasJs.heatStartAngle+spanAngle*i
                if (angle <= canvasJs.coolStartAngle) { // 调整按压角度在0度附近
                    angle += 360
                }

                if (angle >= startAngle && angle <= startAngle+spanAngle) {
                    mouseArea.isSelMode = true
                    modeSelTimer.restart()

                    if (GlobalSetting.unit) {
                        var span = 270/30   // 每个刻度间隔
                    } else {
                        span = 270/40
                    }

                    // 加热制冷模式都存在,需要重新设置当前角度
                    if (i === RoomInfo.Heat_CoolMode || i === RoomInfo.ScheduleIQMode) {
                        // 之前模式为加热模式,则判断制冷按钮位置是否合理
                        if (RoomManage.currRoom.mode === RoomInfo.HeatMode) {
                            // 加热按钮在coolStartAngle和coolStartAngle-span*3内
                            if (canvasJs.heatAngle <= canvasJs.coolStartAngle && canvasJs.heatAngle >= canvasJs.coolStartAngle-span*3) {
                                canvasJs.coolAngle = canvasJs.coolStartAngle
                                canvasJs.heatAngle = canvasJs.coolStartAngle-span*3
                            }
                            // 加热按钮在coolStartAngle-span*3和0度内
                            else if (canvasJs.heatAngle < canvasJs.coolStartAngle-span*3) {
                                if (canvasJs.coolAngle > canvasJs.heatAngle+span*3 && canvasJs.coolAngle <= canvasJs.coolStartAngle) { // 合理区间

                                } else {
                                    canvasJs.coolAngle = canvasJs.heatAngle+span*3
                                }
                            }
                            // 加热按钮在0和-span*3度内
                            else if (canvasJs.heatAngle <= 0 && canvasJs.heatAngle >= -span*3) {
                                if (canvasJs.coolAngle <= canvasJs.coolStartAngle && canvasJs.coolAngle > 0) { // 合理区间

                                } else {
                                    canvasJs.coolAngle = canvasJs.heatAngle+span*3-360
                                }
                            }
                            // 加热按钮在heatStartAngle和-span*3度内
                            else if (canvasJs.heatAngle < -span*3 && canvasJs.heatAngle >= canvasJs.heatStartAngle) {
                                if (canvasJs.coolAngle > canvasJs.heatAngle+span*3 || canvasJs.coolAngle <= canvasJs.coolStartAngle) {

                                } else {
                                    canvasJs.coolAngle = canvasJs.heatAngle+span*3
                                }
                            }
                        }
                        // 之前模式为制冷模式,则判断加热按钮位置是否合理
                        else if (RoomManage.currRoom.mode === RoomInfo.CoolMode) {
                            // 制冷按钮在coolStartAngle和span*3-360内
                            if (canvasJs.coolAngle <= canvasJs.coolStartAngle && canvasJs.coolAngle >= span*3-360) {
                                if (canvasJs.heatAngle >= canvasJs.coolAngle-span*3 && canvasJs.heatAngle <= canvasJs.coolStartAngle) {
                                    canvasJs.heatAngle = canvasJs.coolAngle-span*3
                                }
                            }
                            // 制冷按钮在span*3-360和0度内
                            else if (canvasJs.coolAngle < span*3-360) {
                                if (canvasJs.heatAngle <= canvasJs.coolStartAngle || canvasJs.heatAngle >= -(span*3-(360+canvasJs.coolAngle))) {
                                    canvasJs.heatAngle = -(span*3-(360+canvasJs.coolAngle))
                                }
                            }
                            // 制冷按钮在0和-span*3度内
                            else if (canvasJs.coolAngle >= -span*3) {
                                if (canvasJs.heatAngle <= canvasJs.coolStartAngle || canvasJs.heatAngle >= canvasJs.coolAngle-span*3) {
                                    canvasJs.heatAngle = canvasJs.coolAngle-span*3
                                }
                            }
                            // 制冷按钮在-span*3和heatStartAngle+span*3内
                            else if (canvasJs.coolAngle >= canvasJs.heatStartAngle+span*3 && canvasJs.coolAngle < -span*3) {
                                if (canvasJs.heatAngle <= canvasJs.coolStartAngle || canvasJs.heatAngle >= canvasJs.coolAngle-span*3) {
                                    canvasJs.heatAngle = canvasJs.coolAngle-span*3
                                }
                            }
                            // 制冷按钮在heatStartAngle和heatStartAngle+span*3内
                            else if (canvasJs.coolAngle >= canvasJs.heatStartAngle && canvasJs.coolAngle < canvasJs.heatStartAngle+span*3) {
                                canvasJs.heatAngle = canvasJs.heatStartAngle
                                canvasJs.coolAngle = canvasJs.heatStartAngle+span*3
                            }
                        }
                    }

                    RoomManage.currRoom.mode = i
                    canvasJs.f_setHeatToAndCoolToTemp()
                    root.requestPaint()
                    return
                }
            }
        }

        onReleased: {
            if (mouseArea.isSelMode) {
                modeSelTimer.restart()
            } else {
                rootStackView.f_pop()
            }
        }
    }

    // 计时5s未操作返回上一页
    Timer {
        id: popTimer
        interval: 5000
        running: false
        repeat: false
        onTriggered: {
            rootStackView.f_pop()
        }
    }

    // 操作1s后返回上一页
    Timer {
        id: modeSelTimer
        interval: 1000
        running: false
        repeat: false
        onTriggered: {
            rootStackView.f_pop()
        }
    }

    Canvas {
        id: root
        anchors.horizontalCenter: parent.horizontalCenter
        width: 850
        height: window.height
        antialiasing: true

        onPainted: {
            canvasRenderFinished = true
        }

        onPaint: {
            var ctx = getContext("2d")
            // 去除锯齿
            ctx.clearRect(0, 0, root.width, root.height)
            canvasJs.f_paintBkgColor(ctx)
            f_paintSplitLine(ctx)
            f_paintArcPie(ctx)
        }

        Text {
            id: modeSelText
            visible: canvasRenderFinished ? true : false
            anchors.centerIn: parent
            text: qsTr("select mode")
            color: "white"
            font.pixelSize: 60
        }

        Repeater {
            model: 5
            Column {
                id: imgTextCol
                visible: canvasRenderFinished ? true : false

                /**********************************************************************
                 * 功能描述: 根据index获取当前模式定位位置
                 * 输入参数: index: 当前选择模式的下标
                 * 输出参数: 无
                 * 返 回 值: 无
                 * 其它说明: 无
                 ***********************************************************************/
                function f_getPosByMode(index)
                {
                    var spanAngle = (360+canvasJs.coolStartAngle-canvasJs.heatStartAngle)/5
                    var startAngle = canvasJs.heatStartAngle+spanAngle/2
                    var currAngle = startAngle+index*spanAngle
                    if (currAngle > 0) {
                        currAngle -= 360
                    }

                    var p = Qt.point(imgTextRadius*Math.cos(currAngle*Math.PI/180), imgTextRadius*Math.sin(currAngle*Math.PI/180))
                    return p
                }

                transform: Translate {
                    x: imgTextCol.f_getPosByMode(index).x+canvasJs.center.x-imgTextCol.width/2
                    y: imgTextCol.f_getPosByMode(index).y+canvasJs.center.y-imgTextCol.height/2
                }

                Image {
                    anchors.horizontalCenter: modeText.horizontalCenter
                    sourceSize: Qt.size(32, 32)
                    source: switch(index) {
                                case 0:
                                    return "qrc:/img/off.png"
                                case 1:
                                    return "qrc:/img/fire.png"
                                case 2:
                                    return "qrc:/img/snow.png"
                                case 3:
                                    return "qrc:/img/heat_cool.png"
                                case 4:
                                    return "qrc:/img/schedule.png"
                                default:
                                    return ""
                            }
                }

                Text {
                    id: modeText
                    font.pixelSize: 24
                    color: "white"
                    text: switch (index) {
                          case 0:
                              return qsTr("off")
                          case 1:
                              return qsTr("heat only")
                          case 2:
                              return qsTr("cool only")
                          case 3:
                              return qsTr("heat / cool")
                          case 4:
                              return qsTr("schedule IQ")
                          default:
                              return ""
                          }
                }
            }
        }
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值