/* * * Ext.ux.desktop.Module * */ Ext.define("Ext.ux.desktop.Module", { mixins: { observable: "Ext.util.Observable" }, constructor: function (a) { this.mixins.observable.constructor.call(this, a); this.init() }, init: Ext.emptyFn }); /* * * Ext.ux.desktop.ShortcutModel * */ Ext.define("Ext.ux.desktop.ShortcutModel", { extend: "Ext.data.Model", fields: [ { name: "name" }, { name: "iconCls" }, { name: "module" } ] }); /* * * Ext.ux.desktop.Desktop * */ Ext.define("Ext.ux.desktop.Desktop", { extend: "Ext.panel.Panel", alias: "widget.desktop", uses: ["Ext.util.MixedCollection", "Ext.menu.Menu", "Ext.view.View", "Ext.window.Window", "Ext.ux.desktop.TaskBar", "Ext.ux.desktop.Wallpaper"], activeWindowCls: "ux-desktop-active-win", inactiveWindowCls: "ux-desktop-inactive-win", lastActiveWindow: null, border: false, html: " ", layout: "fit", xTickSize: 1, yTickSize: 1, app: null, shortcuts: null, shortcutItemSelector: "div.ux-desktop-shortcut", mainNavTpl: ["Logout"], shortcutTpl: ['', '
', '', '
', '
', '', "
", '{name}', "
", '
', '
', '
'], taskbarConfig: null, windowMenu: null, initComponent: function () { var b = this; b.windowMenu = new Ext.menu.Menu(b.createWindowMenu()); b.bbar = b.taskbar = new Ext.ux.desktop.TaskBar(b.taskbarConfig); b.taskbar.windowMenu = b.windowMenu; b.windows = new Ext.util.MixedCollection(); b.contextMenu = new Ext.menu.Menu(b.createDesktopMenu()); b.items = [ { xtype: "wallpaper", id: b.id + "_wallpaper" }, b.createDataView() ]; b.callParent(); b.shortcutsView = b.items.getAt(1); b.shortcutsView.on("itemclick", b.onShortcutItemClick, b); var a = b.wallpaper; b.wallpaper = b.items.getAt(0); if (a) { b.setWallpaper(a, b.wallpaperStretch) }; }, afterRender: function () { var a = this; a.callParent(); a.el.on("contextmenu", a.onDesktopMenu, a) }, createDataView: function () { var a = this; return{ xtype: "dataview", overItemCls: "x-view-over", trackOver: true, itemSelector: a.shortcutItemSelector, store: a.shortcuts, style: { position: "absolute" }, x: 0, y: 0, tpl: new Ext.XTemplate(a.shortcutTpl), listeners: { scope: this, 'itemcontextmenu': function (view, record, htmlItem, index, e, options) { e.stopEvent(); } } } }, createMainNavLinks: function () { var a = this; return{ xtype: "dataview", overItemCls: "x-view-over", trackOver: true, itemSelector: a.shortcutItemSelector, store: a.shortcuts, style: { position: "absolute" }, x: 10, y: 10, tpl: new Ext.XTemplate(a.mainNavTpl), listeners: { scope: this, 'itemcontextmenu': function (view, record, htmlItem, index, e, options) { e.stopEvent(); } } } }, addShortcut: function (shortcut) { var a = this; if (a.shortcuts.findExact("module", shortcut.data.module) == -1) { a.shortcuts.add(shortcut); } }, removeShortcut: function (shortcut) { var a = this; var index = a.shortcuts.findExact("module", shortcut.data.module) if (index != -1) { a.shortcuts.removeAt(index); } }, createDesktopMenu: function () { var b = this, a = { items: b.contextMenuItems || [] }; if (a.items.length) { a.items.push("-") } a.items.push( { text: 'Close All', handler: b.closeWindows, scope: b, iconCls: 'icon-delete', minWindows: 1 }, { text: 'Minimize All', handler: b.minimizeWindows, scope: b, iconCls: 'icon-zoom-out', minWindows: 1 }, '-', { text: "Tile", handler: b.tileWindows, scope: b, minWindows: 1 }, { text: "Cascade", handler: b.cascadeWindows, scope: b, minWindows: 1 }, { text: 'Checkerboard', handler: b.checkerboardWindows, scope: b, minWindows: 1, iconCls: 'icon-grid' }, { text: 'Snap Fit', handler: b.snapFitWindows, scope: b, minWindows: 1 }, { text: 'Snap Fit Vertical', handler: b.snapFitVWindows, scope: b, minWindows: 1 }, '-'); return a }, createWindowMenu: function () { var a = this; return{ defaultAlign: "br-tr", items: [ { text: "Restore", handler: a.onWindowMenuRestore, scope: a }, { text: "Minimize", handler: a.onWindowMenuMinimize, scope: a }, { text: "Maximize", handler: a.onWindowMenuMaximize, scope: a }, "-", { text: "Close", handler: a.onWindowMenuClose, scope: a } ], listeners: { beforeshow: a.onWindowMenuBeforeShow, hide: a.onWindowMenuHide, scope: a } } }, onDesktopMenu: function (b) { var a = this, c = a.contextMenu; b.stopEvent(); if (!c.rendered) { c.on("beforeshow", a.onDesktopMenuBeforeShow, a) } c.showAt(b.getXY()); c.doConstrain() }, onDesktopMenuBeforeShow: function (c) { var b = this, a = b.windows.getCount(); c.items.each(function (e) { var d = e.minWindows || 0; e.setDisabled(a < d) }) }, onShortcutItemClick: function (e, a) { var c = this, b = c.app.getModule(a.data.module), d = b && b.createWindow(); if (d) { c.restoreWindow(d) } }, onWindowClose: function (b) { var a = this; a.windows.remove(b); a.taskbar.removeTaskButton(b.taskButton); a.updateActiveWindow() }, onWindowMenuBeforeShow: function (c) { var a = c.items.items, b = c.theWin; a[0].setDisabled(b.maximized !== true && b.hidden !== true); a[1].setDisabled(b.minimized === true); a[2].setDisabled(b.maximized === true || b.hidden === true) }, onWindowMenuClose: function () { var a = this, b = a.windowMenu.theWin; b.close() }, onWindowMenuHide: function (a) { a.theWin = null }, onWindowMenuMaximize: function () { var a = this, b = a.windowMenu.theWin; b.maximize() }, onWindowMenuMinimize: function () { var a = this, b = a.windowMenu.theWin; b.minimize() }, onWindowMenuRestore: function () { var a = this, b = a.windowMenu.theWin; a.restoreWindow(b) }, getWallpaper: function () { return this.wallpaper.wallpaper }, setTickSize: function (b, c) { var e = this, a = e.xTickSize = b, d = e.yTickSize = (arguments.length > 1) ? c : a; e.windows.each(function (g) { var f = g.dd, h = g.resizer; f.xTickSize = a; f.yTickSize = d; h.widthIncrement = a; h.heightIncrement = d }) }, setWallpaper: function (b, a) { this.wallpaper.setWallpaper(b, a); return this }, cascadeWindows: function () { var a = 0, c = 0, b = this.getDesktopZIndexManager(); b.eachBottomUp(function (d) { if (d.isWindow && d.isVisible() && !d.maximized) { d.setPosition(a, c); a += 20; c += 20 } }) }, closeWindows: function () { this.windows.each(function (win) { win.close(); }, this); }, minimizeWindows: function () { this.windows.each(function (win) { this.minimizeWin(win); }, this); }, minimizeWin: function (win) { win.minimized = true; win.hide(); }, tileWindows: function () { var availWidth = this.el.getWidth(true); var x = this.xTickSize; var y = this.yTickSize; var nextY = y; this.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; y = nextY; } win.setPosition(x, y); x += w + this.xTickSize; nextY = Math.max(nextY, y + win.el.getHeight() + this.yTickSize); } }, this); }, checkerboardWindows: function () { var availWidth = this.el.getWidth(true); var availHeight = this.el.getHeight(true); var x = 0, y = 0; var lastx = 0, lasty = 0; // square size should be a value set user? var square = 400; this.windows.each(function (win) { // if (win.isVisible() && !win.maximized) { if (win.isVisible()) { // Subtract padding, should be a value set user? win.setWidth(square - 10); win.setHeight(square - 10); win.setPosition(x, y); x += square; if (x + square > availWidth) { x = lastx; y += square; if (y > availHeight) { lastx += 20; lasty += 20; x = lastx; y = lasty; } } } }, this); }, snapFitWindows: function () { var availWidth = this.el.getWidth(true); var availHeight = this.el.getHeight(true); var x = 0, y = 0; // How to get number of windows? // var snapCount = windows.length; var snapCount = 0; this.windows.each(function (win) { if (win.isVisible()) { snapCount++; } }, this); // above loop seems unnecessary? var snapSize = parseInt(availWidth / snapCount); if (snapSize > 0) { this.windows.each(function (win) { if (win.isVisible()) { // Subtract 10 for padding? win.setWidth(snapSize); win.setHeight(availHeight); win.setPosition(x, y); x += snapSize; } }, this); } }, snapFitVWindows: function () { var availWidth = this.el.getWidth(true); var availHeight = this.el.getHeight(true); var x = 0, y = 0; // How to get number of windows? // var snapCount = windows.length; var snapCount = 0; this.windows.each(function (win) { if (win.isVisible()) { snapCount++; } }, this); // above loop seems unnecessary? var snapSize = parseInt(availHeight / snapCount); if (snapSize > 0) { this.windows.each(function (win) { if (win.isVisible()) { // Subtract 10 for padding? win.setWidth(availWidth); win.setHeight(snapSize); win.setPosition(x, y); y += snapSize; } }, this); } }, createWindow: function (c, b) { var d = this, e, a = Ext.applyIf(c || {}, { stateful: false, isWindow: true, constrainHeader: true, minimizable: true, maximizable: true }); b = b || Compass.ErpApp.Shared.StatusWindow; e = d.add(new b(a)); d.windows.add(e); e.taskButton = d.taskbar.addTaskButton(e); e.animateTarget = e.taskButton.el; e.on({ activate: d.updateActiveWindow, beforeshow: d.updateActiveWindow, deactivate: d.updateActiveWindow, minimize: d.minimizeWindow, destroy: d.onWindowClose, scope: d }); e.on({ boxready: function () { e.dd.xTickSize = d.xTickSize; e.dd.yTickSize = d.yTickSize; if (e.resizer) { e.resizer.widthIncrement = d.xTickSize; e.resizer.heightIncrement = d.yTickSize } }, single: true }); e.doClose = function () { e.doClose = Ext.emptyFn; e.el.disableShadow(); e.el.fadeOut({ listeners: { afteranimate: function () { e.destroy() } } }) }; return e }, getActiveWindow: function () { var b = null, a = this.getDesktopZIndexManager(); if (a) { a.eachTopDown(function (c) { if (c.isWindow && !c.hidden) { b = c; return false } return true }) } return b }, getDesktopZIndexManager: function () { var a = this.windows; return(a.getCount() && a.getAt(0).zIndexManager) || null }, getWindow: function (a) { return this.windows.get(a) }, minimizeWindow: function (a) { a.minimized = true; a.hide() }, restoreWindow: function (a) { if (a.isVisible()) { a.restore(); a.toFront() } else { a.show() } return a }, tileWindows: function () { var b = this, e = b.body.getWidth(true); var a = b.xTickSize, d = b.yTickSize, c = d; b.windows.each(function (g) { if (g.isVisible() && !g.maximized) { var f = g.el.getWidth(); if (a > b.xTickSize && a + f > e) { a = b.xTickSize; d = c } g.setPosition(a, d); a += f + b.xTickSize; c = Math.max(c, d + g.el.getHeight() + b.yTickSize) } }) }, updateActiveWindow: function () { var b = this, c = b.getActiveWindow(), a = b.lastActiveWindow; if (c === a) { return } if (a) { if (a.el.dom) { a.addCls(b.inactiveWindowCls); a.removeCls(b.activeWindowCls) } a.active = false } b.lastActiveWindow = c; if (c) { c.addCls(b.activeWindowCls); c.removeCls(b.inactiveWindowCls); c.minimized = false; c.active = true } b.taskbar.setActiveButton(c && c.taskButton) } }); /* * * Ext.ux.desktop.App * */ Ext.define("Ext.ux.desktop.App", { mixins: { observable: "Ext.util.Observable" }, requires: ["Ext.container.Viewport", "Ext.ux.desktop.Desktop"], isReady: false, modules: null, useQuickTips: true, constructor: function (a) { var b = this; b.addEvents("ready", "beforeunload"); b.mixins.observable.constructor.call(this, a); if (Ext.isReady) { Ext.Function.defer(b.init, 10, b) } else { Ext.onReady(b.init, b) } }, init: function () { var b = this, a; if (b.useQuickTips) { Ext.QuickTips.init() } b.modules = b.getModules(); if (b.modules) { b.initModules(b.modules) } a = b.getDesktopConfig(); b.desktop = new Ext.ux.desktop.Desktop(a); b.viewport = Ext.create("Ext.container.Viewport", { layout: "fit", items: [b.desktop] }); Ext.EventManager.on(window, "beforeunload", b.onUnload, b); b.isReady = true; b.fireEvent("ready", b) }, getDesktopConfig: function () { var b = this, a = { app: b, taskbarConfig: b.getTaskbarConfig() }; Ext.apply(a, b.desktopConfig); return a }, getModules: Ext.emptyFn, getStartConfig: function () { var b = this, a = { app: b, menu: [] }; Ext.apply(a, b.startConfig); Ext.each(b.modules, function (c) { if (c.launcher) { a.menu.push(c.launcher) } }); return a }, getTaskbarConfig: function () { var b = this, a = { app: b, startConfig: b.getStartConfig() }; Ext.apply(a, b.taskbarConfig); return a }, initModules: function (a) { var b = this; Ext.each(a, function (c) { c.app = b }) }, getModule: function (d) { var c = this.modules; for (var e = 0, b = c.length; e < b; e++) { var a = c[e]; if (a.id == d || a.appType == d) { return a } } return null }, onReady: function (b, a) { if (this.isReady) { b.call(a, this) } else { this.on({ ready: b, scope: a, single: true }) } }, getDesktop: function () { return this.desktop }, onUnload: function (a) { if (this.fireEvent("beforeunload", this) === false) { a.stopEvent() } } }); /* * * MyDesktop.WallpaperModel * */ Ext.define("MyDesktop.WallpaperModel", { extend: "Ext.data.Model", fields: [ { name: "text" }, { name: "img" } ] }); /* * * Ext.ux.desktop.Wallpaper * */ Ext.define("Ext.ux.desktop.Wallpaper", { extend: "Ext.Component", alias: "widget.wallpaper", cls: "ux-wallpaper", html: '', stretch: false, wallpaper: null, afterRender: function () { var a = this; a.callParent(); a.setWallpaper(a.wallpaper, a.stretch) }, applyState: function () { var b = this, a = b.wallpaper; b.callParent(arguments); if (a != b.wallpaper) { b.setWallpaper(b.wallpaper) } }, getState: function () { return this.wallpaper && { wallpaper: this.wallpaper } }, setWallpaper: function (b, a) { var c = this, e, d; c.stretch = (a !== false); c.wallpaper = b; if (c.rendered) { e = c.el.dom.firstChild; if (!b || b == Ext.BLANK_IMAGE_URL) { Ext.fly(e).hide() } else { if (c.stretch) { e.src = b; c.el.removeCls("ux-wallpaper-tiled"); Ext.fly(e).setStyle({ width: "100%", height: "100%" }).show() } else { Ext.fly(e).hide(); d = "url(" + b + ")"; c.el.addCls("ux-wallpaper-tiled") } } c.el.setStyle({ backgroundImage: d || "" }) } return c } }); /* * * Ext.ux.desktop.StartMenu * */ Ext.define("Ext.ux.desktop.StartMenu", { extend: "Ext.panel.Panel", requires: ["Ext.menu.Menu", "Ext.toolbar.Toolbar"], ariaRole: "menu", cls: "x-menu ux-start-menu", defaultAlign: "bl-tl", iconCls: "gear", floating: true, shadow: true, width: 300, initComponent: function () { var a = this, b = a.menu; a.menu = new Ext.menu.Menu({ cls: "ux-start-menu-body", border: false, floating: false, autoScroll: true, items: b }); a.menu.layout.align = "stretch"; a.items = [a.menu]; a.layout = "fit"; Ext.menu.Manager.register(a); a.callParent(); a.toolbar = new Ext.toolbar.Toolbar(Ext.apply({ dock: "right", cls: "ux-start-menu-toolbar", vertical: true, width: 100 }, a.toolConfig)); a.toolbar.layout.align = "stretch"; a.addDocked(a.toolbar); delete a.toolItems; a.on("deactivate", function () { a.hide() }); }, addMenuItem: function () { var a = this.menu; a.add.apply(a, arguments) }, addToolItem: function () { var a = this.toolbar; a.add.apply(a, arguments) }, showBy: function (c, f, e) { var b = this; if (b.floating && c) { b.layout.autoSize = true; b.show(); c = c.el || c; var d = b.el.getAlignToXY(c, f || b.defaultAlign, e); if (b.floatParent) { var a = b.floatParent.getTargetEl().getViewRegion(); d[0] -= a.x; d[1] -= a.y } b.showAt(d); b.doConstrain() } return b } }); /* * * Ext.ux.desktop.TaskBar * */ Ext.define("Ext.ux.desktop.TaskBar", { extend: "Ext.toolbar.Toolbar", id: 'desktop-start-menu', //ui: 'cleantoolbar-dark', requires: ["Ext.button.Button", "Ext.resizer.Splitter", "Ext.menu.Menu", "Ext.ux.desktop.StartMenu"], alias: "widget.taskbar", cls: "ux-taskbar", startBtnText: "Start", initComponent: function () { var a = this; a.startMenu = Ext.create('Ext.ux.desktop.StartMenu', a.startConfig); a.windowBar = Ext.create('Ext.toolbar.Toolbar', a.getWindowBarConfig()); a.tray = new Ext.create('Ext.toolbar.Toolbar', a.getTrayConfig()); a.items = [ { xtype: "button", //ui:'cleanbutton', cls: "ux-start-button", iconCls: "ux-start-button-icon", menu: a.startMenu, menuAlign: "bl-tl", text: a.startBtnText }, { xtype: "splitter", html: " ", height: 14, width: 2, cls: "x-toolbar-separator x-toolbar-separator-horizontal" }, a.windowBar, "-", a.tray ]; a.callParent() }, afterLayout: function () { var a = this; a.callParent(); a.windowBar.el.on("contextmenu", a.onButtonContextMenu, a) }, getQuickStart: function () { var b = this, a = { ui:'cleantoolbar-dark', minWidth: 20, width: 60, items: [], enableOverflow: true }; Ext.each(this.quickStart, function (c) { a.items.push({ tooltip: { text: c.name, align: "bl-tl" }, overflowText: c.name, iconCls: c.iconCls, module: c.module, handler: b.onQuickStartClick, scope: b }) }); return a }, getTrayConfig: function () { var a = { width: 80, items: this.trayItems }; delete this.trayItems; return a }, getWindowBarConfig: function () { return{ flex: 1, cls: "ux-desktop-windowbar", items: [" "], layout: { overflowHandler: "Scroller" } } }, getWindowBtnFromEl: function (a) { var b = this.windowBar.getChildByElement(a); return b || null }, onQuickStartClick: function (b) { var a = this.app.getModule(b.module); if (a) { a.createWindow() } }, onButtonContextMenu: function (d) { var c = this, b = d.getTarget(), a = c.getWindowBtnFromEl(b); if (a) { d.stopEvent(); c.windowMenu.theWin = a.win; c.windowMenu.showBy(b) } }, onWindowBtnClick: function (a) { var b = a.win; if (b.minimized || b.hidden) { b.show() } else { if (b.active) { b.minimize() } else { b.toFront() } } }, addTaskButton: function (c) { var a = { iconCls: c.iconCls, ui:'cleanbutton', enableToggle: true, toggleGroup: "all", width: 140, text: Ext.util.Format.ellipsis(c.title, 20), listeners: { click: this.onWindowBtnClick, scope: this }, win: c }; var b = this.windowBar.add(a); b.toggle(true); return b }, removeTaskButton: function (a) { var c, b = this; b.windowBar.items.each(function (d) { if (d === a) { c = d } return !c }); if (c) { b.windowBar.remove(c) } return c }, setActiveButton: function (a) { if (a) { a.toggle(true) } else { this.windowBar.items.each(function (b) { if (b.isButton) { b.toggle(false) } }) } } });