3 This code renders the Gtk tree into a set of Gtk elements.
6 public class JsRender.NodeToGtk : Object {
12 Gee.ArrayList<NodeToGtk> children;
14 Gee.ArrayList<string> els;
15 //Gee.ArrayList<string> skip;
16 Gee.HashMap<string,string> ar_props;
17 public static int vcnt = 0;
19 public NodeToGtk( Node node)
22 this.els = new Gee.ArrayList<string>();
23 this.children = new Gee.ArrayList<NodeToGtk>();
24 //this.skip = new Gee.ArrayList<string>();
25 this.ar_props = new Gee.HashMap<string,string>();
26 this.parentObj = null;
29 public Object? munge ( )
31 var ret = this.mungeNode();
36 return ret.wrapped_object;
39 public NodeToGtk? mungeChild( Node cnode)
41 var x = new NodeToGtk(cnode);
47 public NodeToGtk? mungeNode()
50 var parent = this.parentObj != null ? this.parentObj.wrapped_object : null;
51 var cls = this.node.fqn().replace(".", "");
52 var ns = this.node.fqn().split(".")[0];
53 var gtkbuilder = new global::Gtk.Builder();
55 var cls_gtype = gtkbuilder.get_type_from_name(cls);
56 print("Type: %s ?= %s\n", this.node.fqn(), cls_gtype.name());
58 if (cls_gtype == GLib.Type.INVALID) {
59 print("SKIP - gtype is invalid\n");
62 // if it's a window...
64 if (cls_gtype.is_a(typeof(global::Gtk.Window))) {
65 // what if it has none...
66 if (this.node.items.size < 1) {
69 return this.mungeChild(this.node.items.get(0));
72 var ret = Object.new(cls_gtype);
73 ret.ref(); //??? problematic?
74 this.wrapped_object = ret;
79 //case "GtkTreeStore": // top level.. - named and referenced
80 case "GtkListStore": // top level.. - named and referenced
81 //case "GtkTreeViewColumn": // part of liststore?!?!
82 //case "GtkMenu": // top level..
83 //case "GtkCellRendererText":
84 case "GtkSourceBuffer":
85 case "GtkClutterActor"://fixme..
86 case "GtkClutterEmbed"://fixme.. -- we can not nest embedded.. need to solve..
97 if (parent != null && parent.get_type().is_a(typeof(global::Gtk.Container))) {
98 this.packContainerParams();
101 var cls_gir =Palete.Gir.factoryFqn(this.node.fqn());
102 if (cls_gir == null) {
105 //var id = this.node.uid();
106 //var ret = @"$pad<object class=\"$cls\" id=\"$id\">\n";
108 var props = cls_gir.props;
111 var pviter = props.map_iterator();
112 while (pviter.next()) {
114 // print("Check: " +cls + "::(" + pviter.get_value().propertyof + ")" + pviter.get_key() + " " );
115 var k = pviter.get_key();
116 // skip items we have already handled..
117 if (!this.node.has(k)) {
120 // find out the type of the property...
121 var type = pviter.get_value().type;
122 type = Palete.Gir.fqtypeLookup(type, ns);
124 var val = this.toValue(this.node.get(k).strip(), type);
126 print("skip (failed to transform value %s type = %s from %s\n",
127 cls + "." + k, type, this.node.get(k).strip());
130 print ("set_property ( %s , %s / %s)\n", k, this.node.get(k).strip(), val.strdup_contents());
133 ret.set_property(k, val);
138 // for now... - just try the builder style packing
142 if (this.node.items.size < 1) {
146 for (var i = 0; i < this.node.items.size; i++ ) {
148 var ch = this.mungeChild(this.node.items.get(i));
150 this.children.add(ch);
155 this.afterChildren();
164 public void afterChildren()
166 // things like GtkNotebook - we have to pack children after they have been created..
167 var cls = this.node.fqn().replace(".", "");
169 if (cls == "GtkNotebook") {
170 this.afterChildrenGtkNotebook();
177 public void afterChildrenGtkNotebook()
179 // we have a number of children..
180 // some are labels - this might need to be more complex...
181 // perhaps labels should be a special property labels[] of the notebook..
182 var labels = new Gee.ArrayList<NodeToGtk>();
183 var bodies = new Gee.ArrayList<NodeToGtk>();
184 for (var i = 0; i < this.children.size; i++) {
185 var cn = this.children.get(i).node.fqn().replace(".", "");
186 if (cn != "GtkLabel") {
187 bodies.add(this.children.get(i));
190 labels.add(this.children.get(i));
192 for (var i = 0; i < bodies.size; i++) {
193 ((global::Gtk.Notebook)this.wrapped_object).append_page(
194 (global::Gtk.Notebook) bodies.get(i).wrapped_object,
195 (labels.size > i - 1) ?
196 (global::Gtk.Notebook) labels.get(i).wrapped_object :
209 * called after the this.object has been created
210 * and it needs to be packed onto parent.
212 public void packParent()
214 var cls = this.node.fqn().replace(".", "");
216 var gtkbuilder = new global::Gtk.Builder();
217 var cls_gtype = gtkbuilder.get_type_from_name(cls);
219 if (this.parentObj == null) {
224 var parent = this.parentObj.wrapped_object;
228 if (parent == null) { // no parent.. can not pack.
231 // ------------- handle various special parents .. -----------
233 var par_type = this.parentObj.node.fqn().replace(".", "");
235 if (par_type == "GtkNotebook") {
236 // do not pack - it's done afterwards...
240 // ------------- handle various child types.. -----------
242 if (cls == "GtkMenu") {
247 if (cls == "GtkTreeStore") { // other stores?
248 // tree store is buildable??? ---
249 this.packTreeStore();
252 if (cls =="GtkTreeViewColumn") { // other stores?
253 //?? treeview column is actually buildable -- but we do not use the builder???
254 this.packTreeViewColumn();
257 if (cls_gtype.is_a(typeof(global::Gtk.CellRenderer))) { // other stores?
258 this.packCellRenderer();
264 // -- handle buildable add_child..
265 if ( cls_gtype.is_a(typeof(global::Gtk.Buildable))
267 parent.get_type().is_a(typeof(global::Gtk.Buildable))
270 ((global::Gtk.Buildable)parent).add_child(gtkbuilder,
271 this.wrapped_object, null);
280 public void packMenu()
284 var parent = this.parentObj.wrapped_object;
285 if (!parent.get_type().is_a(typeof(global::Gtk.Widget))) {
286 print("skip menu pack - parent is not a widget");
290 var p = (global::Gtk.Menu)this.wrapped_object;
291 ((global::Gtk.Widget)parent).button_press_event.connect((s, ev) => {
292 p.set_screen(Gdk.Screen.get_default());
294 p.popup(null, null, null, ev.button, ev.time);
299 public void packTreeStore()
301 var parent = this.parentObj.wrapped_object;
302 if (!parent.get_type().is_a(typeof(global::Gtk.TreeView))) {
303 print("skip treestore pack - parent is not a treeview");
306 ((global::Gtk.TreeView)parent).set_model((global::Gtk.TreeModel)this.wrapped_object);
309 public void packTreeViewColumn()
311 var parent = this.parentObj.wrapped_object;
312 if (!parent.get_type().is_a(typeof(global::Gtk.TreeView))) {
313 print("skip packGtkViewColumn pack - parent is not a treeview");
316 ((global::Gtk.TreeView)parent).append_column((global::Gtk.TreeViewColumn)this.wrapped_object);
317 // init contains the add_attribute for what to render...
322 public void packCellRenderer()
324 var parent = this.parentObj.wrapped_object;
325 if (!parent.get_type().is_a(typeof(global::Gtk.TreeViewColumn))) {
326 print("skip packGtkViewColumn pack - parent is not a treeview");
329 ((global::Gtk.TreeViewColumn)parent).pack_start((global::Gtk.CellRenderer)this.wrapped_object, false);
330 // init contains the add_attribute for what to render...
335 public void packContainerParams()
338 if (this.parentObj == null) {
341 // child must be a widget..
342 if (!this.wrapped_object.get_type().is_a(typeof(global::Gtk.Widget))) {
346 var parent_gir = Palete.Gir.factoryFqn(this.parentObj.node.fqn());
348 var parent = this.parentObj.wrapped_object;
350 if (parent_gir == null) {
354 // let's test just setting expand to false...
355 var cls_methods = parent_gir.methods;
356 if (cls_methods == null) {
360 if (!this.node.props.has_key("* pack") ||
361 this.node.props.get("* pack").length < 1) {
365 var ns = this.parentObj.node.fqn().split(".")[0];
367 var pack = this.node.props.get("* pack").split(",");
370 if (cls_methods.has_key(pack[0])) {
371 var mparams = cls_methods.get(pack[0]).paramset.params;
372 for (var i = 1; i < mparams.size; i++ ) {
373 if (i > (pack.length -1)) {
377 var k = mparams.get(i).name;
381 var type = mparams.get(i).type;
382 type = Palete.Gir.fqtypeLookup(type, ns);
384 var val = this.toValue(pack[i].strip(), type);
386 print("skip (failed to transform value %s type = %s from %s\n",
387 this.parentObj.node.fqn() + "." + k, type, pack[i].strip());
390 print ("pack:set_property ( %s , %s / %s)\n", k, pack[i].strip(), val.strdup_contents());
392 ((global::Gtk.Container)parent).child_set_property(
393 (global::Gtk.Widget)this.wrapped_object , k, val);
405 public GLib.Value? toValue(string val, string type) {
407 var gtkbuilder = new global::Gtk.Builder();
409 if (type == "utf8") {
410 var qret = GLib.Value(typeof(string));
411 qret.set_string(val);
415 var prop_gtype = gtkbuilder.get_type_from_name(type);
418 if (prop_gtype == GLib.Type.INVALID) {
424 var ret = GLib.Value(prop_gtype);
429 ret.set_boolean(val.down() == "false" ? false : true);
432 ret.set_uint(int.parse(val));
436 ret.set_int(int.parse(val));
440 ret.set_float(long.parse(val));
449 var sval = GLib.Value(typeof(string));
450 sval.set_string(val);
452 if (!sval.transform(ref ret)) {