# Switch (JavaScript)

Taryn Fox
jewelfox@fursona.net 2012
Posuvný vypínač, který se umí překlápět mezi stavy zapnuto a vypnuto

# Switch

Vypínač má dvě polohy, zapnuto a vypnuto. V tomto příkladu si ukážeme, jak použít více vypínačů dohromady k řízení, který obrázek Image bude v okně zobrazen. Obrázky použité v tomto příkladu můžete stáhnout zde.

Okno může obsahovat ikonu „poškozený obrázek“ místo obrázku, když se soubor s obrázkem s názvem redfox.png, muteswan.png, fruitbat.png nebo gentoopenguin.png nenachází ve stejné složce, jako program. Kód a obrázky si můžete změnit dle své libosti. Fotografie s licencí Creative Commons použité v tomto příkladu byly pořízeny z následujících zdrojů a zmenšeny na 640 × 425 pixelů:

Fotografie červené lišky od Rob Lee, licencováno pod CC-By

Fotografie tučňáka Gentoo od Ken Funakoshi, licencováno pod CC-By-SA

Fotografie kaloně od Shek Graham, licencováno pod CC-By

Fotografie mlčící labutě od Mindaugas Urbonas, licencováno pod CC-By-SA

Informace o zásluhách a licencích vztahujících se k fotografiím jsou zobrazeny v okně AboutDialog. Vždy, když používáte práce licencované pod Creative Commons, pamatujte na zásluhy původních autorů!

# Importované knihovny

#!/usr/bin/gjs

const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk; const Lang = imports.lang;

Toto jsou knihovny, které potřebujeme naimportovat, aby aplikace běžela. Pamatujte si, že řádek, který GNOME říká, že používáme Gjs, musí být vždy na začátku.

# Vytvoření okna aplikace

const SwitchExample = new Lang.Class({ Name: 'Switch Example',

// Vytvoří vlastní aplikaci _init: function() { this.application = new Gtk.Application({ application_id: 'org.example.jsswitch', flags: Gio.ApplicationFlags.FLAGS_NONE });

// Připojí signály "activate" a "startup" k funkcím zpětného volání this.application.connect('activate', Lang.bind(this, this._onActivate)); this.application.connect('startup', Lang.bind(this, this._onStartup)); },

// Funkce zpětného volání pro signál "activate" zobrazujicí okno při aktivaci _onActivate: function() { this._window.present(); },

// Funkce zpětného volání pro signál "startup" sestavující uživatelské rozhraní _onStartup: function() { this._initMenus(); this._buildUI (); },

Všechen kód této ukázky je ve třídě `SwitchExample`. Výše uvedený kód vytvoří Gtk.Application pro naše widgety a okno, ve kterém budou.

Než zavoláme `_buildUI`, aby se vytvořilo okno a widgety v něm, potřebujeme zavolat funkci `_initMenus`, která GNOME řekne, aby vytvořilo nabídku. Reálný kód pro `_initMenus` můžeme vložit za kód `_buildUI`, jelikož nezáleží na tom, v jakém pořadí jsou vloženy, protože `_initMenus` je zavoláno jako první z `_onStartup`.

// Sestaví uživatelské rozhraní aplikace _buildUI: function() {

// Vytvoří okno aplikace this._window = new Gtk.ApplicationWindow({ application: this.application, window_position: Gtk.WindowPosition.CENTER, border_width: 20, title: "Animal Creator"});

Funkce `_buildUI` je místo, ze kterého voláme všechen kód, který vytváří uživatelské rozhraní aplikace. Prvním krokem je vytvoření nového Gtk.ApplicationWindow, do kterého vložíme všechny naše widgety.

# Vytvoření vypínačů

// Vytvoří widget Image a nastaví jeho výchozí obrázek this._image = new Gtk.Image ({file: "redfox.png"});

Neprve vytvoříme Image, který budou vypínače řídit. Pamatujte, že soubor s názvem redfox.png musí být ve stejné složce, jako tato aplikace.

// Vytvoří popisek pro první vypínač this._flyLabel = new Gtk.Label ({ label: "Make it fly", margin_right: 30});

// Vytvoří první vypínač a nastaví jeho výchozí polohu this._flySwitch = new Gtk.Switch ({active: false}); this._flySwitch.connect ('notify::active', Lang.bind (this, this._switchFlip));

// Vytvoří popisek pro druhý vypínač this._birdLabel = new Gtk.Label ({ label: "Make it a bird", margin_right: 30});

// Vytvoří druhý vypínač this._birdSwitch = new Gtk.Switch ({active: false}); this._birdSwitch.connect ('notify::active', Lang.bind (this, this._switchFlip));

Použijeme Label k označení každého z vypínačů a necháme mu malý okraj napravo, aby text nebyl nalepený hned na vypínač. Po té vytvoříme vypínače a nastavíme je na vypnuté ve výchozím stavu.

Signál, který vypínač vyšle při svém přepnutí do polohy vypnuto nebo zapnuto se nazývá `"notify::active"`. Po vytvoření každého z vypínačů napojíme tento signál na funkci nazvanou `_switchFlip`. Když máte více vypínačů, kdy každý dělá něco jiného, můžete je chtít napojit na různé funkce, ale zde jsou oba použity pro stejnou věc: řízení pomocí `_image`, který obrázek se zobrazí.

// Vytvoří mřížku pro popisky a vypínače pod obrázkem this._UIGrid = new Gtk.Grid ({ halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER, margin_top: 20});

// Připojí popisky a vypínače do mřížky this._UIGrid.attach (this._flyLabel, 0, 0, 1, 1); this._UIGrid.attach (this._flySwitch, 1, 0, 1, 1); this._UIGrid.attach (this._birdLabel, 0, 1, 1, 1); this._UIGrid.attach (this._birdSwitch, 1, 1, 1, 1);

// Vytvoří hlavní mřížku pro vložení obrázku a mřížky s ovládacími prvky this._mainGrid = new Gtk.Grid ({ halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER });

// Připojí obrázek a mřížku s ovládacími prvky do hlavní mřížky this._mainGrid.attach (this._image, 0, 0, 1, 1); this._mainGrid.attach (this._UIGrid, 0, 1, 1, 1);

Jako první vytvoříme Grid pro popisky a vypínače, abychom je uspořádali do matice 2 × 2 s okrajem mezi nimi a obrázkem. Pak tuto mřížku vložíme do větší mřížky 2 × 1, která má nahoře obrázek a dole mřížku s popisky a vypínači.

// Přidá hlavní mřížku do okna this._window.add (this._mainGrid);

// Zobrazí okno a všechny jeho synovské widgety this._window.show_all(); },

Nakonec přidáme větší mřížku do okna a oknu řekneme, že má zobrazit sebe a všechny widgety uvnitř sebe.

# Funkce, která obsluhuje situaci, kdy je vypínač přepnut

_switchFlip: function() {

// Změní obrázek podle toho, v jaké poloze je vypínač if (this._flySwitch.get_active()) {

if (this._birdSwitch.get_active()) this._image.set_from_file ("muteswan.png");

else this._image.set_from_file ("fruitbat.png"); }

else {

if (this._birdSwitch.get_active()) this._image.set_from_file ("gentoopenguin.png");

else this._image.set_from_file ("redfox.png");

}

},

Pokaždé, když je přepnut vypínač, tato funkce zkontroluje, které ze dvou vypínačů jsou zapnuté, za použití funkce `get_active()`, která je součástí widgetu `Switch`. Pak příslušně změní obrázek. Názvy souborů si můžete měnit dle libosti, čímž se patřičně změní použité obrázky.

# Vytvoření AboutDialog

_initMenus: function() {

// Sestaví aplikační nabídku, takže můžeme mít volby About a Quit let menu = new Gio.Menu(); menu.append("About", 'app.about'); menu.append("Quit",'app.quit'); this.application.set_app_menu(menu);

// Napojí akci "about" na funkci _showAbout() let aboutAction = new Gio.SimpleAction ({ name: 'about' }); aboutAction.connect('activate', Lang.bind(this, function() { this._showAbout(); })); this.application.add_action(aboutAction);

// Napojí akci "quit" na funkci, která zavře okno let quitAction = new Gio.SimpleAction ({ name: 'quit' }); quitAction.connect('activate', Lang.bind(this, function() { this._window.destroy(); })); this.application.add_action(quitAction); },

Prvním krokem je sestavení GMenu, do kterého položka About patří. Jedná se o nabídku, která se objeví, když kliknete na název aplikace v levém horním rohu obrazovky, vedle nabídky Činnosti. Naše nabídka má jen dvě položky: About a Quit.

_showAbout: function () {

// Pole řetězců se jmény lidí, kteří se na projektu podílejí var artists = ['Rob Lee http://en.wikipedia.org/wiki/File:Fuzzy_Freddy.jpg', 'Ken Funakoshi http://en.wikipedia.org/wiki/File:Pygoscelis_papua_-Nagasaki_Penguin_Aquarium_-swimming_underwater-8a.jpg', 'Shek Graham http://www.flickr.com/photos/shekgraham/127431519/in/photostream/', 'Mindaugas Urbonas http://commons.wikimedia.org/wiki/File:Mute_Swan-Mindaugas_Urbonas.jpg']; var authors = ["GNOME Documentation Team"]; var documenters = ["GNOME Documentation Team"];

// Vytvoří dialogové okno „O aplikaci“ let aboutDialog = new Gtk.AboutDialog({ title: "AboutDialog Example", program_name: "Animal Creator", copyright: "Copyright \xa9 2012 GNOME Documentation Team\n\nRed fox photo licensed CC-By by Rob Lee\nGentoo penguin photo licensed CC-By-SA by Ken Funakoshi\nFruit bat photo licensed CC-By by Shek Graham\nMute swan photo licensed CC-By-SA by Mindaugas Urbonas\nLinks to the originals are available under Credits.\n\nHave you hugged a penguin today?", artists: artists, authors: authors, documenters: documenters, website: "http://developer.gnome.org", website_label: "GNOME Developer Website" });

// Připojí dialogové okno „O aplikaci“ k oknu aboutDialog.modal = true; aboutDialog.transient_for = this._window;

// Zobrazí dialogové okno „O aplikaci“ aboutDialog.show();

// Napojí tlačítko Close na signál "destroy" pro dialogové okno aboutDialog.connect('response', function() { aboutDialog.destroy(); }); }

});

Widget AboutDialog má spoustu různých věcí, které můžete nastavit, abyste ocenili zásluhy každého, kdo na aplikaci pracoval, a nechali vzkaz komukoliv, kdo to bude číst. V tomto případě část s autorskými právy obsahuje naši poznámku a přičítá zásluhy původním fotografům, zatímco část s umělci, když kliknete na tlačítko Credits, uvádí seznam fotografů s odkazy na originální fotografie. Webová adresa URL vložená za jejich jména v poli způsobí, že jména budou v části Credists fungovat jako živé odkazy.

// Spustí aplikaci let app = new SwitchExample (); app.application.run (ARGV);

Nakonec vytvoříme novou instanci výsledné třídy SwitchExample a spustíme aplikaci.

# Úplný kód ukázky

#!/usr/bin/gjs

imports.gi.versions.Gtk = '3.0';

const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk;

class SwitchExample {

// Vytvoří vlastní aplikaci constructor() { this.application = new Gtk.Application({ application_id: 'org.example.jsswitch' });

// Napojí signály "activate" a "startup" k funkcím zpětného volání this.application.connect('activate', this._onActivate.bind(this)); this.application.connect('startup', this._onStartup.bind(this)); }

// Funkce zpětného volání pro signál "activate" zobrazujicí okno při aktivaci _onActivate() { this._window.present(); }

// Funkce zpětného volání pro signál "startup" sestavující uživatelské rozhraní _onStartup() { this._initMenus(); this._buildUI(); }

// Sestaví uživatelské rozhraní aplikace _buildUI() {

// Vytvoří okno aplikace this._window = new Gtk.ApplicationWindow({ application: this.application, window_position: Gtk.WindowPosition.CENTER, border_width: 20, title: "Animal Creator"});

// Vytvoří widget Image a nastaví jeho výchozí obrázek this._image = new Gtk.Image ({file: "redfox.png"});

// Vytvoří popisek pro první vypínač this._flyLabel = new Gtk.Label ({ label: "Make it fly", margin_right: 30});

// Vytvoří první vypínač a nastaví jeho výchozí polohu this._flySwitch = new Gtk.Switch ({active: false}); this._flySwitch.connect ('notify::active', Lang.bind (this, this._switchFlip));

// Vytvoří popisek pro druhý vypínač this._birdLabel = new Gtk.Label ({ label: "Make it a bird", margin_right: 30});

// Vytvoří druhý vypínač this._birdSwitch = new Gtk.Switch ({active: false}); this._birdSwitch.connect ('notify::active', this._switchFlip.bind(this));

// Vytvoří mřížku pro popisky a vypínače pod obrázkem this._UIGrid = new Gtk.Grid ({ halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER, margin_top: 20});

// Připojí popisky a vypínače do mřížky this._UIGrid.attach (this._flyLabel, 0, 0, 1, 1); this._UIGrid.attach (this._flySwitch, 1, 0, 1, 1); this._UIGrid.attach (this._birdLabel, 0, 1, 1, 1); this._UIGrid.attach (this._birdSwitch, 1, 1, 1, 1);

// Vytvoří hlavní mřížku pro vložení obrázku a mřížky s ovládacími prvky this._mainGrid = new Gtk.Grid ({ halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER });

// Připojí obrázek a mřížku s ovládacími prvky do hlavní mřížky this._mainGrid.attach (this._image, 0, 0, 1, 1); this._mainGrid.attach (this._UIGrid, 0, 1, 1, 1);

// Přidá hlavní mřížku do okna this._window.add (this._mainGrid);

// Zobrazí okno a všechny jeho synovské widgety this._window.show_all(); }

_switchFlip() {

// Změní obrázek podle toho, v jaké poloze je vypínač if (this._flySwitch.get_active()) {

if (this._birdSwitch.get_active()) this._image.set_from_file ("muteswan.png"); else this._image.set_from_file ("fruitbat.png"); } else {

if (this._birdSwitch.get_active()) this._image.set_from_file ("gentoopenguin.png"); else this._image.set_from_file ("redfox.png"); } }

_initMenus() {

// Sestaví aplikační nabídku, takže můžeme mít tlačítko „About“ let menu = new Gio.Menu(); menu.append("About", 'app.about'); menu.append("Quit",'app.quit'); this.application.set_app_menu(menu);

// Napojí tlačítko „About“ na funkci _showAbout() let aboutAction = new Gio.SimpleAction ({ name: 'about' }); aboutAction.connect('activate', () => { this._showAbout(); }); this.application.add_action(aboutAction);

// Napojí tlačítko „Quit“ na funkci, která zavírá okno let quitAction = new Gio.SimpleAction ({ name: 'quit' }); quitAction.connect('activate', () => { this._window.destroy(); }); this.application.add_action(quitAction); }

_showAbout() {

// Pole řetězců se jmény lidí, kteří se podílejí na projektu var artists = ['Rob Lee http://en.wikipedia.org/wiki/File:Fuzzy_Freddy.png', 'Ken Funakoshi http://en.wikipedia.org/wiki/File:Pygoscelis_papua_-Nagasaki_Penguin_Aquarium_-swimming_underwater-8a.png', 'Shek Graham http://www.flickr.com/photos/shekgraham/127431519/in/photostream/', 'Mindaugas Urbonas http://commons.wikimedia.org/wiki/File:Mute_Swan-Mindaugas_Urbonas.png']; var authors = ["GNOME Documentation Team"]; var documenters = ["GNOME Documentation Team"];

// Vytvoří dialogové okno „O aplikaci“ let aboutDialog = new Gtk.AboutDialog({ title: "AboutDialog Example", program_name: "Animal Creator", copyright: "Copyright \xa9 2012 GNOME Documentation Team\n\nRed fox photo licensed CC-By by Rob Lee\nGentoo penguin photo licensed CC-By-SA by Ken Funakoshi\nFruit bat photo licensed CC-By by Shek Graham\nMute swan photo licensed CC-By-SA by Mindaugas Urbonas\nLinks to the originals are available under Credits.\n\nHave you hugged a penguin today?", artists: artists, authors: authors, documenters: documenters, website: "http://developer.gnome.org", website_label: "GNOME Developer Website" });

// Připojí dialogové okno „O aplikaci“ k oknu aboutDialog.modal = true; aboutDialog.transient_for = this._window;

// Zobrazí dialogové okno „O aplikaci“ aboutDialog.show();

// Napojí tlačítko „Zavřít“ na signál "destroy" pro dialogové okno aboutDialog.connect('response', function() { aboutDialog.destroy(); }); } };

// Spustí aplikaci let app = new SwitchExample (); app.application.run (ARGV);

# Dokumentace jdoucí do hloubky

GMenu

GSimpleAction

Gtk.Application

Gtk.ApplicationWindow

Gtk.Grid

Gtk.Image

Gtk.Label

Gtk.Switch