# Tree and editors A console program that creates the Atlas VCL data controls on a form that is never shown and verifies what each one does: - `TAtlasTree`: builds a small hierarchy with `AddNode`, sorts children with `SortChildren`, finds a node with `FindCaption` (case-insensitive), moves a node to the root with `MoveNode` and shows that moving a node under its own child raises `EAtlasTreeError`. A lazy node gets its children from `OnLoadChildren` on the first expand only. `ToJSON`/`LoadJSON` copy the tree to a second tree, and a JSON document without the required fields is rejected without changing it. - `TAtlasSheetGrid`: shows a `TAtlasWorkbook` with a `SUM` formula, follows a change to a referenced cell, applies a fixed-decimal format and detaches when the workbook is freed. - `TAtlasInspector`: lists the published properties of a small settings component, assigns integer, floating-point, enumeration and Boolean values with `SetProperty`, rejects an invalid integer and a read-only property with `EAtlasPropertyError`, and detaches when the component is freed. - `TAtlasRichEdit`: formats a selection, saves it with `SaveRTF`, loads the bytes into a second editor with `LoadRTF` (text and bold style survive), finds two matches with `FindNext` and replaces them with `ReplaceAll`. - `TAtlasValueEdit`: validates numbers and dates, shows that a decimal comma is not a number, and that `Required` turns a blank value into an error. Controls that wrap a Windows control need a window handle, so each one is given the hidden form as `Parent` before it is used. A mismatch raises an exception, the program prints `FAIL: ...` and exits with code 1. ## Build and run Open `TreeAndEditors.dpr` in Delphi 13; the IDE creates the project file. Add the Atlas VCL `src` folder to the project's search path, then build and run for Win32 or Win64. No packages need to be installed. The program needs no input. It checks its own results and stops with an error if any of them differs from the output below. ## Expected output ``` TAtlasTree ok: children sorted by caption = Data platform ok: case-insensitive caption search ok: node moved to the root level ok: moving a node under its own child is rejected ok: a lazy node shows an expand button before loading ok: OnLoadChildren ran once on first expand ok: children are not loaded twice ok: JSON round trip keeps captions, expansion and lazy flags = [{"caption":"Engineering",...}] ok: a rejected import leaves the tree unchanged TAtlasSheetGrid ok: column headers use letters = A ok: B1 shows the calculated value = 42 ok: the grid follows workbook changes = 20 ok: cell formats apply to the displayed text = 20.0 ok: the grid detaches when its workbook is freed TAtlasInspector ok: published properties are listed with their values = 3 ok: SetProperty converts and assigns typed values ok: an invalid value is rejected before assignment ok: a read-only property is rejected ok: destroying the component detaches the inspector TAtlasRichEdit ok: selection formatting applied ok: SaveRTF returns RTF bytes ok: LoadRTF restores the text = Atlas notes: draft one, draft two. ok: LoadRTF restores the formatting ok: FindNext selects the first match after the caret ok: FindNext continues from the selection ok: ReplaceAll reports two replacements ok: text after ReplaceAll = Atlas notes: revision one, revision two. TAtlasValueEdit ok: a number is accepted ok: NormalizedValue is the stored form = 12.5 ok: a locale decimal comma is rejected with a message ok: blank is valid when not required ok: blank is invalid when required ok: 2026-02-29 is not a real date ok: 2028-02-29 is a leap day PASS: TreeAndEditors ``` The tree JSON line shows the format `ToJSON` writes: an array of node objects, each with `caption`, `expanded`, `lazy` and `children`. The `Archive` node was expanded, so it is saved as expanded with its loaded child and `lazy` false; the never-expanded `Later` node keeps `lazy` true. ## What to change first - Put the controls on a visible form (`Align := alClient` on a page each) to see them; the calls stay the same. - Replace `TTaskSettings` with one of your own components. The inspector lists published string, character, integer, 64-bit integer, floating-point and enumeration properties (Booleans are enumerations); sets, classes and events are not shown. - In `TLazyLoader.LoadChildren`, query your own data source for the children of `Node`. If the handler raises, the tree removes the children it added and the node stays lazy, so the next expand tries again.