Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / examples / desktop / js / TaskBar.js
old mode 100644 (file)
new mode 100755 (executable)
index b769f19..4c58d91
 /*!
- * Ext JS Library 3.3.1
- * Copyright(c) 2006-2010 Sencha Inc.
+ * Ext JS Library 4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
  * licensing@sencha.com
  * http://www.sencha.com/license
  */
-/**
- * @class Ext.ux.TaskBar
- * @extends Ext.util.Observable
- */
-Ext.ux.TaskBar = function(app){
-    this.app = app;
-    this.init();
-}
-
-Ext.extend(Ext.ux.TaskBar, Ext.util.Observable, {
-    init : function(){
-        this.startMenu = new Ext.ux.StartMenu(Ext.apply({
-            iconCls: 'user',
-            height: 300,
-            shadow: true,
-            title: 'Jack Slocum',
-            width: 300
-        }, this.app.startConfig));
-
-        this.startBtn = new Ext.Button({
-            text: 'Start',
-            id: 'ux-startbutton',
-            iconCls:'start',
-            menu: this.startMenu,
-            menuAlign: 'bl-tl',
-            renderTo: 'ux-taskbar-start',
-            clickEvent: 'mousedown',
-            template: new Ext.Template(
-                '<table cellspacing="0" class="x-btn"><tbody class="{1}"><tr>',
-                '<td class="ux-startbutton-left"><i>&#160;</i></td>',
-                '<td class="ux-startbutton-center"><em class="{2} unselectable="on">',
-                    '<button class="x-btn-text" type="{0}" style="height:30px;"></button>',
-                '</em></td>',
-                '<td class="ux-startbutton-right"><i>&#160;</i></td>',
-                '</tr></tbody></table>')
-        });
-
-        var width = this.startBtn.getEl().getWidth()+10;
-
-        var sbBox = new Ext.BoxComponent({
-            el: 'ux-taskbar-start',
-            id: 'TaskBarStart',
-            minWidth: width,
-            region:'west',
-            split: true,
-            width: width
-        });
-
-        this.tbPanel = new Ext.ux.TaskButtonsPanel({
-            el: 'ux-taskbuttons-panel',
-            id: 'TaskBarButtons',
-            region:'center'
-        });
-
-        var container = new Ext.ux.TaskBarContainer({
-            el: 'ux-taskbar',
-            layout: 'border',
-            items: [sbBox,this.tbPanel]
-        });
-
-        return this;
-    },
-
-    addTaskButton : function(win){
-        return this.tbPanel.addButton(win, 'ux-taskbuttons-panel');
-    },
-
-    removeTaskButton : function(btn){
-        this.tbPanel.removeButton(btn);
-    },
-
-    setActiveButton : function(btn){
-        this.tbPanel.setActiveButton(btn);
-    }
-});
-
-
 
 /**
- * @class Ext.ux.TaskBarContainer
- * @extends Ext.Container
+ * @class Ext.ux.desktop.TaskBar
+ * @extends Ext.toolbar.Toolbar
  */
-Ext.ux.TaskBarContainer = Ext.extend(Ext.Container, {
-    initComponent : function() {
-        Ext.ux.TaskBarContainer.superclass.initComponent.call(this);
-
-        this.el = Ext.get(this.el) || Ext.getBody();
-        this.el.setHeight = Ext.emptyFn;
-        this.el.setWidth = Ext.emptyFn;
-        this.el.setSize = Ext.emptyFn;
-        this.el.setStyle({
-            overflow:'hidden',
-            margin:'0',
-            border:'0 none'
-        });
-        this.el.dom.scroll = 'no';
-        this.allowDomMove = false;
-        this.autoWidth = true;
-        this.autoHeight = true;
-        Ext.EventManager.onWindowResize(this.fireResize, this);
-        this.renderTo = this.el;
+Ext.define('Ext.ux.desktop.TaskBar', {
+    extend: 'Ext.toolbar.Toolbar', // TODO - make this a basic hbox panel...
+
+    requires: [
+        'Ext.button.Button',
+        'Ext.resizer.Splitter',
+        'Ext.menu.Menu',
+
+        'Ext.ux.desktop.StartMenu'
+    ],
+
+    alias: 'widget.taskbar',
+
+    cls: 'ux-taskbar',
+
+    /**
+     * @cfg {String} startBtnText
+     * The text for the Start Button.
+     */
+    startBtnText: 'Start',
+
+    initComponent: function () {
+        var me = this;
+
+        me.startMenu = new Ext.ux.desktop.StartMenu(me.startConfig);
+
+        me.quickStart = new Ext.toolbar.Toolbar(me.getQuickStart());
+
+        me.windowBar = new Ext.toolbar.Toolbar(me.getWindowBarConfig());
+
+        me.tray = new Ext.toolbar.Toolbar(me.getTrayConfig());
+
+        me.items = [
+            {
+                xtype: 'button',
+                cls: 'ux-start-button',
+                iconCls: 'ux-start-button-icon',
+                menu: me.startMenu,
+                menuAlign: 'bl-tl',
+                text: me.startBtnText
+            },
+            me.quickStart,
+            {
+                xtype: 'splitter', html: '&#160;',
+                height: 14, width: 2, // TODO - there should be a CSS way here
+                cls: 'x-toolbar-separator x-toolbar-separator-horizontal'
+            },
+            //'-',
+            me.windowBar,
+            '-',
+            me.tray
+        ];
+
+        me.callParent();
     },
 
-    fireResize : function(w, h){
-        this.onResize(w, h, w, h);
-        this.fireEvent('resize', this, w, h, w, h);
-    }
-});
-
+    afterLayout: function () {
+        var me = this;
+        me.callParent();
+        me.windowBar.el.on('contextmenu', me.onButtonContextMenu, me);
+    },
 
+    /**
+     * This method returns the configuration object for the Quick Start toolbar. A derived
+     * class can override this method, call the base version to build the config and
+     * then modify the returned object before returning it.
+     */
+    getQuickStart: function () {
+        var me = this, ret = {
+            minWidth: 20,
+            width: 60,
+            items: [],
+            enableOverflow: true
+        };
 
-/**
- * @class Ext.ux.TaskButtonsPanel
- * @extends Ext.BoxComponent
- */
-Ext.ux.TaskButtonsPanel = Ext.extend(Ext.BoxComponent, {
-    activeButton: null,
-    enableScroll: true,
-    scrollIncrement: 0,
-    scrollRepeatInterval: 400,
-    scrollDuration: .35,
-    animScroll: true,
-    resizeButtons: true,
-    buttonWidth: 168,
-    minButtonWidth: 118,
-    buttonMargin: 2,
-    buttonWidthSet: false,
-
-    initComponent : function() {
-        Ext.ux.TaskButtonsPanel.superclass.initComponent.call(this);
-        this.on('resize', this.delegateUpdates);
-        this.items = [];
-
-        this.stripWrap = Ext.get(this.el).createChild({
-            cls: 'ux-taskbuttons-strip-wrap',
-            cn: {
-                tag:'ul', cls:'ux-taskbuttons-strip'
-            }
+        Ext.each(this.quickStart, function (item) {
+            ret.items.push({
+                tooltip: { text: item.name, align: 'bl-tl' },
+                //tooltip: item.name,
+                overflowText: item.name,
+                iconCls: item.iconCls,
+                module: item.module,
+                handler: me.onQuickStartClick,
+                scope: me
+            });
         });
-        this.stripSpacer = Ext.get(this.el).createChild({
-            cls:'ux-taskbuttons-strip-spacer'
-        });
-        this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
 
-        this.edge = this.strip.createChild({
-            tag:'li',
-            cls:'ux-taskbuttons-edge'
-        });
-        this.strip.createChild({
-            cls:'x-clear'
-        });
+        return ret;
     },
 
-    addButton : function(win){
-        var li = this.strip.createChild({tag:'li'}, this.edge); // insert before the edge
-        var btn = new Ext.ux.TaskBar.TaskButton(win, li);
-
-        this.items.push(btn);
-
-        if(!this.buttonWidthSet){
-            this.lastButtonWidth = btn.container.getWidth();
-        }
-
-        this.setActiveButton(btn);
-        return btn;
+    /**
+     * This method returns the configuration object for the Tray toolbar. A derived
+     * class can override this method, call the base version to build the config and
+     * then modify the returned object before returning it.
+     */
+    getTrayConfig: function () {
+        var ret = {
+            width: 80,
+            items: this.trayItems
+        };
+        delete this.trayItems;
+        return ret;
     },
 
-    removeButton : function(btn){
-        var li = document.getElementById(btn.container.id);
-        btn.destroy();
-        li.parentNode.removeChild(li);
-
-        var s = [];
-        for(var i = 0, len = this.items.length; i < len; i++) {
-            if(this.items[i] != btn){
-                s.push(this.items[i]);
-            }
-        }
-        this.items = s;
-
-        this.delegateUpdates();
+    getWindowBarConfig: function () {
+        return {
+            flex: 1,
+            cls: 'ux-desktop-windowbar',
+            items: [ '&#160;' ],
+            layout: { overflowHandler: 'Scroller' }
+        };
     },
 
-    setActiveButton : function(btn){
-        this.activeButton = btn;
-        this.delegateUpdates();
+    getWindowBtnFromEl: function (el) {
+        var c = this.windowBar.getChildByElement(el);
+        return c || null;
     },
 
-    delegateUpdates : function(){
-        /*if(this.suspendUpdates){
-            return;
-        }*/
-        if(this.resizeButtons && this.rendered){
-            this.autoSize();
-        }
-        if(this.enableScroll && this.rendered){
-            this.autoScroll();
+    onQuickStartClick: function (btn) {
+        var module = this.app.getModule(btn.module);
+        if (module) {
+            module.createWindow();
         }
     },
-
-    autoSize : function(){
-        var count = this.items.length;
-        var ow = this.el.dom.offsetWidth;
-        var aw = this.el.dom.clientWidth;
-
-        if(!this.resizeButtons || count < 1 || !aw){ // !aw for display:none
-            return;
+    
+    onButtonContextMenu: function (e) {
+        var me = this, t = e.getTarget(), btn = me.getWindowBtnFromEl(t);
+        if (btn) {
+            e.stopEvent();
+            me.windowMenu.theWin = btn.win;
+            me.windowMenu.showBy(t);
         }
+    },
 
-        var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.buttonMargin, this.buttonWidth), this.minButtonWidth); // -4 for float errors in IE
-        var btns = this.stripWrap.dom.getElementsByTagName('button');
-
-        this.lastButtonWidth = Ext.get(btns[0].id).findParent('li').offsetWidth;
-
-        for(var i = 0, len = btns.length; i < len; i++) {
-            var btn = btns[i];
-
-            var tw = Ext.get(btns[i].id).findParent('li').offsetWidth;
-            var iw = btn.offsetWidth;
+    onWindowBtnClick: function (btn) {
+        var win = btn.win;
 
-            btn.style.width = (each - (tw-iw)) + 'px';
+        if (win.minimized || win.hidden) {
+            win.show();
+        } else if (win.active) {
+            win.minimize();
+        } else {
+            win.toFront();
         }
     },
 
-    autoScroll : function(){
-        var count = this.items.length;
-        var ow = this.el.dom.offsetWidth;
-        var tw = this.el.dom.clientWidth;
+    addTaskButton: function(win) {
+        var config = {
+            iconCls: win.iconCls,
+            enableToggle: true,
+            toggleGroup: 'all',
+            width: 140,
+            text: Ext.util.Format.ellipsis(win.title, 20),
+            listeners: {
+                click: this.onWindowBtnClick,
+                scope: this
+            },
+            win: win
+        };
 
-        var wrap = this.stripWrap;
-        var cw = wrap.dom.offsetWidth;
-        var pos = this.getScrollPos();
-        var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
+        var cmp = this.windowBar.add(config);
+        cmp.toggle(true);
+        return cmp;
+    },
 
-        if(!this.enableScroll || count < 1 || cw < 20){ // 20 to prevent display:none issues
-            return;
+    removeTaskButton: function (btn) {
+        var found, me = this;
+        me.windowBar.items.each(function (item) {
+            if (item === btn) {
+                found = item;
+            }
+            return !found;
+        });
+        if (found) {
+            me.windowBar.remove(found);
         }
+        return found;
+    },
 
-        wrap.setWidth(tw); // moved to here because of problem in Safari
-
-        if(l <= tw){
-            wrap.dom.scrollLeft = 0;
-            //wrap.setWidth(tw); moved from here because of problem in Safari
-            if(this.scrolling){
-                this.scrolling = false;
-                this.el.removeClass('x-taskbuttons-scrolling');
-                this.scrollLeft.hide();
-                this.scrollRight.hide();
-            }
-        }else{
-            if(!this.scrolling){
-                this.el.addClass('x-taskbuttons-scrolling');
-            }
-            tw -= wrap.getMargins('lr');
-            wrap.setWidth(tw > 20 ? tw : 20);
-            if(!this.scrolling){
-                if(!this.scrollLeft){
-                    this.createScrollers();
-                }else{
-                    this.scrollLeft.show();
-                    this.scrollRight.show();
+    setActiveButton: function(btn) {
+        if (btn) {
+            btn.toggle(true);
+        } else {
+            this.windowBar.items.each(function (item) {
+                if (item.isButton) {
+                    item.toggle(false);
                 }
-            }
-            this.scrolling = true;
-            if(pos > (l-tw)){ // ensure it stays within bounds
-                wrap.dom.scrollLeft = l-tw;
-            }else{ // otherwise, make sure the active button is still visible
-                this.scrollToButton(this.activeButton, true); // true to animate
-            }
-            this.updateScrollButtons();
+            });
         }
-    },
+    }
+});
 
-    createScrollers : function(){
-        var h = this.el.dom.offsetHeight; //var h = this.stripWrap.dom.offsetHeight;
+/**
+ * @class Ext.ux.desktop.TrayClock
+ * @extends Ext.toolbar.TextItem
+ * This class displays a clock on the toolbar.
+ */
+Ext.define('Ext.ux.desktop.TrayClock', {
+    extend: 'Ext.toolbar.TextItem',
 
-        // left
-        var sl = this.el.insertFirst({
-            cls:'ux-taskbuttons-scroller-left'
-        });
-        sl.setHeight(h);
-        sl.addClassOnOver('ux-taskbuttons-scroller-left-over');
-        this.leftRepeater = new Ext.util.ClickRepeater(sl, {
-            interval : this.scrollRepeatInterval,
-            handler: this.onScrollLeft,
-            scope: this
-        });
-        this.scrollLeft = sl;
+    alias: 'widget.trayclock',
 
-        // right
-        var sr = this.el.insertFirst({
-            cls:'ux-taskbuttons-scroller-right'
-        });
-        sr.setHeight(h);
-        sr.addClassOnOver('ux-taskbuttons-scroller-right-over');
-        this.rightRepeater = new Ext.util.ClickRepeater(sr, {
-            interval : this.scrollRepeatInterval,
-            handler: this.onScrollRight,
-            scope: this
-        });
-        this.scrollRight = sr;
-    },
+    cls: 'ux-desktop-trayclock',
 
-    getScrollWidth : function(){
-        return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
-    },
+    html: '&#160;',
 
-    getScrollPos : function(){
-        return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
-    },
+    timeFormat: 'g:i A',
 
-    getScrollArea : function(){
-        return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
-    },
+    tpl: '{time}',
 
-    getScrollAnim : function(){
-        return {
-            duration: this.scrollDuration,
-            callback: this.updateScrollButtons,
-            scope: this
-        };
-    },
+    initComponent: function () {
+        var me = this;
 
-    getScrollIncrement : function(){
-        return (this.scrollIncrement || this.lastButtonWidth+2);
-    },
+        me.callParent();
 
-    /* getBtnEl : function(item){
-        return document.getElementById(item.id);
-    }, */
-
-    scrollToButton : function(item, animate){
-        item = item.el.dom.parentNode; // li
-        if(!item){ return; }
-        var el = item; //this.getBtnEl(item);
-        var pos = this.getScrollPos(), area = this.getScrollArea();
-        var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
-        var right = left + el.offsetWidth;
-        if(left < pos){
-            this.scrollTo(left, animate);
-        }else if(right > (pos + area)){
-            this.scrollTo(right - area, animate);
+        if (typeof(me.tpl) == 'string') {
+            me.tpl = new Ext.XTemplate(me.tpl);
         }
     },
 
-    scrollTo : function(pos, animate){
-        this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
-        if(!animate){
-            this.updateScrollButtons();
-        }
+    afterRender: function () {
+        var me = this;
+        Ext.Function.defer(me.updateTime, 100, me);
+        me.callParent();
     },
 
-    onScrollRight : function(){
-        var sw = this.getScrollWidth()-this.getScrollArea();
-        var pos = this.getScrollPos();
-        var s = Math.min(sw, pos + this.getScrollIncrement());
-        if(s != pos){
-            this.scrollTo(s, this.animScroll);
-        }
-    },
+    onDestroy: function () {
+        var me = this;
 
-    onScrollLeft : function(){
-        var pos = this.getScrollPos();
-        var s = Math.max(0, pos - this.getScrollIncrement());
-        if(s != pos){
-            this.scrollTo(s, this.animScroll);
+        if (me.timer) {
+            window.clearTimeout(me.timer);
+            me.timer = null;
         }
-    },
-
-    updateScrollButtons : function(){
-        var pos = this.getScrollPos();
-        this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('ux-taskbuttons-scroller-left-disabled');
-        this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('ux-taskbuttons-scroller-right-disabled');
-    }
-});
-
 
-
-/**
- * @class Ext.ux.TaskBar.TaskButton
- * @extends Ext.Button
- */
-Ext.ux.TaskBar.TaskButton = function(win, el){
-    this.win = win;
-    Ext.ux.TaskBar.TaskButton.superclass.constructor.call(this, {
-        iconCls: win.iconCls,
-        text: Ext.util.Format.ellipsis(win.title, 12),
-        renderTo: el,
-        handler : function(){
-            if(win.minimized || win.hidden){
-                win.show();
-            }else if(win == win.manager.getActive()){
-                win.minimize();
-            }else{
-                win.toFront();
-            }
-        },
-        clickEvent:'mousedown',
-        template: new Ext.Template(
-            '<table cellspacing="0" class="x-btn {3}"><tbody><tr>',
-            '<td class="ux-taskbutton-left"><i>&#160;</i></td>',
-            '<td class="ux-taskbutton-center"><em class="{5} unselectable="on">',
-                '<button class="x-btn-text {2}" type="{1}" style="height:28px;">{0}</button>',
-            '</em></td>',
-            '<td class="ux-taskbutton-right"><i>&#160;</i></td>',
-            "</tr></tbody></table>")
-    });
-};
-
-Ext.extend(Ext.ux.TaskBar.TaskButton, Ext.Button, {
-    onRender : function(){
-        Ext.ux.TaskBar.TaskButton.superclass.onRender.apply(this, arguments);
-
-        this.cmenu = new Ext.menu.Menu({
-            items: [{
-                text: 'Restore',
-                handler: function(){
-                    if(!this.win.isVisible()){
-                        this.win.show();
-                    }else{
-                        this.win.restore();
-                    }
-                },
-                scope: this
-            },{
-                text: 'Minimize',
-                handler: this.win.minimize,
-                scope: this.win
-            },{
-                text: 'Maximize',
-                handler: this.win.maximize,
-                scope: this.win
-            }, '-', {
-                text: 'Close',
-                handler: this.closeWin.createDelegate(this, this.win, true),
-                scope: this.win
-            }]
-        });
-
-        this.cmenu.on('beforeshow', function(){
-            var items = this.cmenu.items.items;
-            var w = this.win;
-            items[0].setDisabled(w.maximized !== true && w.hidden !== true);
-            items[1].setDisabled(w.minimized === true);
-            items[2].setDisabled(w.maximized === true || w.hidden === true);
-        }, this);
-
-        this.el.on('contextmenu', function(e){
-            e.stopEvent();
-            if(!this.cmenu.el){
-                this.cmenu.render();
-            }
-            var xy = e.getXY();
-            xy[1] -= this.cmenu.el.getHeight();
-            this.cmenu.showAt(xy);
-        }, this);
+        me.callParent();
     },
 
-    closeWin : function(cMenu, e, win){
-        if(!win.isVisible()){
-            win.show();
-        }else{
-            win.restore();
+    updateTime: function () {
+        var me = this, time = Ext.Date.format(new Date(), me.timeFormat),
+            text = me.tpl.apply({ time: time });
+        if (me.lastText != text) {
+            me.setText(text);
+            me.lastText = text;
         }
-        win.close();
+        me.timer = Ext.Function.defer(me.updateTime, 10000, me);
     }
-});
\ No newline at end of file
+});