JsRender/Gtk.js
[app.Builder.js] / JsRender / Gtk.js
1 //<Script type="text/javascript">
2  
3 Gio = imports.gi.Gio;
4 GLib = imports.gi.GLib;
5
6 XObject = imports.XObject.XObject;
7 File = imports.File.File;
8   
9 //----------------------- our roo verison
10 Base = imports.JsRender.Base.Base;
11
12 var gid = 1;
13
14 Gtk = XObject.define( 
15     
16     
17     function(cfg) {
18         
19         // id ,
20         //"name":"Edit Module Details",
21         // items : 
22         //"btype":"FORM", // was to be components...
23         //"app":"Builder",
24         //"module":"Pman.Tab.BuilderTop2"
25         //console.dump(cfg);
26         cfg.parent = cfg.parent || '';
27         if (!cfg.name || !cfg.fullname ) {
28             
29             // name is in theory filename without .bjs (or .js eventually...)
30             cfg.name = cfg.path.split('/').pop().replace(/\.(bjs|js)$/, '');
31             
32             cfg.fullname = (cfg.parent.length ? (cfg.parent + '.') : '' ) + cfg.name;
33         }
34         
35         
36         this.items = false;
37         if (cfg.json) {
38             var jstr =  JSON.parse(cfg.json);
39             this.items = [ jstr ];
40             //console.log(cfg.items.length);
41             delete cfg.json; // not needed!
42         }
43         this.cn = [];
44          /*
45         var p = cfg.items && cfg.items.length && cfg.items[0].parent ? cfg.items[0].parent : false;
46         
47         // ensure real data is set...
48         Roo.apply(this, {
49             name : cfg.module,
50             parent : p,
51             title : cfg.name,
52             project : cfg.app
53             
54         });
55         
56         this.cn = [];
57         */
58         Gtk.superclass.constructor.call(this, cfg);
59
60         
61         // super?!?!
62         this.id = 'file-gtk-' + gid++;
63         //console.dump(this);
64         // various loader methods..
65        
66     },
67     Base,   
68     {
69         xtype : 'Gtk',
70         setNSID : function(id)
71         {
72             
73             this.items[0]['*class'] = id;
74             
75             
76         },
77         getType: function() {
78             return 'Gtk';
79         },
80         
81         loadItems : function(cb)
82         {
83           
84             print("load Items!");
85             if (this.items !== false) {
86                 return false;
87             }
88             if (!cb) {  
89                 throw {
90                     name: "ArgumentError", 
91                     message : "no callback for loadItems"
92                 };
93             }
94             Seed.print("load: " + this.path);
95             
96             
97
98             
99             var _this = this;     
100             var src = File.read(this.path);
101             
102             var cfg = JSON.parse(src);
103             print("loaded data");
104             //console.dump(cfg);
105             
106             //_this.name = cfg.name; -- this should not happen - name should always match filename!!
107             _this.parent =  cfg.parent;
108             _this.title =  cfg.title;
109             _this.items = cfg.items || []; 
110            
111              cb();
112              
113              
114             
115             
116             
117         },
118         /**
119          * convert xtype for munged output..
120          * 
121          */
122         mungeXtype : function(xtype, els)
123         {
124             els.push('xtype: '+ xtype);
125         },
126         
127         toSource : function()
128         {
129             
130             if (!this.items[0]) {
131                 return false;
132             }
133             var data = JSON.parse(JSON.stringify(this.items[0]));
134             // we should base this on the objects in the tree really..
135             var i = [ 'Gtk', 'Gdk', 'Pango', 'GLib', 'Gio', 'GObject', 
136                 'GtkSource', 'WebKit', 'Vte' ]; //, 'GtkClutter' , 'Gdl'];
137             var src = "";
138             i.forEach(function(e) {
139                 src += e+" = imports.gi." + e +";\n";
140             });
141             
142             src += "console = imports.console;\n"; // path?!!?
143             src += "XObject = imports.XObject.XObject;\n"; // path?!!?
144             
145             
146             src += this.name + '=new XObject('+ this.mungeToString(data) + ");\n";
147             src += this.name + '.init();\n';
148             // register it in the cache
149             src += "XObject.cache['/" + this.name + "'] = " + this.name + ";\n";
150             
151             
152             return src;
153             
154             
155         },
156         save : function() {
157             Base.prototype.save.call(this);
158             this.saveJS();
159             this.saveVala();
160         },
161         
162         /** 
163          *  saveJS
164          * 
165          * save as a javascript file.
166          * why is this not save...???
167          * 
168          * 
169          */
170         saveJS: function()
171         {
172              
173             var fn = GLib.path_get_dirname(this.path) + '/' + this.name + '.js';
174             print("WRITE : " + fn);
175             File.write(fn, this.toSource());
176             
177             return fn;
178         },
179         
180         saveVala: function()
181         {
182              
183             var fn = GLib.path_get_dirname(this.path) + '/' + this.name + '.vala';
184             print("WRITE : " + fn);
185             File.write(fn, this.toVala());
186             
187             return fn;
188         },
189         valaCompileCmd : function()
190         {
191             
192             var fn = '/tmp/' + this.name + '.vala';
193             print("WRITE : " + fn);
194             File.write(fn, this.toVala(true));
195             
196             
197             
198             return ["valac",
199                    "--pkg",  "gio-2.0",
200                    "--pkg" , "posix" ,
201                    "--pkg" , "gtk+-3.0",
202                    "--pkg",  "libnotify",
203                    "--pkg",  "gtksourceview-3.0",
204                    "--pkg", "libwnck-3.0",
205                    fn ,   "-o", "/tmp/" + this.name];
206             
207            
208              
209             
210         },
211         
212         
213         /*
214         getTree : function( o ) {
215             
216             
217             
218         }
219         */
220         getHelpUrl : function(cls)
221         {
222             return 'http://devel.akbkhome.com/seed/' + cls + '.html';
223         },
224         
225         vcnt : false,
226         
227         toVala: function(testcompile)
228         {
229             var ret = '';
230             testcompile = testcompile || false;
231             
232             this.vcnt = 0;
233             //print(JSON.stringify(this.items[0],null,4));
234             //print(JSON.stringify(this.items[0],null,4));Seed.quit();
235
236             var item=  XObject.xclone(this.items[0]);
237             
238             print(JSON.stringify(item,null,4));
239             
240             this.palete  = new imports.Palete.Gtk.Gtk({});
241             
242             this.vitems = [];
243             this.toValaName(item);
244            // print(JSON.stringify(item,null,4));Seed.quit();
245             
246             ret += "/* -- to compile\n";
247             ret += "valac  --pkg gio-2.0  --pkg posix  --pkg gtk+-3.0 --pkg libnotify --pkg gtksourceview-3.0  --pkg  libwnck-3.0 \\\n";
248             //ret += "    " + item.xvala_id + ".vala  -o /tmp/" + item.xvala_id +"\n";
249             ret += "    /tmp/" + this.name + ".vala  -o /tmp/" + this.name +"\n";
250             ret += "*/\n";
251             ret += "\n\n";
252             if (!testcompile) {
253                 ret += "/* -- to test class\n";  
254             }
255             //
256             ret += "static int main (string[] args) {\n";
257             ret += "    Gtk.init (ref args);\n";
258             ret += "    new " + item.xvala_xcls +"();\n";
259             ret += "    " + this.name +".show_all();\n";
260             ret += "     Gtk.main ();\n";
261             ret += "    return 0;\n";
262             ret += "}\n";
263             if (!testcompile) {
264                 ret += "*/\n";
265             }
266             ret += "\n\n";
267             // print(JSON.stringify(item,null,4));
268             this.toValaItem(item,0, function(s) {
269                 ret+= s;
270             });
271             
272             return ret;
273             
274         },
275         
276         toValaNS : function(item)
277         {
278             var ns = item['|xns'] ;
279             if (ns == 'GtkSource') {
280                 return 'Gtk.Source'
281                 ns = 'Gtk.Source';
282             }
283             return ns + '.';
284         },
285         
286         toValaName : function(item) {
287             this.vcnt++;
288             var cls = this.toValaNS(item) + item.xtype;
289             var id = item.id ? item.id : (item.xtype + this.vcnt);
290             var props = this.palete.getPropertiesFor(cls, 'props');
291             
292             
293             
294             item.xvala_cls = cls;
295             item.xvala_xcls = 'Xcls_' + id;
296             item.xvala_id = item.id ? item.id : false;
297             this.vitems.push(item);  
298             // loop children..
299             if (typeof(item.items) == 'undefined') {
300                 return;
301             }
302             for(var i =0;i<item.items.length;i++) {
303                 this.toValaName(item.items[i]);
304             }
305           
306         },
307         
308         
309         toValaItem : function(item, depth, strbuilder)
310         {
311         // print(JSON.stringify(item,null,4));
312             
313             var inpad = new Array( depth +1 ).join("    ");
314             
315             var pad = new Array( depth +2 ).join("    ");
316             var ipad = new Array( depth +3 ).join("    ");
317             
318             var cls = item.xvala_cls;
319             
320             var xcls = item.xvala_xcls;
321             
322             var citems = {};
323             
324             if (!depth) {
325                 // Global Vars..
326                 strbuilder(inpad + "public static " + xcls + "  " + this.name + ";\n\n");
327                 strbuilder(inpad + "private static " + xcls + "  _this;\n\n");
328                  
329                 
330             }
331             
332             // class header..
333             // class xxx {   WrappedGtk  el; }
334             strbuilder(inpad + "public class " + xcls + "\n" + inpad + "{\n");
335             strbuilder(pad + "public " + cls + " el;\n");
336             
337             // properties??
338                 
339                 //public bool paused = false;
340                 //public static StatusIconA statusicon;
341             if (!depth) {
342                 //strbuilder(pad + "public static " + xcls + "  _this;\n");
343                 for(var i=1;i < this.vitems.length; i++) {
344                     if (this.vitems[i].xvala_id  !== false) {
345                         strbuilder(pad + "public " + this.vitems[i].xvala_xcls + " " + this.vitems[i].xvala_id + ";\n");
346                     }
347                 }
348                 
349             }
350             
351             strbuilder("\n" + ipad + "// my vars\n");
352             
353             
354             for (var k in item) {
355                 if (k[0] != '.') {
356                    
357                     continue;
358                 }
359                 var kk = k.substring(1);
360                 var v = item[k];
361                 var vv = v.split(':');
362                 strbuilder(pad + "public " + vv[0] + " " + kk + ";\n");
363                  citems[k] = true; 
364                 
365             }
366             // .vala props.. 
367              
368             // ctor..
369             strbuilder("\n" + ipad + "// ctor \n");
370             strbuilder(pad + "public " + xcls + "()\n" + pad + "{\n");
371             
372             // wrapped ctor..
373             // this may need to look up properties to fill in the arguments..
374             
375             
376             
377             strbuilder(ipad + "this.el = new " + cls + "()\n" );
378             
379             
380             // public static?
381             if (!depth) {
382                 strbuilder(ipad + "_this = this;\n");
383                 strbuilder(ipad + this.name  + " = this;\n");
384             } else {
385                 if (item.xvala_id !== false) {
386                     strbuilder(ipad + "_this." + item.xvala_id  + " = this;\n");
387                    
388                 }
389                 
390                 
391             }
392             // initialize.. my vars..
393             strbuilder("\n" + ipad + "// my vars\n");
394             for (var k in item) {
395                 if (k[0] != '.') {
396                     continue;
397                 }
398                 var kk = k.substring(1);
399                 var v = item[k];
400                 var vv = v.split(':');
401                 if (vv.length < 2) {
402                     continue;
403                 }
404                 strbuilder(ipad + "this." + k + " = " +   vv[1] +";\n");
405                 
406             }
407            
408            
409             // what are the properties of this class???
410             strbuilder("\n" + ipad + "// set gobject values\n");
411             var props = this.palete.getPropertiesFor(item['|xns'] + '.' + item.xtype, 'props');
412             
413             
414             
415             props.forEach(function(p) {
416                
417                     
418                      
419                 if (typeof(item[p.name]) != 'undefined' && typeof(item[p.name]) != 'object' ) {
420                     citems[p.name] = true;
421                     
422                     
423                     strbuilder(ipad + "this.el." + p.name + " = " + JSON.stringify(item[p.name]) + ";\n");
424                     return;
425                 }
426                 if (typeof(item['|' + p.name]) != 'undefined' && typeof(item['|' + p.name]) != 'object' ) {
427                     citems['|' + p.name] = true;
428                     //if (p.ctor_only ) {
429                     //    strbuilder(ipad + "Object(" + p.name + " : " +  item['|' + p.name] + ");\n");
430                     //} else {
431                         strbuilder(ipad + "this." + p.name + " = " +  item['|' + p.name] + ";\n");
432                     //}
433                     return;
434                 }
435                // got a property..
436                
437                
438             });
439                 //code
440             // add all the child items..
441             if (typeof(item.items) != 'undefined') {
442                 for(var i =0;i<item.items.length;i++) {
443                     var ci = item.items[i];
444                     var packing = ci.pack ? ci.pack.split(',') : [ 'add' ];
445                     var pack = packing.shift();
446                     strbuilder(ipad + "var child_" + i + " = new " + ci.xvala_xcls + "();\n" )
447                     
448                     strbuilder(ipad + "this." + pack + " (  new " + ci.xvala_xcls + "()" +
449                                (packing.length ? ", " + packing.join(",") : "") + " );\n"
450                             );
451                                
452                     
453                 }
454             }
455             if (typeof(item['|init']) != 'undefined') {
456                 
457                 
458                     var v = item['|init'].split(/\/*--/);
459                     if (v.length > 1) {
460                         strbuilder("\n" + ipad + "// init method \n");            
461                          var vv = v[1].replace('*/', "");
462                          //print(JSON.stringify(vv));Seed.quit();
463                          vv = vv.replace(/^\n+/,'');
464                          vv = vv.replace(/\n+$/,'');
465                          vv = vv.replace(/\n/g,"\n" + ipad);
466                          strbuilder(ipad + vv  + "\n");
467                     }
468             }
469             
470             citems['|pack'] = true;
471             citems['|items'] = true;
472              citems['|init'] = true;
473             
474             if (item.listeners) {
475             //    print(JSON.stringify(item.listeners));Seed.quit();
476             
477                 strbuilder("\n" + ipad + "// listeners \n");  
478                 // add all the signal handlers..
479                 for (var k in item.listeners) {
480                     
481                     
482                     var v = item.listeners[k].split(/\/*--/);
483                     if (v.length < 2) {
484                         continue;
485                     }
486                     var vv = v[1].replace('*/', "");
487                     //print(JSON.stringify(vv));Seed.quit();
488                     vv = vv.replace(/^\n+/,'');
489                     vv = vv.replace(/\n+$/,'');
490                     vv = vv.replace(/\n/g,"\n" + ipad);
491                     strbuilder(ipad + "this." + k + ".connect( " + vv  + " );\n");
492                     
493                 }
494             }    
495                 
496             
497             
498             
499             // end ctor..
500             strbuilder(pad + "}\n");
501             
502             
503             strbuilder("\n" + pad + "// userdefined functions \n");  
504             
505             // user defined functions...
506             
507             for (var k in item) {
508                 if (typeof(citems[k]) != 'undefined') {
509                     strbuilder("\n" + pad + "// skip " + k + " - already used \n"); 
510                     continue;
511                 }
512                 if (k[0] != '|') {
513                       strbuilder("\n" + pad + "// skip " + k + " - not pipe \n"); 
514                     continue;
515                 }
516                 // function in the format of {type} (args) { .... }
517                 
518                 var v = item[k].split(/\/*--/);
519                 if (v.length < 2) {
520                       strbuilder("\n" + pad + "// skip " + k + " - could not find seperator\n"); 
521                     continue;
522                 }
523                 var vv = v[1].replace('*/', "");
524                 //print(JSON.stringify(vv));Seed.quit();
525                 vv = vv.replace(/^\n+/,'');
526                 vv = vv.replace(/\n+$/,'');
527                 vv = vv.replace(/\n/g,"\n" + ipad);
528                 
529                 vva = vv.split(' ');
530                 var rtype = vva.shift();
531                 var body = vva.join(' ');
532                 
533                 
534                 strbuilder(pad + "public " + rtype + " " + k.substring(1) +body + "\n");
535                 
536                 
537                 
538             }
539             
540             
541             
542             if (depth > 0) {
543                 strbuilder(inpad + "}\n");
544             }
545             
546             
547             // next loop throug children..
548             if (typeof(item.items) != 'undefined') {
549                 for(var i =0;i<item.items.length;i++) {
550                     this.toValaItem(item.items[i], 1, strbuilder);
551                 }
552             }
553             if (depth < 1) {
554                 strbuilder(inpad + "}\n");
555             }
556             
557         }
558         
559         
560         
561     });