3 * Copyright(c) 2006-2010 Ext JS, Inc.
5 * http://www.extjs.com/license
8 * @class Ext.ux.TaskBar
9 * @extends Ext.util.Observable
11 Ext.ux.TaskBar = function(app){
16 Ext.extend(Ext.ux.TaskBar, Ext.util.Observable, {
18 this.startMenu = new Ext.ux.StartMenu(Ext.apply({
24 }, this.app.startConfig));
26 this.startBtn = new Ext.Button({
32 renderTo: 'ux-taskbar-start',
33 clickEvent: 'mousedown',
34 template: new Ext.Template(
35 '<table cellspacing="0" class="x-btn"><tbody class="{1}"><tr>',
36 '<td class="ux-startbutton-left"><i> </i></td>',
37 '<td class="ux-startbutton-center"><em class="{2} unselectable="on">',
38 '<button class="x-btn-text" type="{0}" style="height:30px;"></button>',
40 '<td class="ux-startbutton-right"><i> </i></td>',
41 '</tr></tbody></table>')
44 var width = this.startBtn.getEl().getWidth()+10;
46 var sbBox = new Ext.BoxComponent({
47 el: 'ux-taskbar-start',
55 this.tbPanel = new Ext.ux.TaskButtonsPanel({
56 el: 'ux-taskbuttons-panel',
61 var container = new Ext.ux.TaskBarContainer({
64 items: [sbBox,this.tbPanel]
70 addTaskButton : function(win){
71 return this.tbPanel.addButton(win, 'ux-taskbuttons-panel');
74 removeTaskButton : function(btn){
75 this.tbPanel.removeButton(btn);
78 setActiveButton : function(btn){
79 this.tbPanel.setActiveButton(btn);
86 * @class Ext.ux.TaskBarContainer
87 * @extends Ext.Container
89 Ext.ux.TaskBarContainer = Ext.extend(Ext.Container, {
90 initComponent : function() {
91 Ext.ux.TaskBarContainer.superclass.initComponent.call(this);
93 this.el = Ext.get(this.el) || Ext.getBody();
94 this.el.setHeight = Ext.emptyFn;
95 this.el.setWidth = Ext.emptyFn;
96 this.el.setSize = Ext.emptyFn;
102 this.el.dom.scroll = 'no';
103 this.allowDomMove = false;
104 this.autoWidth = true;
105 this.autoHeight = true;
106 Ext.EventManager.onWindowResize(this.fireResize, this);
107 this.renderTo = this.el;
110 fireResize : function(w, h){
111 this.onResize(w, h, w, h);
112 this.fireEvent('resize', this, w, h, w, h);
119 * @class Ext.ux.TaskButtonsPanel
120 * @extends Ext.BoxComponent
122 Ext.ux.TaskButtonsPanel = Ext.extend(Ext.BoxComponent, {
126 scrollRepeatInterval: 400,
133 buttonWidthSet: false,
135 initComponent : function() {
136 Ext.ux.TaskButtonsPanel.superclass.initComponent.call(this);
137 this.on('resize', this.delegateUpdates);
140 this.stripWrap = Ext.get(this.el).createChild({
141 cls: 'ux-taskbuttons-strip-wrap',
143 tag:'ul', cls:'ux-taskbuttons-strip'
146 this.stripSpacer = Ext.get(this.el).createChild({
147 cls:'ux-taskbuttons-strip-spacer'
149 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
151 this.edge = this.strip.createChild({
153 cls:'ux-taskbuttons-edge'
155 this.strip.createChild({
160 addButton : function(win){
161 var li = this.strip.createChild({tag:'li'}, this.edge); // insert before the edge
162 var btn = new Ext.ux.TaskBar.TaskButton(win, li);
164 this.items.push(btn);
166 if(!this.buttonWidthSet){
167 this.lastButtonWidth = btn.container.getWidth();
170 this.setActiveButton(btn);
174 removeButton : function(btn){
175 var li = document.getElementById(btn.container.id);
177 li.parentNode.removeChild(li);
180 for(var i = 0, len = this.items.length; i < len; i++) {
181 if(this.items[i] != btn){
182 s.push(this.items[i]);
187 this.delegateUpdates();
190 setActiveButton : function(btn){
191 this.activeButton = btn;
192 this.delegateUpdates();
195 delegateUpdates : function(){
196 /*if(this.suspendUpdates){
199 if(this.resizeButtons && this.rendered){
202 if(this.enableScroll && this.rendered){
207 autoSize : function(){
208 var count = this.items.length;
209 var ow = this.el.dom.offsetWidth;
210 var aw = this.el.dom.clientWidth;
212 if(!this.resizeButtons || count < 1 || !aw){ // !aw for display:none
216 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.buttonMargin, this.buttonWidth), this.minButtonWidth); // -4 for float errors in IE
217 var btns = this.stripWrap.dom.getElementsByTagName('button');
219 this.lastButtonWidth = Ext.get(btns[0].id).findParent('li').offsetWidth;
221 for(var i = 0, len = btns.length; i < len; i++) {
224 var tw = Ext.get(btns[i].id).findParent('li').offsetWidth;
225 var iw = btn.offsetWidth;
227 btn.style.width = (each - (tw-iw)) + 'px';
231 autoScroll : function(){
232 var count = this.items.length;
233 var ow = this.el.dom.offsetWidth;
234 var tw = this.el.dom.clientWidth;
236 var wrap = this.stripWrap;
237 var cw = wrap.dom.offsetWidth;
238 var pos = this.getScrollPos();
239 var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
241 if(!this.enableScroll || count < 1 || cw < 20){ // 20 to prevent display:none issues
245 wrap.setWidth(tw); // moved to here because of problem in Safari
248 wrap.dom.scrollLeft = 0;
249 //wrap.setWidth(tw); moved from here because of problem in Safari
251 this.scrolling = false;
252 this.el.removeClass('x-taskbuttons-scrolling');
253 this.scrollLeft.hide();
254 this.scrollRight.hide();
258 this.el.addClass('x-taskbuttons-scrolling');
260 tw -= wrap.getMargins('lr');
261 wrap.setWidth(tw > 20 ? tw : 20);
263 if(!this.scrollLeft){
264 this.createScrollers();
266 this.scrollLeft.show();
267 this.scrollRight.show();
270 this.scrolling = true;
271 if(pos > (l-tw)){ // ensure it stays within bounds
272 wrap.dom.scrollLeft = l-tw;
273 }else{ // otherwise, make sure the active button is still visible
274 this.scrollToButton(this.activeButton, true); // true to animate
276 this.updateScrollButtons();
280 createScrollers : function(){
281 var h = this.el.dom.offsetHeight; //var h = this.stripWrap.dom.offsetHeight;
284 var sl = this.el.insertFirst({
285 cls:'ux-taskbuttons-scroller-left'
288 sl.addClassOnOver('ux-taskbuttons-scroller-left-over');
289 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
290 interval : this.scrollRepeatInterval,
291 handler: this.onScrollLeft,
294 this.scrollLeft = sl;
297 var sr = this.el.insertFirst({
298 cls:'ux-taskbuttons-scroller-right'
301 sr.addClassOnOver('ux-taskbuttons-scroller-right-over');
302 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
303 interval : this.scrollRepeatInterval,
304 handler: this.onScrollRight,
307 this.scrollRight = sr;
310 getScrollWidth : function(){
311 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
314 getScrollPos : function(){
315 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
318 getScrollArea : function(){
319 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
322 getScrollAnim : function(){
324 duration: this.scrollDuration,
325 callback: this.updateScrollButtons,
330 getScrollIncrement : function(){
331 return (this.scrollIncrement || this.lastButtonWidth+2);
334 /* getBtnEl : function(item){
335 return document.getElementById(item.id);
338 scrollToButton : function(item, animate){
339 item = item.el.dom.parentNode; // li
341 var el = item; //this.getBtnEl(item);
342 var pos = this.getScrollPos(), area = this.getScrollArea();
343 var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
344 var right = left + el.offsetWidth;
346 this.scrollTo(left, animate);
347 }else if(right > (pos + area)){
348 this.scrollTo(right - area, animate);
352 scrollTo : function(pos, animate){
353 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
355 this.updateScrollButtons();
359 onScrollRight : function(){
360 var sw = this.getScrollWidth()-this.getScrollArea();
361 var pos = this.getScrollPos();
362 var s = Math.min(sw, pos + this.getScrollIncrement());
364 this.scrollTo(s, this.animScroll);
368 onScrollLeft : function(){
369 var pos = this.getScrollPos();
370 var s = Math.max(0, pos - this.getScrollIncrement());
372 this.scrollTo(s, this.animScroll);
376 updateScrollButtons : function(){
377 var pos = this.getScrollPos();
378 this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('ux-taskbuttons-scroller-left-disabled');
379 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('ux-taskbuttons-scroller-right-disabled');
386 * @class Ext.ux.TaskBar.TaskButton
387 * @extends Ext.Button
389 Ext.ux.TaskBar.TaskButton = function(win, el){
391 Ext.ux.TaskBar.TaskButton.superclass.constructor.call(this, {
392 iconCls: win.iconCls,
393 text: Ext.util.Format.ellipsis(win.title, 12),
395 handler : function(){
396 if(win.minimized || win.hidden){
398 }else if(win == win.manager.getActive()){
404 clickEvent:'mousedown',
405 template: new Ext.Template(
406 '<table cellspacing="0" class="x-btn {3}"><tbody><tr>',
407 '<td class="ux-taskbutton-left"><i> </i></td>',
408 '<td class="ux-taskbutton-center"><em class="{5} unselectable="on">',
409 '<button class="x-btn-text {2}" type="{1}" style="height:28px;">{0}</button>',
411 '<td class="ux-taskbutton-right"><i> </i></td>',
412 "</tr></tbody></table>")
416 Ext.extend(Ext.ux.TaskBar.TaskButton, Ext.Button, {
417 onRender : function(){
418 Ext.ux.TaskBar.TaskButton.superclass.onRender.apply(this, arguments);
420 this.cmenu = new Ext.menu.Menu({
424 if(!this.win.isVisible()){
433 handler: this.win.minimize,
437 handler: this.win.maximize,
441 handler: this.closeWin.createDelegate(this, this.win, true),
446 this.cmenu.on('beforeshow', function(){
447 var items = this.cmenu.items.items;
449 items[0].setDisabled(w.maximized !== true && w.hidden !== true);
450 items[1].setDisabled(w.minimized === true);
451 items[2].setDisabled(w.maximized === true || w.hidden === true);
454 this.el.on('contextmenu', function(e){
460 xy[1] -= this.cmenu.el.getHeight();
461 this.cmenu.showAt(xy);
465 closeWin : function(cMenu, e, win){
466 if(!win.isVisible()){