In my app I have a window with a ListBox and other elements. The height and width of the listbox can be altered by moving grabbars within the window (I use IMSplitter for these). The Listbox is on a PagePanel, so sometimes it is hidden. There is also another grabbar near the bottom of the window, whose movement does not affect the listbox at all (in terms of which rows are visible or its height/width).
I’m looking into why, when the listbox is visible, moving that bottom grabbar is very slow under macOS, and a disaster under Windows. Profiling shows that when I move this bottom grabbar, lots of PaintCellText events fire for the Listbox, even though visually the Listbox is unaltered.
If anyone has any suggestions for how to improve this, I’d appreciate it.
This is Desktop, Xojo 2022r2. I’m testing under Mojave on a 2018 Mini and running Win7 or WIn10 in VirtualBox VMs.
If you don’t find another solution, use a brute force method:
Define a private window boolean property, say mAllowListCellPaint, and set default to True
In the listbox’s CellTextPaint (and maybe other Paint events?) wrap the code with If mAllowListCellPaint … End If
In the splitter event for starting to move (or mouse down if necessary), set mAllowListCellPaint to false
In the splitter event for ending a move (or mouse up if necessary), set mAllowListCellPaint to true again
If profiling shows it also happens when not on the proper page of the PagePanel, also set to true/false when pages are changed so it is only true when on the proper page.
You’ll still get the overhead of it calling the paint events, but since they would not do any drawing it would presumably have less overhead. Or at least it seems like a relatively Q&D thing to test. I’m not familiar with IMSplitter – I use a splitter from Einhugur.
Yes, yesterday I was thinking about essentially what @Douglas_Handy suggests, and partially implemented it as a test (I did the first three steps but not the ending part) and the splitter movement becomes smoother. I’m torn between a pragmatic desire to improve the behaviour of the app, and feeling that doing something such as this, which is very hacky, is a bad road to go down.
The problem does not occur when other PagePanel pages are showing, which is a relief.
I think the reason this problem occurs is because even though that PagePanel page is shared betwen the Listbox (at the top) and a Container (bottom half), when moving the splitter the PagePanel is being resized, and that’s enough for the Framework to decide, hmmm, better fire off all those paint events just in case. What actually happens is that as the splitter moves, it’s the Container whose size is changed, not the Listbox.
I tried with a complete implementation of the flag approach, using MouseDown to set it and MouseUp/MouseExit to clear it. That worked well enough to improve the smoothness of moving the splitter, but as soon as I moved it, all decoration of all text in the listbox disappeared, and the text font shfted to I assume the default. So no text-colour, font-decoration, or choice of font. It reverted once I stopped dragging the splitter and made any change to the listbox.
I’ll give the notion of rejigging how that window is constructed, some thought.
Which MouseDown event? I meant the MouseDown only on your bottom splitter. So any resizing from other things should not disable the paint operations. I don’t know what events are available to you in IMSplitter. If necessary use the MouseDown of some parent (container, page, window, whatever) then check if that point is within the splitter bounds.
All of this is admittedly a hack, but sometimes you just have to work with what you have available for a Q&D circumvention to an issue. Essentially treating the symptom instead of the disease. It is always better to cure the disease. But if treating the symptom with a Q&D hack will at least temporarily provide a better user experience, then that has its virtues too.
The three mouse events were put in the instance of the bottom splitter; so settting/clearing the flag when that splitter is dragged. In the Paint event I was returning False if the flag wa set (splitter being dragged).
I’m now looking at modifying the layout so that moving the bottom splitter should not affect the listbox.