some keyboard navigation for menus
This commit is contained in:
parent
a2ea4b7846
commit
bff58df78f
2 changed files with 122 additions and 78 deletions
|
@ -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,39 +412,41 @@ requires
|
|||
shiftKey: "shift"
|
||||
};
|
||||
|
||||
return function() {
|
||||
document.keydown(keydown);
|
||||
function keydown(e) {
|
||||
var key = [],
|
||||
ret = true,
|
||||
time;
|
||||
$.each(modifierNames, function(k, v) {
|
||||
if (e[k]) {
|
||||
key.push(v);
|
||||
}
|
||||
});
|
||||
// avoid pushing modifier twice
|
||||
if (keyNames[e.keyCode] && keys.indexOf(keyNames[e.keyCode]) == -1) {
|
||||
key.push(keyNames[e.keyCode]);
|
||||
$(function() {
|
||||
$document.keydown(keydown);
|
||||
});
|
||||
function keydown(event) {
|
||||
var key,
|
||||
keys = [],
|
||||
ret = true,
|
||||
time;
|
||||
$.each(modifierNames, function(k, v) {
|
||||
if (event[k]) {
|
||||
keys.push(v);
|
||||
}
|
||||
key = key.join(" ");
|
||||
if (key.match(/^[\w\d-]$|SPACE/)) {
|
||||
time = Ox.time();
|
||||
if (time - bufferTime > bufferTimeout) {
|
||||
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;
|
||||
});
|
||||
|
||||
});
|
||||
// avoid pushing modifier twice
|
||||
if (keyNames[event.keyCode] && keys.indexOf(keyNames[event.keyCode]) == -1) {
|
||||
keys.push(keyNames[event.keyCode]);
|
||||
}
|
||||
|
||||
};
|
||||
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,
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,13 +51,12 @@ $(function() {
|
|||
}
|
||||
]
|
||||
});
|
||||
button
|
||||
.click(menu.toggleMenu)
|
||||
.bind("OxClickMenu", function(event, data) {
|
||||
button.options({
|
||||
value: data.value
|
||||
});
|
||||
button.click(menu.toggleMenu)
|
||||
Ox.Event.bind("OxClickMenu", function(event, data) {
|
||||
button.options({
|
||||
value: data.value
|
||||
});
|
||||
});
|
||||
$select = $("<select>")
|
||||
.css({
|
||||
position: "absolute",
|
||||
|
|
Loading…
Reference in a new issue