Namespace: Beep.Skia.Controls — Inherits: Slider → MaterialControl → SkiaComponent • ProgressBar → MaterialControl → SkiaComponent

Overview

The Slider and ProgressBar controls provide Material Design 3.0 range input and progress feedback, rendered entirely with SkiaSharp. Slider lets users select a value from a range by dragging a thumb along a track, with optional tick marks and a value label. ProgressBar displays a determinate fill percentage or an indeterminate animated stripe to indicate ongoing activity.

Both controls use the active Material theme for track, thumb, and fill colors. The slider thumb scales up on press (with a ripple effect) and the progress bar supports a smooth fill animation when the value changes programmatically.

Snap to Steps

Slider supports an optional Step increment for discrete value snapping with visual tick marks.

Range Mode

Slider can render a two-thumb range selector for choosing a min/max interval.

Indeterminate Animation

ProgressBar's indeterminate mode draws a continuously animating stripe that loops horizontally.

Orientation

Both controls support horizontal and vertical orientations.

Slider Properties

PropertyTypeDescription
Min float Minimum value of the slider range. Default is 0.
Max float Maximum value of the slider range. Default is 100.
Value float Current value. Clamped to [Min, Max]. Setting this programmatically moves the thumb and updates the track fill proportionally.
Step float Snap increment. When > 0, the value snaps to the nearest multiple of Step. Tick marks are rendered at each step interval. Default is 0 (continuous).
Orientation SKOrientation Horizontal (default) or Vertical. Determines the track axis and thumb movement direction. Vertical sliders have their track drawn top-to-bottom.
ThumbSize float Diameter of the circular thumb. Default is 20f. The thumb scales to 24f on press/hover with an animated transition.
TrackThickness float Thickness of the track line. Default is 4f for the inactive portion and 6f for the active (filled) portion.
ShowValueLabel bool When true, a floating label showing the current value appears above the thumb while dragging. Default is true.
ValueFormat string Format string applied to the value label. Default is "0" (integer). Use "0.0" for one decimal, "0%" for percentage.
IsRange bool When true, the slider renders two thumbs for selecting a min/max range. Default is false.
RangeStart float Second thumb value for range mode. Used when IsRange is true.
ShowTickMarks bool When true and Step > 0, small tick marks are rendered along the track at each step position. Default is true.
IsHovered bool Read-only. Whether the mouse is over the slider's touch target area.
IsDragging bool Read-only. Whether the thumb is currently being dragged via pointer.

ProgressBar Properties

PropertyTypeDescription
Value float Current progress value. Clamped to [0, Max]. The filled portion of the track is Value / Max * Width. Ignored when IsIndeterminate is true.
Max float Maximum value. Default is 100. Use 1.0 for 0–1 normalized progress.
IsIndeterminate bool When true, the progress bar displays a continuously animating stripe instead of a determinate fill. The stripe moves horizontally on a loop.
Style ProgressBarStyle Enum: Linear (default, horizontal bar) or Circular (a circular arc indicator). Circular style renders as an SVG-like arc.
TrackThickness float Thickness of the progress bar track. Default is 4f for linear, 4f (stroke width) for circular.
CornerRadius float Rounding of the linear track ends. Default is 2f (half of track thickness for fully rounded caps).
FillColor SKColor Override color for the filled portion. When not set, uses Primary from the active theme.
TrackColor SKColor Override color for the unfilled track. When not set, uses SurfaceVariant from the active theme.
AnimationDuration float Duration in milliseconds for the smooth fill animation when Value changes. Default is 300. Set to 0 for instant updates.

Circular ProgressBar

When Style = ProgressBarStyle.Circular, the control renders as a circular arc. Additional properties apply:

PropertyTypeDescription
ArcStartAnglefloatStarting angle in degrees for the arc. Default is -90 (top).
ArcSweepAnglefloatThe total sweep of the full arc in degrees. Default is 360.

Events

EventOwnerSignatureDescription
ValueChanged Slider EventHandler<float> Raised as the slider value changes during drag or programmatic assignment. Fires continuously during dragging for live feedback.
DragStarted Slider EventHandler Raised when the user begins dragging the thumb (pointer down on thumb).
DragEnded Slider EventHandler Raised when the user releases the thumb (pointer up). The value is finalized.
ValueChanged ProgressBar EventHandler<float> Raised when the animated value reaches its target. Not raised continuously; only at completion of the animation.

Code Example

Continuous Slider with Value Label

var opacitySlider = new Slider
{
    Min = 0,
    Max = 100,
    Value = 75,
    ShowValueLabel = true,
    ValueFormat = "0%",
    X = 40, Y = 40,
    Width = 300, Height = 56
};

opacitySlider.Initialize();
opacitySlider.ValueChanged += (s, val) =>
    Console.WriteLine($"Opacity: {val}%");

drawingManager.AddComponent(opacitySlider);
drawingManager.RequestRedraw();

Stepped Slider with Tick Marks

var fontSizeSlider = new Slider
{
    Min = 8,
    Max = 48,
    Value = 16,
    Step = 4,
    ShowTickMarks = true,
    ShowValueLabel = true,
    ValueFormat = "0px",
    X = 40, Y = 120,
    Width = 300, Height = 56
};

fontSizeSlider.Initialize();
fontSizeSlider.ValueChanged += (s, val) =>
{
    int fontSize = (int)val;
    textLabel.FontSize = fontSize;
    textLabel.Invalidate();
};

drawingManager.AddComponent(fontSizeSlider);

Vertical Slider

var volumeSlider = new Slider
{
    Min = 0,
    Max = 100,
    Value = 65,
    Orientation = SKOrientation.Vertical,
    ShowValueLabel = true,
    X = 380, Y = 40,
    Width = 56, Height = 200
};

volumeSlider.Initialize();
volumeSlider.ValueChanged += (s, val) =>
    Console.WriteLine($"Volume: {val}");

drawingManager.AddComponent(volumeSlider);

Determinate and Indeterminate ProgressBars

var determinateBar = new ProgressBar
{
    Value = 65,
    Max = 100,
    Style = ProgressBarStyle.Linear,
    AnimationDuration = 500,
    X = 40, Y = 260,
    Width = 350, Height = 8
};

determinateBar.Initialize();

var indeterminateBar = new ProgressBar
{
    IsIndeterminate = true,
    Style = ProgressBarStyle.Linear,
    X = 40, Y = 290,
    Width = 350, Height = 8
};

indeterminateBar.Initialize();

drawingManager.AddComponent(determinateBar);
drawingManager.AddComponent(indeterminateBar);

Circular ProgressBar

var circularProgress = new ProgressBar
{
    Value = 72,
    Max = 100,
    Style = ProgressBarStyle.Circular,
    TrackThickness = 6,
    X = 460, Y = 40,
    Width = 80, Height = 80
};

circularProgress.Initialize();

var circularIndeterminate = new ProgressBar
{
    IsIndeterminate = true,
    Style = ProgressBarStyle.Circular,
    TrackThickness = 6,
    X = 460, Y = 140,
    Width = 80, Height = 80
};

circularIndeterminate.Initialize();

drawingManager.AddComponent(circularProgress);
drawingManager.AddComponent(circularIndeterminate);

Range Slider (Two Thumbs)

var priceRange = new Slider
{
    Min = 0,
    Max = 1000,
    Value = 200,
    IsRange = true,
    RangeStart = 800,
    ValueFormat = "$0",
    ShowTickMarks = true,
    Step = 50,
    X = 40, Y = 340,
    Width = 380, Height = 56
};

priceRange.Initialize();
priceRange.ValueChanged += (s, val) =>
    Console.WriteLine($"Range: ${priceRange.RangeStart} - ${val}");

drawingManager.AddComponent(priceRange);
drawingManager.RequestRedraw();

Tip

For real-time feedback during slider drag, subscribe to ValueChanged and update dependent components immediately. The slider's IsDragging property can be checked to distinguish programmatic changes from user interaction. Use DragEnded for expensive operations that should only fire once when the user finishes adjusting.