8de09234b991e37dc8b26c17bde460f3ab7965ff
[roobuilder] / src / Builder4 / PopoverAddObject.vala
1     static Xcls_PopoverAddObject  _PopoverAddObject;
2
3     public class Xcls_PopoverAddObject : Object
4     {
5         public Gtk.Popover el;
6         private Xcls_PopoverAddObject  _this;
7
8         public static Xcls_PopoverAddObject singleton()
9         {
10             if (_PopoverAddObject == null) {
11                 _PopoverAddObject= new Xcls_PopoverAddObject();
12             }
13             return _PopoverAddObject;
14         }
15         public Xcls_viewwin viewwin;
16         public Xcls_view view;
17         public Xcls_selmodel selmodel;
18         public Xcls_model model;
19         public Xcls_maincol maincol;
20
21             // my vars (def)
22         public signal void before_node_change (JsRender.Node? node);
23         public bool modal;
24         public signal void after_node_change (JsRender.Node? node);
25         public bool active;
26         public Xcls_MainWindow mainwindow;
27
28         // ctor
29         public Xcls_PopoverAddObject()
30         {
31             _this = this;
32             this.el = new Gtk.Popover();
33
34             // my vars (dec)
35             this.modal = true;
36             this.active = false;
37
38             // set gobject values
39             this.el.width_request = 900;
40             this.el.height_request = 800;
41             this.el.hexpand = false;
42             this.el.position = Gtk.PositionType.RIGHT;
43             new Xcls_viewwin( _this );
44             this.el.set_child ( _this.viewwin.el  );
45         }
46
47         // user defined functions
48         public void a_clear () {
49             var m = (GLib.ListStore) _this.model.el.model;
50                 m.remove_all();
51         
52                 
53         
54         }
55         public void show (Palete.Palete pal, string cls,  Gtk.Widget onbtn) {
56         
57              
58         
59             var tr = pal.getChildList(cls, false);
60             var m = (GLib.ListStore) _this.model.el.model;
61                 m.remove_all();
62         
63                 
64                 // new version will not support properties here..
65                 // they will be part of the properties, clicking will add a node..
66                 // will change the return list above eventually?
67                 
68          
69                 foreach (var dname in tr) {
70                          
71         
72                         GLib.debug("add to model: %s", dname);          
73                         m.append(pal.fqnToNode(dname));
74                 }
75                  m.sort( (a, b) => {
76         
77                                 return Posix.strcmp( ((JsRender.Node)a).fqn(),  ((JsRender.Node)b).fqn());
78                                 
79                         });
80                  
81             
82             var win = this.mainwindow.el;
83             //var  w = win.get_width();
84             var h = win.get_height();
85         
86             
87             // left tree = 250, editor area = 500?
88             
89             // min 450?
90                 // max hieght ...
91             this.el.set_size_request( 350, h); // full height?
92         
93               this.el.set_parent(onbtn);
94         
95             //if (this.el.relative_to == null) {
96                 //Gtk.Allocation rect;
97                 //onbtn.get_allocation(out rect);
98               //  this.el.set_pointing_to(rect);
99             //}
100             this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
101             this.el.show();
102            
103         }
104         public void hide () {
105          
106                 this.el.hide();
107         }
108         public class Xcls_viewwin : Object
109         {
110             public Gtk.ScrolledWindow el;
111             private Xcls_PopoverAddObject  _this;
112
113
114                 // my vars (def)
115
116             // ctor
117             public Xcls_viewwin(Xcls_PopoverAddObject _owner )
118             {
119                 _this = _owner;
120                 _this.viewwin = this;
121                 this.el = new Gtk.ScrolledWindow();
122
123                 // my vars (dec)
124
125                 // set gobject values
126                 new Xcls_view( _this );
127                 this.el.set_child ( _this.view.el  );
128
129                 // init method
130
131                 this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
132                    this.el.set_size_request(-1,200);
133             }
134
135             // user defined functions
136         }
137         public class Xcls_view : Object
138         {
139             public Gtk.ColumnView el;
140             private Xcls_PopoverAddObject  _this;
141
142
143                 // my vars (def)
144
145             // ctor
146             public Xcls_view(Xcls_PopoverAddObject _owner )
147             {
148                 _this = _owner;
149                 _this.view = this;
150                 new Xcls_selmodel( _this );
151                 this.el = new Gtk.ColumnView( _this.selmodel.el );
152
153                 // my vars (dec)
154
155                 // set gobject values
156                 this.el.hexpand = true;
157                 this.el.vexpand = true;
158                 var child_2 = new Xcls_DragSource4( _this );
159                 child_2.ref();
160                 this.el.add_controller(  child_2.el );
161                 new Xcls_maincol( _this );
162                 this.el.append_column ( _this.maincol.el  );
163                 var child_4 = new Xcls_GestureClick9( _this );
164                 child_4.ref();
165                 this.el.add_controller(  child_4.el );
166             }
167
168             // user defined functions
169             public Gtk.Widget? getWidgetAtRow (uint row) {
170             /*
171             // ?? could be done with model?
172                         
173             from        https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
174                         var colview = gesture.widget;
175                         var line_no = check_list_widget(colview, x,y);
176                      if (line_no > -1) {
177                                 var item = colview.model.get_item(line_no);
178                                  
179                         }
180                         */
181                         GLib.debug("Get Widget At Row %d", (int)row);
182                     var  child = this.el.get_first_child(); 
183                         var line_no = -1; 
184                         var reading_header = true;
185             
186                         while (child != null) {
187                                 GLib.debug("Got %s", child.get_type().name());
188                             if (reading_header) {
189                                  
190                                    
191                                         if (child.get_type().name() != "GtkColumnListView") {
192                                                 child = child.get_next_sibling();
193                                                 continue;
194                                         }
195                                         child = child.get_first_child(); 
196                                         reading_header = false;
197                         }
198                             if (child.get_type().name() != "GtkColumnViewRowWidget") {
199                                     child = child.get_next_sibling();
200                                     continue;
201                             }
202                             line_no++;
203                                 if (line_no == row) {
204                                         GLib.debug("Returning widget %s", child.get_type().name());
205                                     return (Gtk.Widget)child;
206                             }
207                         child = child.get_next_sibling(); 
208                         }
209                         GLib.debug("Rturning null");
210                     return null;
211             
212              }
213             public int getRowAt (double x,  double in_y, out string pos) {
214             
215             
216                  
217             
218             /*
219                         
220             from        https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
221                         var colview = gesture.widget;
222                         var line_no = check_list_widget(colview, x,y);
223                      if (line_no > -1) {
224                                 var item = colview.model.get_item(line_no);
225                                  
226                         }
227                         */
228                          
229                         
230                         //GLib.debug("offset = %d  y = %d", (int) voff, (int) in_y);
231                         var y = in_y + _this.viewwin.el.vadjustment.value; 
232                     var  child = this.el.get_first_child(); 
233                         //Gtk.Allocation alloc = { 0, 0, 0, 0 };
234                         var line_no = -1; 
235                         var reading_header = true;
236                         var real_y = 0;
237                         var header_height  = 0;
238                         pos = "none";
239                         var h = 0;
240                         while (child != null) {
241                                 //GLib.debug("Got %s", child.get_type().name());
242                             if (reading_header) {
243                                         
244             
245                                         if (child.get_type().name() != "GtkColumnListView") {
246                                         h += child.get_height();
247                                                 child = child.get_next_sibling();
248                                                 continue;
249                                         }
250                                         // should be columnlistview
251                                         child = child.get_first_child(); 
252                                     GLib.debug("header height=%d", h);
253                                         header_height =  h;
254                                         
255                                         reading_header = false;
256                                         
257                         }
258                         
259                             if (child.get_type().name() != "GtkColumnViewRowWidget") {
260                                     child = child.get_next_sibling();
261                                     continue;
262                             }
263                             
264                                 if (y < header_height) {
265                                 return -1;
266                         }
267                             
268                             line_no++;
269                                 var hh = child.get_height();
270                                 //child.get_allocation(out alloc);
271                                 //GLib.debug("got cell xy = %d,%d  w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
272                                 //GLib.debug("row %d y= %d %s", line_no, (int) (header_height + alloc.y),
273                                 
274                                 //      child.visible ? "VIS" : "hidden");
275             
276                             if (y >  (header_height + real_y) && y <= (header_height +  real_y + hh) ) {
277                                 if (y > ( header_height + real_y + (hh * 0.8))) {
278                                         pos = "below";
279                                 } else if (y > ( header_height + real_y + (hh * 0.2))) {
280                                         pos = "over";
281                                         } else {
282                                                 pos = "above";
283                                         }
284                                  GLib.debug("getRowAt return : %d, %s", line_no, pos);
285                                     return line_no;
286                             }
287              
288             
289                             if (real_y + hh > y) {
290                                 return -1;
291                         }
292                         real_y += hh;
293                         child = child.get_next_sibling(); 
294                         }
295                     return -1;
296             
297              }
298             public Gtk.Widget? getWidgetAt (double x,  double in_y) {
299             /*
300                         
301             from        https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
302                         var colview = gesture.widget;
303                         var line_no = check_list_widget(colview, x,y);
304                      if (line_no > -1) {
305                                 var item = colview.model.get_item(line_no);
306                                  
307                         }
308                         */
309                         var y = in_y + _this.viewwin.el.vadjustment.value; 
310                     var  child = this.el.get_first_child(); 
311                         //Gtk.Allocation alloc = { 0, 0, 0, 0 };
312                         var line_no = -1; 
313                         var reading_header = true;
314                         var curr_y = 0;
315                         var header_height  = 0;
316                         var h = 0;
317                         while (child != null) {
318                                 //GLib.debug("Got %s", child.get_type().name());
319                         if (reading_header) {
320                                         
321             
322                                         if (child.get_type().name() != "GtkColumnListView") {
323                                         h += child.get_height();
324                                                 child = child.get_next_sibling();
325                                                 continue;
326                                         }
327                                         // should be columnlistview
328                                         child = child.get_first_child(); 
329                                     GLib.debug("header height=%d", h);
330                                         header_height =  h;
331                                         
332                                         reading_header = false;
333                                         
334                         }
335                             line_no++;
336             
337                                 if (y < header_height) {
338                                 return null;
339                         }
340             
341                                 var hh = child.get_height();
342                                 //GLib.debug("got cell xy = %d,%d  w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
343             
344                             if (y > curr_y && y <= header_height + hh + curr_y ) {
345                                     return (Gtk.Widget)child;
346                             }
347                             curr_y +=  hh ;
348             
349                             if (curr_y > y) {
350                                 return null;
351                         }
352                         child = child.get_next_sibling(); 
353                         }
354                     return null;
355             
356              }
357         }
358         public class Xcls_DragSource4 : Object
359         {
360             public Gtk.DragSource el;
361             private Xcls_PopoverAddObject  _this;
362
363
364                 // my vars (def)
365
366             // ctor
367             public Xcls_DragSource4(Xcls_PopoverAddObject _owner )
368             {
369                 _this = _owner;
370                 this.el = new Gtk.DragSource();
371
372                 // my vars (dec)
373
374                 // set gobject values
375                 this.el.actions = Gdk.DragAction.COPY   | Gdk.DragAction.MOVE   ;
376
377                 //listeners
378                 this.el.prepare.connect( (x, y) => {
379                 
380                         
381                         
382                 ///     ( drag_context, data, info, time) => {
383                             
384                 
385                         //print("drag-data-get");
386                         var ndata = _this.selmodel.getSelectedNode();
387                         if (ndata == null) {
388                                 GLib.debug("return empty string - no selection..");
389                                 return null;
390                          
391                         }
392                 
393                   
394                         //data.set_text(tp,tp.length);   
395                 
396                         var     str = ndata.toJsonString();
397                         GLib.debug("prepare  store: %s", str);
398                         GLib.Value ov = GLib.Value(typeof(string));
399                         ov.set_string(str);
400                         var cont = new Gdk.ContentProvider.for_value(ov);
401                     
402                         //GLib.Value v = GLib.Value(typeof(string));
403                         //var str = drop.read_text( [ "text/plain" ] 0);
404                          
405                         //cont.get_value(ref v);
406                         //GLib.debug("set %s", v.get_string());
407                         
408                         return cont;
409                           
410                 });
411                 this.el.drag_begin.connect( ( drag )  => {
412                         GLib.debug("SOURCE: drag-begin");
413                          
414                     // find what is selected in our tree...
415                    var data = _this.selmodel.getSelectedNode();
416                         if (data == null) {
417                                 return  ;
418                         }
419                          
420                     var xname = data.fqn();
421                     GLib.debug ("XNAME  IS %s", xname);
422                 
423                         var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
424                         
425                         
426                     var paintable = new Gtk.WidgetPaintable(widget);
427                     this.el.set_icon(paintable, 0,0);
428                             
429                  
430                 });
431                 this.el.drag_end.connect( (drag, delete_data) => {
432                         _this.hide();
433                 
434                 });
435             }
436
437             // user defined functions
438         }
439
440         public class Xcls_selmodel : Object
441         {
442             public Gtk.SingleSelection el;
443             private Xcls_PopoverAddObject  _this;
444
445
446                 // my vars (def)
447
448             // ctor
449             public Xcls_selmodel(Xcls_PopoverAddObject _owner )
450             {
451                 _this = _owner;
452                 _this.selmodel = this;
453                 new Xcls_model( _this );
454                 this.el = new Gtk.SingleSelection( _this.model.el );
455
456                 // my vars (dec)
457
458                 // set gobject values
459             }
460
461             // user defined functions
462             public JsRender.Node? getSelectedNode () {
463               if (this.el.selected_item == null) {
464                         return null;
465               }                         
466                var tr = (Gtk.TreeListRow)this.el.selected_item;
467                return (JsRender.Node)tr.get_item();
468                  
469             }
470             public JsRender.Node getNodeAt (uint row) {
471             
472                var tr = (Gtk.TreeListRow)this.el.get_item(row);
473                
474                var a = tr.get_item();;   
475                GLib.debug("get_item (2) = %s", a.get_type().name());
476                 
477                return (JsRender.Node)tr.get_item();
478                  
479             }
480         }
481         public class Xcls_model : Object
482         {
483             public Gtk.TreeListModel el;
484             private Xcls_PopoverAddObject  _this;
485
486
487                 // my vars (def)
488
489             // ctor
490             public Xcls_model(Xcls_PopoverAddObject _owner )
491             {
492                 _this = _owner;
493                 _this.model = this;
494                 this.el = new Gtk.TreeListModel(
495     new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
496     false, // passthru
497     true, // autexpand
498     (item) => {
499         return ((JsRender.Node)item).childstore;
500     
501     }
502     
503     
504 );
505
506                 // my vars (dec)
507
508                 // set gobject values
509             }
510
511             // user defined functions
512         }
513
514
515         public class Xcls_maincol : Object
516         {
517             public Gtk.ColumnViewColumn el;
518             private Xcls_PopoverAddObject  _this;
519
520
521                 // my vars (def)
522
523             // ctor
524             public Xcls_maincol(Xcls_PopoverAddObject _owner )
525             {
526                 _this = _owner;
527                 _this.maincol = this;
528                 var child_1 = new Xcls_SignalListItemFactory8( _this );
529                 child_1.ref();
530                 this.el = new Gtk.ColumnViewColumn( "Drag to add Object", child_1.el );
531
532                 // my vars (dec)
533
534                 // set gobject values
535                 this.el.id = "maincol";
536                 this.el.expand = true;
537             }
538
539             // user defined functions
540         }
541         public class Xcls_SignalListItemFactory8 : Object
542         {
543             public Gtk.SignalListItemFactory el;
544             private Xcls_PopoverAddObject  _this;
545
546
547                 // my vars (def)
548
549             // ctor
550             public Xcls_SignalListItemFactory8(Xcls_PopoverAddObject _owner )
551             {
552                 _this = _owner;
553                 this.el = new Gtk.SignalListItemFactory();
554
555                 // my vars (dec)
556
557                 // set gobject values
558
559                 //listeners
560                 this.el.setup.connect( (listitem) => {
561                         
562                  
563                         var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
564                         var icon = new Gtk.Image();
565                         var lbl = new Gtk.Label("");
566                         lbl.use_markup = true;
567                         
568                         
569                         lbl.justify = Gtk.Justification.LEFT;
570                         lbl.xalign = 0;
571                         lbl.margin_start = 4;
572                 //      listitem.activatable = true; ??
573                         
574                         hbox.append(icon);
575                         hbox.append(lbl);
576                          
577                         ((Gtk.ListItem)listitem).set_child(hbox);
578                          
579                 });
580                 this.el.bind.connect( (listitem) => {
581                          //GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
582                         
583                         //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
584                  
585                          
586                         var hbox = (Gtk.Box)  ((Gtk.ListItem)listitem).get_child();
587                  
588                  
589                         
590                         var img = (Gtk.Image) hbox.get_first_child();
591                         var lbl = (Gtk.Label) img.get_next_sibling();
592                         
593                         var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
594                         
595                         
596                         
597                         var node = (JsRender.Node) lr.get_item();
598                         
599                    GLib.debug("node is %s", node.get_type().name());
600                    GLib.debug("lbl is %s", lbl.get_type().name());
601                    GLib.debug("node fqn %s", node.fqn());
602                 // was item (1) in old layout
603                 
604                          
605                         img.file = node.iconFilename;
606                         lbl.label =  node.fqn();
607                 //      lbl.tooltip_markup = node.nodeTip();
608                  
609                   
610                         // bind image...
611                         
612                 });
613             }
614
615             // user defined functions
616         }
617
618
619         public class Xcls_GestureClick9 : Object
620         {
621             public Gtk.GestureClick el;
622             private Xcls_PopoverAddObject  _this;
623
624
625                 // my vars (def)
626
627             // ctor
628             public Xcls_GestureClick9(Xcls_PopoverAddObject _owner )
629             {
630                 _this = _owner;
631                 this.el = new Gtk.GestureClick();
632
633                 // my vars (dec)
634
635                 // set gobject values
636
637                 //listeners
638                 this.el.pressed.connect( (n_press, x, y) => {
639                         if (n_press < 2) { /// doubleclick?
640                                 return;
641                         }
642                         //var pos = "";
643                         // find left tree selected node
644                         var addto = _this.mainwindow.windowstate.left_tree.selmodel.getSelectedNode();
645                         //var row = _this.view.getRowAt(x,y, out pos);
646                         
647                          var add = _this.selmodel.getSelectedNode().deepClone();
648                         addto.appendChild(add);
649                         _this.mainwindow.windowstate.left_props.changed();
650                         _this.mainwindow.windowstate.left_tree.model.selectNode(add);
651                 });
652             }
653
654             // user defined functions
655         }
656
657
658
659     }