From 0e4e120cc8210b45a6b2175d518c69d0770018f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 21 Apr 2015 16:30:13 -0700 Subject: [PATCH] Updated to latest imgui. --- 3rdparty/ocornut-imgui/imconfig.h | 15 +- 3rdparty/ocornut-imgui/imgui.cpp | 258 ++++++++++++++++++++++++------ 3rdparty/ocornut-imgui/imgui.h | 16 +- 3 files changed, 229 insertions(+), 60 deletions(-) diff --git a/3rdparty/ocornut-imgui/imconfig.h b/3rdparty/ocornut-imgui/imconfig.h index ec57f213..17cad4a4 100644 --- a/3rdparty/ocornut-imgui/imconfig.h +++ b/3rdparty/ocornut-imgui/imconfig.h @@ -19,20 +19,25 @@ //#define IMGUI_API __declspec( dllimport ) //---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) -#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS -#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS #define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION #define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION -//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) -//#define IMGUI_DISABLE_TEST_WINDOWS - //---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions. //#define IMGUI_INCLUDE_IMGUI_USER_INL //---- Include imgui_user.h at the end of imgui.h //#define IMGUI_INCLUDE_IMGUI_USER_H +//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) +#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS +#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS + +//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) +//#define IMGUI_DISABLE_TEST_WINDOWS + +//---- Implement STB libraries in a namespace to avoid conflicts +//#define IMGUI_STB_NAMESPACE ImStb + //---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. /* #define IM_VEC2_CLASS_EXTRA \ diff --git a/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/ocornut-imgui/imgui.cpp index d23ba119..e62a3d62 100644 --- a/3rdparty/ocornut-imgui/imgui.cpp +++ b/3rdparty/ocornut-imgui/imgui.cpp @@ -1,4 +1,4 @@ -// ImGui library v1.38 WIP +// ImGui library v1.39 WIP // See ImGui::ShowTestWindow() for sample code. // Read 'Programmer guide' below for notes on how to setup ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui @@ -13,6 +13,7 @@ - API BREAKING CHANGES (read me when you update!) - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - Can I have multiple widgets with the same label? (Yes) + - How do I update to a newer version of ImGui? - Why is my text output blurry? - How can I load a different font than the default? - How can I load multiple fonts? @@ -268,6 +269,15 @@ e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change. e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! + Q: How do I update to a newer version of ImGui? + A: Overwrite the following files: + imgui.cpp + imgui.h + stb_rect_pack.h + stb_textedit.h + stb_truetype.h + Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. + Q: Why is my text output blurry? A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) @@ -494,7 +504,7 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id); static void ItemSize(ImVec2 size, float text_offset_y = 0.0f); static void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); static void PushColumnClipRect(int column_index = -1); -static bool IsClippedEx(const ImRect& bb, bool clip_even_when_logged); +static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); static bool IsMouseHoveringRect(const ImRect& bb); static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); @@ -1148,8 +1158,10 @@ struct ImGuiState ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiStorage ColorEditModeStorage; // for user selection ImGuiID ActiveComboID; + ImVec2 ActiveClickDeltaToCenter; float DragCurrentValue; // current dragged value, always float, not rounded by end-user precision settings ImVec2 DragLastMouseDelta; + float DragSpeedDefaultRatio; // if speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio float DragSpeedScaleSlow; float DragSpeedScaleFast; float ScrollbarClickDeltaToGrabCenter; // distance between mouse and center of grab box, normalized in parent space @@ -1205,8 +1217,10 @@ struct ImGuiState ScalarAsInputTextId = 0; ActiveComboID = 0; + ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f); DragCurrentValue = 0.0f; DragLastMouseDelta = ImVec2(0.0f, 0.0f); + DragSpeedDefaultRatio = 0.01f; DragSpeedScaleSlow = 0.01f; DragSpeedScaleFast = 10.0f; ScrollbarClickDeltaToGrabCenter = 0.0f; @@ -1403,6 +1417,14 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) return &it->val_f; } +void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_p; +} + // FIXME-OPT: Wasting CPU because all SetInt() are preceeded by GetInt() calls so we should have the result from lower_bound already in place. // However we only use SetInt() on explicit user action (so that's maximum once a frame) so the optimisation isn't much needed. void ImGuiStorage::SetInt(ImU32 key, int val) @@ -4255,7 +4277,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) while (line < text_end) { const char* line_end = strchr(line, '\n'); - if (IsClippedEx(line_rect, false)) + if (IsClippedEx(line_rect, NULL, false)) break; const ImVec2 line_size = CalcTextSize(line, line_end, false); @@ -5126,7 +5148,7 @@ static inline float RoundScalar(float value, int decimal_precision) return value; } -static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal) +static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -5137,15 +5159,16 @@ static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGu const bool is_non_linear = fabsf(power - 1.0f) > 0.0001f; - const float slider_sz = horizontal ? slider_bb.GetWidth() : slider_bb.GetHeight(); + const float padding = horizontal ? style.FramePadding.x : style.FramePadding.y; + const float slider_sz = horizontal ? (frame_bb.GetWidth() - padding * 2.0f) : (frame_bb.GetHeight() - padding * 2.0f); float grab_sz; if (decimal_precision > 0) grab_sz = ImMin(style.GrabMinSize, slider_sz); else grab_sz = ImMin(ImMax(1.0f * (slider_sz / (v_max-v_min+1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit const float slider_usable_sz = slider_sz - grab_sz; - const float slider_usable_pos_min = (horizontal ? slider_bb.Min.x : slider_bb.Min.y) + grab_sz*0.5f; - const float slider_usable_pos_max = (horizontal ? slider_bb.Max.x : slider_bb.Max.y) - grab_sz*0.5f; + const float slider_usable_pos_min = (horizontal ? frame_bb.Min.x : frame_bb.Min.y) + padding + grab_sz*0.5f; + const float slider_usable_pos_max = (horizontal ? frame_bb.Max.x : frame_bb.Max.y) - padding - grab_sz*0.5f; bool value_changed = false; @@ -5183,7 +5206,7 @@ static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGu // Negative: rescale to the negative range before powering float a = 1.0f - (normalized_pos / linear_zero_pos); a = powf(a, power); - new_value = ImLerp(ImMin(v_max,0.f), v_min, a); + new_value = ImLerp(ImMin(v_max,0.0f), v_min, a); } else { @@ -5272,7 +5295,6 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); 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)); // NB- we don't call ItemSize() yet because we may turn into a text edit box below @@ -5312,16 +5334,16 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c ItemSize(total_bb, style.FramePadding.y); // Actual slider behavior + render grab - const bool value_changed = SliderBehavior(frame_bb, inner_bb, id, v, v_min, v_max, power, decimal_precision, true); + const bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, true); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. char value_buf[64]; const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); - RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, inner_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); + RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); return value_changed; } @@ -5338,7 +5360,6 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); - const ImRect slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); ItemSize(bb, style.FramePadding.y); @@ -5361,17 +5382,17 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float } // Actual slider behavior + render grab - bool value_changed = SliderBehavior(frame_bb, slider_bb, id, v, v_min, v_max, power, decimal_precision, false); + bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, false); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. // For the vertical slider we allow centered text to overlap the frame padding char value_buf[64]; char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); - RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x, slider_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); + RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, slider_bb.Min.y), label); + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); return value_changed; } @@ -5405,7 +5426,7 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, } // Add multiple sliders on 1 line for compact edition of multiple components -static bool SliderFloatN(const char* label, float v[3], int components, float v_min, float v_max, const char* display_format, float power) +static bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -5457,7 +5478,7 @@ bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); } -static bool SliderIntN(const char* label, int v[3], int components, int v_min, int v_max, const char* display_format) +static bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -5522,7 +5543,7 @@ static bool DragScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, flo bool value_changed = false; - // Process clicking on the slider + // Process clicking on the drag if (g.ActiveId == id) { if (g.IO.MouseDown[0]) @@ -5538,10 +5559,12 @@ static bool DragScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, flo if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f) { float speed = v_speed; + if (speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) + speed = (v_max - v_min) * g.DragSpeedDefaultRatio; if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) - speed = v_speed * g.DragSpeedScaleFast; + speed = speed * g.DragSpeedScaleFast; if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) - speed = v_speed * g.DragSpeedScaleSlow; + speed = speed * g.DragSpeedScaleSlow; float v_cur = g.DragCurrentValue; float delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; @@ -5650,6 +5673,58 @@ bool ImGui::DragFloat(const char* label, float *v, float v_speed, float v_min, f return value_changed; } +static bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power); +} + +bool ImGui::DragFloat3(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power); +} + +bool ImGui::DragFloat4(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); +} + // 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) { @@ -5661,6 +5736,58 @@ bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_m return value_changed; } +static bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format) +{ + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const float w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); + + bool value_changed = false; + ImGui::BeginGroup(); + ImGui::PushID(label); + ImGui::PushItemWidth(w_item_one); + for (int i = 0; i < components; i++) + { + ImGui::PushID(i); + if (i + 1 == components) + { + ImGui::PopItemWidth(); + ImGui::PushItemWidth(w_item_last); + } + value_changed |= ImGui::DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); + ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::PopID(); + + ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); + + return value_changed; +} + +bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format); +} + +bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format); +} + +bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); +} + enum ImGuiPlotType { ImGuiPlotType_Lines, @@ -6863,7 +6990,8 @@ bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg) const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : w, size_arg.y != 0.0f ? size_arg.y : label_size.y); ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); - bb.Max.x += style.AutoFitPadding.x; + if (size_arg.x == 0.0f) + bb.Max.x += style.AutoFitPadding.x; // Selectables are meant to be tightly packed together. So for both rendering and collision we extend to compensate for spacing. ImRect bb_with_spacing = bb; @@ -7254,15 +7382,16 @@ static inline void ItemSize(const ImRect& bb, float text_offset_y) ItemSize(bb.GetSize(), text_offset_y); } -static bool IsClippedEx(const ImRect& bb, bool clip_even_when_logged) +static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (!bb.Overlaps(ImRect(window->ClipRectStack.back()))) { - if (clip_even_when_logged || !g.LogEnabled) - return true; + if (!id || *id != GImGui->ActiveId) + if (clip_even_when_logged || !g.LogEnabled) + return true; } return false; } @@ -7270,7 +7399,7 @@ static bool IsClippedEx(const ImRect& bb, bool clip_even_when_logged) bool ImGui::IsRectClipped(const ImVec2& size) { ImGuiWindow* window = GetCurrentWindow(); - return IsClippedEx(ImRect(window->DC.CursorPos, window->DC.CursorPos + size), true); + return IsClippedEx(ImRect(window->DC.CursorPos, window->DC.CursorPos + size), NULL, true); } static bool ItemAdd(const ImRect& bb, const ImGuiID* id) @@ -7278,13 +7407,10 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id) ImGuiWindow* window = GetCurrentWindow(); window->DC.LastItemID = id ? *id : 0; window->DC.LastItemRect = bb; - if (IsClippedEx(bb, false)) + if (IsClippedEx(bb, id, false)) { - if (!id || *id != GImGui->ActiveId) - { - window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; - return false; - } + window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; + return false; } // This is a sensible default, but widgets are free to override it after calling ItemAdd() @@ -7414,7 +7540,7 @@ void ImGui::NextColumn() window->DC.CurrentLineTextBaseOffset = 0.0f; PushColumnClipRect(); - ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); + ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); // FIXME } } @@ -7430,6 +7556,21 @@ int ImGui::GetColumnsCount() return window->DC.ColumnsCount; } +static float GetDraggedColumnOffset(int column_index) +{ + // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing + // window creates a feedback loop because we store normalized positions/ So while dragging we enforce absolute positioning + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(g.ActiveId == window->DC.ColumnsSetID + ImGuiID(column_index)); + + float x = g.IO.MousePos.x + g.ActiveClickDeltaToCenter.x; + x -= window->Pos.x; + x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing); + + return x; +} + float ImGui::GetColumnOffset(int column_index) { ImGuiState& g = *GImGui; @@ -7437,6 +7578,13 @@ float ImGui::GetColumnOffset(int column_index) if (column_index < 0) column_index = window->DC.ColumnsCurrent; + if (g.ActiveId) + { + const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index); + if (g.ActiveId == column_id) + return GetDraggedColumnOffset(column_index); + } + // Read from cache IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size()); const float t = window->DC.ColumnsOffsetsT[column_index]; @@ -7513,7 +7661,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i); const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); - if (IsClippedEx(column_rect, false)) + if (IsClippedEx(column_rect, &column_id, false)) continue; bool hovered, held; @@ -7528,10 +7676,11 @@ void ImGui::Columns(int columns_count, const char* id, bool border) if (held) { - x -= window->Pos.x; - x = ImClamp(x + g.IO.MouseDelta.x, ImGui::GetColumnOffset(i-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(i+1)-g.Style.ColumnsMinSpacing); + if (g.ActiveIdIsJustActivated) + g.ActiveClickDeltaToCenter.x = x - g.IO.MousePos.x; + + x = GetDraggedColumnOffset(i); SetColumnOffset(i, x); - x += window->Pos.x; } } } @@ -9866,29 +10015,32 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::InputFloat3("input float3", vec4a); } - /* { static int i1=50; static int i2=42; ImGui::DragInt("drag int", &i1, 1); - ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100); + ImGui::SameLine(); + ImGui::TextColored(ImColor(170,170,170,255), "(?)"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input text"); + + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); static float f1=1.00f; static float f2=0.0067f; ImGui::DragFloat("drag float", &f1, 1.0f); - ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f"); + ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); } - */ { static int i1=0; - static int i2=42; + //static int i2=42; ImGui::SliderInt("slider int 0..3", &i1, 0, 3); - ImGui::SliderInt("slider int -100..100", &i2, -100, 100); + //ImGui::SliderInt("slider int -100..100", &i2, -100, 100); - static float f1=1.123f; - static float f2=0; - ImGui::SliderFloat("slider float", &f1, 0.0f, 2.0f); + static float f1=0.123f; + static float f2=0.0f; + ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); static float angle = 0.0f; ImGui::SliderAngle("slider angle", &angle); @@ -9916,18 +10068,24 @@ void ImGui::ShowTestWindow(bool* opened) static int vec4i[4] = { 1, 5, 100, 255 }; ImGui::InputFloat2("input float2", vec4f); + ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); ImGui::InputInt2("input int2", vec4i); ImGui::SliderInt2("slider int2", vec4i, 0, 255); ImGui::InputFloat3("input float3", vec4f); + ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); ImGui::InputInt3("input int3", vec4i); ImGui::SliderInt3("slider int3", vec4i, 0, 255); ImGui::InputFloat4("input float4", vec4f); + ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); ImGui::InputInt4("input int4", vec4i); + ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); ImGui::SliderInt4("slider int4", vec4i, 0, 255); ImGui::Indent(); @@ -10491,9 +10649,9 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::End(); } -void ImGui::ShowMetricsWindow(bool* opened1) +void ImGui::ShowMetricsWindow(bool* opened) { - if (ImGui::Begin("ImGui Metrics", opened1)) + if (ImGui::Begin("ImGui Metrics", opened)) { ImGui::Text("ImGui %s", ImGui::GetVersion()); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); @@ -10504,13 +10662,13 @@ void ImGui::ShowMetricsWindow(bool* opened1) { static void NodeDrawList(ImDrawList* draw_list, const char* label) { - bool opened = ImGui::TreeNode(draw_list, "%s: %d vtx, %d cmds", label, draw_list->vtx_buffer.size(), draw_list->commands.size()); + bool node_opened = ImGui::TreeNode(draw_list, "%s: %d vtx, %d cmds", label, draw_list->vtx_buffer.size(), draw_list->commands.size()); if (draw_list == ImGui::GetWindowDrawList()) { ImGui::SameLine(); ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) } - if (!opened) + if (!node_opened) return; for (const ImDrawCmd* pcmd = draw_list->commands.begin(); pcmd < draw_list->commands.end(); pcmd++) if (pcmd->user_callback) diff --git a/3rdparty/ocornut-imgui/imgui.h b/3rdparty/ocornut-imgui/imgui.h index 49bc50c2..bb9af931 100644 --- a/3rdparty/ocornut-imgui/imgui.h +++ b/3rdparty/ocornut-imgui/imgui.h @@ -1,4 +1,4 @@ -// ImGui library v1.38 WIP +// ImGui library v1.39 WIP // See .cpp file for documentation. // See ImGui::ShowTestWindow() for sample code. // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase. @@ -13,7 +13,7 @@ #include // NULL, malloc, free, qsort, atoi #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.38 WIP" +#define IMGUI_VERSION "1.39 WIP" // Define assertion handler. #ifndef IM_ASSERT @@ -317,9 +317,14 @@ namespace ImGui IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); // Widgets: Drags (tip: ctrl+click on a drag box to input text) - // ImGui 1.38+ work-in-progress, may change name or API. - IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_max >= v_max we have no bound - 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_max >= v_max we have no bound + IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_max >= v_max we have no bound + 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 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_max >= 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"); // 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); @@ -799,6 +804,7 @@ struct ImGuiStorage // - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application. IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0); + IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL); // Use on your own storage if you know only integer are being stored (open/close all tree nodes) IMGUI_API void SetAllInt(int val);