some keyboard navigation for menus

This commit is contained in:
Rolux 2010-02-04 15:20:45 +05:30
parent a2ea4b7846
commit bff58df78f
2 changed files with 122 additions and 78 deletions

View file

@ -108,7 +108,7 @@ requires
$document = $(document), $document = $(document),
$body = $("body"); $body = $("body");
Ox.theme(oxui.defaultTheme); Ox.theme(oxui.defaultTheme);
}) });
/* /*
============================================================================ ============================================================================
@ -209,14 +209,18 @@ requires
bind: function(event, callback) { bind: function(event, callback) {
$eventHandler.bind(event, callback); $eventHandler.bind(event, callback);
}, },
trigger: function(event, data) { one: function(event, callback) {
$eventHandler.trigger(event, data); $eventHandler.one(event, callback);
}, },
unbind: function(event) { trigger: function(event, data) {
Ox.print("trigger", event, data || {});
$eventHandler.trigger(event, data || {});
},
unbind: function(event, callback) {
$eventHandler.unbind(event, callback); $eventHandler.unbind(event, callback);
} }
} }
} }();
Ox.Event_ = function() { Ox.Event_ = function() {
var events = {}; var events = {};
@ -324,32 +328,32 @@ requires
55: "7", 55: "7",
56: "8", 56: "8",
57: "9", 57: "9",
65: "A", 65: "a",
66: "B", 66: "b",
67: "C", 67: "c",
68: "D", 68: "d",
69: "E", 69: "e",
70: "F", 70: "f",
71: "G", 71: "g",
72: "H", 72: "h",
73: "I", 73: "i",
74: "J", 74: "j",
75: "K", 75: "k",
76: "L", 76: "l",
77: "M", 77: "m",
78: "N", 78: "n",
79: "O", 79: "o",
80: "P", 80: "p",
81: "Q", 81: "q",
82: "R", 82: "r",
83: "S", 83: "s",
84: "T", 84: "t",
85: "U", 85: "u",
86: "V", 86: "v",
87: "W", 87: "w",
88: "X", 88: "x",
89: "Y", 89: "y",
90: "Z", 90: "z",
91: "meta.left", 91: "meta.left",
92: "meta.right", 92: "meta.right",
93: "select", 93: "select",
@ -408,39 +412,41 @@ requires
shiftKey: "shift" shiftKey: "shift"
}; };
return function() { $(function() {
document.keydown(keydown); $document.keydown(keydown);
function keydown(e) { });
var key = [], function keydown(event) {
ret = true, var key,
time; keys = [],
$.each(modifierNames, function(k, v) { ret = true,
if (e[k]) { time;
key.push(v); $.each(modifierNames, function(k, v) {
} if (event[k]) {
}); keys.push(v);
// avoid pushing modifier twice
if (keyNames[e.keyCode] && keys.indexOf(keyNames[e.keyCode]) == -1) {
key.push(keyNames[e.keyCode]);
} }
key = key.join(" "); });
if (key.match(/^[\w\d-]$|SPACE/)) { // avoid pushing modifier twice
time = Ox.time(); if (keyNames[event.keyCode] && keys.indexOf(keyNames[event.keyCode]) == -1) {
if (time - bufferTime > bufferTimeout) { keys.push(keyNames[event.keyCode]);
buffer = "";
}
buffer += key == "SPACE" ? " " : key;
bufferTime = time;
}
$.each(stack, function(i, v) {
// fixme: we dont get the return value!
ret = Ox.event.publish(keyboard + Ox.toCamelCase(key) + "." + v);
return ret;
});
} }
key = keys.join(".");
}; if (key.match(/^[\w\d-]$|SPACE/)) {
time = Ox.getTime();
if (time - bufferTime > bufferTimeout) {
buffer = "";
}
buffer += key == "SPACE" ? " " : key;
bufferTime = time;
}
Ox.Event.trigger("key." + key);
/*
$.each(stack, function(i, v) {
// fixme: we dont get the return value!
ret = Ox.event.trigger(keyboard + Ox.toCamelCase(key) + "." + v);
return ret;
});
*/
}
})(); })();
@ -1650,6 +1656,7 @@ requires
left: 0, left: 0,
top: 0 top: 0
}, },
selected: -1,
side: "bottom", side: "bottom",
size: "medium" size: "medium"
}) })
@ -1659,7 +1666,6 @@ requires
" Ox" + Ox.toTitleCase(self.options.size) " Ox" + Ox.toTitleCase(self.options.size)
), ),
itemHeight = options.size == "small" ? 12 : (options.size == "medium" ? 16 : 20), itemHeight = options.size == "small" ? 12 : (options.size == "medium" ? 16 : 20),
selected = -1,
scrollSpeed = 1, scrollSpeed = 1,
$item; $item;
@ -1687,10 +1693,9 @@ requires
menu: that, menu: that,
submenu: that.submenus[item.id] || null submenu: that.submenus[item.id] || null
}); });
item = new Ox.MenuItem(item) that.items.push(new Ox.MenuItem($.extend(item, {
.data("pos", i) position: that.items.length
.appendTo(that.$content); })).appendTo(that.$content));
that.items.push(item);
that.$content.append($item); that.$content.append($item);
} else { } else {
that.$content.append(constructSpace()); that.$content.append(constructSpace());
@ -1704,6 +1709,12 @@ requires
.addClass("OxBottom") .addClass("OxBottom")
.appendTo(that.$element); .appendTo(that.$element);
function clickItem() {
if (self.options.selected > -1) {
that.items[self.options.selected].trigger("click");
}
}
function constructLine() { function constructLine() {
return $("<tr>").append( return $("<tr>").append(
$("<td>", { $("<td>", {
@ -1795,11 +1806,23 @@ requires
} }
function selectNextItem() { function selectNextItem() {
var selected = self.options.selected;
if (selected < that.items.length - 1) {
if (selected > -1) {
that.items[selected].trigger("mouseleave");
}
selected++;
that.items[selected].trigger("mouseenter");
}
} }
function selectPreviousItem() { function selectPreviousItem() {
var selected = self.options.selected;
if (selected > 0) {
that.items[selected].trigger("mouseleave");
selected--;
that.items[selected].trigger("mouseenter");
}
} }
that.hideMenu = function() { that.hideMenu = function() {
@ -1812,6 +1835,13 @@ requires
}); });
// fixme: scroll menu back up! // fixme: scroll menu back up!
that.hide(); that.hide();
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.enter", clickItem);
$document.unbind("click", that.hideMenu);
}; };
that.showMenu = function() { that.showMenu = function() {
@ -1831,6 +1861,13 @@ requires
that.$container.height(maxHeight - itemHeight); that.$container.height(maxHeight - itemHeight);
that.$scrollbars.down.show(); that.$scrollbars.down.show();
} }
Ox.print("binding...")
Ox.Event.bind("key.down", selectNextItem);
Ox.Event.bind("key.up", selectPreviousItem);
Ox.Event.bind("key.enter", clickItem);
setTimeout(function() {
$document.bind("click", that.hideMenu);
}, 100);
}; };
that.toggleMenu = function() { that.toggleMenu = function() {
@ -1855,6 +1892,7 @@ requires
id: "", id: "",
keyboard: "", keyboard: "",
menu: null, // fixme: is passing the menu to 100s of menu items really memory-neutral? menu: null, // fixme: is passing the menu to 100s of menu items really memory-neutral?
position: 0,
submenu: null, submenu: null,
title: [], title: [],
}) })
@ -1867,9 +1905,10 @@ requires
id: Ox.toCamelCase(self.options.menu.id + "/" + self.options.id) id: Ox.toCamelCase(self.options.menu.id + "/" + self.options.id)
}) })
.click(click) .click(click)
.data("group", self.options.group) .data("group", self.options.group) // fixme: why?
.mouseenter(mouseenter) .mouseenter(mouseenter)
.mouseleave(mouseleave); .mouseleave(mouseleave)
.mousemove(mouseenter); // in case selection has goes elsewhere via keyboard
// construct // construct
that.append( that.append(
@ -1921,7 +1960,7 @@ requires
if (self.options.title.length == 2) { if (self.options.title.length == 2) {
that.toggleTitle(); that.toggleTitle();
} }
$("*").trigger("OxClickMenu", { Ox.Event.trigger("OxClickMenu", {
id: self.options.id, id: self.options.id,
value: self.options.title // fixme: value or title? value: self.options.title // fixme: value or title?
}); });
@ -1937,12 +1976,18 @@ requires
$(".OxMenu .OxItem[id!=" + self.options.id + "]").removeClass("selected"); $(".OxMenu .OxItem[id!=" + self.options.id + "]").removeClass("selected");
self.options.submenu && self.options.submenu.showMenu(); // fixme: do we want to switch to this style? self.options.submenu && self.options.submenu.showMenu(); // fixme: do we want to switch to this style?
that.addClass("OxSelected"); that.addClass("OxSelected");
self.options.menu.options({
selected: self.options.position
});
} }
} }
function mouseleave() { function mouseleave() {
if (!that.hasClass("OxDisabled") && !self.options.submenu) { if (!that.hasClass("OxDisabled") && !self.options.submenu) {
that.removeClass("OxSelected"); that.removeClass("OxSelected");
self.options.menu.options({
selected: -1
});
} }
} }

View file

@ -51,13 +51,12 @@ $(function() {
} }
] ]
}); });
button button.click(menu.toggleMenu)
.click(menu.toggleMenu) Ox.Event.bind("OxClickMenu", function(event, data) {
.bind("OxClickMenu", function(event, data) { button.options({
button.options({ value: data.value
value: data.value
});
}); });
});
$select = $("<select>") $select = $("<select>")
.css({ .css({
position: "absolute", position: "absolute",