Skip to main content
Dear ImGui provides a rich set of widgets for building interactive user interfaces. All widgets follow the immediate mode paradigm where you call functions every frame to display and interact with UI elements.

Widget Categories

Dear ImGui widgets are organized into several categories:

Text and Labels

Display formatted text, colored text, and labels

Buttons

Interactive buttons including standard, small, and arrow buttons

Input Widgets

Text input, numeric input, and input validation

Sliders and Drags

Value adjustment widgets with visual feedback

Color Pickers

Color selection and editing widgets

Trees and Selectables

Hierarchical data display and selection widgets

Combos and Lists

Dropdown menus and list boxes

Menus

Menu bars and context menus

Tables

Advanced table layouts with sorting and resizing

Common Widget Patterns

Return Values

Most widgets return true when their value has been changed or when they’ve been activated:
if (ImGui::Button("Click Me")) {
    // Button was clicked this frame
}

static float value = 0.0f;
if (ImGui::SliderFloat("slider", &value, 0.0f, 1.0f)) {
    // Value was changed this frame
}

Widget IDs

Dear ImGui uses the widget label to generate a unique ID. When you need multiple widgets with the same label, use PushID() / PopID():
for (int i = 0; i < 5; i++) {
    ImGui::PushID(i);
    if (ImGui::Button("Click")) {
        // Each button has a unique ID
    }
    ImGui::PopID();
}
You can also use the ## syntax to hide part of the label:
ImGui::Button("Save##file1");  // Label: "Save", ID: "Save##file1"
ImGui::Button("Save##file2");  // Label: "Save", ID: "Save##file2"

Querying Widget State

After calling a widget function, you can query its state using IsItem*() functions:
ImGui::Button("My Button");
if (ImGui::IsItemHovered()) {
    ImGui::SetTooltip("This is a tooltip");
}
if (ImGui::IsItemActive()) {
    // Button is being held down
}
if (ImGui::IsItemClicked()) {
    // Button was clicked
}

Widget Sizing

Many widgets accept a size parameter. Common conventions:
  • size.x == 0.0f: Use default/natural width
  • size.x > 0.0f: Specify exact width in pixels
  • size.x < 0.0f: Align to right edge with specified margin
  • -FLT_MIN: Use all available width
ImGui::Button("Default Size");
ImGui::Button("Fixed Size", ImVec2(200, 50));
ImGui::Button("Full Width", ImVec2(-FLT_MIN, 0));

Widget Flags

Many widget types support flags to customize their behavior:
// Button flags
ImGui::InvisibleButton("hidden", ImVec2(100, 100), ImGuiButtonFlags_MouseButtonRight);

// Input text flags
ImGui::InputText("##input", buf, 256, 
    ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank);

// Slider flags
ImGui::SliderFloat("##slider", &value, 0.0f, 1.0f, "%.3f",
    ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic);

Best Practices

Widget state variables should persist across frames:
static float my_value = 0.0f;  // Good
ImGui::SliderFloat("value", &my_value, 0.0f, 1.0f);
Only check return values when you need to respond to changes:
if (ImGui::SliderFloat("volume", &volume, 0.0f, 1.0f)) {
    UpdateAudioVolume(volume);  // Only update when changed
}
Labels help with debugging and make code more readable:
ImGui::Button("Apply Settings");  // Good
ImGui::Button("OK");              // Less descriptive

Next Steps

Explore specific widget categories to learn about their unique features and usage patterns:

Build docs developers (and LLMs) love