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