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_ListView1( _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();
58 var ar = file.getErrors();
59 if (ar == null || ar.size < 1) {
60 if (this.last_error_counter != file.error_counter) {
64 this.last_error_counter = file.error_counter ;
68 if (this.last_error_counter == file.error_counter) {
73 foreach(var diag in ar) {
76 // print("get inter\n");
77 var node= file.lineToNode( (int)diag.range.start.line) ;
81 var row = _this.model.nodeToRow(node);
85 var w = this.view.getWidgetAtRow(row);
89 // always show errors.
90 var ed = diag.category.down();
91 if (ed != "err" && w.has_css_class("node-err")) {
94 if (ed == "err" && w.has_css_class("node-warn")) {
95 w.remove_css_class("node-warn");
97 if (ed == "err" && w.has_css_class("node-depr")) {
98 w.remove_css_class("node-depr");
100 if (!w.has_css_class("node-"+ ed)) {
101 w.add_css_class("node-" + ed);
107 public void onresize () {
110 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
111 // _this.maincol.el.set_max_width( _this.viewwin.el.get_width() - 32 );
113 public void removeErrors () {
114 var child = this.view.el.get_first_child();
116 var reading_header = true;
118 while (child != null) {
119 //GLib.debug("Got %s", child.get_type().name());
121 if (reading_header) {
124 if (child.get_type().name() != "GtkColumnListView") {
126 child = child.get_next_sibling();
129 // should be columnlistview
130 child = child.get_first_child();
134 reading_header = false;
138 if (child.has_css_class("node-err")) {
139 child.remove_css_class("node-err");
141 if (child.has_css_class("node-warn")) {
142 child.remove_css_class("node-warn");
145 if (child.has_css_class("node-depr")) {
146 child.remove_css_class("node-depr");
149 child = child.get_next_sibling();
151 //GLib.debug("Rturning null");
154 public JsRender.Node? getActiveElement () { // return path to actie node.
157 return _this.selmodel.getSelectedNode();
161 public JsRender.JsRender getActiveFile () {
162 return this.main_window.windowstate.file;
164 public class Xcls_ListView1 : Object
166 public Gtk.ListView el;
167 private Xcls_WindowLeftTree _this;
173 public Xcls_ListView1(Xcls_WindowLeftTree _owner )
176 var child_1 = new Xcls_SignalListItemFactory2( _this );
178 this.el = new Gtk.ListView( null, child_1.el );
182 // set gobject values
185 // user defined functions
187 public class Xcls_SignalListItemFactory2 : Object
189 public Gtk.SignalListItemFactory el;
190 private Xcls_WindowLeftTree _this;
196 public Xcls_SignalListItemFactory2(Xcls_WindowLeftTree _owner )
199 this.el = new Gtk.SignalListItemFactory();
203 // set gobject values
206 // user defined functions
210 public class Xcls_viewwin : Object
212 public Gtk.ScrolledWindow el;
213 private Xcls_WindowLeftTree _this;
219 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
222 _this.viewwin = this;
223 this.el = new Gtk.ScrolledWindow();
227 // set gobject values
228 this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
229 this.el.has_frame = true;
230 this.el.hexpand = true;
231 this.el.vexpand = true;
232 this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
233 new Xcls_view( _this );
234 this.el.child = _this.view.el;
235 new Xcls_LeftTreeMenu( _this );
238 // user defined functions
240 public class Xcls_view : Object
242 public Gtk.ColumnView el;
243 private Xcls_WindowLeftTree _this;
247 public bool blockChanges;
248 public bool headers_visible;
249 public string lastEventSource;
250 public bool button_is_pressed;
251 public Gtk.CssProvider css;
252 public JsRender.Node? dragNode;
255 public Xcls_view(Xcls_WindowLeftTree _owner )
259 new Xcls_selmodel( _this );
260 this.el = new Gtk.ColumnView( _this.selmodel.el );
263 this.blockChanges = false;
264 this.headers_visible = false;
265 this.lastEventSource = "";
266 this.button_is_pressed = false;
267 this.dragNode = null;
269 // set gobject values
270 this.el.name = "left-tree-view";
271 this.el.hexpand = false;
272 this.el.vexpand = true;
273 var child_2 = new Xcls_GestureClick5( _this );
275 this.el.add_controller( child_2.el );
276 var child_3 = new Xcls_GestureClick6( _this );
278 this.el.add_controller( child_3.el );
279 var child_4 = new Xcls_DragSource7( _this );
281 this.el.add_controller( child_4.el );
282 var child_5 = new Xcls_EventControllerKey8( _this );
284 this.el.add_controller( child_5.el );
285 new Xcls_keystate( _this );
286 this.el.add_controller( _this.keystate.el );
287 new Xcls_drop( _this );
288 this.el.add_controller( _this.drop.el );
289 new Xcls_maincol( _this );
290 this.el.append_column ( _this.maincol.el );
291 var child_9 = new Xcls_ColumnViewColumn15( _this );
293 this.el.append_column ( child_9.el );
299 this.css = new Gtk.CssProvider();
301 this.css.load_from_string("
302 #left-tree-view { font-size: 12px;}
303 .drag-over { background-color:#88a3bc; }
305 border-bottom-width: 5px;
306 border-bottom-style: solid;
307 border-bottom-color: #88a3bc;
310 border-top-width: 5px;
311 border-top-style: solid;
312 border-top-color: #88a3bc;
315 border-top-width: 5px;
316 border-top-style: solid;
317 border-top-color: red;
318 border-bottom-width: 5px;
319 border-bottom-style: solid;
320 border-bottom-color: red;
323 border-top-width: 5px;
324 border-top-style: solid;
325 border-top-color: #ABF4EB;
326 border-bottom-width: 5px;
327 border-bottom-style: solid;
328 border-bottom-color: #ABF4EB;
331 border-top-width: 5px;
332 border-top-style: solid;
333 border-top-color: #EEA9FF;
334 border-bottom-width: 5px;
335 border-bottom-style: solid;
336 border-bottom-color: #EEA9FF;
339 #left-tree-view indent {
340 -gtk-icon-size : 2px;
342 #left-tree-view indent:nth-last-child(2) {
347 Gtk.StyleContext.add_provider_for_display(
348 this.el.get_display(),
350 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
357 // user defined functions
358 public Gtk.Widget? getWidgetAtRow (uint row) {
361 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
362 var colview = gesture.widget;
363 var line_no = check_list_widget(colview, x,y);
365 var item = colview.model.get_item(line_no);
369 //GLib.debug("Get Widget At Row %d", (int)row);
370 var child = this.el.get_first_child();
372 var reading_header = true;
374 while (child != null) {
375 //GLib.debug("Got %s", child.get_type().name());
377 if (reading_header) {
380 if (child.get_type().name() != "GtkColumnListView") {
382 child = child.get_next_sibling();
385 // should be columnlistview
386 child = child.get_first_child();
390 reading_header = false;
397 if (line_no == row) {
398 //GLib.debug("Returning widget %s", child.get_type().name());
399 return (Gtk.Widget)child;
401 child = child.get_next_sibling();
403 //GLib.debug("Rturning null");
407 public int getColAt (double x, double y) {
410 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
413 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
414 //GLib.debug("Cehck %d, %d", x,y);
415 var child = this.el.get_first_child();
419 while (child != null) {
421 if (child.get_type().name() == "GtkColumnViewRowWidget") {
422 child = child.get_first_child();
426 //child.get_allocation(out alloc);
427 if (x < (child.get_width() + offx)) {
431 //offx += child.get_width();
433 //child = child.get_next_sibling();
440 public int getRowAt (double x, double in_y, out string pos) {
447 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
448 var colview = gesture.widget;
449 var line_no = check_list_widget(colview, x,y);
451 var item = colview.model.get_item(line_no);
457 GLib.debug("get Widget At Row x = %d y = %d", (int) x, (int) in_y);
458 var y = in_y + _this.viewwin.el.vadjustment.value;
459 var child = this.el.get_first_child();
460 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
462 var reading_header = true;
464 var header_height = 0;
467 while (child != null) {
468 //GLib.debug("Got %s", child.get_type().name());
469 if (reading_header) {
472 if (child.get_type().name() != "GtkColumnListView") {
473 h += child.get_height();
474 child = child.get_next_sibling();
477 // should be columnlistview
478 child = child.get_first_child();
479 //GLib.debug("header height=%d", h);
482 reading_header = false;
487 if (child.get_type().name() != "GtkColumnViewRowWidget") {
488 child = child.get_next_sibling();
492 if (y < header_height) {
497 var hh = child.get_height();
499 if (child.has_css_class("node-err") ||
500 child.has_css_class("node-warn") ||
501 child.has_css_class("node-depr")) {
505 //child.get_allocation(out alloc);
506 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
507 //GLib.debug("row %d y= %d %s", line_no, (int) (header_height + alloc.y),
509 // child.visible ? "VIS" : "hidden");
511 if (y > (header_height + real_y) && y <= (header_height + real_y + hh) ) {
512 if (y > ( header_height + real_y + (hh * 0.8))) {
514 } else if (y > ( header_height + real_y + (hh * 0.2))) {
519 GLib.debug("getRowAt return : %d, %s", line_no, pos);
524 if (real_y + hh > y) {
528 child = child.get_next_sibling();
533 public Gtk.Widget? getWidgetAt (double x, double in_y) {
536 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
537 var colview = gesture.widget;
538 var line_no = check_list_widget(colview, x,y);
540 var item = colview.model.get_item(line_no);
544 var y = in_y + _this.viewwin.el.vadjustment.value;
545 var child = this.el.get_first_child();
546 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
548 var reading_header = true;
550 var header_height = 0;
552 while (child != null) {
553 //GLib.debug("Got %s", child.get_type().name());
554 if (reading_header) {
557 if (child.get_type().name() != "GtkColumnListView") {
558 h += child.get_height();
559 child = child.get_next_sibling();
562 // should be columnlistview
563 child = child.get_first_child();
564 GLib.debug("header height=%d", h);
567 reading_header = false;
572 if (y < header_height) {
576 var hh = child.get_height();
577 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
578 if (child.has_css_class("node-err") ||
579 child.has_css_class("node-warn") ||
580 child.has_css_class("node-depr")) {
584 if (y > curr_y && y <= header_height + hh + curr_y ) {
585 return (Gtk.Widget)child;
592 child = child.get_next_sibling();
598 public class Xcls_GestureClick5 : Object
600 public Gtk.GestureClick el;
601 private Xcls_WindowLeftTree _this;
607 public Xcls_GestureClick5(Xcls_WindowLeftTree _owner )
610 this.el = new Gtk.GestureClick();
614 // set gobject values
617 this.el.released.connect( (n_press, x, y) => {
619 _this.view.button_is_pressed = false;
623 this.el.pressed.connect( (n_press, x, y) => {
625 //console.log("button press?");
627 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
631 _this.view.button_is_pressed = true;
633 _this.view.lastEventSource = "tree";
634 if (! _this.before_node_change() ) {
635 GLib.debug("before_node_change return false");
639 // nothing there -show dialog
640 if (_this.model.el.get_n_items() < 1) {
641 _this.main_window.windowstate.showAddObject(_this.view.el, null);
642 GLib.debug("no items");
646 var row = _this.view.getRowAt(x,y, out pos );
648 GLib.debug("no row selected items");
652 var node = _this.selmodel.getNodeAt(row);
654 GLib.warning("No node found at row %d", row);
660 if (_this.view.getColAt(x,y) > 0 ) {
661 GLib.debug("add colum clicked.");
662 var fqn = node.fqn();
663 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
668 _this.main_window.windowstate.leftTreeBeforeChange();
669 //_this.view.el.get_selection().select_path(res);
670 GLib.debug("Button Pressed - start show window");
671 _this.main_window.windowstate.showAddObject(_this.view.el, node);
672 GLib.debug("Button Pressed - finsihed show window");
681 // user defined functions
684 public class Xcls_GestureClick6 : Object
686 public Gtk.GestureClick el;
687 private Xcls_WindowLeftTree _this;
693 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
696 this.el = new Gtk.GestureClick();
700 // set gobject values
704 this.el.pressed.connect( (n_press, x, y) => {
709 if (_this.model.el.get_n_items() < 1) {
711 GLib.debug("no items");
715 var row = _this.view.getRowAt(x,y, out pos );
717 GLib.debug("no row selected items");
721 var node = _this.selmodel.getNodeAt(row);
723 GLib.warning("No node found at row %d", row);
728 _this.model.selectNode(node);
732 GLib.debug("Prssed %d", (int) this.el.get_current_button());
733 //_this.deletemenu.el.set_parent(_this.view.el);
734 _this.LeftTreeMenu.el.set_parent(_this.view.el);
737 //Gtk.Allocation rect;
738 //_this.view.el.get_allocation(out rect);
739 //_this.deletemenu.el.set_has_arrow(false);
740 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
743 _this.LeftTreeMenu.el.set_offset(
745 (int)y - (int)_this.view.el.get_height());
747 _this.LeftTreeMenu.el.popup();
752 // user defined functions
755 public class Xcls_DragSource7 : Object
757 public Gtk.DragSource el;
758 private Xcls_WindowLeftTree _this;
764 public Xcls_DragSource7(Xcls_WindowLeftTree _owner )
767 this.el = new Gtk.DragSource();
771 // set gobject values
772 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
775 this.el.drag_cancel.connect( (drag, reason) => {
777 _this.view.dragNode = null;
780 this.el.prepare.connect( (x, y) => {
784 /// ( drag_context, data, info, time) => {
787 //print("drag-data-get");
788 var ndata = _this.selmodel.getSelectedNode();
790 GLib.debug("return empty string - no selection..");
796 //data.set_text(tp,tp.length);
798 var str = ndata.toJsonString();
799 GLib.debug("prepare store: %s", str);
800 GLib.Value ov = GLib.Value(typeof(string));
802 var cont = new Gdk.ContentProvider.for_value(ov);
804 GLib.Value v = GLib.Value(typeof(string));
805 //var str = drop.read_text( [ "text/plain" ] 0);
807 cont.get_value(ref v);
810 GLib.debug("set %s", v.get_string());
816 this.el.drag_begin.connect( ( drag ) => {
817 GLib.debug("SOURCE: drag-begin");
819 // find what is selected in our tree...
820 var data = _this.selmodel.getSelectedNode();
824 _this.view.dragNode = data;
825 var xname = data.fqn();
826 GLib.debug ("XNAME IS %s", xname);
828 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
831 var paintable = new Gtk.WidgetPaintable(widget);
832 this.el.set_icon(paintable, 0,0);
836 this.el.drag_end.connect( (drag, delete_data) => {
838 _this.view.dragNode = null;
842 // user defined functions
845 public class Xcls_EventControllerKey8 : Object
847 public Gtk.EventControllerKey el;
848 private Xcls_WindowLeftTree _this;
854 public Xcls_EventControllerKey8(Xcls_WindowLeftTree _owner )
857 this.el = new Gtk.EventControllerKey();
861 // set gobject values
864 this.el.key_pressed.connect( (keyval, keycode, state) => {
868 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
872 _this.model.deleteSelected();
878 // user defined functions
881 public class Xcls_keystate : Object
883 public Gtk.EventControllerKey el;
884 private Xcls_WindowLeftTree _this;
891 public Xcls_keystate(Xcls_WindowLeftTree _owner )
894 _this.keystate = this;
895 this.el = new Gtk.EventControllerKey();
900 // set gobject values
903 this.el.key_released.connect( (keyval, keycode, state) => {
904 GLib.debug("key release %d, %d, %d" , (int) keyval, (int) keycode, state);
905 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
908 //GLib.debug("set state %d , shift = %d", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);
913 this.el.key_pressed.connect( (keyval, keycode, state) => {
915 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
922 // user defined functions
925 public class Xcls_drop : Object
927 public Gtk.DropTarget el;
928 private Xcls_WindowLeftTree _this;
932 public Gtk.Widget? highlightWidget;
933 public JsRender.Node? lastDragNode;
934 public string lastDragString;
937 public Xcls_drop(Xcls_WindowLeftTree _owner )
941 this.el = new Gtk.DropTarget ( typeof(string) ,
942 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
945 this.highlightWidget = null;
946 this.lastDragNode = null;
947 this.lastDragString = "";
949 // set gobject values
952 this.el.accept.connect( (drop) => {
954 GLib.debug("got DropTarget:accept");
956 // NOT REALLY NEEDED? = put stuff in drop?
959 /* ( ctx, x, y, time) => {
960 //Seed.print("TARGET: drag-drop");
963 var src = Gtk.drag_get_source_widget(ctx);
965 if (src != this.el) {
969 this.drag_in_motion = false;
970 // request data that will be recieved by the recieve...
973 this.el, // will receive 'drag-data-received' signal
974 ctx, // represents the current state of the DnD
975 Gdk.Atom.intern("application/json",true), // the target type we want
980 // No target offered by source => error
986 // handle drop around self..
990 //print("GETTING POS");
994 Gtk.TreeViewDropPosition pos;
995 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
997 // if there are not items in the tree.. the we have to set isOver to true for anything..
999 if (_this.model.el.iter_n_children(null) < 1) {
1000 print("got NO children?\n");
1001 isOver = true; //???
1003 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
1008 //var action = Gdk.DragAction.COPY;
1009 // unless we are copying!!! ctl button..
1011 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
1012 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
1013 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
1016 if (_this.model.el.iter_n_children(null) < 1) {
1017 // no children.. -- asume it's ok..
1019 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
1021 // continue through to allow drop...
1029 //print("ISOVER? " + isOver);
1032 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1033 return true; // not over apoint!?! - no action on drop or motion..
1036 // drag node is parent of child..
1037 //console.log("SRC TREEPATH: " + src.treepath);
1038 //console.log("TARGET TREEPATH: " + data.path.to_string());
1040 // nned to check a few here..
1041 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
1042 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
1043 //Gtk.TreeViewDropPosition.AFTER
1044 //Gtk.TreeViewDropPosition.BEFORE
1046 // locally dragged items to not really use the
1047 var selection_text = this.dragData;
1051 if (selection_text == null || selection_text.length < 1) {
1052 //print("Error - drag selection text returned NULL");
1054 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1055 return true; /// -- fixme -- this is not really correct..
1058 // see if we are dragging into ourself?
1059 print ("got selection text of " + selection_text);
1061 var target_path = path.to_string();
1062 //print("target_path="+target_path);
1065 if (selection_text == target_path) {
1066 print("self drag ?? == we should perhaps allow copy onto self..\n");
1068 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1070 return true; /// -- fixme -- this is not really correct..
1075 //print("DUMPING DATA");
1076 //console.dump(data);
1079 //print(data.path.to_string() +' => '+ data.pos);
1081 // dropList is a list of xtypes that this node could be dropped on.
1082 // it is set up when we start to drag..
1085 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
1087 print("targetDAta: " + targetData +"\n");
1089 if (targetData.length < 1) {
1090 //print("Can not find drop node path");
1092 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1098 // continue on to allow drop..
1100 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
1103 var delete_selection_data = false;
1105 if (action == Gdk.DragAction.ASK) {
1106 // Ask the user to move or copy, then set the ctx action.
1109 if (action == Gdk.DragAction.MOVE) {
1110 delete_selection_data = true;
1113 // drag around.. - reorder..
1114 _this.model.moveNode(targetData, action);
1120 // we can send stuff to souce here...
1123 // do we always say failure, so we handle the reall drop?
1124 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
1137 this.el.motion.connect( ( x, y) => {
1139 var is_shift = _this.keystate.is_shift > 0;
1141 GLib.debug("shift is %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
1142 string pos; // over / before / after..
1144 //GLib.debug("got drag motion");
1146 GLib.Value v = GLib.Value(typeof(string));
1147 //var str = drop.read_text( [ "text/plain" ] 0);
1148 var cont = this.el.current_drop.get_drag().content ;
1150 cont.get_value(ref v);
1151 } catch (GLib.Error e) {
1152 GLib.debug("failed to get drag value");
1153 return Gdk.DragAction.COPY;
1157 //GLib.debug("got %s", v.get_string());
1159 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1160 // still dragging same node
1162 this.lastDragNode = new JsRender.Node();
1163 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1167 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
1168 this.lastDragNode.fqn());
1171 foreach(var dp in drop_on_to) {
1174 GLib.debug("droplist: %s", string.joinv(", ", str));
1177 // if there are not items in the tree.. the we have to set isOver to true for anything..
1179 if (_this.model.el.n_items < 1) {
1180 // FIXME check valid drop types?
1181 if (drop_on_to.contains("*top")) {
1182 this.addHighlight(_this.view.el, "over");
1184 this.addHighlight(null, "");
1187 return Gdk.DragAction.COPY; // no need to highlight?
1192 GLib.debug("check is over");
1194 // if path of source and dest are inside each other..
1195 // need to add source info to drag?
1197 var row = _this.view.getRowAt(x,y, out pos);
1200 this.addHighlight(null, "");
1201 return Gdk.DragAction.COPY;
1203 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1205 var node = (JsRender.Node)tr.get_item();
1207 GLib.debug("Drop over node: %s", node.fqn());
1210 if (pos == "above" || pos == "below") {
1211 if (node.parent == null) {
1212 GLib.debug("no parent try center");
1216 if (!drop_on_to.contains(node.parent.fqn())) {
1217 GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1220 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1221 if (_this.view.dragNode != null && is_shift) {
1222 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1223 GLib.debug("shift drop not self not allowed");
1224 this.addHighlight(null, "");
1225 return Gdk.DragAction.COPY;
1238 if (pos == "over") {
1239 if (!drop_on_to.contains(node.fqn())) {
1240 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1241 this.addHighlight(null, "");
1242 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1244 if (_this.view.dragNode != null && is_shift) {
1245 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1246 GLib.debug("shift drop not self not allowed");
1247 this.addHighlight(null, "");
1248 return Gdk.DragAction.COPY;
1255 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1256 var w = _this.view.getWidgetAt(x,y);
1257 this.addHighlight(w, pos);
1258 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1260 this.el.leave.connect( ( ) => {
1261 this.addHighlight(null,"");
1264 this.el.drop.connect( (v, x, y) => {
1266 this.addHighlight(null,"");
1268 var is_shift = _this.keystate.is_shift > 0;
1271 // -- get position..
1272 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1273 // still dragging same node
1275 this.lastDragNode = new JsRender.Node();
1276 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1281 var dropNode = new JsRender.Node();
1282 dropNode.loadFromJsonString(v.get_string(), 1);
1283 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1285 // if there are not items in the tree.. the we have to set isOver to true for anything..
1287 if (_this.model.el.n_items < 1) {
1288 // FIXME check valid drop types?
1289 if (!drop_on_to.contains("*top")) {
1290 GLib.debug("drop on to list does not contain top?");
1293 // add new node to top..
1296 var m = (GLib.ListStore) _this.model.el.model;
1297 _this.main_window.windowstate.file.tree = dropNode;
1298 dropNode.updated_count++;
1301 _this.model.selectNode(dropNode);
1303 return true; // no need to highlight?
1309 var row = _this.view.getRowAt(x,y, out pos);
1311 return false; //Gdk.DragAction.COPY;
1313 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1315 var node = (JsRender.Node)tr.get_item();
1317 if (pos == "above" || pos == "below") {
1318 if (node.parent == null) {
1321 if (!drop_on_to.contains(node.parent.fqn())) {
1324 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1325 if (_this.view.dragNode != null && is_shift) {
1326 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1327 GLib.debug("shift drop not self not allowed");
1338 if (pos == "over") {
1339 if (!drop_on_to.contains(node.fqn())) {
1340 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1344 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1345 GLib.debug("shift drop not self not allowed");
1352 node.appendChild(dropNode);
1353 if (is_shift && _this.view.dragNode != null) {
1354 _this.model.selectNode(null);
1355 _this.view.dragNode.remove();
1358 dropNode.updated_count++;
1359 _this.model.selectNode(dropNode);
1365 GLib.debug("Above - insertBefore");
1367 node.parent.insertBefore(dropNode, node);
1368 if (is_shift && _this.view.dragNode != null) {
1369 _this.model.selectNode(null);
1370 _this.view.dragNode.remove();
1372 dropNode.updated_count++;
1373 _this.model.selectNode(dropNode);
1378 GLib.debug("Below - insertAfter");
1379 if (is_shift && _this.view.dragNode != null) {
1380 _this.model.selectNode(null);
1381 _this.view.dragNode.remove();
1385 node.parent.insertAfter(dropNode, node);
1386 dropNode.updated_count++;
1387 _this.model.selectNode(dropNode);
1393 // should not happen
1405 // user defined functions
1406 public void addHighlight (Gtk.Widget? w, string hl) {
1407 if (this.highlightWidget != null) {
1408 var ww = this.highlightWidget;
1409 GLib.debug("clear drag from previous highlight");
1410 if (ww.has_css_class("drag-below")) {
1411 ww.remove_css_class("drag-below");
1413 if (ww.has_css_class("drag-above")) {
1414 ww.remove_css_class("drag-above");
1416 if (ww.has_css_class("drag-over")) {
1417 ww.remove_css_class("drag-over");
1421 GLib.debug("add drag=%s to widget", hl);
1422 if (!w.has_css_class("drag-" + hl)) {
1423 w.add_css_class("drag-" + hl);
1426 this.highlightWidget = w;
1430 public class Xcls_selmodel : Object
1432 public Gtk.SingleSelection el;
1433 private Xcls_WindowLeftTree _this;
1439 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1442 _this.selmodel = this;
1443 new Xcls_model( _this );
1444 this.el = new Gtk.SingleSelection( _this.model.el );
1448 // set gobject values
1451 this.el.selection_changed.connect( (position, n_items) => {
1455 //if (!this.button_is_pressed && !this.key_is_pressed) {
1456 // then event was started by some other action
1457 // which should manually trigger all the events..
1458 // print("SKIPPING select - no button or key pressed\n");
1463 if (_this.view.blockChanges) { // probably not needed..
1464 GLib.debug("SKIPPING select - blockchanges set..");
1468 if (!_this.before_node_change( ) ) {
1469 _this.view.blockChanges = true;
1470 _this.selmodel.el.unselect_all();
1471 _this.view.blockChanges = false;
1475 if (_this.main_window.windowstate.file == null) {
1476 GLib.debug("SKIPPING select windowstate file is not set...");
1480 //var render = this.get('/LeftTree').getRenderer();
1481 GLib.debug("LEFT TREE -> view -> selection changed called");
1484 // -- it appears that the selection is not updated.
1485 // select the node...
1486 //_this.selmodel.el.set_selected(row);
1488 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1490 var snode = _this.selmodel.getSelectedNode();
1491 if (snode == null) {
1493 GLib.debug("selected rows < 1");
1494 //??this.model.load( false);
1495 _this.node_selected(null);
1503 GLib.debug ("calling left_tree.node_selected");
1504 _this.node_selected(snode);
1509 // no need to scroll. it's in the view as we clicked on it.
1510 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1516 // user defined functions
1517 public JsRender.Node? getSelectedNode () {
1518 if (this.el.selected_item == null) {
1521 var tr = (Gtk.TreeListRow)this.el.selected_item;
1522 return (JsRender.Node)tr.get_item();
1525 public JsRender.Node getNodeAt (uint row) {
1527 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1529 var a = tr.get_item();;
1530 GLib.debug("get_item (2) = %s", a.get_type().name());
1533 return (JsRender.Node)tr.get_item();
1537 public class Xcls_model : Object
1539 public Gtk.TreeListModel el;
1540 private Xcls_WindowLeftTree _this;
1546 public Xcls_model(Xcls_WindowLeftTree _owner )
1550 this.el = this.updateModel(null);
1554 // set gobject values
1557 // user defined functions
1558 public void loadFile (JsRender.JsRender f) {
1561 _this.drop.highlightWidget = null;
1563 var m = (GLib.ListStore) this.el.model;
1565 _this.main_window.windowstate.leftTreeNodeSelected(null);
1567 _this.main_window.windowstate.file = f;
1568 _this.last_error_counter = -1;
1570 if (f.tree == null) {
1577 // if it's still null?
1578 if (f.tree == null) {
1579 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1580 _this.updateErrors();
1584 _this.updateErrors();
1586 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1592 public int nodeToRow (JsRender.Node node)
1595 var s = _this.view.el.model as Gtk.SingleSelection;
1596 for (var i = 0; i < s.n_items; i++) {
1597 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1598 var lr = s.get_item(i) as Gtk.TreeListRow;
1599 //GLib.debug("check node %s", lr.get_item().get_type().name());
1600 if ((lr.get_item() as JsRender.Node).oid == node.oid) {
1609 public void deleteSelected () {
1613 var node = _this.selmodel.getSelectedNode();
1617 GLib.debug("delete Selected - no node slected?");
1620 _this.selmodel.el.unselect_all();
1623 GLib.debug("delete Selected - done");
1626 print("DELETE SELECTED?");
1627 //_this.view.blockChanges = true;
1628 print("GET SELECTION?");
1630 var s = _this.view.el.get_selection();
1632 print("GET SELECTED?");
1637 if (!s.get_selected(out mod, out iter)) {
1638 return; // nothing seleted..
1643 this.activePath= "";
1644 print("GET vnode value?");
1647 this.el.get_value(iter, 2, out value);
1648 var data = (JsRender.Node)(value.get_object());
1649 print("removing node from Render\n");
1650 if (data.parent == null) {
1651 _this.main_window.windowstate.file.tree = null;
1655 print("removing node from Tree\n");
1657 this.el.remove(ref iter);
1667 this.activePath= ""; // again!?!?
1668 //this.changed(null,true);
1672 _this.view.blockChanges = false;
1675 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1676 this.el = new Gtk.TreeListModel(
1677 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1681 return ((JsRender.Node)item).childstore;
1685 if (_this.selmodel.el == null) {
1688 _this.selmodel.el.set_model(this.el);
1691 public void selectNode (JsRender.Node node)
1693 var row = this.nodeToRow(node);
1694 var s = _this.view.el.model as Gtk.SingleSelection;
1698 GLib.debug("Could not find node");
1701 GLib.debug("Select %d", row);
1702 s.set_selected(row);
1703 _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1704 //_this.node_selected(node);
1711 public class Xcls_maincol : Object
1713 public Gtk.ColumnViewColumn el;
1714 private Xcls_WindowLeftTree _this;
1720 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1723 _this.maincol = this;
1724 var child_1 = new Xcls_SignalListItemFactory14( _this );
1726 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1730 // set gobject values
1731 this.el.id = "maincol";
1732 this.el.expand = true;
1733 this.el.resizable = true;
1736 // user defined functions
1738 public class Xcls_SignalListItemFactory14 : Object
1740 public Gtk.SignalListItemFactory el;
1741 private Xcls_WindowLeftTree _this;
1747 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1750 this.el = new Gtk.SignalListItemFactory();
1754 // set gobject values
1757 this.el.setup.connect( (listitem) => {
1759 var expand = new Gtk.TreeExpander();
1761 expand.set_indent_for_depth(true);
1762 expand.set_indent_for_icon(true);
1763 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1764 var icon = new Gtk.Image();
1765 var lbl = new Gtk.Label("");
1766 lbl.use_markup = true;
1767 lbl.ellipsize = Pango.EllipsizeMode.END;
1769 icon.margin_end = 4;
1770 lbl.justify = Gtk.Justification.LEFT;
1773 // listitem.activatable = true; ??
1777 expand.set_child(hbox);
1778 ((Gtk.ListItem)listitem).set_child(expand);
1781 this.el.bind.connect( (listitem) => {
1782 GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1784 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1785 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1788 var hbox = (Gtk.Box) expand.child;
1791 var img = (Gtk.Image) hbox.get_first_child();
1792 var lbl = (Gtk.Label) img.get_next_sibling();
1794 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1795 var node = (JsRender.Node) lr.get_item();
1797 GLib.debug("node is %s", node.get_type().name());
1798 // was item (1) in old layout
1803 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1804 var clsname = node.fqn();
1806 var clsb = clsname.split(".");
1807 var sub = clsb.length > 1 ? clsb[1].down() : "";
1809 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1813 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1814 img.set_from_file(fn);
1817 img.set_from_paintable(
1819 "media-playback-stop", null, 16,1,
1820 Gtk.TextDirection.NONE, 0
1824 } catch (GLib.Error e) {}
1826 expand.set_hide_expander( !node.hasChildren() );
1827 expand.set_list_row(lr);
1829 node.bind_property("iconResourceName",
1831 GLib.BindingFlags.SYNC_CREATE);
1833 node.bind_property("nodeTitleProp",
1835 GLib.BindingFlags.SYNC_CREATE);
1836 node.bind_property("nodeTipProp",
1837 lbl, "tooltip_markup",
1838 GLib.BindingFlags.SYNC_CREATE);
1844 // user defined functions
1848 public class Xcls_ColumnViewColumn15 : Object
1850 public Gtk.ColumnViewColumn el;
1851 private Xcls_WindowLeftTree _this;
1857 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1860 var child_1 = new Xcls_SignalListItemFactory16( _this );
1862 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1866 // set gobject values
1867 this.el.fixed_width = 25;
1870 // user defined functions
1872 public class Xcls_SignalListItemFactory16 : Object
1874 public Gtk.SignalListItemFactory el;
1875 private Xcls_WindowLeftTree _this;
1881 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1884 this.el = new Gtk.SignalListItemFactory();
1888 // set gobject values
1891 this.el.setup.connect( (listitem) => {
1894 var icon = new Gtk.Image();
1896 ((Gtk.ListItem)listitem).set_child(icon);
1898 this.el.bind.connect( (listitem) => {
1900 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1901 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1902 var node = (JsRender.Node) lr.get_item();
1905 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1906 img.set_from_paintable(
1908 "list-add", null, 16,1,
1909 Gtk.TextDirection.NONE, 0
1913 var fqn = node.fqn();
1914 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1916 img.set_visible(cn.size > 0 ? true : false);
1921 // user defined functions
1926 public class Xcls_LeftTreeMenu : Object
1928 public Gtk.Popover el;
1929 private Xcls_WindowLeftTree _this;
1935 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1938 _this.LeftTreeMenu = this;
1939 this.el = new Gtk.Popover();
1943 // set gobject values
1944 var child_1 = new Xcls_Box18( _this );
1945 this.el.child = child_1.el;
1948 // user defined functions
1950 public class Xcls_Box18 : Object
1953 private Xcls_WindowLeftTree _this;
1959 public Xcls_Box18(Xcls_WindowLeftTree _owner )
1962 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1966 // set gobject values
1967 var child_1 = new Xcls_Button19( _this );
1969 this.el.append( child_1.el );
1970 var child_2 = new Xcls_Button20( _this );
1972 this.el.append( child_2.el );
1973 var child_3 = new Xcls_Button21( _this );
1975 this.el.append( child_3.el );
1978 // user defined functions
1980 public class Xcls_Button19 : Object
1982 public Gtk.Button el;
1983 private Xcls_WindowLeftTree _this;
1989 public Xcls_Button19(Xcls_WindowLeftTree _owner )
1992 this.el = new Gtk.Button();
1996 // set gobject values
1997 this.el.has_frame = false;
1998 this.el.label = "Delete Element";
2001 this.el.clicked.connect( ( ) => {
2002 _this.LeftTreeMenu.el.hide();
2003 _this.model.deleteSelected();
2008 // user defined functions
2011 public class Xcls_Button20 : Object
2013 public Gtk.Button el;
2014 private Xcls_WindowLeftTree _this;
2020 public Xcls_Button20(Xcls_WindowLeftTree _owner )
2023 this.el = new Gtk.Button();
2027 // set gobject values
2028 this.el.has_frame = false;
2029 this.el.label = "Save as Template";
2032 this.el.clicked.connect( () => {
2033 _this.LeftTreeMenu.el.hide();
2034 DialogSaveTemplate.singleton().showIt(
2035 (Gtk.Window) _this.el.get_root (),
2036 _this.main_window.windowstate.file.palete(),
2037 _this.getActiveElement()
2044 // user defined functions
2047 public class Xcls_Button21 : Object
2049 public Gtk.Button el;
2050 private Xcls_WindowLeftTree _this;
2056 public Xcls_Button21(Xcls_WindowLeftTree _owner )
2059 this.el = new Gtk.Button();
2063 // set gobject values
2064 this.el.has_frame = false;
2065 this.el.label = "Save as Module";
2068 this.el.clicked.connect( () => {
2070 _this.LeftTreeMenu.el.hide();
2071 var node = _this.getActiveElement();
2074 var sm = DialogSaveModule.singleton();
2078 (Gtk.Window) _this.el.get_root (),
2079 _this.main_window.windowstate.project,
2083 gtk4 migration - disabled this part.. probably not used muchanyway
2086 if (name.length < 1) {
2090 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
2094 var s = _this.view.el.get_selection();
2096 print("GET SELECTED?");
2101 if (!s.get_selected(out mod, out iter)) {
2102 return; // nothing seleted..
2105 var n_cn = mod.iter_n_children(iter) -1;
2106 for (var i = n_cn; i > -1; i--) {
2107 mod.iter_nth_child(out citer, iter, i);
2110 print("removing node from Tree\n");
2112 _this.model.el.remove(ref citer);
2115 _this.node_selected(node, "tree");
2121 // user defined functions