JsRender/NodeToGtk.vala
[app.Builder.js] / JsRender / NodeToGtk.vala
1 /*
2
3  
4 */
5 public class JsRender.NodeToGtk : Object {
6
7         Node node;
8         Object wrapped_object; 
9         Gee.ArrayList<string> els;
10         //Gee.ArrayList<string> skip;
11         Gee.HashMap<string,string> ar_props;
12         public static int vcnt = 0; 
13
14         public NodeToGtk( Node node) 
15         {
16                 this.node = node;
17                 this.els = new Gee.ArrayList<string>(); 
18                 //this.skip = new Gee.ArrayList<string>();
19                 this.ar_props = new Gee.HashMap<string,string>();
20
21         }
22         
23         public Object? munge ( )
24         {
25
26                  return this.mungeNode (null);
27                  
28                      
29         }
30         public Object? mungeChild(  Node cnode)
31         {
32                 var x = new  NodeToGtk(cnode);
33                 return x.mungeNode(this);
34         }
35         
36         public Object? mungeNode(NodeToGtk? parentObj)
37         {
38
39                 var parent = parentObj != null ? parentObj.wrapped_object : null;
40                 var cls = this.node.fqn().replace(".", "");
41                 var ns = this.node.fqn().split(".")[0];
42                 var gtkbuilder = new global::Gtk.Builder();
43
44                 var cls_gtype = gtkbuilder.get_type_from_name(cls);
45                 print("Type: %s ?= %s\n", this.node.fqn(), cls_gtype.name());
46
47                 if (cls_gtype == GLib.Type.INVALID) {
48                         print("SKIP - gtype is invalid\n");
49                         return null;
50                 }
51                 // if it's a window... 
52
53                 if (cls_gtype.is_a(typeof(global::Gtk.Window))) {
54                         // what if it has none...
55                         if (this.node.items.size < 1) {
56                                 return null;
57                         }
58                         return this.mungeChild(this.node.items.get(0));
59                 }
60
61                 var ret = Object.new(cls_gtype);
62                 ret.ref(); //??? problematic?
63                 this.wrapped_object = ret;
64                 
65                  
66                 switch(cls) {
67                         // fixme
68                         case "GtkTreeStore": // top level.. - named and referenced
69                         case "GtkListStore": // top level.. - named and referenced
70                         case "GtkTreeViewColumn": // part of liststore?!?!
71                         case "GtkMenu": // top level..
72                         case "GtkCellRendererText":
73                         case "GtkSourceBuffer":                         
74                         case "GtkClutterActor"://fixme..
75                         ///case "GtkClutterEmbed"://fixme..
76                                 return null;
77                 }
78
79
80                 var do_pack =true;
81                 
82                 if (!cls_gtype.is_a(typeof(global::Gtk.Buildable))) {
83                         print("skipping pack  %s is not a buildable..\n", cls);
84                         do_pack = false;
85                 }
86                 if (parent == null) {
87                         //print("skipping pack  %s is not a buildable..\n", cls);
88                         do_pack = false;
89                 } else  if (!parent.get_type().is_a(typeof(global::Gtk.Buildable))) {
90                         print("skipping pack parent:%s is not a buildable..\n", parent.get_type().name());
91                         do_pack = false;
92                 }
93
94                 // at present we are setting the packing / fill / expand as
95                 // arguments to pack_start etc...
96                 
97                 var parent_gir = parentObj == null ? null : Palete.Gir.factoryFqn(parentObj.node.fqn()); 
98                 
99                 // let's test just setting expand to false...
100                 var cls_methods = parent_gir == null ? null : parent_gir.methods;
101
102                 // pack on a container..
103                 
104                 if (do_pack) {
105                         ((global::Gtk.Buildable)parent).add_child(gtkbuilder, ret, null);
106                 }
107
108                 if  (do_pack && 
109                                 this.node.props.has_key("* pack") 
110                                 &&
111                                 cls_methods != null
112                                 &&
113                                 parent.get_type().is_a(typeof(global::Gtk.Container))) {
114                         var pack = this.node.props.get("* pack").split(",");
115
116                         
117                         if (cls_methods.has_key(pack[0])) {
118                                 var mparams = cls_methods.get(pack[0]).paramset.params;
119                                 for (var i = 1; i < mparams.size; i++ ) {
120                                         if (i > (pack.length -1)) {
121                                                 continue;
122                                         }
123                                         
124                                         var k = mparams.get(i).name;
125
126                                         Value cur_val;
127                                          
128                                         var type = mparams.get(i).type;
129                                         type = Palete.Gir.fqtypeLookup(type, ns);
130
131                                         var val = this.toValue(pack[i].strip(), type);
132                                         if (val == null) {
133                                                 print("skip (failed to transform value %s type = %s from %s\n", 
134                                                         cls + "." + k, type, pack[i].strip());
135                                                 continue;
136                                         }
137                                         print ("pack:set_property ( %s , %s / %s)\n", k, pack[i].strip(), val.strdup_contents());
138                         
139                                         ((global::Gtk.Container)parent).child_set_property((global::Gtk.Widget)ret, k, val);
140                                          
141                                 }
142                                 
143                         }
144                         
145
146
147                         
148                 }
149                    
150
151                 var cls_gir =Palete.Gir.factoryFqn(this.node.fqn()); 
152                 
153                 //var id = this.node.uid();
154                 //var ret = @"$pad<object class=\"$cls\" id=\"$id\">\n";
155                 // properties..
156                 var props = cls_gir.props;
157                 
158               
159                 var pviter = props.map_iterator();
160                 while (pviter.next()) {
161                         
162                                 // print("Check: " +cls + "::(" + pviter.get_value().propertyof + ")" + pviter.get_key() + " " );
163                         var k = pviter.get_key();
164                         // skip items we have already handled..
165                         if  (!this.node.has(k)) {
166                                 continue;
167                         }
168                         // find out the type of the property...
169                         var type = pviter.get_value().type;
170                         type = Palete.Gir.fqtypeLookup(type, ns);
171
172                         var val = this.toValue(this.node.get(k).strip(), type);
173                         if (val == null) {
174                                 print("skip (failed to transform value %s type = %s from %s\n", 
175                                         cls + "." + k, type,  this.node.get(k).strip());
176                                 continue;
177                         }
178                         print ("set_property ( %s , %s / %s)\n", k, this.node.get(k).strip(), val.strdup_contents());
179                         
180                         
181                         ret.set_property(k, val);  
182                         
183
184                 }
185                 // packing???
186                 // for now... - just try the builder style packing
187                 
188                 
189                  
190                 if (this.node.items.size < 1) {
191                         return ret;
192                 }
193                 
194                 for (var i = 0; i < this.node.items.size; i++ ) {
195
196                          this.mungeChild(this.node.items.get(i));
197                          
198                 }
199                 
200                 return ret;
201                 
202
203                  
204
205         }
206
207         public GLib.Value? toValue(string val, string type) {
208
209                 var gtkbuilder = new global::Gtk.Builder();
210
211                 if (type == "utf8") {
212                         var qret = new GLib.Value(typeof(string));
213                         qret.set_string(val);
214                         return qret;
215                 }
216                 
217                 var prop_gtype = gtkbuilder.get_type_from_name(type);
218                 
219
220                 if (prop_gtype == GLib.Type.INVALID) {
221                          
222                         return null;
223                 }
224                 
225                 
226                 var ret = new GLib.Value(prop_gtype);
227
228
229                 switch(type) {
230                         case "gboolean":
231                                 ret.set_boolean(val.down() == "false" ? false : true);
232                                 return ret;
233                         case "guint":
234                                 ret.set_uint(int.parse(val));
235                                 return ret;
236                                 
237                         case "gint":
238                                 ret.set_int(int.parse(val));
239                                 return ret;
240
241                         case "gfloat":
242                                 ret.set_float(long.parse(val));
243                                 return ret;
244                                 
245                         case "utf8":
246                                 ret.set_string(val);
247                                 return ret;
248
249                         default:
250
251                                 var sval =new GLib.Value(typeof(string));
252                                 sval.set_string(val);
253                         
254                                 if (!sval.transform(ref ret)) {
255                                 
256                                         return null;
257                                 }
258                                 return ret;
259                 }
260         }
261         
262          
263           
264                 
265 }