All of my work from commits: dd4a194, 692644a, 4a60203, 5de46bc, 152042d, 64a2d4e...
[philo.git] / contrib / gilbert / media / gilbert / lib / app.js
diff --git a/contrib/gilbert/media/gilbert/lib/app.js b/contrib/gilbert/media/gilbert/lib/app.js
new file mode 100644 (file)
index 0000000..2c3f59c
--- /dev/null
@@ -0,0 +1,346 @@
+Ext.ns('Gilbert.lib.app')
+
+
+Gilbert.lib.app.Desktop = Ext.extend(Ext.Panel, {
+       
+       constructor: function(application, config) {
+               var application = this.application = application;
+               Gilbert.lib.app.Desktop.superclass.constructor.call(this, Ext.applyIf(config||{}, {
+                       region: 'center',
+                       border: false,
+                       padding: '5px',
+                       bodyStyle: 'background: none;',
+               }));
+       },
+       
+});
+
+
+Gilbert.lib.app.MainMenu = Ext.extend(Ext.Toolbar, {
+       
+       constructor: function(application, config) {
+               var application = this.application = application;
+               Gilbert.lib.app.MainMenu.superclass.constructor.call(this, Ext.applyIf(config||{}, {
+                       region: 'north',
+                       autoHeight: true,
+                       items: [
+                               {
+                                       xtype: 'tbtext',
+                                       text: '<span style="font-weight: bolder; text-transform: uppercase;">Gilbert</span>',
+                               },
+                               {
+                                       xtype: 'tbseparator',
+                               },
+                       ],
+               }));
+       },
+       
+});
+
+
+Gilbert.lib.app.TaskBar = Ext.extend(Ext.Toolbar, {
+       
+       constructor: function(application, config) {
+               var application = this.application = application;
+               Gilbert.lib.app.TaskBar.superclass.constructor.call(this, Ext.applyIf(config||{}, {
+                       region: 'south',
+                       enableOverflow: true,
+                       autoHeight: true,
+                       items: [],
+                       plugins: [
+                               new Ext.ux.ToolbarReorderer({
+                                       defaultReorderable: true,
+                               }),
+                       ],
+               }));
+       },
+       
+       get_button_for_window: function(win) {
+               return this.find('represented_window', win)[0];
+       },
+       
+       default_button_handler: function(button) {
+               var win = button.represented_window;
+               if (this.active_window === win) {
+                       win.minimize();
+               } else {
+                       win.show();
+               }
+       },
+       
+       register_window: function(win) {
+               win.on('show', this.window_shown, this);
+               win.on('hide', this.window_hidden, this);
+               win.on('minimize', this.window_minimize, this);
+               win.on('deactivate', this.window_deactivated, this);
+               win.on('activate', this.window_activated, this);
+               win.on('titlechange', this.window_titlechanged, this);
+               win.on('iconchange', this.window_iconchanged, this);
+               
+               var button = new Ext.Button({
+                       text: win.title,
+                       iconCls: win.iconCls,
+                       enableToggle: true,
+                       allowDepress: false,
+                       width: 200,
+                       hidden: true,
+               });
+               button.represented_window = win;
+               button.setHandler(this.default_button_handler, this);
+               
+               this.add(button);
+               
+               win.on('destroy', this.window_destroyed, this);
+       },
+       
+       window_destroyed: function(win) {
+               this.remove(this.get_button_for_window(win));
+               this.application.do_layout();
+       },
+       
+       window_shown: function(win) {
+               if (this.minimizing_window !== win) {
+                       this.get_button_for_window(win).show();
+                       this.application.do_layout();
+               }
+       },
+       
+       window_hidden: function(win) {
+               if (this.minimizing_window !== win) {
+                       this.get_button_for_window(win).hide();
+                       this.application.do_layout();
+               }
+       },
+       
+       window_minimize: function(win) {
+               var button = this.get_button_for_window(win);
+               
+               this.minimizing_window = win;
+               win.hide(button.el, function () {
+                       this.minimizing_window = undefined;
+                       
+                       win.minimized = true;
+                       button.setText('<i>'+win.title+'</i>');
+                       button.setHandler(function (button) {
+                               var win = button.represented_window;
+                               
+                               win.minimized = false;
+                               button.setText(win.title);
+                               button.setHandler(this.default_button_handler, this);
+                               
+                               this.minimizing_window = win;
+                               win.show(button.el, function () {
+                                       this.minimizing_window = undefined;
+                               }, this);
+                       }, this);
+               }, this);
+       },
+       
+       window_deactivated: function(win) {
+               var button = this.get_button_for_window(win);
+               button.toggle(false);
+               button.setText(win.title);
+               
+               if (this.active_window === win) {
+                       this.active_window = undefined;
+               }
+       },
+       
+       window_activated: function(win) {
+               var button = this.get_button_for_window(win);
+               button.toggle(true);
+               button.setText('<b>'+win.title+'</b>');
+               
+               this.active_window = win;
+       },
+       
+       window_titlechanged: function(win) {
+               var button = this.get_button_for_window(win);
+               if (win.minimized) {
+                       button.setText('<i>'+win.title+'</i>');
+               } else {
+                       button.setText(win.title);
+               }
+       },
+       
+       window_iconchanged: function(win) {
+               var button = this.get_button_for_window(win);
+               button.setIconClass(win.iconCls);
+       },
+       
+});
+
+
+Gilbert.lib.app.Application = Ext.extend(Ext.util.Observable, {
+       
+       constructor: function (config) {
+               
+               this.models = {};
+               this.plugins = {};
+               
+               Ext.apply(this, config, {
+                       renderTo: Ext.getBody(),
+               });
+               
+               Gilbert.lib.app.Application.superclass.constructor.call(this);
+               
+               this.addEvents({
+                       'ready': true,
+                       'model_registered': true,
+                       'plugin_registered': true,
+                       'window_created': true,
+               });
+               
+               Ext.onReady(this.pre_init.createDelegate(this));
+       },
+       
+       pre_init: function () {
+               var outer = this;
+               
+               Gilbert.api.plugins.auth.get_preference('gilbert.background', function (background) {
+                       if (background) {
+                               outer.renderTo.setStyle('background', background);
+                       }
+               });
+               Gilbert.api.plugins.auth.get_preference('gilbert.theme', function (theme) {
+                       if (theme) {
+                               var link_element = document.getElementById('gilbert.theme.' + theme);
+                               if (link_element) {
+                                       Ext.each(document.getElementsByClassName('gilbert.theme'), function (theme_element) {
+                                               if (theme_element != link_element) {
+                                                       theme_element.disabled = true;
+                                               } else {
+                                                       theme_element.disabled = false;
+                                               }
+                                       });
+                               }
+                       }
+                       outer.init();
+               });
+       },
+       
+       init: function () {
+               Ext.QuickTips.init();
+               
+               var desktop = this.desktop = new Gilbert.lib.app.Desktop();
+               var mainmenu = this.mainmenu = new Gilbert.lib.app.MainMenu(this);
+               var taskbar = this.taskbar = new Gilbert.lib.app.TaskBar(this);
+               var viewport = this.viewport = new Ext.Viewport({
+                       renderTo: this.renderTo,
+                       layout: 'border',
+                       items: [
+                               this.mainmenu,
+                               this.desktop,
+                               this.taskbar,
+                       ],
+               });
+               
+               var windows = this.windows = new Ext.WindowGroup();
+               
+               Ext.Direct.on('exception', function (exception) {
+                       if (exception.code == Ext.Direct.exceptions.TRANSPORT) {
+                               if (exception.xhr.status == 403) {
+                                       window.alert('You have been unexpectedly logged out.');
+                                       window.location.reload(true);
+                               }
+                       }
+                       if (exception.html) {
+                               var win = this.create_window({
+                                       width: 400,
+                                       height: 300,
+                                       maximizable: true,
+                                       minimizable: false,
+                                       modal: true,
+                                       html_source: exception.html,
+                               }, Gilbert.lib.ui.HTMLWindow);
+                               win.show();
+                       }
+               }, this);
+               
+               var initial_plugins = this.plugins;
+               this.plugins = {};
+               
+               Ext.iterate(initial_plugins, function (name, plugin, plugins) {
+                       this.register_plugin(name, plugin);
+               }, this);
+               
+               this.do_layout();
+               
+               this.renderTo.on('contextmenu', Ext.emptyFn, null, {preventDefault: true});
+               
+               window.onbeforeunload = function (event) {
+                       var notice = 'You will lose all unsaved changes and windows.';
+                       var event = event || window.event;
+                       if (event) {
+                               event.returnValue = notice;
+                       }
+               
+                       return notice;
+               };
+               
+               this.fireEvent('ready', this);
+       },
+       
+       create_window: function(config, cls) {
+               var win = new(cls||Ext.Window)(Ext.applyIf(config||{},{
+                       renderTo: this.desktop.el,
+                       manager: this.windows,
+                       minimizable: true,
+                       constrainHeader: true,
+               }));
+               win.render(this.desktop.el);
+               if (win.modal) {
+                       win.on('show', function () {
+                               this.mainmenu.hide();
+                               this.taskbar.hide();
+                               this.do_layout();
+                       }, this);
+                       win.on('hide', function () {
+                               this.taskbar.show();
+                               this.mainmenu.show();
+                               this.do_layout();
+                       }, this);
+                       win.on('close', function () {
+                               this.taskbar.show();
+                               this.mainmenu.show();
+                               this.do_layout();
+                       }, this);
+               }
+               this.taskbar.register_window(win);
+               this.fireEvent('window_created', win);
+               return win;
+       },
+       
+       do_layout: function() {
+               this.mainmenu.doLayout();
+               this.taskbar.doLayout();
+               this.viewport.doLayout();
+       },
+       
+       register_plugin: function (name, plugin) {
+               if (plugin.init(this) != false) {
+                       this.plugins[name] = plugin;
+                       this.fireEvent('plugin_registered', name, plugin, this);
+               }
+       },
+       
+       get_plugin: function (name) {
+               return this.plugins[name];
+       },
+       
+       register_model: function (app_label, name, model) {
+               if (!this.models[app_label]) {
+                       this.models[app_label] = {};
+               }
+               this.models[app_label][name] = model;
+               this.fireEvent('model_registered', name, model, this);
+       },
+       
+       get_model: function (app_label, name) {
+               if (!this.models[app_label]) {
+                       return undefined;
+               }
+               return this.models[app_label][name];
+       },
+       
+});
\ No newline at end of file