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_keystate keystate;
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);
32 public Xcls_WindowLeftTree()
35 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
38 this.main_window = null;
39 this.last_error_counter = -1;
42 this.el.hexpand = true;
43 this.el.vexpand = true;
44 var child_1 = new Xcls_ListView2( _this );
46 this.el.append( child_1.el );
47 new Xcls_viewwin( _this );
48 this.el.append( _this.viewwin.el );
51 // user defined functions
52 public void updateErrors () {
53 var file = this.getActiveFile();
54 var ar = file.getErrors();
57 this.last_error_counter = file.error_counter ;
61 if (this.last_error_counter == file.error_counter) {
66 foreach(var diag in ar) {
69 // print("get inter\n");
70 var node= file.lineToNode( (int)diag.range.start.line) ;
74 var row = _this.model.nodeToRow(node);
78 var w = this.view.getWidgetAtRow(row);
82 // always show errors.
83 var ed = diag.category.down();
84 if (ed != "err" && w.has_css_class("node-err")) {
87 if (ed == "err" && w.has_css_class("node-warn")) {
88 w.remove_css_class("node-warn");
90 if (ed == "err" && w.has_css_class("node-depr")) {
91 w.remove_css_class("node-depr");
93 if (!w.has_css_class("node-"+ ed)) {
94 w.add_css_class("node-" + ed);
100 public void onresize () {
103 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
104 // _this.maincol.el.set_max_width( _this.viewwin.el.get_width() - 32 );
106 public void removeErrors () {
107 var child = this.view.el.get_first_child();
109 var reading_header = true;
111 while (child != null) {
112 GLib.debug("Got %s", child.get_type().name());
114 if (reading_header) {
117 if (child.get_type().name() != "GtkColumnListView") {
119 child = child.get_next_sibling();
122 // should be columnlistview
123 child = child.get_first_child();
127 reading_header = false;
131 if (!child.has_css_class("node-err")) {
132 child.remove_css_class("node-err");
134 if (!child.has_css_class("node-warn")) {
135 child.remove_css_class("node-warn");
138 if (!child.has_css_class("node-depr")) {
139 child.remove_css_class("node-depr");
142 child = child.get_next_sibling();
144 //GLib.debug("Rturning null");
147 public JsRender.Node? getActiveElement () { // return path to actie node.
150 return _this.selmodel.getSelectedNode();
154 public JsRender.JsRender getActiveFile () {
155 return this.main_window.windowstate.file;
157 public class Xcls_ListView2 : Object
159 public Gtk.ListView el;
160 private Xcls_WindowLeftTree _this;
166 public Xcls_ListView2(Xcls_WindowLeftTree _owner )
169 var child_1 = new Xcls_SignalListItemFactory3( _this );
171 this.el = new Gtk.ListView( null, child_1.el );
175 // set gobject values
178 // user defined functions
180 public class Xcls_SignalListItemFactory3 : Object
182 public Gtk.SignalListItemFactory el;
183 private Xcls_WindowLeftTree _this;
189 public Xcls_SignalListItemFactory3(Xcls_WindowLeftTree _owner )
192 this.el = new Gtk.SignalListItemFactory();
196 // set gobject values
199 // user defined functions
203 public class Xcls_viewwin : Object
205 public Gtk.ScrolledWindow el;
206 private Xcls_WindowLeftTree _this;
212 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
215 _this.viewwin = this;
216 this.el = new Gtk.ScrolledWindow();
220 // set gobject values
221 this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
222 this.el.has_frame = true;
223 this.el.hexpand = true;
224 this.el.vexpand = true;
225 this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
226 new Xcls_view( _this );
227 this.el.child = _this.view.el;
228 new Xcls_LeftTreeMenu( _this );
231 // user defined functions
233 public class Xcls_view : Object
235 public Gtk.ColumnView el;
236 private Xcls_WindowLeftTree _this;
240 public bool blockChanges;
241 public bool headers_visible;
242 public string lastEventSource;
243 public bool button_is_pressed;
244 public Gtk.CssProvider css;
245 public JsRender.Node? dragNode;
248 public Xcls_view(Xcls_WindowLeftTree _owner )
252 new Xcls_selmodel( _this );
253 this.el = new Gtk.ColumnView( _this.selmodel.el );
256 this.blockChanges = false;
257 this.headers_visible = false;
258 this.lastEventSource = "";
259 this.button_is_pressed = false;
260 this.dragNode = null;
262 // set gobject values
263 this.el.name = "left-tree-view";
264 this.el.hexpand = false;
265 this.el.vexpand = true;
266 var child_2 = new Xcls_GestureClick6( _this );
268 this.el.add_controller( child_2.el );
269 var child_3 = new Xcls_GestureClick7( _this );
271 this.el.add_controller( child_3.el );
272 var child_4 = new Xcls_DragSource8( _this );
274 this.el.add_controller( child_4.el );
275 var child_5 = new Xcls_EventControllerKey9( _this );
277 this.el.add_controller( child_5.el );
278 new Xcls_drop( _this );
279 this.el.add_controller( _this.drop.el );
280 new Xcls_maincol( _this );
281 this.el.append_column ( _this.maincol.el );
282 var child_8 = new Xcls_ColumnViewColumn15( _this );
284 this.el.append_column ( child_8.el );
285 new Xcls_keystate( _this );
286 this.el.add_controller( _this.keystate.el );
292 this.css = new Gtk.CssProvider();
294 this.css.load_from_string("
295 #left-tree-view { font-size: 12px;}
296 .drag-over { background-color:#88a3bc; }
298 border-bottom-width: 5px;
299 border-bottom-style: solid;
300 border-bottom-color: #88a3bc;
303 border-top-width: 5px;
304 border-top-style: solid;
305 border-top-color: #88a3bc;
308 border-top-width: 5px;
309 border-top-style: solid;
310 border-top-color: red;
311 border-bottom-width: 5px;
312 border-bottom-style: solid;
313 border-bottom-color: red;
316 border-top-width: 5px;
317 border-top-style: solid;
318 border-top-color: #ABF4EB;
319 border-bottom-width: 5px;
320 border-bottom-style: solid;
321 border-bottom-color: #ABF4EB;
324 border-top-width: 5px;
325 border-top-style: solid;
326 border-top-color: #EEA9FF;
327 border-bottom-width: 5px;
328 border-bottom-style: solid;
329 border-bottom-color: #EEA9FF;
332 #left-tree-view indent {
333 -gtk-icon-size : 2px;
335 #left-tree-view indent:nth-last-child(2) {
340 Gtk.StyleContext.add_provider_for_display(
341 this.el.get_display(),
343 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
350 // user defined functions
351 public Gtk.Widget? getWidgetAtRow (uint row) {
354 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
355 var colview = gesture.widget;
356 var line_no = check_list_widget(colview, x,y);
358 var item = colview.model.get_item(line_no);
362 //GLib.debug("Get Widget At Row %d", (int)row);
363 var child = this.el.get_first_child();
365 var reading_header = true;
367 while (child != null) {
368 GLib.debug("Got %s", child.get_type().name());
370 if (reading_header) {
373 if (child.get_type().name() != "GtkColumnListView") {
375 child = child.get_next_sibling();
378 // should be columnlistview
379 child = child.get_first_child();
383 reading_header = false;
390 if (line_no == row) {
391 //GLib.debug("Returning widget %s", child.get_type().name());
392 return (Gtk.Widget)child;
394 child = child.get_next_sibling();
396 //GLib.debug("Rturning null");
400 public int getColAt (double x, double y) {
403 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
406 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
407 //GLib.debug("Cehck %d, %d", x,y);
408 var child = this.el.get_first_child();
412 while (child != null) {
414 if (child.get_type().name() == "GtkColumnViewRowWidget") {
415 child = child.get_first_child();
419 //child.get_allocation(out alloc);
420 if (x < (child.get_width() + offx)) {
424 //offx += child.get_width();
426 //child = child.get_next_sibling();
433 public int getRowAt (double x, double in_y, out string pos) {
440 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
441 var colview = gesture.widget;
442 var line_no = check_list_widget(colview, x,y);
444 var item = colview.model.get_item(line_no);
450 //GLib.debug("offset = %d y = %d", (int) voff, (int) in_y);
451 var y = in_y + _this.viewwin.el.vadjustment.value;
452 var child = this.el.get_first_child();
453 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
455 var reading_header = true;
457 var header_height = 0;
460 while (child != null) {
461 //GLib.debug("Got %s", child.get_type().name());
462 if (reading_header) {
465 if (child.get_type().name() != "GtkColumnListView") {
466 h += child.get_height();
467 child = child.get_next_sibling();
470 // should be columnlistview
471 child = child.get_first_child();
472 GLib.debug("header height=%d", h);
475 reading_header = false;
479 if (child.get_type().name() != "GtkColumnViewRowWidget") {
480 child = child.get_next_sibling();
484 if (y < header_height) {
489 var hh = child.get_height();
490 //child.get_allocation(out alloc);
491 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
492 //GLib.debug("row %d y= %d %s", line_no, (int) (header_height + alloc.y),
494 // child.visible ? "VIS" : "hidden");
496 if (y > (header_height + real_y) && y <= (header_height + real_y + hh) ) {
497 if (y > ( header_height + real_y + (hh * 0.8))) {
499 } else if (y > ( header_height + real_y + (hh * 0.2))) {
504 GLib.debug("getRowAt return : %d, %s", line_no, pos);
509 if (real_y + hh > y) {
513 child = child.get_next_sibling();
518 public Gtk.Widget? getWidgetAt (double x, double in_y) {
521 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
522 var colview = gesture.widget;
523 var line_no = check_list_widget(colview, x,y);
525 var item = colview.model.get_item(line_no);
529 var y = in_y + _this.viewwin.el.vadjustment.value;
530 var child = this.el.get_first_child();
531 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
533 var reading_header = true;
535 var header_height = 0;
537 while (child != null) {
538 //GLib.debug("Got %s", child.get_type().name());
539 if (reading_header) {
542 if (child.get_type().name() != "GtkColumnListView") {
543 h += child.get_height();
544 child = child.get_next_sibling();
547 // should be columnlistview
548 child = child.get_first_child();
549 GLib.debug("header height=%d", h);
552 reading_header = false;
557 if (y < header_height) {
561 var hh = child.get_height();
562 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
564 if (y > curr_y && y <= header_height + hh + curr_y ) {
565 return (Gtk.Widget)child;
572 child = child.get_next_sibling();
578 public class Xcls_GestureClick6 : Object
580 public Gtk.GestureClick el;
581 private Xcls_WindowLeftTree _this;
587 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
590 this.el = new Gtk.GestureClick();
594 // set gobject values
597 this.el.released.connect( (n_press, x, y) => {
599 _this.view.button_is_pressed = false;
603 this.el.pressed.connect( (n_press, x, y) => {
605 //console.log("button press?");
607 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
611 _this.view.button_is_pressed = true;
613 _this.view.lastEventSource = "tree";
614 if (! _this.before_node_change() ) {
615 GLib.debug("before_node_change return false");
619 // nothing there -show dialog
620 if (_this.model.el.get_n_items() < 1) {
621 _this.main_window.windowstate.showAddObject(_this.view.el, null);
622 GLib.debug("no items");
626 var row = _this.view.getRowAt(x,y, out pos );
628 GLib.debug("no row selected items");
632 var node = _this.selmodel.getNodeAt(row);
634 GLib.warning("No node found at row %d", row);
640 if (_this.view.getColAt(x,y) > 0 ) {
641 GLib.debug("add colum clicked.");
642 var fqn = node.fqn();
643 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
648 _this.main_window.windowstate.leftTreeBeforeChange();
649 //_this.view.el.get_selection().select_path(res);
650 GLib.debug("Button Pressed - start show window");
651 _this.main_window.windowstate.showAddObject(_this.view.el, node);
652 GLib.debug("Button Pressed - finsihed show window");
661 // user defined functions
664 public class Xcls_GestureClick7 : Object
666 public Gtk.GestureClick el;
667 private Xcls_WindowLeftTree _this;
673 public Xcls_GestureClick7(Xcls_WindowLeftTree _owner )
676 this.el = new Gtk.GestureClick();
680 // set gobject values
684 this.el.pressed.connect( (n_press, x, y) => {
689 if (_this.model.el.get_n_items() < 1) {
691 GLib.debug("no items");
695 var row = _this.view.getRowAt(x,y, out pos );
697 GLib.debug("no row selected items");
701 var node = _this.selmodel.getNodeAt(row);
703 GLib.warning("No node found at row %d", row);
706 _this.model.selectNode(node);
710 GLib.debug("Prssed %d", (int) this.el.get_current_button());
711 //_this.deletemenu.el.set_parent(_this.view.el);
712 _this.LeftTreeMenu.el.set_parent(_this.view.el);
715 //Gtk.Allocation rect;
716 //_this.view.el.get_allocation(out rect);
717 //_this.deletemenu.el.set_has_arrow(false);
718 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
721 _this.LeftTreeMenu.el.set_offset(
723 (int)y - (int)_this.view.el.get_height());
725 _this.LeftTreeMenu.el.popup();
730 // user defined functions
733 public class Xcls_DragSource8 : Object
735 public Gtk.DragSource el;
736 private Xcls_WindowLeftTree _this;
742 public Xcls_DragSource8(Xcls_WindowLeftTree _owner )
745 this.el = new Gtk.DragSource();
749 // set gobject values
750 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
753 this.el.drag_cancel.connect( (drag, reason) => {
755 _this.view.dragNode = null;
758 this.el.prepare.connect( (x, y) => {
762 /// ( drag_context, data, info, time) => {
765 //print("drag-data-get");
766 var ndata = _this.selmodel.getSelectedNode();
768 GLib.debug("return empty string - no selection..");
774 //data.set_text(tp,tp.length);
776 var str = ndata.toJsonString();
777 GLib.debug("prepare store: %s", str);
778 GLib.Value ov = GLib.Value(typeof(string));
780 var cont = new Gdk.ContentProvider.for_value(ov);
782 GLib.Value v = GLib.Value(typeof(string));
783 //var str = drop.read_text( [ "text/plain" ] 0);
785 cont.get_value(ref v);
788 GLib.debug("set %s", v.get_string());
794 this.el.drag_begin.connect( ( drag ) => {
795 GLib.debug("SOURCE: drag-begin");
797 // find what is selected in our tree...
798 var data = _this.selmodel.getSelectedNode();
802 _this.view.dragNode = data;
803 var xname = data.fqn();
804 GLib.debug ("XNAME IS %s", xname);
806 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
809 var paintable = new Gtk.WidgetPaintable(widget);
810 this.el.set_icon(paintable, 0,0);
814 this.el.drag_end.connect( (drag, delete_data) => {
816 _this.view.dragNode = null;
820 // user defined functions
823 public class Xcls_EventControllerKey9 : Object
825 public Gtk.EventControllerKey el;
826 private Xcls_WindowLeftTree _this;
832 public Xcls_EventControllerKey9(Xcls_WindowLeftTree _owner )
835 this.el = new Gtk.EventControllerKey();
839 // set gobject values
842 this.el.key_pressed.connect( (keyval, keycode, state) => {
846 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
850 _this.model.deleteSelected();
856 // user defined functions
859 public class Xcls_drop : Object
861 public Gtk.DropTarget el;
862 private Xcls_WindowLeftTree _this;
866 public Gtk.Widget? highlightWidget;
867 public JsRender.Node? lastDragNode;
868 public string lastDragString;
871 public Xcls_drop(Xcls_WindowLeftTree _owner )
875 this.el = new Gtk.DropTarget ( typeof(string) ,
876 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
879 this.highlightWidget = null;
880 this.lastDragNode = null;
881 this.lastDragString = "";
883 // set gobject values
886 this.el.accept.connect( (drop) => {
888 GLib.debug("got DropTarget:accept");
890 // NOT REALLY NEEDED? = put stuff in drop?
893 /* ( ctx, x, y, time) => {
894 //Seed.print("TARGET: drag-drop");
897 var src = Gtk.drag_get_source_widget(ctx);
899 if (src != this.el) {
903 this.drag_in_motion = false;
904 // request data that will be recieved by the recieve...
907 this.el, // will receive 'drag-data-received' signal
908 ctx, // represents the current state of the DnD
909 Gdk.Atom.intern("application/json",true), // the target type we want
914 // No target offered by source => error
920 // handle drop around self..
924 //print("GETTING POS");
928 Gtk.TreeViewDropPosition pos;
929 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
931 // if there are not items in the tree.. the we have to set isOver to true for anything..
933 if (_this.model.el.iter_n_children(null) < 1) {
934 print("got NO children?\n");
937 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
942 //var action = Gdk.DragAction.COPY;
943 // unless we are copying!!! ctl button..
945 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
946 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
947 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
950 if (_this.model.el.iter_n_children(null) < 1) {
951 // no children.. -- asume it's ok..
953 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
955 // continue through to allow drop...
963 //print("ISOVER? " + isOver);
966 Gtk.drag_finish (ctx, false, false, time); // drop failed..
967 return true; // not over apoint!?! - no action on drop or motion..
970 // drag node is parent of child..
971 //console.log("SRC TREEPATH: " + src.treepath);
972 //console.log("TARGET TREEPATH: " + data.path.to_string());
974 // nned to check a few here..
975 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
976 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
977 //Gtk.TreeViewDropPosition.AFTER
978 //Gtk.TreeViewDropPosition.BEFORE
980 // locally dragged items to not really use the
981 var selection_text = this.dragData;
985 if (selection_text == null || selection_text.length < 1) {
986 //print("Error - drag selection text returned NULL");
988 Gtk.drag_finish (ctx, false, false, time); // drop failed..
989 return true; /// -- fixme -- this is not really correct..
992 // see if we are dragging into ourself?
993 print ("got selection text of " + selection_text);
995 var target_path = path.to_string();
996 //print("target_path="+target_path);
999 if (selection_text == target_path) {
1000 print("self drag ?? == we should perhaps allow copy onto self..\n");
1002 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1004 return true; /// -- fixme -- this is not really correct..
1009 //print("DUMPING DATA");
1010 //console.dump(data);
1013 //print(data.path.to_string() +' => '+ data.pos);
1015 // dropList is a list of xtypes that this node could be dropped on.
1016 // it is set up when we start to drag..
1019 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
1021 print("targetDAta: " + targetData +"\n");
1023 if (targetData.length < 1) {
1024 //print("Can not find drop node path");
1026 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1032 // continue on to allow drop..
1034 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
1037 var delete_selection_data = false;
1039 if (action == Gdk.DragAction.ASK) {
1040 // Ask the user to move or copy, then set the ctx action.
1043 if (action == Gdk.DragAction.MOVE) {
1044 delete_selection_data = true;
1047 // drag around.. - reorder..
1048 _this.model.moveNode(targetData, action);
1054 // we can send stuff to souce here...
1057 // do we always say failure, so we handle the reall drop?
1058 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
1071 this.el.motion.connect( ( x, y) => {
1073 var is_shift = _this.keystate.is_shift > 0;
1075 GLib.debug("shift is %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
1076 string pos; // over / before / after..
1078 //GLib.debug("got drag motion");
1080 GLib.Value v = GLib.Value(typeof(string));
1081 //var str = drop.read_text( [ "text/plain" ] 0);
1082 var cont = this.el.current_drop.get_drag().content ;
1084 cont.get_value(ref v);
1085 } catch (GLib.Error e) {
1086 GLib.debug("failed to get drag value");
1087 return Gdk.DragAction.COPY;
1091 //GLib.debug("got %s", v.get_string());
1093 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1094 // still dragging same node
1096 this.lastDragNode = new JsRender.Node();
1097 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1101 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
1102 this.lastDragNode.fqn());
1105 foreach(var dp in drop_on_to) {
1108 GLib.debug("droplist: %s", string.joinv(", ", str));
1111 // if there are not items in the tree.. the we have to set isOver to true for anything..
1113 if (_this.model.el.n_items < 1) {
1114 // FIXME check valid drop types?
1115 if (drop_on_to.contains("*top")) {
1116 this.addHighlight(_this.view.el, "over");
1118 this.addHighlight(null, "");
1121 return Gdk.DragAction.COPY; // no need to highlight?
1126 GLib.debug("check is over");
1128 // if path of source and dest are inside each other..
1129 // need to add source info to drag?
1131 var row = _this.view.getRowAt(x,y, out pos);
1134 this.addHighlight(null, "");
1135 return Gdk.DragAction.COPY;
1137 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1139 var node = (JsRender.Node)tr.get_item();
1141 GLib.debug("Drop over node: %s", node.fqn());
1144 if (pos == "above" || pos == "below") {
1145 if (node.parent == null) {
1146 GLib.debug("no parent try center");
1150 if (!drop_on_to.contains(node.parent.fqn())) {
1151 GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1154 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1155 if (_this.view.dragNode != null && is_shift) {
1156 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1157 GLib.debug("shift drop not self not allowed");
1158 this.addHighlight(null, "");
1159 return Gdk.DragAction.COPY;
1172 if (pos == "over") {
1173 if (!drop_on_to.contains(node.fqn())) {
1174 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1175 this.addHighlight(null, "");
1176 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1178 if (_this.view.dragNode != null && is_shift) {
1179 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1180 GLib.debug("shift drop not self not allowed");
1181 this.addHighlight(null, "");
1182 return Gdk.DragAction.COPY;
1189 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1190 var w = _this.view.getWidgetAt(x,y);
1191 this.addHighlight(w, pos);
1192 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1194 this.el.leave.connect( ( ) => {
1195 this.addHighlight(null,"");
1198 this.el.drop.connect( (v, x, y) => {
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(), 1);
1217 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1219 // if there are not items in the tree.. the we have to set isOver to true for anything..
1221 if (_this.model.el.n_items < 1) {
1222 // FIXME check valid drop types?
1223 if (!drop_on_to.contains("*top")) {
1224 GLib.debug("drop on to list does not contain top?");
1227 // add new node to top..
1230 var m = (GLib.ListStore) _this.model.el.model;
1231 _this.main_window.windowstate.file.tree = dropNode;
1235 _this.model.selectNode(dropNode);
1237 return true; // no need to highlight?
1243 var row = _this.view.getRowAt(x,y, out pos);
1245 return false; //Gdk.DragAction.COPY;
1247 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1249 var node = (JsRender.Node)tr.get_item();
1251 if (pos == "above" || pos == "below") {
1252 if (node.parent == null) {
1255 if (!drop_on_to.contains(node.parent.fqn())) {
1258 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1259 if (_this.view.dragNode != null && is_shift) {
1260 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1261 GLib.debug("shift drop not self not allowed");
1272 if (pos == "over") {
1273 if (!drop_on_to.contains(node.fqn())) {
1274 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1278 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1279 GLib.debug("shift drop not self not allowed");
1286 node.appendChild(dropNode);
1287 if (is_shift && _this.view.dragNode != null) {
1288 _this.model.selectNode(null);
1289 _this.view.dragNode.remove();
1293 _this.model.selectNode(dropNode);
1299 GLib.debug("Above - insertBefore");
1301 node.parent.insertBefore(dropNode, node);
1302 if (is_shift && _this.view.dragNode != null) {
1303 _this.model.selectNode(null);
1304 _this.view.dragNode.remove();
1307 _this.model.selectNode(dropNode);
1312 GLib.debug("Below - insertAfter");
1313 if (is_shift && _this.view.dragNode != null) {
1314 _this.model.selectNode(null);
1315 _this.view.dragNode.remove();
1319 node.parent.insertAfter(dropNode, node);
1320 _this.model.selectNode(dropNode);
1326 // should not happen
1338 // user defined functions
1339 public void addHighlight (Gtk.Widget? w, string hl) {
1340 if (this.highlightWidget != null) {
1341 var ww = this.highlightWidget;
1342 GLib.debug("clear drag from previous highlight");
1343 if (ww.has_css_class("drag-below")) {
1344 ww.remove_css_class("drag-below");
1346 if (ww.has_css_class("drag-above")) {
1347 ww.remove_css_class("drag-above");
1349 if (ww.has_css_class("drag-over")) {
1350 ww.remove_css_class("drag-over");
1354 GLib.debug("add drag=%s to widget", hl);
1355 if (!w.has_css_class("drag-" + hl)) {
1356 w.add_css_class("drag-" + hl);
1359 this.highlightWidget = w;
1363 public class Xcls_selmodel : Object
1365 public Gtk.SingleSelection el;
1366 private Xcls_WindowLeftTree _this;
1372 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1375 _this.selmodel = this;
1376 new Xcls_model( _this );
1377 this.el = new Gtk.SingleSelection( _this.model.el );
1381 // set gobject values
1384 this.el.selection_changed.connect( (position, n_items) => {
1388 //if (!this.button_is_pressed && !this.key_is_pressed) {
1389 // then event was started by some other action
1390 // which should manually trigger all the events..
1391 // print("SKIPPING select - no button or key pressed\n");
1396 if (_this.view.blockChanges) { // probably not needed..
1397 GLib.debug("SKIPPING select - blockchanges set..");
1401 if (!_this.before_node_change( ) ) {
1402 _this.view.blockChanges = true;
1403 _this.selmodel.el.unselect_all();
1404 _this.view.blockChanges = false;
1408 if (_this.main_window.windowstate.file == null) {
1409 GLib.debug("SKIPPING select windowstate file is not set...");
1413 //var render = this.get('/LeftTree').getRenderer();
1414 GLib.debug("LEFT TREE -> view -> selection changed called");
1417 // -- it appears that the selection is not updated.
1418 // select the node...
1419 //_this.selmodel.el.set_selected(row);
1421 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1423 var snode = _this.selmodel.getSelectedNode();
1424 if (snode == null) {
1426 GLib.debug("selected rows < 1");
1427 //??this.model.load( false);
1428 _this.node_selected(null);
1436 GLib.debug ("calling left_tree.node_selected");
1437 _this.node_selected(snode);
1442 // no need to scroll. it's in the view as we clicked on it.
1443 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1449 // user defined functions
1450 public JsRender.Node? getSelectedNode () {
1451 if (this.el.selected_item == null) {
1454 var tr = (Gtk.TreeListRow)this.el.selected_item;
1455 return (JsRender.Node)tr.get_item();
1458 public JsRender.Node getNodeAt (uint row) {
1460 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1462 var a = tr.get_item();;
1463 GLib.debug("get_item (2) = %s", a.get_type().name());
1466 return (JsRender.Node)tr.get_item();
1470 public class Xcls_model : Object
1472 public Gtk.TreeListModel el;
1473 private Xcls_WindowLeftTree _this;
1479 public Xcls_model(Xcls_WindowLeftTree _owner )
1483 this.el = this.updateModel(null);
1487 // set gobject values
1490 // user defined functions
1491 public void loadFile (JsRender.JsRender f) {
1494 _this.drop.highlightWidget = null;
1496 var m = (GLib.ListStore) this.el.model;
1498 _this.main_window.windowstate.leftTreeNodeSelected(null);
1500 _this.main_window.windowstate.file = f;
1501 _this.last_error_counter = -1;
1503 if (f.tree == null) {
1510 // if it's still null?
1511 if (f.tree == null) {
1512 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1513 _this.updateErrors();
1517 _this.updateErrors();
1519 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1525 public int nodeToRow (JsRender.Node node)
1528 var s = _this.view.el.model as Gtk.SingleSelection;
1529 for (var i = 0; i < s.n_items; i++) {
1530 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1531 var lr = s.get_item(i) as Gtk.TreeListRow;
1532 GLib.debug("check node %s", lr.get_item().get_type().name());
1533 if ((lr.get_item() as JsRender.Node).oid == node.oid) {
1542 public void deleteSelected () {
1546 var node = _this.selmodel.getSelectedNode();
1550 GLib.debug("delete Selected - no node slected?");
1553 _this.selmodel.el.unselect_all();
1556 GLib.debug("delete Selected - done");
1559 print("DELETE SELECTED?");
1560 //_this.view.blockChanges = true;
1561 print("GET SELECTION?");
1563 var s = _this.view.el.get_selection();
1565 print("GET SELECTED?");
1570 if (!s.get_selected(out mod, out iter)) {
1571 return; // nothing seleted..
1576 this.activePath= "";
1577 print("GET vnode value?");
1580 this.el.get_value(iter, 2, out value);
1581 var data = (JsRender.Node)(value.get_object());
1582 print("removing node from Render\n");
1583 if (data.parent == null) {
1584 _this.main_window.windowstate.file.tree = null;
1588 print("removing node from Tree\n");
1590 this.el.remove(ref iter);
1600 this.activePath= ""; // again!?!?
1601 //this.changed(null,true);
1605 _this.view.blockChanges = false;
1608 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1609 this.el = new Gtk.TreeListModel(
1610 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1614 return ((JsRender.Node)item).childstore;
1618 if (_this.selmodel.el == null) {
1621 _this.selmodel.el.set_model(this.el);
1624 public void selectNode (JsRender.Node node)
1626 var row = this.nodeToRow(node);
1627 var s = _this.view.el.model as Gtk.SingleSelection;
1631 GLib.debug("Could not find node");
1634 GLib.debug("Select %d", row);
1635 s.set_selected(row);
1636 _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1637 //_this.node_selected(node);
1644 public class Xcls_maincol : Object
1646 public Gtk.ColumnViewColumn el;
1647 private Xcls_WindowLeftTree _this;
1653 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1656 _this.maincol = this;
1657 var child_1 = new Xcls_SignalListItemFactory14( _this );
1659 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1663 // set gobject values
1664 this.el.id = "maincol";
1665 this.el.expand = true;
1666 this.el.resizable = true;
1669 // user defined functions
1671 public class Xcls_SignalListItemFactory14 : Object
1673 public Gtk.SignalListItemFactory el;
1674 private Xcls_WindowLeftTree _this;
1680 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1683 this.el = new Gtk.SignalListItemFactory();
1687 // set gobject values
1690 this.el.setup.connect( (listitem) => {
1692 var expand = new Gtk.TreeExpander();
1694 expand.set_indent_for_depth(true);
1695 expand.set_indent_for_icon(true);
1696 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1697 var icon = new Gtk.Image();
1698 var lbl = new Gtk.Label("");
1699 lbl.use_markup = true;
1700 lbl.ellipsize = Pango.EllipsizeMode.END;
1702 icon.margin_end = 4;
1703 lbl.justify = Gtk.Justification.LEFT;
1706 // listitem.activatable = true; ??
1710 expand.set_child(hbox);
1711 ((Gtk.ListItem)listitem).set_child(expand);
1714 this.el.bind.connect( (listitem) => {
1715 GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1717 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1718 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1721 var hbox = (Gtk.Box) expand.child;
1724 var img = (Gtk.Image) hbox.get_first_child();
1725 var lbl = (Gtk.Label) img.get_next_sibling();
1727 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1728 var node = (JsRender.Node) lr.get_item();
1730 GLib.debug("node is %s", node.get_type().name());
1731 // was item (1) in old layout
1736 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1737 var clsname = node.fqn();
1739 var clsb = clsname.split(".");
1740 var sub = clsb.length > 1 ? clsb[1].down() : "";
1742 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1746 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1747 img.set_from_file(fn);
1750 img.set_from_paintable(
1752 "media-playback-stop", null, 16,1,
1753 Gtk.TextDirection.NONE, 0
1757 } catch (GLib.Error e) {}
1759 expand.set_hide_expander( !node.hasChildren() );
1760 expand.set_list_row(lr);
1762 node.bind_property("iconFilename",
1764 GLib.BindingFlags.SYNC_CREATE);
1766 node.bind_property("nodeTitleProp",
1768 GLib.BindingFlags.SYNC_CREATE);
1769 node.bind_property("nodeTipProp",
1770 lbl, "tooltip_markup",
1771 GLib.BindingFlags.SYNC_CREATE);
1777 // user defined functions
1781 public class Xcls_ColumnViewColumn15 : Object
1783 public Gtk.ColumnViewColumn el;
1784 private Xcls_WindowLeftTree _this;
1790 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1793 var child_1 = new Xcls_SignalListItemFactory16( _this );
1795 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1799 // set gobject values
1800 this.el.fixed_width = 25;
1803 // user defined functions
1805 public class Xcls_SignalListItemFactory16 : Object
1807 public Gtk.SignalListItemFactory el;
1808 private Xcls_WindowLeftTree _this;
1814 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1817 this.el = new Gtk.SignalListItemFactory();
1821 // set gobject values
1824 this.el.setup.connect( (listitem) => {
1827 var icon = new Gtk.Image();
1829 ((Gtk.ListItem)listitem).set_child(icon);
1831 this.el.bind.connect( (listitem) => {
1833 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1834 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1835 var node = (JsRender.Node) lr.get_item();
1838 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1839 img.set_from_paintable(
1841 "list-add", null, 16,1,
1842 Gtk.TextDirection.NONE, 0
1846 var fqn = node.fqn();
1847 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1849 img.set_visible(cn.size > 0 ? true : false);
1854 // user defined functions
1858 public class Xcls_keystate : Object
1860 public Gtk.EventControllerKey el;
1861 private Xcls_WindowLeftTree _this;
1865 public int is_shift;
1868 public Xcls_keystate(Xcls_WindowLeftTree _owner )
1871 _this.keystate = this;
1872 this.el = new Gtk.EventControllerKey();
1877 // set gobject values
1880 this.el.key_released.connect( (keyval, keycode, state) => {
1881 GLib.debug("key release %d, %d, %d" , (int) keyval, (int) keycode, state);
1882 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
1885 //GLib.debug("set state %d , shift = %d", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);
1890 this.el.key_pressed.connect( (keyval, keycode, state) => {
1892 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
1899 // user defined functions
1903 public class Xcls_LeftTreeMenu : Object
1905 public Gtk.Popover el;
1906 private Xcls_WindowLeftTree _this;
1912 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1915 _this.LeftTreeMenu = this;
1916 this.el = new Gtk.Popover();
1920 // set gobject values
1921 var child_1 = new Xcls_Box19( _this );
1922 this.el.child = child_1.el;
1925 // user defined functions
1927 public class Xcls_Box19 : Object
1930 private Xcls_WindowLeftTree _this;
1936 public Xcls_Box19(Xcls_WindowLeftTree _owner )
1939 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1943 // set gobject values
1944 var child_1 = new Xcls_Button20( _this );
1946 this.el.append( child_1.el );
1947 var child_2 = new Xcls_Button21( _this );
1949 this.el.append( child_2.el );
1950 var child_3 = new Xcls_Button22( _this );
1952 this.el.append( child_3.el );
1955 // user defined functions
1957 public class Xcls_Button20 : Object
1959 public Gtk.Button el;
1960 private Xcls_WindowLeftTree _this;
1966 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1969 this.el = new Gtk.Button();
1973 // set gobject values
1974 this.el.label = "Delete Element";
1977 this.el.clicked.connect( ( ) => {
1978 _this.LeftTreeMenu.el.hide();
1979 _this.model.deleteSelected();
1984 // user defined functions
1987 public class Xcls_Button21 : Object
1989 public Gtk.Button el;
1990 private Xcls_WindowLeftTree _this;
1996 public Xcls_Button21(Xcls_WindowLeftTree _owner )
1999 this.el = new Gtk.Button();
2003 // set gobject values
2004 this.el.label = "Save as Template";
2007 this.el.clicked.connect( () => {
2008 _this.LeftTreeMenu.el.hide();
2009 DialogSaveTemplate.singleton().showIt(
2010 (Gtk.Window) _this.el.get_root (),
2011 _this.main_window.windowstate.file.palete(),
2012 _this.getActiveElement()
2019 // user defined functions
2022 public class Xcls_Button22 : Object
2024 public Gtk.Button el;
2025 private Xcls_WindowLeftTree _this;
2031 public Xcls_Button22(Xcls_WindowLeftTree _owner )
2034 this.el = new Gtk.Button();
2038 // set gobject values
2039 this.el.label = "Save as Module";
2042 this.el.clicked.connect( () => {
2044 _this.LeftTreeMenu.el.hide();
2045 var node = _this.getActiveElement();
2048 var sm = DialogSaveModule.singleton();
2052 (Gtk.Window) _this.el.get_root (),
2053 _this.main_window.windowstate.project,
2057 gtk4 migration - disabled this part.. probably not used muchanyway
2060 if (name.length < 1) {
2064 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
2068 var s = _this.view.el.get_selection();
2070 print("GET SELECTED?");
2075 if (!s.get_selected(out mod, out iter)) {
2076 return; // nothing seleted..
2079 var n_cn = mod.iter_n_children(iter) -1;
2080 for (var i = n_cn; i > -1; i--) {
2081 mod.iter_nth_child(out citer, iter, i);
2084 print("removing node from Tree\n");
2086 _this.model.el.remove(ref citer);
2089 _this.node_selected(node, "tree");
2095 // user defined functions