Forum > LCL

[SOLVED] Treeview flicker w. Hottrack when running inside NPP Plugin (dark mode)

(1/9) > >>

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

Go to full version