From 9cb271f4c856c41ecd305882885308836e988834 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 15 Jun 2016 23:09:40 +0200 Subject: [PATCH 01/47] Fixed minor text clipping issue in window title for when using font straying above usual line (#699) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index e0fca101..e67f5a90 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4265,7 +4265,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (style.WindowTitleAlign & ImGuiAlign_Center) pad_right = pad_left; if (pad_left) text_min.x += g.FontSize + style.ItemInnerSpacing.x; if (pad_right) text_max.x -= g.FontSize + style.ItemInnerSpacing.x; - RenderTextClipped(text_min, text_max, name, NULL, &text_size, style.WindowTitleAlign, NULL, &clip_max); + ImVec2 clip_min = ImVec2(text_min.x, window->Pos.y); + RenderTextClipped(text_min, text_max, name, NULL, &text_size, style.WindowTitleAlign, &clip_min, &clip_max); } // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() From 92bff4c8d7cbb7505ce06d33d7e10958ce710e1d Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 16 Jun 2016 23:09:48 +0200 Subject: [PATCH 02/47] ColorEdit4(): better preserve inputting value out of 0..255 range, display then clamped in Hexadecimal form --- imgui.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e67f5a90..5cfe3653 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -863,7 +863,8 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) // HELPERS //----------------------------------------------------------------------------- -#define IM_F32_TO_INT8(_VAL) ((int)((_VAL) * 255.0f + 0.5f)) +#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose +#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 // Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. #ifdef _WIN32 @@ -1184,10 +1185,10 @@ ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in) ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) { ImU32 out; - out = ((ImU32)IM_F32_TO_INT8(ImSaturate(in.x))); - out |= ((ImU32)IM_F32_TO_INT8(ImSaturate(in.y))) << 8; - out |= ((ImU32)IM_F32_TO_INT8(ImSaturate(in.z))) << 16; - out |= ((ImU32)IM_F32_TO_INT8(ImSaturate(in.w))) << 24; + out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)); + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << 8; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << 16; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << 24; return out; } @@ -7944,8 +7945,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 { edit_state.CursorAnim += g.IO.DeltaTime; - // We need to: - // - Display the text (this can be more easily clipped) + // This is going to be messy. We need to: + // - Display the text (this alone can be more easily clipped) // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation) // - Measure text height (for scrollbar) // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) @@ -8110,14 +8111,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() - bool ret = InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); - return ret; + return InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); } bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { - bool ret = InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); - return ret; + return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); } // NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument) @@ -8851,7 +8850,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde RenderFrame(bb.Min, bb.Max, GetColorU32(col), outline_border, style.FrameRounding); if (hovered) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8(col.x), IM_F32_TO_INT8(col.y), IM_F32_TO_INT8(col.z), IM_F32_TO_INT8(col.z)); + SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8_SAT(col.x), IM_F32_TO_INT8_SAT(col.y), IM_F32_TO_INT8_SAT(col.z), IM_F32_TO_INT8_SAT(col.z)); return pressed; } @@ -8892,7 +8891,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) if (edit_mode == ImGuiColorEditMode_HSV) ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); - int i[4] = { IM_F32_TO_INT8(f[0]), IM_F32_TO_INT8(f[1]), IM_F32_TO_INT8(f[2]), IM_F32_TO_INT8(f[3]) }; + int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; int components = alpha ? 4 : 3; bool value_changed = false; @@ -8969,7 +8968,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here if (IsItemHovered()) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8(col[0]), IM_F32_TO_INT8(col[1]), IM_F32_TO_INT8(col[2]), IM_F32_TO_INT8(col[3])); + SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8_SAT(col[0]), IM_F32_TO_INT8_SAT(col[1]), IM_F32_TO_INT8_SAT(col[2]), IM_F32_TO_INT8_SAT(col[3])); if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) { From 4621b357c1c6d9d4c4872c8bf45bb81ba0724ca0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 19 Jun 2016 12:50:22 +0200 Subject: [PATCH 03/47] Wrapped text: fixed incorrect testing for negative wrap coordinates, they are perfectly legal. (#706) --- imgui.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5cfe3653..9e21d0b2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1946,8 +1946,7 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) else if (wrap_pos_x > 0.0f) wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space - const float wrap_width = wrap_pos_x > 0.0f ? ImMax(wrap_pos_x - pos.x, 0.00001f) : 0.0f; - return wrap_width; + return ImMax(wrap_pos_x - pos.x, 1.0f); } //----------------------------------------------------------------------------- @@ -5356,9 +5355,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); // Account of baseline offset - ImVec2 text_pos = window->DC.CursorPos; - text_pos.y += window->DC.CurrentLineTextBaseOffset; - + ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset); ImRect bb(text_pos, text_pos + text_size); ItemSize(text_size); if (!ItemAdd(bb, NULL)) From 2f4e2eec68975c42c3b0b63d3babaa6a4a0b31f9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 25 Jun 2016 13:54:34 +0200 Subject: [PATCH 04/47] InputText, ImGuiTextFilter: using strncpy instead of printf("%s"). --- imgui.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9e21d0b2..7a755a27 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -895,6 +895,13 @@ int ImStrnicmp(const char* str1, const char* str2, int count) return d; } +void ImStrncpy(char* dst, const char* src, int count) +{ + if (count < 1) return; + strncpy(dst, src, (size_t)count); + dst[count-1] = 0; +} + char* ImStrdup(const char *str) { size_t len = strlen(str) + 1; @@ -1431,7 +1438,7 @@ ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) { if (default_filter) { - ImFormatString(InputBuf, IM_ARRAYSIZE(InputBuf), "%s", default_filter); + ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf)); Build(); } else @@ -7631,9 +7638,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) // From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode) const int prev_len_w = edit_state.CurLenW; - edit_state.Text.resize(buf_size+1); // wchar count <= utf-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. - edit_state.InitialText.resize(buf_size+1); // utf-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. - ImFormatString(edit_state.InitialText.Data, edit_state.InitialText.Size, "%s", buf); + edit_state.Text.resize(buf_size+1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + edit_state.InitialText.resize(buf_size+1); // UTF-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + ImStrncpy(edit_state.InitialText.Data, buf, edit_state.InitialText.Size); const char* buf_end = NULL; edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); edit_state.CurLenA = (int)(buf_end - buf); // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. @@ -7839,7 +7846,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Restore initial value if (is_editable) { - ImFormatString(buf, buf_size, "%s", edit_state.InitialText.Data); + ImStrncpy(buf, edit_state.InitialText.Data, buf_size); value_changed = true; } } @@ -7925,7 +7932,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Copy back to user buffer if (is_editable && strcmp(edit_state.TempTextBuffer.Data, buf) != 0) { - ImFormatString(buf, buf_size, "%s", edit_state.TempTextBuffer.Data); + ImStrncpy(buf, edit_state.TempTextBuffer.Data, buf_size); value_changed = true; } } From 13615a1318364addbc7c80c464f21650bb2b2272 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 25 Jun 2016 13:57:05 +0200 Subject: [PATCH 05/47] InputText: render currently edited buffer from the internal buffer, toward #701 --- imgui.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7a755a27..225714c0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7938,10 +7938,13 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } + // Render + // Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on. + const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempTextBuffer.Data : buf; buf = NULL; + if (!is_multiline) RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - // Render 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 ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; ImVec2 text_size(0.f, 0.f); @@ -8067,7 +8070,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } - draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf, buf+edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); // Draw blinking cursor bool cursor_is_visible = (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; @@ -8085,8 +8088,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Render text only const char* buf_end = NULL; if (is_multiline) - text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf, &buf_end) * g.FontSize); // We don't need width - draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, GetColorU32(ImGuiCol_Text), buf, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); + text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_end) * g.FontSize); // We don't need width + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); } if (is_multiline) @@ -8101,7 +8104,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Log as text if (g.LogEnabled && !is_password) - LogRenderedText(render_pos, buf, NULL); + LogRenderedText(render_pos, buf_display, NULL); if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); From 3c8e4907788f5186b56fe936bdd44ac2bcad2a70 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 25 Jun 2016 14:28:58 +0200 Subject: [PATCH 06/47] Comment on dealing with io.WantCaptureKeyboard (#703) --- imgui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 225714c0..ba9eb69a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -391,10 +391,12 @@ 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 can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? - A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame. + A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame, but either should be fine. When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available. ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is a more accurate and complete than testing for ImGui::IsMouseHoveringAnyWindow(). + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantcaptureKeyboard=false'. Depending + on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups. Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF file you want: From 355dae5d999f597bc0c90a28b0522f1316bd6d96 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 25 Jun 2016 14:37:14 +0200 Subject: [PATCH 07/47] Comments amend 3c8e4907788f5186b56fe936bdd44ac2bcad2a70 (committed before saving last comment edit) (#703) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ba9eb69a..de0e32df 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -395,8 +395,8 @@ When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available. ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is a more accurate and complete than testing for ImGui::IsMouseHoveringAnyWindow(). - (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantcaptureKeyboard=false'. Depending - on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups. + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantcaptureKeyboard=false'. + Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF file you want: From de61fcc619606788693092ba00279a787c0181e1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 25 Jun 2016 17:03:49 +0200 Subject: [PATCH 08/47] Minor bits --- imgui.cpp | 5 ++--- imgui.h | 2 +- imgui_demo.cpp | 12 ++++++------ imgui_internal.h | 4 ++-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index de0e32df..8e12e86b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4916,8 +4916,7 @@ void ImGui::SetWindowFocus(const char* name) { if (name) { - ImGuiWindow* window = FindWindowByName(name); - if (window) + if (ImGuiWindow* window = FindWindowByName(name)) FocusWindow(window); } else @@ -9470,7 +9469,7 @@ void ImGui::ValueColor(const char* prefix, const ImVec4& v) ColorButton(v, true); } -void ImGui::ValueColor(const char* prefix, unsigned int v) +void ImGui::ValueColor(const char* prefix, ImU32 v) { Text("%s: %08X", prefix, v); SameLine(); diff --git a/imgui.h b/imgui.h index e806f498..805aa996 100644 --- a/imgui.h +++ b/imgui.h @@ -352,7 +352,7 @@ namespace ImGui IMGUI_API void Value(const char* prefix, unsigned int v); IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); IMGUI_API void ValueColor(const char* prefix, const ImVec4& v); - IMGUI_API void ValueColor(const char* prefix, unsigned int v); + IMGUI_API void ValueColor(const char* prefix, ImU32 v); // Tooltips IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 752cd42b..67846e7a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1020,24 +1020,24 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Hello\nWorld"); ImGui::SameLine(); ImGui::Text("One\nTwo\nThree"); - ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Button("HOP##1"); ImGui::SameLine(); ImGui::Text("Banana"); ImGui::SameLine(); ImGui::Text("Hello\nWorld"); ImGui::SameLine(); ImGui::Text("Banana"); - ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Button("HOP##2"); ImGui::SameLine(); ImGui::Text("Hello\nWorld"); ImGui::SameLine(); ImGui::Text("Banana"); - ImGui::Button("TEST"); ImGui::SameLine(); + ImGui::Button("TEST##1"); ImGui::SameLine(); ImGui::Text("TEST"); ImGui::SameLine(); - ImGui::SmallButton("TEST"); + ImGui::SmallButton("TEST##2"); ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); - ImGui::Button("Widget"); ImGui::SameLine(); + ImGui::Button("Widget##1"); ImGui::SameLine(); ImGui::Text("Widget"); ImGui::SameLine(); - ImGui::SmallButton("Widget"); + ImGui::SmallButton("Widget##2"); // Tree const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; diff --git a/imgui_internal.h b/imgui_internal.h index e19f3e42..8cc895f2 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -481,7 +481,7 @@ struct ImGuiContext ScalarAsInputTextId = 0; DragCurrentValue = 0.0f; DragLastMouseDelta = ImVec2(0.0f, 0.0f); - DragSpeedDefaultRatio = 0.01f; + DragSpeedDefaultRatio = 1.0f / 100.0f; DragSpeedScaleSlow = 0.01f; DragSpeedScaleFast = 10.0f; ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); @@ -643,7 +643,7 @@ struct IMGUI_API ImGuiWindow ImGuiWindow* RootNonPopupWindow; // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself. ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent window. Else point to NULL. - // Focus + // Navigation / Focus int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) int FocusIdxAllRequestCurrent; // Item being requested for focus From e06852abaf2a59bb376890fe65e6429b040354a7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 26 Jun 2016 13:24:30 +0200 Subject: [PATCH 09/47] Fixed Windows default clipboard leaving its buffer unfreed on application's exit. (#714) --- imgui.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8e12e86b..f9bfdd2f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9501,12 +9501,8 @@ void ImGui::ValueColor(const char* prefix, ImU32 v) static const char* GetClipboardTextFn_DefaultImpl() { - static char* buf_local = NULL; - if (buf_local) - { - ImGui::MemFree(buf_local); - buf_local = NULL; - } + static ImVector buf_local; + buf_local.clear(); if (!OpenClipboard(NULL)) return NULL; HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); @@ -9515,19 +9511,18 @@ static const char* GetClipboardTextFn_DefaultImpl() if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) { int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; - buf_local = (char*)ImGui::MemAlloc(buf_len * sizeof(char)); - ImTextStrToUtf8(buf_local, buf_len, wbuf_global, NULL); + buf_local.resize(buf_len); + ImTextStrToUtf8(buf_local.Data, buf_len, wbuf_global, NULL); } GlobalUnlock(wbuf_handle); CloseClipboard(); - return buf_local; + return buf_local.Data; } static void SetClipboardTextFn_DefaultImpl(const char* text) { if (!OpenClipboard(NULL)) return; - const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); if (wbuf_handle == NULL) From c36fd541ad641f3bf6aaa2d311f327c3846ac296 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 27 Jun 2016 09:56:45 +0200 Subject: [PATCH 10/47] InputTextMultiline(): Fixed Ctrl+DownArrow moving scrolling out of bounds --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f9bfdd2f..19fb9bdf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7757,8 +7757,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->Scroll.y - g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_UP | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->Scroll.y + g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_DOWN| k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_UP | k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_DOWN| k_mask); } else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } @@ -9679,6 +9679,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) return; NodeDrawList(window->DrawList, "DrawList"); ImGui::BulletText("Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); + ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); From ba7acdac476b22fdb5c08326f9ed93d2ff37f78b Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 27 Jun 2016 12:59:49 +0200 Subject: [PATCH 11/47] Added assert to track stb_textedit.h issue (#715) --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 19fb9bdf..e411fe09 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7406,6 +7406,7 @@ static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) { const int text_len = obj->CurLenW; + IM_ASSERT(pos <= text_len); if (new_text_len + text_len + 1 > obj->Text.Size) return false; From 297bb3fc92e74942c04fa365b644d267b2bf7e62 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 29 Jun 2016 09:53:02 +0200 Subject: [PATCH 12/47] NextColumn() tidying up with a sane early out --- imgui.cpp | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e411fe09..904cef81 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9178,37 +9178,34 @@ void ImGui::NewLine() void ImGui::NextColumn() { ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) + if (window->SkipItems || window->DC.ColumnsCount <= 1) return; ImGuiContext& g = *GImGui; - if (window->DC.ColumnsCount > 1) - { - PopItemWidth(); - PopClipRect(); - - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) - { - // Columns 1+ cancel out IndentX - window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; - window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent); - } - else - { - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; - window->DrawList->ChannelsSetCurrent(0); - } - window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - window->DC.CursorPos.y = window->DC.ColumnsCellMinY; - window->DC.CurrentLineHeight = 0.0f; - window->DC.CurrentLineTextBaseOffset = 0.0f; + PopItemWidth(); + PopClipRect(); - PushColumnClipRect(); - PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) + { + // Columns 1+ cancel out IndentX + window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent); + } + else + { + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; + window->DrawList->ChannelsSetCurrent(0); } + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + window->DC.CursorPos.y = window->DC.ColumnsCellMinY; + window->DC.CurrentLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = 0.0f; + + PushColumnClipRect(); + PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup } int ImGui::GetColumnIndex() From 74bbfcfaa668fd0e35b41c04b18f7a15f5419833 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 29 Jun 2016 10:07:36 +0200 Subject: [PATCH 13/47] ImGuiListClipper: fixed automatic-height calc path dumbly having user display element 0 twice (#661, #716) First bug out of two. Was easily visible using e.g. 50% alpha text. --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 904cef81..a9f9dbaa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1680,8 +1680,9 @@ bool ImGuiListClipper::Step() if (ItemsCount == 1) { ItemsCount = -1; return false; } float items_height = ImGui::GetCursorPosY() - StartPosY; IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically - ImGui::SetCursorPosY(StartPosY); // Rewind cursor so we can Begin() again, this time with a known height. - Begin(ItemsCount, items_height); + Begin(ItemsCount-1, items_height); + DisplayStart++; + DisplayEnd++; StepNo = 3; return true; } From b9b3dec7da27b87cbb07a75542a0df07bf013491 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 29 Jun 2016 10:19:01 +0200 Subject: [PATCH 14/47] ImGuiListClipper: Fix to behave within column (#661, #662, #716) --- imgui.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a9f9dbaa..3486458b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1622,12 +1622,14 @@ float ImGuiSimpleColumns::CalcExtraSpace(float avail_w) static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) { - // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. - // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. + // Set cursor position and a few other things so that SetScrollHere() and Columns() can work when seeking cursor. + // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. Consider moving within SetCursorXXX functions? ImGui::SetCursorPosY(pos_y); ImGuiWindow* window = ImGui::GetCurrentWindow(); - window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; - window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); + window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. + window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. + if (window->DC.ColumnsCount > 1) + window->DC.ColumnsCellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly } // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 From fe7274b6c7ab0039f5ec588d76a4e237dab1be87 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 29 Jun 2016 10:25:47 +0200 Subject: [PATCH 15/47] SetCursorScreenPos() fixed not adjusting CursorMaxPos as well --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 3486458b..083dfd62 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5129,6 +5129,7 @@ void ImGui::SetCursorScreenPos(const ImVec2& screen_pos) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos = screen_pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); } float ImGui::GetScrollX() From 5525c2356ab9bfeb3840fa80741f50f6e7013365 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 29 Jun 2016 10:30:42 +0200 Subject: [PATCH 16/47] Using GetCurrentWindowRead() instead of GetCurrentWindow() --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 083dfd62..d8ec460e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5082,13 +5082,13 @@ ImVec2 ImGui::GetCursorPos() float ImGui::GetCursorPosX() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x; } float ImGui::GetCursorPosY() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y; } From 86f42b595028798464cee9b32329b36563e1f357 Mon Sep 17 00:00:00 2001 From: Michael Bartnett Date: Thu, 12 May 2016 00:48:38 -0400 Subject: [PATCH 17/47] osx uses super+arrows for home/end, built on work in ocornut/imgui#473 --- imgui.cpp | 11 +++++++---- imgui.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d8ec460e..51b19cb4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -833,6 +833,7 @@ ImGuiIO::ImGuiIO() #ifdef __APPLE__ WordMovementUsesAltKey = true; // OS X style: Text editing cursor movement using Alt instead of Ctrl ShortcutsUseSuperKey = true; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + HomeEndUsesArrowSuperKey = true; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End DoubleClickSelectsWord = true; // OS X style: Double click selects by word instead of selecting whole text MultiSelectUsesSuperKey = true; // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl #endif @@ -7759,11 +7760,13 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); const bool is_shortcutkey_only = (io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_shift_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_shift_down && !is_super_down)); const bool is_wordmove_key_down = (io.WordMovementUsesAltKey ? io.KeyAlt : io.KeyCtrl); + const bool is_line_startend_key_down = io.HomeEndUsesArrowSuperKey && is_super_down && !is_ctrl_down && !is_alt_down; + const bool is_text_startend_key_down = is_line_startend_key_down; - if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_UP | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_DOWN| k_mask); } + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_line_startend_key_down ? STB_TEXTEDIT_K_LINESTART | k_mask : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_line_startend_key_down ? STB_TEXTEDIT_K_LINEEND | k_mask : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_text_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_line_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } diff --git a/imgui.h b/imgui.h index 805aa996..da1682be 100644 --- a/imgui.h +++ b/imgui.h @@ -758,6 +758,7 @@ struct ImGuiIO // Advanced/subtle behaviors bool WordMovementUsesAltKey; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl bool ShortcutsUseSuperKey; // = defined(__APPLE__) // OS X style: Shortcuts using Cmd/Super instead of Ctrl + bool HomeEndUsesArrowSuperKey; // = defined(__APPLE__) // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End bool DoubleClickSelectsWord; // = defined(__APPLE__) // OS X style: Double click selects by word instead of selecting whole text bool MultiSelectUsesSuperKey; // = defined(__APPLE__) // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl [unused yet] From 921fc50c85edccd9df29574566277663109ea17e Mon Sep 17 00:00:00 2001 From: Michael Bartnett Date: Thu, 7 Jul 2016 13:03:00 -0400 Subject: [PATCH 18/47] add shortcut+backspace support --- imgui.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 51b19cb4..e31658ad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7759,6 +7759,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 bool cancel_edit = false; const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); const bool is_shortcutkey_only = (io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_shift_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_shift_down && !is_super_down)); + const bool is_shortcutkey_and_maybe_shift_only = (io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_super_down)); const bool is_wordmove_key_down = (io.WordMovementUsesAltKey ? io.KeyAlt : io.KeyCtrl); const bool is_line_startend_key_down = io.HomeEndUsesArrowSuperKey && is_super_down && !is_ctrl_down && !is_alt_down; const bool is_text_startend_key_down = is_line_startend_key_down; @@ -7770,7 +7771,15 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) { if (is_ctrl_down && !edit_state.HasSelection()) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) + { + if (!edit_state.HasSelection()) + { + if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); + else if (io.ShortcutsUseSuperKey && is_shortcutkey_and_maybe_shift_only) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + } + edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); + } else if (IsKeyPressedMap(ImGuiKey_Enter)) { bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; From 9c71ec38f0f79278aefcf785f436a09c97bc3689 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 Jul 2016 11:19:38 +0200 Subject: [PATCH 19/47] ImVector: reserve() tweak to avoid undefined behavior warning (#731) --- imgui.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 805aa996..dffb5060 100644 --- a/imgui.h +++ b/imgui.h @@ -885,7 +885,8 @@ public: { if (new_capacity <= Capacity) return; T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(value_type)); - memcpy(new_data, Data, (size_t)Size * sizeof(value_type)); + if (Data) + memcpy(new_data, Data, (size_t)Size * sizeof(value_type)); ImGui::MemFree(Data); Data = new_data; Capacity = new_capacity; From d9e2e688e9d0b78f3acbd5ec5ee2eeb7b0671f53 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 13 Jul 2016 01:18:59 +0200 Subject: [PATCH 20/47] InputTextMultiline(): partial fix for when input and internal buffers differs in a way where scrollbar existence differs. (#725) Partial fix, won't stop ids from functioning because of a zombie id. --- imgui.cpp | 10 ++++++++-- imgui_internal.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d8ec460e..6be18795 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1776,6 +1776,12 @@ ImGuiID ImGuiWindow::GetID(const void* ptr) return id; } +ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + return ImHash(str, str_end ? (int)(str_end - str) : 0, seed); +} + //----------------------------------------------------------------------------- // Internal API exposed in imgui_internal.h //----------------------------------------------------------------------------- @@ -7633,7 +7639,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 g.MouseCursor = ImGuiMouseCursor_TextInput; } const bool user_clicked = hovered && io.MouseClicked[0]; - const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetID("#SCROLLY"); + const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0; if (focus_requested || user_clicked || user_scrolled) @@ -7954,7 +7960,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 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 ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; ImVec2 text_size(0.f, 0.f); - if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetID("#SCROLLY"))) + if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY"))) { edit_state.CursorAnim += g.IO.DeltaTime; diff --git a/imgui_internal.h b/imgui_internal.h index 8cc895f2..4dfa6479 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -657,6 +657,7 @@ public: ImGuiID GetID(const char* str, const char* str_end = NULL); ImGuiID GetID(const void* ptr); + ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } From 88721118fdb529a30211ef4e5b789745f367ae68 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 13 Jul 2016 01:54:29 +0200 Subject: [PATCH 21/47] InputTextEx: comments (related to #725) --- imgui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 6be18795..9e11d860 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7960,7 +7960,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 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 ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; ImVec2 text_size(0.f, 0.f); - if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY"))) + const bool is_currently_scrolling = (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY")); + if (g.ActiveId == id || is_currently_scrolling) { edit_state.CursorAnim += g.IO.DeltaTime; @@ -7969,6 +7970,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation) // - Measure text height (for scrollbar) // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) + // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. const ImWchar* text_begin = edit_state.Text.Data; ImVec2 cursor_offset, select_start_offset; From c0f77f12ea67dd74f1c90ad4d8633a02cdc589fd Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 14 Jul 2016 13:08:37 +0200 Subject: [PATCH 22/47] InputText(): Fixed state corruption/crash bug in stb_textedit redo logic when exhausting undo char buffer (#715 #681) --- stb_textedit.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stb_textedit.h b/stb_textedit.h index 23f0f24e..2dddefe4 100644 --- a/stb_textedit.h +++ b/stb_textedit.h @@ -1,4 +1,5 @@ // [ImGui] this is a slightly modified version of stb_truetype.h 1.8 +// [ImGui] - fixed a state corruption/crash bug in stb_text_redo and stb_textedit_discard_redo (#715) // [ImGui] - fixed a crash bug in stb_textedit_discard_redo (#681) // [ImGui] - fixed some minor warnings // [ImGui] - added STB_TEXTEDIT_MOVEWORDLEFT/STB_TEXTEDIT_MOVEWORDRIGHT custom handler (#473) @@ -1101,8 +1102,8 @@ static void stb_textedit_discard_redo(StbUndoState *state) if (state->undo_rec[i].char_storage >= 0) state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05 } + STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point, state->undo_rec + state->redo_point-1, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); ++state->redo_point; - STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); } } @@ -1260,6 +1261,7 @@ static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) if (r.insert_length) { // easy case: need to insert n characters STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); + s->redo_char_point += r.insert_length; } state->cursor = r.where + r.insert_length; From 81036ee46f3009f2bd09060e6503350a66137804 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 14 Jul 2016 13:27:14 +0200 Subject: [PATCH 23/47] InputTextMultiline(): fix so that IsItemActive() can be used afterwards (otherwise the info was lost by using child/group) --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 9e11d860..ec311154 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8111,6 +8111,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line EndChildFrame(); EndGroup(); + if (g.ActiveId == id || is_currently_scrolling) // Set LastItemId which was lost by EndChild/EndGroup, so user can use IsItemActive() + window->DC.LastItemId = g.ActiveId; } if (is_password) From 04b36bc3978e7760201087db8720ffdc9e99f267 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 14 Jul 2016 13:38:44 +0200 Subject: [PATCH 24/47] TODO list --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index ec311154..8a1aadf3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -490,9 +490,11 @@ - input text: flag to disable live update of the user buffer (also applies to float/int text input) - input text: resize behavior - field could stretch when being edited? hover tooltip shows more text? - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) + - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200) + - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. - input number: optional range min/max for Input*() functions - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) From 44a13a7f25763d4d6419307e47ddfdb4e52b3dc0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 16 Jul 2016 11:29:41 +0200 Subject: [PATCH 25/47] Windows: No default IME handler when compiling using GCC. (#738) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8a1aadf3..d74e3fed 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9575,7 +9575,7 @@ static void SetClipboardTextFn_DefaultImpl(const char* text) #endif // Win32 API IME support (for Asian languages, etc.) -#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) +#if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) #include #ifdef _MSC_VER From 4961b2ea18e9446e8a0bd0edb4b3a6942ff8dc89 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 16 Jul 2016 11:44:10 +0200 Subject: [PATCH 26/47] Speculative build fix for FreeBSD+GLIBC configuration See https://github.com/mamedev/mame/commit/a1f9b62dd0a491d6b26291837d43181c0e9e66fa --- imgui_draw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index ba20abc8..1cbd39d8 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -18,9 +18,11 @@ #include "imgui_internal.h" #include // vsnprintf, sscanf, printf -#if !defined(alloca) && !defined(__FreeBSD__) && !defined(__DragonFly__) +#if !defined(alloca) #ifdef _WIN32 #include // alloca +#elif (defined(__FreeBSD__) || defined(FreeBSD_kernel) || defined(__DragonFly__)) && !defined(__GLIBC__) +#include // alloca. FreeBSD uses stdlib.h unless GLIBC #else #include // alloca #endif From e2159057658329eb71bf32e3366d1bf4ca1d3545 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 16 Jul 2016 18:12:41 +0200 Subject: [PATCH 27/47] Fixed scrolling offset when using SetScrollY(), SetScrollFromPosY(), SetScrollHere() with menu bar. Tests: a) add SetScrollY(+20) after Begin("ImGui Demo") test with/without title/menu. b) add ImGuiWindowFlags_MenuBar in BeginChild() in scrolling tracking demo. --- imgui.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d74e3fed..296da315 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -131,11 +131,8 @@ ImGui::NewFrame(); // 3) most of your application code here - ImGui::Begin("My window"); - ImGui::Text("Hello, world."); - ImGui::End(); - MyGameUpdate(); // may use ImGui functions - MyGameRender(); // may use ImGui functions + MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); + MyGameRender(); // may use any ImGui functions // 4) render & swap video buffers ImGui::Render(); @@ -4101,7 +4098,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->ScrollTarget.y < FLT_MAX) { float center_ratio = window->ScrollTargetCenterRatio.y; - window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * window->TitleBarHeight()) - (center_ratio * window->SizeFull.y); + window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * window->SizeFull.y); window->ScrollTarget.y = FLT_MAX; } window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f)); @@ -5172,7 +5169,7 @@ void ImGui::SetScrollX(float scroll_x) void ImGui::SetScrollY(float scroll_y) { ImGuiWindow* window = GetCurrentWindow(); - window->ScrollTarget.y = scroll_y + window->TitleBarHeight(); // title bar height canceled out when using ScrollTargetRelY + window->ScrollTarget.y = scroll_y + window->TitleBarHeight() + window->MenuBarHeight(); // title bar height canceled out when using ScrollTargetRelY window->ScrollTargetCenterRatio.y = 0.0f; } From 19d02becef94e8e0f1d432a8bd55cd783876583c Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 17 Jul 2016 19:17:49 +0200 Subject: [PATCH 28/47] Closing the focused window restore focus to the first active root window in descending z-order (part of #727) --- imgui.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 296da315..14a9fbf0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2250,14 +2250,11 @@ void ImGui::NewFrame() window->SizeFull *= scale; } } - else + else if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) { // Scroll - if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) - { - const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; - SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * window->CalcFontSize() * scroll_lines); - } + const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; + SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * window->CalcFontSize() * scroll_lines); } } @@ -2275,6 +2272,15 @@ void ImGui::NewFrame() window->Accessed = false; } + // Closing the focused window restore focus to the first active root window in descending z-order + if (g.FocusedWindow && !g.FocusedWindow->WasActive) + for (int i = g.Windows.Size-1; i >= 0; i--) + if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) + { + FocusWindow(g.Windows[i]); + break; + } + // No window should be open at the beginning of the frame. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. g.CurrentWindowStack.resize(0); From ffdd7d7f17ee1a2e3ab8fa919e535f54a671bce5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 Jul 2016 15:25:44 +0200 Subject: [PATCH 29/47] Begin: Moved code that calls FocusWindow() on a newly appearing window lower in the function so that Nav branch can use CursorStartPos on the first window frame. (#323) Pushing in master because it _should_ be a no-op but I'd rather test for any issue in Begin() as soon as possible. --- imgui.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 14a9fbf0..19b44536 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3918,16 +3918,10 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); - // New windows appears in front if (!window_was_active) { - window->AutoPosLastDirection = -1; - - if (!(flags & ImGuiWindowFlags_NoFocusOnAppearing)) - if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) - FocusWindow(window); - // Popup first latch mouse position, will position itself when it appears next frame + window->AutoPosLastDirection = -1; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) window->PosFloat = g.IO.MousePos; } @@ -4265,6 +4259,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->AutoFitFramesY > 0) window->AutoFitFramesY--; + // New windows appears in front (we need to do that AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) + if (!window_was_active && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) + FocusWindow(window); + // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) { From 4141144b217ce89e819a1c9a4aac165789342188 Mon Sep 17 00:00:00 2001 From: Adisorn Aeksatean Date: Tue, 19 Jul 2016 22:56:59 +0700 Subject: [PATCH 30/47] Added GetGlyphRangesThai() --- imgui.h | 1 + imgui_draw.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/imgui.h b/imgui.h index dffb5060..27518016 100644 --- a/imgui.h +++ b/imgui.h @@ -1322,6 +1322,7 @@ struct ImFontAtlas IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Japanese + full set of about 21000 CJK Unified Ideographs IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters + IMGUI_API const ImWchar* GetGlyphRangesThai(); //Default + Thai charactors // Members // (Access texture data via GetTexData*() calls which will setup a default font for you.) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1cbd39d8..c5770da8 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1652,6 +1652,17 @@ const ImWchar* ImFontAtlas::GetGlyphRangesCyrillic() return &ranges[0]; } +const ImWchar* ImFontAtlas::GetGlyphRangesThai() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, //Basic Latin + 0x0E00, 0x0E7F, //Thai Unicode + 0, + }; + return &ranges[0]; +} + //----------------------------------------------------------------------------- // ImFont //----------------------------------------------------------------------------- From 8efd05a1489a92f2c4d33ef7a0e2a3f3702c191f Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 20 Jul 2016 11:39:38 +0200 Subject: [PATCH 31/47] Tab->Spaces, missing spaces, typos --- imgui.h | 2 +- imgui_draw.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/imgui.h b/imgui.h index 27518016..fbd8c9fe 100644 --- a/imgui.h +++ b/imgui.h @@ -1322,7 +1322,7 @@ struct ImFontAtlas IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Japanese + full set of about 21000 CJK Unified Ideographs IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters - IMGUI_API const ImWchar* GetGlyphRangesThai(); //Default + Thai charactors + IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters // Members // (Access texture data via GetTexData*() calls which will setup a default font for you.) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c5770da8..45549298 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1654,13 +1654,13 @@ const ImWchar* ImFontAtlas::GetGlyphRangesCyrillic() const ImWchar* ImFontAtlas::GetGlyphRangesThai() { - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, //Basic Latin - 0x0E00, 0x0E7F, //Thai Unicode - 0, - }; - return &ranges[0]; + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + 0x0E00, 0x0E7F, // Thai + 0, + }; + return &ranges[0]; } //----------------------------------------------------------------------------- From d8dacd729bfae825a8a820e02d6e82d39fa5005c Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 29 Jul 2016 10:10:41 +0200 Subject: [PATCH 32/47] Examples: SDL+OpenGL: explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it (#752) --- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 1 + examples/sdl_opengl_example/imgui_impl_sdl.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index d97b4cc0..e0193862 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -186,6 +186,7 @@ void ImGui_ImplSdlGL3_CreateFontsTexture() glBindTexture(GL_TEXTURE_2D, g_FontTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Store our identifier diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp index ae42f143..434a7c22 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp @@ -165,6 +165,7 @@ bool ImGui_ImplSdl_CreateDeviceObjects() glBindTexture(GL_TEXTURE_2D, g_FontTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); // Store our identifier From e5b6ddde2683621c6f063d9814fd8f0780f1a6c8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 29 Jul 2016 10:42:08 +0200 Subject: [PATCH 33/47] InputText(): minor tidying up/simplification following changes for osx style improvements (#650) --- imgui.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5aea9601..ececb106 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7768,16 +7768,14 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Handle various key-presses bool cancel_edit = false; const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_shortcutkey_only = (io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_shift_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_shift_down && !is_super_down)); - const bool is_shortcutkey_and_maybe_shift_only = (io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_super_down)); - const bool is_wordmove_key_down = (io.WordMovementUsesAltKey ? io.KeyAlt : io.KeyCtrl); - const bool is_line_startend_key_down = io.HomeEndUsesArrowSuperKey && is_super_down && !is_ctrl_down && !is_alt_down; - const bool is_text_startend_key_down = is_line_startend_key_down; - - if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_line_startend_key_down ? STB_TEXTEDIT_K_LINESTART | k_mask : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_line_startend_key_down ? STB_TEXTEDIT_K_LINEEND | k_mask : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_text_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_line_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } + const bool is_shortcutkey_only = io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_shift_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_shift_down && !is_super_down); + const bool is_wordmove_key_down = io.WordMovementUsesAltKey ? io.KeyAlt : io.KeyCtrl; + const bool is_startend_key_down = io.HomeEndUsesArrowSuperKey && is_super_down && !is_ctrl_down && !is_alt_down; + + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } @@ -7786,7 +7784,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (!edit_state.HasSelection()) { if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); - else if (io.ShortcutsUseSuperKey && is_shortcutkey_and_maybe_shift_only) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + else if (io.ShortcutsUseSuperKey && is_super_down && !is_alt_down && !is_ctrl_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); } edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } From 0ff22dbf0bea35975f52f0578265c5b7eb7a9e41 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 29 Jul 2016 10:51:35 +0200 Subject: [PATCH 34/47] InputTextEx(): minor tidying up --- imgui.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ececb106..3d5f690b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7717,8 +7717,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 g.ActiveIdAllowOverlap = !io.MouseDown[0]; // Edit in progress - const float mouse_x = (g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; - const float mouse_y = (is_multiline ? (g.IO.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); + const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; + const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); if (select_all || (hovered && !io.DoubleClickSelectsWord && io.MouseDoubleClicked[0])) { @@ -7745,14 +7745,14 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (edit_state.SelectedAllMouseLock && !io.MouseDown[0]) edit_state.SelectedAllMouseLock = false; - if (g.IO.InputCharacters[0]) + if (io.InputCharacters[0]) { // Process text input (before we check for Return because using some IME will effectively send a Return?) // We ignore CTRL inputs, but need to allow CTRL+ALT as some keyboards (e.g. German) use AltGR - which is Alt+Ctrl - to input certain characters. if (!(is_ctrl_down && !is_alt_down) && is_editable) { - for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++) - if (unsigned int c = (unsigned int)g.IO.InputCharacters[n]) + for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++) + if (unsigned int c = (unsigned int)io.InputCharacters[n]) { // Insert character if they pass filtering if (!InputTextFilterCharacter(&c, flags, callback, user_data)) @@ -7820,13 +7820,13 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (cut && !edit_state.HasSelection()) edit_state.SelectAll(); - if (g.IO.SetClipboardTextFn) + if (io.SetClipboardTextFn) { const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW; edit_state.TempTextBuffer.resize((ie-ib) * 4 + 1); ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie); - g.IO.SetClipboardTextFn(edit_state.TempTextBuffer.Data); + io.SetClipboardTextFn(edit_state.TempTextBuffer.Data); } if (cut) @@ -7838,9 +7838,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) { // Paste - if (g.IO.GetClipboardTextFn) + if (io.GetClipboardTextFn) { - if (const char* clipboard = g.IO.GetClipboardTextFn()) + if (const char* clipboard = io.GetClipboardTextFn()) { // Remove new-line from pasted buffer const int clipboard_len = (int)strlen(clipboard); @@ -7977,7 +7977,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool is_currently_scrolling = (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY")); if (g.ActiveId == id || is_currently_scrolling) { - edit_state.CursorAnim += g.IO.DeltaTime; + edit_state.CursorAnim += io.DeltaTime; // This is going to be messy. We need to: // - Display the text (this alone can be more easily clipped) From 666d83b5c78b7b4166298a7a6426cc0367f1d5fb Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 29 Jul 2016 10:56:47 +0200 Subject: [PATCH 35/47] InputText/IO: Got rid of individual OSX options in ImGuiIO, added io.OSXBehaviors (#473, #650) --- imgui.cpp | 19 ++++++++----------- imgui.h | 6 +----- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3d5f690b..7f54786c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -830,11 +830,7 @@ ImGuiIO::ImGuiIO() // Set OS X style defaults based on __APPLE__ compile time flag #ifdef __APPLE__ - WordMovementUsesAltKey = true; // OS X style: Text editing cursor movement using Alt instead of Ctrl - ShortcutsUseSuperKey = true; // OS X style: Shortcuts using Cmd/Super instead of Ctrl - HomeEndUsesArrowSuperKey = true; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End - DoubleClickSelectsWord = true; // OS X style: Double click selects by word instead of selecting whole text - MultiSelectUsesSuperKey = true; // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl + OSXBehaviors = true; #endif } @@ -7720,12 +7716,13 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); - if (select_all || (hovered && !io.DoubleClickSelectsWord && io.MouseDoubleClicked[0])) + const bool osx_double_click_selects_words = io.OSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text + if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0])) { edit_state.SelectAll(); edit_state.SelectedAllMouseLock = true; } - else if (hovered && io.DoubleClickSelectsWord && io.MouseDoubleClicked[0]) + else if (hovered && osx_double_click_selects_words && io.MouseDoubleClicked[0]) { // Select a word only, OS X style (by simulating keystrokes) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); @@ -7768,9 +7765,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Handle various key-presses bool cancel_edit = false; const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_shortcutkey_only = io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_shift_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_shift_down && !is_super_down); - const bool is_wordmove_key_down = io.WordMovementUsesAltKey ? io.KeyAlt : io.KeyCtrl; - const bool is_startend_key_down = io.HomeEndUsesArrowSuperKey && is_super_down && !is_ctrl_down && !is_alt_down; + const bool is_shortcutkey_only = (io.OSXBehaviors ? (is_super_down && !is_ctrl_down) : (is_ctrl_down && !is_super_down)) && !is_alt_down && !is_shift_down; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + const bool is_wordmove_key_down = io.OSXBehaviors ? is_alt_down : is_ctrl_down; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = io.OSXBehaviors && is_super_down && !is_ctrl_down && !is_alt_down; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } @@ -7784,7 +7781,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (!edit_state.HasSelection()) { if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); - else if (io.ShortcutsUseSuperKey && is_super_down && !is_alt_down && !is_ctrl_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + else if (io.OSXBehaviors && is_super_down && !is_alt_down && !is_ctrl_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); } edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } diff --git a/imgui.h b/imgui.h index 66155067..db5fd843 100644 --- a/imgui.h +++ b/imgui.h @@ -756,11 +756,7 @@ struct ImGuiIO ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize // Advanced/subtle behaviors - bool WordMovementUsesAltKey; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl - bool ShortcutsUseSuperKey; // = defined(__APPLE__) // OS X style: Shortcuts using Cmd/Super instead of Ctrl - bool HomeEndUsesArrowSuperKey; // = defined(__APPLE__) // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End - bool DoubleClickSelectsWord; // = defined(__APPLE__) // OS X style: Double click selects by word instead of selecting whole text - bool MultiSelectUsesSuperKey; // = defined(__APPLE__) // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl [unused yet] + bool OSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl //------------------------------------------------------------------ // User Functions From 776ea6b946d7c19f42e0de22a1052c178baaaa73 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 29 Jul 2016 11:01:06 +0200 Subject: [PATCH 36/47] InputTextEx(): more shallow tidying up, still being cautious with this function --- imgui.cpp | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7f54786c..d278a708 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7771,8 +7771,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } @@ -7835,32 +7835,29 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) { // Paste - if (io.GetClipboardTextFn) + if (const char* clipboard = io.GetClipboardTextFn ? io.GetClipboardTextFn() : NULL) { - if (const char* clipboard = io.GetClipboardTextFn()) + // Remove new-line from pasted buffer + const int clipboard_len = (int)strlen(clipboard); + ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); + int clipboard_filtered_len = 0; + for (const char* s = clipboard; *s; ) { - // Remove new-line from pasted buffer - const int clipboard_len = (int)strlen(clipboard); - ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); - int clipboard_filtered_len = 0; - for (const char* s = clipboard; *s; ) - { - unsigned int c; - s += ImTextCharFromUtf8(&c, s, NULL); - if (c == 0) - break; - if (c >= 0x10000 || !InputTextFilterCharacter(&c, flags, callback, user_data)) - continue; - clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; - } - clipboard_filtered[clipboard_filtered_len] = 0; - if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation - { - stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); - edit_state.CursorFollow = true; - } - ImGui::MemFree(clipboard_filtered); + unsigned int c; + s += ImTextCharFromUtf8(&c, s, NULL); + if (c == 0) + break; + if (c >= 0x10000 || !InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; + } + clipboard_filtered[clipboard_filtered_len] = 0; + if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation + { + stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); + edit_state.CursorFollow = true; } + ImGui::MemFree(clipboard_filtered); } } From 7086a1785423bf6f5abae6a63b792d21daffdeeb Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 29 Jul 2016 11:06:16 +0200 Subject: [PATCH 37/47] InputTextEx: got rid of unnecessary locals. --- imgui.cpp | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d278a708..1590f377 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7625,10 +7625,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // NB: we are only allowed to access 'edit_state' if we are the active widget. ImGuiTextEditState& edit_state = g.InputTextState; - const bool is_ctrl_down = io.KeyCtrl; - const bool is_shift_down = io.KeyShift; - const bool is_alt_down = io.KeyAlt; - const bool is_super_down = io.KeySuper; const bool focus_requested = FocusableItemRegister(window, g.ActiveId == id, (flags & (ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; @@ -7678,7 +7674,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } if (flags & ImGuiInputTextFlags_AlwaysInsertMode) edit_state.StbState.insert_mode = true; - if (!is_multiline && (focus_requested_by_tab || (user_clicked && is_ctrl_down))) + if (!is_multiline && (focus_requested_by_tab || (user_clicked && io.KeyCtrl))) select_all = true; } SetActiveID(id, window); @@ -7746,7 +7742,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 { // Process text input (before we check for Return because using some IME will effectively send a Return?) // We ignore CTRL inputs, but need to allow CTRL+ALT as some keyboards (e.g. German) use AltGR - which is Alt+Ctrl - to input certain characters. - if (!(is_ctrl_down && !is_alt_down) && is_editable) + if (!(io.KeyCtrl && !io.KeyAlt) && is_editable) { for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++) if (unsigned int c = (unsigned int)io.InputCharacters[n]) @@ -7764,31 +7760,31 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Handle various key-presses bool cancel_edit = false; - const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_shortcutkey_only = (io.OSXBehaviors ? (is_super_down && !is_ctrl_down) : (is_ctrl_down && !is_super_down)) && !is_alt_down && !is_shift_down; // OS X style: Shortcuts using Cmd/Super instead of Ctrl - const bool is_wordmove_key_down = io.OSXBehaviors ? is_alt_down : is_ctrl_down; // OS X style: Text editing cursor movement using Alt instead of Ctrl - const bool is_startend_key_down = io.OSXBehaviors && is_super_down && !is_ctrl_down && !is_alt_down; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); + const bool is_shortcut_key_only = (io.OSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + const bool is_wordmove_key_down = io.OSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = io.OSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (is_ctrl_down) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) { if (!edit_state.HasSelection()) { if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); - else if (io.OSXBehaviors && is_super_down && !is_alt_down && !is_ctrl_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + else if (io.OSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); } edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Enter)) { bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; - if (!is_multiline || (ctrl_enter_for_new_line && !is_ctrl_down) || (!ctrl_enter_for_new_line && is_ctrl_down)) + if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) { SetActiveID(0); enter_pressed = true; @@ -7800,17 +7796,17 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 edit_state.OnKeyPressed((int)c); } } - else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !is_ctrl_down && !is_shift_down && !is_alt_down && is_editable) + else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !io.KeyCtrl && !io.KeyShift && !io.KeyAlt && is_editable) { unsigned int c = '\t'; // Insert TAB if (InputTextFilterCharacter(&c, flags, callback, user_data)) edit_state.OnKeyPressed((int)c); } else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveID(0); cancel_edit = true; } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } - else if (is_shortcutkey_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } + else if (is_shortcut_key_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) { // Cut, Copy const bool cut = IsKeyPressedMap(ImGuiKey_X); @@ -7832,12 +7828,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 stb_textedit_cut(&edit_state, &edit_state.StbState); } } - else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) { // Paste if (const char* clipboard = io.GetClipboardTextFn ? io.GetClipboardTextFn() : NULL) { - // Remove new-line from pasted buffer + // Filter pasted buffer const int clipboard_len = (int)strlen(clipboard); ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); int clipboard_filtered_len = 0; From cabba0f15882317a5bf891b92e596b32761a13ca Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Jul 2016 18:52:38 +0200 Subject: [PATCH 38/47] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8a9eab15..ea0d4639 100644 --- a/README.md +++ b/README.md @@ -168,13 +168,14 @@ Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Bin Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui). Double-chocolate sponsors: -- Media Molecule, Mobigame +- Media Molecule +- Mobigame Salty caramel supporters: -- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano, Chris Genova, ikrima +- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko. Caramel supporters: -- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley. +- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society. And other supporters; thanks! From 954c890c6782fda494a3ac36f3c5a591db584cf4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 30 Jul 2016 23:41:44 +0200 Subject: [PATCH 39/47] SameLine() with explicit X position is relative to left of group/columns (ref #746, #125, #630) --- imgui.cpp | 12 ++++++++---- imgui_internal.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1590f377..5a55b41a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -150,6 +150,7 @@ 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. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal. - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore. If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you. However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. @@ -4221,6 +4222,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Setup drawing context window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x; + window->DC.GroupOffsetX = 0.0f; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.IndentX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y); window->DC.CursorPos = window->DC.CursorStartPos; @@ -9116,7 +9118,8 @@ void ImGui::BeginGroup() group_data.BackupLogLinePosY = window->DC.LogLinePosY; group_data.AdvanceCursor = true; - window->DC.IndentX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX; + window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX; + window->DC.IndentX = window->DC.GroupOffsetX; window->DC.CursorMaxPos = window->DC.CursorPos; window->DC.CurrentLineHeight = 0.0f; window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; @@ -9140,6 +9143,7 @@ void ImGui::EndGroup() window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; window->DC.IndentX = group_data.BackupIndentX; + window->DC.GroupOffsetX = window->DC.IndentX; window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; if (group_data.AdvanceCursor) @@ -9156,7 +9160,7 @@ void ImGui::EndGroup() // Gets back to previous line and continue with horizontal layout // pos_x == 0 : follow right after previous item -// pos_x != 0 : align to specified x position +// pos_x != 0 : align to specified x position (relative to window/group left) // spacing_w < 0 : use default spacing if pos_x == 0, no spacing if pos_x != 0 // spacing_w >= 0 : enforce spacing amount void ImGui::SameLine(float pos_x, float spacing_w) @@ -9169,7 +9173,7 @@ void ImGui::SameLine(float pos_x, float spacing_w) if (pos_x != 0.0f) { if (spacing_w < 0.0f) spacing_w = 0.0f; - window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w; + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w + window->DC.GroupOffsetX + window->DC.ColumnsOffsetX; window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; } else @@ -9352,7 +9356,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) if (held) { if (g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= 4; // Store from center of column line + g.ActiveIdClickOffset.x -= 4; // Store from center of column line (we used a 8 wide rect for columns clicking) x = GetDraggedColumnOffset(i); SetColumnOffset(i, x); } diff --git a/imgui_internal.h b/imgui_internal.h index 4dfa6479..7b59bb63 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -546,6 +546,7 @@ struct IMGUI_API ImGuiDrawContext int StackSizesBackup[6]; // Store size of various stacks for asserting float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) + float GroupOffsetX; float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. int ColumnsCurrent; int ColumnsCount; From 0a1d456de1dececa7c18f213cea11e94fbe17c6f Mon Sep 17 00:00:00 2001 From: Jamie Seward Date: Sat, 30 Jul 2016 15:26:49 -0700 Subject: [PATCH 40/47] Fix compile warnings in SDL examples --- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 1 - examples/sdl_opengl_example/imgui_impl_sdl.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index e0193862..7011875a 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -152,7 +152,6 @@ bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) } case SDL_TEXTINPUT: { - ImGuiIO& io = ImGui::GetIO(); io.AddInputCharactersUTF8(event->text.text); return true; } diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp index 434a7c22..63ed9f44 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp @@ -131,7 +131,6 @@ bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) } case SDL_TEXTINPUT: { - ImGuiIO& io = ImGui::GetIO(); io.AddInputCharactersUTF8(event->text.text); return true; } From 907265d6320ffdfb438fff94aa88133d33ac3775 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 31 Jul 2016 16:48:06 +0200 Subject: [PATCH 41/47] Using ImGuiID instead of ImU32 is a few places --- imgui.cpp | 17 ++++++++--------- imgui.h | 6 +++--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5a55b41a..de569db5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -999,7 +999,6 @@ ImU32 ImHash(const void* data, int data_size, ImU32 seed) // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller. if (c == '#' && current[0] == '#' && current[1] == '#') crc = seed; - crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; } } @@ -1302,7 +1301,7 @@ void ImGuiStorage::Clear() } // std::lower_bound but without the bullshit -static ImVector::iterator LowerBound(ImVector& data, ImU32 key) +static ImVector::iterator LowerBound(ImVector& data, ImGuiID key) { ImVector::iterator first = data.begin(); ImVector::iterator last = data.end(); @@ -1324,7 +1323,7 @@ static ImVector::iterator LowerBound(ImVector::iterator it = LowerBound(const_cast&>(Data), key); if (it == Data.end() || it->key != key) @@ -1332,12 +1331,12 @@ int ImGuiStorage::GetInt(ImU32 key, int default_val) const return it->val_i; } -bool ImGuiStorage::GetBool(ImU32 key, bool default_val) const +bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const { return GetInt(key, default_val ? 1 : 0) != 0; } -float ImGuiStorage::GetFloat(ImU32 key, float default_val) const +float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const { ImVector::iterator it = LowerBound(const_cast&>(Data), key); if (it == Data.end() || it->key != key) @@ -1384,7 +1383,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) } // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) -void ImGuiStorage::SetInt(ImU32 key, int val) +void ImGuiStorage::SetInt(ImGuiID key, int val) { ImVector::iterator it = LowerBound(Data, key); if (it == Data.end() || it->key != key) @@ -1395,12 +1394,12 @@ void ImGuiStorage::SetInt(ImU32 key, int val) it->val_i = val; } -void ImGuiStorage::SetBool(ImU32 key, bool val) +void ImGuiStorage::SetBool(ImGuiID key, bool val) { SetInt(key, val ? 1 : 0); } -void ImGuiStorage::SetFloat(ImU32 key, float val) +void ImGuiStorage::SetFloat(ImGuiID key, float val) { ImVector::iterator it = LowerBound(Data, key); if (it == Data.end() || it->key != key) @@ -1411,7 +1410,7 @@ void ImGuiStorage::SetFloat(ImU32 key, float val) it->val_f = val; } -void ImGuiStorage::SetVoidPtr(ImU32 key, void* val) +void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) { ImVector::iterator it = LowerBound(Data, key); if (it == Data.end() || it->key != key) diff --git a/imgui.h b/imgui.h index db5fd843..67f46c61 100644 --- a/imgui.h +++ b/imgui.h @@ -62,11 +62,11 @@ struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window si struct ImGuiListClipper; // Helper to manually clip large list of items struct ImGuiContext; // ImGui context (opaque) -// Enumerations (declared as int for compatibility and to not pollute the top of this file) -typedef unsigned int ImU32; +// Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file) +typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) +typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef unsigned short ImWchar; // character for keyboard input/display typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) -typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef int ImGuiCol; // a color identifier for styling // enum ImGuiCol_ typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImGuiKey; // a key identifier (ImGui-side enum) // enum ImGuiKey_ From 7588dfb67e7dd8970b64bffc87c2659fe7684ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Cicho=C5=84?= Date: Fri, 5 Aug 2016 11:47:16 +0200 Subject: [PATCH 42/47] Add ability to test arbitrary rectangle for visibility without need of moving cursor. --- imgui.cpp | 6 ++++++ imgui.h | 1 + 2 files changed, 7 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index de569db5..7332d27c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9102,6 +9102,12 @@ bool ImGui::IsRectVisible(const ImVec2& size) return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); } +bool ImGui::IsRectVisible(const ImVec2& a, const ImVec2& b) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ClipRect.Overlaps(ImRect(a, b)); +} + // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) void ImGui::BeginGroup() { diff --git a/imgui.h b/imgui.h index 67f46c61..40be5091 100644 --- a/imgui.h +++ b/imgui.h @@ -410,6 +410,7 @@ namespace ImGui IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization) + IMGUI_API bool IsRectVisible(const ImVec2& a, const ImVec2& b); // " IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); From a7f6ea592fe38e7ea7896d48afbc37587bfa2360 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 6 Aug 2016 09:22:41 +0200 Subject: [PATCH 43/47] Moved GetColorU32 out of imgui_internal.h to avoid inlining mess (#759) --- imgui.cpp | 14 ++++++++++++++ imgui_internal.h | 3 --- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index de569db5..6005fb26 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1197,6 +1197,20 @@ ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) return out; } +ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) +{ + ImVec4 c = GImGui->Style.Colors[idx]; + c.w *= GImGui->Style.Alpha * alpha_mul; + return ImGui::ColorConvertFloat4ToU32(c); +} + +ImU32 ImGui::GetColorU32(const ImVec4& col) +{ + ImVec4 c = col; + c.w *= GImGui->Style.Alpha; + return ImGui::ColorConvertFloat4ToU32(c); +} + // Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592 // Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) diff --git a/imgui_internal.h b/imgui_internal.h index 7b59bb63..dc02f719 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -703,9 +703,6 @@ namespace ImGui IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); - inline IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); } - inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } - // NB: All position are in absolute pixels coordinates (not window coordinates) // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp! // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers. From af33efb1460218bb649392853f556ed218b2dcb3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 6 Aug 2016 09:35:05 +0200 Subject: [PATCH 44/47] Using IM_COL32() for colors in a few spots (#767) --- imgui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6005fb26..29edee02 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1850,7 +1850,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y) window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); - //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); // Debug + //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // Debug window->DC.PrevLineHeight = line_height; window->DC.PrevLineTextBaseOffset = text_base_offset; @@ -2702,10 +2702,10 @@ void ImGui::Render() const ImVec2 size = cursor_data.Size; const ImTextureID tex_id = g.IO.Fonts->TexID; g.OverlayDrawList.PushTextureID(tex_id); - g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0xFF000000); // Black border - g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], 0xFFFFFFFF); // White fill + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,255)); // Black border + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], IM_COL32(255,255,255,255)); // White fill g.OverlayDrawList.PopTextureID(); } if (!g.OverlayDrawList.VtxBuffer.empty()) From b8397c293379a890811f3fba8ce84ef680f83423 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 6 Aug 2016 09:40:26 +0200 Subject: [PATCH 45/47] Tweak comments (#768) --- imgui.cpp | 4 ++-- imgui.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e091382e..81a57d96 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9116,10 +9116,10 @@ bool ImGui::IsRectVisible(const ImVec2& size) return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); } -bool ImGui::IsRectVisible(const ImVec2& a, const ImVec2& b) +bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) { ImGuiWindow* window = GetCurrentWindowRead(); - return window->ClipRect.Overlaps(ImRect(a, b)); + return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); } // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) diff --git a/imgui.h b/imgui.h index 40be5091..60a15af2 100644 --- a/imgui.h +++ b/imgui.h @@ -409,8 +409,8 @@ namespace ImGui IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) - IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization) - IMGUI_API bool IsRectVisible(const ImVec2& a, const ImVec2& b); // " + IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. + IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); From 5d1a0a6f77955b7b7bff926269fb71915ab48415 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 6 Aug 2016 09:48:04 +0200 Subject: [PATCH 46/47] Removed a handful of obsolete (trivial) function redirection from 1.34 and 1.38 (march-april 2015) OpenNextNode() -> SetNextTreeNodeOpen() GetWindowIsFocused() -> IsWindowFocused() GetItemBoxMin() -> GetItemRectMin() GetItemBoxMax() -> GetItemRectMax() IsMouseHoveringBox() -> IsMouseHoveringRect() IsClipped() -> !IsRectVisible() --- imgui.cpp | 8 ++++---- imgui.h | 8 +------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 81a57d96..90227eb1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -209,15 +209,15 @@ - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "open" state of a popup. BeginPopup() returns true if the popup is opened. - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). - - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete). + - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function until 1.50. - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. - - 2015/03/17 (1.36) - renamed GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). + - 2015/03/17 (1.36) - renamed GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function until 1.50. - 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing - - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function (will obsolete). + - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function until 1.50. - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth (casing) - - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function (will obsolete). + - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function until 1.50. - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once. - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now. - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior diff --git a/imgui.h b/imgui.h index 60a15af2..b85eaeff 100644 --- a/imgui.h +++ b/imgui.h @@ -468,15 +468,9 @@ namespace ImGui static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ - static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpen(open, 0); } // OBSOLETE 1.34+ - static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+ + static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ - static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE 1.36+ - static inline ImVec2 GetItemBoxMax() { return GetItemRectMax(); } // OBSOLETE 1.36+ - static inline bool IsClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.38+ static inline bool IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+ - static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE 1.36+ - static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ #endif } // namespace ImGui From 6eb35b8a0495e7f3fe537a39e59903e5fb45e022 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 7 Aug 2016 13:53:41 +0200 Subject: [PATCH 47/47] BulletText(): doesn't stop displaying at the ## mark --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 90227eb1..8fba82b5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6180,7 +6180,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args) const char* text_begin = g.TempBuffer; const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - const ImVec2 label_size = CalcTextSize(text_begin, text_end, true); + const ImVec2 label_size = CalcTextSize(text_begin, text_end, false); const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding @@ -6190,7 +6190,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args) // Render RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f)); - RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end); + RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end, false); } void ImGui::BulletText(const char* fmt, ...)