diff --git a/build/css/ox.ui.css b/build/css/ox.ui.css index 8e2d342f..3c27d536 100644 --- a/build/css/ox.ui.css +++ b/build/css/ox.ui.css @@ -424,6 +424,7 @@ OxSelect Layers ================================================================================ */ + .OxLayer { position: absolute; width: 100%; @@ -444,6 +445,138 @@ Layers overflow: hidden; z-index: 10; } + +/* +================================================================================ +Lists +================================================================================ +*/ + +.OxListPage { + position: absolute; +} + +.OxTextList .OxCell { + float: left; + height: 12px; + padding: 2px 4px 2px 4px; +} +.OxTextList .OxBar { + z-index: 10; + -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.75); + -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.75); +} +.OxTextList .OxBar .OxHead { + position: absolute; + left: 0; + right: 12px; + height: 16px; + overflow: hidden; + white-space: nowrap; +} +.OxTextList .OxBar .OxCell { + float: left; + padding: 2px 4px 2px 4px; + height: 12px; +} +.OxTextList .OxBar .OxCell:nthChild(1) { + margin-left: 0; +} +.OxTextList .OxBar .OxTitle { + float: left; + height: 15px; + padding: 1px 2px 0 2px; + font-weight: bold; + font-size: 10px; + text-overflow: ellipsis; + cursor: pointer; + overflow: hidden; + white-space: nowrap; +} +.OxTextList .OxBar .OxTitle:first-child { + padding-left: 4px; +} +.OxTextList .OxBar .OxOrder { + float: left; + width: 10px; + height: 13px; + padding: 3px 0 0 6px; + font-size: 7px; + display: none; +} +.OxTextList .OxBar .OxOrder.OxSelected { + cursor: pointer; + display: block; +} +.OxTextList .OxBar .OxResize { + float: left; + width: 5px; + height: 16px; +} +.OxTextList .OxBar .OxResize .OxLeft, +.OxTextList .OxBar .OxResize .OxCenter, +.OxTextList .OxBar .OxResize .OxRight { + float: left; + height: 16px; + cursor: ew-resize; +} +.OxTextList .OxBar .OxResize .OxLeft, +.OxTextList .OxBar .OxResize .OxRight { + width: 2px; +} +.OxTextList .OxBar .OxResize .OxCenter { + width: 1px; +} +.OxTextList .OxBar .OxResize .OxCenter { + float: left; + width: 1px; + height: 16px; + background: rgb(24, 24, 24); + cursor: ew-resize; +} +.OxTextList .OxBar .OxSelect { + position: absolute; + right: 0px; + width: 11px; + height: 16px; + font-size: 11px; + text-align: center; + cursor: pointer; +} + +.OxTextList .OxBody { + float: left; + position: absolute; + left: 0; + top: 16px; + right: 0; + bottom: 0; +} +.OxTextList .OxBody .OxContent { + width: 100%; +} +.OxTextList .OxBody .OxItem { + height: 16px; +} +.OxTextList .OxBody .OxItem .OxCell { + float: left; + height: 14px; + padding: 2px 4px 0 4px; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} +.OxTextList .OxBody .OxItem .OxSpace { + float: left; + width: 4px; + height: 16px; +} +.OxTextList .OxBody .OxItem .OxLine { + float: left; + width: 1px; + height: 16px; +} + /* ================================================================================ Menus diff --git a/build/css/ox.ui.modern.css b/build/css/ox.ui.modern.css index 33c8f246..b0eece15 100644 --- a/build/css/ox.ui.modern.css +++ b/build/css/ox.ui.modern.css @@ -98,6 +98,58 @@ Forms color: rgb(96, 96, 96) } +/* +================================================================================ +Lists +================================================================================ +*/ + +.OxThemeModern .OxTextList .OxItem .OxCell { + border-right: 1px solid rgb(32, 32, 32); +} +.OxThemeModern .OxTextList .OxItem:nth-child(odd) { + background: rgb(14, 14, 14); +} +.OxThemeModern .OxTextList .OxItem:nth-child(even) { + background: rgb(18, 18, 18); +} +.OxThemeModern .OxTextList .OxItem.OxSelected:nth-child(odd) { + background: rgb(30, 30, 30); +} +.OxThemeModern .OxTextList .OxItem.OxSelected:nth-child(even) { + background: rgb(34, 34, 34); +} +.OxThemeModern .OxTextList.OxFocus .OxItem.OxSelected:nth-child(odd) { + background: rgb(62, 62, 62); +} +.OxThemeModern .OxTextList.OxFocus .OxItem.OxSelected:nth-child(even) { + background: rgb(66, 66, 66); +} +.OxThemeModern .OxTextList .OxBar .OxSelected { + background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(80, 80, 80)), color-stop(1, rgb(48, 48, 48))); + color: rgb(255, 255, 255); +} +.OxThemeModern .OxTextList .OxBar .OxOrder { + color: rgb(255, 255, 255); +} +.OxThemeModern .OxTextList .OxBar .OxResize .OxCenter { + background: rgb(24, 24, 24); +} +.OxThemeModern .OxTextList .OxBody .OxItem .OxCell { + border-right: 1px solid rgb(24, 24, 24); +} +.OxThemeModern .OxTextList .OxItem.OxSelected .OxCell { + border-right: 1px solid rgb(40, 40, 40); +} +.OxThemeModern .OxTextList.OxFocus .OxItem.OxSelected .OxCell { + border-right: 1px solid rgb(72, 72, 72); + color: rgb(255, 255, 255); +} +.OxThemeModern .OxTextList .OxBody .OxItem .OxLine { + background: rgb(24, 24, 24); +} + + /* ================================================================================ Menus diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 85eb160b..8f77feaa 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -686,6 +686,7 @@ requires data: data, time: Ox.getTime() }; + //Ox.print("callback", callback, "options.callback", options.callback, "data", data) callback(data); } @@ -2382,7 +2383,243 @@ requires Ox.List = function(options, self) { var self = self || {}, - that = new Ox.Container({}, self); + that = new Ox.Container({}, self) + .defaults({ + itemHeight: 16, + itemWidth: 16, + orientation: "vertical", + request: function() {}, // {sort:, range:, callback:}, without parameter returns {items, size etc.} + rowLength: 1, + sort: [], + type: "text" + }) + .options(options || {}); + + Ox.print("self1", self) + $.extend(self, { + $items: [], + $pages: [], + page: 0, + pageLength: 100, + pages: 0, + selected: [] + }); + Ox.print("self2", self) + $.extend(self, { + pageWidth: self.options.orientation == "horizontal" ? + self.pageLength * self.options.itemWidth : 0, + pageHeight: self.options.orientation == "horizontal" ? 0 : + self.pageLength * self.options.itemHeight / self.options.rowLength + }); + + function addAllToSelection(pos) { + var arr, + len = self.$items.length; + if (!isSelected(pos)) { + if (selected.length == 0) { + addToSelection(pos); + } else { + if (Ox.min(selected) < pos) { + var arr = [pos]; + for (var i = pos - 1; i >= 0; i--) { + if (isSelected(i)) { + $.each(arr, function(i, v) { + addToSelection(v); + }); + break; + } + arr.push(i); + } + } + if (Ox.max(selected) > pos) { + var arr = [pos]; + for (var i = pos + 1; i < len; i++) { + if (isSelected(i)) { + $.each(arr, function(i, v) { + addToSelection(v); + }); + break; + } + arr.push(i); + } + } + } + } + } + + function addToSelection(pos) { + if (!isSelected(pos)) { + selected.push(pos); + if (!Ox.isUndefined(self.$items[pos])) { + self.$items[pos].addClass("OxSelected"); + } + Ox.Event.trigger("select_" + self.options.id, { + items: selected.length + }); + } + } + + function deselect(pos) { + if (isSelected(pos)) { + selected.splice(selected.indexOf(pos), 1); + if (!Ox.isUndefined(self.$items[pos])) { + self.$items[pos].removeClass("OxSelected"); + } + Ox.Event.trigger("select_" + self.options.id, { + items: selected.length + }); + } + } + + function getNext() { + var pos = -1; + if (selected.length) { + var pos = Ox.max(selected) + 1; + if (pos == self.$items.length) { + pos = -1; + } + } + return pos; + } + + function getPage() { + return self.options.orientation == "vertical" + ? Math.floor(that.scrollTop() / pageHeight) + : Math.floor(that.scrollLeft() / pageWidth); + } + + function getPrevious() { + var pos = -1; + if (selected.length) { + var pos = Ox.min(selected) - 1; + } + return pos; + } + + function invertSelection() { + $.each(self.options.items, function(i, v) { + toggleSelection(i); + }); + } + + function isSelected(pos) { + return selected.indexOf(pos) > -1; + } + + function loadPage(page, callback) { + if (page < 0 || page >= pages) { + return; + } + var offset = page * self.pageLength, + range = [offset, offset + (page < self.pages - 1 ? + self.pageLength : self.listLength % self.pageLength)]; + if (Ox.isUndefined(self.$pages[page])) { + Ox.Request.send({ + callback: function(data) { + self.$pages[page] = new Ox.ListPage(); + if (self.options.type == "text") { + self.$pages[page].css({ + top: (page * self.pageHeight) + "px" + }); + } else { + self.$pages[page].css({ + + }); + } + $.each(data, function(i, v) { + var pos = offset + i; + self.$items[pos] = new Ox.ListItem(v); + if (isSelected(pos)) { + self.$items[pos].addClass("OxSelected"); + } + self.$items[pos].appendTo(self.$pages[page]) + }); + }, + range: range, + sort: self.options.sort + }); + } + self.$pages[page].appendTo(that.$content); + } + + function loadPages(page, callback) { + var counter = 0, + fn = function() { + counter++; + counter == 2 && !Ox.isUndefined(callback) && callback(); + }; + loadPage(page, function() { + loadPage(page - 1, fn); + loadPage(page + 1, fn); + }); + } + + function select(pos) { + if (!isSelected(pos) || selected.length > 1) { + selectNone(); + addToSelection(pos); + } + } + + function selectAll() { + $.each(self.$items, function(i, v) { + addToSelection(i); + }); + } + + function selectNext() { + var pos = getNext(); + if (pos > -1) { + select(pos); + scrollTo(pos); + } + } + + function selectNone() { + $.each(self.$items, function(i, v) { + deselect(i); + }); + } + + function selectPrevious() { + var pos = getPrevious(); + if (pos > -1) { + select(pos); + scrollTo(pos); + } + } + + function selectQuery(str) { + $.each(self.$items, function(i, v) { + if (Ox.toLatin(v.title).toUpperCase().indexOf(str) == 0) { + select(i); + scrollTo(i); + return false; + } + }); + } + + function scrollTo(pos) { + + } + + function toggleSelection(pos) { + if (!isSelected(pos)) { + addToSelection(pos); + } else { + deselect(pos); + } + } + + function unloadPage(page) { + !Ox.isUndefined(self.$pages[page]) && self.$pages[page].remove(); + } + + function unloadPages(page) { + unloadPage(page); + unloadPage(page - 1); + unloadPage(page + 1) + } return that; @@ -2392,6 +2629,250 @@ requires }; + Ox.ListPage = function(options, self) { + var self = self || {}, + that = new Ox.Element({}, self) + .addClass("OxListPage"); + return that; + }; + + Ox.TextList = function(options, self) { + + var self = self || {}, + that = new Ox.Element({}, self) + .defaults({ + columns: [], + request: function() {}, // {sort, range, keys, callback} + sort: {} + }) + .options(options || {}) + .addClass("OxTextList"); + + $.extend(self, { + columnWidths: [], + itemHeight: 16, + page: 0, + pageLength: 100, + scrollLeft: 0, + selectedColumn: getColumnById(self.options.sort.key) + }); + $.extend(self, { + pageHeight: self.pageLength * self.itemHeight + }); + Ox.print("self", self); + + // Head + + that.$bar = new Ox.Bar({ + orientation: "horizontal", + size: 16 + }).appendTo(that); + that.$head = new Ox.Container() + .addClass("OxHead") + .appendTo(that.$bar); + that.$head.$content.addClass("OxTitles"); + that.$titles = []; + $.each(self.options.columns, function(i, v) { + var $order, $resize, $left, $center, $right; + self.columnWidths[i] = v.width; + that.$titles[i] = $("