ef59b64e1fba5e51f816b46830452ad8b21e72f8
[roojs1] / Roo / bootstrap / layout / Region.js
1 /*
2  * Based on:
3  * Ext JS Library 1.1.1
4  * Copyright(c) 2006-2007, Ext JS, LLC.
5  *
6  * Originally Released Under LGPL - original licence link has changed is not relivant.
7  *
8  * Fork - LGPL
9  * <script type="text/javascript">
10  */
11  
12 /**
13  * @class Roo.bootstrap.layout.Region
14  * @extends Roo.bootstrap.layout.Basic
15  * This class represents a region in a layout manager.
16  
17  * @cfg {Object}    margins         Margins for the element (defaults to {top: 0, left: 0, right:0, bottom: 0})
18  * @cfg {Object}    cmargins        Margins for the element when collapsed (defaults to: north/south {top: 2, left: 0, right:0, bottom: 2} or east/west {top: 0, left: 2, right:2, bottom: 0})
19  * @cfg {String}    tabPosition     (top|bottom) "top" or "bottom" (defaults to "bottom")
20  * @cfg {Boolean}   alwaysShowTabs  True to always display tabs even when there is only 1 panel (defaults to false)
21  * @cfg {Boolean}   autoScroll      True to enable overflow scrolling (defaults to false)
22  * @cfg {Boolean}   titlebar        True to display a title bar (defaults to true)
23  * @cfg {String}    title           The title for the region (overrides panel titles)
24  * @cfg {Boolean}   animate         True to animate expand/collapse (defaults to false)
25  * @cfg {Boolean}   autoHide        False to disable auto hiding when the mouse leaves the "floated" region (defaults to true)
26  * @cfg {Boolean}   preservePanels  True to preserve removed panels so they can be readded later (defaults to false)
27  * @cfg {Boolean}   closeOnTab      True to place the close icon on the tabs instead of the region titlebar (defaults to false)
28  * @cfg {Boolean}   hideTabs        True to hide the tab strip (defaults to false)
29  * @cfg {Boolean}   resizeTabs      True to enable automatic tab resizing. This will resize the tabs so they are all the same size and fit within
30  *                      the space available, similar to FireFox 1.5 tabs (defaults to false)
31  * @cfg {Number}    minTabWidth     The minimum tab width (defaults to 40)
32  * @cfg {Number}    preferredTabWidth The preferred tab width (defaults to 150)
33  * @cfg {String}    overflow       (hidden|visible) if you have menus in the region, then you need to set this to visible.
34
35  * @cfg {Boolean}   hidden          True to start the region hidden (defaults to false)
36  * @cfg {Boolean}   hideWhenEmpty   True to hide the region when it has no panels
37  * @cfg {Boolean}   disableTabTips  True to disable tab tooltips
38  * @cfg {Number}    width           For East/West panels
39  * @cfg {Number}    height          For North/South panels
40  * @cfg {Boolean}   split           To show the splitter
41  * @cfg {Boolean}   toolbar         xtype configuration for a toolbar - shows on right of tabbar
42  * 
43  * @cfg {string}   cls             Extra CSS classes to add to region
44  * 
45  * @cfg {Roo.bootstrap.layout.Manager}   mgr The manager
46  * @cfg {string}   region  the region that it inhabits..
47  *
48
49  * @xxxcfg {Boolean}   collapsible     DISABLED False to disable collapsing (defaults to true)
50  * @xxxcfg {Boolean}   collapsed       DISABLED True to set the initial display to collapsed (defaults to false)
51
52  * @xxxcfg {String}    collapsedTitle  DISABLED Optional string message to display in the collapsed block of a north or south region
53  * @xxxxcfg {Boolean}   floatable       DISABLED False to disable floating (defaults to true)
54  * @xxxxcfg {Boolean}   showPin         True to show a pin button NOT SUPPORTED YET
55  */
56 Roo.bootstrap.layout.Region = function(config)
57 {
58     this.applyConfig(config);
59
60     var mgr = config.mgr;
61     var pos = config.region;
62     config.skipConfig = true;
63     Roo.bootstrap.layout.Region.superclass.constructor.call(this, config);
64     
65     if (mgr.el) {
66         this.onRender(mgr.el);   
67     }
68      
69     this.visible = true;
70     this.collapsed = false;
71     this.unrendered_panels = [];
72 };
73
74 Roo.extend(Roo.bootstrap.layout.Region, Roo.bootstrap.layout.Basic, {
75
76     position: '', // set by wrapper (eg. north/south etc..)
77     unrendered_panels : null,  // unrendered panels.
78     createBody : function(){
79         /** This region's body element 
80         * @type Roo.Element */
81         this.bodyEl = this.el.createChild({
82                 tag: "div",
83                 cls: "roo-layout-panel-body tab-content" // bootstrap added...
84         });
85     },
86
87     onRender: function(ctr, pos)
88     {
89         var dh = Roo.DomHelper;
90         /** This region's container element 
91         * @type Roo.Element */
92         this.el = dh.append(ctr.dom, {
93                 tag: "div",
94                 cls: (this.config.cls || '') + " roo-layout-region roo-layout-panel roo-layout-panel-" + this.position
95             }, true);
96         /** This region's title element 
97         * @type Roo.Element */
98     
99         this.titleEl = dh.append(this.el.dom,
100             {
101                     tag: "div",
102                     unselectable: "on",
103                     cls: "roo-unselectable roo-layout-panel-hd breadcrumb roo-layout-title-" + this.position,
104                     children:[
105                         {tag: "span", cls: "roo-unselectable roo-layout-panel-hd-text", unselectable: "on", html: "&#160;"},
106                         {tag: "div", cls: "roo-unselectable roo-layout-panel-hd-tools", unselectable: "on"}
107                     ]}, true);
108         
109         this.titleEl.enableDisplayMode();
110         /** This region's title text element 
111         * @type HTMLElement */
112         this.titleTextEl = this.titleEl.dom.firstChild;
113         this.tools = Roo.get(this.titleEl.dom.childNodes[1], true);
114         /*
115         this.closeBtn = this.createTool(this.tools.dom, "roo-layout-close");
116         this.closeBtn.enableDisplayMode();
117         this.closeBtn.on("click", this.closeClicked, this);
118         this.closeBtn.hide();
119     */
120         this.createBody(this.config);
121         if(this.config.hideWhenEmpty){
122             this.hide();
123             this.on("paneladded", this.validateVisibility, this);
124             this.on("panelremoved", this.validateVisibility, this);
125         }
126         if(this.autoScroll){
127             this.bodyEl.setStyle("overflow", "auto");
128         }else{
129             this.bodyEl.setStyle("overflow", this.config.overflow || 'hidden');
130         }
131         //if(c.titlebar !== false){
132             if((!this.config.titlebar && !this.config.title) || this.config.titlebar === false){
133                 this.titleEl.hide();
134             }else{
135                 this.titleEl.show();
136                 if(this.config.title){
137                     this.titleTextEl.innerHTML = this.config.title;
138                 }
139             }
140         //}
141         if(this.config.collapsed){
142             this.collapse(true);
143         }
144         if(this.config.hidden){
145             this.hide();
146         }
147         
148         if (this.unrendered_panels && this.unrendered_panels.length) {
149             for (var i =0;i< this.unrendered_panels.length; i++) {
150                 this.add(this.unrendered_panels[i]);
151             }
152             this.unrendered_panels = null;
153             
154         }
155         
156     },
157     
158     applyConfig : function(c)
159     {
160         /*
161          *if(c.collapsible && this.position != "center" && !this.collapsedEl){
162             var dh = Roo.DomHelper;
163             if(c.titlebar !== false){
164                 this.collapseBtn = this.createTool(this.tools.dom, "roo-layout-collapse-"+this.position);
165                 this.collapseBtn.on("click", this.collapse, this);
166                 this.collapseBtn.enableDisplayMode();
167                 /*
168                 if(c.showPin === true || this.showPin){
169                     this.stickBtn = this.createTool(this.tools.dom, "roo-layout-stick");
170                     this.stickBtn.enableDisplayMode();
171                     this.stickBtn.on("click", this.expand, this);
172                     this.stickBtn.hide();
173                 }
174                 
175             }
176             */
177             /** This region's collapsed element
178             * @type Roo.Element */
179             /*
180              *
181             this.collapsedEl = dh.append(this.mgr.el.dom, {cls: "x-layout-collapsed x-layout-collapsed-"+this.position, children:[
182                 {cls: "x-layout-collapsed-tools", children:[{cls: "x-layout-ctools-inner"}]}
183             ]}, true);
184             
185             if(c.floatable !== false){
186                this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
187                this.collapsedEl.on("click", this.collapseClick, this);
188             }
189
190             if(c.collapsedTitle && (this.position == "north" || this.position== "south")) {
191                 this.collapsedTitleTextEl = dh.append(this.collapsedEl.dom, {tag: "div", cls: "x-unselectable x-layout-panel-hd-text",
192                    id: "message", unselectable: "on", style:{"float":"left"}});
193                this.collapsedTitleTextEl.innerHTML = c.collapsedTitle;
194              }
195             this.expandBtn = this.createTool(this.collapsedEl.dom.firstChild.firstChild, "x-layout-expand-"+this.position);
196             this.expandBtn.on("click", this.expand, this);
197             
198         }
199         
200         if(this.collapseBtn){
201             this.collapseBtn.setVisible(c.collapsible == true);
202         }
203         
204         this.cmargins = c.cmargins || this.cmargins ||
205                          (this.position == "west" || this.position == "east" ?
206                              {top: 0, left: 2, right:2, bottom: 0} :
207                              {top: 2, left: 0, right:0, bottom: 2});
208         */
209         this.margins = c.margins || this.margins || {top: 0, left: 0, right:0, bottom: 0};
210         
211         
212         this.bottomTabs = c.tabPosition != "top";
213         
214         this.autoScroll = c.autoScroll || false;
215         
216         
217        
218         
219         this.duration = c.duration || .30;
220         this.slideDuration = c.slideDuration || .45;
221         this.config = c;
222        
223     },
224     /**
225      * Returns true if this region is currently visible.
226      * @return {Boolean}
227      */
228     isVisible : function(){
229         return this.visible;
230     },
231
232     /**
233      * Updates the title for collapsed north/south regions (used with {@link #collapsedTitle} config option)
234      * @param {String} title (optional) The title text (accepts HTML markup, defaults to the numeric character reference for a non-breaking space, "&amp;#160;")
235      */
236     //setCollapsedTitle : function(title){
237     //    title = title || "&#160;";
238      //   if(this.collapsedTitleTextEl){
239       //      this.collapsedTitleTextEl.innerHTML = title;
240        // }
241     //},
242
243     getBox : function(){
244         var b;
245       //  if(!this.collapsed){
246             b = this.el.getBox(false, true);
247        // }else{
248           //  b = this.collapsedEl.getBox(false, true);
249         //}
250         return b;
251     },
252
253     getMargins : function(){
254         return this.margins;
255         //return this.collapsed ? this.cmargins : this.margins;
256     },
257 /*
258     highlight : function(){
259         this.el.addClass("x-layout-panel-dragover");
260     },
261
262     unhighlight : function(){
263         this.el.removeClass("x-layout-panel-dragover");
264     },
265 */
266     updateBox : function(box)
267     {
268         if (!this.bodyEl) {
269             return; // not rendered yet..
270         }
271         
272         this.box = box;
273         if(!this.collapsed){
274             this.el.dom.style.left = box.x + "px";
275             this.el.dom.style.top = box.y + "px";
276             this.updateBody(box.width, box.height);
277         }else{
278             this.collapsedEl.dom.style.left = box.x + "px";
279             this.collapsedEl.dom.style.top = box.y + "px";
280             this.collapsedEl.setSize(box.width, box.height);
281         }
282         if(this.tabs){
283             this.tabs.autoSizeTabs();
284         }
285     },
286
287     updateBody : function(w, h)
288     {
289         if(w !== null){
290             this.el.setWidth(w);
291             w -= this.el.getBorderWidth("rl");
292             if(this.config.adjustments){
293                 w += this.config.adjustments[0];
294             }
295         }
296         if(h !== null && h > 0){
297             this.el.setHeight(h);
298             h = this.titleEl && this.titleEl.isDisplayed() ? h - (this.titleEl.getHeight()||0) : h;
299             h -= this.el.getBorderWidth("tb");
300             if(this.config.adjustments){
301                 h += this.config.adjustments[1];
302             }
303             this.bodyEl.setHeight(h);
304             if(this.tabs){
305                 h = this.tabs.syncHeight(h);
306             }
307         }
308         if(this.panelSize){
309             w = w !== null ? w : this.panelSize.width;
310             h = h !== null ? h : this.panelSize.height;
311         }
312         if(this.activePanel){
313             var el = this.activePanel.getEl();
314             w = w !== null ? w : el.getWidth();
315             h = h !== null ? h : el.getHeight();
316             this.panelSize = {width: w, height: h};
317             this.activePanel.setSize(w, h);
318         }
319         if(Roo.isIE && this.tabs){
320             this.tabs.el.repaint();
321         }
322     },
323
324     /**
325      * Returns the container element for this region.
326      * @return {Roo.Element}
327      */
328     getEl : function(){
329         return this.el;
330     },
331
332     /**
333      * Hides this region.
334      */
335     hide : function(){
336         //if(!this.collapsed){
337             this.el.dom.style.left = "-2000px";
338             this.el.hide();
339         //}else{
340          //   this.collapsedEl.dom.style.left = "-2000px";
341          //   this.collapsedEl.hide();
342        // }
343         this.visible = false;
344         this.fireEvent("visibilitychange", this, false);
345     },
346
347     /**
348      * Shows this region if it was previously hidden.
349      */
350     show : function(){
351         //if(!this.collapsed){
352             this.el.show();
353         //}else{
354         //    this.collapsedEl.show();
355        // }
356         this.visible = true;
357         this.fireEvent("visibilitychange", this, true);
358     },
359 /*
360     closeClicked : function(){
361         if(this.activePanel){
362             this.remove(this.activePanel);
363         }
364     },
365
366     collapseClick : function(e){
367         if(this.isSlid){
368            e.stopPropagation();
369            this.slideIn();
370         }else{
371            e.stopPropagation();
372            this.slideOut();
373         }
374     },
375 */
376     /**
377      * Collapses this region.
378      * @param {Boolean} skipAnim (optional) true to collapse the element without animation (if animate is true)
379      */
380     /*
381     collapse : function(skipAnim, skipCheck = false){
382         if(this.collapsed) {
383             return;
384         }
385         
386         if(skipCheck || this.fireEvent("beforecollapse", this) != false){
387             
388             this.collapsed = true;
389             if(this.split){
390                 this.split.el.hide();
391             }
392             if(this.config.animate && skipAnim !== true){
393                 this.fireEvent("invalidated", this);
394                 this.animateCollapse();
395             }else{
396                 this.el.setLocation(-20000,-20000);
397                 this.el.hide();
398                 this.collapsedEl.show();
399                 this.fireEvent("collapsed", this);
400                 this.fireEvent("invalidated", this);
401             }
402         }
403         
404     },
405 */
406     animateCollapse : function(){
407         // overridden
408     },
409
410     /**
411      * Expands this region if it was previously collapsed.
412      * @param {Roo.EventObject} e The event that triggered the expand (or null if calling manually)
413      * @param {Boolean} skipAnim (optional) true to expand the element without animation (if animate is true)
414      */
415     /*
416     expand : function(e, skipAnim){
417         if(e) {
418             e.stopPropagation();
419         }
420         if(!this.collapsed || this.el.hasActiveFx()) {
421             return;
422         }
423         if(this.isSlid){
424             this.afterSlideIn();
425             skipAnim = true;
426         }
427         this.collapsed = false;
428         if(this.config.animate && skipAnim !== true){
429             this.animateExpand();
430         }else{
431             this.el.show();
432             if(this.split){
433                 this.split.el.show();
434             }
435             this.collapsedEl.setLocation(-2000,-2000);
436             this.collapsedEl.hide();
437             this.fireEvent("invalidated", this);
438             this.fireEvent("expanded", this);
439         }
440     },
441 */
442     animateExpand : function(){
443         // overridden
444     },
445
446     initTabs : function()
447     {
448         //this.bodyEl.setStyle("overflow", "hidden"); -- this is set in render?
449         
450         var ts = new Roo.bootstrap.panel.Tabs({
451                 el: this.bodyEl.dom,
452                 tabPosition: this.bottomTabs ? 'bottom' : 'top',
453                 disableTooltips: this.config.disableTabTips,
454                 toolbar : this.config.toolbar
455             });
456         
457         if(this.config.hideTabs){
458             ts.stripWrap.setDisplayed(false);
459         }
460         this.tabs = ts;
461         ts.resizeTabs = this.config.resizeTabs === true;
462         ts.minTabWidth = this.config.minTabWidth || 40;
463         ts.maxTabWidth = this.config.maxTabWidth || 250;
464         ts.preferredTabWidth = this.config.preferredTabWidth || 150;
465         ts.monitorResize = false;
466         //ts.bodyEl.setStyle("overflow", this.config.autoScroll ? "auto" : "hidden"); // this is set in render?
467         ts.bodyEl.addClass('roo-layout-tabs-body');
468         this.panels.each(this.initPanelAsTab, this);
469     },
470
471     initPanelAsTab : function(panel){
472         var ti = this.tabs.addTab(
473             panel.getEl().id,
474             panel.getTitle(),
475             null,
476             this.config.closeOnTab && panel.isClosable(),
477             panel.tpl
478         );
479         if(panel.tabTip !== undefined){
480             ti.setTooltip(panel.tabTip);
481         }
482         ti.on("activate", function(){
483               this.setActivePanel(panel);
484         }, this);
485         
486         if(this.config.closeOnTab){
487             ti.on("beforeclose", function(t, e){
488                 e.cancel = true;
489                 this.remove(panel);
490             }, this);
491         }
492         
493         panel.tabItem = ti;
494         
495         return ti;
496     },
497
498     updatePanelTitle : function(panel, title)
499     {
500         if(this.activePanel == panel){
501             this.updateTitle(title);
502         }
503         if(this.tabs){
504             var ti = this.tabs.getTab(panel.getEl().id);
505             ti.setText(title);
506             if(panel.tabTip !== undefined){
507                 ti.setTooltip(panel.tabTip);
508             }
509         }
510     },
511
512     updateTitle : function(title){
513         if(this.titleTextEl && !this.config.title){
514             this.titleTextEl.innerHTML = (typeof title != "undefined" && title.length > 0 ? title : "&#160;");
515         }
516     },
517
518     setActivePanel : function(panel)
519     {
520         panel = this.getPanel(panel);
521         if(this.activePanel && this.activePanel != panel){
522             if(this.activePanel.setActiveState(false) === false){
523                 return;
524             }
525         }
526         this.activePanel = panel;
527         panel.setActiveState(true);
528         if(this.panelSize){
529             panel.setSize(this.panelSize.width, this.panelSize.height);
530         }
531         if(this.closeBtn){
532             this.closeBtn.setVisible(!this.config.closeOnTab && !this.isSlid && panel.isClosable());
533         }
534         this.updateTitle(panel.getTitle());
535         if(this.tabs){
536             this.fireEvent("invalidated", this);
537         }
538         this.fireEvent("panelactivated", this, panel);
539     },
540
541     /**
542      * Shows the specified panel.
543      * @param {Number/String/ContentPanel} panelId The panel's index, id or the panel itself
544      * @return {Roo.ContentPanel} The shown panel, or null if a panel could not be found from panelId
545      */
546     showPanel : function(panel)
547     {
548         panel = this.getPanel(panel);
549         if(panel){
550             if(this.tabs){
551                 var tab = this.tabs.getTab(panel.getEl().id);
552                 if(tab.isHidden()){
553                     this.tabs.unhideTab(tab.id);
554                 }
555                 tab.activate();
556             }else{
557                 this.setActivePanel(panel);
558             }
559         }
560         return panel;
561     },
562
563     /**
564      * Get the active panel for this region.
565      * @return {Roo.ContentPanel} The active panel or null
566      */
567     getActivePanel : function(){
568         return this.activePanel;
569     },
570
571     validateVisibility : function(){
572         if(this.panels.getCount() < 1){
573             this.updateTitle("&#160;");
574             this.closeBtn.hide();
575             this.hide();
576         }else{
577             if(!this.isVisible()){
578                 this.show();
579             }
580         }
581     },
582
583     /**
584      * Adds the passed ContentPanel(s) to this region.
585      * @param {ContentPanel...} panel The ContentPanel(s) to add (you can pass more than one)
586      * @return {Roo.ContentPanel} The panel added (if only one was added; null otherwise)
587      */
588     add : function(panel)
589     {
590         if(arguments.length > 1){
591             for(var i = 0, len = arguments.length; i < len; i++) {
592                 this.add(arguments[i]);
593             }
594             return null;
595         }
596         
597         // if we have not been rendered yet, then we can not really do much of this..
598         if (!this.bodyEl) {
599             this.unrendered_panels.push(panel);
600             return panel;
601         }
602         
603         
604         
605         
606         if(this.hasPanel(panel)){
607             this.showPanel(panel);
608             return panel;
609         }
610         panel.setRegion(this);
611         this.panels.add(panel);
612        /* if(this.panels.getCount() == 1 && !this.config.alwaysShowTabs){
613             // sinle panel - no tab...?? would it not be better to render it with the tabs,
614             // and hide them... ???
615             this.bodyEl.dom.appendChild(panel.getEl().dom);
616             if(panel.background !== true){
617                 this.setActivePanel(panel);
618             }
619             this.fireEvent("paneladded", this, panel);
620             return panel;
621         }
622         */
623         if(!this.tabs){
624             this.initTabs();
625         }else{
626             this.initPanelAsTab(panel);
627         }
628         
629         
630         if(panel.background !== true){
631             this.tabs.activate(panel.getEl().id);
632         }
633         this.fireEvent("paneladded", this, panel);
634         return panel;
635     },
636
637     /**
638      * Hides the tab for the specified panel.
639      * @param {Number/String/ContentPanel} panel The panel's index, id or the panel itself
640      */
641     hidePanel : function(panel){
642         if(this.tabs && (panel = this.getPanel(panel))){
643             this.tabs.hideTab(panel.getEl().id);
644         }
645     },
646
647     /**
648      * Unhides the tab for a previously hidden panel.
649      * @param {Number/String/ContentPanel} panel The panel's index, id or the panel itself
650      */
651     unhidePanel : function(panel){
652         if(this.tabs && (panel = this.getPanel(panel))){
653             this.tabs.unhideTab(panel.getEl().id);
654         }
655     },
656
657     clearPanels : function(){
658         while(this.panels.getCount() > 0){
659              this.remove(this.panels.first());
660         }
661     },
662
663     /**
664      * Removes the specified panel. If preservePanel is not true (either here or in the config), the panel is destroyed.
665      * @param {Number/String/ContentPanel} panel The panel's index, id or the panel itself
666      * @param {Boolean} preservePanel Overrides the config preservePanel option
667      * @return {Roo.ContentPanel} The panel that was removed
668      */
669     remove : function(panel, preservePanel)
670     {
671         panel = this.getPanel(panel);
672         if(!panel){
673             return null;
674         }
675         var e = {};
676         this.fireEvent("beforeremove", this, panel, e);
677         if(e.cancel === true){
678             return null;
679         }
680         preservePanel = (typeof preservePanel != "undefined" ? preservePanel : (this.config.preservePanels === true || panel.preserve === true));
681         var panelId = panel.getId();
682         this.panels.removeKey(panelId);
683         if(preservePanel){
684             document.body.appendChild(panel.getEl().dom);
685         }
686         if(this.tabs){
687             this.tabs.removeTab(panel.getEl().id);
688         }else if (!preservePanel){
689             this.bodyEl.dom.removeChild(panel.getEl().dom);
690         }
691         if(this.panels.getCount() == 1 && this.tabs && !this.config.alwaysShowTabs){
692             var p = this.panels.first();
693             var tempEl = document.createElement("div"); // temp holder to keep IE from deleting the node
694             tempEl.appendChild(p.getEl().dom);
695             this.bodyEl.update("");
696             this.bodyEl.dom.appendChild(p.getEl().dom);
697             tempEl = null;
698             this.updateTitle(p.getTitle());
699             this.tabs = null;
700             this.bodyEl.setStyle("overflow", this.config.autoScroll ? "auto" : "hidden");
701             this.setActivePanel(p);
702         }
703         panel.setRegion(null);
704         if(this.activePanel == panel){
705             this.activePanel = null;
706         }
707         if(this.config.autoDestroy !== false && preservePanel !== true){
708             try{panel.destroy();}catch(e){}
709         }
710         this.fireEvent("panelremoved", this, panel);
711         return panel;
712     },
713
714     /**
715      * Returns the TabPanel component used by this region
716      * @return {Roo.TabPanel}
717      */
718     getTabs : function(){
719         return this.tabs;
720     },
721
722     createTool : function(parentEl, className){
723         var btn = Roo.DomHelper.append(parentEl, {
724             tag: "div",
725             cls: "x-layout-tools-button",
726             children: [ {
727                 tag: "div",
728                 cls: "roo-layout-tools-button-inner " + className,
729                 html: "&#160;"
730             }]
731         }, true);
732         btn.addClassOnOver("roo-layout-tools-button-over");
733         return btn;
734     }
735 });