X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6a7e4474cba9d8be4b2ec445e10f1691f7277c50..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/examples/desktop/js/Desktop.js diff --git a/examples/desktop/js/Desktop.js b/examples/desktop/js/Desktop.js old mode 100644 new mode 100755 index 49aae923..614c68fe --- a/examples/desktop/js/Desktop.js +++ b/examples/desktop/js/Desktop.js @@ -1,202 +1,432 @@ /*! - * Ext JS Library 3.2.0 - * Copyright(c) 2006-2010 Ext JS, Inc. - * licensing@extjs.com - * http://www.extjs.com/license + * Ext JS Library 4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license */ -Ext.Desktop = function(app){ - this.taskbar = new Ext.ux.TaskBar(app); - this.xTickSize = this.yTickSize = 1; - var taskbar = this.taskbar; - var desktopEl = Ext.get('x-desktop'); - var taskbarEl = Ext.get('ux-taskbar'); - var shortcuts = Ext.get('x-shortcuts'); +/** + * @class Ext.ux.desktop.Desktop + * @extends Ext.panel.Panel + *

This class manages the wallpaper, shortcuts and taskbar.

+ */ +Ext.define('Ext.ux.desktop.Desktop', { + extend: 'Ext.panel.Panel', - var windows = new Ext.WindowGroup(); - var activeWindow; + alias: 'widget.desktop', - function minimizeWin(win){ - win.minimized = true; - win.hide(); - } + uses: [ + 'Ext.util.MixedCollection', + 'Ext.menu.Menu', + 'Ext.view.View', // dataview + 'Ext.window.Window', + + 'Ext.ux.desktop.TaskBar', + 'Ext.ux.desktop.Wallpaper', + 'Ext.ux.desktop.FitAllLayout' + ], + + activeWindowCls: 'ux-desktop-active-win', + inactiveWindowCls: 'ux-desktop-inactive-win', + lastActiveWindow: null, + + border: false, + html: ' ', + layout: 'fitall', + + xTickSize: 1, + yTickSize: 1, + + app: null, + + /** + * @cfg {Array|Store} shortcuts + * The items to add to the DataView. This can be a {@link Ext.data.Store Store} or a + * simple array. Items should minimally provide the fields in the + * {@link Ext.ux.desktop.ShorcutModel ShortcutModel}. + */ + shortcuts: null, + + /** + * @cfg {String} shortcutItemSelector + * This property is passed to the DataView for the desktop to select shortcut items. + * If the {@link #shortcutTpl} is modified, this will probably need to be modified as + * well. + */ + shortcutItemSelector: 'div.ux-desktop-shortcut', + + /** + * @cfg {String} shortcutTpl + * This XTemplate is used to render items in the DataView. If this is changed, the + * {@link shortcutItemSelect} will probably also need to changed. + */ + shortcutTpl: [ + '', + '
', + '
', + '', + '
', + '{name}', + '
', + '
', + '
' + ], + + /** + * @cfg {Object} taskbarConfig + * The config object for the TaskBar. + */ + taskbarConfig: null, + + windowMenu: null, + + initComponent: function () { + var me = this; - function markActive(win){ - if(activeWindow && activeWindow != win){ - markInactive(activeWindow); + me.windowMenu = new Ext.menu.Menu(me.createWindowMenu()); + + me.bbar = me.taskbar = new Ext.ux.desktop.TaskBar(me.taskbarConfig); + me.taskbar.windowMenu = me.windowMenu; + + me.windows = new Ext.util.MixedCollection(); + + me.contextMenu = new Ext.menu.Menu(me.createDesktopMenu()); + + me.items = [ + { xtype: 'wallpaper', id: me.id+'_wallpaper' }, + me.createDataView() + ]; + + me.callParent(); + + me.shortcutsView = me.items.getAt(1); + me.shortcutsView.on('itemclick', me.onShortcutItemClick, me); + + var wallpaper = me.wallpaper; + me.wallpaper = me.items.getAt(0); + if (wallpaper) { + me.setWallpaper(wallpaper, me.wallpaperStretch); } - taskbar.setActiveButton(win.taskButton); - activeWindow = win; - Ext.fly(win.taskButton.el).addClass('active-win'); - win.minimized = false; - } + }, + + afterRender: function () { + var me = this; + me.callParent(); + me.el.on('contextmenu', me.onDesktopMenu, me); + }, + + //------------------------------------------------------ + // Overrideable configuration creation methods + + createDataView: function () { + var me = this; + return { + xtype: 'dataview', + overItemCls: 'x-view-over', + trackOver: true, + itemSelector: me.shortcutItemSelector, + store: me.shortcuts, + tpl: new Ext.XTemplate(me.shortcutTpl) + }; + }, - function markInactive(win){ - if(win == activeWindow){ - activeWindow = null; - Ext.fly(win.taskButton.el).removeClass('active-win'); + createDesktopMenu: function () { + var me = this, ret = { + items: me.contextMenuItems || [] + }; + + if (ret.items.length) { + ret.items.push('-'); } - } - function removeWin(win){ - taskbar.removeTaskButton(win.taskButton); - layout(); - } + ret.items.push( + { text: 'Tile', handler: me.tileWindows, scope: me, minWindows: 1 }, + { text: 'Cascade', handler: me.cascadeWindows, scope: me, minWindows: 1 }) - function layout(){ - desktopEl.setHeight(Ext.lib.Dom.getViewHeight()-taskbarEl.getHeight()); - } - Ext.EventManager.onWindowResize(layout); + return ret; + }, + + createWindowMenu: function () { + var me = this; + return { + defaultAlign: 'br-tr', + items: [ + { text: 'Restore', handler: me.onWindowMenuRestore, scope: me }, + { text: 'Minimize', handler: me.onWindowMenuMinimize, scope: me }, + { text: 'Maximize', handler: me.onWindowMenuMaximize, scope: me }, + '-', + { text: 'Close', handler: me.onWindowMenuClose, scope: me } + ], + listeners: { + beforeshow: me.onWindowMenuBeforeShow, + hide: me.onWindowMenuHide, + scope: me + } + }; + }, + + //------------------------------------------------------ + // Event handler methods + + onDesktopMenu: function (e) { + var me = this, menu = me.contextMenu; + e.stopEvent(); + if (!menu.rendered) { + menu.on('beforeshow', me.onDesktopMenuBeforeShow, me); + } + menu.showAt(e.getXY()); + menu.doConstrain(); + }, + + onDesktopMenuBeforeShow: function (menu) { + var me = this, count = me.windows.getCount(); + + menu.items.each(function (item) { + var min = item.minWindows || 0; + item.setDisabled(count < min); + }); + }, + + onShortcutItemClick: function (dataView, record) { + var me = this, module = me.app.getModule(record.data.module), + win = module && module.createWindow(); + + if (win) { + me.restoreWindow(win); + } + }, + + onWindowClose: function(win) { + var me = this; + me.windows.remove(win); + me.taskbar.removeTaskButton(win.taskButton); + me.updateActiveWindow(); + }, + + //------------------------------------------------------ + // Window context menu handlers + + onWindowMenuBeforeShow: function (menu) { + var items = menu.items.items, win = menu.theWin; + items[0].setDisabled(win.maximized !== true && win.hidden !== true); // Restore + items[1].setDisabled(win.minimized === true); // Minimize + items[2].setDisabled(win.maximized === true || win.hidden === true); // Maximize + }, + + onWindowMenuClose: function () { + var me = this, win = me.windowMenu.theWin; + + win.close(); + }, + + onWindowMenuHide: function (menu) { + menu.theWin = null; + }, + + onWindowMenuMaximize: function () { + var me = this, win = me.windowMenu.theWin; + + win.maximize(); + }, + + onWindowMenuMinimize: function () { + var me = this, win = me.windowMenu.theWin; + + win.minimize(); + }, + + onWindowMenuRestore: function () { + var me = this, win = me.windowMenu.theWin; + + me.restoreWindow(win); + }, + + //------------------------------------------------------ + // Dynamic (re)configuration methods + + getWallpaper: function () { + return this.wallpaper.wallpaper; + }, - this.layout = layout; + setTickSize: function(xTickSize, yTickSize) { + var me = this, + xt = me.xTickSize = xTickSize, + yt = me.yTickSize = (arguments.length > 1) ? yTickSize : xt; - this.createWindow = function(config, cls){ - var win = new (cls||Ext.Window)( - Ext.applyIf(config||{}, { - renderTo: desktopEl, - manager: windows, + me.windows.each(function(win) { + var dd = win.dd, resizer = win.resizer; + dd.xTickSize = xt; + dd.yTickSize = yt; + resizer.widthIncrement = xt; + resizer.heightIncrement = yt; + }); + }, + + setWallpaper: function (wallpaper, stretch) { + this.wallpaper.setWallpaper(wallpaper, stretch); + return this; + }, + + //------------------------------------------------------ + // Window management methods + + cascadeWindows: function() { + var x = 0, y = 0, + zmgr = this.getDesktopZIndexManager(); + + zmgr.eachBottomUp(function(win) { + if (win.isWindow && win.isVisible() && !win.maximized) { + win.setPosition(x, y); + x += 20; + y += 20; + } + }); + }, + + createWindow: function(config, cls) { + var me = this, win, cfg = Ext.applyIf(config || {}, { + stateful: false, + isWindow: true, + constrainHeader: true, minimizable: true, maximizable: true - }) - ); - win.dd.xTickSize = this.xTickSize; - win.dd.yTickSize = this.yTickSize; - win.resizer.widthIncrement = this.xTickSize; - win.resizer.heightIncrement = this.yTickSize; - win.render(desktopEl); - win.taskButton = taskbar.addTaskButton(win); - - win.cmenu = new Ext.menu.Menu({ - items: [ + }); - ] - }); + cls = cls || Ext.window.Window; + win = me.add(new cls(cfg)); + + me.windows.add(win); + win.taskButton = me.taskbar.addTaskButton(win); win.animateTarget = win.taskButton.el; win.on({ - 'activate': { - fn: markActive - }, - 'beforeshow': { - fn: markActive - }, - 'deactivate': { - fn: markInactive - }, - 'minimize': { - fn: minimizeWin + activate: me.updateActiveWindow, + beforeshow: me.updateActiveWindow, + deactivate: me.updateActiveWindow, + minimize: me.minimizeWindow, + destroy: me.onWindowClose, + scope: me + }); + + win.on({ + afterrender: function () { + win.dd.xTickSize = me.xTickSize; + win.dd.yTickSize = me.yTickSize; + + if (win.resizer) { + win.resizer.widthIncrement = me.xTickSize; + win.resizer.heightIncrement = me.yTickSize; + } }, - 'close': { - fn: removeWin - } + single: true }); - layout(); + // replace normal window close w/fadeOut animation: + win.doClose = function () { + win.el.disableShadow(); + win.el.fadeOut({ + listeners: { + afteranimate: function () { + win.destroy(); + } + } + }); + }; + return win; - }; + }, - this.getManager = function(){ - return windows; - }; + getActiveWindow: function () { + var win = null, + zmgr = this.getDesktopZIndexManager(); - this.getWindow = function(id){ - return windows.get(id); - } + if (zmgr) { + // We cannot rely on activate/deactive because that fires against non-Window + // components in the stack. - this.getWinWidth = function(){ - var width = Ext.lib.Dom.getViewWidth(); - return width < 200 ? 200 : width; - } + zmgr.eachTopDown(function (comp) { + if (comp.isWindow && !comp.hidden) { + win = comp; + return false; + } + return true; + }); + } - this.getWinHeight = function(){ - var height = (Ext.lib.Dom.getViewHeight()-taskbarEl.getHeight()); - return height < 100 ? 100 : height; - } + return win; + }, - this.getWinX = function(width){ - return (Ext.lib.Dom.getViewWidth() - width) / 2 - } + getDesktopZIndexManager: function () { + var windows = this.windows; + // TODO - there has to be a better way to get this... + return (windows.getCount() && windows.getAt(0).zIndexManager) || null; + }, - this.getWinY = function(height){ - return (Ext.lib.Dom.getViewHeight()-taskbarEl.getHeight() - height) / 2; - } + getWindow: function(id) { + return this.windows.get(id); + }, + + minimizeWindow: function(win) { + win.minimized = true; + win.hide(); + }, - this.setTickSize = function(xTickSize, yTickSize) { - this.xTickSize = xTickSize; - if (arguments.length == 1) { - this.yTickSize = xTickSize; + restoreWindow: function (win) { + if (win.isVisible()) { + win.restore(); + win.toFront(); } else { - this.yTickSize = yTickSize; + win.show(); } - windows.each(function(win) { - win.dd.xTickSize = this.xTickSize; - win.dd.yTickSize = this.yTickSize; - win.resizer.widthIncrement = this.xTickSize; - win.resizer.heightIncrement = this.yTickSize; - }, this); - }; - - this.cascade = function() { - var x = 0, y = 0; - windows.each(function(win) { - if (win.isVisible() && !win.maximized) { - win.setPosition(x, y); - x += 20; - y += 20; - } - }, this); - }; - - this.tile = function() { - var availWidth = desktopEl.getWidth(true); - var x = this.xTickSize; - var y = this.yTickSize; - var nextY = y; - windows.each(function(win) { + return win; + }, + + tileWindows: function() { + var me = this, availWidth = me.body.getWidth(true); + var x = me.xTickSize, y = me.yTickSize, nextY = y; + + me.windows.each(function(win) { if (win.isVisible() && !win.maximized) { var w = win.el.getWidth(); -// Wrap to next row if we are not at the line start and this Window will go off the end - if ((x > this.xTickSize) && (x + w > availWidth)) { - x = this.xTickSize; + // Wrap to next row if we are not at the line start and this Window will + // go off the end + if (x > me.xTickSize && x + w > availWidth) { + x = me.xTickSize; y = nextY; } win.setPosition(x, y); - x += w + this.xTickSize; - nextY = Math.max(nextY, y + win.el.getHeight() + this.yTickSize); - } - }, this); - }; - - this.contextMenu = new Ext.menu.Menu({ - items: [{ - text: 'Tile', - handler: this.tile, - scope: this - }, { - text: 'Cascade', - handler: this.cascade, - scope: this - }] - }); - desktopEl.on('contextmenu', function(e) { - e.stopEvent(); - this.contextMenu.showAt(e.getXY()); - }, this); - - layout(); - - if(shortcuts){ - shortcuts.on('click', function(e, t){ - if(t = e.getTarget('dt', shortcuts)){ - e.stopEvent(); - var module = app.getModule(t.id.replace('-shortcut', '')); - if(module){ - module.createWindow(); - } + x += w + me.xTickSize; + nextY = Math.max(nextY, y + win.el.getHeight() + me.yTickSize); } }); + }, + + updateActiveWindow: function () { + var me = this, activeWindow = me.getActiveWindow(), last = me.lastActiveWindow; + if (activeWindow === last) { + return; + } + + if (last) { + if (last.el.dom) { + last.addCls(me.inactiveWindowCls); + last.removeCls(me.activeWindowCls); + } + last.active = false; + } + + me.lastActiveWindow = activeWindow; + + if (activeWindow) { + activeWindow.addCls(me.activeWindowCls); + activeWindow.removeCls(me.inactiveWindowCls); + activeWindow.minimized = false; + activeWindow.active = true; + } + + me.taskbar.setActiveButton(activeWindow && activeWindow.taskButton); } -}; +});