Guide Dear ImGui

ImGui toggle switch and rounded buttons

Dear ImGui has checkboxes, not switches — but a switch is twenty lines with ImDrawList. Plus: rounded and colored buttons without touching the global style.

Toggle switch

An invisible button takes the clicks; the draw list paints the track and the knob. It returns true when the value changes, like ImGui::Checkbox.

C++
#include "imgui.h"

bool ToggleSwitch(const char* id, bool* v)
{
    ImDrawList* draw = ImGui::GetWindowDrawList();
    const ImVec2 p = ImGui::GetCursorScreenPos();
    const float height = ImGui::GetFrameHeight();
    const float width = height * 1.75f;
    const float radius = height * 0.5f;

    bool changed = false;
    if (ImGui::InvisibleButton(id, ImVec2(width, height)))
    {
        *v = !*v;
        changed = true;
    }

    const ImU32 track = ImGui::GetColorU32(*v ? ImGuiCol_CheckMark
                                              : ImGui::IsItemHovered() ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
    draw->AddRectFilled(p, ImVec2(p.x + width, p.y + height), track, radius);

    const float knobX = *v ? p.x + width - radius : p.x + radius;
    draw->AddCircleFilled(ImVec2(knobX, p.y + radius), radius - 3.0f, IM_COL32(255, 255, 255, 255));
    return changed;
}

// use it like a checkbox, with the label next to it
static bool fullscreen = false;
ToggleSwitch("##fullscreen", &fullscreen);
ImGui::SameLine();
ImGui::TextUnformatted("Fullscreen");

Want it to slide? Keep a float per switch and move it toward 0 or 1 each frame with ImGui::GetIO().DeltaTime, then use it for knobX.

Rounded and colored buttons

Push style variables and colors only around the buttons that need them:

C++
// a rounded, accent-colored button
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 8.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(18.0f, 9.0f));
ImGui::PushStyleColor(ImGuiCol_Button,        ImVec4(0.55f, 0.36f, 0.96f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.62f, 0.45f, 0.97f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive,  ImVec4(0.47f, 0.29f, 0.88f, 1.0f));

if (ImGui::Button("Apply"))
{
    // ...
}

ImGui::PopStyleColor(3);
ImGui::PopStyleVar(2);

// a pill-shaped button: rounding = half the button height
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetFrameHeight() * 0.5f);
ImGui::Button("Pill button");
ImGui::PopStyleVar();

Full-width button

C++
ImGui::Button("Sign in", ImVec2(-FLT_MIN, 0.0f));   // needs <float.h>

Kavro has a Switch widget and 16 more, each with its own style editor (colors, rounding, hover and press states). Drag it in, style it, and Kavro generates the drawing code for C++, C# or Rust.

More guides