meson.build.o7QLX02
[roobuilder] / src / Builder4 / WindowLeftProps.bjs
index cbe08fc..369cd6a 100644 (file)
 {
- "name" : "WindowLeftProps",
- "parent" : "",
- "title" : "",
- "path" : "/home/alan/gitlive/app.Builder.js/src/Builder4/WindowLeftProps.bjs",
- "permname" : "",
- "modOrder" : "",
  "build_module" : "builder",
+ "gen_extended" : false,
  "items" : [
   {
-   "# bool allow_edit" : false,
-   "| void updateKey" : "(string oldkey,  string type, string key ) {\n\n \n\t\n\t_this.model.el.foreach((mod, path,  iter) => {\n\t\t \n        \n        \t  \n       \n\t\t GLib.Value gvaltype, gval,kvalue;\n\t\t mod.get_value(iter, 1 , out gval); // one is key..\n\t\t\n\t     mod.get_value(iter,0, out gvaltype);\n\t     \n \t     mod.get_value(iter,3, out kvalue);\n\t     \n\t      if (oldkey == ((string)gval) && type == ((string)gvaltype)) {\n\t      \n\t\t  \t  //print(\"update iter type=%s, key=%s value=%s\\n\", type, key,(string) kvalue);\n\t      \n   \t \t      this.updateIter(iter, type, key, (string)kvalue);\n   \t \t      return true;\n\t \t  }\n\t     \n\n\t\treturn false;\n\t});\n\t\n\tthis.changed();\n\n\n}\n",
-   "id" : "LeftProps",
-   "|              void before_edit" : "()\n{\n\n    print(\"before edit - stop editing\\n\");\n    \n  // these do not appear to trigger save...\n    _this.keyrender.el.stop_editing(false);\n    _this.keyrender.el.editable  =false;\n\n    _this.valrender.el.stop_editing(false);\n    _this.valrender.el.editable  =false;    \n    \n    \n// technicall stop the popup editor..\n\n}\n",
-   "|              string keySortFormat" : "(string key) {\n    // listeners first - with 0\n    // specials\n    if (key[0] == '*') {\n        return \"1 \" + key;\n    }\n    // functions\n    \n    var bits = key.split(\" \");\n    \n    if (key[0] == '|') {\n        return \"2 \" + bits[bits.length -1];\n    }\n    // signals\n    if (key[0] == '@') {\n        return \"3 \" + bits[bits.length -1];\n    }\n        \n    // props\n    if (key[0] == '#') {\n        return \"4 \" + bits[bits.length -1];\n    }\n    // the rest..\n    return \"5 \" + bits[bits.length -1];    \n\n\n\n}",
-   "|              void finish_editing" : "() {\n     // \n    this.before_edit();\n}",
-   "|              bool startEditingValue" : "( Gtk.TreePath path) {\n\n     // ONLY return true if editing is allowed - eg. combo..\n\n    print(\"start editing?\\n\");\n    if (!this.stop_editor()) {\n        print(\"stop editor failed\\n\");\n        return false;\n    }\n    \n    Gtk.TreeIter iter;\n\n    var mod = this.model.el;\n    mod.get_iter (out iter, path);\n     \n    /*\n        m.set(iter, \n                0, \"listener\",\n                1, miter.get_key(),\n                2, \"<b>\" + miter.get_key() + \"</b>\",\n                3, miter.get_value()\n            ); \n     \n    */\n    GLib.Value gval;\n    mod.get_value(iter, 3 , out gval);\n    var val = (string)gval;\n\n    mod.get_value(iter, 1 , out gval);\n    var key = (string)gval;\n    \n    \n    string kname, kflag, ktype;\n    this.node.normalize_key(key, out kname, out kflag, out ktype);\n     \n    \n    mod.get_value(iter, 0 , out gval);\n    var type = (string)gval; // listerner or prop..\n    \n   \n    \n    var use_textarea = false;\n\n    //------------ things that require the text editor...\n    \n    if (type == \"listener\") {\n        use_textarea = true;\n    }\n    if (key.length > 0 && key[0] == '|') { // user defined method\n        use_textarea = true;\n    }\n    if (key.length > 0 && key[0] == '$') { // raw string\n        use_textarea = true;\n    }\n    if (key.length > 0 && key == \"* init\") {\n        use_textarea = true;\n    }\n    if (val.length > 40) { // long value...\n        use_textarea = true;\n    }\n    \n    \n    \n    if (use_textarea) {\n        print(\"Call show editor\\n\");\n        GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {\n            this.view.el.get_selection().select_path(path);\n            \n            this.show_editor(file, node, type, key);\n            \n            return false;\n        });\n       \n        \n        return false;\n    }\n    \n     var pal = Palete.factory(this.file.project.xtype);\n    \n    string[] opts;\n    var has_opts = pal.typeOptions(this.node.fqn(), kname, ktype, out opts);\n    \n    \n    \n    // others... - fill in options for true/false?\n    print(\"turn on editing %s \\n\" , mod.get_path(iter).to_string());\n   \n       print (ktype.up());\n    if (has_opts) {\n            print(\"start editing try/false)???\");\n            this.valrender.el.has_entry = false;\n          \n            this.valrender.setOptions(opts);\n            \n            this.valrender.el.has_entry = false;\n            this.valrender.el.editable = true;\n             this.allow_edit  = true;\n             GLib.Timeout.add_full(GLib.Priority.DEFAULT,100 , () => {\n                 this.view.el.set_cursor_on_cell(\n                    path,\n                    this.valcol.el,\n                    this.valrender.el,\n                    true\n                );\n                return false;\n            });\n            return true;\n    }\n                              \n       // see if type is a Enum.\n       \n       \n   \n        \n   \n     opts =  {  };\n    this.valrender.setOptions(opts);\n   \n   GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {\n        \n        // at this point - work out the type...\n        // if its' a combo... then show the options..\n        this.valrender.el.has_entry = true;\n        \n        this.valrender.el.editable = true;            \n    \n        \n        this.allow_edit  = true;\n        \n        \n        \n        \n\n        this.view.el.set_cursor_on_cell(\n            path,\n            this.valcol.el,\n            this.valrender.el,\n            true\n        );\n        return false;\n    });\n    return false;\n}\n",
-   "|              void load" : "(JsRender.JsRender file, JsRender.Node? node) \n{\n    print(\"load leftprops\\n\");\n    this.before_edit();\n    this.node = node;\n    this.file = file;\n    \n \n    this.model.el.clear();\n              \n    //this.get('/RightEditor').el.hide();\n    if (node ==null) {\n        return ;\n    }\n     \n    \n\n    //var provider = this.get('/LeftTree').getPaleteProvider();\n    Gtk.TreeIter iter;\n    \n    //typeof(string),  // 0 key type\n     //typeof(string),  // 1 key\n     //typeof(string),  // 2 key (display)\n     //typeof(string),  // 3 value\n     //typeof(string),  // 4 value (display)\n     //typeof(string),  // 5 both (tooltip)\n    \n    \n    \n    \n    // really need a way to sort the hashmap...\n    var m = this.model.el;\n    \n    var miter = node.listeners.map_iterator();\n    var i = 0;\n    \n    while(miter.next()) {\n        i++;\n        m.append(out iter,null);\n        \n        this.updateIter(iter,  \"listener\", miter.get_key(), miter.get_value());\n        \n         \n     }\n     \n      \n    miter = node.props.map_iterator();\n    \n    \n   while(miter.next()) {\n           i++;\n        m.append(out iter,null);\n         this.updateIter(iter,  \"prop\", miter.get_key(), miter.get_value());\n         \n   }\n   print(\"clear selection\\n\");\n   // clear selection?\n   this.model.el.set_sort_column_id(6,Gtk.SortType.ASCENDING); // sort by real key..\n   \n   this.view.el.get_selection().unselect_all();\n   \n   var pane = _this.main_window.editpane.el;\n    var try_size = (i * 25) + 60; // est. 20px per line + 40px header\n    \n    // max 80%...\n    pane.set_position( \n         ((try_size * 1.0f) /  (pane.max_position * 1.0f))  > 0.8f  ? \n        (int) (pane.max_position * 0.2f) :\n        pane.max_position-try_size);\n    \n   \n}\n",
-   "xtype" : "Box",
-   "|              string keyFormat" : "(string val, string type) {\n    \n    // Glib.markup_escape_text(val);\n\n    if (type == \"listener\") {\n        return \"<span font_weight=\\\"bold\\\" color=\\\"#660000\\\">\" + \n            GLib.Markup.escape_text(val) +\n             \"</span>\";\n    }\n    // property..\n    if (val.length < 1) {\n        return \"<span  color=\\\"#FF0000\\\">--empty--</span>\";\n    }\n    \n    //@ = signal\n    //$ = property with \n    //# - object properties\n    //* = special\n    // all of these... - display value is last element..\n    var ar = val.strip().split(\" \");\n    \n    \n    var dval = GLib.Markup.escape_text(ar[ar.length-1]);\n    \n    \n    \n    \n    switch(val[0]) {\n        case '@': // signal // just bold balck?\n            if (dval[0] == '@') {\n                dval = dval.substring(1);\n            }\n        \n            return @\"<span  font_weight=\\\"bold\\\">@ $dval</span>\";        \n        case '#': // object properties?\n            if (dval[0] == '#') {\n                dval = dval.substring(1);\n            }\n            return @\"<span  font_weight=\\\"bold\\\">$dval</span>\";\n        case '*': // special\n            if (dval[0] == '*') {\n                dval = dval.substring(1);\n            }\n            return @\"<span   color=\\\"#0000CC\\\" font_weight=\\\"bold\\\">$dval</span>\";            \n        case '$':\n            if (dval[0] == '$') {\n                dval = dval.substring(1);\n            }\n            return @\"<span   style=\\\"italic\\\">$dval</span>\";\n       case '|': // user defined methods\n            if (dval[0] == '|') {\n                dval = dval.substring(1);\n            }\n            return @\"<span color=\\\"#008000\\\" font_weight=\\\"bold\\\">$dval</span>\";\n            \n              \n            \n        default:\n            return dval;\n    }\n      \n    \n\n}",
    "# JsRender.JsRender file" : "",
+   "# JsRender.Node node" : "",
+   "# Xcls_MainWindow main_window" : "null",
+   "# bool allow_edit" : false,
+   "$ homogeneous" : "false   ",
+   "$ xns" : "Gtk",
    "@ bool stop_editor" : "()",
-   "@ void show_editor" : "(JsRender.JsRender file, JsRender.Node node, string type, string key)",
    "@ void changed" : "()",
-   "|              void deleteSelected" : " () {\n    \n        Gtk.TreeIter iter;\n        Gtk.TreeModel mod;\n        \n        var s = this.view.el.get_selection();\n        s.get_selected(out mod, out iter);\n             \n              \n        GLib.Value gval;\n        mod.get_value(iter, 0 , out gval);\n        var type = (string)gval;\n        \n        mod.get_value(iter, 1 , out gval);\n        var key = (string)gval;\n        \n        switch(type) {\n            case \"listener\":\n                this.node.listeners.unset(key);\n                break;\n                \n            case \"props\":\n                this.node.props.unset(key);\n                break;\n        }\n        this.load(this.file, this.node);\n        \n        _this.changed();\n}",
-   "$ xns" : "Gtk",
-   "|              void startEditingKey" : "( Gtk.TreePath path) {\n    \n     if (!this.stop_editor()) {\n        return;\n     }\n  \n    // others... - fill in options for true/false?\n    \n       \n    GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {\n        this.allow_edit  = true;\n        this.keyrender.el.editable = true;\n     \n        this.view.el.set_cursor_on_cell(\n            path,\n            this.keycol.el,\n            this.keyrender.el,\n            true\n        );\n               \n        return false;\n    });\n      \n    \n}\n",
    "@ void show_add_props" : "(string type)",
+   "@ void show_editor" : "(JsRender.JsRender file, JsRender.Node node, JsRender.NodeProp prop)",
    "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
-   "$ homogeneous" : "false   ",
-   "# Xcls_MainWindow main_window" : "null",
-   "|              void addProp" : " (string in_type, string key, string value, string value_type) {\n      // info includes key, val, skel, etype..\n      //console.dump(info);\n        //type = info.type.toLowerCase();\n        //var data = this.toJS();\n          \n    var type = in_type == \"signals\" ? \"listener\" : in_type;\n      \n    var fkey = (value_type.length > 0 ? value_type + \" \" : \"\") + key;\n              \n    if (type == \"listener\") {\n        if (this.node.listeners.has_key(key)) {\n            return;\n        }\n        this.node.listeners.set(key,value);\n    } else  {\n    \n        if (this.node.props.has_key(fkey)) {\n            return;\n        }\n        this.node.props.set(fkey,value);\n    }\n            \n      \n    // add a row???\n    this.load(this.file, this.node);\n    \n    \n    \n    /// need to find the row which I've just added..\n    \n    \n    var s = this.view.el.get_selection();\n    s.unselect_all();\n    \n    print(\"trying to find new iter\");\n  \n    this.model.el.foreach((model, path, iter) => {\n        GLib.Value gval;\n    \n        this.model.el.get_value(iter, 0 , out gval);\n        if ((string)gval != type) {\n            print(\"not type: %s = %s\\n\", (string)gval , type);\n            return false;\n        }\n        this.model.el.get_value(iter, 1 , out gval);\n        if ((string)gval != fkey) {\n            print(\"not key: %s = %s\\n\", (string)gval , fkey);\n            return false;\n        }\n        // delay this?\n        GLib.Timeout.add_full(GLib.Priority.DEFAULT,40 , () => {\n        \n            this.startEditingValue(this.model.el.get_path(iter));\n            return false;\n        });\n        //s.select_iter(iter);\n        return true; \n    });\n    \n    \n    \n              \n}\n",
-   "|              void updateIter" : "(Gtk.TreeIter iter,  string type, string key, string kvalue) {\n\n    //print(\"update Iter %s, %s\\n\", key,kvalue);\n    //typeof(string),  // 0 key type\n     //typeof(string),  // 1 key\n     //typeof(string),  // 2 key (display)\n     //typeof(string),  // 3 value\n     //typeof(string),  // 4 value (display)\n     //typeof(string),  // 5 both (tooltip)\n     //typeof(string),  // 6 key (sort)\n    \n    var dl = kvalue.strip().split(\"\\n\");\n\n    var dis_val = dl.length > 1 ? (dl[0].strip()+ \"...\") : dl[0];\n    \n    if (type == \"listener\") {\n     \n       \n        \n        this.model.el.set(iter, \n                0, type,\n            1, key,\n            2, this.keyFormat(key ,type),\n            3, kvalue,\n            4, dis_val,\n            5, \"<tt>\" +  GLib.Markup.escape_text(key + \" \" +kvalue) + \"</tt>\",\n            6,  \"0 \" + key\n        ); \n        return;\n    }\n    \n\n\n    this.model.el.set(iter, \n            0, \"props\",\n            1, key,\n            2,  this.keyFormat(key , \"prop\"),\n            3, kvalue,\n            4, dis_val,\n             5, \"<tt>\" + GLib.Markup.escape_text(key + \" \" + kvalue) + \"</tt>\",\n             6,  this.keySortFormat(key)\n        ); \n}",
-   "# JsRender.Node node" : "",
+   "bool hexpand" : true,
+   "bool loading" : false,
+   "bool vexpand" : true,
+   "id" : "LeftProps",
    "items" : [
     {
-     "* pack" : "pack_start,false,true,0",
-     "xtype" : "Box",
      "$ xns" : "Gtk",
      "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
+     "bool hexpand" : true,
      "items" : [
       {
+       "$ xns" : "Gtk",
+       "int margin_end" : 5,
+       "int margin_start" : 5,
+       "string label" : "Add:",
+       "xtype" : "Label"
+      },
+      {
+       "$ tooltip_text" : "\"Add Property\"",
+       "$ xns" : "Gtk",
+       "bool always_show_image" : true,
+       "bool hexpand" : true,
        "listeners" : {
-        "button_press_event" : "  (self, ev) => {\n    _this.before_edit();\n    \n        \n    var p = _this.AddPropertyPopup;\n    p.el.set_screen(Gdk.Screen.get_default());\n    p.el.show_all();\n     p.el.popup(null, null, null, ev.button, ev.time);\n     return true;\n}"
+        "clicked" : [
+         "  ( ) => {",
+         "    ",
+         "     _this.main_window.windowstate.showProps(",
+         "     \t_this.view.el, ",
+         " \t\tJsRender.NodePropType.PROP",
+         "\t);",
+         "  ",
+         "}"
+        ]
        },
+       "string icon_name" : "format-justify-left",
+       "string label" : "Property",
+       "xtype" : "Button"
+      },
+      {
+       "$ tooltip_text" : "\"Add Event Code\"",
+       "$ xns" : "Gtk",
+       "bool always_show_image" : true,
        "bool hexpand" : true,
-       "xtype" : "Button",
-       "* pack" : "add",
+       "listeners" : {
+        "clicked" : [
+         "  ( ) => {",
+         "    ",
+         " ",
+         "   _this.main_window.windowstate.showProps(",
+         "   \t\t_this.view.el, ",
+         "   \t\tJsRender.NodePropType.LISTENER",
+         "\t);",
+         "",
+         " ",
+         "}"
+        ]
+       },
+       "string icon_name" : "appointment-new",
+       "string label" : "Event",
+       "xtype" : "Button"
+      },
+      {
        "$ xns" : "Gtk",
+       "bool always_show_image" : true,
+       "bool hexpand" : true,
        "items" : [
         {
-         "* pack" : "add",
-         "xtype" : "Box",
          "$ xns" : "Gtk",
-         "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
-         "items" : [
-          {
-           "$ Gtk.Stock stock" : "Gtk.Stock.ADD",
-           "* pack" : "add",
-           "xtype" : "Image",
-           "$ xns" : "Gtk",
-           "$ icon_size" : "Gtk.IconSize.MENU"
-          },
-          {
-           "label" : "Other",
-           "xtype" : "Label",
-           "* pack" : "add",
-           "$ xns" : "Gtk"
-          }
-         ]
-        },
-        {
-         "id" : "AddPropertyPopup",
-         "xtype" : "Menu",
          "* pack" : false,
-         "$ xns" : "Gtk",
+         "bool autohide" : true,
+         "id" : "AddPropertyPopup",
          "items" : [
           {
-           "listeners" : {
-            "activate" : " ()  => {\n    _this.addProp( \"prop\", \"id\", \"\", \"\");\n}"
-           },
-           "label" : "id: _this.{ID} (Vala)",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "Using _this.{ID} will map to this element",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) => {\n\n    _this.addProp( \"prop\", \"pack\",\"add\", \"*\");\n}"
-           },
-           "label" : "pack: Pack method (Vala)",
-           "* pack" : "append",
-           "xtype" : "MenuItem",
-           "tooltip_markup" : "how to pack this element onto parent, (method, 2nd arg, 3rd arg) .. the 1st argument is filled by the element",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) => {\n\n    _this.addProp( \"prop\", \"ctor\",\"\", \"*\");\n}"
-           },
-           "label" : "ctor: Alterative to default contructor (Vala)",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "eg. \n\nnew Clutter.Image.from_file(.....)",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) => {\n\n    _this.addProp( \"prop\",  \"init\", \"{\\n\\n}\\n\", \"*\" );\n}"
-           },
-           "label" : "init: initialziation code (vala)",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "This code is called after the ctor",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : " ()  => {\n    _this.addProp( \"prop\", \"cms-id\", \"\", \"string\");\n}"
-           },
-           "label" : "cms-id: (Roo JS/Pman library)",
-           "* pack" : "append",
-           "xtype" : "MenuItem",
-           "tooltip_markup" : "set the cms-id for this element, when converted to javascript, the html value will be wrapped with Pman.Cms.content({cms-id},{original-html})\n",
-           "$ xns" : "Gtk"
-          },
-          {
-           "* pack" : "add",
-           "xtype" : "SeparatorMenuItem",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  (self) => {\n\n    _this.addProp( \"prop\", \"XXXX\", \"\",\"string\");\n\n}"
-           },
-           "label" : "String",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "Add a user defined string property",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp(\"prop\",  \"XXX\", \"0\", \"int\");\n}"
-           },
-           "label" : "Number",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "Add a user defined number property",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp( \"prop\", \"XXX\", \"true\", \"bool\");\n}"
-           },
-           "label" : "Boolean",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "Add a user defined boolean property",
-           "$ xns" : "Gtk"
-          },
-          {
-           "* pack" : "add",
-           "xtype" : "SeparatorMenuItem",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp(\"prop\",  \"XXXX\", \"function() { }\", \"| function\");\n}"
-           },
-           "label" : "Javascript Function",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "Add a user function boolean property",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp( \"prop\", \"XXXX\", \"() {\\n\\n}\\n\", \"| return_type\");\n}"
-           },
-           "label" : "Vala Method",
-           "* pack" : "append",
-           "xtype" : "MenuItem",
-           "tooltip_markup" : "Add a user function boolean property",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp( \"prop\", \"XXXX\", \"()\", \"@ void\");\n}"
-           },
-           "label" : "Vala Signal",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "Add a vala signal",
-           "$ xns" : "Gtk"
-          },
-          {
-           "* pack" : "add",
-           "xtype" : "SeparatorMenuItem",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp(\"prop\",  \"flexy:if\", \"value_or_condition\", \"string\");\n}"
-           },
-           "label" : "Flexy - If",
-           "xtype" : "MenuItem",
-           "* pack" : "append",
-           "tooltip_markup" : "Add a flexy if (for HTML templates)",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp(\"prop\",  \"flexy:include\", \"name_of_file.html\", \"string\");\n}"
-           },
-           "label" : "Flexy - Include",
-           "* pack" : "append",
-           "xtype" : "MenuItem",
-           "tooltip_markup" : "Add a flexy include (for HTML templates)",
-           "$ xns" : "Gtk"
-          },
-          {
-           "listeners" : {
-            "activate" : "  ( ) =>{\n\n    _this.addProp(\"prop\",  \"flexy:foreach\", \"array,key,value\", \"string\");\n}"
-           },
-           "label" : "Flexy - Foreach",
-           "* pack" : "append",
-           "xtype" : "MenuItem",
-           "tooltip_markup" : "Add a flexy foreach (for HTML templates)",
-           "$ xns" : "Gtk"
+           "$ xns" : "Gtk",
+           "* prop" : "child",
+           "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
+           "int spacing" : 0,
+           "items" : [
+            {
+             "$ xns" : "Gtk",
+             "label" : "id: _this.{ID} (Vala)",
+             "listeners" : {
+              "clicked" : [
+               " ()  => {",
+               " \t_this.AddPropertyPopup.el.hide();",
+               " \t// is this userdef or special??",
+               " \tvar add = new JsRender.NodeProp.prop(\"id\");",
+               " \tif (_this.node.has_prop_key(add)) {",
+               "\t \treturn;",
+               " \t}",
+               " \t",
+               " \t_this.node.add_prop( add );",
+               " \t",
+               " \t_this.view.editProp( add );",
+               " \t",
+               "\t",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Using _this.{ID} will map to this element",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "pack: Pack method (Vala)",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) => {",
+               " ",
+               "",
+               "\t_this.AddPropertyPopup.el.hide();",
+               " \t// is this userdef or special??",
+               " \tvar add = new JsRender.NodeProp.special(\"pack\", \"add\");",
+               " \tif (_this.node.has_prop_key(add)) {",
+               "\t \treturn;",
+               " \t}",
+               " \t",
+               " \t_this.node.add_prop( add );",
+               " \t",
+               " \t_this.view.editProp( add );",
+               " \t",
+               "",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "how to pack this element onto parent, (method, 2nd arg, 3rd arg) .. the 1st argument is filled by the element",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "ctor: Alterative to default contructor (Vala)",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) => {",
+               "   ",
+               " _this.AddPropertyPopup.el.hide();",
+               " \t// is this userdef or special??",
+               " \tvar add = new JsRender.NodeProp.special(\"ctor\");",
+               " \tif (_this.node.has_prop_key(add)) {",
+               "\t \treturn;",
+               " \t}",
+               " \t",
+               " \t_this.node.add_prop( add );",
+               " \t",
+               " \t_this.view.editProp( add );",
+               " \t",
+               "}"
+              ]
+             },
+             "tooltip_markup" : [
+              "eg. ",
+              "",
+              "new Clutter.Image.from_file(.....)"
+             ],
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "init: initialziation code (vala)",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) => {",
+               "    ",
+               " _this.AddPropertyPopup.el.hide();",
+               " \t// is this userdef or special??",
+               " \tvar add =  new JsRender.NodeProp.special(\"init\",\"{\\n\\n}\\n\" ) ;",
+               " \tif (_this.node.has_prop_key(add)) {",
+               "\t \treturn;",
+               " \t}",
+               " \t",
+               " \t_this.node.add_prop( add );",
+               " \t",
+               " \t_this.view.editProp( add );",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "This code is called after the ctor",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "cms-id: (Roo JS/Pman library)",
+             "listeners" : {
+              "clicked" : [
+               " ()  => {",
+               "   ",
+               " _this.AddPropertyPopup.el.hide();",
+               " \t// is this userdef or special??",
+               " \tvar add =   new JsRender.NodeProp.prop(\"cms-id\",\"string\", \"\" ) ;",
+               " \tif (_this.node.has_prop_key(add)) {",
+               "\t \treturn;",
+               " \t}",
+               " \t",
+               " \t_this.node.add_prop( add );",
+               " \t",
+               " \t_this.view.editProp( add );",
+               "    ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : [
+              "set the cms-id for this element, when converted to javascript, the html value will be wrapped with Pman.Cms.content({cms-id},{original-html})",
+              ""
+             ],
+             "xtype" : "Button"
+            },
+            {
+             "$ Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
+             "$ xns" : "Gtk",
+             "xtype" : "Separator"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "String",
+             "listeners" : {
+              "clicked" : [
+               "(self) => {",
+               "     _this.AddPropertyPopup.el.hide();",
+               "\t_this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.prop(\"\", \"string\", \"\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t);",
+               " ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a user defined string property",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Number",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               "      _this.AddPropertyPopup.el.hide();",
+               "      ",
+               "       _this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.prop(\"\", \"int\", \"0\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t);",
+               " ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a user defined number property",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Boolean",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               "  ",
+               "  \t     _this.AddPropertyPopup.el.hide();",
+               "   _this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.prop(\"\", \"bool\", \"true\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t); ",
+               " ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a user defined boolean property",
+             "xtype" : "Button"
+            },
+            {
+             "$ Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
+             "$ xns" : "Gtk",
+             "xtype" : "Separator"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Javascript Function",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               "  _this.AddPropertyPopup.el.hide(); ",
+               "   _this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.jsmethod(\"\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t);",
+               "",
+               " ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a user function boolean property",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Vala Method",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               "_this.AddPropertyPopup.el.hide();",
+               "    _this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.valamethod(\"\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t); ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a user function boolean property",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Vala Signal",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               "  _this.AddPropertyPopup.el.hide();",
+               "  _this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.sig(\"\" ) ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t);    ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a vala signal",
+             "xtype" : "Button"
+            },
+            {
+             "$ Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
+             "$ xns" : "Gtk",
+             "xtype" : "Separator"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Flexy - If",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               " \t_this.AddPropertyPopup.el.hide();",
+               " \t_this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.prop(\"flexy:if\", \"string\", \"value_or_condition\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t);",
+               "",
+               "",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a flexy if (for HTML templates)",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Flexy - Include",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               " \t_this.AddPropertyPopup.el.hide();",
+               " \t_this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.prop(\"flexy:include\", \"string\", \"name_of_file.html\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t);",
+               "",
+               "  ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a flexy include (for HTML templates)",
+             "xtype" : "Button"
+            },
+            {
+             "$ xns" : "Gtk",
+             "label" : "Flexy - Foreach",
+             "listeners" : {
+              "clicked" : [
+               "  ( ) =>{",
+               " \t_this.AddPropertyPopup.el.hide();",
+               " \t_this.view.popover.show(",
+               "\t\t_this.view.el, ",
+               "\t\t_this.node, ",
+               "\t\t new JsRender.NodeProp.prop(\"flexy:if\", \"string\", \"value_or_condition\") ,",
+               "\t\t-1,  ",
+               "\t\ttrue",
+               "\t);",
+               "  ",
+               "}"
+              ]
+             },
+             "tooltip_markup" : "Add a flexy include (for HTML templates)",
+             "xtype" : "Button"
+            }
+           ],
+           "xtype" : "Box"
           }
-         ]
+         ],
+         "xtype" : "Popover"
         }
-       ]
+       ],
+       "listeners" : {
+        "clicked" : [
+         "( ) => {",
+         "  //_this.before_edit();",
+         "  ",
+         "        ",
+         "    var p = _this.AddPropertyPopup;",
+         "    ",
+         " //\tGtk.Allocation rect;",
+         "\t//this.el.get_allocation(out rect);",
+         "\tif (p.el.parent == null) {",
+         "\t\t p.el.set_parent(this.el);",
+         "\t }",
+         "    //p.el.set_pointing_to(rect);",
+         "\tp.el.show();",
+         "\tp.el.set_position(Gtk.PositionType.BOTTOM);",
+         "\tp.el.autohide = true;",
+         "     return;",
+         "",
+         "}",
+         ""
+        ]
+       },
+       "string icon_name" : "list-add",
+       "string label" : "Other",
+       "xtype" : "Button"
       }
-     ]
+     ],
+     "xtype" : "Box"
     },
     {
      "# bool editing" : false,
-     "id" : "EditProps",
-     "* init" : "  {\n  \n   this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);\n}\n",
      "$ shadow_type" : "Gtk.ShadowType.IN",
-     "* pack" : "pack_end,true,true,0",
-     "xtype" : "ScrolledWindow",
      "$ xns" : "Gtk",
+     "* init" : [
+      "  {",
+      "  ",
+      "   this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);",
+      "}",
+      ""
+     ],
+     "bool hexpand" : true,
+     "bool vexpand" : true,
+     "id" : "EditProps",
      "items" : [
       {
-       "listeners" : {
-        "button_press_event" : "  ( ev)  => {\n \n    Gtk.TreeViewColumn col;\n    int cell_x;\n    int cell_y;\n    Gtk.TreePath path;\n    if (!this.el.get_path_at_pos((int)ev.x, (int) ev.y, out path, out col, out cell_x, out cell_y )) {\n        print(\"nothing selected on click\");\n        GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {\n            this.el.get_selection().unselect_all();\n\n            return false;\n        });\n         _this.before_edit();\n        return false; //not on a element.\n    }\n    \n     \n     // double click on name..\n     if (ev.type == Gdk.EventType.2BUTTON_PRESS  && ev.button == 1 && col.title == \"Name\") {    \n        // show popup!.   \n        \n         if (this.popover == null) {\n     \t\t   this.popover = new Xcls_PopoverProperty();\n     \t\t   this.popover.mainwindow = _this.main_window;\n \t\t}\n \t\t\n \n         _this.before_edit();\n          _this.stop_editor();\n\t\t  \n         _this.keyrender.el.stop_editing(false);\n         _this.keyrender.el.editable  =false;\n    \n         _this.valrender.el.stop_editing(false);\n         _this.valrender.el.editable  =false;\n         Gtk.TreeIter iter;\n          var mod = this.el.get_model();\n\t\t  mod.get_iter (out iter, path);\n\t\t  \n       \n\t\tGLib.Value gvaltype, gval;\n\t\tmod.get_value(iter, 1 , out gval); // one is key..\n\t\t\n\t     mod.get_value(iter,0, out gvaltype);\n\n        this.popover.show(this.el, _this.node, (string)gvaltype, (string)gval);\n           \n        //  _this.startEditingKey(path); \n         \n        return false;\n    }\n    \n    \n    \n    \n     // right click.\n     if (ev.type == Gdk.EventType.BUTTON_PRESS  && ev.button == 3) {    \n        // show popup!.   \n        //if (col.title == \"Value\") {\n         //     _this.before_edit();\n         //    return false;\n         //}\n\n        var p = _this.ContextMenu;\n\n        p.el.set_screen(Gdk.Screen.get_default());\n        p.el.show_all();\n        p.el.popup(null, null, null,  ev.button, ev.time);\n        //Seed.print(\"click:\" + res.column.title);\n        // select the \n        GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {\n  \n            this.el.get_selection().select_path(path);\n            return false;\n        });\n         _this.before_edit();\n        return false;\n    }\n    \n     \n    if (col.title != \"Value\") {\n        print(\"col title != Value\");\n        \n        GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {\n            this.el.get_selection().select_path(path);\n            return false;\n        });\n        \n        _this.before_edit();\n          //  XObject.error(\"column is not value?\");\n        return false; // ignore.. - key click.. ??? should we do this??\n    }\n    \n    \n    // if the cell can be edited with a pulldown\n    // then we should return true... - and let the start_editing handle it?\n    \n    \n    \n    \n    \n      \n   //             _this.before_edit(); <<< we really need to stop the other editor..\n     _this.keyrender.el.stop_editing(false);\n    _this.keyrender.el.editable  =false;\n    \n           \n    return _this.startEditingValue(path); // assumes selected row..\n        \n   \n\n              \n   \n}"
-       },
-       "id" : "view",
-       "* init" : "{\n    var selection = this.el.get_selection();\n    selection.set_mode( Gtk.SelectionMode.SINGLE);\n\n\n    var description = new Pango.FontDescription();\n    description.set_size(10000);\n    this.el.override_font(description);\n}\n",
-       "tooltip_column" : 5,
-       "xtype" : "TreeView",
        "$ enable_tree_lines" : true,
        "$ headers_visible" : true,
-       "* pack" : "add",
        "$ xns" : "Gtk",
+       "* init" : [
+        "{",
+        " ",
+        "  \tthis.css = new Gtk.CssProvider();",
+        "\t ",
+        "\t\tthis.css.load_from_string(\"",
+        "#leftprops-view { font-size: 12px;}",
+        "\t ",
+        "#leftprops-view  dropdown button { ",
+        "\t\t\tmin-height: 16px;\t\t\t ",
+        "\t\t\toutline-offset : 0;",
+        "\t\t}",
+        "#leftprops-view cell dropdown label  {",
+        " \t\tpadding-top:0px;",
+        "\t\tpadding-bottom:0px;",
+        "}",
+        "#leftprops-view cell   { ",
+        " \t\tpadding-top:2px;",
+        "\t\tpadding-bottom:2px;",
+        "\t\t}",
+        "#leftprops-view cell label,  #leftprops-view cell editablelable {",
+        " \t\tpadding-top:4px;",
+        "\t\tpadding-bottom:4px;",
+        "}\");",
+        " ",
+        "\t\tGtk.StyleContext.add_provider_for_display(",
+        "\t\tthis.el.get_display(),",
+        "\t\tthis.css,",
+        "\t\tGtk.STYLE_PROVIDER_PRIORITY_APPLICATION",
+        "\t);",
+        "\t\t",
+        "   ",
+        "}",
+        ""
+       ],
+       "* pack" : "set_child",
+       "Gtk.CssProvider css" : "",
        "Xcls_PopoverProperty popover" : "null",
+       "bool hexpand" : true,
+       "bool show_row_separators" : true,
+       "bool single_click_activate" : false,
+       "bool vexpand" : true,
+       "id" : "view",
        "items" : [
         {
-         "id" : "model",
-         "$ changed" : "function(str, doRefresh) {\n    if (!this.activePath) {\n        return;\n    }\n    var iter = new Gtk.TreeIter();\n    this.el.get_iter(iter, new Gtk.TreePath.from_string(this.activePath));\n    \n    this.el.set_value(iter, 1, '' +str);\n    this.el.set_value(iter, 3, '' + this.toShort(str));\n    var type = this.getIterValue(iter, 4);\n\n    this.el.set_value(iter, 5, type + ' : ' + str);\n    // update the tree...  \n\n    this.get('/LeftTree.model').changed(this.toJS(), doRefresh); \n}\n",
-         "* pack" : "set_model",
-         "xtype" : "TreeStore",
-         "$ columns" : "     typeof(string),  // 0 key type\n     typeof(string),  // 1 key\n     typeof(string),  // 2 key (display)\n     typeof(string),  // 3 value\n     typeof(string),   // 4 value (display)\n     typeof(string),   // 5 both (tooltip)     \n     typeof(string)   // 6 key (for sorting)\n",
-         "n_columns" : 7,
          "$ xns" : "Gtk",
-         "$ toShort" : "function(str) {\n    var a = typeof(str) == 'string' ? str.split(\"\\n\") : [];\n        return a.length > 1 ? a[0] + '....' : '' + str;\n}\n"
+         "* pack" : false,
+         "id" : "deletemenu",
+         "items" : [
+          {
+           "$ xns" : "Gtk",
+           "* prop" : "child",
+           "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
+           "int spacing" : 0,
+           "items" : [
+            {
+             "$ xns" : "Gtk",
+             "listeners" : {
+              "clicked" : [
+               "( ) => {",
+               "\t",
+               "",
+               "\tvar n = (JsRender.NodeProp) _this.selmodel.el.selected_item;",
+               "",
+               "\t_this.deletemenu.el.hide();",
+               "\t_this.node.remove_prop(n);",
+               "}",
+               ""
+              ]
+             },
+             "string label" : "Delete",
+             "xtype" : "Button"
+            }
+           ],
+           "xtype" : "Box"
+          }
+         ],
+         "xtype" : "Popover"
+        },
+        {
+         "$ xns" : "Gtk",
+         "listeners" : {
+          "pressed" : [
+           "(n_press, in_x, in_y) => {",
+           "",
+           "\tGLib.debug(\"Prssed %d\", (int)  this.el.get_current_button());",
+           "\t",
+           "\tvar col = _this.view.getColAt(in_x, in_y);",
+           "\tif (col != 0) {",
+           "\t\treturn;",
+           "\t}",
+           "\tstring pos;",
+           "\tvar row = _this.view.getRowAt(in_x, in_y, out pos);",
+           "\t",
+           "\tif (row < 0) {",
+           "\t\treturn;",
+           "",
+           "\t}",
+           "\tGLib.debug(\"hit row %d\", row);",
+           "\tvar prop = _this.selmodel.getPropAt(row);",
+           "\t_this.selmodel.selectProp(prop);",
+           "",
+           "\t//var point_at = _this.view.getWidgetAtRow(row);",
+           "\t",
+           "\t    \t// need to shift down, as ev.y does not inclucde header apparently..",
+           "     \t// or popover might be trying to do a central?",
+           "//\t _this.view.editPropertyDetails(prop, (int) in_y + 12); ",
+           "  \t _this.stop_editor();",
+           "     _this.view.popover.show(",
+           " \t\t\t_this.view.el, ",
+           " \t\t\t_this.node, prop,  ",
+           "\t\t (int)in_y);",
+           "    ",
+           "    ",
+           "      ",
+           "}",
+           ""
+          ]
+         },
+         "xtype" : "GestureClick"
+        },
+        {
+         "$ xns" : "Gtk",
+         "listeners" : {
+          "pressed" : [
+           "(n_press, in_x, in_y) => {",
+           "",
+           "\t",
+           "\t ",
+           "\tstring pos;",
+           "\tvar row = _this.view.getRowAt(in_x, in_y, out pos);",
+           "\t",
+           "\tif (row < 0) {",
+           "\t\treturn;",
+           "",
+           "\t}",
+           "\t",
+           "\t_this.stop_editor();",
+           "\tGLib.debug(\"hit row %d\", row);",
+           "\tvar prop = _this.selmodel.getPropAt(row);",
+           "\t_this.selmodel.selectProp(prop);",
+           "\t",
+           "\t",
+           "\t",
+           "\tGLib.debug(\"Prssed %d\", (int)  this.el.get_current_button());",
+           "\t//_this.deletemenu.el.set_parent(_this.view.el);",
+           "\tif (_this.deletemenu.el.parent == null) {",
+           "\t\t_this.deletemenu.el.set_parent(_this.main_window.el);",
+           "\t}",
+           "\t",
+           "\t",
+           "\t ",
+           "\t_this.deletemenu.el.set_offset(",
+           "\t\t\t(int)in_x  - _this.view.el.get_width() ,",
+           "\t\t\t(int)in_y - _this.view.el.get_height()",
+           "\t\t);",
+           "\t_this.deletemenu.el.set_position(Gtk.PositionType.BOTTOM); ",
+           "    _this.deletemenu.el.popup();",
+           "      ",
+           "}",
+           ""
+          ]
+         },
+         "uint button" : 3,
+         "xtype" : "GestureClick"
         },
         {
-         "id" : "keycol",
-         "* init" : " this.el.add_attribute(_this.keyrender.el , \"markup\", 2 );\n this.el.add_attribute(_this.keyrender.el , \"text\", 1 );\n  ",
-         "title" : "Name",
-         "* pack" : "append_column",
-         "xtype" : "TreeViewColumn",
-         "$ resizable" : true,
          "$ xns" : "Gtk",
+         "* prop" : "model",
+         "bool can_unselect" : true,
+         "id" : "selmodel",
          "items" : [
           {
-           "listeners" : {
-            "editing_started" : "(  editable, path) => {\n\n     Gtk.TreeIter  iter;\n    _this.model.el.get_iter(out iter, new Gtk.TreePath.from_string(path));\n    GLib.Value gval;\n                  \n\n\n     //   this.get('/LeftPanel.model').activePath  = path;\n    _this.model.el.get_value(iter,1, out gval);\n        var val = (string)gval;\n                 \n        ((Gtk.Entry)editable).set_text(val);                 \n}",
-            "edited" : "  (path, newtext) => {\n        print(\"Keyrender  - signal:edited\\n\");\n    \n    this.el.editable = false;\n  \n \n\n        Gtk.TreeIter  iter;\n        _this.model.el.get_iter(out iter, new Gtk.TreePath.from_string(path));\n        GLib.Value gval;\n        \n         _this.model.el.get_value(iter,1, out gval);\n        var oldval = (string)gval;\n        \n         _this.model.el.get_value(iter,0, out gval);\n        var ktype = (string)gval;\n       \n        _this.model.el.set_value(iter, 1, newtext);\n        \n        if (oldval == newtext) {\n            return;\n        }\n        \n        \n        print(\"ktype: %s\\n\",ktype);\n        switch(ktype) {\n            case \"listener\":\n                var ov = _this.node.listeners.get(oldval);\n                _this.node.listeners.set(newtext, ov);\n                _this.node.listeners.unset(oldval);\n                \n                _this.updateIter(iter,  ktype, newtext, ov);\n                \n                break;\n            case \"props\":\n                var ov = _this.node.props.get(oldval);\n                _this.node.props.set(newtext, ov);\n                _this.node.props.unset(oldval);\n                _this.updateIter(iter,  ktype, newtext, ov);\n                break;\n         }\n         _this.changed();\n          \n}"
-           },
-           "id" : "keyrender",
-           "* pack" : "pack_start,false",
-           "xtype" : "CellRendererText",
-           "$ xns" : "Gtk"
+           "$ xns" : "GLib",
+           "* ctor" : "new GLib.ListStore(typeof(JsRender.NodeProp))",
+           "* prop" : "model",
+           "id" : "model",
+           "xtype" : "ListStore"
           }
+         ],
+         "xtype" : "SingleSelection",
+         "| JsRender.NodeProp getPropAt" : [
+          "(uint row) {",
+          "",
+          "\treturn   (JsRender.NodeProp) this.el.get_item(row);",
+          "",
+          "\t ",
+          "}"
+         ],
+         "| void selectProp" : [
+          "(JsRender.NodeProp prop) {",
+          "\tfor (var i = 0 ; i < this.el.n_items; i++) {",
+          "\t\tvar r = (JsRender.NodeProp)this.el.get_item(i);",
+          "\t\tif (r.equals(prop)) {",
+          "\t\t\tthis.el.selected = i;",
+          "\t\t\treturn;",
+          "\t\t}",
+          "\t}",
+          "\t ",
+          "}"
+         ],
+         "| void startEditing" : [
+          "(JsRender.NodeProp prop) {",
+          "\t// should we call select?? - caller does int (from windowstate)",
+          "\t",
+          "}"
          ]
         },
         {
-         "id" : "valcol",
-         "* init" : "{\n\t\n\t//     typeof(string),  // 0 key type\n    // typeof(string),  // 1 key\n    // typeof(string),  // 2 key (display)\n    // typeof(string),  // 3 value\n    // typeof(string)   // 4 value (display)\n\n\t\n\tthis.el.add_attribute(_this.valrender.el , \"text\", 4 );\n\t//this.el.add_attribute(_this.valrender.el , \"sensitive\", 4 );\n\t//this.el.add_attribute(this.items[0].el , 'editable', 3 );\n          // this.el.set_cell_data_func(cell, age_cell_data_func, NULL, NULL);\n\n //\tthis.get('/LeftPanel').editableColumn= this;\n}\n",
-         "* pack" : "append_column",
-         "title" : "Value",
-         "xtype" : "TreeViewColumn",
-         "$ resizable" : true,
          "$ xns" : "Gtk",
+         "* pack" : "append_column",
+         "bool expand" : true,
+         "bool resizable" : true,
+         "id" : "keycol",
          "items" : [
           {
+           "$ xns" : "Gtk",
+           "* prop" : "factory",
            "listeners" : {
-            "editing_started" : "( editable, path) => {\n    //_this.editing = true;\n    print(\"editing started called\\n\");\n    if (!_this.allow_edit) {\n       \n         print(\"val - editing_Started\\n\");\n        this.el.editable = false; // make sure it's not editor...\n   \n         \n        return;\n    }\n     _this.allow_edit =false;\n    \n   \n     if (  this.el.has_entry ) {\n   \n         Gtk.TreeIter  iter;\n        _this.model.el.get_iter(out iter, new Gtk.TreePath.from_string(path));\n        GLib.Value gval;\n                      \n\n      \n         //   this.get('/LeftPanel.model').activePath  = path;\n       _this.model.el.get_value(iter,3, out gval);\n    \n\n        var val = (string)gval;\n        var combo =        (Gtk.ComboBox)editable;\n\n        var entry =  (Gtk.Entry) combo.get_child();        \n        entry.set_text(val);\n    }\n   \n}",
-            "edited" : "  (path, newtext) => {\n    print(\"Valrender  - signal:edited\\n\");\n  \n        this.el.editable = false;\n/*  \n m.set(iter, \n                0, \"listener\",\n                1, miter.get_key(),\n                2, \"<b>\" + miter.get_key() + \"</b>\",\n                3, miter.get_value(),\n                4, display_value(short);\n            ); \n\n  */      \n\n        Gtk.TreeIter  iter;\n        _this.model.el.get_iter(out iter, new Gtk.TreePath.from_string(path));\n        GLib.Value gval;\n        \n         _this.model.el.get_value(iter,0, out gval);\n        var ktype = (string)gval;\n        \n        \n         _this.model.el.get_value(iter,3, out gval);\n        var oldval = (string)gval;\n        \n         _this.model.el.get_value(iter,1, out gval);\n        var key = (string)gval;\n        \n         \n        \n        switch(ktype) {\n            case \"listener\":\n                _this.node.listeners.set(key, newtext);\n                _this.updateIter(iter,ktype,key,newtext);\n                break;\n            case \"props\":\n                _this.node.props.set(key,newtext);\n                _this.updateIter(iter,ktype, key,newtext);                \n                break;\n         }\n//         _this.load(_this.file,_this.node);\n         _this.changed();\n          \n}"
+            "bind" : [
+             "(listitem) => {",
+             " var lb = (Gtk.Label) ((Gtk.ListItem)listitem).get_child();",
+             " var item = (JsRender.NodeProp) ((Gtk.ListItem)listitem).get_item();",
+             "",
+             "",
+             "item.bind_property(\"to_display_name_prop\",",
+             "                    lb, \"label\",",
+             "                   GLib.BindingFlags.SYNC_CREATE);",
+             "item.bind_property(\"to_tooltip_name_prop\",",
+             "                    lb, \"tooltip_markup\",",
+             "                   GLib.BindingFlags.SYNC_CREATE);",
+             "// was item (1) in old layout",
+             " ",
+             "",
+             "}",
+             ""
+            ],
+            "setup" : [
+             "(listitem) => {",
+             "\tvar lbl = new Gtk.Label(\"\");",
+             " \t((Gtk.ListItem)listitem).set_child(lbl);",
+             " \tlbl.justify = Gtk.Justification.LEFT;",
+             " \tlbl.xalign = 1;",
+             " \tlbl.use_markup = true;",
+             "\tlbl.ellipsize = Pango.EllipsizeMode.START;",
+             " \t/*lbl.changed.connect(() => {",
+             "\t\t// notify and save the changed value...",
+             "\t \t//var prop = (JsRender.NodeProp) ((Gtk.ListItem)listitem.get_item());",
+             "         ",
+             "        //prop.val = lbl.text;",
+             "        //_this.updateIter(iter,prop);",
+             "        _this.changed();",
+             "\t});",
+             "\t*/",
+             "\t((Gtk.ListItem)listitem).activatable = true;",
+             "}",
+             ""
+            ]
            },
-           "id" : "valrender",
-           "xtype" : "CellRendererCombo",
-           "* pack" : "pack_start,true",
-           "$ editable" : false,
-           "$ has_entry" : true,
-           "$ xns" : "Gtk",
-           "|              void setOptions" : "(string[] ar) {\n      var m = _this.valrendermodel.el;\n        m.clear();\n     Gtk.TreeIter iret;\n    for (var i =0; i < ar.length; i++) {\n            m.append(out iret);\n            m.set_value(iret, 0, ar[i]);\n    }\n\n}",
-           "text_column" : 0,
-           "items" : [
-            {
-             "id" : "valrendermodel",
-             "xtype" : "ListStore",
-             "* pack" : false,
-             "$ columns" : "typeof(string)",
-             "n_columns" : 1,
-             "$ xns" : "Gtk",
-             "* prop" : "model"
-            }
-           ]
+           "xtype" : "SignalListItemFactory"
           }
-         ]
+         ],
+         "title" : "Property",
+         "xtype" : "ColumnViewColumn"
         },
         {
-         "id" : "ContextMenu",
-         "* pack" : false,
-         "xtype" : "Menu",
          "$ xns" : "Gtk",
+         "* pack" : "append_column",
+         "bool expand" : true,
+         "bool resizable" : true,
+         "id" : "valcol",
          "items" : [
           {
+           "$ xns" : "Gtk",
+           "* prop" : "factory",
+           "bool is_setting" : false,
            "listeners" : {
-            "activate" : "  ( )  =>{\n  \n    var s = _this.view.el.get_selection();\n    Gtk.TreeIter iter;\n    Gtk.TreeModel mod;\n    s.get_selected (out  mod, out  iter);\n    \n      if (_this.view.popover == null) {\n     \t\t   _this.view.popover = new Xcls_PopoverProperty();\n     \t\t   _this.view.popover.mainwindow = _this.main_window;\n \t\t}\n \t\t\n \n      _this.before_edit();\n      _this.stop_editor();\n\t  \n     _this.keyrender.el.stop_editing(false);\n     _this.keyrender.el.editable  =false;\n\n     _this.valrender.el.stop_editing(false);\n     _this.valrender.el.editable  =false;\n     \n      \n\tGLib.Value gvaltype, gval;\n\tmod.get_value(iter, 1 , out gval); // one is key..\n\t\n     mod.get_value(iter,0, out gvaltype);\n\n\t_this.view.popover.show(_this.view.el, _this.node, (string)gvaltype, (string)gval);\n       \n    \n    \n   // _this.startEditingKey(model.get_path(iter));\n}"
+            "bind" : [
+             "(listitem) => {",
+             "\t this.is_setting = true;",
+             "",
+             "",
+             "\tvar bx = (Gtk.Box) ((Gtk.ListItem)listitem).get_child();",
+             " ",
+             "\t",
+             "\t",
+             "\t",
+             "\tvar elbl = (Gtk.EditableLabel)bx.get_first_child();",
+             "\tvar lbl = (Gtk.Label) elbl.get_next_sibling();",
+             "\tvar cb  = (Gtk.DropDown) lbl.get_next_sibling();",
+             "\t// decide if it's a combo or editable text..",
+             "\tvar model = (Gtk.StringList) cb.model;",
+             " ",
+             "\telbl.hide();",
+             "\tlbl.hide();",
+             "\tcb.hide();",
+             "\t",
+             "\tvar prop = (JsRender.NodeProp) ((Gtk.ListItem)listitem).get_item();",
+             "\t//GLib.debug(\"prop = %s\", prop.get_type().name());",
+             "\t//GLib.debug(\"prop.val = %s\", prop.val);",
+             "\t//GLib.debug(\"prop.key = %s\", prop.to_display_name());",
+             "\t ",
+             "    var use_textarea =  prop.useTextArea();",
+             "    ",
+             "    ",
+             "    var pal = _this.file.project.palete;",
+             "        ",
+             "    string[] opts;",
+             "    var has_opts = pal.typeOptions(_this.node.fqn(), prop.name, prop.rtype, out opts);",
+             "    ",
+             "    if (!has_opts && prop.ptype == JsRender.NodePropType.RAW) {",
+             "      \tuse_textarea = true;",
+             "    }",
+             "    ",
+             "    ",
+             "    if (use_textarea) {",
+             "    \tprop.bind_property(\"val_short\",",
+             "                    lbl, \"label\",",
+             "                   GLib.BindingFlags.SYNC_CREATE);",
+             "        prop.bind_property(\"val_tooltip\",",
+             "                    lbl, \"tooltip_markup\",",
+             "                   GLib.BindingFlags.SYNC_CREATE);",
+             "        lbl.show();",
+             "\t\tthis.is_setting = false;        ",
+             "        return;",
+             "    \t",
+             "    }",
+             "     ",
+             "        ",
+             "        ",
+             "        ",
+             "        ",
+             "        // others... - fill in options for true/false?",
+             "           // GLib.debug (ktype.up());",
+             "    if (has_opts) {",
+             "\t",
+             "\t\twhile(model.get_n_items() > 0) {",
+             "\t\t\tmodel.remove(0);",
+             "\t\t}",
+             "\t\tcb.show();",
+             " \t\t// can not remove - hopefully always empty.",
+             "\t\tvar sel = -1;",
+             "\t\tfor(var i = 0; i < opts.length; i ++) {",
+             "\t\t\tmodel.append( opts[i]);",
+             "\t\t\t// not sure this is a great idea... ",
+             "\t\t\tif (opts[i].down() == prop.val.down()) {",
+             "\t\t\t\tsel = i;",
+             "\t\t\t}",
+             "\t\t}",
+             "\t\tGLib.debug(\"Set selected item to %d\", sel);",
+             "\t\tcb.set_selected(sel > -1 ? sel : Gtk.INVALID_LIST_POSITION); ",
+             "\t\tthis.is_setting = false;        ",
+             "\t\treturn ;",
+             "    }",
+             "                                  ",
+             "\t// see if type is a Enum.",
+             "\t// triggers a changed event",
+             " ",
+             "\telbl.set_text(prop.val);",
+             " ",
+             "\telbl.show();",
+             "\tthis.is_setting = false;        \t\t ",
+             "\t",
+             "\t",
+             "\t",
+             " ",
+             "",
+             "}",
+             ""
+            ],
+            "setup" : [
+             "(listitem) => {",
+             "\tvar hb = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);",
+             "\tvar elbl  = new Gtk.EditableLabel(\"\");",
+             "\telbl.hexpand = true;",
+             "\thb.append(elbl);",
+             "\tvar lbl  = new Gtk.Label(\"\");",
+             "\thb.append(lbl);",
+             "\tlbl.hexpand = true;",
+             "\tlbl.use_markup = true;",
+             "\tlbl.xalign =0;",
+             "\tlbl.ellipsize = Pango.EllipsizeMode.END;",
+             "\tvar cb = new Gtk.DropDown(new Gtk.StringList({}), null);",
+             "\tcb.hexpand = true;",
+             " ",
+             "\thb.append(cb);",
+             "\t((Gtk.ListItem)listitem).set_child(hb);",
+             "\t ",
+             "\t var ef = new Gtk.EventControllerFocus();",
+             "\t ef.enter.connect(() => {",
+             " \t\t _this.stop_editor();",
+             " \t\t  var prop = (JsRender.NodeProp)((Gtk.ListItem)listitem).get_item();",
+             "\t\t _this.selmodel.selectProp(prop);\t\t",
+             "\t });",
+             "\t elbl.add_controller(ef);",
+             "\t ",
+             "\t ",
+             "\t  // dropdown??? - stop editing, and highliht node",
+             "\t var tb = (Gtk.ToggleButton) cb.get_first_child();",
+             "\t tb.clicked.connect(() => {",
+             "\t\t var prop = (JsRender.NodeProp)((Gtk.ListItem)listitem).get_item();",
+             "\t\t\t",
+             "\t \t _this.stop_editor();",
+             "\t \t _this.selmodel.selectProp(prop);",
+             "\t \t ",
+             "\t });",
+             " \telbl.changed.connect(() => {",
+             "\t\t// notify and save the changed value...",
+             "\t \t",
+             "        //_this.updateIter(iter,prop);",
+             "        // this should happen automatically",
+             "        ",
+             "        if (!_this.loading && !this.is_setting) {",
+             "\t\t    var prop = (JsRender.NodeProp)((Gtk.ListItem)listitem).get_item();",
+             "\t\t\t ",
+             "\t\t ",
+             "\t\t    prop.val = elbl.text;",
+             "        \t GLib.debug(\"calling changed\");",
+             "\t        _this.changed();",
+             "\t       ",
+             "        }",
+             "        ",
+             "\t});",
+             "\t",
+             "\t",
+             "\tcb.notify[\"selected\"].connect(() => {",
+             "\t\t// dropdown selection changed.",
+             "\t\t",
+             "\t\t",
+             "\t\t",
+             "        //_this.updateIter(iter,prop);",
+             "        if (!_this.loading && !this.is_setting) {",
+             "\t\t    var prop = (JsRender.NodeProp)((Gtk.ListItem)listitem).get_item();",
+             "\t\t    var model = (Gtk.StringList)cb.model;",
+             "\t\t    prop.val =   model.get_string(cb.selected);",
+             "\t\t    GLib.debug(\"property set to %s\", prop.val);",
+             "        \tGLib.debug(\"calling changed\");",
+             "\t        _this.changed();",
+             "\t         ",
+             "        }",
+             "        ",
+             "\t\t",
+             "\t});",
+             "\tvar gc = new Gtk.GestureClick();",
+             "\tlbl.add_controller(gc);",
+             "\tgc.pressed.connect(() => {",
+             "\t \tvar prop = (JsRender.NodeProp)((Gtk.ListItem)listitem).get_item();",
+             "\t\t _this.stop_editor();",
+             "\t    _this.show_editor(_this.file, prop.parent, prop);",
+             "\t});",
+             "\t  ",
+             "\t",
+             "\t",
+             "}",
+             ""
+            ]
            },
-           "label" : "Edit (double click)",
-           "* pack" : "append",
-           "xtype" : "MenuItem",
-           "$ xns" : "Gtk"
-          },
-          {
-           "* pack" : "append",
-           "xtype" : "SeparatorMenuItem",
-           "$ xns" : "Gtk"
-          },
+           "xtype" : "SignalListItemFactory"
+          }
+         ],
+         "title" : "Value",
+         "xtype" : "ColumnViewColumn"
+        },
+        {
+         "$ xns" : "Gtk",
+         "* pack" : false,
+         "id" : "ContextMenu",
+         "items" : [
           {
-           "listeners" : {
-            "activate" : "  ( )  =>{\n\t_this.deleteSelected();\n}"
-           },
-           "label" : "Delete",
-           "* pack" : "append",
-           "xtype" : "MenuItem",
-           "$ xns" : "Gtk"
+           "$ xns" : "Gtk",
+           "* prop" : "child",
+           "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
+           "int spacing" : 0,
+           "items" : [
+            {
+             "$ xns" : "Gtk",
+             "label" : "Delete",
+             "listeners" : {
+              "activate" : [
+               "  ( )  =>{",
+               "\t_this.deleteSelected();",
+               "\t",
+               "}"
+              ]
+             },
+             "xtype" : "Button"
+            }
+           ],
+           "xtype" : "Box"
           }
-         ]
+         ],
+         "xtype" : "Popover"
         }
+       ],
+       "string name" : "leftprops-view",
+       "xtype" : "ColumnView",
+       "| Gtk.Widget? getWidgetAtRow" : [
+        "(uint row) {",
+        "/*",
+        "    \t",
+        "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
+        "    \tvar colview = gesture.widget;",
+        "    \tvar line_no = check_list_widget(colview, x,y);",
+        "         if (line_no > -1) {",
+        "    \t\tvar item = colview.model.get_item(line_no);",
+        "    \t\t ",
+        "    \t}",
+        "    \t*/",
+        "\t\tGLib.debug(\"Get Widget At Row %d\", (int)row);",
+        "        var  child = this.el.get_first_child(); ",
+        "    \tvar line_no = -1; ",
+        "    \tvar reading_header = true;",
+        "",
+        "    \twhile (child != null) {",
+        "\t\t\tGLib.debug(\"Got %s\", child.get_type().name());",
+        "    \t    if (reading_header) {",
+        "\t\t\t ",
+        "\t\t\t   ",
+        "\t\t\t\tif (child.get_type().name() != \"GtkColumnListView\") {",
+        "\t\t\t\t\tchild = child.get_next_sibling();",
+        "\t\t\t\t\tcontinue;",
+        "\t\t\t\t}",
+        "\t\t\t\tchild = child.get_first_child(); ",
+        "\t\t\t\treading_header = false;",
+        "\t        }",
+        "\t\t    if (child.get_type().name() != \"GtkColumnViewRowWidget\") {",
+        "    \t\t    child = child.get_next_sibling();",
+        "    \t\t    continue;",
+        "\t\t    }",
+        "\t\t    line_no++;",
+        "\t\t\tif (line_no == row) {",
+        "\t\t\t\tGLib.debug(\"Returning widget %s\", child.get_type().name());",
+        "\t\t\t    return (Gtk.Widget)child;",
+        "\t\t    }",
+        "\t        child = child.get_next_sibling(); ",
+        "    \t}",
+        "\t\tGLib.debug(\"Rturning null\");",
+        "        return null;",
+        "",
+        " }"
+       ],
+       "| int getColAt" : [
+        "(double x,  double y) {",
+        "/*",
+        "    \t",
+        "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
+        "    \t  ",
+        "    \t*/",
+        "\t\t//Gtk.Allocation alloc = { 0, 0, 0, 0 };",
+        "        var  child = this.el.get_first_child(); ",
+        "    \t ",
+        "    \tvar col = 0;",
+        "    \tvar offx = 0;",
+        "    \twhile (child != null) {",
+        "\t\t\tGLib.debug(\"Got %s\", child.get_type().name());",
+        "\t\t\t",
+        "\t\t\tif (child.get_type().name() == \"GtkColumnViewRowWidget\") {",
+        "\t\t\t\tchild = child.get_first_child();",
+        "\t\t\t\tcontinue;",
+        "\t\t\t}",
+        "\t\t\t",
+        "\t\t\t//child.get_allocation(out alloc);",
+        "\t\t\tif (x <  (child.get_width() + offx)) {",
+        "\t\t\t\treturn col;",
+        "\t\t\t}",
+        "\t\t\toffx += child.get_width();",
+        "\t\t\tcol++;",
+        "\t\t\tchild = child.get_next_sibling();",
+        "\t\t}",
+        "    \t     ",
+        "\t\t\t  ",
+        "        return -1;",
+        "",
+        " }"
+       ],
+       "| int getRowAt" : [
+        "(double x,  double in_y, out string pos) {",
+        "",
+        "",
+        "\t ",
+        "",
+        "/*",
+        "    \t",
+        "from    \thttps://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465",
+        "    \tvar colview = gesture.widget;",
+        "    \tvar line_no = check_list_widget(colview, x,y);",
+        "         if (line_no > -1) {",
+        "    \t\tvar item = colview.model.get_item(line_no);",
+        "    \t\t ",
+        "    \t}",
+        "    \t*/",
+        " \t\t ",
+        " \t\t",
+        " \t\t//GLib.debug(\"offset = %d  y = %d\", (int) voff, (int) in_y);",
+        "    \tvar y = in_y + _this.EditProps.el.vadjustment.value; ",
+        "        var  child = this.el.get_first_child(); ",
+        "    \t//Gtk.Allocation alloc = { 0, 0, 0, 0 };",
+        "    \tvar line_no = -1; ",
+        "    \tvar reading_header = true;",
+        "    \tvar real_y = 0;",
+        "    \tvar header_height  = 0;",
+        "    \tpos = \"none\";",
+        "    \tvar h = 0;",
+        "    \twhile (child != null) {",
+        "\t\t\t//GLib.debug(\"Got %s\", child.get_type().name());",
+        "    \t    if (reading_header) {",
+        "\t\t\t\t",
+        "",
+        "\t\t\t\tif (child.get_type().name() != \"GtkColumnListView\") {",
+        "\t\t\t        h += child.get_height();",
+        "\t\t\t\t\tchild = child.get_next_sibling();",
+        "\t\t\t\t\tcontinue;",
+        "\t\t\t\t}",
+        "\t\t\t\t// should be columnlistview",
+        "\t\t\t\tchild = child.get_first_child(); ",
+        "\t\t\t    GLib.debug(\"header height=%d\", h);",
+        "\t\t\t\theader_height =  h;",
+        "\t\t\t\t",
+        "\t\t\t\treading_header = false;",
+        "\t\t\t\t",
+        "\t        }",
+        "\t        ",
+        "\t\t    if (child.get_type().name() != \"GtkColumnViewRowWidget\") {",
+        "    \t\t    child = child.get_next_sibling();",
+        "    \t\t    continue;",
+        "\t\t    }",
+        "\t\t    ",
+        "\t\t \tif (y < header_height) {",
+        "\t\t    \treturn -1;",
+        "\t    \t}",
+        "\t\t    ",
+        "\t\t    line_no++;",
+        "\t\t\tvar hh = child.get_height();",
+        "\t\t\t//child.get_allocation(out alloc);",
+        "\t\t\t//GLib.debug(\"got cell xy = %d,%d  w,h= %d,%d\", alloc.x, alloc.y, alloc.width, alloc.height);",
+        "\t\t\t//GLib.debug(\"row %d y= %d %s\", line_no, (int) (header_height + alloc.y),",
+        "\t\t\t",
+        "\t\t\t//\tchild.visible ? \"VIS\" : \"hidden\");",
+        "",
+        "\t\t    if (y >  (header_height + real_y) && y <= (header_height +  real_y + hh) ) {",
+        "\t\t    \tif (y > ( header_height + real_y + (hh * 0.8))) {",
+        "\t\t    \t\tpos = \"below\";",
+        "\t    \t\t} else if (y > ( header_height + real_y + (hh * 0.2))) {",
+        "\t    \t\t\tpos = \"over\";",
+        "    \t\t\t} else {",
+        "    \t\t\t\tpos = \"above\";",
+        "\t\t\t\t}",
+        "\t\t    \t GLib.debug(\"getRowAt return : %d, %s\", line_no, pos);",
+        "\t\t\t    return line_no;",
+        "\t\t    }",
+        " ",
+        "",
+        "\t\t    if (real_y + hh > y) {",
+        "\t\t        return -1;",
+        "\t        }",
+        "\t        real_y += hh;",
+        "\t        child = child.get_next_sibling(); ",
+        "    \t}",
+        "        return -1;",
+        "",
+        " }"
+       ],
+       "| void editProp" : [
+        "(JsRender.NodeProp prop) ",
+        "{",
+        "\tvar sm = _this.selmodel.el;",
+        " ",
+        "\t\tvar sr = -1;",
+        "\t\tGLib.debug(\"finding node\");",
+        "\t\t_this.selmodel.selectProp(prop);",
+        "\t\t",
+        "\t\tfor (var i = 0 ; i < sm.n_items; i++) {",
+        "\t\t\tvar r = (JsRender.NodeProp)sm.get_item(i);",
+        "\t\t\tif (r.equals(prop)) {",
+        "\t\t\t\tsr = i;",
+        "\t\t\t\tbreak;",
+        "\t\t\t}",
+        "\t\t}",
+        "\t\tif (sr < 0) {",
+        "\t\t\tGLib.debug(\"finding node - cant find it\");",
+        "\t\t\t \t\t",
+        "\t\t\treturn;",
+        "\t\t}",
+        "\t\tvar r = this.getWidgetAtRow(sr);",
+        "\t\tGLib.debug(\"r = %s\", r.get_type().name());",
+        "\t\tvar ca = r.get_first_child();",
+        "\t\tvar ll = (Gtk.Label)ca.get_first_child();",
+        "\t\tvar cb = ca.get_next_sibling();",
+        "\t\tvar b = cb.get_first_child();",
+        "\t\tvar e = (Gtk.EditableLabel) b.get_first_child();",
+        "\t\tvar l = (Gtk.Label) e.get_next_sibling();",
+        "\t\tvar d = (Gtk.DropDown) l.get_next_sibling();",
+        "\t\t",
+        "\t\tGLib.debug(\"row key = %s\", ll.label);",
+        "\t\tif (e.get_visible()) {",
+        "\t\t\t_this.stop_editor();",
+        "\t\t\te.start_editing();",
+        "\t\t\t//GLib.Timeout.add_once(500, () => {",
+        "\t\t\t//\tvar st = (Gtk.Stack) e.get_first_child();",
+        "\t\t\t//\tvar ed = (Gtk.Entry) st.get_visible_child();",
+        "\t\t\t//\ted.grab_focus_without_selecting();",
+        "\t\t\t//});",
+        "\t\t\treturn;",
+        "\t\t}",
+        "\t\tif (d.get_visible()) {",
+        "\t\t\t_this.stop_editor();",
+        "\t\t\td.activate();",
+        "\t\t\treturn;",
+        "\t\t}",
+        "\t\tif (l.get_visible()) {",
+        "\t\t \t_this.stop_editor();",
+        "\t    \t_this.show_editor(_this.file, prop.parent, prop);",
+        "\t\t",
+        "\t\t}",
+        "\t\t",
+        "\t\t",
+        "\t\t",
+        "\t\t//gtkcolumnviewrowwidget",
+        "\t\t  // cell widet",
+        "\t\t  // cell widget",
+        "\t\t  \t// box",
+        "\t\t  \t\t// entry / label / dropdown",
+        "\t\t \t\t",
+        "\t\t ",
+        "}"
        ]
       }
-     ]
+     ],
+     "xtype" : "ScrolledWindow"
     }
+   ],
+   "xtype" : "Box",
+   "| string keyFormat" : [
+    "(string val, string type) {",
+    "    ",
+    "    // Glib.markup_escape_text(val);",
+    "",
+    "    if (type == \"listener\") {",
+    "        return \"<span font_weight=\\\"bold\\\" color=\\\"#660000\\\">\" + ",
+    "            GLib.Markup.escape_text(val) +",
+    "             \"</span>\";",
+    "    }",
+    "    // property..",
+    "    if (val.length < 1) {",
+    "        return \"<span  color=\\\"#FF0000\\\">--empty--</span>\";",
+    "    }",
+    "    ",
+    "    //@ = signal",
+    "    //$ = property with ",
+    "    //# - object properties",
+    "    //* = special",
+    "    // all of these... - display value is last element..",
+    "    var ar = val.strip().split(\" \");",
+    "    ",
+    "    ",
+    "    var dval = GLib.Markup.escape_text(ar[ar.length-1]);",
+    "    ",
+    "    ",
+    "    ",
+    "    ",
+    "    switch(val[0]) {",
+    "        case '@': // signal // just bold balck?",
+    "            if (dval[0] == '@') {",
+    "                dval = dval.substring(1);",
+    "            }",
+    "        ",
+    "            return @\"<span  font_weight=\\\"bold\\\">@ $dval</span>\";        ",
+    "        case '#': // object properties?",
+    "            if (dval[0] == '#') {",
+    "                dval = dval.substring(1);",
+    "            }",
+    "            return @\"<span  font_weight=\\\"bold\\\">$dval</span>\";",
+    "        case '*': // special",
+    "            if (dval[0] == '*') {",
+    "                dval = dval.substring(1);",
+    "            }",
+    "            return @\"<span   color=\\\"#0000CC\\\" font_weight=\\\"bold\\\">$dval</span>\";            ",
+    "        case '$':",
+    "            if (dval[0] == '$') {",
+    "                dval = dval.substring(1);",
+    "            }",
+    "            return @\"<span   style=\\\"italic\\\">$dval</span>\";",
+    "       case '|': // user defined methods",
+    "            if (dval[0] == '|') {",
+    "                dval = dval.substring(1);",
+    "            }",
+    "            return @\"<span color=\\\"#008000\\\" font_weight=\\\"bold\\\">$dval</span>\";",
+    "            ",
+    "              ",
+    "            ",
+    "        default:",
+    "            return dval;",
+    "    }",
+    "      ",
+    "    ",
+    "",
+    "}"
+   ],
+   "| string keySortFormat" : [
+    "(string key) {",
+    "    // listeners first - with 0",
+    "    // specials",
+    "    if (key[0] == '*') {",
+    "        return \"1 \" + key;",
+    "    }",
+    "    // functions",
+    "    ",
+    "    var bits = key.split(\" \");",
+    "    ",
+    "    if (key[0] == '|') {",
+    "        return \"2 \" + bits[bits.length -1];",
+    "    }",
+    "    // signals",
+    "    if (key[0] == '@') {",
+    "        return \"3 \" + bits[bits.length -1];",
+    "    }",
+    "        ",
+    "    // props",
+    "    if (key[0] == '#') {",
+    "        return \"4 \" + bits[bits.length -1];",
+    "    }",
+    "    // the rest..",
+    "    return \"5 \" + bits[bits.length -1];    ",
+    "",
+    "",
+    "",
+    "}"
+   ],
+   "| void a_addProp" : [
+    " (JsRender.NodeProp prop) {",
+    "      // info includes key, val, skel, etype..",
+    "      //console.dump(info);",
+    "        //type = info.type.toLowerCase();",
+    "        //var data = this.toJS();",
+    "          ",
+    "              ",
+    "    if (prop.ptype == JsRender.NodePropType.LISTENER) {",
+    "        if (this.node.listeners.has_key(prop.name)) {",
+    "            return;",
+    "        }",
+    "        this.node.listeners.set(prop.name,prop);",
+    "    } else  {",
+    "         assert(this.node != null);",
+    "         assert(this.node.props != null);",
+    "        if (this.node.props.has_key(prop.to_index_key())) {",
+    "            return;",
+    "        }",
+    "        this.node.props.set(prop.to_index_key(),prop);",
+    "    }",
+    "            ",
+    "      ",
+    "    // add a row???",
+    "    this.load(this.file, this.node);",
+    "    ",
+    "    ",
+    "     ",
+    "    ",
+    "    GLib.debug(\"trying to find new iter\");",
+    " ",
+    "    ",
+    "              ",
+    "}",
+    ""
+   ],
+   "| void deleteSelected" : [
+    " () {",
+    "    ",
+    "\t\treturn;",
+    "\t\t/*",
+    "        ",
+    "        Gtk.TreeIter iter;",
+    "        Gtk.TreeModel mod;",
+    "        ",
+    "        var s = this.view.el.get_selection();",
+    "        s.get_selected(out mod, out iter);",
+    "             ",
+    "              ",
+    "        GLib.Value gval;",
+    "        mod.get_value(iter, 0 , out gval);",
+    "        var prop = (JsRender.NodeProp)gval;",
+    "        if (prop == null) {",
+    "\t        this.load(this.file, this.node);    ",
+    "        \treturn;",
+    "    \t}",
+    "    \t// stop editor after fetching property - otherwise prop is null.",
+    "        this.stop_editor();",
+    "        ",
+    "            \t",
+    "        switch(prop.ptype) {",
+    "            case JsRender.NodePropType.LISTENER:",
+    "                this.node.listeners.unset(prop.to_index_key());",
+    "                break;",
+    "                ",
+    "            default:",
+    "                this.node.props.unset(prop.to_index_key());",
+    "                break;",
+    "        }",
+    "        this.load(this.file, this.node);",
+    "        ",
+    "        _this.changed();",
+    "        */",
+    "}"
+   ],
+   "| void load" : [
+    "(JsRender.JsRender file, JsRender.Node? node) ",
+    "{",
+    "\t// not sure when to initialize this - we should do it on setting main window really.    ",
+    "\t",
+    "\tthis.loading = true;",
+    "    if (this.view.popover == null) {",
+    " \t\t   this.view.popover = new Xcls_PopoverProperty();",
+    " \t\t   this.view.popover.mainwindow = _this.main_window;",
+    "\t}",
+    "    ",
+    "    ",
+    "    if (this.node != null) {",
+    "    \tthis.node.dupeProps(); // ensures removeall will not do somethign silly",
+    "    \t",
+    "    }",
+    "    ",
+    "    GLib.debug(\"load leftprops\\n\");",
+    "",
+    "    this.node = node;",
+    "    this.file = file;",
+    "    ",
+    " ",
+    "    this.model.el.remove_all();",
+    "              ",
+    "    //this.get('/RightEditor').el.hide();",
+    "    if (node ==null) {",
+    "        return ;",
+    "    }",
+    "    node.loadProps(this.model.el); ",
+    "    ",
+    "    ",
+    "   //GLib.debug(\"clear selection\\n\");",
+    "   ",
+    "   \tthis.loading = false;",
+    "    this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);",
+    "   // clear selection?",
+    "  //this.model.el.set_sort_column_id(4,Gtk.SortType.ASCENDING); // sort by real key..",
+    "   ",
+    "   // this.view.el.get_selection().unselect_all();",
+    "   ",
+    "  // _this.keycol.el.set_max_width(_this.EditProps.el.get_allocated_width()/ 2);",
+    "  // _this.valcol.el.set_max_width(_this.EditProps.el.get_allocated_width()/ 2);",
+    "   ",
+    "}",
+    ""
    ]
   }
- ]
+ ],
+ "name" : "WindowLeftProps"
 }
\ No newline at end of file