tryst-segmented
Version, currently 0.1.02 versions
- 0.1.0latestSep 1, 2026
- main branchAug 28, 2026
github.com/jamescook/tryst-segmented
An iOS/web-style segmented control for tryst - a rounded pill row of mutually exclusive options with a sliding accent highlight, replacing a line of ttk radio buttons. Built on Tryst::OwnerDrawnWidget and rendered through tryst-vector.
Installation
# Add this to your shard.yml
dependencies:
tryst-segmented:
github: jamescook/tryst-segmented
version: ~> 0.1.0Then run:
shards installshard.yml
- Crystal
>= 1.21.0- License
- MIT
- Author
- James Cook
Dependencies
Runtime Dependencies
- tryst~> 0.1github: jamescook/tryst
- tryst-vector~> 0.1github: jamescook/tryst-vector
Development Dependencies
- ameba*github: crystal-ameba/ameba, tag: v1.7.0dev
README
tryst-segmented
An iOS/web-style segmented control for tryst, Crystal's Tcl/Tk
binding — a rounded pill of mutually exclusive text options with a
sliding highlight, in place of a row of ttk radio buttons. Built on
Tryst::OwnerDrawnWidget and rendered through
tryst-vector.
require "tryst"
require "tryst-segmented"
app = Tryst::App.new
control = Tryst::SegmentedControl.new(app, options: ["Day", "Week", "Month", "Year"], selected: "Week")
control.pack(padx: 16, pady: 8)
control.on_action { |value| puts "now on #{value}" }
app.show
app.mainloop

API
Constructor
options— the segment labels, left to right. Must be non-empty and contain no duplicates.selected— starts onoptions.firstif not given; must be one ofoptions.accent— a#rrggbbhex string to override the theme's own accent color.disabled_dim— how much the accent/text dim when the whole control is disabled (0.0–1.0, default0.45).height— the pill's height in logical pixels. Segment width comes from each label's own text, not fromheight— segments are never forced to equal width.
Instance methods
#selected/#selected=— read or set the current selection.#selected=never fires#on_action.#on_action { |value| ... }— fires on every user-driven change (click, Left/Right), never for a programmatic#selected=.#disable_segment(option)/#enable_segment(option)/#segment_disabled?(option)— disable one segment without affecting the rest of the control. Independent of#disabled=(inherited, disables the whole control).
Interaction: click a segment, or Tab into the control and use Left/Right (clamped at either end, skipping any disabled segments).
There's no ui.segmented/DSL bind: — like Switch and
ValueSlider, this lives at the App layer, not as a registered
WidgetType (see CUSTOM_WIDGETS.md). Wire a
Tryst::UI::Var manually:
control.on_action { |v| var.value = v }
var.on_change { |v| control.selected = v }
Requirements
Whatever tryst and tryst-vector need — Crystal >= 1.21.0, Tcl/Tk 8.6, and ThorVG >= 1.0 (see tryst-vector's own README).
Examples
crystal run examples/segmented_control_demo.cr
Tests
shards install
crystal spec # host
scripts/docker-test.sh # Debian forky, same suite
scripts/docker-test.sh builds from this repo's own root; shards install inside the image fetches tryst and tryst-vector directly via
their github: dependencies. It takes the same arguments crystal spec does, so a focused run works there too.
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.1.0- Tagged
- Sep 1, 2026
- Commit
b9155a54ef31- Crystal
>= 1.21.0- Indexed
- yes
Dependents
Repository
github.com/jamescook/tryst-segmented
Metadata
- Created
- Aug 29, 2026
- Updated
- Sep 23, 2026
- Synced
- Sep 22, 2026
- Versions
- 2