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