Skip to main content
The TTreeNodeShape class is the fundamental building block of TeeTree. Each node is a full standalone component with comprehensive properties, methods, and events.

Overview

Unlike traditional tree controls where nodes are simple data items, TeeTree nodes are complete visual components with rich formatting capabilities.
// Creating a node
var
  Node: TTreeNodeShape;
begin
  Node := Tree.Shapes.Add('My Node');
  Node.Color := clYellow;
  Node.Border.Width := 2;
end;
Every node in TeeTree is a TTreeNodeShape instance derived from TCustomTreeElement, which provides core functionality shared with connections.

Node Properties

Position and Size

Nodes have explicit position and size properties:
// Position (top-left corner)
Node.X0 := 100;  // or Node.Left := 100;
Node.Y0 := 50;   // or Node.Top := 50;

// Size (bottom-right corner)
Node.X1 := 200;
Node.Y1 := 100;

// Alternative: Width and Height
Node.Width := 100;
Node.Height := 50;
Left and Top are aliases for X0 and Y0 respectively. Use whichever is more intuitive for your code.

Visual Appearance

// Background color
Node.Color := clWhite;        // Default white
Node.Brush.Color := clYellow; // Alternative way

// Border
Node.Border.Color := clBlack;
Node.Border.Width := 1;
Node.Border.Style := psSolid;

// Transparency
Node.Transparency := 50;  // 0-100%
Node.Transparent := True; // No interior fill
// Apply gradient fill
with Node.Gradient do
begin
  Visible := True;
  StartColor := clWhite;
  EndColor := clBlue;
  Direction := gdTopBottom;
end;

// Gradient clipping
Node.GradientClip := True;  // Clip to shape bounds
with Node.Shadow do
begin
  Visible := True;
  Size := 5;
  Color := clGray;
  Transparency := 50;
end;

Node Styles

Nodes support various visual styles:
type
  TTreeShapeStyle = (
    tssRectangle,        // Default
    tssCircle,
    tssVertLine,
    tssHorizLine,
    tssLine,
    tssInvertLine,
    tssDiamond,
    tssTriangleTop,
    tssTriangleBottom,
    tssTriangleLeft,
    tssTriangleRight,
    tssRoundRectangle,
    tssCustom,
    tssChamfer
  );

// Apply style
Node.Style := tssRoundRectangle;
Node.RoundSize := 10;  // Corner radius
When using tssCustom style, you’ll need to override the GetShapePoints method to define your custom shape.

Text Properties

Nodes have sophisticated text handling:
// Simple text assignment
Node.SimpleText := 'Hello World';

// Multi-line text
Node.Text.Clear;
Node.Text.Add('Line 1');
Node.Text.Add('Line 2');

// Text formatting
Node.Text.HorizAlign := htaCenter;  // htaLeft, htaRight
Node.Text.VertAlign := vtaCenter;   // vtaTop, vtaBottom
Node.Text.Angle := 45;              // 0..360 degrees
Node.Text.ClipText := False;        // Allow text outside bounds

// Font
Node.Font.Name := 'Arial';
Node.Font.Size := 12;
Node.Font.Style := [fsBold];
Node.Font.Color := clBlack;

AutoSize

Nodes can automatically size themselves based on content:
Node.AutoSize := True;  // Default
Node.SimpleText := 'This text determines the node size';

// Disable for manual sizing
Node.AutoSize := False;
Node.Width := 200;
Node.Height := 100;
When AutoSize is enabled, the node calculates its size based on text and image dimensions plus margins.

Images

Nodes can display images in various positions:
// Using stock images
Node.ImageIndex := tiFolderClose;
Node.Expanded := False;

// Using custom image
Node.Image.LoadFromFile('myimage.png');

// Image alignment
Node.ImageAlignment := iaLeft;  // iaAutomatic, iaLeftTop, iaRight, etc.

// Custom image size
Node.ImageWidth := 32;
Node.ImageHeight := 32;

// Using ImageList
Node.ImageListIndex := 0;  // Index in Tree.Images

Image Alignment Options

type
  TTreeImageAlignment = (
    iaAutomatic,    // Smart positioning
    iaLeftTop,
    iaRightBottom,
    iaLeftBottom,
    iaRightTop,
    iaLeft,
    iaTop,
    iaRight,
    iaBottom,
    iaCenter
  );

Parent-Child Relationships

Nodes form hierarchies through parent-child relationships:
// Create hierarchy
var
  Parent, Child1, Child2: TTreeNodeShape;
begin
  Parent := Tree.Shapes.Add('Parent');
  Child1 := Parent.AddChild('Child 1');
  Child2 := Parent.AddChild('Child 2');
  
  // Alternative: Set parent explicitly
  Child1.Parent := Parent;
end;

// Access children
for i := 0 to Parent.Children.Count - 1 do
  ProcessChild(Parent.Children[i]);

// Check if node has children
if Node.HasChildren then
  Node.Expanded := True;
When a parent node is destroyed, all its children are automatically freed.

Child Management Methods

// Add children
Child := Node.AddChild('New Child');          // Add at end
Child := Node.AddChildFirst('First Child');   // Add at beginning
Child := Node.Insert(1, 'Insert at Index 1'); // Insert at position

// Add with data
Child := Node.AddChildObject('Child', MyDataPointer);

// Add sibling
Brother := Node.AddBrother('Sibling Node');

// Node count
Count := Node.Count;  // Number of direct children

Expand and Collapse

Nodes can be expanded or collapsed to show/hide children:
// Expand/Collapse
Node.Expanded := True;
Node.Expanded := False;

// Toggle
Node.Toggle;

// Collapse recursively
Node.Collapse(True);  // Collapse this and all descendants

// Show CrossBox
Node.ShowCross := scAuto;    // scAuto, scAlways, scNever

CrossBox Styles

type
  TTreeNodeShapeShowCross = (
    scAuto,    // Show only when node has children
    scAlways,  // Always show
    scNever    // Never show
  );

AutoPosition

Control automatic positioning of nodes:
// Enable both Left and Top auto-positioning
Node.AutoPosition.Left := True;   // Default
Node.AutoPosition.Top := True;    // Default

// Manual X position, automatic Y
Node.AutoPosition.Left := False;
Node.AutoPosition.Top := True;
Node.X0 := 100;  // Fixed X position
The ChildManager class calculates positions for nodes with AutoPosition enabled. See Child Managers for details.

Selection and Interaction

// Select a node
Node.Selected := True;

// Check if selected
if Node.Selected then
  ShowMessage('Node is selected');

// Add to tree selection
Tree.Selected.Add(Node);

// Events
Node.OnClick := NodeClickHandler;
Node.OnDblClick := NodeDblClickHandler;
Node.OnMouseEnter := NodeMouseEnterHandler;
Node.OnMouseLeave := NodeMouseLeaveHandler;

Event Handlers

procedure TForm1.NodeClickHandler(Sender: TTreeNodeShape;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ShowMessage('Clicked: ' + Sender.SimpleText);
end;

Node Navigation

// Access parent and siblings
ParentNode := Node.Parent;
RootNode := Node.Root;
PreviousNode := Node.PreviousBrother;

// Get node level (depth in tree)
Level := Node.Level;  // 0 for root nodes

// Brother index (position among siblings)
Index := Node.BrotherIndex;
Node.BrotherIndex := 0;  // Move to first position

Visibility Control

// Show/Hide
Node.Visible := True;
Node.Show;
Node.Hide;

// Check if inside tree bounds
if Node.InsideTreeBounds then
  ProcessNode(Node);

Data Association

// Store custom data
Node.Data := MyDataPointer;
Node.TagObject := MyObject;
Node.Tag := 123;

// Retrieve data
MyData := PMyDataType(Node.Data);
MyObj := Node.TagObject as TMyClass;
The Data property is a raw pointer. Ensure proper memory management. TagObject provides automatic reference counting on supported platforms.

Advanced Features

Checkboxes

// Use checkbox images
Node.ImageIndex := tiUnChecked;
Node.Checked := False;

// Toggle checkbox
Node.ToggleCheck;
Node.Checked := True;  // Now shows tiChecked

// Check all selected
Tree.Selected.ToggleCheck;

Custom Drawing

// Override DrawShapeCanvas for custom rendering
type
  TMyNode = class(TTreeNodeShape)
  protected
    procedure DrawShapeCanvas(const ACanvas: TCanvas3D;
      const R: TRect); override;
  end;

Z-Order

// Control drawing order
Node.BringToFront;
Node.SendToBack;

Utility Methods

// Geometry
CenterX := Node.XCenter;
CenterY := Node.YCenter;
Bounds := Node.Bounds;  // TRect
Adjusted := Node.AdjustedRectangle;  // Includes image

// Sorting children
Node.SortChildsText(True, False);  // Ascending, case-sensitive

// Select all children
Node.SelectChilds;

// Move node
Node.MoveRelative(10, 20, True);  // DeltaX, DeltaY, MoveChildren

// Resize
Node.Resize(rcRightBottom, 10, 10);  // Corner, DeltaX, DeltaY

Best Practices

Use AutoSize

Let nodes automatically size themselves based on content for consistent appearance

Leverage Parent-Child

Use parent-child relationships instead of manual positioning when possible

Cache References

Store node references in data structures for quick access instead of searching

Handle Events

Use node events for interactive features rather than polling

Next Steps

Connections

Learn how to link nodes together

Child Managers

Understand automatic layout management

Styling Guide

Master visual customization

Build docs developers (and LLMs) love