Progress and rating
TTMSFNCProgressBar displays a horizontal or vertical fill that represents a numeric value between Minimum and Maximum. The same base class powers TTMSFNCRating, which divides the bar into discrete blocks so users can tap or drag to set a star-style rating.
Basic usage
Set Minimum, Maximum, and Value at design time or runtime. The bar redraws immediately when Value changes:
// Show progress of a background operation
procedure TForm1.StartOperation;
begin
TMSFNCProgressBar1.Minimum := 0;
TMSFNCProgressBar1.Maximum := 100;
TMSFNCProgressBar1.Value := 0;
end;
procedure TForm1.UpdateProgress(APercent: Integer);
begin
TMSFNCProgressBar1.Value := APercent;
end;
Shape and segmented display
Layout.Shape switches between psHorizontalLine (default) and psVerticalLine. Layout.Blocks splits the filled area into equal segments with Layout.Spacing pixels of gap between them:
TMSFNCProgressBar1.Layout.Shape := psVerticalLine;
TMSFNCProgressBar1.Layout.Blocks := 8;
TMSFNCProgressBar1.Layout.Spacing := 2;
Displaying the value label
Set Layout.ShowValue to True to draw a text label. Layout.ValueType controls the content:
| Value | Label shows |
|---|---|
pvtPercentage |
Percentage of the range (default) |
pvtValue |
The raw numeric Value |
pvtCustom |
The string you assign to CustomValue |
Position the label with Layout.TextPosition (ptpStart, ptpCenter, ptpEnd, ptpProgressEnd, ptpFollowCenter, ptpFollowEnd, ptpProgressCenter). Rotate the label with Layout.TextOrientation (ptoHorizontal, ptoLeft, ptoRight, ptoUpsideDown).
Add Layout.Prefix and Layout.Suffix strings to wrap the label, for example '%'.
Appearance and threshold levels
Appearance.Fill styles the filled (active) portion; Appearance.DefaultLevelFill styles the unfilled (inactive) background. Use the Levels collection to change colour automatically when Value crosses a threshold:
// Vertical segmented bar with percentage label
procedure TForm1.ConfigureProgressBar;
begin
with TMSFNCProgressBar1 do
begin
// Five equal blocks with gaps between them
Layout.Blocks := 5;
Layout.Spacing := 3;
Layout.Shape := psVerticalLine;
// Label: "72%" centred inside the filled area
Layout.ShowValue := True;
Layout.ValueType := pvtPercentage;
Layout.Decimals := 0;
Layout.Suffix := '%';
Layout.TextPosition := ptpCenter;
// Progress fill colour and background
Appearance.Fill.Color := $0015A34A;
Appearance.DefaultLevelFill.Color := $00E0E0E0;
end;
end;
// Threshold-based colour change using Levels
procedure TForm1.AddLevels;
var
L: TTMSFNCCustomProgressBarLevel;
begin
TMSFNCProgressBar1.Levels.Clear;
L := TTMSFNCCustomProgressBarLevel(TMSFNCProgressBar1.Levels.Add);
L.LevelPosition := 50; // switches at 50 %
L.Fill.Color := $000080FF; // blue above 50 %
L := TTMSFNCCustomProgressBarLevel(TMSFNCProgressBar1.Levels.Add);
L.LevelPosition := 80;
L.Fill.Color := $00E53935; // red above 80 %
end;
Appearance.Stacked makes multiple levels stack visually from left to right rather than replacing each other.
Rating control
TTMSFNCRating shares the same base API. Set Layout.Blocks to the number of rating steps and enable interaction:
| Property | Effect |
|---|---|
Interaction.SnapToValue |
Click snaps to the nearest block |
Interaction.SlideToValue |
Drag slides to a new rating |
Interaction.KeyboardSupport |
Arrow keys change the value |
Interaction.ReadOnlyMode |
Disables all mouse and keyboard input |
// Five-star interactive rating control
procedure TForm1.ConfigureRating;
begin
with TMSFNCRating1 do
begin
Minimum := 0;
Maximum := 5;
Value := 0;
// Five discrete star blocks; click to snap to nearest integer
Layout.Blocks := 5;
Layout.Spacing := 4;
Layout.ShowValue := False;
// Allow the user to drag or click a new rating
Interaction.SnapToValue := True;
Interaction.SlideToValue := True;
Interaction.KeyboardSupport := True;
end;
end;
// React when the user changes the rating
procedure TForm1.TMSFNCRating1ValueChanged(Sender: TObject; AValue: Single);
begin
StatusLabel.Text := Format('Rating: %.0f / 5', [AValue]);
end;
Use OnSlideValueChanged, OnSnapValueChanged, or OnKeyboardValueChanged to react after a change, and their *Change counterparts (with var AAllow: Boolean) to cancel one.
Custom draw hook
OnBeforeDrawBlock fires before each block is rendered and lets you fully replace its drawing by setting ADefaultDraw := False. OnBeforeDrawValue fires before the label and receives the current text string so you can override it:
procedure TForm1.TMSFNCProgressBar1BeforeDrawBlock(Sender: TObject;
AGraphics: TTMSFNCGraphics; ARect: TRectF;
ACorners: TTMSFNCGraphicsCorners;
var AAllow, ADefaultDraw: Boolean);
begin
AGraphics.Fill.Color := $00FF9800;
ADefaultDraw := True; // let the bar draw, but fill colour is already set
end;
Combining blocks, levels, and a custom label
The example below builds a segmented upload indicator that changes colour at 75 % and 90 % and shows a "12 MB / 50 MB" label using pvtCustom:
// Segmented upload progress bar with threshold colours and a custom label
procedure TForm1.FormCreate(Sender: TObject);
begin
with TMSFNCProgressBar1 do
begin
Minimum := 0;
Maximum := 100;
Value := 0;
Layout.Blocks := 10;
Layout.Spacing := 2;
Layout.Shape := psHorizontalLine;
Layout.ShowValue := True;
Layout.ValueType := pvtCustom; // controlled via OnBeforeDrawValue
Layout.TextPosition := ptpCenter;
// Base fill (0–50 %)
Appearance.Fill.Color := $00519657;
// Amber above 75 %
with TTMSFNCCustomProgressBarLevel(Levels.Add) do
begin
LevelPosition := 75;
Fill.Color := $00E69820;
end;
// Red above 90 %
with TTMSFNCCustomProgressBarLevel(Levels.Add) do
begin
LevelPosition := 90;
Fill.Color := $00C62828;
end;
end;
end;
// Supply a friendly "12 MB / 50 MB" label instead of a percentage
procedure TForm1.TMSFNCProgressBar1BeforeDrawValue(Sender: TObject;
AGraphics: TTMSFNCGraphics; AText: string; ARect: TRectF;
APosition: TTMSFNCProgressBarTextPosition;
AOrientation: TTMSFNCProgressBarTextOrientation;
var AAllow: Boolean; var ADefaultDraw: Boolean);
begin
TMSFNCProgressBar1.CustomValue :=
Format('%d MB / %d MB',
[Round(TMSFNCProgressBar1.Value / TMSFNCProgressBar1.Maximum * 50), 50]);
end;