BeginCombo vs Combo in ImGui: Key Differences and When to Use Each
The legacy Combo function is a one-shot helper that automatically creates selectable items, while BeginCombo/EndCombo provides an explicit API for fully custom dropdown content with unlimited flexibility.
Dear ImGui (ocornut/imgui) provides two distinct approaches for creating combo box widgets. Understanding the differences between BeginCombo/EndCombo and the legacy Combo function in ImGui is essential for choosing the right tool based on your UI complexity requirements. While both methods render dropdown controls, they differ fundamentally in API style, customization capabilities, and control granularity.
API Architecture Comparison
Legacy Combo: The Convenience Wrapper
The legacy Combo function acts as a high-level convenience wrapper that internally handles the entire combo lifecycle. Located in imgui.h at lines 664-666, this helper automatically calls BeginCombo, populates the popup with Selectable items based on your input array, and closes with EndCombo. You provide a current_item index pointer, and the function manages preview text generation and state synchronization without exposing the underlying popup construction.
BeginCombo/EndCombo: Explicit Manual Construction
Declared at imgui.h lines 662-663, the BeginCombo/EndCombo pair follows Dear ImGui's explicit "begin/end" pattern. You call BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0) to open the popup, manually populate its contents using any ImGui widgets (not just Selectable), and explicitly close with EndCombo(). This approach requires you to manage the selected value storage and preview string independently, offering complete control over the dropdown's internal layout and behavior.
Key Differences
Content Flexibility
The legacy Combo restricts you to simple text arrays, zero-terminated strings, or getter callbacks that return string pointers. It automatically generates a vertical list of text-only selectable items.
BeginCombo/EndCombo imposes no content restrictions. You can embed images, checkboxes, separators, nested menus, or complex layouts within the popup window. This makes it ideal for icon-based selectors, multi-column dropdowns, or combo boxes containing interactive widgets.
State Management and Preview Control
With the legacy API, the preview displayed in the combo button always corresponds to the text of the currently selected index. The function handles preview_value internally based on your current_item pointer.
Using BeginCombo, you explicitly specify the preview_value parameter on every call, allowing dynamic preview generation independent of the popup contents. For advanced customization, you can pass ImGuiComboFlags_CustomPreview (defined in imgui_internal.h lines 1090-1092) and use BeginComboPreview()/EndComboPreview() to draw arbitrary widgets—such as icons, colors, or formatted text—inside the combo button itself.
Flag Support and Configuration
BeginCombo accepts ImGuiComboFlags for fine-tuned behavior control:
ImGuiComboFlags_HeightSmall/ImGuiComboFlags_HeightRegular/ImGuiComboFlags_HeightLarge/ImGuiComboFlags_HeightLargestcontrol popup heightImGuiComboFlags_PopupAlignLeftaligns the popup to the left edgeImGuiComboFlags_CustomPreviewenables manual preview rendering
The legacy Combo offers no flag parameter, only a popup_max_height_in_items integer for basic height limiting.
Implementation Details
According to the ocornut/imgui source code, all legacy Combo overloads in imgui.cpp internally reduce to the same pattern:
if (BeginCombo(label, preview_value, flags))
{
// Generate Selectable items based on array/callback
EndCombo();
}
This confirms that BeginCombo/EndCombo constitutes the underlying primitive, while Combo is a helper layered on top. The internal combo state tracking occurs through BeginComboDepth and related structures defined in imgui_internal.h.
Code Examples
Legacy Combo (Simplest Implementation)
Use this when you need a standard text list with minimal code:
int current = 0;
const char* items[] = { "Apple", "Banana", "Cherry" };
ImGui::Combo("Fruit", ¤t, items, IM_ARRAYSIZE(items));
BeginCombo/EndCombo (Full Control)
Use this for custom selection logic or non-standard content:
int current = 0;
const char* items[] = { "Apple", "Banana", "Cherry" };
if (ImGui::BeginCombo("Fruit", items[current]))
{
for (int i = 0; i < IM_ARRAYSIZE(items); ++i)
{
const bool is_selected = (current == i);
if (ImGui::Selectable(items[i], is_selected))
current = i;
if (is_selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
Custom Preview with Icons
Use this to render images or styled text in the combo button:
int current = 0;
const char* items[] = { "Apple", "Banana", "Cherry" };
if (ImGui::BeginCombo("Fruit", nullptr, ImGuiComboFlags_CustomPreview))
{
// Draw custom preview in the combo button area
ImGui::BeginComboPreview();
ImGui::Image(fruit_icons[current], ImVec2(16, 16));
ImGui::SameLine();
ImGui::TextUnformatted(items[current]);
ImGui::EndComboPreview();
// Popup contents
for (int i = 0; i < IM_ARRAYSIZE(items); ++i)
{
if (ImGui::Selectable(items[i], current == i))
current = i;
}
ImGui::EndCombo();
}
Summary
- Legacy
Comboprovides the fastest implementation for simple text arrays but limits you to standard lists without customization options. BeginCombo/EndComborequires more code but enables unlimited content flexibility, including images, custom layouts, and interactive widgets inside the dropdown.- Custom previews are only possible through
BeginCombousing theImGuiComboFlags_CustomPreviewflag and theBeginComboPreview()/EndComboPreview()API. - Flag-based configuration (height control, alignment) is exclusive to the
BeginComboAPI. - Both functions ultimately reside in
imgui.hand are implemented inimgui.cpp, with the legacy version calling the explicit API internally.
Frequently Asked Questions
Can I use images inside a combo box using the legacy Combo function?
No, the legacy Combo function only supports text-based items through string arrays or callbacks. To display images, icons, or other visual elements inside the dropdown, you must use BeginCombo/EndCombo and render ImGui::Image widgets manually between the begin and end calls.
How do I control the height of the combo popup?
With BeginCombo, pass height flags such as ImGuiComboFlags_HeightSmall, ImGuiComboFlags_HeightLarge, or ImGuiComboFlags_HeightLargest to the flags parameter. The legacy Combo function only supports the popup_max_height_in_items parameter, which specifies height in terms of item count rather than pixel dimensions.
Is there a performance difference between the two approaches?
No significant performance difference exists because the legacy Combo internally calls BeginCombo and constructs identical Selectable items. The overhead of manual iteration in BeginCombo/EndCombo is negligible; choose based on required functionality rather than optimization concerns.
Can I change what appears in the combo button without changing the selected item?
Yes, but only with BeginCombo. By providing a custom preview_value string or using ImGuiComboFlags_CustomPreview with BeginComboPreview(), you can display formatted text, icons, or dynamic content in the collapsed combo button that differs from the popup's selected item text.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →