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;
165 public class Xcls_ListView1 : Object
167 public Gtk.ListView el;
168 private Xcls_WindowLeftTree _this;
174 public Xcls_ListView1(Xcls_WindowLeftTree _owner )
177 var child_1 = new Xcls_SignalListItemFactory2( _this );
179 this.el = new Gtk.ListView( null, child_1.el );
183 // set gobject values
186 // user defined functions
188 public class Xcls_SignalListItemFactory2 : Object
190 public Gtk.SignalListItemFactory el;
191 private Xcls_WindowLeftTree _this;
197 public Xcls_SignalListItemFactory2(Xcls_WindowLeftTree _owner )
200 this.el = new Gtk.SignalListItemFactory();
204 // set gobject values
207 // user defined functions
211 public class Xcls_viewwin : Object
213 public Gtk.ScrolledWindow el;
214 private Xcls_WindowLeftTree _this;
220 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
223 _this.viewwin = this;
224 this.el = new Gtk.ScrolledWindow();
228 // set gobject values
229 this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
230 this.el.has_frame = true;
231 this.el.hexpand = true;
232 this.el.vexpand = true;
233 this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
234 new Xcls_view( _this );
235 this.el.child = _this.view.el;
236 new Xcls_LeftTreeMenu( _this );
239 // user defined functions
241 public class Xcls_view : Object
243 public Gtk.ColumnView el;
244 private Xcls_WindowLeftTree _this;
248 public bool blockChanges;
249 public bool headers_visible;
250 public string lastEventSource;
251 public bool button_is_pressed;
252 public Gtk.CssProvider css;
253 public JsRender.Node? dragNode;
256 public Xcls_view(Xcls_WindowLeftTree _owner )
260 new Xcls_selmodel( _this );
261 this.el = new Gtk.ColumnView( _this.selmodel.el );
264 this.blockChanges = false;
265 this.headers_visible = false;
266 this.lastEventSource = "";
267 this.button_is_pressed = false;
268 this.dragNode = null;
270 // set gobject values
271 this.el.name = "left-tree-view";
272 this.el.hexpand = false;
273 this.el.vexpand = true;
274 var child_2 = new Xcls_GestureClick5( _this );
276 this.el.add_controller( child_2.el );
277 var child_3 = new Xcls_GestureClick6( _this );
279 this.el.add_controller( child_3.el );
280 var child_4 = new Xcls_DragSource7( _this );
282 this.el.add_controller( child_4.el );
283 var child_5 = new Xcls_EventControllerKey8( _this );
285 this.el.add_controller( child_5.el );
286 new Xcls_keystate( _this );
287 this.el.add_controller( _this.keystate.el );
288 new Xcls_drop( _this );
289 this.el.add_controller( _this.drop.el );
290 new Xcls_maincol( _this );
291 this.el.append_column ( _this.maincol.el );
292 var child_9 = new Xcls_ColumnViewColumn15( _this );
294 this.el.append_column ( child_9.el );
300 this.css = new Gtk.CssProvider();
302 this.css.load_from_string("
303 #left-tree-view { font-size: 12px;}
304 .drag-over { background-color:#88a3bc; }
306 border-bottom-width: 5px;
307 border-bottom-style: solid;
308 border-bottom-color: #88a3bc;
311 border-top-width: 5px;
312 border-top-style: solid;
313 border-top-color: #88a3bc;
316 border-top-width: 5px;
317 border-top-style: solid;
318 border-top-color: red;
319 border-bottom-width: 5px;
320 border-bottom-style: solid;
321 border-bottom-color: red;
324 border-top-width: 5px;
325 border-top-style: solid;
326 border-top-color: #ABF4EB;
327 border-bottom-width: 5px;
328 border-bottom-style: solid;
329 border-bottom-color: #ABF4EB;
332 border-top-width: 5px;
333 border-top-style: solid;
334 border-top-color: #EEA9FF;
335 border-bottom-width: 5px;
336 border-bottom-style: solid;
337 border-bottom-color: #EEA9FF;
340 #left-tree-view indent {
341 -gtk-icon-size : 2px;
343 #left-tree-view indent:nth-last-child(2) {
348 Gtk.StyleContext.add_provider_for_display(
349 this.el.get_display(),
351 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
358 // user defined functions
359 public Gtk.Widget? getWidgetAtRow (uint row) {
362 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
363 var colview = gesture.widget;
364 var line_no = check_list_widget(colview, x,y);
366 var item = colview.model.get_item(line_no);
370 //GLib.debug("Get Widget At Row %d", (int)row);
371 var child = this.el.get_first_child();
373 var reading_header = true;
375 while (child != null) {
376 //GLib.debug("Got %s", child.get_type().name());
378 if (reading_header) {
381 if (child.get_type().name() != "GtkColumnListView") {
383 child = child.get_next_sibling();
386 // should be columnlistview
387 child = child.get_first_child();
391 reading_header = false;
398 if (line_no == row) {
399 //GLib.debug("Returning widget %s", child.get_type().name());
400 return (Gtk.Widget)child;
402 child = child.get_next_sibling();
404 //GLib.debug("Rturning null");
408 public int getColAt (double x, double y) {
411 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
414 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
415 //GLib.debug("Cehck %d, %d", x,y);
416 var child = this.el.get_first_child();
420 while (child != null) {
422 if (child.get_type().name() == "GtkColumnViewRowWidget") {
423 child = child.get_first_child();
427 //child.get_allocation(out alloc);
428 if (x < (child.get_width() + offx)) {
432 //offx += child.get_width();
434 //child = child.get_next_sibling();
441 public int getRowAt (double x, double y, out string pos) {
444 var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
445 //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
450 var row= w.get_ancestor(GLib.Type.from_name("GtkColumnViewRowWidget"));
455 //GLib.debug("got colview %s", row == null ? "nothing" : row.get_type().name());
460 while (cr.get_prev_sibling() != null) {
462 cr = cr.get_prev_sibling();
465 //GLib.debug("row number is %d", rn);
466 //GLib.debug("click %d, %d", (int)x, (int)y);
468 Graphene.Rect bounds;
469 row.compute_bounds(this.el, out bounds);
470 //GLib.debug("click x=%d, y=%d, w=%d, h=%d",
471 // (int)bounds.get_x(), (int)bounds.get_y(),
472 // (int)bounds.get_width(), (int)bounds.get_height()
474 var ypos = y - bounds.get_y();
475 //GLib.debug("rel ypos = %d", (int)ypos);
476 var rpos = 100.0 * (ypos / bounds.get_height());
477 //GLib.debug("rel pos = %d %%", (int)rpos);
482 } else if (rpos < 20) {
487 public Gtk.Widget? getWidgetAt (double x, double y) {
489 var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
490 //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
495 var row= w.get_ancestor(GLib.Type.from_name("GtkColumnViewRowWidget"));
504 public class Xcls_GestureClick5 : Object
506 public Gtk.GestureClick el;
507 private Xcls_WindowLeftTree _this;
513 public Xcls_GestureClick5(Xcls_WindowLeftTree _owner )
516 this.el = new Gtk.GestureClick();
520 // set gobject values
523 this.el.released.connect( (n_press, x, y) => {
525 _this.view.button_is_pressed = false;
529 this.el.pressed.connect( (n_press, x, y) => {
531 //console.log("button press?");
533 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
537 _this.view.button_is_pressed = true;
539 _this.view.lastEventSource = "tree";
540 if (! _this.before_node_change() ) {
541 GLib.debug("before_node_change return false");
545 // nothing there -show dialog
546 if (_this.model.el.get_n_items() < 1) {
547 _this.main_window.windowstate.showAddObject(_this.view.el, null);
548 GLib.debug("no items");
552 var row = _this.view.getRowAt(x,y, out pos );
554 GLib.debug("no row selected items");
558 var node = _this.selmodel.getNodeAt(row);
560 GLib.warning("No node found at row %d", row);
566 if (_this.view.getColAt(x,y) > 0 ) {
567 GLib.debug("add colum clicked.");
568 var fqn = node.fqn();
569 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
574 _this.main_window.windowstate.leftTreeBeforeChange();
575 //_this.view.el.get_selection().select_path(res);
576 GLib.debug("Button Pressed - start show window");
577 _this.main_window.windowstate.showAddObject(_this.view.el, node);
578 GLib.debug("Button Pressed - finsihed show window");
587 // user defined functions
590 public class Xcls_GestureClick6 : Object
592 public Gtk.GestureClick el;
593 private Xcls_WindowLeftTree _this;
599 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
602 this.el = new Gtk.GestureClick();
606 // set gobject values
610 this.el.pressed.connect( (n_press, x, y) => {
615 if (_this.model.el.get_n_items() < 1) {
617 GLib.debug("no items");
621 var row = _this.view.getRowAt(x,y, out pos );
623 GLib.debug("no row selected items");
627 var node = _this.selmodel.getNodeAt(row);
629 GLib.warning("No node found at row %d", row);
634 _this.model.selectNode(node);
638 GLib.debug("Prssed %d", (int) this.el.get_current_button());
639 //_this.deletemenu.el.set_parent(_this.view.el);
640 _this.LeftTreeMenu.el.set_parent(_this.view.el);
643 //Gtk.Allocation rect;
644 //_this.view.el.get_allocation(out rect);
645 //_this.deletemenu.el.set_has_arrow(false);
646 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
649 _this.LeftTreeMenu.el.set_offset(
651 (int)y - (int)_this.view.el.get_height());
653 _this.LeftTreeMenu.el.popup();
658 // user defined functions
661 public class Xcls_DragSource7 : Object
663 public Gtk.DragSource el;
664 private Xcls_WindowLeftTree _this;
670 public Xcls_DragSource7(Xcls_WindowLeftTree _owner )
673 this.el = new Gtk.DragSource();
677 // set gobject values
678 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
681 this.el.drag_cancel.connect( (drag, reason) => {
683 _this.view.dragNode = null;
686 this.el.prepare.connect( (x, y) => {
690 /// ( drag_context, data, info, time) => {
693 //print("drag-data-get");
694 var ndata = _this.selmodel.getSelectedNode();
696 GLib.debug("return empty string - no selection..");
702 //data.set_text(tp,tp.length);
704 var str = ndata.toJsonString();
705 GLib.debug("prepare store: %s", str);
706 GLib.Value ov = GLib.Value(typeof(string));
708 var cont = new Gdk.ContentProvider.for_value(ov);
710 GLib.Value v = GLib.Value(typeof(string));
711 //var str = drop.read_text( [ "text/plain" ] 0);
713 cont.get_value(ref v);
716 GLib.debug("set %s", v.get_string());
722 this.el.drag_begin.connect( ( drag ) => {
723 GLib.debug("SOURCE: drag-begin");
725 // find what is selected in our tree...
726 var data = _this.selmodel.getSelectedNode();
730 _this.view.dragNode = data;
731 var xname = data.fqn();
732 GLib.debug ("XNAME IS %s", xname);
734 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
737 var paintable = new Gtk.WidgetPaintable(widget);
738 this.el.set_icon(paintable, 0,0);
742 this.el.drag_end.connect( (drag, delete_data) => {
744 _this.view.dragNode = null;
748 // user defined functions
751 public class Xcls_EventControllerKey8 : Object
753 public Gtk.EventControllerKey el;
754 private Xcls_WindowLeftTree _this;
760 public Xcls_EventControllerKey8(Xcls_WindowLeftTree _owner )
763 this.el = new Gtk.EventControllerKey();
767 // set gobject values
770 this.el.key_pressed.connect( (keyval, keycode, state) => {
774 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
778 _this.model.deleteSelected();
784 // user defined functions
787 public class Xcls_keystate : Object
789 public Gtk.EventControllerKey el;
790 private Xcls_WindowLeftTree _this;
797 public Xcls_keystate(Xcls_WindowLeftTree _owner )
800 _this.keystate = this;
801 this.el = new Gtk.EventControllerKey();
806 // set gobject values
809 this.el.key_released.connect( (keyval, keycode, state) => {
810 GLib.debug("key release %d, %d, %d" , (int) keyval, (int) keycode, state);
811 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
814 //GLib.debug("set state %d , shift = %d", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);
819 this.el.key_pressed.connect( (keyval, keycode, state) => {
821 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
828 // user defined functions
831 public class Xcls_drop : Object
833 public Gtk.DropTarget el;
834 private Xcls_WindowLeftTree _this;
838 public Gtk.Widget? highlightWidget;
839 public JsRender.Node? lastDragNode;
840 public string lastDragString;
843 public Xcls_drop(Xcls_WindowLeftTree _owner )
847 this.el = new Gtk.DropTarget ( typeof(string) ,
848 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
851 this.highlightWidget = null;
852 this.lastDragNode = null;
853 this.lastDragString = "";
855 // set gobject values
858 this.el.accept.connect( (drop) => {
860 GLib.debug("got DropTarget:accept");
862 // NOT REALLY NEEDED? = put stuff in drop?
865 /* ( ctx, x, y, time) => {
866 //Seed.print("TARGET: drag-drop");
869 var src = Gtk.drag_get_source_widget(ctx);
871 if (src != this.el) {
875 this.drag_in_motion = false;
876 // request data that will be recieved by the recieve...
879 this.el, // will receive 'drag-data-received' signal
880 ctx, // represents the current state of the DnD
881 Gdk.Atom.intern("application/json",true), // the target type we want
886 // No target offered by source => error
892 // handle drop around self..
896 //print("GETTING POS");
900 Gtk.TreeViewDropPosition pos;
901 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
903 // if there are not items in the tree.. the we have to set isOver to true for anything..
905 if (_this.model.el.iter_n_children(null) < 1) {
906 print("got NO children?\n");
909 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
914 //var action = Gdk.DragAction.COPY;
915 // unless we are copying!!! ctl button..
917 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
918 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
919 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
922 if (_this.model.el.iter_n_children(null) < 1) {
923 // no children.. -- asume it's ok..
925 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
927 // continue through to allow drop...
935 //print("ISOVER? " + isOver);
938 Gtk.drag_finish (ctx, false, false, time); // drop failed..
939 return true; // not over apoint!?! - no action on drop or motion..
942 // drag node is parent of child..
943 //console.log("SRC TREEPATH: " + src.treepath);
944 //console.log("TARGET TREEPATH: " + data.path.to_string());
946 // nned to check a few here..
947 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
948 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
949 //Gtk.TreeViewDropPosition.AFTER
950 //Gtk.TreeViewDropPosition.BEFORE
952 // locally dragged items to not really use the
953 var selection_text = this.dragData;
957 if (selection_text == null || selection_text.length < 1) {
958 //print("Error - drag selection text returned NULL");
960 Gtk.drag_finish (ctx, false, false, time); // drop failed..
961 return true; /// -- fixme -- this is not really correct..
964 // see if we are dragging into ourself?
965 print ("got selection text of " + selection_text);
967 var target_path = path.to_string();
968 //print("target_path="+target_path);
971 if (selection_text == target_path) {
972 print("self drag ?? == we should perhaps allow copy onto self..\n");
974 Gtk.drag_finish (ctx, false, false, time); // drop failed..
976 return true; /// -- fixme -- this is not really correct..
981 //print("DUMPING DATA");
982 //console.dump(data);
985 //print(data.path.to_string() +' => '+ data.pos);
987 // dropList is a list of xtypes that this node could be dropped on.
988 // it is set up when we start to drag..
991 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
993 print("targetDAta: " + targetData +"\n");
995 if (targetData.length < 1) {
996 //print("Can not find drop node path");
998 Gtk.drag_finish (ctx, false, false, time); // drop failed..
1004 // continue on to allow drop..
1006 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
1009 var delete_selection_data = false;
1011 if (action == Gdk.DragAction.ASK) {
1012 // Ask the user to move or copy, then set the ctx action.
1015 if (action == Gdk.DragAction.MOVE) {
1016 delete_selection_data = true;
1019 // drag around.. - reorder..
1020 _this.model.moveNode(targetData, action);
1026 // we can send stuff to souce here...
1029 // do we always say failure, so we handle the reall drop?
1030 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
1043 this.el.motion.connect( ( x, y) => {
1045 var is_shift = _this.keystate.is_shift > 0;
1047 GLib.debug("shift is %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
1048 string pos; // over / before / after..
1050 //GLib.debug("got drag motion");
1052 GLib.Value v = GLib.Value(typeof(string));
1053 //var str = drop.read_text( [ "text/plain" ] 0);
1054 var cont = this.el.current_drop.get_drag().content ;
1056 cont.get_value(ref v);
1057 } catch (GLib.Error e) {
1058 GLib.debug("failed to get drag value");
1059 return Gdk.DragAction.COPY;
1063 //GLib.debug("got %s", v.get_string());
1065 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1066 // still dragging same node
1068 this.lastDragNode = new JsRender.Node();
1069 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1073 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
1074 this.lastDragNode.fqn());
1077 foreach(var dp in drop_on_to) {
1080 GLib.debug("droplist: %s", string.joinv(", ", str));
1083 // if there are not items in the tree.. the we have to set isOver to true for anything..
1085 if (_this.model.el.n_items < 1) {
1086 // FIXME check valid drop types?
1087 if (drop_on_to.contains("*top")) {
1088 this.addHighlight(_this.view.el, "over");
1090 this.addHighlight(null, "");
1093 return Gdk.DragAction.COPY; // no need to highlight?
1098 GLib.debug("check is over");
1100 // if path of source and dest are inside each other..
1101 // need to add source info to drag?
1103 var row = _this.view.getRowAt(x,y, out pos);
1106 this.addHighlight(null, "");
1107 return Gdk.DragAction.COPY;
1109 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1111 var node = (JsRender.Node)tr.get_item();
1113 GLib.debug("Drop over node: %s", node.fqn());
1116 if (pos == "above" || pos == "below") {
1117 if (node.parent == null) {
1118 GLib.debug("no parent try center");
1122 if (!drop_on_to.contains(node.parent.fqn())) {
1123 GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1126 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1127 if (_this.view.dragNode != null && is_shift) {
1128 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1129 GLib.debug("shift drop not self not allowed");
1130 this.addHighlight(null, "");
1131 return Gdk.DragAction.COPY;
1144 if (pos == "over") {
1145 if (!drop_on_to.contains(node.fqn())) {
1146 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1147 this.addHighlight(null, "");
1148 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1150 if (_this.view.dragNode != null && is_shift) {
1151 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1152 GLib.debug("shift drop not self not allowed");
1153 this.addHighlight(null, "");
1154 return Gdk.DragAction.COPY;
1161 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1162 var w = _this.view.getWidgetAt(x,y);
1163 this.addHighlight(w, pos);
1164 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1166 this.el.leave.connect( ( ) => {
1167 this.addHighlight(null,"");
1170 this.el.drop.connect( (v, x, y) => {
1172 this.addHighlight(null,"");
1174 var is_shift = _this.keystate.is_shift > 0;
1177 // -- get position..
1178 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1179 // still dragging same node
1181 this.lastDragNode = new JsRender.Node();
1182 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1187 var dropNode = new JsRender.Node();
1188 dropNode.loadFromJsonString(v.get_string(), 1);
1189 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1191 // if there are not items in the tree.. the we have to set isOver to true for anything..
1193 if (_this.model.el.n_items < 1) {
1194 // FIXME check valid drop types?
1195 if (!drop_on_to.contains("*top")) {
1196 GLib.debug("drop on to list does not contain top?");
1199 // add new node to top..
1202 var m = (GLib.ListStore) _this.model.el.model;
1203 _this.main_window.windowstate.file.tree = dropNode;
1204 dropNode.updated_count++;
1207 _this.model.selectNode(dropNode);
1209 return true; // no need to highlight?
1215 var row = _this.view.getRowAt(x,y, out pos);
1217 return false; //Gdk.DragAction.COPY;
1219 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1221 var node = (JsRender.Node)tr.get_item();
1223 if (pos == "above" || pos == "below") {
1224 if (node.parent == null) {
1227 if (!drop_on_to.contains(node.parent.fqn())) {
1230 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1231 if (_this.view.dragNode != null && is_shift) {
1232 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1233 GLib.debug("shift drop not self not allowed");
1244 if (pos == "over") {
1245 if (!drop_on_to.contains(node.fqn())) {
1246 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1250 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1251 GLib.debug("shift drop not self not allowed");
1258 node.appendChild(dropNode);
1259 if (is_shift && _this.view.dragNode != null) {
1260 _this.model.selectNode(null);
1261 _this.view.dragNode.remove();
1264 dropNode.updated_count++;
1265 _this.model.selectNode(dropNode);
1271 GLib.debug("Above - insertBefore");
1273 node.parent.insertBefore(dropNode, node);
1274 if (is_shift && _this.view.dragNode != null) {
1275 _this.model.selectNode(null);
1276 _this.view.dragNode.remove();
1278 dropNode.updated_count++;
1279 _this.model.selectNode(dropNode);
1284 GLib.debug("Below - insertAfter");
1285 if (is_shift && _this.view.dragNode != null) {
1286 _this.model.selectNode(null);
1287 _this.view.dragNode.remove();
1291 node.parent.insertAfter(dropNode, node);
1292 dropNode.updated_count++;
1293 _this.model.selectNode(dropNode);
1299 // should not happen
1311 // user defined functions
1312 public void addHighlight (Gtk.Widget? w, string hl) {
1313 if (this.highlightWidget != null) {
1314 var ww = this.highlightWidget;
1315 GLib.debug("clear drag from previous highlight");
1316 if (ww.has_css_class("drag-below")) {
1317 ww.remove_css_class("drag-below");
1319 if (ww.has_css_class("drag-above")) {
1320 ww.remove_css_class("drag-above");
1322 if (ww.has_css_class("drag-over")) {
1323 ww.remove_css_class("drag-over");
1327 GLib.debug("add drag=%s to widget", hl);
1328 if (!w.has_css_class("drag-" + hl)) {
1329 w.add_css_class("drag-" + hl);
1332 this.highlightWidget = w;
1336 public class Xcls_selmodel : Object
1338 public Gtk.SingleSelection el;
1339 private Xcls_WindowLeftTree _this;
1345 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1348 _this.selmodel = this;
1349 new Xcls_model( _this );
1350 this.el = new Gtk.SingleSelection( _this.model.el );
1354 // set gobject values
1357 this.el.selection_changed.connect( (position, n_items) => {
1361 //if (!this.button_is_pressed && !this.key_is_pressed) {
1362 // then event was started by some other action
1363 // which should manually trigger all the events..
1364 // print("SKIPPING select - no button or key pressed\n");
1369 if (_this.view.blockChanges) { // probably not needed..
1370 GLib.debug("SKIPPING select - blockchanges set..");
1374 if (!_this.before_node_change( ) ) {
1375 _this.view.blockChanges = true;
1376 _this.selmodel.el.unselect_all();
1377 _this.view.blockChanges = false;
1381 if (_this.main_window.windowstate.file == null) {
1382 GLib.debug("SKIPPING select windowstate file is not set...");
1386 //var render = this.get('/LeftTree').getRenderer();
1387 GLib.debug("LEFT TREE -> view -> selection changed called");
1390 // -- it appears that the selection is not updated.
1391 // select the node...
1392 //_this.selmodel.el.set_selected(row);
1394 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1396 var snode = _this.selmodel.getSelectedNode();
1397 if (snode == null) {
1399 GLib.debug("selected rows < 1");
1400 //??this.model.load( false);
1401 _this.node_selected(null);
1409 GLib.debug ("calling left_tree.node_selected");
1410 _this.node_selected(snode);
1415 // no need to scroll. it's in the view as we clicked on it.
1416 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1422 // user defined functions
1423 public JsRender.Node? getSelectedNode () {
1424 if (this.el.selected_item == null) {
1427 var tr = (Gtk.TreeListRow)this.el.selected_item;
1428 return (JsRender.Node)tr.get_item();
1431 public JsRender.Node getNodeAt (uint row) {
1433 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1435 var a = tr.get_item();;
1436 GLib.debug("get_item (2) = %s", a.get_type().name());
1439 return (JsRender.Node)tr.get_item();
1443 public class Xcls_model : Object
1445 public Gtk.TreeListModel el;
1446 private Xcls_WindowLeftTree _this;
1452 public Xcls_model(Xcls_WindowLeftTree _owner )
1456 this.el = this.updateModel(null);
1460 // set gobject values
1463 // user defined functions
1464 public void loadFile (JsRender.JsRender f) {
1467 _this.drop.highlightWidget = null;
1469 var m = (GLib.ListStore) this.el.model;
1471 _this.main_window.windowstate.leftTreeNodeSelected(null);
1473 _this.main_window.windowstate.file = f;
1474 _this.last_error_counter = -1;
1476 if (f.tree == null) {
1483 // if it's still null?
1484 if (f.tree == null) {
1485 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1486 _this.updateErrors();
1490 _this.updateErrors();
1492 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1498 public int nodeToRow (JsRender.Node node)
1501 var s = _this.view.el.model as Gtk.SingleSelection;
1502 for (var i = 0; i < s.n_items; i++) {
1503 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1504 var lr = s.get_item(i) as Gtk.TreeListRow;
1505 //GLib.debug("check node %s", lr.get_item().get_type().name());
1506 var nn = (lr.get_item() as JsRender.Node);
1507 if (nn != null && nn.oid == node.oid) {
1516 public void deleteSelected () {
1520 var node = _this.selmodel.getSelectedNode();
1524 GLib.debug("delete Selected - no node slected?");
1527 _this.selmodel.el.unselect_all();
1530 GLib.debug("delete Selected - done");
1533 print("DELETE SELECTED?");
1534 //_this.view.blockChanges = true;
1535 print("GET SELECTION?");
1537 var s = _this.view.el.get_selection();
1539 print("GET SELECTED?");
1544 if (!s.get_selected(out mod, out iter)) {
1545 return; // nothing seleted..
1550 this.activePath= "";
1551 print("GET vnode value?");
1554 this.el.get_value(iter, 2, out value);
1555 var data = (JsRender.Node)(value.get_object());
1556 print("removing node from Render\n");
1557 if (data.parent == null) {
1558 _this.main_window.windowstate.file.tree = null;
1562 print("removing node from Tree\n");
1564 this.el.remove(ref iter);
1574 this.activePath= ""; // again!?!?
1575 //this.changed(null,true);
1579 _this.view.blockChanges = false;
1582 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1583 this.el = new Gtk.TreeListModel(
1584 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1588 return ((JsRender.Node)item).childstore;
1592 if (_this.selmodel.el == null) {
1595 _this.selmodel.el.set_model(this.el);
1598 public void selectNode (JsRender.Node? node)
1600 var s = _this.view.el.model as Gtk.SingleSelection;
1602 s.selected=Gtk.INVALID_LIST_POSITION;
1605 var row = this.nodeToRow(node);
1610 GLib.debug("Could not find node");
1611 s.selected=Gtk.INVALID_LIST_POSITION;
1614 GLib.debug("Select %d", row);
1615 s.set_selected(row);
1616 _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1617 //_this.node_selected(node);
1624 public class Xcls_maincol : Object
1626 public Gtk.ColumnViewColumn el;
1627 private Xcls_WindowLeftTree _this;
1633 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1636 _this.maincol = this;
1637 var child_1 = new Xcls_SignalListItemFactory14( _this );
1639 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1643 // set gobject values
1644 this.el.id = "maincol";
1645 this.el.expand = true;
1646 this.el.resizable = true;
1649 // user defined functions
1651 public class Xcls_SignalListItemFactory14 : Object
1653 public Gtk.SignalListItemFactory el;
1654 private Xcls_WindowLeftTree _this;
1660 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1663 this.el = new Gtk.SignalListItemFactory();
1667 // set gobject values
1670 this.el.setup.connect( (listitem) => {
1672 var expand = new Gtk.TreeExpander();
1674 expand.set_indent_for_depth(true);
1675 expand.set_indent_for_icon(true);
1676 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1677 var icon = new Gtk.Image();
1678 var lbl = new Gtk.Label("");
1679 lbl.use_markup = true;
1680 lbl.ellipsize = Pango.EllipsizeMode.END;
1682 icon.margin_end = 4;
1683 lbl.justify = Gtk.Justification.LEFT;
1686 // listitem.activatable = true; ??
1690 expand.set_child(hbox);
1691 ((Gtk.ListItem)listitem).set_child(expand);
1694 this.el.bind.connect( (listitem) => {
1695 GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1697 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1698 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1701 var hbox = (Gtk.Box) expand.child;
1704 var img = (Gtk.Image) hbox.get_first_child();
1705 var lbl = (Gtk.Label) img.get_next_sibling();
1707 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1708 var node = (JsRender.Node) lr.get_item();
1710 GLib.debug("node is %s", node.get_type().name());
1711 // was item (1) in old layout
1716 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1717 var clsname = node.fqn();
1719 var clsb = clsname.split(".");
1720 var sub = clsb.length > 1 ? clsb[1].down() : "";
1722 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1726 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1727 img.set_from_file(fn);
1730 img.set_from_paintable(
1732 "media-playback-stop", null, 16,1,
1733 Gtk.TextDirection.NONE, 0
1737 } catch (GLib.Error e) {}
1739 expand.set_hide_expander( !node.hasChildren() );
1740 expand.set_list_row(lr);
1742 node.bind_property("iconResourceName",
1744 GLib.BindingFlags.SYNC_CREATE);
1746 node.bind_property("nodeTitleProp",
1748 GLib.BindingFlags.SYNC_CREATE);
1749 node.bind_property("nodeTipProp",
1750 lbl, "tooltip_markup",
1751 GLib.BindingFlags.SYNC_CREATE);
1757 // user defined functions
1761 public class Xcls_ColumnViewColumn15 : Object
1763 public Gtk.ColumnViewColumn el;
1764 private Xcls_WindowLeftTree _this;
1770 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1773 var child_1 = new Xcls_SignalListItemFactory16( _this );
1775 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1779 // set gobject values
1780 this.el.fixed_width = 25;
1783 // user defined functions
1785 public class Xcls_SignalListItemFactory16 : Object
1787 public Gtk.SignalListItemFactory el;
1788 private Xcls_WindowLeftTree _this;
1794 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1797 this.el = new Gtk.SignalListItemFactory();
1801 // set gobject values
1804 this.el.setup.connect( (listitem) => {
1807 var icon = new Gtk.Image();
1809 ((Gtk.ListItem)listitem).set_child(icon);
1811 this.el.bind.connect( (listitem) => {
1813 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1814 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1815 var node = (JsRender.Node) lr.get_item();
1818 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1819 img.set_from_paintable(
1821 "list-add", null, 16,1,
1822 Gtk.TextDirection.NONE, 0
1826 var fqn = node.fqn();
1827 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1829 img.set_visible(cn.size > 0 ? true : false);
1834 // user defined functions
1839 public class Xcls_LeftTreeMenu : Object
1841 public Gtk.Popover el;
1842 private Xcls_WindowLeftTree _this;
1848 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1851 _this.LeftTreeMenu = this;
1852 this.el = new Gtk.Popover();
1856 // set gobject values
1857 var child_1 = new Xcls_Box18( _this );
1858 this.el.child = child_1.el;
1861 // user defined functions
1863 public class Xcls_Box18 : Object
1866 private Xcls_WindowLeftTree _this;
1872 public Xcls_Box18(Xcls_WindowLeftTree _owner )
1875 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1879 // set gobject values
1880 var child_1 = new Xcls_Button19( _this );
1882 this.el.append( child_1.el );
1883 var child_2 = new Xcls_Button20( _this );
1885 this.el.append( child_2.el );
1886 var child_3 = new Xcls_Button21( _this );
1888 this.el.append( child_3.el );
1891 // user defined functions
1893 public class Xcls_Button19 : Object
1895 public Gtk.Button el;
1896 private Xcls_WindowLeftTree _this;
1902 public Xcls_Button19(Xcls_WindowLeftTree _owner )
1905 this.el = new Gtk.Button();
1909 // set gobject values
1910 this.el.has_frame = false;
1911 this.el.label = "Delete Element";
1914 this.el.clicked.connect( ( ) => {
1915 _this.LeftTreeMenu.el.hide();
1916 _this.model.deleteSelected();
1921 // user defined functions
1924 public class Xcls_Button20 : Object
1926 public Gtk.Button el;
1927 private Xcls_WindowLeftTree _this;
1933 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1936 this.el = new Gtk.Button();
1940 // set gobject values
1941 this.el.has_frame = false;
1942 this.el.label = "Save as Template";
1945 this.el.clicked.connect( () => {
1946 _this.LeftTreeMenu.el.hide();
1947 DialogSaveTemplate.singleton().showIt(
1948 (Gtk.Window) _this.el.get_root (),
1949 _this.main_window.windowstate.file.palete(),
1950 _this.getActiveElement()
1957 // user defined functions
1960 public class Xcls_Button21 : Object
1962 public Gtk.Button el;
1963 private Xcls_WindowLeftTree _this;
1969 public Xcls_Button21(Xcls_WindowLeftTree _owner )
1972 this.el = new Gtk.Button();
1976 // set gobject values
1977 this.el.has_frame = false;
1978 this.el.label = "Save as Module";
1981 this.el.clicked.connect( () => {
1983 _this.LeftTreeMenu.el.hide();
1984 var node = _this.getActiveElement();
1987 var sm = DialogSaveModule.singleton();
1991 (Gtk.Window) _this.el.get_root (),
1992 _this.main_window.windowstate.project,
1996 gtk4 migration - disabled this part.. probably not used muchanyway
1999 if (name.length < 1) {
2003 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
2007 var s = _this.view.el.get_selection();
2009 print("GET SELECTED?");
2014 if (!s.get_selected(out mod, out iter)) {
2015 return; // nothing seleted..
2018 var n_cn = mod.iter_n_children(iter) -1;
2019 for (var i = n_cn; i > -1; i--) {
2020 mod.iter_nth_child(out citer, iter, i);
2023 print("removing node from Tree\n");
2025 _this.model.el.remove(ref citer);
2028 _this.node_selected(node, "tree");
2034 // user defined functions