Skip to content

Commit 199e684

Browse files
committed
Preload margin with length and sides instead of number of rows
1 parent f7251bd commit 199e684

File tree

2 files changed

+80
-38
lines changed

2 files changed

+80
-38
lines changed

src/Wt/WTableView.C

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ WTableView::WTableView()
5858
dropEvent_(impl_, "dropEvent"),
5959
scrolled_(impl_, "scrolled"),
6060
itemTouchSelectEvent_(impl_, "itemTouchSelectEvent"),
61-
preloadMarginRows_(-1),
6261
firstColumn_(-1),
6362
lastColumn_(-1),
6463
viewportLeft_(0),
@@ -69,6 +68,8 @@ WTableView::WTableView()
6968
scrollToHint_(ScrollHint::EnsureVisible),
7069
columnResizeConnected_(false)
7170
{
71+
preloadMargin_[0] = preloadMargin_[1] = preloadMargin_[2] = preloadMargin_[3] = WLength();
72+
7273
setSelectable(false);
7374

7475
setStyleClass("Wt-itemview Wt-tableview");
@@ -686,14 +687,15 @@ void WTableView::renderTable(const int fr, const int lr,
686687
assert(lastRow() == lr && firstRow() == fr);
687688
assert(lastColumn() == lc && firstColumn() == fc);
688689

689-
const int marginHeight = preloadMarginRows_ == -1 ?
690-
viewportHeight_ / 2 :
691-
static_cast<int>(preloadMarginRows_ * rowHeight().toPixels()) / 2;
690+
const int marginTop = static_cast<int>(std::round((preloadMargin(Side::Top).isAuto() ? viewportHeight_ : preloadMargin(Side::Top).toPixels()) / 2));
691+
const int marginBottom = static_cast<int>(std::round((preloadMargin(Side::Bottom).isAuto() ? viewportHeight_ : preloadMargin(Side::Bottom).toPixels()) / 2));
692+
const int marginLeft = static_cast<int>(std::round((preloadMargin(Side::Left).isAuto() ? viewportWidth_ : preloadMargin(Side::Left).toPixels()) / 2));
693+
const int marginRight = static_cast<int>(std::round((preloadMargin(Side::Right).isAuto() ? viewportWidth_ : preloadMargin(Side::Right).toPixels()) / 2));
692694

693-
int scrollX1 = std::max(0, viewportLeft_ - viewportWidth_ / 2);
694-
int scrollX2 = viewportLeft_ + viewportWidth_ / 2;
695-
int scrollY1 = std::max(0, viewportTop_ - marginHeight);
696-
int scrollY2 = viewportTop_ + marginHeight;
695+
int scrollX1 = std::max(0, viewportLeft_ - marginLeft);
696+
int scrollX2 = viewportLeft_ + marginRight;
697+
int scrollY1 = std::max(0, viewportTop_ - marginTop);
698+
int scrollY2 = viewportTop_ + marginBottom;
697699

698700
WStringStream s;
699701

@@ -1637,7 +1639,6 @@ void WTableView::computeRenderedArea()
16371639
{
16381640
if (ajaxMode()) {
16391641
const int borderRows = 5;
1640-
const int borderColumnPixels = 200;
16411642

16421643
int modelHeight = 0;
16431644
if (model())
@@ -1651,19 +1652,22 @@ void WTableView::computeRenderedArea()
16511652
const int height = std::min(viewportHeight_,
16521653
static_cast<int>(canvas_->height().toPixels()));
16531654

1654-
const int renderedRows = static_cast<int>(height / rowHeight().toPixels()
1655-
+ 0.5);
1655+
const int renderedRows = static_cast<int>(std::ceil(height / rowHeight().toPixels()));
16561656

1657-
renderedFirstRow_ = static_cast<int>(top / rowHeight().toPixels());
1657+
const int renderedRowsAbove = preloadMargin(Side::Top).isAuto() ? renderedRows + borderRows :
1658+
static_cast<int>(std::round(preloadMargin(Side::Top).toPixels() / rowHeight().toPixels()));
16581659

1659-
const int marginRows = preloadMarginRows_ == -1 ? renderedRows + borderRows : preloadMarginRows_;
1660+
const int renderedRowsBelow = preloadMargin(Side::Bottom).isAuto() ? renderedRows + borderRows :
1661+
static_cast<int>(std::round(preloadMargin(Side::Bottom).toPixels() / rowHeight().toPixels()));
1662+
1663+
renderedFirstRow_ = static_cast<int>(top / rowHeight().toPixels());
16601664

16611665
renderedLastRow_
1662-
= static_cast<int>(std::min(static_cast<long long>(renderedFirstRow_) + renderedRows + marginRows,
1666+
= static_cast<int>(std::min(static_cast<long long>(renderedFirstRow_) + renderedRows + renderedRowsBelow,
16631667
static_cast<long long>(modelHeight - 1)));
16641668
renderedFirstRow_
1665-
= static_cast<int>(std::max(static_cast<long long>(renderedFirstRow_) - marginRows,
1666-
0LL));
1669+
= static_cast<int>(std::max(static_cast<long long>(renderedFirstRow_) - renderedRowsAbove,
1670+
static_cast<long long>(0)));
16671671
} else {
16681672
renderedFirstRow_ = 0;
16691673
renderedLastRow_ = modelHeight - 1;
@@ -1672,17 +1676,22 @@ void WTableView::computeRenderedArea()
16721676
if (renderedFirstRow_ % 2 == 1)
16731677
--renderedFirstRow_;
16741678

1679+
const int borderColumnPixels = 200;
1680+
const int marginLeft = static_cast<int>(std::round(preloadMargin(Side::Left).isAuto() ? viewportWidth_ + borderColumnPixels : preloadMargin(Side::Left).toPixels()));
1681+
const int marginRight = static_cast<int>(std::round(preloadMargin(Side::Right).isAuto() ? viewportWidth_ + borderColumnPixels : preloadMargin(Side::Right).toPixels()));
1682+
16751683
/* column range */
16761684
int left
1677-
= std::max(0, viewportLeft_ - viewportWidth_ - borderColumnPixels);
1685+
= static_cast<int>(std::max(static_cast<long long>(0),
1686+
static_cast<long long>(viewportLeft_) - marginLeft));
16781687
int right
1679-
= std::min(std::max(static_cast<int>(canvas_->width().toPixels()),
1680-
viewportWidth_), // When a column was made wider, and the
1681-
// canvas is narrower than the viewport,
1682-
// the size of the canvas will not have
1683-
// been updated yet, so we use the viewport
1684-
// width instead.
1685-
viewportLeft_ + 2 * viewportWidth_ + borderColumnPixels);
1688+
= static_cast<int>(std::min(static_cast<long long>(std::max(static_cast<int>(canvas_->width().toPixels()),
1689+
viewportWidth_)), // When a column was made wider, and the
1690+
// canvas is narrower than the viewport,
1691+
// the size of the canvas will not have
1692+
// been updated yet, so we use the viewport
1693+
// width instead.
1694+
static_cast<long long>(viewportLeft_) + viewportWidth_ + marginRight));
16861695

16871696
int total = 0;
16881697
renderedFirstColumn_ = rowHeaderCount();
@@ -2118,15 +2127,42 @@ void WTableView::setOverflow(Overflow overflow,
21182127
contentsContainer_->setOverflow(overflow, orientation);
21192128
}
21202129

2121-
void WTableView::setPreloadMarginRows(int rows)
2130+
void WTableView::setPreloadMargin(const WLength &margin, WFlags<Side> side)
21222131
{
2123-
preloadMarginRows_ = rows;
2132+
if (side.test(Side::Top)) {
2133+
preloadMargin_[0] = margin;
2134+
}
2135+
if (side.test(Side::Right)) {
2136+
preloadMargin_[1] = margin;
2137+
}
2138+
if (side.test(Side::Bottom)) {
2139+
preloadMargin_[2] = margin;
2140+
}
2141+
if (side.test(Side::Left)) {
2142+
preloadMargin_[3] = margin;
2143+
}
21242144

21252145
computeRenderedArea();
21262146

21272147
scheduleRerender(RenderState::NeedAdjustViewPort);
21282148
}
21292149

2150+
WLength WTableView::preloadMargin(Side side) const
2151+
{
2152+
switch (side) {
2153+
case Side::Top:
2154+
return preloadMargin_[0];
2155+
case Side::Right:
2156+
return preloadMargin_[1];
2157+
case Side::Bottom:
2158+
return preloadMargin_[2];
2159+
case Side::Left:
2160+
return preloadMargin_[3];
2161+
default:
2162+
return WLength();
2163+
}
2164+
}
2165+
21302166
void WTableView::setRowHeaderCount(int count)
21312167
{
21322168
WAbstractItemView::setRowHeaderCount(count);

src/Wt/WTableView.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,24 +123,30 @@ class WT_API WTableView : public WAbstractItemView
123123
WFlags<Orientation> orientation
124124
= (Orientation::Horizontal | Orientation::Vertical));
125125

126-
/*! \brief Sets the amount of rows to preload.
126+
/*! \brief Sets preloading margin
127127
*
128-
* Configures the amount of rows before and after the currently visible
129-
* range that should be loaded. If N rows are shown, and C is the margin,
130-
* then N + 2C rows are loaded: N visible, C rows before, and C rows after.
128+
* By default the table view loads in an area equal to 3 times its height
129+
* and 3 times its width. This makes it so that the user can scroll a full
130+
* page in each direction without the delay caused when the table view
131+
* dynamically needs to load more data.
131132
*
132-
* Set to 0 if you don't want to load more rows than are currently visible.
133+
* setPreloadMargin() allows to customize this margin.
133134
*
134-
* Set to -1 if you want to keep default behaviour. This means that if N rows
135-
* are visible, then 3N rows are loaded: N visible, N rows before, and N rows after.
135+
* e.g. if the table view is H pixels high, and C is the preload margin in pixels
136+
* set on the top and bottom, then enough rows are loaded to fill the area
137+
* that is H + 2C pixels high. H pixels visible, C pixels above, and C pixels below.
138+
*
139+
* Set to 0 pixels if you don't want to load more rows or columns than are currently visible.
140+
*
141+
* Set to a default-constructed WLength (auto) if you want to keep default behaviour.
136142
*/
137-
void setPreloadMarginRows(int rows);
143+
void setPreloadMargin(const WLength &margin, WFlags<Side> side = AllSides);
138144

139-
/*! \brief Get the preload margin.
145+
/*! \brief Retrieves the preloading margin
140146
*
141-
* \sa setPreloadMarginRows()
147+
* \sa setPreloadMargin
142148
*/
143-
int preloadMarginRows() const { return preloadMarginRows_; }
149+
WLength preloadMargin(Side side) const;
144150

145151
virtual void setHidden(bool hidden,
146152
const WAnimation& animation = WAnimation()) override;
@@ -195,7 +201,7 @@ class WT_API WTableView : public WAbstractItemView
195201
Signals::connection touchMoveConnection_;
196202
Signals::connection touchEndConnection_;
197203

198-
int preloadMarginRows_;
204+
WLength preloadMargin_[4];
199205

200206
/* Ajax only: First and last columns rendered (this somewhat
201207
* redundant with the state contained in the widgets, but because

0 commit comments

Comments
 (0)