1 static Xcls_WindowLeftTree _WindowLeftTree;
3 public class Xcls_WindowLeftTree : Object
6 private Xcls_WindowLeftTree _this;
8 public static Xcls_WindowLeftTree singleton()
10 if (_WindowLeftTree == null) {
11 _WindowLeftTree= new Xcls_WindowLeftTree();
13 return _WindowLeftTree;
15 public Xcls_viewwin viewwin;
16 public Xcls_view view;
17 public Xcls_drop drop;
18 public Xcls_selmodel selmodel;
19 public Xcls_model model;
20 public Xcls_maincol maincol;
21 public Xcls_LeftTreeMenu LeftTreeMenu;
24 public signal bool before_node_change ();
25 public Xcls_MainWindow main_window;
26 public signal void changed ();
27 public signal void node_selected (JsRender.Node? node);
30 public Xcls_WindowLeftTree()
33 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
36 this.main_window = null;
39 this.el.hexpand = true;
40 this.el.vexpand = true;
41 var child_1 = new Xcls_ListView2( _this );
43 this.el.append( child_1.el );
44 new Xcls_viewwin( _this );
45 this.el.append( _this.viewwin.el );
48 // user defined functions
49 public void onresize () {
52 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
53 // _this.maincol.el.set_max_width( _this.viewwin.el.get_width() - 32 );
55 public JsRender.Node? getActiveElement () { // return path to actie node.
58 return _this.selmodel.getSelectedNode();
62 public JsRender.JsRender getActiveFile () {
63 return this.main_window.windowstate.file;
65 public class Xcls_ListView2 : Object
67 public Gtk.ListView el;
68 private Xcls_WindowLeftTree _this;
74 public Xcls_ListView2(Xcls_WindowLeftTree _owner )
77 var child_1 = new Xcls_SignalListItemFactory3( _this );
79 this.el = new Gtk.ListView( null, child_1.el );
86 // user defined functions
88 public class Xcls_SignalListItemFactory3 : Object
90 public Gtk.SignalListItemFactory el;
91 private Xcls_WindowLeftTree _this;
97 public Xcls_SignalListItemFactory3(Xcls_WindowLeftTree _owner )
100 this.el = new Gtk.SignalListItemFactory();
104 // set gobject values
107 // user defined functions
111 public class Xcls_viewwin : Object
113 public Gtk.ScrolledWindow el;
114 private Xcls_WindowLeftTree _this;
120 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
123 _this.viewwin = this;
124 this.el = new Gtk.ScrolledWindow();
128 // set gobject values
129 this.el.has_frame = true;
130 this.el.hexpand = true;
131 this.el.vexpand = true;
132 new Xcls_view( _this );
133 this.el.child = _this.view.el;
134 new Xcls_LeftTreeMenu( _this );
138 this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
141 // user defined functions
143 public class Xcls_view : Object
145 public Gtk.ColumnView el;
146 private Xcls_WindowLeftTree _this;
150 public bool blockChanges;
151 public bool headers_visible;
152 public string lastEventSource;
153 public bool button_is_pressed;
154 public Gtk.CssProvider css;
157 public Xcls_view(Xcls_WindowLeftTree _owner )
161 new Xcls_selmodel( _this );
162 this.el = new Gtk.ColumnView( _this.selmodel.el );
165 this.blockChanges = false;
166 this.headers_visible = false;
167 this.lastEventSource = "";
168 this.button_is_pressed = false;
170 // set gobject values
171 this.el.name = "left-tree-view";
172 this.el.hexpand = false;
173 this.el.vexpand = true;
174 var child_2 = new Xcls_GestureClick6( _this );
176 this.el.add_controller( child_2.el );
177 var child_3 = new Xcls_GestureClick7( _this );
179 this.el.add_controller( child_3.el );
180 var child_4 = new Xcls_DragSource8( _this );
182 this.el.add_controller( child_4.el );
183 var child_5 = new Xcls_EventControllerKey9( _this );
185 this.el.add_controller( child_5.el );
186 new Xcls_drop( _this );
187 this.el.add_controller( _this.drop.el );
188 new Xcls_maincol( _this );
189 this.el.append_column ( _this.maincol.el );
190 var child_8 = new Xcls_ColumnViewColumn15( _this );
192 this.el.append_column ( child_8.el );
198 this.css = new Gtk.CssProvider();
200 this.css.load_from_string("
201 #left-tree-view { font-size: 12px;}
202 .drag-over { background-color:#88a3bc; }
204 border-bottom-width: 5px;
205 border-bottom-style: solid;
206 border-bottom-color: #88a3bc;
209 border-top-width: 5px;
210 border-top-style: solid;
211 border-top-color: #88a3bc;
213 #left-tree-view indent {
214 -gtk-icon-size : 2px;
218 Gtk.StyleContext.add_provider_for_display(
219 this.el.get_display(),
221 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
228 // user defined functions
229 public Gtk.Widget? getWidgetAtRow (uint row) {
232 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
233 var colview = gesture.widget;
234 var line_no = check_list_widget(colview, x,y);
236 var item = colview.model.get_item(line_no);
240 //GLib.debug("Get Widget At Row %d", (int)row);
241 var child = this.el.get_first_child();
243 var reading_header = true;
245 while (child != null) {
246 GLib.debug("Got %s", child.get_type().name());
248 if (reading_header) {
251 if (child.get_type().name() != "GtkColumnListView") {
253 child = child.get_next_sibling();
256 // should be columnlistview
257 child = child.get_first_child();
261 reading_header = false;
268 if (line_no == row) {
269 //GLib.debug("Returning widget %s", child.get_type().name());
270 return (Gtk.Widget)child;
272 child = child.get_next_sibling();
274 //GLib.debug("Rturning null");
278 public int getColAt (double x, double y) {
281 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
284 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
285 //GLib.debug("Cehck %d, %d", x,y);
286 var child = this.el.get_first_child();
290 while (child != null) {
292 if (child.get_type().name() == "GtkColumnViewRowWidget") {
293 child = child.get_first_child();
297 //child.get_allocation(out alloc);
298 if (x < (child.get_width() + offx)) {
302 //offx += child.get_width();
304 //child = child.get_next_sibling();
311 public int getRowAt (double x, double in_y, out string pos) {
318 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
319 var colview = gesture.widget;
320 var line_no = check_list_widget(colview, x,y);
322 var item = colview.model.get_item(line_no);
328 //GLib.debug("offset = %d y = %d", (int) voff, (int) in_y);
329 var y = in_y + _this.viewwin.el.vadjustment.value;
330 var child = this.el.get_first_child();
331 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
333 var reading_header = true;
335 var header_height = 0;
338 while (child != null) {
339 //GLib.debug("Got %s", child.get_type().name());
340 if (reading_header) {
343 if (child.get_type().name() != "GtkColumnListView") {
344 h += child.get_height();
345 child = child.get_next_sibling();
348 // should be columnlistview
349 child = child.get_first_child();
350 GLib.debug("header height=%d", h);
353 reading_header = false;
357 if (child.get_type().name() != "GtkColumnViewRowWidget") {
358 child = child.get_next_sibling();
362 if (y < header_height) {
367 var hh = child.get_height();
368 //child.get_allocation(out alloc);
369 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
370 //GLib.debug("row %d y= %d %s", line_no, (int) (header_height + alloc.y),
372 // child.visible ? "VIS" : "hidden");
374 if (y > (header_height + real_y) && y <= (header_height + real_y + hh) ) {
375 if (y > ( header_height + real_y + (hh * 0.8))) {
377 } else if (y > ( header_height + real_y + (hh * 0.2))) {
382 GLib.debug("getRowAt return : %d, %s", line_no, pos);
387 if (real_y + hh > y) {
391 child = child.get_next_sibling();
396 public Gtk.Widget? getWidgetAt (double x, double in_y) {
399 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
400 var colview = gesture.widget;
401 var line_no = check_list_widget(colview, x,y);
403 var item = colview.model.get_item(line_no);
407 var y = in_y + _this.viewwin.el.vadjustment.value;
408 var child = this.el.get_first_child();
409 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
411 var reading_header = true;
413 var header_height = 0;
415 while (child != null) {
416 //GLib.debug("Got %s", child.get_type().name());
417 if (reading_header) {
420 if (child.get_type().name() != "GtkColumnListView") {
421 h += child.get_height();
422 child = child.get_next_sibling();
425 // should be columnlistview
426 child = child.get_first_child();
427 GLib.debug("header height=%d", h);
430 reading_header = false;
435 if (y < header_height) {
439 var hh = child.get_height();
440 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
442 if (y > curr_y && y <= header_height + hh + curr_y ) {
443 return (Gtk.Widget)child;
450 child = child.get_next_sibling();
456 public class Xcls_GestureClick6 : Object
458 public Gtk.GestureClick el;
459 private Xcls_WindowLeftTree _this;
465 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
468 this.el = new Gtk.GestureClick();
472 // set gobject values
475 this.el.released.connect( (n_press, x, y) => {
477 _this.view.button_is_pressed = false;
481 this.el.pressed.connect( (n_press, x, y) => {
483 //console.log("button press?");
485 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
489 _this.view.button_is_pressed = true;
491 _this.view.lastEventSource = "tree";
492 if (! _this.before_node_change() ) {
493 GLib.debug("before_node_change return false");
497 // nothing there -show dialog
498 if (_this.model.el.get_n_items() < 1) {
499 _this.main_window.windowstate.showAddObject(_this.view.el, null);
500 GLib.debug("no items");
504 var row = _this.view.getRowAt(x,y, out pos );
506 GLib.debug("no row selected items");
510 var node = _this.selmodel.getNodeAt(row);
512 GLib.warning("No node found at row %d", row);
518 if (_this.view.getColAt(x,y) > 0 ) {
519 GLib.debug("add colum clicked.");
520 var fqn = node.fqn();
521 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
526 _this.main_window.windowstate.leftTreeBeforeChange();
527 //_this.view.el.get_selection().select_path(res);
528 GLib.debug("Button Pressed - start show window");
529 _this.main_window.windowstate.showAddObject(_this.view.el, node);
530 GLib.debug("Button Pressed - finsihed show window");
539 // user defined functions
542 public class Xcls_GestureClick7 : Object
544 public Gtk.GestureClick el;
545 private Xcls_WindowLeftTree _this;
551 public Xcls_GestureClick7(Xcls_WindowLeftTree _owner )
554 this.el = new Gtk.GestureClick();
558 // set gobject values
562 this.el.pressed.connect( (n_press, x, y) => {
567 if (_this.model.el.get_n_items() < 1) {
569 GLib.debug("no items");
573 var row = _this.view.getRowAt(x,y, out pos );
575 GLib.debug("no row selected items");
579 var node = _this.selmodel.getNodeAt(row);
581 GLib.warning("No node found at row %d", row);
584 _this.model.selectNode(node);
588 GLib.debug("Prssed %d", (int) this.el.get_current_button());
589 //_this.deletemenu.el.set_parent(_this.view.el);
590 _this.LeftTreeMenu.el.set_parent(_this.view.el);
593 //Gtk.Allocation rect;
594 //_this.view.el.get_allocation(out rect);
595 //_this.deletemenu.el.set_has_arrow(false);
596 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
599 _this.LeftTreeMenu.el.set_offset(
601 (int)y - (int)_this.view.el.get_height());
603 _this.LeftTreeMenu.el.popup();
608 // user defined functions
611 public class Xcls_DragSource8 : Object
613 public Gtk.DragSource el;
614 private Xcls_WindowLeftTree _this;
620 public Xcls_DragSource8(Xcls_WindowLeftTree _owner )
623 this.el = new Gtk.DragSource();
627 // set gobject values
628 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
631 this.el.prepare.connect( (x, y) => {
635 /// ( drag_context, data, info, time) => {
638 //print("drag-data-get");
639 var ndata = _this.selmodel.getSelectedNode();
641 GLib.debug("return empty string - no selection..");
647 //data.set_text(tp,tp.length);
649 var str = ndata.toJsonString();
650 GLib.debug("prepare store: %s", str);
651 GLib.Value ov = GLib.Value(typeof(string));
653 var cont = new Gdk.ContentProvider.for_value(ov);
655 GLib.Value v = GLib.Value(typeof(string));
656 //var str = drop.read_text( [ "text/plain" ] 0);
658 cont.get_value(ref v);
661 GLib.debug("set %s", v.get_string());
667 this.el.drag_begin.connect( ( drag ) => {
668 GLib.debug("SOURCE: drag-begin");
670 // find what is selected in our tree...
671 var data = _this.selmodel.getSelectedNode();
676 var xname = data.fqn();
677 GLib.debug ("XNAME IS %s", xname);
679 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
682 var paintable = new Gtk.WidgetPaintable(widget);
683 this.el.set_icon(paintable, 0,0);
689 // user defined functions
692 public class Xcls_EventControllerKey9 : Object
694 public Gtk.EventControllerKey el;
695 private Xcls_WindowLeftTree _this;
701 public Xcls_EventControllerKey9(Xcls_WindowLeftTree _owner )
704 this.el = new Gtk.EventControllerKey();
708 // set gobject values
711 this.el.key_pressed.connect( (keyval, keycode, state) => {
715 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
719 _this.model.deleteSelected();
725 // user defined functions
728 public class Xcls_drop : Object
730 public Gtk.DropTarget el;
731 private Xcls_WindowLeftTree _this;
735 public Gtk.Widget? highlightWidget;
736 public JsRender.Node? lastDragNode;
737 public string lastDragString;
740 public Xcls_drop(Xcls_WindowLeftTree _owner )
744 this.el = new Gtk.DropTarget ( typeof(string) ,
745 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
748 this.highlightWidget = null;
749 this.lastDragNode = null;
750 this.lastDragString = "";
752 // set gobject values
755 this.el.accept.connect( (drop) => {
757 GLib.debug("got DropTarget:accept");
759 // NOT REALLY NEEDED? = put stuff in drop?
762 /* ( ctx, x, y, time) => {
763 //Seed.print("TARGET: drag-drop");
766 var src = Gtk.drag_get_source_widget(ctx);
768 if (src != this.el) {
772 this.drag_in_motion = false;
773 // request data that will be recieved by the recieve...
776 this.el, // will receive 'drag-data-received' signal
777 ctx, // represents the current state of the DnD
778 Gdk.Atom.intern("application/json",true), // the target type we want
783 // No target offered by source => error
789 // handle drop around self..
793 //print("GETTING POS");
797 Gtk.TreeViewDropPosition pos;
798 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
800 // if there are not items in the tree.. the we have to set isOver to true for anything..
802 if (_this.model.el.iter_n_children(null) < 1) {
803 print("got NO children?\n");
806 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
811 //var action = Gdk.DragAction.COPY;
812 // unless we are copying!!! ctl button..
814 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
815 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
816 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
819 if (_this.model.el.iter_n_children(null) < 1) {
820 // no children.. -- asume it's ok..
822 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
824 // continue through to allow drop...
832 //print("ISOVER? " + isOver);
835 Gtk.drag_finish (ctx, false, false, time); // drop failed..
836 return true; // not over apoint!?! - no action on drop or motion..
839 // drag node is parent of child..
840 //console.log("SRC TREEPATH: " + src.treepath);
841 //console.log("TARGET TREEPATH: " + data.path.to_string());
843 // nned to check a few here..
844 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
845 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
846 //Gtk.TreeViewDropPosition.AFTER
847 //Gtk.TreeViewDropPosition.BEFORE
849 // locally dragged items to not really use the
850 var selection_text = this.dragData;
854 if (selection_text == null || selection_text.length < 1) {
855 //print("Error - drag selection text returned NULL");
857 Gtk.drag_finish (ctx, false, false, time); // drop failed..
858 return true; /// -- fixme -- this is not really correct..
861 // see if we are dragging into ourself?
862 print ("got selection text of " + selection_text);
864 var target_path = path.to_string();
865 //print("target_path="+target_path);
868 if (selection_text == target_path) {
869 print("self drag ?? == we should perhaps allow copy onto self..\n");
871 Gtk.drag_finish (ctx, false, false, time); // drop failed..
873 return true; /// -- fixme -- this is not really correct..
878 //print("DUMPING DATA");
879 //console.dump(data);
882 //print(data.path.to_string() +' => '+ data.pos);
884 // dropList is a list of xtypes that this node could be dropped on.
885 // it is set up when we start to drag..
888 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
890 print("targetDAta: " + targetData +"\n");
892 if (targetData.length < 1) {
893 //print("Can not find drop node path");
895 Gtk.drag_finish (ctx, false, false, time); // drop failed..
901 // continue on to allow drop..
903 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
906 var delete_selection_data = false;
908 if (action == Gdk.DragAction.ASK) {
909 // Ask the user to move or copy, then set the ctx action.
912 if (action == Gdk.DragAction.MOVE) {
913 delete_selection_data = true;
916 // drag around.. - reorder..
917 _this.model.moveNode(targetData, action);
923 // we can send stuff to souce here...
926 // do we always say failure, so we handle the reall drop?
927 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
940 this.el.motion.connect( ( x, y) => {
942 string pos; // over / before / after..
944 GLib.debug("got drag motion");
946 GLib.Value v = GLib.Value(typeof(string));
947 //var str = drop.read_text( [ "text/plain" ] 0);
948 var cont = this.el.current_drop.get_drag().content ;
950 cont.get_value(ref v);
951 } catch (GLib.Error e) {
952 GLib.debug("failed to get drag value");
953 return Gdk.DragAction.COPY;
957 GLib.debug("got %s", v.get_string());
959 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
960 // still dragging same node
962 this.lastDragNode = new JsRender.Node();
963 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
967 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
968 this.lastDragNode.fqn());
971 foreach(var dp in drop_on_to) {
974 GLib.debug("droplist: %s", string.joinv(", ", str));
977 // if there are not items in the tree.. the we have to set isOver to true for anything..
979 if (_this.model.el.n_items < 1) {
980 // FIXME check valid drop types?
981 if (drop_on_to.contains("*top")) {
982 this.addHighlight(_this.view.el, "over");
984 this.addHighlight(null, "");
987 return Gdk.DragAction.COPY; // no need to highlight?
992 GLib.debug("check is over");
994 // if path of source and dest are inside each other..
995 // need to add source info to drag?
997 var row = _this.view.getRowAt(x,y, out pos);
1000 this.addHighlight(null, "");
1001 return Gdk.DragAction.COPY;
1003 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1005 var node = (JsRender.Node)tr.get_item();
1007 GLib.debug("Drop over node: %s", node.fqn());
1010 if (pos == "above" || pos == "below") {
1011 if (node.parent == null) {
1012 GLib.debug("no parent try center");
1016 if (!drop_on_to.contains(node.parent.fqn())) {
1017 GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1020 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1025 if (pos == "over") {
1026 if (!drop_on_to.contains(node.fqn())) {
1027 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1028 this.addHighlight(null, "");
1029 return Gdk.DragAction.COPY;
1034 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1035 var w = _this.view.getWidgetAt(x,y);
1036 this.addHighlight(w, pos);
1037 return Gdk.DragAction.COPY;
1039 this.el.leave.connect( ( ) => {
1040 this.addHighlight(null,"");
1043 this.el.drop.connect( (v, x, y) => {
1045 this.addHighlight(null,"");
1050 // -- get position..
1051 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1052 // still dragging same node
1054 this.lastDragNode = new JsRender.Node();
1055 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1060 var dropNode = new JsRender.Node();
1061 dropNode.loadFromJsonString(v.get_string(), 1);
1062 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1064 // if there are not items in the tree.. the we have to set isOver to true for anything..
1066 if (_this.model.el.n_items < 1) {
1067 // FIXME check valid drop types?
1068 if (!drop_on_to.contains("*top")) {
1069 GLib.debug("drop on to list does not contain top?");
1072 // add new node to top..
1075 var m = (GLib.ListStore) _this.model.el.model;
1076 _this.main_window.windowstate.file.tree = dropNode;
1080 _this.model.selectNode(dropNode);
1082 return true; // no need to highlight?
1088 var row = _this.view.getRowAt(x,y, out pos);
1090 return false; //Gdk.DragAction.COPY;
1092 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1094 var node = (JsRender.Node)tr.get_item();
1096 if (pos == "above" || pos == "below") {
1097 if (node.parent == null) {
1100 if (!drop_on_to.contains(node.parent.fqn())) {
1103 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1108 if (pos == "over") {
1109 if (!drop_on_to.contains(node.fqn())) {
1110 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1118 node.appendChild(dropNode);
1119 _this.model.selectNode(dropNode);
1124 GLib.debug("Above - insertBefore");
1126 node.parent.insertBefore(dropNode, node);
1127 _this.model.selectNode(dropNode);
1132 GLib.debug("Below - insertAfter");
1133 node.parent.insertAfter(dropNode, node);
1134 _this.model.selectNode(dropNode);
1140 // should not happen
1152 // user defined functions
1153 public void addHighlight (Gtk.Widget? w, string hl) {
1154 if (this.highlightWidget != null) {
1155 var ww = this.highlightWidget;
1156 GLib.debug("clear drag from previous highlight");
1157 if (ww.has_css_class("drag-below")) {
1158 ww.remove_css_class("drag-below");
1160 if (ww.has_css_class("drag-above")) {
1161 ww.remove_css_class("drag-above");
1163 if (ww.has_css_class("drag-over")) {
1164 ww.remove_css_class("drag-over");
1168 GLib.debug("add drag=%s to widget", hl);
1169 if (!w.has_css_class("drag-" + hl)) {
1170 w.add_css_class("drag-" + hl);
1173 this.highlightWidget = w;
1177 public class Xcls_selmodel : Object
1179 public Gtk.SingleSelection el;
1180 private Xcls_WindowLeftTree _this;
1186 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1189 _this.selmodel = this;
1190 new Xcls_model( _this );
1191 this.el = new Gtk.SingleSelection( _this.model.el );
1195 // set gobject values
1198 this.el.selection_changed.connect( (position, n_items) => {
1202 //if (!this.button_is_pressed && !this.key_is_pressed) {
1203 // then event was started by some other action
1204 // which should manually trigger all the events..
1205 // print("SKIPPING select - no button or key pressed\n");
1210 if (_this.view.blockChanges) { // probably not needed..
1211 GLib.debug("SKIPPING select - blockchanges set..");
1215 if (!_this.before_node_change( ) ) {
1216 _this.view.blockChanges = true;
1217 _this.selmodel.el.unselect_all();
1218 _this.view.blockChanges = false;
1222 if (_this.main_window.windowstate.file == null) {
1223 GLib.debug("SKIPPING select windowstate file is not set...");
1227 //var render = this.get('/LeftTree').getRenderer();
1228 GLib.debug("LEFT TREE -> view -> selection changed called");
1231 // -- it appears that the selection is not updated.
1232 // select the node...
1233 //_this.selmodel.el.set_selected(row);
1235 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1237 var snode = _this.selmodel.getSelectedNode();
1238 if (snode == null) {
1240 GLib.debug("selected rows < 1");
1241 //??this.model.load( false);
1242 _this.node_selected(null);
1250 GLib.debug ("calling left_tree.node_selected");
1251 _this.node_selected(snode);
1256 // no need to scroll. it's in the view as we clicked on it.
1257 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1263 // user defined functions
1264 public JsRender.Node? getSelectedNode () {
1265 if (this.el.selected_item == null) {
1268 var tr = (Gtk.TreeListRow)this.el.selected_item;
1269 return (JsRender.Node)tr.get_item();
1272 public JsRender.Node getNodeAt (uint row) {
1274 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1276 var a = tr.get_item();;
1277 GLib.debug("get_item (2) = %s", a.get_type().name());
1280 return (JsRender.Node)tr.get_item();
1284 public class Xcls_model : Object
1286 public Gtk.TreeListModel el;
1287 private Xcls_WindowLeftTree _this;
1293 public Xcls_model(Xcls_WindowLeftTree _owner )
1297 this.el = this.updateModel(null);
1301 // set gobject values
1304 // user defined functions
1305 public void loadFile (JsRender.JsRender f) {
1308 _this.drop.highlightWidget = null;
1310 var m = (GLib.ListStore) this.el.model;
1312 _this.main_window.windowstate.leftTreeNodeSelected(null);
1314 _this.main_window.windowstate.file = f;
1317 if (f.tree == null) {
1324 // if it's still null?
1325 if (f.tree == null) {
1326 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1334 if (f.tree.readItems().size < 1) {
1337 //this.get('/Window.leftvpaned').el.set_position(80);
1339 _this.view.el.set_cursor(
1340 new Gtk.TreePath.from_string("0"), null, false);
1344 //this.get('/Window.leftvpaned').el.set_position(200);
1350 //_this.maincol.el.set_max_width(_this.viewwin.el.get_allocated_width() - 32);
1352 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1358 public void deleteSelected () {
1362 var node = _this.selmodel.getSelectedNode();
1366 GLib.debug("delete Selected - no node slected?");
1369 _this.selmodel.el.unselect_all();
1372 GLib.debug("delete Selected - done");
1375 print("DELETE SELECTED?");
1376 //_this.view.blockChanges = true;
1377 print("GET SELECTION?");
1379 var s = _this.view.el.get_selection();
1381 print("GET SELECTED?");
1386 if (!s.get_selected(out mod, out iter)) {
1387 return; // nothing seleted..
1392 this.activePath= "";
1393 print("GET vnode value?");
1396 this.el.get_value(iter, 2, out value);
1397 var data = (JsRender.Node)(value.get_object());
1398 print("removing node from Render\n");
1399 if (data.parent == null) {
1400 _this.main_window.windowstate.file.tree = null;
1404 print("removing node from Tree\n");
1406 this.el.remove(ref iter);
1416 this.activePath= ""; // again!?!?
1417 //this.changed(null,true);
1421 _this.view.blockChanges = false;
1424 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1425 this.el = new Gtk.TreeListModel(
1426 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1430 return ((JsRender.Node)item).childstore;
1434 _this.selmodel.el.set_model(this.el);
1437 public void selectNode (JsRender.Node node)
1440 var s = (Gtk.SingleSelection)_this.view.el.model;
1441 for (var i = 0; i < s.n_items; i++) {
1442 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1443 var lr = (Gtk.TreeListRow)s.get_item(i);
1444 GLib.debug("check node %s", lr.get_item().get_type().name());
1445 if (((JsRender.Node)lr.get_item()).oid == node.oid) {
1452 GLib.debug("Could not find node");
1455 GLib.debug("Select %d", row);
1456 s.set_selected(row);
1457 _this.node_selected(node);
1464 public class Xcls_maincol : Object
1466 public Gtk.ColumnViewColumn el;
1467 private Xcls_WindowLeftTree _this;
1473 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1476 _this.maincol = this;
1477 var child_1 = new Xcls_SignalListItemFactory14( _this );
1479 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1483 // set gobject values
1484 this.el.id = "maincol";
1485 this.el.expand = true;
1486 this.el.resizable = true;
1489 // user defined functions
1491 public class Xcls_SignalListItemFactory14 : Object
1493 public Gtk.SignalListItemFactory el;
1494 private Xcls_WindowLeftTree _this;
1500 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1503 this.el = new Gtk.SignalListItemFactory();
1507 // set gobject values
1510 this.el.setup.connect( (listitem) => {
1512 var expand = new Gtk.TreeExpander();
1514 expand.set_indent_for_depth(true);
1515 expand.set_indent_for_icon(true);
1516 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1517 var icon = new Gtk.Image();
1518 var lbl = new Gtk.Label("");
1519 lbl.use_markup = true;
1520 lbl.ellipsize = Pango.EllipsizeMode.END;
1522 icon.margin_end = 4;
1523 lbl.justify = Gtk.Justification.LEFT;
1526 // listitem.activatable = true; ??
1530 expand.set_child(hbox);
1531 ((Gtk.ListItem)listitem).set_child(expand);
1534 this.el.bind.connect( (listitem) => {
1535 GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1537 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1538 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1541 var hbox = (Gtk.Box) expand.child;
1544 var img = (Gtk.Image) hbox.get_first_child();
1545 var lbl = (Gtk.Label) img.get_next_sibling();
1547 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1548 var node = (JsRender.Node) lr.get_item();
1550 GLib.debug("node is %s", node.get_type().name());
1551 // was item (1) in old layout
1556 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1557 var clsname = node.fqn();
1559 var clsb = clsname.split(".");
1560 var sub = clsb.length > 1 ? clsb[1].down() : "";
1562 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1566 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1567 img.set_from_file(fn);
1570 img.set_from_paintable(
1572 "media-playback-stop", null, 16,1,
1573 Gtk.TextDirection.NONE, 0
1577 } catch (GLib.Error e) {}
1579 expand.set_hide_expander( !node.hasChildren() );
1580 expand.set_list_row(lr);
1582 node.bind_property("iconFilename",
1584 GLib.BindingFlags.SYNC_CREATE);
1586 node.bind_property("nodeTitleProp",
1588 GLib.BindingFlags.SYNC_CREATE);
1589 node.bind_property("nodeTipProp",
1590 lbl, "tooltip_markup",
1591 GLib.BindingFlags.SYNC_CREATE);
1597 // user defined functions
1601 public class Xcls_ColumnViewColumn15 : Object
1603 public Gtk.ColumnViewColumn el;
1604 private Xcls_WindowLeftTree _this;
1610 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1613 var child_1 = new Xcls_SignalListItemFactory16( _this );
1615 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1619 // set gobject values
1620 this.el.fixed_width = 25;
1623 // user defined functions
1625 public class Xcls_SignalListItemFactory16 : Object
1627 public Gtk.SignalListItemFactory el;
1628 private Xcls_WindowLeftTree _this;
1634 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1637 this.el = new Gtk.SignalListItemFactory();
1641 // set gobject values
1644 this.el.setup.connect( (listitem) => {
1647 var icon = new Gtk.Image();
1649 ((Gtk.ListItem)listitem).set_child(icon);
1651 this.el.bind.connect( (listitem) => {
1653 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1654 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1655 var node = (JsRender.Node) lr.get_item();
1658 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1659 img.set_from_paintable(
1661 "list-add", null, 16,1,
1662 Gtk.TextDirection.NONE, 0
1666 var fqn = node.fqn();
1667 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1669 img.set_visible(cn.size > 0 ? true : false);
1674 // user defined functions
1679 public class Xcls_LeftTreeMenu : Object
1681 public Gtk.Popover el;
1682 private Xcls_WindowLeftTree _this;
1688 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1691 _this.LeftTreeMenu = this;
1692 this.el = new Gtk.Popover();
1696 // set gobject values
1697 var child_1 = new Xcls_Box18( _this );
1698 this.el.child = child_1.el;
1701 // user defined functions
1703 public class Xcls_Box18 : Object
1706 private Xcls_WindowLeftTree _this;
1712 public Xcls_Box18(Xcls_WindowLeftTree _owner )
1715 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1719 // set gobject values
1720 var child_1 = new Xcls_Button19( _this );
1722 this.el.append( child_1.el );
1723 var child_2 = new Xcls_Button20( _this );
1725 this.el.append( child_2.el );
1726 var child_3 = new Xcls_Button21( _this );
1728 this.el.append( child_3.el );
1731 // user defined functions
1733 public class Xcls_Button19 : Object
1735 public Gtk.Button el;
1736 private Xcls_WindowLeftTree _this;
1742 public Xcls_Button19(Xcls_WindowLeftTree _owner )
1745 this.el = new Gtk.Button();
1749 // set gobject values
1750 this.el.label = "Delete Element";
1753 this.el.clicked.connect( ( ) => {
1757 _this.LeftTreeMenu.el.hide();
1758 _this.model.deleteSelected();
1762 // user defined functions
1765 public class Xcls_Button20 : Object
1767 public Gtk.Button el;
1768 private Xcls_WindowLeftTree _this;
1774 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1777 this.el = new Gtk.Button();
1781 // set gobject values
1782 this.el.label = "Save as Template";
1785 this.el.clicked.connect( () => {
1786 _this.LeftTreeMenu.el.hide();
1787 DialogSaveTemplate.singleton().showIt(
1788 (Gtk.Window) _this.el.get_root (),
1789 _this.main_window.windowstate.file.palete(),
1790 _this.getActiveElement()
1797 // user defined functions
1800 public class Xcls_Button21 : Object
1802 public Gtk.Button el;
1803 private Xcls_WindowLeftTree _this;
1809 public Xcls_Button21(Xcls_WindowLeftTree _owner )
1812 this.el = new Gtk.Button();
1816 // set gobject values
1817 this.el.label = "Save as Module";
1820 this.el.clicked.connect( () => {
1822 _this.LeftTreeMenu.el.hide();
1823 var node = _this.getActiveElement();
1826 var sm = DialogSaveModule.singleton();
1830 (Gtk.Window) _this.el.get_root (),
1831 _this.main_window.windowstate.project,
1835 gtk4 migration - disabled this part.. probably not used muchanyway
1838 if (name.length < 1) {
1842 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
1846 var s = _this.view.el.get_selection();
1848 print("GET SELECTED?");
1853 if (!s.get_selected(out mod, out iter)) {
1854 return; // nothing seleted..
1857 var n_cn = mod.iter_n_children(iter) -1;
1858 for (var i = n_cn; i > -1; i--) {
1859 mod.iter_nth_child(out citer, iter, i);
1862 print("removing node from Tree\n");
1864 _this.model.el.remove(ref citer);
1867 _this.node_selected(node, "tree");
1873 // user defined functions