@qooxdoo/framework
Version:
The JS Framework for Coders
225 lines (186 loc) • 6.53 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2008 1&1 Internet AG, Germany, http://www.1und1.de
License:
MIT: https://opensource.org/licenses/MIT
See the LICENSE file in the project's top-level directory for details.
Authors:
* Sebastian Werner (wpbasti)
************************************************************************ */
/**
* A selection manager, which handles the selection in widgets extending
* {@link qx.ui.core.scroll.AbstractScrollArea}.
*/
qx.Class.define("qx.ui.core.selection.ScrollArea", {
extend: qx.ui.core.selection.Widget,
/*
*****************************************************************************
MEMBERS
*****************************************************************************
*/
members: {
/*
---------------------------------------------------------------------------
BASIC SUPPORT
---------------------------------------------------------------------------
*/
// overridden
_isSelectable(item) {
return (
this._isItemSelectable(item) &&
item.getLayoutParent() === this._getWidget().getChildrenContainer()
);
},
/*
---------------------------------------------------------------------------
DIMENSION AND LOCATION
---------------------------------------------------------------------------
*/
// overridden
_getDimension() {
return this._getWidget().getPaneSize();
},
/*
---------------------------------------------------------------------------
SCROLL SUPPORT
---------------------------------------------------------------------------
*/
// overridden
_getScroll() {
var widget = this._getWidget();
return {
left: widget.getScrollX(),
top: widget.getScrollY()
};
},
// overridden
_scrollBy(xoff, yoff) {
var widget = this._getWidget();
widget.scrollByX(xoff);
widget.scrollByY(yoff);
},
/*
---------------------------------------------------------------------------
QUERY SUPPORT
---------------------------------------------------------------------------
*/
// overridden
_getFirstVisibleSelectable() {
var selectables = this.getSelectables();
var widget = this._getWidget();
var scrollTop = widget.getScrollY();
for (var i = 0; i < selectables.length; i++) {
var bottom = widget.getItemBottom(selectables[i]);
if (bottom > scrollTop) {
return selectables[i];
}
}
return null;
},
// overridden
_getLastVisibleSelectable() {
var selectables = this.getSelectables();
var widget = this._getWidget();
var scrollTop = widget.getScrollY();
var innerHeight = widget.getInnerSize().height;
var scrollBottom = scrollTop + innerHeight;
var last = null;
for (var i = 0; i < selectables.length; i++) {
var top = widget.getItemTop(selectables[i]);
if (top > scrollBottom) {
break;
}
var bottom = widget.getItemBottom(selectables[i]);
if (bottom > scrollTop) {
last = selectables[i];
}
}
return last;
},
// overridden
_getPage(lead, up) {
var selectables = this.getSelectables();
var length = selectables.length;
var start = selectables.indexOf(lead);
// Given lead is not a selectable?!?
if (start === -1) {
throw new Error("Invalid lead item: " + lead);
}
var widget = this._getWidget();
var scrollTop = widget.getScrollY();
var innerHeight = widget.getInnerSize().height;
var top, bottom, found;
if (up) {
var min = scrollTop;
var i = start;
// Loop required to scroll pages up dynamically
while (1) {
// Iterate through all selectables from start
for (; i >= 0; i--) {
top = widget.getItemTop(selectables[i]);
// This item is out of the visible block
if (top < min) {
// Use previous one
found = i;
break;
}
}
// Nothing found. Return first item.
if (found == null) {
var first = this._getFirstSelectable();
return first == lead ? null : first;
}
// Found item, but is identical to start or even before start item
// Update min position and try on previous page
if (found >= start) {
// Reduce min by the distance of the lead item to the visible
// bottom edge. This is needed instead of a simple subtraction
// of the inner height to keep the last lead visible on page key
// presses. This is the behavior of native toolkits as well.
min -= innerHeight + scrollTop - widget.getItemBottom(lead);
found = null;
continue;
}
// Return selectable
return selectables[found];
}
} else {
var max = innerHeight + scrollTop;
var i = start;
// Loop required to scroll pages down dynamically
while (1) {
// Iterate through all selectables from start
for (; i < length; i++) {
bottom = widget.getItemBottom(selectables[i]);
// This item is out of the visible block
if (bottom > max) {
// Use next one
found = i;
break;
}
}
// Nothing found. Return last item.
if (found == null) {
var last = this._getLastSelectable();
return last == lead ? null : last;
}
// Found item, but is identical to start or even before start item
// Update max position and try on next page
if (found <= start) {
// Extend max by the distance of the lead item to the visible
// top edge. This is needed instead of a simple addition
// of the inner height to keep the last lead visible on page key
// presses. This is the behavior of native toolkits as well.
max += widget.getItemTop(lead) - scrollTop;
found = null;
continue;
}
// Return selectable
return selectables[found];
}
}
}
}
});