Virtual Scrolling

Difference between version 53 and 55 - Previous - Next
Last Update: 2020-2-130-29 (version 2.112)

2018-5-18: Available on SourceForge: https://sourceforge.net/p/tcl-virtualscrolling/

[bll] 2020-2-15 There seems to be some confusion about the intent of this package.  It is not intended to be a replacement for tktable or treectrl or tablelist.  It is intended to be a virtual scrolling solution that could be used by one of those type of packages or for any other display of scrolling multiple rows by an application.

Features:
   * Set a number of lines as reserved.  These lines will stay at the top of the display and not scroll (setReserved).
   * Set the page overlap for the page up/down keys (setPageAdjust).
   * Row 0 is reserved as a heading line.

Since the configuration and population of each row is done within your callback procedures, you can do most anything you want to your display.

In the following image, you can see the heading line, a reserved line 
(the line in bold text, showing the song's original data), and the scrolling area.
The populate row callback changes the highlight depending on which row is selected.  Each line includes a radio button, 
frame (colored square), and labels.

[virtualscrolling-img-a]

[bll] 2014-8-23 This is a virtual scrolling solution that does not use a frame wrapper or canvas wrapper.  The scrolling frame and scrolling canvas wrapper solutions are all quite memory intensive, as many rows of widgets are generally created ahead of time.  Destroying the rows that are no longer displayed is not a solution, as destroying and creating new widgets is very slow.  My initial try with a scrolling frame solution failed with more than a couple of thousand rows (due to the large amount of memory needed for the widget display), and I had the need to handle more than 30000 rows.

The code uses two callbacks, one to configure a row with the widgets, and one to populate the data.  Each displayed row's widgets are configured with the configuration callback, and each row is populated with the populate callback.  When the region is scrolled, the populated data is changed, and the widgets are left in place.

For basic scrolling areas, the configure callback is only executed on initialization and when the window is resized. 

The 'reconfigure' and 'reconfWidget' procedures are used for complex displays (e.g. mixed headings and widgets) as in the example ('testsd3.tcl').  The 'grid forget' command is used to avoid slowness associated with destroying and creating new widgets.  This requires some extra widget management.

The code handles multiple scrolling regions in a single window.

Row 0 is left available for a heading line (which is not scrolled).

It is also possible to reserve more heading lines.

Scrolling by dragging (moveto) is sped up by using a short delay before redisplaying.

A new set of data can be displayed by simply calling the 'display' procedure again. 

<<discussion>>Discussion

It even works with a million entries (just change the number in 'test2.tcl'), which are built up within two seconds. Really good performance! [HolgerJ], 2015-12-27

[moi] 2016-10-25 Not good my man.  It sounds good but to bad I cant try it.  it says tcl/Tk 8.6 needs it. 

[bll] 2016-10-25 Actually it needs 8.5 (for {*}), so that's a mistake.

[moi] 2016-10-26 I travel today without my desktop.  On my laptop, it says invalid command ::oo::class.  I belive errors is here.  It wants verson 8.6.  Not so?

[bll] 2016-10-26 You are right.  I believe the OO package is available as a separate package for version 8.5.  You can use the prior version (http://wiki.tcl-lang.org/_/revision?N=40544&V=24), which does not require OO.  Though it will not have the fix I am applying right now.  The OO version is easier to use.

[kpv] 2016-11-02 This reminds me a bit of [Hack-O-Matic]. The original design wanted to draw 32k*8 boxes and was taking too long. I posted a redesign where I just drew as many boxes that filled the screen and had the contents change as you scroll.

[bll] 2016-11-2 Yes.  Also [Hugelist] and [Virtuallist].  But I did not find those until long after I wrote this package.

<<enddiscussion>>

<<discussion>>Change History
[bll] 2020-10-29 (2.12) Code cleanup.

[bll] 2020-9-28 (2.11) Improved mousewheel handling.

[bll] 2020-1-10 (2.10) clean up mousewheel binding; spinbox wheel handling.

[bll] 2018-3-5 (2.8) Bug: Clear the row height cache on a reconfigure.

[bll] 2017-12-13 Add a check for 'Text' class in the bound handlers.

[bll] 2017-9-27 Got rid of the popdownWindow call.

[bll] 2017-8-29 Cleaned up key binding handling. 

Added two new methods:  

setPageAdjust: pass this a negative number if you want the page up/down to display an overlap of the data.  

setReserved: Specify how many lines are reserved at the top.  These lines still need to be populated by your populate callback, but this method allows the scrolling routines to know about the reserved lines and adjust the scrolling behaviour appropriately.

[bll] 2017-6-30 Fixed to use <Configure> and <Visibility> events.  Fixed to use bindtags so that user defined bindings will not be modified.

[bll] 2016-11-11 Fixed an issue for certain display situations.

[bll] 2016-11-2 More fixes for re-calculating the row heights for certain situations.

[bll] 2016-10-26  Fixed issues calculating the row height (frames in the row do not have their full height set until fully displayed).

[bll] 2016-10-24  Various bugfixes.  Removed autoscroll.  Rewrote to be an object.
A little easier to use now, but the API can still use some work and cleanup.

[bll] 2016-5-1  Fix resize.  Added autoscroll capability.

[bll] 2016-3-3  Generate Leave and Enter events for whatever widget is under the mouse pointer.

[bll] 2016-2-26 Use max of height,reqheight on resize.

[bll] 2016-2-21 Use reqheight on a resize.

[bll] 2016-2-16 Simplified and fixed chkScroll.

[bll] 2016-1-18 Fixed a problem with propagation being turned off too early.

[bll] 2015-10-19 Added a check for window existence.

[bll] 2015-10-13 Fixes for arrow key handling in conjunction with comboboxes.

[bll] 2015-08-19 Update with fixes for row multiplier and test script for row multiplier.   Additional helper routines.

[bll] 2014-11-24 Fixes for strange windows behaviours and bug fixes in height/row comparisons.

[bll] 2014-11-21 Rewrite.  It now works with windows that are already sized and as the original: do X number of rows for the initial display.  Resizing works properly.  It is more stable now, but a little bit slower.

[bll] 2014-11-20 Updated with changes that disallow the resize function until the first display has finished.  Added mouse wheel binding routines.  Adjusted test routines to make sure windows were children of the scrolling frame.

[bll] 2014-10-4 removed update, added mapped window checks, don't scroll if maximum is not set up yet.

<<enddiscussion>>

----

See also: [scrollbar] and [Scrolling widgets without a text or canvas wrapper].

<<categories>> Widget | Tk