Forum > LCL
[SOLVED] Treeview flicker w. Hottrack when running inside NPP Plugin (dark mode)
d7_2_laz:
Made good progress to bring an old 32bit DLL plugin for Notepad++ to Lazarus 64bit.
The code base for the demo i experiment with is from
"Notepad++ Plugin Template for Delphi & Lazarus"
https://bitbucket.org/rdipardo/delphiplugintemplate/src/default/
After some beginner struggle it seems to work quite fine.
Regarding the gui there are only two major things left. The one i'd like to ask here, because i think it might be LCL related too.
Treeview (will need a bit additional work on custom paint here, no problem):
In my own component (based on custom treeview) now i had to notice heavy horrible flicker on mouse move.
Tried to find the reason: it is here:
TreeviewXY.Hottrack := true.
Without Hottrack no flicker. And, no flicker in 'normal' mode (light theme) too.
What's going on?
What i do assume is that there is a concurrent painting LCL vs. NPP themeing where both are disturbing and triggering each other, which results in a heavy flicker. Pls. note that i use myself extensively custom drawing without seeing such flicker.
I could reproduce simply by placing a shelltreeview onto a plugin demo docking form.
Hotrack on: heavy flicker in dark mode
Hotrack off: no flicker at all
Unfortunately i need the Hottrack for some reasons and won't like to switch it off.
Found the guilty line here:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---//treeview.inc:procedure TCustomTreeView.UpdateHotTrack(X, Y: Integer);begin............................. Invalidate; // OOPS! This will repaint the whole control .....end;
From my own code for 'mouse hover' i was used for such case:
- repaint the line where the mouse is over
- repaint/refresh the line the mouse pointer had left
That had been ugly enough, because i had been forced to duplicate the whole treeview paint code, only because there is not measure to override/influence the color of the background erasure at the beginning (i had posted a special forum's topic on this times ago). Anyhow.
My question to the LCL experts: is there a more granular approach possible, without engaging the massive cavalry of invalidating all?
If someone is interested to try a test project: i can provide one, which would only require:
Lazarus 3.x (up) Windows 64 bit
A notepad++ 64bit installation recent version (i mainly prefer portable versions)
Select "dark mode" in the NPP options
And adapt two paths in the project settings.
Edit: i assume that the Delphi users of the demo plugin template don't have this problem, as here the treeview is OS-based, not pure VCL object, differently to Lazarus.
d7_2_laz:
I just did a little POC, and yeees
It works, but of course it covers only half of the story.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TCustomTreeView.UpdateHotTrack(X, Y: Integer);var aNode: TTreeNode; R: TRect;begin......... // Invalidate; // please no brute force here aNode := GetNodeAtY(Y); If aNode <> nil then begin R := ANode.DisplayRect(False); InvalidateRect(Handle, @R, True); end;
The previous mouse-hovered, now mouse-left node would be needed to be remembered and InvalidateRect'ed too. This memory would be needed to be resetted when another context appears.
Any ideas?
d7_2_laz:
POC, part 2 - yeees - would work perfectly i think:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---//comctrls.pp: TCustomTreeView = class(TCustomControl) FHotTrackedPrevNode: TTreeNode; //treeview.inc: constructor TCustomTreeView.Create(AnOwner: TComponent); FHotTrackedPrevNode := nil; procedure TCustomTreeView.UpdateHotTrack(X, Y: Integer); // Invalidate; // please no brute force if Assigned(FHotTrackedPrevNode) then begin if FHotTrackedPrevNode.Visible then begin R := FHotTrackedPrevNode.DisplayRect(False); InvalidateRect(Handle, @R, True); end; FHotTrackedPrevNode := nil; end; if Assigned(FNodeUnderCursor) then begin R := FNodeUnderCursor.DisplayRect(False); InvalidateRect(Handle, @R, True); FHotTrackedPrevNode := FNodeUnderCursor; end;
Would this make sense?
d7_2_laz:
For the NPP plugin the horrible flicker fully went away ..
Just retested outside the NPP plugin stuff, with a regular stand-alone exe,
and felt that even this would behave a bit more smoother now ...
Any opinions about?
AlexTP:
It is right approach. If I knew about this flicker before, I would do the same.
PS. Welcome to write plugin for _my_ editor, see signature.
Navigation
[0] Message Index
[#] Next page