<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2001/XInclude" type="guide" style="task" id="scale.js" xml:lang="cs">
<info>
<title type="text">Scale (JavaScript)</title>
<link type="guide" xref="beginner.js#entry"/>
<revision version="0.1" date="2012-06-20" status="draft"/>
<credit type="author copyright">
<name>Taryn Fox</name>
<email its:translate="no">jewelfox@fursona.net</email>
<years>2012</years>
</credit>
<desc>Stupnice, která odpovídá číselné hodnotě</desc>
</info>
<title>Scale</title>
<media type="image" mime="image/png" src="media/scalepenguins.png"/>
<p>Widget <code>Scale</code> (stupnice), je vodorovná nebo svislá lišta s táhlem, která představuje hodnotu z nějakého číselného rozsahu. Když vytvoříte novou stupnici, nastavíte ji výchozí polohu, která čísla odpovídají dolní a horní mezi rozsahu, a věci, jako o kolik se má posunout nahoru/dolů při kliknutí na konce lišty. Abyste nemuseli všechny tyto věci psát znovu a znovu, když stupnici vytváříte, můžete vytvořit objekt <code>Adjustment</code> (přizpůsobení), který si to vše pamatuje, a stupnici pak akorát řeknete, že ho má použít.</p>
<p>Tato stupnice je jednoduchý widget, pomocí kterého můžeme upravovat velikost ledové kry, na které žijí tučňáci. Počet tučňáků na kře je násobkem hodnot ze dvou stupnic. Hrajte si s nimi a uvidíte, co se bude dít.</p>
<links type="section"/>
<section id="imports">
<title>Importované knihovny</title>
<code mime="application/javascript">
#!/usr/bin/gjs
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
</code>
<p>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.</p>
</section>
<section id="applicationwindow">
<title>Vytvoření okna aplikace</title>
<code mime="application/javascript">
const ScaleExample = new Lang.Class({
Name: 'Scale Example',
// Vytvoří vlastní aplikaci
_init: function() {
this.application = new Gtk.Application({
application_id: 'org.example.jsscale'
});
// Napojí 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._buildUI ();
},
</code>
<p>Všechen kód této ukázky je ve třídě ScaleExample. Výše uvedený kód vytvoří <link href="http://www.roojs.com/seed/gir-1.2-gtk-3.0/gjs/Gtk.Application.html">Gtk.Application</link> pro naše widgety a okno, ve kterém budou.</p>
<code mime="application/javascript">
// 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: "Birds on a Floe"});
</code>
<p>Funkce <code>_buildUI</code> 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 <link xref="GtkApplicationWindow.js">Gtk.ApplicationWindow</link>, do kterého vložíme všechny naše widgety.</p>
</section>
<section id="button">
<title>Vytvoření stupnic</title>
<code mime="application/javascript">
// Vytvoří vodorovnou stupnici
this._hScale = Gtk.Scale.new_with_range (Gtk.Orientation.HORIZONTAL, 0.0, 100.0, 5.0);
this._hScale.set_valign (Gtk.Align.START);
this._hScale.set_value (50);
this._hScale.set_digits (0);
// this._hScale.set_draw_value (false);
</code>
<p>Metoda <code>new_with_range</code> je jedním ze způsobů, jak vytvořit nový widget <code>Scale</code>. Přebírané parametry jsou <link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Orientation.html">Gtk.Orientation</link>, nejnižší hodnota, nejvyšší hodnota a přírůstek pro jeden krok. Potom použijeme metody widgetu k nastavení jeho počáteční hodnoty a kolik desetinných míst má používat. V tomto případě také nastavíme svislé zarovnání, které určuje, kde v okně se objeví.</p>
<p>Můžeme použít metodu <code>set_draw_value</code>, abychom řekli, jestli se má nebo nemá vedle stupnice zobrazovat číselná hodnota. V tomto příkladu je zakomentováno.</p>
<code mime="application/javascript">
// Vytvoří hlavní přizpůsobení, které se použije pro svislou (nebo jinou) stupnici
this._adjustment = new Gtk.Adjustment ({
value: 95,
lower: 0,
upper: 100,
step_increment: 5,
page_increment: 10 });
</code>
<p>Objekt <code>Adjustment</code> (přizpůsobení) můžete použít pro zjednodušení věcí okolo vytváření nové stupnice. Vlastnost <code>"value"</code> u přizpůsobení je to stejné, co výchozí hodnota u stupnice, zatímco <code>"upper"</code> a <code>"lower"</code> určují meze číselného rozsahu. Mezi tím jsou přírůstky hodnot říkající, jak moc se má posunout táhlo, když uděláte takové věci, jako že na stupnici kliknete.</p>
<code mime="application/javascript">
// Vytvoří svislou stupnici používající přizpůsobení,
// které jsme právě vytvořili
this._vScale = new Gtk.Scale ({
orientation: Gtk.Orientation.VERTICAL,
adjustment: this._adjustment,
digits: 0,
// draw_value: false,
margin_left: 10 });
</code>
<p>Zde vytvoříme novou stupnici pomocí přiřazení <code>_adjustment</code> do její vlastnosti <code>"adjustment"</code>. Jedná se o velkou zkratku, i když i tak pořád musíme stupnici říct, na kolik desetinných míst má fungovat. Poznamenejme, že vlastnost <code>"draw_value"</code> je zakomentovaná. Jedná se o způsob, jak říct, že se nemá vedle stupnice zobrazovat číselná hodnota, když stupnici vytváříte tímto způsobem.</p>
<code mime="application/javascript">
// Vytvoří popisek, který zobrazuje součin dvou hodnot
this._product = (this._hScale.get_value() * this._vScale.get_value());
this._label = new Gtk.Label ({
label: (String(this._product) + " penguins on the iceberg."),
height_request: 200,
width_request: 200,
wrap: true});
// Napojí dvě stupnice na funkci, která přepočítává údaj pro popisek
this._hScale.connect ("value-changed", Lang.bind (this, this._recalc));
this._vScale.connect ("value-changed", Lang.bind (this, this._recalc));
</code>
<p>Můžeme použít metodu <code>get_value_method</code> k nalezení číselné hodnoty, na kterou je stupnice nastavena. S ní pak můžeme dělat cokoliv je potřeba, včetně vzájemného vynásobení hodnot ze dvou stupnic. Součin pak zobrazíme ve widgetu <link xref="label.js">Label</link>. Nastavíme, aby se text popisku zalamovat, protože bude rovněž zobrazovat bláznivou zprávu.</p>
<p>Když máme vytvořený popisek, napojíme signály <code>"value-changed"</code> od obou stupnic na funkci <code>_recals</code>, která bude přepočítávat počet tučňáků na ledové kře a podávat o nich novou zprávu.</p>
<code mime="application/javascript">
// Vytvoří mřížku pro uspořádání věcí
this._UIGrid = new Gtk.Grid ({
halign: Gtk.Align.CENTER,
valign: Gtk.Align.CENTER,
margin_top: 20,
margin_left: 20});
// Připojí vše do mřížky
this._UIGrid.attach (this._label, 0, 0, 1, 1);
this._UIGrid.attach (this._hScale, 0, 1, 1, 1);
this._UIGrid.attach (this._vScale, 1, 0, 1, 1);
</code>
<p>Zde pro všechno vytvoříme widget <link xref="grid.js">Grid</link> a všechny naše widgety do něj připojíme. Všimněte si, že zde (a i u některých widgetů) použijeme okraje, abychom zachovali potřebné rozestupy.</p>
<code mime="application/javascript">
// Přidá mřížku do okna
this._window.add (this._UIGrid);
// Zobrazí okno a všechny jeho synovské widgety
this._window.show_all();
},
</code>
<p>Nakonec přidáme mřížku do okna a následně oknu řekneme, aby zobrazilo sebe a všechny widgety uvnitř sebe.</p>
</section>
<section id="scales-handler">
<title>Funkce, která obsluhuje změnu hodnoty na stupnici</title>
<code mime="application/javascript">
_recalc: function() {
// Zjistí, jaký je součin hodnot ze dvou stupnic
var product = (this._hScale.get_value() * this._vScale.get_value());
// Vytvoří prázdný komentář pro případ, kdy není jaký bláznivý komentář vytvořit
var comment = "";
// Vytvoří bláznivý komentář vycházející z počtu tučňáků
if (product > 9000) {
comment = "It's over 9000!";
}
else if (product < 1000 && product > 0) {
comment = "They're getting lonely.";
}
else if (product == 0) {
comment = "They're all gone…";
}
else comment = "";
// Nastaví nový text pro ._label
this._label.set_label (String (product) + " penguins on the iceberg. " + comment);
}
});
</code>
<p>Pamatujete, jak jsme od stupnice získali hodnotu pomocí její metody <code>get_value</code>? Zde jednoduše přepočítáme součin dvou hodnot po té, co je stupnice posunuta, přidáme bláznivou zprávu v závislosti na tom, kolik tučňáků zůstalo, a změníme formulaci v <code>_label</code> ukazujícím nový počet a zprávu.</p>
<code mime="application/javascript">
// Spustí aplikaci
let app = new ScaleExample ();
app.application.run (ARGV);
</code>
<p>Nakonec vytvoříme novou instanci konečné třídy ScaleExample a aplikaci spustíme.</p>
</section>
<section id="complete">
<title>Úplný kód ukázky</title>
<code mime="application/javascript" style="numbered">#!/usr/bin/gjs
imports.gi.versions.Gtk = '3.0';
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
class ScaleExample {
// Vytvoří vlastní aplikaci
constructor() {
this.application = new Gtk.Application({
application_id: 'org.example.jsscale'
});
// 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._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: "Birds on a Floe"});
// Vytvoří vodorovnou stupnici
this._hScale = Gtk.Scale.new_with_range (Gtk.Orientation.HORIZONTAL, 0.0, 100.0, 5.0);
this._hScale.set_valign (Gtk.Align.START);
this._hScale.set_value (50);
this._hScale.set_digits (0);
// this._hScale.set_draw_value (false);
// Vytvoří hlavní přizpůsobení, které se použije pro svislou (nebo jinou) stupnici
this._adjustment = new Gtk.Adjustment ({
value: 95,
lower: 0,
upper: 100,
step_increment: 5,
page_increment: 10 });
// Vytvoří svislou stupnici používající přizpůsobení,
// které jsme právě vytvořili
this._vScale = new Gtk.Scale ({
orientation: Gtk.Orientation.VERTICAL,
adjustment: this._adjustment,
digits: 0,
// draw_value: false,
margin_left: 10 });
// Vytvoří popisek, který zobrazuje součin dvou hodnot
this._product = (this._hScale.get_value() * this._vScale.get_value());
this._label = new Gtk.Label ({
label: (String(this._product) + " penguins on the iceberg."),
height_request: 200,
width_request: 200,
wrap: true});
// Napojí dvě stupnice na funkci, která přepočítává údaj pro popisek
this._hScale.connect ("value-changed", this._recalc.bind(this));
this._vScale.connect ("value-changed", this._recalc.bind(this));
// Vytvoří mřížku pro uspořádání věcí
this._UIGrid = new Gtk.Grid ({
halign: Gtk.Align.CENTER,
valign: Gtk.Align.CENTER,
margin_top: 20,
margin_left: 20});
// Připojí vše do mřížky
this._UIGrid.attach (this._label, 0, 0, 1, 1);
this._UIGrid.attach (this._hScale, 0, 1, 1, 1);
this._UIGrid.attach (this._vScale, 1, 0, 1, 1);
// Přidá mřížku do okna
this._window.add (this._UIGrid);
// Zobrazí okno a všechny jeho synovské widgety
this._window.show_all();
}
_recalc() {
// Zjistí, jaký je součin hodnot ze dvou stupnic
var product = (this._hScale.get_value() * this._vScale.get_value());
// Vytvoří prázdný komentář pro případ, kdy není jaký bláznivý komentář vytvořit
var comment = "";
// Vytvoří bláznivý komentář vycházející z počtu tučňáků
if (product > 9000) {
comment = "It's over 9000!";
}
else if (product < 1000 && product > 0) {
comment = "They're getting lonely.";
}
else if (product == 0) {
comment = "They're all gone ...";
}
else comment = "";
// Nastaví nový text pro ._label
this._label.set_label (String (product) + " penguins on the iceberg. " + comment);
}
};
// Spustí aplikaci
let app = new ScaleExample ();
app.application.run (ARGV);
</code>
</section>
<section id="in-depth">
<title>Dokumentace jdoucí do hloubky</title>
<list>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Adjustment.html">Gtk.Adjustment</link></p></item>
<item><p><link href="http://www.roojs.com/seed/gir-1.2-gtk-3.0/gjs/Gtk.Application.html">Gtk.Application</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkApplicationWindow.html">Gtk.ApplicationWindow</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Grid.html">Gtk.Grid</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Label.html">Gtk.Label</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Scale.html">Gtk.Scale</link></p></item>
</list>
</section>
</page>