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