From 5ab23ab1c0f945b247f1115e80de27f1abead25a Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Jul 2015 17:25:56 -0600 Subject: [PATCH 1/6] Allegro 5 example: removed public domain mark, MIT as the rest, with @bggd approval --- examples/allegro5_example/README.md | 2 -- examples/allegro5_example/imgui_impl_a5.cpp | 2 +- examples/allegro5_example/imgui_impl_a5.h | 2 +- examples/allegro5_example/main.cpp | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/allegro5_example/README.md b/examples/allegro5_example/README.md index 62128a33..9488b938 100644 --- a/examples/allegro5_example/README.md +++ b/examples/allegro5_example/README.md @@ -14,5 +14,3 @@ g++ -I ../imgui main.cpp imgui_impl_a5.cpp ../imgui/imgui.cpp -lallegro -lallegr ``` cl /MD /I /I ..\imgui main.cpp imgui_impl_a5.cpp ..\imgui\imgui.cpp /link /LIBPATH: allegro-5.0.10-monolith-md.lib user32.lib ``` - -public domain diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index 9d3c94e3..126e2185 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -1,6 +1,6 @@ // ImGui Allegro 5 bindings // https://github.com/ocornut/imgui -// by @birthggd, public domain +// by @birthggd #include // uint64_t #include // memcpy diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h index e31ecfe7..0285381e 100644 --- a/examples/allegro5_example/imgui_impl_a5.h +++ b/examples/allegro5_example/imgui_impl_a5.h @@ -1,6 +1,6 @@ // ImGui Allegro 5 bindings // https://github.com/ocornut/imgui -// by @birthggd, public domain +// by @birthggd #pragma once diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 4de89251..1898a579 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -1,5 +1,4 @@ // ImGui - standalone example application for Allegro 5 -// public domain #include #include From f2bed00d80006f8b5563066f9d4760629e0f5a37 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Jul 2015 08:39:44 -0600 Subject: [PATCH 2/6] Examples: README --- examples/README.txt | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index f5af693f..cb0aefa8 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1,17 +1,29 @@ Those are standalone ready-to-build applications to demonstrate ImGui. -Unfortunately in 2015 it is still a massive pain to create and maintain portable build files. +Binaries of those demos are available from the main GitHub page. + +ImGui is highly portable and only requires a few things to run: + - Providing mouse/keyboard inputs + - Load the font atlas texture into GPU memory + - Providing a render function to process the drawing commands (we rendere indexed textured triangles) + - Extra just as clipboard support, mouse cursor supports, Windows IME support. +So this is essentially what those examples are doing + the obligatory cruft for portability. + +Unfortunately in 2015 it is still a massive pain to create and maintain portable build files using +external library like the ones used here. I choose to provide Visual Studio 10 .sln files and Makefile for Linux/OSX. Please let me know if they don't work with your setup! -You can probably just import the .cpp files into your own system and figure out the linkage from there. +You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those +directly with a command-line compiler. opengl_example/ OpenGL example, using GLFW + fixed pipeline. This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works, because it is the simplest shortest one! + Prefer following this example to learn how ImGui works! opengl3_example/ OpenGL example, using GLFW/GL3W + programmable pipeline. - This uses more modern calls and custom shaders. + This uses more modern OpenGL calls and custom shaders. + Even if your application is using modern OpenGL you are better off copying the code from the fixed pipeline version! I don't think there is an advantage using this over the simpler example, but it is provided for reference. directx9_example/ @@ -22,11 +34,11 @@ directx11_example/ This is quite long and tedious, because: DirectX11. ios_example/ - iOS example. - Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. + iOS example. + Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. sdl_opengl_example/ - SDL2 + OpenGL example. + SDL2 + OpenGL example. allegro5_example/ - Allegro 5 example. + Allegro 5 example. From d2701727b9475c923749b6eac7177f5e957d3e38 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 10 Jul 2015 18:17:46 -0600 Subject: [PATCH 3/6] InputText: added ImGuiInputTextFlags_NoHorizontalScroll flag. Added HasSelection() helper in ImGuiTextEditCallbackData as a clarification. --- imgui.cpp | 17 ++++++++++++----- imgui.h | 2 ++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 284782ea..6034d1fc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7419,11 +7419,18 @@ static bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (edit_state.CursorFollow) { // Horizontal scroll in chunks of quarter width - const float scroll_increment_x = size.x * 0.25f; - if (cursor_offset.x < edit_state.ScrollX) - edit_state.ScrollX = ImMax(0.0f, cursor_offset.x - scroll_increment_x); - else if (cursor_offset.x - size.x >= edit_state.ScrollX) - edit_state.ScrollX = cursor_offset.x - size.x + scroll_increment_x; + if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll)) + { + const float scroll_increment_x = size.x * 0.25f; + if (cursor_offset.x < edit_state.ScrollX) + edit_state.ScrollX = ImMax(0.0f, cursor_offset.x - scroll_increment_x); + else if (cursor_offset.x - size.x >= edit_state.ScrollX) + edit_state.ScrollX = cursor_offset.x - size.x + scroll_increment_x; + } + else + { + edit_state.ScrollX = 0.0f; + } // Vertical scroll if (is_multiline) diff --git a/imgui.h b/imgui.h index 9c5eb404..f174841b 100644 --- a/imgui.h +++ b/imgui.h @@ -461,6 +461,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter). + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally // [Internal] ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() }; @@ -919,6 +920,7 @@ struct ImGuiTextEditCallbackData // NB: calling those function loses selection. void DeleteChars(int pos, int bytes_count); void InsertChars(int pos, const char* text, const char* text_end = NULL); + bool HasSelection() const { return SelectionStart != SelectionEnd; } }; // ImColor() is just a helper that implicity converts to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float) From 827ff970cd0feaa7d71a90e9ce10359207042094 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 10 Jul 2015 18:47:55 -0600 Subject: [PATCH 4/6] InputText: Added ImGuiInputTextFlags_AlwaysInsertMode flag --- imgui.cpp | 2 ++ imgui.h | 1 + 2 files changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 6034d1fc..e660048b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7120,6 +7120,8 @@ static bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 edit_state.StbState.select_start = ImMin(edit_state.StbState.select_start, edit_state.CurLenW); edit_state.StbState.select_end = ImMin(edit_state.StbState.select_end, edit_state.CurLenW); } + if (flags & ImGuiInputTextFlags_AlwaysInsertMode) + edit_state.StbState.insert_mode = true; if (!is_multiline && (focus_requested_by_tab || (user_clicked && is_ctrl_down))) select_all = true; } diff --git a/imgui.h b/imgui.h index f174841b..a0192338 100644 --- a/imgui.h +++ b/imgui.h @@ -462,6 +462,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter). ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally + ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode // [Internal] ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() }; From 8094aa78d2c150476d20f62d71143762c75345dc Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 10 Jul 2015 18:54:26 -0600 Subject: [PATCH 5/6] Fixed incorrect assert triggering when code steal ActiveID move user moving window by calling e.g. SetKeyboardFocusHere() --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e660048b..82d3f1dc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1288,7 +1288,7 @@ struct ImGuiState bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdIsFocusedOnly; // Set only by active widget. Denote focus but no active interaction ImGuiWindow* ActiveIdWindow; - ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Only valid if ActiveID is the "#MOVE" identifier of a window. + ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Pointer is only valid if ActiveID is the "#MOVE" identifier of a window. float SettingsDirtyTimer; ImVector Settings; int DisableHideTextAfterDoubleHash; @@ -2399,13 +2399,14 @@ void ImGui::Render() ImGui::End(); // Click to focus window and start moving (after we're done with all our widgets) + if (!g.ActiveId) + g.MovedWindow = NULL; if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0]) { if (!(g.FocusedWindow && !g.FocusedWindow->WasActive && g.FocusedWindow->Active)) // Unless we just made a popup appear { if (g.HoveredRootWindow != NULL) { - IM_ASSERT(g.MovedWindow == NULL); g.MovedWindow = g.HoveredWindow; SetActiveId(g.HoveredRootWindow->MoveID, g.HoveredRootWindow); } From b67593a4b179228be9b67cd0615a866288028e70 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 10 Jul 2015 19:36:34 -0600 Subject: [PATCH 6/6] Changed SameLine() parameters from int to float. --- imgui.cpp | 57 ++++++++++++++++++++++++++++--------------------------- imgui.h | 2 +- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 82d3f1dc..f4c13809 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -136,6 +136,7 @@ Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. + - 2015/07/10 (1.43) - changed SameLine() parameters from int to float. - 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete). - 2015/07/02 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount. - 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence @@ -6161,7 +6162,7 @@ static bool SliderFloatN(const char* label, float* v, int components, float v_mi { ImGui::PushID(i); value_changed |= ImGui::SliderFloat("##v", &v[i], v_min, v_max, display_format, power); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::PopID(); ImGui::PopItemWidth(); } @@ -6203,7 +6204,7 @@ static bool SliderIntN(const char* label, int* v, int components, int v_min, int { ImGui::PushID(i); value_changed |= ImGui::SliderInt("##v", &v[i], v_min, v_max, display_format); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::PopID(); ImGui::PopItemWidth(); } @@ -6387,7 +6388,7 @@ static bool DragFloatN(const char* label, float* v, int components, float v_spee { ImGui::PushID(i); value_changed |= ImGui::DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::PopID(); ImGui::PopItemWidth(); } @@ -6427,10 +6428,10 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu bool value_changed = ImGui::DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power); ImGui::PopItemWidth(); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); value_changed |= ImGui::DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power); ImGui::PopItemWidth(); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); ImGui::EndGroup(); @@ -6465,7 +6466,7 @@ static bool DragIntN(const char* label, int* v, int components, float v_speed, i { ImGui::PushID(i); value_changed |= ImGui::DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::PopID(); ImGui::PopItemWidth(); } @@ -6505,10 +6506,10 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_ bool value_changed = ImGui::DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? IM_INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format); ImGui::PopItemWidth(); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); value_changed |= ImGui::DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? IM_INT_MAX : v_max, display_format_max ? display_format_max : display_format); ImGui::PopItemWidth(); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); ImGui::EndGroup(); @@ -6672,7 +6673,7 @@ bool ImGui::Checkbox(const char* label, bool* v) ImRect total_bb = check_bb; if (label_size.x > 0) - SameLine(0, (int)style.ItemInnerSpacing.x); + SameLine(0, style.ItemInnerSpacing.x); const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); if (label_size.x > 0) { @@ -6730,7 +6731,7 @@ bool ImGui::RadioButton(const char* label, bool active) ImRect total_bb = check_bb; if (label_size.x > 0) - SameLine(0, (int)style.ItemInnerSpacing.x); + SameLine(0, style.ItemInnerSpacing.x); const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); if (label_size.x > 0) { @@ -7575,13 +7576,13 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, if (step > 0.0f) { ImGui::PopItemWidth(); - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) { *v -= g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; value_changed = true; } - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) { *v += g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; @@ -7592,7 +7593,7 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, if (label_size.x > 0) { - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); ItemSize(label_size, style.FramePadding.y); } @@ -7625,7 +7626,7 @@ static bool InputFloatN(const char* label, float* v, int components, int decimal { ImGui::PushID(i); value_changed |= ImGui::InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::PopID(); ImGui::PopItemWidth(); } @@ -7668,7 +7669,7 @@ static bool InputIntN(const char* label, int* v, int components, ImGuiInputTextF { ImGui::PushID(i); value_changed |= ImGui::InputInt("##v", &v[i], 0, 0, extra_flags); - ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::PopID(); ImGui::PopItemWidth(); } @@ -8342,7 +8343,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) for (int n = 0; n < components; n++) { if (n > 0) - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); if (n + 1 == components) ImGui::PushItemWidth(w_item_last); value_changed |= ImGui::DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]); @@ -8377,7 +8378,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) break; } - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); const ImVec4 col_display(col[0], col[1], col[2], 1.0f); if (ImGui::ColorButton(col_display)) @@ -8385,7 +8386,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) { - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); const char* button_titles[3] = { "RGB", "HSV", "HEX" }; if (ButtonEx(button_titles[edit_mode], ImVec2(0,0), ImGuiButtonFlags_DontClosePopups)) g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! @@ -8393,7 +8394,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) } else { - ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); } ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); @@ -8615,11 +8616,11 @@ void ImGui::EndGroup() } // Gets back to previous line and continue with horizontal layout -// column_x == 0 : follow on previous item -// columm_x != 0 : align to specified column +// pos_x == 0 : follow on previous item +// pos_x != 0 : align to specified column // spacing_w < 0 : use default spacing if column_x==0, no spacing if column_x!=0 // spacing_w >= 0 : enforce spacing -void ImGui::SameLine(int column_x, int spacing_w) +void ImGui::SameLine(float pos_x, float spacing_w) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -8627,16 +8628,16 @@ void ImGui::SameLine(int column_x, int spacing_w) return; float x, y; - if (column_x != 0) + if (pos_x != 0.0f) { - if (spacing_w < 0) spacing_w = 0; - x = window->Pos.x + (float)column_x + (float)spacing_w; + if (spacing_w < 0.0f) spacing_w = 0.0f; + x = window->Pos.x + pos_x + spacing_w; y = window->DC.CursorPosPrevLine.y; } else { - if (spacing_w < 0) spacing_w = (int)g.Style.ItemSpacing.x; - x = window->DC.CursorPosPrevLine.x + (float)spacing_w; + if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x; + x = window->DC.CursorPosPrevLine.x + spacing_w; y = window->DC.CursorPosPrevLine.y; } window->DC.CurrentLineHeight = window->DC.PrevLineHeight; @@ -11368,7 +11369,7 @@ void ImGui::ShowTestWindow(bool* opened) } } ImGui::PlotLines("##Graph", &values.front(), (int)values.Size, values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); - ImGui::SameLine(0, (int)ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x); ImGui::BeginGroup(); ImGui::Text("Graph"); ImGui::Checkbox("pause", &pause); diff --git a/imgui.h b/imgui.h index a0192338..3964fd94 100644 --- a/imgui.h +++ b/imgui.h @@ -170,7 +170,7 @@ namespace ImGui IMGUI_API void BeginGroup(); // once closing a group it is seen as a single item (so you can use IsItemHovered() on a group, SameLine() between groups, etc. IMGUI_API void EndGroup(); IMGUI_API void Separator(); // horizontal line - IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets or groups to layout them horizontally + IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally IMGUI_API void Spacing(); // add spacing IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels