X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/source/widgets/menu/Menu.js diff --git a/source/widgets/menu/Menu.js b/source/widgets/menu/Menu.js deleted file mode 100644 index 2f990a39..00000000 --- a/source/widgets/menu/Menu.js +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Ext JS Library 2.2.1 - * Copyright(c) 2006-2009, Ext JS, LLC. - * licensing@extjs.com - * - * http://extjs.com/license - */ - -/** - * @class Ext.menu.Menu - * @extends Ext.util.Observable - * A menu object. This is the container to which you add all other menu items. Menu can also serve as a base class - * when you want a specialized menu based off of another component (like {@link Ext.menu.DateMenu} for example). - * @constructor - * Creates a new Menu - * @param {Object} config Configuration options - */ -Ext.menu.Menu = function(config){ - if(Ext.isArray(config)){ - config = {items:config}; - } - Ext.apply(this, config); - this.id = this.id || Ext.id(); - this.addEvents( - /** - * @event beforeshow - * Fires before this menu is displayed - * @param {Ext.menu.Menu} this - */ - 'beforeshow', - /** - * @event beforehide - * Fires before this menu is hidden - * @param {Ext.menu.Menu} this - */ - 'beforehide', - /** - * @event show - * Fires after this menu is displayed - * @param {Ext.menu.Menu} this - */ - 'show', - /** - * @event hide - * Fires after this menu is hidden - * @param {Ext.menu.Menu} this - */ - 'hide', - /** - * @event click - * Fires when this menu is clicked (or when the enter key is pressed while it is active) - * @param {Ext.menu.Menu} this - * @param {Ext.menu.Item} menuItem The menu item that was clicked - * @param {Ext.EventObject} e - */ - 'click', - /** - * @event mouseover - * Fires when the mouse is hovering over this menu - * @param {Ext.menu.Menu} this - * @param {Ext.EventObject} e - * @param {Ext.menu.Item} menuItem The menu item that was clicked - */ - 'mouseover', - /** - * @event mouseout - * Fires when the mouse exits this menu - * @param {Ext.menu.Menu} this - * @param {Ext.EventObject} e - * @param {Ext.menu.Item} menuItem The menu item that was clicked - */ - 'mouseout', - /** - * @event itemclick - * Fires when a menu item contained in this menu is clicked - * @param {Ext.menu.BaseItem} baseItem The BaseItem that was clicked - * @param {Ext.EventObject} e - */ - 'itemclick' - ); - Ext.menu.MenuMgr.register(this); - Ext.menu.Menu.superclass.constructor.call(this); - var mis = this.items; - /** - * A MixedCollection of this Menu's items - * @property items - * @type Ext.util.MixedCollection - */ - - this.items = new Ext.util.MixedCollection(); - if(mis){ - this.add.apply(this, mis); - } -}; - -Ext.extend(Ext.menu.Menu, Ext.util.Observable, { - /** - * @cfg {Object} defaults - * A config object that will be applied to all items added to this container either via the {@link #items} - * config or via the {@link #add} method. The defaults config can contain any number of - * name/value property pairs to be added to each item, and should be valid for the types of items - * being added to the menu. - */ - /** - * @cfg {Mixed} items - * An array of items to be added to this menu. See {@link #add} for a list of valid item types. - */ - /** - * @cfg {Number} minWidth The minimum width of the menu in pixels (defaults to 120) - */ - minWidth : 120, - /** - * @cfg {Boolean/String} shadow True or "sides" for the default effect, "frame" for 4-way shadow, and "drop" - * for bottom-right shadow (defaults to "sides") - */ - shadow : "sides", - /** - * @cfg {String} subMenuAlign The {@link Ext.Element#alignTo} anchor position value to use for submenus of - * this menu (defaults to "tl-tr?") - */ - subMenuAlign : "tl-tr?", - /** - * @cfg {String} defaultAlign The default {@link Ext.Element#alignTo} anchor position value for this menu - * relative to its element of origin (defaults to "tl-bl?") - */ - defaultAlign : "tl-bl?", - /** - * @cfg {Boolean} allowOtherMenus True to allow multiple menus to be displayed at the same time (defaults to false) - */ - allowOtherMenus : false, - /** - * @cfg {Boolean} ignoreParentClicks True to ignore clicks on any item in this menu that is a parent item (displays - * a submenu) so that the submenu is not dismissed when clicking the parent item (defaults to false). - */ - ignoreParentClicks : false, - - // private - hidden:true, - - // private - createEl : function(){ - return new Ext.Layer({ - cls: "x-menu", - shadow:this.shadow, - constrain: false, - parentEl: this.parentEl || document.body, - zindex:15000 - }); - }, - - // private - render : function(){ - if(this.el){ - return; - } - var el = this.el = this.createEl(); - - if(!this.keyNav){ - this.keyNav = new Ext.menu.MenuNav(this); - } - if(this.plain){ - el.addClass("x-menu-plain"); - } - if(this.cls){ - el.addClass(this.cls); - } - // generic focus element - this.focusEl = el.createChild({ - tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1" - }); - var ul = el.createChild({tag: "ul", cls: "x-menu-list"}); - ul.on("click", this.onClick, this); - ul.on("mouseover", this.onMouseOver, this); - ul.on("mouseout", this.onMouseOut, this); - this.items.each(function(item){ - var li = document.createElement("li"); - li.className = "x-menu-list-item"; - ul.dom.appendChild(li); - item.render(li, this); - }, this); - this.ul = ul; - this.autoWidth(); - }, - - // private - autoWidth : function(){ - var el = this.el, ul = this.ul; - if(!el){ - return; - } - var w = this.width; - if(w){ - el.setWidth(w); - }else if(Ext.isIE){ - el.setWidth(this.minWidth); - var t = el.dom.offsetWidth; // force recalc - el.setWidth(ul.getWidth()+el.getFrameWidth("lr")); - } - }, - - // private - delayAutoWidth : function(){ - if(this.el){ - if(!this.awTask){ - this.awTask = new Ext.util.DelayedTask(this.autoWidth, this); - } - this.awTask.delay(20); - } - }, - - // private - findTargetItem : function(e){ - var t = e.getTarget(".x-menu-list-item", this.ul, true); - if(t && t.menuItemId){ - return this.items.get(t.menuItemId); - } - }, - - // private - onClick : function(e){ - var t; - if(t = this.findTargetItem(e)){ - if(t.menu && this.ignoreParentClicks){ - t.expandMenu(); - }else{ - t.onClick(e); - this.fireEvent("click", this, t, e); - } - } - }, - - // private - setActiveItem : function(item, autoExpand){ - if(item != this.activeItem){ - if(this.activeItem){ - this.activeItem.deactivate(); - } - this.activeItem = item; - item.activate(autoExpand); - }else if(autoExpand){ - item.expandMenu(); - } - }, - - // private - tryActivate : function(start, step){ - var items = this.items; - for(var i = start, len = items.length; i >= 0 && i < len; i+= step){ - var item = items.get(i); - if(!item.disabled && item.canActivate){ - this.setActiveItem(item, false); - return item; - } - } - return false; - }, - - // private - onMouseOver : function(e){ - var t; - if(t = this.findTargetItem(e)){ - if(t.canActivate && !t.disabled){ - this.setActiveItem(t, true); - } - } - this.over = true; - this.fireEvent("mouseover", this, e, t); - }, - - // private - onMouseOut : function(e){ - var t; - if(t = this.findTargetItem(e)){ - if(t == this.activeItem && t.shouldDeactivate(e)){ - this.activeItem.deactivate(); - delete this.activeItem; - } - } - this.over = false; - this.fireEvent("mouseout", this, e, t); - }, - - /** - * Read-only. Returns true if the menu is currently displayed, else false. - * @type Boolean - */ - isVisible : function(){ - return this.el && !this.hidden; - }, - - /** - * Displays this menu relative to another element - * @param {Mixed} element The element to align to - * @param {String} position (optional) The {@link Ext.Element#alignTo} anchor position to use in aligning to - * the element (defaults to this.defaultAlign) - * @param {Ext.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined) - */ - show : function(el, pos, parentMenu){ - this.parentMenu = parentMenu; - if(!this.el){ - this.render(); - } - this.fireEvent("beforeshow", this); - this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false); - }, - - /** - * Displays this menu at a specific xy position - * @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based) - * @param {Ext.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined) - */ - showAt : function(xy, parentMenu, /* private: */_e){ - this.parentMenu = parentMenu; - if(!this.el){ - this.render(); - } - if(_e !== false){ - this.fireEvent("beforeshow", this); - xy = this.el.adjustForConstraints(xy); - } - this.el.setXY(xy); - this.el.show(); - this.hidden = false; - this.focus(); - this.fireEvent("show", this); - }, - - - - focus : function(){ - if(!this.hidden){ - this.doFocus.defer(50, this); - } - }, - - doFocus : function(){ - if(!this.hidden){ - this.focusEl.focus(); - } - }, - - /** - * Hides this menu and optionally all parent menus - * @param {Boolean} deep (optional) True to hide all parent menus recursively, if any (defaults to false) - */ - hide : function(deep){ - if(this.el && this.isVisible()){ - this.fireEvent("beforehide", this); - if(this.activeItem){ - this.activeItem.deactivate(); - this.activeItem = null; - } - this.el.hide(); - this.hidden = true; - this.fireEvent("hide", this); - } - if(deep === true && this.parentMenu){ - this.parentMenu.hide(true); - } - }, - - /** - * Adds one or more items of any type supported by the Menu class, or that can be converted into menu items. - * Any of the following are valid: - * - * Usage: - *

-// Create the menu
-var menu = new Ext.menu.Menu();
-
-// Create a menu item to add by reference
-var menuItem = new Ext.menu.Item({ text: 'New Item!' });
-
-// Add a bunch of items at once using different methods.
-// Only the last item added will be returned.
-var item = menu.add(
-    menuItem,                // add existing item by ref
-    'Dynamic Item',          // new TextItem
-    '-',                     // new separator
-    { text: 'Config Item' }  // new item by config
-);
-
- * @param {Mixed} args One or more menu items, menu item configs or other objects that can be converted to menu items - * @return {Ext.menu.Item} The menu item that was added, or the last one if multiple items were added - */ - add : function(){ - var a = arguments, l = a.length, item; - for(var i = 0; i < l; i++){ - var el = a[i]; - if(el.render){ // some kind of Item - item = this.addItem(el); - }else if(typeof el == "string"){ // string - if(el == "separator" || el == "-"){ - item = this.addSeparator(); - }else{ - item = this.addText(el); - } - }else if(el.tagName || el.el){ // element - item = this.addElement(el); - }else if(typeof el == "object"){ // must be menu item config? - Ext.applyIf(el, this.defaults); - item = this.addMenuItem(el); - } - } - return item; - }, - - /** - * Returns this menu's underlying {@link Ext.Element} object - * @return {Ext.Element} The element - */ - getEl : function(){ - if(!this.el){ - this.render(); - } - return this.el; - }, - - /** - * Adds a separator bar to the menu - * @return {Ext.menu.Item} The menu item that was added - */ - addSeparator : function(){ - return this.addItem(new Ext.menu.Separator()); - }, - - /** - * Adds an {@link Ext.Element} object to the menu - * @param {Mixed} el The element or DOM node to add, or its id - * @return {Ext.menu.Item} The menu item that was added - */ - addElement : function(el){ - return this.addItem(new Ext.menu.BaseItem(el)); - }, - - /** - * Adds an existing object based on {@link Ext.menu.BaseItem} to the menu - * @param {Ext.menu.Item} item The menu item to add - * @return {Ext.menu.Item} The menu item that was added - */ - addItem : function(item){ - this.items.add(item); - if(this.ul){ - var li = document.createElement("li"); - li.className = "x-menu-list-item"; - this.ul.dom.appendChild(li); - item.render(li, this); - this.delayAutoWidth(); - } - return item; - }, - - /** - * Creates a new {@link Ext.menu.Item} based an the supplied config object and adds it to the menu - * @param {Object} config A MenuItem config object - * @return {Ext.menu.Item} The menu item that was added - */ - addMenuItem : function(config){ - if(!(config instanceof Ext.menu.Item)){ - if(typeof config.checked == "boolean"){ // must be check menu item config? - config = new Ext.menu.CheckItem(config); - }else{ - config = new Ext.menu.Item(config); - } - } - return this.addItem(config); - }, - - /** - * Creates a new {@link Ext.menu.TextItem} with the supplied text and adds it to the menu - * @param {String} text The text to display in the menu item - * @return {Ext.menu.Item} The menu item that was added - */ - addText : function(text){ - return this.addItem(new Ext.menu.TextItem(text)); - }, - - /** - * Inserts an existing object based on {@link Ext.menu.BaseItem} to the menu at a specified index - * @param {Number} index The index in the menu's list of current items where the new item should be inserted - * @param {Ext.menu.Item} item The menu item to add - * @return {Ext.menu.Item} The menu item that was added - */ - insert : function(index, item){ - this.items.insert(index, item); - if(this.ul){ - var li = document.createElement("li"); - li.className = "x-menu-list-item"; - this.ul.dom.insertBefore(li, this.ul.dom.childNodes[index]); - item.render(li, this); - this.delayAutoWidth(); - } - return item; - }, - - /** - * Removes an {@link Ext.menu.Item} from the menu and destroys the object - * @param {Ext.menu.Item} item The menu item to remove - */ - remove : function(item){ - this.items.removeKey(item.id); - item.destroy(); - }, - - /** - * Removes and destroys all items in the menu - */ - removeAll : function(){ - if(this.items){ - var f; - while(f = this.items.first()){ - this.remove(f); - } - } - }, - - /** - * Destroys the menu by unregistering it from {@link Ext.menu.MenuMgr}, purging event listeners, - * removing all of the menus items, then destroying the underlying {@link Ext.Element} - */ - destroy : function(){ - this.beforeDestroy(); - Ext.menu.MenuMgr.unregister(this); - if (this.keyNav) { - this.keyNav.disable(); - } - this.removeAll(); - if (this.ul) { - this.ul.removeAllListeners(); - } - if (this.el) { - this.el.destroy(); - } - }, - - // private - beforeDestroy : Ext.emptyFn - -}); - -// MenuNav is a private utility class used internally by the Menu -Ext.menu.MenuNav = function(menu){ - Ext.menu.MenuNav.superclass.constructor.call(this, menu.el); - this.scope = this.menu = menu; -}; - -Ext.extend(Ext.menu.MenuNav, Ext.KeyNav, { - doRelay : function(e, h){ - var k = e.getKey(); - if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){ - this.menu.tryActivate(0, 1); - return false; - } - return h.call(this.scope || this, e, this.menu); - }, - - up : function(e, m){ - if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){ - m.tryActivate(m.items.length-1, -1); - } - }, - - down : function(e, m){ - if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){ - m.tryActivate(0, 1); - } - }, - - right : function(e, m){ - if(m.activeItem){ - m.activeItem.expandMenu(true); - } - }, - - left : function(e, m){ - m.hide(); - if(m.parentMenu && m.parentMenu.activeItem){ - m.parentMenu.activeItem.activate(); - } - }, - - enter : function(e, m){ - if(m.activeItem){ - e.stopPropagation(); - m.activeItem.onClick(e); - m.fireEvent("click", this, m.activeItem); - return true; - } - } -}); \ No newline at end of file