# How to Implement Custom Data Types for Sliders and Drag Controls in ImGui

> Learn to implement custom data types for ImGui sliders and drag controls. Extend ImGuiDataType and provide DataTypeInfo for custom scalar types. Boost your UI development.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-15

---

**Dear ImGui's generic slider and drag widgets work with any scalar type by extending the `ImGuiDataType_` enum and providing a corresponding `ImGuiDataTypeInfo` entry that describes size, format, and conversion traits.**

Dear ImGui (ocornut/imgui) provides generic scalar widgets that manipulate raw memory through type descriptors, allowing you to implement custom data types for sliders and drag controls without modifying the core widget logic. Instead of limiting sliders to built-in primitives like `float` or `int`, the library exposes `SliderScalar` and `DragScalar` functions that accept any POD type through a declarative type system defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) and [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp).

## Understanding the Type System Architecture

The extensibility lives in three coordinated components that bridge the public API and internal implementations.

### The ImGuiDataType_ Enum (imgui.h)

Located at line 1515 in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), the `ImGuiDataType_` enumeration declares unique integer identifiers for each supported type. When you add a custom type, you append a new entry here (e.g., `ImGuiDataType_MyVec2`) before `ImGuiDataType_COUNT`. This identifier serves as the bridge between the generic widget API and the type metadata table.

### The ImGuiDataTypeInfo Table (imgui.cpp)

Around line 778 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), the `GetImGuiDataTypeInfo()` function (backed by the static `GImGuiDataTypeInfo[]` table) maps each enum value to an `ImGuiDataTypeInfo` struct. This metadata supplies the widget code with:

- **Size**: Byte size of the type (`sizeof(MyVec2)`)
- **PrintFmt**: Default format string for text rendering (e.g., `"%0.2f"`)
- **IsIntegral** and **IsFloatingPoint**: Classification flags that determine clamping behavior

### Generic Widget Implementation (imgui_widgets.cpp)

The `SliderScalar` implementation in [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) (around line 3316) and the `DragScalar` functions treat the data pointer as opaque raw memory. They delegate bounds checking and interaction handling to `SliderBehavior` and `DragBehavior`, using the type metadata to perform clamping and string formatting without knowing the concrete C++ type.

## Step-by-Step Implementation

Follow these steps to expose a new data type to the slider and drag controls.

### Step 1: Extend the ImGuiDataType_ Enum

Add your custom type identifier to the enum in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h):

```cpp
enum ImGuiDataType_
{
    // ... existing entries like ImGuiDataType_Float, ImGuiDataType_S32 ...
    ImGuiDataType_MyVec2,       // Custom 2D vector
    ImGuiDataType_MyBlendMode,  // Custom enum
    ImGuiDataType_COUNT
};

```

### Step 2: Define Type Metadata in ImGuiDataTypeInfo

Register the type characteristics in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) within the `GImGuiDataTypeInfo` array:

```cpp
static const ImGuiDataTypeInfo GImGuiDataTypeInfo[] =
{
    // ... existing entries ...
    { sizeof(MyVec2),     "%0.2f", false, false }, // MyVec2 - treated as floating point
    { sizeof(int),        "%d",    true,  false }  // MyBlendMode - stored as int
};

```

### Step 3: Use SliderScalar and DragScalar with Custom Types

Call the generic widgets with your new type identifier:

```cpp
MyVec2 v = {0.5f, 0.25f};
MyVec2 v_min = {0.0f, 0.0f};
MyVec2 v_max = {1.0f, 1.0f};

ImGui::SliderScalar("MyVec2", ImGuiDataType_MyVec2, &v, &v_min, &v_max, "%.2f");

```

## Practical Code Examples

Below is a complete implementation showing a custom vector struct and enum working with the generic widget API.

```cpp
// ------------------------------------------------------------
// 1. Define custom types
// ------------------------------------------------------------
struct MyVec2 { float x, y; };
enum class MyBlendMode : int { Opaque = 0, Transparent = 1, Additive = 2 };

// ------------------------------------------------------------
// 2. Extend ImGuiDataType_ (in imgui.h)
// ------------------------------------------------------------
enum ImGuiDataType_
{
    // ... existing entries ...
    ImGuiDataType_MyVec2,          // Custom type 1
    ImGuiDataType_MyBlendMode,    // Custom type 2
    ImGuiDataType_COUNT
};

// ------------------------------------------------------------
// 3. Add DataTypeInfo entries (in imgui.cpp)
// ------------------------------------------------------------
static const ImGuiDataTypeInfo GImGuiDataTypeInfo[] =
{
    // ... existing entries ...
    { sizeof(MyVec2),      "%0.2f",  false, false }, // MyVec2
    { sizeof(int),        "%d",    true,  false }   // MyBlendMode (int-based)
};

// ------------------------------------------------------------
// 4. Use the generic widgets
// ------------------------------------------------------------
void ShowCustomWidgets()
{
    static MyVec2    v = { 0.5f, 0.25f };
    static MyVec2    v_min = { 0.0f, 0.0f };
    static MyVec2    v_max = { 1.0f, 1.0f };
    static MyBlendMode mode = MyBlendMode::Opaque;
    static int       mode_min = 0;
    static int       mode_max = 2;

    // Slider for the whole vector (2 components)
    ImGui::SliderScalarN("MyVec2", ImGuiDataType_MyVec2, &v, 2,
                         &v_min, &v_max, "%.2f");

    // Drag control for a single component
    ImGui::DragScalar("MyVec2 X", ImGuiDataType_Float, &v.x, 0.01f,
                      &v_min.x, &v_max.x, "%.3f");

    // Slider for the custom enum using integer representation
    ImGui::SliderScalar("Blend Mode", ImGuiDataType_MyBlendMode,
                        &mode, &mode_min, &mode_max, "%d");
    
    // Display human-readable label
    const char* mode_names[] = { "Opaque", "Transparent", "Additive" };
    ImGui::SameLine(); 
    ImGui::Text("(%s)", mode_names[(int)mode]);
}

```

## Working with Multi-Component Types

For vector types containing multiple scalars, use `SliderScalarN` or `DragScalarN` as shown in the example above. These functions treat the data pointer as an array of the specified type, iterating through `components` elements. When operating on a `MyVec2` with `components=2`, the widget applies the same min/max bounds to each float within the struct sequentially.

Since the widget operates on raw memory, you can also wrap existing types by creating a thin struct containing a single scalar value and exposing it via a custom `ImGuiDataType_` entry. The widget reads and writes the underlying bytes transparently, allowing you to impose semantic meaning on standard primitives without changing the rendering logic.

## Summary

- Extend `ImGuiDataType_` in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) to declare your custom type identifier before `ImGuiDataType_COUNT`
- Populate `ImGuiDataTypeInfo` in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) with size, format string, and type classification flags (`IsIntegral`, `IsFloatingPoint`)
- Use `SliderScalar`, `DragScalar`, `SliderScalarN`, or `DragScalarN` with your new type enum and appropriate min/max pointers
- The generic widgets in [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) handle clamping via `SliderBehavior` and `DragBehavior` using the raw memory description
- Multi-component types work transparently with the `...ScalarN` variants that iterate over contiguous memory blocks

## Frequently Asked Questions

### Can I implement custom data types without modifying Dear ImGui's source code?

Currently, extending `ImGuiDataType_` and `ImGuiDataTypeInfo` requires modifying [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) and [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) because the type table is static and indexed by the enum. However, you can work around this limitation by treating your custom type as a supported underlying type (like `float` or `int`) and handling the conversion manually in your application code before calling the widget.

### How does SliderScalar handle bounds checking for custom structs?

The `SliderBehavior` function performs bounds checking using raw memory comparisons based on the `Size` field from `ImGuiDataTypeInfo`. For multi-component types like `MyVec2`, the widget treats each component as an independent scalar when using `SliderScalarN`, applying the min/max values to each float within the struct. The widget clamps values by comparing the underlying bytes as if they were the specified scalar type.

### What format strings work with custom types in DragScalar?

The `PrintFmt` field in your `ImGuiDataTypeInfo` entry determines the default formatting, but you can override this by passing a custom format string as the final parameter to `DragScalar` or `SliderScalar`. For integer-based enums, use `"%d"`; for floating-point vectors, use `"%.2f"` or similar precision specifiers. The format string follows standard `printf` conventions compatible with the underlying scalar representation.

### Why does my custom type slider show incorrect values or corrupt memory?

Ensure the `Size` field in your `ImGuiDataTypeInfo` entry exactly matches `sizeof(YourType)` and that the `IsFloatingPoint` or `IsIntegral` flags correctly reflect the underlying representation. Mismatched sizes cause the widget to read incorrect memory offsets, while incorrect type flags affect the formatting logic and clamping behavior. Verify that your custom type is a POD (Plain Old Data) struct without virtual functions or complex constructors.