some keyboard navigation, some submenu
This commit is contained in:
parent
bff58df78f
commit
8277cab528
5 changed files with 197 additions and 74 deletions
|
@ -55,6 +55,10 @@ Forms
|
||||||
background: -moz-linear-gradient(top, rgb(224, 224, 224), rgb(192, 192, 192));
|
background: -moz-linear-gradient(top, rgb(224, 224, 224), rgb(192, 192, 192));
|
||||||
background: -webkit-gradient(linear, left top, left bottom, from(rgb(224, 224, 224)), to(rgb(192, 192, 192)));
|
background: -webkit-gradient(linear, left top, left bottom, from(rgb(224, 224, 224)), to(rgb(192, 192, 192)));
|
||||||
}
|
}
|
||||||
|
.OxThemeClassic .OxButton:focus {
|
||||||
|
-moz-box-shadow: 0 0 2px rgb(128, 128, 128);
|
||||||
|
-webkit-box-shadow: 0 2 4px rgb(128, 128, 128);
|
||||||
|
}
|
||||||
.OxThemeClassic .OxButton:active,
|
.OxThemeClassic .OxButton:active,
|
||||||
.OxThemeClassic .OxRange.OxActive {
|
.OxThemeClassic .OxRange.OxActive {
|
||||||
//background: rgb(160, 160, 160);
|
//background: rgb(160, 160, 160);
|
||||||
|
@ -112,7 +116,7 @@ Menus
|
||||||
.OxThemeClassic .OxMenu .OxScrollbar.OxSelected {
|
.OxThemeClassic .OxMenu .OxScrollbar.OxSelected {
|
||||||
background: rgba(192, 192, 192, 0.96);
|
background: rgba(192, 192, 192, 0.96);
|
||||||
}
|
}
|
||||||
.OxThemeModern .OxMenu .OxItem.OxDisabled .OxCell {
|
.OxThemeClassic .OxMenu .OxItem.OxDisabled .OxCell {
|
||||||
color: rgb(160, 160, 160);
|
color: rgb(160, 160, 160);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -442,22 +442,22 @@ Menus
|
||||||
.OxMenu .OxLine {
|
.OxMenu .OxLine {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
.OxMenu .OxScrollBar {
|
.OxMenu .OxScrollbar {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.OxMenu.OxLarge .OxScrollBar {
|
.OxMenu.OxLarge .OxScrollbar {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
.OxMenu.OxMedium .OxScrollBar {
|
.OxMenu.OxMedium .OxScrollbar {
|
||||||
height: 13px;
|
height: 13px;
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
font-size: 8px;
|
font-size: 8px;
|
||||||
}
|
}
|
||||||
.OxMenu.OxSmall .OxScrollBar {
|
.OxMenu.OxSmall .OxScrollbar {
|
||||||
height: 10px;
|
height: 10px;
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
font-size: 6px;
|
font-size: 6px;
|
||||||
|
|
|
@ -53,52 +53,52 @@ requires
|
||||||
apple: "\uF8FF",
|
apple: "\uF8FF",
|
||||||
arrow_down: "\u2193",
|
arrow_down: "\u2193",
|
||||||
arrow_left: "\u2190",
|
arrow_left: "\u2190",
|
||||||
"arrow right": "\u2192",
|
arrow_right: "\u2192",
|
||||||
"arrow up": "\u2191",
|
arrow_up: "\u2191",
|
||||||
"backspace": "\u232B",
|
backspace: "\u232B",
|
||||||
"backup": "\u2707",
|
backup: "\u2707",
|
||||||
"ballot": "\u2717",
|
ballot: "\u2717",
|
||||||
"black star": "\u2605",
|
black_star: "\u2605",
|
||||||
"burn": "\u2622",
|
burn: "\u2622",
|
||||||
"caps lock": "\u21EA",
|
caps_lock: "\u21EA",
|
||||||
"check": "\u2713",
|
check: "\u2713",
|
||||||
"CLEAR": "\u2327",
|
clear: "\u2327",
|
||||||
"CLICK": "\uF803",
|
click: "\uF803",
|
||||||
"CLOSE": "\u2715",
|
close: "\u2715",
|
||||||
"COMMAND": "\u2318",
|
command: "\u2318",
|
||||||
"CONTROL": "\u2303",
|
control: "\u2303",
|
||||||
"CUT": "\u2702",
|
cut: "\u2702",
|
||||||
"DELETE": "\u2326",
|
"delete": "\u2326",
|
||||||
"DIAMOND": "\u25C6",
|
diamond: "\u25C6",
|
||||||
"EDIT": "\uF802",
|
edit: "\uF802",
|
||||||
"EJECT": "\u23CF",
|
eject: "\u23CF",
|
||||||
"ESCAPE": "\u238B",
|
escape: "\u238B",
|
||||||
"END": "\u2198",
|
end: "\u2198",
|
||||||
"ENTER": "\u2324",
|
enter: "\u2324",
|
||||||
"FLY": "\u2708",
|
fly: "\u2708",
|
||||||
"GEAR": "\u2699",
|
gear: "\u2699",
|
||||||
"HOME": "\u2196",
|
home: "\u2196",
|
||||||
"INFO": "\u24D8",
|
info: "\u24D8",
|
||||||
"NAVIGATE": "\u2388",
|
navigate: "\u2388",
|
||||||
"OPTION": "\u2387",
|
option: "\u2387",
|
||||||
"PAGE UP": "\u21DE",
|
page_up: "\u21DE",
|
||||||
"PAGE DOWN": "\u21DF",
|
page_down: "\u21DF",
|
||||||
"REDO": "\u21BA",
|
redo: "\u21BA",
|
||||||
"RETURN": "\u21A9",
|
"return": "\u21A9",
|
||||||
"SELECT": "\u21D5",
|
select: "\u21D5",
|
||||||
"SHIFT": "\u21E7",
|
shift: "\u21E7",
|
||||||
"SOUND": "\u266B",
|
sound: "\u266B",
|
||||||
"SPACE": "\u2423",
|
space: "\u2423",
|
||||||
"TAB": "\u21E5",
|
tab: "\u21E5",
|
||||||
"TRASH": "\u267A",
|
trash: "\u267A",
|
||||||
"TRIANGLE DOWN": "\u25BC",
|
triangle_down: "\u25BC",
|
||||||
"TRIANGLE LEFT": "\u25C0",
|
triangle_left: "\u25C0",
|
||||||
triangle_right: "\u25BA",
|
triangle_right: "\u25BA",
|
||||||
"TRIANGLE UP": "\u25B2",
|
triangle_up: "\u25B2",
|
||||||
"UNDO": "\u21BB",
|
undo: "\u21BB",
|
||||||
"VOLTAGE": "\u26A1",
|
voltage: "\u26A1",
|
||||||
"WARNING": "\u26A0",
|
warning: "\u26A0",
|
||||||
"WHITE STAR": "\u2606"
|
white_star: "\u2606"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
$window, $document, $body;
|
$window, $document, $body;
|
||||||
|
@ -1634,6 +1634,44 @@ requires
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
Ox.Select
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
Ox.Select = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Button({}, self)
|
||||||
|
.defaults({
|
||||||
|
id: "",
|
||||||
|
items: []
|
||||||
|
})
|
||||||
|
.options(options)
|
||||||
|
.click(click),
|
||||||
|
items;
|
||||||
|
|
||||||
|
$.each(self.options.items, function(i, item) {
|
||||||
|
items.push({
|
||||||
|
checked: false,
|
||||||
|
group: self.options.id,
|
||||||
|
title: item.title
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
that.$menu = new Ox.Menu({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
function click() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
============================================================================
|
============================================================================
|
||||||
Menus
|
Menus
|
||||||
|
@ -1685,18 +1723,27 @@ requires
|
||||||
.addClass("OxContent")
|
.addClass("OxContent")
|
||||||
.appendTo(that.$container);
|
.appendTo(that.$container);
|
||||||
$.each(self.options.items, function(i, item) {
|
$.each(self.options.items, function(i, item) {
|
||||||
|
var position;
|
||||||
if (item.id) {
|
if (item.id) {
|
||||||
if (!$.isEmptyObject(item.submenu)) {
|
|
||||||
that.submenus[item.id] = new Ox.Menu(item.submenu);
|
|
||||||
}
|
|
||||||
$.extend(item, {
|
$.extend(item, {
|
||||||
menu: that,
|
menu: that,
|
||||||
submenu: that.submenus[item.id] || null
|
|
||||||
});
|
});
|
||||||
that.items.push(new Ox.MenuItem($.extend(item, {
|
that.items.push(new Ox.MenuItem($.extend(item, {
|
||||||
position: that.items.length
|
position: position = that.items.length
|
||||||
})).appendTo(that.$content));
|
})).appendTo(that.$content));
|
||||||
that.$content.append($item);
|
if (item.items) {
|
||||||
|
that.submenus[item.id] = new Ox.Menu({
|
||||||
|
element: that.items[position],
|
||||||
|
id: Ox.toCamelCase(self.options.id + "/" + item.id),
|
||||||
|
items: item.items,
|
||||||
|
offset: {
|
||||||
|
left: 0,
|
||||||
|
top: -4
|
||||||
|
},
|
||||||
|
side: "right",
|
||||||
|
size: self.options.size
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
that.$content.append(constructSpace());
|
that.$content.append(constructSpace());
|
||||||
that.$content.append(constructLine());
|
that.$content.append(constructLine());
|
||||||
|
@ -1712,6 +1759,8 @@ requires
|
||||||
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");
|
||||||
|
} else {
|
||||||
|
that.hideMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1727,7 +1776,7 @@ requires
|
||||||
function constructScrollbar(direction) {
|
function constructScrollbar(direction) {
|
||||||
var interval;
|
var interval;
|
||||||
return $("<div/>", {
|
return $("<div/>", {
|
||||||
addClass: "OxScrollbar Ox" + Ox.toTitleCase(direction),
|
"class": "OxScrollbar Ox" + Ox.toTitleCase(direction),
|
||||||
html: oxui.symbols["triangle_" + direction],
|
html: oxui.symbols["triangle_" + direction],
|
||||||
click: function() { // fixme: do we need to listen to click event?
|
click: function() { // fixme: do we need to listen to click event?
|
||||||
return false;
|
return false;
|
||||||
|
@ -1777,6 +1826,26 @@ requires
|
||||||
return $("#" + Ox.toCamelCase(options.id + "/" + id));
|
return $("#" + Ox.toCamelCase(options.id + "/" + id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isFirstEnabledItem() {
|
||||||
|
var ret = true;
|
||||||
|
$.each(that.items, function(i, item) {
|
||||||
|
if (i < self.options.selected && !item.options("disabled")) {
|
||||||
|
return ret = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLastEnabledItem() {
|
||||||
|
var ret = true;
|
||||||
|
$.each(that.items, function(i, item) {
|
||||||
|
if (i > self.options.selected && !item.options("disabled")) {
|
||||||
|
return ret = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function scrollMenu(speed) {
|
function scrollMenu(speed) {
|
||||||
var containerHeight = that.$container.height(),
|
var containerHeight = that.$container.height(),
|
||||||
contentHeight = that.$content.height(),
|
contentHeight = that.$content.height(),
|
||||||
|
@ -1807,20 +1876,24 @@ requires
|
||||||
|
|
||||||
function selectNextItem() {
|
function selectNextItem() {
|
||||||
var selected = self.options.selected;
|
var selected = self.options.selected;
|
||||||
if (selected < that.items.length - 1) {
|
if (!isLastEnabledItem()) {
|
||||||
if (selected > -1) {
|
if (selected > -1) {
|
||||||
that.items[selected].trigger("mouseleave");
|
that.items[selected].trigger("mouseleave");
|
||||||
}
|
}
|
||||||
selected++;
|
do {
|
||||||
|
selected++;
|
||||||
|
} while (that.items[selected].options("disabled"))
|
||||||
that.items[selected].trigger("mouseenter");
|
that.items[selected].trigger("mouseenter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPreviousItem() {
|
function selectPreviousItem() {
|
||||||
var selected = self.options.selected;
|
var selected = self.options.selected;
|
||||||
if (selected > 0) {
|
if (!isFirstEnabledItem()) {
|
||||||
that.items[selected].trigger("mouseleave");
|
that.items[selected].trigger("mouseleave");
|
||||||
selected--;
|
do {
|
||||||
|
selected--;
|
||||||
|
} while (that.items[selected].options("disabled"))
|
||||||
that.items[selected].trigger("mouseenter");
|
that.items[selected].trigger("mouseenter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1838,8 +1911,9 @@ 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)
|
Ox.Event.unbind("key down", selectNextItem);
|
||||||
Ox.Event.unbind("key up", selectPreviousItem)
|
Ox.Event.unbind("key up", selectPreviousItem);
|
||||||
|
Ox.Event.unbind("key.escape", that.hideMenu);
|
||||||
Ox.Event.unbind("key.enter", clickItem);
|
Ox.Event.unbind("key.enter", clickItem);
|
||||||
$document.unbind("click", that.hideMenu);
|
$document.unbind("click", that.hideMenu);
|
||||||
};
|
};
|
||||||
|
@ -1861,9 +1935,10 @@ requires
|
||||||
that.$container.height(maxHeight - itemHeight);
|
that.$container.height(maxHeight - itemHeight);
|
||||||
that.$scrollbars.down.show();
|
that.$scrollbars.down.show();
|
||||||
}
|
}
|
||||||
Ox.print("binding...")
|
Ox.print("binding...");
|
||||||
Ox.Event.bind("key.down", selectNextItem);
|
Ox.Event.bind("key.down", selectNextItem);
|
||||||
Ox.Event.bind("key.up", selectPreviousItem);
|
Ox.Event.bind("key.up", selectPreviousItem);
|
||||||
|
Ox.Event.bind("key.escape", that.hideMenu);
|
||||||
Ox.Event.bind("key.enter", clickItem);
|
Ox.Event.bind("key.enter", clickItem);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$document.bind("click", that.hideMenu);
|
$document.bind("click", that.hideMenu);
|
||||||
|
@ -1890,10 +1965,10 @@ requires
|
||||||
group: "",
|
group: "",
|
||||||
icon: "",
|
icon: "",
|
||||||
id: "",
|
id: "",
|
||||||
|
items: [],
|
||||||
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,
|
position: 0,
|
||||||
submenu: null,
|
|
||||||
title: [],
|
title: [],
|
||||||
})
|
})
|
||||||
.options($.extend(options, {
|
.options($.extend(options, {
|
||||||
|
@ -1908,7 +1983,7 @@ requires
|
||||||
.data("group", self.options.group) // fixme: why?
|
.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
|
.mousemove(mousemove); // in case selection has goes elsewhere via keyboard
|
||||||
|
|
||||||
// construct
|
// construct
|
||||||
that.append(
|
that.append(
|
||||||
|
@ -1943,11 +2018,11 @@ requires
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
$("<td>", {
|
$("<td>", {
|
||||||
"class": "OxCell Ox" + (self.options.submenu ? "Submenu" : "Key"),
|
"class": "OxCell Ox" + (self.options.items.length ? "Submenu" : "Key"),
|
||||||
html: self.options.submenu ? oxui.symbols.triangle_right :
|
html: self.options.items.length ? oxui.symbols.triangle_right :
|
||||||
oxui.symbols[self.options.keyboard.key] || self.options.keyboard.key
|
oxui.symbols[self.options.keyboard.key] || self.options.keyboard.key
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
|
|
||||||
function click() {
|
function click() {
|
||||||
if (!that.hasClass("OxDisabled") && !self.options.submenu) {
|
if (!that.hasClass("OxDisabled") && !self.options.submenu) {
|
||||||
|
@ -1968,13 +2043,19 @@ requires
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isSelected() {
|
||||||
|
return self.options.position == self.options.menu.options("selected");
|
||||||
|
}
|
||||||
|
|
||||||
function mouseenter() {
|
function mouseenter() {
|
||||||
if (!that.is(".OxDisabled") && !that.is(".OxSelected")) {
|
if (!self.options.disabled && !isSelected()) {
|
||||||
$.each(self.options.menu.submenus, function(id, submenu) {
|
$.each(self.options.menu.submenus, function(id, submenu) {
|
||||||
submenu.hideMenu();
|
submenu.hideMenu();
|
||||||
});
|
});
|
||||||
$(".OxMenu .OxItem[id!=" + self.options.id + "]").removeClass("selected");
|
if (self.options.menu.options("selected") > -1) {
|
||||||
self.options.submenu && self.options.submenu.showMenu(); // fixme: do we want to switch to this style?
|
self.options.menu.items[self.options.menu.options("selected")].trigger("mouseleave");
|
||||||
|
}
|
||||||
|
self.options.items.length && self.options.menu.submenus[self.options.id].showMenu(); // fixme: do we want to switch to this style?
|
||||||
that.addClass("OxSelected");
|
that.addClass("OxSelected");
|
||||||
self.options.menu.options({
|
self.options.menu.options({
|
||||||
selected: self.options.position
|
selected: self.options.position
|
||||||
|
@ -1983,7 +2064,7 @@ requires
|
||||||
}
|
}
|
||||||
|
|
||||||
function mouseleave() {
|
function mouseleave() {
|
||||||
if (!that.hasClass("OxDisabled") && !self.options.submenu) {
|
if (!self.options.disabled && !self.options.submenu) {
|
||||||
that.removeClass("OxSelected");
|
that.removeClass("OxSelected");
|
||||||
self.options.menu.options({
|
self.options.menu.options({
|
||||||
selected: -1
|
selected: -1
|
||||||
|
@ -1991,6 +2072,15 @@ requires
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mousemove() {
|
||||||
|
var selected = self.options.menu.options("selected");
|
||||||
|
if (!self.options.disabled && !isSelected()) {
|
||||||
|
self.options.menu.items[self.options.menu.options("selected")]
|
||||||
|
.trigger("mouseleave");
|
||||||
|
mouseenter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function parseKeyboard(str) {
|
function parseKeyboard(str) {
|
||||||
var modifiers = str.split(' '),
|
var modifiers = str.split(' '),
|
||||||
key = modifiers.pop();
|
key = modifiers.pop();
|
||||||
|
|
BIN
demos/.DS_Store
vendored
BIN
demos/.DS_Store
vendored
Binary file not shown.
|
@ -39,6 +39,7 @@ $(function() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
checked: false,
|
checked: false,
|
||||||
|
disabled: true,
|
||||||
group: "123",
|
group: "123",
|
||||||
id: "fifth",
|
id: "fifth",
|
||||||
title: "Fifth"
|
title: "Fifth"
|
||||||
|
@ -48,10 +49,38 @@ $(function() {
|
||||||
group: "123",
|
group: "123",
|
||||||
id: "sixth",
|
id: "sixth",
|
||||||
title: "Sixth"
|
title: "Sixth"
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
id: "more",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
checked: true,
|
||||||
|
group: "789",
|
||||||
|
id: "seventh",
|
||||||
|
title: "Seventh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
checked: false,
|
||||||
|
group: "789",
|
||||||
|
id: "eighth",
|
||||||
|
title: "Eighth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
checked: false,
|
||||||
|
group: "789",
|
||||||
|
id: "ninth",
|
||||||
|
title: "Ninth"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
title: "More",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
button.click(menu.toggleMenu)
|
button.click(function() {
|
||||||
|
$(this).focus();
|
||||||
|
menu.toggleMenu();
|
||||||
|
});
|
||||||
Ox.Event.bind("OxClickMenu", function(event, data) {
|
Ox.Event.bind("OxClickMenu", function(event, data) {
|
||||||
button.options({
|
button.options({
|
||||||
value: data.value
|
value: data.value
|
||||||
|
|
Loading…
Reference in a new issue