99c8b632cd30f6145d4768918c3087ceb7539a5a
[app.Builder.js] / Builder / LeftPanel.js
1 //<Script type="text/javascript">
2 Gio = imports.gi.Gio;
3 Gtk = imports.gi.Gtk;
4 Gdk = imports.gi.Gdk;
5 GLib = imports.gi.GLib;
6 GObject = imports.gi.GObject;
7 Pango = imports.gi.Pango ;
8
9 XObject = imports.XObject.XObject;
10 console = imports.console;
11
12
13 LeftPanelPopup  = imports.Builder.LeftPanelPopup.LeftPanelPopup;
14 RightEditor     = imports.Builder.RightEditor.RightEditor;
15 /**
16  * 
17  * really the properties..
18  */
19
20
21 LeftPanel = new XObject({
22         
23         xtype: Gtk.ScrolledWindow,
24         smooth_scroll : true,
25         pack : [ 'pack_end', true, true, 0 ],
26         shadow_type : Gtk.ShadowType.IN,
27         
28         init : function () {
29             XObject.prototype.init.call(this); 
30             this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
31         },
32         items : [
33             {
34                 id : 'view',
35                 
36                 xtype : Gtk.TreeView,
37                 
38                 tooltip_column : 1,
39                 headers_visible :   false ,
40                 enable_tree_lines :  true ,
41                      
42                 init : function () {
43                     XObject.prototype.init.call(this); 
44                        
45                     this.selection = this.el.get_selection();
46                     this.selection.set_mode( Gtk.SelectionMode.SINGLE);
47                  
48                     
49                     var description = new Pango.FontDescription.c_new();
50                     description.set_size(8000);
51                     this.el.modify_font(description);
52                 },     
53                 listeners : {
54                     
55                   
56                     'button-press-event' : function(tv, ev) {
57                         if (ev.type != Gdk.EventType.BUTTON_PRESS  || ev.button.button != 3) {
58                             Seed.print("click" + ev.type);
59                             return false;
60                         }
61                       
62                     
63                         var res = { }; 
64                         this.el.get_path_at_pos(ev.button.x,ev.button.y, res);
65                         
66                         if (res.column.title == 'value') {
67                             return false;
68                         }
69                         if (!LeftPanelPopup.el) LeftPanelPopup.init();
70                         LeftPanelPopup.el.set_screen(Gdk.Screen.get_default());
71                         LeftPanelPopup.el.show_all();
72                         LeftPanelPopup.el.popup(null, null, null, null, 3, ev.button.time);
73                         Seed.print("click:" + res.column.title);
74                         return false;
75                         
76                     }
77                 },
78                 items : [
79                 
80                     {
81                         id : 'model',
82                         pack : [ 'set_model' ],
83                         xtype : Gtk.ListStore,
84                         
85                         init : function ()
86                         {
87                             XObject.prototype.init.call(this); 
88                             this.el.set_column_types ( 5, [
89                                 GObject.TYPE_STRING,  // 0 real key
90                                 GObject.TYPE_STRING, // 1 real value 
91                                  GObject.TYPE_STRING,  // 2 visable key
92                                  GObject.TYPE_STRING, // 3 visable value
93                                  GObject.TYPE_STRING, // 4 need to store type of!!!
94                               
95                             ]);
96                                     
97                             
98                          
99                         },
100                         toShort: function(str) {
101                             var a = typeof(str) == 'string' ? str.split("\n") : [];
102                             return a.length > 1 ? a[0] + '....' : '' + str;
103                         },
104                         load : function (ar)
105                         {
106                             this.el.clear();
107                             
108                             RightEditor.el.hide();
109                             if (ar === false) {
110                                 return ;
111                             }
112                             var ret = {}; 
113                             
114                             // sort!!!?
115                             var iter = new Gtk.TreeIter();
116                             for (var i in ar) {
117                                 if (typeof(ar[i]) == 'object') {
118                                     continue;
119                                 }
120                                 this.el.append(iter);
121                                 var p = this.el.get_path(iter).to_string();
122                                 ret[i] = p;
123                                 this.el.set_value(iter, 0, i);
124                                 this.el.set_value(iter, 1, '' + ar[i]);
125                                 this.el.set_value(iter, 2, i);
126                                 this.el.set_value(iter, 3, this.toShort(ar[i]));
127                                 this.el.set_value(iter, 4, typeof(ar[i]));
128                             }
129                             ar.listeners = ar.listeners || {};
130                             for (var i in ar.listeners ) {
131                                 this.el.append(iter);
132                                 var p = this.el.get_path(iter).to_string();
133                                 ret['!' + i] = p;
134                                 
135                                 this.el.set_value(iter, 0, '!'+  i  );
136                                 this.el.set_value(iter, 1, '' + ar.listeners[i]);
137                                 this.el.set_value(iter, 2, '<b>'+ i + '</b>');
138                                 
139                                 this.el.set_value(iter, 3, '' + this.toShort(ar.listeners[i]));
140                                 this.el.set_value(iter, 4, typeof(ar[i]));
141                             }
142                             return ret;
143                         },
144                         
145                         
146                         
147                         add : function( info ) {
148                             // info includes key, val, skel, etype..
149                              console.dump(info);
150                             type = info.type.toLowerCase();
151                             var data = this.toJS();
152                             
153                             if (info.etype == 'events') {
154                                 data.listeners = data.listeners || { };
155                                 if (typeof(data.listeners[info.key]) != 'undefined') {
156                                     return; //already set!
157                                 }
158                             } else {
159                                 if (typeof(data[info.key]) != 'undefined') {
160                                     return;
161                                 }
162                             }
163                             
164                             if (typeof(info.val) == 'undefined') {
165                                     
166                                 info.val = '';
167                                 if (info.type == 'boolean') {
168                                     info.val = true;
169                                 }
170                                 if (type == 'number') {
171                                     info.val = 0;
172                                 }
173                                 // utf8 == string..
174                                 
175                                 
176                             }
177                             var k = info.key;
178                             if (info.etype == 'events') {
179                              
180                                 data.listeners[info.key] = info.val;
181                                 k = '!' + info.key;
182                             } else {
183                                 data[info.key] = info.val;
184                             }
185                             
186                             
187                             var map = this.load(data);
188                             
189                             var LeftTree        = imports.Builder.LeftTree.LeftTree;
190                             
191                             LeftTree.get('model').changed(data, true); 
192                             //LeftPanel.get('view').selection.select_path(new Gtk.TreePath.from_string(map[k]));
193                             //this.editSelected( true )
194                              GLib.timeout_add(0, 100, function() {
195                                 
196                                 LeftPanel.get('view').el.set_cursor_on_cell(
197                                     new Gtk.TreePath.from_string(map[k]), 
198                                     LeftPanel.editableColumn.el,
199                                     LeftPanel.editableColumn.items[0].el,
200                                     true);
201                             });
202                             /*
203                             LeftPanel.get('view').el.row_activated(
204                                 new Gtk.TreePath.from_string(map[k]), 
205                                 LeftPanel.editableColumn.el
206                             );
207                             */
208                             
209                             
210                         },
211                         deleteSelected : function()
212                         {
213                             var data = this.toJS();
214                             var iter = new Gtk.TreeIter();
215                             var s = LeftPanel.get('view').selection;
216                             s.get_selected(this.el, iter);
217                                  
218                                
219                             var gval = new GObject.Value('');
220                             LeftPanel.get('model').el.get_value(iter, 0 ,gval);
221                             
222                             var val = gval.value;
223                             if (val[0] == '!') {
224                                 // listener..
225                                 if (!data.listeners || typeof(data.listeners[  val.substring(1)]) == 'undefined') {
226                                     return;
227                                 }
228                                 delete data.listeners[  val.substring(1)];
229                                 if (!XObject.keys(data.listeners).length) {
230                                     delete data.listeners;
231                                 }
232                                 
233                             } else {
234                                 if (typeof(data[val]) == 'undefined') {
235                                     return;
236                                 }
237                                 delete data[val];
238                             }
239                             
240                             
241                             this.load(data);
242                             var LeftTree        = imports.Builder.LeftTree.LeftTree;
243                             LeftTree.get('model').changed(data, true);
244                             
245                         },
246                         
247                         
248                         
249                         activePath : false,
250                         changed : function(str, doRefresh)
251                         {
252                             if (!this.activePath) {
253                                 return;
254                             }
255                             var iter = new Gtk.TreeIter();
256                             this.el.get_iter(iter, new Gtk.TreePath.from_string(this.activePath));
257                             
258                             this.el.set_value(iter, 1, '' +str);
259                             this.el.set_value(iter, 3, '' + this.toShort(str));
260                             // update the tree...
261                             var LeftTree        = imports.Builder.LeftTree.LeftTree;
262                             LeftTree.get('model').changed(this.toJS(), doRefresh); 
263                         },
264                         toJS: function()
265                         {
266                             var iter = new Gtk.TreeIter();
267                             LeftPanel.get('model').el.get_iter_first(iter);
268                             var ar = {};
269                                
270                             while (true) {
271                                 
272                                 var k = this.getValue(iter, 0);
273                                 Seed.print(k);
274                                 if (k[0] == '!') {
275                                     ar.listeners = ar.listeners || {};
276                                     ar.listeners[  k.substring(1)] = this.getValue(iter, 1);
277                                     
278                                 } else {
279                                     ar[ k ] = this.getValue(iter, 1);
280                                 }
281                                 
282                                 if (! LeftPanel.get('model').el.iter_next(iter)) {
283                                     break;
284                                 }
285                             }
286                                 Seed.print(JSON.stringify(ar));
287                             return ar;
288                             // convert the list into a json string..
289                         
290                             
291                         },
292                         /** get's a value, and tries to use type column to work out what type */
293                         getValue: function (iter, col) {
294                             var gval = new GObject.Value('');
295                             LeftPanel.get('model').el.get_value(iter, col ,gval);
296                             var val = '' + gval.value;
297                             if (col != 1) {
298                                 return val;
299                             }
300                             gval = new GObject.Value('');
301                             LeftPanel.get('model').el.get_value(iter,4  ,gval);
302                             switch(gval.value) {
303                                 case 'number':
304                                     return parseFloat(val);
305                                 case 'boolean':
306                                     return val == 'true' ? true : false;
307                                 default: 
308                                     return val;
309                             }
310                             
311                         },
312                         
313                         editSelected: function( e)
314                         {
315                             print("EDIT SELECTED?");
316                             var iter = new Gtk.TreeIter();
317                             var s = LeftPanel.get('view').selection;
318                             s.get_selected(LeftPanel.get('model').el, iter);
319                             var m = LeftPanel.get('model');
320                            
321                             var gval = new GObject.Value('');
322                             this.el.get_value(iter, 0 ,gval);
323                             var val = '' + gval.value;
324                             
325                             gval = new GObject.Value('');
326                             this.el.get_value(iter, 1 ,gval);
327                             var rval = gval.value;
328                             var activePath = this.el.get_path(iter).to_string(); 
329                             this.activePath = activePath ;
330                             // was activeIter...
331                             //  not listener...
332                             
333                             var showEditor = false;
334                             
335                             if (val[0] == '!') {
336                                 showEditor = true;
337                             }
338                             if (val[0] == '|') {
339                                 if (rval.match(/function/g) || rval.match(/\n/g)) {
340                                     showEditor = true;
341                                 }
342                             }
343                             
344                             if (showEditor) {
345                                 var _this = this;
346                                 this.activePath = false;
347                                 GLib.timeout_add(0, 1, function() {
348                                     //   Gdk.threads_enter();
349                                     RightEditor.el.show();
350                                     RightEditor.get('view').load( rval );
351                                     
352                                     e.editing_done();
353                                     e.remove_widget();
354                                     _this.activePath = activePath ;
355                                     
356                              //       Gdk.threads_leave();
357                                     return false;
358                                 });
359                                 return;
360                             }
361                              
362                             RightEditor.el.hide();
363
364                             var type = this.getValue(iter,4);
365                             print("type = " + type);
366                             // toggle boolean
367                             if (type == 'boolean') {
368                                 // let's show a pulldown..
369                                 LeftPanel.editableColumn.setOptions([ 'true' , 'false']);
370                                 
371                                 return;
372                                 val = ! this.getValue(iter,1);
373                                 
374                                 this.activePath = false;
375                                 var _this = this;
376                                 GLib.timeout_add(0, 1, function() {
377                                     //   Gdk.threads_enter();
378                                      
379                                     e.editing_done();
380                                     e.remove_widget();
381                                     _this.activePath = activePath ;
382                                     _this.changed(''+val,true);
383                                     
384                              
385                                     return false;
386                                 });
387                             }
388                             
389                              // otherwise we are going to show the text editor..   
390                              
391                             
392                             //r.stop_editing(true);
393                        
394                         }
395                           
396                         
397                     },
398
399                     {
400                         
401                         xtype: Gtk.TreeViewColumn,
402                         pack : ['append_column'],
403                         title : 'key',
404                         init : function ()
405                         {
406                             XObject.prototype.init.call(this); 
407                             this.el.add_attribute(this.items[0].el , 'markup', 2 );
408                             
409                         },
410                         items : [
411                             {
412                                 xtype : Gtk.CellRendererText,
413                                 pack : ['pack_start'],
414                             }
415                         ]
416                     },
417                             
418                     {
419                         
420                         xtype: Gtk.TreeViewColumn,
421                         pack : ['append_column'],
422                         title : 'value',
423                         init : function ()
424                         {
425                             XObject.prototype.init.call(this); 
426                             this.el.add_attribute(this.items[0].el , 'text', 3 );
427                            // this.el.set_cell_data_func(cell, age_cell_data_func, NULL, NULL);
428
429                             LeftPanel.editableColumn= this;
430                         },
431                         setOptions : function(ar)
432                         {
433                             this.items[0].el.has_entry = false; // stop editable.
434                            //this.items[0].el.editable = false;
435                             var m = this.items[0].el.model;
436                             m.clear();
437                             var iter = new Gtk.TreeIter();
438                             ar.forEach(function(i) {
439                                    // sort!!!?
440                                 m.append(iter);
441                                 m.set_value(iter, 0, i);
442                             });
443                             
444                             
445                           
446                         },
447                         listeners :  {
448                             clicked : function () {
449                                 this.items[0].el.has_entry = false;
450                             }
451                         },
452                         items : [
453                         /*
454                          
455                             {
456                                 
457                                 xtype : Gtk.CellRendererText,
458                                 pack : ['pack_start'],
459                                 editable : true,
460                                 
461                                  
462                                 listeners : {
463  
464                                     edited : function(r,p, t) {
465                                         LeftPanel.get('model').changed(t, true);
466                                         LeftPanel.get('model').activePath = false;
467                                         
468                                     },
469                                    
470                                     'editing-started' : function(r, e, p) {
471                                         LeftPanel.get('model').editSelected(e);
472                                     }    
473                                 },
474                                 
475                             },
476                             */
477                             {
478                                 
479                                 xtype : function() {
480                                     var  ret = new Gtk.CellRendererCombo();
481                                     ret.model = new Gtk.ListStore();
482                                     ret.model.set_column_types ( 1, [
483                                         GObject.TYPE_STRING,  // 0 real key
484                                         
485                                     ]);
486                                     
487                                     return  ret;
488                                 },
489                                 pack : ['pack_start'],
490                                 editable : true,
491                                 has_entry : true,
492                                 text_column : 0,
493                                 listeners : {
494  
495                                     edited : function(r,p, t) {
496                                         LeftPanel.get('model').changed(t, true);
497                                         LeftPanel.get('model').activePath = false;
498                                         
499                                     },
500                                    
501                                     'editing-started' : function(r, e, p) {
502                                         this.el.has_entry = false;
503                                         LeftPanel.get('model').editSelected(e);
504                                     }    
505                                 },
506                                 
507                                 
508                             }
509                         ]
510                     }
511                 
512                 ]
513             }
514         ]    
515             
516     }
517 );
518     
519      
520