BI-PGA Programování grafických aplikací
Jdi na navigaci předmětu

Widgety

Widgety

Tvorba aplikace

Tento příklad byl vytvořen, aby demonstroval, jak pracovat se systémem widgetu.

Cilem demonstrační aplikace je ukázat ovládání tlačítek, posuvníků a polí pro zadávání textu pomocí příkladu konfigurovatelné hry Game of life.

Pro vytvoření tlačítka použijeme:

this.controls.addButton({ label: "", identifier: "", position: });
  • label - text, který se zobrazí na tlačítku
  • identifier - název tlačítka
  • position - pozice tlačítka v okně widgetu

Pro vytvoření polí pro text použijeme:

this.controls.addTextInput({ value: "", label: "",  identifier: "" });
  • value - text, který pole bude obsahovat při prvním spuštění
  • label - text o maximální délce 5 znaků, který se zobrazí vlevo od vstupního pole
  • identifier - název pole

Pro vytvoření posuvníků použijeme:

this.controls.addSlider({
    identifier: "",
    minimum: ,
    maximum: ,
    label: "",
    property: "",
    increments:
});
  • identifier - název posuvníku
  • minimum - minimální povolená hodnota pro posuvník
  • maximum - maximální povolená hodnota pro posuvník
  • label - text o maximální délce 5 znaků, který se zobrazí zleva od posuvníka
  • property - obsahuje (celé!) jméno proměnné, která má být změněna. (ve formátu řetězce!)
  • increments - přírůstková jednotka

Budeme řídit akce widgetů uvnitř bloku, kde 'data.identifier' obsahuje název widgetu

 event: function (eventType, position, user_id, data, date) {
       if (eventType === "widgetEvent") {
            switch (data.identifier) {
            }
       }
 }

Podíváme se na příklad aplikace pracující s widgety

Ukázka 1. instructions.json
{
  "main_script": "Widgets.js",
  "width": 500,
  "height": 500,
  "animation": true,
  "title": "Widgets",
  "author": "Oleksandr Khokhych"
}
Ukázka 2. Widgets.js
var Widgets = SAGE2_App.extend({

    init: function (data) {

        this.SAGE2Init("canvas", data);
        this.ctx = this.element.getContext("2d");

        this.resizeEvents = "continuous";

        this.size = 10;             // velikost jedné buňky
        this.backcolor = "black";   // barva pozadí
        this.cellcolor = "lime";    // barva buňky
        this.statement = false;     // stav herního režimu

        this.UBLimit = 3;           // horní hranice pro vytvoření nové buňky
        this.LBLimit = 3;           // dolní hranice pro vytvoření nové buňky

        this.UALimit = 3;           // horní hranice pro život starých buněk
        this.LALimit = 2;           // dolní hranice pro život starých buněk

        // vytvoření tlačítka s textem "Play" a identifikáčním názvem "PlayButton" na pozici 1
        this.controls.addButton({ label: "Play", identifier: "PlayButton", position: 1 });
        // vytvoření tlačítka s obrazkem typu "play-pause" a identifikáčním názvem "PauseButton" na pozici 2
        this.controls.addButton({ type: "play-pause", identifier: "PauseButton", position: 2 });
        // vytvoření tlačítka s obrazkem typu "next" a identifikáčním názvem "NextButton" na pozici 6
        this.controls.addButton({ type: "next", identifier: "NextButton", position: 6 });
        // vytvoření tlačítka s textem "Clear" a identifikáčním názvem "ClearButton" na pozici 7
        this.controls.addButton({ label: "Clear", identifier: "ClearButton", position: 7 });

        // vytvoření pole s textem "lime", předponou "Color" a identifikáčním názvem "SetColor"
        this.controls.addTextInput({ value: "lime", label: "Color",  identifier: "SetColor" });

        // vytvoření posuvníku
        this.controls.addSlider({
            identifier: "LBLiveSlider", // identifikáční název
            minimum: 0,                 // minimální hodnota
            maximum: 8,                 // maximální hodnota
            label: "LB",                // předpona
            property: "this.LBLimit",   // proměnna
            increments: 1
        });
        this.controls.addSlider({
            identifier: "UBLiveSlider", // identifikáční název
            minimum: 0,                 // minimální hodnota
            maximum: 8,                 // maximální hodnota
            label: "UB",                // předpona
            property: "this.UBLimit",   // proměnna
            increments: 1
        });

        this.controls.addSlider({
            identifier: "LALiveSlider", // identifikáční název
            minimum: 0,                 // minimální hodnota
            maximum: 8,                 // maximální hodnota
            label: "LA",                // předpona
            property: "this.LALimit",   // proměnna
            increments: 1
        });
        this.controls.addSlider({
            identifier: "UALiveSlider", // identifikáční název
            minimum: 0,                 // minimální hodnota
            maximum: 8,                 // maximální hodnota
            label: "UA",                // předpona
            property: "this.UALimit",   // proměnna
            increments: 1
        });

        // potvrzení a dokončení přidávání widgetů
        this.controls.finishedAddingControls();

        // vytvoříme pole pro buňky
        this.board = new Array(50);

        for (var i = 0; i < 50; i++) {
            this.board[i] = new Array(50);
            for (var j = 0; j < 50; j++) {
                this.board[i][j] = false;
            }
        }
        // souřadnice sousedů vzhledem k buňce
        //                 X  Y      X  Y      X  Y
        this.nighbors = [[-1, -1],  [0, -1],  [1, -1],
                         [-1, 0], /*[0, 0],*/ [1, 0],
                         [-1, 1],   [0, 1],   [1, 1]];
    },

    draw: function (date) {
        // vymažeme obrazovku
        this.ctx.fillStyle = this.backcolor;
        this.ctx.fillRect(0, 0, this.element.width, this.element.height);

        // nakreslíme všechny živé buňky
        this.ctx.fillStyle = this.cellcolor;
        for (var y = 0; y < 50; y++) {
            for (var x = 0; x < 50; x++) {
                if (this.board[y][x]) {
                    this.ctx.fillRect(x * this.size, y * this.size, this.size, this.size);
                }
            }
        }
        // Pokud je aktivní automatický režim, voláme funkcí 'this.next()' každých 300 milisekund
        if (this.statement) setTimeout(this.next(), 300);
    },

    resize: function (date) {
        this.refresh(date);
    },

    next: function (date) {
        // vytvoříme dočasné pole buněk
        var tempboard = new Array(50);

        for (var i = 0; i < 50; i++) {
            tempboard[i] = new Array(50);
            for (var j = 0; j < 50; j++) {
                tempboard[i][j] = false;
            }
        }
        // pro každou buňku
        for (var i = 0; i < 50; i++) { //Y
            for (var j = 0; j < 50; j++) { //X

                // vypočítáme počet aktivních sousedních buněk
                var count = 0;

                for (let [a, b] of this.nighbors) {
                    let y = (i + b + 50) % 50;
                    let x = (j + a + 50) % 50;
                    if (this.board[y][x]) count++;
                }
                // pokud jsou dodržena všechna pravidla, buňka zůstane naživu
                if ((this.board[i][j] && this.LALimit <= count && count <= this.UALimit) ||
                    (!this.board[i][j] && this.LBLimit <= count && count <= this.UBLimit))
                    tempboard[i][j] = true;
            }
        }
        // zkopírujeme hodnotu dočasného pole
        this.board = tempboard.slice(0);
    },

    event: function (eventType, position, user_id, data, date) {
        // pokud je stisknuto levé tlačítko myši
        if (eventType === "pointerPress" && (data.button === "left")) {
            // v závislosti na souřadnicích najdeme buňku
            var x = parseInt(position.x / this.size);
            var y = parseInt(position.y / this.size);
            // změníme stav vybrané buňky na opačný
            this.board[y][x] = !this.board[y][x];

            this.refresh(date);
        }
        // pokud událost přišla z widgetu
        else if (eventType === "widgetEvent") {
            // v závislosti na widgetu
            switch (data.identifier) {
                // pokud bylo stisknuto tlačítko "PlayButton"
                case "PlayButton":
                    if (!this.statement) {
                        // měníme herní režim na automatický
                        this.statement = true;
                        this.refresh(date);
                    }
                    break;
                // pokud bylo stisknuto tlačítko "PauseButton"
                case "PauseButton":
                    if (this.statement) {
                        // měníme herní režim na manuální
                        this.statement = false;
                        this.refresh(date);
                    }
                    break;
                // pokud bylo stisknuto tlačítko "PauseButton"
                case "NextButton":
                    // nakreslíme novou generaci buněk
                    if (!this.statement) this.next(date);
                    break;
                // pokud bylo stisknuto tlačítko "ClearButton"
                case "ClearButton":
                    // vyčistíme pole
                    for (var i = 0; i < 50; i++) {
                        for (var j = 0; j < 50; j++) {
                            this.board[i][j] = false;
                        }
                    }
                    this.refresh(date);
                    break;
                // pokud byla v textovém poli "SetColor" stisknuta klávesa 'Enter'
                case "SetColor":
                    // změníme barvu buněk na barvu zadanou do textového pole
                    this.cellcolor = data.text;
                    this.refresh(date);
                    break;
            }
        }
    }
});
img1
img2
img3
img4
img5

Odkazy

Zdrojový kód: Widgets