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

View file

@ -51,9 +51,8 @@ $(function() {
}
]
});
button
.click(menu.toggleMenu)
.bind("OxClickMenu", function(event, data) {
button.click(menu.toggleMenu)
Ox.Event.bind("OxClickMenu", function(event, data) {
button.options({
value: data.value
});