wxWidgets / Phoenix

wxPython's Project Phoenix. A new implementation of wxPython, better, stronger, faster than he was before.
http://wxpython.org/
2.33k stars 516 forks source link

wx.lib.agw.thumbnailctrl should be able to preload thumbnails #1175

Open awiebe opened 5 years ago

awiebe commented 5 years ago

Operating system:all wxPython version & source: master Python version & source: python3

Description of the problem: https://github.com/wxWidgets/Phoenix/blob/fd1c26d2e14fc0cee3e03a794c49446f9f45e2af/wx/lib/agw/thumbnailctrl.py#L11 The thumbnail view (wx.lib.agw.thumbnailctrl) cannot preload images which sucks for user experience with large images, as the thumbnails are loaded only after the thumbnail grid is moved into view. It would be better if in addition to loading the currently shown area some upcoming thumbnails were loaded, and some were retained to speed up scrolling backwards.

For the purposes of this feature let a page be a float defined as page = scroll_y/viewport_height

Ideally there should be two parameters which dictates how many "pages" of thumbnails should be preloaded both before and after the current page.

Calculate the entire width of the scrollable view and divide it into N pages. If at any time part of a page is visible it should stay loaded and its preload rules should apply.

Which pages are in view should be checked every frame the scrollbar is being dragged, not only when it is release.

e.g.

Suppose we set the preload to 1 page

Suppose we set the preload to 2 pages

Example code

import os

import wx
import wx.lib.agw.thumbnailctrl as TC

class MyFrame(wx.Frame):

    def __init__(self, parent):

        wx.Frame.__init__(self, parent, -1, "ThumbnailCtrl Demo")

        panel = wx.Panel(self)

        sizer = wx.BoxSizer(wx.VERTICAL)

        thumbnail = TC.ThumbnailCtrl(panel, imagehandler=TC.NativeImageHandler)
        sizer.Add(thumbnail, 1, wx.EXPAND | wx.ALL, 10)

        thumbnail.ShowDir(os.getcwd())
        panel.SetSizer(sizer)

       panel.SetPreload(2) #Load 2 full scrolls ahead and behind including the current view (5 total)

Preload and Retain

You might also consider splitting preload and retain. But this may needlessly complicate the implementation for not much more flexibility.

awiebe commented 5 years ago

It might be as easy as changing https://github.com/wxWidgets/Phoenix/blob/fd1c26d2e14fc0cee3e03a794c49446f9f45e2af/wx/lib/agw/thumbnailctrl.py#L1852

To

(self._preload*2+1)*self._rows*(self._tHeight + self._tBorder) + \

But I don't know how that will treat the offset, to work properly that should be the size with a centre-left anchor. for that to work properly and conditional logic would probably apply when the virtual plane is at the top and bottom of the scroll view.