Builder/RightGtkView.js
[app.Builder.js] / Builder / RightGtkView.js
1 //<script type="text/javascript">
2 Gio = imports.gi.Gio;
3 Gtk = imports.gi.Gtk;
4 Gdk = imports.gi.Gdk;
5 GObject = imports.gi.GObject;
6  
7
8 /**
9 * we use a hidden window to render the created dialog...
10 * then use snapshot to render it to an image...
11
12 */
13  
14
15 XObject = imports.XObject.XObject;
16 File = imports.File.File;
17 console = imports.console;
18
19 LeftTree = imports.Builder.LeftTree.LeftTree ;
20 LeftPanel = imports.Builder.LeftPanel.LeftPanel;
21  //console.dump(imports.Builder.LeftTree);
22  //Seed.quit();
23
24 RightGtkView = new XObject({
25         xtype : Gtk.VBox,
26         lastSrc : '',
27         pack : [ 'append_page', new Gtk.Label({ label : "Gtk View" })  ],
28         items : [
29         
30             {
31                 xtype: Gtk.HBox,
32                 pack : [ 'pack_start', false, true, 0 ],
33                 items : [       
34                     {
35                         
36                         
37                         xtype: Gtk.Button,
38                         label : 'Show in New Window',
39                         pack : [ 'pack_start', false, false, 0 ],
40                         listeners : {
41                             // pressed...
42                             'button-press-event' : function(w, ev ){
43                                 /// dump..
44                                 RightGtkView.showInWindow();
45                                 return true;
46                                 // show the MidPropTree..
47                             }
48                           
49                         }
50                     }
51                 ]
52             }, 
53             {
54             
55                      
56                 renderedData : false, 
57                 xtype: Gtk.ScrolledWindow,
58                
59                 smooth_scroll : true,
60                 shadow_type : Gtk.ShadowType.IN ,
61                 init : function() {
62                     XObject.prototype.init.call(this); 
63                      
64                     this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
65                 },
66                 
67                 items : [
68                 
69                 
70                     {
71                         id : 'view',
72                         xtype : function() {
73                             return new Gtk.Image.from_stock (Gtk.STOCK_HOME, 100) 
74
75                         },
76                         packing : ['add' ],
77                         ready : false,
78                         init : function() {
79                             XObject.prototype.init.call(this); 
80                             // fixme!
81                            
82                             Gtk.drag_dest_set
83                             (
84                                     this.el,              /* widget that will accept a drop */
85                                     Gtk.DestDefaults.MOTION  | Gtk.DestDefaults.HIGHLIGHT,
86                                     null,            /* lists of target to support */
87                                     0,              /* size of list */
88                                     Gdk.DragAction.COPY         /* what to do with data after dropped */
89                             );
90                             
91                            // print("RB: TARGETS : " + LeftTree.atoms["STRING"]);
92                             Gtk.drag_dest_set_target_list(this.el, LeftTree.targetList);
93                             //Gtk.drag_dest_add_text_targets(this.el);
94                         },   
95                         listeners : {
96                             
97                               
98                             
99                             "drag-leave" : function () {
100                                 Seed.print("TARGET: drag-leave");
101                                 // stop monitoring of mouse montion in rendering..
102                                 return true;
103                             },
104                             'drag-motion' : function (w, ctx,  x,   y,   time, ud) 
105                             {
106                                 
107                             
108                                // console.log('DRAG MOTION'); 
109                                 // status:
110                                 // if lastCurrentNode == this.currentNode.. -- don't change anything..
111                                  
112                                 
113                                 // A) find out from drag all the places that node could be dropped.
114                                 var src = Gtk.drag_get_source_widget(ctx);
115                                 if (!src.dropList) {
116                                     Gdk.drag_status(ctx, 0, time);
117                                     return true;
118                                 }
119                                 // b) get what we are over.. (from activeNode)
120                                 // tree is empty.. - list should be correct..
121                                 if (!LeftTree.get('model').currentTree) {
122                                     Gdk.drag_status(ctx, Gdk.DragAction.COPY,time);
123                                     return true;
124                                     
125                                 }
126                                 // c) ask tree where it should be dropped... - eg. parent.. (after node ontop)
127                                 var activeNode = this.getActiveNode(x, y);
128                                 
129                                 
130                                 var tg = LeftTree.get('model').findDropNode(activeNode, src.dropList);
131                                 console.dump(tg);
132                                 if (!tg.length) {
133                                     Gdk.drag_status(ctx, 0,time);
134                                     LeftTree.get('view').highlight(false);
135                                     return true;
136                                 }
137                                  
138                                 // if we have a target..
139                                 // -> highlight it! (in browser)
140                                 // -> highlight it! (in tree)
141                                 
142                                 Gdk.drag_status(ctx, Gdk.DragAction.COPY,time);
143                                 LeftTree.get('view').highlight(tg);
144                                 this.targetData = tg;
145                                 // for tree we should handle this...
146                                 return true;
147                                 
148                             },
149                             "drag-drop"  : function (w, ctx,x,y,time, ud) 
150                             {
151                                         
152                                 Seed.print("TARGET: drag-drop");
153                                 is_valid_drop_site = true;
154                                 
155                                  
156                                 Gtk.drag_get_data
157                                 (
158                                         w,         /* will receive 'drag-data-received' signal */
159                                         ctx,        /* represents the current state of the DnD */
160                                         LeftTree.atoms["STRING"],    /* the target type we want */
161                                         time            /* time stamp */
162                                 );
163                                 
164                                 
165                                 /* No target offered by source => error */
166                                
167
168                                 return  is_valid_drop_site;
169                                 
170
171                             },
172                             "drag-data-received" : function (w, ctx,  x,  y, sel_data,  target_type,  time, ud) 
173                             {
174                                 Seed.print("GtkView: drag-data-received");
175                                 delete_selection_data = false;
176                                 dnd_success = false;
177                                 /* Deal with what we are given from source */
178                                 if( sel_data && sel_data.length ) {
179                                     
180                                     if (ctx.action == Gdk.DragAction.ASK)  {
181                                         /* Ask the user to move or copy, then set the ctx action. */
182                                     }
183
184                                     if (ctx.action == Gdk.DragAction.MOVE) {
185                                         delete_selection_data = true;
186                                     }
187                                     var source = Gtk.drag_get_source_widget(ctx);
188
189                                     Seed.print("Browser: source.DRAGDATA? " + source.dragData);
190                                     if (this.targetData) {
191                                         Seed.print(this.targetData);
192                                         LeftTree.get('model').dropNode(this.targetData,  source.dragData);
193                                     }
194                                     
195                                     
196                                     
197                                     dnd_success = true;
198          
199                                 }
200
201                                 if (dnd_success == false)
202                                 {
203                                         Seed.print ("DnD data transfer failed!\n");
204                                 }
205                                 
206                                 Gtk.drag_finish (ctx, dnd_success, delete_selection_data, time);
207                                 return true;
208                             }
209                             
210                            //'line-mark-activated' : line_mark_activated,
211                            
212                             
213                         },
214                          
215                         getActiveNode : function(x,y)
216                         {
217                            // workout what node is here..
218                             return '0'; // top..
219                         }
220                     }
221                 ]
222             }
223                 
224         ],
225         
226         showInWindow: function ()
227         {
228             var src= this.lastSrc;
229             if (!this.lastSrc.length) {
230                 return;
231                }
232             var x = new imports.sandbox.Context();
233             x.add_globals();
234             print(src);
235             try {
236                 x.eval(src);
237             } catch( e) {
238                 print(e.toString());
239                 return;
240             }
241              
242             var _top = x.get_global_object()._top;
243             
244             _top.el.set_screen(Gdk.Screen.get_default()); // just in case..
245             _top.el.show_all();
246             if (_top.el.popup) {
247                 _top.el.popup(null, null, null, null, 3, null);
248             }
249         },
250         
251         buildJS: function(data) {
252             var i = [ 'Gtk', 'Gdk', 'Pango' ];
253             var src = "";
254             i.forEach(function(e) {
255                 src += e+" = imports.gi." + e +";\n";
256             });
257             src += "XObject = imports.XObject.XObject;\n"; // path?!!?
258             
259             src += '_top=new XObject('+ this.mungeToString(data) + ')\n;';
260             src += '_top.init();\n';
261             print(src);
262             this.lastSrc = src;
263             return src;
264         },
265         
266         renderJS : function(data)
267         {
268             // can we mess with data?!?!?
269             
270             /**
271              * first effort..
272              * sandbox it? - nope then will have dificulting passing. stuff aruond..
273              * 
274              */
275             if (!data) {
276                  return; 
277             }
278             var src = this.buildJS(data);
279             var x = new imports.sandbox.Context();
280             x.add_globals();
281             //x.get_global_object().a = "hello world";
282             
283             try {
284                 x.eval(src);
285             } catch( e) {
286                print(e.toString());
287                return;
288             }
289             
290             var r = new Gdk.Rectangle();
291             var _top = x.get_global_object()._top;
292             
293             _top.el.set_screen(Gdk.Screen.get_default()); // just in case..
294             _top.el.show_all();
295             if (_top.el.popup) {
296                 _top.el.popup(null, null, null, null, 3, null);
297             }
298             
299             
300             
301             var pb = _top.el.get_snapshot(r);
302             if (!pb) {
303                 return;
304             }
305             _top.el.hide();
306             _top.el.destroy();
307             x._top = false;
308             var Window = imports.Builder.Window.Window;
309             var gc = new Gdk.GC.c_new(Window.el.window);
310                 
311                 // 10 points all round..
312             var full = new Gdk.Pixmap.c_new (Window.el.window, r.width+20, r.height+20, pb.get_depth());
313             // draw a white background..
314            // gc.set_rgb_fg_color({ red: 0, white: 0, black : 0 });
315             Gdk.draw_rectangle(full, gc, true, 0, 0, r.width+20, r.height+20);
316             // paint image..
317             Gdk.draw_drawable (full, gc, pb, 0, 0, 10, 10, r.width, r.height);
318             // boxes..
319             //gc.set_rgb_fg_color({ red: 255, white: 255, black : 255 });
320             Gdk.draw_rectangle(full, gc, true, 0, 0, 10, 10);
321             this.get('view').el.set_from_pixmap(full, null);
322             //var img = new Gtk.Image.from_file("/home/alan/solarpanels.jpeg");
323             
324             
325             
326         },
327         mungeToString:  function(obj, isListener)
328         {
329             var keys = [];
330             var isArray = false;
331             isListener = isListener || false;
332             
333             if (obj.constructor.toString() === Array.toString()) {
334                 for (var i= 0; i < obj.length; i++) {
335                     keys.push(i);
336                 }
337                 isArray = true;
338             } else {
339                 for (var i in obj) {
340                     keys.push(i);
341                 }
342             }
343             var els = [];
344             var skip = [];
345             if (!isArray && 
346                     typeof(obj['|xns']) != 'undefined' &&
347                     typeof(obj['xtype']) != 'undefined'
348                 ) {
349                     els.push('xtype: '+ obj['|xns'] + '.' + obj['xtype']);
350                     skip.push('|xns','xtype');
351                 }
352             
353             var _this = this;
354             
355             keys.forEach(function(i) {
356                 var el = obj[i];
357                 if (!isArray && skip.indexOf(i) > -1) {
358                     return;
359                 }
360                 if (isListener) {
361                     els.push(JSON.stringify(i) + ":" + obj[i]);
362                     return;
363                 }
364                 if (typeof(i) == 'string' && i[0] == '|') {
365                     // does not hapepnd with arrays..
366                     els.push(JSON.stringify(i.substring(1)) + ":" + obj[i]);
367                     return;
368                 }
369                 var left = isArray ? '' : (JSON.stringify(i) + " : " )
370                 if (typeof(el) == 'object') {
371                     els.push(left + _this.mungeToString(el, i == 'listeners'));
372                     return;
373                 }
374                 els.push(JSON.stringify(i) + ":" + JSON.stringify(obj[i]));
375             });
376             return (isArray ? '[' : '{') + 
377                 els.join(', ') +
378                 (isArray ? ']' : '}');
379                
380                 
381              
382             
383             
384         }
385         
386     }
387     
388     
389 );
390