diff --git a/README.md b/README.md index b4b52ccc..7f211b31 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ In your Render function, try translating your projection matrix by (0.5f,0.5f) o Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). -However note that ImGui is programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential. Many programmers have unfortunately been taught by their environment to make complicated things instead of simple things. Strip yourself out of all those heavy layers and start making tools! +However note that ImGui is programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential. Many programmers have unfortunately been taught by their environment to make complicated unproductive things. Strip yourself out of all those heavy layers and start making lots of useful tools! Is ImGui fast? diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 36de57ec..f4d1e013 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -69,7 +69,7 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int if (g_VboSize < needed_vtx_size) { g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer - glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); } // Copy and convert all vertices into a single contiguous buffer diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp index cdf1fab5..0b57536e 100644 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ b/examples/opengl_example/imgui_impl_glfw.cpp @@ -76,7 +76,7 @@ static void ImGui_ImplGlfw_RenderDrawLists(ImDrawList** const cmd_lists, int cmd { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->texture_id); glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); - glDrawElements(GL_TRIANGLES, pcmd->idx_count, GL_UNSIGNED_SHORT, idx_buffer); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->idx_count, GL_UNSIGNED_SHORT, idx_buffer); } idx_buffer += pcmd->idx_count; } diff --git a/imgui.cpp b/imgui.cpp index d877331a..0d2dc900 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -748,7 +748,7 @@ static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2 rhs) { return ImVec2(lhs.x*rhs.x, lhs.y*rhs.y); } static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2 rhs) { return ImVec2(lhs.x/rhs.x, lhs.y/rhs.y); } static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } -static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } +//static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } //static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-lhs.w); } @@ -6410,6 +6410,31 @@ bool ImGui::DragFloat4(const char* label, float v[2], float v_speed, float v_min return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); } +bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* display_format, const char* display_format_max, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGui::PushID(label); + ImGui::BeginGroup(); + PushMultiItemsWidths(2); + + 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); + 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::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + ImGui::PopID(); + + return value_changed; +} + // NB: v_speed is float to allow adjusting the drag speed with more precision bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format) { @@ -6463,6 +6488,31 @@ bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); } +bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* display_format, const char* display_format_max) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGui::PushID(label); + ImGui::BeginGroup(); + PushMultiItemsWidths(2); + + 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); + 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::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + ImGui::PopID(); + + return value_changed; +} + enum ImGuiPlotType { ImGuiPlotType_Lines, @@ -11354,6 +11404,19 @@ void ImGui::ShowTestWindow(bool* opened) //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); //ImGui::PopItemWidth(); + if (ImGui::TreeNode("Ranges")) + { + ImGui::Unindent(); + + static float begin = 10, end = 90; + static int begin_i = 100, end_i = 1000; + ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%"); + ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %.0f units", "Max: %.0f units"); + + ImGui::Indent(); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Multi-component Widgets")) { ImGui::Unindent(); @@ -11711,7 +11774,7 @@ void ImGui::ShowTestWindow(bool* opened) if (i > 0) ImGui::SameLine(); ImGui::BeginGroup(); ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom"); - ImGui::BeginChild(ImGui::GetID((void *)i), ImVec2(ImGui::GetWindowWidth() * 0.17f, 200.0f), true); + ImGui::BeginChild(ImGui::GetID((void *)(intptr_t)i), ImVec2(ImGui::GetWindowWidth() * 0.17f, 200.0f), true); if (scroll_to) ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_px, i * 0.25f); for (int line = 0; line < 100; line++) diff --git a/imgui.h b/imgui.h index 66471bbb..9b0cbb79 100644 --- a/imgui.h +++ b/imgui.h @@ -6,7 +6,9 @@ #pragma once +#if !defined(IMGUI_DISABLE_INCLUDE_IMCONFIG_H) || defined(IMGUI_INCLUDE_IMCONFIG_H) #include "imconfig.h" // User-editable configuration file +#endif #include // FLT_MAX #include // va_list #include // ptrdiff_t, NULL @@ -58,7 +60,7 @@ struct ImVec2 ImVec2() { x = y = 0.0f; } ImVec2(float _x, float _y) { x = _x; y = _y; } -#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2. +#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2. IM_VEC2_CLASS_EXTRA #endif }; @@ -69,7 +71,7 @@ struct ImVec4 ImVec4() { x = y = z = w = 0.0f; } ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } -#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec4. +#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4. IM_VEC4_CLASS_EXTRA #endif }; @@ -195,8 +197,8 @@ namespace ImGui IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y // ID scopes - // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them - // You can also use "##extra" within your widget name to distinguish them from each others (see 'Programmer Guide') + // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. + // You can also use "##extra" within your widget name to distinguish them from each others. Read the FAQ for more details. IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack! IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); IMGUI_API void PushID(const void* ptr_id); @@ -248,10 +250,12 @@ namespace ImGui IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", const char* display_format_max = NULL, float power = 1.0f); IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_min >= v_max we have no bound IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); + IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL); // Widgets: Input IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);