YOUSEFUL / DELPHI / COMPONENTS

TAtlasThemer

Applies one of eleven built-in colour palettes to a control and every control inside it, and saves the choice by name.

Non-visual component Palette: Atlas Unit Atlas.Themes · Inherits TComponent · Product Atlas VCL

Description

Set Root to a form, panel or other container and ThemeIndex to a palette. Apply walks Root and every control inside it: each gets the theme's surface colour and text colour, and seFont and seClient are removed from its StyleElements so that native styling does not override them. Some controls get more: TAtlasGrid its header (primary) and alternate row colours, any TCustomGrid its fixed-cell colour, TAtlasDiagram its node colours, and TAtlasActionTile the primary colour with white text.

The palettes, index 0 to 10, are Harbor, Forest, Plum, Slate, Copper, Indigo, Ocean, Wine, Olive, Graphite and Midnight. The first ten share a white surface, a light grey alternate colour and near-black text and differ only in the primary colour; Midnight is the dark palette. The unit functions AtlasTheme(Index) and AtlasThemeCount return the palettes as TAtlasTheme records, and AtlasContrast(A, B) returns the WCAG contrast ratio of two colours (1 to 21). In every palette, text on surface, text on alternate and white on primary reach at least 4.5:1; that alone does not make an application accessible.

Apply runs when you set Root or ThemeIndex. Controls created afterwards keep their own colours until you call Apply again, and a pane floating in a TAtlasWorkspace tool window is outside Root, so it is skipped while it floats. Chart series, gauge bars, native buttons and tab strips keep their colours. There are no custom palettes and no VCL style integration.

Members

MemberKindWhat it does
ApplymethodApplies the current theme to Root and every control inside it and repaints them.
SaveToFilemethodWrites the name of the current theme (for example Midnight) to a UTF-8 text file.
LoadFromFilemethodReads a theme name written by SaveToFile (case-insensitive, surrounding white space ignored) and sets ThemeIndex, which applies it.
RootpropertyThe control whose tree is themed.
ThemeIndexpropertyPalette index, 0 to AtlasThemeCount - 1.

Properties

Root property

property Root: TWinControl read FRoot write SetRoot;

The control whose tree is themed. Setting it applies the current theme at once. Cleared automatically when that control is destroyed.

pascal
Themer.Root := Form;

ThemeIndex property

property ThemeIndex: Integer read FThemeIndex write SetThemeIndex default 0;

Palette index, 0 to AtlasThemeCount - 1. A valid index is applied at once; any other raises EArgumentOutOfRangeException and keeps the previous one.

pascal
Themer.ThemeIndex := 10; // Midnight

Methods

Apply method

procedure Apply;

Applies the current theme to Root and every control inside it and repaints them. Does nothing when Root is nil. Call it after adding controls.

pascal
Themer.Apply; // after creating more controls under Root

SaveToFile method

procedure SaveToFile(const FileName: string);

Writes the name of the current theme (for example Midnight) to a UTF-8 text file.

pascal
Themer.SaveToFile('theme.txt');

LoadFromFile method

procedure LoadFromFile(const FileName: string);

Reads a theme name written by SaveToFile (case-insensitive, surrounding white space ignored) and sets ThemeIndex, which applies it. Raises EArgumentException for an unknown name; file errors such as a missing file propagate.

pascal
Themer.LoadFromFile('theme.txt');

Examples

Theme picker

Fills a combo box with the palette names and applies the chosen one. Create the other controls first, then the picker.

pascal
uses System.Classes, Vcl.Forms, Vcl.StdCtrls, Atlas.Themes;

type
  TThemePicker = class
  private
    FThemer: TAtlasThemer;
    procedure Changed(Sender: TObject);
  public
    constructor Create(Form: TForm; Choice: TComboBox);
  end;

constructor TThemePicker.Create(Form: TForm; Choice: TComboBox);
var
  I: Integer;
begin
  inherited Create;
  FThemer := TAtlasThemer.Create(Form);
  FThemer.Root := Form;
  Choice.Style := csDropDownList;
  for I := 0 to AtlasThemeCount - 1 do Choice.Items.Add(AtlasTheme(I).Name);
  Choice.ItemIndex := FThemer.ThemeIndex;
  Choice.OnChange := Changed;
end;

procedure TThemePicker.Changed(Sender: TObject);
begin
  FThemer.ThemeIndex := TComboBox(Sender).ItemIndex;
end;

Remember the theme between runs

Stores the theme name in a file and falls back to the first palette when the file names an unknown theme.

pascal
uses System.SysUtils, System.IOUtils, Atlas.Themes;

procedure RestoreTheme(Themer: TAtlasThemer; const FileName: string);
begin
  if TFile.Exists(FileName) then
  try
    Themer.LoadFromFile(FileName);
  except
    on EArgumentException do Themer.ThemeIndex := 0;
  end;
end;

procedure StoreTheme(Themer: TAtlasThemer; const FileName: string);
begin
  Themer.SaveToFile(FileName);
end;

List the palettes with their contrast

Uses the unit functions AtlasThemeCount, AtlasTheme and AtlasContrast.

pascal
uses System.Classes, System.SysUtils, Vcl.Graphics, Atlas.Themes;

procedure ListThemes(Lines: TStrings);
var
  I: Integer;
  Theme: TAtlasTheme;
begin
  for I := 0 to AtlasThemeCount - 1 do
  begin
    Theme := AtlasTheme(I);
    Lines.Add(Format('%d %s: text %.1f:1, header %.1f:1', [I, Theme.Name,
      AtlasContrast(Theme.Text, Theme.Surface), AtlasContrast(clWhite, Theme.Primary)]));
  end;
end;

TAtlasTheme · TAtlasWorkspace · TAtlasDiagram · TAtlasActionTile · TAtlasChart

Also in Atlas VCL

TAtlasTable · TAtlasGrid · TAtlasValueEdit · TAtlasTree · TAtlasWorkbook · TAtlasSheetGrid · TAtlasPivot · TAtlasInspector · TAtlasRichEdit · TAtlasSpellChecker · TAtlasChart · TAtlasGauge · TAtlasWizard · TAtlasWorkspace · TAtlasCommandBar · TAtlasActionTile · TAtlasTileBoard · TAtlasNavigation · TAtlasMap · TAtlasGraph · TAtlasDiagram · TAtlasPrintDocument · TAtlasSchedule · TAtlasScheduler · TAtlasTaskPlan · TAtlasGantt · TAtlasPdfDocument · TAtlasPdfViewer