📄 menu.js
字号:
this.hide();},// place the context menu immediately adjacent to the mouse pointer, keeping it onscreenpositionContextMenu : function () { this._showOffscreen(); // place the menu immediately adjacent to the mouse pointer, keeping it onscreen var event = isc.EH.getLastEvent(); this.placeNear(event.x, event.y); },// Menu items and submenus // --------------------------------------------------------------------------------------------//> @method menu.getItem()// Get a particular item by number or by reference // (allows most routines to take either an actual item or an item number)// @group menuItems// @param item (number | object ) number of the item or pointer to the object// @return (object) Pointer to the item, or null if not defined//<getItem : function (item) { return isc.Class.getArrayItem(item, this.data, "name");},//> @method menu.getItemNum()// Given an item, return the item number associated with it.// @group menuItems// @param item (number | object ) Number of the item or pointer to the object// @return (object) Number to the item, or -1 if not defined.//<getItemNum : function (item) { return isc.Class.getArrayItemIndex(item, this.data, "name");},//>EditModeaddItem : function (item, index) { if (index == null) index = 0; this.data.addAt(item, index); this.markForRedraw();},removeItem : function (item) { this.data.remove(item); this.markForRedraw();},//<EditMode//> @method menu.changeSubMenu() (A)// Hide the last open submenu, if any, and show the submenu for this.body.lastOverRow, if// specified// @group visibility//<changeSubmenu : function () { var overItem = this.getItem(this.body.lastOverRow); // If the menu to be shown is already showing, just bail. if (overItem && this._openItem == overItem) return; this.hideSubmenu(); if (overItem != null) this.showSubmenu(overItem);},// Helper method to determine whether an item has a submenuhasSubmenu : function (item) { if (!item) return false; if (item.submenu) return true; if (isc.isA.Tree(this._treeData)) { // If this is a client-only tree we can avoid showing submenus if the node // has no children. return (this._treeData.isFolder(item) && ((isc.ResultTree && isc.isA.ResultTree(this._treeData)) || this._treeData.hasChildren(item))); } return false;},//> @method menu.showSubmenu() (A)// Show the submenu for the specified item, if it has one.// <P>// Normally triggered automatically by user interaction.//// @group visibility// @param item (MenuItem | number) the item in question, or it's index// @visibility external//<showSubmenu : function (item) { var submenu = this.getSubmenu(item); if (!submenu) return; this.placeSubmenu(item, submenu); },//> @method menu.getSubmenu() (A)// Get the submenu for a particular menu item.// <P>// Override to provide dynamic generation of submenus.// // @param item (MenuItem | number) the item in question, or it's index// @return (Menu) the submenu// @visibility external//<getSubmenu : function (item) { // normalize item to the item pointer in case a number was passed in item = this.getItem(item); // if there's no submenu (or no children in tree-mode), bail if (!this.hasSubmenu(item)) return; // Force the submenu to inherit most developer defined UI properties // from this menu. // Note: This properties block will be applied to the submenus that we generate here, // but not to a submenu that's already a Menu widget var properties = isc.applyMask(this, this.submenuInheritanceMask); // Have submenus inherit any custom fields (need to duplicate rather than just inherit // the fields array) if (!this._standardFields) { var fields = []; for (var i = 0; i < this.fields.length; i++) { // do a deep duplicate of our fields so we don't manipulate our // submenus' field objects by accident fields[i] = isc.addProperties({}, this.fields[i]); } properties.fields = fields; } var submenu = item.submenu; // tree mode if (!submenu) { // item is a parent in a Tree; create a submenu based on the Tree children of this // parent. var rootMenu = (this._rootMenu || this), menuLevel = (rootMenu == this ? 0 : this._menuLevel); if (!rootMenu._submenus) rootMenu._submenus = []; //>DEBUG this.logDebug("RootMenu:" + rootMenu.getID() + ", submenus:" + rootMenu._submenus + ", Level:" + menuLevel); //<DEBUG // check if we've already created a submenu at this level submenu = rootMenu._submenus[menuLevel]; if (!submenu) { // create the menu isc.addProperties(properties, { ID:(rootMenu.getID() + "_childrenSubMenu_" + menuLevel), _rootMenu:rootMenu, _menuLevel:menuLevel + 1, // it's submenu will be one level below itself autoDraw:false, // for treeMenus, pass the parentNode to the submenu so it can initiate a fetch // for the relevant node treeParentNode: this._treeData ? item : null, masterMenu: this }); var cons = this.submenuConstructor || isc.Menu; submenu = cons.create(properties); // cache the submenu for this level rootMenu._submenus[menuLevel] = submenu; // Ensure that we clean up when submenus get destroy()d rootMenu.observe(submenu, "destroy", "observer.submenuDestroyed(" + menuLevel +");"); } } else if (!isc.isA.Menu(submenu)) { if (isc.isA.String(submenu)) { submenu = window[submenu]; } else if (isc.isAn.Array(submenu)) { submenu = isc.Menu.create({autoDraw: false, data: submenu}, properties); } else if (isc.isAn.Object(submenu)) { submenu = isc.Menu.create(isc.addProperties({autoDraw: false}, properties, submenu)); } item.submenu = submenu; } if (this._treeData) submenu.setTreeNode(item); return submenu;},// Method invoked when a generated submenu gets destroy()d.// Clean out our reference to it to avoid leaks.submenuDestroyed : function (menuLevel) { delete this._submenus[menuLevel];},// show a menu as a submenu next to the given itemplaceSubmenu : function (item, submenu) { // remember the submenu so we can close it later this._openItem = item; this._open_submenu = submenu; // Show the submenu offscreen. This ensures that is has been drawn (so we can determine // it's size), but is not visible to the user. // It also prevents Moz's strange "flash" in the old position. submenu._showOffscreen(); // place the menu adjacent to the item that's showing it // Note: use '_placeRect()' to avoid placing submenus offscreen (and avoid occluding the // super-menu) var itemNum = this.getItemNum(item), submenuRect = submenu.getPeerRect(), pos = isc.Canvas._placeRect( submenuRect[2], submenuRect[3], {left:this.getPageLeft() - this.submenuOffset, width:this.getVisibleWidth() + this.submenuOffset, top:this.body.getRowPageTop(itemNum) // No need for height - we want it to be as close to that point as possible }, this.submenuDirection == this._$left ? this._$left : this._$right, false ) submenu.setPageRect(pos[0], pos[1]); // the "target" property is passed to the click() function. if the main menu has been // given a "target" other than itself (the default), give it to the submenu if it also has // no target. if (this.target != this && submenu.target != submenu) { submenu.target = this.target; } submenu.show(); submenu._parentMenu = this; submenu._parentItemNum = itemNum; // If we just placed a submenu, we don't want to do a delayed 'placeSubmenu' for another // menu that we're waiting on data from. if (isc.Menu._submenuQueue) delete isc.Menu._submenuQueue[this.getID()];},//> @method menu.hideMenuTree() (A)// Hide this menu and any open submenus of this menu// @group visibility//<hideMenuTree : function () { this.hideSubmenu(); this.hide();},//> @method menu.hideSubmenu() (A)// hide the open sub menu of this menu if there is one// @group visibility//<hideSubmenu : function () { if (this._open_submenu) { this._open_submenu.hideSubmenu(); this._open_submenu.hide(); delete this._open_submenu; delete this._openItem; }},//> @method menu.getSubmenuImage() (A)// return the icon that indicates that there's a submenu in this item (if there is one)//// @param item (paramtype) item in question//<_$left:"left", _$right:"right",getSubmenuImage : function (item) { if (!this.hasSubmenu(item)) return " "; if (!this._submenuImage) { var leftSM = (this.submenuDirection == this._$left), subImgObj = isc.addProperties({}, this.submenuImage), subDisImgObj = isc.addProperties({}, this.submenuDisabledImage); subImgObj.src = isc.Img.urlForState(subImgObj.src, null, null, (leftSM ? this._$left : null)); subDisImgObj.src = isc.Img.urlForState(subDisImgObj.src, null, null, (leftSM ? this._$left : null)); this._submenuImage = this.imgHTML(subImgObj); this._submenuDisabledImage = this.imgHTML(subDisImgObj); } return (this.itemIsEnabled(item) ? this._submenuImage : this._submenuDisabledImage);},// Enabling and disabling items, setting titles, showing icons, etc.// --------------------------------------------------------------------------------------------//> @method menu.itemIsEnabled() (A)// @group enable// Return if a particular item (specified by number) is enabled// @param item (item | number) pointer to (or number of) the item in question// @return (boolean) true == item is enabled, false == disabled//<itemIsEnabled : function (item) { // normalize item to the item pointer in case a number was passed in item = this.getItem(item); return (item && item.enabled != false && item.isSeparator != true);},//> @method menu._makeDynamicItemsFunction() (A)// Create "this.setDynamicItems", a function that for all items will:// * enable/disable them automatically based on an 'enableif' property// * change their titles based on a 'dynamicTitle' property// * set their icons based on a 'dynamicIcon' property// * check/uncheck items based on a 'checkIf' property//<_makeDynamicItemsFunction : function (){ var output = isc.SB.create(); // if the menu has an 'enableIf' item, stick that first // this way you can pre-seed the individual enableIf items with variables, etc. if (this.enableIf) output.append(this.enableIf, ";"); // iterate through the items, checking for enableif or dynamicTitle properties for (var i = 0; i < this.data.length; i++) { var item = this.getItem(i); if (!item) continue; if (item.enableIf) { output.append("changed|=this.setItemEnabled(",i,",",item.enableIf,");\r"); } if (item.checkIf) { output.append("changed|=this.setItemChecked(",i,",",item.checkIf,");\r"); } if (item.dynamicTitle) { output.append("changed|=this.setItemTitle(",i,",",item.dynamicTitle,");\r"); } if (item.dynamicIcon) { output.append("changed|=this.setItemIcon(",i,",",item.dynamicIcon,");\r"); } } // if nothing to do, just skip it var updateCode = output.toString(); if (updateCode == "") return; output = isc.SB.create(); // add a 'redraw' command to the function output.append("var target=this.target,changed=false;\r", updateCode, "if(changed&&this.isDrawn()){\r", "this.redraw('dynamic item change');\r", (isc.Browser.isIE ? "this.body.setRowStyle(0);\r" : ""), "}"); // create the setDynamicItems which will be called automatically before the menu is shown this.addMethods({setDynamicIte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -