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