@@ -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+
21302166void WTableView ::setRowHeaderCount (int count )
21312167{
21322168 WAbstractItemView ::setRowHeaderCount (count );
0 commit comments