Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- TRoot = Record
- RootName : String;
- RootId : Integer;
- Kids : TList; //(of TKid)
- End;
- TKid = Record
- KidName : String;
- KidId : Integer;
- End;
- TNodeClass = class
- public
- Name: string;
- ID: Integer;
- end;
- type
- TNode = class
- public
- ID: integer;
- Name: string;
- VTNode: PVirtualNode;
- Sub: TObjectList<TNode>;
- constructor Create(aName: string = ''; anID: integer = 0);
- destructor Destroy; override;
- end;
- constructor TNode.Create(aName:string; anID: Integer);
- begin
- Name := aName;
- ID := anID;
- Sub := TObjectList<TNode>.Create;
- end;
- destructor TNode.Destroy;
- begin
- Sub.Free;
- end;
- Root := TNode.Create;
- // Create the Contacts leaf
- Root.Sub.Add(TNode.Create('Contacts', -1));
- // Add some contacts
- Root.Sub[0].Sub.Add(TNode.Create('Abraham', 1));
- Root.Sub[0].Sub.Add(TNode.Create('Lincoln', 2));
- // Create the "Recent Calls" leaf
- Root.Sub.Add(TNode.Create('Recent Calls', -1));
- // Add some recent calls
- Root.Sub[1].Sub.Add(TNode.Create('+00 (000) 00.00.00', 3));
- Root.Sub[1].Sub.Add(TNode.Create('+00 (001) 12.34.56', 4));
- procedure TForm1.AddNodestoTree(ParentNode: PVirtualNode; Node: TNode);
- var SubNode: TNode;
- ThisNode: PVirtualNode;
- begin
- ThisNode := VT.AddChild(ParentNode, Node); // This call adds a new TVirtualNode to the VT, and saves "Node" as the payload
- Node.VTNode := ThisNode; // Save the PVirtualNode for future reference. This is only an example,
- // the same TNode might be registered multiple times in the same VT,
- // so it would be associated with multiple PVirtualNode's.
- for SubNode in Node.Sub do
- AddNodestoTree(ThisNode, SubNode);
- end;
- // And start processing like this:
- VT.NodeDataSize := SizeOf(Pointer); // Make sure we specify the size of the node's payload.
- // A variable holding an object reference in Delphi is actually
- // a pointer, so the node needs enough space to hold 1 pointer.
- AddNodesToTree(nil, Root);
- procedure TForm1.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
- Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
- var PayloadObject:TObject;
- Node: TNode;
- Contact : TContact;
- ContactCategory : TContactCategory;
- begin
- PayloadObject := TObject(VT.GetNodeData(Node)^); // Extract the payload of the node as a TObject so
- // we can check it's type before proceeding.
- if not Assigned(PayloadObject) then
- CellText := 'Bug: Node payload not assigned'
- else if PayloadObject is TNode then
- begin
- Node := TNode(PayloadObject); // We know it's a TNode, assign it to the proper var so we can easily work with it
- CellText := Node.Name;
- end
- else if PayloadObject is TContact then
- begin
- Contact := TContact(PayloadObject);
- CellText := Contact.FirstName + ' ' + Contact.LastName + ' (' + Contact.PhoneNumber + ')';
- end
- else if PayloadObject is TContactCategory then
- begin
- ContactCategory := TContactCategory(PayloadObject);
- CellText := ContactCategory.CategoryName + ' (' + IntToStr(ContactCategory.Contacts.Count) + ' contacts)';
- end
- else
- CellText := 'Bug: don''t know how to extract CellText from ' + PayloadObject.ClassName;
- end;
- procedure TForm1.ButtonModifyClick(Sender: TObject);
- begin
- Root.Sub[0].Sub[0].Name := 'Someone else'; // I'll modify the node itself
- VT.InvalidateNode(Root.Sub[0].Sub[0].VTNode); // and invalidate the tree; when displayed again, it will
- // show the updated text.
- end;
- uses
- svCollections.GenericTrees;
- type
- TMainData = record
- Name: string;
- ID: Integer;
- end;
- MyTree: TSVTree<TMainData>;
- MyTree: TSVTree<TMainData>.Create(False);
- MyTree.VirtualTree := VST;
- procedure TForm1.BuildStructure(Count: Integer);
- var
- i, j: Integer;
- svNode, svNode2: TSVTreeNode<TMainData>;
- Data: TMainData;
- begin
- MyTree.BeginUpdate;
- try
- for i := 0 to Count - 1 do
- begin
- Data.Name := Format('Root %D', [i]);
- Data.ID := i;
- svNode := MyTree.AddChild(nil, Data);
- for j:= 0 to 10 - 1 do
- begin
- Data.Name := Format('Child %D', [j]);
- Data.ID := j;
- svNode2 := MyTree.AddChild(svNode, Data);
- end;
- end;
- finally
- MyTree.EndUpdate;
- end;
- end;
- procedure TForm1.vt1InitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
- var ChildCount: Cardinal);
- var
- svNode: TSVTreeNode<TMainData>;
- begin
- svNode := MyTree.GetNode(Sender.GenerateIndex(Node));
- if Assigned(svNode) then
- begin
- ChildCount := svNode.FChildCount;
- end;
- end;
- procedure TForm1.vt1InitNode(Sender: TBaseVirtualTree; ParentNode,
- Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
- var
- svNode: TSVTreeNode<TMainData>;
- begin
- svNode := MyTree.GetNode(Sender.GenerateIndex(Node));
- if Assigned(svNode) then
- begin
- //if TSVTree<TTestas> is synced with Virtual Treeview and we are building tree by
- // setting RootNodeCount, then we must set svNode.FVirtualNode := Node to
- // have correct node references
- svNode.FVirtualNode := Node; // Don't Forget!!!!
- if svNode.HasChildren then
- begin
- Include(InitialStates, ivsHasChildren);
- end;
- end;
- end;
- //display info how you like, I simply get name and ID values
- procedure TForm1.vt1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
- Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
- var
- svNode: TSVTreeNode<TMainData>;
- begin
- svNode := MyTree.GetNode(Sender.GenerateIndex(Node));
- if Assigned(svNode) then
- begin
- CellText := Format('%S ID:%D',[svNode.FValue.Name, svNode.FValue.ID]);
- end;
- end;
- type
- TNode = class
- Parent: TNode;
- NextSibling: TNode;
- FirstChild: TNode;
- end;
- TTree = class
- Root: TNode;
- function AddNode(Parent: TNode): TNode;
- end;
- function TTree.AddNode(Parent: TNode);
- var
- Node: TNode;
- begin
- Result := TNode.Create;
- Result.Parent := Parent;
- Result.NextSibling := nil;
- Result.FirstChild := nil;
- //this may be the first node in the tree
- if not Assigned(Root) then begin
- Assert(not Assigned(Parent));
- Root := Result;
- exit;
- end;
- //this may be the first child of this parent
- if Assigned(Parent) and not Assigned(Parent.FirstChild) then begin
- Parent.FirstChild := Result;
- end;
- //find the previous sibling and assign its next sibling to the new node
- if Assigned(Parent) then begin
- Node := Parent.FirstChild;
- end else begin
- Node := Root;
- end;
- if Assigned(Node) then begin
- while Assigned(Node.NextSibling) do begin
- Node := Node.NextSibling;
- end;
- Node.NextSibling := Result;
- end;
- end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement