Skip to content

Releases

Version 3.0.1

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 23 Sep 12:54

Fixed

  • The outline of the track is one pixel again. Since 2.0.0 it was drawn across
    two rows of pixels at half strength on any display at 100%: the stroke was
    moved inside the 40 × 20 track on the assumption that integer coordinates
    fall on pixel edges, while GDI+ puts them on pixel centres unless told
    otherwise. It is told now, so the outline, the track fill and the thumb all
    sit on the pixel grid, at 200% as well. Fractional scales are antialiased as
    before.

  • The palette icon carries transparency and comes in four sizes. It was three
    bitmaps on white, so the palette showed a white halo around it and stretched
    it on a scaled display. The .dcr now holds PNG images at 16, 24, 32 and
    128 pixels as well, which the IDE composites over its own background and
    picks by scale; the bitmaps stay as the fallback for an IDE that reads no
    PNG. The files the .dcr is built from are in the repository.

Version 3.0.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 22 Sep 23:40

The release takes the major number: the rename below breaks every
installation of 2.1.0.

Added

  • ReadOnly: Boolean, default False. A read-only switch shows a value the
    user may not change: the pointer, the space bar and a drag of the thumb are
    all closed, while Checked set from code works as always and still raises
    OnChange. It is not Enabled := False — the switch keeps its normal
    colours, stays in the tab order and still takes the focus when clicked. Since
    nothing the user does reaches it, there is no hover highlight and no pressed
    state, and OnClick, which reports a switch that changed, does not fire.

  • An accelerator in the header. &Sound underlines the S, and Alt+S gives the
    switch the focus and toggles it, the way an accelerator works a check box.
    Both halves follow the rules a click follows: the value changes only where the
    keyboard may change it, so KeyboardToggle off or ReadOnly on leaves the
    switch as it was, and the focus is taken only where a click would take it. The
    underline keeps to the convention Windows sets for the window: hidden until
    Alt is pressed, like the focus ring.

  • ParentHeaderFont: Boolean, default True. The header font used to follow
    Font only until something assigned to HeaderFont, and after that there was
    no way back: the flag that remembered it was internal and write-once, so a
    header font touched once in the designer stayed detached for good, with
    nothing in the Object Inspector to say so or undo it. The flag is now a
    property, and putting it back to True returns the header to Font at once.

  • TCustomFluentToggleSwitch, the ancestor that carries the implementation.
    TFluentToggleSwitch descends from it and does nothing but publish
    properties, so a component descending from the custom class can publish its
    own selection or leave a property out. Code using TFluentToggleSwitch is
    unaffected: the class name, the published properties and the .dfm it
    streams are what they were.

  • Right-to-left layout. BiDiMode was published from the start and never
    read, so a switch on a right-to-left form laid itself out left to right. At
    bdRightToLeft the switch is now mirrored, the way WinUI, Android and iOS
    mirror theirs: the thumb rests at the right end while off and travels left
    to turn on, the caption goes to the other side of the track, the header and
    the switch under it align against the other edge, and both lines are read
    right to left. TextPosition and HeaderAlignment are read the way the
    text runs, as TCheckBox and TLabel read Alignment. The two reading-only
    modes change the reading order alone. As everywhere in the VCL, this takes a
    system set up for a right-to-left language; elsewhere BiDiMode still
    changes nothing.

Changed

  • Breaking. An ampersand in HeaderText is no longer drawn as one. It marks
    the letter after it, and && draws a single ampersand, as in every VCL
    caption. A header that carried a literal ampersand — Sound & vibration —
    now reads Sound vibration with the space underlined, and measures
    narrower, so a switch left at AutoSize changes width with it. Doubling the
    ampersand keeps the old picture: Sound && vibration.

  • Breaking. A compiled package carries the compiler version in its name:
    FluentToggleSwitchR370.bpl under Florence, FluentToggleSwitchR290.bpl
    under Athens, the way RAD Studio names rtl290 and vcl370. Both packages
    used to build as FluentToggleSwitchR.bpl and FluentToggleSwitchD.bpl
    whichever IDE produced them. Inside the IDE that collided with nothing, since
    every version keeps its own Bpl directory, but two applications deployed
    with runtime packages into one directory overwrote each other's copy, and the
    name said nothing about which was which.

  • Each package states what it is for. The runtime package is runtime only and
    no longer appears in Component → Install Packages, where installing it
    registered nothing; the design-time package is design-time only. Their
    descriptions name the role, so the two are no longer identical entries in the
    IDE lists.

  • Both packages build for Win64 as well as Win32, and so do the tests. The
    runtime package targeted Win32 alone while the README promised both, so a
    Win64 application built with runtime packages had nothing to link against.
    The component source needed no change for it — no pointer casts, no
    assembler, no platform conditionals — and the tests pass on both platforms.
    The Win64 design-time package installs into the 64-bit IDE of Florence.

  • Both packages are set to explicit rebuild, the way component libraries
    ship: a project that requires them no longer rebuilds them under its own
    settings.

  • The version resource of both packages is filled in: company, product and
    copyright as they read in LICENSE, a description naming the package, and a
    comment pointing at the repository. The properties of a .bpl now say who
    made it and under what licence — which is worth something, since the file
    travels without LICENSE beside it.

Upgrading from 2.1.0

The .bpl files are renamed, so the IDE still has the old ones registered.

  1. Under Component → Install Packages remove the entry without a version
    suffix, FluentToggleSwitchD.bpl, and FluentToggleSwitchR.bpl if it is
    listed there too.
  2. Delete FluentToggleSwitchR.bpl and FluentToggleSwitchD.bpl — the ones
    without a suffix — from $(BDSCOMMONDIR)\Bpl. Nothing rebuilds them any
    more, and while they are there a project asking for the package by name can
    still find them. The .dcp, .bpi and .lib in $(BDSCOMMONDIR)\Dcp
    keep their names: the suffix applies to the .bpl alone, so those files are
    simply overwritten and must stay.
  3. Build and install the packages again, as in Installing in the README.

Version 2.1.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 18 Sep 10:13

Changed

  • Both packages now leave their .dcu in .\$(Platform)\$(Config), beside the
    package itself, instead of $(BDSCOMMONDIR)\Dcp. The old directory is on the
    library path by default, which is why installing the packages used to be
    enough on its own; it is also shared by every platform and configuration, so
    Win32 and Win64, Debug and Release wrote .dcu of the same names over each
    other and the last build won. The setting came from the IDE template and was
    never a decision.

    Projects now compile the component from source under their own compiler
    settings, the way the other component libraries for Delphi work, rather than
    linking .dcu built with the package's settings.

  • The leak monitor of the test project follows DUnitX through a rename of its
    own: Florence ships DUnitX.ServiceLocator with TDUnitXServiceLocator,
    Athens ships DUnitX.IoC with TDUnitXIoC. The unit picks one by compiler
    version, so the tests build on both. Nothing outside tests/ is affected.

Upgrading from 2.0.0

Installing the packages no longer makes the unit visible on its own.

  1. Add the source directory of this release to the library path, under
    Tools | Options | Language | Delphi | Library, for every platform you
    build for. Without it projects stop finding Fluent.ToggleSwitch.
  2. Delete what the old layout left behind:
    $(BDSCOMMONDIR)\Dcp\Fluent.ToggleSwitch*.dcu. While those files are
    there the compiler keeps finding them, and the change appears to have done
    nothing.

Nothing in the component itself changed: same unit, same class, same
properties.

Version 2.0.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 17 Sep 15:35
ddd42c8

The switch answers the keyboard, carries a header, and follows the accent colour while the program runs.

This is not a drop-in replacement for 1.6. The unit and the package are renamed, the package is split in two, and two events mean something different. The upgrade steps are at the end of the changelog entry.

Demo

Breaking

  • The unit is Fluent.ToggleSwitch, the enumerations are TFluentTextPosition and TFluentHeaderPosition, and the palette page is Fluent. The class keeps its name.
  • One package became two: FluentToggleSwitchR holds the component and builds for Win32 and Win64, FluentToggleSwitchD is what you install into the IDE. A program using the component no longer drags designide behind it.
  • OnChange reports the value and fires for an assignment in code as well as for the user.
  • OnClick reports the action: only on a real toggle, and after the value has moved.
  • The colour properties default to clDefault rather than clNone.
  • TextSpacing defaults to 12 and is measured from the track outline.
  • The switch measures 42 by 22 rather than 44 by 24.
  • TabStop defaults to True.

Added

The space bar toggles the switch, with KeyboardToggle to turn that off. A focus ring that follows the Windows convention, hidden until someone navigates by keyboard, with ShowFocus to opt out. A header above or below the switch with six properties of its own, described by ShowHeader, HeaderText, HeaderPosition, HeaderAlignment, HeaderSpacing and HeaderFont. A baseline handed to the form designer, published even with the caption hidden. The Windows accent colour followed while the program runs. A palette icon, a public TextTop, and a full API reference.

Fixed

TextSpacing was not scaled for the display. A gesture the system takes back, whether a modal dialog, the switch being disabled, or another window taking the capture, is now dropped rather than carried through. A drag begun while the thumb was still travelling counted from the wrong place. Freeing the switch from its own handler is safe.

Performance

The animation timer sits on the window the switch already has. It used to be a TTimer, which allocates a hidden window, and a passing pointer was enough to create one per switch. The layout is worked out once per event rather than once per property.

Installing

Build FluentToggleSwitchR, then build and install FluentToggleSwitchD. The component appears on the Fluent palette page.

Known limitations

Dark surfaces and VCL styles (#10), TAction (#11), right-to-left layout (#12), accessibility (#13), a header outside the control's window (#14), and four smaller API gaps (#15).

Version 1.6.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 10 Sep 09:03
b7eef0c

What's Changed

Added

  • Package version — the package reported 1.0.0.0 no matter which release was installed. The number is now stamped into the compiled package and into its description, so the installed version is listed in Component → Install Packages without opening any file

Changed

  • The switch is mouse-only — it no longer takes focus. Clicking it leaves focus where it was, and TabStop defaults to False, so the Tab key skips it. It already ignored the keyboard and drew no focus indicator, so the focus it held was invisible and did nothing

Upgrading

TabStop stays published, so forms that stored it explicitly still load. If something relied on clicking the switch to move focus off an edit, and so to fire that edit's OnExit, it will no longer happen.

Full Changelog: v1.5.0...v1.6.0

Version 1.5.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 09 Sep 23:52
257f4e0

What's Changed

A performance pass over the component. Behavior and appearance are unchanged.

Changed

  • Per-frame allocations — a frame built a path, up to four brushes and a pen. At 60 frames per second that is roughly 450 GDI+ allocations per second per animating switch. It now builds one path, one brush and one pen per frame and recolors them for each shape. They stay local to the paint: the GDI+ wrapper unit shuts the library down in its finalization, which runs before the forms are freed, so objects held in fields would be deleted after GDI+ is gone
  • Animation timer — every instance created a timer, and with it a hidden window, even when nothing ever animated. It is created on first use now
  • Hidden controls — animations are skipped while the switch is not showing, for example on an inactive tab page. The state applies immediately instead
  • Text metrics — height is measured when the font or the text changes rather than on every frame, and the font is assigned to the canvas once per paint instead of twice. Vertical centering now uses the same metric as the auto-sizing, which for some fonts disagreed with it
  • Pixel alignment — the track sits on whole pixels, so its outline stays crisp when the text makes the control an odd number of pixels tall
  • Transparent shapes — fills and strokes with zero alpha are skipped rather than rasterized

Tests

  • Rendering through PaintTo is covered, and a loop creates, renders and frees fifty instances so FastMM4 covers the drawing objects

Full Changelog: v1.4.0...v1.5.0

Version 1.4.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 09 Sep 23:37
4cdaf1d

What's Changed

Animation and accent color now follow the WinUI 3 template instead of approximating it.

Changed

  • Slide timing — the thumb waits 33 ms, then slides for 367 ms along the cubic Bezier curve 0.1,0.9 0.2,1.0, replacing the previous 150 ms ease-out. AnimationDuration now defaults to 367. The curve is front-loaded, covering 90% of the travel in the first 120 ms
  • State transitions — hover, press and disabled changes cross-fade over 83 ms (250 ms into disabled) instead of taking effect instantly. Thumb size and position animate together with the colors, and interrupting a transition no longer jumps
  • Accent color — the On track uses the accent color configured in Windows, read from the system palette, falling back to #0067C0 (the Windows 11 default). The previous #0078D4 is the base accent, not the shade the light theme calls for, and #005A9E came from the Windows 10 palette
  • Hover and press on the On track — these now lighten the track toward the background by lowering opacity to 0.9 and 0.8. They previously darkened it, the opposite of the WinUI behavior

Fixed

  • A click that nudged the pointer by less than the drag threshold left the thumb permanently offset by those few pixels
  • Disabling the component while it was pressed left it stuck in the pressed state, because a disabled window never receives the matching mouse release
  • A DPI change measured the layout once at the old scale before correcting itself

Full Changelog: v1.3.0...v1.4.0

Version 1.3.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 09 Sep 23:03
8baca61

What's Changed

Visuals and interaction now match the Windows 11 ToggleSwitch (WinUI 3, Light theme). See #5.

Added

  • Thumb dragging — the thumb can be dragged within the track; releasing it past the middle switches the state, otherwise it snaps back
  • Pressed thumb — stretches into a 17×14 pill hugging the track edge, as in WinUI 3

Changed

  • Off-state colors — translucent fill, stroke and thumb from the WinUI 3 Light theme, blended over the parent background; hover darkens the track fill instead of the stroke and thumb
  • Transition — Off and On tracks cross-fade instead of interpolating colors
  • Track stroke — centered on the outline and scaled with DPI (was a fixed 1 px inset stroke)
  • OnChange — fires only when the user toggles the switch; setting Checked in code no longer raises it
  • Click area — clicking anywhere on the component, including the text label, toggles it and focuses the control
  • DPI — sizes are recomputed from the base constants on every DPI change

Removed

  • Space and Enter no longer toggle the switch
  • Focus rectangle

Docs

  • Added CHANGELOG.md
  • README updated for the new behavior

Full Changelog: v1.2.0...v1.3.0

Version 1.2.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 13 Mar 10:20

What's Changed

Fixes

  • DPI-aware scaling — correct rendering on high-DPI displays (per-monitor V2), scaled geometry fields instead of hard-coded constants
  • AdjustBounds fix — text properties can be set safely before Parent assignment (uses screen DC instead of control Canvas)
  • Keyboard OnClick — Space/Enter now fires OnClick in addition to OnChange
  • Color=clNone fix — background now uses parent color as documented in README
  • Click area — only the track responds to clicks, text label remains passive
  • Compiler warnings resolved — added missing units (System.Types, System.UITypes), removed unused variables

Tests

  • New tests: handle guard (no-parent scenario), toggle logic, OnChange event firing, default state

Docs

  • Added DPI-aware feature to README
  • Updated platform to Win32/Win64
  • Added demo screenshot

Demo

  • Dynamic layout — positions calculated from control heights, no overlap on high-DPI

Full Changelog: v1.1.0...v1.2.0

Version 1.1.0

Choose a tag to compare

@Abduction-Lamp Abduction-Lamp released this 12 Mar 21:22

Added

  • Customizable colors — 5 new published properties (TrackFrameColor, TrackColorOff, TrackColorOn, ThumbColorOff, ThumbColorOn) to override the default WinUI 3 color scheme. Set to clNone (default) to use built-in colors
  • Text label — optional text next to the toggle with 5 new properties (ShowText, TextOn, TextOff, TextPosition, TextSpacing) and a new TTextPosition enum (tpLeft, tpRight). The component auto-adjusts its width based on text content
  • Font property — re-published Font for text label rendering via Object Inspector
  • DUnitX tests — 17 unit tests covering color properties, text properties, auto-sizing, and input validation

Fixed

  • Click area is now restricted to the track — clicking the text label does not toggle the switch
  • Component correctly recalculates bounds after DPI scaling (ChangeScale override)
  • Negative TextSpacing values are clamped to 0
  • Test runner always waits for user input before closing the console window
  • FastMM4 is now conditionally compiled ({$IFDEF FASTMM})

Installation

  1. Open ToggleSwitch-PG.groupproj in Delphi IDE
  2. In Project Manager: right-click ToggleSwitch.bpl → Compile → Install
  3. Done — use TFluentToggleSwitch in any project

Full Changelog: v1.0.1...v1.1.0