Criando uma aplicação com o qooxdoo

O qooxdoo é um framework javascript universal usado para criar aplicações interativas, aplicativos para dispositivos móveis, aplicações web single-page, entre outros.

Irei repassar aqui um tutorial da própria qooxdoo para criar uma pequena aplicação web single-page contendo um cliente do twitter onde o usuário possa ler tweets públicos e poder postar tweets também.

No tutorial estarei utilizando o windows 7.

Primeiro passo é baixar o python para poder usar a poderosa ferramenta de gerar aplicações.

Link: http://www.activestate.com/activepython/downloads

Agora é só baixar a SDK do qooxdoo.

Link: http://downloads.sourceforge.net/qooxdoo/qooxdoo-2.0.1-sdk.zip

Instale o python, após a instalação extraia a sdk e coloque em uma pasta de sua preferência, aqui coloquei em C:\qooxdoo-2.0.1-sdk. Antes de começarmos a criar nossa aplicação vamos colocar o python na lista de variáveis de ambiente do windows.

Abra o cmd e digite o comando set PATH=C:\Python27; %PATH% sem aspas, onde C:\Python27 é o diretório de instalação do python.

Para criar uma aplicação é muito simples basta rodar o script create-application.py localizado em tool/bin na pasta da SDK, ainda no cmd digite: C:\qooxdoo-2.0.1-sdk\tool\bin\create-application.py –name=twitter

Isto irá criar uma aplicação chamada twitter contendo toda a estrutura de diretórios e configurações necessárias para o funcionamento da mesma, agora basta executar o comando cd twitter e entrar na pasta da aplicação agora digitando o comando generate.py para gerar os scripts de sua aplicação.

Depois de gerar os scripts, crie na pasta source/class/twitter um arquivo chamado MainWindow.js e dentro deste arquivo escreva o seguinte código.

qx.Class.define("twitter.MainWindow",
{
  extend : qx.ui.window.Window,

    construct : function()
    {
      this.base(arguments, "twitter");
    }
});

O que acabamos de fazer com esse código foi definir uma classe chamada “twitter.MainWindow” que extende da classe Window do qooxdo, o construtor da classe sobrescreve o construtor da super-classe  passando como parâmetro o título da janela, no caso “twitter”. Salve este arquivo  e abra o Application.js e abaixo do bloco de comentário coloque o seguinte código.

var main = new twitter.MainWindow();
main.open();

Nós apenas instânciamos nossa classe MainWindow e executamos o método open. Antes de testarmos nossa aplicação no navegador devemos gerar mais uma vez os scripts, já que estamos utilizando a classe Window do qooxdoo como dependência, então execute mais uma vez o comando generate.py no cmd e abra o arquivo index.html para visulaizar a aplicação no navegador. Você deve ver algo parecido com isto:

Vamos agora fazer algumas alterações na interface gráfica da nossa janela, ainda no Application.js acrescente este código:

main.moveTo(50, 30);

movemos nossa janela para uma nova localização. Voltando agora para o arquivo MainWindow.js coloque o seguinte código no construtor da janela:

//Esconder os botões da janela
this.setShowClose(false);
this.setShowMaximize(false);
this.setShowMinimize(false);

// ajustar o tamanho da janela
this.setWidth(250);
this.setHeight(300);

Atualize a página e veja as mudanças. Abaixo coloque o seguinte código:

// add o layout
var layout = new qx.ui.layout.Grid(0, 0);
this.setLayout(layout);

// toolbar
var toolbar = new qx.ui.toolbar.ToolBar();
this.add(toolbar, {row: 0, column: 0, colSpan: 2});

// lista
var list = new qx.ui.form.List();
this.add(list, {row: 1, column: 0, colSpan: 2});

this.setContentPadding(0);
layout.setRowFlex(1, 1);
layout.setColumnFlex(0, 1);

// Botão recarregar
var reloadButton = new qx.ui.toolbar.Button("Recarregar");
toolbar.add(reloadButton);

// textarea
var textarea = new qx.ui.form.TextArea();
this.add(textarea, {row: 2, column: 0});

// Botão postar
var postButton = new qx.ui.form.Button("Postar");
this.add(postButton, {row: 2, column: 1});

reloadButton.setToolTipText("Recarregar os tweets.");
textarea.setPlaceholder("Digite sua mensagem aqui...");
postButton.setToolTipText("´");

Na linha 2 criamos um layout do tipo grid e setamos ele em nossa janela, na linha 6 criamos uma toolbar e adicionamos ela a nossa janela já preparada para receber os componentes e ajusta-los em forma de grade, mesma coisa com a lista da linha 10. Na linha 13 setamos o padding da janela no valor 0, já as linhas 14 e 15 servem para deixar a lista flexível. Na linha 18 é adicionado um botão na toolbar para recarregar os tweets e nas linhas seguintes são adicionados um textarea e outro botão à janela, nas linhas finais são dados alguns toques para finalizar a nossa janela como mostrar pra que serve o botão quando o mouse fica sobre ele.

No final do construtor acrescente este código:

event : 
 {
	"reload" : "qx.event.type.Event",
	"post"   : "qx.event.type.Data"
 }

E abaixo de postButton.setToolTipText(“Poste esta mensagem no twitter.”); coloque:

reloadButton.addListener("execute", function() {
	this.fireEvent("reload");
}, this);
postButton.addListener("execute", function() {
	this.fireDataEvent("post", textarea.getValue());
}, this);

Até agora nosso arquivo MainWindow.js está assim:

qx.Class.define("twitter.MainWindow",
{
  extend : qx.ui.window.Window,

  construct : function()
  {
    this.base(arguments, "twitter", "twitter/t_small-c.png");

    // hide the window buttons
    this.setShowClose(false);
    this.setShowMaximize(false);
    this.setShowMinimize(false);

    // adjust size
    this.setWidth(250);
    this.setHeight(300);

    // add the layout
    var layout = new qx.ui.layout.Grid(0, 0);
    layout.setRowFlex(1, 1);
    layout.setColumnFlex(0, 1);
    this.setLayout(layout);
    this.setContentPadding(0);

    // toolbar
    var toolbar = new qx.ui.toolbar.ToolBar();
    this.add(toolbar, {row: 0, column: 0, colSpan: 2});

    // reload button
    var reloadButton = new qx.ui.toolbar.Button("Reload");
    toolbar.add(reloadButton);
    reloadButton.setToolTipText("Reload the tweets.");
    reloadButton.addListener("execute", function() {
      this.fireEvent("reload");
    }, this);

    // list
    var list = new qx.ui.form.List();
    this.add(list, {row: 1, column: 0, colSpan: 2});

    // textarea
    var textarea = new qx.ui.form.TextArea();
    this.add(textarea, {row: 2, column: 0});
    textarea.setPlaceholder("Enter your message here...");
    textarea.addListener("input", function(e) {
      var value = e.getData();
      postButton.setEnabled(value.length < 140 && value.length > 0);
    }, this);

    // post button
    var postButton = new qx.ui.form.Button("Post");
    this.add(postButton, {row: 2, column: 1});
    postButton.setToolTipText("Post this message on twitter.");
    postButton.addListener("execute", function() {
      this.fireDataEvent("post", textarea.getValue());
    }, this);
    postButton.setWidth(60);
    postButton.setEnabled(false);
  },

  events :
  {
    "reload" : "qx.event.type.Event",
    "post" : "qx.event.type.Data"
  }
});

Vamos agora para nosso arquivo Application.js e escrever este código:

main.addListener("reload", function() {
	this.debug("reload");
}, this);

main.addListener("post", function(e) {
	this.debug("post: " + e.getData());
}, this);

Até agora nosso arquivo Application.js está desta forma:

/* ************************************************************************

Copyright:

License:

Authors:

************************************************************************ */

/* ************************************************************************

#asset(twitter/*)

************************************************************************ */

/**
* This is the main application class of your custom application "twitter"
*/
qx.Class.define("twitter.Application",
{
  extend : qx.application.Standalone,

  /*
*****************************************************************************
MEMBERS
*****************************************************************************
*/

  members :
  {
    /**
* This method contains the initial application code and gets called
* during startup of the application
*
* @lint ignoreDeprecated(alert)
*/
    main : function()
    {
      // Call super class
      this.base(arguments);

      // Enable logging in debug variant
      if (qx.core.Environment.get("qx.debug"))
      {
        // support native logging capabilities, e.g. Firebug for Firefox
        qx.log.appender.Native;
        // support additional cross-browser console. Press F7 to toggle visibility
        qx.log.appender.Console;
      }

      /*
-------------------------------------------------------------------------
Below is your actual application code...
-------------------------------------------------------------------------
*/

      var main = new twitter.MainWindow();
      main.moveTo(50, 30);
      main.open();

      main.addListener("reload", function() {
        this.debug("reload");
      }, this);

      main.addListener("post", function(e) {
        this.debug("post: " + e.getData());
      }, this);
    }
  }
});

Gere mais uma vez os scripts e veja como está a aplicação, ela deve está parecida com esta imagem:

Agora vamos dar início a interação com o twitter, crie outro arquivo na mesma pasta que Application.js e MainWindow.js chamado de TwitterService e inicialmente escreva o seguinte código:

qx.Class.define("twitter.TwitterService",
{
  extend : qx.core.Object,
  members :
  {
  }
});

Diferente da classe MainWindow, esta não precisa extender de uma classe complexa como a Window, ela extende da classe Object que é uma classe simples. Acrescente este código antes de members:

properties : {
    tweets : {
      nullable: true,
      event: "changeTweets"
    }
  },

  events : {
    "postOk" : "qx.event.type.Event"
  },

E dentro de members o seguinte código:

__store : null,

    fetchTweets : function() {
      if (this.__store == null) {
        var url = "http://api.twitter.com/1/statuses/public_timeline.json";
        this.__store = new qx.data.store.Jsonp(url, null, "callback");
        this.__store.bind("model", this, "tweets");
      } else {
        this.__store.reload();
      }
    },

    post : function(message)
      window.open("http://twitter.com/?status=" + encodeURIComponent(message));
    }
  }

Aqui em cima criamos uma propriedade chamada tweets, que pode ser nulo e possui um evento chamado “changeTweets“. Criamos também um evento chamdo “postOk” do tipo “qx.event.type.Event” além dos membros, um atributo privado chamado “__store” (dois “__” fazem com que o atributo torne-se privado) e dois métodos o fetchTweets e o post, fetchTweets responsável pela captura de tweets públicos do twitter e post por postar o conteúdo no twitter.

Vamos voltar agora ao nosso arquivo Application.js e criar uma instância da nossa classe TwitterService e digite o seguinte código:

var service = new twitter.TwitterService();

E troque este trecho de código:

main.addListener("reload", function() {
	this.debug("reload");
}, this);

Por esse:

main.addListener("reload", function() {
  service.fetchTweets();
}, this);

E este:

main.addListener("post", function(e) {
	this.debug("post: " + e.getData());
}, this);

Por este:

main.addListener("post", function(e) {
        service.post(e.getData());
}, this);

Vamos agora para o arquivo MainWindow.js e criar um acessor para a lista, então troque onde tem var list = new qx.ui.form.List();por:

this.__list = new qx.ui.form.List();

E onde estiver list trocar por this.__list, faça o mesmo para textarea. Ainda no mesmo arquivo abaixo de events crie dois membros o __list e o __textarea ficando assim:

events :
  {
    "reload" : "qx.event.type.Event",
    "post" : "qx.event.type.Data"
  },

  members : {
    __list : null,
    __textarea : null,

Ainda dentro de members crie duas funções a getList e a clearPostMessage com o seguinte conteúdo:

getList : function() {
      return this.__list;
    },

    clearPostMessage : function() {
      this.__textarea.setValue(null);
    }

O nosso arquivo MainWindow agora está assim:

qx.Class.define("twitter.MainWindow",
{
  extend : qx.ui.window.Window,

  construct : function()
  {
    this.base(arguments, "twitter", "twitter/t_small-c.png");

    // hide the window buttons
    this.setShowClose(false);
    this.setShowMaximize(false);
    this.setShowMinimize(false);

    // adjust size
    this.setWidth(250);
    this.setHeight(300);

    // add the layout
    var layout = new qx.ui.layout.Grid(0, 0);
    layout.setRowFlex(1, 1);
    layout.setColumnFlex(0, 1);
    this.setLayout(layout);
    this.setContentPadding(0);

    // toolbar
    var toolbar = new qx.ui.toolbar.ToolBar();
    this.add(toolbar, {row: 0, column: 0, colSpan: 2});

    // reload button
    var reloadButton = new qx.ui.toolbar.Button("Reload");
    toolbar.add(reloadButton);
    reloadButton.setToolTipText("Reload the tweets.");
    reloadButton.addListener("execute", function() {
      this.fireEvent("reload");
    }, this);

    // list
    this.__list = new qx.ui.form.List();
    this.add(this.__list, {row: 1, column: 0, colSpan: 2});

    // textarea
    this.__textarea = new qx.ui.form.TextArea();
    this.add(this.__textarea, {row: 2, column: 0});
    this.__textarea.setPlaceholder("Enter your message here...");
    this.__textarea.addListener("input", function(e) {
      var value = e.getData();
      postButton.setEnabled(value.length < 140 && value.length > 0);
    }, this);

    // post button
    var postButton = new qx.ui.form.Button("Post");
    this.add(postButton, {row: 2, column: 1});
    postButton.setToolTipText("Post this message on twitter.");
    postButton.addListener("execute", function() {
      this.fireDataEvent("post", this.__textarea.getValue());
    }, this);
    postButton.setWidth(60);
    postButton.setEnabled(false);
  },

  events :
  {
    "reload" : "qx.event.type.Event",
    "post" : "qx.event.type.Data"
  },

  members : {
    __list : null,
    __textarea : null,

    getList : function() {
      return this.__list;
    },

    clearPostMessage : function() {
      this.__textarea.setValue(null);
    }
  }
});

Vamos voltar agora para o Application.js e criar um controle para nossa lista com o seguinte código:

var controller = new qx.data.controller.List(null, main.getList());
      controller.setLabelPath("text");
      controller.setIconPath("user.profile_image_url");
      controller.setDelegate({
        configureItem : function(item) {
          item.getChildControl("icon").setWidth(48);
          item.getChildControl("icon").setHeight(48);
          item.getChildControl("icon").setScale(true);
          item.setRich(true);
        }
      });

Agora vamos chamar o método bind para vincular o controle com o modelo vindo do twitter e chamar os tweets quando iniciar a aplicação:

service.bind("tweets", controller, "model");
service.fetchTweets();

Gere novamente os scripts e recarregue a página e teste nosso aplicativo funcionando.

Na hora de postar você será redirecionado para o site do twitter para autenticação, pois é muito complicado fazer a autenticação pelo aplicativo, pois o twitter só usa o OAuth para autenticar os usuários. Para baixar o projeto clique aqui.

Fonte: qooxdoo Docs

 

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *