r862 - in branches/experimental: tests/visual/menu ui

r862 - in branches/experimental: tests/visual/menu ui


Author: paul.bakaus
Date: Tue Nov 4 08:29:57 2008
New Revision: 862
Added:
branches/experimental/ui/ui.core.position.js
Modified:
branches/experimental/tests/visual/menu/menu.html
branches/experimental/ui/ui.menu.js
Log:
menu: implemented context mode, hide all other menus when clicking around,
etc
core(experimental): implemented new fn.position plugin to position any DOM
element
Modified: branches/experimental/tests/visual/menu/menu.html
==============================================================================
--- branches/experimental/tests/visual/menu/menu.html    (original)
+++ branches/experimental/tests/visual/menu/menu.html    Tue Nov 4 08:29:57
2008
@@ -9,14 +9,28 @@
        <script type="text/javascript" src="../../../jquery-1.2.6.js"></script>
        <script type="text/javascript" src="../../../ui/ui.core.js"></script>
        <script type="text/javascript" src="../../../ui/ui.menu.js"></script>
+        <script src="../../../ui/ui.core.position.js" type="text/javascript"
charset="utf-8"></script>
+        
+        <style type="text/css" media="screen">
+            
+            body,html {
+                margin: 0;
+                padding: 0;
+            }
+            
+            #menu2 {
+                border: 5px solid black;
+            }
+        
+        </style>
        
        <script type="text/javascript">
            
            $(document).ready(function() {
                
-                $('#menu1').menu({
-                    mode: 'static'
-                });
+                //$('#menu1').menu({
+                //    mode: 'static'
+                //});
                
                $('button').menu({
                    items: '#items2'
Added: branches/experimental/ui/ui.core.position.js
==============================================================================
--- (empty file)
+++ branches/experimental/ui/ui.core.position.js    Tue Nov 4 08:29:57 2008
@@ -0,0 +1,68 @@
+$.fn.position = function(e, o) {
+    
+    var parentOffset = this.parent().offset();
+    parentOffset = {
+        top: this.parent()[0] == document.body ? 0 : parentOffset.top,
+        left: this.parent()[0] == document.body ? 0 : parentOffset.left
+    };
+    
+    var options = $.extend({
+        relativeTo: 'mouse',
+        direction: 'default'    
+    }, o);
+    
+    if($(options.relativeTo).length && $(options.relativeTo)[0].nodeName) {
+        
+        var element = $(options.relativeTo),offset = element.offset();
+        var relHeight = element[0].offsetHeight, relWidth =
element[0].offsetWidth, height = this[0].offsetHeight, width =
this[0].offsetWidth;
+        var leftOffset = 0, topOffset = 0;
+
+        
+        if((/(left|right)/).test(options.direction)) {
+            leftOffset = options.direction == 'left' ? -(width) : relWidth;
+            topOffset = e ? ( $(window).height()-offset.top < height ?
-(height-relHeight) : 0 ) : 0;
+        } else {
+            
+            if(options.direction == 'above') {
+                topOffset = -(height);
+            } else if(options.direction == 'below') {
+                topOffset = relHeight;
+            } else {
+                topOffset = $(window).height()-offset.top < height ? -(height) :
relHeight;
+            }
+            
+        }
+        
+
+        switch(options.direction) {
+            case 'right':
+                leftOffset = relWidth;
+                topOffset = e ? ( $(window).height()-offset.top < height ?
-(height-relHeight) : 0 ) : 0;
+                break;
+            case 'left':
+                leftOffset = -(width);
+                topOffset = e ? ( $(window).height()-offset.top < height ?
-(height-relHeight) : 0 ) : 0;
+                break;
+            case 'above':
+                topOffset = -(height);
+                break;
+            case 'below':
+                topOffset = relHeight;
+                break;
+        }
+
+        this.css({
+            left: offset.left - parentOffset.left + leftOffset,
+            top: offset.top - parentOffset.top + topOffset
+        });
+        
+    } else {
+        
+        this.css({
+            left: e.pageX - parentOffset.left,
+            top: e.pageY - parentOffset.top
+        });
+        
+    }
+    
+};
\ No newline at end of file
Modified: branches/experimental/ui/ui.menu.js
==============================================================================
--- branches/experimental/ui/ui.menu.js    (original)
+++ branches/experimental/ui/ui.menu.js    Tue Nov 4 08:29:57 2008
@@ -12,6 +12,14 @@
*/
(function($) {
+$(document).ready(function() {
+    $(window).bind('click', function(e) {
+        
+        $.ui.menu.prototype.closeAll(e);
+        
+    });
+});
+
$.widget("ui.menu", {
    
    _init: function() {
@@ -71,14 +79,14 @@
        if(o.mode != 'static') {
            
            if(o.mode == 'dropdown') {
-                this.element.bind('click', function() {
-                    self.toggle();
+                this.element.bind('click', function(e) {
+                    self.toggle(e);
                });
            }
            
            if(o.mode == 'context') {
                this.element.bind('contextmenu', function(e) {
-                    self.open();
+                    self.open(e);
                    e.preventDefault();
                });
            }
@@ -118,13 +126,17 @@
                $('> a', this)
                    .addClass('ui-menu-indicator') //Add a class that shows the little
arrow to indicate a sub list
                    .html('<span class="'+self.options.nextMenuClass+'">'+$('> a',
this).text()+'</span>') //Insert a new span
-                    .hover(function() {
+                    .hover(function(e) {
                        
                        if(hideTimer) clearTimeout(hideTimer);
                        var subList = $(this).next();
                        
                        showTimer = setTimeout(function(){
-                            subList.addClass('ui-component-content').show();    
+                            subList.addClass('ui-component-content').show();
+                            subList.position(e, {
+                                relativeTo: subList.parent(),
+                                direction: 'right'
+                            });    
                        }, 300);
                        
                    }, function() {
@@ -160,27 +172,48 @@
        
    },
    
-    toggle: function() {
-        return this[this.visible ? 'close' : 'open']();
+    toggle: function(e) {
+        return this[this.visible ? 'close' : 'open'](e);
    },
    
-    open: function() {
-        
+    open: function(e) {
+
+        if(this.options.exclusive) {
+            this.closeAll();
+        }
+    
        this.menu.show();
-        var offset = this.element.offset();
-        
-        this.menu.css({
-            left: offset.left,
-            top: offset.top + this.element.height()
+        this.menu.position(e, {
+            relativeTo: this.options.mode == 'context' ? 'mouse' : this.element,
+            direction: this.options.direction
        });
        
+        $.ui.menu.manager.push(this);
        this.visible = true;
        
    },
    
+    closeAll: function(excludeEvent) {
+
+        var exclusion = null;
+        if(excludeEvent) {
+            var q = $(excludeEvent.target).parents().andSelf().each(function() {
+                if($.data(this, 'menu') && ($.data(this, 'menu').options.mode
== 'context' ? excludeEvent.which == 3 : true)) exclusion =
$.data(this, 'menu');
+            });
+        }
+
+        for (var i=0; i < $.ui.menu.manager.length; i++) {
+            if(exclusion != $.ui.menu.manager[i]) $.ui.menu.manager[i].close();
+        };
+        
+    },
+    
    close: function() {
        
        this.menu.hide();
+        for (var i=0; i < $.ui.menu.manager.length; i++) {
+            if($.ui.menu.manager[i] == this) $.ui.menu.manager.splice(i,1);
+        };
        this.visible = false;
        
    }
@@ -188,11 +221,13 @@
});
$.extend($.ui.menu, {
+    manager: [],
    defaults: {
        type: 'normal', //Can be set to either normal, ipod style or toolbar
        mode: 'dropdown', //Can be set to context (open on click) or static
(render into the selected element)
        items: '> ul', //Can be either a jQuery selector, therefore using markup
in the selected node, or a JSON list of menu entries
-        appendTo: 'body', //Only in case of context/dropdown - where the actual
menu is being appended to
+        appendTo: 'body', //Only in case of context/dropdown - where the actual
menu is being appended to,
+        exclusive: true, //Defines wether only this menu can be shown at the
same time
        
        width: 180,
        height: null, //If height specified and surpassed, up and down arrows at
both ends are shown to navigate up and down,