Skip to content

Commit

Permalink
Change for #832: Turn TVirtualNode.LastChild into a readonly property…
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmarder committed Aug 13, 2023
1 parent b4cd92f commit 07fa2dd
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 22 deletions.
38 changes: 19 additions & 19 deletions Source/VirtualTrees.BaseTree.pas
Original file line number Diff line number Diff line change
Expand Up @@ -5047,9 +5047,9 @@ procedure TBaseVirtualTree.SetChildCount(Node: PVirtualNode; NewChildCount: Card
if Assigned(Node.LastChild) then
Node.LastChild.SetNextSibling(Child);
Child.SetParent(Node);
Node.LastChild := Child;
Node.SetLastChild(Child);
if Node.FirstChild = nil then
Node.FirstChild := Child;
Node.SetFirstChild(Child);
System.Dec(Remaining);
System.Inc(Index);

Expand Down Expand Up @@ -13775,7 +13775,7 @@ procedure TBaseVirtualTree.InternalConnectNode(Node, Destination: PVirtualNode;
Node.SetParent(Destination.Parent);
Node.SetIndex(Destination.Index);
if Node.PrevSibling = nil then
Node.Parent.FirstChild := Node
Node.Parent.SetFirstChild(Node)
else
Node.PrevSibling.SetNextSibling(Node);

Expand All @@ -13794,7 +13794,7 @@ procedure TBaseVirtualTree.InternalConnectNode(Node, Destination: PVirtualNode;
Node.SetPrevSibling(Destination);
Node.SetParent(Destination.Parent);
if Node.NextSibling = nil then
Node.Parent.LastChild := Node
Node.Parent.SetLastChild(Node)
else
Node.NextSibling.SetPrevSibling(Node);
Node.SetIndex(Destination.Index);
Expand All @@ -13814,13 +13814,13 @@ procedure TBaseVirtualTree.InternalConnectNode(Node, Destination: PVirtualNode;
// If there's a first child then there must also be a last child.
Destination.FirstChild.SetPrevSibling(Node);
Node.SetNextSibling(Destination.FirstChild);
Destination.FirstChild := Node;
Destination.SetFirstChild(Node);
end
else
begin
// First child node at this location.
Destination.FirstChild := Node;
Destination.LastChild := Node;
Destination.SetFirstChild(Node);
Destination.SetLastChild(Node);
Node.SetNextSibling(nil);
end;
Node.SetPrevSibling(nil);
Expand All @@ -13841,13 +13841,13 @@ procedure TBaseVirtualTree.InternalConnectNode(Node, Destination: PVirtualNode;
// If there's a last child then there must also be a first child.
Destination.LastChild.SetNextSibling(Node);
Node.SetPrevSibling(Destination.LastChild);
Destination.LastChild := Node;
Destination.SetLastChild(Node);
end
else
begin
// first child node at this location
Destination.FirstChild := Node;
Destination.LastChild := Node;
Destination.SetFirstChild(Node);
Destination.SetLastChild(Node);
Node.SetPrevSibling(nil);
end;
Node.SetNextSibling(nil);
Expand Down Expand Up @@ -13957,7 +13957,7 @@ procedure TBaseVirtualTree.InternalDisconnectNode(Node: PVirtualNode; KeepFocus:
if Assigned(Node.PrevSibling) then
Node.PrevSibling.SetNextSibling(Node.NextSibling)
else
Parent.FirstChild := Node.NextSibling;
Parent.SetFirstChild(Node.NextSibling);

if Assigned(Node.NextSibling) then
begin
Expand All @@ -13976,7 +13976,7 @@ procedure TBaseVirtualTree.InternalDisconnectNode(Node: PVirtualNode; KeepFocus:
end;
end
else
Parent.LastChild := Node.PrevSibling;
Parent.SetLastChild(Node.PrevSibling);
end;
end;

Expand Down Expand Up @@ -15132,8 +15132,8 @@ function TBaseVirtualTree.ReadChunk(Stream: TStream; Version: Integer; Node: PVi
if Assigned(Node.LastChild) then
Node.LastChild.SetNextSibling(Run)
else
Node.FirstChild := Run;
Node.LastChild := Run;
Node.SetFirstChild(Run);
Node.SetLastChild(Run);
Run.SetParent(Node);

ReadNode(Stream, Version, Run);
Expand Down Expand Up @@ -16912,8 +16912,8 @@ procedure TBaseVirtualTree.DeleteChildren(Node: PVirtualNode; ResetHasChildren:
AdjustTotalHeight(Node, NodeHeight[Node]);
AdjustTotalCount(Node, 1);
end;
Node.FirstChild := nil;
Node.LastChild := nil;
Node.SetFirstChild(nil);
Node.SetLastChild(nil);
finally
System.Dec(FUpdateCount);
end;
Expand Down Expand Up @@ -22463,9 +22463,9 @@ procedure TBaseVirtualTree.Sort(Node: PVirtualNode; Column: TColumnIndex; Direct
try
// Sort the linked list, check direction flag only once.
if Direction = sdAscending then
Node.FirstChild := MergeSortAscending(Node.FirstChild, Node.ChildCount)
Node.SetFirstChild(MergeSortAscending(Node.FirstChild, Node.ChildCount))
else
Node.FirstChild := MergeSortDescending(Node.FirstChild, Node.ChildCount);
Node.SetFirstChild(MergeSortDescending(Node.FirstChild, Node.ChildCount));
finally
EndOperation(okSortNode);
end;
Expand All @@ -22481,7 +22481,7 @@ procedure TBaseVirtualTree.Sort(Node: PVirtualNode; Column: TColumnIndex; Direct
Run.NextSibling.SetPrevSibling(Run);
Run := Run.NextSibling;
until False;
Node.LastChild := Run;
Node.SetLastChild(Run);

InvalidateCache;
end;
Expand Down
21 changes: 18 additions & 3 deletions Source/VirtualTrees.Types.pas
Original file line number Diff line number Diff line change
Expand Up @@ -904,18 +904,23 @@ TScrollBarOptions = class(TPersistent)
private
fParent: PVirtualNode; // reference to the node's parent (for the root this contains the treeview)
fPrevSibling: PVirtualNode; // link to the node's previous sibling or nil if it is the first node
fNextSibling: PVirtualNode; // link to the node's next sibling or nil if it is the last node
fNextSibling: PVirtualNode; // link to the node's next sibling or nil if it is the last node
public // still public as it is used as var parameter in MergeSortAscending()
FirstChild: PVirtualNode; // link to the node's first child...
private
fLastChild: PVirtualNode; // link to the node's last child...
public
FirstChild, // link to the node's first child...
LastChild: PVirtualNode; // link to the node's last child...
procedure SetParent(const pParent: PVirtualNode); inline; //internal method, do not call directly but use Parent[Node] := x on tree control.
procedure SetPrevSibling(const pPrevSibling: PVirtualNode); inline; //internal method, do not call directly
procedure SetNextSibling(const pNextSibling: PVirtualNode); inline; //internal method, do not call directly
procedure SetFirstChild(const pFirstChild: PVirtualNode); inline; //internal method, do not call directly
procedure SetLastChild(const pLastChild: PVirtualNode); inline; //internal method, do not call directly
procedure SetIndex(const pIndex: Cardinal); inline; //internal method, do not call directly.
property Index: Cardinal read fIndex;
property Parent: PVirtualNode read fParent;
property PrevSibling: PVirtualNode read fPrevSibling;
property NextSibling: PVirtualNode read fNextSibling;
property LastChild: PVirtualNode read fLastChild;
private
Data: record end; // this is a placeholder, each node gets extra data determined by NodeDataSize
public
Expand Down Expand Up @@ -1182,6 +1187,16 @@ procedure TVirtualNode.SetData<T>(pUserData: T);
Include(Self.States, vsOnFreeNodeCallRequired);
end;

procedure TVirtualNode.SetFirstChild(const pFirstChild: PVirtualNode);
begin
FirstChild := pFirstChild;
end;

procedure TVirtualNode.SetLastChild(const pLastChild: PVirtualNode);
begin
fLastChild := pLastChild;
end;

procedure TVirtualNode.SetIndex(const pIndex: Cardinal);
begin
fIndex := pIndex;
Expand Down

0 comments on commit 07fa2dd

Please sign in to comment.