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