packages feed

hsqml-demo-manic-0.3.4.0: qml/Board.qml

import QtQuick 2.0
import QtGraphicalEffects 1.0
import HsQML.Model 1.0

Item {
    id: c;
    property int tilesWide : 8;
    property int tilesHigh : 8;
    property bool isVirtual : false;
    property color bgColor : 'cornsilk';

    property double tileSize : Math.floor(Math.min(
        width / tilesWide,  height / tilesHigh));
    property var tileSource : newTileSource();
    property var gridModel : newGrid();
    property var plumbedGrid : gridModel.plumb();

    signal pressedComplete();

    property double countDown;
    NumberAnimation on countDown {
        id: countAnim;
        from: 3; to: 0;
        duration: 9000;
        running: false;
        onStopped: volumeAnim.start(); 
    }

    property double n : 0;
    NumberAnimation on n {
        id: volumeAnim;
        from: 0; to: 100 + 0.1;
        duration: 5000 * (100 + 0.1);
        running: false;
    }

    property bool gameOver :
        (!countAnim.running && !volumeAnim.running) ||
        n > (plumbedGrid.maxIndex+1) ||
        plumbedGrid.leaks.length == 0;

    function start() {
        tileSource = newTileSource();
        gridModel = newGrid();
        if (c.isVirtual) {
            virtualMouse.pick();
        }
        countAnim.restart();
        volumeAnim.stop();
        n = 0;
    }

    Rectangle {
        width: c.tileSize*c.tilesWide;
        height: c.tileSize*c.tilesHigh;
        color: c.bgColor;
        MouseArea {
            id: realMouse;
            anchors.fill: parent;
            hoverEnabled: true;
        }
    }

    Repeater {
        anchors.fill: parent;
        model: AutoListModel {
            mode: AutoListModel.ByKey;
            source: {
                var rs = plumbedGrid.leaks;
                rs.sort(function(a,b) {return a.idx-b.idx;});
                return rs;
            }
            equalityTest: function(a,b) {
                a.idx==b.idx && a.colour==b.colour && a.exitA==b.exitA;}
            keyFunction: function(a) {return a.x+'-'+a.y;}
        }

        Leak {
            tileSize: c.tileSize;
            tileX: modelData.x;
            tileY: modelData.y;
            colour: modelData.colour;
            exitBearing: modelData.exitA;
            trigger: n >= modelData.idx;
        }
    }

    Repeater {
        id: tiles;
        model: AutoListModel {
            source: plumbedGrid.plumbing;
            mode: AutoListModel.ByKey;
            equalityTest: function(a,b) {
                return a.idx==b.idx && a.entryA==b.entryA && a.exitA==b.exitA;}
            keyFunction: function(a) {return a.x+"-"+a.y;}
        }

        Plumb {
            tileSize: c.tileSize;
            x: modelData.x*c.tileSize;
            y: modelData.y*c.tileSize;
            entryA: modelData.entryA;
            exitA: modelData.exitA;
            colour: modelData.colour;
            label: modelData.colour;
            volume: modelData.idx < 0 ?
                0 : Math.min(Math.max(c.n-modelData.idx,0),1.1);
        }
    }

    Text {
        visible: c.countDown > 0;
        anchors.centerIn: parent;
        text: Math.floor(c.countDown+1);
        font.pixelSize: c.tileSize*2;
        scale: 1+Math.ceil(c.countDown)-c.countDown;
        opacity: 0.5-(Math.ceil(c.countDown)-c.countDown)/2;
    }

    Rectangle {
        id: mouseView;
        property var mouse: c.gameOver ? noMouse :
            (c.isVirtual ? virtualMouse : realMouse);
        property int tileX: Math.floor(mouse.mouseX/c.tileSize);
        property int tileY: Math.floor(mouse.mouseY/c.tileSize);
        property bool tilePlacable:
            plumbedGrid.isPlacable(Math.floor(c.n), tileX, tileY);

        Connections {
            target: mouseView.mouse;
            onPressed: {
                if (mouseView.tilePlacable) {
                    c.gridModel = c.gridModel.place(
                        mouseView.tileX, mouseView.tileY, tileSource.top.tile);
                    c.tileSource = c.tileSource.next;
                }
                c.pressedComplete();
            } 
        }

        visible: mouseView.mouse.containsMouse;
        x: tileX*c.tileSize;
        y: tileY*c.tileSize;
        width: c.tileSize; height: c.tileSize;
        color: 'lightgray'; opacity: 0.5;
        Text {
            visible: !mouseView.tilePlacable;
            anchors.centerIn: parent;
            color: 'red';
            font.pixelSize: c.tileSize;
            text: 'X';
        }
    }

    Item {
        id: virtualMouse;
        property bool done : false;
        property bool active : true;
        property double oldTileX : 0;
        property double oldTileY : 0;
        property double tileX : 0;
        property double tileY : 0;
        property double dur : 0;
        Behavior on tileX {
            NumberAnimation {
                id: animX;
                duration: virtualMouse.dur;
            }
        }
        Behavior on tileY {
            NumberAnimation {
                id: animY;
                duration: virtualMouse.dur;
            }
        }
        NumberAnimation {
            id: xyAnim;
            duration: virtualMouse.dur;
            onStopped: virtualMouse.pressed();
        }
        function pick() {
            if (done) return;
            gridModel.pick(c.tileSource, tileX, tileY, Math.floor(c.n));
        }
        focus: true;
        Keys.enabled: true;
        Keys.onSpacePressed: done = true;
        function move(pos) {
            dur = 300*Math.max(1,Math.sqrt(
                (tileX-pos.x)*(tileX-pos.x)+(tileY-pos.y)*(tileY-pos.y)));
            tileX = pos.x;
            tileY = pos.y;
            xyAnim.start();
        }
        Connections {
            target: c;
            onPressedComplete: virtualMouse.pick();
        }
        Connections {
            target: c.gridModel;
            onPicked: virtualMouse.move(pos); 
        }
        property int mouseX : (tileX+0.5)*c.tileSize;
        property int mouseY : (tileY+0.5)*c.tileSize;
        property bool containsMouse : true;
        signal pressed();

        Image {
            visible: mouseView.mouse == virtualMouse; 
            x: virtualMouse.mouseX; y: virtualMouse.mouseY;
            source: 'mouse.svg'
        }
    }

    Item {
        id: noMouse;
        property int mouseX : 0;
        property int mouseY : 0;
        property bool containsMouse : false;
        signal pressed();
    }
}