From bcf722e637b18c0884a0ba1f7b621c22f232bfd2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 2 Oct 2025 20:06:10 +0200 Subject: [PATCH 1/5] Docs: updated FAQ "What is the difference between Dear ImGui and traditional UI toolkits?". (#8862) --- docs/CHANGELOG.txt | 2 ++ docs/FAQ.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++ imgui.cpp | 1 + 3 files changed, 58 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ea29c0b8d..66846d00e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -85,6 +85,8 @@ Other Changes: - Backends: all backends call ImGuiPlatformIO::ClearPlatformHandlers() and ClearRendererHandlers() on shutdown, so as not to leave function pointers which may be dangling when using backend in e.g. DLL. (#8945, #2769) +- Docs: updated FAQ with new "What is the difference between Dear ImGui and + traditional UI toolkits?" entry. (#8862) - Backends: DirectX12: reuse a command list and allocator for texture uploads instead of recreating them each time. (#8963, #8465) [@RT2Code] - Backends: DirectX12: Rework synchronization logic. (#8961) [@RT2Code] diff --git a/docs/FAQ.md b/docs/FAQ.md index 519a0e8a9..ec75b35f6 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -13,6 +13,7 @@ or view this file with any Markdown viewer. :---------------------------------------------------------- | | [Where is the documentation?](#q-where-is-the-documentation) | | [What is this library called?](#q-what-is-this-library-called) | +| [What is the difference between Dear ImGui and traditional UI toolkits?](#q-what-is-the-difference-between-dear-imgui-and-traditional-ui-toolkits) | | [Which version should I get?](#q-which-version-should-i-get) | | **Q&A: Integration** | | **[How to get started?](#q-how-to-get-started)** | @@ -75,6 +76,60 @@ or view this file with any Markdown viewer. --- +### Q: What is the difference between Dear ImGui and traditional UI toolkits? + +Here's a very simplified comparaison between the approach taked by Dear ImGui vs traditional toolkits: + +| Dear ImGui | Qt/Gtk/WPF.. | +|----------------------------|--------------------------| +| UI fully issued on every update. | UI issued once then later modified. | +| UI layout is fully dynamic and can change at any time.
UI is generally emitted programmatically, which empower changes and reflecting a dynamic set of data. | UI layout is mostly static.
UI may be emitted programmatically or from data created by offline tools. UI need extra code to evolve, which is often tedious and error-prone if it needs to be reflect dynamic data and systems. | +| Application can submit UI based on arbitrary logic and then forget about it. | Application needs more bookkeeping of UI elements. | +| UI library stores minimal amount of data. At one point in time it typically doesn't know or remember which other widgets are displayed and which widgets are coming next. As a result, certain layout features (alignment, resizing) are not as easy to implement or requires ad-hoc code. | UI library stores entire widgets tree and state. UI library can use this retained data to easily layout things. | +| UI code may be added anywhere.
You can even create UI to edit a local variable! | UI code needs to be added in certains spots. | +| UI layout/logic/action/data bindings are all nearby in the code. | UI layout/logic/action/data bindings in different functions, different files or formats. | +| Data is naturally always synchronized. | Use callback/signal/slot for synchronizing data (error-prone). | +| API is simple and easy to learn. In particular, doing simple things is very easy. | API is more complex and specialized. | +| API is generally low-level (raw language types). | API are higher-level (more abstractions, advanced language features). | +| Less fancy look and feel. | Standard look and feel. | +| Compile yourself. Easy to debug, hack, modify. | Mostly use precompiled librairies. Compiling and modifying is daunting if not impossible. | +| Run on every platforms. | Run on limited desktop platforms. | + +Idiomatic Dear ImGui code: +```cpp +if (ImGui::Button("Save")) + MySaveFunction(); + +ImGui::SliderFloat("Slider", &m_MyValue, 0.0f, 1.0f); +``` +Idiomatic code with traditional toolkit: +```cpp +UiButton* button = new UiButton("Save"); +button->OnClick = &MySaveFunction; +parent->Add(button); + +UiSlider* slider = new UiSlider("Slider"); +slider->SetRange(0.0f, 1.0f); +slider->BindData(&m_MyValue); +parent->Add(slider); +``` +This is only meant to give you a intuitive feeling of the main differences, but everything goes deeper than that. + +Some of those properties are typically associated to the umbrella term "IMGUI", but the term has no simple and well-agreed definition. There are many erroneous statements and misunderstanding with what IMGUI means. It is partly caused by the fact that most popular IMGUI implementations (including Dear ImGui) have originated from game industry needs and have targetted very specific use cases, causing people to conflate IMGUI properties with what a specific library does. However, it is perfectly possible to implement an IMGUI library that would have very different properties than e.g. Dear ImGui. My take on defining what an IMGUI is: + +**IMGUI refers to the API: literally the interface between the application and the UI system.** +- An IMGUI API favor the application code owning its data and being the single source of truth for it. +- An IMGUI API tries to minimize the application having to retain/manage data related to the UI system. +- An IMGUI API tries to minimize the UI system having to retain/manage data related to the application. +- Synchronization between application data and UI data is natural and less error-prone. + +**IMGUI does NOT refer to the implementation. Whatever happens inside the UI library code doesn't matter.** +
Also see: [Links to many articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki/#about-the-imgui-paradigm). + +##### [Return to Index](#index) + +--- + ### Q: Which version should I get? I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported. diff --git a/imgui.cpp b/imgui.cpp index 1e881ca63..6c37effe5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1055,6 +1055,7 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures: associated with it. Q: What is this library called? + Q: What is the difference between Dear ImGui and traditional UI toolkits? Q: Which version should I get? >> This library is called "Dear ImGui", please don't call it "ImGui" :) >> See https://www.dearimgui.com/faq for details. From a97b0c32ab1a969714a7e3a232ac4948fbbd9f50 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 2 Oct 2025 20:31:14 +0200 Subject: [PATCH 2/5] Update FAQ.md --- docs/FAQ.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index ec75b35f6..c141e1b70 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -80,8 +80,8 @@ or view this file with any Markdown viewer. Here's a very simplified comparaison between the approach taked by Dear ImGui vs traditional toolkits: -| Dear ImGui | Qt/Gtk/WPF.. | -|----------------------------|--------------------------| +| Dear ImGui | Qt/Gtk/WPF... | +|--------------------------|--------------------------| | UI fully issued on every update. | UI issued once then later modified. | | UI layout is fully dynamic and can change at any time.
UI is generally emitted programmatically, which empower changes and reflecting a dynamic set of data. | UI layout is mostly static.
UI may be emitted programmatically or from data created by offline tools. UI need extra code to evolve, which is often tedious and error-prone if it needs to be reflect dynamic data and systems. | | Application can submit UI based on arbitrary logic and then forget about it. | Application needs more bookkeeping of UI elements. | @@ -92,7 +92,7 @@ Here's a very simplified comparaison between the approach taked by Dear ImGui vs | API is simple and easy to learn. In particular, doing simple things is very easy. | API is more complex and specialized. | | API is generally low-level (raw language types). | API are higher-level (more abstractions, advanced language features). | | Less fancy look and feel. | Standard look and feel. | -| Compile yourself. Easy to debug, hack, modify. | Mostly use precompiled librairies. Compiling and modifying is daunting if not impossible. | +| Compile yourself. Easy to debug, hack, modify, study. | Mostly use precompiled librairies. Compiling, modifying or studying is daunting if not impossible. | | Run on every platforms. | Run on limited desktop platforms. | Idiomatic Dear ImGui code: @@ -113,7 +113,7 @@ slider->SetRange(0.0f, 1.0f); slider->BindData(&m_MyValue); parent->Add(slider); ``` -This is only meant to give you a intuitive feeling of the main differences, but everything goes deeper than that. +This is only meant to give you a intuitive feeling of the main differences, but pros & cons goes deeper than that. Some of those properties are typically associated to the umbrella term "IMGUI", but the term has no simple and well-agreed definition. There are many erroneous statements and misunderstanding with what IMGUI means. It is partly caused by the fact that most popular IMGUI implementations (including Dear ImGui) have originated from game industry needs and have targetted very specific use cases, causing people to conflate IMGUI properties with what a specific library does. However, it is perfectly possible to implement an IMGUI library that would have very different properties than e.g. Dear ImGui. My take on defining what an IMGUI is: From 3ac624b795fcb939a42ec0b43160f65cf4ff83e5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 3 Oct 2025 18:26:06 +0200 Subject: [PATCH 3/5] Update FAQ.md typos. (#8862) --- docs/FAQ.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index c141e1b70..e72f63f74 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -78,22 +78,22 @@ or view this file with any Markdown viewer. ### Q: What is the difference between Dear ImGui and traditional UI toolkits? -Here's a very simplified comparaison between the approach taked by Dear ImGui vs traditional toolkits: +Here's a very simplified comparison between the approach taken by Dear ImGui vs traditional toolkits: -| Dear ImGui | Qt/Gtk/WPF... | +| Dear ImGui | Qt/GTK/WPF... | |--------------------------|--------------------------| | UI fully issued on every update. | UI issued once then later modified. | -| UI layout is fully dynamic and can change at any time.
UI is generally emitted programmatically, which empower changes and reflecting a dynamic set of data. | UI layout is mostly static.
UI may be emitted programmatically or from data created by offline tools. UI need extra code to evolve, which is often tedious and error-prone if it needs to be reflect dynamic data and systems. | +| UI layout is fully dynamic and can change at any time.
UI is generally emitted programmatically, which empowers reflecting a dynamic set of data. | UI layout is mostly static.
UI may be emitted programmatically or from data created by offline tools. UI need extra code to evolve, which is often tedious and error-prone if it needs to be reflecting dynamic data and systems. | | Application can submit UI based on arbitrary logic and then forget about it. | Application needs more bookkeeping of UI elements. | -| UI library stores minimal amount of data. At one point in time it typically doesn't know or remember which other widgets are displayed and which widgets are coming next. As a result, certain layout features (alignment, resizing) are not as easy to implement or requires ad-hoc code. | UI library stores entire widgets tree and state. UI library can use this retained data to easily layout things. | -| UI code may be added anywhere.
You can even create UI to edit a local variable! | UI code needs to be added in certains spots. | -| UI layout/logic/action/data bindings are all nearby in the code. | UI layout/logic/action/data bindings in different functions, different files or formats. | +| UI library stores minimal amounts of data. At one point in time, it typically doesn't know or remember which other widgets are displayed and which widgets are coming next. As a result, certain layout features (alignment, resizing) are not as easy to implement or require ad-hoc code. | UI library stores entire widgets tree and state. UI library can use this retained data to easily layout things. | +| UI code may be added anywhere.
You can even create UI to edit a local variable! | UI code needs to be added in dedicated spots. | +| UI layout/logic/action/data bindings are all nearby in the code. | UI layout/logic/action/data bindings in distinct functions, files or formats. | | Data is naturally always synchronized. | Use callback/signal/slot for synchronizing data (error-prone). | -| API is simple and easy to learn. In particular, doing simple things is very easy. | API is more complex and specialized. | -| API is generally low-level (raw language types). | API are higher-level (more abstractions, advanced language features). | +| API is simple and easy to learn. In particular, doing basic things is very easy. | API is more complex and specialized. | +| API is low-level (raw language types). | API are higher-level (more abstractions, advanced language features). | | Less fancy look and feel. | Standard look and feel. | -| Compile yourself. Easy to debug, hack, modify, study. | Mostly use precompiled librairies. Compiling, modifying or studying is daunting if not impossible. | -| Run on every platforms. | Run on limited desktop platforms. | +| Compile yourself. Easy to debug, hack, modify, study. | Mostly use precompiled libraries. Compiling, modifying or studying is daunting if not impossible. | +| Run on every platform. | Run on limited desktop platforms. | Idiomatic Dear ImGui code: ```cpp @@ -113,12 +113,12 @@ slider->SetRange(0.0f, 1.0f); slider->BindData(&m_MyValue); parent->Add(slider); ``` -This is only meant to give you a intuitive feeling of the main differences, but pros & cons goes deeper than that. +This is only meant to give you a intuitive feeling of the main differences, but pros & cons go deeper than that. -Some of those properties are typically associated to the umbrella term "IMGUI", but the term has no simple and well-agreed definition. There are many erroneous statements and misunderstanding with what IMGUI means. It is partly caused by the fact that most popular IMGUI implementations (including Dear ImGui) have originated from game industry needs and have targetted very specific use cases, causing people to conflate IMGUI properties with what a specific library does. However, it is perfectly possible to implement an IMGUI library that would have very different properties than e.g. Dear ImGui. My take on defining what an IMGUI is: +Some of those properties are typically associated to the umbrella term "IMGUI", but the term has no simple and well-agreed definition. There are many erroneous statements and misunderstandings with what IMGUI means. It is partly caused by the fact that most popular IMGUI implementations (including Dear ImGui) have originated from game industry needs and have targeted specific use cases, causing people to conflate IMGUI properties with what a specific library does. However, it is perfectly possible to implement an IMGUI library that would have very different properties than e.g. Dear ImGui. My take on defining what an IMGUI is: **IMGUI refers to the API: literally the interface between the application and the UI system.** -- An IMGUI API favor the application code owning its data and being the single source of truth for it. +- An IMGUI API favors the application code owning its data and being the single source of truth for it. - An IMGUI API tries to minimize the application having to retain/manage data related to the UI system. - An IMGUI API tries to minimize the UI system having to retain/manage data related to the application. - Synchronization between application data and UI data is natural and less error-prone. From 1cdec11e24832f81be947d357ed8c451e59c2de9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 3 Oct 2025 18:54:15 +0200 Subject: [PATCH 4/5] Drag and Drop: rework RenderDragDropTargetRect() into RenderDragDropTargetRectForItem() and add RenderDragDropTargetRectEx(). (#1603, #5204) --- imgui.cpp | 13 +++++++++---- imgui_internal.h | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6c37effe5..272dba95d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -14793,7 +14793,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop payload.Preview = was_accepted_previously; flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that live for 1 frame) if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) - RenderDragDropTargetRect(r, g.DragDropTargetClipRect); + RenderDragDropTargetRectForItem(r); g.DragDropAcceptFrameCount = g.FrameCount; if ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) && g.DragDropMouseButton == -1) @@ -14809,21 +14809,26 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop } // FIXME-STYLE FIXME-DRAGDROP: Settle on a proper default visuals for drop target. -void ImGui::RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect) +void ImGui::RenderDragDropTargetRectForItem(const ImRect& bb) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImRect bb_display = bb; - bb_display.ClipWith(item_clip_rect); // Clip THEN expand so we have a way to visualize that target is not entirely visible. + bb_display.ClipWith(g.DragDropTargetClipRect); // Clip THEN expand so we have a way to visualize that target is not entirely visible. bb_display.Expand(3.5f); bool push_clip_rect = !window->ClipRect.Contains(bb_display); if (push_clip_rect) window->DrawList->PushClipRectFullScreen(); - window->DrawList->AddRect(bb_display.Min, bb_display.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); // FIXME-DPI + RenderDragDropTargetRectEx(window->DrawList, bb_display); if (push_clip_rect) window->DrawList->PopClipRect(); } +void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb) +{ + draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); // FIXME-DPI +} + const ImGuiPayload* ImGui::GetDragDropPayload() { ImGuiContext& g = *GImGui; diff --git a/imgui_internal.h b/imgui_internal.h index f66b91f7d..cdeddc919 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3423,7 +3423,8 @@ namespace ImGui IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); IMGUI_API void ClearDragDrop(); IMGUI_API bool IsDragDropPayloadBeingAccepted(); - IMGUI_API void RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect); + IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb); + IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb); // Typing-Select API // (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature) From 27a9374ef3fc6572f8dd1fa9ddf72e1802fceb8b Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 3 Oct 2025 19:04:37 +0200 Subject: [PATCH 5/5] Drag and Drop: added BeginDragDropTargetViewport(), still in imgui_internal.h for now. (#5204) --- imgui.cpp | 37 ++++++++++++++++++++++++++++++++++++- imgui_internal.h | 2 ++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 272dba95d..8928335aa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4160,6 +4160,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) DragDropSourceFrameCount = -1; DragDropMouseButton = -1; DragDropTargetId = 0; + DragDropTargetFullViewport = 0; DragDropAcceptFlags = ImGuiDragDropFlags_None; DragDropAcceptIdCurrRectSurface = 0.0f; DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; @@ -14722,6 +14723,31 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) g.DragDropTargetRect = bb; g.DragDropTargetClipRect = window->ClipRect; // May want to be overridden by user depending on use case? g.DragDropTargetId = id; + g.DragDropTargetFullViewport = 0; + g.DragDropWithinTarget = true; + return true; +} + +// Typical usage would be: +// if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) +// if (ImGui::BeginDragDropTargetViewport(ImGui::GetMainViewport(), NULL)) +// But we are leaving the hover test to the caller for maximum flexibility. +bool ImGui::BeginDragDropTargetViewport(ImGuiViewport* viewport, const ImRect* p_bb) +{ + ImGuiContext& g = *GImGui; + if (!g.DragDropActive) + return false; + + ImRect bb = p_bb ? *p_bb : ((ImGuiViewportP*)viewport)->GetWorkRect(); + ImGuiID id = viewport->ID; + if (!IsMouseHoveringRect(bb.Min, bb.Max, false) || (id == g.DragDropPayload.SourceId)) + return false; + + IM_ASSERT(g.DragDropWithinTarget == false && g.DragDropWithinSource == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget() + g.DragDropTargetRect = bb; + g.DragDropTargetClipRect = bb; + g.DragDropTargetId = id; + g.DragDropTargetFullViewport = id; g.DragDropWithinTarget = true; return true; } @@ -14792,8 +14818,17 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop // Render default drop visuals payload.Preview = was_accepted_previously; flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that live for 1 frame) - if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) + const bool draw_target_rect = payload.Preview && !(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); + if (draw_target_rect && g.DragDropTargetFullViewport != 0) + { + ImRect bb = g.DragDropTargetRect; + bb.Expand(-3.5f); + RenderDragDropTargetRectEx(GetForegroundDrawList(), bb); + } + else if (draw_target_rect) + { RenderDragDropTargetRectForItem(r); + } g.DragDropAcceptFrameCount = g.FrameCount; if ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) && g.DragDropMouseButton == -1) diff --git a/imgui_internal.h b/imgui_internal.h index cdeddc919..fe79a862f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2372,6 +2372,7 @@ struct ImGuiContext ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping) ImRect DragDropTargetClipRect; // Store ClipRect at the time of item's drawing ImGuiID DragDropTargetId; + ImGuiID DragDropTargetFullViewport; ImGuiDragDropFlags DragDropAcceptFlags; float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface) ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) @@ -3421,6 +3422,7 @@ namespace ImGui // Drag and Drop IMGUI_API bool IsDragDropActive(); IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); + IMGUI_API bool BeginDragDropTargetViewport(ImGuiViewport* viewport, const ImRect* p_bb = NULL); IMGUI_API void ClearDragDrop(); IMGUI_API bool IsDragDropPayloadBeingAccepted(); IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb);