Recent

Author Topic: TreeView + Checkbox  (Read 11696 times)

RuudB

  • New Member
  • *
  • Posts: 37
TreeView + Checkbox
« on: December 09, 2017, 12:38:43 pm »
Hello,

I ran into a program, DirSync Pro, https://www.dirsyncpro.org/ that enables you to synchronize directories using so called jobs. These jobs are shown in a TreeView. In this case one can select which job to run or not by (de)selecting a checkbox in front of the text of the item, see attachment. I know Lazarus has this Treeview but couldn't find anything with an extra checkbox. OK, then something else has to be used.
But looking at the Project Inspector I noticed it uses a TreeView as well. And each items has a little icon in front of the text. As Lazarus can be compiled by Lazarus (AFAIK), I looked for this kind of TreeView but didn't find anything. If these icons are possible, what else is possible?

Thank you for any info!

Kind regards, Ruud Baltissen



balazsszekely

  • Guest
Re: TreeView + Checkbox
« Reply #1 on: December 09, 2017, 01:38:04 pm »
Hi RuudB,

Welcome to the forum. TTreeView is limited in many ways,  I would go with TVirtualStringTree instead. It has check support among many things, is fast, works well in every major widget set.  You can download it from the following webpage: https://github.com/blikblum/VirtualTreeView-Lazarus/releases . You have to install lclextensions package first.

PS: If you have questions regarding VST don't hesitate to ask.

regards,
GetMem

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: TreeView + Checkbox
« Reply #2 on: December 09, 2017, 02:20:31 pm »
Maybe TTreeView has builtin checkboxes somewhere, but I never was successful with this. Instead I usually add a second image list which is linked to StateImages of the treeview; this imagelist contains two icons, a checked and a non-checked icon. The "StateIndex" of the tree items is used to decide which one of the icons is selected. The state icons are displayed in addition to any other node icons.

These functions facilitate accessing the checked state:
Code: Pascal  [Select][+][-]
  1. const
  2.   ImgIndexChecked = 0;   // Image index of checked icon
  3.   ImgIndexUnchecked = 1;  // Image index of unchecked icon
  4.  
  5. procedure CheckNode(Node: TTreeNode; Checked:boolean);
  6. begin
  7.   if Assigned(Node) then
  8.     if Checked then
  9.       Node.StateIndex := ImgIndexChecked      
  10.     else
  11.       Node.StateIndex := ImgIndexUnchecked;  
  12. end;
  13.  
  14. procedure ToggleTreeViewCheckBoxes(Node: TTreeNode);
  15. begin
  16.   if Assigned(Node) then begin
  17.     if Node.StateIndex = ImgIndexUnchecked then
  18.       Node.StateIndex := ImgIndexChecked
  19.     else
  20.     if Node.StateIndex = ImgIndexChecked then
  21.       Node.StateIndex := ImgIndexUnchecked
  22.   end;
  23. end;
  24.  
  25. function NodeChecked(ANode:TTreeNode): Boolean;
  26. begin
  27.   result := (ANode.StateIndex = ImgIndexChecked);
  28. end;

Finally you must hook  into the Click event to catch the clicks onto the state icons:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.TreeView1Click(Sender: TObject);
  2. var
  3.   P: TPoint;
  4.   node: TTreeNode;
  5.   ht: THitTests;
  6. begin
  7.   GetCursorPos(P);
  8.   P := TreeView1.ScreenToClient(P);
  9.   ht := TreeView1.GetHitTestInfoAt(P.X, P.Y);
  10.   if (htOnStateIcon in ht) then begin
  11.     node := TreeView1.GetNodeAt(P.X, P.Y);
  12.     ToggleTreeViewCheckBoxes(node);
  13.     [...]
  14.  

« Last Edit: December 09, 2017, 02:31:16 pm by wp »

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: TreeView + Checkbox
« Reply #3 on: December 09, 2017, 03:15:11 pm »
This will fill the ImageList with checkboxes:
Code: Pascal  [Select][+][-]
  1. uses ImgList, LCLIntf, Themes;
  2.  
  3. procedure FillImageListWithChecks(ImageList: TCustomImageList);
  4.  
  5.   procedure DrawCheck(Canvas: TCanvas; Checked: Boolean; const Rect: TRect);
  6.   const
  7.     CCheckedButtons: array [Boolean] of TThemedButton =
  8.       (tbCheckBoxUncheckedNormal, tbCheckBoxCheckedNormal);
  9.   begin
  10.     Canvas.FillRect(Rect);
  11.     ThemeServices.DrawElement(Canvas.Handle, ThemeServices.GetElementDetails(
  12.       CCheckedButtons[Checked]), Rect);
  13.   end;
  14.  
  15. var
  16.   Checks: TBitmap;
  17.   W, H: Integer;
  18.   OneCheckRect: TRect;
  19.   Canvas: TCanvas;
  20. begin
  21.   if ImageList = nil then
  22.     Exit;
  23.   H := GetSystemMetrics(SM_CYMENUCHECK);
  24.   W := GetSystemMetrics(SM_CXMENUCHECK);
  25.   ImageList.Height := H;
  26.   ImageList.Width := W;
  27.   Checks := TBitmap.Create;
  28.   try
  29.     Checks.Height := H;
  30.     Checks.Width := 2 * W;
  31.     OneCheckRect := Rect(0, 0, W, H);
  32.     Canvas := Checks.Canvas;
  33.     DrawCheck(Canvas, False, OneCheckRect);
  34.     OffsetRect(OneCheckRect, W, 0);
  35.     DrawCheck(Canvas, True, OneCheckRect);
  36.     ImageList.AddMasked(Checks, Canvas.Brush.Color);
  37.   finally
  38.     Checks.Free;
  39.   end;
  40. end;
  41. ...
  42. FillImageListWithChecks(TreeView1.StateImages);

RuudB

  • New Member
  • *
  • Posts: 37
Re: TreeView + Checkbox
« Reply #4 on: December 09, 2017, 04:46:39 pm »
Hallo GetMem,
...  I would go with TVirtualStringTree instead. ...
I downloaded both plus the demo. Then I had to find out how to use packages and how to install them. But when compiling one of the example, it couldn't find the unit VirtualTrees. So I to pay attention to the reply of "wp". And here I got results. But read it an be surprised  :)

Anyway thank you for your reply. I will try later again to see what went wrong.

Kind regards/groetjes, Ruud Baltissen
www.baltissen.org

RuudB

  • New Member
  • *
  • Posts: 37
Re: TreeView + Checkbox
« Reply #5 on: December 09, 2017, 04:58:17 pm »
... Instead I usually add a second image list which is linked to StateImages of the treeview; this imagelist contains two icons, a checked and a non-checked icon. ...
I first tried your code but that didn't work at all. But the reason could be that hadn't loaded an ImageList yet (never heard of it). So I started looking, found it, looked for some more explanation on the Web how to use it, just double-click it, but then bumped in an article about the use of it in combination with TreeView. It was quite simple:

  TreeView1.StateImages :=ImageList1;
  TreeView1.Images :=ImageList1;
....
  NewNode := Treeview1.Items.Add (nil, 'All jobs');
  TreeView1.Items[0].Selected := True;
  NewNode.ImageIndex :=0;
  NewNode.SelectedIndex :=1;
  NewNode.StateIndex :=2;

This "All jobs" node had a V in front of it. (This V was an icon I had to make myself). But to be honest, I have not a complete idea what is going on but I will find out by playing with the numbers a bit....

Kind regards/groetjes, Ruud Baltissen
www.baltissen.org
« Last Edit: December 09, 2017, 06:24:48 pm by RuudB »

balazsszekely

  • Guest
Re: TreeView + Checkbox
« Reply #6 on: December 09, 2017, 05:09:47 pm »
@RuudB
Quote
I downloaded both plus the demo. Then I had to find out how to use packages and how to install them. But when compiling one of the example, it couldn't find the unit VirtualTrees.
Most likely you did not install the packages correctly. Extract the content of lclextensions-0.6.1.zip and virtualtreeview-5.5.3-R1.zip to two separate folder. Start Lazarus, go to Main menu-->Package-->Open Package File(.lpk). Locate lclextensions_package.lpk, press the "Compile" toolbutton then the "Use-->Install" button, choose to rebuild IDE. Do the same for package virtualtreeview_package.lpk. Now you can open/compile/run the "Advanced" project from the examples directory.


RuudB

  • New Member
  • *
  • Posts: 37
Re: TreeView + Checkbox
« Reply #7 on: December 09, 2017, 06:47:16 pm »
.... Now you can open/compile/run the "Advanced" project from the examples directory.
I did exactly as described. In the last line of the Package menu you can check what has been installed and both packages show as "installed". But yet the unit VirtualTrees is not found.

Kind regards/groetjes, Ruud Baltissen
www.baltissen.org

balazsszekely

  • Guest
Re: TreeView + Checkbox
« Reply #8 on: December 09, 2017, 06:52:44 pm »
Quote
I did exactly as described. In the last line of the Package menu you can check what has been installed and both packages show as "installed". But yet the unit VirtualTrees is not found.
Page "Virtual Controls" is visible in the Component Palette?

RuudB

  • New Member
  • *
  • Posts: 37
Re: TreeView + Checkbox
« Reply #9 on: December 09, 2017, 07:34:12 pm »
Page "Virtual Controls" is visible in the Component Palette?
No, see attached PNG.

balazsszekely

  • Guest
Re: TreeView + Checkbox
« Reply #10 on: December 09, 2017, 07:42:43 pm »
@ RuudB
Please update to Lazarus 1.8. Your version is way to old.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4467
  • I like bugs.
Re: TreeView + Checkbox
« Reply #11 on: December 09, 2017, 08:17:44 pm »
@ RuudB
Please update to Lazarus 1.8. Your version is way to old.
Huh, indeed! Lazarus 1.2.6 was released well over 3 years ago. You forgot to mention it. People assume you have the latest version unless told otherwise.
May I ask why you have such an old version?

Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: TreeView + Checkbox
« Reply #12 on: December 09, 2017, 09:45:54 pm »
Since you seem to have problems applying my code snippets above I am attaching a complete demo project showing the TTreeView with checkbox stateimages and additional node images. It compiles with even Laz 1.0 (although the two images per node are displayed differently than today).

RuudB

  • New Member
  • *
  • Posts: 37
Re: TreeView + Checkbox
« Reply #13 on: December 10, 2017, 09:58:18 am »
May I ask why you have such an old version?
For the very simple reason that I don't use Lazarus that often and it works very fine for the few programs I wrote for my self and therefore I never ever thought about checking for an update :)

RuudB

  • New Member
  • *
  • Posts: 37
Re: TreeView + Checkbox
« Reply #14 on: December 10, 2017, 10:02:16 am »
@ RuudB
Please update to Lazarus 1.8. Your version is way to old.
I tried yesterday evening and this morning. But for one or another reason 1.8.0 isn't able to compile and ends with an error that it cannot find the unit Interfaces. See more details here: http://forum.lazarus.freepascal.org/index.php/topic,39242.0.html
So for the moment it remains 1.2.6  :)

Kind regards/groetjes, Ruud Baltissen

 

TinyPortal © 2005-2018