1 static Xcls_WindowLeftTree _WindowLeftTree;
3 public class Xcls_WindowLeftTree : Object
6 private Xcls_WindowLeftTree _this;
8 public static Xcls_WindowLeftTree singleton()
10 if (_WindowLeftTree == null) {
11 _WindowLeftTree= new Xcls_WindowLeftTree();
13 return _WindowLeftTree;
15 public Xcls_viewwin viewwin;
16 public Xcls_view view;
17 public Xcls_drop drop;
18 public Xcls_selmodel selmodel;
19 public Xcls_model model;
20 public Xcls_maincol maincol;
21 public Xcls_LeftTreeMenu LeftTreeMenu;
24 public signal bool before_node_change ();
25 public Xcls_MainWindow main_window;
26 public signal void changed ();
27 public signal void node_selected (JsRender.Node? node);
30 public Xcls_WindowLeftTree()
33 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
36 this.main_window = null;
39 this.el.hexpand = true;
40 this.el.vexpand = true;
41 var child_1 = new Xcls_ListView2( _this );
43 this.el.append( child_1.el );
44 new Xcls_viewwin( _this );
45 this.el.append( _this.viewwin.el );
48 // user defined functions
49 public void onresize () {
52 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
53 // _this.maincol.el.set_max_width( _this.viewwin.el.get_width() - 32 );
55 public JsRender.Node? getActiveElement () { // return path to actie node.
58 return _this.selmodel.getSelectedNode();
62 public JsRender.JsRender getActiveFile () {
63 return this.main_window.windowstate.file;
65 public class Xcls_ListView2 : Object
67 public Gtk.ListView el;
68 private Xcls_WindowLeftTree _this;
74 public Xcls_ListView2(Xcls_WindowLeftTree _owner )
77 var child_1 = new Xcls_SignalListItemFactory3( _this );
79 this.el = new Gtk.ListView( null, child_1.el );
86 // user defined functions
88 public class Xcls_SignalListItemFactory3 : Object
90 public Gtk.SignalListItemFactory el;
91 private Xcls_WindowLeftTree _this;
97 public Xcls_SignalListItemFactory3(Xcls_WindowLeftTree _owner )
100 this.el = new Gtk.SignalListItemFactory();
104 // set gobject values
107 // user defined functions
111 public class Xcls_viewwin : Object
113 public Gtk.ScrolledWindow el;
114 private Xcls_WindowLeftTree _this;
120 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
123 _this.viewwin = this;
124 this.el = new Gtk.ScrolledWindow();
128 // set gobject values
129 this.el.has_frame = true;
130 this.el.hexpand = true;
131 this.el.vexpand = true;
132 new Xcls_view( _this );
133 this.el.child = _this.view.el;
134 new Xcls_LeftTreeMenu( _this );
138 this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
141 // user defined functions
143 public class Xcls_view : Object
145 public Gtk.ColumnView el;
146 private Xcls_WindowLeftTree _this;
150 public bool blockChanges;
151 public bool headers_visible;
152 public string lastEventSource;
153 public bool button_is_pressed;
154 public Gtk.CssProvider css;
157 public Xcls_view(Xcls_WindowLeftTree _owner )
161 new Xcls_selmodel( _this );
162 this.el = new Gtk.ColumnView( _this.selmodel.el );
165 this.blockChanges = false;
166 this.headers_visible = false;
167 this.lastEventSource = "";
168 this.button_is_pressed = false;
170 // set gobject values
171 this.el.name = "left-tree-view";
172 this.el.hexpand = false;
173 this.el.vexpand = true;
174 var child_2 = new Xcls_GestureClick6( _this );
176 this.el.add_controller( child_2.el );
177 var child_3 = new Xcls_GestureClick7( _this );
179 this.el.add_controller( child_3.el );
180 var child_4 = new Xcls_DragSource8( _this );
182 this.el.add_controller( child_4.el );
183 var child_5 = new Xcls_EventControllerKey9( _this );
185 this.el.add_controller( child_5.el );
186 new Xcls_drop( _this );
187 this.el.add_controller( _this.drop.el );
188 new Xcls_maincol( _this );
189 this.el.append_column ( _this.maincol.el );
190 var child_8 = new Xcls_ColumnViewColumn15( _this );
192 this.el.append_column ( child_8.el );
198 this.css = new Gtk.CssProvider();
200 this.css.load_from_string("
201 #left-tree-view { font-size: 12px;}
202 .drag-over { background-color:#88a3bc; }
204 border-bottom-width: 5px;
205 border-bottom-style: solid;
206 border-bottom-color: #88a3bc;
209 border-top-width: 5px;
210 border-top-style: solid;
211 border-top-color: #88a3bc;
213 #left-tree-view indent {
214 -gtk-icon-size : 2px;
216 #left-tree-view indent:nth-last-child(2) {
221 Gtk.StyleContext.add_provider_for_display(
222 this.el.get_display(),
224 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
231 // user defined functions
232 public Gtk.Widget? getWidgetAtRow (uint row) {
235 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
236 var colview = gesture.widget;
237 var line_no = check_list_widget(colview, x,y);
239 var item = colview.model.get_item(line_no);
243 //GLib.debug("Get Widget At Row %d", (int)row);
244 var child = this.el.get_first_child();
246 var reading_header = true;
248 while (child != null) {
249 GLib.debug("Got %s", child.get_type().name());
251 if (reading_header) {
254 if (child.get_type().name() != "GtkColumnListView") {
256 child = child.get_next_sibling();
259 // should be columnlistview
260 child = child.get_first_child();
264 reading_header = false;
271 if (line_no == row) {
272 //GLib.debug("Returning widget %s", child.get_type().name());
273 return (Gtk.Widget)child;
275 child = child.get_next_sibling();
277 //GLib.debug("Rturning null");
281 public int getColAt (double x, double y) {
284 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
287 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
288 //GLib.debug("Cehck %d, %d", x,y);
289 var child = this.el.get_first_child();
293 while (child != null) {
295 if (child.get_type().name() == "GtkColumnViewRowWidget") {
296 child = child.get_first_child();
300 //child.get_allocation(out alloc);
301 if (x < (child.get_width() + offx)) {
305 //offx += child.get_width();
307 //child = child.get_next_sibling();
314 public int getRowAt (double x, double in_y, out string pos) {
321 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
322 var colview = gesture.widget;
323 var line_no = check_list_widget(colview, x,y);
325 var item = colview.model.get_item(line_no);
331 //GLib.debug("offset = %d y = %d", (int) voff, (int) in_y);
332 var y = in_y + _this.viewwin.el.vadjustment.value;
333 var child = this.el.get_first_child();
334 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
336 var reading_header = true;
338 var header_height = 0;
341 while (child != null) {
342 //GLib.debug("Got %s", child.get_type().name());
343 if (reading_header) {
346 if (child.get_type().name() != "GtkColumnListView") {
347 h += child.get_height();
348 child = child.get_next_sibling();
351 // should be columnlistview
352 child = child.get_first_child();
353 GLib.debug("header height=%d", h);
356 reading_header = false;
360 if (child.get_type().name() != "GtkColumnViewRowWidget") {
361 child = child.get_next_sibling();
365 if (y < header_height) {
370 var hh = child.get_height();
371 //child.get_allocation(out alloc);
372 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
373 //GLib.debug("row %d y= %d %s", line_no, (int) (header_height + alloc.y),
375 // child.visible ? "VIS" : "hidden");
377 if (y > (header_height + real_y) && y <= (header_height + real_y + hh) ) {
378 if (y > ( header_height + real_y + (hh * 0.8))) {
380 } else if (y > ( header_height + real_y + (hh * 0.2))) {
385 GLib.debug("getRowAt return : %d, %s", line_no, pos);
390 if (real_y + hh > y) {
394 child = child.get_next_sibling();
399 public Gtk.Widget? getWidgetAt (double x, double in_y) {
402 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
403 var colview = gesture.widget;
404 var line_no = check_list_widget(colview, x,y);
406 var item = colview.model.get_item(line_no);
410 var y = in_y + _this.viewwin.el.vadjustment.value;
411 var child = this.el.get_first_child();
412 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
414 var reading_header = true;
416 var header_height = 0;
418 while (child != null) {
419 //GLib.debug("Got %s", child.get_type().name());
420 if (reading_header) {
423 if (child.get_type().name() != "GtkColumnListView") {
424 h += child.get_height();
425 child = child.get_next_sibling();
428 // should be columnlistview
429 child = child.get_first_child();
430 GLib.debug("header height=%d", h);
433 reading_header = false;
438 if (y < header_height) {
442 var hh = child.get_height();
443 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
445 if (y > curr_y && y <= header_height + hh + curr_y ) {
446 return (Gtk.Widget)child;
453 child = child.get_next_sibling();
459 public class Xcls_GestureClick6 : Object
461 public Gtk.GestureClick el;
462 private Xcls_WindowLeftTree _this;
468 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
471 this.el = new Gtk.GestureClick();
475 // set gobject values
478 this.el.released.connect( (n_press, x, y) => {
480 _this.view.button_is_pressed = false;
484 this.el.pressed.connect( (n_press, x, y) => {
486 //console.log("button press?");
488 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
492 _this.view.button_is_pressed = true;
494 _this.view.lastEventSource = "tree";
495 if (! _this.before_node_change() ) {
496 GLib.debug("before_node_change return false");
500 // nothing there -show dialog
501 if (_this.model.el.get_n_items() < 1) {
502 _this.main_window.windowstate.showAddObject(_this.view.el, null);
503 GLib.debug("no items");
507 var row = _this.view.getRowAt(x,y, out pos );
509 GLib.debug("no row selected items");
513 var node = _this.selmodel.getNodeAt(row);
515 GLib.warning("No node found at row %d", row);
521 if (_this.view.getColAt(x,y) > 0 ) {
522 GLib.debug("add colum clicked.");
523 var fqn = node.fqn();
524 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
529 _this.main_window.windowstate.leftTreeBeforeChange();
530 //_this.view.el.get_selection().select_path(res);
531 GLib.debug("Button Pressed - start show window");
532 _this.main_window.windowstate.showAddObject(_this.view.el, node);
533 GLib.debug("Button Pressed - finsihed show window");
542 // user defined functions
545 public class Xcls_GestureClick7 : Object
547 public Gtk.GestureClick el;
548 private Xcls_WindowLeftTree _this;
554 public Xcls_GestureClick7(Xcls_WindowLeftTree _owner )
557 this.el = new Gtk.GestureClick();
561 // set gobject values
565 this.el.pressed.connect( (n_press, x, y) => {
570 if (_this.model.el.get_n_items() < 1) {
572 GLib.debug("no items");
576 var row = _this.view.getRowAt(x,y, out pos );
578 GLib.debug("no row selected items");
582 var node = _this.selmodel.getNodeAt(row);
584 GLib.warning("No node found at row %d", row);
587 _this.model.selectNode(node);
591 GLib.debug("Prssed %d", (int) this.el.get_current_button());
592 //_this.deletemenu.el.set_parent(_this.view.el);
593 _this.LeftTreeMenu.el.set_parent(_this.view.el);
596 //Gtk.Allocation rect;
597 //_this.view.el.get_allocation(out rect);
598 //_this.deletemenu.el.set_has_arrow(false);
599 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
602 _this.LeftTreeMenu.el.set_offset(
604 (int)y - (int)_this.view.el.get_height());
606 _this.LeftTreeMenu.el.popup();
611 // user defined functions
614 public class Xcls_DragSource8 : Object
616 public Gtk.DragSource el;
617 private Xcls_WindowLeftTree _this;
623 public Xcls_DragSource8(Xcls_WindowLeftTree _owner )
626 this.el = new Gtk.DragSource();
630 // set gobject values
631 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
634 this.el.prepare.connect( (x, y) => {
638 /// ( drag_context, data, info, time) => {
641 //print("drag-data-get");
642 var ndata = _this.selmodel.getSelectedNode();
644 GLib.debug("return empty string - no selection..");
650 //data.set_text(tp,tp.length);
652 var str = ndata.toJsonString();
653 GLib.debug("prepare store: %s", str);
654 GLib.Value ov = GLib.Value(typeof(string));
656 var cont = new Gdk.ContentProvider.for_value(ov);
658 GLib.Value v = GLib.Value(typeof(string));
659 //var str = drop.read_text( [ "text/plain" ] 0);
661 cont.get_value(ref v);
664 GLib.debug("set %s", v.get_string());
670 this.el.drag_begin.connect( ( drag ) => {
671 GLib.debug("SOURCE: drag-begin");
673 // find what is selected in our tree...
674 var data = _this.selmodel.getSelectedNode();
679 var xname = data.fqn();
680 GLib.debug ("XNAME IS %s", xname);
682 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
685 var paintable = new Gtk.WidgetPaintable(widget);
686 this.el.set_icon(paintable, 0,0);
692 // user defined functions
695 public class Xcls_EventControllerKey9 : Object
697 public Gtk.EventControllerKey el;
698 private Xcls_WindowLeftTree _this;
704 public Xcls_EventControllerKey9(Xcls_WindowLeftTree _owner )
707 this.el = new Gtk.EventControllerKey();
711 // set gobject values
714 this.el.key_pressed.connect( (keyval, keycode, state) => {
718 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
722 _this.model.deleteSelected();
728 // user defined functions
731 public class Xcls_drop : Object
733 public Gtk.DropTarget el;
734 private Xcls_WindowLeftTree _this;
738 public Gtk.Widget? highlightWidget;
739 public JsRender.Node? lastDragNode;
740 public string lastDragString;
743 public Xcls_drop(Xcls_WindowLeftTree _owner )
747 this.el = new Gtk.DropTarget ( typeof(string) ,
748 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
751 this.highlightWidget = null;
752 this.lastDragNode = null;
753 this.lastDragString = "";
755 // set gobject values
758 this.el.accept.connect( (drop) => {
760 GLib.debug("got DropTarget:accept");
762 // NOT REALLY NEEDED? = put stuff in drop?
765 /* ( ctx, x, y, time) => {
766 //Seed.print("TARGET: drag-drop");
769 var src = Gtk.drag_get_source_widget(ctx);
771 if (src != this.el) {
775 this.drag_in_motion = false;
776 // request data that will be recieved by the recieve...
779 this.el, // will receive 'drag-data-received' signal
780 ctx, // represents the current state of the DnD
781 Gdk.Atom.intern("application/json",true), // the target type we want
786 // No target offered by source => error
792 // handle drop around self..
796 //print("GETTING POS");
800 Gtk.TreeViewDropPosition pos;
801 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
803 // if there are not items in the tree.. the we have to set isOver to true for anything..
805 if (_this.model.el.iter_n_children(null) < 1) {
806 print("got NO children?\n");
809 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
814 //var action = Gdk.DragAction.COPY;
815 // unless we are copying!!! ctl button..
817 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
818 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
819 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
822 if (_this.model.el.iter_n_children(null) < 1) {
823 // no children.. -- asume it's ok..
825 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
827 // continue through to allow drop...
835 //print("ISOVER? " + isOver);
838 Gtk.drag_finish (ctx, false, false, time); // drop failed..
839 return true; // not over apoint!?! - no action on drop or motion..
842 // drag node is parent of child..
843 //console.log("SRC TREEPATH: " + src.treepath);
844 //console.log("TARGET TREEPATH: " + data.path.to_string());
846 // nned to check a few here..
847 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
848 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
849 //Gtk.TreeViewDropPosition.AFTER
850 //Gtk.TreeViewDropPosition.BEFORE
852 // locally dragged items to not really use the
853 var selection_text = this.dragData;
857 if (selection_text == null || selection_text.length < 1) {
858 //print("Error - drag selection text returned NULL");
860 Gtk.drag_finish (ctx, false, false, time); // drop failed..
861 return true; /// -- fixme -- this is not really correct..
864 // see if we are dragging into ourself?
865 print ("got selection text of " + selection_text);
867 var target_path = path.to_string();
868 //print("target_path="+target_path);
871 if (selection_text == target_path) {
872 print("self drag ?? == we should perhaps allow copy onto self..\n");
874 Gtk.drag_finish (ctx, false, false, time); // drop failed..
876 return true; /// -- fixme -- this is not really correct..
881 //print("DUMPING DATA");
882 //console.dump(data);
885 //print(data.path.to_string() +' => '+ data.pos);
887 // dropList is a list of xtypes that this node could be dropped on.
888 // it is set up when we start to drag..
891 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
893 print("targetDAta: " + targetData +"\n");
895 if (targetData.length < 1) {
896 //print("Can not find drop node path");
898 Gtk.drag_finish (ctx, false, false, time); // drop failed..
904 // continue on to allow drop..
906 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
909 var delete_selection_data = false;
911 if (action == Gdk.DragAction.ASK) {
912 // Ask the user to move or copy, then set the ctx action.
915 if (action == Gdk.DragAction.MOVE) {
916 delete_selection_data = true;
919 // drag around.. - reorder..
920 _this.model.moveNode(targetData, action);
926 // we can send stuff to souce here...
929 // do we always say failure, so we handle the reall drop?
930 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
943 this.el.motion.connect( ( x, y) => {
945 string pos; // over / before / after..
947 GLib.debug("got drag motion");
949 GLib.Value v = GLib.Value(typeof(string));
950 //var str = drop.read_text( [ "text/plain" ] 0);
951 var cont = this.el.current_drop.get_drag().content ;
953 cont.get_value(ref v);
954 } catch (GLib.Error e) {
955 GLib.debug("failed to get drag value");
956 return Gdk.DragAction.COPY;
960 GLib.debug("got %s", v.get_string());
962 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
963 // still dragging same node
965 this.lastDragNode = new JsRender.Node();
966 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
970 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
971 this.lastDragNode.fqn());
974 foreach(var dp in drop_on_to) {
977 GLib.debug("droplist: %s", string.joinv(", ", str));
980 // if there are not items in the tree.. the we have to set isOver to true for anything..
982 if (_this.model.el.n_items < 1) {
983 // FIXME check valid drop types?
984 if (drop_on_to.contains("*top")) {
985 this.addHighlight(_this.view.el, "over");
987 this.addHighlight(null, "");
990 return Gdk.DragAction.COPY; // no need to highlight?
995 GLib.debug("check is over");
997 // if path of source and dest are inside each other..
998 // need to add source info to drag?
1000 var row = _this.view.getRowAt(x,y, out pos);
1003 this.addHighlight(null, "");
1004 return Gdk.DragAction.COPY;
1006 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1008 var node = (JsRender.Node)tr.get_item();
1010 GLib.debug("Drop over node: %s", node.fqn());
1013 if (pos == "above" || pos == "below") {
1014 if (node.parent == null) {
1015 GLib.debug("no parent try center");
1019 if (!drop_on_to.contains(node.parent.fqn())) {
1020 GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1023 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1028 if (pos == "over") {
1029 if (!drop_on_to.contains(node.fqn())) {
1030 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1031 this.addHighlight(null, "");
1032 return Gdk.DragAction.COPY;
1037 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1038 var w = _this.view.getWidgetAt(x,y);
1039 this.addHighlight(w, pos);
1040 return Gdk.DragAction.COPY;
1042 this.el.leave.connect( ( ) => {
1043 this.addHighlight(null,"");
1046 this.el.drop.connect( (v, x, y) => {
1048 this.addHighlight(null,"");
1053 // -- get position..
1054 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1055 // still dragging same node
1057 this.lastDragNode = new JsRender.Node();
1058 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1063 var dropNode = new JsRender.Node();
1064 dropNode.loadFromJsonString(v.get_string(), 1);
1065 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1067 // if there are not items in the tree.. the we have to set isOver to true for anything..
1069 if (_this.model.el.n_items < 1) {
1070 // FIXME check valid drop types?
1071 if (!drop_on_to.contains("*top")) {
1072 GLib.debug("drop on to list does not contain top?");
1075 // add new node to top..
1078 var m = (GLib.ListStore) _this.model.el.model;
1079 _this.main_window.windowstate.file.tree = dropNode;
1083 _this.model.selectNode(dropNode);
1085 return true; // no need to highlight?
1091 var row = _this.view.getRowAt(x,y, out pos);
1093 return false; //Gdk.DragAction.COPY;
1095 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1097 var node = (JsRender.Node)tr.get_item();
1099 if (pos == "above" || pos == "below") {
1100 if (node.parent == null) {
1103 if (!drop_on_to.contains(node.parent.fqn())) {
1106 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1111 if (pos == "over") {
1112 if (!drop_on_to.contains(node.fqn())) {
1113 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1121 node.appendChild(dropNode);
1122 _this.model.selectNode(dropNode);
1127 GLib.debug("Above - insertBefore");
1129 node.parent.insertBefore(dropNode, node);
1130 _this.model.selectNode(dropNode);
1135 GLib.debug("Below - insertAfter");
1136 node.parent.insertAfter(dropNode, node);
1137 _this.model.selectNode(dropNode);
1143 // should not happen
1155 // user defined functions
1156 public void addHighlight (Gtk.Widget? w, string hl) {
1157 if (this.highlightWidget != null) {
1158 var ww = this.highlightWidget;
1159 GLib.debug("clear drag from previous highlight");
1160 if (ww.has_css_class("drag-below")) {
1161 ww.remove_css_class("drag-below");
1163 if (ww.has_css_class("drag-above")) {
1164 ww.remove_css_class("drag-above");
1166 if (ww.has_css_class("drag-over")) {
1167 ww.remove_css_class("drag-over");
1171 GLib.debug("add drag=%s to widget", hl);
1172 if (!w.has_css_class("drag-" + hl)) {
1173 w.add_css_class("drag-" + hl);
1176 this.highlightWidget = w;
1180 public class Xcls_selmodel : Object
1182 public Gtk.SingleSelection el;
1183 private Xcls_WindowLeftTree _this;
1189 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1192 _this.selmodel = this;
1193 new Xcls_model( _this );
1194 this.el = new Gtk.SingleSelection( _this.model.el );
1198 // set gobject values
1201 this.el.selection_changed.connect( (position, n_items) => {
1205 //if (!this.button_is_pressed && !this.key_is_pressed) {
1206 // then event was started by some other action
1207 // which should manually trigger all the events..
1208 // print("SKIPPING select - no button or key pressed\n");
1213 if (_this.view.blockChanges) { // probably not needed..
1214 GLib.debug("SKIPPING select - blockchanges set..");
1218 if (!_this.before_node_change( ) ) {
1219 _this.view.blockChanges = true;
1220 _this.selmodel.el.unselect_all();
1221 _this.view.blockChanges = false;
1225 if (_this.main_window.windowstate.file == null) {
1226 GLib.debug("SKIPPING select windowstate file is not set...");
1230 //var render = this.get('/LeftTree').getRenderer();
1231 GLib.debug("LEFT TREE -> view -> selection changed called");
1234 // -- it appears that the selection is not updated.
1235 // select the node...
1236 //_this.selmodel.el.set_selected(row);
1238 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1240 var snode = _this.selmodel.getSelectedNode();
1241 if (snode == null) {
1243 GLib.debug("selected rows < 1");
1244 //??this.model.load( false);
1245 _this.node_selected(null);
1253 GLib.debug ("calling left_tree.node_selected");
1254 _this.node_selected(snode);
1259 // no need to scroll. it's in the view as we clicked on it.
1260 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1266 // user defined functions
1267 public JsRender.Node? getSelectedNode () {
1268 if (this.el.selected_item == null) {
1271 var tr = (Gtk.TreeListRow)this.el.selected_item;
1272 return (JsRender.Node)tr.get_item();
1275 public JsRender.Node getNodeAt (uint row) {
1277 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1279 var a = tr.get_item();;
1280 GLib.debug("get_item (2) = %s", a.get_type().name());
1283 return (JsRender.Node)tr.get_item();
1287 public class Xcls_model : Object
1289 public Gtk.TreeListModel el;
1290 private Xcls_WindowLeftTree _this;
1296 public Xcls_model(Xcls_WindowLeftTree _owner )
1300 this.el = this.updateModel(null);
1304 // set gobject values
1307 // user defined functions
1308 public void loadFile (JsRender.JsRender f) {
1311 _this.drop.highlightWidget = null;
1313 var m = (GLib.ListStore) this.el.model;
1315 _this.main_window.windowstate.leftTreeNodeSelected(null);
1317 _this.main_window.windowstate.file = f;
1320 if (f.tree == null) {
1327 // if it's still null?
1328 if (f.tree == null) {
1329 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1337 if (f.tree.readItems().size < 1) {
1340 //this.get('/Window.leftvpaned').el.set_position(80);
1342 _this.view.el.set_cursor(
1343 new Gtk.TreePath.from_string("0"), null, false);
1347 //this.get('/Window.leftvpaned').el.set_position(200);
1353 //_this.maincol.el.set_max_width(_this.viewwin.el.get_allocated_width() - 32);
1355 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1361 public void deleteSelected () {
1365 var node = _this.selmodel.getSelectedNode();
1369 GLib.debug("delete Selected - no node slected?");
1372 _this.selmodel.el.unselect_all();
1375 GLib.debug("delete Selected - done");
1378 print("DELETE SELECTED?");
1379 //_this.view.blockChanges = true;
1380 print("GET SELECTION?");
1382 var s = _this.view.el.get_selection();
1384 print("GET SELECTED?");
1389 if (!s.get_selected(out mod, out iter)) {
1390 return; // nothing seleted..
1395 this.activePath= "";
1396 print("GET vnode value?");
1399 this.el.get_value(iter, 2, out value);
1400 var data = (JsRender.Node)(value.get_object());
1401 print("removing node from Render\n");
1402 if (data.parent == null) {
1403 _this.main_window.windowstate.file.tree = null;
1407 print("removing node from Tree\n");
1409 this.el.remove(ref iter);
1419 this.activePath= ""; // again!?!?
1420 //this.changed(null,true);
1424 _this.view.blockChanges = false;
1427 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1428 this.el = new Gtk.TreeListModel(
1429 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1433 return ((JsRender.Node)item).childstore;
1437 if (_this.selmodel.el == null) {
1440 _this.selmodel.el.set_model(this.el);
1443 public void selectNode (JsRender.Node node)
1446 var s = (Gtk.SingleSelection)_this.view.el.model;
1447 for (var i = 0; i < s.n_items; i++) {
1448 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1449 var lr = (Gtk.TreeListRow)s.get_item(i);
1450 GLib.debug("check node %s", lr.get_item().get_type().name());
1451 if (((JsRender.Node)lr.get_item()).oid == node.oid) {
1458 GLib.debug("Could not find node");
1461 GLib.debug("Select %d", row);
1462 s.set_selected(row);
1463 _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1464 //_this.node_selected(node);
1471 public class Xcls_maincol : Object
1473 public Gtk.ColumnViewColumn el;
1474 private Xcls_WindowLeftTree _this;
1480 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1483 _this.maincol = this;
1484 var child_1 = new Xcls_SignalListItemFactory14( _this );
1486 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1490 // set gobject values
1491 this.el.id = "maincol";
1492 this.el.expand = true;
1493 this.el.resizable = true;
1496 // user defined functions
1498 public class Xcls_SignalListItemFactory14 : Object
1500 public Gtk.SignalListItemFactory el;
1501 private Xcls_WindowLeftTree _this;
1507 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1510 this.el = new Gtk.SignalListItemFactory();
1514 // set gobject values
1517 this.el.setup.connect( (listitem) => {
1519 var expand = new Gtk.TreeExpander();
1521 expand.set_indent_for_depth(true);
1522 expand.set_indent_for_icon(true);
1523 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1524 var icon = new Gtk.Image();
1525 var lbl = new Gtk.Label("");
1526 lbl.use_markup = true;
1527 lbl.ellipsize = Pango.EllipsizeMode.END;
1529 icon.margin_end = 4;
1530 lbl.justify = Gtk.Justification.LEFT;
1533 // listitem.activatable = true; ??
1537 expand.set_child(hbox);
1538 ((Gtk.ListItem)listitem).set_child(expand);
1541 this.el.bind.connect( (listitem) => {
1542 GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1544 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1545 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1548 var hbox = (Gtk.Box) expand.child;
1551 var img = (Gtk.Image) hbox.get_first_child();
1552 var lbl = (Gtk.Label) img.get_next_sibling();
1554 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1555 var node = (JsRender.Node) lr.get_item();
1557 GLib.debug("node is %s", node.get_type().name());
1558 // was item (1) in old layout
1563 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1564 var clsname = node.fqn();
1566 var clsb = clsname.split(".");
1567 var sub = clsb.length > 1 ? clsb[1].down() : "";
1569 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1573 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1574 img.set_from_file(fn);
1577 img.set_from_paintable(
1579 "media-playback-stop", null, 16,1,
1580 Gtk.TextDirection.NONE, 0
1584 } catch (GLib.Error e) {}
1586 expand.set_hide_expander( !node.hasChildren() );
1587 expand.set_list_row(lr);
1589 node.bind_property("iconFilename",
1591 GLib.BindingFlags.SYNC_CREATE);
1593 node.bind_property("nodeTitleProp",
1595 GLib.BindingFlags.SYNC_CREATE);
1596 node.bind_property("nodeTipProp",
1597 lbl, "tooltip_markup",
1598 GLib.BindingFlags.SYNC_CREATE);
1604 // user defined functions
1608 public class Xcls_ColumnViewColumn15 : Object
1610 public Gtk.ColumnViewColumn el;
1611 private Xcls_WindowLeftTree _this;
1617 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1620 var child_1 = new Xcls_SignalListItemFactory16( _this );
1622 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1626 // set gobject values
1627 this.el.fixed_width = 25;
1630 // user defined functions
1632 public class Xcls_SignalListItemFactory16 : Object
1634 public Gtk.SignalListItemFactory el;
1635 private Xcls_WindowLeftTree _this;
1641 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1644 this.el = new Gtk.SignalListItemFactory();
1648 // set gobject values
1651 this.el.setup.connect( (listitem) => {
1654 var icon = new Gtk.Image();
1656 ((Gtk.ListItem)listitem).set_child(icon);
1658 this.el.bind.connect( (listitem) => {
1660 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1661 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1662 var node = (JsRender.Node) lr.get_item();
1665 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1666 img.set_from_paintable(
1668 "list-add", null, 16,1,
1669 Gtk.TextDirection.NONE, 0
1673 var fqn = node.fqn();
1674 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1676 img.set_visible(cn.size > 0 ? true : false);
1681 // user defined functions
1686 public class Xcls_LeftTreeMenu : Object
1688 public Gtk.Popover el;
1689 private Xcls_WindowLeftTree _this;
1695 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1698 _this.LeftTreeMenu = this;
1699 this.el = new Gtk.Popover();
1703 // set gobject values
1704 var child_1 = new Xcls_Box18( _this );
1705 this.el.child = child_1.el;
1708 // user defined functions
1710 public class Xcls_Box18 : Object
1713 private Xcls_WindowLeftTree _this;
1719 public Xcls_Box18(Xcls_WindowLeftTree _owner )
1722 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1726 // set gobject values
1727 var child_1 = new Xcls_Button19( _this );
1729 this.el.append( child_1.el );
1730 var child_2 = new Xcls_Button20( _this );
1732 this.el.append( child_2.el );
1733 var child_3 = new Xcls_Button21( _this );
1735 this.el.append( child_3.el );
1738 // user defined functions
1740 public class Xcls_Button19 : Object
1742 public Gtk.Button el;
1743 private Xcls_WindowLeftTree _this;
1749 public Xcls_Button19(Xcls_WindowLeftTree _owner )
1752 this.el = new Gtk.Button();
1756 // set gobject values
1757 this.el.label = "Delete Element";
1760 this.el.clicked.connect( ( ) => {
1761 _this.LeftTreeMenu.el.hide();
1762 _this.model.deleteSelected();
1767 // user defined functions
1770 public class Xcls_Button20 : Object
1772 public Gtk.Button el;
1773 private Xcls_WindowLeftTree _this;
1779 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1782 this.el = new Gtk.Button();
1786 // set gobject values
1787 this.el.label = "Save as Template";
1790 this.el.clicked.connect( () => {
1791 _this.LeftTreeMenu.el.hide();
1792 DialogSaveTemplate.singleton().showIt(
1793 (Gtk.Window) _this.el.get_root (),
1794 _this.main_window.windowstate.file.palete(),
1795 _this.getActiveElement()
1802 // user defined functions
1805 public class Xcls_Button21 : Object
1807 public Gtk.Button el;
1808 private Xcls_WindowLeftTree _this;
1814 public Xcls_Button21(Xcls_WindowLeftTree _owner )
1817 this.el = new Gtk.Button();
1821 // set gobject values
1822 this.el.label = "Save as Module";
1825 this.el.clicked.connect( () => {
1827 _this.LeftTreeMenu.el.hide();
1828 var node = _this.getActiveElement();
1831 var sm = DialogSaveModule.singleton();
1835 (Gtk.Window) _this.el.get_root (),
1836 _this.main_window.windowstate.project,
1840 gtk4 migration - disabled this part.. probably not used muchanyway
1843 if (name.length < 1) {
1847 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
1851 var s = _this.view.el.get_selection();
1853 print("GET SELECTED?");
1858 if (!s.get_selected(out mod, out iter)) {
1859 return; // nothing seleted..
1862 var n_cn = mod.iter_n_children(iter) -1;
1863 for (var i = n_cn; i > -1; i--) {
1864 mod.iter_nth_child(out citer, iter, i);
1867 print("removing node from Tree\n");
1869 _this.model.el.remove(ref citer);
1872 _this.node_selected(node, "tree");
1878 // user defined functions