3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4 <title>The source code</title>
5 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <body onload="prettyPrint();">
9 <pre class="prettyprint lang-js">/*!
10 * Ext JS Library 3.3.1
11 * Copyright(c) 2006-2010 Sencha Inc.
12 * licensing@sencha.com
13 * http://www.sencha.com/license
15 <div id="cls-Ext.layout.ToolbarLayout"></div>/**
16 * @class Ext.layout.ToolbarLayout
17 * @extends Ext.layout.ContainerLayout
18 * Layout manager used by Ext.Toolbar. This is highly specialised for use by Toolbars and would not
19 * usually be used by any other class.
21 Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
26 <div id="prop-Ext.layout.ToolbarLayout-triggerWidth"></div>/**
27 * @property triggerWidth
29 * The width allocated for the menu trigger at the extreme right end of the Toolbar
33 <div id="prop-Ext.layout.ToolbarLayout-noItemsMenuText"></div>/**
34 * @property noItemsMenuText
36 * HTML fragment to render into the toolbar overflow menu if there are no items to display
38 noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
42 * @property lastOverflow
44 * Used internally to record whether the last layout caused an overflow or not
52 * String used to build the HTML injected to support the Toolbar's layout. The align property is
53 * injected into this string inside the td.x-toolbar-left element during onLayout.
56 '<table cellspacing="0" class="x-toolbar-ct">',
59 '<td class="x-toolbar-left" align="{0}">',
60 '<table cellspacing="0">',
62 '<tr class="x-toolbar-left-row"></tr>',
66 '<td class="x-toolbar-right" align="right">',
67 '<table cellspacing="0" class="x-toolbar-right-ct">',
71 '<table cellspacing="0">',
73 '<tr class="x-toolbar-right-row"></tr>',
78 '<table cellspacing="0">',
80 '<tr class="x-toolbar-extras-row"></tr>',
95 * Create the wrapping Toolbar HTML and render/move all the items into the correct places
97 onLayout : function(ct, target) {
98 //render the Toolbar <table> HTML if it's not already present
100 var align = ct.buttonAlign == 'center' ? 'center' : 'left';
102 target.addClass('x-toolbar-layout-ct');
103 target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
105 this.leftTr = target.child('tr.x-toolbar-left-row', true);
106 this.rightTr = target.child('tr.x-toolbar-right-row', true);
107 this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
109 if (this.hiddenItem == undefined) {
110 <div id="prop-Ext.layout.ToolbarLayout-hiddenItems"></div>/**
111 * @property hiddenItems
113 * Holds all items that are currently hidden due to there not being enough space to render them
114 * These items will appear on the expand menu.
116 this.hiddenItems = [];
120 var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
121 items = ct.items.items,
124 //render each item if not already rendered, place it into the correct (left or right) target
125 for (var i = 0, len = items.length, c; i < len; i++, position++) {
131 } else if (!c.rendered) {
132 c.render(this.insertCell(c, side, position));
133 this.configureItem(c);
135 if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
136 var td = this.insertCell(c, side, position);
137 td.appendChild(c.getPositionEl().dom);
138 c.container = Ext.get(td);
143 //strip extra empty cells
144 this.cleanup(this.leftTr);
145 this.cleanup(this.rightTr);
146 this.cleanup(this.extrasTr);
147 this.fitToSize(target);
152 * Removes any empty nodes from the given element
153 * @param {Ext.Element} el The element to clean up
155 cleanup : function(el) {
156 var cn = el.childNodes, i, c;
158 for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
167 * Inserts the given Toolbar item into the given element
168 * @param {Ext.Component} c The component to add
169 * @param {Ext.Element} target The target to add the component to
170 * @param {Number} position The position to add the component at
172 insertCell : function(c, target, position) {
173 var td = document.createElement('td');
174 td.className = 'x-toolbar-cell';
176 target.insertBefore(td, target.childNodes[position] || null);
183 * Hides an item because it will not fit in the available width. The item will be unhidden again
184 * if the Toolbar is resized to be large enough to show it
185 * @param {Ext.Component} item The item to hide
187 hideItem : function(item) {
188 this.hiddenItems.push(item);
190 item.xtbHidden = true;
191 item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
197 * Unhides an item that was previously hidden due to there not being enough space left on the Toolbar
198 * @param {Ext.Component} item The item to show
200 unhideItem : function(item) {
202 item.xtbHidden = false;
203 this.hiddenItems.remove(item);
208 * Returns the width of the given toolbar item. If the item is currently hidden because there
209 * is not enough room to render it, its previous width is returned
210 * @param {Ext.Component} c The component to measure
211 * @return {Number} The width of the item
213 getItemWidth : function(c) {
214 return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
219 * Called at the end of onLayout. At this point the Toolbar has already been resized, so we need
220 * to fit the items into the available width. We add up the width required by all of the items in
221 * the toolbar - if we don't have enough space we hide the extra items and render the expand menu
223 * @param {Ext.Element} target The Element the Toolbar is currently laid out within
225 fitToSize : function(target) {
226 if (this.container.enableOverflow === false) {
230 var width = target.dom.clientWidth,
231 tableWidth = target.dom.firstChild.offsetWidth,
232 clipWidth = width - this.triggerWidth,
233 lastWidth = this.lastWidth || 0,
235 hiddenItems = this.hiddenItems,
236 hasHiddens = hiddenItems.length != 0,
237 isLarger = width >= lastWidth;
239 this.lastWidth = width;
241 if (tableWidth > width || (hasHiddens && isLarger)) {
242 var items = this.container.items.items,
247 for (var i = 0; i < len; i++) {
251 loopWidth += this.getItemWidth(item);
252 if (loopWidth > clipWidth) {
253 if (!(item.hidden || item.xtbHidden)) {
256 } else if (item.xtbHidden) {
257 this.unhideItem(item);
263 //test for number of hidden items again here because they may have changed above
264 hasHiddens = hiddenItems.length != 0;
269 if (!this.lastOverflow) {
270 this.container.fireEvent('overflowchange', this.container, true);
271 this.lastOverflow = true;
273 } else if (this.more) {
278 if (this.lastOverflow) {
279 this.container.fireEvent('overflowchange', this.container, false);
280 this.lastOverflow = false;
287 * Returns a menu config for a given component. This config is used to create a menu item
288 * to be added to the expander menu
289 * @param {Ext.Component} component The component to create the config for
290 * @param {Boolean} hideOnClick Passed through to the menu item
292 createMenuConfig : function(component, hideOnClick){
293 var config = Ext.apply({}, component.initialConfig),
294 group = component.toggleGroup;
296 Ext.copyTo(config, component, [
297 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
301 text : component.overflowText || component.text,
302 hideOnClick: hideOnClick
305 if (group || component.enableToggle) {
308 checked: component.pressed,
310 checkchange: function(item, checked){
311 component.toggle(checked);
317 delete config.ownerCt;
326 * Adds the given Toolbar item to the given menu. Buttons inside a buttongroup are added individually.
327 * @param {Ext.menu.Menu} menu The menu to add to
328 * @param {Ext.Component} component The component to add
330 addComponentToMenu : function(menu, component) {
331 if (component instanceof Ext.Toolbar.Separator) {
334 } else if (Ext.isFunction(component.isXType)) {
335 if (component.isXType('splitbutton')) {
336 menu.add(this.createMenuConfig(component, true));
338 } else if (component.isXType('button')) {
339 menu.add(this.createMenuConfig(component, !component.menu));
341 } else if (component.isXType('buttongroup')) {
342 component.items.each(function(item){
343 this.addComponentToMenu(menu, item);
351 * Deletes the sub-menu of each item in the expander menu. Submenus are created for items such as
352 * splitbuttons and buttongroups, where the Toolbar item cannot be represented by a single menu item
354 clearMenu : function(){
355 var menu = this.moreMenu;
356 if (menu && menu.items) {
357 menu.items.each(function(item){
365 * Called before the expand menu is shown, this rebuilds the menu since it was last shown because
366 * it is possible that the items hidden due to space limitations on the Toolbar have changed since.
367 * @param {Ext.menu.Menu} m The menu
369 beforeMoreShow : function(menu) {
370 var items = this.container.items.items,
375 var needsSep = function(group, item){
376 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
381 for (var i = 0; i < len; i++) {
383 if (item.xtbHidden) {
384 if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
387 this.addComponentToMenu(menu, item);
392 // put something so the menu isn't empty if no compatible items found
393 if (menu.items.length < 1) {
394 menu.add(this.noItemsMenuText);
400 * Creates the expand trigger and menu, adding them to the <tr> at the extreme right of the
403 initMore : function(){
408 * @type Ext.menu.Menu
409 * The expand menu - holds items for every Toolbar item that cannot be shown
410 * because the Toolbar is currently not wide enough.
412 this.moreMenu = new Ext.menu.Menu({
413 ownerCt : this.container,
415 beforeshow: this.beforeMoreShow,
424 * The expand button which triggers the overflow menu to be shown
426 this.more = new Ext.Button({
427 iconCls: 'x-toolbar-more-icon',
428 cls : 'x-toolbar-more',
429 menu : this.moreMenu,
430 ownerCt: this.container
433 var td = this.insertCell(this.more, this.extrasTr, 100);
434 this.more.render(td);
438 destroy : function(){
439 Ext.destroy(this.more, this.moreMenu);
442 delete this.extrasTr;
443 Ext.layout.ToolbarLayout.superclass.destroy.call(this);
447 Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;