Stroke Kind Guide
The stroke kind components let users choose a line style (TTMSFNCGraphicsStrokeKind) for use with graphics strokes, pens, or drawing tools. Two controls serve this purpose:
| Component | Presentation |
|---|---|
TTMSFNCStrokeKindSelector |
An always-visible grid showing all stroke pattern samples |
TTMSFNCStrokeKindPicker |
A compact control that opens the selector in a dropdown |
Available stroke kinds include: gskSolid, gskDash, gskDot, gskDashDot, gskDashDotDot, and gskNone.
Using the selector
The selector displays all items in a grid. Read SelectedStrokeKind to get the current choice, or handle OnStrokeKindSelected to react immediately.
// TTMSFNCStrokeKindSelector shows all available stroke patterns in a grid.
// Read or set the selected kind via SelectedStrokeKind.
TMSFNCStrokeKindSelector1.SelectedStrokeKind := gskSolid;
procedure TForm1.TMSFNCStrokeKindSelector1StrokeKindSelected(Sender: TObject;
AStrokeKind: TTMSFNCGraphicsStrokeKind);
begin
// Apply the chosen stroke kind to a drawing stroke
ShapeStroke.Kind := AStrokeKind;
Panel1.Invalidate;
end;
Using the picker
The picker is suited to toolbars where space is limited. Setting CloseOnSelection := True collapses the dropdown automatically after a choice is made.
// TTMSFNCStrokeKindPicker opens the selector in a dropdown.
// Connect it to a graphics stroke via OnStrokeKindSelected.
TMSFNCStrokeKindPicker1.SelectedStrokeKind := gskDash;
TMSFNCStrokeKindPicker1.CloseOnSelection := True;
procedure TForm1.TMSFNCStrokeKindPicker1StrokeKindSelected(Sender: TObject;
AStrokeKind: TTMSFNCGraphicsStrokeKind);
begin
TMSFNCRichEditor1.Pen.Kind := AStrokeKind;
end;
Combining selector and picker
When the application shows both a settings panel (selector) and a toolbar (picker), keeping their SelectedStrokeKind in sync provides a consistent UI.
// Use selector and picker together: selector previews all choices in-place,
// picker saves space in a toolbar. Both share the same selected kind.
procedure TForm1.FormCreate(Sender: TObject);
begin
TMSFNCStrokeKindSelector1.SelectedStrokeKind := gskSolid;
TMSFNCStrokeKindPicker1.SelectedStrokeKind := gskSolid;
// Keep them in sync when the selector changes
TMSFNCStrokeKindSelector1.OnStrokeKindSelected := SelectorKindChanged;
end;
procedure TForm1.SelectorKindChanged(Sender: TObject;
AStrokeKind: TTMSFNCGraphicsStrokeKind);
begin
TMSFNCStrokeKindPicker1.SelectedStrokeKind := AStrokeKind;
ApplyStrokeKindToCanvas(AStrokeKind);
end;
Sizing for high-DPI displays
Rows and Columns are counts, so they are never rescaled - the grid keeps its
shape and the cells grow with the display scale. The measurements that are
rescaled are the selector's Appearance.HorizontalSpacing / VerticalSpacing
and Appearance.Font, and the picker's DropDownWidth / DropDownHeight.
Assign all of those in design units once, before the first paint, and let
the DPI pass grow them; assigning already-scaled values scales them twice.
uses
System.SysUtils, FMX.TMSFNCUtils, FMX.TMSFNCCustomSelector,
FMX.TMSFNCStrokeKindSelector, FMX.TMSFNCStrokeKindPicker;
procedure TForm1.ApplyStrokeKindMetrics;
begin
TMSFNCStrokeKindSelector1.BeginUpdate;
try
{ Rows and Columns are counts, so they are never rescaled: the grid keeps
its shape and the cells grow with the display scale. }
TMSFNCStrokeKindSelector1.Columns := 3;
TMSFNCStrokeKindSelector1.Rows := 2;
{ The selector rescales Appearance.HorizontalSpacing, VerticalSpacing and
Appearance.Font when the display scale changes, so these are design
values - assign them once, before the first paint. }
TMSFNCStrokeKindSelector1.Appearance.HorizontalSpacing := 4;
TMSFNCStrokeKindSelector1.Appearance.VerticalSpacing := 4;
TMSFNCStrokeKindSelector1.Appearance.Font.Size := 10;
finally
TMSFNCStrokeKindSelector1.EndUpdate;
end;
TMSFNCStrokeKindPicker1.BeginUpdate;
try
{ The picker rescales DropDownWidth and DropDownHeight in the same pass,
so give it the design-DPI box and let the pass grow it. }
TMSFNCStrokeKindPicker1.DropDownWidth := 180;
TMSFNCStrokeKindPicker1.DropDownHeight := 120;
TMSFNCStrokeKindPicker1.CloseOnSelection := True;
finally
TMSFNCStrokeKindPicker1.EndUpdate;
end;
if TTMSFNCUtils.IsHighDPIScale(Self) then
StatusLabel.Text := Format('Stroke kind grid laid out at %.2fx',
[TTMSFNCUtils.GetDPIScale(Self)]);
end;