improvements for resizing and scrolling lists

This commit is contained in:
rolux 2010-09-07 17:58:15 +02:00
parent 89cd41d2ac
commit fe1232618c
5 changed files with 224 additions and 162 deletions

View File

@ -166,8 +166,8 @@ Lists
*/
.OxThemeClassic .OxIconList .OxItem > .OxReflection > div {
background: -moz-linear-gradient(top, rgba(240, 240, 240, 0.5), rgba(240, 240, 240, 1));
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(240, 240, 240, 0.5)), color-stop(1, rgba(240, 240, 240, 1)));
background: -moz-linear-gradient(top, rgba(240, 240, 240, 0.75), rgba(240, 240, 240, 1));
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(240, 240, 240, 0.75)), color-stop(1, rgba(240, 240, 240, 1)));
}
.OxThemeClassic .OxIconList .OxItem.OxSelected > .OxIcon img {
border-color: rgb(128, 128, 128);

View File

@ -664,12 +664,16 @@ Lists
================================================================================
*/
.OxListPage {
position: absolute;
.OxIconList.OxBoth {
overflow-x: hidden;
}
.OxIconList .OxPage {
padding: 4px;
position: absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
}
.OxIconList .OxItem {
@ -686,6 +690,11 @@ Lists
position: relative;
}
.OxIconList .OxItem > .OxIcon,
.OxIconList .OxItem > .OxText {
left: -2px;
}
.OxIconList .OxItem > .OxIcon img {
position: absolute;
left: 0;
@ -693,6 +702,7 @@ Lists
bottom: 0;
margin: auto;
border: 2px solid rgba(0, 0, 0, 0);
cursor: pointer;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
@ -714,8 +724,8 @@ Lists
top: 0;
right: 0;
margin: auto;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
//-moz-border-radius: 4px;
//-webkit-border-radius: 4px;
-moz-transform: scaleY(-1);
-webkit-transform: scaleY(-1);
}
@ -730,7 +740,7 @@ Lists
text-align: center;
padding: 1px 2px;
border: 2px solid rgba(0, 0, 0, 0);
max-width: 120px;
max-width: 124px;
word-wrap: break-word;
cursor: pointer;
-moz-border-radius: 4px;

View File

@ -146,9 +146,19 @@ Lists
================================================================================
*/
.OxThemeModern .OxIconList .OxItem {
//background: rgb(20, 20, 20);
}
.OxThemeModern .OxIconList .OxItem img.OxLoading {
background: -moz-linear-gradient(top, rgb(32, 32, 32), rgb(0, 0, 0));
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(32, 32, 32)), color-stop(1, rgb(0, 0, 0)));
}
.OxThemeModern .OxIconList .OxItem > .OxIcon img.OxLoading {
border-color: rgb(16, 16, 16);
}
.OxThemeModern .OxIconList .OxItem > .OxReflection > div {
background: -moz-linear-gradient(top, rgba(16, 16, 16, 0.75), rgba(16, 16, 16, 1));
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(16, 16, 16, 0.5)), color-stop(1, rgba(16, 16, 16, 1)));
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(16, 16, 16, 0.75)), color-stop(1, rgba(16, 16, 16, 1)));
}
.OxThemeModern .OxIconList .OxItem.OxSelected > .OxIcon img {
border-color: rgb(128, 128, 128);

View File

@ -61,6 +61,9 @@ $(function() {
width: '32px',
height: '32px'
}))
.mousedown(function(e) {
e.preventDefault();
})
.appendTo($div),
deg = 0,
interval = setInterval(function() {
@ -125,6 +128,9 @@ $(function() {
border: 0,
cursor: 'pointer'
}))
.mousedown(function(e) {
e.preventDefault();
})
.mouseenter(function() {
$(this).animate({
width: '72px',

View File

@ -228,7 +228,7 @@ requires
callback({
config: config,
user: user
});
});
});
});
});
@ -242,7 +242,7 @@ requires
};
that.options = function() {
return Ox.getset(self.options, Array.prototype.slice.call(arguments), self.change, that);
return Ox.getset(self.options, Array.prototype.slice.call(arguments), self.change, that);
};
that.request = function(action, data, callback) {
@ -585,9 +585,9 @@ requires
keypress(event);
}
}
});
});
} else {
$document.keydown(keypress);
$document.keydown(keypress);
}
});
function keypress(event) {
@ -612,7 +612,7 @@ requires
buffer = '';
}
buffer += key == 'SPACE' ? ' ' : key;
bufferTime = time;
bufferTime = time;
}
Ox.Event.trigger('', 'key_' + key);
//return false;
@ -622,9 +622,9 @@ requires
ret = Ox.event.trigger(keyboard + Ox.toCamelCase(key) + '.' + v);
return ret;
});
*/
*/
}
})();
/*
@ -756,7 +756,7 @@ requires
title: 'Details',
click: function() {
$dialog.close(function() {
debug(request);
debug(request);
});
}
},
@ -1077,7 +1077,7 @@ requires
}
*/
});
ret = that;
ret = that;
}
return ret;
};
@ -1677,7 +1677,7 @@ requires
elementWidth = that.width(),
offset = that.offset(),
x = event.clientX,
y = event.clientY;
y = event.clientY;
$window.mousemove(function(event) {
that.css({
margin: 0
@ -1699,7 +1699,7 @@ requires
});
$window.one('mouseup', function() {
$window.unbind('mousemove');
});
});
}
function getButtonById(id) {
@ -1762,7 +1762,7 @@ requires
});
$window.one('mouseup', function() {
$window.unbind('mousemove');
});
});
}
self.onChange = function(key, value) {
@ -2084,7 +2084,7 @@ requires
function mouseenter(event) {
self.$tooltip.show(event.clientX, event.clientY);
}
}
function mouseleave(event) {
self.$tooltip.hide();
@ -4014,7 +4014,7 @@ requires
function getVal(px) {
var px = self.trackSize / self.values >= 16 ? px : px - 8,
valPerPx = (self.options.max - self.options.min) /
(self.trackSize - self.thumbSize);
(self.trackSize - self.thumbSize);
return Ox.limit(self.options.min +
Math.floor(px * valPerPx / self.options.step) * self.options.step,
self.options.min, self.options.max);
@ -4641,7 +4641,7 @@ requires
serialize function
size 'large', 'medium' or 'small'
type 'password', 'select' or 'text'
unit string, or
unit string, or
array [{ id, title, checked }] (selectable unit)
unitWidth integer (px)
value string, or
@ -4977,7 +4977,7 @@ requires
function changeKey(event, data) {
Ox.print('changeKey', data);
if (data) { // fixme: necessary?
self.key = {
self.key = {
id: data.id,
title: data.value // fixme: should be data.title
};
@ -5102,7 +5102,7 @@ requires
size: 'medium',
type: 'text',
value: '',
width: 128
width: 128
})
.options(options || {})
.addClass('OxInput Ox' + Ox.toTitleCase(self.options.size) + (
@ -5538,7 +5538,7 @@ requires
function getVal(px) {
var px = trackWidth / values >= 16 ? px : px - 8,
valPerPx = (self.options.max - self.options.min) /
(trackWidth - thumbWidth);
(trackWidth - thumbWidth);
return Ox.limit(self.options.min +
Math.floor(px * valPerPx / self.options.step) * self.options.step,
self.options.min, self.options.max);
@ -5638,11 +5638,11 @@ requires
orientation: self.options.orientation,
keys: self.options.keys,
request: self.options.request,
rowLength: 4,
// rowLength: 4,
size: 128,
type: 'icon',
type: 'icon',
}/*, self*/)
.addClass('OxIconList')
.addClass('OxIconList Ox' + Ox.toTitleCase(self.options.orientation))
.click(click)
.dblclick(dblclick)
.scroll(scroll);
@ -5652,7 +5652,7 @@ requires
}
function constructItem(data) {
var data = self.options.item(data, self.options.sort);
var data = self.options.item(data, self.options.sort, self.options.size);
return new Ox.IconItem($.extend(data, {
size: self.options.size
}));
@ -5674,7 +5674,7 @@ requires
Ox.IconItem = function(options, self) {
var self = self || {}
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
height: 0,
@ -5687,12 +5687,10 @@ requires
})
.options(options || {})
Ox.print('IconItem', options);
$.extend(self, {
height: self.options.size * 1.5,
height: self.options.size * 1.5,
url: oxui.path + '/png/ox.ui.' + Ox.theme() + '/icon.png',
width: self.options.size + 4
width: self.options.size
});
that.css({
@ -5703,10 +5701,11 @@ requires
.addClass('OxIcon')
.css({
top: self.options.size == 64 ? -70 : -120,
width: self.options.size + 'px',
width: (self.options.size + 4) + 'px',
height: self.options.size + 'px'
});
that.$iconImage = $('<img>')
.addClass('OxLoading OxTarget')
.attr({
src: self.options.url
})
@ -5714,30 +5713,25 @@ requires
width: self.options.width + 'px',
height: self.options.height + 'px'
})
.mousedown(mousedown)
.mouseenter(mouseenter)
.mouseleave(mouseleave)
/*
.load(function() {
that.$iconImage.attr({
src: self.options.url
})
Ox.print('width:', that.$iconImage[0].width);
});
*/
.load(load);
that.$textBox = $('<div>')
.addClass('OxText')
.css({
top: (self.options.size / 2) + 'px',
width: self.options.size + 'px',
width: (self.options.size + 4) + 'px',
height: (self.options.size == 64 ? 38 : 58) + 'px'
})
that.$text = $('<div>')
.addClass('OxTarget')
.html(
formatTitle(self.options.title) +
'<br/><span class="OxInfo">' + self.options.info + '</span>'
)
.mouseenter(mouseenter)
.mouseleave(mouseleave)
.mouseleave(mouseleave);
that.$reflection = $('<div>')
.addClass('OxReflection')
.css({
@ -5746,19 +5740,14 @@ requires
height: (self.options.size / 2) + 'px'
});
that.$reflectionImage = $('<img>')
.addClass('OxLoading')
.attr({
src: self.options.url
})
.css({
width: self.options.width + 'px',
height: self.options.height + 'px'
})
/*
.one('load', function() {
that.$reflectionImage.attr({
src: self.options.url
});
})*/;
});
that.$gradient = $('<div>')
.css({
//top: (-self.options.size / 2) + 'px',
@ -5797,13 +5786,21 @@ requires
}).join('<br/>');
}
function load() {
that.$iconImage.removeClass('OxLoading');
that.$reflectionImage.removeClass('OxLoading');
}
function mousedown(e) {
e.preventDefault();
}
function mouseenter() {
Ox.print('mouseenter');
that.addClass('OxHover');
}
function mouseleave() {
//that.removeClass('OxHover');
that.removeClass('OxHover');
}
return that;
@ -5822,13 +5819,13 @@ requires
orientation: 'vertical',
pageLength: 100,
request: function() {}, // {sort:, range:, callback:}, without parameter returns {items, size etc.}
rowLength: 1,
//rowLength: 1,
sort: [],
type: 'text',
unique: ''
})
.options(options || {})
.click(click)
.mousedown(mousedown)
.scroll(scroll);
$.extend(self, {
@ -5836,7 +5833,7 @@ requires
$pages: [],
clickTimeout: 0,
ids: {},
itemMargin: self.options.type == 'text' ? 0 : 8,
itemMargin: self.options.type == 'text' ? 0 : 8, // 2 x 4 px margin ... fixme: the 2x should be computed later
keyboardEvents: {
key_alt_control_a: invertSelection,
key_control_a: selectAll,
@ -5848,9 +5845,11 @@ requires
key_pageup: scrollPageUp,
key_space: preview
},
listMargin: self.options.type == 'text' ? 0 : 8, // 2 x 4 px padding
page: 0,
preview: false,
requests: [],
scrollTimeout: 0,
selected: []
});
self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'up' : 'left')] = selectPrevious;
@ -5858,15 +5857,21 @@ requires
self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'shift_up' : 'shift_left')] = addPreviousToSelection;
self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'shift_down' : 'shift_right')] = addNextToSelection;
if (self.options.orientation == 'both') {
self.keyboardEvents['key_down'] = selectBelow;
self.keyboardEvents['key_up'] = selectAbove;
self.keyboardEvents['key_shift_down'] = addBelowToSelection;
self.keyboardEvents['key_shift_up'] = addAboveToSelection;
$.extend(self.keyboardEvents, {
key_down: selectBelow,
key_up: selectAbove,
key_shift_down: addBelowToSelection,
key_shift_up: addAboveToSelection
});
self.pageLengthByRowLength = [
0, 60, 60, 60, 60, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60
];
}
updateQuery();
Ox.print('s.o', self.options)
that.addEvent(self.keyboardEvents);
$window.resize(resize);
function addAboveToSelection() {
var pos = getAbove();
@ -5964,49 +5969,6 @@ requires
});
}
function click(e) {
Ox.print('click')
var $item = findItem(e),
pos,
deselectTimeout = false;
selectTimeout = false;
that.gainFocus();
if ($item) {
if (!self.clickTimeout) {
// click
pos = $item.data('position');
if (e.metaKey) {
if (!isSelected(pos)) {
addToSelection(pos);
} else {
deselectTimeout = true;
}
} else if (e.shiftKey) {
addAllToSelection(pos);
} else if (!isSelected(pos)) {
select(pos);
} else {
selectTimeout = true;
}
self.clickTimeout = setTimeout(function() {
self.clickTimeout = 0;
if (deselectTimeout) {
deselect(pos);
} else if (selectTimeout) {
select(pos);
}
}, 250);
} else {
// dblclick
clearTimeout(self.clickTimeout);
self.clickTimeout = 0;
open();
}
} else {
selectNone();
}
}
function deselect(pos) {
if (isSelected(pos)) {
self.selected.splice(self.selected.indexOf(pos), 1);
@ -6020,11 +5982,16 @@ requires
function findItem(e) {
var $element = $(e.target),
$item = null;
while (!$element.hasClass('OxItem') && !$element.hasClass('OxPage') && !$element.is('body')) {
while (!$element.hasClass('OxTarget') && !$element.hasClass('OxPage') && !$element.is('body')) {
$element = $element.parent();
}
if ($element.hasClass('OxItem')) {
$item = $element;
if ($element.hasClass('OxTarget')) {
while (!$element.hasClass('OxItem') && !$element.hasClass('OxPage') && !$element.is('body')) {
$element = $element.parent();
}
if ($element.hasClass('OxItem')) {
$item = $element;
}
}
return $item;
}
@ -6032,8 +5999,7 @@ requires
function getAbove() {
var pos = -1;
if (self.selected.length) {
pos = self.selected[self.selected.length - 1] - getRowLength(); // fixme: need self.rowLength
Ox.print(getRowLength(), getWidth())
pos = self.selected[self.selected.length - 1] - self.rowLength
if (pos < 0) {
pos = -1;
}
@ -6044,7 +6010,7 @@ requires
function getBelow() {
var pos = -1;
if (self.selected.length) {
pos = self.selected[self.selected.length - 1] + getRowLength();
pos = self.selected[self.selected.length - 1] + self.rowLength;
if (pos >= self.$items.length) {
pos = -1;
}
@ -6071,8 +6037,8 @@ requires
function getPage() {
return self.options.orientation == 'horizontal'
? Math.floor(that.scrollLeft() / self.pageWidth)
: Math.floor(that.scrollTop() / self.pageHeight);
? Math.floor((that.scrollLeft() - self.listMargin / 2) / self.pageWidth)
: Math.floor((that.scrollTop() - self.listMargin / 2) / self.pageHeight);
}
function getPositions() {
@ -6113,18 +6079,17 @@ requires
if (self.selected.length) {
pos = (self.options.orientation == 'both' ?
self.selected[self.selected.length - 1] :
Ox.max(self.selected)) - 1;
Ox.min(self.selected)) - 1;
}
return pos;
}
function getRow(pos) {
return Math.floor(pos / getRowLength());
return Math.floor(pos / self.rowLength);
}
function getRowLength() {
// fixme: should the first margin be a separate listMargin?
return Math.floor((getWidth() - self.itemMargin) / (self.options.itemWidth + self.itemMargin));
return Math.floor((getWidth() - self.listMargin) / (self.options.itemWidth + self.itemMargin));
}
function getSelectedIds() {
@ -6155,27 +6120,28 @@ requires
}
function loadPage(page, callback) {
Ox.print('loadPage', page)
if (page < 0 || page >= self.pages) {
!Ox.isUndefined(callback) && callback();
return;
}
Ox.print('loadPage', page);
var keys = $.inArray('id', self.options.keys) > -1 ? self.options.keys :
$.merge(self.options.keys, ['id']),
offset = page * self.options.pageLength,
offset = page * self.pageLength,
range = [offset, offset + (page < self.pages - 1 ?
self.options.pageLength : self.listLength % self.options.pageLength)];
self.pageLength : self.listLength % self.pageLength)];
if (Ox.isUndefined(self.$pages[page])) {
self.requests.push(self.options.request({
callback: function(result) {
self.$pages[page] = new Ox.ListPage();
if (self.options.type == 'text') {
self.$pages[page].css({
top: (page * self.pageHeight) + 'px'
self.$pages[page] = new Ox.ListPage()
.css({
width: self.pageWidth + 'px'
});
if (self.options.orientation == 'horizontal') {
} else {
self.$pages[page].css({
top: (page * self.pageHeight + self.listMargin / 2) + 'px'
});
}
$.each(result.data.items, function(i, v) {
@ -6233,6 +6199,49 @@ requires
});
}
function mousedown(e) {
Ox.print('click')
var $item = findItem(e),
pos,
deselectTimeout = false;
selectTimeout = false;
that.gainFocus();
if ($item) {
if (!self.clickTimeout) {
// click
pos = $item.data('position');
if (e.metaKey) {
if (!isSelected(pos)) {
addToSelection(pos);
} else {
deselectTimeout = true;
}
} else if (e.shiftKey) {
addAllToSelection(pos);
} else if (!isSelected(pos)) {
select(pos);
} else {
selectTimeout = true;
}
self.clickTimeout = setTimeout(function() {
self.clickTimeout = 0;
if (deselectTimeout) {
deselect(pos);
} else if (selectTimeout) {
select(pos);
}
}, 250);
} else {
// dblclick
clearTimeout(self.clickTimeout);
self.clickTimeout = 0;
open();
}
} else {
selectNone();
}
}
function open() {
that.triggerEvent('open', {
ids: getSelectedIds()
@ -6250,33 +6259,54 @@ requires
}
}
function resize() {
if (self.options.orientation == 'both') {
var rowLength = getRowLength(),
pageLength = self.pageLengthByRowLength[rowLength];
if (pageLength != self.pageLength) {
updateQuery();
} else if (rowLength != self.rowLength) {
self.rowLength = rowLength;
self.pageWidth = (self.options.itemWidth + self.itemMargin) * self.rowLength;
$.each(self.$pages, function(i, $page) {
$page.css({
width: self.pageWidth + 'px'
});
});
}
}
}
function scroll() {
var page = self.page;
self.page = getPage();
setTimeout(function() {
if (self.page == getPage()) {
if (self.page == page - 1) {
unloadPage(self.page + 2);
loadPage(self.page - 1);
} else if (self.page == page + 1) {
unloadPage(self.page - 2);
loadPage(self.page + 1);
} else if (self.page == page - 2) {
unloadPage(self.page + 3);
unloadPage(self.page + 2);
loadPage(self.page);
loadPage(self.page - 1);
} else if (self.page == page + 2) {
unloadPage(self.page - 3);
unloadPage(self.page - 2);
loadPage(self.page);
loadPage(self.page + 1);
} else if (self.page != page) {
unloadPages(page);
loadPages(self.page);
}
self.scrollTimeout && clearTimeout(self.scrollTimeout);
self.scrollTimeout = setTimeout(function() {
self.scrollTimeout = 0;
self.page = getPage();
if (self.page != page) {
Ox.print('page', page, '-->', self.page);
}
}, 100);
if (self.page == page - 1) {
unloadPage(self.page + 2);
loadPage(self.page - 1);
} else if (self.page == page + 1) {
unloadPage(self.page - 2);
loadPage(self.page + 1);
} else if (self.page == page - 2) {
unloadPage(self.page + 3);
unloadPage(self.page + 2);
loadPage(self.page);
loadPage(self.page - 1);
} else if (self.page == page + 2) {
unloadPage(self.page - 3);
unloadPage(self.page - 2);
loadPage(self.page);
loadPage(self.page + 1);
} else if (self.page != page) {
unloadPages(page);
loadPages(self.page);
}
}, 250);
}
function scrollPageDown() {
@ -6300,7 +6330,7 @@ requires
size = getWidth();
} else {
positions[0] = (self.options.orientation == 'vertical' ? pos : getRow(pos)) * itemHeight;
positions[1] = positions[0] + itemHeight;
positions[1] = positions[0] + itemHeight + (self.options.orientation == 'vertical' ? 0 : self.itemMargin);
scroll = that.scrollTop();
size = getHeight();
if (positions[0] < scroll) {
@ -6416,7 +6446,7 @@ requires
}
Ox.print('unloadPage', page)
Ox.print('self.$pages', self.$pages)
Ox.print(!Ox.isUndefined(self.$pages[page]))
Ox.print('page not undefined', !Ox.isUndefined(self.$pages[page]))
!Ox.isUndefined(self.$pages[page]) && self.$pages[page].remove();
}
@ -6432,15 +6462,20 @@ requires
callback: function(result) {
var keys = {};
that.triggerEvent('load', result.data);
self.rowLength = getRowLength();
self.pageLength = self.options.orientation == 'both' ?
self.pageLengthByRowLength[self.rowLength] :
self.options.pageLength;
$.extend(self, {
listHeight: result.data.items * self.options.itemHeight, // fixme: should be listSize
listHeight: Math.ceil(result.data.items * (self.options.itemHeight + self.itemMargin) / self.rowLength), // fixme: should be listSize
listLength: result.data.items,
pages: Math.ceil(result.data.items / self.options.pageLength),
pageWidth: self.options.orientation == 'horizontal' ?
self.options.pageLength * self.options.itemWidth : 0,
pages: Math.ceil(result.data.items / self.pageLength),
pageWidth: self.options.orientation == 'vertical' ? 0 :
(self.options.itemWidth + self.itemMargin) * self.rowLength,
pageHeight: self.options.orientation == 'horizontal' ? 0 :
self.options.pageLength * self.options.itemHeight / self.options.rowLength
Math.ceil(self.pageLength * (self.options.itemHeight + self.itemMargin) / self.rowLength)
});
Ox.print('list self', self);
that.$content.css({
height: self.listHeight + 'px'
});
@ -6770,6 +6805,7 @@ requires
function constructItem(data) {
var $item = $('<div>')
.addClass('OxTarget')
.css({
width: getItemWidth() + 'px'
});
@ -7512,7 +7548,7 @@ requires
$target.data('position') : -1;
if (self.focused && position != self.selected) {
if (position > -1) {
clickTitle(position);
clickTitle(position);
} else {
focused = self.focused;
that.menus[self.selected].hideMenu();
@ -8059,7 +8095,7 @@ requires
that.items[selected].removeClass('OxSelected');
}
do {
selected++;
selected++;
} while (that.items[selected].options('disabled'))
selectItem(selected);
offset = that.items[selected].offset().top + itemHeight -
@ -8079,7 +8115,7 @@ requires
});
}
}
}
}
}
function selectPreviousItem() {
@ -8090,7 +8126,7 @@ requires
if (!isFirstEnabledItem()) {
that.items[selected].removeClass('OxSelected');
do {
selected--;
selected--;
} while (that.items[selected].options('disabled'))
selectItem(selected);
}
@ -8380,7 +8416,7 @@ requires
oxui.symbols[self.options.keyboard.key] ||
self.options.keyboard.key.toUpperCase()
})
);
);
function parseKeyboard(str) {
var modifiers = str.split(' '),