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_keystate keystate;
18 public Xcls_drop drop;
19 public Xcls_selmodel selmodel;
20 public Xcls_model model;
21 public Xcls_maincol maincol;
22 public Xcls_LeftTreeMenu LeftTreeMenu;
25 public signal bool before_node_change ();
26 public Xcls_MainWindow? main_window;
27 public int last_error_counter;
28 public signal void changed ();
29 public signal void node_selected (JsRender.Node? node);
30 public Gee.ArrayList<Gtk.Widget>? error_widgets;
33 public Xcls_WindowLeftTree()
36 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
39 this.main_window = null;
40 this.last_error_counter = -1;
41 this.error_widgets = null;
44 this.el.hexpand = true;
45 this.el.vexpand = true;
46 var child_1 = new Xcls_ListView1( _this );
48 this.el.append( child_1.el );
49 new Xcls_viewwin( _this );
50 this.el.append( _this.viewwin.el );
53 // user defined functions
54 public void updateErrors () {
55 var file = this.getActiveFile();
60 var ar = file.getErrors();
61 if (ar == null || ar.size < 1) {
62 if (this.last_error_counter != file.error_counter) {
66 this.last_error_counter = file.error_counter ;
70 if (this.last_error_counter == file.error_counter) {
74 this.error_widgets = new Gee.ArrayList<Gtk.Widget>();
75 foreach(var diag in ar) {
78 // print("get inter\n");
79 var node= file.lineToNode( (int)diag.range.start.line) ;
83 var row = _this.model.nodeToRow(node);
87 var w = this.view.getWidgetAtRow(row);
91 this.error_widgets.add(w);
92 // always show errors.
93 var ed = diag.category.down();
94 if (ed != "err" && w.has_css_class("node-err")) {
97 if (ed == "err" && w.has_css_class("node-warn")) {
98 w.remove_css_class("node-warn");
100 if (ed == "err" && w.has_css_class("node-depr")) {
101 w.remove_css_class("node-depr");
103 if (!w.has_css_class("node-"+ ed)) {
104 w.add_css_class("node-" + ed);
110 public void onresize () {
113 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
114 // _this.maincol.el.set_max_width( _this.viewwin.el.get_width() - 32 );
116 public void removeErrors () {
117 if (this.error_widgets == null || this.error_widgets.size < 1) {
120 foreach(var child in this.error_widgets) {
122 if (child.has_css_class("node-err")) {
123 child.remove_css_class("node-err");
125 if (child.has_css_class("node-warn")) {
126 child.remove_css_class("node-warn");
129 if (child.has_css_class("node-depr")) {
130 child.remove_css_class("node-depr");
133 this.error_widgets = null;
137 var child = this.view.el.get_first_child();
139 var reading_header = true;
141 while (child != null) {
142 //GLib.debug("Got %s", child.get_type().name());
144 if (reading_header) {
147 if (child.get_type().name() != "GtkColumnListView") {
149 child = child.get_next_sibling();
152 // should be columnlistview
153 child = child.get_first_child();
157 reading_header = false;
161 if (child.has_css_class("node-err")) {
162 child.remove_css_class("node-err");
164 if (child.has_css_class("node-warn")) {
165 child.remove_css_class("node-warn");
168 if (child.has_css_class("node-depr")) {
169 child.remove_css_class("node-depr");
172 child = child.get_next_sibling();
174 //GLib.debug("Rturning null");
178 public JsRender.Node? getActiveElement () { // return path to actie node.
181 return _this.selmodel.getSelectedNode();
185 public JsRender.JsRender getActiveFile () {
186 return this.main_window.windowstate.file;
189 public class Xcls_ListView1 : Object
191 public Gtk.ListView el;
192 private Xcls_WindowLeftTree _this;
198 public Xcls_ListView1(Xcls_WindowLeftTree _owner )
201 var child_1 = new Xcls_SignalListItemFactory2( _this );
203 this.el = new Gtk.ListView( null, child_1.el );
207 // set gobject values
210 // user defined functions
212 public class Xcls_SignalListItemFactory2 : Object
214 public Gtk.SignalListItemFactory el;
215 private Xcls_WindowLeftTree _this;
221 public Xcls_SignalListItemFactory2(Xcls_WindowLeftTree _owner )
224 this.el = new Gtk.SignalListItemFactory();
228 // set gobject values
231 // user defined functions
235 public class Xcls_viewwin : Object
237 public Gtk.ScrolledWindow el;
238 private Xcls_WindowLeftTree _this;
244 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
247 _this.viewwin = this;
248 this.el = new Gtk.ScrolledWindow();
252 // set gobject values
253 this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
254 this.el.has_frame = true;
255 this.el.hexpand = true;
256 this.el.vexpand = true;
257 this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
258 new Xcls_view( _this );
259 this.el.child = _this.view.el;
260 new Xcls_LeftTreeMenu( _this );
263 // user defined functions
265 public class Xcls_view : Object
267 public Gtk.ColumnView el;
268 private Xcls_WindowLeftTree _this;
272 public bool blockChanges;
273 public bool headers_visible;
274 public string lastEventSource;
275 public bool button_is_pressed;
276 public Gtk.CssProvider css;
277 public JsRender.Node? dragNode;
280 public Xcls_view(Xcls_WindowLeftTree _owner )
284 new Xcls_selmodel( _this );
285 this.el = new Gtk.ColumnView( _this.selmodel.el );
288 this.blockChanges = false;
289 this.headers_visible = false;
290 this.lastEventSource = "";
291 this.button_is_pressed = false;
292 this.dragNode = null;
294 // set gobject values
295 this.el.name = "left-tree-view";
296 this.el.hexpand = false;
297 this.el.vexpand = true;
298 var child_2 = new Xcls_GestureClick5( _this );
300 this.el.add_controller( child_2.el );
301 var child_3 = new Xcls_GestureClick6( _this );
303 this.el.add_controller( child_3.el );
304 var child_4 = new Xcls_DragSource7( _this );
306 this.el.add_controller( child_4.el );
307 var child_5 = new Xcls_EventControllerKey8( _this );
309 this.el.add_controller( child_5.el );
310 new Xcls_keystate( _this );
311 this.el.add_controller( _this.keystate.el );
312 new Xcls_drop( _this );
313 this.el.add_controller( _this.drop.el );
314 new Xcls_maincol( _this );
315 this.el.append_column ( _this.maincol.el );
316 var child_9 = new Xcls_ColumnViewColumn15( _this );
318 this.el.append_column ( child_9.el );
324 this.css = new Gtk.CssProvider();
326 this.css.load_from_string("
327 #left-tree-view { font-size: 12px;}
328 .drag-over { background-color:#88a3bc; }
330 border-bottom-width: 5px;
331 border-bottom-style: solid;
332 border-bottom-color: #88a3bc;
335 border-top-width: 5px;
336 border-top-style: solid;
337 border-top-color: #88a3bc;
340 border-top-width: 5px;
341 border-top-style: solid;
342 border-top-color: red;
343 border-bottom-width: 5px;
344 border-bottom-style: solid;
345 border-bottom-color: red;
348 border-top-width: 5px;
349 border-top-style: solid;
350 border-top-color: #ABF4EB;
351 border-bottom-width: 5px;
352 border-bottom-style: solid;
353 border-bottom-color: #ABF4EB;
356 border-top-width: 5px;
357 border-top-style: solid;
358 border-top-color: #EEA9FF;
359 border-bottom-width: 5px;
360 border-bottom-style: solid;
361 border-bottom-color: #EEA9FF;
364 #left-tree-view indent {
365 -gtk-icon-size : 2px;
367 #left-tree-view indent:nth-last-child(2) {
372 Gtk.StyleContext.add_provider_for_display(
373 this.el.get_display(),
375 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
382 // user defined functions
383 public Gtk.Widget? getWidgetAtRow (uint row) {
386 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
387 var colview = gesture.widget;
388 var line_no = check_list_widget(colview, x,y);
390 var item = colview.model.get_item(line_no);
394 //GLib.debug("Get Widget At Row %d", (int)row);
395 var child = this.el.get_first_child();
397 var reading_header = true;
399 while (child != null) {
400 //GLib.debug("Got %s", child.get_type().name());
402 if (reading_header) {
405 if (child.get_type().name() != "GtkColumnListView") {
407 child = child.get_next_sibling();
410 // should be columnlistview
411 child = child.get_first_child();
415 reading_header = false;
422 if (line_no == row) {
423 //GLib.debug("Returning widget %s", child.get_type().name());
424 return (Gtk.Widget)child;
426 child = child.get_next_sibling();
428 //GLib.debug("Rturning null");
432 public int getColAt (double x, double y) {
435 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
438 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
439 //GLib.debug("Cehck %d, %d", x,y);
440 var child = this.el.get_first_child();
444 while (child != null) {
446 if (child.get_type().name() == "GtkColumnViewRowWidget") {
447 child = child.get_first_child();
451 //child.get_allocation(out alloc);
452 if (x < (child.get_width() + offx)) {
456 //offx += child.get_width();
458 //child = child.get_next_sibling();
465 public int getRowAt (double x, double y, out string pos) {
468 var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
469 //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
474 var row= w.get_ancestor(GLib.Type.from_name("GtkColumnViewRowWidget"));
479 //GLib.debug("got colview %s", row == null ? "nothing" : row.get_type().name());
484 while (cr.get_prev_sibling() != null) {
486 cr = cr.get_prev_sibling();
489 //GLib.debug("row number is %d", rn);
490 //GLib.debug("click %d, %d", (int)x, (int)y);
492 Graphene.Rect bounds;
493 row.compute_bounds(this.el, out bounds);
494 //GLib.debug("click x=%d, y=%d, w=%d, h=%d",
495 // (int)bounds.get_x(), (int)bounds.get_y(),
496 // (int)bounds.get_width(), (int)bounds.get_height()
498 var ypos = y - bounds.get_y();
499 //GLib.debug("rel ypos = %d", (int)ypos);
500 var rpos = 100.0 * (ypos / bounds.get_height());
501 //GLib.debug("rel pos = %d %%", (int)rpos);
506 } else if (rpos < 20) {
511 public Gtk.Widget? getWidgetAt (double x, double y) {
513 var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
514 //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
519 var row= w.get_ancestor(GLib.Type.from_name("GtkColumnViewRowWidget"));
528 public class Xcls_GestureClick5 : Object
530 public Gtk.GestureClick el;
531 private Xcls_WindowLeftTree _this;
537 public Xcls_GestureClick5(Xcls_WindowLeftTree _owner )
540 this.el = new Gtk.GestureClick();
544 // set gobject values
547 this.el.released.connect( (n_press, x, y) => {
549 _this.view.button_is_pressed = false;
553 this.el.pressed.connect( (n_press, x, y) => {
555 //console.log("button press?");
557 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
561 _this.view.button_is_pressed = true;
563 _this.view.lastEventSource = "tree";
564 if (! _this.before_node_change() ) {
565 GLib.debug("before_node_change return false");
569 // nothing there -show dialog
570 if (_this.model.el.get_n_items() < 1) {
571 _this.main_window.windowstate.showAddObject(_this.view.el, null);
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);
590 if (_this.view.getColAt(x,y) > 0 ) {
591 GLib.debug("add colum clicked.");
592 var fqn = node.fqn();
593 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
598 _this.main_window.windowstate.leftTreeBeforeChange();
599 //_this.view.el.get_selection().select_path(res);
600 GLib.debug("Button Pressed - start show window");
601 _this.main_window.windowstate.showAddObject(_this.view.el, node);
602 GLib.debug("Button Pressed - finsihed show window");
611 // user defined functions
614 public class Xcls_GestureClick6 : Object
616 public Gtk.GestureClick el;
617 private Xcls_WindowLeftTree _this;
623 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
626 this.el = new Gtk.GestureClick();
630 // set gobject values
634 this.el.pressed.connect( (n_press, x, y) => {
639 if (_this.model.el.get_n_items() < 1) {
641 GLib.debug("no items");
645 var row = _this.view.getRowAt(x,y, out pos );
647 GLib.debug("no row selected items");
651 var node = _this.selmodel.getNodeAt(row);
653 GLib.warning("No node found at row %d", row);
658 _this.model.selectNode(node);
662 GLib.debug("Prssed %d", (int) this.el.get_current_button());
663 //_this.deletemenu.el.set_parent(_this.view.el);
664 _this.LeftTreeMenu.el.set_parent(_this.view.el);
667 //Gtk.Allocation rect;
668 //_this.view.el.get_allocation(out rect);
669 //_this.deletemenu.el.set_has_arrow(false);
670 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
673 _this.LeftTreeMenu.el.set_offset(
675 (int)y - (int)_this.view.el.get_height());
677 _this.LeftTreeMenu.el.popup();
682 // user defined functions
685 public class Xcls_DragSource7 : Object
687 public Gtk.DragSource el;
688 private Xcls_WindowLeftTree _this;
694 public Xcls_DragSource7(Xcls_WindowLeftTree _owner )
697 this.el = new Gtk.DragSource();
701 // set gobject values
702 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
705 this.el.drag_cancel.connect( (drag, reason) => {
707 _this.view.dragNode = null;
710 this.el.prepare.connect( (x, y) => {
714 /// ( drag_context, data, info, time) => {
717 //print("drag-data-get");
718 var ndata = _this.selmodel.getSelectedNode();
720 GLib.debug("return empty string - no selection..");
726 //data.set_text(tp,tp.length);
728 var str = ndata.toJsonString();
729 GLib.debug("prepare store: %s", str);
730 GLib.Value ov = GLib.Value(typeof(string));
732 var cont = new Gdk.ContentProvider.for_value(ov);
734 GLib.Value v = GLib.Value(typeof(string));
735 //var str = drop.read_text( [ "text/plain" ] 0);
737 cont.get_value(ref v);
740 GLib.debug("set %s", v.get_string());
746 this.el.drag_begin.connect( ( drag ) => {
747 GLib.debug("SOURCE: drag-begin");
749 // find what is selected in our tree...
750 var data = _this.selmodel.getSelectedNode();
754 _this.view.dragNode = data;
755 var xname = data.fqn();
756 GLib.debug ("XNAME IS %s", xname);
758 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
761 var paintable = new Gtk.WidgetPaintable(widget);
762 this.el.set_icon(paintable, 0,0);
766 this.el.drag_end.connect( (drag, delete_data) => {
768 _this.view.dragNode = null;
772 // user defined functions
775 public class Xcls_EventControllerKey8 : Object
777 public Gtk.EventControllerKey el;
778 private Xcls_WindowLeftTree _this;
784 public Xcls_EventControllerKey8(Xcls_WindowLeftTree _owner )
787 this.el = new Gtk.EventControllerKey();
791 // set gobject values
794 this.el.key_pressed.connect( (keyval, keycode, state) => {
798 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
802 _this.model.deleteSelected();
808 // user defined functions
811 public class Xcls_keystate : Object
813 public Gtk.EventControllerKey el;
814 private Xcls_WindowLeftTree _this;
821 public Xcls_keystate(Xcls_WindowLeftTree _owner )
824 _this.keystate = this;
825 this.el = new Gtk.EventControllerKey();
830 // set gobject values
833 this.el.key_released.connect( (keyval, keycode, state) => {
834 GLib.debug("key release %d, %d, %d" , (int) keyval, (int) keycode, state);
835 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
838 //GLib.debug("set state %d , shift = %d", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);
843 this.el.key_pressed.connect( (keyval, keycode, state) => {
845 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
852 // user defined functions
855 public class Xcls_drop : Object
857 public Gtk.DropTarget el;
858 private Xcls_WindowLeftTree _this;
862 public Gtk.Widget? highlightWidget;
863 public JsRender.Node? lastDragNode;
864 public string lastDragString;
867 public Xcls_drop(Xcls_WindowLeftTree _owner )
871 this.el = new Gtk.DropTarget ( typeof(string) ,
872 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
875 this.highlightWidget = null;
876 this.lastDragNode = null;
877 this.lastDragString = "";
879 // set gobject values
882 this.el.accept.connect( (drop) => {
884 GLib.debug("got DropTarget:accept");
886 // NOT REALLY NEEDED? = put stuff in drop?
889 /* ( ctx, x, y, time) => {
890 //Seed.print("TARGET: drag-drop");
893 var src = Gtk.drag_get_source_widget(ctx);
895 if (src != this.el) {
899 this.drag_in_motion = false;
900 // request data that will be recieved by the recieve...
903 this.el, // will receive 'drag-data-received' signal
904 ctx, // represents the current state of the DnD
905 Gdk.Atom.intern("application/json",true), // the target type we want
910 // No target offered by source => error
916 // handle drop around self..
920 //print("GETTING POS");
924 Gtk.TreeViewDropPosition pos;
925 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
927 // if there are not items in the tree.. the we have to set isOver to true for anything..
929 if (_this.model.el.iter_n_children(null) < 1) {
930 print("got NO children?\n");
933 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
938 //var action = Gdk.DragAction.COPY;
939 // unless we are copying!!! ctl button..
941 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
942 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
943 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
946 if (_this.model.el.iter_n_children(null) < 1) {
947 // no children.. -- asume it's ok..
949 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
951 // continue through to allow drop...
959 //print("ISOVER? " + isOver);
962 Gtk.drag_finish (ctx, false, false, time); // drop failed..
963 return true; // not over apoint!?! - no action on drop or motion..
966 // drag node is parent of child..
967 //console.log("SRC TREEPATH: " + src.treepath);
968 //console.log("TARGET TREEPATH: " + data.path.to_string());
970 // nned to check a few here..
971 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
972 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
973 //Gtk.TreeViewDropPosition.AFTER
974 //Gtk.TreeViewDropPosition.BEFORE
976 // locally dragged items to not really use the
977 var selection_text = this.dragData;
981 if (selection_text == null || selection_text.length < 1) {
982 //print("Error - drag selection text returned NULL");
984 Gtk.drag_finish (ctx, false, false, time); // drop failed..
985 return true; /// -- fixme -- this is not really correct..
988 // see if we are dragging into ourself?
989 print ("got selection text of " + selection_text);
991 var target_path = path.to_string();
992 //print("target_path="+target_path);
995 if (selection_text == target_path) {
996 print("self drag ?? == we should perhaps allow copy onto self..\n");
998 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1000 return true; /// -- fixme -- this is not really correct..
1005 //print("DUMPING DATA");
1006 //console.dump(data);
1009 //print(data.path.to_string() +' => '+ data.pos);
1011 // dropList is a list of xtypes that this node could be dropped on.
1012 // it is set up when we start to drag..
1015 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
1017 print("targetDAta: " + targetData +"\n");
1019 if (targetData.length < 1) {
1020 //print("Can not find drop node path");
1022 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1028 // continue on to allow drop..
1030 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
1033 var delete_selection_data = false;
1035 if (action == Gdk.DragAction.ASK) {
1036 // Ask the user to move or copy, then set the ctx action.
1039 if (action == Gdk.DragAction.MOVE) {
1040 delete_selection_data = true;
1043 // drag around.. - reorder..
1044 _this.model.moveNode(targetData, action);
1050 // we can send stuff to souce here...
1053 // do we always say failure, so we handle the reall drop?
1054 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
1067 this.el.motion.connect( ( x, y) => {
1069 var is_shift = _this.keystate.is_shift > 0;
1071 //GLib.debug("shift is %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
1072 string pos; // over / before / after..
1074 //GLib.debug("got drag motion");
1076 GLib.Value v = GLib.Value(typeof(string));
1077 //var str = drop.read_text( [ "text/plain" ] 0);
1078 var cont = this.el.current_drop.get_drag().content ;
1080 cont.get_value(ref v);
1081 } catch (GLib.Error e) {
1082 // GLib.debug("failed to get drag value");
1083 return Gdk.DragAction.COPY;
1087 //GLib.debug("got %s", v.get_string());
1089 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1090 // still dragging same node
1092 this.lastDragNode = new JsRender.Node();
1093 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1097 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
1098 this.lastDragNode.fqn());
1101 foreach(var dp in drop_on_to) {
1104 //GLib.debug("droplist: %s", string.joinv(", ", str));
1107 // if there are not items in the tree.. the we have to set isOver to true for anything..
1109 if (_this.model.el.n_items < 1) {
1110 // FIXME check valid drop types?
1111 if (drop_on_to.contains("*top")) {
1112 this.addHighlight(_this.view.el, "over");
1114 this.addHighlight(null, "");
1117 return Gdk.DragAction.COPY; // no need to highlight?
1124 // if path of source and dest are inside each other..
1125 // need to add source info to drag?
1127 var row = _this.view.getRowAt(x,y, out pos);
1128 //GLib.debug("check is over %d, %d, %s", (int)x,(int)y, pos);
1131 this.addHighlight(null, "");
1132 return Gdk.DragAction.COPY;
1134 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1136 var node = (JsRender.Node)tr.get_item();
1138 //GLib.debug("Drop over node: %s", node.fqn());
1141 if (pos == "above" || pos == "below") {
1142 if (node.parent == null) {
1143 //GLib.debug("no parent try center");
1147 if (!drop_on_to.contains(node.parent.fqn())) {
1148 //GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1151 //GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1152 if (_this.view.dragNode != null && is_shift) {
1153 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1154 GLib.debug("shift drop not self not allowed");
1155 this.addHighlight(null, "");
1156 return Gdk.DragAction.COPY;
1169 if (pos == "over") {
1170 if (!drop_on_to.contains(node.fqn())) {
1171 //GLib.debug("drop on does not contain %s - try center" , node.fqn());
1172 this.addHighlight(null, "");
1173 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1175 if (_this.view.dragNode != null && is_shift) {
1176 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1177 //GLib.debug("shift drop not self not allowed");
1178 this.addHighlight(null, "");
1179 return Gdk.DragAction.COPY;
1186 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1187 var w = _this.view.getWidgetAt(x,y);
1188 this.addHighlight(w, pos);
1189 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1191 this.el.leave.connect( ( ) => {
1192 this.addHighlight(null,"");
1195 this.el.drop.connect( (v, x, y) => {
1197 // must get the pos before we clear the hightlihg.
1199 var row = _this.view.getRowAt(x,y, out pos);
1200 this.addHighlight(null,"");
1202 var is_shift = _this.keystate.is_shift > 0;
1205 // -- get position..
1206 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1207 // still dragging same node
1209 this.lastDragNode = new JsRender.Node();
1210 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1215 var dropNode = new JsRender.Node();
1216 dropNode.loadFromJsonString(v.get_string(), 2);
1217 GLib.debug("dropped node %s", dropNode.toJsonString());
1220 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1222 // if there are not items in the tree.. the we have to set isOver to true for anything..
1224 if (_this.model.el.n_items < 1) {
1225 // FIXME check valid drop types?
1226 if (!drop_on_to.contains("*top")) {
1227 GLib.debug("drop on to list does not contain top?");
1230 // add new node to top..
1231 GLib.debug("adding to top");
1233 var m = (GLib.ListStore) _this.model.el.model;
1234 _this.main_window.windowstate.file.tree = dropNode;
1235 dropNode.updated_count++;
1238 _this.model.selectNode(dropNode);
1240 return true; // no need to highlight?
1248 GLib.debug("could not get row %d,%d, %s", (int)x,(int)y,pos);
1249 return false; //Gdk.DragAction.COPY;
1251 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1253 var node = (JsRender.Node)tr.get_item();
1255 if (pos == "above" || pos == "below") {
1256 if (node.parent == null) {
1259 if (!drop_on_to.contains(node.parent.fqn())) {
1262 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1263 if (_this.view.dragNode != null && is_shift) {
1264 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1265 GLib.debug("shift drop not self not allowed");
1276 if (pos == "over") {
1277 if (!drop_on_to.contains(node.fqn())) {
1278 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1282 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1283 GLib.debug("shift drop not self not allowed");
1291 if (is_shift && _this.view.dragNode != null) {
1292 _this.model.selectNode(null);
1293 _this.view.dragNode.remove();
1295 node.appendChild(dropNode);
1296 dropNode.updated_count++;
1297 _this.model.selectNode(dropNode);
1303 GLib.debug("Above - insertBefore");
1306 if (is_shift && _this.view.dragNode != null) {
1307 _this.model.selectNode(null);
1308 _this.view.dragNode.remove();
1310 node.parent.insertBefore(dropNode, node);
1311 dropNode.updated_count++;
1312 _this.model.selectNode(dropNode);
1317 GLib.debug("Below - insertAfter");
1318 if (is_shift && _this.view.dragNode != null) {
1319 _this.model.selectNode(null);
1320 _this.view.dragNode.remove();
1324 node.parent.insertAfter(dropNode, node);
1325 dropNode.updated_count++;
1326 _this.model.selectNode(dropNode);
1332 // should not happen
1344 // user defined functions
1345 public void addHighlight (Gtk.Widget? w, string hl) {
1346 if (this.highlightWidget != null) {
1347 var ww = this.highlightWidget;
1348 //GLib.debug("clear drag from previous highlight");
1349 if (ww.has_css_class("drag-below")) {
1350 ww.remove_css_class("drag-below");
1352 if (ww.has_css_class("drag-above")) {
1353 ww.remove_css_class("drag-above");
1355 if (ww.has_css_class("drag-over")) {
1356 ww.remove_css_class("drag-over");
1360 //GLib.debug("add drag=%s to widget", hl);
1361 if (!w.has_css_class("drag-" + hl)) {
1362 w.add_css_class("drag-" + hl);
1365 this.highlightWidget = w;
1369 public class Xcls_selmodel : Object
1371 public Gtk.SingleSelection el;
1372 private Xcls_WindowLeftTree _this;
1378 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1381 _this.selmodel = this;
1382 new Xcls_model( _this );
1383 this.el = new Gtk.SingleSelection( _this.model.el );
1387 // set gobject values
1390 this.el.selection_changed.connect( (position, n_items) => {
1394 //if (!this.button_is_pressed && !this.key_is_pressed) {
1395 // then event was started by some other action
1396 // which should manually trigger all the events..
1397 // print("SKIPPING select - no button or key pressed\n");
1402 if (_this.view.blockChanges) { // probably not needed..
1403 GLib.debug("SKIPPING select - blockchanges set..");
1407 if (!_this.before_node_change( ) ) {
1408 _this.view.blockChanges = true;
1409 _this.selmodel.el.unselect_all();
1410 _this.view.blockChanges = false;
1414 if (_this.main_window.windowstate.file == null) {
1415 GLib.debug("SKIPPING select windowstate file is not set...");
1419 //var render = this.get('/LeftTree').getRenderer();
1420 GLib.debug("LEFT TREE -> view -> selection changed called");
1423 // -- it appears that the selection is not updated.
1424 // select the node...
1425 //_this.selmodel.el.set_selected(row);
1427 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1429 var snode = _this.selmodel.getSelectedNode();
1430 if (snode == null) {
1432 GLib.debug("selected rows < 1");
1433 //??this.model.load( false);
1434 _this.node_selected(null);
1442 GLib.debug ("calling left_tree.node_selected %s", snode.toJsonString());
1443 _this.node_selected(snode);
1448 // no need to scroll. it's in the view as we clicked on it.
1449 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1455 // user defined functions
1456 public JsRender.Node? getSelectedNode () {
1457 if (this.el.selected_item == null) {
1462 var tr = (Gtk.TreeListRow)this.el.selected_item;
1464 return (JsRender.Node)tr.get_item();
1467 public JsRender.Node getNodeAt (uint row) {
1469 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1471 var a = tr.get_item();;
1472 GLib.debug("get_item (2) = %s", a.get_type().name());
1475 return (JsRender.Node)tr.get_item();
1479 public class Xcls_model : Object
1481 public Gtk.TreeListModel el;
1482 private Xcls_WindowLeftTree _this;
1488 public Xcls_model(Xcls_WindowLeftTree _owner )
1492 this.el = this.updateModel(null);
1496 // set gobject values
1499 // user defined functions
1500 public void loadFile (JsRender.JsRender f) {
1503 _this.drop.highlightWidget = null;
1505 var m = (GLib.ListStore) this.el.model;
1507 _this.main_window.windowstate.leftTreeNodeSelected(null);
1509 _this.main_window.windowstate.file = f;
1510 _this.last_error_counter = -1;
1512 if (f.tree == null) {
1519 // if it's still null?
1520 if (f.tree == null) {
1521 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1522 _this.updateErrors();
1526 _this.updateErrors();
1528 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1534 public int nodeToRow (JsRender.Node node)
1537 var s = _this.view.el.model as Gtk.SingleSelection;
1538 for (var i = 0; i < s.n_items; i++) {
1539 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1540 var lr = s.get_item(i) as Gtk.TreeListRow;
1541 //GLib.debug("check node %s", lr.get_item().get_type().name());
1542 var nn = (lr.get_item() as JsRender.Node);
1543 if (nn != null && nn.oid == node.oid) {
1552 public void deleteSelected () {
1556 var node = _this.selmodel.getSelectedNode();
1560 GLib.debug("delete Selected - no node slected?");
1563 _this.selmodel.el.unselect_all();
1566 GLib.debug("delete Selected - done");
1569 print("DELETE SELECTED?");
1570 //_this.view.blockChanges = true;
1571 print("GET SELECTION?");
1573 var s = _this.view.el.get_selection();
1575 print("GET SELECTED?");
1580 if (!s.get_selected(out mod, out iter)) {
1581 return; // nothing seleted..
1586 this.activePath= "";
1587 print("GET vnode value?");
1590 this.el.get_value(iter, 2, out value);
1591 var data = (JsRender.Node)(value.get_object());
1592 print("removing node from Render\n");
1593 if (data.parent == null) {
1594 _this.main_window.windowstate.file.tree = null;
1598 print("removing node from Tree\n");
1600 this.el.remove(ref iter);
1610 this.activePath= ""; // again!?!?
1611 //this.changed(null,true);
1615 _this.view.blockChanges = false;
1618 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1619 this.el = new Gtk.TreeListModel(
1620 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1624 return ((JsRender.Node)item).childstore;
1628 if (_this.selmodel.el == null) {
1631 _this.selmodel.el.set_model(this.el);
1634 public void selectNode (JsRender.Node? node)
1636 var s = _this.view.el.model as Gtk.SingleSelection;
1638 s.selected=Gtk.INVALID_LIST_POSITION;
1641 var row = this.nodeToRow(node);
1646 GLib.debug("Could not find node");
1647 s.selected=Gtk.INVALID_LIST_POSITION;
1650 GLib.debug("Select %d", row);
1651 s.set_selected(row);
1652 _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1653 //_this.node_selected(node);
1660 public class Xcls_maincol : Object
1662 public Gtk.ColumnViewColumn el;
1663 private Xcls_WindowLeftTree _this;
1669 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1672 _this.maincol = this;
1673 var child_1 = new Xcls_SignalListItemFactory14( _this );
1675 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1679 // set gobject values
1680 this.el.id = "maincol";
1681 this.el.expand = true;
1682 this.el.resizable = true;
1685 // user defined functions
1687 public class Xcls_SignalListItemFactory14 : Object
1689 public Gtk.SignalListItemFactory el;
1690 private Xcls_WindowLeftTree _this;
1696 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1699 this.el = new Gtk.SignalListItemFactory();
1703 // set gobject values
1706 this.el.setup.connect( (listitem) => {
1708 var expand = new Gtk.TreeExpander();
1710 expand.set_indent_for_depth(true);
1711 expand.set_indent_for_icon(true);
1712 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1713 var icon = new Gtk.Image();
1714 var lbl = new Gtk.Label("");
1715 lbl.use_markup = true;
1716 lbl.ellipsize = Pango.EllipsizeMode.END;
1718 icon.margin_end = 4;
1719 lbl.justify = Gtk.Justification.LEFT;
1722 // listitem.activatable = true; ??
1726 expand.set_child(hbox);
1727 ((Gtk.ListItem)listitem).set_child(expand);
1730 this.el.bind.connect( (listitem) => {
1731 // GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1733 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1734 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1737 var hbox = (Gtk.Box) expand.child;
1740 var img = (Gtk.Image) hbox.get_first_child();
1741 var lbl = (Gtk.Label) img.get_next_sibling();
1743 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1744 var node = (JsRender.Node) lr.get_item();
1745 if (node == null || node.fqn() == "") {
1748 //GLib.debug("node is %s", node.get_type().name());
1749 // was item (1) in old layout
1754 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1755 var clsname = node.fqn();
1757 var clsb = clsname.split(".");
1758 var sub = clsb.length > 1 ? clsb[1].down() : "";
1760 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1764 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1765 img.set_from_file(fn);
1768 img.set_from_paintable(
1770 "media-playback-stop", null, 16,1,
1771 Gtk.TextDirection.NONE, 0
1775 } catch (GLib.Error e) {}
1777 expand.set_hide_expander( !node.hasChildren() );
1778 expand.set_list_row(lr);
1780 node.bind_property("iconResourceName",
1782 GLib.BindingFlags.SYNC_CREATE);
1784 node.bind_property("nodeTitleProp",
1786 GLib.BindingFlags.SYNC_CREATE);
1787 node.bind_property("nodeTipProp",
1788 lbl, "tooltip_markup",
1789 GLib.BindingFlags.SYNC_CREATE);
1795 // user defined functions
1799 public class Xcls_ColumnViewColumn15 : Object
1801 public Gtk.ColumnViewColumn el;
1802 private Xcls_WindowLeftTree _this;
1808 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1811 var child_1 = new Xcls_SignalListItemFactory16( _this );
1813 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1817 // set gobject values
1818 this.el.fixed_width = 25;
1821 // user defined functions
1823 public class Xcls_SignalListItemFactory16 : Object
1825 public Gtk.SignalListItemFactory el;
1826 private Xcls_WindowLeftTree _this;
1832 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1835 this.el = new Gtk.SignalListItemFactory();
1839 // set gobject values
1842 this.el.setup.connect( (listitem) => {
1845 var icon = new Gtk.Image();
1847 ((Gtk.ListItem)listitem).set_child(icon);
1849 this.el.bind.connect( (listitem) => {
1851 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1852 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1853 var node = (JsRender.Node) lr.get_item();
1856 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1857 img.set_from_paintable(
1859 "list-add", null, 16,1,
1860 Gtk.TextDirection.NONE, 0
1864 var fqn = node.fqn();
1865 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1867 img.set_visible(cn.size > 0 ? true : false);
1872 // user defined functions
1877 public class Xcls_LeftTreeMenu : Object
1879 public Gtk.Popover el;
1880 private Xcls_WindowLeftTree _this;
1886 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1889 _this.LeftTreeMenu = this;
1890 this.el = new Gtk.Popover();
1894 // set gobject values
1895 var child_1 = new Xcls_Box18( _this );
1897 this.el.child = child_1.el;
1900 // user defined functions
1902 public class Xcls_Box18 : Object
1905 private Xcls_WindowLeftTree _this;
1911 public Xcls_Box18(Xcls_WindowLeftTree _owner )
1914 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1918 // set gobject values
1919 var child_1 = new Xcls_Button19( _this );
1921 this.el.append( child_1.el );
1922 var child_2 = new Xcls_Button20( _this );
1924 this.el.append( child_2.el );
1925 var child_3 = new Xcls_Button21( _this );
1927 this.el.append( child_3.el );
1930 // user defined functions
1932 public class Xcls_Button19 : Object
1934 public Gtk.Button el;
1935 private Xcls_WindowLeftTree _this;
1941 public Xcls_Button19(Xcls_WindowLeftTree _owner )
1944 this.el = new Gtk.Button();
1948 // set gobject values
1949 this.el.has_frame = false;
1950 this.el.label = "Delete Element";
1953 this.el.clicked.connect( ( ) => {
1954 _this.LeftTreeMenu.el.hide();
1955 _this.model.deleteSelected();
1960 // user defined functions
1963 public class Xcls_Button20 : Object
1965 public Gtk.Button el;
1966 private Xcls_WindowLeftTree _this;
1972 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1975 this.el = new Gtk.Button();
1979 // set gobject values
1980 this.el.has_frame = false;
1981 this.el.label = "Save as Template";
1984 this.el.clicked.connect( () => {
1985 _this.LeftTreeMenu.el.hide();
1986 DialogSaveTemplate.singleton().showIt(
1987 (Gtk.Window) _this.el.get_root (),
1988 _this.main_window.windowstate.file.palete(),
1989 _this.getActiveElement()
1996 // user defined functions
1999 public class Xcls_Button21 : Object
2001 public Gtk.Button el;
2002 private Xcls_WindowLeftTree _this;
2008 public Xcls_Button21(Xcls_WindowLeftTree _owner )
2011 this.el = new Gtk.Button();
2015 // set gobject values
2016 this.el.has_frame = false;
2017 this.el.label = "Save as Module";
2020 this.el.clicked.connect( () => {
2022 _this.LeftTreeMenu.el.hide();
2023 var node = _this.getActiveElement();
2026 var sm = DialogSaveModule.singleton();
2030 (Gtk.Window) _this.el.get_root (),
2031 _this.main_window.windowstate.project,
2035 gtk4 migration - disabled this part.. probably not used muchanyway
2038 if (name.length < 1) {
2042 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
2046 var s = _this.view.el.get_selection();
2048 print("GET SELECTED?");
2053 if (!s.get_selected(out mod, out iter)) {
2054 return; // nothing seleted..
2057 var n_cn = mod.iter_n_children(iter) -1;
2058 for (var i = n_cn; i > -1; i--) {
2059 mod.iter_nth_child(out citer, iter, i);
2062 print("removing node from Tree\n");
2064 _this.model.el.remove(ref citer);
2067 _this.node_selected(node, "tree");
2073 // user defined functions