src/Builder4/WindowRooView.bjs
[app.Builder.js] / src / Builder4 / WindowRooView.vala
1 static Xcls_WindowRooView  _WindowRooView;
2
3 public class Xcls_WindowRooView : Object 
4 {
5     public Gtk.VPaned el;
6     private Xcls_WindowRooView  _this;
7
8     public static Xcls_WindowRooView singleton()
9     {
10         if (_WindowRooView == null) {
11             _WindowRooView= new Xcls_WindowRooView();
12         }
13         return _WindowRooView;
14     }
15     public Xcls_viewbox viewbox;
16     public Xcls_AutoRedraw AutoRedraw;
17     public Xcls_viewcontainer viewcontainer;
18     public Xcls_view view;
19     public Xcls_inspectorcontainer inspectorcontainer;
20
21         // my vars (def)
22     public JsRender.JsRender file;
23
24     // ctor 
25     public Xcls_WindowRooView()
26     {
27         _this = this;
28         this.el = new Gtk.VPaned();
29
30         // my vars (dec)
31
32         // set gobject values
33         var child_0 = new Xcls_viewbox( _this );
34         child_0.ref();
35         this.el.pack1 (  child_0.el , true,true );
36         var child_1 = new Xcls_inspectorcontainer( _this );
37         child_1.ref();
38         this.el.pack2 (  child_1.el , true,true );
39     }
40
41     // user defined functions 
42     public void loadFile (JsRender.JsRender file)
43     {
44         this.file = file;
45         this.view.renderJS(true);
46     }
47     public void createThumb () {
48         
49         
50         if (this.file == null) {
51             return;
52         }
53         var filename = this.file.getIconFileName(false);
54         
55         var  win = this.el.get_parent_window();
56         var width = win.get_width();
57         var height = win.get_height();
58     
59         Gdk.Pixbuf screenshot = Gdk.pixbuf_get_from_window(win, 0, 0, width, this.el.position);
60     
61         screenshot.save(filename,"png");
62         return;
63         
64         
65         
66         
67         
68         
69         
70         var p = new WebKit.PrintOperation(_this.view.el);
71          
72         var ps = new Gtk.PrintSettings();
73         ps.set_printer("Print to File");
74         ps.set("output-file-format", "pdf");
75         ps.set("output-uri", "file://" + filename + ".pdf");
76     
77         // find the printer...
78         
79         /*
80         var ar = Gtk.PaperSize.get_paper_sizes(false);
81         var psetup = new Gtk.PageSetup();
82         for(var i = 0; i < ar.length(); i++) {
83             if (ar.nth_data(i).get_name() =="iso_a4") {
84                 psetup.set_paper_size(ar.nth_data(i));
85             }
86         }
87         psetup.set_orientation(Gtk.PageOrientation.LANDSCAPE);
88         
89          
90         p.set_page_setup(psetup);
91         */
92         p.set_print_settings(ps);
93         
94         p.finished.connect(() => {
95             print("creating thumbnail for " + filename + ".pdf\n"); 
96             var s = new Cairo.PdfSurface(filename + ".pdf", 400,400);
97         
98             s.write_to_png (filename);
99             
100            // var f = GLib.File.new_for_path (filename + ".pdf");
101            // f.delete();
102         });
103         
104         
105         p.print();
106         
107         // should we hold until it's printed...
108         
109           
110     
111         
112         
113     
114     
115         
116          
117     }
118     public void requestRedraw () {
119         this.view.renderJS(false);
120     }
121     public class Xcls_viewbox : Object 
122     {
123         public Gtk.VBox el;
124         private Xcls_WindowRooView  _this;
125
126
127             // my vars (def)
128
129         // ctor 
130         public Xcls_viewbox(Xcls_WindowRooView _owner )
131         {
132             _this = _owner;
133             _this.viewbox = this;
134             this.el = new Gtk.VBox( false, 0 );
135
136             // my vars (dec)
137
138             // set gobject values
139             var child_0 = new Xcls_HBox3( _this );
140             child_0.ref();
141             this.el.pack_start (  child_0.el , false,true,0 );
142             var child_1 = new Xcls_viewcontainer( _this );
143             child_1.ref();
144             this.el.pack_end (  child_1.el , true,true,0 );
145         }
146
147         // user defined functions 
148     }
149     public class Xcls_HBox3 : Object 
150     {
151         public Gtk.HBox el;
152         private Xcls_WindowRooView  _this;
153
154
155             // my vars (def)
156
157         // ctor 
158         public Xcls_HBox3(Xcls_WindowRooView _owner )
159         {
160             _this = _owner;
161             this.el = new Gtk.HBox( true, 0 );
162
163             // my vars (dec)
164
165             // set gobject values
166             this.el.height_request = 20;
167             this.el.vexpand = false;
168             var child_0 = new Xcls_Button4( _this );
169             child_0.ref();
170             this.el.pack_start (  child_0.el , false,false,0 );
171             var child_1 = new Xcls_AutoRedraw( _this );
172             child_1.ref();
173             this.el.pack_start (  child_1.el , false,false,0 );
174             var child_2 = new Xcls_Button6( _this );
175             child_2.ref();
176             this.el.pack_start (  child_2.el , false,false,0 );
177         }
178
179         // user defined functions 
180     }
181     public class Xcls_Button4 : Object 
182     {
183         public Gtk.Button el;
184         private Xcls_WindowRooView  _this;
185
186
187             // my vars (def)
188
189         // ctor 
190         public Xcls_Button4(Xcls_WindowRooView _owner )
191         {
192             _this = _owner;
193             this.el = new Gtk.Button();
194
195             // my vars (dec)
196
197             // set gobject values
198             this.el.label = "Redraw";
199
200             // listeners 
201             this.el.clicked.connect( ( ) => {
202                 _this.view.renderJS(  true);
203             });
204         }
205
206         // user defined functions 
207     }
208     public class Xcls_AutoRedraw : Object 
209     {
210         public Gtk.CheckButton el;
211         private Xcls_WindowRooView  _this;
212
213
214             // my vars (def)
215
216         // ctor 
217         public Xcls_AutoRedraw(Xcls_WindowRooView _owner )
218         {
219             _this = _owner;
220             _this.AutoRedraw = this;
221             this.el = new Gtk.CheckButton();
222
223             // my vars (dec)
224
225             // set gobject values
226             this.el.active = true;
227             this.el.label = "Auto Redraw On";
228
229             // listeners 
230             this.el.toggled.connect( (state) => {
231                 this.el.set_label(this.el.active  ? "Auto Redraw On" : "Auto Redraw Off");
232             });
233         }
234
235         // user defined functions 
236     }
237     public class Xcls_Button6 : Object 
238     {
239         public Gtk.Button el;
240         private Xcls_WindowRooView  _this;
241
242
243             // my vars (def)
244
245         // ctor 
246         public Xcls_Button6(Xcls_WindowRooView _owner )
247         {
248             _this = _owner;
249             this.el = new Gtk.Button();
250
251             // my vars (dec)
252
253             // set gobject values
254             this.el.label = "Full Redraw";
255
256             // listeners 
257             this.el.clicked.connect( () => {
258               _this.view.redraws = 99;
259                 _this.view.el.web_context.clear_cache();  
260               //_this.view.renderJS(true);
261               FakeServerCache.clear();
262               _this.view.reInit();
263             
264             });
265         }
266
267         // user defined functions 
268     }
269     public class Xcls_viewcontainer : Object 
270     {
271         public Gtk.ScrolledWindow el;
272         private Xcls_WindowRooView  _this;
273
274
275             // my vars (def)
276
277         // ctor 
278         public Xcls_viewcontainer(Xcls_WindowRooView _owner )
279         {
280             _this = _owner;
281             _this.viewcontainer = this;
282             this.el = new Gtk.ScrolledWindow( null, null );
283
284             // my vars (dec)
285
286             // set gobject values
287             this.el.shadow_type = Gtk.ShadowType.IN;
288             var child_0 = new Xcls_view( _this );
289             child_0.ref();
290             this.el.add (  child_0.el  );
291
292             // init method 
293
294             this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
295         }
296
297         // user defined functions 
298     }
299     public class Xcls_view : Object 
300     {
301         public WebKit.WebView el;
302         private Xcls_WindowRooView  _this;
303
304
305             // my vars (def)
306         public string renderedData;
307         public bool refreshRequired;
308         public WebKit.WebInspector inspector;
309         public string runjs;
310         public int redraws;
311         public GLib.DateTime lastRedraw;
312         public string runhtml;
313         public bool pendingRedraw;
314
315         // ctor 
316         public Xcls_view(Xcls_WindowRooView _owner )
317         {
318             _this = _owner;
319             _this.view = this;
320             this.el = new WebKit.WebView();
321
322             // my vars (dec)
323             this.renderedData = "";
324             this.refreshRequired = false;
325             this.runjs = "";
326             this.redraws = 0;
327             this.lastRedraw = null;
328             this.runhtml = "";
329             this.pendingRedraw = false;
330
331             // set gobject values
332
333             // init method 
334
335             {
336                 // this may not work!?
337                 var settings =  this.el.get_settings();
338                 settings.enable_developer_extras = true;
339                 
340                 
341                 var fs= new FakeServer(this.el);
342                 fs.ref();
343                 // this was an attempt to change the url perms.. did not work..
344                 // settings.enable_file_access_from_file_uris = true;
345                 // settings.enable_offline_web_application_cache - true;
346                 // settings.enable_universal_access_from_file_uris = true;
347                
348                  
349                 
350                 
351                 
352             
353                  // FIXME - base url of script..
354                  // we need it so some of the database features work.
355                 this.el.load_html( "Render not ready" , 
356                         //fixme - should be a config option!
357                         // or should we catch stuff and fix it up..
358                         "http://localhost/app.Builder/"
359                 );
360                     
361                     
362                //this.el.open('file:///' + __script_path__ + '/../builder.html');
363                 /*
364                 Gtk.drag_dest_set
365                 (
366                         this.el,              //
367                         Gtk.DestDefaults.MOTION  | Gtk.DestDefaults.HIGHLIGHT,
368                         null,            // list of targets
369                         Gdk.DragAction.COPY         // what to do with data after dropped 
370                 );
371                                         
372                // print("RB: TARGETS : " + LeftTree.atoms["STRING"]);
373                 Gtk.drag_dest_set_target_list(this.el, this.get('/Window').targetList);
374                 */
375                 GLib.Timeout.add_seconds(1,  ()  =>{
376                      //print("run refresh?");
377                      if (this.el == null) {
378                         return false;
379                      }
380                      this.runRefresh(); 
381                      return true;
382                  });
383                 
384                 
385             }
386
387             // listeners 
388             this.el.script_dialog.connect( (dialog) => {
389                 if (this.el == null) {
390                     return true;
391                 }
392                 
393                  var msg = dialog.get_message();
394                  if (msg.length < 4) {
395                     return false;
396                  }
397                  if (msg.substring(0,4) != "IPC:") {
398                      return false;
399                  }
400                  var ar = msg.split(":", 3);
401                 if (ar.length < 3) {
402                     return false;
403                 }
404                 switch(ar[1]) {
405                     case "SAVEHTML":
406                         _this.file.saveHTML(ar[2]);
407                         return true;
408                     default:
409                         return false;
410                 }
411                 
412             });
413             this.el.show.connect( ( ) => {
414                 this.initInspector();;
415             });
416             this.el.drag_drop.connect( ( ctx, x, y,time, ud) => {
417                 return false;
418                 /*
419                 print("TARGET: drag-drop");
420                     var is_valid_drop_site = true;
421                     
422                      
423                     Gtk.drag_get_data
424                     (
425                             w,         // will receive 'drag-data-received' signal 
426                             ctx,        /* represents the current state of the DnD 
427                             this.get('/Window').atoms["STRING"],    /* the target type we want 
428                             time            /* time stamp 
429                     );
430                                     
431                                     
432                                     /* No target offered by source => error 
433                                    
434             
435                 return  is_valid_drop_site;
436                 */
437             });
438             this.el.load_changed.connect( (le) => {
439                 if (le != WebKit.LoadEvent.FINISHED) {
440                     return;
441                 }
442                 if (this.runjs.length < 1) {
443                     return;
444                 }
445               //  this.el.run_javascript(this.runjs, null);
446                  FakeServerCache.remove(    this.runjs);
447                 this.runjs = "";
448             });
449         }
450
451         // user defined functions 
452         public void reInit () {
453            print("reInit?");
454                  // if this happens destroy the webkit..
455                  // recreate it..
456              this.el.stop_loading();
457                  
458              if (_this.viewbox.el.get_parent() == null) {
459                 return;
460              }
461                  
462                  
463             _this.viewbox.el.remove(_this.viewcontainer.el);
464             _this.el.remove(_this.inspectorcontainer.el);        
465                  
466                  // destory seems to cause problems.
467                  //this.el.destroy();
468                 //_this.viewcontainer.el.destroy();
469                  //_this.inspectorcontainer.el.destroy();
470              var  inv =new Xcls_inspectorcontainer(_this);
471               inv.ref();
472               _this.el.pack2(inv.el,true,true);
473               
474               
475              this.el = null;         
476              var nv =new Xcls_viewcontainer(_this);
477              nv.ref();
478              _this.viewbox.el.pack_end(nv.el,true,true,0);
479                  
480                  
481              inv.el.show_all();
482              nv.el.show_all();
483                  //while(Gtk.events_pending ()) Gtk.main_iteration ();
484                  //_this.view.renderJS(true); 
485              _this.view.refreshRequired  = true;
486         }
487         public void runRefresh () 
488         {
489             // this is run every 2 seconds from the init..
490         
491           
492             
493             if (!this.refreshRequired) {
494                // print("no refresh required");
495                 return;
496             }
497         
498             if (this.lastRedraw != null) {
499                // do not redraw if last redraw was less that 5 seconds ago.
500                if ((int64)(new DateTime.now_local()).difference(this.lastRedraw) < 5000 ) {
501                     return;
502                 }
503             }
504             
505             if (_this.file == null) {
506                 return;
507             }
508             
509             
510              this.refreshRequired = false;
511            //  print("HTML RENDERING");
512              
513              
514              //this.get('/BottomPane').el.show();
515              //this.get('/BottomPane').el.set_current_page(2);// webkit inspector
516             _this.file.webkit_page_id  = this.el.get_page_id();
517             
518             var js = _this.file.toSourcePreview();
519         
520             if (js.length < 1) {
521                 print("no data");
522                 return;
523             }
524         //    var  data = js[0];
525             this.redraws++;
526           
527             var project = _this.file.project;  
528         
529              //print (project.fn);
530              // set it to non-empty.
531              
532         //     runhtml = runhtml.length ?  runhtml : '<script type="text/javascript"></script>'; 
533         
534         
535         //   this.runhtml  = this.runhtml || '';
536          
537          
538             // then we need to reload the browser using
539             // load_html_string..
540         
541             // then trigger a redraw once it's loaded..
542             this.pendingRedraw = true;
543         
544             var runhtml = "<script type=\"text/javascript\">\n" ;
545             string builderhtml;
546             
547             
548             GLib.FileUtils.get_contents(BuilderApplication.configDirectory() + "/resources/roo.builder.js", out builderhtml);
549         
550             runhtml += builderhtml + "\n";
551             runhtml += "</script>\n" ;
552         
553             // fix to make sure they are the same..
554             this.runhtml = project.runhtml;
555             // need to modify paths
556         
557             string inhtml;
558             var base_template = _this.file.project.base_template;
559             
560             if (base_template.length > 0 && !FileUtils.test(
561                 BuilderApplication.configDirectory() + "/resources/" +  base_template, FileTest.EXISTS)  
562                 ) {
563                    print("invalid base_template name - using default:  %s\n", base_template);
564                    base_template = "";
565             
566             }
567             
568             GLib.FileUtils.get_contents(
569                 BuilderApplication.configDirectory() + "/resources/" + 
570                     (base_template.length > 0 ? base_template :  "roo.builder.html")
571                     , out inhtml);
572             
573             
574             this.renderedData = js;
575         
576         
577             string js_src = js + "\n" +
578                 "Roo.onReady(function() {\n" +
579                 "if (" + _this.file.name +".show) " +  _this.file.name +".show({});\n" +
580                 "Roo.XComponent.build();\n" +
581                 "});\n";
582                 
583            // print("render js: " + js);
584             //if (!this.ready) {
585           //      console.log('not loaded yet');
586             //}
587             this.lastRedraw = new DateTime.now_local();
588         
589         
590             //this.runjs = js_src;
591             var fc =    FakeServerCache.factory_with_data(js_src);
592             this.runjs = fc.fname;
593             
594                 var html = inhtml.replace("</head>", runhtml + this.runhtml + 
595                     "<script type=\"text/javascript\" src=\"xhttp://localhost" + fc.fname + "\"></script>" +   
596                       //  "<script type=\"text/javascript\">\n" +
597                       //  js_src + "\n" + 
598                       //  "</script>" + 
599                                 
600                 "</head>");
601                 //print("LOAD HTML " + html);
602                 
603                  var rootURL = _this.file.project.rootURL;
604            
605                 
606                 
607                 this.el.load_html( html , 
608                     //fixme - should be a config option!
609                     (rootURL.length > 0 ? rootURL : "xhttp://localhost/app.Builder.js/")
610                 );
611                 
612             // force the inspector...        
613                //   this.initInspector();
614                 
615                 // - no need for this, the builder javascript will call it when build is complete
616                 //GLib.Timeout.add_seconds(1, () => {
617                 //    this.el.run_javascript("Builder.saveHTML()",null);
618                 //    return false;
619                 //});
620         //     print( "before render" +    this.lastRedraw);
621         //    print( "after render" +    (new Date()));
622             
623         }
624         public void initInspector () {
625             
626            /* if (this.inspector == this.el.get_inspector()) {
627                 this.inspector.show();
628                 this.inspector.open_window();        
629                 print("init inspecter called, and inspector is the same as existing\n");
630                 return;
631             }
632             print("new inspector?\n");
633         */
634             this.inspector = this.el.get_inspector();
635             this.inspector.ref();
636             
637             // got a new inspector...
638                 
639             this.inspector.open_window.connect(() => {
640                  this.inspector = this.el.get_inspector();
641                 print("inspector attach\n");
642                 var wv = this.inspector.get_web_view();
643                 if (wv != null) {
644                     print("got inspector web view\n");
645                     
646                     var cn = _this.inspectorcontainer.el.get_child();
647                     if (cn != null) {
648                          _this.inspectorcontainer.el.remove(cn);
649                      }
650                     
651                     _this.inspectorcontainer.el.add(wv);
652                     wv.show();
653                 } else {
654                     //this.inspector.close();
655                     
656                     //this.inspector = null;
657                    
658          
659                 }
660                 return true;
661                
662             });
663             /*
664             this.inspector.closed.connect(() => {
665                  print("inspector closed?!?");
666                  // if this happens destroy the webkit..
667                  // recreate it..
668                  this.el.stop_loading();
669                  
670                  if (_this.viewbox.el.get_parent() == null) {
671                     return;
672                  }
673                  
674                  
675                 _this.viewbox.el.remove(_this.viewcontainer.el);
676                 _this.el.remove(_this.inspectorcontainer.el);        
677                  
678                  // destory seems to cause problems.
679                  //this.el.destroy();
680                 //_this.viewcontainer.el.destroy();
681                  //_this.inspectorcontainer.el.destroy();
682         
683                  this.el = null;         
684                  var nv =new Xcls_viewcontainer(_this);
685                  nv.ref();
686                  _this.viewbox.el.pack_end(nv.el,true,true,0);
687                  
688                   var  inv =new Xcls_inspectorcontainer(_this);
689                   inv.ref();
690                   _this.el.pack2(inv.el,true,true);
691                  
692                  inv.el.show_all();
693                  nv.el.show_all();
694                  //while(Gtk.events_pending ()) Gtk.main_iteration ();
695                  //_this.view.renderJS(true); 
696                  _this.view.refreshRequired  = true;
697                
698             }); 
699             */
700             
701             this.inspector.show();
702         }
703         public void renderJS (bool force) {
704         
705             // this is the public redraw call..
706             // we refresh in a loop privately..
707             var autodraw = _this.AutoRedraw.el.active;
708             if (!autodraw && !force) {
709                 print("Skipping redraw - no force, and autodraw off");
710                 return;
711             }
712              
713             this.refreshRequired  = true;
714         }
715     }
716     public class Xcls_inspectorcontainer : Object 
717     {
718         public Gtk.ScrolledWindow el;
719         private Xcls_WindowRooView  _this;
720
721
722             // my vars (def)
723
724         // ctor 
725         public Xcls_inspectorcontainer(Xcls_WindowRooView _owner )
726         {
727             _this = _owner;
728             _this.inspectorcontainer = this;
729             this.el = new Gtk.ScrolledWindow( null, null );
730
731             // my vars (dec)
732
733             // set gobject values
734             this.el.shadow_type = Gtk.ShadowType.IN;
735
736             // init method 
737
738             this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
739         }
740
741         // user defined functions 
742     }
743 }