if(!CU) var CU = {}; /** * Namespace and static functions for pie menus * */ CU.PieMenu = function() { /** * The currently open piemenu */ var _elem; /** * _elem visible/not */ var _visible = false; /** * holds the setTimeout-id for autohiding the menu */ var _hideTimer = null; $(document).click(_hide); /** * _hide event handler */ function _hide() { if(_visible && _elem) { _elem.hide(); _visible = false; } } return { /** * Menu autohide timeout, in seconds */ autoHideTimeout: 2, /** * Function for displaying a menu * * @param CU.PieMenu.Leaf leaf The root menu leaf * @param Object event the click event */ show: function(leaf,event) { var ev = $.event.fix( event || window.event || {} ); if(_elem) _hide(); _elem = leaf; _elem.setPosition(ev.pageX-25,ev.pageY-25); _visible = true; _elem.show(); _elem.showNeighbors(); ev.stopPropagation(); }, /** * Called when menu loses focus. Used to start auto hide timer */ offFocus: function() { if(_hideTimer == null) _hideTimer = setTimeout(_hide,CU.PieMenu.autoHideTimeout*1000); }, /** * Called when menu gets focus. Used to stop auto hide timer */ onFocus: function() { clearTimeout(_hideTimer); _hideTimer = null; } }; }(); /** * Piemenu leaf class * * The menus are built of these * * @param string text The text to show in the leaf * @param string link optional, the URL where clicking the leaf will take */ CU.PieMenu.Leaf = function(text,link) { /** * A jQuery object containing the leaf's HTML element */ this.element; /** * the neighboring leaves */ var _neighbors = { top:null,left:null,right:null,bottom:null }; var _position = { x:0, y:0 }; /** * parent leaf */ var _parent = null; var _self = this; var _link = link; _self.element = $('
').html(text); $(document.body).append(_self.element.hide()); _self.element.hover(_onHover,_offHover); _self.element.click(_go); this.setParent = function(p) { _parent = p; }; this.setPosition = function(x,y) { _self.element.css({left:x,top:y}); _position.x = x; _position.y = y; }; this.show = function(hideNeighbors) { _self.element.show(); }; this.hide = function() { _self.element.hide(); _hideNeighbors(); }; /** * add a neighbor leaf. * * @param string where Which neighbor the new leaf is. Can be left,top,right,bottom * @param CU.PieMenu.Leaf leaf */ this.addNeighbor = function(where,leaf) { _neighbors[where] = leaf; leaf.setParent(this); }; function _go() { if(_link) window.location = _link; } function _onHover() { CU.PieMenu.onFocus(); //Only hide parent's neighbors if this leaf has neighbors. if(_parent && (_neighbors.left || _neighbors.top || _neighbors.right || _neighbors.bottom)) _parent.hideNeighbors(_self); _showNeighbors(); } function _offHover() { CU.PieMenu.offFocus(); } function _showNeighbors() { for(property in _neighbors) { if(_neighbors[property] == null) continue; _neighbors[property].show(true); //The neighbors need to be positioned correctly so this switch does that... //TODO: change this cause this sucks and uses a hardcoded width =) switch(property) { case 'left': _neighbors[property].setPosition(_position.x-50,_position.y); break; case 'right': _neighbors[property].setPosition(_position.x+50,_position.y); break; case 'top': _neighbors[property].setPosition(_position.x,_position.y-50); break; case 'bottom': _neighbors[property].setPosition(_position.x,_position.y+50); break; } _neighbors[property].hideNeighbors(); } } function _hideNeighbors(except) { for(property in _neighbors) { if(_neighbors[property] != null && _neighbors[property] != except) _neighbors[property].hide(); } } //these two funcs need to be public too this.hideNeighbors = _hideNeighbors; this.showNeighbors = _showNeighbors; }