--- /dev/null
+<html>\r
+<head>\r
+ <title>The source code</title>\r
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
+</head>\r
+<body onload="prettyPrint();">\r
+ <pre class="prettyprint lang-js"><div id="cls-Ext.ux.TaskBar"></div>/**\r
+ * @class Ext.ux.TaskBar\r
+ * @extends Ext.util.Observable\r
+ */\r
+Ext.ux.TaskBar = function(app){\r
+ this.app = app;\r
+ this.init();\r
+}\r
+\r
+Ext.extend(Ext.ux.TaskBar, Ext.util.Observable, {\r
+ init : function(){\r
+ this.startMenu = new Ext.ux.StartMenu(Ext.apply({\r
+ iconCls: 'user',\r
+ height: 300,\r
+ shadow: true,\r
+ title: 'Jack Slocum',\r
+ width: 300\r
+ }, this.app.startConfig));\r
+ \r
+ this.startBtn = new Ext.Button({\r
+ text: 'Start',\r
+ id: 'ux-startbutton',\r
+ iconCls:'start',\r
+ menu: this.startMenu,\r
+ menuAlign: 'bl-tl',\r
+ renderTo: 'ux-taskbar-start',\r
+ clickEvent: 'mousedown',\r
+ template: new Ext.Template(\r
+ '<table cellspacing="0" class="x-btn {3}"><tbody><tr>',\r
+ '<td class="ux-startbutton-left"><i> </i></td>',\r
+ '<td class="ux-startbutton-center"><em class="{5} unselectable="on">',\r
+ '<button class="x-btn-text {2}" type="{1}" style="height:30px;">{0}</button>',\r
+ '</em></td>',\r
+ '<td class="ux-startbutton-right"><i> </i></td>',\r
+ "</tr></tbody></table>")\r
+ });\r
+\r
+ var width = this.startBtn.getEl().getWidth()+10;\r
+ \r
+ var sbBox = new Ext.BoxComponent({\r
+ el: 'ux-taskbar-start',\r
+ id: 'TaskBarStart',\r
+ minWidth: width,\r
+ region:'west',\r
+ split: true,\r
+ width: width\r
+ });\r
+ \r
+ this.tbPanel = new Ext.ux.TaskButtonsPanel({\r
+ el: 'ux-taskbuttons-panel',\r
+ id: 'TaskBarButtons',\r
+ region:'center'\r
+ });\r
+ \r
+ var container = new Ext.ux.TaskBarContainer({\r
+ el: 'ux-taskbar',\r
+ layout: 'border',\r
+ items: [sbBox,this.tbPanel]\r
+ });\r
+ \r
+ return this;\r
+ },\r
+ \r
+ addTaskButton : function(win){\r
+ return this.tbPanel.addButton(win, 'ux-taskbuttons-panel');\r
+ },\r
+ \r
+ removeTaskButton : function(btn){\r
+ this.tbPanel.removeButton(btn);\r
+ },\r
+ \r
+ setActiveButton : function(btn){\r
+ this.tbPanel.setActiveButton(btn);\r
+ }\r
+});\r
+\r
+\r
+\r
+<div id="cls-Ext.ux.TaskBarContainer"></div>/**\r
+ * @class Ext.ux.TaskBarContainer\r
+ * @extends Ext.Container\r
+ */\r
+Ext.ux.TaskBarContainer = Ext.extend(Ext.Container, {\r
+ initComponent : function() {\r
+ Ext.ux.TaskBarContainer.superclass.initComponent.call(this);\r
+ \r
+ this.el = Ext.get(this.el) || Ext.getBody();\r
+ this.el.setHeight = Ext.emptyFn;\r
+ this.el.setWidth = Ext.emptyFn;\r
+ this.el.setSize = Ext.emptyFn;\r
+ this.el.setStyle({\r
+ overflow:'hidden',\r
+ margin:'0',\r
+ border:'0 none'\r
+ });\r
+ this.el.dom.scroll = 'no';\r
+ this.allowDomMove = false;\r
+ this.autoWidth = true;\r
+ this.autoHeight = true;\r
+ Ext.EventManager.onWindowResize(this.fireResize, this);\r
+ this.renderTo = this.el;\r
+ },\r
+\r
+ fireResize : function(w, h){\r
+ this.fireEvent('resize', this, w, h, w, h);\r
+ }\r
+});\r
+\r
+\r
+\r
+<div id="cls-Ext.ux.TaskButtonsPanel"></div>/**\r
+ * @class Ext.ux.TaskButtonsPanel\r
+ * @extends Ext.BoxComponent\r
+ */\r
+Ext.ux.TaskButtonsPanel = Ext.extend(Ext.BoxComponent, {\r
+ activeButton: null,\r
+ enableScroll: true,\r
+ scrollIncrement: 0,\r
+ scrollRepeatInterval: 400,\r
+ scrollDuration: .35,\r
+ animScroll: true,\r
+ resizeButtons: true,\r
+ buttonWidth: 168,\r
+ minButtonWidth: 118,\r
+ buttonMargin: 2,\r
+ buttonWidthSet: false,\r
+ \r
+ initComponent : function() {\r
+ Ext.ux.TaskButtonsPanel.superclass.initComponent.call(this);\r
+ this.on('resize', this.delegateUpdates);\r
+ this.items = [];\r
+ \r
+ this.stripWrap = Ext.get(this.el).createChild({\r
+ cls: 'ux-taskbuttons-strip-wrap',\r
+ cn: {\r
+ tag:'ul', cls:'ux-taskbuttons-strip'\r
+ }\r
+ });\r
+ this.stripSpacer = Ext.get(this.el).createChild({\r
+ cls:'ux-taskbuttons-strip-spacer'\r
+ });\r
+ this.strip = new Ext.Element(this.stripWrap.dom.firstChild);\r
+ \r
+ this.edge = this.strip.createChild({\r
+ tag:'li',\r
+ cls:'ux-taskbuttons-edge'\r
+ });\r
+ this.strip.createChild({\r
+ cls:'x-clear'\r
+ });\r
+ },\r
+ \r
+ addButton : function(win){\r
+ var li = this.strip.createChild({tag:'li'}, this.edge); // insert before the edge\r
+ var btn = new Ext.ux.TaskBar.TaskButton(win, li);\r
+ \r
+ this.items.push(btn);\r
+ \r
+ if(!this.buttonWidthSet){\r
+ this.lastButtonWidth = btn.container.getWidth();\r
+ }\r
+ \r
+ this.setActiveButton(btn);\r
+ return btn;\r
+ },\r
+ \r
+ removeButton : function(btn){\r
+ var li = document.getElementById(btn.container.id);\r
+ btn.destroy();\r
+ li.parentNode.removeChild(li);\r
+ \r
+ var s = [];\r
+ for(var i = 0, len = this.items.length; i < len; i++) {\r
+ if(this.items[i] != btn){\r
+ s.push(this.items[i]);\r
+ }\r
+ }\r
+ this.items = s;\r
+ \r
+ this.delegateUpdates();\r
+ },\r
+ \r
+ setActiveButton : function(btn){\r
+ this.activeButton = btn;\r
+ this.delegateUpdates();\r
+ },\r
+ \r
+ delegateUpdates : function(){\r
+ /*if(this.suspendUpdates){\r
+ return;\r
+ }*/\r
+ if(this.resizeButtons && this.rendered){\r
+ this.autoSize();\r
+ }\r
+ if(this.enableScroll && this.rendered){\r
+ this.autoScroll();\r
+ }\r
+ },\r
+ \r
+ autoSize : function(){\r
+ var count = this.items.length;\r
+ var ow = this.el.dom.offsetWidth;\r
+ var aw = this.el.dom.clientWidth;\r
+\r
+ if(!this.resizeButtons || count < 1 || !aw){ // !aw for display:none\r
+ return;\r
+ }\r
+ \r
+ var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.buttonMargin, this.buttonWidth), this.minButtonWidth); // -4 for float errors in IE\r
+ var btns = this.stripWrap.dom.getElementsByTagName('button');\r
+ \r
+ this.lastButtonWidth = Ext.get(btns[0].id).findParent('li').offsetWidth;\r
+ \r
+ for(var i = 0, len = btns.length; i < len; i++) { \r
+ var btn = btns[i];\r
+ \r
+ var tw = Ext.get(btns[i].id).findParent('li').offsetWidth;\r
+ var iw = btn.offsetWidth;\r
+ \r
+ btn.style.width = (each - (tw-iw)) + 'px';\r
+ }\r
+ },\r
+ \r
+ autoScroll : function(){\r
+ var count = this.items.length;\r
+ var ow = this.el.dom.offsetWidth;\r
+ var tw = this.el.dom.clientWidth;\r
+ \r
+ var wrap = this.stripWrap;\r
+ var cw = wrap.dom.offsetWidth;\r
+ var pos = this.getScrollPos();\r
+ var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;\r
+ \r
+ if(!this.enableScroll || count < 1 || cw < 20){ // 20 to prevent display:none issues\r
+ return;\r
+ }\r
+ \r
+ wrap.setWidth(tw); // moved to here because of problem in Safari\r
+ \r
+ if(l <= tw){\r
+ wrap.dom.scrollLeft = 0;\r
+ //wrap.setWidth(tw); moved from here because of problem in Safari\r
+ if(this.scrolling){\r
+ this.scrolling = false;\r
+ this.el.removeClass('x-taskbuttons-scrolling');\r
+ this.scrollLeft.hide();\r
+ this.scrollRight.hide();\r
+ }\r
+ }else{\r
+ if(!this.scrolling){\r
+ this.el.addClass('x-taskbuttons-scrolling');\r
+ }\r
+ tw -= wrap.getMargins('lr');\r
+ wrap.setWidth(tw > 20 ? tw : 20);\r
+ if(!this.scrolling){\r
+ if(!this.scrollLeft){\r
+ this.createScrollers();\r
+ }else{\r
+ this.scrollLeft.show();\r
+ this.scrollRight.show();\r
+ }\r
+ }\r
+ this.scrolling = true;\r
+ if(pos > (l-tw)){ // ensure it stays within bounds\r
+ wrap.dom.scrollLeft = l-tw;\r
+ }else{ // otherwise, make sure the active button is still visible\r
+ this.scrollToButton(this.activeButton, true); // true to animate\r
+ }\r
+ this.updateScrollButtons();\r
+ }\r
+ },\r
+\r
+ createScrollers : function(){\r
+ var h = this.el.dom.offsetHeight; //var h = this.stripWrap.dom.offsetHeight;\r
+ \r
+ // left\r
+ var sl = this.el.insertFirst({\r
+ cls:'ux-taskbuttons-scroller-left'\r
+ });\r
+ sl.setHeight(h);\r
+ sl.addClassOnOver('ux-taskbuttons-scroller-left-over');\r
+ this.leftRepeater = new Ext.util.ClickRepeater(sl, {\r
+ interval : this.scrollRepeatInterval,\r
+ handler: this.onScrollLeft,\r
+ scope: this\r
+ });\r
+ this.scrollLeft = sl;\r
+\r
+ // right\r
+ var sr = this.el.insertFirst({\r
+ cls:'ux-taskbuttons-scroller-right'\r
+ });\r
+ sr.setHeight(h);\r
+ sr.addClassOnOver('ux-taskbuttons-scroller-right-over');\r
+ this.rightRepeater = new Ext.util.ClickRepeater(sr, {\r
+ interval : this.scrollRepeatInterval,\r
+ handler: this.onScrollRight,\r
+ scope: this\r
+ });\r
+ this.scrollRight = sr;\r
+ },\r
+ \r
+ getScrollWidth : function(){\r
+ return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();\r
+ },\r
+\r
+ getScrollPos : function(){\r
+ return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;\r
+ },\r
+\r
+ getScrollArea : function(){\r
+ return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;\r
+ },\r
+\r
+ getScrollAnim : function(){\r
+ return {\r
+ duration: this.scrollDuration,\r
+ callback: this.updateScrollButtons,\r
+ scope: this\r
+ };\r
+ },\r
+\r
+ getScrollIncrement : function(){\r
+ return (this.scrollIncrement || this.lastButtonWidth+2);\r
+ },\r
+ \r
+ /* getBtnEl : function(item){\r
+ return document.getElementById(item.id);\r
+ }, */\r
+ \r
+ scrollToButton : function(item, animate){\r
+ item = item.el.dom.parentNode; // li\r
+ if(!item){ return; }\r
+ var el = item; //this.getBtnEl(item);\r
+ var pos = this.getScrollPos(), area = this.getScrollArea();\r
+ var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;\r
+ var right = left + el.offsetWidth;\r
+ if(left < pos){\r
+ this.scrollTo(left, animate);\r
+ }else if(right > (pos + area)){\r
+ this.scrollTo(right - area, animate);\r
+ }\r
+ },\r
+ \r
+ scrollTo : function(pos, animate){\r
+ this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);\r
+ if(!animate){\r
+ this.updateScrollButtons();\r
+ }\r
+ },\r
+ \r
+ onScrollRight : function(){\r
+ var sw = this.getScrollWidth()-this.getScrollArea();\r
+ var pos = this.getScrollPos();\r
+ var s = Math.min(sw, pos + this.getScrollIncrement());\r
+ if(s != pos){\r
+ this.scrollTo(s, this.animScroll);\r
+ } \r
+ },\r
+\r
+ onScrollLeft : function(){\r
+ var pos = this.getScrollPos();\r
+ var s = Math.max(0, pos - this.getScrollIncrement());\r
+ if(s != pos){\r
+ this.scrollTo(s, this.animScroll);\r
+ }\r
+ },\r
+ \r
+ updateScrollButtons : function(){\r
+ var pos = this.getScrollPos();\r
+ this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('ux-taskbuttons-scroller-left-disabled');\r
+ this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('ux-taskbuttons-scroller-right-disabled');\r
+ }\r
+});\r
+\r
+\r
+\r
+<div id="cls-Ext.ux.TaskBar.TaskButton"></div>/**\r
+ * @class Ext.ux.TaskBar.TaskButton\r
+ * @extends Ext.Button\r
+ */\r
+Ext.ux.TaskBar.TaskButton = function(win, el){\r
+ this.win = win;\r
+ Ext.ux.TaskBar.TaskButton.superclass.constructor.call(this, {\r
+ iconCls: win.iconCls,\r
+ text: Ext.util.Format.ellipsis(win.title, 12),\r
+ renderTo: el,\r
+ handler : function(){\r
+ if(win.minimized || win.hidden){\r
+ win.show();\r
+ }else if(win == win.manager.getActive()){\r
+ win.minimize();\r
+ }else{\r
+ win.toFront();\r
+ }\r
+ },\r
+ clickEvent:'mousedown',\r
+ template: new Ext.Template(\r
+ '<table cellspacing="0" class="x-btn {3}"><tbody><tr>',\r
+ '<td class="ux-taskbutton-left"><i> </i></td>',\r
+ '<td class="ux-taskbutton-center"><em class="{5} unselectable="on">',\r
+ '<button class="x-btn-text {2}" type="{1}" style="height:28px;">{0}</button>',\r
+ '</em></td>',\r
+ '<td class="ux-taskbutton-right"><i> </i></td>',\r
+ "</tr></tbody></table>") \r
+ });\r
+};\r
+\r
+Ext.extend(Ext.ux.TaskBar.TaskButton, Ext.Button, {\r
+ onRender : function(){\r
+ Ext.ux.TaskBar.TaskButton.superclass.onRender.apply(this, arguments);\r
+\r
+ this.cmenu = new Ext.menu.Menu({\r
+ items: [{\r
+ text: 'Restore',\r
+ handler: function(){\r
+ if(!this.win.isVisible()){\r
+ this.win.show();\r
+ }else{\r
+ this.win.restore();\r
+ }\r
+ },\r
+ scope: this\r
+ },{\r
+ text: 'Minimize',\r
+ handler: this.win.minimize,\r
+ scope: this.win\r
+ },{\r
+ text: 'Maximize',\r
+ handler: this.win.maximize,\r
+ scope: this.win\r
+ }, '-', {\r
+ text: 'Close',\r
+ handler: this.closeWin.createDelegate(this, this.win, true),\r
+ scope: this.win\r
+ }]\r
+ });\r
+\r
+ this.cmenu.on('beforeshow', function(){\r
+ var items = this.cmenu.items.items;\r
+ var w = this.win;\r
+ items[0].setDisabled(w.maximized !== true && w.hidden !== true);\r
+ items[1].setDisabled(w.minimized === true);\r
+ items[2].setDisabled(w.maximized === true || w.hidden === true);\r
+ }, this);\r
+\r
+ this.el.on('contextmenu', function(e){\r
+ e.stopEvent();\r
+ if(!this.cmenu.el){\r
+ this.cmenu.render();\r
+ }\r
+ var xy = e.getXY();\r
+ xy[1] -= this.cmenu.el.getHeight();\r
+ this.cmenu.showAt(xy);\r
+ }, this);\r
+ },\r
+ \r
+ closeWin : function(cMenu, e, win){\r
+ if(!win.isVisible()){\r
+ win.show();\r
+ }else{\r
+ win.restore();\r
+ }\r
+ win.close();\r
+ }\r
+});</pre> \r
+</body>\r
+</html>
\ No newline at end of file