fix #7989 - add support for extended classes (partial)
authorAlan Knowles <alan@roojs.com>
Sat, 27 Jan 2024 23:06:44 +0000 (07:06 +0800)
committerAlan Knowles <alan@roojs.com>
Sat, 27 Jan 2024 23:06:44 +0000 (07:06 +0800)
16 files changed:
.roobuilder.jcfg
ChangeLog
INSTALL [deleted file]
debian/changelog
meson.build
src/Application.vala
src/Builder4/About.bjs
src/Builder4/DialogConfirm.bjs
src/JsRender/Gtk.vala
src/JsRender/Node.vala
src/JsRender/NodeToVala.vala
src/JsRender/NodeToValaExtended.vala [new file with mode: 0644]
src/JsRender/NodeToValaWrapped.vala [new file with mode: 0644]
src/JsRender/NodeWriter.vala [new file with mode: 0644]
src/Palete/GirObject.vala
src/Palete/VapiParser.vala

index 1dc1f9c..235a9ea 100644 (file)
                 "src/Palete/LanguageClientJavascript.vala",
                 "src/Lsp.vala",
                 "src/Palete/LanguageClientDummy.vala",
-                "src/Palete/ValaCompileRequest.vala"
+                "src/Palete/ValaCompileRequest.vala",
+                "src/JsRender/NodeWriter.vala",
+                "src/JsRender/NodeToValaExtended.vala",
+                "src/JsRender/NodeToValaWrapped.vala"
             ]
         }
     ],
index e69de29..4ae3111 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -0,0 +1 @@
+See debian/changelog
\ No newline at end of file
diff --git a/INSTALL b/INSTALL
deleted file mode 100644 (file)
index e82fd21..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,368 +0,0 @@
-Installation Instructions
-*************************
-
-   Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free
-Software Foundation, Inc.
-
-   Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved.  This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
-   Briefly, the shell command './configure && make && make install'
-should configure, build, and install this package.  The following
-more-detailed instructions are generic; see the 'README' file for
-instructions specific to this package.  Some packages provide this
-'INSTALL' file but do not implement all of the features documented
-below.  The lack of an optional feature in a given package is not
-necessarily a bug.  More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
-   The 'configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a 'Makefile' in each directory of the package.
-It may also create one or more '.h' files containing system-dependent
-definitions.  Finally, it creates a shell script 'config.status' that
-you can run in the future to recreate the current configuration, and a
-file 'config.log' containing compiler output (useful mainly for
-debugging 'configure').
-
-   It can also use an optional file (typically called 'config.cache' and
-enabled with '--cache-file=config.cache' or simply '-C') that saves the
-results of its tests to speed up reconfiguring.  Caching is disabled by
-default to prevent problems with accidental use of stale cache files.
-
-   If you need to do unusual things to compile the package, please try
-to figure out how 'configure' could check whether to do them, and mail
-diffs or instructions to the address given in the 'README' so they can
-be considered for the next release.  If you are using the cache, and at
-some point 'config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
-   The file 'configure.ac' (or 'configure.in') is used to create
-'configure' by a program called 'autoconf'.  You need 'configure.ac' if
-you want to change it or regenerate 'configure' using a newer version of
-'autoconf'.
-
-   The simplest way to compile this package is:
-
-  1. 'cd' to the directory containing the package's source code and type
-     './configure' to configure the package for your system.
-
-     Running 'configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
-
-  2. Type 'make' to compile the package.
-
-  3. Optionally, type 'make check' to run any self-tests that come with
-     the package, generally using the just-built uninstalled binaries.
-
-  4. Type 'make install' to install the programs and any data files and
-     documentation.  When installing into a prefix owned by root, it is
-     recommended that the package be configured and built as a regular
-     user, and only the 'make install' phase executed with root
-     privileges.
-
-  5. Optionally, type 'make installcheck' to repeat any self-tests, but
-     this time using the binaries in their final installed location.
-     This target does not install anything.  Running this target as a
-     regular user, particularly if the prior 'make install' required
-     root privileges, verifies that the installation completed
-     correctly.
-
-  6. You can remove the program binaries and object files from the
-     source code directory by typing 'make clean'.  To also remove the
-     files that 'configure' created (so you can compile the package for
-     a different kind of computer), type 'make distclean'.  There is
-     also a 'make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-  7. Often, you can also type 'make uninstall' to remove the installed
-     files again.  In practice, not all packages have tested that
-     uninstallation works correctly, even though it is required by the
-     GNU Coding Standards.
-
-  8. Some packages, particularly those that use Automake, provide 'make
-     distcheck', which can by used by developers to test that all other
-     targets like 'make install' and 'make uninstall' work correctly.
-     This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the 'configure' script does not know about.  Run './configure --help'
-for details on some of the pertinent environment variables.
-
-   You can give 'configure' initial values for configuration parameters
-by setting variables in the command line or in the environment.  Here is
-an example:
-
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
-   *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU 'make'.  'cd' to the
-directory where you want the object files and executables to go and run
-the 'configure' script.  'configure' automatically checks for the source
-code in the directory that 'configure' is in and in '..'.  This is known
-as a "VPATH" build.
-
-   With a non-GNU 'make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use 'make distclean' before
-reconfiguring for another architecture.
-
-   On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple '-arch' options to the
-compiler but only a single '-arch' option to the preprocessor.  Like
-this:
-
-     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CPP="gcc -E" CXXCPP="g++ -E"
-
-   This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the 'lipo' tool if you have problems.
-
-Installation Names
-==================
-
-   By default, 'make install' installs the package's commands under
-'/usr/local/bin', include files under '/usr/local/include', etc.  You
-can specify an installation prefix other than '/usr/local' by giving
-'configure' the option '--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like '--bindir=DIR' to specify different values for particular
-kinds of files.  Run 'configure --help' for a list of the directories
-you can set and what kinds of files go in them.  In general, the default
-for these options is expressed in terms of '${prefix}', so that
-specifying just '--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
-   The most portable way to affect installation locations is to pass the
-correct locations to 'configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-'make install' command line to change installation locations without
-having to reconfigure or recompile.
-
-   The first method involves providing an override variable for each
-affected directory.  For example, 'make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-'${prefix}'.  Any directories that were specified during 'configure',
-but not in terms of '${prefix}', must each be overridden at install time
-for the entire installation to be relocated.  The approach of makefile
-variable overrides for each directory variable is required by the GNU
-Coding Standards, and ideally causes no recompilation.  However, some
-platforms have known limitations with the semantics of shared libraries
-that end up requiring recompilation when using this method, particularly
-noticeable in packages that use GNU Libtool.
-
-   The second method involves providing the 'DESTDIR' variable.  For
-example, 'make install DESTDIR=/alternate/directory' will prepend
-'/alternate/directory' before all installation names.  The approach of
-'DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters.  On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of '${prefix}'
-at 'configure' time.
-
-Optional Features
-=================
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving 'configure' the
-option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
-
-   Some packages pay attention to '--enable-FEATURE' options to
-'configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to '--with-PACKAGE' options, where PACKAGE
-is something like 'gnu-as' or 'x' (for the X Window System).  The
-'README' should mention any '--enable-' and '--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, 'configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the 'configure' options '--x-includes=DIR' and
-'--x-libraries=DIR' to specify their locations.
-
-   Some packages offer the ability to configure how verbose the
-execution of 'make' will be.  For these packages, running './configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with 'make V=1'; while running './configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with 'make V=0'.
-
-Particular systems
-==================
-
-   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU CC
-is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
-     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
-   HP-UX 'make' updates targets which have the same timestamps as their
-prerequisites, which makes it generally unusable when shipped generated
-files such as 'configure' are involved.  Use GNU 'make' instead.
-
-   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its '<wchar.h>' header file.  The option '-nodtk' can be used as a
-workaround.  If GNU CC is not installed, it is therefore recommended to
-try
-
-     ./configure CC="cc"
-
-and if that doesn't work, try
-
-     ./configure CC="cc -nodtk"
-
-   On Solaris, don't put '/usr/ucb' early in your 'PATH'.  This
-directory contains several dysfunctional programs; working variants of
-these programs are available in '/usr/bin'.  So, if you need '/usr/ucb'
-in your 'PATH', put it _after_ '/usr/bin'.
-
-   On Haiku, software installed for all users goes in '/boot/common',
-not '/usr/local'.  It is recommended to use the following options:
-
-     ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
-   There may be some features 'configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on.  Usually, assuming the package is built to be run on the
-_same_ architectures, 'configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-'--build=TYPE' option.  TYPE can either be a short name for the system
-type, such as 'sun4', or a canonical name which has the form:
-
-     CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
-     OS
-     KERNEL-OS
-
-   See the file 'config.sub' for the possible values of each field.  If
-'config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
-   If you are _building_ compiler tools for cross-compiling, you should
-use the option '--target=TYPE' to select the type of system they will
-produce code for.
-
-   If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with '--host=TYPE'.
-
-Sharing Defaults
-================
-
-   If you want to set default values for 'configure' scripts to share,
-you can create a site shell script called 'config.site' that gives
-default values for variables like 'CC', 'cache_file', and 'prefix'.
-'configure' looks for 'PREFIX/share/config.site' if it exists, then
-'PREFIX/etc/config.site' if it exists.  Or, you can set the
-'CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all 'configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-   Variables not defined in a site shell script can be set in the
-environment passed to 'configure'.  However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost.  In order to avoid this problem, you should set
-them in the 'configure' command line, using 'VAR=value'.  For example:
-
-     ./configure CC=/usr/local2/bin/gcc
-
-causes the specified 'gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
-Autoconf limitation.  Until the limitation is lifted, you can use this
-workaround:
-
-     CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-'configure' Invocation
-======================
-
-   'configure' recognizes the following options to control how it
-operates.
-
-'--help'
-'-h'
-     Print a summary of all of the options to 'configure', and exit.
-
-'--help=short'
-'--help=recursive'
-     Print a summary of the options unique to this package's
-     'configure', and exit.  The 'short' variant lists options used only
-     in the top level, while the 'recursive' variant lists options also
-     present in any nested packages.
-
-'--version'
-'-V'
-     Print the version of Autoconf used to generate the 'configure'
-     script, and exit.
-
-'--cache-file=FILE'
-     Enable the cache: use and save the results of the tests in FILE,
-     traditionally 'config.cache'.  FILE defaults to '/dev/null' to
-     disable caching.
-
-'--config-cache'
-'-C'
-     Alias for '--cache-file=config.cache'.
-
-'--quiet'
-'--silent'
-'-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to '/dev/null' (any error
-     messages will still be shown).
-
-'--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     'configure' can determine that directory automatically.
-
-'--prefix=DIR'
-     Use DIR as the installation prefix.  *note Installation Names:: for
-     more details, including other options available for fine-tuning the
-     installation locations.
-
-'--no-create'
-'-n'
-     Run the configure checks, but stop before creating any output
-     files.
-
-'configure' also accepts some other, not widely useful, options.  Run
-'configure --help' for more details.
index 2d2bb10..dc0d47b 100644 (file)
@@ -1,4 +1,16 @@
-roobuilder (5.0.1) UNRELEASED; urgency=medium
+roobuilder (5.0.2) UNRELEASED; urgency=medium
+
+  * support for extended writing of vala applications
+    Note that sealed classes causes issues, so generally it's not usable yet
+  * Move Node (drag with shift pressed)
+  * Changing property key now triggers save/language server
+  * Fixed sending wrong 'save' to language-server (caused LS to crash)
+  * Fixed Gtkview - uses toSource(), rather than file.get_contents()
+
+ -- Alan Knowles <alan@touchbox>  Sun, 28 Jan 2024 06:54:56 +0800
+
+roobuilder (5.0.1) unstable; urgency=medium
 
   * switch to meson build
   * remove internal compiler - switch to call meson/ninja
index 2d108d5..6e12dd8 100644 (file)
@@ -145,6 +145,9 @@ roobuilder_src = files([
    'src/Lsp.vala',
    'src/Palete/LanguageClientDummy.vala',
    'src/Palete/ValaCompileRequest.vala',
+   'src/JsRender/NodeWriter.vala',
+   'src/JsRender/NodeToValaExtended.vala',
+   'src/JsRender/NodeToValaWrapped.vala',
 ])
 
 roobuilder = executable('roobuilder',
index 84260d5..a6638b8 100644 (file)
                                                var oldfn = file.targetName();
                                                
                                                print("\n\n\n\nFile : %s\n", oldfn);
-                                               //GLib.FileUtils.get_contents(oldfn, out oldstr);
+                                               
                                                                                
                                                var outstr = file.toSourceCode();
+                                               
+                                               /* line number checking
                                                var bad = false;
                                                // check line numbers:
                                                var bits = outstr.split("\n");
                                                var end = bits.length;
                                                for(var i = 0;i < end; i++) {
                                                        print("%i : %s\n", i+1 , bits[i]);
-                                                       if (!bad && bits[i].has_prefix("/*") && !bits[i].has_prefix("/*%d*/".printf(i+1))) {
+                                                       if (!bad && bits[i].has_prefix("/*") && !bits[i].has_prefix(("/*%d*" +"/").printf(i+1))) {
                                                                end = i + 5 > bits.length ? bits.length: (i + 5);
                                                                print ("^^^^ mismatch\null");
                                                                bad = true;
                                                if (bad) {
                                                        GLib.error("got bad file");
                                                }
-                                               /*
+                                               */
+                                               // compare files. 
+                                               string oldstr;
+                                               GLib.FileUtils.get_contents(oldfn, out oldstr);
                                                if (outstr != oldstr) { 
                                                        
                                                        GLib.FileUtils.set_contents("/tmp/" + file.name   + ".out",   outstr);
                                                        print("meld   %s /tmp/%s\n", oldfn,  file.name + ".out");
                                                        //GLib.Process.exit(Posix.EXIT_SUCCESS);                
-                                               }
-*.*                                            */
+                                               }                                               
                                                //print("# Files match %s\n", file.name);
                                        }               
                                } catch (FileError e) {
@@ -797,5 +801,4 @@ flutter-project  -  was try and read flutter data (but desnt work.)
                
 
  
-
\ No newline at end of file
index 8f560d8..9737a50 100644 (file)
@@ -1,6 +1,6 @@
 {
  "build_module" : "builder",
- "gen_extended" : true,
+ "gen_extended" : false,
  "items" : [
   {
    "$ authors" : "{ \"Alan Knowles\" }",
@@ -25,4 +25,4 @@
   }
  ],
  "name" : "About"
-}
\ No newline at end of file
+}
index 551f453..306efab 100644 (file)
@@ -1,6 +1,6 @@
 {
  "build_module" : "builder",
- "gen_extended" : true,
+ "gen_extended" : false,
  "items" : [
   {
    "$ buttons" : "Gtk.ButtonsType.YES_NO",
@@ -41,4 +41,4 @@
   }
  ],
  "name" : "DialogConfirm"
-}
\ No newline at end of file
+}
index caee6c7..2a3451c 100644 (file)
@@ -135,7 +135,9 @@ namespace JsRender {
                                this.tree.loadFromJson(tree_base, int.parse(bjs_version_str));
 
                        }
-                       NodeToVala.mungeFile(this); // force line numbering..
+                       this.gen_extended ? 
+                               NodeToValaExtended.mungeFile(this) :
+                               NodeToValaWrapped.mungeFile(this); // force line numbering..?? should we call toSourceCode???
                        this.loaded = true;
                
                }
@@ -156,8 +158,11 @@ namespace JsRender {
                        GLib.debug("toSource - using Cache");
                        return this.last_source;
                }
-               GLib.debug("toSource - generating");
-                   this.last_source =   NodeToVala.mungeFile(this);
+               GLib.debug("toSource - generating %s", this.gen_extended  ? "Extended": "Wrapped");
+               
+                   this.last_source =          this.gen_extended ? 
+                               NodeToValaExtended.mungeFile(this) :
+                               NodeToValaWrapped.mungeFile(this);
                    this.last_source_version = this.version;
                    return this.last_source;
                    
@@ -216,7 +221,7 @@ namespace JsRender {
                        var fn = this.targetName();
                        GLib.debug("WRITE :%s\n " , fn);
                        try {
-                               this.writeFile(fn,  NodeToVala.mungeFile(this));
+                               this.writeFile(fn, this.toSourceCode());
                } catch (GLib.Error e) {}
                
                
index a06076a..8d64b09 100644 (file)
@@ -99,9 +99,9 @@ public class JsRender.Node : GLib.Object {
        private Gee.ArrayList<Node> items; // child items..
        public GLib.ListStore  childstore; // must be kept in sync with items
        public GLib.ListStore?  propstore; // must be kept in sync with items
-       public string  xvala_cls;
-       public string xvala_xcls; // 'Xcls_' + id;
-       public string xvala_id; // item id or ""
+       public string  xvala_cls; // set by node to vala
+       public string xvala_xcls; // 'Xcls_' + id; // set by nodetoVala
+       public string xvala_id; // item id or "" // set by nodetovala
        
        // line markers..
        public int line_start;
index 76480ee..b96e8f9 100644 (file)
 */
 
  
-public class JsRender.NodeToVala : Object {
+public abstract class JsRender.NodeToVala : NodeWriter {
 
-       Node node;
-
-       int depth;
-       string inpad;
-       string pad;
-       string ipad;
-       string cls;  // node fqn()
-       string xcls;
-       
-       string ret;
+       protected string this_el = "??";
+        
+       int child_count = 1; // used to number the children.
+       public string cls;  // node fqn()
+       public string xcls;
        
-       int cur_line;
 
-       Gee.ArrayList<string> ignoreList;
        Gee.ArrayList<string> ignoreWrappedList; 
        Gee.ArrayList<string> myvars;
-       Gee.ArrayList<Node> vitems; // top level items
-       NodeToVala top;
-       JsRender file;
-       int pane_number = 0;
+
+
+        
+       int pane_number = 0;// ?? used when generating Gtk.Pane tabs
+       
+       
+       static construct {
+               NodeWriter.globalIgnore("pack");
+               NodeWriter.globalIgnore("init");
+               NodeWriter.globalIgnore("xns");
+               NodeWriter.globalIgnore("xtype");
+               NodeWriter.globalIgnore("id");
        
+       }
        /* 
         * ctor - just initializes things
         * - wraps a render node 
         */
-       public NodeToVala( JsRender file,  Node node,  int depth, NodeToVala? parent) 
+       protected NodeToVala( JsRender file,  Node node,  int depth, NodeToVala? parent) 
        {
 
+               base (file, node, depth, parent);
+        
+               this.initPadding('\t', 1);
                
-               this.node = node;
-               this.depth = depth;
-               if (file.name.contains(".")) { // namespaced..
-                       this.inpad = string.nfill(depth > 0 ? 2 : 1, '\t');
-               } else {
-                       this.inpad = string.nfill(depth > 0 ? 1 : 0, '\t');
-               }
-               this.pad = this.inpad + "\t";
-               
-               this.node.node_pad = this.inpad;
-               this.ipad = this.inpad + "\t\t";
                this.cls = node.xvala_cls;
                this.xcls = node.xvala_xcls;
                if (depth == 0 && this.xcls.contains(".")) {
@@ -70,180 +64,26 @@ public class JsRender.NodeToVala : Object {
                        this.xcls = ar[ar.length-1];
                }
                
-               
-               this.ret = "";
-               this.cur_line = parent == null ? 0 : parent.cur_line;
-               
-               
-               this.top = parent == null ? this : parent.top;
-               this.ignoreList = new Gee.ArrayList<string>();
+
                this.ignoreWrappedList  = new Gee.ArrayList<string>();
                this.myvars = new Gee.ArrayList<string>();
-               this.vitems = new Gee.ArrayList<Node>();
-               this.file = file;
-               
-               // initialize line data..
-               node.line_start = this.cur_line;
-               node.line_end  = this.cur_line;
-               node.lines = new Gee.ArrayList<int>();
-               node.line_map = new Gee.HashMap<int,string>();
-               if (parent == null) {
-                       node.node_lines = new Gee.ArrayList<int>();
-                       node.node_lines_map = new Gee.HashMap<int,Node>();
-                }
-               
-       }
-
-       public int vcnt = 0;
-       string toValaNS(Node item)
-       {
-               var ns = item.get("xns") ;
-               //if (ns == "GtkSource") {  technically on Gtk3?
-               //      return "Gtk.Source";
-               //}
-               return ns + ".";
-       }
-       public void  toValaName(Node item, int depth =0) 
-       {
-               this.vcnt++;
-
-               var ns =  this.toValaNS(item) ;
-               var cls = ns + item.get("xtype");
-               
-               
-               item.xvala_cls = cls;
-               
-               
-               string id = item.get("id").length > 0 ?
-                       item.get("id") :  "%s%d".printf(item.get("xtype"), this.vcnt);
-
-               
-               
-               
-               if (id[0] == '*' || id[0] == '+') {
-                       item.xvala_xcls = "Xcls_" + id.substring(1);
-               } else {
-                       item.xvala_xcls = "Xcls_" + id;
-               }
-                       
-               
-               item.xvala_id =  id;
-               if (depth > 0) {                        
-                       this.vitems.add(item);
-                       
-               // setting id on top level class changes it classname..                 
-               // oddly enough we havent really thought about namespacing here.
-               
-               } else if (!item.props.has_key("id")) { 
-                       // use the file name..
-                       item.xvala_xcls =  this.file.file_without_namespace;
-                       // is id used?
-                       item.xvala_id = this.file.file_without_namespace;
-
-               }
-               // loop children..
-                                                                                                                          
-               if (item.readItems().size < 1) {
-                       return;
-               }
-               for(var i =0;i<item.readItems().size;i++) {
-                       this.toValaName(item.readItems().get(i), depth+1);
-               }
-                                         
-       }
-       /**
-        *  Main entry point to convert a file into a string..
-        */
-       public static string mungeFile(JsRender file) 
-       {
-               if (file.tree == null) {
-                       return "";
-               }
-
-               var n = new NodeToVala(file, file.tree, 0, null);
-               n.file = file;
-               n.vcnt = 0;
-               
-               n.toValaName(file.tree);
-               
-               
-               GLib.debug("top cls %s / xlcs %s\n ",file.tree.xvala_cls,file.tree.xvala_cls); 
-               n.cls = file.tree.xvala_cls;
-               n.xcls = file.tree.xvala_xcls;
-               return n.munge();
-               
-
-       }
-       int child_count = 1; // used to number the children.
-       public string munge ( )
-       {
-               //return this.mungeToString(this.node);
                this.child_count = 1;
-               this.ignore("pack");
-               this.ignore("init");
-               this.ignore("xns");
-               this.ignore("xtype");
-               this.ignore("id");
-               
-               this.namespaceHeader();
-               this.globalVars();
-               this.classHeader();
-               this.addSingleton();
-               this.addTopProperties();
-               this.addMyVars();
-               this.addPlusProperties();
-               this.addValaCtor();
-               this.addUnderThis();
-               this.addWrappedCtor();  // var this.el = new XXXXX()
-
-               this.addInitMyVars();
-               this.addWrappedProperties();
-               this.addChildren();
-               this.addAutoShow(); // autoshow menuitems
-               
-               this.addInit();
-               this.addListeners();
-               this.addEndCtor();
-               this.addUserMethods();
-               this.iterChildren();
-               this.namespaceFooter();
-               
-               return this.ret;
                 
-                        
-       } 
-       public string mungeChild(  Node cnode)
-       {
-               var x = new  NodeToVala(this.file, cnode,  this.depth+1, this);
-               return x.munge();
-       }
-       public void addLine(string str= "")
-       {
-               
-               if (str.contains("\n")) {
-                       this.addMultiLine(str);
-                       return;
-               }
-               this.cur_line++;
-               if (BuilderApplication.opt_bjs_compile != null) {
-                       this.ret += "/*%d*/ ".printf(this.cur_line) + str + "\n";
-               } else {
-                       this.ret += str + "\n";
-               }
        }
-       public void addMultiLine(string str= "")
+       public void initCls()
        {
-                
-               this.cur_line += str.split("\n").length;
-               //this.ret +=  "/*%d*/ ".printf(l) + str + "\n";
-               this.ret +=   str + "\n";
+               this.cls = this.file.tree.xvala_cls;
+               this.xcls = this.file.tree.xvala_xcls;
        }
+       public abstract  string mungeChild(  Node cnode);
+       
         
        public void namespaceHeader()
        {
                if (this.depth > 0 || this.file.file_namespace == "") {
                        return;
-               }
+               } 
                this.addLine("namespace " + this.file.file_namespace);
                this.addLine("{");
        
@@ -256,82 +96,33 @@ public class JsRender.NodeToVala : Object {
                this.addLine("}");
        
        }
-       public void globalVars()
-       {
-               if (this.depth > 0) {
-                       return;
-               }
-               // Global Vars..??? when did this get removed..?
-               //this.ret += this.inpad + "public static " + this.xcls + "  " + this.node.xvala_id+ ";\n\n";
+       
 
-               this.addLine(this.inpad + "static " + this.xcls + "  _" + this.node.xvala_id+ ";");
-               this.addLine();
-                  
-       }
+       protected abstract void classHeader();
+        
 
-       void classHeader()
-       {
-                          
-               // class header..
-               // class xxx {   WrappedGtk  el; }
-               this.node.line_start = this.cur_line;
-               
-               this.top.node.setNodeLine(this.cur_line, this.node);
-               
-               this.addLine(this.inpad + "public class " + this.xcls + " : Object");
-               this.addLine(this.inpad + "{");
-               
-                
-               this.addLine(this.pad + "public " + this.cls + " el;");
-               this.addLine(this.pad + "private " + this.top.xcls + "  _this;");
-               this.addLine();
-                       
-                       
-                       
-                       // singleton
-       }
-       void addSingleton() 
-       {
-               if (depth > 0) {
-                       return;
-               }
-               this.addLine(pad + "public static " + xcls + " singleton()");
-               this.addLine(this.pad + "{");
-               this.addLine(this.ipad +    "if (_" + this.node.xvala_id  + " == null) {");
-               this.addLine(this.ipad +    "    _" + this.node.xvala_id + "= new "+ this.xcls + "();");  // what about args?
-               this.addLine(this.ipad +    "}");
-               this.addLine(this.ipad +    "return _" + this.node.xvala_id +";");
-               this.addLine(this.pad + "}");
-       }
                        
        /**
         * when ID is used... on an element, it registeres a property on the top level...
         * so that _this.ID always works..
         * 
         */
-       void addTopProperties()
+       protected void addTopProperties()
        {
                if (this.depth > 0) {
                        return;
                }
                // properties - global..??
+               foreach(var n in this.top_level_items) { 
 
-               var iter = this.vitems.list_iterator();
-               while(iter.next()) {
-                       var n = iter.get();
-
-                        
                        if (!n.props.has_key("id") || n.xvala_id.length < 0) {
                                continue;
                                
                        }
-                       if (n.xvala_id[0] == '*') {
-                               continue;
-                       }
-                       if (n.xvala_id[0] == '+') {
+                       if (n.xvala_id[0] == '*' || n.xvala_id[0] == '+') {
                                continue;
                        }
+                        
                        this.addLine(this.pad + "public " + n.xvala_xcls + " " + n.xvala_id + ";");
                        
                }
@@ -343,7 +134,7 @@ public class JsRender.NodeToVala : Object {
         * 
         */
  
-       void addMyVars()
+       protected void addMyVars()
        {
                GLib.debug("callinged addMhyVars");
                
@@ -362,11 +153,8 @@ public class JsRender.NodeToVala : Object {
          
                
                        // Key = TYPE:name
-               var iter = this.node.props.map_iterator();
-               while (iter.next()) {
-                        
-                       var prop = iter.get_value();
-                       
+               foreach(var prop in this.node.props.values) {
+                  
                        if (this.shouldIgnore(prop.name)) {
                                continue;
                        }
@@ -414,7 +202,7 @@ public class JsRender.NodeToVala : Object {
        }
        
        // if id of child is '+' then it's a property of this..
-       void addPlusProperties()
+       protected void addPlusProperties()
        {
                if (this.node.readItems().size < 1) {
                        return;
@@ -436,48 +224,11 @@ public class JsRender.NodeToVala : Object {
        /**
         * add the constructor definition..
         */
-       void addValaCtor()
-       {
-                       
-               
-               // .vala props.. 
-               
-               var cargs_str = "";
-               // ctor..
-               this.addLine();
-               this.addLine(this.pad + "// ctor");
-               
-               if (this.node.has("* args")) {
-                       // not sure what this is supposed to be ding..
-               
-                       cargs_str =  this.node.get("* args");
-                       //var ar = this.node.get("* args");.split(",");
-                       //for (var ari =0; ari < ar.length; ari++) {
-                               //      cargs +=  (ar[ari].trim().split(" ").pop();
-                                 // }
-                       }
-       
-               if (this.depth < 1) {
-                
-                       // top level - does not pass the top level element..
-                       this.addLine(this.pad + "public " + this.xcls + "(" +  cargs_str +")");
-                       this.addLine(this.pad + "{");
-               } else {
-                       if (cargs_str.length > 0) {
-                               cargs_str = ", " + cargs_str;
-                       }
-                       // for sub classes = we passs the top level as _owner
-                       this.addLine(this.pad + "public " + this.xcls + "(" +  this.top.xcls + " _owner " + cargs_str + ")");
-                       this.addLine(this.pad + "{");
-               }
-               
-
-       }
+       protected abstract void addValaCtor();
        /**
         *  make sure _this is defined..
         */
-       void addUnderThis() 
+       protected void addUnderThis() 
        {
                // public static?
                if (depth < 1) {
@@ -502,206 +253,9 @@ public class JsRender.NodeToVala : Object {
                         
        }
         
-       /**
-        * Initialize this.el to point to the wrapped element.
-        * 
-        * 
-        */
-
-       void addWrappedCtor()
-       {
-               // wrapped ctor..
-               // this may need to look up properties to fill in the arguments..
-               // introspection does not workk..... - as things like gtkmessagedialog
-               /*
-               if (cls == 'Gtk.Table') {
-
-               var methods = this.palete.getPropertiesFor(cls, 'methods');
-
-               print(JSON.stringify(this.palete.proplist[cls], null,4));
-               Seed.quit();
-               }
-               */
-               
-               // ctor can still override.
-               if (this.node.has("* ctor")) {
-                       this.node.setLine(this.cur_line, "p", "* ctor");
-                       this.addLine(this.ipad + "this.el = " + this.node.get("* ctor")+ ";");
-                       return;
-               }
-               
-               this.node.setLine(this.cur_line, "p", "* xtype");;
-               
-               // is the wrapped element a struct?
-               
-               var ncls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
-               if (ncls != null && ncls.nodetype == "Struct") {
-                       // we can use regular setters to apply the values.
-                       this.addLine(this.ipad + "this.el = " + this.node.fqn() + "();");
-                       return;
-               
-               
-               }
-
-               var ctor = ".new";
-               var args_str = "";
-               switch(this.node.fqn()) {
-               
-               // FIXME -- these are all GTK3 - can be removed when I get rid of them..
-                       case "Gtk.ComboBox":
-                               var is_entry = this.node.has("has_entry") && this.node.get_prop("has_entry").val.down() == "true";
-                               if (!is_entry) { 
-                                       break; // regular ctor.
-                               }
-                               this.ignoreWrapped("has_entry");
-                               ctor = ".with_entry";
-                               break;
-                               
-               
-                       case "Gtk.ListStore":
-                       case "Gtk.TreeStore":
-
-                               // not sure if this works.. otherwise we have to go with varargs and count + vals...
-                               if (this.node.has("* types")) {
-                                       args_str = this.node.get_prop("* types").val;
-                               }
-                               if (this.node.has("n_columns") && this.node.has("columns")) { // old value?
-                                       args_str = " { " + this.node.get_prop("columns").val + " } ";
-                                       this.ignoreWrapped("columns");
-                                       this.ignoreWrapped("n_columns");
-                               }
-                               
-                               this.addLine(this.ipad + "this.el = new " + this.node.fqn() + ".newv( " + args_str + " );");
-                               return;
-                               
-                       case "Gtk.LinkButton": // args filled with values.
-                               if (this.node.has("label")) {
-                                       ctor = ".with_label";    
-                               }
-                               break;
-                               
-                       default:
-                               break;
-               }
-               var default_ctor = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn() + ctor);              
-                
-               
-               // use the default ctor - with arguments (from properties)
-               
-               if (default_ctor != null && default_ctor.paramset != null && default_ctor.paramset.params.size > 0) {
-                       string[] args  = {};
-                       foreach(var param in default_ctor.paramset.params) {
-                                
-                               var n = param.name;
-                           GLib.debug("building CTOR ARGS: %s, %s", n, param.is_varargs ? "VARARGS": "");
-                               if (n == "___") { // for some reason our varargs are converted to '___' ...
-                                       continue;
-                               }
-                               
-                               if (this.node.has(n)) {  // node does not have a value
-                                       
-                                       this.ignoreWrapped(n);
-                                       this.ignore(n);
-                                       
-                                       var v = this.node.get(n);
-
-                                       if (param.type == "string") {
-                                               v = "\"" +  v.escape("") + "\"";
-                                       }
-                                       if (v == "TRUE" || v == "FALSE") {
-                                               v = v.down();
-                                       }
-
-                                       
-                                       args += v;
-                                       continue;
-                               }
-                               var propnode = this.node.findProp(n);
-                               if (propnode != null) {
-                                       // assume it's ok..
-                                       
-                                       var pname = this.addPropSet(propnode, propnode.has("id") ? propnode.get_prop("id").val : "");
-                                       args += (pname + ".el") ;
-                                       if (!propnode.has("id")) {
-                                               this.addLine(this.ipad + pname +".ref();"); 
-                                       }
-                                       
-                                       
-                                       
-                                       this.ignoreWrapped(n);
-                                       
-                                       continue;
-                               }
-                                       
-                                        
-                                       
-                                       
-                                
-                               if (param.type.contains("int")) {
-                                       args += "0";
-                                       continue;
-                               }
-                               if (param.type.contains("float")) {
-                                       args += "0f";
-                                       continue;
-                               }
-                               if (param.type.contains("bool")) {
-                                       args += "true"; // always default to true?
-                                       continue;
-                               }
-                               // any other types???
-                               
-                               
-                               
-                               
-                               args += "null";
-                                
-                               
-
-                       }
-                       this.node.setLine(this.cur_line, "p", "* xtype");
-                       this.addLine(this.ipad + "this.el = new " + this.node.fqn() + "( "+ string.joinv(", ",args) + " );") ;
-                       return;
-                       
-               }
-               // default ctor with no params..
-                if (default_ctor != null && ctor != ".new" ) {
-                       this.node.setLine(this.cur_line, "p", "* xtype");
-                       
-                       this.addLine(this.ipad + "this.el = new " + this.node.fqn() + ctor + "(  );") ;
-                       return;
-                }
-               
-               
-               this.addLine(this.ipad + "this.el = new " + this.node.fqn() + "(" + args_str + ");");
-               
-               
-
-                       
-       }
-       public static Gee.ArrayList<string> menuitem_children = null;
        
-       void addAutoShow()
-       {
-               if (menuitem_children == null) {
-                       menuitem_children = new Gee.ArrayList<string>();
-                       menuitem_children.add("Gtk.MenuItem");
-                       var gir = this.file.project.palete.getClass("Gtk.MenuItem");
-                       if (gir != null) {
-                           foreach(var impl in gir.implementations) {
-                                   menuitem_children.add(impl);
-                           }
-                   }
-               }
-
-               if (menuitem_children.contains(this.node.fqn())) {
-                       this.addLine(this.ipad + "this.el.show();");
-               
-               }
-       }
-
-       void addInitMyVars()
+        
+       protected void addInitMyVars()
        {
                        //var meths = this.palete.getPropertiesFor(item['|xns'] + '.' + item.xtype, 'methods');
                        //print(JSON.stringify(meths,null,4));Seed.quit();
@@ -744,7 +298,7 @@ public class JsRender.NodeToVala : Object {
 
 
        
-       void addWrappedProperties()
+       protected  void addWrappedProperties()
        {
                var cls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
                if (cls == null) {
@@ -755,10 +309,8 @@ public class JsRender.NodeToVala : Object {
                this.addLine();
                this.addLine(this.ipad + "// set gobject values");
                
-
-               var iter = cls.props.map_iterator();
-               while (iter.next()) {
-                       var p = iter.get_key();
+               foreach(var p in cls.props.keys) { 
+                       var val = cls.props.get(p);
                        //print("Check Write %s\n", p);
                        if (!this.node.has(p)) {
                                continue;
@@ -783,25 +335,24 @@ public class JsRender.NodeToVala : Object {
                        var is_raw = prop.ptype == NodePropType.RAW;
                        
                        // what's the type.. - if it's a string.. then we quote it..
-                       if (iter.get_value().type == "string" && !is_raw) {
+                       if (val.type == "string" && !is_raw) {
                                 v = "\"" +  v.escape("") + "\"";
                        }
                        if (v == "TRUE" || v == "FALSE") {
                                v = v.down();
                        }
-                       if (iter.get_value().type == "float" && v[v.length-1] != 'f') {
+                       if (val.type == "float" && v[v.length-1] != 'f') {
                                v += "f";
                        }
                        
                        prop.start_line = this.cur_line;
-                       this.addLine("%sthis.el.%s = %s;".printf(ipad,p,v)); // // %s,  iter.get_value().type);
+                       this.addLine("%s%s%s = %s;".printf(ipad,this.this_el,p,v)); // // %s,  iter.get_value().type);
                        prop.end_line = this.cur_line;          
                           // got a property..
                           
 
                }
-               
-       }
+       } 
        /**
         *  pack the children into the parent.
         * 
@@ -809,7 +360,7 @@ public class JsRender.NodeToVala : Object {
         * - this allows you to define children and add them manually..
         */
 
-       void addChildren()
+       protected  void addChildren()
        {
                                //code
                if (this.node.readItems().size < 1) {
@@ -856,12 +407,13 @@ public class JsRender.NodeToVala : Object {
        
                                
                                this.ignoreWrapped(child.get_prop("* prop").val);
+                               var el_name = this.this_el == "this.el." ? ".el" : "";
+                               this.addLine(ipad + this.this_el  + child.get_prop("* prop").val + " = " + childname + el_name +";");
                                
-                               this.addLine(ipad + "this.el." + child.get_prop("* prop").val + " = " + childname + ".el;");
                                continue;
                        } 
-                        if (!child.has("id")) {
-                               this.addLine(this.ipad + childname +".ref();"); 
+                        if (!child.has("id") && this.this_el == "this.el.") {
+                               this.addLine(this.ipad +  childname +".ref();"); 
                         } 
                        this.packChild(child, childname, cols, colpos);
                        
@@ -878,7 +430,7 @@ public class JsRender.NodeToVala : Object {
                }
        }
        
-       string addPropSet(Node child, string child_name) 
+       protected string addPropSet(Node child, string child_name) 
        {
         
                
@@ -897,8 +449,19 @@ public class JsRender.NodeToVala : Object {
                if (child_name == "") {
                        prefix = "var " + childname + " = ";
                }
+               var cls =  child.xvala_xcls;
+               /*
+               if (this.this_el == "this.") {
+                       var clsdata = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
+                       //if (clsdata.is_sealed) {
+                               cls = this.node.fqn(); // need ctor data...
+                               this.addLine(this.ipad + @"$(prefix)new $cls( _this $xargs);" );
+                               return child_name == "" ? childname : ("_this." + child_name);  
+                       }
+               }
+               */
                
-               this.addLine(this.ipad +  prefix + "new " + child.xvala_xcls + "( _this " + xargs + ");" );
+               this.addLine(this.ipad + @"$(prefix)new $cls( _this $xargs);" );
                 
                // add a ref... (if 'id' is not set... to a '+' ?? what does that mean? - fake ids?
                // remove '+' support as I cant remember what it does!!!
@@ -917,7 +480,7 @@ public class JsRender.NodeToVala : Object {
        
 
        
-       void packChild(Node child, string childname, int cols, int colpos, string propname= "")
+       protected void packChild(Node child, string childname, int cols, int colpos, string propname= "")
        {
                
                GLib.debug("packChild %s=>%s", this.node.fqn(), child.fqn());
@@ -928,7 +491,8 @@ public class JsRender.NodeToVala : Object {
                if (child.has("* pack") && child.get("* pack").down() == "true") {
                        return; // force no packing
                }
-               
+               var el_name = this.this_el == "this.el." ? ".el" : "";
+               var this_el = this.this_el;
                // BC really - don't want to support this anymore.
                if (child.has("* pack")) {
                        
@@ -938,12 +502,10 @@ public class JsRender.NodeToVala : Object {
                        }
                        
                        var pack = packing[0];
-                       this.addLine(this.ipad + "this.el." + pack.strip() + " ( " + childname + ".el " +
+                       this.addLine(this.ipad + this.this_el + pack.strip() + " ( " + childname + el_name + " " +
                                   (packing.length > 1 ? 
                                                (", " + string.joinv(",", packing).substring(pack.length+1))
-                                       :
-                                                       ""
-                                               ) + " );");
+                                       : "" ) + " );");
                        return;  
                }
                var childcls =  this.file.project.palete.getClass(child.fqn()); // very trusting..
@@ -953,7 +515,7 @@ public class JsRender.NodeToVala : Object {
                // GTK4
                var is_event = childcls.inherits.contains("Gtk.EventController") || childcls.implements.contains("Gtk.EventController");
                if (is_event) {
-                   this.addLine(this.ipad + "this.el.add_controller(  %s.el );".printf(childname) );
+                   this.addLine(this.ipad + this.this_el + "add_controller(  %s.el );".printf(childname) );
                    return;
                }
                
@@ -966,7 +528,7 @@ public class JsRender.NodeToVala : Object {
                        case "Gtk.Layout":
                                var x = child.has("x") ?  child.get_prop("x").val  : "0";
                                var y = child.has("y") ?  child.get_prop("y").val  : "0";
-                               this.addLine(this.ipad + "this.el.put( %s.el, %s, %s );".printf(childname,x,y) );
+                               this.addLine(@"$(ipad)$(this_el)put( $(childname)$(el_name), $(x), $(y) );");
                                return;
                                
                        
@@ -975,15 +537,16 @@ public class JsRender.NodeToVala : Object {
                                var named = child.has("stack_name") ?  child.get_prop("stack_name").val.escape() : "";
                                var title = child.has("stack_title") ?  child.get_prop("stack_title").val.escape()  : "";
                                if (title.length > 0) {
-                                       this.addLine(this.ipad + "this.el.add_titled( %s.el, \"%s\", \"%s\" );".printf(childname,named,title)); 
-                               } else {
-                                       this.addLine(this.ipad + "this.el.add_named( %s.el, \"%s\" );".printf(childname,named));
-                               }
+                                       this.addLine(@"$(ipad)$(this_el)add_titled( $(childname)$(el_name), \"$(named)\", \"$(title)\" );");
+                                       return;
+                               } 
+                               this.addLine(@"$(ipad)$(this_el)add_named( $(childname)$(el_name), \"$(named)\");");
                                return;
                                
                        case "Gtk.Notebook": // use label
                                var label = child.has("notebook_label") ?  child.get_prop("notebook_label").val.escape() : "";
-                               this.addLine(this.ipad + "this.el.append_page( %s.el, new Gtk.Label(\"%s\"));".printf(childname, label));       
+                               this.addLine(@"$(ipad)$(this_el)append_page( $(childname)$(el_name), new Gtk.Label(\"$(label)\");");
+                               
                                return;
                                
                         
@@ -993,36 +556,42 @@ public class JsRender.NodeToVala : Object {
                        
                        case "Gtk.TreeViewColumn": //adding Renderers - I think these are all proprerties of the renderer used...
                                if (child.has("markup_column") && int.parse(child.get_prop("markup_column").val) > -1) {
-                                       this.addLine(this.ipad + "this.el.add_attribute( %s.el, \"markup\", %s );".printf(childname, child.get_prop("markup_column").val));
+                                       var val = child.get_prop("markup_column").val;
+                                       this.addLine(@"$(ipad)$(this_el)add_attribute( $(childname)$(el_name), \"markup\", $(val) );");
                                }
                                if (child.has("text_column") && int.parse(child.get_prop("text_column").val) > -1) {
-                                       this.addLine(this.ipad + "this.el.add_attribute(  %s.el, \"text\", %s );".printf(childname, child.get_prop("text_column").val));
+                                       var val = child.get_prop("text_column").val;
+                                       this.addLine(@"$(ipad)$(this_el)add_attribute( $(childname)$(el_name), \"text\", $(val) );");
                                }
                                if (child.has("pixbuf_column") && int.parse(child.get_prop("pixbuf_column").val) > -1) {
-                                       this.addLine(this.ipad + "this.el.add_attribute(  %s.el, \"pixbuf\", %s );".printf(childname, child.get_prop("pixbuf_column").val));
+                                       var val = child.get_prop("pixbuf_column").val;
+                                       this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"pixbuf\", $(val) );");
                                }
                                if (child.has("pixbuf_column") && int.parse(child.get_prop("active_column").val) > -1) {
-                                       this.addLine(this.ipad + "this.el.add_attribute(  %s.el, \"active\", %s );".printf(childname, child.get_prop("active_column").val));
+                                       var val = child.get_prop("active_column").val;
+                                       this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"active\", $(val) );");
                                }
                                if (child.has("background_column") && int.parse(child.get_prop("background_column").val) > -1) {
-                                       this.addLine(this.ipad + "this.el.add_attribute(  %s.el, \"background-rgba\", %s );".printf(childname, child.get_prop("background_column").val));
+                               var val = child.get_prop("background_column").val;
+                                       this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"background-rgba\", $(val) );");
                                }
                                this.addLine(this.ipad + "this.el.add( " + childname + ".el );");
                                // any more!?
                                return;
-                       
+               
                        case "Gtk.Dialog":
                                if (propname == "buttons[]") {
                                        var resp_id = int.parse(childname.replace("child_", ""));
                                        if (child.has("* response_id")) { 
                                                resp_id = int.parse(child.get_prop("* response_id").val);
                                        }
-                                       this.addLine(this.ipad + "this.el.add_action_widget( %s.el, %d);".printf(childname,resp_id) );
+                                       this.addLine(@"$(ipad)$(this_el).add_action_widget( $(childname)$(el_name), $(resp_id) );");
+
                                        return;
                                }
                        
-                               
-                               this.addLine(this.ipad + "this.el.get_content_area().add( " + childname + ".el );");
+                               this.addLine(@"$(ipad)$$(this_el)get_content_area().add( $(childname)$(el_name) );");
                                return;
 
                
@@ -1031,22 +600,22 @@ public class JsRender.NodeToVala : Object {
        
        
        // known working with GTK4 !
-                       case "Gtk.HeaderBar": // it could be end... - not sure how to hanle that other than overriding the pack method?
-                               this.addLine(this.ipad + "this.el.pack_start( "+ childname + ".el );");
+                       case "Gtk.HeaderBar": // it could be end... - not sure how to hanle that other than overriding                                  this.addLine(this.ipad + "this.el.add_action_widget( %s.el, %d);".printf(childname,resp_id) ); the pack method?
+                               this.addLine(@"$(ipad)$(this_el)pack_start( $(childname)$(el_name) );");
                                return;
                        
                        case "GLib.Menu":
-                               this.addLine(this.ipad + "this.el.append_item( "+ childname + ".el );");
+                               this.addLine(@"$(ipad)$(this_el)append_item( $(childname)$(el_name) );");
                                return; 
                        
                        case "Gtk.Paned":
                                this.pane_number++;
                                switch(this.pane_number) {
                                        case 1:
-                                               this.addLine(this.ipad + "this.el.pack_start( %s.el );".printf(childname));
+                                               this.addLine(@"$(ipad)$(this_el)pack_start( $(childname)$(el_name) );");
                                                return;
-                                       case 2:                                 
-                                               this.addLine(this.ipad + "this.el.pack_end( %s.el );".printf(childname));
+                                       case 2: 
+                                               this.addLine(@"$(ipad)$(this_el)pack_end( $(childname)$(el_name) );");
                                                return;
                                        default:
                                                // do nothing
@@ -1055,7 +624,7 @@ public class JsRender.NodeToVala : Object {
                                return;
                        
                        case "Gtk.ColumnView":
-                               this.addLine(this.ipad + "this.el.append_column( "+ childname + ".el );");
+                               this.addLine(@"$(ipad)$(this_el)append_column( $(childname)$(el_name) );");
                                return;
                        
                        case "Gtk.Grid":
@@ -1063,12 +632,12 @@ public class JsRender.NodeToVala : Object {
                                var y = "%d".printf(( colpos - (colpos % cols) ) / cols);
                                var w = child.has("colspan") ? child.get_prop("colspan").val : "1";
                                var h = "1";
-                               this.addLine(this.ipad + "this.el.attach( %s.el, %s, %s, %s, %s );".printf(childname ,x,y, w, h) );
+                               this.addLine(@"$(ipad)$(this_el)attach( $(childname)$(el_name), $x, $y, $w, $h );");
                                return;
                        
                        default:
+                               this.addLine(@"$(ipad)$(this_el)append( $(childname)$(el_name) );");
                            // gtk4 uses append!!!! - gtk3 - uses add..
-                               this.addLine(this.ipad + "this.el.append( "+ childname + ".el );");
                                return;
                
                
@@ -1083,7 +652,7 @@ public class JsRender.NodeToVala : Object {
 
                        
 
-       void addInit()
+       protected void addInit()
        {
 
                
@@ -1100,7 +669,7 @@ public class JsRender.NodeToVala : Object {
                this.addMultiLine(ipad + this.padMultiline(ipad, init.val) );
                init.end_line = this.cur_line;
         }
-        void addListeners()
+        protected void addListeners()
         {
                if (this.node.listeners.size < 1) {
                        return;
@@ -1119,12 +688,12 @@ public class JsRender.NodeToVala : Object {
                        
                        prop.start_line = this.cur_line;
                        this.node.setLine(this.cur_line, "l", k);
-                       this.addMultiLine(this.ipad + "this.el." + k + ".connect( " + 
+                       this.addMultiLine(this.ipad + this.this_el + k + ".connect( " + 
                                        this.padMultiline(this.ipad,v) +");"); 
                        prop.end_line = this.cur_line;
                }
        }    
-       void addEndCtor()
+       protected void addEndCtor()
        {
                         
                        // end ctor..
@@ -1174,7 +743,7 @@ public class JsRender.NodeToVala : Object {
  * 
  */
         
-       void addUserMethods()
+       protected void addUserMethods()
        {
                this.addLine();
                this.addLine(this.pad + "// user defined functions");
@@ -1204,7 +773,7 @@ public class JsRender.NodeToVala : Object {
                }
        }
 
-       void iterChildren()
+       protected void iterChildren()
        {
                this.node.line_end = this.cur_line;
                this.node.sortLines();
@@ -1225,26 +794,15 @@ public class JsRender.NodeToVala : Object {
                }
                        
        }
 
-       string padMultiline(string pad, string str)
-       {
-               var ar = str.strip().split("\n");
-               return string.joinv("\n" + pad , ar);
-       }
        
-       void ignore(string i) {
-               this.ignoreList.add(i);
-               
-       }
-       void ignoreWrapped(string i) {
+       protected void ignoreWrapped(string i) {
                this.ignoreWrappedList.add(i);
                
        }
-       bool shouldIgnore(string i)
-       {
-               return ignoreList.contains(i);
-       }
-       bool shouldIgnoreWrapped(string i)
+       
+       protected  bool shouldIgnoreWrapped(string i)
        {
                return ignoreWrappedList.contains(i);
        }
diff --git a/src/JsRender/NodeToValaExtended.vala b/src/JsRender/NodeToValaExtended.vala
new file mode 100644 (file)
index 0000000..0dcad4b
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+
+This coverts nodes to vala code (but unlike the original) does it by extending the original wrapped class
+
+*/
+
+public class  JsRender.NodeToValaExtended : NodeToVala {
+
+        
+        
+       /* 
+        * ctor - just initializes things
+        * - wraps a render node 
+        */
+       public NodeToValaExtended( JsRender file,  Node node,  int depth, NodeToValaExtended? parent) 
+       {
+               base (file, node, depth, parent);
+               this.this_el = "this.";
+       }
+       /**
+        *  Main entry point to convert a file into a string..
+        */
+       public static string mungeFile(JsRender file) 
+       {
+               if (file.tree == null) {
+                       return "";
+               }
+
+               var n = new NodeToValaExtended(file, file.tree, 0, null);
+               n.toValaName(file.tree);
+               
+               
+               GLib.debug("top cls %s / xlcs %s\n ",file.tree.xvala_cls,file.tree.xvala_cls); 
+                               n.initCls();
+               return n.munge();
+               
+
+       }
+       int child_count = 1; // used to number the children.
+       public override string munge ( )
+       {
+               //return this.mungeToString(this.node);
+               this.child_count = 1;
+        
+               
+               this.namespaceHeader();
+
+               this.classHeader();
+
+               this.addTopProperties(); /// properties set with 'id'
+               this.addMyVars(); // user defined properties.
+               
+               // skip '+' properties?? not sure where they are used.
+               this.addValaCtor();
+                
+               this.addInitMyVars();
+               this.addWrappedProperties();
+               this.addChildren(); // to constructor code
+               //this.addSealedChildren();
+               //this.addAutoShow(); // not needed gtk4 autoshow menuitems
+               
+               this.addInit();
+               this.addListeners();
+               this.addEndCtor();
+               this.addUserMethods();
+               this.iterChildren(); // add children class definitions.
+               this.namespaceFooter();
+               
+               return this.ret;
+                
+                        
+       } 
+       
+       public override string mungeChild(  Node cnode)
+       {
+               var x = new  NodeToValaExtended(this.file, cnode,  this.depth+1, this);
+               return x.munge();
+       }
+       
+       
+       protected override void classHeader()
+       {
+                          
+               var top = this.top as NodeToVala;
+               if (top == null) {
+                       return;
+               }
+               // class header..
+               // class xxx {   WrappedGtk  el; }
+               this.node.line_start = this.cur_line;
+               
+               this.top.node.setNodeLine(this.cur_line, this.node);
+               
+               this.addLine(this.inpad + "public class " + this.xcls + " : " + this.cls);
+               this.addLine(this.inpad + "{");
+               
+               this.addLine(this.pad + "private " + top.xcls + "  _this;"); /// or protected??
+               this.addLine();
+                       
+                       
+                       
+                       // singleton
+       }
+       
+       /**
+        * add the constructor definition..
+        * this probably has to match the parent constructor.. 
+        **?? NO SUPPORT FOR * ARGS?
+        ** for child elements we have to add '_owner to the ctor arguments.
+        for most elements we have to call object ( a: a, b: b)  if the parent requires properties..
+        eg. like Gtk.Box
+        
+        
+        */
+        
+       protected override void addValaCtor()
+       {
+                       
+               
+               
+               var ncls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
+               if (ncls == null || ncls.nodetype != "Class") { 
+                       this.addLine(this.ipad + "** classname is invalid - can not make ctor "  + this.node.fqn());
+                       return;
+               }
+               var ctor = ".new";
+               var default_ctor = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn() + ctor);              
+               
+               if (default_ctor == null) {
+                       this.addLine(this.ipad + "** classname is invalid - can not find ctor "  + this.node.fqn() + ".new");
+                       return;
+               }
+               // simple ctor...(will not need ctor params..
+               
+               
+               // now we can skip ctor arguments if we have actually set them?
+               string[] args  = {};
+               if (default_ctor.paramset != null &&  default_ctor.paramset.params.size > 0)  {
+                       foreach(var param in default_ctor.paramset.params) {
+                                        
+                               var n = param.name;
+                               GLib.debug("building CTOR ARGS: %s, %s", n, param.is_varargs ? "VARARGS": "");
+                               // not sure if it's even worth warning on this...
+                               if (n == "___") { // for some reason our varargs are converted to '___' ...
+                                       continue;
+                               }
+                               if (this.node.has(n)) {
+                                       continue;
+                               }
+                               var propnode = this.node.findProp(n);
+                               if (propnode != null) {
+                                       continue;
+                               }
+                               // finally      
+                               args += (param.type + " " + n);
+                                 
+
+                       }
+               }
+               // create the ctor method
+               
+               if (this.depth < 1) {
+                
+                       // top level - does not pass the top level element..
+                       this.addLine(this.pad + "public " + this.xcls + "()");
+                       this.addLine(this.pad + "{");
+                          
+               } else {
+                       var top = this.top as NodeToVala;
+                       var tcls = top == null ? "???" : top.xcls;
+                       args += (tcls + " _owner" );
+                               // for sub classes = we passs the top level as _owner
+                       this.addLine(this.pad + "public " + this.xcls + "(" +  tcls + " _owner )");
+                       this.addLine(this.pad + "{");   
+                        
+               }
+               this.addUnderThis(); // set up '_this = _owner or _this = this;
+               
+               // if there are no ctor args, then we do not need to call object // or create props.
+               if (default_ctor.paramset == null ||  default_ctor.paramset.params.size < 1)  {
+                       return;
+               }
+               // .vala props.. 
+               var obj_args = new Gee.HashMap<string,string>();
+               foreach(var param in default_ctor.paramset.params) {
+                       var n = param.name;
+                       if (n == "___") { // for some reason our varargs are converted to '___' ...
+                                       continue;
+                       }
+                       if (this.node.has(n)) {  // node does not have a value
+                               
+                               this.ignoreWrapped(n);
+                               this.ignore(n);
+                               
+                               var v = this.node.get(n);
+
+                               if (param.type == "string") {
+                                       v = "\"" +  v.escape("") + "\"";
+                               }
+                               if (v == "TRUE" || v == "FALSE") {
+                                       v = v.down();
+                               }
+                               obj_args.set(n, v);
+                                
+                               continue;
+                       }
+                       var propnode = this.node.findProp(n);
+                       if (propnode != null) {
+                               // assume it's ok..
+                               
+                               var pname = this.addPropSet(propnode, propnode.has("id") ? propnode.get_prop("id").val : "");
+                               obj_args.set(n, pname);
+                                
+                               if (!propnode.has("id")) {
+                                       this.addLine(this.ipad + pname +".ref();"); 
+                               }
+                                
+                               this.ignoreWrapped(n); //??? not sure why we dont ignore it as well. 
+                                
+                               continue;
+                       }
+               }
+               if (obj_args.keys.size < 1) {
+                       return;
+               }
+               this.addLine(this.ipad + "Object(");
+               // at this point we might have object...
+               var ks = obj_args.keys.to_array();
+               for(var i = 0; i < ks.length; i++ ) {
+                       var k = ks[i];
+                       var v = obj_args.get(k);
+                       this.addLine(this.ipad + "\t" + k + ": " + v + (i == (ks.length-1) ? "" : ","));
+               }
+               this.addLine(this.ipad + ");");
+
+       }
+       
+       
+        
+       
+}
diff --git a/src/JsRender/NodeToValaWrapped.vala b/src/JsRender/NodeToValaWrapped.vala
new file mode 100644 (file)
index 0000000..5ddf32f
--- /dev/null
@@ -0,0 +1,367 @@
+/**
+       this is the code to write the 'classic' node to vala output
+       */
+       /**
+ * 
+ * Code to convert node tree to Vala...
+ * 
+ * usage : x = (new JsRender.NodeToVala(node)).munge();
+ * 
+ * Fixmes?
+ *
+ *  pack - can we come up with a replacement?
+     - parent.child == child_widget -- actually uses getters and effectively does 'add'?
+       (works on most)?
+    
+     
+ * args  -- vala constructor args (should really only be used at top level - we did use it for clutter originally(
+ * ctor  -- different ctor argument
+ * 
+ * 
+ * 
+*/
+
+public class JsRender.NodeToValaWrapped : NodeToVala {
+
+
+       
+
+       public NodeToValaWrapped( JsRender file,  Node node,  int depth, NodeToVala? parent) 
+       {
+               base (file, node, depth, parent);
+               this.this_el = "this.el.";
+       }
+       
+       /**
+        *  Main entry point to convert a file into a string..
+        */
+       public static string mungeFile(JsRender file) 
+       {
+               if (file.tree == null) {
+                       return "";
+               }
+
+               var n = new NodeToValaWrapped(file, file.tree, 0, null);
+               n.toValaName(file.tree);
+                
+               GLib.debug("top cls %s / xlcs %s\n ",file.tree.xvala_cls,file.tree.xvala_cls); 
+               n.initCls();
+               return n.munge();
+               
+
+       }
+       public override string munge ( )
+       {
+               //return this.mungeToString(this.node);
+               
+       
+               
+               this.namespaceHeader();
+               this.globalVars();
+               this.classHeader();
+               this.addSingleton();
+               this.addTopProperties();
+               this.addMyVars();
+               this.addPlusProperties(); // (this is child properties whos 'id' starts with '+' ??? not sure..
+               this.addValaCtor();
+               this.addUnderThis();
+               this.addWrappedCtor();  // var this.el = new XXXXX()
+
+               this.addInitMyVars();
+               this.addWrappedProperties();
+               this.addChildren();
+               //this.addAutoShow(); // not needed gtk4 autoshow menuitems
+               
+               this.addInit();
+               this.addListeners();
+               this.addEndCtor();
+               this.addUserMethods();
+               this.iterChildren();
+               this.namespaceFooter();
+               
+               return this.ret;
+                
+                        
+       }
+       public override string mungeChild(  Node cnode)
+       {
+               var x = new  NodeToValaWrapped(this.file, cnode,  this.depth+1, this);
+               return x.munge();
+       }
+       
+       protected override void classHeader()
+       {
+               var top = this.top as NodeToVala;
+               if (top == null) {
+                        
+                       return;
+               }
+               // class header..
+               // class xxx {   WrappedGtk  el; }
+               this.node.line_start = this.cur_line;
+               
+               this.top.node.setNodeLine(this.cur_line, this.node);
+               
+               this.addLine(this.inpad + "public class " + this.xcls + " : Object");
+               this.addLine(this.inpad + "{");
+               
+                
+               this.addLine(this.pad + "public " + this.cls + " el;");
+               this.addLine(this.pad + "private " + top.xcls + "  _this;");
+               this.addLine();
+                       
+                       
+                       
+                       // singleton
+       }
+       public void globalVars()
+       {
+               if (this.depth > 0) {
+                       return;
+               }
+               // Global Vars..??? when did this get removed..?
+               //this.ret += this.inpad + "public static " + this.xcls + "  " + this.node.xvala_id+ ";\n\n";
+
+               this.addLine(this.inpad + "static " + this.xcls + "  _" + this.node.xvala_id+ ";");
+               this.addLine();
+                  
+       }
+       protected void addSingleton() 
+       {
+               if (depth > 0) {
+                       return;
+               }
+               this.addLine(pad + "public static " + xcls + " singleton()");
+               this.addLine(this.pad + "{");
+               this.addLine(this.ipad +    "if (_" + this.node.xvala_id  + " == null) {");
+               this.addLine(this.ipad +    "    _" + this.node.xvala_id + "= new "+ this.xcls + "();");  // what about args?
+               this.addLine(this.ipad +    "}");
+               this.addLine(this.ipad +    "return _" + this.node.xvala_id +";");
+               this.addLine(this.pad + "}");
+       }
+       /**
+        * add the constructor definition..
+        */
+       protected override void addValaCtor()
+       {
+                       
+               
+               // .vala props.. 
+               
+               var cargs_str = "";
+               // ctor..
+               this.addLine();
+               this.addLine(this.pad + "// ctor");
+               
+               if (this.node.has("* args")) {
+                       // not sure what this is supposed to be ding..
+               
+                       cargs_str =  this.node.get("* args");
+                       //var ar = this.node.get("* args");.split(",");
+                       //for (var ari =0; ari < ar.length; ari++) {
+                               //      cargs +=  (ar[ari].trim().split(" ").pop();
+                                 // }
+                       }
+       
+               if (this.depth < 1) {
+                
+                       // top level - does not pass the top level element..
+                       this.addLine(this.pad + "public " + this.xcls + "(" +  cargs_str +")");
+                       this.addLine(this.pad + "{");
+               } else {
+                       if (cargs_str.length > 0) {
+                               cargs_str = ", " + cargs_str;
+                       }
+                       var top = this.top as NodeToVala;
+                       var tcls = top == null ? "???" : top.xcls;
+                       // for sub classes = we passs the top level as _owner
+                       this.addLine(this.pad + "public " + this.xcls + "(" +  tcls + " _owner " + cargs_str + ")");
+                       this.addLine(this.pad + "{");
+               }
+               
+
+       }
+       /**
+        * Initialize this.el to point to the wrapped element.
+        * 
+        * 
+        */
+
+       void addWrappedCtor()
+       {
+               // wrapped ctor..
+               // this may need to look up properties to fill in the arguments..
+               // introspection does not workk..... - as things like gtkmessagedialog
+               /*
+               if (cls == 'Gtk.Table') {
+
+               var methods = this.palete.getPropertiesFor(cls, 'methods');
+
+               print(JSON.stringify(this.palete.proplist[cls], null,4));
+               Seed.quit();
+               }
+               */
+               
+               // ctor can still override.
+               if (this.node.has("* ctor")) {
+                       this.node.setLine(this.cur_line, "p", "* ctor");
+                       this.addLine(this.ipad + "this.el = " + this.node.get("* ctor")+ ";");
+                       return;
+               }
+               
+               this.node.setLine(this.cur_line, "p", "* xtype");;
+               
+               // is the wrapped element a struct?
+               
+               var ncls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
+               if (ncls != null && ncls.nodetype == "Struct") {
+                       // we can use regular setters to apply the values.
+                       this.addLine(this.ipad + "this.el = " + this.node.fqn() + "();");
+                       return;
+               
+               
+               }
+
+               var ctor = ".new";
+               var args_str = "";
+               switch(this.node.fqn()) {
+               
+               // FIXME -- these are all GTK3 - can be removed when I get rid of them..
+                       case "Gtk.ComboBox":
+                               var is_entry = this.node.has("has_entry") && this.node.get_prop("has_entry").val.down() == "true";
+                               if (!is_entry) { 
+                                       break; // regular ctor.
+                               }
+                               this.ignoreWrapped("has_entry");
+                               ctor = ".with_entry";
+                               break;
+                               
+               
+                       case "Gtk.ListStore":
+                       case "Gtk.TreeStore":
+
+                               // not sure if this works.. otherwise we have to go with varargs and count + vals...
+                               if (this.node.has("* types")) {
+                                       args_str = this.node.get_prop("* types").val;
+                               }
+                               if (this.node.has("n_columns") && this.node.has("columns")) { // old value?
+                                       args_str = " { " + this.node.get_prop("columns").val + " } ";
+                                       this.ignoreWrapped("columns");
+                                       this.ignoreWrapped("n_columns");
+                               }
+                               
+                               this.addLine(this.ipad + "this.el = new " + this.node.fqn() + ".newv( " + args_str + " );");
+                               return;
+                               
+                       case "Gtk.LinkButton": // args filled with values.
+                               if (this.node.has("label")) {
+                                       ctor = ".with_label";    
+                               }
+                               break;
+                               
+                       default:
+                               break;
+               }
+               var default_ctor = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn() + ctor);              
+                
+               
+               // use the default ctor - with arguments (from properties)
+               
+               if (default_ctor != null && default_ctor.paramset != null && default_ctor.paramset.params.size > 0) {
+                       string[] args  = {};
+                       foreach(var param in default_ctor.paramset.params) {
+                                
+                               var n = param.name;
+                           GLib.debug("building CTOR ARGS: %s, %s", n, param.is_varargs ? "VARARGS": "");
+                               if (n == "___") { // for some reason our varargs are converted to '___' ...
+                                       continue;
+                               }
+                               
+                               if (this.node.has(n)) {  // node does not have a value
+                                       
+                                       this.ignoreWrapped(n);
+                                       this.ignore(n);
+                                       
+                                       var v = this.node.get(n);
+
+                                       if (param.type == "string") {
+                                               v = "\"" +  v.escape("") + "\"";
+                                       }
+                                       if (v == "TRUE" || v == "FALSE") {
+                                               v = v.down();
+                                       }
+
+                                       
+                                       args += v;
+                                       continue;
+                               }
+                               var propnode = this.node.findProp(n);
+                               if (propnode != null) {
+                                       // assume it's ok..
+                                       
+                                       var pname = this.addPropSet(propnode, propnode.has("id") ? propnode.get_prop("id").val : "");
+                                       args += (pname + ".el") ;
+                                       if (!propnode.has("id")) {
+                                               this.addLine(this.ipad + pname +".ref();"); 
+                                       }
+                                       
+                                       
+                                       
+                                       this.ignoreWrapped(n);
+                                       
+                                       continue;
+                               }
+                                       
+                                        
+                                       
+                                       
+                                
+                               if (param.type.contains("int")) {
+                                       args += "0";
+                                       continue;
+                               }
+                               if (param.type.contains("float")) {
+                                       args += "0f";
+                                       continue;
+                               }
+                               if (param.type.contains("bool")) {
+                                       args += "true"; // always default to true?
+                                       continue;
+                               }
+                               // any other types???
+                               
+                               
+                               
+                               
+                               args += "null";
+                                
+                               
+
+                       }
+                       this.node.setLine(this.cur_line, "p", "* xtype");
+                       this.addLine(this.ipad + "this.el = new " + this.node.fqn() + "( "+ string.joinv(", ",args) + " );") ;
+                       return;
+                       
+               }
+               // default ctor with no params..
+                if (default_ctor != null && ctor != ".new" ) {
+                       this.node.setLine(this.cur_line, "p", "* xtype");
+                       
+                       this.addLine(this.ipad + "this.el = new " + this.node.fqn() + ctor + "(  );") ;
+                       return;
+                }
+               
+               
+               this.addLine(this.ipad + "this.el = new " + this.node.fqn() + "(" + args_str + ");");
+                       
+       }
+        
+                
+
+}
diff --git a/src/JsRender/NodeWriter.vala b/src/JsRender/NodeWriter.vala
new file mode 100644 (file)
index 0000000..235a046
--- /dev/null
@@ -0,0 +1,193 @@
+
+namespace JsRender {
+       public abstract class NodeWriter : Object {
+       
+       
+               protected JsRender file;
+               protected Node node;
+
+               protected int depth;
+               protected string inpad;  // the pad for the class outer
+               protected string pad;   // the padd for the methods / properties.
+               protected string ipad;
+                
+               protected Gee.ArrayList<Node> top_level_items; // top level items (was vitems)
+               protected int cur_line;
+               protected NodeWriter top; 
+               
+               public string ret {
+                       get {
+                               return this.output;
+                       }
+                       private set {
+                               GLib.error("set called on nodewriter ret");
+                       }
+               }
+        
+               string output = "";  // the result of outputing..
+               
+               Gee.ArrayList<string> ignoreList;
+               static  Gee.ArrayList<string>? globalIgnoreList = null; 
+               static construct {
+                       globalIgnoreList = new Gee.ArrayList<string>();
+               }
+                
+               /* 
+                * ctor - just initializes things
+                * - wraps a render node 
+                */
+               protected NodeWriter( JsRender file,  Node node,  int depth, NodeWriter? parent) 
+               {
+                       this.file = file;
+                       this.node = node;
+                       this.depth = depth;
+                       if (parent == null) {
+                               this.var_name_count = 0;
+                       }
+                       this.top_level_items = new Gee.ArrayList<Node>();
+                       this.cur_line = parent == null ? 0 : parent.cur_line;
+                       this.top = parent == null ? this : parent.top;
+                        
+               // initialize line data..
+                       node.line_start = this.cur_line;
+                       node.line_end  = this.cur_line;
+                       node.lines = new Gee.ArrayList<int>();
+                       node.line_map = new Gee.HashMap<int,string>();
+                       if (parent == null) {
+                               node.node_lines = new Gee.ArrayList<int>();
+                               node.node_lines_map = new Gee.HashMap<int,Node>();
+                        }
+                        
+                       this.ignoreList = new Gee.ArrayList<string>();
+                       
+               }
+               
+               int var_name_count = 0; // was vcnt
+
+               string toValaNS(Node item)
+               {
+                       return item.get("xns") + ".";
+               }
+               /**
+                       fills in all the xvala_cls names into the nodes
+                       
+               */
+               
+               
+               public void initPadding(char pad, int len) 
+               {
+               
+                       var has_ns = this.file.xtype == "Gtk" &&  this.file.file_namespace.length > 0;
+                       
+                       if (has_ns) { // namespaced..
+                               this.inpad = string.nfill((depth > 0 ? 2 : 1)* len, pad);
+                       } else {
+                               this.inpad = string.nfill((depth > 0 ? 1 : 0) * len , pad);
+                       }
+                       this.pad = this.inpad + string.nfill(len, pad);
+                       this.node.node_pad = this.inpad;
+                       this.ipad = this.inpad +  string.nfill(2* len, pad);;
+               
+               
+               }
+               
+               public void  toValaName(Node item, int depth =0) 
+               {
+                       this.var_name_count++;
+
+                       var ns =  this.toValaNS(item) ;
+                       var cls = ns + item.get("xtype");
+                       
+                       item.xvala_cls = cls;
+                       
+                       string id = item.get("id").length > 0 ?
+                               item.get("id") :  "%s%d".printf(item.get("xtype"), this.var_name_count);
+
+                       
+                       
+                       
+                       if (id[0] == '*' || id[0] == '+') {
+                               item.xvala_xcls = "Xcls_" + id.substring(1);
+                       } else {
+                               item.xvala_xcls = "Xcls_" + id;
+                       }
+                               
+                       
+                       item.xvala_id =  id;
+                       if (depth > 0) {                        
+                               this.top_level_items.add(item);
+                               
+                       // setting id on top level class changes it classname..                 
+                       // oddly enough we havent really thought about namespacing here.
+                       
+                       } else if (!item.props.has_key("id")) { 
+                               // use the file name..
+                               item.xvala_xcls =  this.file.file_without_namespace;
+                               // is id used?
+                               item.xvala_id = this.file.file_without_namespace;
+
+                       }
+                               // loop children..
+                                                                                                                                  
+                       if (item.readItems().size < 1) {
+                               return;
+                       }
+                       for(var i =0;i<item.readItems().size;i++) {
+                               this.toValaName(item.readItems().get(i), depth+1);
+                       }
+                                                 
+               }
+               
+               protected void addLine(string str= "")
+               {
+                       
+                       if (str.contains("\n")) {
+                               this.addMultiLine(str);
+                               return;
+                       }
+                       //GLib.debug(str);
+                       this.cur_line++;
+                       //if (BuilderApplication.opt_bjs_compile != null) {
+                       //      this.output += "/*%d*/ ".printf(this.cur_line) + str + "\n";
+                       //} else {
+                               this.output += str + "\n";
+                       //}
+               }
+               protected void addMultiLine(string str= "")
+               {
+                        
+                       this.cur_line += str.split("\n").length;
+                       //this.ret +=  "/*%d*/ ".printf(l) + str + "\n";
+                       //GLib.debug(str);
+                       this.output +=   str + "\n";
+               }
+               protected string padMultiline(string pad, string str)
+               {
+                       var ar = str.strip().split("\n");
+                       return string.joinv("\n" + pad , ar);
+               }
+               protected static void globalIgnore(string i) {
+                       if (globalIgnoreList == null) {
+                               globalIgnoreList =  new Gee.ArrayList<string>(); // should not happend.. but dont know about ctor process..
+                       }
+                       globalIgnoreList.add(i);
+               }
+               
+               protected void ignore(string i) {
+                       this.ignoreList.add(i);
+                       
+               }
+               
+               protected bool shouldIgnore(string i)
+               {
+                       return globalIgnoreList.contains(i) || ignoreList.contains(i);
+               }
+               
+               
+               // interface
+               public abstract string munge();
+               
+               
+               
+       }
+}
\ No newline at end of file
index cb08c8f..5a8361c 100644 (file)
@@ -36,6 +36,7 @@ namespace Palete {
                public bool is_writable = true;
                public bool is_readable = true;
                public bool is_abstract = false;
+               public bool is_sealed = false;
                public  string parent;
                public  string value;
                // to be filled in...
index 3d63c2f..a805377 100644 (file)
@@ -184,6 +184,7 @@ namespace Palete {
                        c.parent = cls.base_class == null ? "" : cls.base_class.get_full_name() ;  // extends...
                        c.gparent = parent;
                        c.is_abstract = cls.is_abstract;
+                       c.is_sealed = cls.is_sealed;
                        foreach(var p in cls.get_properties()) {
                                this.add_property(c, p);
                        }