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_view view;
16 public Xcls_model model;
17 public Xcls_iconrender iconrender;
18 public Xcls_renderer renderer;
19 public Xcls_LeftTreeMenu LeftTreeMenu;
22 public signal bool before_node_change ();
23 public signal void changed ();
24 public signal void node_selected (JsRender.Node? node, string source);
25 public Xcls_MainWindow main_window;
28 public Xcls_WindowLeftTree()
31 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
34 this.main_window = null;
37 var child_0 = new Xcls_Button2( _this );
39 this.el.add ( child_0.el );
40 var child_1 = new Xcls_ScrolledWindow4( _this );
42 this.el.add ( child_1.el );
45 // user defined functions
46 public JsRender.Node? getActiveElement () { // return path to actie node.
48 var path = this.getActivePath();
49 if (path.length < 1) {
52 return _this.model.pathToNode(path);
55 public JsRender.JsRender getActiveFile () {
56 return this.main_window.windowstate.file;
58 public string getActivePath () {
60 var view = this.view.el;
61 if (view.get_selection().count_selected_rows() < 1) {
66 view.get_selection().get_selected(out mod, out iter);
67 return mod.get_path(iter).to_string();
69 public class Xcls_Button2 : Object
72 private Xcls_WindowLeftTree _this;
78 public Xcls_Button2(Xcls_WindowLeftTree _owner )
81 this.el = new Gtk.Button();
86 this.el.hexpand = true;
87 this.el.always_show_image = true;
88 this.el.label = "Add Child Element";
89 var child_0 = new Xcls_Image3( _this );
91 this.el.set_image ( child_0.el );
94 this.el.clicked.connect( ( ) => {
97 _this.main_window.windowstate.showAddObject(this.el);
102 // user defined functions
104 public class Xcls_Image3 : Object
107 private Xcls_WindowLeftTree _this;
113 public Xcls_Image3(Xcls_WindowLeftTree _owner )
116 this.el = new Gtk.Image();
120 // set gobject values
121 this.el.icon_name = "list-add";
124 // user defined functions
128 public class Xcls_ScrolledWindow4 : Object
130 public Gtk.ScrolledWindow el;
131 private Xcls_WindowLeftTree _this;
137 public Xcls_ScrolledWindow4(Xcls_WindowLeftTree _owner )
140 this.el = new Gtk.ScrolledWindow( null, null );
144 // set gobject values
145 this.el.shadow_type = Gtk.ShadowType.IN;
146 var child_0 = new Xcls_view( _this );
148 this.el.add ( child_0.el );
149 var child_1 = new Xcls_LeftTreeMenu( _this );
154 this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
157 // user defined functions
159 public class Xcls_view : Object
161 public Gtk.TreeView el;
162 private Xcls_WindowLeftTree _this;
166 public string dragData;
168 public string[] dropList;
170 public bool button_is_pressed;
171 public string lastEventSource;
172 public bool key_is_pressed;
173 public bool drag_in_motion;
174 public bool blockChanges;
177 public Xcls_view(Xcls_WindowLeftTree _owner )
181 this.el = new Gtk.TreeView();
184 this.button_is_pressed = false;
185 this.lastEventSource = "";
186 this.key_is_pressed = false;
187 this.blockChanges = false;
189 // set gobject values
190 this.el.expand = true;
191 this.el.tooltip_column = 1;
192 this.el.enable_tree_lines = true;
193 this.el.headers_visible = false;
194 var child_0 = new Xcls_model( _this );
196 this.el.set_model ( child_0.el );
197 var child_1 = new Xcls_TreeViewColumn7( _this );
199 this.el.append_column ( child_1.el );
204 var description = new Pango.FontDescription();
205 description.set_size(8000);
206 this.el.override_font(description);
208 var selection = this.el.get_selection();
209 selection.set_mode( Gtk.SelectionMode.SINGLE);
212 // is this really needed??
214 this.selection.signal['changed'].connect(function() {
215 _this.get('/LeftTree.view').listeners.cursor_changed.apply(
216 _this.get('/LeftTree.view'), [ _this.get('/LeftTree.view'), '']
220 Gtk.drag_source_set (
221 this.el, /* widget will be drag-able */
222 Gdk.ModifierType.BUTTON1_MASK, /* modifier that will start a drag */
223 BuilderApplication.targetList, /* lists of target to support */
224 Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK /* what to do with data after dropped */
228 //Gtk.drag_source_add_text_targets(this.el);
232 this.el, /* widget that will accept a drop */
233 Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT,
234 BuilderApplication.targetList, /* lists of target to support */
235 Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK /* what to do with data after dropped */
238 //Gtk.drag_dest_set_target_list(this.el, Builder.Application.targetList);
239 //Gtk.drag_dest_add_text_targets(this.el);
243 this.el.button_release_event.connect( (ev) => {
244 this.button_is_pressed = false;
247 this.el.button_press_event.connect( ( ev) => {
248 //console.log("button press?");
249 this.button_is_pressed = true;
250 print("BUTTON DOWN\n");
252 this.lastEventSource = "tree";
253 if (! _this.before_node_change() ) {
260 if (ev.type != Gdk.EventType.BUTTON_PRESS || ev.button != 3) {
261 //print("click" + ev.type);
265 if (!_this.view.el.get_path_at_pos((int)ev.x,(int)ev.y, out res, null, null, null) ) {
270 _this.main_window.windowstate.leftTreeBeforeChange();
274 this.el.get_selection().select_path(res);
276 //if (!this.get('/LeftTreeMenu').el) {
277 // this.get('/LeftTreeMenu').init();
280 _this.LeftTreeMenu.el.set_screen(Gdk.Screen.get_default());
281 _this.LeftTreeMenu.el.show_all();
282 _this.LeftTreeMenu.el.popup(null, null, null, 3, ev.time);
283 // print("click:" + res.path.to_string());
286 this.el.cursor_changed.connect( ( ) => {
287 print("LEFT TREE Cursor Changed\n");
288 if (!this.button_is_pressed && !this.key_is_pressed) {
289 // then event was started by some other action
290 // which should manually trigger all the events..
291 print("SKIPPING select - no button or key pressed\n");
296 if (this.blockChanges) { // probably not needed..
297 print("SKIPPING select - blockchanges set..\n");
300 if (!_this.before_node_change( ) ) {
301 this.blockChanges = true;
302 this.el.get_selection().unselect_all();
303 this.blockChanges = false;
307 if (_this.main_window.windowstate.file == null) {
308 print("SKIPPING select windowstate file is not set...\n");
312 //var render = this.get('/LeftTree').getRenderer();
313 print("LEFT TREE -> view -> selection changed called\n");
316 // -- it appears that the selection is not updated.
318 GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {
319 print("LEFT TREE -> view -> selection changed TIMEOUT CALLED\n");
321 if (this.el.get_selection().count_selected_rows() < 1) {
323 print("selected rows < 1\n");
324 //??this.model.load( false);
325 _this.node_selected(null, this.lastEventSource);
330 //console.log('changed');
331 var s = this.el.get_selection();
334 s.get_selected(out mod, out iter);
339 _this.model.el.get_value(iter, 2, out value);
340 _this.model.activePath = mod.get_path(iter).to_string();
342 var node = (JsRender.Node)value.dup_object();
343 print ("calling left_tree.node_selected\n");
344 _this.node_selected(node, this.lastEventSource);
345 while (Gtk.events_pending()) {
346 Gtk.main_iteration();
348 var cp = mod.get_path(iter);
350 this.el.get_visible_range(out sp, out ep);
351 // if sp is before cp then retuns 1.
352 // if cp is before ep then retuns 1.
353 if (cp.compare(sp) >= 0 && ep.compare(cp) >=1) {
359 this.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
363 //_this.after_node_change(node);
365 // _this.model.file.changed(node, "tree");
367 //Seed.print( value.get_string());
371 this.el.drag_begin.connect( ( ctx) => {
372 //print('SOURCE: drag-begin');
375 //this.targetData = "";
377 // find what is selected in our tree...
379 var s = _this.view.el.get_selection();
380 if (s.count_selected_rows() < 1) {
385 s.get_selected(out mod, out iter);
389 // set some properties of the tree for use by the dropped element.
391 _this.model.el.get_value(iter, 2, out value);
392 var tp = mod.get_path(iter).to_string();
393 var data = (JsRender.Node)(value.dup_object());
394 var xname = data.fqn();
395 print ("XNAME IS " + xname+ "\n");
397 this.dropList = _this.main_window.windowstate.file.palete().getDropList(xname);
399 print ("DROP LIST IS " + string.joinv(", ", this.dropList) + "\n");
402 // make the drag icon a picture of the node that was selected
405 // by default returns the path..
406 var path = _this.model.el.get_path(iter);
409 var pix = this.el.create_row_drag_icon ( path);
411 Gtk.drag_set_icon_surface (ctx, pix) ;
415 this.el.drag_data_get.connect( ( drag_context, data, info, time) => {
418 //print("drag-data-get");
419 var s = this.el.get_selection();
420 if (s.count_selected_rows() < 1) {
422 print("return empty string - no selection..");
429 s.get_selected(out mod, out iter);
434 _this.model.el.get_value(iter, 2, out value);
435 var ndata = (JsRender.Node)(value.dup_object());
439 var tp = mod.get_path(iter).to_string();
440 // by default returns the path..
442 if ( info != Gdk.Atom.intern("STRING",true) ) {
443 tp = ndata.toJsonString();
446 //data.set_text(tp,tp.length);
448 data.set (data.get_target (), 8, (uchar[]) tp.to_utf8 ());
451 // print("return " + tp);
453 this.el.drag_end.connect( (drag_context) => {
454 //Seed.print('LEFT-TREE: drag-end');
456 this.dropList = null;
457 // this.targetData = "";
458 this.highlightDropPath("",0);
461 this.el.drag_motion.connect( ( ctx, x, y, time) => {
462 print("got drag motion\n");
463 var src = Gtk.drag_get_source_widget(ctx);
467 if (src != this.el) {
471 // the point of this is to detect where an item could be dropped..
472 print("requesting drag data\n");
473 this.drag_in_motion = true;
475 // request data that will be recieved by the recieve...
478 this.el, // will receive 'drag-data-received' signal
479 ctx, // represents the current state of the DnD
480 Gdk.Atom.intern("STRING",true), // the target type we want
487 print("action: %d\n", ctx.get_actions());
488 //print("GETTING POS");
492 Gtk.TreeViewDropPosition pos;
493 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
495 // if there are not items in the tree.. the we have to set isOver to true for anything..
497 if (_this.model.el.iter_n_children(null) < 1) {
498 print("got NO children?\n");
501 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
505 // ------------- a drag from self..
508 //var action = Gdk.DragAction.COPY;
509 // unless we are copying!!! ctl button..
511 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
512 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
513 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
516 if (_this.model.el.iter_n_children(null) < 1) {
517 // no children.. -- asume it's ok..
519 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
521 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
522 Gdk.drag_status(ctx, action ,time);
525 // continue through to allow drop...
533 //print("ISOVER? " + isOver);
536 Gdk.drag_status(ctx, 0 ,time);
537 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
542 // drag node is parent of child..
543 //console.log("SRC TREEPATH: " + src.treepath);
544 //console.log("TARGET TREEPATH: " + data.path.to_string());
546 // nned to check a few here..
547 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
548 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
549 //Gtk.TreeViewDropPosition.AFTER
550 //Gtk.TreeViewDropPosition.BEFORE
552 // locally dragged items to not really use the
553 var selection_text = this.dragData;
557 if (selection_text == null || selection_text.length < 1) {
558 //print("Error - drag selection text returned NULL");
559 Gdk.drag_status(ctx, 0 ,time);
560 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
565 // see if we are dragging into ourself?
566 var target_path = path.to_string();
567 print ("Drag %s onto %s--%d\n ", selection_text, target_path, pos);
569 // pos : 3 = ontop - 0 = after, 1 = before
570 //print("target_path="+target_path);
573 if (selection_text == target_path) {
574 print("self drag ?? == we should perhaps allow copy onto self..\n");
576 Gdk.drag_status(ctx, 0 ,time);
577 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
579 // -- fixme -- this is not really correct..
584 //print("DUMPING DATA");
585 //console.dump(data);
588 //print(data.path.to_string() +' => '+ data.pos);
590 // dropList is a list of xtypes that this node could be dropped on.
591 // it is set up when we start to drag..
594 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
596 print("targetDAta: " + targetData +"\n");
598 if (targetData.length < 1) {
599 //print("Can not find drop node path");
601 Gdk.drag_status(ctx, 0, time);
602 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
606 var td_ar = targetData.split("|");
610 Gdk.drag_status(ctx, action ,time);
611 this.highlightDropPath(td_ar[0], (Gtk.TreeViewDropPosition)int.parse(td_ar[1]));
616 this.el.key_press_event.connect( (ev) => {
617 this.key_is_pressed = true;
620 this.el.key_release_event.connect( (ev) => {
621 this.key_is_pressed = false;
624 this.el.drag_data_received.connect( (ctx, x, y, sel, info, time) => {
626 // THIS CODE ONLY RELATES TO drag or drop of "NEW" elements or "FROM another tree.."
629 // print("Tree: drag-data-received\n");
630 var selection_text = (string)sel.get_data();
631 //print("selection_text= %s\n",selection_text);
633 var is_drag = this.drag_in_motion;
637 GLib.debug("Is Drag %s\n", is_drag ? "Y": "N");
641 Gtk.TreeViewDropPosition pos;
642 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
644 // if there are not items in the tree.. the we have to set isOver to true for anything..
646 if (_this.model.el.iter_n_children(null) < 1) {
647 GLib.debug("got NO children?\n");
650 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
654 //console.log("LEFT-TREE: drag-motion");
655 var src = Gtk.drag_get_source_widget(ctx);
657 // a drag from self - this should be handled by drop and motion.
658 if (src == this.el) {
659 GLib.debug("Source == this element should not happen.. ? \n");
662 //print("drag_data_recieved from another element");
667 if (selection_text == null || selection_text.length < 1 || !isOver) {
668 // nothing valid foudn to drop...
669 GLib.debug("empty sel text or not over");
671 Gdk.drag_status(ctx, 0, time);
672 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
675 Gtk.drag_finish (ctx, false, false, time); // drop failed..
680 var dropNode = new JsRender.Node();
682 var dropNodeType = selection_text;
683 var show_templates = true;
685 if (dropNodeType[0] == '{') {
686 var pa = new Json.Parser();
688 pa.load_from_data(dropNodeType);
690 Gtk.drag_finish (ctx, false, false, time); // drop failed..
695 dropNode.loadFromJson( pa.get_root().get_object(), 2);
696 dropNodeType = dropNode.fqn();
697 show_templates = false;
701 if (selection_text.contains(":")) {
702 var bits = selection_text.split(":");
703 dropNode.setFqn(bits[0]);
704 dropNode.props.set("* prop", bits[1]);
707 dropNode.setFqn(selection_text);
712 // dropList --- need to gather this ...
713 GLib.debug("get dropList for : %s\n",dropNodeType);
714 var dropList = _this.main_window.windowstate.file.palete().getDropList(dropNodeType);
716 GLib.debug("dropList: %s\n", string.joinv(" , ", dropList));
718 // if drag action is link ... then we can drop it anywahere...
719 if ((ctx.get_actions() & Gdk.DragAction.LINK) > 0) {
720 // if path is null?? dragging into an empty tree?
721 targetData = (path == null ? "" : path.to_string()) + "|%d".printf((int)pos);
725 targetData = _this.model.findDropNodeByPath( isEmpty ? "" : path.to_string(), dropList, pos);
730 GLib.debug("targetDAta: %s", targetData );
732 if (targetData.length < 1) {
734 // invalid drop path..
735 if (this.drag_in_motion) {
736 Gdk.drag_status(ctx, 0, time);
737 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
740 Gtk.drag_finish (ctx, false, false, time); // drop failed..
747 var td_ar = targetData.split("|");
750 if (this.drag_in_motion) {
751 Gdk.drag_status(ctx, Gdk.DragAction.COPY ,time);
753 this.highlightDropPath( td_ar[0] , (Gtk.TreeViewDropPosition)int.parse(td_ar[1]));
756 // continue on to allow drop..
759 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
761 // {parent}|{pos}|{prop}
764 _this.model.dropNode(targetData, dropNode, show_templates);
765 GLib.debug("ADD new node!!!\n");
767 ///Xcls_DialogTemplateSelect.singleton().show( _this.model.file.palete(), node);
769 Gtk.drag_finish (ctx, false, false,time);
776 this.el.drag_drop.connect( ( ctx, x, y, time) => {
777 //Seed.print("TARGET: drag-drop");
780 var src = Gtk.drag_get_source_widget(ctx);
782 if (src != this.el) {
786 this.drag_in_motion = false;
787 // request data that will be recieved by the recieve...
790 this.el, // will receive 'drag-data-received' signal
791 ctx, // represents the current state of the DnD
792 Gdk.Atom.intern("application/json",true), // the target type we want
797 // No target offered by source => error
803 // handle drop around self..
807 //print("GETTING POS");
811 Gtk.TreeViewDropPosition pos;
812 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
814 // if there are not items in the tree.. the we have to set isOver to true for anything..
816 if (_this.model.el.iter_n_children(null) < 1) {
817 print("got NO children?\n");
820 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
825 //var action = Gdk.DragAction.COPY;
826 // unless we are copying!!! ctl button..
828 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
829 Gdk.DragAction.COPY : Gdk.DragAction.MOVE ;
830 // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
833 if (_this.model.el.iter_n_children(null) < 1) {
834 // no children.. -- asume it's ok..
836 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
838 // continue through to allow drop...
846 //print("ISOVER? " + isOver);
849 Gtk.drag_finish (ctx, false, false, time); // drop failed..
850 return true; // not over apoint!?! - no action on drop or motion..
853 // drag node is parent of child..
854 //console.log("SRC TREEPATH: " + src.treepath);
855 //console.log("TARGET TREEPATH: " + data.path.to_string());
857 // nned to check a few here..
858 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
859 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
860 //Gtk.TreeViewDropPosition.AFTER
861 //Gtk.TreeViewDropPosition.BEFORE
863 // locally dragged items to not really use the
864 var selection_text = this.dragData;
868 if (selection_text == null || selection_text.length < 1) {
869 //print("Error - drag selection text returned NULL");
871 Gtk.drag_finish (ctx, false, false, time); // drop failed..
872 return true; /// -- fixme -- this is not really correct..
875 // see if we are dragging into ourself?
876 print ("got selection text of " + selection_text);
878 var target_path = path.to_string();
879 //print("target_path="+target_path);
882 if (selection_text == target_path) {
883 print("self drag ?? == we should perhaps allow copy onto self..\n");
885 Gtk.drag_finish (ctx, false, false, time); // drop failed..
887 return true; /// -- fixme -- this is not really correct..
892 //print("DUMPING DATA");
893 //console.dump(data);
896 //print(data.path.to_string() +' => '+ data.pos);
898 // dropList is a list of xtypes that this node could be dropped on.
899 // it is set up when we start to drag..
902 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
904 print("targetDAta: " + targetData +"\n");
906 if (targetData.length < 1) {
907 //print("Can not find drop node path");
909 Gtk.drag_finish (ctx, false, false, time); // drop failed..
915 // continue on to allow drop..
917 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
920 var delete_selection_data = false;
922 if (action == Gdk.DragAction.ASK) {
923 /* Ask the user to move or copy, then set the ctx action. */
926 if (action == Gdk.DragAction.MOVE) {
927 delete_selection_data = true;
930 // drag around.. - reorder..
931 _this.model.moveNode(targetData, action);
937 // we can send stuff to souce here...
940 // do we always say failure, so we handle the reall drop?
941 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
953 // user defined functions
954 public void highlightDropPath ( string treepath, Gtk.TreeViewDropPosition pos) {
956 // highlighting for drag/drop
957 if (treepath.length > 0) {
958 this.el.set_drag_dest_row( new Gtk.TreePath.from_string( treepath ), pos);
960 this.el.set_drag_dest_row(null, Gtk.TreeViewDropPosition.INTO_OR_AFTER);
964 public void setCursor (string treepath, string sourceEvent) {
965 this.lastEventSource = sourceEvent;
966 //this.blockChanges = true; << block changes prevents loading of 'node data' and firing of node_selected..
967 this.el.set_cursor(new Gtk.TreePath.from_string(treepath), null, false);
968 // fire node_selected..
969 //this.blockChanges = false;
970 this.lastEventSource = "";
972 public void selectNode (string treepath_str, string source) {
973 this.lastEventSource = source;
974 //this.selection.select_path(new Gtk.TreePath.from_string( treepath_str));
975 var tp = new Gtk.TreePath.from_string(treepath_str);
977 this.el.set_cursor(tp, null, false);
978 this.el.scroll_to_cell(tp, null, false, 0,0);
981 public class Xcls_model : Object
983 public Gtk.TreeStore el;
984 private Xcls_WindowLeftTree _this;
988 public DialogTemplateSelect template_select;
989 public string activePath;
992 public Xcls_model(Xcls_WindowLeftTree _owner )
996 this.el = new Gtk.TreeStore( 4, typeof(string),typeof(string),typeof(Object),typeof(Gdk.Pixbuf) );
999 this.template_select = null;
1000 this.activePath = "";
1002 // set gobject values
1006 print("model initialized");
1009 // user defined functions
1010 public string findDropNode (string treepath_str, string[] targets) {
1012 // this is used by the dragdrop code in the roo version AFAIR..
1014 //var path = treepath_str.replace(/^builder-/, '');
1015 // treemap is depreciated... - should really check if model has any entries..
1017 if (this.el.iter_n_children(null) < 1) {
1019 return "|%d".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
1021 //print("FIND treepath: " + path);
1022 //console.dump(this.treemap);
1024 //if (!treepath_str.match(/^builder-/)) {
1025 // return []; // nothing!
1027 if (targets.length > 0 && targets[0] == "*") {
1028 return treepath_str;
1030 return this.findDropNodeByPath(treepath_str,targets, -1);
1032 public void loadFile (JsRender.JsRender f) {
1035 _this.main_window.windowstate.leftTreeNodeSelected(null, "");
1037 _this.main_window.windowstate.file = f;
1040 if (f.tree == null) {
1047 // if it's still null?
1048 if (f.tree == null) {
1052 var o = new Gee.ArrayList<JsRender.Node>();
1056 _this.view.el.expand_all();
1058 if (f.tree.items.size < 1) {
1061 //this.get('/Window.leftvpaned').el.set_position(80);
1063 _this.view.el.set_cursor(
1064 new Gtk.TreePath.from_string("0"), null, false);
1068 //this.get('/Window.leftvpaned').el.set_position(200);
1075 public void updateSelected () {
1078 var s = _this.view.el.get_selection();
1085 if (!s.get_selected(out mod, out iter)) {
1086 return; // nothing seleted..
1090 this.el.get_value(iter, 2, out value);
1091 var node = (JsRender.Node)(value.get_object());
1093 this.el.set(iter, 0, node.nodeTitle(),
1094 1, node.nodeTip(), -1
1097 public string findDropNodeByPath (string treepath_str, string[] targets, int in_pref = -1) {
1099 var path = treepath_str; // dupe it..
1102 // pref : 3 = ontop - 0 = after, 1 = before
1103 int pref = in_pref < 0 ? Gtk.TreeViewDropPosition.INTO_OR_AFTER : in_pref;
1107 //console.dump(this.treemap);
1109 print("findDropNodeByPath : got path length %d / %s\n", path.length, path);
1111 if (path.length == 0) {
1112 // top drop. // just return empty..
1113 return "|%d".printf((int)pref) ;
1118 while (path.length > 0) {
1120 if (path.length == treepath_str.length && pref != Gtk.TreeViewDropPosition.INTO_OR_AFTER) {
1121 if (path.last_index_of(":") < 0 ) {
1124 path = path.substring(0, path.last_index_of(":"));
1125 last = treepath_str;
1126 print("DROP before or after : using %s\n",path);
1130 //print("LOOKING FOR PATH: " + path);
1131 var node_data = this.pathToNode(path);
1133 if (node_data == null) {
1134 print("node not found");
1138 var xname = node_data.fqn();
1142 for (var i =0; i < targets.length; i++) {
1143 var tg = targets[i];
1144 if ((tg == xname) ) {
1148 // if target is "xxxx:name"
1149 if (tg.contains(xname +":")) {
1151 var ar = tg.split(":");
1157 if (match.length > 0) {
1158 if (last.length > 0) { // pref is after/before..
1159 // then it's after last
1163 return last + "|%d".printf((int)pref) + "|" + prop;
1167 // we need to add prop - as :store -> needs to bee added when dropping onto.
1168 return path + "|%d".printf( (int) Gtk.TreeViewDropPosition.INTO_OR_AFTER) + "|" + prop;
1172 var par = path.split(":");
1173 string [] ppar = {};
1174 for (var i = 0; i < par.length-1; i++) {
1178 path = string.joinv(":", ppar);
1187 public void moveNode (string target_data, Gdk.DragAction action)
1190 /// target_data = "path|pos");
1193 //print("MOVE NODE");
1194 // console.dump(target_data);
1195 Gtk.TreeIter old_iter;
1198 var s = _this.view.el.get_selection();
1199 s.get_selected(out mod , out old_iter);
1200 mod.get_path(old_iter);
1202 var node = this.pathToNode(mod.get_path(old_iter).to_string());
1203 //console.dump(node);
1205 print("moveNode: ERROR - node is null?");
1210 // needs to drop first, otherwise the target_data
1211 // treepath will be invalid.
1214 if ((action & Gdk.DragAction.MOVE) > 0) {
1215 print("REMOVING OLD NODE : " + target_data + "\n");
1217 this.dropNode(target_data, node, false);
1218 this.el.remove(ref old_iter);
1223 print("DROPPING NODE // copy: " + target_data + "\n");
1224 node = node.deepClone();
1225 this.dropNode(target_data, node, false);
1228 this.activePath= "";
1229 //this.updateNode(false,true);
1231 public void deleteSelected () {
1233 print("DELETE SELECTED?");
1234 //_this.view.blockChanges = true;
1235 print("GET SELECTION?");
1237 var s = _this.view.el.get_selection();
1239 print("GET SELECTED?");
1244 if (!s.get_selected(out mod, out iter)) {
1245 return; // nothing seleted..
1250 this.activePath= "";
1251 print("GET vnode value?");
1254 this.el.get_value(iter, 2, out value);
1255 var data = (JsRender.Node)(value.get_object());
1256 print("removing node from Render\n");
1257 if (data.parent == null) {
1258 _this.main_window.windowstate.file.tree = null;
1262 print("removing node from Tree\n");
1264 this.el.remove(ref iter);
1274 this.activePath= ""; // again!?!?
1275 //this.changed(null,true);
1279 _this.view.blockChanges = false;
1281 public void load (Gee.ArrayList<JsRender.Node> tr, Gtk.TreeIter? iter)
1284 //this.insert(citer,iter,0);
1285 var ic = Gtk.IconTheme.get_default();
1286 var pixdef = ic.load_icon("emblem-new", 16,0);
1288 for(var i =0 ; i < tr.size; i++) {
1290 this.el.insert(out citer,iter,-1); // why not append?
1292 this.el.append(out citer,null);
1295 this.el.set(citer, 0, tr.get(i).nodeTitle(),
1296 1, tr.get(i).nodeTip(), -1
1298 var o = GLib.Value(typeof(Object));
1299 o.set_object((Object)tr.get(i));
1301 this.el.set_value(citer, 2, o);
1303 var clsname = tr.get(i).fqn();
1305 var clsb = clsname.split(".");
1306 var sub = clsb.length > 1 ? clsb[1].down() : "";
1309 var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1310 if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1311 pix = new Gdk.Pixbuf.from_file (fn);
1315 this.el.set_value(citer, 3, pix );
1321 if (tr.get(i).items.size > 0) {
1322 this.load(tr.get(i).items, citer);
1329 public JsRender.Node pathToNode (string path) {
1333 _this.model.el.get_iter_from_string(out iter, path);
1336 _this.model.el.get_value(iter, 2, out value);
1338 return (JsRender.Node)value.dup_object();
1341 public void dropNode (string target_data_str, JsRender.Node node, bool show_templates) {
1342 // print("drop Node");
1343 // console.dump(node);
1344 // console.dump(target_data);
1347 // {parent}|{pos}|{prop}
1350 // 0 = before , 1=after 2/3 onto
1352 GLib.debug("dropNode %s", target_data_str);
1353 var target_data= target_data_str.split("|");
1355 var parent_str = target_data[0].length > 0 ? target_data[0] : "";
1356 var pos = target_data.length > 1 ? int.parse(target_data[1]) : 2; // ontop..
1359 Gtk.TreePath tree_path = parent_str.length > 0 ? new Gtk.TreePath.from_string( parent_str ) : null;
1363 //print("add " + tp + "@" + target_data[1] );
1365 JsRender.Node parentNode = null;
1367 Gtk.TreeIter iter_after;
1368 Gtk.TreeIter iter_par ;
1371 if (target_data.length == 3 && target_data[2].length > 0) {
1372 node.props.set("* prop", target_data[2]);
1375 Gtk.TreePath expand_parent = null;
1377 // we only need to show the template if it's come from else where?
1378 if (show_templates) {
1380 var ts = _this.main_window.windowstate.template_select;
1382 var new_node = ts.show(
1383 _this.main_window, // (Gtk.Window) _this.el.get_toplevel (),
1384 _this.main_window.windowstate.file.palete(),
1386 _this.main_window.windowstate.project);
1388 if (new_node == null) {
1389 return; // do not add?
1394 //print("pos is %d \n".printf(pos));
1396 Gtk.TreeIter n_iter;
1398 if ( parent_str.length < 1) {
1399 this.el.append(out n_iter, null); // drop at top level..
1401 _this.main_window.windowstate.file.tree = node;
1404 } else if (pos < 2) {
1405 //print(target_data[1] > 0 ? 'insert_after' : 'insert_before');
1407 this.el.get_iter(out iter_after, tree_path );
1408 this.el.iter_parent(out iter_par, iter_after);
1409 expand_parent = this.el.get_path(iter_par);
1412 this.el.get_value( iter_par, 2, out value);
1413 parentNode = (JsRender.Node)value.dup_object();
1416 this.el.get_value( iter_after, 2, out value);
1417 var relNode = (JsRender.Node)value.dup_object();
1421 this.el.insert_after(out n_iter, iter_par , iter_after);
1422 var ix = parentNode.items.index_of(relNode);
1423 parentNode.items.insert(ix+1, node);
1426 this.el.insert_before(out n_iter, iter_par , iter_after);
1427 var ix = parentNode.items.index_of(relNode);
1428 parentNode.items.insert(ix, node);
1431 node.parent = parentNode;
1436 // print("appending to " + parent_str);
1437 this.el.get_iter(out iter_par, tree_path);
1438 this.el.append(out n_iter, iter_par );
1439 expand_parent = this.el.get_path(iter_par);
1442 this.el.get_value( iter_par, 2, out value);
1443 parentNode = (JsRender.Node)value.dup_object();
1444 node.parent = parentNode;
1445 parentNode.items.add(node);
1448 // reparent node in tree...
1451 // why only on no parent???
1453 //if (node.parent = null) {
1460 // work out what kind of packing to use.. -- should be in
1461 if (!node.has("pack") && parent_str.length > 1) {
1463 _this.main_window.windowstate.file.palete().fillPack(node,parentNode);
1470 this.el.set(n_iter, 0, node.nodeTitle(), 1, node.nodeTip(), -1 );
1471 var o = GLib.Value(typeof(Object));
1472 o.set_object((Object)node);
1474 this.el.set_value(n_iter, 2, o);
1479 // load children - if it has any..
1481 if (node.items.size > 0) {
1482 this.load(node.items, n_iter);
1483 _this.view.el.expand_row(this.el.get_path(n_iter), true);
1484 } else if (expand_parent != null && !_this.view.el.is_row_expanded(expand_parent)) {
1485 _this.view.el.expand_row(expand_parent,true);
1488 //if (tp != null && (node.items.length() > 0 || pos > 1)) {
1489 // _this.view.el.expand_row(this.el.get_path(iter_par), true);
1491 // wee need to get the empty proptypes from somewhere..
1493 //var olditer = this.activeIter;
1494 this.activePath = this.el.get_path(n_iter).to_string();
1497 // pretend button was pressed, so that we can trigger select node...
1498 _this.view.button_is_pressed = true;
1499 _this.view.lastEventSource = "";
1500 _this.view.el.set_cursor(this.el.get_path(n_iter), null, false);
1501 _this.view.button_is_pressed = false;
1507 public string treePathFromNode (JsRender.Node node) {
1508 // iterate through the tree and find the node
1511 this.el.foreach((mod, pth, iter) => {
1516 _this.model.el.get_value(iter, 2, out value);
1520 var n = (JsRender.Node)value;
1522 print("compare %s to %s\n", n.fqn(), node.fqn());
1524 ret = pth.to_string();
1534 public class Xcls_TreeViewColumn7 : Object
1536 public Gtk.TreeViewColumn el;
1537 private Xcls_WindowLeftTree _this;
1543 public Xcls_TreeViewColumn7(Xcls_WindowLeftTree _owner )
1546 this.el = new Gtk.TreeViewColumn();
1550 // set gobject values
1551 this.el.title = "test";
1552 var child_0 = new Xcls_iconrender( _this );
1554 this.el.pack_start ( child_0.el , true );
1555 var child_1 = new Xcls_renderer( _this );
1557 this.el.pack_start ( child_1.el , true );
1561 this.el.add_attribute(_this.renderer.el , "markup", 0 );
1562 this.el.add_attribute(_this.iconrender.el , "pixbuf", 3 );
1565 // user defined functions
1567 public class Xcls_iconrender : Object
1569 public Gtk.CellRendererPixbuf el;
1570 private Xcls_WindowLeftTree _this;
1576 public Xcls_iconrender(Xcls_WindowLeftTree _owner )
1579 _this.iconrender = this;
1580 this.el = new Gtk.CellRendererPixbuf();
1584 // set gobject values
1587 // user defined functions
1590 public class Xcls_renderer : Object
1592 public Gtk.CellRendererText el;
1593 private Xcls_WindowLeftTree _this;
1599 public Xcls_renderer(Xcls_WindowLeftTree _owner )
1602 _this.renderer = this;
1603 this.el = new Gtk.CellRendererText();
1607 // set gobject values
1610 // user defined functions
1615 public class Xcls_LeftTreeMenu : Object
1618 private Xcls_WindowLeftTree _this;
1624 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1627 _this.LeftTreeMenu = this;
1628 this.el = new Gtk.Menu();
1632 // set gobject values
1633 var child_0 = new Xcls_MenuItem11( _this );
1635 this.el.add ( child_0.el );
1636 var child_1 = new Xcls_MenuItem12( _this );
1638 this.el.add ( child_1.el );
1639 var child_2 = new Xcls_MenuItem13( _this );
1641 this.el.add ( child_2.el );
1644 // user defined functions
1646 public class Xcls_MenuItem11 : Object
1648 public Gtk.MenuItem el;
1649 private Xcls_WindowLeftTree _this;
1655 public Xcls_MenuItem11(Xcls_WindowLeftTree _owner )
1658 this.el = new Gtk.MenuItem();
1662 // set gobject values
1663 this.el.label = "Delete Element";
1666 this.el.activate.connect( ( ) => {
1671 _this.model.deleteSelected();
1675 // user defined functions
1678 public class Xcls_MenuItem12 : Object
1680 public Gtk.MenuItem el;
1681 private Xcls_WindowLeftTree _this;
1687 public Xcls_MenuItem12(Xcls_WindowLeftTree _owner )
1690 this.el = new Gtk.MenuItem();
1694 // set gobject values
1695 this.el.label = "Save as Template";
1698 this.el.activate.connect( () => {
1700 DialogSaveTemplate.singleton().show(
1701 (Gtk.Window) _this.el.get_toplevel (),
1702 _this.main_window.windowstate.file.palete(),
1703 _this.getActiveElement()
1710 // user defined functions
1713 public class Xcls_MenuItem13 : Object
1715 public Gtk.MenuItem el;
1716 private Xcls_WindowLeftTree _this;
1722 public Xcls_MenuItem13(Xcls_WindowLeftTree _owner )
1725 this.el = new Gtk.MenuItem();
1729 // set gobject values
1730 this.el.label = "Save as Module";
1733 this.el.activate.connect( () => {
1734 var node = _this.getActiveElement();
1735 var name = DialogSaveModule.singleton().show(
1736 (Gtk.Window) _this.el.get_toplevel (),
1737 _this.main_window.windowstate.project,
1740 if (name.length < 1) {
1744 node.props.set("* xinclude", name);
1748 var s = _this.view.el.get_selection();
1750 print("GET SELECTED?");
1755 if (!s.get_selected(out mod, out iter)) {
1756 return; // nothing seleted..
1759 var n_cn = mod.iter_n_children(iter) -1;
1760 for (var i = n_cn; i > -1; i--) {
1761 mod.iter_nth_child(out citer, iter, i);
1764 print("removing node from Tree\n");
1766 _this.model.el.remove(ref citer);
1769 _this.node_selected(node, "tree");
1775 // user defined functions