Support user defined properties in JS (BC for old files really?)
[roobuilder] / src / Builder4 / PopoverProperty.vala
1 static Xcls_PopoverProperty  _PopoverProperty;
2
3 public class Xcls_PopoverProperty : Object
4 {
5     public Gtk.Popover el;
6     private Xcls_PopoverProperty  _this;
7
8     public static Xcls_PopoverProperty singleton()
9     {
10         if (_PopoverProperty == null) {
11             _PopoverProperty= new Xcls_PopoverProperty();
12         }
13         return _PopoverProperty;
14     }
15     public Xcls_header header;
16     public Xcls_kflag kflag;
17     public Xcls_dbcellrenderer dbcellrenderer;
18     public Xcls_dbmodel dbmodel;
19     public Xcls_ktype ktype;
20     public Xcls_kname kname;
21     public Xcls_error error;
22     public Xcls_buttonbar buttonbar;
23
24         // my vars (def)
25     public bool is_new;
26     public signal void success (Project.Project pr, JsRender.JsRender file);
27     public string key_type;
28     public JsRender.NodeProp? prop;
29     public JsRender.Node node;
30     public Xcls_MainWindow mainwindow;
31     public bool done;
32     public string old_keyname;
33
34     // ctor
35     public Xcls_PopoverProperty()
36     {
37         _this = this;
38         this.el = new Gtk.Popover( null );
39
40         // my vars (dec)
41         this.is_new = false;
42         this.mainwindow = null;
43         this.done = false;
44
45         // set gobject values
46         this.el.border_width = 0;
47         this.el.modal = true;
48         this.el.position = Gtk.PositionType.RIGHT;
49         var child_0 = new Xcls_Box2( _this );
50         child_0.ref();
51         this.el.add(  child_0.el );
52
53         //listeners
54         this.el.closed.connect( () => {
55         
56                 GLib.debug("popover closed");
57                 if (_this.is_new) {
58                         // dont allow hiding if we are creating a new one.
59                         // on.hide will reshow it.
60                         return;
61                 }
62                 if (_this.prop == null) {
63                         // hide and dont update.
64                         return;
65                 }
66                 if (this.kname.el.get_text().strip().length < 1) {
67                         return;
68                 }
69                 
70                 var oldkey = this.prop.to_index_key();  
71                         
72                  
73                 this.updateProp();
74                         
75                 var newkey = this.prop.to_index_key();  
76                 if (oldkey != newkey) {
77                 
78                         if (_this.prop.ptype == JsRender.NodePropType.LISTENER) {
79                                 this.node.listeners.unset(oldkey);
80                                 this.node.listeners.set(newkey, _this.prop);
81                         } else {
82                                 this.node.props.unset(oldkey);
83                                 this.node.props.set(newkey, _this.prop);
84                         }
85                 
86                 }
87                 _this.mainwindow.windowstate.left_props.reload();
88         
89         
90           
91         });
92         this.el.hide.connect( () => {
93                 GLib.debug("popover hidden");
94                 if (_this.is_new || this.kname.el.get_text().strip().length < 1) {
95                         // dont allow hiding if we are creating a new one.
96                         GLib.debug("prevent hiding as its new or text is empty"); 
97                         this.el.show_all();
98                         return;
99         
100                 }
101                 
102         });
103     }
104
105     // user defined functions
106     public void updateProp () {
107      
108         Gtk.TreeIter citer;
109         GLib.Value gval;
110         this.kflag.el.get_active_iter(out citer);
111         this.dbmodel.el.get_value(citer, 0, out  gval);
112     
113     
114         _this.prop.name = this.kname.el.get_text().strip(); 
115         _this.prop.rtype = this.ktype.el.get_text().strip(); 
116         _this.prop.ptype =  (JsRender.NodePropType) gval;
117     
118     }
119     public void show (
120         Gtk.Widget btn, 
121         JsRender.Node node, 
122         JsRender.NodeProp prop, 
123         int y,
124         bool is_new = false
125          ) 
126     {
127         
128        
129         this.is_new = is_new; 
130         var pref = is_new ? "Add " : "Modify ";
131         if (prop.ptype == JsRender.NodePropType.LISTENER) {
132                 this.header.el.title = pref + "Event Listener"; // cant really happen yet?
133         } else {
134                 this.header.el.title = pref + "Property";
135         }
136         this.prop = prop;
137         this.node = node;
138         
139         _this.kname.el.set_text(prop.name);
140         _this.ktype.el.set_text(prop.rtype);
141         
142         _this.dbmodel.loadData(prop );
143         // does node have this property...
144     
145     
146         _this.node = node;
147         //console.log('show all');
148         this.el.set_modal(true);
149         this.el.set_relative_to(btn);
150         if (y > -1) {
151                 
152         
153                 var  r = Gdk.Rectangle() {
154                         x = btn.get_allocated_width(), // align left...
155                         y = y,
156                         width = 1,
157                         height = 1
158                 };
159                 this.el.set_pointing_to( r);
160         }
161         
162         
163     
164         //this.el.set_position(Gtk.PositionType.TOP);
165     
166         // window + header?
167          print("SHOWALL - POPIP\n");
168         this.el.show_all();
169         this.kname.el.grab_focus();
170         this.buttonbar.el.hide();
171         if (this.is_new) {
172                 this.buttonbar.el.show();
173         }
174          this.error.setError("");
175     
176         //this.success = c.success;
177      
178     }
179     public class Xcls_Box2 : Object
180     {
181         public Gtk.Box el;
182         private Xcls_PopoverProperty  _this;
183
184
185             // my vars (def)
186
187         // ctor
188         public Xcls_Box2(Xcls_PopoverProperty _owner )
189         {
190             _this = _owner;
191             this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
192
193             // my vars (dec)
194
195             // set gobject values
196             this.el.homogeneous = false;
197             var child_0 = new Xcls_header( _this );
198             child_0.ref();
199             this.el.pack_start (  child_0.el , false,true,0 );
200             var child_1 = new Xcls_Label4( _this );
201             child_1.ref();
202             this.el.add (  child_1.el  );
203             var child_2 = new Xcls_kflag( _this );
204             child_2.ref();
205             this.el.add (  child_2.el  );
206             var child_3 = new Xcls_Label8( _this );
207             child_3.ref();
208             this.el.add (  child_3.el  );
209             var child_4 = new Xcls_ktype( _this );
210             child_4.ref();
211             this.el.add (  child_4.el  );
212             var child_5 = new Xcls_Label10( _this );
213             child_5.ref();
214             this.el.add (  child_5.el  );
215             var child_6 = new Xcls_kname( _this );
216             child_6.ref();
217             this.el.add (  child_6.el  );
218             var child_7 = new Xcls_error( _this );
219             child_7.ref();
220             this.el.add (  child_7.el  );
221             var child_8 = new Xcls_buttonbar( _this );
222             child_8.ref();
223             this.el.add (  child_8.el  );
224         }
225
226         // user defined functions
227     }
228     public class Xcls_header : Object
229     {
230         public Gtk.HeaderBar el;
231         private Xcls_PopoverProperty  _this;
232
233
234             // my vars (def)
235
236         // ctor
237         public Xcls_header(Xcls_PopoverProperty _owner )
238         {
239             _this = _owner;
240             _this.header = this;
241             this.el = new Gtk.HeaderBar();
242
243             // my vars (dec)
244
245             // set gobject values
246             this.el.title = "Modify / Create Property";
247         }
248
249         // user defined functions
250     }
251
252     public class Xcls_Label4 : Object
253     {
254         public Gtk.Label el;
255         private Xcls_PopoverProperty  _this;
256
257
258             // my vars (def)
259
260         // ctor
261         public Xcls_Label4(Xcls_PopoverProperty _owner )
262         {
263             _this = _owner;
264             this.el = new Gtk.Label( "Special Flags" );
265
266             // my vars (dec)
267
268             // set gobject values
269             this.el.halign = Gtk.Align.START;
270             this.el.justify = Gtk.Justification.LEFT;
271             this.el.margin_top = 12;
272         }
273
274         // user defined functions
275     }
276
277     public class Xcls_kflag : Object
278     {
279         public Gtk.ComboBox el;
280         private Xcls_PopoverProperty  _this;
281
282
283             // my vars (def)
284
285         // ctor
286         public Xcls_kflag(Xcls_PopoverProperty _owner )
287         {
288             _this = _owner;
289             _this.kflag = this;
290             this.el = new Gtk.ComboBox();
291
292             // my vars (dec)
293
294             // set gobject values
295             var child_0 = new Xcls_dbcellrenderer( _this );
296             child_0.ref();
297             this.el.pack_start (  child_0.el , true );
298             var child_1 = new Xcls_dbmodel( _this );
299             child_1.ref();
300             this.el.set_model (  child_1.el  );
301
302             // init method
303
304             this.el.add_attribute(_this.dbcellrenderer.el , "markup", 1 );
305         }
306
307         // user defined functions
308     }
309     public class Xcls_dbcellrenderer : Object
310     {
311         public Gtk.CellRendererText el;
312         private Xcls_PopoverProperty  _this;
313
314
315             // my vars (def)
316
317         // ctor
318         public Xcls_dbcellrenderer(Xcls_PopoverProperty _owner )
319         {
320             _this = _owner;
321             _this.dbcellrenderer = this;
322             this.el = new Gtk.CellRendererText();
323
324             // my vars (dec)
325
326             // set gobject values
327         }
328
329         // user defined functions
330     }
331
332     public class Xcls_dbmodel : Object
333     {
334         public Gtk.ListStore el;
335         private Xcls_PopoverProperty  _this;
336
337
338             // my vars (def)
339
340         // ctor
341         public Xcls_dbmodel(Xcls_PopoverProperty _owner )
342         {
343             _this = _owner;
344             _this.dbmodel = this;
345             this.el = new Gtk.ListStore.newv(  { typeof(JsRender.NodePropType),typeof(string) }  );
346
347             // my vars (dec)
348
349             // set gobject values
350         }
351
352         // user defined functions
353         public void loadData (JsRender.NodeProp prop) {
354             this.el.clear();                                    
355             Gtk.TreeIter iter;
356             var el = this.el;
357             
358             
359             // vala signal.. '@'
360             // raw value '$'
361             // user defined property '#'
362             // user defined method '|'
363             // special property '*' => prop  |args|ctor|init
364             
365             
366             
367            /// el.append(out iter);
368             
369              
370            // el.set_value(iter, 0, "");
371            // el.set_value(iter, 1, "aaa  - Just add Element - aaa");
372         
373             
374                 if (prop.ptype == JsRender.NodePropType.LISTENER) { 
375                         el.append(out iter);
376                         el.set(iter, 0, JsRender.NodePropType.LISTENER, 1,   "Event Handler / Listener", -1);
377                 }        
378                 else if (_this.mainwindow.windowstate.file.xtype == "Gtk") {
379                          el.append(out iter);
380                     el.set(iter, 0, JsRender.NodePropType.PROP, 1,   "Normal Property", -1);
381                 
382                         
383                         el.append(out iter);
384                         el.set(iter, 0, JsRender.NodePropType.RAW, 1,   "Raw Property (not escaped)", -1);
385                          
386                         
387                         el.append(out iter);
388                         el.set(iter, 0, JsRender.NodePropType.USER, 1,   "User defined property", -1);
389                          
390                         el.append(out iter);
391                         el.set(iter, 0, JsRender.NodePropType.METHOD, 1,   "User defined method", -1);
392                          
393                         el.append(out iter);
394                         el.set(iter, 0, JsRender.NodePropType.SPECIAL, 1,   "Special property (eg. prop | args | ctor | init )", -1);
395                          
396                         
397                         el.append(out iter);
398                     el.set(iter, 0, JsRender.NodePropType.SIGNAL, 1,   "Vala Signal", -1);
399                          
400                         
401                 } else { 
402                         // javascript
403                     el.append(out iter);
404                     el.set(iter, 0, JsRender.NodePropType.PROP, 1,   "Normal Property", -1);
405                 
406                         el.append(out iter);
407                         el.set(iter, 0, JsRender.NodePropType.RAW, 1,   "Raw Property (not escaped)", -1);
408                         
409                         // we appear to still use this?!? (builderCfg?)
410                         el.append(out iter);
411                         el.set(iter, 0, JsRender.NodePropType.USER, 1,   "User defined property", -1);
412                         
413                         
414                         el.append(out iter);
415                         el.set(iter, 0, JsRender.NodePropType.METHOD, 1,   "User defined method", -1);
416                  
417                         el.append(out iter);
418                         el.set(iter, 0,  JsRender.NodePropType.SPECIAL, 1,   "(*) Special property (eg. prop )", -1);
419                          
420                 
421                 }
422                 // set selected, based on arg
423                 el.foreach((tm, tp, titer) => {
424                         GLib.Value val;
425                         el.get_value(titer, 0, out val);
426                          
427                         //print("check %s against %s\n", (string)val, _this.prop.ptype);
428                         if (((JsRender.NodePropType)val) == prop.ptype) {
429                                 _this.kflag.el.set_active_iter(titer);
430                                 return true;
431                         }
432                         return false;
433                 });
434                 
435         
436                                              
437         }
438     }
439
440
441     public class Xcls_Label8 : Object
442     {
443         public Gtk.Label el;
444         private Xcls_PopoverProperty  _this;
445
446
447             // my vars (def)
448
449         // ctor
450         public Xcls_Label8(Xcls_PopoverProperty _owner )
451         {
452             _this = _owner;
453             this.el = new Gtk.Label( "Type or Return Type" );
454
455             // my vars (dec)
456
457             // set gobject values
458             this.el.halign = Gtk.Align.START;
459             this.el.justify = Gtk.Justification.LEFT;
460             this.el.margin_top = 12;
461             this.el.visible = true;
462         }
463
464         // user defined functions
465     }
466
467     public class Xcls_ktype : Object
468     {
469         public Gtk.Entry el;
470         private Xcls_PopoverProperty  _this;
471
472
473             // my vars (def)
474
475         // ctor
476         public Xcls_ktype(Xcls_PopoverProperty _owner )
477         {
478             _this = _owner;
479             _this.ktype = this;
480             this.el = new Gtk.Entry();
481
482             // my vars (dec)
483
484             // set gobject values
485             this.el.visible = true;
486         }
487
488         // user defined functions
489     }
490
491     public class Xcls_Label10 : Object
492     {
493         public Gtk.Label el;
494         private Xcls_PopoverProperty  _this;
495
496
497             // my vars (def)
498
499         // ctor
500         public Xcls_Label10(Xcls_PopoverProperty _owner )
501         {
502             _this = _owner;
503             this.el = new Gtk.Label( "Name" );
504
505             // my vars (dec)
506
507             // set gobject values
508             this.el.halign = Gtk.Align.START;
509             this.el.justify = Gtk.Justification.LEFT;
510             this.el.tooltip_text = "center, north, south, east, west";
511             this.el.margin_top = 12;
512             this.el.visible = true;
513         }
514
515         // user defined functions
516     }
517
518     public class Xcls_kname : Object
519     {
520         public Gtk.Entry el;
521         private Xcls_PopoverProperty  _this;
522
523
524             // my vars (def)
525
526         // ctor
527         public Xcls_kname(Xcls_PopoverProperty _owner )
528         {
529             _this = _owner;
530             _this.kname = this;
531             this.el = new Gtk.Entry();
532
533             // my vars (dec)
534
535             // set gobject values
536             this.el.visible = true;
537
538             //listeners
539             this.el.focus_out_event.connect( ()=>{
540                 _this.error.setError("");
541                 var val = this.el.get_text().strip(); 
542                 if (val.length < 1) {
543                         _this.error.setError("Name can not be empty");
544                 }
545                 return true;
546             });
547             this.el.key_release_event.connect( ()=>{
548                 _this.error.setError("");
549                 var val = this.el.get_text().strip(); 
550                 if (val.length < 1) {
551                         _this.error.setError("Name can not be empty");
552                 }
553                 return true;
554             });
555         }
556
557         // user defined functions
558     }
559
560     public class Xcls_error : Object
561     {
562         public Gtk.Label el;
563         private Xcls_PopoverProperty  _this;
564
565
566             // my vars (def)
567
568         // ctor
569         public Xcls_error(Xcls_PopoverProperty _owner )
570         {
571             _this = _owner;
572             _this.error = this;
573             this.el = new Gtk.Label( "<span color=\"red\">Error Message</span>" );
574
575             // my vars (dec)
576
577             // set gobject values
578             this.el.halign = Gtk.Align.START;
579             this.el.justify = Gtk.Justification.LEFT;
580             this.el.tooltip_text = "center, north, south, east, west";
581             this.el.margin_top = 0;
582             this.el.visible = true;
583             this.el.use_markup = true;
584         }
585
586         // user defined functions
587         public void setError (string err)   {
588                 if (err == "") {
589                         this.el.hide();
590                 } else {
591                         this.el.show();
592                         
593                         this.el.label = "<span color=\"red\">" + err + "</span>";
594                 }
595         }
596     }
597
598     public class Xcls_buttonbar : Object
599     {
600         public Gtk.Box el;
601         private Xcls_PopoverProperty  _this;
602
603
604             // my vars (def)
605
606         // ctor
607         public Xcls_buttonbar(Xcls_PopoverProperty _owner )
608         {
609             _this = _owner;
610             _this.buttonbar = this;
611             this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
612
613             // my vars (dec)
614
615             // set gobject values
616             this.el.margin_top = 20;
617             var child_0 = new Xcls_Button14( _this );
618             child_0.ref();
619             this.el.add (  child_0.el  );
620             var child_1 = new Xcls_Button16( _this );
621             child_1.ref();
622             this.el.add (  child_1.el  );
623         }
624
625         // user defined functions
626     }
627     public class Xcls_Button14 : Object
628     {
629         public Gtk.Button el;
630         private Xcls_PopoverProperty  _this;
631
632
633             // my vars (def)
634
635         // ctor
636         public Xcls_Button14(Xcls_PopoverProperty _owner )
637         {
638             _this = _owner;
639             this.el = new Gtk.Button();
640
641             // my vars (dec)
642
643             // set gobject values
644             this.el.hexpand = true;
645             this.el.always_show_image = true;
646             this.el.label = "Cancel";
647             var child_0 = new Xcls_Image15( _this );
648             child_0.ref();
649             this.el.image = child_0.el;
650
651             //listeners
652             this.el.pressed.connect( () => { 
653             
654                 _this.prop = null;
655                 _this.is_new = false;
656                 _this.kname.el.set_text("Cancel");
657                 _this.el.hide();
658             
659             });
660         }
661
662         // user defined functions
663     }
664     public class Xcls_Image15 : Object
665     {
666         public Gtk.Image el;
667         private Xcls_PopoverProperty  _this;
668
669
670             // my vars (def)
671
672         // ctor
673         public Xcls_Image15(Xcls_PopoverProperty _owner )
674         {
675             _this = _owner;
676             this.el = new Gtk.Image();
677
678             // my vars (dec)
679
680             // set gobject values
681             this.el.icon_name = "window-close";
682         }
683
684         // user defined functions
685     }
686
687
688     public class Xcls_Button16 : Object
689     {
690         public Gtk.Button el;
691         private Xcls_PopoverProperty  _this;
692
693
694             // my vars (def)
695
696         // ctor
697         public Xcls_Button16(Xcls_PopoverProperty _owner )
698         {
699             _this = _owner;
700             this.el = new Gtk.Button();
701
702             // my vars (dec)
703
704             // set gobject values
705             this.el.hexpand = true;
706             this.el.always_show_image = true;
707             this.el.label = "Add Property";
708             var child_0 = new Xcls_Image17( _this );
709             child_0.ref();
710             this.el.image = child_0.el;
711
712             //listeners
713             this.el.pressed.connect( () => {
714                 // check if text is not empty..
715                 if ( _this.kname.el.get_text().strip().length < 1) {
716                         // error should already be showing?
717                         return;
718                 }
719                 _this.updateProp();
720                 
721                 // since we can't add listeners?!?!?
722                 // only check props.
723                 // check if property already exists in node.    
724                 var prop = _this.prop;
725                 if (_this.node.props.has_key(prop.to_index_key())) {
726                         _this.error.setError("Property already exists");
727                         return; 
728                 }
729                 
730                 
731                  
732                 _this.is_new = false;   
733                   
734                 // hide self
735                 _this.prop = null; // skip checks..
736                 _this.el.hide();
737             
738             // add it, 
739                 // trigger editing of property.
740                 // allow hide to work?
741                 while (Gtk.events_pending()) {
742                         Gtk.main_iteration();
743                 }
744                 
745                 _this.mainwindow.windowstate.left_props.addProp(prop);          
746                 
747             
748             });
749         }
750
751         // user defined functions
752     }
753     public class Xcls_Image17 : Object
754     {
755         public Gtk.Image el;
756         private Xcls_PopoverProperty  _this;
757
758
759             // my vars (def)
760
761         // ctor
762         public Xcls_Image17(Xcls_PopoverProperty _owner )
763         {
764             _this = _owner;
765             this.el = new Gtk.Image();
766
767             // my vars (dec)
768
769             // set gobject values
770             this.el.icon_name = "list-add";
771         }
772
773         // user defined functions
774     }
775
776
777
778
779 }