1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
|
<?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="topic" style="task" id="02_welcome_to_the_grid.js" xml:lang="pt-BR">
<info>
<link type="guide" xref="beginner.js#tutorials"/>
<link type="seealso" xref="grid.js"/>
<link type="seealso" xref="image.js"/>
<link type="seealso" xref="label.js"/>
<revision version="0.1" date="2012-07-28" status="draft"/>
<credit type="author copyright">
<name>Taryn Fox</name>
<email its:translate="no">jewelfox@fursona.net</email>
<years>2012</years>
</credit>
<desc>Aprenda como posicionar componentes de interface de usuário, como Images e Labels.</desc>
<mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
<mal:name>Rafael Ferreira</mal:name>
<mal:email>rafael.f.f1@gmail.com</mal:email>
<mal:years>2013</mal:years>
</mal:credit>
</info>
<title>2. Bem-vindo à Grid</title>
<synopsis>
<p>Este tutorial vai mostrar a você como criar widgets básicos ou partes da interface de usuário do GNOME, como Images (imagens) e Labels (rótulos). Você, então, aprenderá como organizá-las em uma Grid (grade), que permite que você coloca widgets exatamente onde você os quer.</p>
<note style="warning"><p>Você já viu <link xref="hellognome.js">o primeiro tutorial desta série</link>? Você vai querer vê-lo antes de continuar.</p></note>
</synopsis>
<links type="section"/>
<section id="native">
<title>Se tornando nativo</title>
<p>No último tutorial, nós criamos o que era basicamente um quadro de janela do GNOME para um aplicativo web. Todo o código específico do GNOME que nós precisamos aprender se resolver colocando o WebView -- o widget contendo nosso aplicativo -- em um ApplicationWindow, e falando para ele exibir. O aplicativo em si foi escrito em HTML e JavaScript, assim como a maioria das páginas na web.</p>
<p>Agora, nós vamos usar apenas widgets nativos do GNOME. Um widget é apenas uma coisa, como uma caixa de seleção ou imagem, e o GNOME tem uma ampla variedade delas para se escolher. Nós chamamos elas de widgets "nativas" para diferenciá-las de coisas como o botão e cabeçalho nos aplicativos web que nós escrevemos. Porque em vez de usarmos código web, essas vão ser 100 porcento GNOME, usando o GTK+.</p>
<note style="tip"><p>GTK+ significa "GIMP Toolkit" (kit de ferramentas do GIMP). É como uma caixa de ferramentas de widgets que você pode acessar, enquanto construindo seus aplicativos. Ele foi escrito originalmente para <link href="http://www.gimp.org/">o GIMP</link>, que é um software livre de edição de imagens.</p></note>
</section>
<section id="setup">
<title>Configurando seu aplicativo</title>
<p>Antes de nos aprofundarmos na caixa de ferramentas do GTK+, nós primeiro precisamos escrever o código básico padrão que nosso aplicativo requer.</p>
<code mime="application/javascript">
#!/usr/bin/gjs
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
</code>
<p>Essa parte sempre vai no começo do seu código. Dependendo do que você vai fazer com ele, você pode querer declarar muitas importações aqui. O que nós estamos escrevendo hoje é bem básico, de forma que isso é tudo que precisamos; o Gtk para os widgets, e Lang de forma que nós possamos usar o Lang.bind para conectar os sinais de ativação e inicialização de nosso aplicativo para requisitar funções.</p>
<p>Falando nisso:</p>
<code mime="application/javascript">
const WelcomeToTheGrid = new Lang.Class({
Name: 'Bem-vindo à Grid',
// Cria o aplicativo em si
_init: function() {
this.application = new Gtk.Application();
// Conecta os sinais 'activate' e 'startup' para as funções de chamada
this.application.connect('activate', Lang.bind(this, this._onActivate));
this.application.connect('startup', Lang.bind(this, this._onStartup));
},
// Função de chamada para o sinal 'activate' apresenta janelas quando ativa
_onActivate: function() {
this._window.present();
},
// Função de chamada para sinal 'startup' constrói a interface gráfica
_onStartup: function() {
this._buildUI ();
},
</code>
<p>Esse é o começo de um aplicativo em si e a função _init que cria-o. Ela fala para _buildUI criar um ApplicationWindow, com o qual nós vamos chamar _window, e fala para nossa janela para se apresentar quando for necessário.</p>
<p>Essa parte, de novo, é basicamente um copia-e-cola, mas você sempre deseja dar seu aplicativo um nome único.</p>
<code mime="application/javascript">
// Constrói a interface gráfica do aplicativo
_buildUI: function() {
// Cria a janela do aplicativo
this._window = new Gtk.ApplicationWindow({
application: this.application,
window_position: Gtk.WindowPosition.CENTER,
border_width: 10,
title: "Bem-vindo à Grid"});
</code>
<p>Finalmente, nós começamos a função _buildUI criando uma nova ApplicationWindow. Nós especificamos que ela vai com este aplicativo, que ela deveria aparecer no centro da tela, e que deve haver pelo menos 10 pixels entre a borda exterior e quaisquer widgets dentro dela. Nós também damos a ela um título, que vai aparecer no topo da janela.</p>
</section>
<section id="toolbox">
<title>Alcançando a caixa de ferramentas do GTK+</title>
<p>Quais widgets nós deveríamos usar? Bem, digamos que nós queremos escrever um aplicativo que se parece com este:</p>
<media type="image" mime="image/png" src="media/02_jsgrid_01.png"/>
<p>Nós vamos precisar, no mínimo, de uma imagem e um rótulo de texto para seguir. Vamos começar com a imagem:</p>
<code mime="application/javascript">
// Cria uma imagem
this._image = new Gtk.Image ({ file: "gnome-image.png" });
</code>
<p>Você pode baixar o arquivo de imagem neste exemplo <link href="https://live.gnome.org/TarynFox?action=AttachFile&do=get&target=gnome-image.png">arquivo</link>. Certifique-se de colocá-lo no mesmo diretório do código que você está escrevendo.</p>
<code mime="application/javascript">
// Cria um rótulo
this._label = new Gtk.Label ({ label: "Bem-vindo ao GNOME, também!" });
</code>
<p>Aquele código adiciona o rótulo abaixo. Você pode ver como nós criamos widgets aqui; cada um é uma parte do GTK e nós podemos dar a ele propriedades que personalizam como ele se comporta. neste caso, nós definimos a propriedade do arquivo de imagem para ser o nome do arquivo da imagem que queremos e adicionamos a propriedade de rótulo do Label para ser a sentença que desejamos embaixo da imagem.</p>
<note style="tip"><p>Sim, isso soa redundante um Label ter uma propriedade de rótulo, mas não é. Outros widgets que contêm texto possuem uma propriedade de rótulo, de forma que é <em>consistente</em> para o widget de Label ter um também.</p></note>
<p>Nós não podemos simplesmente adicionar estes widgets a nossa janela em ordem, porém, da mesma forma que elementos HTML aparecem na ordem que você escreve-os. Isso porque em ApplicationWindow pode conter apenas um widget.</p>
<p>Como nós resolvemos isso? Marcando aquele widget como um widget contêiner, que pode manter mais de um widget e organizá-los dentro dele. Conheça: a Grid.</p>
<code mime="application/javascript">
// Cria a Grid
this._grid = new Gtk.Grid ();
</code>
<p>Nós não estamos desistindo de nenhuma propriedade ainda. Aquelas virão posteriormente, na medida em que aprendemos como usar os poderes da Grid. Primeiro, vamos anexar a Image e Label que nós fizemos para nossa Grid.</p>
<code mime="application/javascript">
// Anexa a imagem e o rótulo à grade
this._grid.attach (this._image, 0, 0, 1, 1);
this._grid.attach (this._label, 0, 1, 1, 1);
</code>
<p>Este código parece muito complicado, mas não é. Aqui segue o que aqueles números significam:</p>
<list type="numbered">
<item><p>O <em>primeiro</em> número é qual posição esquerda-para-direita deve-se coloca as coisas, começando de 0. Qualquer widget que usa um 0 aqui vai para o mais esquerda possível.</p></item>
<item><p>O <em>segundo</em> número é qual posição de cima-para-baixo deve-se colocar uma dado widget, começando de 0. O Label vai embaixo da Image, de forma que nós damos à Image um 0 e o Label um 1 aqui.</p></item>
<item><p>O <em>terceiro</em> e <em>quarto</em> números são quantas colunas e linhas um widget deveria levar. Nós vamos ver como estes funcionam em um minuto.</p></item>
</list>
<code mime="application/javascript">
// Adiciona a grade à janela
this._window.add (this._grid);
// Mostra a janela e todos seus widgets filhos
this._window.show_all();
}
});
// Executa o aplicativo
let app = new WelcomeToTheGrid ();
app.application.run (ARGV);
</code>
<p>Agora que nós criamos a Grid e anexamos todos os nossos widgets a ela, nós adicionamos-a à janela e falamos para a janela se mostrar, como parte da função _buildUI. Como sempre, para finalizar nós criamos uma nova instância da classe do aplicativo e falamos para ele executar.</p>
<p>Salva seu aplicativo como welcome_to_the_grid.js. Então, para executar seu aplicativo basta abrir um terminal, ir até o diretório onde seu aplicativo se encontra e digitar</p>
<screen> <output style="prompt">$ </output>gjs welcome_to_the_grid.js </screen>
<media type="image" mime="image/png" src="media/02_jsgrid_02.png"/>
<p>Pronto! Mas espera. Isso não parece correto. Por que o Label está misturado próximo à Image desta forma? Isso não ficou legal e fica mais difícil de ler. O que nós podemos fazer quanto a isso?</p>
</section>
<section id="tweaking">
<title>Ajustando a Grid</title>
<p>Uma coisa que nós podemos fazer é dar ao Label uma propriedade margin_top no momento de sua criação. Isso funciona mais ou menos como definir uma margem para um elemento HTML usando estilo CSS embutido.</p>
<code mime="application/javascript">
// Cria um rótulo
this._label = new Gtk.Label ({
label: "Bem-vindo ao GNOME, também!",
margin_top: 20 });
</code>
<p>É claro que, se nós fizermos isso, então se substituirmos a Label com alguma outra coisa -- ou adicionar em outro widget --, então nós teremos que repetir o margin_top nele também. Do contrário, nós acabaremos com alguma coisa como isso:</p>
<media type="image" mime="image/png" src="media/02_jsgrid_03.png"/>
<p>Nós poderíamos dar à Image uma propriedade margin_bottom, mas isso não vai funcionar quando a nova Label estiver em uma coluna separada. Então, que tal nós tentarmos isso:</p>
<code mime="application/javascript">
// Cria a Grid
this._grid = new Gtk.Grid ({
row_spacing: 20 });
</code>
<p>Isso resolve, de forma que há sempre 20 pixels de espaço entre cada linha horizontal.</p>
<note style="tip"><p>Sim, você também pode definir a propriedade column_spacing em uma Grid ou as propriedades margin_left e margin_right em qualquer widget. Tente-os, se você quiser!</p></note>
</section>
<section id="adding">
<title>Adicionando mais widgets</title>
<p>Se nós quiséssemos adicionar um segundo Label, como que nós vamos fazê-lo de forma que ela realmente pareça como pertencente dali? Uma forma é centralizar a Image na parte superior, de forma que esteja em cima de ambas Labels, em vez de apenas uma para a esquerda. É aí que aqueles outros números no método para anexar na Grid entram:</p>
<code mime="application/javascript">
// Cria um segundo rótulo
this._labelTwo = new Gtk.Label ({
label: "O bolo é uma torta." });
// Anexa a imagem e rótulos à grade
this._grid.attach (this._image, 0, 0, 2, 1);
this._grid.attach (this._label, 0, 1, 1, 1);
this._grid.attach (this._labelTwo, 1, 1, 1, 1);
</code>
<p>Após termos criado um segundo Label, nós o anexamos o segundo Label, o anexamos à Grid à direita do primeiro Label. Lembre-se, os primeiros dois números contam colunas e linhas da esquerda para a direita e de cima para baixo, começando com 0. Então, se o primeiro Label está na coluna 0 e linha 1, nós podemos colocar o segundo na coluna 1 e linha 1 para colocá-lo à direita do primeiro Label.</p>
<p>Note que o número 2 na declaração de anexação para a Image. É o que faz o truque aqui. Aquele número é quantas colunas uma Image se estende, lembra-se? Então, quando nós colocarmos isso junto, nós obteremos algo tipo isso:</p>
<media type="image" mime="image/png" src="media/02_jsgrid_04.png"/>
<p>Há duas coisas das quais você deveria tomar nota, aqui.</p>
<list>
<item><p>A definição da Image para se estender a duas colunas não estica a imagem em si horizontalmente. Ao invés disso, ela estica a caixa invisível utilizadas pelo widget da Image para preencher ambas colunas e, então, colocar a imagem no centro daquela caixa.</p></item>
<item><p>Ainda que tenhamos definido as propriedades row_spacing da Grid e border_width da ApplicationWindow, nós ainda não definimos nada que coloque uma borda entre as duas Labels. Elas estavam separadas anteriormente, quando a Imagem estava apenas em uma coluna, mas agora que ela estende ambas, o GNOME não vê um motivo para mantê-los separados.</p></item>
</list>
<p>Há pelo menos três formas de resolvermos o último. Primeiro, nós podemos definir um margin_left ou margin_right em um dos Labels:</p>
<media type="image" mime="image/png" src="media/02_jsgrid_05.png"/>
<p>Segundo, nós podemos definir a propriedade column_homogenous da Grid para "true".</p>
<code mime="application/javascript">
// Cria a Grid
this._grid = new Gtk.Grid ({
column_homogeneous: true,
row_spacing: 20 });
</code>
<p>Isso faz com que ela se pareça com algo como isso:</p>
<media type="image" mime="image/png" src="media/02_jsgrid_06.png"/>
<p>E terceiro, nós podemos definir a propriedade column_spacing da Grid, da mesma forma que nós definimos sua row_spacing.</p>
<code mime="application/javascript">
// Cria a Grid
this._grid = new Gtk.Grid ({
column_spacing: 20,
row_spacing: 20 });
</code>
<p>Isso faz com que ela se pareça com isso:</p>
<media type="image" mime="image/png" src="media/02_jsgrid_07.png"/>
</section>
<section id="stock">
<title>Usando imagens padrões</title>
<p>O GNOME já possui um monte de imagens padrões em mãos, que nós podemos usar se não quisermos criar nossa própria ou se nós quisermos um ícone reconhecido universalmente. Aqui está como nós criamos imagens padrões, comparado com como nós criamos um normal:</p>
<code mime="application/javascript">
// Cria uma imagem
this._image = new Gtk.Image ({ file: "gnome-image.png" });
// Cria uma segunda imagem usando o ícone padrão
this._icon = new Gtk.Image ({ stock: 'gtk-about' });
</code>
<p>Após isso, nós anexamos-o à Grid à esquerda do primeiro Label. (Nós não vamos usar o segundo para este exemplo.)</p>
<code mime="application/javascript">
// Anexa as imagens e rótulos à grade
this._grid.attach (this._image, 0, 0, 2, 1);
this._grid.attach (this._icon, 0, 1, 1, 1);
this._grid.attach (this._label, 1, 1, 1, 1);
</code>
<p>Isso nos dá isso, quando nós o executamos:</p>
<media type="image" mime="image/png" src="media/02_jsgrid_08.png"/>
<p>É assim que o ícone padrão "Sobre" se parece. Você pode ver uma lista de todos os itens padrões começando com o gtk-about na <link href="https://developer.gnome.org/gtk3/3.4/gtk3-Stock-Items.html#GTK-STOCK-ABOUT:CAPS">documentação de desenvolvimento do GNOME</link>. Foi escrita para programadores de C, mas você não precisa saber C para usá-la; basta olha na parte nos sinais de citação, como "gtk-about" e copiar aquela parte para usar o ícone ao lado dele.</p>
<note style="tip"><p>Nós colocamos aspas simples em volta de 'gtk-about' aqui porque, ao contrário de strings de texto que têm aspas duplas em volta, aquela parte nunca precisará ser traduzida para outro idioma. Na verdade, se ela <em>fosse</em> traduzida, ela quebraria o ícone porque seu nome ainda é "gtk-about" independentemente do seu idioma.</p></note>
</section>
<section id="next">
<title>O que vem em seguida?</title>
<p>Antes de irmos para o próximo tutorial, vamos tentar algo um pouco diferente:</p>
<code mime="application/javascript">
// Cria um botão
this._button = new Gtk.Button ({
label: "Bem-vindo ao GNOME, também!"});
// Anexa as imagens e botão à grade
this._grid.attach (this._image, 0, 0, 2, 1);
this._grid.attach (this._icon, 0, 1, 1, 1);
this._grid.attach (this._button, 1, 1, 1, 1);
</code>
<p>É isso mesmo, nós tornamos o Label em um Button apenas alterando o seu nome! Se você executar o aplicativo e clicar nele, porém, você descobrirá que ele faz nada. Como nós vamos fazer nosso Button fazer algo? É o que vamos descobrir, em <link xref="03_getting_the_signal.js">nosso próximo tutorial</link>.</p>
<p>Se você quiser, sinta-se à vontade para gastar algum tempo experimentando Grids, Labels e Images, incluindo imagens padrões.</p>
<note style="tip"><p>Um truque que você pode usar para fazer layouts mais complexos é aninhar Grids dentro de Grids. Isso permite que você agrupe widgets relacionados e rearranje-os facilmente. Dê uma olhada na amostra de código do <link xref="radiobutton.js">RadioButton</link>, se você quiser ver como ele é feito.</p></note>
</section>
<section id="complete">
<title>Amostra de código completo</title>
<code mime="application/javascript" style="numbered">#!/usr/bin/gjs
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const WelcomeToTheGrid = new Lang.Class({
Name: 'Bem-vindo à Grid',
// Cria o aplicativo em si
_init: function() {
this.application = new Gtk.Application();
// Conecta os sinais 'activate' e 'startup' às funções de chamada
this.application.connect('activate', Lang.bind(this, this._onActivate));
this.application.connect('startup', Lang.bind(this, this._onStartup));
},
// Função de chamada para o sinal 'activate' apresenta janelas quando ativo
_onActivate: function() {
this._window.present();
},
// Função de chamada para o sinal 'startup' constrói a interface gráfica
_onStartup: function() {
this._buildUI ();
},
// Constrói a interface gráfica do aplicativo
_buildUI: function() {
// Cria a janela do aplicativo
this._window = new Gtk.ApplicationWindow({
application: this.application,
window_position: Gtk.WindowPosition.CENTER,
border_width: 10,
title: "Bem-vindo à Grid"});
// Cria a Grid
this._grid = new Gtk.Grid ({
// column_homogeneous: true,
// column_spacing: 20,
row_spacing: 20 });
// Cria uma imagem
this._image = new Gtk.Image ({ file: "gnome-image.png" });
// Cria uma segunda imagem usando um ícone padrão
this._icon = new Gtk.Image ({ stock: 'gtk-about' });
// Cria um rótulo
this._label = new Gtk.Label ({
label: "Bem-vindo ao GNOME, também!",
/* margin_top: 20 */ });
/* Cria um segundo rótulo
this._labelTwo = new Gtk.Label ({
label: "O bolo é uma torta." }); */
/* Cria um botão
this._button = new Gtk.Button ({
label: "Bem-vindo ao GNOME, também!"}); */
// Anexa as imagens e botão à grade
this._grid.attach (this._image, 0, 0, 2, 1);
this._grid.attach (this._icon, 0, 1, 1, 1);
this._grid.attach (this._label, 1, 1, 1, 1);
// this._grid.attach (this._label, 0, 1, 1, 1);
// this._grid.attach (this._labelTwo, 1, 1, 1, 1);
// this._grid.attach (this._button, 1, 1, 1, 1);
// Adiciona a grade à janela
this._window.add (this._grid);
// Mostra a janela e todos os widgets filhos
this._window.show_all();
}
});
// Executa o aplicativo
let app = new WelcomeToTheGrid ();
app.application.run (ARGV);
</code>
</section>
</page>
|