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