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);
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();
56 if (this.last_error_counter != file.error_counter) {
60 this.last_error_counter = file.error_counter ;
64 if (this.last_error_counter == file.error_counter) {
69 foreach(var diag in ar) {
72 // print("get inter\n");
73 var node= file.lineToNode( (int)diag.range.start.line) ;
77 var row = _this.model.nodeToRow(node);
81 var w = this.view.getWidgetAtRow(row);
85 // always show errors.
86 var ed = diag.category.down();
87 if (ed != "err" && w.has_css_class("node-err")) {
90 if (ed == "err" && w.has_css_class("node-warn")) {
91 w.remove_css_class("node-warn");
93 if (ed == "err" && w.has_css_class("node-depr")) {
94 w.remove_css_class("node-depr");
96 if (!w.has_css_class("node-"+ ed)) {
97 w.add_css_class("node-" + ed);
103 public void onresize () {
106 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
107 // _this.maincol.el.set_max_width( _this.viewwin.el.get_width() - 32 );
109 public void removeErrors () {
110 var child = this.view.el.get_first_child();
112 var reading_header = true;
114 while (child != null) {
115 //GLib.debug("Got %s", child.get_type().name());
117 if (reading_header) {
120 if (child.get_type().name() != "GtkColumnListView") {
122 child = child.get_next_sibling();
125 // should be columnlistview
126 child = child.get_first_child();
130 reading_header = false;
134 if (child.has_css_class("node-err")) {
135 child.remove_css_class("node-err");
137 if (child.has_css_class("node-warn")) {
138 child.remove_css_class("node-warn");
141 if (child.has_css_class("node-depr")) {
142 child.remove_css_class("node-depr");
145 child = child.get_next_sibling();
147 //GLib.debug("Rturning null");
150 public JsRender.Node? getActiveElement () { // return path to actie node.
153 return _this.selmodel.getSelectedNode();
157 public JsRender.JsRender getActiveFile () {
158 return this.main_window.windowstate.file;
160 public class Xcls_ListView2 : Object
162 public Gtk.ListView el;
163 private Xcls_WindowLeftTree _this;
169 public Xcls_ListView2(Xcls_WindowLeftTree _owner )
172 var child_1 = new Xcls_SignalListItemFactory3( _this );
174 this.el = new Gtk.ListView( null, child_1.el );
178 // set gobject values
181 // user defined functions
183 public class Xcls_SignalListItemFactory3 : Object
185 public Gtk.SignalListItemFactory el;
186 private Xcls_WindowLeftTree _this;
192 public Xcls_SignalListItemFactory3(Xcls_WindowLeftTree _owner )
195 this.el = new Gtk.SignalListItemFactory();
199 // set gobject values
202 // user defined functions
206 public class Xcls_viewwin : Object
208 public Gtk.ScrolledWindow el;
209 private Xcls_WindowLeftTree _this;
215 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
218 _this.viewwin = this;
219 this.el = new Gtk.ScrolledWindow();
223 // set gobject values
224 this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
225 this.el.has_frame = true;
226 this.el.hexpand = true;
227 this.el.vexpand = true;
228 this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
229 new Xcls_view( _this );
230 this.el.child = _this.view.el;
231 new Xcls_LeftTreeMenu( _this );
234 // user defined functions
236 public class Xcls_view : Object
238 public Gtk.ColumnView el;
239 private Xcls_WindowLeftTree _this;
243 public bool blockChanges;
244 public bool headers_visible;
245 public string lastEventSource;
246 public bool button_is_pressed;
247 public Gtk.CssProvider css;
248 public JsRender.Node? dragNode;
251 public Xcls_view(Xcls_WindowLeftTree _owner )
255 new Xcls_selmodel( _this );
256 this.el = new Gtk.ColumnView( _this.selmodel.el );
259 this.blockChanges = false;
260 this.headers_visible = false;
261 this.lastEventSource = "";
262 this.button_is_pressed = false;
263 this.dragNode = null;
265 // set gobject values
266 this.el.name = "left-tree-view";
267 this.el.hexpand = false;
268 this.el.vexpand = true;
269 var child_2 = new Xcls_GestureClick6( _this );
271 this.el.add_controller( child_2.el );
272 var child_3 = new Xcls_GestureClick7( _this );
274 this.el.add_controller( child_3.el );
275 var child_4 = new Xcls_DragSource8( _this );
277 this.el.add_controller( child_4.el );
278 var child_5 = new Xcls_EventControllerKey9( _this );
280 this.el.add_controller( child_5.el );
281 new Xcls_keystate( _this );
282 this.el.add_controller( _this.keystate.el );
283 new Xcls_drop( _this );
284 this.el.add_controller( _this.drop.el );
285 new Xcls_maincol( _this );
286 this.el.append_column ( _this.maincol.el );
287 var child_9 = new Xcls_ColumnViewColumn16( _this );
289 this.el.append_column ( child_9.el );
295 this.css = new Gtk.CssProvider();
297 this.css.load_from_string("
298 #left-tree-view { font-size: 12px;}
299 .drag-over { background-color:#88a3bc; }
301 border-bottom-width: 5px;
302 border-bottom-style: solid;
303 border-bottom-color: #88a3bc;
306 border-top-width: 5px;
307 border-top-style: solid;
308 border-top-color: #88a3bc;
311 border-top-width: 5px;
312 border-top-style: solid;
313 border-top-color: red;
314 border-bottom-width: 5px;
315 border-bottom-style: solid;
316 border-bottom-color: red;
319 border-top-width: 5px;
320 border-top-style: solid;
321 border-top-color: #ABF4EB;
322 border-bottom-width: 5px;
323 border-bottom-style: solid;
324 border-bottom-color: #ABF4EB;
327 border-top-width: 5px;
328 border-top-style: solid;
329 border-top-color: #EEA9FF;
330 border-bottom-width: 5px;
331 border-bottom-style: solid;
332 border-bottom-color: #EEA9FF;
335 #left-tree-view indent {
336 -gtk-icon-size : 2px;
338 #left-tree-view indent:nth-last-child(2) {
343 Gtk.StyleContext.add_provider_for_display(
344 this.el.get_display(),
346 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
353 // user defined functions
354 public Gtk.Widget? getWidgetAtRow (uint row) {
357 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
358 var colview = gesture.widget;
359 var line_no = check_list_widget(colview, x,y);
361 var item = colview.model.get_item(line_no);
365 //GLib.debug("Get Widget At Row %d", (int)row);
366 var child = this.el.get_first_child();
368 var reading_header = true;
370 while (child != null) {
371 GLib.debug("Got %s", child.get_type().name());
373 if (reading_header) {
376 if (child.get_type().name() != "GtkColumnListView") {
378 child = child.get_next_sibling();
381 // should be columnlistview
382 child = child.get_first_child();
386 reading_header = false;
393 if (line_no == row) {
394 //GLib.debug("Returning widget %s", child.get_type().name());
395 return (Gtk.Widget)child;
397 child = child.get_next_sibling();
399 //GLib.debug("Rturning null");
403 public int getColAt (double x, double y) {
406 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
409 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
410 //GLib.debug("Cehck %d, %d", x,y);
411 var child = this.el.get_first_child();
415 while (child != null) {
417 if (child.get_type().name() == "GtkColumnViewRowWidget") {
418 child = child.get_first_child();
422 //child.get_allocation(out alloc);
423 if (x < (child.get_width() + offx)) {
427 //offx += child.get_width();
429 //child = child.get_next_sibling();
436 public int getRowAt (double x, double in_y, out string pos) {
443 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
444 var colview = gesture.widget;
445 var line_no = check_list_widget(colview, x,y);
447 var item = colview.model.get_item(line_no);
453 //GLib.debug("offset = %d y = %d", (int) voff, (int) in_y);
454 var y = in_y + _this.viewwin.el.vadjustment.value;
455 var child = this.el.get_first_child();
456 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
458 var reading_header = true;
460 var header_height = 0;
463 while (child != null) {
464 //GLib.debug("Got %s", child.get_type().name());
465 if (reading_header) {
468 if (child.get_type().name() != "GtkColumnListView") {
469 h += child.get_height();
470 child = child.get_next_sibling();
473 // should be columnlistview
474 child = child.get_first_child();
475 //GLib.debug("header height=%d", h);
478 reading_header = false;
483 if (child.get_type().name() != "GtkColumnViewRowWidget") {
484 child = child.get_next_sibling();
488 if (y < header_height) {
493 var hh = child.get_height();
495 if (child.has_css_class("node-err") ||
496 child.has_css_class("node-warn") ||
497 child.has_css_class("node-depr")) {
501 //child.get_allocation(out alloc);
502 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
503 //GLib.debug("row %d y= %d %s", line_no, (int) (header_height + alloc.y),
505 // child.visible ? "VIS" : "hidden");
507 if (y > (header_height + real_y) && y <= (header_height + real_y + hh) ) {
508 if (y > ( header_height + real_y + (hh * 0.8))) {
510 } else if (y > ( header_height + real_y + (hh * 0.2))) {
515 GLib.debug("getRowAt return : %d, %s", line_no, pos);
520 if (real_y + hh > y) {
524 child = child.get_next_sibling();
529 public Gtk.Widget? getWidgetAt (double x, double in_y) {
532 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
533 var colview = gesture.widget;
534 var line_no = check_list_widget(colview, x,y);
536 var item = colview.model.get_item(line_no);
540 var y = in_y + _this.viewwin.el.vadjustment.value;
541 var child = this.el.get_first_child();
542 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
544 var reading_header = true;
546 var header_height = 0;
548 while (child != null) {
549 //GLib.debug("Got %s", child.get_type().name());
550 if (reading_header) {
553 if (child.get_type().name() != "GtkColumnListView") {
554 h += child.get_height();
555 child = child.get_next_sibling();
558 // should be columnlistview
559 child = child.get_first_child();
560 GLib.debug("header height=%d", h);
563 reading_header = false;
568 if (y < header_height) {
572 var hh = child.get_height();
573 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
574 if (child.has_css_class("node-err") ||
575 child.has_css_class("node-warn") ||
576 child.has_css_class("node-depr")) {
580 if (y > curr_y && y <= header_height + hh + curr_y ) {
581 return (Gtk.Widget)child;
588 child = child.get_next_sibling();
594 public class Xcls_GestureClick6 : Object
596 public Gtk.GestureClick el;
597 private Xcls_WindowLeftTree _this;
603 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
606 this.el = new Gtk.GestureClick();
610 // set gobject values
613 this.el.released.connect( (n_press, x, y) => {
615 _this.view.button_is_pressed = false;
619 this.el.pressed.connect( (n_press, x, y) => {
621 //console.log("button press?");
623 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
627 _this.view.button_is_pressed = true;
629 _this.view.lastEventSource = "tree";
630 if (! _this.before_node_change() ) {
631 GLib.debug("before_node_change return false");
635 // nothing there -show dialog
636 if (_this.model.el.get_n_items() < 1) {
637 _this.main_window.windowstate.showAddObject(_this.view.el, null);
638 GLib.debug("no items");
642 var row = _this.view.getRowAt(x,y, out pos );
644 GLib.debug("no row selected items");
648 var node = _this.selmodel.getNodeAt(row);
650 GLib.warning("No node found at row %d", row);
656 if (_this.view.getColAt(x,y) > 0 ) {
657 GLib.debug("add colum clicked.");
658 var fqn = node.fqn();
659 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
664 _this.main_window.windowstate.leftTreeBeforeChange();
665 //_this.view.el.get_selection().select_path(res);
666 GLib.debug("Button Pressed - start show window");
667 _this.main_window.windowstate.showAddObject(_this.view.el, node);
668 GLib.debug("Button Pressed - finsihed show window");
677 // user defined functions
680 public class Xcls_GestureClick7 : Object
682 public Gtk.GestureClick el;
683 private Xcls_WindowLeftTree _this;
689 public Xcls_GestureClick7(Xcls_WindowLeftTree _owner )
692 this.el = new Gtk.GestureClick();
696 // set gobject values
700 this.el.pressed.connect( (n_press, x, y) => {
705 if (_this.model.el.get_n_items() < 1) {
707 GLib.debug("no items");
711 var row = _this.view.getRowAt(x,y, out pos );
713 GLib.debug("no row selected items");
717 var node = _this.selmodel.getNodeAt(row);
719 GLib.warning("No node found at row %d", row);
724 _this.model.selectNode(node);
728 GLib.debug("Prssed %d", (int) this.el.get_current_button());
729 //_this.deletemenu.el.set_parent(_this.view.el);
730 _this.LeftTreeMenu.el.set_parent(_this.view.el);
733 //Gtk.Allocation rect;
734 //_this.view.el.get_allocation(out rect);
735 //_this.deletemenu.el.set_has_arrow(false);
736 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
739 _this.LeftTreeMenu.el.set_offset(
741 (int)y - (int)_this.view.el.get_height());
743 _this.LeftTreeMenu.el.popup();
748 // user defined functions
751 public class Xcls_DragSource8 : Object
753 public Gtk.DragSource el;
754 private Xcls_WindowLeftTree _this;
760 public Xcls_DragSource8(Xcls_WindowLeftTree _owner )
763 this.el = new Gtk.DragSource();
767 // set gobject values
768 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
771 this.el.drag_cancel.connect( (drag, reason) => {
773 _this.view.dragNode = null;
776 this.el.prepare.connect( (x, y) => {
780 /// ( drag_context, data, info, time) => {
783 //print("drag-data-get");
784 var ndata = _this.selmodel.getSelectedNode();
786 GLib.debug("return empty string - no selection..");
792 //data.set_text(tp,tp.length);
794 var str = ndata.toJsonString();
795 GLib.debug("prepare store: %s", str);
796 GLib.Value ov = GLib.Value(typeof(string));
798 var cont = new Gdk.ContentProvider.for_value(ov);
800 GLib.Value v = GLib.Value(typeof(string));
801 //var str = drop.read_text( [ "text/plain" ] 0);
803 cont.get_value(ref v);
806 GLib.debug("set %s", v.get_string());
812 this.el.drag_begin.connect( ( drag ) => {
813 GLib.debug("SOURCE: drag-begin");
815 // find what is selected in our tree...
816 var data = _this.selmodel.getSelectedNode();
820 _this.view.dragNode = data;
821 var xname = data.fqn();
822 GLib.debug ("XNAME IS %s", xname);
824 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
827 var paintable = new Gtk.WidgetPaintable(widget);
828 this.el.set_icon(paintable, 0,0);
832 this.el.drag_end.connect( (drag, delete_data) => {
834 _this.view.dragNode = null;
838 // user defined functions
841 public class Xcls_EventControllerKey9 : Object
843 public Gtk.EventControllerKey el;
844 private Xcls_WindowLeftTree _this;
850 public Xcls_EventControllerKey9(Xcls_WindowLeftTree _owner )
853 this.el = new Gtk.EventControllerKey();
857 // set gobject values
860 this.el.key_pressed.connect( (keyval, keycode, state) => {
864 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
868 _this.model.deleteSelected();
874 // user defined functions
877 public class Xcls_keystate : Object
879 public Gtk.EventControllerKey el;
880 private Xcls_WindowLeftTree _this;
887 public Xcls_keystate(Xcls_WindowLeftTree _owner )
890 _this.keystate = this;
891 this.el = new Gtk.EventControllerKey();
896 // set gobject values
899 this.el.key_released.connect( (keyval, keycode, state) => {
900 GLib.debug("key release %d, %d, %d" , (int) keyval, (int) keycode, state);
901 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
904 //GLib.debug("set state %d , shift = %d", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);
909 this.el.key_pressed.connect( (keyval, keycode, state) => {
911 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
918 // user defined functions
921 public class Xcls_drop : Object
923 public Gtk.DropTarget el;
924 private Xcls_WindowLeftTree _this;
928 public Gtk.Widget? highlightWidget;
929 public JsRender.Node? lastDragNode;
930 public string lastDragString;
933 public Xcls_drop(Xcls_WindowLeftTree _owner )
937 this.el = new Gtk.DropTarget ( typeof(string) ,
938 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
941 this.highlightWidget = null;
942 this.lastDragNode = null;
943 this.lastDragString = "";
945 // set gobject values
948 this.el.accept.connect( (drop) => {
950 GLib.debug("got DropTarget:accept");
952 // NOT REALLY NEEDED? = put stuff in drop?
955 /* ( ctx, x, y, time) => {
956 //Seed.print("TARGET: drag-drop");
959 var src = Gtk.drag_get_source_widget(ctx);
961 if (src != this.el) {
965 this.drag_in_motion = false;
966 // request data that will be recieved by the recieve...
969 this.el, // will receive 'drag-data-received' signal
970 ctx, // represents the current state of the DnD
971 Gdk.Atom.intern("application/json",true), // the target type we want
976 // No target offered by source => error
982 // handle drop around self..
986 //print("GETTING POS");
990 Gtk.TreeViewDropPosition pos;
991 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
993 // if there are not items in the tree.. the we have to set isOver to true for anything..
995 if (_this.model.el.iter_n_children(null) < 1) {
996 print("got NO children?\n");
999 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
1004 //var action = Gdk.DragAction.COPY;
1005 // unless we are copying!!! ctl button..
1007 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
1008 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
1009 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
1012 if (_this.model.el.iter_n_children(null) < 1) {
1013 // no children.. -- asume it's ok..
1015 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
1017 // continue through to allow drop...
1025 //print("ISOVER? " + isOver);
1028 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1029 return true; // not over apoint!?! - no action on drop or motion..
1032 // drag node is parent of child..
1033 //console.log("SRC TREEPATH: " + src.treepath);
1034 //console.log("TARGET TREEPATH: " + data.path.to_string());
1036 // nned to check a few here..
1037 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
1038 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
1039 //Gtk.TreeViewDropPosition.AFTER
1040 //Gtk.TreeViewDropPosition.BEFORE
1042 // locally dragged items to not really use the
1043 var selection_text = this.dragData;
1047 if (selection_text == null || selection_text.length < 1) {
1048 //print("Error - drag selection text returned NULL");
1050 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1051 return true; /// -- fixme -- this is not really correct..
1054 // see if we are dragging into ourself?
1055 print ("got selection text of " + selection_text);
1057 var target_path = path.to_string();
1058 //print("target_path="+target_path);
1061 if (selection_text == target_path) {
1062 print("self drag ?? == we should perhaps allow copy onto self..\n");
1064 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1066 return true; /// -- fixme -- this is not really correct..
1071 //print("DUMPING DATA");
1072 //console.dump(data);
1075 //print(data.path.to_string() +' => '+ data.pos);
1077 // dropList is a list of xtypes that this node could be dropped on.
1078 // it is set up when we start to drag..
1081 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
1083 print("targetDAta: " + targetData +"\n");
1085 if (targetData.length < 1) {
1086 //print("Can not find drop node path");
1088 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1094 // continue on to allow drop..
1096 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
1099 var delete_selection_data = false;
1101 if (action == Gdk.DragAction.ASK) {
1102 // Ask the user to move or copy, then set the ctx action.
1105 if (action == Gdk.DragAction.MOVE) {
1106 delete_selection_data = true;
1109 // drag around.. - reorder..
1110 _this.model.moveNode(targetData, action);
1116 // we can send stuff to souce here...
1119 // do we always say failure, so we handle the reall drop?
1120 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
1133 this.el.motion.connect( ( x, y) => {
1135 var is_shift = _this.keystate.is_shift > 0;
1137 GLib.debug("shift is %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
1138 string pos; // over / before / after..
1140 //GLib.debug("got drag motion");
1142 GLib.Value v = GLib.Value(typeof(string));
1143 //var str = drop.read_text( [ "text/plain" ] 0);
1144 var cont = this.el.current_drop.get_drag().content ;
1146 cont.get_value(ref v);
1147 } catch (GLib.Error e) {
1148 GLib.debug("failed to get drag value");
1149 return Gdk.DragAction.COPY;
1153 //GLib.debug("got %s", v.get_string());
1155 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1156 // still dragging same node
1158 this.lastDragNode = new JsRender.Node();
1159 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1163 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
1164 this.lastDragNode.fqn());
1167 foreach(var dp in drop_on_to) {
1170 GLib.debug("droplist: %s", string.joinv(", ", str));
1173 // if there are not items in the tree.. the we have to set isOver to true for anything..
1175 if (_this.model.el.n_items < 1) {
1176 // FIXME check valid drop types?
1177 if (drop_on_to.contains("*top")) {
1178 this.addHighlight(_this.view.el, "over");
1180 this.addHighlight(null, "");
1183 return Gdk.DragAction.COPY; // no need to highlight?
1188 GLib.debug("check is over");
1190 // if path of source and dest are inside each other..
1191 // need to add source info to drag?
1193 var row = _this.view.getRowAt(x,y, out pos);
1196 this.addHighlight(null, "");
1197 return Gdk.DragAction.COPY;
1199 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1201 var node = (JsRender.Node)tr.get_item();
1203 GLib.debug("Drop over node: %s", node.fqn());
1206 if (pos == "above" || pos == "below") {
1207 if (node.parent == null) {
1208 GLib.debug("no parent try center");
1212 if (!drop_on_to.contains(node.parent.fqn())) {
1213 GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1216 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1217 if (_this.view.dragNode != null && is_shift) {
1218 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1219 GLib.debug("shift drop not self not allowed");
1220 this.addHighlight(null, "");
1221 return Gdk.DragAction.COPY;
1234 if (pos == "over") {
1235 if (!drop_on_to.contains(node.fqn())) {
1236 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1237 this.addHighlight(null, "");
1238 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1240 if (_this.view.dragNode != null && is_shift) {
1241 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1242 GLib.debug("shift drop not self not allowed");
1243 this.addHighlight(null, "");
1244 return Gdk.DragAction.COPY;
1251 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1252 var w = _this.view.getWidgetAt(x,y);
1253 this.addHighlight(w, pos);
1254 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1256 this.el.leave.connect( ( ) => {
1257 this.addHighlight(null,"");
1260 this.el.drop.connect( (v, x, y) => {
1262 this.addHighlight(null,"");
1264 var is_shift = _this.keystate.is_shift > 0;
1267 // -- get position..
1268 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1269 // still dragging same node
1271 this.lastDragNode = new JsRender.Node();
1272 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1277 var dropNode = new JsRender.Node();
1278 dropNode.loadFromJsonString(v.get_string(), 1);
1279 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1281 // if there are not items in the tree.. the we have to set isOver to true for anything..
1283 if (_this.model.el.n_items < 1) {
1284 // FIXME check valid drop types?
1285 if (!drop_on_to.contains("*top")) {
1286 GLib.debug("drop on to list does not contain top?");
1289 // add new node to top..
1292 var m = (GLib.ListStore) _this.model.el.model;
1293 _this.main_window.windowstate.file.tree = dropNode;
1297 _this.model.selectNode(dropNode);
1299 return true; // no need to highlight?
1305 var row = _this.view.getRowAt(x,y, out pos);
1307 return false; //Gdk.DragAction.COPY;
1309 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1311 var node = (JsRender.Node)tr.get_item();
1313 if (pos == "above" || pos == "below") {
1314 if (node.parent == null) {
1317 if (!drop_on_to.contains(node.parent.fqn())) {
1320 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1321 if (_this.view.dragNode != null && is_shift) {
1322 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1323 GLib.debug("shift drop not self not allowed");
1334 if (pos == "over") {
1335 if (!drop_on_to.contains(node.fqn())) {
1336 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1340 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1341 GLib.debug("shift drop not self not allowed");
1348 node.appendChild(dropNode);
1349 if (is_shift && _this.view.dragNode != null) {
1350 _this.model.selectNode(null);
1351 _this.view.dragNode.remove();
1355 _this.model.selectNode(dropNode);
1361 GLib.debug("Above - insertBefore");
1363 node.parent.insertBefore(dropNode, node);
1364 if (is_shift && _this.view.dragNode != null) {
1365 _this.model.selectNode(null);
1366 _this.view.dragNode.remove();
1369 _this.model.selectNode(dropNode);
1374 GLib.debug("Below - insertAfter");
1375 if (is_shift && _this.view.dragNode != null) {
1376 _this.model.selectNode(null);
1377 _this.view.dragNode.remove();
1381 node.parent.insertAfter(dropNode, node);
1382 _this.model.selectNode(dropNode);
1388 // should not happen
1400 // user defined functions
1401 public void addHighlight (Gtk.Widget? w, string hl) {
1402 if (this.highlightWidget != null) {
1403 var ww = this.highlightWidget;
1404 GLib.debug("clear drag from previous highlight");
1405 if (ww.has_css_class("drag-below")) {
1406 ww.remove_css_class("drag-below");
1408 if (ww.has_css_class("drag-above")) {
1409 ww.remove_css_class("drag-above");
1411 if (ww.has_css_class("drag-over")) {
1412 ww.remove_css_class("drag-over");
1416 GLib.debug("add drag=%s to widget", hl);
1417 if (!w.has_css_class("drag-" + hl)) {
1418 w.add_css_class("drag-" + hl);
1421 this.highlightWidget = w;
1425 public class Xcls_selmodel : Object
1427 public Gtk.SingleSelection el;
1428 private Xcls_WindowLeftTree _this;
1434 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1437 _this.selmodel = this;
1438 new Xcls_model( _this );
1439 this.el = new Gtk.SingleSelection( _this.model.el );
1443 // set gobject values
1446 this.el.selection_changed.connect( (position, n_items) => {
1450 //if (!this.button_is_pressed && !this.key_is_pressed) {
1451 // then event was started by some other action
1452 // which should manually trigger all the events..
1453 // print("SKIPPING select - no button or key pressed\n");
1458 if (_this.view.blockChanges) { // probably not needed..
1459 GLib.debug("SKIPPING select - blockchanges set..");
1463 if (!_this.before_node_change( ) ) {
1464 _this.view.blockChanges = true;
1465 _this.selmodel.el.unselect_all();
1466 _this.view.blockChanges = false;
1470 if (_this.main_window.windowstate.file == null) {
1471 GLib.debug("SKIPPING select windowstate file is not set...");
1475 //var render = this.get('/LeftTree').getRenderer();
1476 GLib.debug("LEFT TREE -> view -> selection changed called");
1479 // -- it appears that the selection is not updated.
1480 // select the node...
1481 //_this.selmodel.el.set_selected(row);
1483 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1485 var snode = _this.selmodel.getSelectedNode();
1486 if (snode == null) {
1488 GLib.debug("selected rows < 1");
1489 //??this.model.load( false);
1490 _this.node_selected(null);
1498 GLib.debug ("calling left_tree.node_selected");
1499 _this.node_selected(snode);
1504 // no need to scroll. it's in the view as we clicked on it.
1505 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1511 // user defined functions
1512 public JsRender.Node? getSelectedNode () {
1513 if (this.el.selected_item == null) {
1516 var tr = (Gtk.TreeListRow)this.el.selected_item;
1517 return (JsRender.Node)tr.get_item();
1520 public JsRender.Node getNodeAt (uint row) {
1522 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1524 var a = tr.get_item();;
1525 GLib.debug("get_item (2) = %s", a.get_type().name());
1528 return (JsRender.Node)tr.get_item();
1532 public class Xcls_model : Object
1534 public Gtk.TreeListModel el;
1535 private Xcls_WindowLeftTree _this;
1541 public Xcls_model(Xcls_WindowLeftTree _owner )
1545 this.el = this.updateModel(null);
1549 // set gobject values
1552 // user defined functions
1553 public void loadFile (JsRender.JsRender f) {
1556 _this.drop.highlightWidget = null;
1558 var m = (GLib.ListStore) this.el.model;
1560 _this.main_window.windowstate.leftTreeNodeSelected(null);
1562 _this.main_window.windowstate.file = f;
1563 _this.last_error_counter = -1;
1565 if (f.tree == null) {
1572 // if it's still null?
1573 if (f.tree == null) {
1574 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1575 _this.updateErrors();
1579 _this.updateErrors();
1581 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1587 public int nodeToRow (JsRender.Node node)
1590 var s = _this.view.el.model as Gtk.SingleSelection;
1591 for (var i = 0; i < s.n_items; i++) {
1592 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1593 var lr = s.get_item(i) as Gtk.TreeListRow;
1594 GLib.debug("check node %s", lr.get_item().get_type().name());
1595 if ((lr.get_item() as JsRender.Node).oid == node.oid) {
1604 public void deleteSelected () {
1608 var node = _this.selmodel.getSelectedNode();
1612 GLib.debug("delete Selected - no node slected?");
1615 _this.selmodel.el.unselect_all();
1618 GLib.debug("delete Selected - done");
1621 print("DELETE SELECTED?");
1622 //_this.view.blockChanges = true;
1623 print("GET SELECTION?");
1625 var s = _this.view.el.get_selection();
1627 print("GET SELECTED?");
1632 if (!s.get_selected(out mod, out iter)) {
1633 return; // nothing seleted..
1638 this.activePath= "";
1639 print("GET vnode value?");
1642 this.el.get_value(iter, 2, out value);
1643 var data = (JsRender.Node)(value.get_object());
1644 print("removing node from Render\n");
1645 if (data.parent == null) {
1646 _this.main_window.windowstate.file.tree = null;
1650 print("removing node from Tree\n");
1652 this.el.remove(ref iter);
1662 this.activePath= ""; // again!?!?
1663 //this.changed(null,true);
1667 _this.view.blockChanges = false;
1670 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1671 this.el = new Gtk.TreeListModel(
1672 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1676 return ((JsRender.Node)item).childstore;
1680 if (_this.selmodel.el == null) {
1683 _this.selmodel.el.set_model(this.el);
1686 public void selectNode (JsRender.Node node)
1688 var row = this.nodeToRow(node);
1689 var s = _this.view.el.model as Gtk.SingleSelection;
1693 GLib.debug("Could not find node");
1696 GLib.debug("Select %d", row);
1697 s.set_selected(row);
1698 _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1699 //_this.node_selected(node);
1706 public class Xcls_maincol : Object
1708 public Gtk.ColumnViewColumn el;
1709 private Xcls_WindowLeftTree _this;
1715 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1718 _this.maincol = this;
1719 var child_1 = new Xcls_SignalListItemFactory15( _this );
1721 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1725 // set gobject values
1726 this.el.id = "maincol";
1727 this.el.expand = true;
1728 this.el.resizable = true;
1731 // user defined functions
1733 public class Xcls_SignalListItemFactory15 : Object
1735 public Gtk.SignalListItemFactory el;
1736 private Xcls_WindowLeftTree _this;
1742 public Xcls_SignalListItemFactory15(Xcls_WindowLeftTree _owner )
1745 this.el = new Gtk.SignalListItemFactory();
1749 // set gobject values
1752 this.el.setup.connect( (listitem) => {
1754 var expand = new Gtk.TreeExpander();
1756 expand.set_indent_for_depth(true);
1757 expand.set_indent_for_icon(true);
1758 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1759 var icon = new Gtk.Image();
1760 var lbl = new Gtk.Label("");
1761 lbl.use_markup = true;
1762 lbl.ellipsize = Pango.EllipsizeMode.END;
1764 icon.margin_end = 4;
1765 lbl.justify = Gtk.Justification.LEFT;
1768 // listitem.activatable = true; ??
1772 expand.set_child(hbox);
1773 ((Gtk.ListItem)listitem).set_child(expand);
1776 this.el.bind.connect( (listitem) => {
1777 GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1779 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1780 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1783 var hbox = (Gtk.Box) expand.child;
1786 var img = (Gtk.Image) hbox.get_first_child();
1787 var lbl = (Gtk.Label) img.get_next_sibling();
1789 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1790 var node = (JsRender.Node) lr.get_item();
1792 GLib.debug("node is %s", node.get_type().name());
1793 // was item (1) in old layout
1798 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1799 var clsname = node.fqn();
1801 var clsb = clsname.split(".");
1802 var sub = clsb.length > 1 ? clsb[1].down() : "";
1804 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1808 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1809 img.set_from_file(fn);
1812 img.set_from_paintable(
1814 "media-playback-stop", null, 16,1,
1815 Gtk.TextDirection.NONE, 0
1819 } catch (GLib.Error e) {}
1821 expand.set_hide_expander( !node.hasChildren() );
1822 expand.set_list_row(lr);
1824 node.bind_property("iconFilename",
1826 GLib.BindingFlags.SYNC_CREATE);
1828 node.bind_property("nodeTitleProp",
1830 GLib.BindingFlags.SYNC_CREATE);
1831 node.bind_property("nodeTipProp",
1832 lbl, "tooltip_markup",
1833 GLib.BindingFlags.SYNC_CREATE);
1839 // user defined functions
1843 public class Xcls_ColumnViewColumn16 : Object
1845 public Gtk.ColumnViewColumn el;
1846 private Xcls_WindowLeftTree _this;
1852 public Xcls_ColumnViewColumn16(Xcls_WindowLeftTree _owner )
1855 var child_1 = new Xcls_SignalListItemFactory17( _this );
1857 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1861 // set gobject values
1862 this.el.fixed_width = 25;
1865 // user defined functions
1867 public class Xcls_SignalListItemFactory17 : Object
1869 public Gtk.SignalListItemFactory el;
1870 private Xcls_WindowLeftTree _this;
1876 public Xcls_SignalListItemFactory17(Xcls_WindowLeftTree _owner )
1879 this.el = new Gtk.SignalListItemFactory();
1883 // set gobject values
1886 this.el.setup.connect( (listitem) => {
1889 var icon = new Gtk.Image();
1891 ((Gtk.ListItem)listitem).set_child(icon);
1893 this.el.bind.connect( (listitem) => {
1895 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1896 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1897 var node = (JsRender.Node) lr.get_item();
1900 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1901 img.set_from_paintable(
1903 "list-add", null, 16,1,
1904 Gtk.TextDirection.NONE, 0
1908 var fqn = node.fqn();
1909 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1911 img.set_visible(cn.size > 0 ? true : false);
1916 // user defined functions
1921 public class Xcls_LeftTreeMenu : Object
1923 public Gtk.Popover el;
1924 private Xcls_WindowLeftTree _this;
1930 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1933 _this.LeftTreeMenu = this;
1934 this.el = new Gtk.Popover();
1938 // set gobject values
1939 var child_1 = new Xcls_Box19( _this );
1940 this.el.child = child_1.el;
1943 // user defined functions
1945 public class Xcls_Box19 : Object
1948 private Xcls_WindowLeftTree _this;
1954 public Xcls_Box19(Xcls_WindowLeftTree _owner )
1957 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1961 // set gobject values
1962 var child_1 = new Xcls_Button20( _this );
1964 this.el.append( child_1.el );
1965 var child_2 = new Xcls_Button21( _this );
1967 this.el.append( child_2.el );
1968 var child_3 = new Xcls_Button22( _this );
1970 this.el.append( child_3.el );
1973 // user defined functions
1975 public class Xcls_Button20 : Object
1977 public Gtk.Button el;
1978 private Xcls_WindowLeftTree _this;
1984 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1987 this.el = new Gtk.Button();
1991 // set gobject values
1992 this.el.label = "Delete Element";
1995 this.el.clicked.connect( ( ) => {
1996 _this.LeftTreeMenu.el.hide();
1997 _this.model.deleteSelected();
2002 // user defined functions
2005 public class Xcls_Button21 : Object
2007 public Gtk.Button el;
2008 private Xcls_WindowLeftTree _this;
2014 public Xcls_Button21(Xcls_WindowLeftTree _owner )
2017 this.el = new Gtk.Button();
2021 // set gobject values
2022 this.el.label = "Save as Template";
2025 this.el.clicked.connect( () => {
2026 _this.LeftTreeMenu.el.hide();
2027 DialogSaveTemplate.singleton().showIt(
2028 (Gtk.Window) _this.el.get_root (),
2029 _this.main_window.windowstate.file.palete(),
2030 _this.getActiveElement()
2037 // user defined functions
2040 public class Xcls_Button22 : Object
2042 public Gtk.Button el;
2043 private Xcls_WindowLeftTree _this;
2049 public Xcls_Button22(Xcls_WindowLeftTree _owner )
2052 this.el = new Gtk.Button();
2056 // set gobject values
2057 this.el.label = "Save as Module";
2060 this.el.clicked.connect( () => {
2062 _this.LeftTreeMenu.el.hide();
2063 var node = _this.getActiveElement();
2066 var sm = DialogSaveModule.singleton();
2070 (Gtk.Window) _this.el.get_root (),
2071 _this.main_window.windowstate.project,
2075 gtk4 migration - disabled this part.. probably not used muchanyway
2078 if (name.length < 1) {
2082 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
2086 var s = _this.view.el.get_selection();
2088 print("GET SELECTED?");
2093 if (!s.get_selected(out mod, out iter)) {
2094 return; // nothing seleted..
2097 var n_cn = mod.iter_n_children(iter) -1;
2098 for (var i = n_cn; i > -1; i--) {
2099 mod.iter_nth_child(out citer, iter, i);
2102 print("removing node from Tree\n");
2104 _this.model.el.remove(ref citer);
2107 _this.node_selected(node, "tree");
2113 // user defined functions