0
The Joy of writing JavaScript Applications
How Qooxdoo puts the fun back into programming for the
                        ...
The Browser: my application platform




      Applications in the Browser: Netscapes original Plan.
      Performance: Sq...
Qooxdoo: application in the browser




      Web 2.0 is all about the look and feel.
      Web pages with eye candy.
    ...
Qooxdoo features



      Turns JS into a grown up OO language.
      No HTML or CSS knowledge required.
      Cross Brows...
Jump right in




      Install Python. http://www.python.org/download/
      Unpack Qooxdoo. http://qooxdoo.org/download/...
Jump right in




      Install Python. http://www.python.org/download/
      Unpack Qooxdoo. http://qooxdoo.org/download/...
Generating the first application


      Point your path to qooxdoo-0.8-sdk/tools/bin
      Change directory to your develo...
Generating the first application


      Point your path to qooxdoo-0.8-sdk/tools/bin
      Change directory to your develo...
generated files



   hello/generate.py
   hello/config.json
   hello/source/resource/hello/test.png
   hello/source/transl...
source code: hello/source/class/hello/Application.js I
 1   /* Tell qooxdoo that we need the resources in hello /*
 2   # ...
source code: hello/source/class/hello/Application.js II

21             // Create a button
22             var button1 = ne...
Qooxdoo and JavaScript




      It’s just like Perl and OO
      It’s all about anonymous functions
      and closures . ...
Qooxdoo and JavaScript




      It’s just like Perl and OO
      It’s all about anonymous functions
      and closures . ...
Qooxdoo and JavaScript




      It’s just like Perl and OO
      It’s all about anonymous functions
      and closures . ...
A function pointer example




1   var add_alert = function (a , b ){
2       alert ( ’ The Result is : ’ +( a + b ));
3  ...
Scoping for the naïve

    You know scoping from other languages
1   var j = 100;
2   var z = 22;
3   for ( var z = 1; z <...
Scoping for the naïve

    You know scoping from other languages
1   var j = 100;
2   var z = 22;
3   for ( var z = 1; z <...
Scoping for the disillusioned

    JavaScript scoping works only within function blocks.
1   var j = 100;
2   var z = 22;
...
Scoping for the disillusioned

    JavaScript scoping works only within function blocks.
1   var j = 100;
2   var z = 22;
...
A simple closures example
 1   var set ;
 2   var get ;
 3   var j =2;
 4   ( function (){ // the magic javascript scope t...
A simple closures example
 1   var set ;
 2   var get ;
 3   var j =2;
 4   ( function (){ // the magic javascript scope t...
A simple closures example
 1   var set ;
 2   var get ;
 3   var j =2;
 4   ( function (){ // the magic javascript scope t...
A broken function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){
3       var g = z ;
4       j [ g ] = functi...
A broken function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){
3       var g = z ;
4       j [ g ] = functi...
A broken function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){
3       var g = z ;
4       j [ g ] = functi...
A working function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){( function (){ // for a block
3       var g ...
A working function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){( function (){ // for a block
3       var g ...
fun with this

1   var hello = {
2             world : ’ You ’ ,
3             show : function (){
4       alert ( ’ Hello...
fun with this

1   var hello = {
2             world : ’ You ’ ,
3             show : function (){
4       alert ( ’ Hello...
Class definition



    In its most basic form, a Qooxdoo class is very simple.
1   qx . Class . define ( ’ my . first . Cl...
Class inheritance



    The map contains the meat of the class.
1   qx . Class . define ( quot; my . cool . Class quot; ,...
Static members


    Static member names are in the statics key.
    They use UPPERCASE names by convention.
1   qx . Clas...
Static members


    Static member names are in the statics key.
    They use UPPERCASE names by convention.
1   qx . Clas...
Instance Members


    Instance members reside in the members map.
1   qx . Class . define ( quot; my . cool . Class quot;...
Instance Members


    Instance members reside in the members map.
1   qx . Class . define ( quot; my . cool . Class quot;...
Calling the Superclass


 1   qx . Class . define ( quot; my . cool . Class quot; ,
 2   {
 3      extend : my . great . S...
Generic access to static members


 1   qx . Class . define ( quot; my . cool . Class quot; ,
 2   {
 3      extend : qx ....
mixins


1   qx . Mixin . define ( ’ my . cool . MMixin ’ ,{
2         // code and variables like in a class
3   });

    ...
class access control




    There is the following naming convention for class members.
1   publicMember
2   _protectedMe...
static, abstract and singleton classes

1   qx . Class . define ( ’ my . static . Class ’ , {
2      type : ’ static ’
3  ...
Browser specific code


     Normally Qooxdoo takes care of all browser differences, but if
     you must intervene . . .
 1...
The demo Browser




1   $ cd $QX / frontend / application / demobrowser /
2   $ ./ generate . py build
3   $ gnome - open...
The API Documentation




1   $ cd $QX / frontend / framework
2   $ ./ generate . py api
3   $ gnome - open api / index . ...
The Qooxdoo generator


  Python is the sole dependency
      generator.py is the tool
      it gets called by generate.py...
Running your Qooxdoo program in source




    Use source code during development
1   $ cd hello
2   $ ./ generate . py so...
Deploying your Qooxdoo program




1   $ cd hello
2   $ ./ generate . py build
3   $ cp - rp build ~/ public_html / hello
...
Button, TextField and some Action
 1   // Create a textfield
 2   var tf1 = new qx . ui . form . TextField ( ’ Demo Text ’...
The Layout Manager



     Qooxdoo Widgets can contain other widgets.
     Layout manager positions child widgets.
     qx...
Container and Layout
 1   // a container with horizontal layouyt manager
 2   var hbox = new qx . ui . layout . HBox ();
 ...
Grid Layout




      qx.ui.layout.Grid
      fully dynamic
      ideal for dialogs
      one widget per cell
      row an...
About the Qooxdoo Layout Widgets


      A container widget needs a layout manager to place its
      children.
      The ...
Localized Applications
 1   var lmgr = qx . locale . Manager . getInstance ();
 2   var bt3 = new qx . ui . form . ToggleB...
calling code on the server




      JSON RPC for transport
      various language bindings
      often minimal server cod...
An RPC Example: Client
 1   var rpc = new qx . io . remote . Rpc ( ’ jsonrpc . cgi ’ , ’ myclass ’ );
 2   var bt4 = new q...
An RPC Example: Server CGI
     source/jsonrpc.cgi:
 1   # !/ usr / bin / perl -w
 2   use strict ;
 3   use lib qw ( perl...
An RPC Example: the myclass service

     source/perl/Qooxdoo/Services/myclass.pm:
 1   package Qooxdoo :: Services :: myc...
An RPC Example: Getting it to work



      Install language bindings from Qooxdoo website.
      ln -s /var/www/lisa08 bu...
Organizing the code into multiple classes



      Object orientation “by the book”.
      One file per class.
      Java’s...
The textclick class I
 1   /* *
 2     * textclick combines a textfield and a button .
 3     */
 4   qx . Class . define ...
The textclick class II


21     members :
22     {
23     /* *
24       * Get a handle to the Button widget .
25       */
...
Using the textclick class



1   var mywi = new lisa08 . ui . textclick (
2               this . tr ( ’ Copy Text from Exa...
The Message Bus

         Communication in “large” applications.
         Singleton message bus class.
         Careful wi...
Code walk through of the SmokeTrace application.
?
Tobi Oetiker <tobi@oetiker.ch>
Upcoming SlideShare
Loading in...5
×

LISA QooxdooTutorial Slides

2,287

Published on

A Slideset for a half day qooxdoo tutorial.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,287
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
66
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "LISA QooxdooTutorial Slides"

  1. 1. The Joy of writing JavaScript Applications How Qooxdoo puts the fun back into programming for the web Tobias Oetiker OETIKER+PARTNER AG 22nd Large Installation System Administration Conference
  2. 2. The Browser: my application platform Applications in the Browser: Netscapes original Plan. Performance: SquirelFish, V8, Tracemonkey engines. JavaScript graduated with Web 2.0 Widget libraries for breakfast, lunch and dinner. A separte hack for every browser.
  3. 3. Qooxdoo: application in the browser Web 2.0 is all about the look and feel. Web pages with eye candy. Applications running in the browser. Back to client/server computing. Qooxdoo is a complete environment.
  4. 4. Qooxdoo features Turns JS into a grown up OO language. No HTML or CSS knowledge required. Cross Browser: >= FF 1.5, Safari 3, Chrome, IE6, Opera8. Multilingual. Full API Documentation. Users works ’inside the box’. LGPL, EPL Fun.
  5. 5. Jump right in Install Python. http://www.python.org/download/ Unpack Qooxdoo. http://qooxdoo.org/download/ Get Js2-mode for emacs http://code.google.com/p/js2-mode/ Do this NOW!
  6. 6. Jump right in Install Python. http://www.python.org/download/ Unpack Qooxdoo. http://qooxdoo.org/download/ Get Js2-mode for emacs http://code.google.com/p/js2-mode/ Do this NOW!
  7. 7. Generating the first application Point your path to qooxdoo-0.8-sdk/tools/bin Change directory to your development space. Run create-application.py –name hello CD into the hello directory. Run generate.py source Point your browser to hello/source/index.html
  8. 8. Generating the first application Point your path to qooxdoo-0.8-sdk/tools/bin Change directory to your development space. Run create-application.py –name hello CD into the hello directory. Run generate.py source Point your browser to hello/source/index.html
  9. 9. generated files hello/generate.py hello/config.json hello/source/resource/hello/test.png hello/source/translation/readme.txt hello/source/class/hello/test/DemoTest.js hello/source/class/hello/Application.js hello/source/index.html hello/Manifest.json hello/readme.txt
  10. 10. source code: hello/source/class/hello/Application.js I 1 /* Tell qooxdoo that we need the resources in hello /* 2 # asset ( hello /*) 3 */ 4 qx . Class . define ( quot; hello . Application quot; , 5 { 6 extend : qx . application . Standalone , 7 members : 8 { 9 main : function () 10 { 11 // Call super class 12 this . base ( arguments ); 13 // Enable logging in debug variant 14 if ( qx . core . Variant . isSet ( quot; qx . debug quot; , quot; on quot; )) 15 { // native logging capabilities 16 qx . log . appender . Native ; 17 // additional cross - browser console . 18 // Press F7 to toggle visibility 19 qx . log . appender . Console ; 20 }
  11. 11. source code: hello/source/class/hello/Application.js II 21 // Create a button 22 var button1 = new qx . ui . form . Button ( 23 quot; First Button quot; , quot; hello / test . png quot; ); 24 // Document is the application root 25 var doc = this . getRoot (); 26 // Add button to document at fixed coordinates 27 doc . add ( button1 , { left : 100 , top : 50}); 28 // Add an event listener 29 button1 . addListener ( quot; execute quot; , function ( e ) { 30 alert ( quot; Hello World ! quot; ); 31 }); 32 } 33 } 34 }); The original Qooxdoo hello world application, modified to fit the slide.
  12. 12. Qooxdoo and JavaScript It’s just like Perl and OO It’s all about anonymous functions and closures . . . and scoping.
  13. 13. Qooxdoo and JavaScript It’s just like Perl and OO It’s all about anonymous functions and closures . . . and scoping.
  14. 14. Qooxdoo and JavaScript It’s just like Perl and OO It’s all about anonymous functions and closures . . . and scoping.
  15. 15. A function pointer example 1 var add_alert = function (a , b ){ 2 alert ( ’ The Result is : ’ +( a + b )); 3 } 4 add_alert (1 ,2);
  16. 16. Scoping for the naïve You know scoping from other languages 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){ 4 var j = z ; 5 } 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Or so you thought
  17. 17. Scoping for the naïve You know scoping from other languages 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){ 4 var j = z ; 5 } 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Or so you thought
  18. 18. Scoping for the disillusioned JavaScript scoping works only within function blocks. 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){( function (){ 4 var j = z ; 5 })()} 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Note that z is outside the function block!
  19. 19. Scoping for the disillusioned JavaScript scoping works only within function blocks. 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){( function (){ 4 var j = z ; 5 })()} 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Note that z is outside the function block!
  20. 20. A simple closures example 1 var set ; 2 var get ; 3 var j =2; 4 ( function (){ // the magic javascript scope trick 5 var j ; 6 set = function ( x ){ j = x }; 7 get = function (){ alert ( ’ Hidden j is ’+ j )}; 8 })(); // end of scope 9 set (33); 10 get (); 11 alert ( ’ Outside j is still ’+ j ); Everything as expected.
  21. 21. A simple closures example 1 var set ; 2 var get ; 3 var j =2; 4 ( function (){ // the magic javascript scope trick 5 var j ; 6 set = function ( x ){ j = x }; 7 get = function (){ alert ( ’ Hidden j is ’+ j )}; 8 })(); // end of scope 9 set (33); 10 get (); 11 alert ( ’ Outside j is still ’+ j ); Everything as expected.
  22. 22. A simple closures example 1 var set ; 2 var get ; 3 var j =2; 4 ( function (){ // the magic javascript scope trick 5 var j ; 6 set = function ( x ){ j = x }; 7 get = function (){ alert ( ’ Hidden j is ’+ j )}; 8 })(); // end of scope 9 set (33); 10 get (); 11 alert ( ’ Outside j is still ’+ j ); Everything as expected.
  23. 23. A broken function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){ 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 } 8 j [2](2); JavaScript! Has! No! Scope! For! Loop! Blocks!
  24. 24. A broken function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){ 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 } 8 j [2](2); JavaScript! Has! No! Scope! For! Loop! Blocks!
  25. 25. A broken function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){ 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 } 8 j [2](2); JavaScript! Has! No! Scope! For! Loop! Blocks!
  26. 26. A working function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){( function (){ // for a block 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 })()} // end of block 8 j [2](2); Again the anonymous function trick comes to the rescue.
  27. 27. A working function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){( function (){ // for a block 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 })()} // end of block 8 j [2](2); Again the anonymous function trick comes to the rescue.
  28. 28. fun with this 1 var hello = { 2 world : ’ You ’ , 3 show : function (){ 4 alert ( ’ Hello ’+ this . world + ’ this : ’+ this ); } 5 }; 6 hello . show (); // method call 7 var plain = hello . show ; // function pointer 8 var world = ’ Me ’; // change this . world 9 plain (); // method call this refers to this refers to the browsers the hello object. base Window object.
  29. 29. fun with this 1 var hello = { 2 world : ’ You ’ , 3 show : function (){ 4 alert ( ’ Hello ’+ this . world + ’ this : ’+ this ); } 5 }; 6 hello . show (); // method call 7 var plain = hello . show ; // function pointer 8 var world = ’ Me ’; // change this . world 9 plain (); // method call this refers to this refers to the browsers the hello object. base Window object.
  30. 30. Class definition In its most basic form, a Qooxdoo class is very simple. 1 qx . Class . define ( ’ my . first . Class ’ ); In reality you would use something like this 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 // declare constructor , members , ... 3 }); A regular class can then be instantiated 1 var myClass = new my . cool . Class ;
  31. 31. Class inheritance The map contains the meat of the class. 1 qx . Class . define ( quot; my . cool . Class quot; , 2 { 3 extend : my . great . SuperClass , 4 construct : function () { ... } , 5 destruct : function () { ... } 6 }); Embrace and extend.
  32. 32. Static members Static member names are in the statics key. They use UPPERCASE names by convention. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 statics : { 3 FOO : VALUE , 4 BAR : function () { ... } 5 } 6 }); Static members are accessed with their full name: 1 my . cool . Class . FOO = 3.141; 2 my . cool . Class . BAR ();
  33. 33. Static members Static member names are in the statics key. They use UPPERCASE names by convention. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 statics : { 3 FOO : VALUE , 4 BAR : function () { ... } 5 } 6 }); Static members are accessed with their full name: 1 my . cool . Class . FOO = 3.141; 2 my . cool . Class . BAR ();
  34. 34. Instance Members Instance members reside in the members map. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 members : { 3 foo : VALUE , 4 bar : function () { ... } 5 } 6 }); Use new to create an instance. 1 var myClass1 = new my . cool . Class ; 2 myClass1 . foo = 3.141; 3 myClass1 . bar ();
  35. 35. Instance Members Instance members reside in the members map. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 members : { 3 foo : VALUE , 4 bar : function () { ... } 5 } 6 }); Use new to create an instance. 1 var myClass1 = new my . cool . Class ; 2 myClass1 . foo = 3.141; 3 myClass1 . bar ();
  36. 36. Calling the Superclass 1 qx . Class . define ( quot; my . cool . Class quot; , 2 { 3 extend : my . great . SuperClass , 4 construct : function ( x ) { 5 this . base ( arguments , x ); // superclass constructor 6 } 7 members : { 8 foo : function ( x ) { 9 this . base ( arguments , x ); 10 } 11 } 12 }); The this.base construct works for both constructor and member functions.
  37. 37. Generic access to static members 1 qx . Class . define ( quot; my . cool . Class quot; , 2 { 3 extend : qx . core . Object , 4 construct : function ( x ){ this . base ( arguments , x )} , 5 statics : { 6 PI : 3.141 7 } 8 members : { 9 circumference : function ( radius ) { 10 return 2 * this . self ( arguments ). PI * radius ; 11 } 12 } 13 }); this.self only works for subclasses of qx.core.Object
  38. 38. mixins 1 qx . Mixin . define ( ’ my . cool . MMixin ’ ,{ 2 // code and variables like in a class 3 }); Like classes, but without inheritance. By convention Mixin names start with ’M’. 1 qx . Class . define ( ’ my . cool . Class ’ , { 2 include : [ my . cool . MMixin , my . other . cool . MMixin ] 3 ... 4 }); Include mixins when creating new classes. 1 qx . Class . include ( qx . ui . core . Widget , qx . MWidgetFeatures ); Or even inject them into an existing class.
  39. 39. class access control There is the following naming convention for class members. 1 publicMember 2 _protectedMember 3 __privateMember In the Qooxdoo build process it is optionally possible to randomize the names of private members to protect access.
  40. 40. static, abstract and singleton classes 1 qx . Class . define ( ’ my . static . Class ’ , { 2 type : ’ static ’ 3 statics : { ... }; 4 }); Neither members nor constructors are allowed in static classes. 1 qx . Class . define ( ’ my . abstract . Class ’ , { 2 type : ’ abstract ’ 3 }); Abstract classes must be sub-classed for use. 1 qx . Class . define ( ’ my . singleton . Class ’ , { 2 type : ’ singleton ’ 3 }); 4 var instance = my . singleton . Class . getIntance () There is only one instance which gets created on the first call.
  41. 41. Browser specific code Normally Qooxdoo takes care of all browser differences, but if you must intervene . . . 1 members : { 2 foo : qx . core . Variant . select ( 3 ’ qx . bom . client . Engine . NAME ’ , { 4 ’ mshtml | opera ’: function () { 5 // Internet Explorer or Opera 6 }, 7 ’ default ’: function () { 8 // All other browsers 9 } 10 } 11 ) 12 }
  42. 42. The demo Browser 1 $ cd $QX / frontend / application / demobrowser / 2 $ ./ generate . py build 3 $ gnome - open build / index . html Or surf to http://demo.qooxdoo.org/current/demobrowser
  43. 43. The API Documentation 1 $ cd $QX / frontend / framework 2 $ ./ generate . py api 3 $ gnome - open api / index . html Or surf to http://demo.qooxdoo.org/current/apiviewer
  44. 44. The Qooxdoo generator Python is the sole dependency generator.py is the tool it gets called by generate.py The generator has many functions source - prep development code build - prep code for deployment api - build api doc lint - check your code for beauty pretty - fix the code layout ...
  45. 45. Running your Qooxdoo program in source Use source code during development 1 $ cd hello 2 $ ./ generate . py source 3 $ gnome - open source / index . html As long as you do not use any new classes, press reload in the browser to see changes.
  46. 46. Deploying your Qooxdoo program 1 $ cd hello 2 $ ./ generate . py build 3 $ cp - rp build ~/ public_html / hello only two js files code gets optimized and compressed no external dependencies
  47. 47. Button, TextField and some Action 1 // Create a textfield 2 var tf1 = new qx . ui . form . TextField ( ’ Demo Text ’ ); 3 // Add button to root 4 root . add ( tf1 , { column : 0 , row : 0}); 5 // Create a button 6 var bt1 = new qx . ui . form . Button ( 7 ’ Open Alert ’ , ’ lisa08 / test . png ’ ); 8 // Add button to root 9 root . add ( bt1 , { column : 1 , row : 0}); 10 // Add an event listener 11 bt1 . addListener ( ’ execute ’ , function ( e ) { 12 // closure !! 13 this . info ( ’ TextField : ’+ tf1 . getValue ()); 14 alert ( ’ TextField : ’ + tf1 . getValue ()); 15 }); Try F7 to see inline console!
  48. 48. The Layout Manager Qooxdoo Widgets can contain other widgets. Layout manager positions child widgets. qx.ui.container.Composite basic qx.ui.container.Scroll draws scroll bars qx.ui.window.Window directs children to an inner composite pane. Layout manager set at construction time Modified with setLayout method.
  49. 49. Container and Layout 1 // a container with horizontal layouyt manager 2 var hbox = new qx . ui . layout . HBox (); 3 hbox . setSpacing (4); // set property 4 5 // assign layout 6 var ctr1 = new qx . ui . container . Composite ( hbox ); 7 ctr1 . setWidth (600); ctr1 . setHeight (40); 8 // layout properties : position 9 root . add ( ctr1 ,{ column : 0 , row : 1 , colSpan : 2}); 10 11 var tf2 = new qx . ui . form . TextField ( ’ Some More Text ’ ); 12 var bt2 = new qx . ui . form . ToggleButton ( ’ AllowGrowY ’ ); 13 bt2 . addListener ( ’ changeChecked ’ , function ( e ) { 14 // modify widget property 15 tf2 . setAllowGrowY ( e . getData ()); 16 this . info ( ’ New Value for AllowGrowY : ’+ e . getData ()); 17 }); 18 ctr1 . add ( tf2 ); ctr1 . add ( bt2 );
  50. 50. Grid Layout qx.ui.layout.Grid fully dynamic ideal for dialogs one widget per cell row and column spans minimal and maximal column and row sizes fixed row and column sizes
  51. 51. About the Qooxdoo Layout Widgets A container widget needs a layout manager to place its children. The layout manager object has properties. Every widget has basic properties like: alignment, growability, shrinkability, stretchability, margins, padding, width and height. Each widget can have layout-specific properties. Layout properties get checked as the widget is added to a layout. Lets play with the layout demos!
  52. 52. Localized Applications 1 var lmgr = qx . locale . Manager . getInstance (); 2 var bt3 = new qx . ui . form . ToggleButton ( 3 this . tr ( ’ Translate ! ’) 4 ); 5 root . add ( bt3 , { column : 1 , row : 3}); 6 bt3 . addListener ( ’ changeChecked ’ , function ( e ) { 7 var lang = e . getData () ? ’ de ’ : ’ en ’; 8 lmgr . setLocale ( lang ); 9 this . info ( ’ Language set to : ’+ lang ); 10 }); add locale to config.json ./generate.py translation translate de.po ./generate.py source
  53. 53. calling code on the server JSON RPC for transport various language bindings often minimal server code async with callbacks qx.io.Rpc
  54. 54. An RPC Example: Client 1 var rpc = new qx . io . remote . Rpc ( ’ jsonrpc . cgi ’ , ’ myclass ’ ); 2 var bt4 = new qx . ui . form . Button ( this . tr ( ’ Call RPC ’ )); 3 root . add ( bt4 , { column : 1 , row : 4}); 4 var that = this ; // we want this ’ this ’! 5 var callback = function ( result , ex , id ) { 6 that . RpcRunning = null ; // free the reference 7 if ( ex == null ) { 8 alert ( ’ The RPC call returned : ’+ result ); 9 that . info ( ’ RPC call returned : ’+ result ); 10 } else { 11 alert ( ’ Async ( ’ + id + ’) exception : ’ + ex ); 12 that . error ( ’ Async ( ’ + id + ’) exception : ’ + ex ); 13 } 14 }; 15 bt4 . addListener ( ’ execute ’ , function ( e ) { 16 that . RpcRunning = rpc . callAsync ( 17 callback , ’ mymethod ’ , ’ Hello ’ ); 18 }); The example only works on a cgi enabled webserver.
  55. 55. An RPC Example: Server CGI source/jsonrpc.cgi: 1 # !/ usr / bin / perl -w 2 use strict ; 3 use lib qw ( perl ); 4 5 use CGI ; 6 # use CGI :: Fast ; 7 use CGI :: Session ; 8 use Qooxdoo :: JSONRPC ; 9 10 # $Qooxdoo :: JSONRPC :: debug =1; 11 my $cgi = new CGI ; 12 # while ( my $cgi = new CGI :: Fast ){ 13 my $session = new CGI :: Session ; 14 Qooxdoo :: JSONRPC :: handle_request ( $cgi , $session ); 15 # } For best performance use CGI::Fast and configure CGI::Session to keep the session data in a database.
  56. 56. An RPC Example: the myclass service source/perl/Qooxdoo/Services/myclass.pm: 1 package Qooxdoo :: Services :: myclass ; 2 use strict ; 3 4 # for now let everyone access the methods 5 sub GetAccessibility { ’ public ’ }; 6 7 sub method_mymethod { 8 my $error = shift ; 9 my $arg = shift ; 10 return ’ The argument was : ’. $arg ; 11 } 12 13 1; The myclass module gets loaded dynamically.
  57. 57. An RPC Example: Getting it to work Install language bindings from Qooxdoo website. ln -s /var/www/lisa08 build ./generate.py build cp -rp source/jsonrpc.cgi source/perl build Open the application in the browser. Make sure the cgis are actually executed Watch the Apache error log while testing.
  58. 58. Organizing the code into multiple classes Object orientation “by the book”. One file per class. Java’s file name based approach. Supported by the generator. Ideal for code re-use. Use Inline Docs! ./generate.py api
  59. 59. The textclick class I 1 /* * 2 * textclick combines a textfield and a button . 3 */ 4 qx . Class . define ( quot; lisa08 . ui . textclick quot; , 5 { 6 extend : qx . ui . container . Composite , 7 /* * 8 * @param button_text { String } button text . 9 */ 10 construct : function ( button_text ) { 11 this . base ( arguments , 12 new qx . ui . layout . HBox (). set ({ spacing : 4}) 13 ); 14 this . __tf = new qx . ui . form . TextField (); 15 this . __bt = new qx . ui . form . Button ( button_text ); 16 this . add ( this . __tf ); 17 this . add ( this . __bt ); 18 }, 19 20
  60. 60. The textclick class II 21 members : 22 { 23 /* * 24 * Get a handle to the Button widget . 25 */ 26 getButton : function () { return this . __bt } , 27 /* * 28 * Get a handle to the TextField widget . 29 */ 30 getTextField : function () { return this . __tf } , 31 __bt : null , 32 __tf : null 33 } 34 });
  61. 61. Using the textclick class 1 var mywi = new lisa08 . ui . textclick ( 2 this . tr ( ’ Copy Text from Example 1 ’ )); 3 4 mywi . getButton (). addListener ( ’ execute ’ , function ( e ) { 5 mywi . getTextField (). setValue ( tf1 . getValue ()); 6 this . info ( ’ Set textfield to ’+ tf1 . getValue ()); 7 }); 8 9 root . add ( mywi ,{ column : 0 , row : 5 , colSpan : 2});
  62. 62. The Message Bus Communication in “large” applications. Singleton message bus class. Careful with references: memory leaks! 1 var mywi2 = new lisa08 . ui . textclick ( 2 this . tr ( ’ Send Hello to Textfield ’ )); 3 var bus = qx . event . message . Bus . getInstance (); 4 mywi2 . getButton (). addListener ( ’ execute ’ , function ( e ) { 5 bus . dispatch ( ’ mybus .1 ’ , ’ Hello World ’ ); 6 this . info ( ’ Sent Hello World on this bus ’ ); 7 } , this ); // context provided for console 8 bus . subscribe ( ’ mybus .1 ’ , function ( m ){ 9 mywi2 . getTextField (). setValue ( m . getData ()); 10 this . info ( ’ Got ’+ m . getData ()+ ’ from the bus ’ ); 11 } , this ); 12 13 root . add ( mywi2 ,{ column : 0 , row : 6 , colSpan : 2});
  63. 63. Code walk through of the SmokeTrace application.
  64. 64. ?
  65. 65. Tobi Oetiker <tobi@oetiker.ch>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×