From 94116f1143a7bf552b759a913122e495dc4deee4 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Mar 2018 22:41:05 +0100 Subject: [PATCH 01/19] Examples: GLFW: Don't alter cursor mode if GLFW_CURSOR input mode is GLFW_CURSOR_DISABLED. (#1202) [@PhilCK] --- CHANGELOG.txt | 1 + examples/opengl2_example/imgui_impl_glfw_gl2.cpp | 2 +- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d345c19d..dbc6bd81 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -173,6 +173,7 @@ Other Changes: - Examples: Win32 (DirectX9,10,11,12: Support for windows using the CS_DBLCLKS class flag by handling the double-click messages (WM_LBUTTONDBLCLK etc.). (#1538, #754) [@ndandoulakis] - Examples: Win32 (DirectX9,10,11,12): Made the Win32 proc handlers not assert if there is no active context yet, to be more flexible with creation order. (#1565) - Examples: GLFW: Added support for mouse cursor shapes (the diagonal resize cursors are unfortunately not supported by GLFW at the moment. (#1495) +- Examples: GLFW: Don't attempt to change the mouse cursor input mode if it is set to GLFW_CURSOR_DISABLED by the application. (#1202) [@PhilCK] - Examples: SDL: Added support for mouse cursor shapes. (#1626) [@olls] - Examples: SDL: Using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging (SDL 2.0.4+ only, otherwise using SDL_WINDOW_INPUT_FOCUS instead of previously SDL_WINDOW_MOUSE_FOCUS). (#1559) - Examples: SDL: Enabled vsync by default so people don't come at us with demoes running at 2000 FPS burning a cpu core. diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 149051ba..2789f0d1 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -345,7 +345,7 @@ void ImGui_ImplGlfwGL2_NewFrame() } // Update OS/hardware mouse cursor if imgui isn't drawing a software cursor - if ((io.ConfigFlags & ImGuiConfigFlags_NoSetMouseCursor) == 0) + if ((io.ConfigFlags & ImGuiConfigFlags_NoSetMouseCursor) == 0 && glfwGetInputMode(g_Window, GLFW_CURSOR) != GLFW_CURSOR_DISABLED) { ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index a0f631c1..348a0b04 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -477,7 +477,7 @@ void ImGui_ImplGlfwGL3_NewFrame() } // Update OS/hardware mouse cursor if imgui isn't drawing a software cursor - if ((io.ConfigFlags & ImGuiConfigFlags_NoSetMouseCursor) == 0) + if ((io.ConfigFlags & ImGuiConfigFlags_NoSetMouseCursor) == 0 && glfwGetInputMode(g_Window, GLFW_CURSOR) != GLFW_CURSOR_DISABLED) { ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) From 21ac470a8a5885ef9811b3c0738fd59bfa700cda Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 21 Mar 2018 19:45:19 +0100 Subject: [PATCH 02/19] Nav: Fixed a crash with IMGUI_DEBUG_NAV_SCORING enabled + added info to Metrics. --- imgui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 41e25c2d..4e0417ee 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2320,7 +2320,9 @@ static void NavRestoreLayer(int layer) static inline void NavUpdateAnyRequestFlag() { ImGuiContext& g = *GImGui; - g.NavAnyRequest = g.NavMoveRequest || g.NavInitRequest || IMGUI_DEBUG_NAV_SCORING; + g.NavAnyRequest = g.NavMoveRequest || g.NavInitRequest || (IMGUI_DEBUG_NAV_SCORING && g.NavWindow != NULL); + if (g.NavAnyRequest) + IM_ASSERT(g.NavWindow != NULL); } static bool NavMoveRequestButNoResultYet() @@ -13258,6 +13260,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec)", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec), ActiveIdSource: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, input_source_names[g.ActiveIdSource]); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); + ImGui::Text("MovingWindow: '%s'", g.MovingWindow ? g.MovingWindow->Name : "NULL"); ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); ImGui::Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); ImGui::Text("NavInputSource: %s", input_source_names[g.NavInputSource]); From c796960ff93c240c652960f98e361cdf141ef70d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Mar 2018 17:49:53 +0100 Subject: [PATCH 03/19] InputFloat: Scientific input. InputText: Added ImGuiInputTextFlags_CharsScientific to add 'e' 'E' to list of characters that can be input. (later useful for #1011) --- CHANGELOG.txt | 1 + imgui.cpp | 11 ++++++++--- imgui.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index dbc6bd81..801b483d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -104,6 +104,7 @@ Other Changes: - ArrowButton: Added ArrowButton() given a cardinal direction (e.g. ImGuiDir_Left). - InputText: Added alternative clipboard shortcuts: Shift+Delete (cut), Ctrl+Insert (copy), Shift+Insert (paste). (#1541) - InputText: Fixed losing Cursor X position when clicking outside on an item that's submitted after the InputText(). It was only noticeable when restoring focus programmatically. (#1418, #1554) +- InputText: Added ImGuiInputTextFlags_CharsScientific flag to also allow 'e'/'E' for input of values using scientific notation. Automatically used by InputFloat. - Style: Enable window border by default. (#707) - Style: Exposed ImGuiStyleVar_WindowTitleAlign, ImGuiStyleVar_ScrollbarSize, ImGuiStyleVar_ScrollbarRounding, ImGuiStyleVar_GrabRounding + added an assert to reduce accidental breakage. (#1181) - Style: Added style.MouseCursorScale help when using the software mouse cursor facility. (#939). diff --git a/imgui.cpp b/imgui.cpp index 4e0417ee..03cf76b1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9779,12 +9779,16 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys. return false; - if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank)) + if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific)) { if (flags & ImGuiInputTextFlags_CharsDecimal) if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/')) return false; + if (flags & ImGuiInputTextFlags_CharsScientific) + if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/') && (c != 'e') && (c != 'E')) + return false; + if (flags & ImGuiInputTextFlags_CharsHexadecimal) if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return false; @@ -10446,7 +10450,7 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf)); bool value_changed = false; - if (!(extra_flags & ImGuiInputTextFlags_CharsHexadecimal)) + if ((extra_flags & (ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0) extra_flags |= ImGuiInputTextFlags_CharsDecimal; extra_flags |= ImGuiInputTextFlags_AutoSelectAll; if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) // PushId(label) + "" gives us the expected ID from outside point of view @@ -10489,6 +10493,7 @@ bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, strcpy(display_format, "%f"); // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1 else ImFormatString(display_format, IM_ARRAYSIZE(display_format), "%%.%df", decimal_precision); + extra_flags |= ImGuiInputTextFlags_CharsScientific; return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), display_format, extra_flags); } @@ -10496,7 +10501,7 @@ bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiIn { // Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes. const char* scalar_format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d"; - return InputScalarEx(label, ImGuiDataType_Int, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), scalar_format, extra_flags); + return InputScalarEx(label, ImGuiDataType_Int, (void*)v, (void*)(step>0 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), scalar_format, extra_flags); } bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags) diff --git a/imgui.h b/imgui.h index f48681b9..a07e6344 100644 --- a/imgui.h +++ b/imgui.h @@ -603,6 +603,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). + ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) // [Internal] ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() }; From c19b27813dad08c1bc26a5252a7c273e0645e74a Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Mar 2018 18:58:40 +0100 Subject: [PATCH 04/19] Added InputDouble() function. We use a format string instead of a decimal_precision parameter to also for "%e" and variants. (#1011) May transition the other InputXXX function to use format strings as well. --- CHANGELOG.txt | 2 + imgui.cpp | 100 +++++++++++++++++++++++++++++++++-------------- imgui.h | 1 + imgui_demo.cpp | 11 ++++-- imgui_internal.h | 6 ++- 5 files changed, 86 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 801b483d..266c7ff5 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -126,6 +126,8 @@ Other Changes: - Drag and Drop: Increased payload type string to 32 characters instead of 8. (#143) - Drag and Drop: TreeNode as drop target displays rectangle over full frame. (#1597, #143) - DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559) +- InputFloat: Allow inputing value using scientific notation e.g. "1e+10". +- InputDouble: Added InputDouble() function. We use a format string instead of a decimal_precision parameter to also for "%e" and variants. (#1011) - Slider, Combo: Use ImGuiCol_FrameBgHovered color when hovered. (#1456) [@stfx] - Combo: BeginCombo(): Added ImGuiComboFlags_NoArrowButton to disable the arrow button and only display the wide value preview box. - Combo: BeginCombo(): Added ImGuiComboFlags_NoPreview to disable the preview and only display a square arrow button. diff --git a/imgui.cpp b/imgui.cpp index 03cf76b1..a16cd5c2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -725,7 +725,7 @@ static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size); static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size); -static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2); +static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg_1, const void* arg_2); static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); namespace ImGui @@ -8380,6 +8380,8 @@ static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, ImFormatString(buf, buf_size, display_format, *(int*)data_ptr); else if (data_type == ImGuiDataType_Float) ImFormatString(buf, buf_size, display_format, *(float*)data_ptr); + else if (data_type == ImGuiDataType_Double) + ImFormatString(buf, buf_size, display_format, *(double*)data_ptr); } static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size) @@ -8398,27 +8400,45 @@ static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, else ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(float*)data_ptr); } + else if (data_type == ImGuiDataType_Double) + { + if (decimal_precision < 0) + ImFormatString(buf, buf_size, "%f", *(double*)data_ptr); + else + ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(double*)data_ptr); + } } -static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2)// Store into value1 +static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2) { + IM_ASSERT(op == '+' || op == '-'); if (data_type == ImGuiDataType_Int) { - if (op == '+') - *(int*)value1 = *(int*)value1 + *(const int*)value2; - else if (op == '-') - *(int*)value1 = *(int*)value1 - *(const int*)value2; + if (op == '+') *(int*)output = *(int*)arg1 + *(const int*)arg2; + else if (op == '-') *(int*)output = *(int*)arg1 - *(const int*)arg2; } else if (data_type == ImGuiDataType_Float) { - if (op == '+') - *(float*)value1 = *(float*)value1 + *(const float*)value2; - else if (op == '-') - *(float*)value1 = *(float*)value1 - *(const float*)value2; + if (op == '+') *(float*)output = *(float*)arg1 + *(const float*)arg2; + else if (op == '-') *(float*)output = *(float*)arg1 - *(const float*)arg2; + } + else if (data_type == ImGuiDataType_Double) + { + if (op == '+') *(double*)output = *(double*)arg1 + *(const double*)arg2; + else if (op == '-') *(double*)output = *(double*)arg1 - *(const double*)arg2; } } +static size_t GDataTypeSize[ImGuiDataType_COUNT] = +{ + sizeof(int), + sizeof(float), + sizeof(double), + sizeof(float) * 2, +}; + // User can input math operators (e.g. +100) to edit a numerical values. +// NB: This is _not_ a full expression evaluator. We should probably add one though.. static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format) { while (ImCharIsSpace(*buf)) @@ -8440,45 +8460,56 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b if (!buf[0]) return false; + IM_ASSERT(data_type < ImGuiDataType_COUNT); + int data_backup[2]; + IM_ASSERT(GDataTypeSize[data_type] <= sizeof(data_backup)); + memcpy(data_backup, data_ptr, GDataTypeSize[data_type]); + if (data_type == ImGuiDataType_Int) { if (!scalar_format) scalar_format = "%d"; int* v = (int*)data_ptr; - const int old_v = *v; int arg0i = *v; if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1) return false; - // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision float arg1f = 0.0f; if (op == '+') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i + arg1f); } // Add (use "+-" to subtract) else if (op == '*') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i * arg1f); } // Multiply else if (op == '/') { if (sscanf(buf, "%f", &arg1f) == 1 && arg1f != 0.0f) *v = (int)(arg0i / arg1f); }// Divide - else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign constant (read as integer so big values are not lossy) - return (old_v != *v); + else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign integer constant } else if (data_type == ImGuiDataType_Float) { // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in scalar_format = "%f"; float* v = (float*)data_ptr; - const float old_v = *v; - float arg0f = *v; + float arg0f = *v, arg1f = 0.0f; if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1) return false; - - float arg1f = 0.0f; if (sscanf(buf, scalar_format, &arg1f) < 1) return false; if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) else if (op == '*') { *v = arg0f * arg1f; } // Multiply else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide else { *v = arg1f; } // Assign constant - return (old_v != *v); } - - return false; + else if (data_type == ImGuiDataType_Double) + { + scalar_format = "%lf"; + double* v = (double*)data_ptr; + double arg0f = *v, arg1f = 0.0f; + if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1) + return false; + if (sscanf(buf, scalar_format, &arg1f) < 1) + return false; + if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) + else if (op == '*') { *v = arg0f * arg1f; } // Multiply + else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide + else { *v = arg1f; } // Assign constant + } + return memcmp(data_backup, data_ptr, GDataTypeSize[data_type]) != 0; } // Create text input in place of a slider (when CTRL+Clicking on slider) @@ -10463,13 +10494,13 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data SameLine(0, style.ItemInnerSpacing.x); if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) { - DataTypeApplyOp(data_type, '-', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + DataTypeApplyOp(data_type, '-', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); value_changed = true; } SameLine(0, style.ItemInnerSpacing.x); if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) { - DataTypeApplyOp(data_type, '+', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + DataTypeApplyOp(data_type, '+', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); value_changed = true; } } @@ -10488,13 +10519,24 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) { - char display_format[16]; - if (decimal_precision < 0) - strcpy(display_format, "%f"); // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1 - else - ImFormatString(display_format, IM_ARRAYSIZE(display_format), "%%.%df", decimal_precision); extra_flags |= ImGuiInputTextFlags_CharsScientific; - return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), display_format, extra_flags); + if (decimal_precision < 0) + { + // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1 + return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), "%f", extra_flags); + } + else + { + char display_format[16]; + ImFormatString(display_format, IM_ARRAYSIZE(display_format), "%%.%df", decimal_precision); + return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), display_format, extra_flags); + } +} + +bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* display_format, ImGuiInputTextFlags extra_flags) +{ + extra_flags |= ImGuiInputTextFlags_CharsScientific; + return InputScalarEx(label, ImGuiDataType_Double, (void*)v, (void*)(step>0.0 ? &step : NULL), (void*)(step_fast>0.0 ? &step_fast : NULL), display_format, extra_flags); } bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags extra_flags) diff --git a/imgui.h b/imgui.h index a07e6344..a79705bd 100644 --- a/imgui.h +++ b/imgui.h @@ -357,6 +357,7 @@ namespace ImGui IMGUI_API bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputDouble(const char* label, double* v, double step = 0.0f, double step_fast = 0.0f, const char* display_format = "%.6f", ImGuiInputTextFlags extra_flags = 0); // Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds) IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for logarithmic sliders diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9be5fef0..b3d42391 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -335,8 +335,8 @@ void ImGui::ShowDemoWindow(bool* p_open) { static char str0[128] = "Hello, world!"; - static int i0=123; - static float f0=0.001f; + static int i0 = 123; + static float f0 = 0.001f; ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); ImGui::SameLine(); ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n"); @@ -345,12 +345,17 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); + // NB: You can use the %e notation as well. + static double d0 = 999999.000001; + ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.6f"); + ImGui::SameLine(); ShowHelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n"); + static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; ImGui::InputFloat3("input float3", vec4a); } { - static int i1=50, i2=42; + static int i1 = 50, i2 = 42; ImGui::DragInt("drag int", &i1, 1); ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); diff --git a/imgui_internal.h b/imgui_internal.h index 8114faae..479f25be 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -248,7 +248,9 @@ enum ImGuiDataType { ImGuiDataType_Int, ImGuiDataType_Float, - ImGuiDataType_Float2 + ImGuiDataType_Double, + ImGuiDataType_Float2, + ImGuiDataType_COUNT }; enum ImGuiInputSource @@ -258,7 +260,7 @@ enum ImGuiInputSource ImGuiInputSource_Nav, ImGuiInputSource_NavKeyboard, // Only used occasionally for storage, not tested/handled by most code ImGuiInputSource_NavGamepad, // " - ImGuiInputSource_COUNT, + ImGuiInputSource_COUNT }; // FIXME-NAV: Clarify/expose various repeat delay/rate From b69dc45f6e94e931c38cc9e7101b7f4f97b4756d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Mar 2018 20:14:31 +0100 Subject: [PATCH 05/19] Internals: Removed ImGuiDataType_Float2. --- imgui.cpp | 57 ++++++++++++++++++++++++------------------------ imgui_internal.h | 1 - 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a16cd5c2..4699e673 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6570,33 +6570,34 @@ void ImGui::PopStyleColor(int count) struct ImGuiStyleVarInfo { ImGuiDataType Type; + ImU32 Count; ImU32 Offset; void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } }; static const ImGuiStyleVarInfo GStyleVarInfo[] = { - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign }; static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) @@ -6609,7 +6610,7 @@ static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) { const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type == ImGuiDataType_Float) + if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1) { ImGuiContext& g = *GImGui; float* pvar = (float*)var_info->GetVarPtr(&g.Style); @@ -6623,7 +6624,7 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) { const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type == ImGuiDataType_Float2) + if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2) { ImGuiContext& g = *GImGui; ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style); @@ -6639,11 +6640,12 @@ void ImGui::PopStyleVar(int count) ImGuiContext& g = *GImGui; while (count > 0) { + // We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it. ImGuiStyleMod& backup = g.StyleModifiers.back(); const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx); - if (info->Type == ImGuiDataType_Float) (*(float*)info->GetVarPtr(&g.Style)) = backup.BackupFloat[0]; - else if (info->Type == ImGuiDataType_Float2) (*(ImVec2*)info->GetVarPtr(&g.Style)) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); - else if (info->Type == ImGuiDataType_Int) (*(int*)info->GetVarPtr(&g.Style)) = backup.BackupInt[0]; + void* data = info->GetVarPtr(&g.Style); + if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; } + else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; } g.StyleModifiers.pop_back(); count--; } @@ -8433,8 +8435,7 @@ static size_t GDataTypeSize[ImGuiDataType_COUNT] = { sizeof(int), sizeof(float), - sizeof(double), - sizeof(float) * 2, + sizeof(double) }; // User can input math operators (e.g. +100) to edit a numerical values. diff --git a/imgui_internal.h b/imgui_internal.h index 479f25be..b5c5b0e4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -249,7 +249,6 @@ enum ImGuiDataType ImGuiDataType_Int, ImGuiDataType_Float, ImGuiDataType_Double, - ImGuiDataType_Float2, ImGuiDataType_COUNT }; From cd602b883271362256769dc6dbb265aef477a2e3 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Mar 2018 12:03:57 +0100 Subject: [PATCH 06/19] Examples: SDL: Note about SDL breaking the IME under Windows (I can't seem a way SDL2 Windows IME implementation can possibly work, the functions are never called/referenced). --- examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 2 ++ examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h | 2 ++ examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 ++ examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h | 2 ++ 4 files changed, 8 insertions(+) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 117a073a..0149864d 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -3,6 +3,8 @@ // Implemented features: // [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. +// Missing features: +// [ ] SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **Prefer using the code in the sdl_opengl3_example/ folder** diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h index 4df1c169..d3ef9168 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h @@ -3,6 +3,8 @@ // Implemented features: // [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. +// Missing features: +// [ ] SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **Prefer using the code in the sdl_opengl3_example/ folder** diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 16c1d440..8b04b933 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -4,6 +4,8 @@ // Implemented features: // [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. +// Missing features: +// [ ] SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h index 3aa00c3d..c694a481 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h @@ -4,6 +4,8 @@ // Implemented features: // [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. +// Missing features: +// [ ] SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). From cc96477b1c6be28b116a0fe12ba6a11b7a1a565e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 25 Mar 2018 14:45:40 +0200 Subject: [PATCH 07/19] Comments (#1695) --- imconfig.h | 3 ++- imgui.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/imconfig.h b/imconfig.h index 4ba73134..47f4f54f 100644 --- a/imconfig.h +++ b/imconfig.h @@ -5,7 +5,8 @@ //----------------------------------------------------------------------------- // A) You may edit imconfig.h (and not overwrite it when updating imgui, or maintain a patch/branch with your modifications to imconfig.h) // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" -// Note that options such as IMGUI_API, IM_VEC2_CLASS_EXTRA or ImDrawIdx needs to be defined consistently everywhere you include imgui.h, not only for the imgui*.cpp compilation units. +// C) Many compile-time options have an effect on data structures. They need defined consistently _everywhere_ imgui.h is included, +// not only for the imgui*.cpp compilation units. Defining those options in imconfig.h will ensure they correctly get used everywhere. //----------------------------------------------------------------------------- #pragma once diff --git a/imgui.cpp b/imgui.cpp index 4699e673..33574f66 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8,7 +8,12 @@ // Gallery (please post your screenshots/video there!): https://github.com/ocornut/imgui/issues/1269 // Developed by Omar Cornut and every direct or indirect contributors to the GitHub. // This library is free but I need your support to sustain development and maintenance. -// If you work for a company, please consider financial support, see Readme. For individuals: https://www.patreon.com/imgui +// If you work for a company, please consider financial support, see README. For individuals: https://www.patreon.com/imgui + +// It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library. +// Note that 'ImGui::' is a namespace and so you can add functions into it from your own source files without modifying imgui.h or imgui.cpp. +// You may include imgui_internal.h to access internal data structures, but it doesn't come with any guarantee of forward compatibility. +// Discussing your changes on the GitHub Issue Tracker may lead you to a better solution or official support for them. /* From ca39070ca0853128c1a718cc18b8d9cc7ecb9fa4 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 28 Mar 2018 23:32:02 +0200 Subject: [PATCH 08/19] Examples: Win32: Fixes for MingW which doesn't support a 2007 define? I have no idea why people still use MingW (#1704, #1463) --- examples/directx10_example/imgui_impl_dx10.cpp | 5 +++++ examples/directx11_example/imgui_impl_dx11.cpp | 5 +++++ examples/directx12_example/imgui_impl_dx12.cpp | 5 +++++ examples/directx9_example/imgui_impl_dx9.cpp | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index cc2ebddb..60c79d52 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -275,6 +275,11 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } +// MingW (which is stuck in the past) doesn't have this Vista-era define.. +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif + // Process Win32 mouse/keyboard inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index a9748eea..f319d2c4 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -282,6 +282,11 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } +// MingW (which is stuck in the past) doesn't have this Vista-era define.. +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif + // Process Win32 mouse/keyboard inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp index a6f36f6f..04df1dbc 100644 --- a/examples/directx12_example/imgui_impl_dx12.cpp +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -253,6 +253,11 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } +// MingW (which is stuck in the past) doesn't have this Vista-era define.. +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif + // Process Win32 mouse/keyboard inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 1c1bb1c0..aa40d34a 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -215,6 +215,11 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } +// MingW (which is stuck in the past) doesn't have this Vista-era define.. +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif + // Process Win32 mouse/keyboard inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. From 664ab85f76d59023684e077ea5654bbaeea3abc0 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 2 Apr 2018 17:31:51 +0200 Subject: [PATCH 09/19] Examples: Tweak comments. (#1704, #1708). --- examples/directx10_example/imgui_impl_dx10.cpp | 2 +- examples/directx11_example/imgui_impl_dx11.cpp | 2 +- examples/directx12_example/imgui_impl_dx12.cpp | 2 +- examples/directx9_example/imgui_impl_dx9.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 60c79d52..ae6dadc9 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -275,7 +275,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } -// MingW (which is stuck in the past) doesn't have this Vista-era define.. +// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. #ifndef WM_MOUSEHWHEEL #define WM_MOUSEHWHEEL 0x020E #endif diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index f319d2c4..6249120a 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -282,7 +282,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } -// MingW (which is stuck in the past) doesn't have this Vista-era define.. +// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. #ifndef WM_MOUSEHWHEEL #define WM_MOUSEHWHEEL 0x020E #endif diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp index 04df1dbc..d327c36e 100644 --- a/examples/directx12_example/imgui_impl_dx12.cpp +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -253,7 +253,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } -// MingW (which is stuck in the past) doesn't have this Vista-era define.. +// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. #ifndef WM_MOUSEHWHEEL #define WM_MOUSEHWHEEL 0x020E #endif diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index aa40d34a..967e07e3 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -215,7 +215,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() return true; } -// MingW (which is stuck in the past) doesn't have this Vista-era define.. +// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. #ifndef WM_MOUSEHWHEEL #define WM_MOUSEHWHEEL 0x020E #endif From c461401b2123e4a22c12f63b613ef8b2cb124ccb Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 3 Apr 2018 20:05:59 +0200 Subject: [PATCH 10/19] Comments, FAQ --- README.md | 8 ++++---- imgui.cpp | 61 +++++++++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 080ae31d..8cb24a04 100644 --- a/README.md +++ b/README.md @@ -232,7 +232,7 @@ The library started its life and is best known as "ImGui" only due to the fact t How can I tell whether to dispatch mouse/keyboard to imgui or to my application?
How can I display an image? What is ImTextureID, how does it works? -
How can I have multiple widgets with the same label, or without any label? (Yes). A primer on labels and ID stack. +
How can I have multiple widgets with the same label or without a label? A primer on labels and the ID Stack.
How can I load a different font than the default?
How can I easily use icons in my application?
How can I load multiple fonts? @@ -301,7 +301,7 @@ Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Bin Ongoing dear imgui development is financially supported on [**Patreon**](http://www.patreon.com/imgui) and by private sponsors. Double-chocolate sponsors: -- Blizzard +- Blizzard Entertainment - Media Molecule - Mobigame - Insomniac Games @@ -311,10 +311,10 @@ Double-chocolate sponsors: - DotEmu Salty caramel supporters: -- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse, Lionel Landwerlin. +- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse, Lionel Landwerlin, Nikolay Ivanov, Ron Gilbert. 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, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić, Jonas Bernemann, Johan Andersson, Nathan Hartman, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Felipe Alfonso, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Edsel Malasig, Andrew Johnson. +- 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, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić, Jonas Bernemann, Johan Andersson, Nathan Hartman, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Felipe Alfonso, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Edsel Malasig, Andrew Johnson, Sean Hunter, Jordan Mellow. And other supporters; thanks! (Please contact me or PR if you would like to be added or removed from this list) diff --git a/imgui.cpp b/imgui.cpp index 33574f66..5596d24e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -30,7 +30,7 @@ - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I tell whether to dispatch mouse/keyboard to imgui or to my application? - How can I display an image? What is ImTextureID, how does it works? - - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels and the ID stack. + - How can I have multiple widgets with the same label or without a label? A primer on labels and the ID Stack. - How can I load a different font than the default? - How can I easily use icons in my application? - How can I load multiple fonts? @@ -433,63 +433,66 @@ It could be an identifier to your OpenGL texture (cast GLuint to void*), a pointer to your custom engine material (cast MyMaterial* to void*), etc. At the end of the chain, your renderer takes this void* to cast it back into whatever it needs to select a current texture to render. Refer to examples applications, where each renderer (in a imgui_impl_xxxx.cpp file) is treating ImTextureID as a different thing. - (c++ tip: OpenGL uses integers to identify textures. You can safely store an integer into a void*, just cast it to void*, don't take it's address!) + (C++ tip: OpenGL uses integers to identify textures. You can safely store an integer into a void*, just cast it to void*, don't take it's address!) To display a custom image/texture within an ImGui window, you may use ImGui::Image(), ImGui::ImageButton(), ImDrawList::AddImage() functions. Dear ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use. You may call ImGui::ShowMetricsWindow() to explore active draw lists and visualize/understand how the draw data is generated. It is your responsibility to get textures uploaded to your GPU. - Q: Can I have multiple widgets with the same label? Can I have widget without a label? - A: Yes. A primer on labels and the ID stack... + Q: How can I have multiple widgets with the same label or without a label? + A: A primer on labels and the ID Stack... - Elements that are typically not clickable, such as Text() items don't need an ID. - Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui often needs to remember what is - the "active" widget). to do so they need a unique ID. unique ID are typically derived from a string label, an integer index or a pointer. + the "active" widget). To do so they need a unique ID. Unique ID are typically derived from a string label, an integer index or a pointer. - Button("OK"); // Label = "OK", ID = hash of "OK" - Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" + Button("OK"); // Label = "OK", ID = top of id stack + hash of "OK" + Button("Cancel"); // Label = "Cancel", ID = top of id stack + hash of "Cancel" - - ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" - in two different windows or in two different locations of a tree. + - ID are uniquely scoped within windows, tree nodes, etc. which all push to the ID stack. So having two buttons labeled "OK" + in two different windows or in two different locations of a tree is fine. - If you have a same ID twice in the same location, you'll have a conflict: Button("OK"); - Button("OK"); // ID collision! Both buttons will be treated as the same. + Button("OK"); // ID collision! Interacting with either button will trigger the first one. Fear not! this is easy to solve and there are many ways to solve it! - - When passing a label you can optionally specify extra unique ID information within string itself. + - Solving ID conflict in a simple/local context: + When passing a label you can optionally specify extra unique ID information within string itself. Use "##" to pass a complement to the ID that won't be visible to the end-user. This helps solving the simple collision cases when you know which items are going to be created. - Button("Play"); // Label = "Play", ID = hash of "Play" - Button("Play##foo1"); // Label = "Play", ID = hash of "Play##foo1" (different from above) - Button("Play##foo2"); // Label = "Play", ID = hash of "Play##foo2" (different from above) + Button("Play"); // Label = "Play", ID = top of id stack + hash of "Play" + Button("Play##foo1"); // Label = "Play", ID = top of id stack + hash of "Play##foo1" (different from above) + Button("Play##foo2"); // Label = "Play", ID = top of id stack + hash of "Play##foo2" (different from above) - If you want to completely hide the label, but still need an ID: - Checkbox("##On", &b); // Label = "", ID = hash of "##On" (no label!) + Checkbox("##On", &b); // Label = "", ID = top of id stack + hash of "##On" (no label!) - Occasionally/rarely you might want change a label while preserving a constant ID. This allows you to animate labels. For example you may want to include varying information in a window title bar, but windows are uniquely identified by their ID.. Use "###" to pass a label that isn't part of ID: - Button("Hello###ID"; // Label = "Hello", ID = hash of "ID" - Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above) + Button("Hello###ID"; // Label = "Hello", ID = top of id stack + hash of "ID" + Button("World###ID"; // Label = "World", ID = top of id stack + hash of "ID" (same as above) sprintf(buf, "My game (%f FPS)###MyGame", fps); Begin(buf); // Variable label, ID = hash of "MyGame" - - Use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window. + - Solving ID conflict in a more general manner: + Use PushID() / PopID() to create scopes and manipulate the ID stack, as to avoid ID conflicts within the same Window. This is the most convenient way of distinguishing ID if you are iterating and creating many UI elements. - You can push a pointer, a string or an integer value. Remember that ID are formed from the concatenation of _everything_ in the ID stack! + You can push a pointer, a string or an integer value into the ID stack. + Remember that ID are formed from the concatenation of _everything_ in the ID stack! for (int i = 0; i < 100; i++) { PushID(i); - Button("Click"); // Label = "Click", ID = hash of integer + "label" (unique) + Button("Click"); // Label = "Click", ID = top of id stack + hash of integer + hash of "Click" PopID(); } @@ -497,7 +500,7 @@ { MyObject* obj = Objects[i]; PushID(obj); - Button("Click"); // Label = "Click", ID = hash of pointer + "label" (unique) + Button("Click"); // Label = "Click", ID = top of id stack + hash of pointer + hash of "Click" PopID(); } @@ -505,35 +508,35 @@ { MyObject* obj = Objects[i]; PushID(obj->Name); - Button("Click"); // Label = "Click", ID = hash of string + "label" (unique) + Button("Click"); // Label = "Click", ID = top of id stack + hash of string + hash of "Click" PopID(); } - More example showing that you can stack multiple prefixes into the ID stack: - Button("Click"); // Label = "Click", ID = hash of "Click" + Button("Click"); // Label = "Click", ID = top of id stack + hash of "Click" PushID("node"); - Button("Click"); // Label = "Click", ID = hash of "node" + "Click" + Button("Click"); // Label = "Click", ID = top of id stack + hash of "node" + hash of "Click" PushID(my_ptr); - Button("Click"); // Label = "Click", ID = hash of "node" + ptr + "Click" + Button("Click"); // Label = "Click", ID = top of id stack + hash of "node" + hash of ptr + hash of "Click" PopID(); PopID(); - Tree nodes implicitly creates a scope for you by calling PushID(). - Button("Click"); // Label = "Click", ID = hash of "Click" + Button("Click"); // Label = "Click", ID = top of id stack + hash of "Click" if (TreeNode("node")) { - Button("Click"); // Label = "Click", ID = hash of "node" + "Click" + Button("Click"); // Label = "Click", ID = top of id stack + hash of "node" + hash of "Click" TreePop(); } - When working with trees, ID are used to preserve the open/close state of each tree node. Depending on your use cases you may want to use strings, indices or pointers as ID. - e.g. when displaying a single object that may change over time (dynamic 1-1 relationship), using a static string as ID will preserve your + e.g. when following a single pointer that may change over time, using a static string as ID will preserve your node open/closed state when the targeted object change. e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. - experiment and see what makes more sense! + experiment and see what makes more sense in your situation! 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/OTF file you want: From 77e234d9df88760c937246b367c7f04fbba73748 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 3 Apr 2018 20:22:44 +0200 Subject: [PATCH 11/19] Comments --- imgui.cpp | 98 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5596d24e..684ecf37 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11,9 +11,10 @@ // If you work for a company, please consider financial support, see README. For individuals: https://www.patreon.com/imgui // It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library. -// Note that 'ImGui::' is a namespace and so you can add functions into it from your own source files without modifying imgui.h or imgui.cpp. -// You may include imgui_internal.h to access internal data structures, but it doesn't come with any guarantee of forward compatibility. -// Discussing your changes on the GitHub Issue Tracker may lead you to a better solution or official support for them. +// Note that 'ImGui::' being a namespace, you can add functions into the namespace from your own source files, without +// modifying imgui.h or imgui.cpp. You may include imgui_internal.h to access internal data structures, but it doesn't +// come with any guarantee of forward compatibility. Discussing your changes on the GitHub Issue Tracker may lead you +// to a better solution or official support for them. /* @@ -53,8 +54,8 @@ - Minimize setup and maintenance - Minimize state storage on user side - Portable, minimize dependencies, run on target (consoles, phones, etc.) - - Efficient runtime and memory consumption (NB- we do allocate when "growing" content e.g. creating a window, opening a tree node - for the first time, etc. but a typical frame won't allocate anything) + - Efficient runtime and memory consumption (NB- we do allocate when "growing" content e.g. creating a window, + opening a tree node for the first time, etc. but a typical frame should not allocate anything) Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: - Doesn't look fancy, doesn't animate @@ -91,8 +92,8 @@ READ FIRST - Read the FAQ below this section! - - Your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention - on your side, no state duplication, less sync, less bugs. + - Your code creates the UI, if your code doesn't run the UI is gone! The UI can be highly dynamic, there are no construction + or destruction steps, less data retention on your side, less state duplication, less state synchronization, less bugs. - Call and read ImGui::ShowDemoWindow() for demo code demonstrating most features. - You can learn about immediate-mode gui principles at http://www.johno.se/book/imgui.html or watch http://mollyrocket.com/861 @@ -100,18 +101,18 @@ - Overwrite all the sources files except for imconfig.h (if you have made modification to your copy of imconfig.h) - Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes. - If a function/type has been renamed / or marked obsolete, try to fix the name in your code before it is permanently removed from the public API. - If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it. - Please report any issue to the GitHub page! + If a function/type has been renamed / or marked obsolete, try to fix the name in your code before it is permanently removed + from the public API. If you have a problem with a missing function/symbols, search for its name in the code, there will + likely be a comment about it. Please report any issue to the GitHub page! - Try to keep your copy of dear imgui reasonably up to date. GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE + - Run and study the examples and demo to get acquainted with the library. - Add the Dear ImGui source files to your projects, using your preferred build system. It is recommended you build the .cpp files as part of your project and not as a library. - You can later customize the imconfig.h file to tweak some compilation time behavior, such as integrating imgui types with your own maths types. - - See examples/ folder for standalone sample applications. - - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. + - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/ folder. - When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them. - Init: retrieve the ImGuiIO structure with ImGui::GetIO() and fill the fields marked 'Settings': at minimum you need to set io.DisplaySize @@ -199,7 +200,8 @@ MyEngineBindTexture(pcmd->TextureId); // We are using scissoring to clip some objects. All low-level graphics API supports it. - // If your engine doesn't support scissoring yet, you will get some small glitches (some elements outside their bounds) which you can fix later. + // If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches + // (some elements visible outside their bounds) but you can fix that once everywhere else works! MyEngineScissor((int)pcmd->ClipRect.x, (int)pcmd->ClipRect.y, (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); // Render 'pcmd->ElemCount/3' indexed triangles. @@ -215,22 +217,25 @@ - When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated. They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide mouse inputs from the rest of your application. Read the FAQ below for more information about those flags. + - Please read the FAQ above. Amusingly, it is called a FAQ because people frequently have the same issues! USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS [BETA] - The gamepad/keyboard navigation is in Beta. Ask questions and report issues at https://github.com/ocornut/imgui/issues/787 - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. - Keyboard: - - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. - - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag will be set. - For more advanced uses, you may want to read from: + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. + NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. + - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag + will be set. For more advanced uses, you may want to read from: - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. - io.NavVisible: true when the navigation cursor is visible (and usually goes false when mouse is used). - or query focus information with e.g. IsWindowFocused(), IsItemFocused() etc. functions. Please reach out if you think the game vs navigation input sharing could be improved. - Gamepad: - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. - - Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). + - Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + fill the io.NavInputs[] fields before calling NewFrame(). + Note that io.NavInputs[] is cleared by EndFrame(). - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. For each entry of io.NavInputs[], set the following values: 0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks. - We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone. @@ -444,14 +449,15 @@ - Elements that are typically not clickable, such as Text() items don't need an ID. - - Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui often needs to remember what is - the "active" widget). To do so they need a unique ID. Unique ID are typically derived from a string label, an integer index or a pointer. + - Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui + often needs to remember what is the "active" widget). To do so they need a unique ID. Unique ID + are typically derived from a string label, an integer index or a pointer. Button("OK"); // Label = "OK", ID = top of id stack + hash of "OK" Button("Cancel"); // Label = "Cancel", ID = top of id stack + hash of "Cancel" - - ID are uniquely scoped within windows, tree nodes, etc. which all push to the ID stack. So having two buttons labeled "OK" - in two different windows or in two different locations of a tree is fine. + - ID are uniquely scoped within windows, tree nodes, etc. which all pushes to the ID stack. Having + two buttons labeled "OK" in different windows or different tree locations is fine. - If you have a same ID twice in the same location, you'll have a conflict: @@ -461,9 +467,10 @@ Fear not! this is easy to solve and there are many ways to solve it! - Solving ID conflict in a simple/local context: - When passing a label you can optionally specify extra unique ID information within string itself. + When passing a label you can optionally specify extra ID information within string itself. Use "##" to pass a complement to the ID that won't be visible to the end-user. - This helps solving the simple collision cases when you know which items are going to be created. + This helps solving the simple collision cases when you know e.g. at compilation time which items + are going to be created: Button("Play"); // Label = "Play", ID = top of id stack + hash of "Play" Button("Play##foo1"); // Label = "Play", ID = top of id stack + hash of "Play##foo1" (different from above) @@ -473,9 +480,9 @@ Checkbox("##On", &b); // Label = "", ID = top of id stack + hash of "##On" (no label!) - - Occasionally/rarely you might want change a label while preserving a constant ID. This allows you to animate labels. - For example you may want to include varying information in a window title bar, but windows are uniquely identified by their ID.. - Use "###" to pass a label that isn't part of ID: + - Occasionally/rarely you might want change a label while preserving a constant ID. This allows + you to animate labels. For example you may want to include varying information in a window title bar, + but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID: Button("Hello###ID"; // Label = "Hello", ID = top of id stack + hash of "ID" Button("World###ID"; // Label = "World", ID = top of id stack + hash of "ID" (same as above) @@ -484,8 +491,9 @@ Begin(buf); // Variable label, ID = hash of "MyGame" - Solving ID conflict in a more general manner: - Use PushID() / PopID() to create scopes and manipulate the ID stack, as to avoid ID conflicts within the same Window. - This is the most convenient way of distinguishing ID if you are iterating and creating many UI elements. + Use PushID() / PopID() to create scopes and manipulate the ID stack, as to avoid ID conflicts + within the same window. This is the most convenient way of distinguishing ID when iterating and + creating many UI elements programmatically. You can push a pointer, a string or an integer value into the ID stack. Remember that ID are formed from the concatenation of _everything_ in the ID stack! @@ -533,25 +541,28 @@ - When working with trees, ID are used to preserve the open/close state of each tree node. Depending on your use cases you may want to use strings, indices or pointers as ID. - e.g. when following a single pointer that may change over time, using a static string as ID will preserve your - node open/closed state when the targeted object change. - e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. - experiment and see what makes more sense in your situation! + e.g. when following a single pointer that may change over time, using a static string as ID + will preserve your node open/closed state when the targeted object change. + e.g. when displaying a list of objects, using indices or pointers as ID will preserve the + node open/closed state differently. See what makes more sense in your situation! - Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) + Q: How can I load a different font than the default? A: Use the font atlas to load the TTF/OTF file you want: ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + (default is ProggyClean.ttf, rendered at size 13, embedded in dear imgui's source code) - New programmers: remember that in C/C++ and most programming languages if you want to use a backslash \ in a string literal you need to write a double backslash "\\": - io.Fonts->AddFontFromFileTTF("MyDataFolder\MyFontFile.ttf", size_in_pixels); // WRONG + New programmers: remember that in C/C++ and most programming languages if you want to use a + backslash \ within a string literal, you need to write it double backslash "\\": + io.Fonts->AddFontFromFileTTF("MyDataFolder\MyFontFile.ttf", size_in_pixels); // WRONG (you are escape the M here!) io.Fonts->AddFontFromFileTTF("MyDataFolder\\MyFontFile.ttf", size_in_pixels); // CORRECT io.Fonts->AddFontFromFileTTF("MyDataFolder/MyFontFile.ttf", size_in_pixels); // ALSO CORRECT Q: How can I easily use icons in my application? - A: The most convenient and practical way is to merge an icon font such as FontAwesome inside you main font. Then you can refer to icons within your - strings. Read 'How can I load multiple fonts?' and the file 'misc/fonts/README.txt' for instructions and useful header files. + A: The most convenient and practical way is to merge an icon font such as FontAwesome inside you + main font. Then you can refer to icons within your strings. Read 'How can I load multiple fonts?' + and the file 'misc/fonts/README.txt' for instructions and useful header files. Q: How can I load multiple fonts? A: Use the font atlas to pack them into a single texture: @@ -596,13 +607,16 @@ builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted) io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data); - All your strings needs to use UTF-8 encoding. In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. - Specifying literal in your source code using a local code page (such as CP-923 for Japanese or CP-1251 for Cyrillic) will NOT work! + All your strings needs to use UTF-8 encoding. In C++11 you can encode a string literal in UTF-8 + by using the u8"hello" syntax. Specifying literal in your source code using a local code page + (such as CP-923 for Japanese or CP-1251 for Cyrillic) will NOT work! Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. - Text input: it is up to your application to pass the right character code to io.AddInputCharacter(). The applications in examples/ are doing that. - For languages using IME, on Windows you can copy the Hwnd of your application to io.ImeWindowHandle. - The default implementation of io.ImeSetInputScreenPosFn() on Windows will set your IME position correctly. + Text input: it is up to your application to pass the right character code by calling + io.AddInputCharacter(). The applications in examples/ are doing that. For languages relying + on an Input Method Editor (IME), on Windows you can copy the Hwnd of your application in the + io.ImeWindowHandle field. The default implementation of io.ImeSetInputScreenPosFn() will set + your Microsoft IME position correctly. Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) A: - You can create a dummy window. Call SetNextWindowBgAlpha(0.0f), call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flags. From 78610a54d21361f62231b5c0f93c911037865faa Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 3 Apr 2018 20:55:30 +0200 Subject: [PATCH 12/19] Fixed Clang zealous cast-call warning (on par with GCC) which decided to warn against explicit C-style casts now. --- imgui.cpp | 13 +++++++------ imgui_draw.cpp | 3 ++- imgui_internal.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 684ecf37..8eb666b8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -687,14 +687,15 @@ #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. -#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' // +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' +#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxxx *' drops const qualifier #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size #pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*' #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value -#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false #endif @@ -1025,11 +1026,11 @@ char* ImStrdup(const char *str) return (char*)memcpy(buf, (const void*)str, len); } -char* ImStrchrRange(const char* str, const char* str_end, char c) +const char* ImStrchrRange(const char* str, const char* str_end, char c) { for ( ; str < str_end; str++) if (*str == c) - return (char*)str; + return str; return NULL; } @@ -3762,7 +3763,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) line_end[-1] = 0; const char* name_end = line_end - 1; const char* type_start = line + 1; - char* type_end = ImStrchrRange(type_start, name_end, ']'); + char* type_end = (char*)ImStrchrRange(type_start, name_end, ']'); const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; if (!type_end || !name_start) { @@ -9424,7 +9425,7 @@ struct ImGuiPlotArrayGetterData static float Plot_ArrayGetter(void* data, int idx) { ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; - const float v = *(float*)(void*)((unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); + const float v = *(const float*)(const void*)((const unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); return v; } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index a2d0215f..4eba6394 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -41,6 +41,7 @@ #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxx *' drops const qualifier // #if __has_warning("-Wcomma") #pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here // #endif @@ -54,7 +55,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value -#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif //------------------------------------------------------------------------- diff --git a/imgui_internal.h b/imgui_internal.h index b5c5b0e4..65edf576 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -113,7 +113,7 @@ IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); IMGUI_API char* ImStrdup(const char* str); -IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c); +IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); From 84fbc49403d1e18ba0774f453eb72bcf7c9701ec Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 3 Apr 2018 22:13:35 +0200 Subject: [PATCH 13/19] BeginChild: named child don't include the full id inside their name (#1698) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8eb666b8..2f00e0ba 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5097,7 +5097,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b char title[256]; if (name) - ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s_%08X", parent_window->Name, name, id); + ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s", parent_window->Name, name); else ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id); From 1e116e6c1777399415a8873e3709546ee990b15e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 3 Apr 2018 23:18:43 +0200 Subject: [PATCH 14/19] Removed need for -Wnocast-qual on modern Clang/Xcode as a token of good behavior. Unfortunately the old stb_ decompress code is a little const clunky. + warning fix in stb_textedit which is already in master afaik. --- imgui.cpp | 12 +++++------- imgui_draw.cpp | 46 +++++++++++++++++++++++----------------------- stb_textedit.h | 3 +-- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2f00e0ba..1f0bec9c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -688,14 +688,12 @@ #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' -#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxxx *' drops const qualifier #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size #pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*' #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value -#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false #endif @@ -3763,7 +3761,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) line_end[-1] = 0; const char* name_end = line_end - 1; const char* type_start = line + 1; - char* type_end = (char*)ImStrchrRange(type_start, name_end, ']'); + char* type_end = (char*)(intptr_t)ImStrchrRange(type_start, name_end, ']'); const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; if (!type_end || !name_start) { @@ -3839,8 +3837,8 @@ static void MarkIniSettingsDirty(ImGuiWindow* window) // FIXME: Add a more explicit sort order in the window structure. static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs) { - const ImGuiWindow* a = *(const ImGuiWindow**)lhs; - const ImGuiWindow* b = *(const ImGuiWindow**)rhs; + const ImGuiWindow* const a = *(const ImGuiWindow* const *)lhs; + const ImGuiWindow* const b = *(const ImGuiWindow* const *)rhs; if (int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup)) return d; if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) @@ -12935,14 +12933,14 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s // Store in heap g.DragDropPayloadBufHeap.resize((int)data_size); payload.Data = g.DragDropPayloadBufHeap.Data; - memcpy((void*)payload.Data, data, data_size); + memcpy((void*)(intptr_t)payload.Data, data, data_size); } else if (data_size > 0) { // Store locally memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); payload.Data = g.DragDropPayloadBufLocal; - memcpy((void*)payload.Data, data, data_size); + memcpy((void*)(intptr_t)payload.Data, data, data_size); } else { diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 4eba6394..b7ba849b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -41,7 +41,6 @@ #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // -#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxx *' drops const qualifier // #if __has_warning("-Wcomma") #pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here // #endif @@ -55,7 +54,6 @@ #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value -#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif //------------------------------------------------------------------------- @@ -84,11 +82,13 @@ namespace IMGUI_STB_NAMESPACE #pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wmissing-prototypes" #pragma clang diagnostic ignored "-Wimplicit-fallthrough" +#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxx *' drops const qualifier // #endif #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits] +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif #ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION @@ -1508,8 +1508,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) } // Default font TTF is compressed with stb_compress then base85 encoded (see misc/fonts/binary_to_compressed_c.cpp for encoder) -static unsigned int stb_decompress_length(unsigned char *input); -static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length); +static unsigned int stb_decompress_length(const unsigned char *input); +static unsigned int stb_decompress(unsigned char *output, const unsigned char *input, unsigned int length); static const char* GetDefaultCompressedFontDataTTFBase85(); static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; } static void Decode85(const unsigned char* src, unsigned char* dst) @@ -1576,9 +1576,9 @@ ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float si ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { - const unsigned int buf_decompressed_size = stb_decompress_length((unsigned char*)compressed_ttf_data); + const unsigned int buf_decompressed_size = stb_decompress_length((const unsigned char*)compressed_ttf_data); unsigned char* buf_decompressed_data = (unsigned char *)ImGui::MemAlloc(buf_decompressed_size); - stb_decompress(buf_decompressed_data, (unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size); + stb_decompress(buf_decompressed_data, (const unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size); ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); IM_ASSERT(font_cfg.FontData == NULL); @@ -2756,27 +2756,28 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im // Decompression from stb.h (public domain) by Sean Barrett https://github.com/nothings/stb/blob/master/stb.h //----------------------------------------------------------------------------- -static unsigned int stb_decompress_length(unsigned char *input) +static unsigned int stb_decompress_length(const unsigned char *input) { return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]; } -static unsigned char *stb__barrier, *stb__barrier2, *stb__barrier3, *stb__barrier4; +static unsigned char *stb__barrier_out_e, *stb__barrier_out_b; +static const unsigned char *stb__barrier_in_b; static unsigned char *stb__dout; -static void stb__match(unsigned char *data, unsigned int length) +static void stb__match(const unsigned char *data, unsigned int length) { // INVERSE of memmove... write each byte before copying the next... - IM_ASSERT (stb__dout + length <= stb__barrier); - if (stb__dout + length > stb__barrier) { stb__dout += length; return; } - if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; } + IM_ASSERT(stb__dout + length <= stb__barrier_out_e); + if (stb__dout + length > stb__barrier_out_e) { stb__dout += length; return; } + if (data < stb__barrier_out_b) { stb__dout = stb__barrier_out_e+1; return; } while (length--) *stb__dout++ = *data++; } -static void stb__lit(unsigned char *data, unsigned int length) +static void stb__lit(const unsigned char *data, unsigned int length) { - IM_ASSERT (stb__dout + length <= stb__barrier); - if (stb__dout + length > stb__barrier) { stb__dout += length; return; } - if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; } + IM_ASSERT(stb__dout + length <= stb__barrier_out_e); + if (stb__dout + length > stb__barrier_out_e) { stb__dout += length; return; } + if (data < stb__barrier_in_b) { stb__dout = stb__barrier_out_e+1; return; } memcpy(stb__dout, data, length); stb__dout += length; } @@ -2785,7 +2786,7 @@ static void stb__lit(unsigned char *data, unsigned int length) #define stb__in3(x) ((i[x] << 16) + stb__in2((x)+1)) #define stb__in4(x) ((i[x] << 24) + stb__in3((x)+1)) -static unsigned char *stb_decompress_token(unsigned char *i) +static const unsigned char *stb_decompress_token(const unsigned char *i) { if (*i >= 0x20) { // use fewer if's for cases that expand small if (*i >= 0x80) stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2; @@ -2833,21 +2834,20 @@ static unsigned int stb_adler32(unsigned int adler32, unsigned char *buffer, uns return (unsigned int)(s2 << 16) + (unsigned int)s1; } -static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length) +static unsigned int stb_decompress(unsigned char *output, const unsigned char *i, unsigned int /*length*/) { unsigned int olen; if (stb__in4(0) != 0x57bC0000) return 0; if (stb__in4(4) != 0) return 0; // error! stream is > 4GB olen = stb_decompress_length(i); - stb__barrier2 = i; - stb__barrier3 = i+length; - stb__barrier = output + olen; - stb__barrier4 = output; + stb__barrier_in_b = i; + stb__barrier_out_e = output + olen; + stb__barrier_out_b = output; i += 16; stb__dout = output; for (;;) { - unsigned char *old_i = i; + const unsigned char *old_i = i; i = stb_decompress_token(i); if (i == old_i) { if (*i == 0x05 && i[1] == 0xfa) { diff --git a/stb_textedit.h b/stb_textedit.h index 4b731a0c..7324fb6b 100644 --- a/stb_textedit.h +++ b/stb_textedit.h @@ -677,9 +677,8 @@ static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) } // API paste: replace existing selection with passed-in text -static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) +static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *text, int len) { - STB_TEXTEDIT_CHARTYPE *text = (STB_TEXTEDIT_CHARTYPE *) ctext; // if there's a selection, the paste should delete it stb_textedit_clamp(str, state); stb_textedit_delete_selection(str,state); From 2fa113c8955b5aa0c4af0180f0a834130fabf718 Mon Sep 17 00:00:00 2001 From: Francisco Demartino Date: Tue, 3 Apr 2018 19:03:55 -0300 Subject: [PATCH 15/19] README.md: add link to Gallery Part 6 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8cb24a04..13cfbe95 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,8 @@ User screenshots:
[Gallery Part 2](https://github.com/ocornut/imgui/issues/539) (Feb 2016 to Aug 2016)
[Gallery Part 3](https://github.com/ocornut/imgui/issues/772) (Aug 2016 to Jan 2017)
[Gallery Part 4](https://github.com/ocornut/imgui/issues/973) (Jan 2017 to Aug 2017) -
[Gallery Part 5](https://github.com/ocornut/imgui/issues/1269) (Aug 2017 onward) +
[Gallery Part 5](https://github.com/ocornut/imgui/issues/1269) (Aug 2017 to Feb 2018) +
[Gallery Part 6](https://github.com/ocornut/imgui/issues/1607) (Feb 2018 onward)
Also see the [Mega screenshots](https://github.com/ocornut/imgui/issues/1273) for an idea of the available features. Various tools From cd1e6e384f7a8a8c194d4182db534cb1510873e1 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 4 Apr 2018 12:39:24 +0200 Subject: [PATCH 16/19] Tooltip windows uses PopupBorderSize (#1697) + commented out debug stuff. --- imgui.cpp | 4 +++- imgui.h | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1f0bec9c..acda1fb1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4825,6 +4825,7 @@ void ImGui::OpenPopupEx(ImGuiID id) popup_ref.OpenMousePos = g.IO.MousePos; popup_ref.OpenPopupPos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; + //printf("[%05d] OpenPopupEx(0x%08X)\n", g.FrameCount, id); if (g.OpenPopupStack.Size < current_stack_size + 1) { g.OpenPopupStack.push_back(popup_ref); @@ -5727,7 +5728,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Lock window rounding, border size and rounding so that altering the border sizes for children doesn't have side-effects. window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; - window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; window->WindowPadding = style.WindowPadding; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); @@ -6391,6 +6392,7 @@ void ImGui::FocusWindow(ImGuiWindow* window) g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId g.NavIdIsAlive = false; g.NavLayer = 0; + //printf("[%05d] FocusWindow(\"%s\")\n", g.FrameCount, window ? window->Name : NULL); } // Passing NULL allow to disable keyboard focus diff --git a/imgui.h b/imgui.h index a79705bd..1e8b9aff 100644 --- a/imgui.h +++ b/imgui.h @@ -963,8 +963,8 @@ struct ImGuiStyle ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. float ChildBorderSize; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). - float PopupRounding; // Radius of popup window corners rounding. - float PopupBorderSize; // Thickness of border around popup windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + float PopupRounding; // Radius of popup window corners rounding. (Note that tooltip windows use WindowRounding) + float PopupBorderSize; // Thickness of border around popup/tooltip windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets). float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). From 4649967112f71b149cc4c8e67c28d815d5edf0e9 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 4 Apr 2018 15:01:01 +0200 Subject: [PATCH 17/19] Added extra comments and assertions to avoid user combining ImGuiCond flags. (#1694) --- CHANGELOG.txt | 7 +++++-- imgui.cpp | 7 +++++++ imgui.h | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 266c7ff5..b9647414 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -206,7 +206,8 @@ Breaking Changes: - Renamed `ImGuiTextBuffer::append()` helper to `appendf()`, and `appendv()` to `appendfv()` for consistency. If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. - ImDrawList: Removed 'bool anti_aliased = true' final parameter of `ImDrawList::AddPolyline()` and `ImDrawList::AddConvexPolyFilled()`. Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame. - Style, ImDrawList: Renamed `style.AntiAliasedShapes` to `style.AntiAliasedFill` for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags. -- Style, Begin: Removed `ImGuiWindowFlags_ShowBorders` window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. `style.FrameBorderSize`, `style.WindowBorderSize`). Use `ImGui::ShowStyleEditor()` to look them up. +- Style, Begin: Removed `ImGuiWindowFlags_ShowBorders` window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. `style.FrameBorderSize`, `style.WindowBorderSize`, `style.PopupBorderSize`). + Use `ImGui::ShowStyleEditor()` to look them up. Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended that you use the `StyleColorsClassic()`, `StyleColorsDark()`, `StyleColorsLight()` functions. Also see `ShowStyleSelector()`. - Style: Removed `ImGuiCol_ComboBg` in favor of combo boxes using `ImGuiCol_PopupBg` for consistency. Combo are normal popups. @@ -231,7 +232,8 @@ Other Changes: - Style: Added StyleColorsDark() style. (#707) [@dougbinks] - Style: Added StyleColorsLight() style. Best used with frame borders + thicker font than the default font. (#707) - Style: Added style.PopupRounding setting. (#1112) -- Style: Added style.FrameBorderSize, style.WindowBorderSize. Removed ImGuiWindowFlags_ShowBorders window flag! Borders are now fully set up in the ImGuiStyle structure. Use ImGui::ShowStyleEditor() to look them up. (#707, fix #819, #1031) +- Style: Added style.FrameBorderSize, style.WindowBorderSize, style.PopupBorderSize. Removed ImGuiWindowFlags_ShowBorders window flag! + Borders are now fully set up in the ImGuiStyle structure. Use ImGui::ShowStyleEditor() to look them up. (#707, fix #819, #1031) - Style: Various small changes to the classic style (most noticeably, buttons are now using blue shades). (#707) - Style: Renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - Style: Renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. @@ -261,6 +263,7 @@ Other Changes: - Window: Using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. (#1380, #1502) - Window: Active Modal window always set the WantCaptureKeyboard flag. (#744) - Window: Moving window doesn't use accumulating MouseDelta so straying out of imgui boundaries keeps moved imgui window at the same cursor-relative position. +- Window: BeginChild() which an explicit name doesn't include the hash within the internal window name. (#1698) - IsWindowFocused(): Added ImGuiFocusedFlags_ChildWindows flag to include child windows in the focused test. (#1382). - IsWindowFocused(): Added ImGuiFocusedFlags_RootWindow flag to start focused test from the root (top-most) window. Obsolete IsRootWindowFocused(). (#1382) - IsWindowHovered(): Added ImGuiHoveredFlags_ChildWindows flag to include child windows in the hovered test. (#1382). diff --git a/imgui.cpp b/imgui.cpp index acda1fb1..6aeedb58 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6846,6 +6846,8 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) // Test condition (NB: bit 0 is always true) and clear flags for next time if (cond && (window->SetWindowPosAllowFlags & cond) == 0) return; + + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX); @@ -6880,6 +6882,8 @@ static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond con // Test condition (NB: bit 0 is always true) and clear flags for next time if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) return; + + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. window->SetWindowSizeAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); // Set @@ -6971,6 +6975,7 @@ void ImGui::SetWindowFocus(const char* name) void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { ImGuiContext& g = *GImGui; + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. g.NextWindowData.PosVal = pos; g.NextWindowData.PosPivotVal = pivot; g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always; @@ -6979,6 +6984,7 @@ void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pi void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { ImGuiContext& g = *GImGui; + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. g.NextWindowData.SizeVal = size; g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always; } @@ -7002,6 +7008,7 @@ void ImGui::SetNextWindowContentSize(const ImVec2& size) void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { ImGuiContext& g = *GImGui; + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. g.NextWindowData.CollapsedVal = collapsed; g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; } diff --git a/imgui.h b/imgui.h index 1e8b9aff..c4b658d5 100644 --- a/imgui.h +++ b/imgui.h @@ -937,7 +937,7 @@ enum ImGuiMouseCursor_ }; // Condition for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions -// All those functions treat 0 as a shortcut to ImGuiCond_Always. From the point of view of the user use this as an enum (don't combine multiple values into flags). +// Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always. enum ImGuiCond_ { ImGuiCond_Always = 1 << 0, // Set the variable From 5aa3f99b4c76c1212394bd55e2bacaf54594197b Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 4 Apr 2018 17:21:36 +0200 Subject: [PATCH 18/19] Internal: using more consistent comparaison with HiddenFrames to not imply it could be -1. Tweaked comments. --- imgui.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6aeedb58..710e85ed 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3245,7 +3245,7 @@ static void ImGui::NavUpdate() g.NavScoringCount = 0; #if IMGUI_DEBUG_NAV_RECTS if (g.NavWindow) { for (int layer = 0; layer < 2; layer++) g.OverlayDrawList.AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG] - if (g.NavWindow) { ImU32 col = (g.NavWindow->HiddenFrames <= 0) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredMousePos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); g.OverlayDrawList.AddCircleFilled(p, 3.0f, col); g.OverlayDrawList.AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } + if (g.NavWindow) { ImU32 col = (g.NavWindow->HiddenFrames == 0) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredMousePos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); g.OverlayDrawList.AddCircleFilled(p, 3.0f, col); g.OverlayDrawList.AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } #endif } @@ -3902,7 +3902,7 @@ static void AddWindowToDrawData(ImVector* out_render_list, ImGuiWin for (int i = 0; i < window->DC.ChildWindows.Size; i++) { ImGuiWindow* child = window->DC.ChildWindows[i]; - if (child->Active && child->HiddenFrames <= 0) // clipped children may have been marked not active + if (child->Active && child->HiddenFrames == 0) // clipped children may have been marked not active AddWindowToDrawData(out_render_list, child); } } @@ -4070,10 +4070,10 @@ void ImGui::Render() for (int n = 0; n != g.Windows.Size; n++) { ImGuiWindow* window = g.Windows[n]; - if (window->Active && window->HiddenFrames <= 0 && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != window_to_render_front_most) + if (window->Active && window->HiddenFrames == 0 && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != window_to_render_front_most) AddWindowToDrawDataSelectLayer(window); } - if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames <= 0) // NavWindowingTarget is always temporarily displayed as the front-most window + if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames == 0) // NavWindowingTarget is always temporarily displayed as the front-most window AddWindowToDrawDataSelectLayer(window_to_render_front_most); g.DrawDataBuilder.FlattenIntoSingleLayer(); @@ -4773,7 +4773,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_ if (ImGuiWindow* window = FindWindowByName(window_name)) if (window->Active) { - // Hide previous tooltips. We can't easily "reset" the content of a window so we create a new one. + // Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one. window->HiddenFrames = 1; ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount); } @@ -5619,7 +5619,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update the Appearing flag bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on - const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); + const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames > 0); if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; @@ -5775,7 +5775,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); ImVec2 size_full_modified(FLT_MAX, FLT_MAX); - if (flags & ImGuiWindowFlags_AlwaysAutoResize && !window->Collapsed) + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed) { // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. if (!window_size_x_set_by_api) @@ -5785,7 +5785,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { - // Auto-fit only grows during the first few frames + // Auto-fit may only grow window during the first few frames // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) window->SizeFull.x = size_full_modified.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; From fc30462f18fa03b9004324567118b76e0e930209 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 4 Apr 2018 19:35:08 +0200 Subject: [PATCH 19/19] Hide new windows for one frame until they calculate their size. Also fixes SetNextWindowPos() given a non-zero pivot. (#1694) --- CHANGELOG.txt | 1 + imgui.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index b9647414..b359fb7b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -257,6 +257,7 @@ Other Changes: - Window: Fixed a one frame glitch. When an appearing window claimed the focus themselves, the title bar wouldn't use the focused color for one frame. - Window: Added ImGuiWindowFlags_ResizeFromAnySide flag to resize from any borders or from the lower-left corner of a window. This requires your backend to honor GetMouseCursor() requests for full usability. (#822) - Window: Sizing fixes when useing SetNextWindowSize() on individual axises. +- Window: Hide new window for one frame until they calculate their size. Also fixes SetNextWindowPos() given a non-zero pivot. (#1694) - Window: Made mouse wheel scrolling accomodate better to windows that are smaller than the scroll step. - Window: SetNextWindowContentSize() adjust for the size of decorations (title bar/menu bar), but _not_ for borders are we consistently make borders not affect layout. If you need a non-child window of an exact size with border enabled but zero window padding, you'll need to accodomate for the border size yourself. diff --git a/imgui.cpp b/imgui.cpp index 710e85ed..dc1ff923 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5597,7 +5597,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Find or create ImGuiWindow* window = FindWindowByName(name); - if (!window) + const bool window_just_created = (window == NULL); + if (window_just_created) { ImVec2 size_on_first_use = (g.NextWindowData.SizeCond != 0) ? g.NextWindowData.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. window = CreateNewWindow(name, size_on_first_use, flags); @@ -5759,7 +5760,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) if (window->HiddenFrames > 0) window->HiddenFrames--; - if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_just_activated_by_user) + if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0) { window->HiddenFrames = 1; if (flags & ImGuiWindowFlags_AlwaysAutoResize) @@ -5772,6 +5773,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } } + // Hide new windows for one frame until they calculate their size + if (window_just_created && (!window_size_x_set_by_api || !window_size_y_set_by_api)) + window->HiddenFrames = 1; + // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); ImVec2 size_full_modified(FLT_MAX, FLT_MAX);