Exemplo n.º 1
0
    /**
     * @param {!Painter} painter
     * @param {!CircuitStats} stats
     * @param {!Hand} hand
     */
    paint(painter, stats, hand) {
        painter.fillRect(this.area, Config.BACKGROUND_COLOR_TOOLBOX);

        for (let groupIndex = 0; groupIndex < Gates.Sets.length; groupIndex++) {
            let group = Gates.Sets[groupIndex];
            painter.printLine(group.hint, this.groupLabelRect(groupIndex), 0.5, 'black', 16);

            for (let gateIndex = 0; gateIndex < group.gates.length; gateIndex++) {
                let gate = group.gates[gateIndex];
                if (gate !== null) {
                    let rect = this.gateDrawRect(groupIndex, gateIndex);
                    let isHighlighted = seq(hand.hoverPoints()).any(pt => rect.containsPoint(pt));
                    let drawer = gate.customDrawer || GatePainting.DEFAULT_DRAWER;
                    painter.noteTouchBlocker({rect, cursor: 'pointer'});
                    drawer(new GateDrawParams(
                        painter,
                        true,
                        isHighlighted,
                        false,
                        false,
                        rect,
                        Util.notNull(gate),
                        stats,
                        null,
                        [],
                        undefined));
                }
            }
        }

        // Draw tooltip when hovering, but also when dragging a gate over its own toolbox spot.
        let f = this.findGateAt(hand.pos);
        if (f !== null && (hand.heldGate === undefined || f.gate.symbol === hand.heldGate.symbol)) {
            let gateRect = this.gateDrawRect(f.groupIndex, f.gateIndex);
            let hintRect = new Rect(gateRect.right() + 1, gateRect.center().y, 500, 200).
                snapInside(painter.paintableArea().skipTop(gateRect.y));
            painter.defer(() => WidgetPainter.paintGateTooltip(painter, hintRect, f.gate, stats.time));
        }

        let r = new Rect(0, 0, Config.TOOLBOX_MARGIN_X, this.area.h);
        let {x, y} = r.center();
        painter.ctx.save();
        painter.ctx.translate(x, y);
        painter.ctx.rotate(-Math.PI/2);
        painter.printLine("Toolbox", new Rect(-r.h / 2, -r.w / 2, r.h, r.w), 0.5, 'black', 24);
        painter.ctx.restore();
    }
Exemplo n.º 2
0
 /**
  * @param {!InspectorWidget|*} other
  * @returns {!boolean}
  */
 isEqualTo(other) {
     if (this === other) {
         return true;
     }
     //noinspection JSUnresolvedVariable
     return other instanceof InspectorWidget &&
         this.drawArea.isEqualTo(other.drawArea) &&
         this.displayedCircuit.isEqualTo(other.displayedCircuit) &&
         this.toolboxWidget.isEqualTo(other.toolboxWidget) &&
         this.hand.isEqualTo(other.hand);
 }
Exemplo n.º 3
0
Arquivo: Gates.js Projeto: perak/Quirk
    ).withCustomDrawer(args => {
        if (args.isInToolbox || args.isHighlighted) {
            GatePainting.DEFAULT_DRAWER(args);
            return;
        }

        // A swap gate half is shown as a small X (joined by a line to the other half; that's handled elsewhere).
        let swapRect = Rect.centeredSquareWithRadius(args.rect.center(), args.rect.w / 6);
        args.painter.strokeLine(swapRect.topLeft(), swapRect.bottomRight());
        args.painter.strokeLine(swapRect.topRight(), swapRect.bottomLeft());
    })
Exemplo n.º 4
0
    /**
     * @param {!Painter} painter
     * @param {!CircuitStats} stats
     * @param {!boolean} shift
     */
    paint(painter, stats, shift) {
        painter.fillRect(this.drawArea, Config.BACKGROUND_COLOR);

        this.toolboxWidget.paint(painter, stats, this.hand);
        this.displayedCircuit.paint(painter, this.hand, stats, shift);
        this._paintHand(painter, stats);
        this._drawHint(painter);

        // When a gate is being dragged off the bottom, this fades it out instead of clipping it.
        let y1 = this.displayedCircuit.top +
            DisplayedCircuit.desiredHeight(this.displayedCircuit.circuitDefinition.numWires);
        let y2 = this.drawArea.bottom();
        var gradient = painter.ctx.createLinearGradient(0, y1, 0, y2);
        gradient.addColorStop(0, 'rgba(255,255,255,0)');
        gradient.addColorStop(1, 'white');
        painter.ctx.fillStyle = gradient;
        painter.ctx.fillRect(0, y1, this.drawArea.w, y2-y1);
    }
Exemplo n.º 5
0
    /**
     * Draws a peek gate on each wire at the right-hand side of the circuit.
     *
     * @param {!Painter} painter
     * @param {!CircuitStats} stats
     * @param {!int} col
     * @param {!Hand} hand
     * @private
     */
    _drawOutputSuperpositionDisplay(painter, stats, col, hand) {
        let numWire = this.importantWireCount();
        if (numWire >= Config.NO_SUPERPOSITION_DRAWING_WIRE_THRESHOLD) {
            return;
        }

        let [colWires, rowWires] = [Math.floor(numWire/2), Math.ceil(numWire/2)];
        let [colCount, rowCount] = [1 << colWires, 1 << rowWires];
        let outputStateBuffer = stats.finalState.rawBuffer();
        if (stats.circuitDefinition.numWires !== this.importantWireCount()) {
            outputStateBuffer = outputStateBuffer.slice(0, outputStateBuffer.length/2);
        }
        let amplitudeGrid = new Matrix(colCount, rowCount, outputStateBuffer);

        let topRect = this.gateRect(0, col);
        let bottomRect = this.gateRect(numWire-1, col);
        let gridRect = new Rect(topRect.x, topRect.y, 0, bottomRect.bottom() - topRect.y);
        gridRect = gridRect.withW(gridRect.h * (colCount/rowCount));
        MathPainter.paintMatrix(
            painter,
            amplitudeGrid,
            gridRect,
            numWire < Config.SIMPLE_SUPERPOSITION_DRAWING_WIRE_THRESHOLD ? Config.SUPERPOSITION_MID_COLOR : undefined,
            'black',
            numWire < Config.SIMPLE_SUPERPOSITION_DRAWING_WIRE_THRESHOLD ? Config.SUPERPOSITION_FORE_COLOR : undefined,
            Config.SUPERPOSITION_BACK_COLOR,
            hand.hoverPoints());

        let expandedRect = gridRect.withW(gridRect.w + 50).withH(gridRect.h + 50);
        let [dw, dh] = [gridRect.w / colCount, gridRect.h / rowCount];

        // Row labels.
        for (let i = 0; i < rowCount; i++) {
            let label = "_".repeat(colWires) + Util.bin(i, rowWires);
            let x = gridRect.right();
            let y = expandedRect.y + dh*(i+0.5);
            painter.print(label, x + 2, y, 'left', 'middle', 'black', '12px monospace', 50, dh, (w, h) => {
                painter.fillRect(new Rect(x, y-h/2, w + 4, h), 'lightgray');
            });
        }

        // Column labels.
        painter.ctx.save();
        painter.ctx.rotate(Math.PI/2);
        let maxY = 0;
        for (let i = 0; i < colCount; i++) {
            let labelRect = expandedRect.skipTop(gridRect.h + 2).skipLeft(dw*i).skipBottom(2).withW(dw);
            labelRect = new Rect(labelRect.y, -labelRect.x-labelRect.w, labelRect.h, labelRect.w);

            let label = Util.bin(i, colWires) + "_".repeat(rowWires);
            let x = expandedRect.x + dw*(i+0.5);
            let y = gridRect.bottom();
            painter.print(label, y + 2, -x, 'left', 'middle', 'black', '12px monospace', 50, dw, (w, h) => {
                painter.fillRect(new Rect(y, -x-h/2, w + 4, h), 'lightgray');
                maxY = Math.max(maxY, w + 8);
            });
        }
        painter.ctx.restore();

        // Hint text.
        painter.printParagraph(
            "Final amplitudes\n(deferring measurement)",
            expandedRect.withY(gridRect.bottom() + maxY).withH(40).withW(200),
            new Point(0, 0),
            'gray');
    }