/** * @class Ext.air.NativeWindow * @extends Ext.air.NativeObservable * * Wraps the AIR NativeWindow class to give an Ext friendly API.
This class also adds * automatic state management (position and size) for the window (by id) and it can be used * for easily creating "minimize to system tray" for the main window in your application.
* * Note: Many of the config options for this class can only be applied to NEW windows. Passing * in an existing instance of a window along with those config options will have no effect. * * @constructor * @param {Object} config */ Ext.air.NativeWindow = function(config){ Ext.apply(this, config); /** * @type String */ this.id = this.id || Ext.uniqueId(); this.addEvents( /** * @event close * @param {Object} e The air event object */ 'close', /** * @event closing * @param {Object} e The air event object */ 'closing', /** * @event move * @param {Object} e The air event object */ 'move', /** * @event moving * @param {Object} e The air event object */ 'moving', /** * @event resize * @param {Object} e The air event object */ 'resize', /** * @event resizing * @param {Object} e The air event object */ 'resizing', /** * @event displayStateChange * @param {Object} e The air event object */ 'displayStateChange', /** * @event displayStateChanging * @param {Object} e The air event object */ 'displayStateChanging' ); Ext.air.NativeWindow.superclass.constructor.call(this); if(!this.instance){ var options = new air.NativeWindowInitOptions(); options.systemChrome = this.chrome; options.type = this.type; options.resizable = this.resizable; options.minimizable = this.minimizable; options.maximizable = this.maximizable; options.transparent = this.transparent; this.loader = window.runtime.flash.html.HTMLLoader.createRootWindow(false, options, false); this.loader.load(new air.URLRequest(this.file)); this.instance = this.loader.window.nativeWindow; }else{ this.loader = this.instance.stage.getChildAt(0); } var provider = Ext.state.Manager; var b = air.Screen.mainScreen.visibleBounds; var state = provider.get(this.id) || {}; provider.set(this.id, state); var win = this.instance; var width = Math.max(state.width || this.width, 100); var height = Math.max(state.height || this.height, 100); var centerX = b.x + ((b.width/2)-(width/2)); var centerY = b.y + ((b.height/2)-(height/2)); var x = !Ext.isEmpty(state.x, false) ? state.x : (!Ext.isEmpty(this.x, false) ? this.x : centerX); var y = !Ext.isEmpty(state.y, false) ? state.y : (!Ext.isEmpty(this.y, false) ? this.y : centerY); win.width = width; win.height = height; win.x = x; win.y = y; win.addEventListener('move', function(){ if(win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) { state.x = win.x; state.y = win.y; } }); win.addEventListener('resize', function(){ if (win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) { state.width = win.width; state.height = win.height; } }); Ext.air.NativeWindowManager.register(this); this.on('close', this.unregister, this); /** * @cfg {Boolean} minimizeToTray * True to enable minimizing to the system tray. Note: this should only be applied * to the primary window in your application. A trayIcon is required. */ if(this.minimizeToTray){ this.initMinimizeToTray(this.trayIcon, this.trayMenu); } }; Ext.extend(Ext.air.NativeWindow, Ext.air.NativeObservable, { /** * @cfg {air.NativeWindow} instance * The native window instance to wrap. If undefined, a new window will be created. */ /** * @cfg {String} trayIcon * The icon to display when minimized in the system tray */ /** * @cfg {NativeMenu} trayMenu * Menu to display when the tray icon is right clicked */ /** * @cfg {String} trayTip * Tooltip for the tray icon */ /** * @cfg {String} chrome * The native window chrome (defaults to 'standard', can also be 'none'). */ chrome: 'standard', // can also be none /** * @cfg {String} type * The native window type - normal, utility or lightweight. (defaults to normal) */ type: 'normal', // can be normal, utility or lightweight /** * @cfg {Number} width */ width:600, /** * @cfg {Number} height */ height:400, /** * @cfg {Boolean} resizable */ resizable: true, /** * @cfg {Boolean} minimizable */ minimizable: true, /** * @cfg {Boolean} maximizable */ maximizable: true, /** * @cfg {Boolean} transparent */ transparent: false, /** * Returns the air.NativeWindow instance * @return air.NativeWindow */ getNative : function(){ return this.instance; }, /** * Returns the x/y coordinates for centering the windw on the screen * @return {x: Number, y: Number} */ getCenterXY : function(){ var b = air.Screen.mainScreen.visibleBounds; return { x: b.x + ((b.width/2)-(this.width/2)), y: b.y + ((b.height/2)-(this.height/2)) }; }, /** * Shows the window */ show :function(){ if(this.trayed){ Ext.air.SystemTray.hideIcon(); this.trayed = false; } this.instance.visible = true; }, /** * Shows and activates the window */ activate : function(){ this.show(); this.instance.activate(); }, /** * Hides the window */ hide :function(){ this.instance.visible = false; }, /** * Closes the window */ close : function(){ this.instance.close(); }, /** * Returns true if this window is minimized * @return Boolean */ isMinimized :function(){ return this.instance.displayState == air.NativeWindowDisplayState.MINIMIZED; }, /** * Returns true if this window is maximized * @return Boolean */ isMaximized :function(){ return this.instance.displayState == air.NativeWindowDisplayState.MAXIMIZED; }, /** * Moves the window to the passed xy and y coordinates * @param {Number} x * @param {Number} y */ moveTo : function(x, y){ this.x = this.instance.x = x; this.y = this.instance.y = y; }, /** * @param {Number} width * @param {Number} height */ resize : function(width, height){ this.width = this.instance.width = width; this.height = this.instance.height = height; }, unregister : function(){ Ext.air.NativeWindowManager.unregister(this); }, initMinimizeToTray : function(icon, menu){ var tray = Ext.air.SystemTray; tray.setIcon(icon, this.trayTip); this.on('displayStateChanging', function(e){ if(e.afterDisplayState == 'minimized'){ e.preventDefault(); this.hide(); tray.showIcon(); this.trayed = true; } }, this); tray.on('click', function(){ this.activate(); }, this); if(menu){ tray.setMenu(menu); } } }); /** * Returns the first opened window in your application * @return air.NativeWindow * @static */ Ext.air.NativeWindow.getRootWindow = function(){ return air.NativeApplication.nativeApplication.openedWindows[0]; }; /** * Returns the javascript "window" object of the first opened window in your application * @return Window * @static */ Ext.air.NativeWindow.getRootHtmlWindow = function(){ return Ext.air.NativeWindow.getRootWindow().stage.getChildAt(0).window; }; /** * @class Ext.air.NativeWindowGroup * * A collection of NativeWindows. */ Ext.air.NativeWindowGroup = function(){ var list = {}; return { /** * @param {Object} win */ register : function(win){ list[win.id] = win; }, /** * @param {Object} win */ unregister : function(win){ delete list[win.id]; }, /** * @param {String} id */ get : function(id){ return list[id]; }, /** * Closes all windows */ closeAll : function(){ for(var id in list){ if(list.hasOwnProperty(id)){ list[id].close(); } } }, /** * Executes the specified function once for every window in the group, passing each * window as the only parameter. Returning false from the function will stop the iteration. * @param {Function} fn The function to execute for each item * @param {Object} scope (optional) The scope in which to execute the function */ each : function(fn, scope){ for(var id in list){ if(list.hasOwnProperty(id)){ if(fn.call(scope || list[id], list[id]) === false){ return; } } } } }; }; /** * @class Ext.air.NativeWindowManager * @extends Ext.air.NativeWindowGroup * * Collection of all NativeWindows created. * * @singleton */ Ext.air.NativeWindowManager = new Ext.air.NativeWindowGroup();