1 static Xcls_WindowLeftTree _WindowLeftTree;
3 public class Xcls_WindowLeftTree : Object
6 private Xcls_WindowLeftTree _this;
8 public static Xcls_WindowLeftTree singleton()
10 if (_WindowLeftTree == null) {
11 _WindowLeftTree= new Xcls_WindowLeftTree();
13 return _WindowLeftTree;
15 public Xcls_viewwin viewwin;
16 public Xcls_view view;
17 public Xcls_drop drop;
18 public Xcls_selmodel selmodel;
19 public Xcls_model model;
20 public Xcls_maincol maincol;
21 public Xcls_keystate keystate;
22 public Xcls_LeftTreeMenu LeftTreeMenu;
25 public signal bool before_node_change ();
26 public Xcls_MainWindow main_window;
27 public signal void changed ();
28 public signal void node_selected (JsRender.Node? node);
31 public Xcls_WindowLeftTree()
34 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
37 this.main_window = null;
40 this.el.hexpand = true;
41 this.el.vexpand = true;
42 var child_1 = new Xcls_ListView2( _this );
44 this.el.append( child_1.el );
45 new Xcls_viewwin( _this );
46 this.el.append( _this.viewwin.el );
49 // user defined functions
50 public void onresize () {
53 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
54 // _this.maincol.el.set_max_width( _this.viewwin.el.get_width() - 32 );
56 public JsRender.Node? getActiveElement () { // return path to actie node.
59 return _this.selmodel.getSelectedNode();
63 public JsRender.JsRender getActiveFile () {
64 return this.main_window.windowstate.file;
66 public class Xcls_ListView2 : Object
68 public Gtk.ListView el;
69 private Xcls_WindowLeftTree _this;
75 public Xcls_ListView2(Xcls_WindowLeftTree _owner )
78 var child_1 = new Xcls_SignalListItemFactory3( _this );
80 this.el = new Gtk.ListView( null, child_1.el );
87 // user defined functions
89 public class Xcls_SignalListItemFactory3 : Object
91 public Gtk.SignalListItemFactory el;
92 private Xcls_WindowLeftTree _this;
98 public Xcls_SignalListItemFactory3(Xcls_WindowLeftTree _owner )
101 this.el = new Gtk.SignalListItemFactory();
105 // set gobject values
108 // user defined functions
112 public class Xcls_viewwin : Object
114 public Gtk.ScrolledWindow el;
115 private Xcls_WindowLeftTree _this;
121 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
124 _this.viewwin = this;
125 this.el = new Gtk.ScrolledWindow();
129 // set gobject values
130 this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
131 this.el.has_frame = true;
132 this.el.hexpand = true;
133 this.el.vexpand = true;
134 this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
135 new Xcls_view( _this );
136 this.el.child = _this.view.el;
137 new Xcls_LeftTreeMenu( _this );
140 // user defined functions
142 public class Xcls_view : Object
144 public Gtk.ColumnView el;
145 private Xcls_WindowLeftTree _this;
149 public bool blockChanges;
150 public bool headers_visible;
151 public string lastEventSource;
152 public bool button_is_pressed;
153 public Gtk.CssProvider css;
154 public JsRender.Node? dragNode;
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;
169 this.dragNode = null;
171 // set gobject values
172 this.el.name = "left-tree-view";
173 this.el.hexpand = false;
174 this.el.vexpand = true;
175 var child_2 = new Xcls_GestureClick6( _this );
177 this.el.add_controller( child_2.el );
178 var child_3 = new Xcls_GestureClick7( _this );
180 this.el.add_controller( child_3.el );
181 var child_4 = new Xcls_DragSource8( _this );
183 this.el.add_controller( child_4.el );
184 var child_5 = new Xcls_EventControllerKey9( _this );
186 this.el.add_controller( child_5.el );
187 new Xcls_drop( _this );
188 this.el.add_controller( _this.drop.el );
189 new Xcls_maincol( _this );
190 this.el.append_column ( _this.maincol.el );
191 var child_8 = new Xcls_ColumnViewColumn15( _this );
193 this.el.append_column ( child_8.el );
194 new Xcls_keystate( _this );
195 this.el.add_controller( _this.keystate.el );
201 this.css = new Gtk.CssProvider();
203 this.css.load_from_string("
204 #left-tree-view { font-size: 12px;}
205 .drag-over { background-color:#88a3bc; }
207 border-bottom-width: 5px;
208 border-bottom-style: solid;
209 border-bottom-color: #88a3bc;
212 border-top-width: 5px;
213 border-top-style: solid;
214 border-top-color: #88a3bc;
216 #left-tree-view indent {
217 -gtk-icon-size : 2px;
219 #left-tree-view indent:nth-last-child(2) {
224 Gtk.StyleContext.add_provider_for_display(
225 this.el.get_display(),
227 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
234 // user defined functions
235 public Gtk.Widget? getWidgetAtRow (uint row) {
238 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
239 var colview = gesture.widget;
240 var line_no = check_list_widget(colview, x,y);
242 var item = colview.model.get_item(line_no);
246 //GLib.debug("Get Widget At Row %d", (int)row);
247 var child = this.el.get_first_child();
249 var reading_header = true;
251 while (child != null) {
252 GLib.debug("Got %s", child.get_type().name());
254 if (reading_header) {
257 if (child.get_type().name() != "GtkColumnListView") {
259 child = child.get_next_sibling();
262 // should be columnlistview
263 child = child.get_first_child();
267 reading_header = false;
274 if (line_no == row) {
275 //GLib.debug("Returning widget %s", child.get_type().name());
276 return (Gtk.Widget)child;
278 child = child.get_next_sibling();
280 //GLib.debug("Rturning null");
284 public int getColAt (double x, double y) {
287 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
290 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
291 //GLib.debug("Cehck %d, %d", x,y);
292 var child = this.el.get_first_child();
296 while (child != null) {
298 if (child.get_type().name() == "GtkColumnViewRowWidget") {
299 child = child.get_first_child();
303 //child.get_allocation(out alloc);
304 if (x < (child.get_width() + offx)) {
308 //offx += child.get_width();
310 //child = child.get_next_sibling();
317 public int getRowAt (double x, double in_y, out string pos) {
324 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
325 var colview = gesture.widget;
326 var line_no = check_list_widget(colview, x,y);
328 var item = colview.model.get_item(line_no);
334 //GLib.debug("offset = %d y = %d", (int) voff, (int) in_y);
335 var y = in_y + _this.viewwin.el.vadjustment.value;
336 var child = this.el.get_first_child();
337 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
339 var reading_header = true;
341 var header_height = 0;
344 while (child != null) {
345 //GLib.debug("Got %s", child.get_type().name());
346 if (reading_header) {
349 if (child.get_type().name() != "GtkColumnListView") {
350 h += child.get_height();
351 child = child.get_next_sibling();
354 // should be columnlistview
355 child = child.get_first_child();
356 GLib.debug("header height=%d", h);
359 reading_header = false;
363 if (child.get_type().name() != "GtkColumnViewRowWidget") {
364 child = child.get_next_sibling();
368 if (y < header_height) {
373 var hh = child.get_height();
374 //child.get_allocation(out alloc);
375 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
376 //GLib.debug("row %d y= %d %s", line_no, (int) (header_height + alloc.y),
378 // child.visible ? "VIS" : "hidden");
380 if (y > (header_height + real_y) && y <= (header_height + real_y + hh) ) {
381 if (y > ( header_height + real_y + (hh * 0.8))) {
383 } else if (y > ( header_height + real_y + (hh * 0.2))) {
388 GLib.debug("getRowAt return : %d, %s", line_no, pos);
393 if (real_y + hh > y) {
397 child = child.get_next_sibling();
402 public Gtk.Widget? getWidgetAt (double x, double in_y) {
405 from https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
406 var colview = gesture.widget;
407 var line_no = check_list_widget(colview, x,y);
409 var item = colview.model.get_item(line_no);
413 var y = in_y + _this.viewwin.el.vadjustment.value;
414 var child = this.el.get_first_child();
415 //Gtk.Allocation alloc = { 0, 0, 0, 0 };
417 var reading_header = true;
419 var header_height = 0;
421 while (child != null) {
422 //GLib.debug("Got %s", child.get_type().name());
423 if (reading_header) {
426 if (child.get_type().name() != "GtkColumnListView") {
427 h += child.get_height();
428 child = child.get_next_sibling();
431 // should be columnlistview
432 child = child.get_first_child();
433 GLib.debug("header height=%d", h);
436 reading_header = false;
441 if (y < header_height) {
445 var hh = child.get_height();
446 //GLib.debug("got cell xy = %d,%d w,h= %d,%d", alloc.x, alloc.y, alloc.width, alloc.height);
448 if (y > curr_y && y <= header_height + hh + curr_y ) {
449 return (Gtk.Widget)child;
456 child = child.get_next_sibling();
462 public class Xcls_GestureClick6 : Object
464 public Gtk.GestureClick el;
465 private Xcls_WindowLeftTree _this;
471 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
474 this.el = new Gtk.GestureClick();
478 // set gobject values
481 this.el.released.connect( (n_press, x, y) => {
483 _this.view.button_is_pressed = false;
487 this.el.pressed.connect( (n_press, x, y) => {
489 //console.log("button press?");
491 //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
495 _this.view.button_is_pressed = true;
497 _this.view.lastEventSource = "tree";
498 if (! _this.before_node_change() ) {
499 GLib.debug("before_node_change return false");
503 // nothing there -show dialog
504 if (_this.model.el.get_n_items() < 1) {
505 _this.main_window.windowstate.showAddObject(_this.view.el, null);
506 GLib.debug("no items");
510 var row = _this.view.getRowAt(x,y, out pos );
512 GLib.debug("no row selected items");
516 var node = _this.selmodel.getNodeAt(row);
518 GLib.warning("No node found at row %d", row);
524 if (_this.view.getColAt(x,y) > 0 ) {
525 GLib.debug("add colum clicked.");
526 var fqn = node.fqn();
527 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
532 _this.main_window.windowstate.leftTreeBeforeChange();
533 //_this.view.el.get_selection().select_path(res);
534 GLib.debug("Button Pressed - start show window");
535 _this.main_window.windowstate.showAddObject(_this.view.el, node);
536 GLib.debug("Button Pressed - finsihed show window");
545 // user defined functions
548 public class Xcls_GestureClick7 : Object
550 public Gtk.GestureClick el;
551 private Xcls_WindowLeftTree _this;
557 public Xcls_GestureClick7(Xcls_WindowLeftTree _owner )
560 this.el = new Gtk.GestureClick();
564 // set gobject values
568 this.el.pressed.connect( (n_press, x, y) => {
573 if (_this.model.el.get_n_items() < 1) {
575 GLib.debug("no items");
579 var row = _this.view.getRowAt(x,y, out pos );
581 GLib.debug("no row selected items");
585 var node = _this.selmodel.getNodeAt(row);
587 GLib.warning("No node found at row %d", row);
590 _this.model.selectNode(node);
594 GLib.debug("Prssed %d", (int) this.el.get_current_button());
595 //_this.deletemenu.el.set_parent(_this.view.el);
596 _this.LeftTreeMenu.el.set_parent(_this.view.el);
599 //Gtk.Allocation rect;
600 //_this.view.el.get_allocation(out rect);
601 //_this.deletemenu.el.set_has_arrow(false);
602 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM);
605 _this.LeftTreeMenu.el.set_offset(
607 (int)y - (int)_this.view.el.get_height());
609 _this.LeftTreeMenu.el.popup();
614 // user defined functions
617 public class Xcls_DragSource8 : Object
619 public Gtk.DragSource el;
620 private Xcls_WindowLeftTree _this;
626 public Xcls_DragSource8(Xcls_WindowLeftTree _owner )
629 this.el = new Gtk.DragSource();
633 // set gobject values
634 this.el.actions = Gdk.DragAction.COPY | Gdk.DragAction.MOVE ;
637 this.el.drag_cancel.connect( (drag, reason) => {
639 _this.view.dragNode = null;
642 this.el.prepare.connect( (x, y) => {
646 /// ( drag_context, data, info, time) => {
649 //print("drag-data-get");
650 var ndata = _this.selmodel.getSelectedNode();
652 GLib.debug("return empty string - no selection..");
658 //data.set_text(tp,tp.length);
660 var str = ndata.toJsonString();
661 GLib.debug("prepare store: %s", str);
662 GLib.Value ov = GLib.Value(typeof(string));
664 var cont = new Gdk.ContentProvider.for_value(ov);
666 GLib.Value v = GLib.Value(typeof(string));
667 //var str = drop.read_text( [ "text/plain" ] 0);
669 cont.get_value(ref v);
672 GLib.debug("set %s", v.get_string());
678 this.el.drag_begin.connect( ( drag ) => {
679 GLib.debug("SOURCE: drag-begin");
681 // find what is selected in our tree...
682 var data = _this.selmodel.getSelectedNode();
686 _this.view.dragNode = data;
687 var xname = data.fqn();
688 GLib.debug ("XNAME IS %s", xname);
690 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
693 var paintable = new Gtk.WidgetPaintable(widget);
694 this.el.set_icon(paintable, 0,0);
698 this.el.drag_end.connect( (drag, delete_data) => {
700 _this.view.dragNode = null;
704 // user defined functions
707 public class Xcls_EventControllerKey9 : Object
709 public Gtk.EventControllerKey el;
710 private Xcls_WindowLeftTree _this;
716 public Xcls_EventControllerKey9(Xcls_WindowLeftTree _owner )
719 this.el = new Gtk.EventControllerKey();
723 // set gobject values
726 this.el.key_pressed.connect( (keyval, keycode, state) => {
730 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace) {
734 _this.model.deleteSelected();
740 // user defined functions
743 public class Xcls_drop : Object
745 public Gtk.DropTarget el;
746 private Xcls_WindowLeftTree _this;
750 public Gtk.Widget? highlightWidget;
751 public JsRender.Node? lastDragNode;
752 public string lastDragString;
755 public Xcls_drop(Xcls_WindowLeftTree _owner )
759 this.el = new Gtk.DropTarget ( typeof(string) ,
760 Gdk.DragAction.COPY | Gdk.DragAction.MOVE );
763 this.highlightWidget = null;
764 this.lastDragNode = null;
765 this.lastDragString = "";
767 // set gobject values
770 this.el.accept.connect( (drop) => {
772 GLib.debug("got DropTarget:accept");
774 // NOT REALLY NEEDED? = put stuff in drop?
777 /* ( ctx, x, y, time) => {
778 //Seed.print("TARGET: drag-drop");
781 var src = Gtk.drag_get_source_widget(ctx);
783 if (src != this.el) {
787 this.drag_in_motion = false;
788 // request data that will be recieved by the recieve...
791 this.el, // will receive 'drag-data-received' signal
792 ctx, // represents the current state of the DnD
793 Gdk.Atom.intern("application/json",true), // the target type we want
798 // No target offered by source => error
804 // handle drop around self..
808 //print("GETTING POS");
812 Gtk.TreeViewDropPosition pos;
813 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
815 // if there are not items in the tree.. the we have to set isOver to true for anything..
817 if (_this.model.el.iter_n_children(null) < 1) {
818 print("got NO children?\n");
821 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
826 //var action = Gdk.DragAction.COPY;
827 // unless we are copying!!! ctl button..
829 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
830 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
831 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
834 if (_this.model.el.iter_n_children(null) < 1) {
835 // no children.. -- asume it's ok..
837 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
839 // continue through to allow drop...
847 //print("ISOVER? " + isOver);
850 Gtk.drag_finish (ctx, false, false, time); // drop failed..
851 return true; // not over apoint!?! - no action on drop or motion..
854 // drag node is parent of child..
855 //console.log("SRC TREEPATH: " + src.treepath);
856 //console.log("TARGET TREEPATH: " + data.path.to_string());
858 // nned to check a few here..
859 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
860 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
861 //Gtk.TreeViewDropPosition.AFTER
862 //Gtk.TreeViewDropPosition.BEFORE
864 // locally dragged items to not really use the
865 var selection_text = this.dragData;
869 if (selection_text == null || selection_text.length < 1) {
870 //print("Error - drag selection text returned NULL");
872 Gtk.drag_finish (ctx, false, false, time); // drop failed..
873 return true; /// -- fixme -- this is not really correct..
876 // see if we are dragging into ourself?
877 print ("got selection text of " + selection_text);
879 var target_path = path.to_string();
880 //print("target_path="+target_path);
883 if (selection_text == target_path) {
884 print("self drag ?? == we should perhaps allow copy onto self..\n");
886 Gtk.drag_finish (ctx, false, false, time); // drop failed..
888 return true; /// -- fixme -- this is not really correct..
893 //print("DUMPING DATA");
894 //console.dump(data);
897 //print(data.path.to_string() +' => '+ data.pos);
899 // dropList is a list of xtypes that this node could be dropped on.
900 // it is set up when we start to drag..
903 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
905 print("targetDAta: " + targetData +"\n");
907 if (targetData.length < 1) {
908 //print("Can not find drop node path");
910 Gtk.drag_finish (ctx, false, false, time); // drop failed..
916 // continue on to allow drop..
918 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
921 var delete_selection_data = false;
923 if (action == Gdk.DragAction.ASK) {
924 // Ask the user to move or copy, then set the ctx action.
927 if (action == Gdk.DragAction.MOVE) {
928 delete_selection_data = true;
931 // drag around.. - reorder..
932 _this.model.moveNode(targetData, action);
938 // we can send stuff to souce here...
941 // do we always say failure, so we handle the reall drop?
942 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
955 this.el.motion.connect( ( x, y) => {
957 var is_shift = _this.keystate.is_shift > 0;
959 GLib.debug("shift is %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
960 string pos; // over / before / after..
962 //GLib.debug("got drag motion");
964 GLib.Value v = GLib.Value(typeof(string));
965 //var str = drop.read_text( [ "text/plain" ] 0);
966 var cont = this.el.current_drop.get_drag().content ;
968 cont.get_value(ref v);
969 } catch (GLib.Error e) {
970 GLib.debug("failed to get drag value");
971 return Gdk.DragAction.COPY;
975 //GLib.debug("got %s", v.get_string());
977 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
978 // still dragging same node
980 this.lastDragNode = new JsRender.Node();
981 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
985 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
986 this.lastDragNode.fqn());
989 foreach(var dp in drop_on_to) {
992 GLib.debug("droplist: %s", string.joinv(", ", str));
995 // if there are not items in the tree.. the we have to set isOver to true for anything..
997 if (_this.model.el.n_items < 1) {
998 // FIXME check valid drop types?
999 if (drop_on_to.contains("*top")) {
1000 this.addHighlight(_this.view.el, "over");
1002 this.addHighlight(null, "");
1005 return Gdk.DragAction.COPY; // no need to highlight?
1010 GLib.debug("check is over");
1012 // if path of source and dest are inside each other..
1013 // need to add source info to drag?
1015 var row = _this.view.getRowAt(x,y, out pos);
1018 this.addHighlight(null, "");
1019 return Gdk.DragAction.COPY;
1021 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1023 var node = (JsRender.Node)tr.get_item();
1025 GLib.debug("Drop over node: %s", node.fqn());
1028 if (pos == "above" || pos == "below") {
1029 if (node.parent == null) {
1030 GLib.debug("no parent try center");
1034 if (!drop_on_to.contains(node.parent.fqn())) {
1035 GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1038 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1039 if (_this.view.dragNode != null && is_shift) {
1040 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1041 GLib.debug("shift drop not self not allowed");
1042 this.addHighlight(null, "");
1043 return Gdk.DragAction.COPY;
1056 if (pos == "over") {
1057 if (!drop_on_to.contains(node.fqn())) {
1058 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1059 this.addHighlight(null, "");
1060 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1062 if (_this.view.dragNode != null && is_shift) {
1063 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1064 GLib.debug("shift drop not self not allowed");
1065 this.addHighlight(null, "");
1066 return Gdk.DragAction.COPY;
1073 // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1074 var w = _this.view.getWidgetAt(x,y);
1075 this.addHighlight(w, pos);
1076 return is_shift ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY;
1078 this.el.leave.connect( ( ) => {
1079 this.addHighlight(null,"");
1082 this.el.drop.connect( (v, x, y) => {
1084 this.addHighlight(null,"");
1086 var is_shift = _this.keystate.is_shift > 0;
1089 // -- get position..
1090 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1091 // still dragging same node
1093 this.lastDragNode = new JsRender.Node();
1094 this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1099 var dropNode = new JsRender.Node();
1100 dropNode.loadFromJsonString(v.get_string(), 1);
1101 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1103 // if there are not items in the tree.. the we have to set isOver to true for anything..
1105 if (_this.model.el.n_items < 1) {
1106 // FIXME check valid drop types?
1107 if (!drop_on_to.contains("*top")) {
1108 GLib.debug("drop on to list does not contain top?");
1111 // add new node to top..
1114 var m = (GLib.ListStore) _this.model.el.model;
1115 _this.main_window.windowstate.file.tree = dropNode;
1119 _this.model.selectNode(dropNode);
1121 return true; // no need to highlight?
1127 var row = _this.view.getRowAt(x,y, out pos);
1129 return false; //Gdk.DragAction.COPY;
1131 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1133 var node = (JsRender.Node)tr.get_item();
1135 if (pos == "above" || pos == "below") {
1136 if (node.parent == null) {
1139 if (!drop_on_to.contains(node.parent.fqn())) {
1142 GLib.debug("drop contains %s - using %s" , node.parent.fqn(), pos);
1143 if (_this.view.dragNode != null && is_shift) {
1144 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1145 GLib.debug("shift drop not self not allowed");
1156 if (pos == "over") {
1157 if (!drop_on_to.contains(node.fqn())) {
1158 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1162 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1163 GLib.debug("shift drop not self not allowed");
1170 node.appendChild(dropNode);
1171 if (is_shift && _this.view.dragNode != null) {
1172 _this.model.selectNode(null);
1173 _this.view.dragNode.remove();
1177 _this.model.selectNode(dropNode);
1183 GLib.debug("Above - insertBefore");
1185 node.parent.insertBefore(dropNode, node);
1186 if (is_shift && _this.view.dragNode != null) {
1187 _this.model.selectNode(null);
1188 _this.view.dragNode.remove();
1191 _this.model.selectNode(dropNode);
1196 GLib.debug("Below - insertAfter");
1197 if (is_shift && _this.view.dragNode != null) {
1198 _this.model.selectNode(null);
1199 _this.view.dragNode.remove();
1203 node.parent.insertAfter(dropNode, node);
1204 _this.model.selectNode(dropNode);
1210 // should not happen
1222 // user defined functions
1223 public void addHighlight (Gtk.Widget? w, string hl) {
1224 if (this.highlightWidget != null) {
1225 var ww = this.highlightWidget;
1226 GLib.debug("clear drag from previous highlight");
1227 if (ww.has_css_class("drag-below")) {
1228 ww.remove_css_class("drag-below");
1230 if (ww.has_css_class("drag-above")) {
1231 ww.remove_css_class("drag-above");
1233 if (ww.has_css_class("drag-over")) {
1234 ww.remove_css_class("drag-over");
1238 GLib.debug("add drag=%s to widget", hl);
1239 if (!w.has_css_class("drag-" + hl)) {
1240 w.add_css_class("drag-" + hl);
1243 this.highlightWidget = w;
1247 public class Xcls_selmodel : Object
1249 public Gtk.SingleSelection el;
1250 private Xcls_WindowLeftTree _this;
1256 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1259 _this.selmodel = this;
1260 new Xcls_model( _this );
1261 this.el = new Gtk.SingleSelection( _this.model.el );
1265 // set gobject values
1268 this.el.selection_changed.connect( (position, n_items) => {
1272 //if (!this.button_is_pressed && !this.key_is_pressed) {
1273 // then event was started by some other action
1274 // which should manually trigger all the events..
1275 // print("SKIPPING select - no button or key pressed\n");
1280 if (_this.view.blockChanges) { // probably not needed..
1281 GLib.debug("SKIPPING select - blockchanges set..");
1285 if (!_this.before_node_change( ) ) {
1286 _this.view.blockChanges = true;
1287 _this.selmodel.el.unselect_all();
1288 _this.view.blockChanges = false;
1292 if (_this.main_window.windowstate.file == null) {
1293 GLib.debug("SKIPPING select windowstate file is not set...");
1297 //var render = this.get('/LeftTree').getRenderer();
1298 GLib.debug("LEFT TREE -> view -> selection changed called");
1301 // -- it appears that the selection is not updated.
1302 // select the node...
1303 //_this.selmodel.el.set_selected(row);
1305 GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1307 var snode = _this.selmodel.getSelectedNode();
1308 if (snode == null) {
1310 GLib.debug("selected rows < 1");
1311 //??this.model.load( false);
1312 _this.node_selected(null);
1320 GLib.debug ("calling left_tree.node_selected");
1321 _this.node_selected(snode);
1326 // no need to scroll. it's in the view as we clicked on it.
1327 // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1333 // user defined functions
1334 public JsRender.Node? getSelectedNode () {
1335 if (this.el.selected_item == null) {
1338 var tr = (Gtk.TreeListRow)this.el.selected_item;
1339 return (JsRender.Node)tr.get_item();
1342 public JsRender.Node getNodeAt (uint row) {
1344 var tr = (Gtk.TreeListRow)this.el.get_item(row);
1346 var a = tr.get_item();;
1347 GLib.debug("get_item (2) = %s", a.get_type().name());
1350 return (JsRender.Node)tr.get_item();
1354 public class Xcls_model : Object
1356 public Gtk.TreeListModel el;
1357 private Xcls_WindowLeftTree _this;
1363 public Xcls_model(Xcls_WindowLeftTree _owner )
1367 this.el = this.updateModel(null);
1371 // set gobject values
1374 // user defined functions
1375 public void loadFile (JsRender.JsRender f) {
1378 _this.drop.highlightWidget = null;
1380 var m = (GLib.ListStore) this.el.model;
1382 _this.main_window.windowstate.leftTreeNodeSelected(null);
1384 _this.main_window.windowstate.file = f;
1387 if (f.tree == null) {
1394 // if it's still null?
1395 if (f.tree == null) {
1396 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1404 if (f.tree.readItems().size < 1) {
1407 //this.get('/Window.leftvpaned').el.set_position(80);
1409 _this.view.el.set_cursor(
1410 new Gtk.TreePath.from_string("0"), null, false);
1414 //this.get('/Window.leftvpaned').el.set_position(200);
1420 //_this.maincol.el.set_max_width(_this.viewwin.el.get_allocated_width() - 32);
1422 _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1428 public void deleteSelected () {
1432 var node = _this.selmodel.getSelectedNode();
1436 GLib.debug("delete Selected - no node slected?");
1439 _this.selmodel.el.unselect_all();
1442 GLib.debug("delete Selected - done");
1445 print("DELETE SELECTED?");
1446 //_this.view.blockChanges = true;
1447 print("GET SELECTION?");
1449 var s = _this.view.el.get_selection();
1451 print("GET SELECTED?");
1456 if (!s.get_selected(out mod, out iter)) {
1457 return; // nothing seleted..
1462 this.activePath= "";
1463 print("GET vnode value?");
1466 this.el.get_value(iter, 2, out value);
1467 var data = (JsRender.Node)(value.get_object());
1468 print("removing node from Render\n");
1469 if (data.parent == null) {
1470 _this.main_window.windowstate.file.tree = null;
1474 print("removing node from Tree\n");
1476 this.el.remove(ref iter);
1486 this.activePath= ""; // again!?!?
1487 //this.changed(null,true);
1491 _this.view.blockChanges = false;
1494 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1495 this.el = new Gtk.TreeListModel(
1496 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1500 return ((JsRender.Node)item).childstore;
1504 if (_this.selmodel.el == null) {
1507 _this.selmodel.el.set_model(this.el);
1510 public void selectNode (JsRender.Node node)
1513 var s = (Gtk.SingleSelection)_this.view.el.model;
1514 for (var i = 0; i < s.n_items; i++) {
1515 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1516 var lr = (Gtk.TreeListRow)s.get_item(i);
1517 GLib.debug("check node %s", lr.get_item().get_type().name());
1518 if (((JsRender.Node)lr.get_item()).oid == node.oid) {
1525 GLib.debug("Could not find node");
1528 GLib.debug("Select %d", row);
1529 s.set_selected(row);
1530 _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1531 //_this.node_selected(node);
1538 public class Xcls_maincol : Object
1540 public Gtk.ColumnViewColumn el;
1541 private Xcls_WindowLeftTree _this;
1547 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1550 _this.maincol = this;
1551 var child_1 = new Xcls_SignalListItemFactory14( _this );
1553 this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1557 // set gobject values
1558 this.el.id = "maincol";
1559 this.el.expand = true;
1560 this.el.resizable = true;
1563 // user defined functions
1565 public class Xcls_SignalListItemFactory14 : Object
1567 public Gtk.SignalListItemFactory el;
1568 private Xcls_WindowLeftTree _this;
1574 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1577 this.el = new Gtk.SignalListItemFactory();
1581 // set gobject values
1584 this.el.setup.connect( (listitem) => {
1586 var expand = new Gtk.TreeExpander();
1588 expand.set_indent_for_depth(true);
1589 expand.set_indent_for_icon(true);
1590 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1591 var icon = new Gtk.Image();
1592 var lbl = new Gtk.Label("");
1593 lbl.use_markup = true;
1594 lbl.ellipsize = Pango.EllipsizeMode.END;
1596 icon.margin_end = 4;
1597 lbl.justify = Gtk.Justification.LEFT;
1600 // listitem.activatable = true; ??
1604 expand.set_child(hbox);
1605 ((Gtk.ListItem)listitem).set_child(expand);
1608 this.el.bind.connect( (listitem) => {
1609 GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1611 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1612 var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1615 var hbox = (Gtk.Box) expand.child;
1618 var img = (Gtk.Image) hbox.get_first_child();
1619 var lbl = (Gtk.Label) img.get_next_sibling();
1621 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1622 var node = (JsRender.Node) lr.get_item();
1624 GLib.debug("node is %s", node.get_type().name());
1625 // was item (1) in old layout
1630 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1631 var clsname = node.fqn();
1633 var clsb = clsname.split(".");
1634 var sub = clsb.length > 1 ? clsb[1].down() : "";
1636 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1640 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1641 img.set_from_file(fn);
1644 img.set_from_paintable(
1646 "media-playback-stop", null, 16,1,
1647 Gtk.TextDirection.NONE, 0
1651 } catch (GLib.Error e) {}
1653 expand.set_hide_expander( !node.hasChildren() );
1654 expand.set_list_row(lr);
1656 node.bind_property("iconFilename",
1658 GLib.BindingFlags.SYNC_CREATE);
1660 node.bind_property("nodeTitleProp",
1662 GLib.BindingFlags.SYNC_CREATE);
1663 node.bind_property("nodeTipProp",
1664 lbl, "tooltip_markup",
1665 GLib.BindingFlags.SYNC_CREATE);
1671 // user defined functions
1675 public class Xcls_ColumnViewColumn15 : Object
1677 public Gtk.ColumnViewColumn el;
1678 private Xcls_WindowLeftTree _this;
1684 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1687 var child_1 = new Xcls_SignalListItemFactory16( _this );
1689 this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1693 // set gobject values
1694 this.el.fixed_width = 25;
1697 // user defined functions
1699 public class Xcls_SignalListItemFactory16 : Object
1701 public Gtk.SignalListItemFactory el;
1702 private Xcls_WindowLeftTree _this;
1708 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1711 this.el = new Gtk.SignalListItemFactory();
1715 // set gobject values
1718 this.el.setup.connect( (listitem) => {
1721 var icon = new Gtk.Image();
1723 ((Gtk.ListItem)listitem).set_child(icon);
1725 this.el.bind.connect( (listitem) => {
1727 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child();
1728 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1729 var node = (JsRender.Node) lr.get_item();
1732 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1733 img.set_from_paintable(
1735 "list-add", null, 16,1,
1736 Gtk.TextDirection.NONE, 0
1740 var fqn = node.fqn();
1741 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1743 img.set_visible(cn.size > 0 ? true : false);
1748 // user defined functions
1752 public class Xcls_keystate : Object
1754 public Gtk.EventControllerKey el;
1755 private Xcls_WindowLeftTree _this;
1759 public int is_shift;
1762 public Xcls_keystate(Xcls_WindowLeftTree _owner )
1765 _this.keystate = this;
1766 this.el = new Gtk.EventControllerKey();
1771 // set gobject values
1774 this.el.key_released.connect( (keyval, keycode, state) => {
1775 GLib.debug("key release %d, %d, %d" , (int) keyval, (int) keycode, state);
1776 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
1779 //GLib.debug("set state %d , shift = %d", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);
1784 this.el.key_pressed.connect( (keyval, keycode, state) => {
1786 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
1793 // user defined functions
1797 public class Xcls_LeftTreeMenu : Object
1799 public Gtk.Popover el;
1800 private Xcls_WindowLeftTree _this;
1806 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1809 _this.LeftTreeMenu = this;
1810 this.el = new Gtk.Popover();
1814 // set gobject values
1815 var child_1 = new Xcls_Box19( _this );
1816 this.el.child = child_1.el;
1819 // user defined functions
1821 public class Xcls_Box19 : Object
1824 private Xcls_WindowLeftTree _this;
1830 public Xcls_Box19(Xcls_WindowLeftTree _owner )
1833 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1837 // set gobject values
1838 var child_1 = new Xcls_Button20( _this );
1840 this.el.append( child_1.el );
1841 var child_2 = new Xcls_Button21( _this );
1843 this.el.append( child_2.el );
1844 var child_3 = new Xcls_Button22( _this );
1846 this.el.append( child_3.el );
1849 // user defined functions
1851 public class Xcls_Button20 : Object
1853 public Gtk.Button el;
1854 private Xcls_WindowLeftTree _this;
1860 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1863 this.el = new Gtk.Button();
1867 // set gobject values
1868 this.el.label = "Delete Element";
1871 this.el.clicked.connect( ( ) => {
1872 _this.LeftTreeMenu.el.hide();
1873 _this.model.deleteSelected();
1878 // user defined functions
1881 public class Xcls_Button21 : Object
1883 public Gtk.Button el;
1884 private Xcls_WindowLeftTree _this;
1890 public Xcls_Button21(Xcls_WindowLeftTree _owner )
1893 this.el = new Gtk.Button();
1897 // set gobject values
1898 this.el.label = "Save as Template";
1901 this.el.clicked.connect( () => {
1902 _this.LeftTreeMenu.el.hide();
1903 DialogSaveTemplate.singleton().showIt(
1904 (Gtk.Window) _this.el.get_root (),
1905 _this.main_window.windowstate.file.palete(),
1906 _this.getActiveElement()
1913 // user defined functions
1916 public class Xcls_Button22 : Object
1918 public Gtk.Button el;
1919 private Xcls_WindowLeftTree _this;
1925 public Xcls_Button22(Xcls_WindowLeftTree _owner )
1928 this.el = new Gtk.Button();
1932 // set gobject values
1933 this.el.label = "Save as Module";
1936 this.el.clicked.connect( () => {
1938 _this.LeftTreeMenu.el.hide();
1939 var node = _this.getActiveElement();
1942 var sm = DialogSaveModule.singleton();
1946 (Gtk.Window) _this.el.get_root (),
1947 _this.main_window.windowstate.project,
1951 gtk4 migration - disabled this part.. probably not used muchanyway
1954 if (name.length < 1) {
1958 node.set_prop( new JsRender.NodeProp.special("xinclude", name));
1962 var s = _this.view.el.get_selection();
1964 print("GET SELECTED?");
1969 if (!s.get_selected(out mod, out iter)) {
1970 return; // nothing seleted..
1973 var n_cn = mod.iter_n_children(iter) -1;
1974 for (var i = n_cn; i > -1; i--) {
1975 mod.iter_nth_child(out citer, iter, i);
1978 print("removing node from Tree\n");
1980 _this.model.el.remove(ref citer);
1983 _this.node_selected(node, "tree");
1989 // user defined functions