some more menu and keyboard navigation

This commit is contained in:
Rolux 2010-02-05 14:43:03 +05:30
parent 88057655f0
commit 150c3df7b6
2 changed files with 198 additions and 60 deletions

View file

@ -47,7 +47,6 @@ requires
}(), }(),
path: $("script[src*=ox.ui.js]").attr("src") path: $("script[src*=ox.ui.js]").attr("src")
.replace("js/ox.ui.js", ""), .replace("js/ox.ui.js", ""),
stack: [], // fixme: used?
symbols: { // fixme: make lowercase symbols: { // fixme: make lowercase
alt: "\u2325", alt: "\u2325",
apple: "\uF8FF", apple: "\uF8FF",
@ -203,21 +202,52 @@ requires
// use dom elements / jquery instead // use dom elements / jquery instead
Ox.Event = function() { Ox.Event = function() {
var $eventHandler = $("<div>"); var keyboardEvents = {};
$eventHandler = $("<div>");
function isKeyboardEvent(event) {
return event.substr(0, 4) == "key_";
}
return { return {
bind: function(event, callback) { bind: function(id, event, callback) {
$eventHandler.bind(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) { bindKeyboard: function(id) {
$eventHandler.one(event, callback); $.each(keyboardEvents[id] || [], function(i, event) {
Ox.Event.bind(id, event.event, event.callback);
});
}, },
trigger: function(event, data) { trigger: function(event, data) {
Ox.print("trigger", event, data || {}); Ox.print("trigger", event, data || {});
$eventHandler.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); $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 = []; var stack = [];
return { return {
focus: function(id) { focus: function(id) {
/*
if (stack.length) {
Ox.Event.unbindKeyboard(stack[stack.length - 1]);
}
*/
var index = stack.indexOf(id); var index = stack.indexOf(id);
if (index > -1) { 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) { 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; buffer += key == "SPACE" ? " " : key;
bufferTime = time; bufferTime = time;
} }
Ox.Event.trigger("key." + key); Ox.Event.trigger("key_" + key);
/* /*
$.each(stack, function(i, v) { $.each(stack, function(i, v) {
// fixme: we dont get the return value! // fixme: we dont get the return value!
@ -656,7 +703,6 @@ requires
}; };
}(); }();
/* /*
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Ox.URL Ox.URL
@ -771,20 +817,35 @@ requires
}; };
// public // 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 = function(defaults) {
/* /*
that.defaults({foo: x}) sets self.defaults that.defaults({foo: x}) sets self.defaults
*/ */
self.defaults = defaults; self.defaults = defaults;
return that; return that;
} };
that.gain = function() { that.gainFocus = function() {
Ox.Focus.gain(that.id); Ox.Focus.focus(that.id);
} };
that.lose = function() { that.hasFocus = function() {
Ox.Focus.lose(that.id); return Ox.Focus.focused() == that.id;
} };
that.options = function() { that.loseFocus = function() {
Ox.Focus.blur(that.id);
};
that.options = function() { // fixme: use Ox.getset
/* /*
that.options() returns self.options that.options() returns self.options
that.options("foo") returns self.options.foo that.options("foo") returns self.options.foo
@ -817,26 +878,21 @@ requires
} }
return ret; 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.remove = function() {
that.$element.remove(); that.$element.remove();
delete elements[that.ox]; delete elements[that.ox];
} }
that.subscribe = function() { that.unbindEvent = function() {
Ox.Event.subscribe.apply(that, arguments); /*
// or unbindEvent(event, fn) or unbindEvent({event0: fn0, event1: fn1, ...})
that.$element.bind.apply(that, arguments); */
return that; if (arguments.length == 1) {
} $.each(arguments[0], function(event, fn) {
that.unsubscribe = function() { Ox.Event.unbind(that.id, event, fn);
Ox.Event.unsubscribe.apply(that, arguments); })
return that; } else {
Ox.Event.unbind(that.id, arguments[0], arguments[1]);
}
} }
// return // return
@ -1694,9 +1750,10 @@ requires
left: 0, left: 0,
top: 0 top: 0
}, },
parent: null,
selected: -1, selected: -1,
side: "bottom", side: "bottom",
size: "medium" size: "medium",
}) })
.options(options) .options(options)
.addClass( .addClass(
@ -1740,8 +1797,9 @@ requires
left: 0, left: 0,
top: -4 top: -4
}, },
parent: that,
side: "right", side: "right",
size: self.options.size size: self.options.size,
}); });
} }
} else { } else {
@ -1756,6 +1814,12 @@ requires
.addClass("OxBottom") .addClass("OxBottom")
.appendTo(that.$element); .appendTo(that.$element);
function click(event) {
if (!$(event.target).is(".OxCell")) {
that.hideMenu();
}
}
function clickItem() { function clickItem() {
if (self.options.selected > -1) { if (self.options.selected > -1) {
that.items[self.options.selected].trigger("click"); that.items[self.options.selected].trigger("click");
@ -1823,6 +1887,7 @@ requires
} }
function getElement(id) { function getElement(id) {
// fixme: needed?
return $("#" + Ox.toCamelCase(options.id + "/" + id)); 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() { that.hideMenu = function() {
Ox.print("hideMenu") Ox.print("hideMenu")
$.each(that.submenus, function(i, submenu) { $.each(that.submenus, function(i, submenu) {
@ -1911,11 +2007,20 @@ requires
if (self.options.selected > -1) { if (self.options.selected > -1) {
that.items[self.options.selected].trigger("mouseleave"); that.items[self.options.selected].trigger("mouseleave");
} }
Ox.Event.unbind("key down", selectNextItem); that.loseFocus();
Ox.Event.unbind("key up", selectPreviousItem); that.unbindEvent({
Ox.Event.unbind("key.escape", that.hideMenu); key_up: selectPreviousItem,
Ox.Event.unbind("key.enter", clickItem); key_down: selectNextItem,
$document.unbind("click", that.hideMenu); key_left: selectSupermenu,
key_right: selectSubmenu,
key_escape: that.hideMenu,
key_enter: clickItem
});
$document.unbind("click", click);
};
that.selectFirstItem = function() {
selectNextItem();
}; };
that.showMenu = function() { that.showMenu = function() {
@ -1935,13 +2040,19 @@ requires
that.$container.height(maxHeight - itemHeight); that.$container.height(maxHeight - itemHeight);
that.$scrollbars.down.show(); that.$scrollbars.down.show();
} }
Ox.print("binding..."); if (!self.options.parent) {
Ox.Event.bind("key.down", selectNextItem); that.gainFocus();
Ox.Event.bind("key.up", selectPreviousItem); }
Ox.Event.bind("key.escape", that.hideMenu); that.bindEvent({
Ox.Event.bind("key.enter", clickItem); key_up: selectPreviousItem,
key_down: selectNextItem,
key_left: selectSupermenu,
key_right: selectSubmenu,
key_escape: that.hideMenu,
key_enter: clickItem
});
setTimeout(function() { setTimeout(function() {
$document.bind("click", that.hideMenu); $document.bind("click", click);
}, 100); }, 100);
}; };
@ -2025,7 +2136,7 @@ requires
); );
function click() { function click() {
if (!that.hasClass("OxDisabled") && !self.options.submenu) { if (!that.hasClass("OxDisabled") && !self.options.items.length) {
self.options.menu.hideMenu(); self.options.menu.hideMenu();
if (self.options.checked !== null && (!self.options.group || !self.options.checked)) { if (self.options.checked !== null && (!self.options.group || !self.options.checked)) {
that.options({ that.options({
@ -2039,7 +2150,6 @@ requires
id: self.options.id, id: self.options.id,
value: self.options.title // fixme: value or title? value: self.options.title // fixme: value or title?
}); });
return false;
} }
} }
@ -2050,7 +2160,10 @@ requires
function mouseenter() { function mouseenter() {
if (!self.options.disabled && !isSelected()) { if (!self.options.disabled && !isSelected()) {
$.each(self.options.menu.submenus, function(id, submenu) { $.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) { if (self.options.menu.options("selected") > -1) {
self.options.menu.items[self.options.menu.options("selected")].trigger("mouseleave"); self.options.menu.items[self.options.menu.options("selected")].trigger("mouseleave");

View file

@ -74,18 +74,43 @@ $(function() {
}, },
], ],
title: "More", 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() { button
$(this).blur(); // fix for firefox .click(function() {
menu.toggleMenu(); $(this).blur(); // fix for firefox
}); menu.toggleMenu();
Ox.Event.bind("OxClickMenu", function(event, data) { })
button.options({ .bindEvent("OxClickMenu", function(event, data) {
value: data.value button.options({
value: data.value
});
}); });
});
$select = $("<select>") $select = $("<select>")
.css({ .css({
position: "absolute", position: "absolute",