Upgrade to ExtJS 3.1.0 - Released 12/16/2009
[extjs.git] / src / widgets / WindowManager.js
1 /*!
2  * Ext JS Library 3.1.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**
8  * @class Ext.WindowGroup
9  * An object that manages a group of {@link Ext.Window} instances and provides z-order management
10  * and window activation behavior.
11  * @constructor
12  */
13 Ext.WindowGroup = function(){
14     var list = {};
15     var accessList = [];
16     var front = null;
17
18     // private
19     var sortWindows = function(d1, d2){
20         return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
21     };
22
23     // private
24     var orderWindows = function(){
25         var a = accessList, len = a.length;
26         if(len > 0){
27             a.sort(sortWindows);
28             var seed = a[0].manager.zseed;
29             for(var i = 0; i < len; i++){
30                 var win = a[i];
31                 if(win && !win.hidden){
32                     win.setZIndex(seed + (i*10));
33                 }
34             }
35         }
36         activateLast();
37     };
38
39     // private
40     var setActiveWin = function(win){
41         if(win != front){
42             if(front){
43                 front.setActive(false);
44             }
45             front = win;
46             if(win){
47                 win.setActive(true);
48             }
49         }
50     };
51
52     // private
53     var activateLast = function(){
54         for(var i = accessList.length-1; i >=0; --i) {
55             if(!accessList[i].hidden){
56                 setActiveWin(accessList[i]);
57                 return;
58             }
59         }
60         // none to activate
61         setActiveWin(null);
62     };
63
64     return {
65         /**
66          * The starting z-index for windows in this WindowGroup (defaults to 9000)
67          * @type Number The z-index value
68          */
69         zseed : 9000,
70
71         /**
72          * <p>Registers a {@link Ext.Window Window} with this WindowManager. This should not
73          * need to be called under normal circumstances. Windows are automatically registered
74          * with a {@link Ext.Window#manager manager} at construction time.</p>
75          * <p>Where this may be useful is moving Windows between two WindowManagers. For example,
76          * to bring the Ext.MessageBox dialog under the same manager as the Desktop's
77          * WindowManager in the desktop sample app:</p><code><pre>
78 var msgWin = Ext.MessageBox.getDialog();
79 MyDesktop.getDesktop().getManager().register(msgWin);
80 </pre></code>
81          * @param {Window} win The Window to register.
82          */
83         register : function(win){
84             if(win.manager){
85                 win.manager.unregister(win);
86             }
87             win.manager = this;
88
89             list[win.id] = win;
90             accessList.push(win);
91             win.on('hide', activateLast);
92         },
93
94         /**
95          * <p>Unregisters a {@link Ext.Window Window} from this WindowManager. This should not
96          * need to be called. Windows are automatically unregistered upon destruction.
97          * See {@link #register}.</p>
98          * @param {Window} win The Window to unregister.
99          */
100         unregister : function(win){
101             delete win.manager;
102             delete list[win.id];
103             win.un('hide', activateLast);
104             accessList.remove(win);
105         },
106
107         /**
108          * Gets a registered window by id.
109          * @param {String/Object} id The id of the window or a {@link Ext.Window} instance
110          * @return {Ext.Window}
111          */
112         get : function(id){
113             return typeof id == "object" ? id : list[id];
114         },
115
116         /**
117          * Brings the specified window to the front of any other active windows in this WindowGroup.
118          * @param {String/Object} win The id of the window or a {@link Ext.Window} instance
119          * @return {Boolean} True if the dialog was brought to the front, else false
120          * if it was already in front
121          */
122         bringToFront : function(win){
123             win = this.get(win);
124             if(win != front){
125                 win._lastAccess = new Date().getTime();
126                 orderWindows();
127                 return true;
128             }
129             return false;
130         },
131
132         /**
133          * Sends the specified window to the back of other active windows in this WindowGroup.
134          * @param {String/Object} win The id of the window or a {@link Ext.Window} instance
135          * @return {Ext.Window} The window
136          */
137         sendToBack : function(win){
138             win = this.get(win);
139             win._lastAccess = -(new Date().getTime());
140             orderWindows();
141             return win;
142         },
143
144         /**
145          * Hides all windows in this WindowGroup.
146          */
147         hideAll : function(){
148             for(var id in list){
149                 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
150                     list[id].hide();
151                 }
152             }
153         },
154
155         /**
156          * Gets the currently-active window in this WindowGroup.
157          * @return {Ext.Window} The active window
158          */
159         getActive : function(){
160             return front;
161         },
162
163         /**
164          * Returns zero or more windows in this WindowGroup using the custom search function passed to this method.
165          * The function should accept a single {@link Ext.Window} reference as its only argument and should
166          * return true if the window matches the search criteria, otherwise it should return false.
167          * @param {Function} fn The search function
168          * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the Window being tested.
169          * that gets passed to the function if not specified)
170          * @return {Array} An array of zero or more matching windows
171          */
172         getBy : function(fn, scope){
173             var r = [];
174             for(var i = accessList.length-1; i >=0; --i) {
175                 var win = accessList[i];
176                 if(fn.call(scope||win, win) !== false){
177                     r.push(win);
178                 }
179             }
180             return r;
181         },
182
183         /**
184          * Executes the specified function once for every window in this WindowGroup, passing each
185          * window as the only parameter. Returning false from the function will stop the iteration.
186          * @param {Function} fn The function to execute for each item
187          * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the current Window in the iteration.
188          */
189         each : function(fn, scope){
190             for(var id in list){
191                 if(list[id] && typeof list[id] != "function"){
192                     if(fn.call(scope || list[id], list[id]) === false){
193                         return;
194                     }
195                 }
196             }
197         }
198     };
199 };
200
201
202 /**
203  * @class Ext.WindowMgr
204  * @extends Ext.WindowGroup
205  * The default global window group that is available automatically.  To have more than one group of windows
206  * with separate z-order stacks, create additional instances of {@link Ext.WindowGroup} as needed.
207  * @singleton
208  */
209 Ext.WindowMgr = new Ext.WindowGroup();