use event delegation for menu

This commit is contained in:
Rolux 2010-02-07 20:31:22 +05:30
parent 4cc7bad63c
commit 47e0c28de9

View file

@ -292,12 +292,10 @@ requires
var stack = [];
return {
focus: function(id) {
/*
if (stack.length) {
Ox.Event.unbindKeyboard(stack[stack.length - 1]);
}
*/
var index = stack.indexOf(id);
if (stack.length) {
Ox.Event.unbindKeyboard(stack[stack.length - 1])
}
if (index > -1) {
stack.splice(index, 1);
}
@ -313,9 +311,7 @@ requires
stack.splice(stack.length - 2, 0, stack.pop());
}
Ox.Event.unbindKeyboard(id);
/*
Ox.Event.bindKeyboard(stack[stack.length - 1]);
*/
Ox.print("blur", stack);
}
};
@ -734,7 +730,7 @@ requires
.addClass("OxContent")
.appendTo(that);
return that;
}
};
/*
----------------------------------------------------------------------------
@ -802,6 +798,9 @@ requires
} else if (length == 4) {
ret = that.$element[v](args[0], args[1], args[2], args[3]);
}
if (v == "data") {
Ox.print("data ret", ret, $(ret))
}
// if the $element of an ox object was returned
// then return the ox object instead
// so we can do oxObj.jqFn().oxFn()
@ -813,7 +812,7 @@ requires
// shared
self.onChange = function() {
// self.onChange(option, value)
// self.onChange(key, value)
// is called when an option changes
// (to be implemented by widget)
};
@ -1180,8 +1179,8 @@ requires
Ox.Toolbar = function(options, self) {
var self = self || {},
that = new Ox.Bar({
size: oxui.getBarSize(options.size)
}, self);
size: oxui.getBarSize(options.size)
}, self);
return that;
};
@ -1755,7 +1754,7 @@ requires
if (item.checked) {
selected = i;
}
})
});
that.$button = new Ox.Button($.extend(self.options, {
id: self.options.id,
@ -1827,6 +1826,10 @@ requires
Ox.MainMenu = function(options, self) {
var self = self || {},
that = new Ox.Bar({}, self)
.options
}
Ox.Menu = function(options, self) {
@ -1850,11 +1853,16 @@ requires
.addClass(
"OxMenu Ox" + Ox.toTitleCase(self.options.side) +
" Ox" + Ox.toTitleCase(self.options.size)
),
)
.click(click)
.mouseenter(mouseenter)
.mouseleave(mouseleave)
.mousemove(mousemove),
itemHeight = self.options.size == "small" ? 12 : (self.options.size == "medium" ? 16 : 20),
menuHeight,
scrollSpeed = 1, // fixme: should this be self.scrollSpeed?
scrollSpeed = 1,
$item; // fixme: used?
// fixme: attach all private vars to self?
// construct
that.items = [];
@ -1874,12 +1882,10 @@ requires
$.each(self.options.items, function(i, item) {
var position;
if (item.id) {
$.extend(item, {
menu: that,
});
that.items.push(new Ox.MenuItem($.extend(item, {
menu: that,
position: position = that.items.length
})).appendTo(that.$content));
})).data("position", position).appendTo(that.$content)); // fixme: jquery bug when passing {position: position}? does not return the object?;
if (item.items) {
that.submenus[item.id] = new Ox.Menu({
element: that.items[position],
@ -1907,12 +1913,35 @@ requires
.appendTo(that.$element);
function click(event) {
if (!$(event.target).is(".OxCell")) {
that.hideMenu();
var item,
$target = $(event.target);
that.hideMenu();
if ($target.is(".OxCell")) {
item = that.items[$target.parent().data("position")];
if (!item.options("disabled")) {
if (that.options("parent")) {
that.options("parent").hideMenu();
}
if (!item.options("items").length) {
if (item.options("checked") !== null && (!item.options("group") || !item.options("checked"))) {
item.options({
checked: !item.options("checked")
});
Ox.Event.trigger("click." + that.id, {
id: item.options("id"),
value: item.options("title")[0] // fixme: value or title?
});
}
if (item.options("title").length == 2) {
item.toggleTitle();
}
}
}
}
}
function clickItem() {
// called on key.enter
if (self.options.selected > -1) {
that.items[self.options.selected].trigger("click");
} else {
@ -2004,6 +2033,31 @@ requires
return ret;
}
function mouseenter() {
that.gainFocus();
}
function mouseleave() {
if (self.options.selected > -1 && !that.items[self.options.selected].options("items").length) {
selectItem(-1);
}
}
function mousemove(event) {
var item,
position,
$target = $(event.target);
if ($target.is(".OxCell")) {
position = $target.parent().data("position");
item = that.items[position];
if (!item.options("disabled") && position != self.options.selected) {
selectItem(position);
}
} else {
mouseleave();
}
}
function scrollMenu(speed) {
var containerHeight = that.$container.height(),
contentHeight = that.$content.height(),
@ -2041,6 +2095,27 @@ requires
}
}
function selectItem(position) {
var item;
if (self.options.selected > -1) {
that.items[self.options.selected].removeClass("OxSelected");
}
if (position > -1) {
item = that.items[position];
$.each(that.submenus, function(id, submenu) {
if (!submenu.is(":hidden")) {
submenu.hideMenu();
return false;
}
});
item.options("items").length && that.submenus[item.options("id")].showMenu(); // fixme: do we want to switch to this style?
item.addClass("OxSelected");
}
that.options({
selected: position
});
}
function selectNextItem() {
var offset,
selected = self.options.selected;
@ -2048,12 +2123,12 @@ requires
if (selected == -1) {
scrollMenuUp();
} else {
that.items[selected].trigger("mouseleave");
that.items[selected].removeClass("OxSelected");
}
do {
selected++;
} while (that.items[selected].options("disabled"))
that.items[selected].trigger("mouseenter");
selectItem(selected);
offset = that.items[selected].offset().top + itemHeight -
that.$container.offset().top - that.$container.height();
if (offset > 0) {
@ -2079,11 +2154,11 @@ requires
selected = self.options.selected;
if (selected > - 1) {
if (!isFirstEnabledItem()) {
that.items[selected].trigger("mouseleave");
that.items[selected].removeClass("OxSelected");
do {
selected--;
} while (that.items[selected].options("disabled"))
that.items[selected].trigger("mouseenter");
selectItem(selected);
}
offset = that.items[selected].offset().top - that.$container.offset().top;
Ox.print(offset);
@ -2107,7 +2182,7 @@ requires
if (self.options.selected > -1) {
var submenu = that.submenus[that.items[self.options.selected].options("id")];
if (submenu && submenu.hasEnabledItems()) {
that.loseFocus();
//that.loseFocus();
submenu.gainFocus();
submenu.selectFirstItem();
}
@ -2117,7 +2192,7 @@ requires
function selectSupermenu() {
if (self.options.parent) {
that.items[self.options.selected].trigger("mouseleave");
that.loseFocus();
// that.loseFocus();
self.options.parent.gainFocus();
}
}
@ -2243,13 +2318,9 @@ requires
}))
.addClass("OxItem" + (self.options.disabled ? " OxDisabled" : ""))
.attr({
id: Ox.toCamelCase(self.options.menu.id + "/" + self.options.id)
id: Ox.toCamelCase(self.options.menu.options("id") + "/" + self.options.id)
})
.click(click)
.data("group", self.options.group) // fixme: why?
.mouseenter(mouseenter)
.mouseleave(mouseleave)
.mousemove(mousemove); // in case selection has goes elsewhere via keyboard
.data("group", self.options.group); // fixme: why?
// construct
that.append(
@ -2290,70 +2361,6 @@ requires
})
);
function click() {
if (!that.hasClass("OxDisabled")) {
self.options.menu.hideMenu();
if (self.options.menu.options("parent")) {
self.options.menu.options("parent").hideMenu();
}
if (!self.options.items.length) {
if (self.options.checked !== null && (!self.options.group || !self.options.checked)) {
that.options({
checked: !self.options.checked
});
Ox.Event.trigger("click." + self.options.menu.id, {
id: self.options.id,
value: self.options.title[0] // fixme: value or title?
});
}
if (self.options.title.length == 2) {
that.toggleTitle();
}
}
}
}
function isSelected() {
return self.options.position == self.options.menu.options("selected");
}
function mouseenter() {
if (!self.options.disabled && !isSelected()) {
$.each(self.options.menu.submenus, function(id, submenu) {
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");
}
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
});
}
}
function mouseleave() {
if (!self.options.disabled && !self.options.items.length) {
that.removeClass("OxSelected");
self.options.menu.options({
selected: -1
});
}
}
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();