All of my work from commits: dd4a194, 692644a, 4a60203, 5de46bc, 152042d, 64a2d4e...
[philo.git] / contrib / gilbert / media / gilbert / lib / app.js
1 Ext.ns('Gilbert.lib.app')
2
3
4 Gilbert.lib.app.Desktop = Ext.extend(Ext.Panel, {
5         
6         constructor: function(application, config) {
7                 var application = this.application = application;
8                 Gilbert.lib.app.Desktop.superclass.constructor.call(this, Ext.applyIf(config||{}, {
9                         region: 'center',
10                         border: false,
11                         padding: '5px',
12                         bodyStyle: 'background: none;',
13                 }));
14         },
15         
16 });
17
18
19 Gilbert.lib.app.MainMenu = Ext.extend(Ext.Toolbar, {
20         
21         constructor: function(application, config) {
22                 var application = this.application = application;
23                 Gilbert.lib.app.MainMenu.superclass.constructor.call(this, Ext.applyIf(config||{}, {
24                         region: 'north',
25                         autoHeight: true,
26                         items: [
27                                 {
28                                         xtype: 'tbtext',
29                                         text: '<span style="font-weight: bolder; text-transform: uppercase;">Gilbert</span>',
30                                 },
31                                 {
32                                         xtype: 'tbseparator',
33                                 },
34                         ],
35                 }));
36         },
37         
38 });
39
40
41 Gilbert.lib.app.TaskBar = Ext.extend(Ext.Toolbar, {
42         
43         constructor: function(application, config) {
44                 var application = this.application = application;
45                 Gilbert.lib.app.TaskBar.superclass.constructor.call(this, Ext.applyIf(config||{}, {
46                         region: 'south',
47                         enableOverflow: true,
48                         autoHeight: true,
49                         items: [],
50                         plugins: [
51                                 new Ext.ux.ToolbarReorderer({
52                                         defaultReorderable: true,
53                                 }),
54                         ],
55                 }));
56         },
57         
58         get_button_for_window: function(win) {
59                 return this.find('represented_window', win)[0];
60         },
61         
62         default_button_handler: function(button) {
63                 var win = button.represented_window;
64                 if (this.active_window === win) {
65                         win.minimize();
66                 } else {
67                         win.show();
68                 }
69         },
70         
71         register_window: function(win) {
72                 win.on('show', this.window_shown, this);
73                 win.on('hide', this.window_hidden, this);
74                 win.on('minimize', this.window_minimize, this);
75                 win.on('deactivate', this.window_deactivated, this);
76                 win.on('activate', this.window_activated, this);
77                 win.on('titlechange', this.window_titlechanged, this);
78                 win.on('iconchange', this.window_iconchanged, this);
79                 
80                 var button = new Ext.Button({
81                         text: win.title,
82                         iconCls: win.iconCls,
83                         enableToggle: true,
84                         allowDepress: false,
85                         width: 200,
86                         hidden: true,
87                 });
88                 button.represented_window = win;
89                 button.setHandler(this.default_button_handler, this);
90                 
91                 this.add(button);
92                 
93                 win.on('destroy', this.window_destroyed, this);
94         },
95         
96         window_destroyed: function(win) {
97                 this.remove(this.get_button_for_window(win));
98                 this.application.do_layout();
99         },
100         
101         window_shown: function(win) {
102                 if (this.minimizing_window !== win) {
103                         this.get_button_for_window(win).show();
104                         this.application.do_layout();
105                 }
106         },
107         
108         window_hidden: function(win) {
109                 if (this.minimizing_window !== win) {
110                         this.get_button_for_window(win).hide();
111                         this.application.do_layout();
112                 }
113         },
114         
115         window_minimize: function(win) {
116                 var button = this.get_button_for_window(win);
117                 
118                 this.minimizing_window = win;
119                 win.hide(button.el, function () {
120                         this.minimizing_window = undefined;
121                         
122                         win.minimized = true;
123                         button.setText('<i>'+win.title+'</i>');
124                         button.setHandler(function (button) {
125                                 var win = button.represented_window;
126                                 
127                                 win.minimized = false;
128                                 button.setText(win.title);
129                                 button.setHandler(this.default_button_handler, this);
130                                 
131                                 this.minimizing_window = win;
132                                 win.show(button.el, function () {
133                                         this.minimizing_window = undefined;
134                                 }, this);
135                         }, this);
136                 }, this);
137         },
138         
139         window_deactivated: function(win) {
140                 var button = this.get_button_for_window(win);
141                 button.toggle(false);
142                 button.setText(win.title);
143                 
144                 if (this.active_window === win) {
145                         this.active_window = undefined;
146                 }
147         },
148         
149         window_activated: function(win) {
150                 var button = this.get_button_for_window(win);
151                 button.toggle(true);
152                 button.setText('<b>'+win.title+'</b>');
153                 
154                 this.active_window = win;
155         },
156         
157         window_titlechanged: function(win) {
158                 var button = this.get_button_for_window(win);
159                 if (win.minimized) {
160                         button.setText('<i>'+win.title+'</i>');
161                 } else {
162                         button.setText(win.title);
163                 }
164         },
165         
166         window_iconchanged: function(win) {
167                 var button = this.get_button_for_window(win);
168                 button.setIconClass(win.iconCls);
169         },
170         
171 });
172
173
174 Gilbert.lib.app.Application = Ext.extend(Ext.util.Observable, {
175         
176         constructor: function (config) {
177                 
178                 this.models = {};
179                 this.plugins = {};
180                 
181                 Ext.apply(this, config, {
182                         renderTo: Ext.getBody(),
183                 });
184                 
185                 Gilbert.lib.app.Application.superclass.constructor.call(this);
186                 
187                 this.addEvents({
188                         'ready': true,
189                         'model_registered': true,
190                         'plugin_registered': true,
191                         'window_created': true,
192                 });
193                 
194                 Ext.onReady(this.pre_init.createDelegate(this));
195         },
196         
197         pre_init: function () {
198                 var outer = this;
199                 
200                 Gilbert.api.plugins.auth.get_preference('gilbert.background', function (background) {
201                         if (background) {
202                                 outer.renderTo.setStyle('background', background);
203                         }
204                 });
205                 Gilbert.api.plugins.auth.get_preference('gilbert.theme', function (theme) {
206                         if (theme) {
207                                 var link_element = document.getElementById('gilbert.theme.' + theme);
208                                 if (link_element) {
209                                         Ext.each(document.getElementsByClassName('gilbert.theme'), function (theme_element) {
210                                                 if (theme_element != link_element) {
211                                                         theme_element.disabled = true;
212                                                 } else {
213                                                         theme_element.disabled = false;
214                                                 }
215                                         });
216                                 }
217                         }
218                         outer.init();
219                 });
220         },
221         
222         init: function () {
223                 Ext.QuickTips.init();
224                 
225                 var desktop = this.desktop = new Gilbert.lib.app.Desktop();
226                 var mainmenu = this.mainmenu = new Gilbert.lib.app.MainMenu(this);
227                 var taskbar = this.taskbar = new Gilbert.lib.app.TaskBar(this);
228                 var viewport = this.viewport = new Ext.Viewport({
229                         renderTo: this.renderTo,
230                         layout: 'border',
231                         items: [
232                                 this.mainmenu,
233                                 this.desktop,
234                                 this.taskbar,
235                         ],
236                 });
237                 
238                 var windows = this.windows = new Ext.WindowGroup();
239                 
240                 Ext.Direct.on('exception', function (exception) {
241                         if (exception.code == Ext.Direct.exceptions.TRANSPORT) {
242                                 if (exception.xhr.status == 403) {
243                                         window.alert('You have been unexpectedly logged out.');
244                                         window.location.reload(true);
245                                 }
246                         }
247                         if (exception.html) {
248                                 var win = this.create_window({
249                                         width: 400,
250                                         height: 300,
251                                         maximizable: true,
252                                         minimizable: false,
253                                         modal: true,
254                                         html_source: exception.html,
255                                 }, Gilbert.lib.ui.HTMLWindow);
256                                 win.show();
257                         }
258                 }, this);
259                 
260                 var initial_plugins = this.plugins;
261                 this.plugins = {};
262                 
263                 Ext.iterate(initial_plugins, function (name, plugin, plugins) {
264                         this.register_plugin(name, plugin);
265                 }, this);
266                 
267                 this.do_layout();
268                 
269                 this.renderTo.on('contextmenu', Ext.emptyFn, null, {preventDefault: true});
270                 
271                 window.onbeforeunload = function (event) {
272                         var notice = 'You will lose all unsaved changes and windows.';
273                         var event = event || window.event;
274                         if (event) {
275                                 event.returnValue = notice;
276                         }
277                 
278                         return notice;
279                 };
280                 
281                 this.fireEvent('ready', this);
282         },
283         
284         create_window: function(config, cls) {
285                 var win = new(cls||Ext.Window)(Ext.applyIf(config||{},{
286                         renderTo: this.desktop.el,
287                         manager: this.windows,
288                         minimizable: true,
289                         constrainHeader: true,
290                 }));
291                 win.render(this.desktop.el);
292                 if (win.modal) {
293                         win.on('show', function () {
294                                 this.mainmenu.hide();
295                                 this.taskbar.hide();
296                                 this.do_layout();
297                         }, this);
298                         win.on('hide', function () {
299                                 this.taskbar.show();
300                                 this.mainmenu.show();
301                                 this.do_layout();
302                         }, this);
303                         win.on('close', function () {
304                                 this.taskbar.show();
305                                 this.mainmenu.show();
306                                 this.do_layout();
307                         }, this);
308                 }
309                 this.taskbar.register_window(win);
310                 this.fireEvent('window_created', win);
311                 return win;
312         },
313         
314         do_layout: function() {
315                 this.mainmenu.doLayout();
316                 this.taskbar.doLayout();
317                 this.viewport.doLayout();
318         },
319         
320         register_plugin: function (name, plugin) {
321                 if (plugin.init(this) != false) {
322                         this.plugins[name] = plugin;
323                         this.fireEvent('plugin_registered', name, plugin, this);
324                 }
325         },
326         
327         get_plugin: function (name) {
328                 return this.plugins[name];
329         },
330         
331         register_model: function (app_label, name, model) {
332                 if (!this.models[app_label]) {
333                         this.models[app_label] = {};
334                 }
335                 this.models[app_label][name] = model;
336                 this.fireEvent('model_registered', name, model, this);
337         },
338         
339         get_model: function (app_label, name) {
340                 if (!this.models[app_label]) {
341                         return undefined;
342                 }
343                 return this.models[app_label][name];
344         },
345         
346 });