Mike Scott
Mike Scott

Reputation: 167

Populating VirtualStringTree as virtually as possible?

I'm trying to populate a VirtualStringTree. My underlying data are like this, here showing 3 of many branches, each of which has a varied number of twigs.

string 1
  chunk:string 1, fname:c:\temp\file0.txt, freq:8
  chunk:string 1, fname:c:\temp\file4.txt, freq:5
  chunk:string 1, fname:c:\temp\file2.txt, freq:6
string 2
  chunk:string 2, fname:c:\temp\file1.txt, freq:10
  chunk:string 2, fname:c:\temp\file5.txt, freq:6
  chunk:string 2, fname:c:\temp\file3.txt, freq:4
  chunk:string 2, fname:c:\temp\file4.txt, freq:3
string 3
  chunk:string 3, fname:c:\temp\file2.txt, freq:12
  chunk:string 3, fname:c:\temp\file0.txt, freq:4
  chunk:string 3, fname:c:\temp\file4.txt, freq:5

My query concerns how to ensure the tree knows how many different kinds of sub-nodes it needs. RootNodeCount is simple, but I don't know how to assign a varied "ChildNodeCount" without initialising all my data (in which case why use a VirtualStringTree).

My attempt has been to go through the entries in my data and using AddChild with either nil as its parameter or the last node as its parameter. That is working. But I think it isn't a virtual solution because every call to AddChild calls InitNode.

VirtualStringTreeBoiler.Clear;
VirtualStringTreeBoiler.BeginUpdate;
VirtualStringTreeBoiler.NodeDataSize := SizeOf(TBoilerRec);
repetition_seeker.BuildNodeIndex;
VirtualStringTreeBoiler.RootNodeCount := 0;
mum := nil;
MainNode := nil;
for i := 0 to repetition_seeker.NodeCount - 1 do
begin
  rec := repetition_seeker.NodeIndexToMainAndSub[i];
  if rec.sub_ndx<0 then
  begin
    MainNode := VirtualStringTreeBoiler.AddChild(mum);
    MainNode.index := i;
  end else begin
    SubNode := VirtualStringTreeBoiler.AddChild(MainNode);
    SubNode.Index := i;
  end;
end;
VirtualStringTreeBoiler.EndUpdate;

Is there an efficient way to inform the tree how many children a node has -- but virtually? Could I see an example?

Upvotes: 2

Views: 327

Answers (1)

Mike Scott
Mike Scott

Reputation: 167

I struggled for a-g-e-s over this. Just in case it helps anyone else, what I learned (for my simple data with lots of branches each with a varied number of sub-branches but no sub-sub-branches) is:

  1. Set RootNodeCount to the number of branches you have (as suggested everywhere) as soon as you know that number.

  2. Don't create an index system for your data, that is a waste of effort. Let the Tree do it automatically.

  3. In InitNode, first check the Level: Level := Sender.GetNodeLevel(Node); If the level is 0, check whether your data for that node's index has any sub-branches:

    if repeats.chunks_list.FileOccurrences[Node.Index].Count>0 then Include(InitialStates, ivsHasChildren); and the InitChildren event gets called. In that you set it

    ChildCount := repeats.chunks_list.FileOccurrences[Node.Index].Count;

If the level is above 0, then Exclude(InitialStates, ivsHasChildren) and then simply access the data of the ParentNode.index, seeking the sub-branch numbered by Node.index.

  1. Nodes get numbered automatically. No need to set their Index property or their ChildCount property.

  2. Set their CheckType to ctTriStateCheckbox for level 0 (top level) nodes and TCheckType(level) for a sub-branch.

Upvotes: 2

Related Questions