diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js
index 154ff97c..6cba1500 100644
--- a/build/js/ox.ui.js
+++ b/build/js/ox.ui.js
@@ -47,7 +47,6 @@ requires
}(),
path: $("script[src*=ox.ui.js]").attr("src")
.replace("js/ox.ui.js", ""),
- stack: [], // fixme: used?
symbols: { // fixme: make lowercase
alt: "\u2325",
apple: "\uF8FF",
@@ -203,21 +202,52 @@ requires
// use dom elements / jquery instead
+
Ox.Event = function() {
- var $eventHandler = $("
");
+ var keyboardEvents = {};
+ $eventHandler = $("
");
+ function isKeyboardEvent(event) {
+ return event.substr(0, 4) == "key_";
+ }
return {
- bind: function(event, callback) {
- $eventHandler.bind(event, callback);
+ bind: function(id, event, callback) {
+ if (isKeyboardEvent(event)) {
+ keyboardEvents[id] = keyboardEvents[id] || [];
+ keyboardEvents[id].push({
+ event: event,
+ callback: callback
+ });
+ }
+ if (!isKeyboardEvent(event) || Ox.Focus.focused() == id) {
+ $eventHandler.bind(event, callback);
+ }
},
- one: function(event, callback) {
- $eventHandler.one(event, callback);
+ bindKeyboard: function(id) {
+ $.each(keyboardEvents[id] || [], function(i, event) {
+ Ox.Event.bind(id, event.event, event.callback);
+ });
},
trigger: function(event, data) {
Ox.print("trigger", event, data || {});
$eventHandler.trigger(event, data || {});
},
- unbind: function(event, callback) {
+ unbind: function(id, event, callback) {
+ if (isKeyboardEvent(event)) {
+ $.each(keyboardEvents[id] || [], function(i, e) {
+ if (e.event == event) {
+ keyboardEvents[id].splice(i, 1);
+ return false;
+ }
+ });
+ }
$eventHandler.unbind(event, callback);
+ },
+ unbindKeyboard: function(id) {
+ //Ox.print(keyboardEvents)
+ //Ox.print("unbindKeyboard", id, keyboardEvents[id])
+ $.each(keyboardEvents[id] || [], function(i, e) {
+ $eventHandler.unbind(e.event, e.callback);
+ });
}
}
}();
@@ -265,14 +295,31 @@ requires
var stack = [];
return {
focus: function(id) {
+ /*
+ if (stack.length) {
+ Ox.Event.unbindKeyboard(stack[stack.length - 1]);
+ }
+ */
var index = stack.indexOf(id);
if (index > -1) {
- oxui.stack.splice(i, 1);
+ stack.splice(index, 1);
}
- oxui.stack.push(id);
+ stack.push(id);
+ Ox.Event.bindKeyboard(id);
+ console.log("focus", stack);
+ },
+ focused: function() {
+ return stack[stack.length - 1];
},
blur: function(id) {
- oxui.stack.pop();
+ if (stack.indexOf(id) > -1) {
+ stack.splice(stack.length - 2, 0, stack.pop());
+ }
+ Ox.Event.unbindKeyboard(id);
+ /*
+ Ox.Event.bindKeyboard(stack[stack.length - 1]);
+ */
+ console.log("blur", stack);
}
};
}();
@@ -438,7 +485,7 @@ requires
buffer += key == "SPACE" ? " " : key;
bufferTime = time;
}
- Ox.Event.trigger("key." + key);
+ Ox.Event.trigger("key_" + key);
/*
$.each(stack, function(i, v) {
// fixme: we dont get the return value!
@@ -656,7 +703,6 @@ requires
};
}();
-
/*
----------------------------------------------------------------------------
Ox.URL
@@ -771,20 +817,35 @@ requires
};
// public
+ that.bindEvent = function() {
+ /*
+ bindEvent(event, fn) or bindEvent({event0: fn0, event1: fn1, ...})
+ */
+ if (arguments.length == 1) {
+ $.each(arguments[0], function(event, fn) {
+ Ox.Event.bind(that.id, event, fn);
+ })
+ } else {
+ Ox.Event.bind(that.id, arguments[0], arguments[1]);
+ }
+ };
that.defaults = function(defaults) {
/*
that.defaults({foo: x}) sets self.defaults
*/
self.defaults = defaults;
return that;
- }
- that.gain = function() {
- Ox.Focus.gain(that.id);
- }
- that.lose = function() {
- Ox.Focus.lose(that.id);
- }
- that.options = function() {
+ };
+ that.gainFocus = function() {
+ Ox.Focus.focus(that.id);
+ };
+ that.hasFocus = function() {
+ return Ox.Focus.focused() == that.id;
+ };
+ that.loseFocus = function() {
+ Ox.Focus.blur(that.id);
+ };
+ that.options = function() { // fixme: use Ox.getset
/*
that.options() returns self.options
that.options("foo") returns self.options.foo
@@ -817,26 +878,21 @@ requires
}
return ret;
}
- that.publish = function() {
- arguments[0] = arguments[0] + "." + that.id;
- Ox.Event.publish.apply(that, arguments);
- // or, maybe better:
- $(".OxWidget").trigger.apply(that, arguments);
- return that;
- }
that.remove = function() {
that.$element.remove();
delete elements[that.ox];
}
- that.subscribe = function() {
- Ox.Event.subscribe.apply(that, arguments);
- // or
- that.$element.bind.apply(that, arguments);
- return that;
- }
- that.unsubscribe = function() {
- Ox.Event.unsubscribe.apply(that, arguments);
- return that;
+ that.unbindEvent = function() {
+ /*
+ unbindEvent(event, fn) or unbindEvent({event0: fn0, event1: fn1, ...})
+ */
+ if (arguments.length == 1) {
+ $.each(arguments[0], function(event, fn) {
+ Ox.Event.unbind(that.id, event, fn);
+ })
+ } else {
+ Ox.Event.unbind(that.id, arguments[0], arguments[1]);
+ }
}
// return
@@ -1694,9 +1750,10 @@ requires
left: 0,
top: 0
},
+ parent: null,
selected: -1,
side: "bottom",
- size: "medium"
+ size: "medium",
})
.options(options)
.addClass(
@@ -1740,8 +1797,9 @@ requires
left: 0,
top: -4
},
+ parent: that,
side: "right",
- size: self.options.size
+ size: self.options.size,
});
}
} else {
@@ -1756,6 +1814,12 @@ requires
.addClass("OxBottom")
.appendTo(that.$element);
+ function click(event) {
+ if (!$(event.target).is(".OxCell")) {
+ that.hideMenu();
+ }
+ }
+
function clickItem() {
if (self.options.selected > -1) {
that.items[self.options.selected].trigger("click");
@@ -1823,6 +1887,7 @@ requires
}
function getElement(id) {
+ // fixme: needed?
return $("#" + Ox.toCamelCase(options.id + "/" + id));
}
@@ -1898,6 +1963,37 @@ requires
}
}
+ function selectSubmenu() {
+ var submenu = that.submenus[that.items[self.options.selected].options("id")];
+ if (submenu && submenu.hasEnabledItems()) {
+ that.loseFocus();
+ submenu.gainFocus();
+ submenu.selectFirstItem();
+ }
+ }
+
+ function selectSupermenu() {
+ if (self.options.parent) {
+ that.items[self.options.selected].trigger("mouseleave");
+ that.loseFocus();
+ self.options.parent.gainFocus();
+ }
+ }
+
+ self.onChange = function(key, value) {
+
+ }
+
+ that.hasEnabledItems = function() {
+ var ret = false;
+ $.each(that.items, function(i, item) {
+ if (!item.options("disabled")) {
+ return ret = true;
+ }
+ });
+ return ret;
+ };
+
that.hideMenu = function() {
Ox.print("hideMenu")
$.each(that.submenus, function(i, submenu) {
@@ -1911,11 +2007,20 @@ requires
if (self.options.selected > -1) {
that.items[self.options.selected].trigger("mouseleave");
}
- Ox.Event.unbind("key down", selectNextItem);
- Ox.Event.unbind("key up", selectPreviousItem);
- Ox.Event.unbind("key.escape", that.hideMenu);
- Ox.Event.unbind("key.enter", clickItem);
- $document.unbind("click", that.hideMenu);
+ that.loseFocus();
+ that.unbindEvent({
+ key_up: selectPreviousItem,
+ key_down: selectNextItem,
+ key_left: selectSupermenu,
+ key_right: selectSubmenu,
+ key_escape: that.hideMenu,
+ key_enter: clickItem
+ });
+ $document.unbind("click", click);
+ };
+
+ that.selectFirstItem = function() {
+ selectNextItem();
};
that.showMenu = function() {
@@ -1935,13 +2040,19 @@ requires
that.$container.height(maxHeight - itemHeight);
that.$scrollbars.down.show();
}
- Ox.print("binding...");
- Ox.Event.bind("key.down", selectNextItem);
- Ox.Event.bind("key.up", selectPreviousItem);
- Ox.Event.bind("key.escape", that.hideMenu);
- Ox.Event.bind("key.enter", clickItem);
+ if (!self.options.parent) {
+ that.gainFocus();
+ }
+ that.bindEvent({
+ key_up: selectPreviousItem,
+ key_down: selectNextItem,
+ key_left: selectSupermenu,
+ key_right: selectSubmenu,
+ key_escape: that.hideMenu,
+ key_enter: clickItem
+ });
setTimeout(function() {
- $document.bind("click", that.hideMenu);
+ $document.bind("click", click);
}, 100);
};
@@ -2025,7 +2136,7 @@ requires
);
function click() {
- if (!that.hasClass("OxDisabled") && !self.options.submenu) {
+ if (!that.hasClass("OxDisabled") && !self.options.items.length) {
self.options.menu.hideMenu();
if (self.options.checked !== null && (!self.options.group || !self.options.checked)) {
that.options({
@@ -2039,7 +2150,6 @@ requires
id: self.options.id,
value: self.options.title // fixme: value or title?
});
- return false;
}
}
@@ -2050,7 +2160,10 @@ requires
function mouseenter() {
if (!self.options.disabled && !isSelected()) {
$.each(self.options.menu.submenus, function(id, submenu) {
- submenu.hideMenu();
+ if (!submenu.is(":hidden")) {
+ submenu.hideMenu();
+ return false;
+ }
});
if (self.options.menu.options("selected") > -1) {
self.options.menu.items[self.options.menu.options("selected")].trigger("mouseleave");
diff --git a/demos/test/menu.js b/demos/test/menu.js
index 271070e7..823e6e07 100644
--- a/demos/test/menu.js
+++ b/demos/test/menu.js
@@ -74,18 +74,43 @@ $(function() {
},
],
title: "More",
+ },
+ {
+ id: "even_more",
+ items: [
+ {
+ checked: true,
+ group: "101112",
+ id: "tenth",
+ title: "Tenth"
+ },
+ {
+ checked: false,
+ group: "101112",
+ id: "eleventh",
+ title: "Eleventh"
+ },
+ {
+ checked: false,
+ group: "101112",
+ id: "twelfth",
+ title: "Twelfth"
+ },
+ ],
+ title: "Even More",
}
]
});
- button.click(function() {
- $(this).blur(); // fix for firefox
- menu.toggleMenu();
- });
- Ox.Event.bind("OxClickMenu", function(event, data) {
- button.options({
- value: data.value
+ button
+ .click(function() {
+ $(this).blur(); // fix for firefox
+ menu.toggleMenu();
+ })
+ .bindEvent("OxClickMenu", function(event, data) {
+ button.options({
+ value: data.value
+ });
});
- });
$select = $("