Fix #7987 - drag move supported with shift key now
[roobuilder] / src / Builder4 / WindowLeftTree.bjs
1 {
2  "build_module" : "builder",
3  "gen_extended" : false,
4  "items" : [
5   {
6    "# Xcls_MainWindow main_window" : "null",
7    "$ xns" : "Gtk",
8    "@ bool before_node_change" : "()",
9    "@ void changed" : "()",
10    "@ void node_selected" : "(JsRender.Node? node)",
11    "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
12    "bool hexpand" : true,
13    "bool vexpand" : true,
14    "id" : "WindowLeftTree",
15    "items" : [
16     {
17      "$ xns" : "Gtk",
18      "items" : [
19       {
20        "$ xns" : "Gtk",
21        "* prop" : "factory",
22        "xtype" : "SignalListItemFactory"
23       }
24      ],
25      "xtype" : "ListView"
26     },
27     {
28      "$ xns" : "Gtk",
29      "Gtk.PolicyType hscrollbar_policy" : "Gtk.PolicyType.AUTOMATIC",
30      "Gtk.PolicyType vscrollbar_policy" : "Gtk.PolicyType.AUTOMATIC",
31      "bool has_frame" : true,
32      "bool hexpand" : true,
33      "bool vexpand" : true,
34      "id" : "viewwin",
35      "items" : [
36       {
37        "# bool blockChanges" : false,
38        "$ JsRender.Node? dragNode" : "null",
39        "$ string lastEventSource" : "\"\"",
40        "$ xns" : "Gtk",
41        "* init" : [
42         "{",
43         " ",
44         "  this.css = new Gtk.CssProvider();",
45         "//\ttry {",
46         "\t\tthis.css.load_from_string(\"",
47         "#left-tree-view { font-size: 12px;}\t",
48         ".drag-over  { background-color:#88a3bc; }",
49         ".drag-below  {   ",
50         " border-bottom-width: 5px; ",
51         " border-bottom-style: solid;",
52         " border-bottom-color: #88a3bc;",
53         "}",
54         ".drag-above  {",
55         " border-top-width: 5px;",
56         " border-top-style: solid;",
57         " border-top-color: #88a3bc;",
58         "}",
59         "#left-tree-view indent {",
60         "-gtk-icon-size : 2px;",
61         "}",
62         "#left-tree-view indent:nth-last-child(2)  {",
63         "min-width: 24px;",
64         "}",
65         "\");",
66         "",
67         "\tGtk.StyleContext.add_provider_for_display(",
68         "\t\tthis.el.get_display(),",
69         "\t\tthis.css,",
70         "\t\tGtk.STYLE_PROVIDER_PRIORITY_APPLICATION",
71         "\t);",
72         "\t",
73         "\t  ",
74         "}",
75         ""
76        ],
77        "* prop" : "child",
78        "Boolean id" : "view",
79        "Gtk.CssProvider css" : "",
80        "bool button_is_pressed" : false,
81        "bool headers_visible" : false,
82        "bool hexpand" : false,
83        "bool vexpand" : true,
84        "items" : [
85         {
86          "$ xns" : "Gtk",
87          "listeners" : {
88           "pressed" : [
89            "(n_press, x, y) => {",
90            " ",
91            "    //console.log(\"button press?\");",
92            "    ",
93            "    //this.el.set_state(Gtk.EventSequenceState.CLAIMED);",
94            "",
95            "",
96            "    ",
97            "    _this.view.button_is_pressed = true;",
98            "      ",
99            "    _this.view.lastEventSource = \"tree\";",
100            "    if (! _this.before_node_change() ) {",
101            "    \tGLib.debug(\"before_node_change return false\");",
102            "       return ;",
103            "    }",
104            "    ",
105            "\t // nothing there -show dialog",
106            "    if (_this.model.el.get_n_items() < 1) {",
107            "\t    _this.main_window.windowstate.showAddObject(_this.view.el, null);",
108            "        GLib.debug(\"no items\");",
109            "\t    return ;",
110            "    }",
111            "    string pos;",
112            "    var row = _this.view.getRowAt(x,y, out pos );",
113            "    if (row < 0) {",
114            "\t    GLib.debug(\"no row selected items\");",
115            "\t    return;",
116            "    }",
117            "    ",
118            "    var node =   _this.selmodel.getNodeAt(row);",
119            "    if (node == null) {",
120            "    \tGLib.warning(\"No node found at row %d\", row);",
121            "    \treturn;",
122            "\t}",
123            "",
124            "     ",
125            "     ",
126            "    if (_this.view.getColAt(x,y) > 0 ) {",
127            "\t    GLib.debug(\"add colum clicked.\");",
128            "        var fqn = node.fqn();",
129            "    \tvar cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);",
130            "  \t\tif (cn.size < 1) {",
131            "  \t\t\treturn ;",
132            "\t\t}",
133            "",
134            "\t\t_this.main_window.windowstate.leftTreeBeforeChange();",
135            "\t\t//_this.view.el.get_selection().select_path(res);",
136            "\t\tGLib.debug(\"Button Pressed - start show window\");",
137            "\t\t_this.main_window.windowstate.showAddObject(_this.view.el, node);",
138            "\t\tGLib.debug(\"Button Pressed - finsihed show window\");",
139            "     \treturn ;",
140            "\t}",
141            "    ",
142            "\t ",
143            "     ",
144            "}",
145            ""
146           ],
147           "released" : [
148            "(n_press, x, y) => {",
149            " ",
150            "    _this.view.button_is_pressed = false;",
151            "",
152            "",
153            "}",
154            ""
155           ]
156          },
157          "xtype" : "GestureClick"
158         },
159         {
160          "$ xns" : "Gtk",
161          "listeners" : {
162           "pressed" : [
163            "(n_press, x, y) => {",
164            "",
165            "\t",
166            "\t  ",
167            "\t ",
168            "    if (_this.model.el.get_n_items() < 1) {",
169            " ",
170            "        GLib.debug(\"no items\");",
171            "\t    return ;",
172            "    }",
173            "    string pos;",
174            "    var row = _this.view.getRowAt(x,y, out pos );",
175            "    if (row < 0) {",
176            "\t    GLib.debug(\"no row selected items\");",
177            "\t    return;",
178            "    }",
179            "    ",
180            "    var node =   _this.selmodel.getNodeAt(row);",
181            "    if (node == null) {",
182            "    \tGLib.warning(\"No node found at row %d\", row);",
183            "    \treturn;",
184            "\t}",
185            "\t_this.model.selectNode(node);",
186            "     ",
187            "     ",
188            "     ",
189            "\tGLib.debug(\"Prssed %d\", (int)  this.el.get_current_button());",
190            "\t//_this.deletemenu.el.set_parent(_this.view.el);",
191            "\t_this.LeftTreeMenu.el.set_parent(_this.view.el);",
192            "\t",
193            "\t",
194            "\t//Gtk.Allocation rect;",
195            "\t//_this.view.el.get_allocation(out rect);",
196            " \t//_this.deletemenu.el.set_has_arrow(false);",
197            "\t_this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM); ",
198            "\t",
199            "\t\t",
200            "\t_this.LeftTreeMenu.el.set_offset( ",
201            "\t\t\t(int)x  ,",
202            "\t\t\t(int)y - (int)_this.view.el.get_height());",
203            "",
204            "    _this.LeftTreeMenu.el.popup();",
205            "      ",
206            "}",
207            ""
208           ]
209          },
210          "uint button" : 3,
211          "xtype" : "GestureClick"
212         },
213         {
214          "$ Gdk.DragAction[] actions" : "Gdk.DragAction.COPY   | Gdk.DragAction.MOVE   ",
215          "$ xns" : "Gtk",
216          "listeners" : {
217           "drag_begin" : [
218            "( drag )  => {",
219            "\tGLib.debug(\"SOURCE: drag-begin\");",
220            "\t ",
221            "    // find what is selected in our tree...",
222            "    var data = _this.selmodel.getSelectedNode();",
223            "\tif (data == null) {",
224            "\t\treturn  ;",
225            "\t}",
226            "\t_this.view.dragNode = data;",
227            "    var xname = data.fqn();",
228            "    GLib.debug (\"XNAME  IS %s\", xname);",
229            "",
230            " \tvar widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);",
231            " \t",
232            " \t",
233            "    var paintable = new Gtk.WidgetPaintable(widget);",
234            "    this.el.set_icon(paintable, 0,0);",
235            "            ",
236            " ",
237            "}"
238           ],
239           "drag_cancel" : [
240            "(drag, reason) => {",
241            "",
242            "\t_this.view.dragNode = null;",
243            "\treturn true;",
244            "}",
245            ""
246           ],
247           "drag_end" : [
248            "(drag, delete_data) => {",
249            "",
250            "_this.view.dragNode = null;",
251            "}",
252            ""
253           ],
254           "prepare" : [
255            "(x, y) => {",
256            "",
257            "\t",
258            "\t",
259            "///\t( drag_context, data, info, time) => {",
260            "            ",
261            "",
262            "\t//print(\"drag-data-get\");",
263            " \tvar ndata = _this.selmodel.getSelectedNode();",
264            "\tif (ndata == null) {",
265            "\t \tGLib.debug(\"return empty string - no selection..\");",
266            "\t\treturn null;",
267            "\t ",
268            "\t}",
269            "",
270            "  ",
271            "\t//data.set_text(tp,tp.length);   ",
272            "",
273            "\tvar \tstr = ndata.toJsonString();",
274            "\tGLib.debug(\"prepare  store: %s\", str);",
275            "\tGLib.Value ov = GLib.Value(typeof(string));",
276            "\tov.set_string(str);",
277            " \tvar cont = new Gdk.ContentProvider.for_value(ov);",
278            "    /*",
279            "\tGLib.Value v = GLib.Value(typeof(string));",
280            "\t//var str = drop.read_text( [ \"text/plain\" ] 0);",
281            "\t ",
282            "\t\tcont.get_value(ref v);",
283            "\t ",
284            "\t}",
285            "\tGLib.debug(\"set %s\", v.get_string());",
286            "      */  ",
287            " \treturn cont;",
288            "\t ",
289            "\t ",
290            "}",
291            ""
292           ]
293          },
294          "xtype" : "DragSource"
295         },
296         {
297          "$ xns" : "Gtk",
298          "listeners" : {
299           "key_pressed" : [
300            "(keyval, keycode, state) => {",
301            "",
302            " ",
303            "",
304            "\tif (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace)  {",
305            "\t\treturn true;",
306            "\t}",
307            "",
308            "\t_this.model.deleteSelected();",
309            "\treturn true;",
310            "",
311            "}",
312            ""
313           ]
314          },
315          "xtype" : "EventControllerKey"
316         },
317         {
318          "$ xns" : "Gtk",
319          "* ctor" : [
320           "new Gtk.DropTarget ( typeof(string) ,",
321           "\t\tGdk.DragAction.COPY   | Gdk.DragAction.MOVE   )"
322          ],
323          "Gtk.Widget? highlightWidget" : "null",
324          "JsRender.Node? lastDragNode" : "null",
325          "id" : "drop",
326          "listeners" : {
327           "accept" : [
328            "(drop) => {",
329            "",
330            "\tGLib.debug(\"got DropTarget:accept\");",
331            " ",
332            "// NOT REALLY NEEDED? = put stuff in drop?",
333            "",
334            "",
335            "/* (  ctx, x, y, time)  => {",
336            "      //Seed.print(\"TARGET: drag-drop\");",
337            "   ",
338            "   ",
339            "    var src = Gtk.drag_get_source_widget(ctx);",
340            "     ",
341            "   if (src != this.el) {",
342            "   ",
343            "    ",
344            "       ",
345            "       this.drag_in_motion = false;   ",
346            "            // request data that will be recieved by the recieve...              ",
347            "        Gtk.drag_get_data",
348            "        (",
349            "                this.el,         // will receive 'drag-data-received' signal ",
350            "                ctx,        // represents the current state of the DnD ",
351            "                Gdk.Atom.intern(\"application/json\",true),    // the target type we want ",
352            "                time            // time stamp ",
353            "        );",
354            "",
355            "         ",
356            "        // No target offered by source => error",
357            "   ",
358            "",
359            "         return  false;",
360            "     }",
361            "     ",
362            "     // handle drop around self..",
363            "     ",
364            "                  ",
365            "            ",
366            "    //print(\"GETTING POS\");",
367            "    var  targetData = \"\";",
368            "    ",
369            "    Gtk.TreePath path;",
370            "    Gtk.TreeViewDropPosition pos;",
371            "    var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);",
372            "    ",
373            "    // if there are not items in the tree.. the we have to set isOver to true for anything..",
374            "    var isEmpty = false;",
375            "    if (_this.model.el.iter_n_children(null) < 1) {",
376            "        print(\"got NO children?\\n\");",
377            "        isOver = true; //??? ",
378            "        isEmpty = true;",
379            "        pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;",
380            "    }",
381            "    ",
382            "     ",
383            "     ",
384            "    //var action = Gdk.DragAction.COPY;",
385            "        // unless we are copying!!! ctl button..",
386            "    ",
387            "    var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?",
388            "                 Gdk.DragAction.COPY  : Gdk.DragAction.MOVE ;",
389            "                // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;",
390            "",
391            "      ",
392            "    if (_this.model.el.iter_n_children(null) < 1) {",
393            "        // no children.. -- asume it's ok..",
394            "        ",
395            "        targetData = \"|%d|\".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);",
396            "         ",
397            "        // continue through to allow drop...",
398            "",
399            "    } else {",
400            "                ",
401            "                ",
402            "    ",
403            "                ",
404            "                ",
405            "                //print(\"ISOVER? \" + isOver);",
406            "        if (!isOver) {",
407            "            ",
408            "            Gtk.drag_finish (ctx, false, false, time);        // drop failed..",
409            "            return true; // not over apoint!?! - no action on drop or motion..",
410            "        }",
411            "                ",
412            "        // drag node is parent of child..",
413            "        //console.log(\"SRC TREEPATH: \" + src.treepath);",
414            "        //console.log(\"TARGET TREEPATH: \" + data.path.to_string());",
415            "        ",
416            "        // nned to check a  few here..",
417            "        //Gtk.TreeViewDropPosition.INTO_OR_AFTER",
418            "        //Gtk.TreeViewDropPosition.INTO_OR_BEFORE",
419            "        //Gtk.TreeViewDropPosition.AFTER",
420            "        //Gtk.TreeViewDropPosition.BEFORE",
421            "        ",
422            "        // locally dragged items to not really use the ",
423            "        var selection_text = this.dragData;",
424            "        ",
425            "        ",
426            "        ",
427            "        if (selection_text == null || selection_text.length < 1) {",
428            "            //print(\"Error  - drag selection text returned NULL\");",
429            "          ",
430            "             Gtk.drag_finish (ctx, false, false, time);        // drop failed..",
431            "             return true; /// -- fixme -- this is not really correct..",
432            "        }                ",
433            "                ",
434            "                // see if we are dragging into ourself?",
435            "                print (\"got selection text of  \" + selection_text);",
436            "        ",
437            "        var target_path = path.to_string();",
438            "        //print(\"target_path=\"+target_path);",
439            "",
440            "        // ",
441            "        if (selection_text  == target_path) {",
442            "            print(\"self drag ?? == we should perhaps allow copy onto self..\\n\");",
443            "            ",
444            "             Gtk.drag_finish (ctx, false, false, time);        // drop failed..",
445            "",
446            "             return true; /// -- fixme -- this is not really correct..",
447            "",
448            "        }",
449            "                ",
450            "        // check that ",
451            "        //print(\"DUMPING DATA\");",
452            "        //console.dump(data);",
453            "        // path, pos",
454            "        ",
455            "        //print(data.path.to_string() +' => '+  data.pos);",
456            "        ",
457            "        // dropList is a list of xtypes that this node could be dropped on.",
458            "        // it is set up when we start to drag..",
459            "        ",
460            "        ",
461            "        targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);",
462            "            ",
463            "        print(\"targetDAta: \" + targetData +\"\\n\");",
464            "        ",
465            "        if (targetData.length < 1) {",
466            "            //print(\"Can not find drop node path\");",
467            "             ",
468            "            Gtk.drag_finish (ctx, false, false, time);        // drop failed..",
469            "            return true;",
470            "        }",
471            "                    ",
472            "                ",
473            "                ",
474            "                // continue on to allow drop..",
475            "  }",
476            "        // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..",
477            "",
478            "",
479            "     var delete_selection_data = false;",
480            "        ",
481            "    if (action == Gdk.DragAction.ASK)  {",
482            "        // Ask the user to move or copy, then set the ctx action. ",
483            "    }",
484            "",
485            "    if (action == Gdk.DragAction.MOVE) {",
486            "        delete_selection_data = true;",
487            "    }",
488            "      ",
489            "                // drag around.. - reorder..",
490            "    _this.model.moveNode(targetData, action);",
491            "        ",
492            "       ",
493            "        ",
494            "        ",
495            "        ",
496            "        // we can send stuff to souce here...",
497            "",
498            "",
499            "// do we always say failure, so we handle the reall drop?",
500            "    Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);",
501            "",
502            "    return true;",
503            " ",
504            " ",
505            " ",
506            " ",
507            " ",
508            " ",
509            "}",
510            "*/",
511            "\treturn true;",
512            "}",
513            ""
514           ],
515           "drop" : [
516            "(v, x, y) => {",
517            "\t",
518            "\tthis.addHighlight(null,\"\");",
519            " ",
520            " \tvar is_shift = _this.keystate.is_shift > 0;",
521            " ",
522            " \tvar pos = \"\";",
523            " \t// -- get position..",
524            " \tif (this.lastDragString != v.get_string() || this.lastDragNode == null) {",
525            "\t\t// still dragging same node",
526            " ",
527            "\t\tthis.lastDragNode = new JsRender.Node(); ",
528            "\t\tthis.lastDragNode.loadFromJsonString(v.get_string(), 1);",
529            "\t}",
530            "    ",
531            " \t     ",
532            "       ",
533            "    var dropNode = new JsRender.Node(); ",
534            "\tdropNode.loadFromJsonString(v.get_string(), 1);",
535            "\tvar drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());",
536            "   ",
537            "    // if there are not items in the tree.. the we have to set isOver to true for anything..",
538            " ",
539            "    if (_this.model.el.n_items < 1) {",
540            "    \t// FIXME check valid drop types?",
541            "    \tif (!drop_on_to.contains(\"*top\")) {",
542            "\t\t\tGLib.debug(\"drop on to list does not contain top?\");",
543            "\t\t\treturn false;\t",
544            "\t\t}",
545            "\t\t// add new node to top..",
546            "\t\t",
547            "\t\t",
548            "\t\t var m = (GLib.ListStore) _this.model.el.model;",
549            "     \t_this.main_window.windowstate.file.tree = dropNode;  ",
550            "    ",
551            "   ",
552            "\t\tm.append(dropNode);",
553            "\t\t_this.model.selectNode(dropNode); \t",
554            "\t\t_this.changed();",
555            "\t\treturn true; // no need to highlight?",
556            "     ",
557            "    }",
558            "",
559            "",
560            "",
561            "\tvar row = _this.view.getRowAt(x,y, out pos);",
562            "\tif (row < 0) {",
563            "\t\treturn   false; //Gdk.DragAction.COPY;",
564            "\t}",
565            "\tvar tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);",
566            "\t",
567            "\tvar node =  (JsRender.Node)tr.get_item();",
568            "",
569            " \tif (pos == \"above\" || pos == \"below\") {",
570            "\t\tif (node.parent == null) {",
571            "\t\t\tpos = \"over\";",
572            "\t\t} else {",
573            "\t \t\tif (!drop_on_to.contains(node.parent.fqn())) {",
574            "\t\t\t\tpos = \"over\";",
575            " \t\t\t} else {",
576            "\t\t\t\tGLib.debug(\"drop  contains %s - using %s\" , node.parent.fqn(), pos);",
577            "\t\t\t\tif (_this.view.dragNode  != null && is_shift) {",
578            "\t\t \t\t\tif (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {",
579            "\t\t\t \t\t\tGLib.debug(\"shift drop not self not allowed\");",
580            "  \t\t\t\t\t\treturn false;\t",
581            "\t\t \t\t\t}",
582            "\t\t \t\t\t",
583            "\t\t \t\t}",
584            "\t\t\t\t",
585            "\t\t\t\t",
586            "\t\t\t}",
587            " \t\t}",
588            " \t\t",
589            " \t}",
590            " \tif (pos == \"over\") {",
591            "\t \tif (!drop_on_to.contains(node.fqn())) {",
592            "\t\t\tGLib.debug(\"drop on does not contain %s - try center\" , node.fqn());",
593            "\t\t\treturn false;",
594            "",
595            "\t\t}",
596            "\t\tif (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {",
597            " \t\t\tGLib.debug(\"shift drop not self not allowed\");",
598            "\t\t\treturn false;\t",
599            "\t\t}",
600            "\t}",
601            " \t",
602            " \tswitch(pos) {",
603            " \t\tcase \"over\":",
604            "\t \t\tnode.appendChild(dropNode);",
605            "\t \t\tif (is_shift && _this.view.dragNode != null) {",
606            "\t\t \t\t_this.model.selectNode(null); ",
607            "\t\t \t\t_this.view.dragNode.remove();",
608            "\t \t\t}",
609            "\t \t\t\t",
610            "\t \t\t",
611            " \t\t\t_this.model.selectNode(dropNode); ",
612            " \t\t\t",
613            " \t\t\t_this.changed();\t\t\t\t \t\t",
614            "\t \t\treturn true;",
615            "\t \t\t",
616            " \t\tcase \"above\":",
617            " \t\t\tGLib.debug(\"Above - insertBefore\");",
618            " \t\t",
619            "\t\t\tnode.parent.insertBefore(dropNode, node);",
620            "\t \t\tif (is_shift && _this.view.dragNode != null) {",
621            "\t\t \t\t_this.model.selectNode(null); \t \t\t",
622            "\t\t \t\t_this.view.dragNode.remove();",
623            "\t \t\t}",
624            "\t",
625            " \t\t\t_this.model.selectNode(dropNode); \t\t\t",
626            " \t\t\t_this.changed();",
627            " \t\t\treturn true;",
628            " \t\t\t",
629            " \t\tcase \"below\":",
630            " \t\t\tGLib.debug(\"Below - insertAfter\"); \t\t",
631            "\t \t\tif (is_shift && _this.view.dragNode != null) {",
632            "\t\t \t\t_this.model.selectNode(null); \t \t\t",
633            "\t\t \t\t_this.view.dragNode.remove();",
634            "\t \t\t}",
635            "\t",
636            " \t\t\t",
637            " \t\t\tnode.parent.insertAfter(dropNode, node);",
638            " \t\t\t_this.model.selectNode(dropNode);\t",
639            " \t\t\t_this.changed();",
640            " \t\t\t// select it",
641            " \t\t\treturn true;",
642            " \t\t\t",
643            " \t\tdefault:",
644            " \t\t\t// should not happen",
645            " \t\t\treturn false;",
646            " \t}",
647            " \t",
648            "\t",
649            "     ",
650            "\t\t",
651            "\t\t",
652            "",
653            "}",
654            " "
655           ],
656           "leave" : [
657            "( ) => {",
658            "\tthis.addHighlight(null,\"\");",
659            "",
660            "}",
661            ""
662           ],
663           "motion" : [
664            "(  x, y) => {",
665            " ",
666            "\tvar is_shift = _this.keystate.is_shift > 0;",
667            "\t",
668            "\tGLib.debug(\"shift is    %s\", _this.keystate.is_shift > 0 ? \"SHIFT\" : \"-\");",
669            "\tstring pos; // over / before / after..",
670            "",
671            "    //GLib.debug(\"got drag motion\");",
672            "",
673            "    GLib.Value v = GLib.Value(typeof(string));",
674            "   \t//var str = drop.read_text( [ \"text/plain\" ] 0);",
675            "   \tvar cont = this.el.current_drop.get_drag().content ;",
676            "   \ttry {",
677            "  \t\tcont.get_value(ref v);",
678            "\t} catch (GLib.Error e) {",
679            "\t    GLib.debug(\"failed to get drag value\");",
680            "\t\treturn Gdk.DragAction.COPY;\t ",
681            "\t",
682            "\t}",
683            " ",
684            "\t//GLib.debug(\"got %s\", v.get_string());",
685            "\t  ",
686            "\tif (this.lastDragString != v.get_string() || this.lastDragNode == null) {",
687            "\t\t// still dragging same node",
688            " ",
689            "\t\tthis.lastDragNode = new JsRender.Node(); ",
690            "\t\tthis.lastDragNode.loadFromJsonString(v.get_string(), 1);",
691            "\t}",
692            "    ",
693            "",
694            "\tvar drop_on_to = _this.main_window.windowstate.file.palete().getDropList(",
695            "\t\t\t\tthis.lastDragNode.fqn());",
696            "     ",
697            "     string[] str = {};",
698            "     foreach(var dp in drop_on_to) {",
699            "     \tstr += dp;",
700            " \t}",
701            " \tGLib.debug(\"droplist: %s\", string.joinv(\", \", str));",
702            "     ",
703            "     ",
704            "    // if there are not items in the tree.. the we have to set isOver to true for anything..",
705            " ",
706            "    if (_this.model.el.n_items < 1) {",
707            "    \t// FIXME check valid drop types?",
708            "    \tif (drop_on_to.contains(\"*top\")) {",
709            "\t\t\tthis.addHighlight(_this.view.el, \"over\");",
710            "\t\t} else {",
711            "\t\t\tthis.addHighlight(null, \"\");\t\t",
712            "\t\t}",
713            "",
714            "\t\treturn Gdk.DragAction.COPY; // no need to highlight?",
715            "     ",
716            "    }",
717            "    ",
718            "    ",
719            " \tGLib.debug(\"check is over\");",
720            " \t ",
721            "    // if path of source and dest are inside each other..",
722            "    // need to add source info to drag?",
723            "    // the fail();",
724            " \tvar row = _this.view.getRowAt(x,y, out pos);",
725            " \t",
726            " \tif (row < 0) {",
727            "\t\tthis.addHighlight(null, \"\");\t",
728            "\t \treturn Gdk.DragAction.COPY;",
729            " \t}",
730            "\tvar tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);",
731            "\t",
732            "\tvar node =  (JsRender.Node)tr.get_item();",
733            "\t",
734            "\tGLib.debug(\"Drop over node: %s\", node.fqn());",
735            "\t",
736            "",
737            " \tif (pos == \"above\" || pos == \"below\") {",
738            "\t\tif (node.parent == null) {",
739            "\t\t\tGLib.debug(\"no parent try center\");",
740            "\t\t\tpos = \"over\";",
741            "\t\t} else {",
742            "\t \t\t ",
743            "\t \t\tif (!drop_on_to.contains(node.parent.fqn())) {",
744            "\t\t\t\tGLib.debug(\"drop on does not contain %s - try center\" , node.parent.fqn());",
745            "\t \t\t\tpos = \"over\";",
746            " \t\t\t} else {",
747            "\t\t\t\tGLib.debug(\"drop  contains %s - using %s\" , node.parent.fqn(), pos);",
748            "\t\t\t\tif (_this.view.dragNode  != null && is_shift) {",
749            "\t\t \t\t\tif (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {",
750            "\t\t\t \t\t\tGLib.debug(\"shift drop not self not allowed\");",
751            "\t\t \t\t\t\tthis.addHighlight(null, \"\");",
752            "\t\t \t\t\t\treturn Gdk.DragAction.COPY;\t",
753            "\t\t \t\t\t}",
754            "\t\t \t\t\t",
755            "\t\t \t\t}",
756            "\t\t\t\t",
757            "\t\t\t}",
758            "\t\t\t",
759            "\t\t\t",
760            "\t\t\t",
761            " \t\t}",
762            " \t\t",
763            " \t\t",
764            " \t}",
765            " \tif (pos == \"over\") {",
766            "\t \tif (!drop_on_to.contains(node.fqn())) {",
767            "\t\t\tGLib.debug(\"drop on does not contain %s - try center\" , node.fqn());",
768            "\t\t\tthis.addHighlight(null, \"\"); ",
769            "\t\t\treturn is_shift ?  Gdk.DragAction.MOVE :  Gdk.DragAction.COPY;\t\t",
770            "\t\t}",
771            "\t\tif (_this.view.dragNode  != null && is_shift) {",
772            " \t\t\tif (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {",
773            "\t \t\t\tGLib.debug(\"shift drop not self not allowed\");",
774            " \t\t\t\tthis.addHighlight(null, \"\");",
775            " \t\t\t\treturn Gdk.DragAction.COPY;\t",
776            " \t\t\t}",
777            "\t\t}",
778            " \t\t\t",
779            "\t}",
780            " \t",
781            " \t",
782            " \t    // _this.view.highlightDropPath(\"\", (Gtk.TreeViewDropPosition)0);",
783            "\tvar w = _this.view.getWidgetAt(x,y);",
784            "\tthis.addHighlight(w, pos); ",
785            "\treturn is_shift ?  Gdk.DragAction.MOVE :  Gdk.DragAction.COPY;\t\t",
786            "}"
787           ]
788          },
789          "string lastDragString" : "\"\"",
790          "xtype" : "DropTarget",
791          "| void addHighlight" : [
792           "(Gtk.Widget? w, string hl) {",
793           "\tif (this.highlightWidget != null) {",
794           "\t\tvar ww  = this.highlightWidget;",
795           "\t\tGLib.debug(\"clear drag from previous highlight\");",
796           "\t\tif (ww.has_css_class(\"drag-below\")) {",
797           "\t\t\t ww.remove_css_class(\"drag-below\");",
798           "\t\t}",
799           "\t\tif (ww.has_css_class(\"drag-above\")) {",
800           "\t\t\t ww.remove_css_class(\"drag-above\");",
801           "\t\t}",
802           "\t\tif (ww.has_css_class(\"drag-over\")) {",
803           "\t\t\t ww.remove_css_class(\"drag-over\");",
804           "\t\t}",
805           "\t}",
806           "\tif (w != null) {",
807           "\t\tGLib.debug(\"add drag=%s to widget\", hl);\t",
808           "\t\tif (!w.has_css_class(\"drag-\" + hl)) {",
809           "\t\t\tw.add_css_class(\"drag-\" + hl);",
810           "\t\t}",
811           "\t}",
812           "\tthis.highlightWidget = w;",
813           "}"
814          ]
815         },
816         {
817          "$ xns" : "Gtk",
818          "* prop" : "model",
819          "id" : "selmodel",
820          "items" : [
821           {
822            "$ xns" : "Gtk",
823            "* ctor" : "this.updateModel(null)",
824            "* prop" : "model",
825            "id" : "model",
826            "xtype" : "TreeListModel",
827            "| Gtk.TreeListModel updateModel" : [
828             "(GLib.ListStore? m) {",
829             "\tthis.el = new Gtk.TreeListModel(",
830             "\t\tm != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..",
831             "\t\tfalse, // passthru",
832             "\t\ttrue, // autexpand",
833             "\t\t(item) => {",
834             "\t\t\treturn ((JsRender.Node)item).childstore;",
835             "\t\t",
836             "\t\t}",
837             "\t);",
838             "\tif (_this.selmodel.el == null) {",
839             "\t\treturn this.el;",
840             "\t}",
841             "\t_this.selmodel.el.set_model(this.el);",
842             "\treturn this.el;",
843             "}"
844            ],
845            "| void deleteSelected" : [
846             "() {",
847             "",
848             "",
849             "\t",
850             "\tvar node = _this.selmodel.getSelectedNode();",
851             "\t",
852             "",
853             "     if (node == null) {",
854             "     \tGLib.debug(\"delete Selected - no node slected?\");",
855             "\t     return;",
856             "     }",
857             "    _this.selmodel.el.unselect_all();",
858             "    ",
859             "    node.remove();",
860             " \tGLib.debug(\"delete Selected - done\");",
861             "    _this.changed();",
862             "/*    ",
863             "    print(\"DELETE SELECTED?\");",
864             "    //_this.view.blockChanges = true;",
865             "    print(\"GET SELECTION?\");",
866             "",
867             "    var s = _this.view.el.get_selection();",
868             "    ",
869             "    print(\"GET  SELECTED?\");",
870             "   Gtk.TreeIter iter;",
871             "    Gtk.TreeModel mod;",
872             "",
873             "    ",
874             "    if (!s.get_selected(out mod, out iter)) {",
875             "        return; // nothing seleted..",
876             "    }",
877             "      ",
878             "",
879             "",
880             "    this.activePath= \"\";      ",
881             "    print(\"GET  vnode value?\");",
882             "",
883             "    GLib.Value value;",
884             "    this.el.get_value(iter, 2, out value);",
885             "    var data = (JsRender.Node)(value.get_object());",
886             "    print(\"removing node from Render\\n\");",
887             "    if (data.parent == null) {",
888             "       _this.main_window.windowstate.file.tree = null;",
889             "    } else {",
890             "        data.remove();",
891             "    }",
892             "    print(\"removing node from Tree\\n\");    ",
893             "    s.unselect_all();",
894             "    this.el.remove(ref iter);",
895             "",
896             "    ",
897             "    ",
898             "    ",
899             "    // ",
900             "    ",
901             "    ",
902             "",
903             "",
904             "    this.activePath= \"\"; // again!?!?      ",
905             "    //this.changed(null,true);",
906             "    ",
907             "    _this.changed();",
908             "    ",
909             "    _this.view.blockChanges = false;",
910             "    */",
911             "}",
912             ""
913            ],
914            "| void loadFile" : [
915             "(JsRender.JsRender f) {",
916             "    //console.dump(f);",
917             "    ",
918             "    _this.drop.highlightWidget = null;",
919             "    ",
920             "    var m = (GLib.ListStore) this.el.model;",
921             "\tm.remove_all();",
922             "    _this.main_window.windowstate.leftTreeNodeSelected(null);",
923             "    // needed???",
924             "    _this.main_window.windowstate.file = f;",
925             "    ",
926             "   ",
927             "    if (f.tree == null) {",
928             "\t    try {",
929             "\t        f.loadItems( );",
930             "        } catch (Error e) {",
931             "    \t\treturn;",
932             "        }",
933             "    }",
934             "    // if it's still null?",
935             "    if (f.tree == null) {",
936             "\t\t_this.main_window.windowstate.showAddObject(_this.view.el, null);",
937             "    ",
938             "        return;",
939             "    }",
940             "  \tm.append(f.tree);",
941             "  \t// expand???",
942             "",
943             "/*",
944             "    if (f.tree.readItems().size < 1) {",
945             "        // single item..",
946             "        ",
947             "        //this.get('/Window.leftvpaned').el.set_position(80);",
948             "        // select first...",
949             "        _this.view.el.set_cursor( ",
950             "            new  Gtk.TreePath.from_string(\"0\"), null, false);",
951             "        ",
952             "        ",
953             "    } else {",
954             "          //this.get('/Window.leftvpaned').el.set_position(200);",
955             "    }",
956             "  */  ",
957             "    ",
958             "    ",
959             "",
960             "    //_this.maincol.el.set_max_width(_this.viewwin.el.get_allocated_width() - 32);",
961             " ",
962             "    _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);",
963             "   ",
964             "    return;",
965             " ",
966             "            ",
967             "}",
968             ""
969            ],
970            "| void selectNode" : [
971             "(JsRender.Node node) ",
972             "{",
973             "\tvar row = -1;",
974             "\tvar s = (Gtk.SingleSelection)_this.view.el.model;",
975             "\tfor (var i = 0; i < s.n_items; i++) {",
976             "\t\t//GLib.debug(\"check node %s\", s.get_item(i).get_type().name());",
977             "\t\tvar lr = (Gtk.TreeListRow)s.get_item(i);",
978             "\t\tGLib.debug(\"check node %s\", lr.get_item().get_type().name());",
979             "\t\tif (((JsRender.Node)lr.get_item()).oid == node.oid) {",
980             "\t\t\trow  = i;",
981             "\t\t\tbreak;",
982             "\t\t}",
983             "\t}",
984             "\tif (row < 0) {",
985             "\t\t// select none?",
986             "\t\tGLib.debug(\"Could not find node\");",
987             "\t\treturn;",
988             "\t}",
989             "\tGLib.debug(\"Select %d\", row);",
990             "\ts.set_selected(row);",
991             "\t_this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);",
992             "\t//_this.node_selected(node);\t\t\t",
993             "\t",
994             "",
995             "}"
996            ]
997           }
998          ],
999          "listeners" : {
1000           "selection_changed" : [
1001            "(position, n_items) => {",
1002            "",
1003            "\t",
1004            "\t\t",
1005            "\t\t//if (!this.button_is_pressed && !this.key_is_pressed) {",
1006            "\t\t\t// then event was started by some other action",
1007            "\t\t\t// which should manually trigger all the events..",
1008            "\t\t//\tprint(\"SKIPPING select - no button or key pressed\\n\");",
1009            "\t\t//\treturn;",
1010            "\t\t//}",
1011            "",
1012            "",
1013            "\t\t if (_this.view.blockChanges) { // probably not needed.. ",
1014            "\t\t\tGLib.debug(\"SKIPPING select - blockchanges set..\");     ",
1015            "\t\t   return  ;",
1016            "\t\t }",
1017            "",
1018            "\t\t  if (!_this.before_node_change( ) ) {",
1019            "\t\t\t _this.view.blockChanges = true;",
1020            "\t\t\t _this.selmodel.el.unselect_all();",
1021            "\t\t\t _this.view.blockChanges = false;",
1022            "\t\t\t ",
1023            "\t\t\t return;",
1024            "\t\t }",
1025            "\t\t if (_this.main_window.windowstate.file == null) {",
1026            "\t   \t\tGLib.debug(\"SKIPPING select windowstate file is not set...\");     ",
1027            "\t\t\treturn;",
1028            "\t\t } ",
1029            "\t\t ",
1030            "\t\t //var render = this.get('/LeftTree').getRenderer();                ",
1031            "\t\tGLib.debug(\"LEFT TREE -> view -> selection changed called\");",
1032            "\t\t",
1033            "\t\t",
1034            "\t\t// -- it appears that the selection is not updated.",
1035            "\t\t // select the node...",
1036            "\t\t //_this.selmodel.el.set_selected(row);",
1037            " ",
1038            "\t\t GLib.debug(\"LEFT TREE -> view -> selection changed TIMEOUT CALLED\");",
1039            "",
1040            "\t    var snode = _this.selmodel.getSelectedNode();",
1041            "\t    if (snode == null) {",
1042            "",
1043            "\t         GLib.debug(\"selected rows < 1\");",
1044            "\t        //??this.model.load( false);",
1045            "\t        _this.node_selected(null);",
1046            "\t        ",
1047            "\t        return   ;",
1048            "\t    }",
1049            "\t ",
1050            "\t    // why dup_?",
1051            "\t    ",
1052            "",
1053            "\t    GLib.debug (\"calling left_tree.node_selected\");",
1054            "\t    _this.node_selected(snode);",
1055            "\t   ",
1056            "\t     ",
1057            "\t    ",
1058            "\t     ",
1059            "\t    // no need to scroll. it's in the view as we clicked on it.",
1060            "\t   // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);",
1061            "\t    ",
1062            "\t    return  ;",
1063            "}",
1064            ""
1065           ]
1066          },
1067          "xtype" : "SingleSelection",
1068          "| JsRender.Node getNodeAt" : [
1069           "(uint row) {",
1070           "",
1071           "   var tr = (Gtk.TreeListRow)this.el.get_item(row);",
1072           "   ",
1073           "   var a = tr.get_item();;   ",
1074           "   GLib.debug(\"get_item (2) = %s\", a.get_type().name());",
1075           "  \t",
1076           "   ",
1077           "   return (JsRender.Node)tr.get_item();",
1078           "\t ",
1079           "}"
1080          ],
1081          "| JsRender.Node? getSelectedNode" : [
1082           "() {",
1083           "  if (this.el.selected_item == null) {",
1084           "\t\treturn null;",
1085           "  }\t\t\t        ",
1086           "   var tr = (Gtk.TreeListRow)this.el.selected_item;",
1087           "   return (JsRender.Node)tr.get_item();",
1088           "\t ",
1089           "}"
1090          ]
1091         },
1092         {
1093          "$ xns" : "Gtk",
1094          "* pack" : "append_column",
1095          "bool expand" : true,
1096          "bool resizable" : true,
1097          "id" : "maincol",
1098          "items" : [
1099           {
1100            "$ xns" : "Gtk",
1101            "* prop" : "factory",
1102            "listeners" : {
1103             "bind" : [
1104              "(listitem) => {",
1105              "\t GLib.debug(\"listitme is is %s\", ((Gtk.ListItem)listitem).get_type().name());",
1106              "\t",
1107              "\t//var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();",
1108              "\tvar expand = (Gtk.TreeExpander)  ((Gtk.ListItem)listitem).get_child();",
1109              "\t ",
1110              "\t ",
1111              "\tvar hbox = (Gtk.Box) expand.child;",
1112              " ",
1113              "\t",
1114              "\tvar img = (Gtk.Image) hbox.get_first_child();",
1115              "\tvar lbl = (Gtk.Label) img.get_next_sibling();",
1116              "\t",
1117              "\tvar lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();",
1118              "\tvar node = (JsRender.Node) lr.get_item();",
1119              "\t",
1120              "   GLib.debug(\"node is %s\", node.get_type().name());",
1121              "// was item (1) in old layout",
1122              "",
1123              "\t",
1124              " ",
1125              " \t /* ",
1126              " \tvar ic = Gtk.IconTheme.get_for_display(_this.el.get_display());",
1127              "    var clsname = node.fqn();",
1128              "    ",
1129              "    var clsb = clsname.split(\".\");",
1130              "    var sub = clsb.length > 1 ? clsb[1].down()  : \"\";",
1131              "     ",
1132              "    var fn = \"/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-\" + sub + \".png\";",
1133              "    try { ",
1134              "    \t ",
1135              "    \t\t ",
1136              "\t\tif (FileUtils.test (fn, FileTest.IS_REGULAR)) {",
1137              "\t\t    img.set_from_file(fn);",
1138              "\t\t \t ",
1139              "\t \t} else {",
1140              "\t \t\timg.set_from_paintable(",
1141              "\t\t\t \tic.lookup_icon (",
1142              "\t\t\t \t\t\"media-playback-stop\", null,  16,1, ",
1143              "\t    \t\t\t Gtk.TextDirection.NONE, 0",
1144              "    \t\t\t)",
1145              "\t\t\t );",
1146              "\t \t}",
1147              " \t} catch (GLib.Error e) {}",
1148              "    */",
1149              "    expand.set_hide_expander( !node.hasChildren() );",
1150              " \texpand.set_list_row(lr);",
1151              " \t",
1152              " \tnode.bind_property(\"iconFilename\",",
1153              "                    img, \"file\",",
1154              "                   GLib.BindingFlags.SYNC_CREATE);",
1155              " \t",
1156              " \tnode.bind_property(\"nodeTitleProp\",",
1157              "                    lbl, \"label\",",
1158              "                   GLib.BindingFlags.SYNC_CREATE);",
1159              " \tnode.bind_property(\"nodeTipProp\",",
1160              "                    lbl, \"tooltip_markup\",",
1161              "                   GLib.BindingFlags.SYNC_CREATE);",
1162              " \t// bind image...",
1163              " \t",
1164              "}",
1165              ""
1166             ],
1167             "setup" : [
1168              "(listitem) => {",
1169              "\t",
1170              "\tvar expand = new Gtk.TreeExpander();",
1171              "\t ",
1172              "\texpand.set_indent_for_depth(true);",
1173              "\texpand.set_indent_for_icon(true);",
1174              "\tvar hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);",
1175              "\tvar icon = new Gtk.Image();",
1176              "\tvar lbl = new Gtk.Label(\"\");",
1177              "\tlbl.use_markup = true;",
1178              "\tlbl.ellipsize = Pango.EllipsizeMode.END;",
1179              "\t",
1180              "\ticon.margin_end = 4;",
1181              " \tlbl.justify = Gtk.Justification.LEFT;",
1182              " \tlbl.xalign = 0;",
1183              "",
1184              "//\tlistitem.activatable = true; ??",
1185              "\t",
1186              "\thbox.append(icon);",
1187              "\thbox.append(lbl);",
1188              "\texpand.set_child(hbox);",
1189              "\t((Gtk.ListItem)listitem).set_child(expand);",
1190              "\t",
1191              "}",
1192              ""
1193             ]
1194            },
1195            "xtype" : "SignalListItemFactory"
1196           }
1197          ],
1198          "title" : "Property",
1199          "xtype" : "ColumnViewColumn"
1200         },
1201         {
1202          "$ xns" : "Gtk",
1203          "* pack" : "append_column",
1204          "int fixed_width" : 25,
1205          "items" : [
1206           {
1207            "$ xns" : "Gtk",
1208            "* prop" : "factory",
1209            "listeners" : {
1210             "bind" : [
1211              "(listitem) => {",
1212              "",
1213              " \tvar img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child(); ",
1214              " \tvar lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();",
1215              "\tvar node = (JsRender.Node) lr.get_item();",
1216              "\t",
1217              "  ",
1218              "    var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());",
1219              "\timg.set_from_paintable(",
1220              "\t \tic.lookup_icon (",
1221              "\t \t\t\"list-add\", null,  16,1, ",
1222              "\t\t\t Gtk.TextDirection.NONE, 0",
1223              "\t\t)",
1224              "\t );",
1225              "\t ",
1226              " \tvar fqn = node.fqn();",
1227              "    var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);",
1228              "",
1229              "\timg.set_visible(cn.size > 0 ? true : false);",
1230              " \t ",
1231              "}",
1232              ""
1233             ],
1234             "setup" : [
1235              "(listitem) => {",
1236              "",
1237              "\t ",
1238              "\tvar icon = new Gtk.Image();",
1239              "\t ",
1240              "\t((Gtk.ListItem)listitem).set_child(icon);",
1241              "}",
1242              ""
1243             ]
1244            },
1245            "xtype" : "SignalListItemFactory"
1246           }
1247          ],
1248          "string title" : "Add",
1249          "xtype" : "ColumnViewColumn"
1250         },
1251         {
1252          "$ xns" : "Gtk",
1253          "id" : "keystate",
1254          "int is_shift" : 0,
1255          "listeners" : {
1256           "key_pressed" : [
1257            "(keyval, keycode, state) => {",
1258            "",
1259            " \tif (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {",
1260            " \t\tthis.is_shift = 1;",
1261            "\t}",
1262            "\treturn true;",
1263            "}",
1264            ""
1265           ],
1266           "key_released" : [
1267            "(keyval, keycode, state) => {",
1268            "\tGLib.debug(\"key release %d, %d, %d\" , (int) keyval, (int)  keycode, state);",
1269            " \tif (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {",
1270            " \t\tthis.is_shift = 0;",
1271            "\t}",
1272            "\t//GLib.debug(\"set state %d , shift = %d\", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);",
1273            "",
1274            "",
1275            " ",
1276            "}"
1277           ]
1278          },
1279          "xtype" : "EventControllerKey"
1280         }
1281        ],
1282        "string name" : "left-tree-view",
1283        "xtype" : "ColumnView",
1284        "| Gtk.Widget? getWidgetAt" : [
1285         "(double x,  double in_y) {",
1286         "/*",
1287         "    \t",
1288         "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
1289         "    \tvar colview = gesture.widget;",
1290         "    \tvar line_no = check_list_widget(colview, x,y);",
1291         "         if (line_no > -1) {",
1292         "    \t\tvar item = colview.model.get_item(line_no);",
1293         "    \t\t ",
1294         "    \t}",
1295         "    \t*/",
1296         "    \tvar y = in_y + _this.viewwin.el.vadjustment.value; ",
1297         "        var  child = this.el.get_first_child(); ",
1298         "    \t//Gtk.Allocation alloc = { 0, 0, 0, 0 };",
1299         "    \tvar line_no = -1; ",
1300         "    \tvar reading_header = true;",
1301         "    \tvar curr_y = 0;",
1302         "    \tvar header_height  = 0;",
1303         "    \tvar h = 0;",
1304         "    \twhile (child != null) {",
1305         "\t\t\t//GLib.debug(\"Got %s\", child.get_type().name());",
1306         "\t        if (reading_header) {",
1307         "\t\t\t\t",
1308         "",
1309         "\t\t\t\tif (child.get_type().name() != \"GtkColumnListView\") {",
1310         "\t\t\t        h += child.get_height();",
1311         "\t\t\t\t\tchild = child.get_next_sibling();",
1312         "\t\t\t\t\tcontinue;",
1313         "\t\t\t\t}",
1314         "\t\t\t\t// should be columnlistview",
1315         "\t\t\t\tchild = child.get_first_child(); ",
1316         "\t\t\t    GLib.debug(\"header height=%d\", h);",
1317         "\t\t\t\theader_height =  h;",
1318         "\t\t\t\t",
1319         "\t\t\t\treading_header = false;",
1320         "\t\t\t\t",
1321         "\t        }",
1322         "\t\t    line_no++;",
1323         "",
1324         "\t\t\tif (y < header_height) {",
1325         "\t\t    \treturn null;",
1326         "\t    \t}",
1327         "",
1328         "\t\t\tvar hh = child.get_height();",
1329         "\t\t\t//GLib.debug(\"got cell xy = %d,%d  w,h= %d,%d\", alloc.x, alloc.y, alloc.width, alloc.height);",
1330         "",
1331         "\t\t    if (y > curr_y && y <= header_height + hh + curr_y ) {",
1332         "\t\t\t    return (Gtk.Widget)child;",
1333         "\t\t    }",
1334         "\t\t    curr_y +=  hh ;",
1335         "",
1336         "\t\t    if (curr_y > y) {",
1337         "\t\t        return null;",
1338         "\t        }",
1339         "\t        child = child.get_next_sibling(); ",
1340         "    \t}",
1341         "        return null;",
1342         "",
1343         " }"
1344        ],
1345        "| Gtk.Widget? getWidgetAtRow" : [
1346         "(uint row) {",
1347         "/*",
1348         "    \t",
1349         "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
1350         "    \tvar colview = gesture.widget;",
1351         "    \tvar line_no = check_list_widget(colview, x,y);",
1352         "         if (line_no > -1) {",
1353         "    \t\tvar item = colview.model.get_item(line_no);",
1354         "    \t\t ",
1355         "    \t}",
1356         "    \t*/",
1357         "\t\t//GLib.debug(\"Get Widget At Row %d\", (int)row);",
1358         "        var  child = this.el.get_first_child(); ",
1359         "    \tvar line_no = -1; ",
1360         "    \tvar reading_header = true;",
1361         "\t ",
1362         "    \twhile (child != null) {",
1363         "\t\t\tGLib.debug(\"Got %s\", child.get_type().name());",
1364         "    \t   ",
1365         "    \t   if (reading_header) {",
1366         "\t\t\t\t",
1367         "",
1368         "\t\t\t\tif (child.get_type().name() != \"GtkColumnListView\") {",
1369         "\t\t\t\t   ",
1370         "\t\t\t\t\tchild = child.get_next_sibling();",
1371         "\t\t\t\t\tcontinue;",
1372         "\t\t\t\t}",
1373         "\t\t\t\t// should be columnlistview",
1374         "\t\t\t\tchild = child.get_first_child(); ",
1375         "\t\t\t ",
1376         "\t\t\t ",
1377         "\t\t\t\t",
1378         "\t\t\t\treading_header = false;",
1379         "\t\t\t\t ",
1380         "\t\t    }",
1381         "\t\t    ",
1382         "\t\t  ",
1383         "    \t    ",
1384         "\t\t    line_no++;",
1385         "\t\t\tif (line_no == row) {",
1386         "\t\t\t\t//GLib.debug(\"Returning widget %s\", child.get_type().name());",
1387         "\t\t\t    return (Gtk.Widget)child;",
1388         "\t\t    }",
1389         "\t        child = child.get_next_sibling(); ",
1390         "    \t}",
1391         "\t\t//GLib.debug(\"Rturning null\");",
1392         "        return null;",
1393         "",
1394         " }"
1395        ],
1396        "| int getColAt" : [
1397         "(double x,  double y) {",
1398         "/*",
1399         "    \t",
1400         "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
1401         "    \t  ",
1402         "    \t*/",
1403         "\t\t//Gtk.Allocation alloc = { 0, 0, 0, 0 };",
1404         "\t\t//GLib.debug(\"Cehck %d, %d\", x,y);",
1405         "        var  child = this.el.get_first_child(); ",
1406         "    \t ",
1407         "    \tvar col = 0;",
1408         "    \tvar offx = 0;",
1409         "    \twhile (child != null) {",
1410         "\t\t\t",
1411         "\t\t\tif (child.get_type().name() == \"GtkColumnViewRowWidget\") {",
1412         "\t\t\t\tchild = child.get_first_child();",
1413         "\t\t\t\tcontinue;",
1414         "\t\t\t}",
1415         "\t\t\t",
1416         "\t\t\t//child.get_allocation(out alloc);",
1417         "\t\t\tif (x <  (child.get_width() + offx)) {",
1418         "\t\t\t\treturn col;",
1419         "\t\t\t}",
1420         "\t\t\treturn 1;",
1421         "\t\t\t//offx += child.get_width();",
1422         "\t\t\t//col++;",
1423         "\t\t\t//child = child.get_next_sibling();",
1424         "\t\t}",
1425         "    \t     ",
1426         "\t\t\t  ",
1427         "        return -1;",
1428         "",
1429         " }"
1430        ],
1431        "| int getRowAt" : [
1432         "(double x,  double in_y, out string pos) {",
1433         "",
1434         "",
1435         "\t ",
1436         "",
1437         "/*",
1438         "    \t",
1439         "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
1440         "    \tvar colview = gesture.widget;",
1441         "    \tvar line_no = check_list_widget(colview, x,y);",
1442         "         if (line_no > -1) {",
1443         "    \t\tvar item = colview.model.get_item(line_no);",
1444         "    \t\t ",
1445         "    \t}",
1446         "    \t*/",
1447         " \t\t ",
1448         " \t\t",
1449         " \t\t//GLib.debug(\"offset = %d  y = %d\", (int) voff, (int) in_y);",
1450         "    \tvar y = in_y + _this.viewwin.el.vadjustment.value; ",
1451         "        var  child = this.el.get_first_child(); ",
1452         "    \t//Gtk.Allocation alloc = { 0, 0, 0, 0 };",
1453         "    \tvar line_no = -1; ",
1454         "    \tvar reading_header = true;",
1455         "    \tvar real_y = 0;",
1456         "    \tvar header_height  = 0;",
1457         "    \tpos = \"none\";",
1458         "    \tvar h = 0;",
1459         "    \twhile (child != null) {",
1460         "\t\t\t//GLib.debug(\"Got %s\", child.get_type().name());",
1461         "    \t    if (reading_header) {",
1462         "\t\t\t\t",
1463         "",
1464         "\t\t\t\tif (child.get_type().name() != \"GtkColumnListView\") {",
1465         "\t\t\t        h += child.get_height();",
1466         "\t\t\t\t\tchild = child.get_next_sibling();",
1467         "\t\t\t\t\tcontinue;",
1468         "\t\t\t\t}",
1469         "\t\t\t\t// should be columnlistview",
1470         "\t\t\t\tchild = child.get_first_child(); ",
1471         "\t\t\t    GLib.debug(\"header height=%d\", h);",
1472         "\t\t\t\theader_height =  h;",
1473         "\t\t\t\t",
1474         "\t\t\t\treading_header = false;",
1475         "\t\t\t\t",
1476         "\t        }",
1477         "\t        ",
1478         "\t\t    if (child.get_type().name() != \"GtkColumnViewRowWidget\") {",
1479         "    \t\t    child = child.get_next_sibling();",
1480         "    \t\t    continue;",
1481         "\t\t    }",
1482         "\t\t    ",
1483         "\t\t \tif (y < header_height) {",
1484         "\t\t    \treturn -1;",
1485         "\t    \t}",
1486         "\t\t    ",
1487         "\t\t    line_no++;",
1488         "\t\t\tvar hh = child.get_height();",
1489         "\t\t\t//child.get_allocation(out alloc);",
1490         "\t\t\t//GLib.debug(\"got cell xy = %d,%d  w,h= %d,%d\", alloc.x, alloc.y, alloc.width, alloc.height);",
1491         "\t\t\t//GLib.debug(\"row %d y= %d %s\", line_no, (int) (header_height + alloc.y),",
1492         "\t\t\t",
1493         "\t\t\t//\tchild.visible ? \"VIS\" : \"hidden\");",
1494         "",
1495         "\t\t    if (y >  (header_height + real_y) && y <= (header_height +  real_y + hh) ) {",
1496         "\t\t    \tif (y > ( header_height + real_y + (hh * 0.8))) {",
1497         "\t\t    \t\tpos = \"below\";",
1498         "\t    \t\t} else if (y > ( header_height + real_y + (hh * 0.2))) {",
1499         "\t    \t\t\tpos = \"over\";",
1500         "    \t\t\t} else {",
1501         "    \t\t\t\tpos = \"above\";",
1502         "\t\t\t\t}",
1503         "\t\t    \t GLib.debug(\"getRowAt return : %d, %s\", line_no, pos);",
1504         "\t\t\t    return line_no;",
1505         "\t\t    }",
1506         " ",
1507         "",
1508         "\t\t    if (real_y + hh > y) {",
1509         "\t\t        return -1;",
1510         "\t        }",
1511         "\t        real_y += hh;",
1512         "\t        child = child.get_next_sibling(); ",
1513         "    \t}",
1514         "        return -1;",
1515         "",
1516         " }"
1517        ]
1518       },
1519       {
1520        "$ xns" : "Gtk",
1521        "* pack" : false,
1522        "id" : "LeftTreeMenu",
1523        "items" : [
1524         {
1525          "$ xns" : "Gtk",
1526          "* prop" : "child",
1527          "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
1528          "int spacing" : 0,
1529          "items" : [
1530           {
1531            "$ xns" : "Gtk",
1532            "label" : "Delete Element",
1533            "listeners" : {
1534             "clicked" : [
1535              " ( ) => {",
1536              "_this.LeftTreeMenu.el.hide();",
1537              " _this.model.deleteSelected();",
1538              "_this.changed();",
1539              "}"
1540             ]
1541            },
1542            "xtype" : "Button"
1543           },
1544           {
1545            "$ xns" : "Gtk",
1546            "label" : "Save as Template",
1547            "listeners" : {
1548             "clicked" : [
1549              "  () => {",
1550              "_this.LeftTreeMenu.el.hide();",
1551              "     DialogSaveTemplate.singleton().showIt(",
1552              "            (Gtk.Window) _this.el.get_root (), ",
1553              "            _this.main_window.windowstate.file.palete(), ",
1554              "            _this.getActiveElement()",
1555              "    );",
1556              "     ",
1557              "    ",
1558              "}"
1559             ]
1560            },
1561            "xtype" : "Button"
1562           },
1563           {
1564            "$ xns" : "Gtk",
1565            "label" : "Save as Module",
1566            "listeners" : {
1567             "clicked" : [
1568              "  () => {",
1569              "    ",
1570              "    _this.LeftTreeMenu.el.hide();",
1571              "    var node = _this.getActiveElement();",
1572              "      ",
1573              "     ",
1574              "     var sm = DialogSaveModule.singleton();",
1575              "     ",
1576              "     ",
1577              "    sm.showIt(",
1578              "            (Gtk.Window) _this.el.get_root (), ",
1579              "            _this.main_window.windowstate.project, ",
1580              "            node",
1581              "     );",
1582              "     /*",
1583              "     gtk4 migration - disabled this part.. probably not used muchanyway",
1584              "     ",
1585              "     ",
1586              "     if (name.length < 1) {",
1587              "            return;",
1588              "  ",
1589              "     }",
1590              "     node.set_prop( new JsRender.NodeProp.special(\"xinclude\", name));",
1591              "     node.items.clear();",
1592              "",
1593              "",
1594              "    var s = _this.view.el.get_selection();",
1595              "    ",
1596              "    print(\"GET  SELECTED?\");",
1597              "    Gtk.TreeIter iter;",
1598              "    Gtk.TreeModel mod;",
1599              "",
1600              "    ",
1601              "    if (!s.get_selected(out mod, out iter)) {",
1602              "        return; // nothing seleted..",
1603              "    }",
1604              "    Gtk.TreeIter citer;",
1605              "    var n_cn = mod.iter_n_children(iter) -1;",
1606              "    for (var i = n_cn; i > -1; i--) {",
1607              "        mod.iter_nth_child(out citer, iter, i);",
1608              "        ",
1609              "",
1610              "        print(\"removing node from Tree\\n\");    ",
1611              "    ",
1612              "        _this.model.el.remove(ref citer);",
1613              "    }",
1614              "    _this.changed();",
1615              "    _this.node_selected(node, \"tree\");",
1616              "     */",
1617              "    ",
1618              "}"
1619             ]
1620            },
1621            "xtype" : "Button"
1622           }
1623          ],
1624          "xtype" : "Box"
1625         }
1626        ],
1627        "xtype" : "Popover"
1628       }
1629      ],
1630      "xtype" : "ScrolledWindow"
1631     }
1632    ],
1633    "xtype" : "Box",
1634    "| JsRender.JsRender getActiveFile" : [
1635     "() {",
1636     "    return this.main_window.windowstate.file;",
1637     "}",
1638     ""
1639    ],
1640    "| JsRender.Node? getActiveElement" : [
1641     " () { // return path to actie node.",
1642     "",
1643     "     ",
1644     "\treturn _this.selmodel.getSelectedNode();",
1645     "    ",
1646     "    ",
1647     "}",
1648     ""
1649    ],
1650    "| void onresize" : [
1651     "() {",
1652     " ",
1653     "\t ",
1654     "\t//GLib.debug(\"Got allocation width of scrolled view %d\", allocation.width );",
1655     "//\t_this.maincol.el.set_max_width( _this.viewwin.el.get_width()  - 32 );",
1656     "}",
1657     "",
1658     ""
1659    ]
1660   }
1661  ],
1662  "name" : "WindowLeftTree"
1663 }