From f1f321d3f6d585df3d6320a23e5b69885d392405 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 5 Oct 2019 16:07:00 +0200 Subject: [PATCH 1/6] Update README.md --- docs/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index b4540c17..7d29ace9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -120,9 +120,14 @@ On most platforms and when using C++, **you should be able to use a combination Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading one texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that. If you are an experienced programmer at ease with those concepts, it should take you less than two hours to integrate Dear ImGui in your custom engine. **Make sure to spend time reading the FAQ, comments, and one of the examples/ application!** -_NB: those third-party bindings may be more or less maintained, more or less close to the original API (as people who create language bindings sometimes haven't used the C++ API themselves.. for the good reason that they aren't C++ users!). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ +_NB: third-party bindings may be more or less maintained, more or less close to the original API (as people who create language bindings sometimes haven't used the C++ API themselves.. for the good reason that they aren't C++ users!). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ -Languages: +Officially maintained bindings in repository: +- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, OpenGL (legacy), OpenGL3/ES/ES2 (modern), Vulkan, Metal. +- Platforms: GLFW, SDL2, Win32, Glut, OSX. +- Others: Allegro5, Marmalade. + +Third-party - Languages bindings: - C: [cimgui](https://github.com/cimgui/cimgui) (auto-generated! **you can use its json output to generate bindings for other languages**) - C#/.Net: [ImGui.NET](https://github.com/mellinoe/ImGui.NET) - ChaiScript: [imgui-chaiscript](https://github.com/JuJuBoSc/imgui-chaiscript) @@ -141,11 +146,7 @@ Languages: - Rust: [imgui-rs](https://github.com/Gekkio/imgui-rs) or [imgui-rust](https://github.com/nsf/imgui-rust) - Swift: [swift-imgui](https://github.com/mnmly/Swift-imgui) -Frameworks: -- Renderers: DirectX 9/10/11/12, Metal, OpenGL2, OpenGL3+/ES2/ES3, Vulkan: [examples/](https://github.com/ocornut/imgui/tree/master/examples) -- Platform: GLFW, SDL, Win32, OSX, GLUT: [examples/](https://github.com/ocornut/imgui/tree/master/examples) -- Framework: Allegro 5, Emscripten, Marmalade: [examples/](https://github.com/ocornut/imgui/tree/master/examples) -- Unmerged PR: Android: [#421](https://github.com/ocornut/imgui/pull/421) +Third-party - Engines/Frameworks bindings: - bsf: [bsfimgui](https://github.com/pgruenbacher/bsfImgui) - Cinder: [Cinder-ImGui](https://github.com/simongeilfus/Cinder-ImGui) - Cocos2d-x: [imguix](https://github.com/c0i/imguix), [#551](https://github.com/ocornut/imgui/issues/551) @@ -164,6 +165,7 @@ Frameworks: - SFML: [imgui-sfml](https://github.com/eliasdaler/imgui-sfml) - Software renderer: [imgui_software_renderer](https://github.com/emilk/imgui_software_renderer) - Unreal Engine 4: [segross/UnrealImGui](https://github.com/segross/UnrealImGui) or [sronsse/UnrealEngine_ImGui](https://github.com/sronsse/UnrealEngine_ImGui) +- Unmerged PR: Android: [#421](https://github.com/ocornut/imgui/pull/421) For other bindings: see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings/). Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas. From 73fa6509a516c2b43478947e6cc713c538ce2ec2 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 5 Oct 2019 16:53:28 +0200 Subject: [PATCH 2/6] Internal: InputTextEx: tweaked a bit of code (should be a no-op) --- imgui.cpp | 2 +- imgui_widgets.cpp | 29 ++++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4e95e011..7bf2bf59 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4303,7 +4303,7 @@ void ImGui::Render() } // Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. -// CalcTextSize("") should return ImVec2(0.0f, GImGui->FontSize) +// CalcTextSize("") should return ImVec2(0.0f, g.FontSize) ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) { ImGuiContext& g = *GImGui; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d6631a17..1561c157 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3404,11 +3404,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ BeginGroup(); const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); + const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line + const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y); + + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + const ImRect total_bb(frame_bb.Min, frame_bb.Min + total_size); ImGuiWindow* draw_window = window; + ImVec2 inner_size = frame_size; if (is_multiline) { if (!ItemAdd(total_bb, id, &frame_bb)) @@ -3423,9 +3426,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ EndGroup(); return false; } - draw_window = GetCurrentWindow(); + draw_window = g.CurrentWindow; // Child window draw_window->DC.NavLayerActiveMaskNext |= draw_window->DC.NavLayerCurrentMask; // This is to ensure that EndChild() will display a navigation highlight - size.x -= draw_window->ScrollbarSizes.x; + inner_size.x -= draw_window->ScrollbarSizes.x; } else { @@ -3914,7 +3917,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); } - const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x, frame_bb.Min.y + size.y); // Not using frame_bb.Max because we have adjusted size + const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + inner_size.x, frame_bb.Min.y + inner_size.y); // Not using frame_bb.Max because we have adjusted size ImVec2 draw_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; ImVec2 text_size(0.0f, 0.0f); @@ -3995,7 +3998,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Store text height (note that we haven't calculated text width at all, see GitHub issues #383, #1224) if (is_multiline) - text_size = ImVec2(size.x, line_count * g.FontSize); + text_size = ImVec2(inner_size.x, line_count * g.FontSize); } // Scroll @@ -4004,11 +4007,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Horizontal scroll in chunks of quarter width if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll)) { - const float scroll_increment_x = size.x * 0.25f; + const float scroll_increment_x = inner_size.x * 0.25f; if (cursor_offset.x < state->ScrollX) state->ScrollX = (float)(int)ImMax(0.0f, cursor_offset.x - scroll_increment_x); - else if (cursor_offset.x - size.x >= state->ScrollX) - state->ScrollX = (float)(int)(cursor_offset.x - size.x + scroll_increment_x); + else if (cursor_offset.x - inner_size.x >= state->ScrollX) + state->ScrollX = (float)(int)(cursor_offset.x - inner_size.x + scroll_increment_x); } else { @@ -4021,8 +4024,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ float scroll_y = draw_window->Scroll.y; if (cursor_offset.y - g.FontSize < scroll_y) scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); - else if (cursor_offset.y - size.y >= scroll_y) - scroll_y = cursor_offset.y - size.y; + else if (cursor_offset.y - inner_size.y >= scroll_y) + scroll_y = cursor_offset.y - inner_size.y; draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag draw_window->Scroll.y = scroll_y; } @@ -4093,7 +4096,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { // Render text only (no selection, no cursor) if (is_multiline) - text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width + text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width else if (!is_displaying_hint && g.ActiveId == id) buf_display_end = buf_display + state->CurLenA; else if (!is_displaying_hint) From 323412dd23bb414c8885ee545a5ca0aaa3a40e84 Mon Sep 17 00:00:00 2001 From: Harris Brakmic Date: Sun, 6 Oct 2019 13:02:01 +0200 Subject: [PATCH 3/6] Examples: Allegro5: updated build instructions for macOS --- examples/example_allegro5/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/example_allegro5/README.md b/examples/example_allegro5/README.md index 5ef45557..10d9d6e9 100644 --- a/examples/example_allegro5/README.md +++ b/examples/example_allegro5/README.md @@ -9,12 +9,14 @@ Note that the back-end supports _BOTH_ 16-bit and 32-bit indices, but 32-bit ind # How to Build -### On Ubuntu 14.04+ +### On Ubuntu 14.04+ and macOS ```bash -g++ -DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" -I .. -I ../.. main.cpp ../imgui_impl_allegro5.cpp ../../imgui*.cpp -lallegro -lallegro_primitives -o allegro5_example +g++ -DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" -I .. -I ../.. main.cpp ../imgui_impl_allegro5.cpp ../../imgui*.cpp -lallegro -lallegro_main -lallegro_primitives -o allegro5_example ``` +On macOS, install Allegro with homebrew: `brew install allegro`. + ### On Windows with Visual Studio's CLI You may install Allegro using vcpkg: From 8aad3482a412af966082c297d5c7f05e070b7d98 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Oct 2019 17:22:55 +0200 Subject: [PATCH 4/6] ImVector: Fixed index_from_ptr() not asserting when passed end() element. --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index a7e5fd7e..1db78b4a 100644 --- a/imgui.h +++ b/imgui.h @@ -1276,7 +1276,7 @@ struct ImVector inline const T* find(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data == v) break; else ++data; return data; } inline bool find_erase(const T& v) { const T* it = find(v); if (it < Data + Size) { erase(it); return true; } return false; } inline bool find_erase_unsorted(const T& v) { const T* it = find(v); if (it < Data + Size) { erase_unsorted(it); return true; } return false; } - inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; return (int)off; } + inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; return (int)off; } }; //----------------------------------------------------------------------------- From 3b271b1847f0cf159cfd0dfeaa171034fcab2507 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Oct 2019 17:52:31 +0200 Subject: [PATCH 5/6] Demo: Added simple item reordering demo in Widgets -> Drag and Drop section. (#2823, #143) [@rokups] --- docs/CHANGELOG.txt | 1 + imgui_demo.cpp | 47 +++++++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e1cd2ad9..64bbe6bd 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -40,6 +40,7 @@ Other Changes: - InputText, Nav: Fixed Home/End key broken when activating Keyboard Navigation. (#787) - TreeNode: Fixed combination of ImGuiTreeNodeFlags_SpanFullWidth and ImGuiTreeNodeFlags_OpenOnArrow incorrectly locating the arrow hit position to the left of the frame. (#2451, #2438, #1897) +- Demo: Added simple item reordering demo in Widgets -> Drag and Drop section. (#2823, #143) [@rokups] ----------------------------------------------------------------------- diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 036d9068..0eeec980 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1506,24 +1506,21 @@ static void ShowDemoWindowWidgets() if (ImGui::TreeNode("Drag and Drop")) { + if (ImGui::TreeNode("Drag and drop in standard widgets")) { // ColorEdit widgets automatically act as drag source and drag target. // They are using standardized payload strings IMGUI_PAYLOAD_TYPE_COLOR_3F and IMGUI_PAYLOAD_TYPE_COLOR_4F to allow your own widgets // to use colors in their drag and drop interaction. Also see the demo in Color Picker -> Palette demo. - ImGui::BulletText("Drag and drop in standard widgets"); - ImGui::SameLine(); HelpMarker("You can drag from the colored squares."); - ImGui::Indent(); - static float col1[3] = { 1.0f,0.0f,0.2f }; - static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; + static float col1[3] = { 1.0f, 0.0f, 0.2f }; + static float col2[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; ImGui::ColorEdit3("color 1", col1); ImGui::ColorEdit4("color 2", col2); - ImGui::Unindent(); + ImGui::TreePop(); } + if (ImGui::TreeNode("Drag and drop to copy/swap items")) { - ImGui::BulletText("Drag and drop to copy/swap items"); - ImGui::Indent(); enum Mode { Mode_Copy, @@ -1577,7 +1574,31 @@ static void ShowDemoWindowWidgets() } ImGui::PopID(); } - ImGui::Unindent(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Drag to reorder items (simple)")) + { + // Simple reordering + HelpMarker("We don't use the drag and drop api at all here! Instead we query when the item is held but not hovered, and order items accordingly."); + static const char* item_names[] = { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" }; + for (int n = 0; n < IM_ARRAYSIZE(item_names); n++) + { + const char* item = item_names[n]; + ImGui::Selectable(item); + + if (ImGui::IsItemActive() && !ImGui::IsItemHovered()) + { + int n_next = n + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1); + if (n_next >= 0 && n_next < IM_ARRAYSIZE(item_names)) + { + item_names[n] = item_names[n_next]; + item_names[n_next] = item; + ImGui::ResetMouseDragDelta(); + } + } + } + ImGui::TreePop(); } ImGui::TreePop(); @@ -1607,10 +1628,10 @@ static void ShowDemoWindowWidgets() if (item_type == 10){ ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy. if (item_type == 11){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", ¤t, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); } - // Display the value of IsItemHovered() and other common item state functions. + // Display the value of IsItemHovered() and other common item state functions. // Note that the ImGuiHoveredFlags_XXX flags can be combined. - // Because BulletText is an item itself and that would affect the output of IsItemXXX functions, - // we query every state in a single call to avoid storing them and to simplify the code + // Because BulletText is an item itself and that would affect the output of IsItemXXX functions, + // we query every state in a single call to avoid storing them and to simplify the code ImGui::BulletText( "Return value = %d\n" "IsItemFocused() = %d\n" @@ -1653,7 +1674,7 @@ static void ShowDemoWindowWidgets() if (embed_all_inside_a_child_window) ImGui::BeginChild("outer_child", ImVec2(0, ImGui::GetFontSize() * 20), true); - // Testing IsWindowFocused() function with its various flags. + // Testing IsWindowFocused() function with its various flags. // Note that the ImGuiFocusedFlags_XXX flags can be combined. ImGui::BulletText( "IsWindowFocused() = %d\n" From 927472f5ff978bcc9f67708316481a3fcae4c04d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Oct 2019 19:14:08 +0200 Subject: [PATCH 6/6] Combo: Added _NoMove flag to prevent window from docking, which has an effect in Docking branch (in Master was not noticeable as the Combo code kept repositioning the window). (#2835) --- imgui_widgets.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 1561c157..0da7353e 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1505,8 +1505,10 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF SetNextWindowPos(pos); } + // We don't use BeginPopupEx() solely because we have a custom name string, which we could make an argument to BeginPopupEx() + ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove; + // Horizontally align ourselves with the framed text - ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(style.FramePadding.x, style.WindowPadding.y)); bool ret = Begin(name, NULL, window_flags); PopStyleVar();