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