diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5e95a508..a4181a09 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,19 +36,36 @@ HOW TO UPDATE? - Please report any issue! ----------------------------------------------------------------------- - VERSION 1.90.8 WIP (In Progress) + VERSION 1.90.8 (Released 2024-06-06) ----------------------------------------------------------------------- +Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.8 + Breaking changes: +- Reordered various ImGuiInputTextFlags values. This should NOT be breaking unless + you are using generated headers that have values not matching the main library. +- Removed ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft + from imgui.h, was mostly unused and misleading. + Other changes: +- Inputs: fixed IsMouseClicked(..., repeat=true); broken in 1.90.7 on 2024/05/22. + (due to an internal api parameter swap, repeat wouldn't be honored and + ownership would be accidentally checked even though this api is meant to not + check ownership). (#7657) [@korenkonder] - Windows: fixed altering FramePadding mid-frame not correctly affecting logic responsible for honoring io.ConfigWindowsMoveFromTitleBarOnly. (#7576, #899) - Scrollbar: made scrolling logic more standard: clicking above or below the grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150) - Scrollbar: fixed miscalculation of vertical scrollbar visibility when required solely by the presence of an horizontal scrollbar. (#1574) +- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_ParseEmptyRefVal + to parse an empty field as zero-value. (#7305) [@supermerill, @ocornut] +- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_DisplayEmptyRefVal + to display a zero-value as empty. (#7305) [@supermerill, @ocornut] +- Popups: fixed an issue preventing to close a popup opened over a modal by clicking + over void (it required clicking over the visible part of the modal). (#7654) - Tables: fixed an issue where ideal size reported to parent container wouldn't correctly take account of inner scrollbar, affecting potential auto-resize of parent container. (#7651) diff --git a/examples/example_sdl3_sdlrenderer3/main.cpp b/examples/example_sdl3_sdlrenderer3/main.cpp index 890c2696..22cbab4d 100644 --- a/examples/example_sdl3_sdlrenderer3/main.cpp +++ b/examples/example_sdl3_sdlrenderer3/main.cpp @@ -161,7 +161,7 @@ int main(int, char**) // Rendering ImGui::Render(); //SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); - SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255)); + SDL_SetRenderDrawColorFloat(renderer, clear_color.x, clear_color.y, clear_color.z, clear_color.w); SDL_RenderClear(renderer); ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), renderer); SDL_RenderPresent(renderer); diff --git a/imgui.cpp b/imgui.cpp index d82c035e..65b7b246 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (main code and documentation) // Help: @@ -438,6 +438,8 @@ CODE - likewise io.MousePos and GetMousePos() will use OS coordinates. If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos. + - 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. + - 2024/06/06 (1.90.8) - removed 'ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft', was mostly unused and misleading. - 2024/05/27 (1.90.7) - commented out obsolete symbols marked obsolete in 1.88 (May 2022): - old: CaptureKeyboardFromApp(bool) - new: SetNextFrameWantCaptureKeyboard(bool) @@ -7936,9 +7938,13 @@ void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags) if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case. if (ImGuiWindow* blocking_modal = FindBlockingModal(window)) { + // This block would typically be reached in two situations: + // - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag. + // - User clicking on void or anything behind a modal while a modal is open (window == NULL) IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "", blocking_modal->Name); if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) - BringWindowToDisplayBehind(window, blocking_modal); // Still bring to right below modal. + BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?) + ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals return; } @@ -9527,7 +9533,7 @@ bool ImGui::IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id) bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat) { - return IsMouseClicked(button, ImGuiKeyOwner_Any, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None); + return IsMouseClicked(button, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None, ImGuiKeyOwner_Any); } bool ImGui::IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id) @@ -10362,7 +10368,7 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags) // This is the only public API until we expose owner_id versions of the API as replacements. bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord) { - return IsKeyChordPressed(key_chord, 0, ImGuiInputFlags_None); + return IsKeyChordPressed(key_chord, ImGuiInputFlags_None, ImGuiKeyOwner_Any); } // This is equivalent to comparing KeyMods + doing a IsKeyPressed() diff --git a/imgui.h b/imgui.h index 5d6f28d1..c04fe7d3 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (headers) // Help: @@ -27,8 +27,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.90.8 WIP" -#define IMGUI_VERSION_NUM 19074 +#define IMGUI_VERSION "1.90.8" +#define IMGUI_VERSION_NUM 19080 #define IMGUI_HAS_TABLE #define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch @@ -1125,28 +1125,37 @@ enum ImGuiChildFlags_ // (Those are per-item flags. There are shared flags in ImGuiIO: io.ConfigInputTextCursorBlink and io.ConfigInputTextEnterKeepActive) enum ImGuiInputTextFlags_ { + // Basic filters (also see ImGuiInputTextFlags_CallbackCharFilter) ImGuiInputTextFlags_None = 0, ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef - ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z - ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs - ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus - ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. - ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Callback on pressing TAB (for completion handling) - ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Callback on pressing Up/Down arrows (for history handling) - ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Callback on each iteration. User code may query cursor position, modify text buffer. - ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. - ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field - ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). - ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally - ImGuiInputTextFlags_AlwaysOverwrite = 1 << 13, // Overwrite mode - ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode - ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' + ImGuiInputTextFlags_CharsScientific = 1 << 2, // Allow 0123456789.+-*/eE (Scientific notation input) + ImGuiInputTextFlags_CharsUppercase = 1 << 3, // Turn a..z into A..Z + ImGuiInputTextFlags_CharsNoBlank = 1 << 4, // Filter out spaces, tabs + + // Inputs + ImGuiInputTextFlags_AllowTabInput = 1 << 5, // Pressing TAB input a '\t' character into the text field + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 6, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. + ImGuiInputTextFlags_EscapeClearsAll = 1 << 7, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 8, // In multi-line mode, validate with Enter, add new line with Ctrl+Enter (default is opposite: validate with Ctrl+Enter, add line with Enter). + + // Other options + ImGuiInputTextFlags_ReadOnly = 1 << 9, // Read-only mode + ImGuiInputTextFlags_Password = 1 << 10, // Password mode, display all characters as '*', disable copy + ImGuiInputTextFlags_AlwaysOverwrite = 1 << 11, // Overwrite mode + ImGuiInputTextFlags_AutoSelectAll = 1 << 12, // Select entire text when first taking mouse focus + ImGuiInputTextFlags_ParseEmptyRefVal = 1 << 13, // InputFloat(), InputInt(), InputScalar() etc. only: parse empty string as zero value. + ImGuiInputTextFlags_DisplayEmptyRefVal = 1 << 14, // InputFloat(), InputInt(), InputScalar() etc. only: when value is zero, do not display it. Generally used with ImGuiInputTextFlags_ParseEmptyRefVal. + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 15, // Disable following the cursor horizontally 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) - ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) - ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) - ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) + + // Callback features + ImGuiInputTextFlags_CallbackCompletion = 1 << 17, // Callback on pressing TAB (for completion handling) + ImGuiInputTextFlags_CallbackHistory = 1 << 18, // Callback on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 19, // Callback on each iteration. User code may query cursor position, modify text buffer. + ImGuiInputTextFlags_CallbackCharFilter = 1 << 20, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. + ImGuiInputTextFlags_CallbackResize = 1 << 21, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) + ImGuiInputTextFlags_CallbackEdit = 1 << 22, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) // Obsolete names //ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior @@ -1166,7 +1175,7 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow. IMPORTANT: node can still be marked open/close if you don't set the _Leaf flag! - ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). + ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding() before the node. ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line without using AllowOverlap mode. ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (cover the indent area). ImGuiTreeNodeFlags_SpanTextWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text. @@ -1729,10 +1738,8 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default) ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button - - // [Internal] - ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, - ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, + ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, // [Internal] + //ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, }; // Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() @@ -3521,7 +3528,7 @@ namespace ImGui static inline void PopAllowKeyboardFocus() { PopTabStop(); } // OBSOLETED in 1.89 (from August 2022) IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // Use new ImageButton() signature (explicit item id, regular FramePadding) - // OBSOLETED in 1.87 (from February 2022) + // OBSOLETED in 1.87 (from February 2022 but more formally obsoleted April 2024) IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // Map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]. When using a 1.87+ backend using io.AddKeyEvent(), calling GetKeyIndex() with ANY ImGuiKey_XXXX values will return the same value! //static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); return key; } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 346b88b7..8d761031 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (demo code) // Help: @@ -2334,20 +2334,24 @@ static void ShowDemoWindowWidgets() IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs"); static bool inputs_step = true; + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_None; ImGui::SeparatorText("Inputs"); ImGui::Checkbox("Show step buttons", &inputs_step); - ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d"); - ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u"); - ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d"); - ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u"); - ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); - ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X"); - ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); - ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X"); - ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL); - ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL); - ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL); - ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ParseEmptyRefVal", &flags, ImGuiInputTextFlags_ParseEmptyRefVal); + ImGui::CheckboxFlags("ImGuiInputTextFlags_DisplayEmptyRefVal", &flags, ImGuiInputTextFlags_DisplayEmptyRefVal); + ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X", flags); + ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", flags); + ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL, NULL, NULL, flags); ImGui::TreePop(); } @@ -3951,7 +3955,7 @@ static void ShowDemoWindowPopups() static int item = 1; static float color[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - ImGui::ColorEdit4("color", color); + ImGui::ColorEdit4("Color", color); if (ImGui::Button("Add another modal..")) ImGui::OpenPopup("Stacked 2"); @@ -3963,6 +3967,7 @@ static void ShowDemoWindowPopups() if (ImGui::BeginPopupModal("Stacked 2", &unused_open)) { ImGui::Text("Hello from Stacked The Second!"); + ImGui::ColorEdit4("Color", color); // Allow opening another nested popup if (ImGui::Button("Close")) ImGui::CloseCurrentPopup(); ImGui::EndPopup(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 3d6cf3ee..be237e37 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index 6b8bff33..2b660b10 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. @@ -14,8 +14,8 @@ Index of this file: // [SECTION] Macros // [SECTION] Generic helpers // [SECTION] ImDrawList support -// [SECTION] Widgets support: flags, enums, data structures // [SECTION] Data types support +// [SECTION] Widgets support: flags, enums, data structures // [SECTION] Popup support // [SECTION] Inputs support // [SECTION] Clipper support @@ -810,6 +810,40 @@ struct ImDrawDataBuilder ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); } }; +//----------------------------------------------------------------------------- +// [SECTION] Data types support +//----------------------------------------------------------------------------- + +struct ImGuiDataVarInfo +{ + ImGuiDataType Type; + ImU32 Count; // 1+ + ImU32 Offset; // Offset in parent structure + void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); } +}; + +struct ImGuiDataTypeStorage +{ + ImU8 Data[8]; // Opaque storage to fit any data up to ImGuiDataType_COUNT +}; + +// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo(). +struct ImGuiDataTypeInfo +{ + size_t Size; // Size in bytes + const char* Name; // Short descriptive name for the type, for debugging + const char* PrintFmt; // Default printf format for the type + const char* ScanFmt; // Default scanf format for the type +}; + +// Extend ImGuiDataType_ +enum ImGuiDataTypePrivate_ +{ + ImGuiDataType_String = ImGuiDataType_COUNT + 1, + ImGuiDataType_Pointer, + ImGuiDataType_ID, +}; + //----------------------------------------------------------------------------- // [SECTION] Widgets support: flags, enums, data structures //----------------------------------------------------------------------------- @@ -1197,6 +1231,7 @@ enum ImGuiNextItemDataFlags_ ImGuiNextItemDataFlags_HasWidth = 1 << 0, ImGuiNextItemDataFlags_HasOpen = 1 << 1, ImGuiNextItemDataFlags_HasShortcut = 1 << 2, + ImGuiNextItemDataFlags_HasRefVal = 1 << 3, }; struct ImGuiNextItemData @@ -1209,7 +1244,8 @@ struct ImGuiNextItemData ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut() ImGuiInputFlags ShortcutFlags; // Set by SetNextItemShortcut() bool OpenVal; // Set by SetNextItemOpen() - ImGuiCond OpenCond : 8; + ImU8 OpenCond; // Set by SetNextItemOpen() + ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; } inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! @@ -1283,40 +1319,6 @@ struct ImGuiPtrOrIndex ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; } }; -//----------------------------------------------------------------------------- -// [SECTION] Data types support -//----------------------------------------------------------------------------- - -struct ImGuiDataVarInfo -{ - ImGuiDataType Type; - ImU32 Count; // 1+ - ImU32 Offset; // Offset in parent structure - void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); } -}; - -struct ImGuiDataTypeTempStorage -{ - ImU8 Data[8]; // Can fit any data up to ImGuiDataType_COUNT -}; - -// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo(). -struct ImGuiDataTypeInfo -{ - size_t Size; // Size in bytes - const char* Name; // Short descriptive name for the type, for debugging - const char* PrintFmt; // Default printf format for the type - const char* ScanFmt; // Default scanf format for the type -}; - -// Extend ImGuiDataType_ -enum ImGuiDataTypePrivate_ -{ - ImGuiDataType_String = ImGuiDataType_COUNT + 1, - ImGuiDataType_Pointer, - ImGuiDataType_ID, -}; - //----------------------------------------------------------------------------- // [SECTION] Popup support //----------------------------------------------------------------------------- @@ -2357,6 +2359,7 @@ struct ImGuiContext ImGuiInputTextDeactivatedState InputTextDeactivatedState; ImFont InputTextPasswordFont; ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiDataTypeStorage DataTypeZeroValue; // 0 for all data types int BeginMenuDepth; int BeginComboDepth; ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets @@ -2593,6 +2596,7 @@ struct ImGuiContext MouseStationaryTimer = 0.0f; TempInputId = 0; + memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue)); BeginMenuDepth = BeginComboDepth = 0; ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_; ColorEditCurrentID = ColorEditSavedID = 0; @@ -3768,7 +3772,7 @@ namespace ImGui IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type); IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format); IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2); - IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format); + IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty = NULL); IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2); IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max); @@ -3779,6 +3783,7 @@ namespace ImGui IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL); inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); } inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active + IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data); // Color IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 34ab36e6..24263bd8 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 3c86ffda..aeb7b885 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.8 WIP +// dear imgui, v1.90.8 // (widgets code) /* @@ -488,7 +488,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool // Default only reacts to left mouse button if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0) - flags |= ImGuiButtonFlags_MouseButtonDefault_; + flags |= ImGuiButtonFlags_MouseButtonLeft; // Default behavior requires click + release inside bounding box if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0) @@ -2147,17 +2147,24 @@ void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const // 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 and replace this dumb mess.. -bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format) +bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty) { + // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. + const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); + ImGuiDataTypeStorage data_backup; + memcpy(&data_backup, p_data, type_info->Size); + while (ImCharIsBlankA(*buf)) buf++; if (!buf[0]) + { + if (p_data_when_empty != NULL) + { + memcpy(p_data, p_data_when_empty, type_info->Size); + return memcmp(&data_backup, p_data, type_info->Size) != 0; + } return false; - - // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. - const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); - ImGuiDataTypeTempStorage data_backup; - memcpy(&data_backup, p_data, type_info->Size); + } // Sanitize format // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf @@ -3477,11 +3484,11 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG { // Backup old value size_t data_type_size = type_info->Size; - ImGuiDataTypeTempStorage data_backup; + ImGuiDataTypeStorage data_backup; memcpy(&data_backup, p_data, data_type_size); // Apply new value (or operations) then clamp - DataTypeApplyFromText(data_buf, data_type, p_data, format); + DataTypeApplyFromText(data_buf, data_type, p_data, format, NULL); if (p_clamp_min || p_clamp_max) { if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0) @@ -3497,6 +3504,13 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG return value_changed; } +void ImGui::SetNextItemRefVal(ImGuiDataType data_type, void* p_data) +{ + ImGuiContext& g = *GImGui; + g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasRefVal; + memcpy(&g.NextItemData.RefVal, p_data, DataTypeGetInfo(data_type)->Size); +} + // Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional. // Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) @@ -3511,8 +3525,13 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data if (format == NULL) format = DataTypeGetInfo(data_type)->PrintFmt; + void* p_data_default = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasRefVal) ? &g.NextItemData.RefVal : &g.DataTypeZeroValue; + char buf[64]; - DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); + if ((flags & ImGuiInputTextFlags_DisplayEmptyRefVal) && DataTypeCompare(data_type, p_data, p_data_default) == 0) + buf[0] = 0; + else + DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); flags |= ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string. flags |= (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint; @@ -3521,7 +3540,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data if (p_step == NULL) { if (InputText(label, buf, IM_ARRAYSIZE(buf), flags)) - value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL); } else { @@ -3531,7 +3550,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data PushID(label); SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2)); if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view - value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL); IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable); // Step buttons @@ -6504,7 +6523,7 @@ void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond) return; g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasOpen; g.NextItemData.OpenVal = is_open; - g.NextItemData.OpenCond = cond ? cond : ImGuiCond_Always; + g.NextItemData.OpenCond = (ImU8)(cond ? cond : ImGuiCond_Always); } // CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag).