1

I am using wxScrolledWindow to display data(in rows and columns form). For example, I have 4 columns and around 1200 rows(all of which have the same height). Say first column represents name, 2nd column represents phone number, and so on. This works well but the problem is that since i've added all the 1200 rows into the wxScrolledWindow the program is consuming large amount of memory.

So, I want that only the rows that are visible to the user should be present at a given time inside the wxScrollWindow and when the user starts scrolling the other rows should be dynamically created. After searching for this I came to know that this is called virtual scrolling and wxWidgets offers this in wxListCtrl using the wxLC_VIRTUAL style. But the problem with this is that i cannot customize the appearance of wxListCtrl. For example, say the 3rd column in my custom scrollist contains a button with some text and the 4th column contains some wxStaticText and i want to change the height, background colour of each row meanwhile maintaining virtual scrolling.

So my questions are:

  1. Is there some documentation where i can read the theory of virtual scrolling(on which wxListCtrl's virtual scroll was based on) so that i can implement it by myself. Note that i have read the github repo of wxWidgets but from there i couldn't figure out and also i feel the the documentation there is lacking.

  2. Is there a working demo of implementing virtual scrolling in wxwidgets for a wxScrollWindow or for any other window. I mean just so that I can use it as a reference and starting point.

PS: I have searched the web for the same but couldn't find any post that shows how we can implement virtual scrolling in wxwidgets so I decided to ask It myself.

Kal
  • 475
  • 1
  • 16
  • 1
    You can implement something like this using the [wxVListBox](https://docs.wxwidgets.org/trunk/classwx_v_list_box.html) control. It may not be immediately clear how to use it from the documentation, but I wrote a demo somewhat similar to what you're asking for [here](https://forums.wxwidgets.org/viewtopic.php?p=170555#p170555), – New Pagodi Jul 03 '22 at 16:40
  • @Kai, you could also try to use wxGrid. – Igor Jul 03 '22 at 17:51
  • @NewPagodi All of the rows in my `wxScrolledWindow` have the same height. The demo whose link you gave does not draw all the rows/elements at one time right? I mean only when needed the user scrolls those new elements shoul be created. Can this be done in `wxScrolledWindow` instead of `wxVListBox` ? If yes can you please give a demo using wxSctolledWindow. – Kal Jul 04 '22 at 06:08
  • With a VListBox, only the visible rows are drawn. That's what the virtual methods like OnDrawItem do. If you really wanted to, you could do this with wxScrolledCanvas as mentioned below, but that's totally unstructured and up to you to implement everything. I don't have an example available. – New Pagodi Jul 04 '22 at 06:22
  • @NewPagodi The demo you gave do not work anymore. See [this](https://stackoverflow.com/q/72870420/19414420) for the errors. – Kal Jul 05 '22 at 13:40
  • @NewPagodi Did you see the errors that I am getting [here](https://stackoverflow.com/q/72870420/19414420) – Kal Jul 06 '22 at 08:34
  • I think the other user already answered that. You just need to add the '&' to use the public getter. – New Pagodi Jul 06 '22 at 16:43

1 Answers1

1

There is no such thing as "virtual scrolling", which is why you haven't found anything explaining how to do it. The wxLC_VIRTUAL flag reuses the old Microsoft terminology to call controls not storing their data fully "virtual", but this is only very peripherally related to scrolling.

Scrolling itself is implemented simply by drawing the "logical canvas", which may be much bigger than the "physical view" of it, which is the window, at the offset determined by the scrollbars position. So the only thing to do is to set this offset correctly, which is done by PrepareDC() function of wxScrolledCanvas or wxScrolledWindow, both of which are actually specializations of wxScrolled<> template. After passing your wxPaintDC to this function, you should simply draw on it as usual (well, maybe optimizing by not drawing the parts that are outside of the visible area) without caring about scrolling at all -- and yet it will work, all on its own. You should look at the scroll sample to see how exactly this works.

Note that wxScrolled<> assumes that all your rows have the same height. If this is not the case, you can use wxVScrolledWindow ("V" means "variable", as in rows of variable height) or the already mentioned wxVListBox, which inherits from it.

The simplest possible class allowing decent customization possibilities is wxSimpleHtmlListBox.

VZ.
  • 21,740
  • 3
  • 39
  • 42
  • Ok so if there is no virtual scrolling then what is happening when we scroll up or down in a virtual wxListCtrl? I mean how is that new elements are shown when the user scrolls. I want to know that so that I can do this with `wxScrolledWindow`. Btw all rows in my wxScrolledWindow have the same height. Can you describe that process(the theory) like when user scrolls then an scroll event is sent which draws new elements using some function etc. – Kal Jul 04 '22 at 06:12
  • @Kal, are you prepared to reinvent all this inside wxScrolled? All this is MSW/Windows internal code. You can try to look at generic version of the control and see how it is done. – Igor Jul 04 '22 at 14:08
  • I've updated the answer to explain how scrolling works. – VZ. Jul 05 '22 at 00:00
  • @VZ. Ok Is there a demo of `wxVListBox` in the sample folder that comes with installation of wxwidgets? I can only find a directory called `vscroll` which has file named `vstest.cpp` that uses `wxVScrollWindow`. So is there a demo sample that uses `wxVListBox`. – Kal Jul 05 '22 at 05:50
  • `wxHtmlListBox` is a subclass of `wxVListBox`, so you can look at its sample. But then you wrote that you're working with the uniform height rows, in which case you don't need the extra complexity of `wxVListBox` at all, so I don't really understand why do you want to look at it. – VZ. Jul 05 '22 at 11:26