some more menu and keyboard navigation
This commit is contained in:
parent
88057655f0
commit
150c3df7b6
2 changed files with 198 additions and 60 deletions
|
@ -47,7 +47,6 @@ requires
|
|||
}(),
|
||||
path: $("script[src*=ox.ui.js]").attr("src")
|
||||
.replace("js/ox.ui.js", ""),
|
||||
stack: [], // fixme: used?
|
||||
symbols: { // fixme: make lowercase
|
||||
alt: "\u2325",
|
||||
apple: "\uF8FF",
|
||||
|
@ -203,21 +202,52 @@ requires
|
|||
|
||||
// use dom elements / jquery instead
|
||||
|
||||
|
||||
Ox.Event = function() {
|
||||
var $eventHandler = $("<div>");
|
||||
var keyboardEvents = {};
|
||||
$eventHandler = $("<div>");
|
||||
function isKeyboardEvent(event) {
|
||||
return event.substr(0, 4) == "key_";
|
||||
}
|
||||
return {
|
||||
bind: function(event, callback) {
|
||||
$eventHandler.bind(event, callback);
|
||||
bind: function(id, event, callback) {
|
||||
if (isKeyboardEvent(event)) {
|
||||
keyboardEvents[id] = keyboardEvents[id] || [];
|
||||
keyboardEvents[id].push({
|
||||
event: event,
|
||||
callback: callback
|
||||
});
|
||||
}
|
||||
if (!isKeyboardEvent(event) || Ox.Focus.focused() == id) {
|
||||
$eventHandler.bind(event, callback);
|
||||
}
|
||||
},
|
||||
one: function(event, callback) {
|
||||
$eventHandler.one(event, callback);
|
||||
bindKeyboard: function(id) {
|
||||
$.each(keyboardEvents[id] || [], function(i, event) {
|
||||
Ox.Event.bind(id, event.event, event.callback);
|
||||
});
|
||||
},
|
||||
trigger: function(event, data) {
|
||||
Ox.print("trigger", event, data || {});
|
||||
$eventHandler.trigger(event, data || {});
|
||||
},
|
||||
unbind: function(event, callback) {
|
||||
unbind: function(id, event, callback) {
|
||||
if (isKeyboardEvent(event)) {
|
||||
$.each(keyboardEvents[id] || [], function(i, e) {
|
||||
if (e.event == event) {
|
||||
keyboardEvents[id].splice(i, 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
$eventHandler.unbind(event, callback);
|
||||
},
|
||||
unbindKeyboard: function(id) {
|
||||
//Ox.print(keyboardEvents)
|
||||
//Ox.print("unbindKeyboard", id, keyboardEvents[id])
|
||||
$.each(keyboardEvents[id] || [], function(i, e) {
|
||||
$eventHandler.unbind(e.event, e.callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
@ -265,14 +295,31 @@ requires
|
|||
var stack = [];
|
||||
return {
|
||||
focus: function(id) {
|
||||
/*
|
||||
if (stack.length) {
|
||||
Ox.Event.unbindKeyboard(stack[stack.length - 1]);
|
||||
}
|
||||
*/
|
||||
var index = stack.indexOf(id);
|
||||
if (index > -1) {
|
||||
oxui.stack.splice(i, 1);
|
||||
stack.splice(index, 1);
|
||||
}
|
||||
oxui.stack.push(id);
|
||||
stack.push(id);
|
||||
Ox.Event.bindKeyboard(id);
|
||||
console.log("focus", stack);
|
||||
},
|
||||
focused: function() {
|
||||
return stack[stack.length - 1];
|
||||
},
|
||||
blur: function(id) {
|
||||
oxui.stack.pop();
|
||||
if (stack.indexOf(id) > -1) {
|
||||
stack.splice(stack.length - 2, 0, stack.pop());
|
||||
}
|
||||
Ox.Event.unbindKeyboard(id);
|
||||
/*
|
||||
Ox.Event.bindKeyboard(stack[stack.length - 1]);
|
||||
*/
|
||||
console.log("blur", stack);
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
@ -438,7 +485,7 @@ requires
|
|||
buffer += key == "SPACE" ? " " : key;
|
||||
bufferTime = time;
|
||||
}
|
||||
Ox.Event.trigger("key." + key);
|
||||
Ox.Event.trigger("key_" + key);
|
||||
/*
|
||||
$.each(stack, function(i, v) {
|
||||
// fixme: we dont get the return value!
|
||||
|
@ -656,7 +703,6 @@ requires
|
|||
};
|
||||
}();
|
||||
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------------------
|
||||
Ox.URL
|
||||
|
@ -771,20 +817,35 @@ requires
|
|||
};
|
||||
|
||||
// public
|
||||
that.bindEvent = function() {
|
||||
/*
|
||||
bindEvent(event, fn) or bindEvent({event0: fn0, event1: fn1, ...})
|
||||
*/
|
||||
if (arguments.length == 1) {
|
||||
$.each(arguments[0], function(event, fn) {
|
||||
Ox.Event.bind(that.id, event, fn);
|
||||
})
|
||||
} else {
|
||||
Ox.Event.bind(that.id, arguments[0], arguments[1]);
|
||||
}
|
||||
};
|
||||
that.defaults = function(defaults) {
|
||||
/*
|
||||
that.defaults({foo: x}) sets self.defaults
|
||||
*/
|
||||
self.defaults = defaults;
|
||||
return that;
|
||||
}
|
||||
that.gain = function() {
|
||||
Ox.Focus.gain(that.id);
|
||||
}
|
||||
that.lose = function() {
|
||||
Ox.Focus.lose(that.id);
|
||||
}
|
||||
that.options = function() {
|
||||
};
|
||||
that.gainFocus = function() {
|
||||
Ox.Focus.focus(that.id);
|
||||
};
|
||||
that.hasFocus = function() {
|
||||
return Ox.Focus.focused() == that.id;
|
||||
};
|
||||
that.loseFocus = function() {
|
||||
Ox.Focus.blur(that.id);
|
||||
};
|
||||
that.options = function() { // fixme: use Ox.getset
|
||||
/*
|
||||
that.options() returns self.options
|
||||
that.options("foo") returns self.options.foo
|
||||
|
@ -817,26 +878,21 @@ requires
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
that.publish = function() {
|
||||
arguments[0] = arguments[0] + "." + that.id;
|
||||
Ox.Event.publish.apply(that, arguments);
|
||||
// or, maybe better:
|
||||
$(".OxWidget").trigger.apply(that, arguments);
|
||||
return that;
|
||||
}
|
||||
that.remove = function() {
|
||||
that.$element.remove();
|
||||
delete elements[that.ox];
|
||||
}
|
||||
that.subscribe = function() {
|
||||
Ox.Event.subscribe.apply(that, arguments);
|
||||
// or
|
||||
that.$element.bind.apply(that, arguments);
|
||||
return that;
|
||||
}
|
||||
that.unsubscribe = function() {
|
||||
Ox.Event.unsubscribe.apply(that, arguments);
|
||||
return that;
|
||||
that.unbindEvent = function() {
|
||||
/*
|
||||
unbindEvent(event, fn) or unbindEvent({event0: fn0, event1: fn1, ...})
|
||||
*/
|
||||
if (arguments.length == 1) {
|
||||
$.each(arguments[0], function(event, fn) {
|
||||
Ox.Event.unbind(that.id, event, fn);
|
||||
})
|
||||
} else {
|
||||
Ox.Event.unbind(that.id, arguments[0], arguments[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// return
|
||||
|
@ -1694,9 +1750,10 @@ requires
|
|||
left: 0,
|
||||
top: 0
|
||||
},
|
||||
parent: null,
|
||||
selected: -1,
|
||||
side: "bottom",
|
||||
size: "medium"
|
||||
size: "medium",
|
||||
})
|
||||
.options(options)
|
||||
.addClass(
|
||||
|
@ -1740,8 +1797,9 @@ requires
|
|||
left: 0,
|
||||
top: -4
|
||||
},
|
||||
parent: that,
|
||||
side: "right",
|
||||
size: self.options.size
|
||||
size: self.options.size,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
@ -1756,6 +1814,12 @@ requires
|
|||
.addClass("OxBottom")
|
||||
.appendTo(that.$element);
|
||||
|
||||
function click(event) {
|
||||
if (!$(event.target).is(".OxCell")) {
|
||||
that.hideMenu();
|
||||
}
|
||||
}
|
||||
|
||||
function clickItem() {
|
||||
if (self.options.selected > -1) {
|
||||
that.items[self.options.selected].trigger("click");
|
||||
|
@ -1823,6 +1887,7 @@ requires
|
|||
}
|
||||
|
||||
function getElement(id) {
|
||||
// fixme: needed?
|
||||
return $("#" + Ox.toCamelCase(options.id + "/" + id));
|
||||
}
|
||||
|
||||
|
@ -1898,6 +1963,37 @@ requires
|
|||
}
|
||||
}
|
||||
|
||||
function selectSubmenu() {
|
||||
var submenu = that.submenus[that.items[self.options.selected].options("id")];
|
||||
if (submenu && submenu.hasEnabledItems()) {
|
||||
that.loseFocus();
|
||||
submenu.gainFocus();
|
||||
submenu.selectFirstItem();
|
||||
}
|
||||
}
|
||||
|
||||
function selectSupermenu() {
|
||||
if (self.options.parent) {
|
||||
that.items[self.options.selected].trigger("mouseleave");
|
||||
that.loseFocus();
|
||||
self.options.parent.gainFocus();
|
||||
}
|
||||
}
|
||||
|
||||
self.onChange = function(key, value) {
|
||||
|
||||
}
|
||||
|
||||
that.hasEnabledItems = function() {
|
||||
var ret = false;
|
||||
$.each(that.items, function(i, item) {
|
||||
if (!item.options("disabled")) {
|
||||
return ret = true;
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
that.hideMenu = function() {
|
||||
Ox.print("hideMenu")
|
||||
$.each(that.submenus, function(i, submenu) {
|
||||
|
@ -1911,11 +2007,20 @@ 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.escape", that.hideMenu);
|
||||
Ox.Event.unbind("key.enter", clickItem);
|
||||
$document.unbind("click", that.hideMenu);
|
||||
that.loseFocus();
|
||||
that.unbindEvent({
|
||||
key_up: selectPreviousItem,
|
||||
key_down: selectNextItem,
|
||||
key_left: selectSupermenu,
|
||||
key_right: selectSubmenu,
|
||||
key_escape: that.hideMenu,
|
||||
key_enter: clickItem
|
||||
});
|
||||
$document.unbind("click", click);
|
||||
};
|
||||
|
||||
that.selectFirstItem = function() {
|
||||
selectNextItem();
|
||||
};
|
||||
|
||||
that.showMenu = function() {
|
||||
|
@ -1935,13 +2040,19 @@ 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.escape", that.hideMenu);
|
||||
Ox.Event.bind("key.enter", clickItem);
|
||||
if (!self.options.parent) {
|
||||
that.gainFocus();
|
||||
}
|
||||
that.bindEvent({
|
||||
key_up: selectPreviousItem,
|
||||
key_down: selectNextItem,
|
||||
key_left: selectSupermenu,
|
||||
key_right: selectSubmenu,
|
||||
key_escape: that.hideMenu,
|
||||
key_enter: clickItem
|
||||
});
|
||||
setTimeout(function() {
|
||||
$document.bind("click", that.hideMenu);
|
||||
$document.bind("click", click);
|
||||
}, 100);
|
||||
};
|
||||
|
||||
|
@ -2025,7 +2136,7 @@ requires
|
|||
);
|
||||
|
||||
function click() {
|
||||
if (!that.hasClass("OxDisabled") && !self.options.submenu) {
|
||||
if (!that.hasClass("OxDisabled") && !self.options.items.length) {
|
||||
self.options.menu.hideMenu();
|
||||
if (self.options.checked !== null && (!self.options.group || !self.options.checked)) {
|
||||
that.options({
|
||||
|
@ -2039,7 +2150,6 @@ requires
|
|||
id: self.options.id,
|
||||
value: self.options.title // fixme: value or title?
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2050,7 +2160,10 @@ requires
|
|||
function mouseenter() {
|
||||
if (!self.options.disabled && !isSelected()) {
|
||||
$.each(self.options.menu.submenus, function(id, submenu) {
|
||||
submenu.hideMenu();
|
||||
if (!submenu.is(":hidden")) {
|
||||
submenu.hideMenu();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (self.options.menu.options("selected") > -1) {
|
||||
self.options.menu.items[self.options.menu.options("selected")].trigger("mouseleave");
|
||||
|
|
|
@ -74,18 +74,43 @@ $(function() {
|
|||
},
|
||||
],
|
||||
title: "More",
|
||||
},
|
||||
{
|
||||
id: "even_more",
|
||||
items: [
|
||||
{
|
||||
checked: true,
|
||||
group: "101112",
|
||||
id: "tenth",
|
||||
title: "Tenth"
|
||||
},
|
||||
{
|
||||
checked: false,
|
||||
group: "101112",
|
||||
id: "eleventh",
|
||||
title: "Eleventh"
|
||||
},
|
||||
{
|
||||
checked: false,
|
||||
group: "101112",
|
||||
id: "twelfth",
|
||||
title: "Twelfth"
|
||||
},
|
||||
],
|
||||
title: "Even More",
|
||||
}
|
||||
]
|
||||
});
|
||||
button.click(function() {
|
||||
$(this).blur(); // fix for firefox
|
||||
menu.toggleMenu();
|
||||
});
|
||||
Ox.Event.bind("OxClickMenu", function(event, data) {
|
||||
button.options({
|
||||
value: data.value
|
||||
button
|
||||
.click(function() {
|
||||
$(this).blur(); // fix for firefox
|
||||
menu.toggleMenu();
|
||||
})
|
||||
.bindEvent("OxClickMenu", function(event, data) {
|
||||
button.options({
|
||||
value: data.value
|
||||
});
|
||||
});
|
||||
});
|
||||
$select = $("<select>")
|
||||
.css({
|
||||
position: "absolute",
|
||||
|
|
Loading…
Reference in a new issue