src/Builder4/WindowState.vala
[app.Builder.js] / src / Builder4 / WindowState.vala
1 /**
2  * as state management is a bit too complicated inside the builder
3  * it's better to seperate this into this class
4  * 
5  * This class has references to all the Class instances that make up the window..
6  * 
7  */
8 public class WindowState : Object 
9 {
10     public MainWindow win;
11
12     public enum State {
13         PREVIEW,
14         OBJECT,
15         PROP,
16         LISTENER,
17         CODE,
18         FILES,
19         PROJECT // project settings..
20     };
21
22     public State state;
23
24     
25     public Xcls_WindowLeftTree  left_tree;
26     public Xcls_WindowAddProp   add_props;
27     public Xcls_LeftProps       left_props;
28     public Xcls_ProjectSettings projectsettings;
29     public ValaProjectSettings  vala_projectsettings;
30     public Xcls_RightPalete     rightpalete;
31     public Editor               code_editor;    
32     public Xcls_WindowRooView   window_rooview;
33     public Xcls_GtkView         window_gladeview;
34     public Xcls_DialogNewComponent new_file_dialog;     
35
36     public Xcls_WindowLeftProjects left_projects; // can not see where this is initialized.. 
37     // ctor 
38     public WindowState(MainWindow win)
39     {
40         this.win = win;
41         // initialize
42
43         // left elements..
44         this.leftTreeInit();
45         this.propsListInit();
46
47         // on clutter space...
48         this.projectEditInit();
49         this.codeEditInit();
50         this.projectListInit();)
51         this.fileViewInit();
52         
53         // adding stuff
54         this.objectAddInit();
55         this.propsAddInit();
56      
57         
58         // previews...
59         this.gtkViewInit();
60         this.webkitViewInit();
61
62         // dialogs
63
64         this.fileNewInit();
65     }
66
67
68     // left tree
69
70     public void leftTreeInit()
71     {
72      
73         this.left_tree = new Xcls_WindowLeftTree();
74         this.left_tree.ref();
75         this.left_tree.main_window = _this.win;
76     
77         this.win.tree.el.pack_start(this.left_tree.el,true, true,0);
78         this.left_tree.el.show_all();
79            
80         this.left_tree.before_node_change.connect(() => {
81             return this.leftTreeBeforeChange();
82
83         });
84
85         this.left_tree.node_selected.connect((sel) => {
86             this.leftTreeNodeSelected(sel);
87         });
88      
89         this.left_tree.changed.connect(() => {
90             this.window_rooview.requestRedraw();
91             this.left_tree.model.file.save();
92         });
93          
94     }
95
96     public bool leftTreeBeforeChange(JsRender.Node? sel)
97     {
98         if (this.state != "codeedit") {
99             this.left_props.finish_editing();
100             return true;
101         }
102         if (!this.code_editor.saveContents()) {
103             return false;
104         }
105         return false;
106     }
107     
108     public void leftTreeNodeSelected(JsRender.Node? sel)
109     {
110
111         print("node_selected called %s\n", (sel == null) ? "NULL" : "a value");
112
113         if (sel == null) {
114             this.left_props.el.hide();
115         } 
116         this.left_props.el.show();
117         this.left_props.load(this.left_tree.getActiveFile(), sel);
118         switch (this.state) {
119             
120             case State.OBJECT: 
121                   
122                  if (sel == null) {
123                     this.rightpalete.clear();
124                     break;
125                 }
126                 this.rightpalete.load(this.left_tree.getActiveFile().palete(), sel.fqn());
127                 break;
128                  
129         
130            case State.PROP:
131                 if (sel == null) {
132                     this.add_props.clear();
133                     break;
134                 }
135                 this.add_props.show(this.left_tree.getActiveFile().palete(), "props", sel.fqn());
136                 break;
137
138             case State.LISTENER:
139                
140                 if (sel == null) {
141                     this.add_props.clear();
142                     break;
143                 }
144                 this.add_props.show(_this.left_tree.getActiveFile().palete(), "signals", sel.fqn());
145                 break;
146                 
147             case State.CODEEDIT:
148             // SAVE FIRST???
149         
150             this.codeEditHide();
151             break;
152                
153                             
154         }
155          
156
157     }
158
159
160
161
162     public void propsListInit()
163     {
164     
165         this.left_props =new Xcls_LeftProps();
166         this.left_props.ref();
167         this.left_props.main_window = _this;
168         this.win.props.el.pack_start(this.left_props.el,true, true,0);
169         this.left_props.el.show_all();
170     
171         this.left_props.show_editor.connect( (file, node, type,  key) => {
172             this.codeEditShow(file, node, type,  key);
173         });
174
175     
176         this.left_props.stop_editor.connect( () => {
177             if (this.state != "codeedit") {
178                 return true;
179             }
180     
181             var ret =  this.code_editor.saveContents();
182             if (!ret) {
183                 return false;
184             }
185             this.codeEditHide();
186             return ret;
187         });
188     
189         this.left_props.changed.connect(() => {
190               if (this.left_tree.getActiveFile().xtype == "Roo" ) {
191                    this.window_rooview.requestRedraw();
192                    
193                } else {
194                   this.window_gladeview.loadFile(this.left_tree.getActiveFile());
195               }
196               this.left_tree.model.updateSelected();
197               this.left_tree.model.file.save();
198         });
199     
200
201
202     }
203
204     //-------------  projects edit
205
206     public void projectEditInit()
207     {
208         this.projectsettings  =new Xcls_ProjectSettings();
209         this.projectsettings.ref();  /// really?
210     
211         this.vala_projectsettings  =new ValaProjectSettings();
212         this.vala_projectsettings.ref();
213         this.vala_projectsettings.window = this;
214     
215         ((Gtk.Container)(this.win.projecteditview.el.get_widget())).add(this.projectsettings.el);
216         //this.projectsettings.el.show_all();
217
218         var stage = this.win.projecteditview.el.get_stage();
219         stage.set_background_color(  Clutter.Color.from_string("#000"));
220     
221         this.projectsettings.buttonPressed.connect((btn) => {
222              if (this.left_tree.getActiveFile().xtype == "Roo" ) {
223                 if (btn == "save") {
224                     this.window_rooview.view.renderJS(true);
225                 }
226                 if (btn == "apply") {
227                     this.window_rooview.view.renderJS(true);
228                     return;
229                 }
230             } else {
231                 // do nothing for gtk..
232             }
233             if (btn == "save" || btn == "apply") {
234                 this.win.project.save();
235          
236             }
237             
238             this.projectEditHide();
239              
240          });
241
242     }
243     // ----------- object adding
244     public void objectAddInit()
245     {
246
247         this.rightpalete  = new Xcls_RightPalete();
248         this.rightpalete.ref();  /// really?
249         ((Gtk.Container)(this.win.objectview.el.get_widget())).add(this.rightpalete.el);
250         //this.projectsettings.el.show_all();
251
252         stage = _this.win.objectview.el.get_stage();
253         stage.set_background_color(  Clutter.Color.from_string("#000"));
254            
255     }
256     
257     // -----------  properties adding list...
258     // listener uses the properties 
259     public void propsAddInit()
260     {
261     // Add properties
262         this.add_props  = new Xcls_WindowAddProp();
263         this.add_props.ref();  /// really?
264         ((Gtk.Container)(this.win.addpropsview.el.get_widget())).add(this.add_props.el);
265         //this.projectsettings.el.show_all();
266
267         var  stage = _this.win.addpropsview.el.get_stage();
268         stage.set_background_color(  Clutter.Color.from_string("#000"));
269
270
271         this.add_props.select.connect( (key,type,skel, etype) => {
272             this.left_props.addProp(etype, key, skel, type);
273         });
274
275     }
276     public void propsAddShow()
277     {
278
279     }
280     public void propsAddHide()
281     {
282     
283     }
284
285
286
287     
288     // ----------- Add / Edit listener
289     // listener uses the properties 
290     //public void listenerInit()     { }
291     public void listenerShow()
292     {
293
294     }
295     public void listenerHide()
296     {
297     
298     }
299
300     // -------------- codeEditor
301
302     public void codeEditInit()
303     {
304         this.code_editor  = new  Editor();
305         this.code_editor.ref();  /// really?
306         ((Gtk.Container)(this.win.codeeditview.el.get_widget())).add(this.code_editor.el);
307         //this.projectsettings.el.show_all();
308
309         stage = _this.win.codeeditview.el.get_stage();
310         stage.set_background_color(  Clutter.Color.from_string("#000"));
311         // editor.save...
312
313         this.code_editor.save.connect( () => {
314              this.left_tree.model.file.save();
315              this.left_tree.model.updateSelected();
316         });
317         
318     }
319
320     // ----------- list of projects on left
321     public void  projectListInit() 
322     {
323
324         this.left_projects = new Xcls_WindowLeftProjects();
325          this.left_projects.ref();
326          this.win.leftpane.el.pack_start(this.left_projects.el,true, true,0);
327          this.left_projects.el.show_all();
328          this.left_projects.project_selected.connect((proj) => {
329             proj.scanDirs();
330             this.clutterfiles.loadProject(proj);
331         
332          });
333
334     }
335     // ----------- file view
336
337     public void fileViewInit()
338     {
339         stage = _this.rooview.el.get_stage(); \\ seems odd... 
340         this.clutterfiles = new Xcls_ClutterFiles();
341         this.clutterfiles.ref();
342         stage.add_child(this.clutterfiles.el);
343         this.clutterfiles.el.show_all();
344
345
346         this.clutterfiles.open.connect((file) => { 
347             this.fileViewOpen(file);
348         });
349
350     }
351     public void fileNewInit()
352     {
353         this.new_file_dialog = new Xcls_DialogNewComponent();
354         // force it modal to the main window..
355         this.new_file_dialog.el.set_transient_for(this.el);
356         this.new_file_dialog.el.set_modal(true);
357     
358         this.new_file_dialog.success.connect((project,file) =>
359         {
360             this.fileViewOpen(file);
361         });
362
363     }
364
365     
366     public void fileViewOpen(JsRender.JsRender file)
367     {
368         this.win.project = file.project;
369         this.previewShow();
370             this.left_tree.model.loadFile(file);
371     
372         var ctr= ((Gtk.Container)(this.win.rooview.el.get_widget()));
373         var ctr_p= ((Gtk.Container)(this.win.projecteditview.el.get_widget()));
374     
375         if (file.xtype == "Roo" ) { 
376             ctr.foreach( (w) => { ctr.remove(w); });
377             ctr_p.foreach( (w) => { ctr_p.remove(w); });
378             ctr.add(this.window_rooview.el);
379             ctr_p.add(this.projectsettings.el);            
380             this.window_rooview.loadFile(file);
381             this.window_rooview.el.show_all();
382             this.projectsettings.el.show_all();            
383
384         } else {
385             ctr.foreach( (w) => { ctr.remove(w); });
386             ctr_p.foreach( (w) => { ctr_p.remove(w); });            
387             ctr.add(this.window_gladeview.el);
388             ctr_p.add(this.vala_projectsettings.el);
389             this.window_gladeview.loadFile(file);
390             this.window_gladeview.el.show_all();
391             this.vala_projectsettings.el.show_all();
392         }
393         print("OPEN : " + file.name);
394         this.editpane.el.set_position(_this.editpane.el.max_position);
395         this.win.setTitle(file.project.name + " : " +file.name);
396              
397
398         }
399
400     
401     // ---------  webkit view
402     public void webkitViewInit()
403     {
404         this.window_rooview  =new Xcls_WindowRooView();
405         this.window_rooview.ref();
406         ((Gtk.Container)(this.win.rooview.el.get_widget())).add(this.window_rooview.el);
407         this.window_rooview.el.show_all();
408
409         stage = this.win.rooview.el.get_stage();
410         stage.set_background_color(  Clutter.Color.from_string("#000"));
411     }
412
413     // ------ Gtk  - view
414
415     public void gtkViewInit()
416     {
417         this.window_gladeview  =new Xcls_GtkView();
418         this.window_gladeview.ref();
419     }
420
421     public void switchState(State new_state)
422     {
423         if (this.state == State.PREVIEW) {
424             // try and do a snapshot..
425             
426             
427         }
428
429         
430
431
432         
433         switch (this.state) {
434
435             case State.PREVIEW:
436                 if (this.left_tree.getActiveFile() != null) {
437                      if (this.left_tree.getActiveFile().xtype == "Roo" ) {
438                          this.window_rooview.createThumb();
439                      } else {
440                           this.window_gladeview.createThumb();
441                       }
442                 }
443                 // normally we are going from preview to another state.
444                 // and different windows hide the preview in differnt ways..
445                 
446                 break;
447             
448            case State.LISTENER:
449            case State.PROP:
450                 this.win.addpropsview.el.save_easing_state();
451                 this.win.addpropsview.el.set_scale(0.0f,0.0f);
452                 this.win.addpropsview.el.restore_easing_state();   
453                 break;
454                 
455             case State.CODE:
456                 this.win.codeeditview.el.save_easing_state();
457                 this.win.codeeditview.el.set_scale(0.0f,0.0f);
458                 this.win.codeeditview.el.restore_easing_state();    
459                 break;
460
461
462              case State.OBJECT:
463                 this.win.objectview.el.save_easing_state();
464                 this.win.objectview.el.set_scale(0.0f,0.0f);
465                 this.win.objectview.el.restore_easing_state();    
466                 break;
467
468            case State.PROJECT:
469                 this.win.projecteditview.el.save_easing_state();
470                 this.win.projecteditview.el.set_scale(0.0f,0.0f);
471                 this.win.projecteditview.el.restore_easing_state();    
472                 break;
473         }
474         
475         var oldstate  =this.state;
476         this.state = new_state;
477
478                 
479         this.buttonShowHide();
480         
481         switch (this.state) {
482             
483             case State.PREVIEW:  // this is the default state when working...
484                  this.win.rooview.el.save_easing_state();
485                  this.win.rooview.el.set_scale(1.0f,1.0f);
486                  this.win.rooview.el.restore_easing_state();
487                
488                 break;
489
490
491             case State.LISTENER:
492             case State.PROP:
493                 var ae =      this.left_tree.getActiveElement();
494                 if (ae == null) {
495                     this.state = this.oldstate;
496                     this.buttonShowHide();
497                     return;
498                 }
499                 this.add_props.el.show_all();
500                 this.add_props.show(
501                     Palete.factory(this.win.project.xtype), 
502                     this.state == State.LISTENER ? "signals" : "props",
503                     ae.fqn()
504                 );
505  
506                     
507  
508                 this.win.rooview.el.save_easing_state();
509                 // -- FIXME? this needs to be State aware?
510                 _this.clutterembed.setSizesAlloc( this.state == State.LISTENER  ? "addlistener" : "addprop");
511                 this.win.rooview.el.restore_easing_state();
512                 
513               
514                 this.win.addpropsview.el.save_easing_state();
515                 this.win.addpropsview.el.set_scale(1.0f,1.0f);
516                 this.win.addpropsview.el.restore_easing_state();
517                  
518                 
519             case State.CODE:
520
521                 this.code_editor.el.show_all();
522                 
523                 // caller needs to call editor - show....
524                 this.win.rooview.el.save_easing_state();
525                 // -- FIXME? this needs to be State aware?
526                 _this.clutterembed.setSizesAlloc( "codeedit");
527                 this.win.rooview.el.restore_easing_state();
528                 
529  
530                 this.win.codeeditview.el.save_easing_state();
531                 this.win.codeeditview.el.set_scale(1.0f,1.0f);
532                 this.win.codeeditview.el.restore_easing_state();    
533                 break;
534
535
536              case State.OBJECT:
537                  var n = _this.left_tree.getActiveElement();
538
539                     if (_this.left_tree.model.file == null) {
540                         this.state = this.oldstate;
541                         this.buttonShowHide();
542                         return;
543                     }
544                     
545                     if (n == null && _this.left_tree.model.file.tree != null) {
546                         this.state = this.oldstate;
547                         this.buttonShowHide();
548                         return;
549                     }
550
551
552                 
553                 this.win.objectview.el.save_easing_state();
554                 this.win.objectview.el.set_scale(0.0f,0.0f);
555                 this.win.objectview.el.restore_easing_state();    
556                 break;
557
558            case State.PROJECT:
559                 this.win.projecteditview.el.save_easing_state();
560                 this.win.projecteditview.el.set_scale(0.0f,0.0f);
561                 this.win.projecteditview.el.restore_easing_state();    
562                 break;
563                 
564            case State.FILES:  // can only get here from PREVIEW state.. in theory..
565                 
566    
567                 this.win.editpane.el.hide(); // holder for tree and properties..
568              
569                 this.left_projects.el.show(); 
570             
571                 var el = this.win.rooview.el;
572                 el.save_easing_state();
573                 el.set_easing_duration(1000);
574
575                 el.set_rotation_angle(Clutter.RotateAxis.Y_AXIS, 360.0f);
576                 el.set_scale(0.0f,0.0f);
577
578  
579                 if (this.win.project != null) {
580                     this.left_projects.selectProject(_this.project);
581                 }
582              
583                 el.restore_easing_state();
584                 
585                 break;
586
587
588
589
590             
591     }
592     
593     // -- buttons show hide.....
594
595     public void buttonsShowHide()
596     {
597         // basically hide everything, then show the relivant..
598
599          this.win.backbutton.el.hide();
600     
601         this.win.projectbutton.el.hide(); // show file nav...
602         this.win.editfilebutton.el.hide();
603         this.win.projecteditbutton.el.hide();
604          
605         
606         this.win.objectshowbutton.el.hide(); // add objects
607         this.win.addpropbutton.el.hide();  
608         this.win.addlistenerbutton.el.hide(); 
609
610     
611     
612         this.win.addprojectbutton.el.hide();
613         this.win.addfilebutton.el.hide();
614         this.win.delprojectbutton.el.hide();
615         this.win.new_window.el.hide();
616
617         
618         switch (this.state) {
619             
620             case State.PREVIEW:  // this is the default state when working...
621                
622                 this.win.projectbutton.el.show(); // show file nav...
623                 this.win.editfilebutton.el.show();
624                 this.win.projecteditbutton.el.show();
625                  
626                 
627                 this.win.objectshowbutton.el.show(); // add objects
628                 this.win.addpropbutton.el.show();  
629                 this.win.addlistenerbutton.el.show(); 
630                 break;
631             
632            
633             case State.CODE: 
634             case State.PROP:
635             case State.LISTENER:
636             case State.OBJECT
637                 
638                 this.win.backbutton.el.show();
639                 this.win.objectshowbutton.el.show(); // add objects
640                 this.win.addpropbutton.el.show();  
641                 this.win.addlistenerbutton.el.show(); 
642                  break;
643                 
644             case State.FILES:
645                 this.win.backbutton.el.show();
646                      
647                 this.win.addprojectbutton.el.show();
648                 this.win.addfilebutton.el.show();
649                 this.win.delprojectbutton.el.show();
650                 this.win.new_window.el.show();
651                 break;
652         
653
654     }
655
656
657     
658
659     
660 }
661
662