diff --git a/build/css/ox.ui.classic.css b/build/css/ox.ui.classic.css index 5aaf4c35..fb8b443a 100644 --- a/build/css/ox.ui.classic.css +++ b/build/css/ox.ui.classic.css @@ -4,6 +4,10 @@ body.OxThemeClassic { .OxThemeClassic div { color: rgb(16, 16, 16); } +.OxThemeClassic .OxHighlight { + background: rgb(255, 255, 0); +} + /* ================================================================================ @@ -54,6 +58,7 @@ Forms color: rgb(64, 64, 64); } .OxThemeClassic .OxButton, +.OxThemeClassic div.OxInput, .OxThemeClassic .OxRange { //background: -moz-linear-gradient(left top, left bottom, from(rgb(192, 192, 192)), to(rgb(160, 160, 160))); //background: -webkit-gradient(linear, left top, left bottom, from(rgb(192, 192, 192)), to(rgb(160, 160, 160))); @@ -85,17 +90,17 @@ Forms border-bottom: 1px solid rgb(192, 192, 192); } -.OxThemeClassic .OxInput, +.OxThemeClassic input.OxInput, .OxThemeClassic .OxTrack { background: -moz-linear-gradient(top, rgb(224, 224, 224), rgb(255, 255, 255)); background: -webkit-gradient(linear, left top, left bottom, from(rgb(224, 224, 224)), to(rgb(255, 255, 255))); } -.OxThemeClassic .OxInput:focus { +.OxThemeClassic input.OxInput:focus { border: 1px solid rgb(160, 160, 160); -moz-box-shadow: 0 0 2px rgb(128, 128, 128); - -webkit-box-shadow: 0 2 4px rgb(128, 128, 128); + -webkit-box-shadow: 0 0 2px rgb(128, 128, 128); } -.OxThemeClassic .OxInput.OxPlaceholder { +.OxThemeClassic input.OxInput.OxPlaceholder { color: rgb(160, 160, 160) } diff --git a/build/css/ox.ui.css b/build/css/ox.ui.css index 2cbb5bdf..2d15402c 100644 --- a/build/css/ox.ui.css +++ b/build/css/ox.ui.css @@ -20,6 +20,7 @@ div, input { td { padding: 0px; } + /* ================================================================================ Core @@ -194,9 +195,11 @@ input::-moz-focus-inner { border: none; } .OxButton.OxSymbol, -.OxButton.OxSymbol:active { +.OxButton.OxSymbol:active, +.OxButton.OxSymbol:focus { border: 1px solid rgba(0, 0, 0, 0); background: rgba(0, 0, 0, 0); + -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0); } /* -------------------------------------------------------------------------------- @@ -273,6 +276,31 @@ OxButtonGroup } /* -------------------------------------------------------------------------------- +OxInput +-------------------------------------------------------------------------------- +*/ +div.OxInput { + -moz-border-radius: 8px; + -webkit-border-radius: 8px; +} +div.OxInput.OxMedium { + height: 14px; +} +div.OxInput > .OxButton:first-child { + float: left; + margin-top: -1px; +} +div.OxInput > .OxButton:last-child { + float: left; + margin-left: -1px; + margin-top: -1px; +} +input.OxInput { + float: left; + margin: -1px -1px 0 -1px; +} +/* +-------------------------------------------------------------------------------- OxRange -------------------------------------------------------------------------------- */ @@ -318,7 +346,7 @@ OxSelect -------------------------------------------------------------------------------- */ .OxSelect.OxMedium { - padding: 0 8px 0 8px; + } .OxSelect > .OxButton { text-align: left; @@ -330,7 +358,7 @@ OxSelect -webkit-user-select: none; } .OxSelect.OxMedium > .OxSymbol { - margin: -16px 8px 0 8px; + margin: -16px 0 0 8px; } /* @@ -403,11 +431,14 @@ Menus padding-top: 2px; font-size: 9px; } -.OxMainMenu .OxTitle.OxSelected { +.OxMainMenu > .OxTitle.OxSelected { background: rgb(48, 48, 48); background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(80, 80, 80)), color-stop(1, rgb(48, 48, 48))); } - +.OxMainMenu > .OxExtras { + float: right; + padding: 4px 12px 0 0; +} .OxMenu { diff --git a/build/css/ox.ui.modern.css b/build/css/ox.ui.modern.css index 09854aa3..1dea9ac2 100644 --- a/build/css/ox.ui.modern.css +++ b/build/css/ox.ui.modern.css @@ -4,6 +4,10 @@ body.OxThemeModern { .OxThemeModern div { color: rgb(240, 240, 240); } +.OxThemeModern .OxHighlight { + background: rgb(255, 255, 0); + color: rgb(0, 0, 0); +} /* ================================================================================ @@ -45,6 +49,7 @@ Forms color: rgb(192, 192, 192); } .OxThemeModern .OxButton, +.OxThemeModern div.OxInput, .OxThemeModern .OxRange { background: -moz-linear-gradient(top, rgb(96, 96, 96), rgb(64, 64, 64)); background: -webkit-gradient(linear, left top, left bottom, from(rgb(96, 96, 96)), to(rgb(64, 64, 64))); diff --git a/build/js/ox.js b/build/js/ox.js index a361cb04..ed0bf3da 100644 --- a/build/js/ox.js +++ b/build/js/ox.js @@ -1360,6 +1360,14 @@ Ox.startsWith = function(str, sub) { return str.substr(0, sub.length) === sub; }; +Ox.stripTags = function(str) { + /* + >>> Ox.stripTags("foo") + foo + */ + return str.replace(/(<.*?>)/gi, ""); +}; + Ox.toCamelCase = function(str) { /* >>> Ox.toCamelCase("foo-bar-baz") diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 9f3d9fff..bc8b835b 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -454,13 +454,34 @@ requires $(function() { // fixme: how to do this better? - if ($.browser.safari) { - $document.keydown(keydown); + // in firefox on mac, keypress doesn't fire for up/down + // if the cursor is at the start/end of an input element + // on linux, it doesn't seem to fire if the input element has focus + if ($.browser.mozilla) { + $document.keypress(keypress); + $document.keydown(function(event) { + var $element = $("input:focus"); + if ($element.length) { + console.log("@", $element[0].selectionStart, $element[0].selectionEnd) + if ( + ( + keyNames[event.keyCode] == "up" && + $element[0].selectionStart + $element[0].selectionEnd == 0 + ) || ( + keyNames[event.keyCode] == "down" && + $element[0].selectionStart == $element.val().length && + $element[0].selectionEnd == $element.val().length + ) + ) { + keypress(event); + } + } + }); } else { - $document.keypress(keydown); + $document.keydown(keypress); } }); - function keydown(event) { + function keypress(event) { var key, keys = [], ret = true, @@ -484,6 +505,7 @@ requires bufferTime = time; } Ox.Event.trigger("key_" + key); + //return false; /* $.each(stack, function(i, v) { // fixme: we dont get the return value! @@ -772,33 +794,49 @@ requires // private function wrapjQuery() { - $.each(oxui.jQueryFunctions, function(i, v) { - that[v] = function() { + $.each(oxui.jQueryFunctions, function(i, fn) { + that[fn] = function() { var args = arguments, length = args.length, id, ret; - $.each(args, function(i, v) { + $.each(args, function(i, arg) { // if an ox object was passed // then pass its $element instead // so we can do oxObj.jqFn(oxObj) - if (v.ox) { - args[i] = v.$element; + if (arg.ox) { + args[i] = arg.$element; } + /* + if (arg.ox) { // fixme: or is this too much magic? + if (fn == "appendTo" && arg.$content) { + args[i] = arg.$content + } else { + args[i] = arg.$element; + } + } + */ }); + /* + if (fn == "html" && that.$content) { // fixme: or is this too much magic? + $element = that.$content; + } else { + $element = that.$element; + } + */ // why does this not work? // ret = that.$element[v].apply(this, arguments); if (length == 0) { - ret = that.$element[v](); + ret = that.$element[fn](); } else if (length == 1) { - ret = that.$element[v](args[0]); + ret = that.$element[fn](args[0]); } else if (length == 2) { - ret = that.$element[v](args[0], args[1]); + ret = that.$element[fn](args[0], args[1]); } else if (length == 3) { - ret = that.$element[v](args[0], args[1], args[2]); + ret = that.$element[fn](args[0], args[1], args[2]); } else if (length == 4) { - ret = that.$element[v](args[0], args[1], args[2], args[3]); + ret = that.$element[fn](args[0], args[1], args[2], args[3]); } - if (v == "data") { + if (fn == "data") { // Ox.print("data ret", ret, $(ret)) } // if the $element of an ox object was returned @@ -827,7 +865,7 @@ requires 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]); } @@ -897,12 +935,12 @@ requires ret = that; } return ret; - } + }; that.remove = function() { that.$element.remove(); delete elements[that.ox]; return that; - } + }; that.triggerEvent = function() { /* triggerEvent(event, fn) or triggerEvent({event0: fn0, event1: fn1, ...}) @@ -915,7 +953,7 @@ requires Ox.Event.trigger(arguments[0] + "_" + self.options.id, arguments[1] || {}); } return that; - } + }; that.unbindEvent = function() { /* unbindEvent(event, fn) or unbindEvent({event0: fn0, event1: fn1, ...}) @@ -928,7 +966,7 @@ requires Ox.Event.unbind(that.id, arguments[0], arguments[1]); } return that; - } + }; // return return that; @@ -1137,10 +1175,10 @@ requires orientation: "horizontal", size: 16 }) - .options(options || {}), + .options(options || {}) + .addClass("OxBar Ox" + Ox.toTitleCase(self.options.orientation)), dimensions = oxui.getDimensions(self.options.orientation); - that.addClass("OxBar Ox" + Ox.toTitleCase(self.options.orientation)) - .css(dimensions[0], "100%") + that.css(dimensions[0], "100%") .css(dimensions[1], self.options.size + "px"); return that; }; @@ -1192,6 +1230,8 @@ requires */ Ox.Dialog = function(options, self) { + // fixme: this was just pasted from previous version ... update + // fixme: dialog should be derived from a generic draggable var self = self || {}, options = $.extend({ title: "", @@ -1280,6 +1320,9 @@ requires callback(); }) } + that.disableButtons = function() { + // to be used on submit of form, like login + }; that.open = function() { if (!that.$layer.length) { that.$layer = new Ox.Element() @@ -1302,6 +1345,15 @@ requires ============================================================================ */ + Ox.Form = function(options, self) { + + var self = self || {}, + that = new Ox.Element("div", self) + .defaults() + .options(); + + }; + /* ---------------------------------------------------------------------------- Ox.Button @@ -1499,46 +1551,282 @@ requires */ Ox.Input = function(options, self) { + + /* options: + * autocomplete function, or array of values, or dict with array of values per label or placeholder + * clear boolean, clear button, or not + * highlight boolean, highlight value in autocomplete menu, or not + * id + * label string or array (select) -- label and placeholder are mutually exclusive + * labelWidth integer (px) + * placeholder string or array (select) -- label and placeholder are mutually exclusive + * selected integer, selected label or placeholder + * size "large", "medium" or "small" + * type "text", "password", "textarea", etc. + */ + var self = self || {}, - that = new Ox.Element(options.type=='textarea'?'textarea':'input', self) + that = new Ox.Element("div", self) .defaults({ + autocomplete: null, + clear: false, + highlight: false, + id: "", + label: "", + labelWidth: 0, placeholder: "", + selected: 0, size: "medium", type: "text" }) - .options(options || {}); - if(options.type != 'textarea') { - that.attr({type: self.options.type}) + .options(options || {}) + .addClass("OxInput Ox" + Ox.toTitleCase(self.options.size)), + autocomplete; + + if (self.options.label) { + self.options.label = Ox.makeArray(self.options.label); + self.label = self.options.label[self.options.selected]; + } else if (self.options.placeholder) { + self.options.placeholder = Ox.makeArray(self.options.placeholder); + self.placeholder = self.options.placeholder[self.options.selected]; } - that.attr({ - placeholder: self.options.placeholder + if (Ox.isArray(self.options.autocomplete)) { + autocomplete = self.options.autocomplete; + self.options.autocomplete = {}; + self.options.autocomplete[self.placeholder] = autocomplete; + } + + if (self.options.label) { + that.$label = "foo"; + } else if (self.options.placeholder.length > 1) { + that.$select = new Ox.Button({ + style: "symbol", + type: "image", + value: "select" + }) + .click(select) + .appendTo(that); + self.placeholderId = self.options.id + "_placeholder"; + self.placeholderMenu = new Ox.Menu({ + element: that, + id: self.placeholderId, + items: $.map(self.options.placeholder, function(title, position) { + return { + checked: position == self.options.selected, + id: title.toLowerCase(), + group: self.placeholderId, // fixme: same id, works here, but should be different + title: title + }; + }), + offset: { + left: 4, + top: 0 + } + }); + that.bindEvent("change_" + self.placeholderId, changePlaceholder); + } + + that.$input = new Ox.Element( + self.options.type == "textarea" ? "textarea" : "input", self + ) + .attr({ + placeholder: self.placeholder, + type: self.options.type == "textarea" ? null : self.options.type }) - .addClass("OxInput Ox" + - Ox.toTitleCase(self.options.size) + " OxPlaceholder") - //.change(change) + .addClass( + "OxInput Ox" + Ox.toTitleCase(self.options.size) + + " OxPlaceholder" + ) .focus(focus) - .blur(blur); - /* doesn't work yet + .blur(blur) + .change(change) + .appendTo(that); + + if (self.options.clear) { + that.$clear = new Ox.Button({ + style: "symbol", + type: "image", + value: "clear" + }) + .click(clear) + .appendTo(that); + } + + if (options.autocomplete) { + that.$input.attr({ + autocomplete: "off" + }); + self.autocompleteId = self.options.id + "_menu"; // fixme: we do this in other places ... are we doing it the same way? var name? + self.autocompleteMenu = new Ox.Menu({ + element: that, + id: self.autocompleteId, + offset: { + left: 4, + top: 0 + }, + size: self.options.size + }); + that.bindEvent("click_" + self.autocompleteId, onClick); + } + + that.bindEvent({ + key_enter: submit, + key_escape: cancel + }); + + function autocomplete(value, callback) { + value = value.toLowerCase(); + var items = []; + if (value === "") { + // items = self.options.autocomplete[self.placeholder]; + } else { + $.each(self.options.autocomplete[self.placeholder], function(i, item) { + if (item.toLowerCase().indexOf(value) > -1) { + if (self.options.highlight) { + item = item.replace( + new RegExp("(" + value + ")", "ig"), + "$1" + ); + } + items.push(item); + } + }); + } + callback(items); + } + + function call() { + var value = that.$input.val(); + if (self.options.autocomplete) { + Ox.isFunction(self.options.autocomplete) ? + self.options.autocomplete(value, callback) : + autocomplete(value, callback); + } + } + + function callback(items) { + var selected = items.length == 1 ? 0 : -1; + if (items.length) { + items = $.map(items, function(title, position) { + if (that.$input.val().toLowerCase() == Ox.stripTags(title.toLowerCase())) { + selected = position; + } + return { + id: title.toLowerCase(), // fixme: need function to do lowercase, underscores etc? + title: title + }; + }); + self.placeholderMenu.hideMenu(); + self.autocompleteMenu.options({ + items: items, + selected: selected + }).showMenu(); + } else { + self.autocompleteMenu.hideMenu(); + } + } + + function cancel() { + that.$input.blur(); + } + + function clear() { + that.$input.val("").focus(); + //call(); + } + function change() { - Ox.print("change", that.val(), that.hasClass("OxPlaceholder")) - if ((that.val() !== "") != that.hasClass("OxPlaceholder")) { - that.toggleClass("OxPlaceholder"); - } - } - */ - function focus() { - Ox.print("focus", that.val(), that.attr("class")) - if (that.hasClass("OxPlaceholder")) { - that.val("").removeClass("OxPlaceholder"); + + } + + function changePlaceholder(event, data) { + Ox.print("cP", event, data); + self.placeholder = data.value; // fixme: could be "title" as well + if (that.$input.is(".OxPlaceholder")) { + that.$input.val(self.placeholder); + //that.$input.focus(); + } else { + that.$input.focus(); + call(); } } + function blur() { - Ox.print("blur", that.val(), that.attr("class")) - if (that.val() === "") { - that.addClass("OxPlaceholder").val(that.attr("placeholder")); + that.loseFocus(); + if (that.$input.val() === "") { + that.$input.addClass("OxPlaceholder").val(that.$input.attr("placeholder")); + } + if (self.options.autocomplete) { + $document.unbind("keydown", keypress); + $document.unbind("keypress", keypress); } } + + function focus() { + that.gainFocus(); + if (that.$input.is(".OxPlaceholder")) { + that.$input.val("").removeClass("OxPlaceholder"); + } + if (self.options.autocomplete) { + // fixme: different in webkit and firefox (?), see keyboard handler, need generic function + $document.bind("keydown", keypress); + $document.bind("keypress", keypress); + Ox.isFunction(self.options.autocomplete) ? + self.options.autocomplete(that.$input.val(), callback) : + autocomplete(that.$input.val(), callback); + } + } + + function keypress(event) { + if (event.keyCode != 13) { + setTimeout(function() { + var value = that.$input.val(); + if (value != self.value) { + self.value = value; + call(); + } + }, 25); + } + } + + function onClick(event, data) { + Ox.print("onClick", data) + that.$input.focus().val(Ox.stripTags(data.title)); + self.autocompleteMenu.hideMenu(); + submit(); + } + + function select() { + self.placeholderMenu.showMenu(); + } + + function selection() { + // fixme: not used! + var start, end; + if (arguments.length == 0) { + return [self.element.selectionStart, self.element.selectionEnd]; + } else { + start = arguments[0]; + end = arguments[1] || start; + self.element.setSelectionRange(start, end); + } + } + + function submit() { + that.$input.trigger("blur"); + that.triggerEvent("submit", that.$input.val()); + } + + that.width = function(value) { + that.$element.width(value); + that.$input.width(value - 2 - self.options.labelWidth - + (self.options.placeholder.length > 1) * 26 - + self.options.clear * 15); + return that; + } + return that; + }; /* @@ -1770,7 +2058,7 @@ requires Ox.Select = function(options, self) { var self = self || {}, - that = new Ox.Element("div", self) + that = new Ox.Element("div", self) // fixme: do we use "div", or {}, or "", by default? .defaults({ id: "", items: [], @@ -1841,7 +2129,7 @@ requires that.width = function(val) { // fixme: silly hack, and won't work for css() - that.$element.width(val); + that.$element.width(val + 16); that.$button.width(val); that.$symbol.width(val); return that; @@ -1878,14 +2166,21 @@ requires Ox.MainMenu = function(options, self) { + /* options: + * extras + * menus + * size + */ + var self = self || {}, that = new Ox.Bar({}, self) .defaults({ + extras: [], menus: [], size: "medium" }) .options(options || {}) - .addClass("OxMainMenu Ox" + Ox.toTitleCase(self.options.size)) // fixme: bar should accept small/medium/large + .addClass("OxMainMenu Ox" + Ox.toTitleCase(self.options.size)) // fixme: bar should accept small/medium/large ... like toolbar .click(click) .mousemove(mousemove); @@ -1895,8 +2190,7 @@ requires that.titles = []; that.layer = $("
").addClass("OxLayer"); - $.each(options.menus, function(position, menu) { - var event = + $.each(self.options.menus, function(position, menu) { that.titles[position] = $("
") .addClass("OxTitle") .html(menu.title) @@ -1910,6 +2204,15 @@ requires that.bindEvent("hide_" + that.menus[position].options("id"), onHideMenu); }); + if (self.options.extras.length) { + that.extras = $("
") + .addClass("OxExtras") + .appendTo(that.$element); + $.each(self.options.extras, function(position, extra) { + extra.appendTo(that.extras); + }); + } + function click(event) { var $target = $(event.target), position = typeof $target.data("position") != "undefined" ? @@ -1963,14 +2266,22 @@ requires }; - that.addMenuAfter = function() { + that.addMenuAfter = function(id) { }; - that.addMenuBefore = function() { + that.addMenuBefore = function(id) { }; + that.disableItem = function(id) { + + }; + + that.enableItem = function(id) { + + }; + that.removeMenu = function() { }; @@ -2019,7 +2330,10 @@ requires events: change_groupId {id, value} checked item of a group has changed click_itemId item not belonging to a group was clicked + click_menuId {id, value} item not belonging to a group was clicked + deselect_menuId {id, value} item was deselected not needed, not implemented hide_menuId menu was hidden + select_menuId {id, value} item was selected not needed, not implemented */ @@ -2049,7 +2363,7 @@ requires .mouseleave(mouseleave) .mousemove(mousemove), itemHeight = self.options.size == "small" ? 12 : (self.options.size == "medium" ? 16 : 20), - menuHeight, + // menuHeight, scrollSpeed = 1, $item; // fixme: used? // fixme: attach all private vars to self? @@ -2069,34 +2383,7 @@ requires that.$content = $("") .addClass("OxContent") .appendTo(that.$container); - $.each(self.options.items, function(i, item) { - var position; - if (item.id) { - that.items.push(new Ox.MenuItem($.extend(item, { - menu: that, - position: position = that.items.length - })).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], - id: Ox.toCamelCase(self.options.id + "/" + item.id), - items: item.items, - mainmenu: self.options.mainmenu, - offset: { - left: 0, - top: -4 - }, - parent: that, - side: "right", - size: self.options.size, - }); - } - } else { - that.$content.append(constructSpace()); - that.$content.append(constructLine()); - that.$content.append(constructSpace()); - } - }); + constructItems(self.options.items); that.$scrollbars.down = constructScrollbar("down") .appendTo(that.$element); that.$bottom = $("
") @@ -2138,6 +2425,10 @@ requires value: item.options("title")[0] // fixme: value or title? }); } else { + Ox.Event.trigger("click_" + self.options.id, { + id: item.options("id"), + title: item.options("title")[0] + }); Ox.Event.trigger("click_" + item.options("id")); } if (item.options("title").length == 2) { @@ -2156,6 +2447,45 @@ requires } } + function constructItems(items) { + that.items = []; + that.$content.empty(); + scrollMenuUp(); + $.each(items, function(i, item) { + var position; + if (item.id) { + that.items.push(new Ox.MenuItem($.extend(item, { + menu: that, + position: position = that.items.length + })).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], + id: Ox.toCamelCase(self.options.id + "/" + item.id), + items: item.items, + mainmenu: self.options.mainmenu, + offset: { + left: 0, + top: -4 + }, + parent: that, + side: "right", + size: self.options.size, + }); + } + } else { + that.$content.append(constructSpace()); + that.$content.append(constructLine()); + that.$content.append(constructSpace()); + } + }); + if (!that.is(":hidden")) { + Ox.print("hide&show") + that.hideMenu(); + that.showMenu(); + } + } + function constructLine() { return $("
").append( $("
", { @@ -2304,9 +2634,9 @@ requires function selectItem(position) { var item; - Ox.print("selectItem", position) if (self.options.selected > -1) { - that.items[self.options.selected].removeClass("OxSelected"); + item = that.items[self.options.selected] + item.removeClass("OxSelected"); } if (position > -1) { item = that.items[position]; @@ -2316,13 +2646,10 @@ requires return false; } }); - Ox.print("length", item.options("items").length) 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 - }); + self.options.selected = position; } function selectNextItem() { @@ -2412,7 +2739,11 @@ requires } self.onChange = function(key, value) { - + if (key == "items") { + constructItems(value); + } else if (key == "selected") { + selectItem(value); + } } that.addItemAfter = function(item) { @@ -2454,6 +2785,9 @@ requires }); selectItem(-1); scrollMenuUp(); + that.$scrollbars.up.is(":visible") && that.$scrollbars.up.hide(); + that.$scrollbars.down.is(":visible") && that.$scrollbars.down.hide(); + //that.$scrollbars.down.hide(); if (self.options.parent) { self.options.element.removeClass("OxSelected"); } @@ -2483,37 +2817,40 @@ requires }; that.showMenu = function() { - Ox.print("showMenu") + Ox.print("showMenu"); if (!self.options.parent && !that.$layer.parent().length) { that.$layer.appendTo($body); } that.parent().length || that.appendTo($body); + that.css({ + left: "-1000px", + top: "-1000px", + }).show(); var offset = self.options.element.offset(), width = self.options.element.outerWidth(), height = self.options.element.outerHeight(), left = offset.left + self.options.offset.left + (self.options.side == "bottom" ? 0 : width), top = offset.top + self.options.offset.top + (self.options.side == "bottom" ? height : 0), - maxHeight = Math.floor($window.height() - top - 16); - menuHeight = menuHeight || that.outerHeight(); - Ox.print("menuHeight", menuHeight, "maxHeight", maxHeight); + menuHeight = that.$content.outerHeight(); // fixme: why is outerHeight 0 when hidden? + menuMaxHeight = Math.floor($window.height() - top - 16), + Ox.print("menuHeight", menuHeight, "menuMaxHeight", menuMaxHeight, that.items.length); if (self.options.parent) { - if (menuHeight > maxHeight) { - top = Ox.limit(top - menuHeight + maxHeight, self.options.parent.offset().top, top); - maxHeight = Math.floor($window.height() - top - 16); + if (menuHeight > menuMaxHeight) { + top = Ox.limit(top - menuHeight + menuMaxHeight, self.options.parent.offset().top, top); + menuMaxHeight = Math.floor($window.height() - top - 16); } } that.css({ left: left + "px", top: top + "px" - }).show(); - if (menuHeight > maxHeight) { - Ox.print(maxHeight - itemHeight); - that.$container.height(maxHeight - itemHeight - 8); // margin + }); + if (menuHeight > menuMaxHeight) { + that.$container.height(menuMaxHeight - itemHeight - 8); // margin that.$scrollbars.down.show(); + } else { + that.$container.height(menuHeight); } - if (!self.options.parent) { - that.gainFocus(); - } + !self.options.parent && that.gainFocus(); that.bindEvent({ key_up: selectPreviousItem, key_down: selectNextItem, @@ -2606,7 +2943,7 @@ requires ); function parseKeyboard(str) { - var modifiers = str.split(' '), + var modifiers = str.split(" "), key = modifiers.pop(); return { modifiers: modifiers, @@ -2634,9 +2971,15 @@ requires that.$status.html(value ? oxui.symbols.check : "") } else if (key == "disabled") { that.toggleClass("disabled"); // fixme: this will only work if onChange is only invoked on actual change + } else if (key == "title") { + } } + that.toggle = function() { + // toggle id and title + }; + that.toggleChecked = function() { }; @@ -2649,7 +2992,7 @@ requires that.options({ title: that.$title.html() == self.options.title[0] ? self.options.title[1] : self.options.title[0] - }) + }); }; return that; @@ -2817,6 +3160,10 @@ requires return that; }; + Ox.TabPanel = function(options, self) { + + }; + })(); /* diff --git a/build/png/ox.ui.classic/buttonClear.png b/build/png/ox.ui.classic/buttonClear.png new file mode 100644 index 00000000..620e25bd Binary files /dev/null and b/build/png/ox.ui.classic/buttonClear.png differ diff --git a/build/png/ox.ui.classic/buttonSelect.png b/build/png/ox.ui.classic/buttonSelect.png new file mode 100644 index 00000000..28ef8b22 Binary files /dev/null and b/build/png/ox.ui.classic/buttonSelect.png differ diff --git a/build/png/ox.ui.modern/buttonClear.png b/build/png/ox.ui.modern/buttonClear.png new file mode 100644 index 00000000..4a6a7c14 Binary files /dev/null and b/build/png/ox.ui.modern/buttonClear.png differ diff --git a/build/png/ox.ui.modern/buttonSelect.png b/build/png/ox.ui.modern/buttonSelect.png new file mode 100644 index 00000000..6b5b17cb Binary files /dev/null and b/build/png/ox.ui.modern/buttonSelect.png differ diff --git a/demos/test/index.html b/demos/test/index.html index fbbfd832..481aa51d 100644 --- a/demos/test/index.html +++ b/demos/test/index.html @@ -60,6 +60,52 @@ })*/; var mainMenu = new Ox.MainMenu({ + extras: [ + new Ox.Input({ + autocomplete: { + "Find: Title": [ + "A bout de souffle", + "Casino", + "Diaries, Notes and Sketches", + "L'age d'or", + "Far From Heaven", + "In girum imus nocte et consumimur igni", + "It Felt Like a Kiss", + "Mulholland Dr.", + "Querelle", + "Vertigo" + ], + "Find: Director": [ + "Luis Buñuel", + "Adam Curtis", + "Guy Debord", + "Rainer Werner Fassbinder", + "Jean-Luc Godard", + "Todd Haynes", + "Alfred Hitchcock", + "David Lynch", + "Jonas Mekas", + "Martin Scorsese" + ], + "Find: Country": [ + "Austria", + "Canada", + "France", + "Germany", + "Italy", + "Japan", + "Spain", + "Swizerland", + "UK", + "USA" + ] + }, + clear: true, + highlight: false, + id: "find", + placeholder: ["Find: Title", "Find: Director", "Find: Country"], + }).width(256) + ], menus: [ { id: "oxjs", @@ -290,6 +336,12 @@ type: "text", value: "Foo" }).addClass("margin").appendTo(mainPanel); + Ox.Button({ + selectable: true, + size: size, + type: "text", + value: "Bar" + }).addClass("margin").appendTo(mainPanel); Ox.Select({ id: "select1", items: [ @@ -326,6 +378,75 @@ } ] }).addClass("margin").width(96).appendTo(mainPanel); + Ox.Button({ + selectable: true, + size: size, + type: "text", + value: "Foo" + }).addClass("margin").appendTo(mainPanel); + Ox.Button({ + selectable: true, + size: size, + type: "text", + value: "Bar" + }).addClass("margin").appendTo(mainPanel); + Ox.Input({ + autocomplete: { + City: [ + "Albuquerque", + "Austin", + "Baltimore", + "Boston", + "Chicago", + "Cleveland", + "Dallas", + "Denver", + "Detroit", + "El Paso", + "Honululu", + "Houston", + "Kansas City", + "Las Vegas", + "Los Angeles", + "Memphis", + "Miami", + "Minneapolis", + "Nashville", + "New Orleans", + "New York", + "Oklahoma City", + "Philadelphia", + "Phoenix", + "Pittsburgh", + "Portland", + "San Antonio", + "San Diego", + "San Francisco", + "St. Louis", + "St. Paul", + "Seattle", + "Washington" + ], + State: [ + "Alabama", "Alaska", "Arizona", "Arkansas", "California", + "Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida", + "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", + "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", + "Maryland", "Massachusetts", "Michigan", "Minnessota", "Mississippi", + "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", + "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", + "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", + "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", + "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", + "Wyoming" + ] + }, + clear: false, + highlight: true, + id: "citystate", + placeholder: ["City", "State"], + selected: 1 + }).addClass("margin").width(160).appendTo(mainPanel); //*/ function switchTheme() { if (Ox.theme() == "classic") { diff --git a/source/psd/buttons.psd b/source/psd/buttons.psd index c307394f..06c894ff 100644 Binary files a/source/psd/buttons.psd and b/source/psd/buttons.psd differ