X-Git-Url: http://git.roojs.org/?p=app.Builder.js;a=blobdiff_plain;f=XObject.js;h=05463b0d291ecc904b4f60290696dcd4a8f331ee;hp=fd3b56617ea8a0a8f1293e687d3430172a77048e;hb=refs%2Fheads%2Forigin.version_1_1;hpb=c73b7374935cf2fdf8499295bd8e3630e25709de diff --git a/XObject.js b/XObject.js index fd3b56617..05463b0d2 100644 --- a/XObject.js +++ b/XObject.js @@ -28,33 +28,56 @@ GObject = imports.gi.GObject; * Xyz.init(); // create and show. * * + * use XObject.debug = 1 to turn on debugging * - * @arg xtype {String|Function} constructor or string. - * @arg id {String} (optional) id for registry - * @arg xns {String|Object} (optional) namespace eg. Gtk or 'Gtk' - used with xtype. - * @arg items {Array} (optional) list of child elements which will be constructed.. using XObject - * @arg listeners {Object} (optional) map Gobject signals to functions - * @arg pack {Function|String|Array} (optional) how this object gets added to it's parent - * @arg el {Object} (optional) premade GObject - * - * --- needs a xdebug option! + * If XObjectBase/[xns]/[xtype].js exists, it will use this to override properties.. * * * He's some questions. - * - should we generate ID's for all elements? (if so we probably need to garbage collect) * - should we have a special property to use as the constructor / gobject.properties rather * than sending all basic types to this? * + * @cfg xtype {String|Function} constructor or string. + * @cfg id {String} (optional) id for registry + * @cfg xns {String|Object} (optional) namespace eg. Gtk or 'Gtk' - used with xtype. + * @cfg items {Array} (optional) list of child elements which will be constructed.. using XObject + * @cfg listeners {Object} (optional) map Gobject signals to functions + * @cfg pack {Function|String|Array} (optional) how this object gets added to it's parent + * @cfg el {Object} (optional) premade GObject + * + * + * + * + * * */ function XObject (cfg) { // first apply cfg if set. //print("new XOBJECT!!!"); - this.config = {}; - this.constructor = XObject; + + //print ("XObject ctr"); + + this.config = {}; // used to initialize GObject + + this.cfg = XObject.extend({}, cfg); // used to store original configuration.. for referencing.. + + // we could use this to determine if + // we are actually inside a inherited class... + // as define() should actually set this up.. + + if (!this.constructor) { + + this.constructor = XObject; + var base = XObject.baseXObject(cfg); + if (base) { + XObject.extend(this,base.prototype); + } + + } // copy down all elements into self.. + // make an extra copy in this.config?? - which is the one used in the constructor later for (var i in cfg) { this[i] = cfg[i]; @@ -74,20 +97,45 @@ function XObject (cfg) { this.config[i] = cfg[i]; } + + this.items = this.items || []; + + // pack can be false! if (typeof(this.pack) == 'undefined') { - var Gtk = imports.gi.Gtk; + this.pack = [ 'add' ] + /* + var Gtk = imports.gi.Gtk; switch (true) { // any others!! case (this.xtype == Gtk.MenuItem): this.pack = [ 'append' ]; break; } + */ } + // interesting question should we call constructor on items here... + // as the real work is done in init anyway.. + var _this= this; + var items = []; + this.items.forEach(function(i) { + items.push(i); + }); + this.items = []; + // create XObject for all the children. + items.forEach(function(i,n) { + var base = XObject.baseXObject(i); + base = base || XObject; + var item = (i.constructor == XObject) ? i : new base(i); + item.parent = _this; + _this.items.push(item); + //_this.addItem(i); + }); + } @@ -120,16 +168,14 @@ XObject.prototype = { */ init : function() { - /* - var items = []; - this.items.forEach(function(i) { - items.push(i); - }); - this.items = []; - */ + + // var items = []; + //this.items.forEach(function(i) { + // items.push(i); + //}); // remove items. this.listeners = this.listeners || {}; - + //this.items = []; // do we need to call 'beforeInit here?' @@ -140,14 +186,14 @@ XObject.prototype = { var isSeed = typeof(Seed) != 'undefined'; // xtype= Gtk.Menu ?? what about c_new stuff? - if (XObject.debug) print("init: ID:"+ this.id +" typeof(xtype): " + typeof(this.xtype)); + XObject.log("init: ID:"+ this.id +" typeof(xtype): " + typeof(this.xtype)); if (!this.el && typeof(this.xtype) == 'function') { - if (XObject.debug) print("func?" + XObject.keys(this.config).join(',')); + XObject.log("func?" + XObject.keys(this.config).join(',')); this.el = this.xtype(this.config); } if (!this.el && typeof(this.xtype) == 'object') { - if (XObject.debug) print("obj?" + XObject.keys(this.config).join(',')); + XObject.log("obj?" + XObject.keys(this.config).join(',')); this.el = new (this.xtype)(this.config); } @@ -156,16 +202,16 @@ XObject.prototype = { var NS = imports.gi[this.xns]; if (!NS) { - Seed.print('Invalid xns: ' + this.xns); + XObject.error('Invalid xns: ' + this.xns, true); } constructor = NS[this.xtype]; if (!constructor) { - Seed.print('Invalid xtype: ' + this.xns + '.' + this.xtype); + XObject.error('Invalid xtype: ' + this.xns + '.' + this.xtype); } this.el = isSeed ? new constructor(this.config) : new constructor(); } - if (XObject.debug) print("init: ID:"+ this.id +" typeof(el):" + this.el); + XObject.log("init: ID:"+ this.id +" typeof(el):" + this.el); // always overlay props.. // check for 'write' on object.. @@ -192,6 +238,12 @@ XObject.prototype = { if (i == 'type') { // problem with Gtk.Window... - not decided on a better way to handle this. continue; } + if (i == 'buttons') { // problem with Gtk.MessageDialog.. + continue; + } + if (i[0] == '.') { // parent? - + continue; + } this.el[i] = this.config[i]; } @@ -202,25 +254,24 @@ XObject.prototype = { // XObject.registry[o.xnsid][o.id] = this; //} - if (this.items) { - var items = []; - this.items.forEach(function(i) { - items.push(i); - }); - this.items = []; - var _this=this; + var type = this.xtype.type ? GObject.type_name(this.xtype.type) : ''; + XObject.log("add children to " + type); + + var _this=this; + this.items.forEach(function(i,n) { + _this.addItem(i,n); + }) - items.forEach(function(i) { - _this.addItem(i); - }); - } for (var i in this.listeners) { this.addListener(i, this.listeners[i]); } - // delete this.listeners ? - + this.init = XObject.emptyFn; + + // delete this.listeners ? + // do again so child props work! + // do we need to call 'init here?' }, @@ -231,60 +282,38 @@ XObject.prototype = { * uses pack property to determine how to add it. * @arg cfg {Object} same as XObject constructor. */ - addItem : function(o) + addItem : function(item, pos) { - if (typeof(o) == 'undefined') { - print("Invalid Item added to this!"); - imports.console.dump(this); + + if (typeof(item) == 'undefined') { + XObject.error("Invalid Item added to this!"); + imports.console.dump(this.cfg); Seed.quit(); } // what about extended items!?!?!? - var item = (o.constructor == XObject) ? o : new XObject(o); - item.parent = this; - - - - var items = []; - o.items = o.items || []; - o.items.forEach(function(i) { - items.push(i); - }); - o.items = []; - - - this.items.push(item); - - + item.init(); //print("CTR:PROTO:" + ( item.id ? item.id : '??')); // print("addItem - call init [" + item.pack.join(',') + ']'); if (!item.el) { - print("NO EL!"); + XObject.error("NO EL!"); imports.console.dump(item); Seed.quit(); } + print(XObject.type(this.xtype) + ":pack=" + item.pack); - - - - if (item.pack===false) { // no - items.forEach(function(i) { - item.addItem(i); - }); - + if (item.pack===false) { // no packing.. various items have this .. return; } - if (typeof(item.pack) == 'function') { + + if (typeof(item.pack) == 'function') { // pack is a function.. // parent, child item.pack.apply(item, [ this , item ]); item.parent = this; - - - items.forEach(function(i) { - item.addItem(i); - }); return; } + + // pack = 'add,x,y' var args = []; var pack_m = false; if (typeof(item.pack) == 'string') { @@ -306,27 +335,31 @@ XObject.prototype = { // handle error. if (pack_m && typeof(this.el[pack_m]) == 'undefined') { - Seed.print('pack method not available : ' + this.xtype + '.' + pack_m); + + throw { + name: "ArgumentError", + message : 'pack method not available : ' + this.id + " : " + this.xtype + '.' + pack_m + " ADDING " + item.el + + } + return; } + // finally call the pack method //Seed.print('Pack ' + this.el + '.'+ pack_m + '(' + item.el + ')'); - - args.unshift(item.el); - if (XObject.debug) print(pack_m + '[' + args.join(',') +']'); - //Seed.print('args: ' + args.length); - if (pack_m) { - this.el[pack_m].apply(this.el, args); - } + args.unshift(item.el); + - items.forEach(function(i) { - item.addItem(i); - }) + XObject.log(pack_m + '[' + args.join(',') +']'); + //Seed.print('args: ' + args.length); + if (pack_m) { + this.el[pack_m].apply(this.el, args); + } @@ -341,8 +374,8 @@ XObject.prototype = { addListener : function(sig, fn) { - if (XObject.debug) Seed.print("Add signal " + sig); - + XObject.log("Add signal " + sig); + fn.id= sig; var _li = XObject.createDelegate(fn,this); // private listeners that are not copied to GTk. @@ -367,7 +400,7 @@ XObject.prototype = { */ get : function(xid) { - if (XObject.debug) print("SEARCH FOR " + xid + " in " + this.id); + XObject.log("SEARCH FOR " + xid + " in " + this.id); var ret= false; var oid = '' + xid; if (!xid.length) { @@ -381,8 +414,21 @@ XObject.prototype = { return this.parent.get(xid.substring(1)); } if (xid[0] == '/') { + if (typeof(XObject.cache[xid]) != 'undefined') { return XObject.cache[xid]; + } + if (xid.indexOf('.') > -1) { + + var child = xid.split('.'); + var nxid = child.shift(); + + child = child.join('.'); + if (typeof(XObject.cache[nxid]) != 'undefined') { + return XObject.cache[nxid].get(child); + } + + } var e = this; while (e.parent) { @@ -409,8 +455,6 @@ XObject.prototype = { xid = child.shift(); child = child.join('.'); - - } if (xid == this.id) { @@ -452,7 +496,7 @@ XObject.prototype = { return; } if (!ch.get) { - print("invalid item..."); + XObject.error("invalid item..."); imports.console.dump(_this); Seed.quit(); } @@ -485,7 +529,7 @@ XObject.prototype = { /** * Copies all the properties of config to obj. * - * Pretty much the same as JQuery/Prototype.. + * Pretty much the same as JQuery/Prototype.. or Roo.apply * @param {Object} obj The receiver of the properties * @param {Object} config The source of the properties * @param {Object} defaults A different object that will also be applied for default values @@ -520,7 +564,48 @@ XObject.extend(XObject, * */ cache: { }, - + /** + * Empty function + * + */ + emptyFn : function () { }, + + + + /** + * Debug Logging + * @param {String|Object} output String to print. + */ + log : function(output) + { + if (!this.debug) { + return; + } + print("LOG:" + output); + }, + + /** + * Error Logging + * @param {String|Object} output String to print. + */ + error : function(output) + { + print("ERROR: " + output); + }, + /** + * fatal error + * @param {String|Object} output String to print. + */ + fatal : function(output) + { + + throw { + name: "ArgumentError", + message : output + + } + }, + /** * Copies all the properties of config to obj, if the do not exist. * @param {Object} obj The receiver of the properties @@ -530,7 +615,8 @@ XObject.extend(XObject, */ - extendIf : function(o, c){ + extendIf : function(o, c) + { if(!o || !c || typeof c != 'object'){ return o; @@ -567,7 +653,8 @@ XObject.extend(XObject, * @return {Function} constructor (eg. class * @method define */ - define : function(){ + define : function() + { // inline overrides var io = function(o){ for(var m in o){ @@ -576,14 +663,14 @@ XObject.extend(XObject, }; return function(constructor, parentClass, overrides) { if (typeof(parentClass) == 'undefined') { - print("XObject.define: Missing parentClass: when applying: " ); - print(new String(constructor)); + XObject.error("XObject.define: Missing parentClass: when applying: " ); + XObject.error(new String(constructor)); Seed.quit(); } if (typeof(parentClass.prototype) == 'undefined') { - print("Missing protype: when applying: " ); - print(new String(constructor)); - print(new String(parentClass)); + XObject.error("Missing protype: when applying: " ); + XObject.error(new String(constructor)); + XObject.error(new String(parentClass)); Seed.quit(); } var F = function(){}; @@ -624,7 +711,52 @@ XObject.extend(XObject, } return ret; }, - + /** + * return the Gobject name of a constructor - does not appear to work on structs.. + * @param {Object} gobject ctr + * @return {String} returns name + * @member XObject type + */ + type : function(o) + { + if (typeof(o) == 'object') { + return GObject.type_name(o.type); + // print("GNAME:" +gname + " GTYPE:"+cfg.xtype.type); + } + return 'unknown'; + }, + /** + * return the XObjectBase class for a cfg (which includes an xtype) + * @param {Object} configuration. + * @return {function} constructor + * @member XObject baseXObject + */ + baseXObject : function(cfg) + { + try { + // loocks for XObject/Gtk/TreeView.js [ TreeView = { .... } ] + // xns is not a string!!!? + var gname = false; + if (typeof(cfg.xtype) == 'object') { + gname = XObject.type(cfg.xtype); + + } + print("TRYING BASE OBJECT : " + gname); + // in the situation where we have been called and there is a base object + // defining the behavior.. + // then we should copy the prototypes from the base object into this.. + var base = gname ? imports.XObjectBase[gname][gname] : false; + return base; + + } catch (e) { + // if debug? + XObject.log("error finding " + gname + " - " + e.toString()); + return false; + } + + + }, + /** * @member XObject createDelegate * creates a delage metdhod @@ -638,6 +770,8 @@ XObject.extend(XObject, createDelegate : function(method, obj, args, appendArgs){ return function() { + XObject.log("CALL: " + obj.id + ':'+ method.id); + var callArgs = args || arguments; if(appendArgs === true){ callArgs = Array.prototype.slice.call(arguments, 0);