From ed3f29e99f77660536365e2be3b50b1422bd2f96 Mon Sep 17 00:00:00 2001 From: Rolux Date: Fri, 5 Feb 2010 10:50:13 +0530 Subject: [PATCH] some keyboard navigation, some submenu --- build/css/ox.ui.classic.css | 6 +- build/css/ox.ui.css | 8 +- build/js/ox.ui.js | 226 +++++++++++++++++++++++++----------- demos/.DS_Store | Bin 6148 -> 6148 bytes demos/test/menu.js | 31 ++++- 5 files changed, 197 insertions(+), 74 deletions(-) diff --git a/build/css/ox.ui.classic.css b/build/css/ox.ui.classic.css index 2656d1f..f13fe13 100644 --- a/build/css/ox.ui.classic.css +++ b/build/css/ox.ui.classic.css @@ -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); } diff --git a/build/css/ox.ui.css b/build/css/ox.ui.css index cf779a2..c4fbb45 100644 --- a/build/css/ox.ui.css +++ b/build/css/ox.ui.css @@ -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; diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 2e3d8cf..154ff97 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -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 $("
", { - 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( $("", { - "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(); diff --git a/demos/.DS_Store b/demos/.DS_Store index b4ffc5244546ec1450e32823ea304eccc24772b5..1ca89b4e44d977add7c1e9244249092f3609009e 100644 GIT binary patch delta 19 acmZoMXffE}$IND?qhM@ev^j)%g9rdOtOZ#B delta 19 acmZoMXffE}$IND-qhM@exjBS+g9rdO>;+-~ diff --git a/demos/test/menu.js b/demos/test/menu.js index c9b0fca..c210e18 100644 --- a/demos/test/menu.js +++ b/demos/test/menu.js @@ -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