qooxdoo-Objektorientierung
==========================

Klassendefinition
-----------------

Instantiierung wäre: var myClass = new my.cool.Class(123);

qx.Class.define("my.cool.Class",  // Klassendefinition, Namensräume
{
  extend : my.great.SuperClass,  // Einfachvererbung
  
  // type : "static",    // Nur statische Member, keine Instantiierung
  // type : "abstract",  // Ableitung erforderlich zum Instantiieren
  // type : "singleton", // Nur eine Instanz (mit getInstance())
  
  implement : [my.cool.IInterface],
  // Def.: qx.Interface.define("my.cool.IInterface",{ ... });

  include : [my.cool.MMixin],
  // Def.: qx.Mixin.define("my.cool.MMixin",{ ... });
  
  construct : function(arg)
  { this.base(arguments, arg); // Aufruf Basisklassenkonstruktor
    ...
  },
  destruct : function() { ... },

  statics : // Klassenattribute und -methoden (Statische Member) 
  { PI : 3.141,
    F : function(x) { ... }
  },
  
  members :  // (Instanz-) Attribute und Methoden 
  { foo : "value",
    myPublicMember : function()
    { ...
    },
    _myProtectedMember : function()
    { ...
    },
    __myPrivateMember : function()
    { ...
    },
    applyMyProperty : function(value) // s.u.
    { ...value...
    }
  },

  // ===Properties===  
  properties : 
  { myProperty : 
    { check:"Number",          // Typ (auch: check:[1,2,3],
                               // Funktionen,Interfaces,uvm.)
      apply:"applyMyProperty", // Bei Änderung aufgerufen
      init: 123456,            // Defaultwert 
      nullable:    false,
      inheritable: true,       // analog CSS
      themable:    false,
    }
  },
  // var bla= myClass.getMyProperty();
  // myClass.setMyProperty(321);
  // myClass.set({ myProperty:321 ,...});
  // myClass.addEventListener(
  //   "changeMyProperty", function(e){...});
  // qooxdoo Inspector-Unterstützung
  // Property Groups:
  //   widget.setPadding(10, 20, 30, 40);  entspricht:
  //     widget.setPaddingTop(10);
  //     widget.setPaddingRight(20); etc.
  //   Def.: properties:{padding:{group:["top","right","bottom","left"]}}
  
  // ===Events===
  events :
  { click: "qx.event.type.MouseEvent"
  }
  // myClass.addEventListener("click", function(e){...});

});


Applikation
-----------
qx.Class.define("myTest.Application",
{
  extend : qx.application.Standalone,
  
  members :
  { main : function()
    { this.base(arguments); // Call super class

      var myButton = new qx.ui.form.Button("Click here");
      myButton.addListener("execute", function(e)
      { alert("Hello world!");
      },this);
      
      this.getRoot().add(myButton);
    }
  }
});


Kreuzungsperspektive-Demo-Applikation
-------------------------------------


http://kreuzungsperspektive.de/test/index.html

qx.Class.define("remote_table_test.Application",
{
  extend : qx.application.Standalone,
  
  members :
  { main : function()
    { 
      this.base(arguments); // Call super class

      this.dock = new qx.ui.container.Composite(new qx.ui.layout.Dock());
      this.getRoot().add(this.dock,{edge:0});

      this.tableModel = new remote_table_test.KrPeRemoteDataModel();
      this.tableModel.setColumns(["Kr-Nr.","Richtungen","Bilder"],["Kr","Richtungen","Bilder"]);
      
      this.table = new qx.ui.table.Table(this.tableModel);
      this.table.set({marginLeft:16,marginBottom:16,marginTop:16,marginRight:16,
                      allowGrowY:true, rowHeight:80});

      var tableColumnModel = this.table.get("tableColumnModel");
      tableColumnModel.setColumnWidth  (0,44);
      tableColumnModel.setColumnVisible(0,true);
      tableColumnModel.setColumnWidth  (1,100);
      tableColumnModel.setColumnVisible(1,true);
      tableColumnModel.setDataCellRenderer(1,new qx.ui.table.cellrenderer.Html());
      tableColumnModel.setColumnWidth  (2,748);
      tableColumnModel.setColumnVisible(2,true);
      tableColumnModel.setDataCellRenderer(2,new qx.ui.table.cellrenderer.Html());
              
      this.dock.add(this.table,{edge:"west"});
    }
  }
});

qx.Class.define("remote_table_test.KrPeRemoteDataModel",
{
  extend : qx.ui.table.model.Remote,
 
  members :
  {
    // overloaded - called whenever the table requests the row count
    _loadRowCount : function()
    {
      var url = "http://kreuzungsperspektive.de/kiel-0/DataN/0";
      var req = new qx.io.remote.Request(url, "GET", "application/json");
      
      req.addListener("completed",function(response)
      { var result = response.getContent();
        if (result != null) this._onRowCountLoaded(result.KrN);
      }, this);
 
      req.send();
    },
 
    // overloaded - called whenever the table requests new data
    _loadRowData : function(firstRow, lastRow)
    {
      var url = "http://kreuzungsperspektive.de/kiel-"+ firstRow +"/DataN/"+ (lastRow-firstRow+1);
      var req = new qx.io.remote.Request(url, "GET", "application/json");
 
      req.addListener("completed", function(response)
      { var result = response.getContent();
        if (result != null)
        { var myresult=[];
          for (var i=0; i<=lastRow-firstRow; i++)
            if (result[i].Kr && result[i].Rs)
            { var r="";
              var b="";
              for (var j=0; j<result[i].Rs.length; j++)
                if (result[i].Rs[j])
                { r+=(result[i].Rs[j].StBez?result[i].Rs[j].StBez:'-')+"<br>";
                  b+='<img src="http://kreuzungsperspektive.de/p4/'+result[i].Rs[j].img+'" style="vertical-align:top;">';
                }
              myresult[i]={Kr:result[i].Kr, Richtungen:r, Bilder:b};
            }
            else
              myresult[i]={Kr:i+firstRow, Richtungen:"-"};
          this._onRowDataLoaded(myresult);
          alert("Geladen: Kr:"+result[0].Kr+"-"+result[lastRow-firstRow].Kr+"  index:"+firstRow+"-"+lastRow);
        }   
      }, this);      
  
      req.send();
    }
  }
});


Architektur
-----------


http://qooxdoo.org/documentation/1.0/architecture

Tablenobjekt Grobüberblick (7 Interfaces, 45 Klassen) -------------------------- Tabelle (qx.ui.table.Table) (Zellgeometrie:rowHeight) Daten (tableModel->ITableModel(z.B. qx.ui.table.model.Remote)) Spalten (tableColumnModel->qx.ui.table.columnmodel.Resize) (Zellgeometrie:columnWidth) (Eigenschaften der Spalten per Index, Sichtbarkeit der Spalten) Spaltenkopf (headerCellRenderer->IHeaderRenderer(z.B. qx.ui.table.headerrenderer.Default)) (Anzeige von Spaltenname, Sortiermöglichkeit, Umgrößerbarkeit) Spaltenkopfumgrößerung (qx.ui.table.columnmodel.resizebehavior.Default) Zelle (Spezifikation im tableColumnModel): Anzeige (dataCellRenderer->ICellRenderer(z.B. qx.ui.table.cellrenderer.String)) (Darstellung als HTML) (automatisches z.B. Färben: qx.ui.table.cellrenderer.Conditional) Editieren (cellEditorFactory->ICellEditorFactory(z.B. qx.ui.table.celleditor.TextField)) (Anzeige eines Eingabefeldes) Sichtbarkeit-der-Spalten-Menü (...und Menuitems...) Zeilen (IRowRenderer(z.B. qx.ui.table.rowrenderer.Default)) (Zeigt, ob Zeile highlighted (fokussiert/selektiert)) Selektionsmanager (qx.ui.table.selection.Manager) (Zeilen-Selektion) (vermittelt zwischen Benutzerinteraktionen und Selektionsmodell) Selektionsmodell (z.B. qx.ui.table.selection.Model) (Selektions-Modi: Kein/Einfach/EinfachIntervall/MehrfachIntervall) Darstellungsbereiche (Pane) für diverse Elemente, insbesondere Zellen und Scroller

http://demo.qooxdoo.org/current/apiviewer/#qx.ui.table