Recent

Author Topic: [Resolved] Tlistview flicker problem if icon is updated  (Read 3867 times)

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
[Resolved] Tlistview flicker problem if icon is updated
« on: November 25, 2017, 07:39:53 pm »
Hi Lazarus/LCL/FPC experts,

just for fun I have tried to make a TListView Icon spin. On my test form I have a lone TListView (ViewStyle := vsReport, RowSelect := true), and I added a bunch of images to my SmallImages list, the images [0..5] contain the pictures of my rotating symbol. To check things out I let the symbol spin using a timer:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2.    begin
  3.      if ListView1.Selected<>NIL then
  4.         ListView1.Selected.ImageIndex:=(ListView1.Selected.ImageIndex + 1) mod 5;
  5.    end;
  6.  
  7.  
The timer is set to 200ms, the principle works well, the icon of the selected row does indeed spin. But it seems like the LCL Listview redraws the whole row, not only the icon, causing the whole selected row flicker annoyingly.

Does anyone know a way to reduce the flicker, or at least modify the repaint behaviour in such a way that only the icon flickers, but not the entire row??

Thx, Armin.

(Lazarus 1.6.4 on Windows 7/Windows 10)
« Last Edit: November 27, 2017, 08:16:37 am by Nimral »
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

jamie

  • Hero Member
  • *****
  • Posts: 6133
Re: Tlistview flicker problem if icon is updated
« Reply #1 on: November 25, 2017, 09:47:02 pm »
You could experiment a little with the Region property of the Canvas.
 
ListView1.Canvas.Region := SomewhereRegion

 The Region has a ClicpRect in it that limits the areas of painting.

The idea is to set it to the area of where the Images are updating.

 When you do this, all other areas should be ignored.
 
 Also, there is a property called Clipping:Boolean;

 Give it a go. ;)


 
The only true wisdom is knowing you know nothing

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Tlistview flicker problem if icon is updated
« Reply #2 on: November 25, 2017, 09:50:37 pm »
On my test form I have a lone TListView (ViewStyle := vsReport, RowSelect := true), and I added a bunch of images to my SmallImages list, the images [0..5] contain the pictures of my rotating symbol.
...But it seems like the LCL Listview redraws the whole row, not only the icon, causing the whole selected row flicker annoyingly.
Windows 7, Lazarus 1.8 RC5. I do not see flicker with or without themes.
The code in Lazarus only changes the image:
Code: Pascal  [Select][+][-]
  1. procedure TListItem.SetImageIndex(const AValue: TImageIndex);
  2. begin
  3.   if AValue = FImageIndex then
  4.     Exit;
  5.   FImageIndex := AValue;
  6.   if WSUpdateAllowed then
  7.     TWSCustomListViewClass(FOwner.FOwner.WidgetSetClass).ItemSetImage(FOwner.FOwner, GetIndex, Self, 0, FImageIndex);
  8. end;
  9.  
  10. class procedure TWin32WSCustomListView.ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer);
  11. var
  12.   lvi: TLvItem;
  13. begin
  14.   if not WSCheckHandleAllocated(ALV, 'ItemSetImage') then
  15.     Exit;
  16.   lvi.Mask := LVIF_IMAGE;  // <- ONLY IMAGE
  17.   lvi.iItem := AIndex;
  18.   lvi.iSubItem := ASubIndex;
  19.   lvi.iImage := AImageIndex;
  20.   ListView_SetItem(ALV.Handle, lvi);
  21. end;
By the way, if there are 6 images ([0..5]), then it's better to use them all: ...) mod 6.

jamie

  • Hero Member
  • *****
  • Posts: 6133
Re: Tlistview flicker problem if icon is updated
« Reply #3 on: November 26, 2017, 02:06:18 am »
Maybe ListView1.DoubleBuffered := True;  Will help?
The only true wisdom is knowing you know nothing

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: Tlistview flicker problem if icon is updated
« Reply #4 on: November 26, 2017, 11:00:56 am »
Hi Jamie&Serge,

thank you for your quick replies. See attached video --> it DOES flicker :-). DoubleBuffer is already on, doesn't seem to change anything.

You think an upgrade to 1.8 may help, has the LCL code been worked over?

Armin.

Here is the complete source I use for testing, is a snipped from a larger project, so don't wonder about the initialization routine:

Code: Pascal  [Select][+][-]
  1. unit unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   ComCtrls, ExtCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     ImageList1: TImageList;
  19.     ListView1: TListView;
  20.     Timer1: TTimer;
  21.     procedure Button2Click(Sender: TObject);
  22.     procedure FormCreate(Sender: TObject);
  23.     procedure ListView1Click(Sender: TObject);
  24.     procedure Timer1Timer(Sender: TObject);
  25.   private
  26.     { private declarations }
  27.   public
  28.     { public declarations }
  29.   end;
  30.  
  31. var
  32.   Form1: TForm1;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TForm1 }
  39.  
  40. procedure TForm1.ListView1Click(Sender: TObject);
  41.  
  42. begin
  43. end;
  44.  
  45. procedure TForm1.Timer1Timer(Sender: TObject);
  46. begin
  47.   if ListView1.Selected<>NIL then
  48.      ListView1.Selected.ImageIndex:= (ListView1.Selected.ImageIndex + 1) mod 5;
  49. end;
  50.  
  51. procedure TForm1.Button2Click(Sender: TObject);
  52.  
  53. begin
  54.      Timer1.Enabled := not Timer1.Enabled;
  55. end;
  56.  
  57. procedure TForm1.FormCreate(Sender: TObject);
  58.  
  59. var i : integer;
  60.     ListItem: TListItem;
  61.     Col:TListColumn;
  62.  
  63. begin
  64.   With ListView1 do
  65.    begin
  66.    DoubleBuffered := true;
  67.    RowSelect := true;
  68.    if Columns.Count = 0 then
  69.       begin
  70.         Col := Columns.Add;
  71.         Col.Caption := '';
  72.         Col.AutoSize := true;
  73.         Col := Columns.Add;
  74.         Col.Caption := '1st Subitem';
  75.         Col.Width := 100;
  76.         Col := Columns.Add;
  77.         Col.Caption := '2nd SubItem';
  78.         Col.Width := 100;
  79.       end;
  80.    clear;
  81.    for i := 0 to 100 do
  82.      begin
  83.        ListItem := Items.Add;
  84.        ListItem.ImageIndex:=1;
  85.        ListItem.SubItems.Add('Item ' + IntToStr(i));
  86.        ListItem.SubItems.Add('SubItem ' + IntToStr(i));
  87.      end;
  88.    end;
  89. end;
  90.  
  91. end.
  92.  
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

balazsszekely

  • Guest
Re: Tlistview flicker problem if icon is updated
« Reply #5 on: November 26, 2017, 11:13:59 am »
@Nimral
You should also attach the small test project, apparently there is an ImageList in your project.  Also tell us when the flicker occurs.

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: Tlistview flicker problem if icon is updated
« Reply #6 on: November 26, 2017, 02:25:55 pm »
@Nimral
You should also attach the small test project, apparently there is an ImageList in your project.  Also tell us when the flicker occurs.

Hi GetMem,

--> Attachment!

Itemlist is pretty straightforward, I took an icon and made a few rotated versions of it. Not even the whole 360° yet, wanted to test first.

Armin.
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

balazsszekely

  • Guest
Re: Tlistview flicker problem if icon is updated
« Reply #7 on: November 26, 2017, 04:56:14 pm »
@Nimral

Testing environment:
1. Win7(64 bit), Lazarus Trunk, FPC 3.0.2
2. Linux Mint Cinnamon(64 bit), Lazarus Trunk, FPC Trunk
3. XP(32 bit), Lazarus 1.8RC5, FPC 3.0.4

I see no flicker whatsoever. The icons are rotating nicely.

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: Tlistview flicker problem if icon is updated
« Reply #8 on: November 26, 2017, 05:43:29 pm »
Hi GetMem,

Thanks for your feedback. Seems I need to look deeper into that issue tomorrow. As you see in my video, there definitiely is a flicker problem, but if you say, it's not standard LCL behaviour, there must be another reason, why it appears on my system.

I'll put my demo code through various demo machines tomorrow, let's see if there is some dependency on graphics hardware or driver.

Greetz,

Armin.
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

balazsszekely

  • Guest
Re: Tlistview flicker problem if icon is updated
« Reply #9 on: November 26, 2017, 08:00:53 pm »
Quote
but if you say, it's not standard LCL behaviour, there must be another reason, why it appears on my system.
All I'm saying is I cannot reproduce the issue in a newer version of Lazarus. The bug most likely was already fixed.

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: Tlistview flicker problem if icon is updated
« Reply #10 on: November 27, 2017, 08:16:10 am »
Hi guys,

I put the program through some other computers I had lying around, as well as through several virtual machines (MS Remote Desktop), and the problem does not appear on any system but my development computer. I tried both 1.6.4 and 1.8 RC4. Since my development system is a virtualized (VMWare 12) system I suspect that it is most likely a problem with the VMWare VGA driver.

This is somewhat surprising, I usually don't have any notable screen refresh problems in VMware, that's why it didn't come to my mind to suspect a problem with the virtualization.

Sorry guys for having bugged you, and thanks for your helpful hints.

Armin.
« Last Edit: November 27, 2017, 08:39:39 am by Nimral »
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

 

TinyPortal © 2005-2018