2 * (c) 2005-2009 Matt Brown (http://dowdybrown.com)
4 * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
5 * file except in compliance with the License. You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11 * either express or implied. See the License for the specific language governing permissions
12 * and limitations under the License.
15 Rico.Menu = Class.create(
16 /** @lends Rico.Menu# */
19 * @class Implements popup menus and submenus
23 initialize: function(options) {
24 Object.extend(this, new Rico.Popup());
25 Object.extend(this.options, {
28 if (typeof options=='string')
29 this.options.width=options;
31 Object.extend(this.options, options || {});
33 this.highlightElem=null;
34 new Image().src = Rico.imgDir+'left.gif';
35 new Image().src = Rico.imgDir+'right.gif';
38 createDiv: function(parentNode) {
40 this.div = document.createElement('div');
41 this.div.className = Prototype.Browser.WebKit ? 'ricoMenuSafari' : 'ricoMenu';
42 this.div.style.position="absolute";
43 this.div.style.top='0px';
44 this.div.style.left='0px';
45 this.div.style.width=this.options.width;
46 if (!parentNode) parentNode = document.getElementsByTagName("body")[0];
47 parentNode.appendChild(this.div);
48 this.width=this.div.offsetWidth;
49 this.setDiv(this.div,this.cancelmenu.bindAsEventListener(this));
50 this.direction=Element.getStyle(this.div,'direction') || 'ltr';
51 this.direction=this.direction.toLowerCase(); // ltr or rtl
56 showmenu: function(e,hideFunc){
58 this.hideFunc=hideFunc;
59 if (this.div.childNodes.length==0) {
63 this.openmenu(e.clientX,e.clientY,0,0);
66 openmenu: function(x,y,clickItemWi,clickItemHt) {
67 var newLeft=RicoUtil.docScrollLeft()+x;
68 //window.status='openmenu: newLeft='+newLeft+' width='+this.width+' windowWi='+RicoUtil.windowWidth();
69 if (this.direction == 'rtl') {
70 if (newLeft > this.width+clickItemWi) newLeft-=this.width+clickItemWi;
72 if (x+this.width+this.options.margin > RicoUtil.windowWidth()) newLeft-=this.width+clickItemWi;
74 var newTop=RicoUtil.docScrollTop()+y;
75 this.div.style.visibility="hidden";
76 this.div.style.display="block";
77 var contentHt=this.div.offsetHeight;
78 if (y+contentHt+this.options.margin > RicoUtil.windowHeight())
79 newTop=Math.max(newTop-contentHt+clickItemHt,0);
80 this.openPopup(newLeft,newTop);
81 this.div.style.visibility ="visible";
85 clearMenu: function() {
86 this.div.innerHTML="";
87 this.defaultAction=null;
91 addMenuHeading: function(hdg) {
92 var el=document.createElement('div');
94 el.className='ricoMenuHeading';
95 this.div.appendChild(el);
98 addMenuBreak: function() {
99 var brk=document.createElement('div');
100 brk.className="ricoMenuBreak";
101 this.div.appendChild(brk);
104 addSubMenuItem: function(menutext, submenu, translate) {
105 var dir=this.direction=='rtl' ? 'left' : 'right';
106 var a=this.addMenuItem(menutext,null,true,null,translate);
107 a.className='ricoSubMenu';
108 a.style.backgroundImage='url('+Rico.imgDir+dir+'.gif)';
109 a.style.backgroundRepeat='no-repeat';
110 a.style.backgroundPosition=dir;
111 a.onmouseover=this.showSubMenu.bind(this,a,submenu);
112 a.onmouseout=this.subMenuOut.bindAsEventListener(this);
115 showSubMenu: function(a,submenu) {
116 if (this.openSubMenu) this.hideSubMenu();
117 this.openSubMenu=submenu;
118 this.openMenuAnchor=a;
119 var pos=Position.page(a);
120 if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen';
121 submenu.openmenu(pos[0]+a.offsetWidth, pos[1], a.offsetWidth-2, a.offsetHeight+2);
124 subMenuOut: function(e) {
125 if (!this.openSubMenu) return;
127 var elem=Event.element(e);
128 var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
130 while (reltg != null && reltg != this.openSubMenu.div)
131 reltg=reltg.parentNode;
133 if (reltg == this.openSubMenu.div) return;
137 hideSubMenu: function() {
138 if (this.openMenuAnchor) {
139 this.openMenuAnchor.className='ricoSubMenu';
140 this.openMenuAnchor=null;
142 if (this.openSubMenu) {
143 this.openSubMenu.hidemenu();
144 this.openSubMenu=null;
148 addMenuItemId: function(phraseId,action,enabled,title,target) {
149 if ( arguments.length < 3 ) enabled=true;
150 this.addMenuItem(RicoTranslate.getPhraseById(phraseId),action,enabled,title,false,target);
153 addMenuItem: function(menutext,action,enabled,title,translate,target) {
155 if (translate==null) translate=true;
156 var a = document.createElement(typeof action=='string' ? 'a' : 'div');
157 if ( arguments.length < 3 || enabled ) {
158 switch (typeof action) {
164 if (target) a.target = target;
167 a.className = 'enabled';
168 if (this.defaultAction==null) this.defaultAction=action;
171 a.className = 'disabled';
173 a.innerHTML = translate ? RicoTranslate.getPhrase(menutext) : menutext;
174 if (typeof title=='string')
175 a.title = translate ? RicoTranslate.getPhrase(title) : title;
176 a=this.div.appendChild(a);
177 Event.observe(a,"mouseover", this.mouseOver.bindAsEventListener(this));
178 Event.observe(a,"mouseout", this.mouseOut.bindAsEventListener(this));
182 mouseOver: function(e) {
183 if (this.highlightElem && this.highlightElem.className=='enabled-hover') {
184 // required for Safari
185 this.highlightElem.className='enabled';
186 this.highlightElem=null;
188 var elem=Event.element(e);
189 if (this.openMenuAnchor && this.openMenuAnchor!=elem)
191 if (elem.className=='enabled') {
192 elem.className='enabled-hover';
193 this.highlightElem=elem;
197 mouseOut: function(e) {
198 var elem=Event.element(e);
199 if (elem.className=='enabled-hover') elem.className='enabled';
200 if (this.highlightElem==elem) this.highlightElem=null;
203 isVisible: function() {
204 return this.div && Element.visible(this.div);
207 cancelmenu: function() {
208 if (!this.isVisible()) return;
209 if (this.hideFunc) this.hideFunc();
214 hidemenu: function() {
215 if (!this.div) return;
216 if (this.openSubMenu) this.openSubMenu.hidemenu();
222 Rico.includeLoaded('ricoMenu.js');