YOUSEFUL / DELPHI / COMPONENTS
TAtlasTree
A tree view with lazy child loading, safe node moves, caption search, sorting and JSON persistence.
Description
TAtlasTree (unit Atlas.Tree) is a VCL tree view with helpers for application hierarchies. Nodes are ordinary TTreeNode objects owned by the tree; a node reference becomes invalid when the node is deleted or the tree is reloaded. The tree needs a window handle before nodes are added, so set Parent first: adding a node to a tree without a parent raises EInvalidOperation (... has no parent window).
Lazy loading. AddNode(Parent, Caption, True) creates a node with an expand button and no children. The first time it expands (after OnExpanding), the tree calls OnLoadChildren inside Items.BeginUpdate/EndUpdate; add the children there with AddNode. If the handler adds nothing, the expand button disappears. If it raises, the children it added are removed, the node stays lazy so the next expand tries again, and the exception propagates. The handler runs once per node: collapsing and expanding again does not reload.
Persistence. ToJSON and LoadJSON store captions, the expanded state and the lazy flag; not images, Data pointers or the selection. LoadJSON builds the new nodes in a hidden staging tree and replaces the current nodes only when the whole document is valid.
Captions can be edited in place by the user because ReadOnly is False after Create; set it to True or handle OnEditing. TAtlasThemer sets Color and Font.Color. Tree-specific errors raise EAtlasTreeError.
Members
| Member | Kind | What it does |
|---|---|---|
Create | constructor | Creates a 320 x 360 tree with in-place caption editing allowed (ReadOnly False), the selection visible when unfocused (HideSelection False) and double buffering. |
AddNode | method | Adds a node as the last child of Parent, or as the last root node when Parent is nil, and returns it. |
MoveNode | method | Moves Node, with its children, to become the last child of NewParent, or the last root node when NewParent is nil. |
FindCaption | method | Returns the first node after StartAfter (from the first node when nil) whose caption equals Caption, ignoring the case of ASCII letters, searching depth-first through all loaded nodes whether expanded or not. |
SortChildren | method | Sorts the direct children of Parent, or the root nodes when Parent is nil, by caption with the Windows lstrcmp comparison. |
ToJSON | method | Returns the nodes as a JSON array of objects {"caption": ..., "expanded": ..., "lazy": ..., "children": [...]} in tree order. |
LoadJSON | method | Replaces all nodes with the nodes of a document written by ToJSON. |
Items | property | The TTreeNodes collection (standard VCL): iterate with Items.GetFirstNode and GetNext, count with Items.Count, empty with Items.Clear, and wrap bulk changes in Items.BeginUpdate/EndUpdate. |
Selected | property | The selected node, or nil (standard VCL). |
OnLoadChildren | event | Called on the first expand of a lazy node; add its children with AddNode(Node, ...). |
ReadOnly | property | Standard VCL property. |
HideSelection | property | Standard VCL property. |
Align | property | Standard VCL property, published by this class. |
Anchors | property | Standard VCL property, published by this class. |
Color | property | Standard VCL property, published by this class. |
Font | property | Standard VCL property, published by this class. |
ParentFont | property | Standard VCL property, published by this class. |
ShowRoot | property | Standard VCL property, published by this class. |
ShowLines | property | Standard VCL property, published by this class. |
ShowButtons | property | Standard VCL property, published by this class. |
Indent | property | Standard VCL property, published by this class. |
TabOrder | property | Standard VCL property, published by this class. |
TabStop | property | Standard VCL property, published by this class. |
OnChange | event | Standard VCL event, published by this class. |
OnEdited | event | Standard VCL event, published by this class. |
OnEditing | event | Standard VCL event, published by this class. |
OnExpanding | event | Standard VCL event, published by this class. |
OnExpanded | event | Standard VCL event, published by this class. |
OnCollapsing | event | Standard VCL event, published by this class. |
OnCollapsed | event | Standard VCL event, published by this class. |
OnClick | event | Standard VCL event, published by this class. |
OnDblClick | event | Standard VCL event, published by this class. |
Constructors
Create constructor
constructor Create(AOwner: TComponent); override;Creates a 320 x 360 tree with in-place caption editing allowed (ReadOnly False), the selection visible when unfocused (HideSelection False) and double buffering.
Properties
Items property
property Items;The TTreeNodes collection (standard VCL): iterate with Items.GetFirstNode and GetNext, count with Items.Count, empty with Items.Clear, and wrap bulk changes in Items.BeginUpdate/EndUpdate.
Selected property
property Selected;The selected node, or nil (standard VCL).
ReadOnly property
property ReadOnly;Standard VCL property. False after Create, so users can edit captions in place; set True to prevent it.
HideSelection property
property HideSelection;Standard VCL property. False after Create: the selection stays visible when the tree loses focus.
Align property
property Align;Standard VCL property, published by this class.
Anchors property
property Anchors;Standard VCL property, published by this class.
Color property
property Color;Standard VCL property, published by this class.
Font property
property Font;Standard VCL property, published by this class.
ParentFont property
property ParentFont;Standard VCL property, published by this class.
ShowRoot property
property ShowRoot;Standard VCL property, published by this class.
ShowLines property
property ShowLines;Standard VCL property, published by this class.
ShowButtons property
property ShowButtons;Standard VCL property, published by this class.
Indent property
property Indent;Standard VCL property, published by this class.
TabOrder property
property TabOrder;Standard VCL property, published by this class.
TabStop property
property TabStop;Standard VCL property, published by this class.
Events
OnLoadChildren event
property OnLoadChildren: TAtlasLoadChildrenEvent read FOnLoadChildren write FOnLoadChildren;Called on the first expand of a lazy node; add its children with AddNode(Node, ...). See the description for what happens when the handler adds nothing or raises.
OnChange event
property OnChange;Standard VCL event, published by this class.
OnEdited event
property OnEdited;Standard VCL event, published by this class.
OnEditing event
property OnEditing;Standard VCL event, published by this class.
OnExpanding event
property OnExpanding;Standard VCL event, published by this class.
OnExpanded event
property OnExpanded;Standard VCL event, published by this class.
OnCollapsing event
property OnCollapsing;Standard VCL event, published by this class.
OnCollapsed event
property OnCollapsed;Standard VCL event, published by this class.
OnClick event
property OnClick;Standard VCL event, published by this class.
OnDblClick event
property OnDblClick;Standard VCL event, published by this class.
Methods
AddNode method
function AddNode(Parent: TTreeNode; const Caption: string; LazyChildren: Boolean = False): TTreeNode;Adds a node as the last child of Parent, or as the last root node when Parent is nil, and returns it. With LazyChildren = True the node shows an expand button and gets its children from OnLoadChildren on first expand. Raises EAtlasTreeError when Parent belongs to another tree.
Root := Tree.AddNode(nil, 'Engineering');
Tree.AddNode(Root, 'Archive', True);MoveNode method
procedure MoveNode(Node, NewParent: TTreeNode);Moves Node, with its children, to become the last child of NewParent, or the last root node when NewParent is nil. Raises EAtlasTreeError when Node is nil, when either node belongs to another tree, or when NewParent is Node itself or one of its descendants.
FindCaption method
function FindCaption(const Caption: string; StartAfter: TTreeNode = nil): TTreeNode;Returns the first node after StartAfter (from the first node when nil) whose caption equals Caption, ignoring the case of ASCII letters, searching depth-first through all loaded nodes whether expanded or not. Returns nil when there is none; the search does not wrap around. Children of lazy nodes that were never expanded do not exist yet and are not found. Raises EAtlasTreeError when StartAfter belongs to another tree.
Node := Tree.FindCaption('archive');
while Node <> nil do
Node := Tree.FindCaption('archive', Node);SortChildren method
procedure SortChildren(Parent: TTreeNode = nil);Sorts the direct children of Parent, or the root nodes when Parent is nil, by caption with the Windows lstrcmp comparison. Deeper levels keep their order. Raises EAtlasTreeError when Parent belongs to another tree.
ToJSON method
function ToJSON: string;Returns the nodes as a JSON array of objects {"caption": ..., "expanded": ..., "lazy": ..., "children": [...]} in tree order. lazy is true for a node that has an expand button but no loaded children.
LoadJSON method
procedure LoadJSON(const Text: string);Replaces all nodes with the nodes of a document written by ToJSON. Every node needs a string caption, Boolean expanded and lazy, and an array children; nesting is limited to 128 levels. When the text is not a JSON array or a node is invalid it raises EAtlasTreeError and keeps the current nodes. OnLoadChildren is not called while loading. Needs a parent window.
Examples
Browse folders with lazy loading
Each folder node is lazy; its subfolders are read on first expand. The example run creates two folders and prints children after expand: 2 first: alpha.
uses System.SysUtils, System.IOUtils, Vcl.Forms, Vcl.Controls, Vcl.ComCtrls, Atlas.Tree;
type
TFolderBrowser = class
private
FTree: TAtlasTree;
function PathOf(Node: TTreeNode): string;
procedure LoadFolders(Sender: TObject; Node: TTreeNode);
public
constructor Create(Form: TForm; const RootFolder: string);
property Tree: TAtlasTree read FTree;
end;
constructor TFolderBrowser.Create(Form: TForm; const RootFolder: string);
begin
inherited Create;
FTree := TAtlasTree.Create(Form);
FTree.Parent := Form; // the tree needs its window before nodes are added
FTree.Align := alLeft;
FTree.ReadOnly := True; // folder names are not edited in place
FTree.OnLoadChildren := LoadFolders;
FTree.AddNode(nil, RootFolder, True);
end;
function TFolderBrowser.PathOf(Node: TTreeNode): string;
begin
Result := Node.Text;
while Node.Parent <> nil do
begin
Node := Node.Parent;
Result := TPath.Combine(Node.Text, Result);
end;
end;
procedure TFolderBrowser.LoadFolders(Sender: TObject; Node: TTreeNode);
var
Folder: string;
begin
// Runs on the first expand only. If it raises (no access, for example), the
// tree removes what was added and the node stays expandable.
for Folder in TDirectory.GetDirectories(PathOf(Node)) do
FTree.AddNode(Node, ExtractFileName(Folder), True);
end;Find, move, save and restore nodes
Moves Support under Sales, saves the tree, clears it and restores it; a file that is not a JSON array is rejected with Expected a JSON array and the three nodes are kept.
uses System.SysUtils, System.IOUtils, Vcl.ComCtrls, Atlas.Tree;
procedure SaveTree(Tree: TAtlasTree; const FileName: string);
begin
TFile.WriteAllText(FileName, Tree.ToJSON, TEncoding.UTF8);
end;
procedure RestoreTree(Tree: TAtlasTree; const FileName: string);
begin
try
Tree.LoadJSON(TFile.ReadAllText(FileName, TEncoding.UTF8));
except
on E: EAtlasTreeError do
Writeln('Tree not restored: ', E.Message); // the current nodes are kept
end;
end;
procedure MoveUnder(Tree: TAtlasTree; const Caption, NewParentCaption: string);
var
Node, NewParent: TTreeNode;
begin
Node := Tree.FindCaption(Caption);
NewParent := Tree.FindCaption(NewParentCaption);
if (Node <> nil) and (NewParent <> nil) then
Tree.MoveNode(Node, NewParent); // raises EAtlasTreeError if it would create a cycle
end;Related
TAtlasLoadChildrenEvent · EAtlasTreeError · TAtlasInspector
Also in Atlas VCL
TAtlasTable · TAtlasGrid · TAtlasValueEdit · TAtlasWorkbook · TAtlasSheetGrid · TAtlasPivot · TAtlasInspector · TAtlasRichEdit · TAtlasSpellChecker · TAtlasChart · TAtlasGauge · TAtlasThemer · TAtlasWizard · TAtlasWorkspace · TAtlasCommandBar · TAtlasActionTile · TAtlasTileBoard · TAtlasNavigation · TAtlasMap · TAtlasGraph · TAtlasDiagram · TAtlasPrintDocument · TAtlasSchedule · TAtlasScheduler · TAtlasTaskPlan · TAtlasGantt · TAtlasPdfDocument · TAtlasPdfViewer