# FTRRangeSlider – Customer Usage Guide

## Overview

`FTRRangeSlider` is a dual-thumb range slider for selecting a minimum and maximum value on a single track.

It is useful when an application needs to let the user select a range, such as:

* Minimum and maximum price
* Minimum and maximum age
* Temperature range
* Distance range
* Percentage range
* Quantity range
* Any other numeric interval

The control provides two independent thumbs:

* **Left thumb** — represents the lower value.
* **Right thumb** — represents the upper value.

The selected range is displayed between the two thumbs.

**Namespace:** `FTRControls`

**Toolbox:** FTR Controls

**Default event:** `ValuesChanged`

---

# Basic Usage

After adding the FTR Controls assembly to your Windows Forms project, add `FTRRangeSlider` to your form from the Visual Studio toolbox.

The control can also be created programmatically.

### Example

```csharp
var range = new FTRRangeSlider
{
    Minimum = 0,
    Maximum = 100,
    ValueLeft = 20,
    ValueRight = 80
};

Controls.Add(range);
```

This creates a range from `20` to `80` within an overall range of `0` to `100`.

---

# Default Configuration

When the control is created, its main defaults are:

| Property           |    Default |
| ------------------ | ---------: |
| `Minimum`          |        `0` |
| `Maximum`          |      `100` |
| `ValueLeft`        |       `20` |
| `ValueRight`       |       `80` |
| `Step`             |        `1` |
| `ShowValueTooltip` |     `true` |
| `ValueSuffix`      |       `""` |
| `SmoothScrolling`  |     `true` |
| `ShowTicks`        |    `false` |
| `TickFrequency`    |       `10` |
| `TrackHeight`      |        `6` |
| `ThumbSize`        |       `16` |
| Default size       | `200 × 35` |

The actual thumb and track dimensions may be adjusted automatically for high-DPI displays.

---

# Understanding the Range

## Minimum

`Minimum` defines the lowest value that can be selected.

Default:

```text
0
```

Example:

```csharp
range.Minimum = 0;
```

---

## Maximum

`Maximum` defines the highest value that can be selected.

Default:

```text
100
```

Example:

```csharp
range.Maximum = 1000;
```

The control keeps the configured range valid.

If `Maximum` is set lower than `Minimum`, the control automatically adjusts `Maximum` so that it is not below `Minimum`.

---

# Setting the Two Values

## ValueLeft

`ValueLeft` represents the value of the left/lower thumb.

Default:

```text
20
```

Example:

```csharp
range.ValueLeft = 25;
```

The value cannot be:

* Lower than `Minimum`
* Higher than `ValueRight`

If an invalid value is assigned, the control automatically adjusts it to the nearest valid value.

For example:

```csharp
range.ValueLeft = 90;
```

when:

```text
ValueRight = 80
```

results in:

```text
ValueLeft = 80
```

---

## ValueRight

`ValueRight` represents the value of the right/upper thumb.

Default:

```text
80
```

Example:

```csharp
range.ValueRight = 90;
```

The value cannot be:

* Higher than `Maximum`
* Lower than `ValueLeft`

For example:

```csharp
range.ValueRight = 10;
```

when:

```text
ValueLeft = 20
```

results in:

```text
ValueRight = 20
```

This guarantees that:

```text
ValueLeft <= ValueRight
```

at all times.

---

# Example: Price Range

A common use case is selecting a price range.

```csharp
var priceRange = new FTRRangeSlider
{
    Minimum = 0,
    Maximum = 10000,
    ValueLeft = 1000,
    ValueRight = 5000,
    ValueSuffix = " $"
};
```

The user can now select a minimum and maximum price between `$0` and `$10,000`.

---

# Step

`Step` defines the increment used when changing values with the keyboard or when dragging a thumb.

Default:

```text
1
```

Example:

```csharp
range.Step = 5;
```

With:

```text
Step = 5
```

values move in increments of approximately:

```text
5, 10, 15, 20, 25, ...
```

The value is snapped to the configured step relative to `Minimum`.

`Step` cannot be less than `1`. If a value below `1` is assigned, the control uses `1`.

Example:

```csharp
range.Step = 0;
```

results in:

```text
Step = 1
```

---

# Mouse Interaction

## Selecting a Thumb

The user can click and drag either thumb.

When the user presses the left mouse button, the control determines which thumb is closer to the click position and selects that thumb for dragging.

If both thumbs are equally close, the side of the click determines which thumb is selected.

This means the user does not have to click exactly on a thumb to begin moving it.

---

## Dragging the Left Thumb

Dragging the left thumb changes `ValueLeft`.

The left thumb can never move beyond the right thumb.

```text
Minimum ──── [Left] ═════════ [Right] ──── Maximum
```

The selected range automatically adjusts as the thumb moves.

---

## Dragging the Right Thumb

Dragging the right thumb changes `ValueRight`.

The right thumb can never move below the left thumb.

```text
Minimum ──── [Left] ═════════ [Right] ──── Maximum
```

---

# Keyboard Control

The slider supports keyboard control when it has focus.

## Left Arrow

Moves the left thumb toward the minimum.

```text
Left Arrow → ValueLeft - Step
```

## Right Arrow

Moves the left thumb toward the maximum.

```text
Right Arrow → ValueLeft + Step
```

The left thumb cannot move beyond the right thumb.

---

## Down Arrow

Moves the left thumb toward the minimum.

```text
Down Arrow → ValueLeft - Step
```

## Up Arrow

Moves the left thumb toward the maximum.

```text
Up Arrow → ValueLeft + Step
```

---

# Controlling the Right Thumb with Shift

Hold `Shift` while using the arrow keys to control the right thumb.

| Key             | Effect                |
| --------------- | --------------------- |
| `Shift + Left`  | Decrease `ValueRight` |
| `Shift + Down`  | Decrease `ValueRight` |
| `Shift + Right` | Increase `ValueRight` |
| `Shift + Up`    | Increase `ValueRight` |

The right thumb cannot move below the left thumb or above `Maximum`.

### Example

With:

```text
ValueLeft  = 20
ValueRight = 80
Step       = 5
```

pressing:

```text
Shift + Right
```

changes the right value to:

```text
85
```

---

# Value Tooltips

## ShowValueTooltip

Controls whether a tooltip is displayed while a thumb is being dragged.

Default:

```text
true
```

Example:

```csharp
range.ShowValueTooltip = true;
```

When dragging the left thumb, the tooltip displays:

```text
Min: 20
```

When dragging the right thumb, it displays:

```text
Max: 80
```

The tooltip disappears when dragging ends.

To disable it:

```csharp
range.ShowValueTooltip = false;
```

---

# ValueSuffix

`ValueSuffix` adds text after the numeric value shown in the tooltip.

Default:

```text
""
```

This is useful for displaying units.

### Percentage

```csharp
range.ValueSuffix = "%";
```

Tooltip example:

```text
Min: 20%
```

### Currency

```csharp
range.ValueSuffix = " $";
```

Tooltip example:

```text
Max: 5000 $
```

### Distance

```csharp
range.ValueSuffix = " km";
```

Tooltip example:

```text
Min: 25 km
```

The suffix is displayed exactly as provided.

---

# Smooth Scrolling — Premium

`SmoothScrolling` controls whether programmatic value changes are visually animated.

Default:

```text
true
```

Example:

```csharp
range.SmoothScrolling = true;
```

When smooth scrolling is enabled, changing a value programmatically produces a smooth visual transition toward the new position.

For example:

```csharp
range.ValueLeft = 70;
```

causes the visual thumb to move smoothly toward `70` when it is not being dragged.

When smooth scrolling is disabled:

```csharp
range.SmoothScrolling = false;
```

the visual position changes immediately.

### Important licensing behavior

`SmoothScrolling` is marked as a Premium feature.

The control defaults to smooth scrolling enabled. Without an active Premium license, attempting to explicitly enable the property may display the FTR Controls activation prompt and the requested change is not applied.

Disabling smooth scrolling is allowed.

---

# Tick Marks — Premium

## ShowTicks

Controls whether tick marks are displayed below the slider track.

Default:

```text
false
```

Example:

```csharp
range.ShowTicks = true;
```

When enabled, tick marks are displayed according to `TickFrequency`.

`ShowTicks` requires an appropriate Premium license.

---

## TickFrequency

Defines the numeric interval between tick marks.

Default:

```text
10
```

Example:

```csharp
range.TickFrequency = 10;
```

For a range from `0` to `100`, this produces tick positions corresponding to approximately:

```text
0, 10, 20, 30, ... 100
```

`TickFrequency` cannot be less than `1`.

If a value below `1` is assigned, the control uses `1`.

---

## Large Ranges

For very large ranges, the control automatically reduces the number of rendered tick marks to keep the slider readable.

Therefore, when a very small `TickFrequency` is used over a large range, not every theoretical tick is necessarily displayed.

This behavior does not change the actual `Minimum`, `Maximum`, or selected values.

---

# Appearance

## TrackColor

Controls the color of the unselected slider track.

Example:

```csharp
range.TrackColor = Color.LightGray;
```

---

## SliderColor

Controls the color of the selected range between the two thumbs.

Example:

```csharp
range.SliderColor = Color.DodgerBlue;
```

---

## ThumbColor

Controls the fill color of the two slider thumbs.

Example:

```csharp
range.ThumbColor = Color.White;
```

---

## ThumbBorderColor

Controls the border color of the two slider thumbs.

Example:

```csharp
range.ThumbBorderColor = Color.DodgerBlue;
```

---

## TickColor

Controls the color of tick marks when `ShowTicks` is enabled.

Example:

```csharp
range.TickColor = Color.Gray;
```

---

# Track Height

## TrackHeight

Controls the thickness of the slider track.

Default:

```text
6 pixels
```

Example:

```csharp
range.TrackHeight = 8;
```

The minimum supported value is:

```text
1 pixel
```

Values below `1` are automatically changed to `1`.

---

# Thumb Size

## ThumbSize

Controls the diameter of the two slider thumbs.

Default:

```text
16 pixels
```

Example:

```csharp
range.ThumbSize = 20;
```

The minimum supported value is:

```text
8 pixels
```

Values below `8` are automatically changed to `8`.

The control automatically takes the thumb size into account when calculating the usable track area.

---

# Hover and Focus Appearance

The slider provides visual feedback when the mouse is over a thumb or when the control has keyboard focus.

A subtle glow is displayed around hovered or focused thumbs.

While a thumb is being dragged, the visual emphasis becomes stronger.

These effects are automatic and do not require additional configuration.

---

# ValuesChanged Event

`ValuesChanged` is the default event of `FTRRangeSlider`.

It is raised whenever either `ValueLeft` or `ValueRight` changes.

Example:

```csharp
range.ValuesChanged += (sender, e) =>
{
    label.Text = $"{range.ValueLeft} – {range.ValueRight}";
};
```

A common pattern is to use the event to update other parts of the application's user interface.

---

# Example: Updating Labels

```csharp
var range = new FTRRangeSlider
{
    Minimum = 0,
    Maximum = 100,
    ValueLeft = 20,
    ValueRight = 80
};

range.ValuesChanged += (sender, e) =>
{
    minimumLabel.Text = range.ValueLeft.ToString();
    maximumLabel.Text = range.ValueRight.ToString();
};
```

Whenever either thumb changes, both displayed values are refreshed.

---

# Example: Price Filter

```csharp
var priceRange = new FTRRangeSlider
{
    Minimum = 0,
    Maximum = 5000,
    ValueLeft = 500,
    ValueRight = 2500,
    Step = 100,
    ValueSuffix = " $",
    ShowValueTooltip = true
};

priceRange.ValuesChanged += (sender, e) =>
{
    ApplyPriceFilter(
        priceRange.ValueLeft,
        priceRange.ValueRight);
};
```

This configuration is suitable for a product-price filter.

---

# Example: Percentage Range

```csharp
var percentageRange = new FTRRangeSlider
{
    Minimum = 0,
    Maximum = 100,
    ValueLeft = 20,
    ValueRight = 80,
    Step = 5,
    ValueSuffix = "%",
    ShowValueTooltip = true
};
```

The user can select a percentage range in increments of `5`.

---

# Example: Temperature Range

```csharp
var temperatureRange = new FTRRangeSlider
{
    Minimum = -20,
    Maximum = 50,
    ValueLeft = 5,
    ValueRight = 30,
    Step = 1,
    ValueSuffix = " °C"
};
```

This can be used to select a temperature interval.

---

# Themes

`FTRRangeSlider` integrates with the FTR Controls theme system.

The control supports the following FTR theme modes:

* Light
* Dark
* Color
* Duotone

Theme changes automatically update the slider's theme-dependent colors.

The themed appearance includes:

* Track
* Selected range
* Thumb
* Thumb border
* Tick marks

The control also exposes:

```csharp
range.ApplyTheme();
```

This reapplies the currently active FTR theme.

In normal usage, applications do not need to call this method manually because the control applies the theme when it is created and responds to the global theme system.

---

# Premium Features

The following features require an appropriate FTR Controls Premium license:

| Feature           | Premium |
| ----------------- | :-----: |
| `SmoothScrolling` |   Yes   |
| `ShowTicks`       |   Yes   |

The following related properties are **not themselves Premium**, although some only have a visible effect when a Premium feature is enabled:

| Property           | Premium |
| ------------------ | :-----: |
| `TickFrequency`    |    No   |
| `TrackHeight`      |    No   |
| `ThumbSize`        |    No   |
| `TrackColor`       |    No   |
| `SliderColor`      |    No   |
| `ThumbColor`       |    No   |
| `ThumbBorderColor` |    No   |
| `TickColor`        |    No   |
| `Step`             |    No   |
| `ShowValueTooltip` |    No   |
| `ValueSuffix`      |    No   |

If a Premium property is enabled without the required license, the FTR Controls activation prompt may be displayed and the requested Premium setting is not applied.

---

# Complete Configuration Example

```csharp
var range = new FTRRangeSlider
{
    Minimum = 0,
    Maximum = 1000,

    ValueLeft = 200,
    ValueRight = 800,

    Step = 50,

    ShowValueTooltip = true,
    ValueSuffix = " units",

    SmoothScrolling = true,

    TrackHeight = 8,
    ThumbSize = 18,

    TrackColor = Color.LightGray,
    SliderColor = Color.DodgerBlue,
    ThumbColor = Color.White,
    ThumbBorderColor = Color.DodgerBlue
};

range.ValuesChanged += (sender, e) =>
{
    minimumLabel.Text = $"Minimum: {range.ValueLeft}";
    maximumLabel.Text = $"Maximum: {range.ValueRight}";
};
```

For a Premium configuration with tick marks:

```csharp
range.ShowTicks = true;
range.TickFrequency = 100;
```

---

# Quick Reference

| Property / Event   | Type     |         Default | Premium |
| ------------------ | -------- | --------------: | :-----: |
| `Minimum`          | `int`    |             `0` |    No   |
| `Maximum`          | `int`    |           `100` |    No   |
| `ValueLeft`        | `int`    |            `20` |    No   |
| `ValueRight`       | `int`    |            `80` |    No   |
| `Step`             | `int`    |             `1` |    No   |
| `ShowValueTooltip` | `bool`   |          `true` |    No   |
| `ValueSuffix`      | `string` |            `""` |    No   |
| `SmoothScrolling`  | `bool`   |          `true` |   Yes   |
| `ShowTicks`        | `bool`   |         `false` |   Yes   |
| `TickFrequency`    | `int`    |            `10` |    No   |
| `TrackColor`       | `Color`  | Theme-dependent |    No   |
| `SliderColor`      | `Color`  | Theme-dependent |    No   |
| `ThumbColor`       | `Color`  | Theme-dependent |    No   |
| `ThumbBorderColor` | `Color`  | Theme-dependent |    No   |
| `TickColor`        | `Color`  | Theme-dependent |    No   |
| `TrackHeight`      | `int`    |             `6` |    No   |
| `ThumbSize`        | `int`    |            `16` |    No   |
| `ValuesChanged`    | Event    |               — |    No   |

---

# Important Behavior Notes

* `ValueLeft` can never be greater than `ValueRight`.
* `ValueRight` can never be less than `ValueLeft`.
* Both values are automatically constrained to `Minimum` and `Maximum`.
* If `Maximum` becomes lower than `Minimum`, the control adjusts `Maximum` to maintain a valid range.
* `Step` is used for keyboard changes and mouse dragging.
* `Step` has a minimum value of `1`.
* `TrackHeight` has a minimum value of `1`.
* `ThumbSize` has a minimum value of `8`.
* Clicking the slider selects the thumb closest to the click position.
* The selected thumb can then be dragged along the track.
* Left/Down and Right/Up control the left thumb.
* Holding `Shift` changes the arrow-key target to the right thumb.
* The value tooltip appears only while a thumb is being dragged.
* `ValueSuffix` is appended to the value displayed in the tooltip.
* `ValuesChanged` is raised when either selected value actually changes.
* `ShowTicks` requires Premium licensing.
* `SmoothScrolling` requires Premium licensing to explicitly enable it.
* Theme-dependent colors are automatically updated when the FTR theme changes.
