123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-layout-container-boxOverflow-Menu'>/**
- </span> * @private
- */
- Ext.define('Ext.layout.container.boxOverflow.Menu', {
- /* Begin Definitions */
- extend: 'Ext.layout.container.boxOverflow.None',
- requires: ['Ext.toolbar.Separator', 'Ext.button.Button'],
- alternateClassName: 'Ext.layout.boxOverflow.Menu',
-
- /* End Definitions */
- <span id='Ext-layout-container-boxOverflow-Menu-cfg-triggerButtonCls'> /**
- </span> * @cfg {String} triggerButtonCls
- * CSS class added to the Button which shows the overflow menu.
- */
- <span id='Ext-layout-container-boxOverflow-Menu-property-noItemsMenuText'> /**
- </span> * @property {String} noItemsMenuText
- * HTML fragment to render into the toolbar overflow menu if there are no items to display
- */
- noItemsMenuText : '<div class="' + Ext.baseCSSPrefix + 'toolbar-no-items">(None)</div>',
- constructor: function(layout) {
- var me = this;
- me.callParent(arguments);
- me.triggerButtonCls = me.triggerButtonCls || Ext.baseCSSPrefix + 'box-menu-' + layout.getNames().right;
- <span id='Ext-layout-container-boxOverflow-Menu-property-menuItems'> /**
- </span> * @property {Array} menuItems
- * Array of all items that are currently hidden and should go into the dropdown menu
- */
- me.menuItems = [];
- },
- beginLayout: function (ownerContext) {
- this.callParent(arguments);
- // Before layout, we need to re-show all items which we may have hidden due to a
- // previous overflow...
- this.clearOverflow(ownerContext);
- },
- beginLayoutCycle: function (ownerContext, firstCycle) {
- this.callParent(arguments);
- if (!firstCycle) {
- // if we are being re-run, we need to clear any overflow from the last run and
- // recache the childItems collection
- this.clearOverflow(ownerContext);
- this.layout.cacheChildItems(ownerContext);
- }
- },
- onRemove: function(comp){
- Ext.Array.remove(this.menuItems, comp);
- },
- // We don't define a prefix in menu overflow.
- getSuffixConfig: function() {
- var me = this,
- layout = me.layout,
- oid = layout.owner.id;
- <span id='Ext-layout-container-boxOverflow-Menu-property-menu'> /**
- </span> * @private
- * @property {Ext.menu.Menu} menu
- * The expand menu - holds items for every item that cannot be shown
- * because the container is currently not large enough.
- */
- me.menu = new Ext.menu.Menu({
- listeners: {
- scope: me,
- beforeshow: me.beforeMenuShow
- }
- });
- <span id='Ext-layout-container-boxOverflow-Menu-property-menuTrigger'> /**
- </span> * @private
- * @property {Ext.button.Button} menuTrigger
- * The expand button which triggers the overflow menu to be shown
- */
- me.menuTrigger = new Ext.button.Button({
- id : oid + '-menu-trigger',
- cls : Ext.layout.container.Box.prototype.innerCls + ' ' + me.triggerButtonCls,
- hidden : true,
- ownerCt : layout.owner, // To enable the Menu to ascertain a valid zIndexManager owner in the same tree
- ownerLayout: layout,
- iconCls : Ext.baseCSSPrefix + me.getOwnerType(layout.owner) + '-more-icon',
- ui : layout.owner instanceof Ext.toolbar.Toolbar ? 'default-toolbar' : 'default',
- menu : me.menu,
- getSplitCls: function() { return '';}
- });
- return me.menuTrigger.getRenderTree();
- },
-
- getOverflowCls: function() {
- return Ext.baseCSSPrefix + this.layout.direction + '-box-overflow-body';
- },
- handleOverflow: function(ownerContext) {
- var me = this,
- layout = me.layout,
- names = layout.getNames(),
- plan = ownerContext.state.boxPlan,
- posArgs = [null, null];
- me.showTrigger(ownerContext);
- // Center the menuTrigger button.
- // TODO: Should we emulate align: 'middle' like this, or should we 'stretchmax' the menuTrigger?
- posArgs[names.heightIndex] = (plan.maxSize - me.menuTrigger[names.getHeight]()) / 2;
- me.menuTrigger.setPosition.apply(me.menuTrigger, posArgs);
- return {
- reservedSpace: me.menuTrigger[names.getWidth]()
- };
- },
- <span id='Ext-layout-container-boxOverflow-Menu-method-captureChildElements'> /**
- </span> * Finishes the render operation of the trigger Button.
- * @private
- */
- captureChildElements: function() {
- var menuTrigger = this.menuTrigger;
- if (menuTrigger.rendering) {
- menuTrigger.finishRender();
- }
- },
- _asLayoutRoot: { isRoot: true },
- <span id='Ext-layout-container-boxOverflow-Menu-method-clearOverflow'> /**
- </span> * @private
- * Called by the layout, when it determines that there is no overflow.
- * Also called as an interceptor to the layout's onLayout method to reshow
- * previously hidden overflowing items.
- */
- clearOverflow: function(ownerContext) {
- var me = this,
- items = me.menuItems,
- item,
- i = 0,
- length = items.length,
- owner = me.layout.owner,
- asLayoutRoot = me._asLayoutRoot;
- owner.suspendLayouts();
- me.captureChildElements();
- me.hideTrigger();
- owner.resumeLayouts();
- for (; i < length; i++) {
- item = items[i];
- // What we are doing here is preventing the layout bubble from invalidating our
- // owner component. We need just the button to be added to the layout run.
- item.suspendLayouts();
- item.show();
- item.resumeLayouts(asLayoutRoot);
- }
- items.length = 0;
- },
- <span id='Ext-layout-container-boxOverflow-Menu-method-showTrigger'> /**
- </span> * @private
- * Shows the overflow trigger when enableOverflow is set to true and the items
- * in the layout are too wide to fit in the space available
- */
- showTrigger: function(ownerContext) {
- var me = this,
- layout = me.layout,
- owner = layout.owner,
- names = layout.getNames(),
- startProp = names.x,
- sizeProp = names.width,
- plan = ownerContext.state.boxPlan,
- available = plan.targetSize[sizeProp],
- childItems = ownerContext.childItems,
- len = childItems.length,
- menuTrigger = me.menuTrigger,
- childContext,
- comp, i, props;
- // We don't want the menuTrigger.show to cause owner's layout to be invalidated, so
- // we force just the button to be invalidated and added to the current run.
- menuTrigger.suspendLayouts();
- menuTrigger.show();
- menuTrigger.resumeLayouts(me._asLayoutRoot);
- available -= me.menuTrigger.getWidth();
- owner.suspendLayouts();
- // Hide all items which are off the end, and store them to allow them to be restored
- // before each layout operation.
- me.menuItems.length = 0;
- for (i = 0; i < len; i++) {
- childContext = childItems[i];
- props = childContext.props;
- if (props[startProp] + props[sizeProp] > available) {
- comp = childContext.target;
- me.menuItems.push(comp);
- comp.hide();
- }
- }
- owner.resumeLayouts();
- },
- <span id='Ext-layout-container-boxOverflow-Menu-method-hideTrigger'> /**
- </span> * @private
- */
- hideTrigger: function() {
- var menuTrigger = this.menuTrigger;
- if (menuTrigger) {
- menuTrigger.hide();
- }
- },
- <span id='Ext-layout-container-boxOverflow-Menu-method-beforeMenuShow'> /**
- </span> * @private
- * Called before the overflow menu is shown. This constructs the menu's items, caching them for as long as it can.
- */
- beforeMenuShow: function(menu) {
- var me = this,
- items = me.menuItems,
- i = 0,
- len = items.length,
- item,
- prev,
- needsSep = function(group, prev){
- return group.isXType('buttongroup') && !(prev instanceof Ext.toolbar.Separator);
- };
- menu.suspendLayouts();
- me.clearMenu();
- menu.removeAll();
- for (; i < len; i++) {
- item = items[i];
- // Do not show a separator as a first item
- if (!i && (item instanceof Ext.toolbar.Separator)) {
- continue;
- }
- if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
- menu.add('-');
- }
- me.addComponentToMenu(menu, item);
- prev = item;
- }
- // put something so the menu isn't empty if no compatible items found
- if (menu.items.length < 1) {
- menu.add(me.noItemsMenuText);
- }
- menu.resumeLayouts();
- },
-
- <span id='Ext-layout-container-boxOverflow-Menu-method-createMenuConfig'> /**
- </span> * @private
- * Returns a menu config for a given component. This config is used to create a menu item
- * to be added to the expander menu
- * @param {Ext.Component} component The component to create the config for
- * @param {Boolean} hideOnClick Passed through to the menu item
- */
- createMenuConfig : function(component, hideOnClick) {
- var config = Ext.apply({}, component.initialConfig),
- group = component.toggleGroup;
- Ext.copyTo(config, component, [
- 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
- ]);
- Ext.apply(config, {
- text : component.overflowText || component.text,
- hideOnClick: hideOnClick,
- destroyMenu: false
- });
- // Clone must have same value, and must sync original's value on change
- if (component.isFormField) {
- config.value = component.getValue();
- // We're going to add a listener
- if (!config.listeners) {
- config.listeners = {};
- }
- // Sync the original component's value when the clone changes value.
- // This intentionally overwrites any developer-configured change listener on the clone.
- // That's because we monitor the clone's change event, and sync the
- // original field by calling setValue, so the original field's change
- // event will still fire.
- config.listeners.change = function(c, newVal, oldVal) {
- component.setValue(newVal);
- }
- }
- // ToggleButtons become CheckItems
- else if (group || component.enableToggle) {
- Ext.apply(config, {
- iconAlign: 'right',
- hideOnClick: false,
- group : group,
- checked: component.pressed,
- listeners: {
- checkchange: function(item, checked) {
- component.toggle(checked);
- }
- }
- });
- }
- delete config.ownerCt;
- delete config.xtype;
- delete config.id;
- return config;
- },
- <span id='Ext-layout-container-boxOverflow-Menu-method-addComponentToMenu'> /**
- </span> * @private
- * Adds the given Toolbar item to the given menu. Buttons inside a buttongroup are added individually.
- * @param {Ext.menu.Menu} menu The menu to add to
- * @param {Ext.Component} component The component to add
- * TODO: Implement overrides in Ext.layout.container.boxOverflow which create overrides
- * for SplitButton, Button, ButtonGroup, and TextField. And a generic one for Component
- * which create clones suitable for use in an overflow menu.
- */
- addComponentToMenu : function(menu, component) {
- var me = this,
- i, items, iLen;
- if (component instanceof Ext.toolbar.Separator) {
- menu.add('-');
- } else if (component.isComponent) {
- if (component.isXType('splitbutton')) {
- menu.add(me.createMenuConfig(component, true));
- } else if (component.isXType('button')) {
- menu.add(me.createMenuConfig(component, !component.menu));
- } else if (component.isXType('buttongroup')) {
- items = component.items.items;
- iLen = items.length;
- for (i = 0; i < iLen; i++) {
- me.addComponentToMenu(menu, items[i]);
- }
- } else {
- menu.add(Ext.create(Ext.getClassName(component), me.createMenuConfig(component)));
- }
- }
- },
- <span id='Ext-layout-container-boxOverflow-Menu-method-clearMenu'> /**
- </span> * @private
- * Deletes the sub-menu of each item in the expander menu. Submenus are created for items such as
- * splitbuttons and buttongroups, where the Toolbar item cannot be represented by a single menu item
- */
- clearMenu : function() {
- var menu = this.menu,
- items, i, iLen, item;
-
- if (menu && menu.items) {
- items = menu.items.items;
- iLen = items.length;
-
- for (i = 0; i < iLen; i++) {
- item = items[i];
- if (item.setMenu) {
- item.setMenu(null);
- }
- }
- }
- },
- <span id='Ext-layout-container-boxOverflow-Menu-method-destroy'> /**
- </span> * @private
- */
- destroy: function() {
- var trigger = this.menuTrigger;
-
- if (trigger && !this.layout.owner.items.contains(trigger)) {
- // Ensure we delete the ownerCt if it's not in the items
- // so we don't get spurious container remove warnings.
- delete trigger.ownerCt;
- }
- Ext.destroy(this.menu, trigger);
- }
- });
- </pre>
- </body>
- </html>
|