diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 7f4cac80..d106aab3 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -49,17 +49,31 @@ Other Changes:
- Settings: Fixed saving an empty .ini file if CreateContext/DestroyContext are called without a single call to NewFrame(). (#1741)
- Window: Fixed default proportional item width lagging by one frame on resize.
-- Window: Fixed popups/tooltips/menus not honoring style.DisplaySafeAreaPadding as well as it should have (part of menus displayed outside the safe area, etc.).
+- Window: Fixed pop-ups/tooltips/menus not honoring style.DisplaySafeAreaPadding as well as it should have (part of menus displayed outside the safe area, etc.).
- Window: Fixed windows using the ImGuiWindowFlags_NoSavedSettings flag from not using the same default position as other windows. (#1760)
- Window: Relaxed the internal stack size checker to allow Push/Begin/Pop/.../End patterns to be used with PushStyleColor, PushStyleVar, PushFont without causing a false positive assert. (#1767)
- Columns: Fixed a bug introduced in 1.51 where columns would affect the contents size of their container, often creating feedback loops when ImGuiWindowFlags_AlwaysAutoResize was used. (#1760)
+- Settings: Added LoadIniSettingsFromDisk(), LoadIniSettingsFromMemory(), SaveIniSettingsToDisk(), SaveIniSettingsToMemory() to manually load/save .ini settings. (#923, #993)
+- Settings: Added io.WantSaveIniSettings flag, which is set to notify the application that e.g. SaveIniSettingsToMemory() should be called. (#923, #993)
- MenuBar: Made BeginMainMenuBar() honor style.DisplaySafeAreaPadding so the text can be made visible on TV settings that don't display all pixels. (#1439) [@dougbinks]
-- InputText: On Mac OS X, filter out characters when the Cmd modifier is held. (#1747) [@sivu]
-- InputText: On Mac OS X, support Cmd+Shift+Z for Redo. Cmd+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise]
+- InputText: On Mac OS X, filter out characters when the CMD modifier is held. (#1747) [@sivu]
+- InputText: On Mac OS X, support CMD+SHIFT+Z for Redo. CMD+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise]
+- InputText: Fixed returning true when edition is canceled with ESC and the current buffer matches the initial value.
+- InputFloat,InputFloat2,InputFloat3,InputFloat4: Added variations taking a more flexible and consistent optional "const char* format" parameter instead of "int decimal_precision".
+ This allow using custom formats to display values in scientific notation, and is generally more consistent with other API. Obsoleted functions using the optional "int decimal_precision" parameter. (#648)
+- DragFloat, DragInt: Cancel mouse tweak when current value is initially past the min/max boundaries and mouse is pushing in the same direction (keyboard/gamepad version already did this).
+- DragFloat, SliderFloat: Fixes to allow input of scientific notation numbers when using CTRL+Click to input the value. (~#648, #1011)
+- DragFloat, SliderFloat: Rounding-on-write uses the provided format string instead of parsing the precision from the string, which allows for finer uses of %e %g etc. (#648, #642)
+- Nav: Fixed hovering a Selectable() with the mouse so that it update the navigation cursor (as it happened in the pre-1.60 navigation branch). (#787)
- Style: Changed default style.DisplaySafeAreaPadding values from (4,4) to (3,3) so it is smaller than FramePadding and has no effect on main menu bar on a computer. (#1439)
+- Fonts: When building font atlas, glyphs that are missing in the fonts are not using the glyph slot to render a dummy/default glyph. Saves space and allow merging fonts with
+ overlapping font ranges such as FontAwesome5 which split out the Brands separately from the Solid fonts. (#1703, #1671)
+- Misc: Added IMGUI_CHECKVERSION() macro to compare version string and data structure sizes in order to catch issues with mismatching compilation unit settings. (#1695, #1769)
- Demo: Fixed Overlay: Added a context menu item to enable freely moving the window.
+- Examples: Calling IMGUI_CHECKVERSION() in the main.cpp of every example application.
- Examples: Allegro 5: Added support for 32-bit indices setup via defining ImDrawIdx, to avoid an unnecessary conversion (Allegro 5 doesn't support 16-bit indices).
- Examples: Allegro 5: Renamed bindings from imgui_impl_a5.cpp to imgui_impl_allegro5.cpp.
+- Examples: DirectX 9 : Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud. (#1790, #1687) [@sr-tream]
- Various minor fixes, tweaks, refactoring, comments.
-----------------------------------------------------------------------
@@ -69,7 +83,7 @@ Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.60
The gamepad/keyboard navigation branch (which has been in the work since July 2016) has been merged.
Gamepad/keyboard navigation is still marked as Beta and has to be enabled explicitly.
-Various internal refactors have also been done, as part of the navigation work and as part of the upcoming viewport/docking work.
+Various internal refactoring have also been done, as part of the navigation work and as part of the upcoming viewport/docking work.
VIEWPORT BRANCH
(IN PROGRESS, WILL MERGE INTO THE MAIN LISTS WHEN WE MERGE THE BRANCH)
@@ -105,10 +119,10 @@ VIEWPORT BRANCH
Breaking Changes:
- Obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render().
- e.g. with example back-ends, call ImDrawData* draw_data = ImGui::GetDrawData(); ImGui_ImplXXXX_RenderDrawData(draw_data).
+ e.g. with example backends, call ImDrawData* draw_data = ImGui::GetDrawData(); ImGui_ImplXXXX_RenderDrawData(draw_data).
- Reorganized context handling to be more explicit: (#1599)
- YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END.
- - removed Shutdown() function, as DestroyContext() serve this purpose. If you are using an old back-end from the examples/ folder, remove the line that calls Shutdown().
+ - removed Shutdown() function, as DestroyContext() serve this purpose. If you are using an old backend from the examples/ folder, remove the line that calls Shutdown().
- you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwise CreateContext() will create its own font atlas instance.
- removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts.
- removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts.
@@ -150,23 +164,23 @@ Other Changes:
- Context: Added SetAllocatorFunctions() to rewire memory allocators (as a replacement to previous parameters to CreateContext()). Allocators are shared by all contexts and imgui helpers. (#1565, #586, #992, #1007, #1558)
- Context: You may pass a ImFontAtlas to CreateContext() to specify a font atlas to share. Shared font atlas are not owned by the context and not destroyed along with it. (#1599)
- Context: Added IMGUI_DISABLE_DEFAULT_ALLOCATORS to disable linking with malloc/free. (#1565, #586, #992, #1007, #1558)
-- IO: Added io.ConfigFlags for user application to store settings for imgui and for the back-end:
+- IO: Added io.ConfigFlags for user application to store settings for imgui and for the backend:
- ImGuiConfigFlags_NavEnableKeyboard: Enable keyboard navigation.
- - ImGuiConfigFlags_NavEnableGamepad: Enable gamepad navigation (provided ImGuiBackendFlags_HasGamepad is also set by back-end).
+ - ImGuiConfigFlags_NavEnableGamepad: Enable gamepad navigation (provided ImGuiBackendFlags_HasGamepad is also set by backend).
- ImGuiConfigFlags_NavEnableSetMousePos: Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward.
- - ImGuiConfigFlags_NoMouseCursorChange: Instruct back-end to not alter mouse cursor shape and visibility (by default the example back-end use mouse cursor API of the platform when available)
- - ImGuiConfigFlags_NoMouse: Instruct imgui to clear mouse position/buttons in NewFrame(). This allows ignoring the mouse information passed by the back-end.
+ - ImGuiConfigFlags_NoMouseCursorChange: Instruct backend to not alter mouse cursor shape and visibility (by default the example backend use mouse cursor API of the platform when available)
+ - ImGuiConfigFlags_NoMouse: Instruct imgui to clear mouse position/buttons in NewFrame(). This allows ignoring the mouse information passed by the backend.
- ImGuiConfigFlags_IsSRGB, ImGuiConfigFlags_IsTouchScreen: Flags for general application use.
-- IO: Added io.BackendFlags for back-end to store its capabilities (currently: _HasGamepad, _HasMouseCursors, _HasSetMousePos). This will be used more in the next version.
+- IO: Added io.BackendFlags for backend to store its capabilities (currently: _HasGamepad, _HasMouseCursors, _HasSetMousePos). This will be used more in the next version.
- IO: Added ImGuiKey_Insert, ImGuiKey_Space keys. Setup in all example bindings. (#1541)
- IO: Added Horizontal Mouse Wheel support for horizontal scrolling. (#1463) [@tseeker]
- IO: Added IsAnyMouseDown() helper which is helpful for bindings to handle mouse capturing.
- Window: Clicking on a window with the ImGuiWIndowFlags_NoMove flags takes an ActiveId so we can't hover something else when dragging afterwards. (#1381, #1337)
- Window: IsWindowHovered(): Added ImGuiHoveredFlags_AnyWindow, ImGuiFocusedFlags_AnyWindow flags (See Breaking Changes). Added to demo. (#1382)
-- Window: Added SetNextWindowBgAlpha() helper. Particularly helpul since the legacy 5-parameters version of Begin() has been marked as obsolete in 1.53. (#1567)
+- Window: Added SetNextWindowBgAlpha() helper. Particularly helpful since the legacy 5-parameters version of Begin() has been marked as obsolete in 1.53. (#1567)
- Window: Fixed SetNextWindowContentSize() with 0.0f on Y axis (or SetNextWindowContentWidth()) overwriting the contents size. Got broken on Dec 10 (1.53). (#1363)
- 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: 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: Default style is now StyleColorsDark(), instead of the old StyleColorsClassic(). (#707)
@@ -174,7 +188,7 @@ Other Changes:
- 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).
- Style: Close button nows display a cross before hovering. Fixed cross positioning being a little off. Uses button colors for highlight when hovering. (#707)
-- Popup: OpenPopup() Always reopen existing popup. (Removed imgui_internal.h's OpenPopupEx() which was used for this.) (#1497, #1533).
+- Popup: OpenPopup() Always reopen existing pop-ups. (Removed imgui_internal.h's OpenPopupEx() which was used for this.) (#1497, #1533).
- Popup: BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid(), OpenPopupOnItemClick() all react on mouse release instead of mouse press. (~#439)
- Popup: Better handling of user mistakenly calling OpenPopup() every frame (with reopen_existing option). The error will now be more visible and easier to understand. (#1497)
- Popup: BeginPopup(): Exposed extra_flags parameter that are passed through to Begin(). (#1533)
@@ -208,7 +222,7 @@ Other Changes:
- ImFontAtlas: Moved mouse cursor data out of ImGuiContext, fix drawing them with multiple contexts. Also remove the last remaining undesirable dependency on ImGui in imgui_draw.cpp. (#939)
- ImFontAtlas: Added ImFontAtlasFlags_NoPowerOfTwoHeight flag to disable padding font height to nearest power of two. (#1613)
- ImFontAtlas: Added ImFontAtlasFlags_NoMouseCursors flag to disable baking software mouse cursors, mostly to save texture memory on very low end hardware. (#1613)
-- ImDrawList: Fixed AddRect() with antialiasing disabled (lower-right corner pixel was often missing, rounding looks a little better.) (#1646)
+- ImDrawList: Fixed AddRect() with anti-aliasing disabled (lower-right corner pixel was often missing, rounding looks a little better.) (#1646)
- ImDrawList: Added CloneOutput() helper to facilitate the cloning of ImDrawData or ImDrawList for multi-threaded rendering.
- Misc: Functions passed to libc qsort are explicitly marked cdecl to support compiling with vectorcall as the default calling convention. (#1230, #1611) [@RandyGaul]
- Misc: ImVec2: added [] operator. This is becoming desirable for some code working of either axes independently. Better adding it sooner than later.
@@ -220,7 +234,7 @@ Other Changes:
- Misc: Added IMGUI_USER_CONFIG to define a custom configuration filename. (#255, #1573, #1144, #41)
- Misc: Added IMGUI_STB_TRUETYPE_FILENAME and IMGUI_STB_RECT_PACK_FILENAME compile time directives to use another version of the stb_ files.
- Misc: Updated stb_rect_pack from 0.10 to 0.11 (minor changes).
- (Those flags are not used by ImGui itself, they only exists to make it easy for the engine/back-end to pass information to the application in a standard manner.)
+ (Those flags are not used by ImGui itself, they only exists to make it easy for the engine/backend to pass information to the application in a standard manner.)
- Metrics: Added display of Columns state.
- Demo: Improved Selectable() examples. (#1528)
- Demo: Tweaked the Child demos, added a menu bar to the second child to test some navigation functions.
@@ -230,7 +244,7 @@ Other Changes:
- Examples: Using Dark theme by default. (#707). Tweaked demo code.
- Examples: Added support for horizontal mouse wheel for API that allows it. (#1463) [@tseeker]
- Examples: All examples now setup the io.BackendFlags to signify they can honor mouse cursors, gamepad, etc.
-- Examples: DirectX10: Fixed erroneous call to io.Fonts->ClearInputData() + ClearTexData() that was left in DX10 example but removed in 1.47 (Nov 2015) in every other back-ends. (#1733)
+- Examples: DirectX10: Fixed erroneous call to io.Fonts->ClearInputData() + ClearTexData() that was left in DX10 example but removed in 1.47 (Nov 2015) in every other backends. (#1733)
- Examples: DirectX12: Added DirectX 12 example. (#301) [@jdm3]
- Examples: OpenGL3+GLFW,SDL: Changed GLSL shader version from 330 to 150. (#1466, #1504)
- Examples: OpenGL3+GLFW,SDL: Added a way to override the GLSL version string in the Init function. (#1466, #1504).
@@ -245,9 +259,9 @@ Other Changes:
- 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.
-- Examples: SDL: Using SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency() to handle framerate over 1000 FPS properly. (#996)
-- Examples: SDL: Using scancode exclusively instead of a confusing mixture of scancodes and keycodes.
+- Examples: SDL: Enabled vsync by default so people don't come at us when the examples are running at 2000 FPS and burning a CPU core.
+- Examples: SDL: Using SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency() to handle frame-rate over 1000 FPS properly. (#996)
+- Examples: SDL: Using scan-code exclusively instead of a confusing mixture of scan-codes and key-codes.
- Examples: SDL: Visual Studio: Added .vcxproj file. Using %SDL2_DIR% in the default .vcxproj and build files instead of %SDL_DIR%, the earlier being more standard.
- Examples: Vulkan: Visual Studio: Added .vcxproj file.
- Examples: Apple: Fixed filenames in OSX xcode project. Various other Mac friendly fixes. [@gerryhernandez etc.]
@@ -275,7 +289,7 @@ Breaking Changes:
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.
+- Style: Removed `ImGuiCol_ComboBg` in favor of combo boxes using `ImGuiCol_PopupBg` for consistency. Combo are normal pop-ups.
- Style: Renamed `ImGuiCol_ChildWindowBg` to `ImGuiCol_ChildBg`.
- Style: Renamed `style.ChildWindowRounding` to `style.ChildRounding`, `ImGuiStyleVar_ChildWindowRounding` to `ImGuiStyleVar_ChildRounding`.
- Removed obsolete redirection functions: SetScrollPosHere() - marked obsolete in v1.42, July 2015.
@@ -306,11 +320,11 @@ Other Changes:
- Style: Made the ScaleAllSizes() helper rounds down every values so they are aligned on integers.
- Focus: Added SetItemDefaultFocus(), which in the current (master) branch behave the same as doing `if (IsWindowAppearing()) SetScrollHere()`.
In the navigation branch this will also set the default focus. Prefer using this when creating combo boxes with `BeginCombo()` so your code will be forward-compatible with gamepad/keyboard navigation features. (#787)
-- Combo: Popup grows horizontally to accomodate for contents that is larger then the parent combo button.
+- Combo: Pop-up grows horizontally to accommodate for contents that is larger then the parent combo button.
- Combo: Added BeginCombo()/EndCombo() API which allows use to submit content of any form and manage your selection state without relying on indices.
-- Combo: Added ImGuiComboFlags_PopupAlignLeft flag to BeginCombo() to prioritize keeping the popup on the left side (for small-button-looking combos).
-- Combo: Added ImGuiComboFlags_HeightSmall, ImGuiComboFlags_HeightLarge, ImGuiComboFlags_HeightLargest to easily provide desired popup height.
-- Combo: You can use SetNextWindowSizeConstraints() before BeginCombo() to specify specific popup width/height constraints.
+- Combo: Added ImGuiComboFlags_PopupAlignLeft flag to BeginCombo() to prioritize keeping the pop-up on the left side (for small-button-looking combos).
+- Combo: Added ImGuiComboFlags_HeightSmall, ImGuiComboFlags_HeightLarge, ImGuiComboFlags_HeightLargest to easily provide desired pop-up height.
+- Combo: You can use SetNextWindowSizeConstraints() before BeginCombo() to specify specific pop-up width/height constraints.
- Combo: Offset popup position by border size so that a double border isn't so visible. (#707)
- Combo: Recycling windows by using a stack number instead of a unique id, wasting less memory (like menus do).
- InputText: Added ImGuiInputTextFlags_NoUndoRedo flag. (#1506, #1508) [@ibachar]
@@ -321,11 +335,11 @@ Other Changes:
- Window: Made it possible to use SetNextWindowPos() on a child window.
- 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: Sizing fixes when using 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: Made mouse wheel scrolling accommodate 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.
+ If you need a non-child window of an exact size with border enabled but zero window padding, you'll need to accommodate for the border size yourself.
- 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.
@@ -338,7 +352,7 @@ Other Changes:
- IsWindowHovered(): Always return true when current window is being moved. (#1382)
- Scrollbar: Fixed issues with vertical scrollbar flickering/appearing, typically when manually resizing and using a pattern of filling available height (e.g. full sized BeginChild).
- Scrollbar: Minor graphical fix for when scrollbar don't have enough visible space to display the full grab.
-- Scrolling: Fixed padding and scrolling asymetry where lower/right sides of a window wouldn't use WindowPadding properly + causing minor scrolling glitches.
+- Scrolling: Fixed padding and scrolling asymmetry where lower/right sides of a window wouldn't use WindowPadding properly + causing minor scrolling glitches.
- Tree: TreePush with zero arguments was ambiguous. Resolved by making it call TreePush(const void*). [@JasonWilkins]
- Tree: Renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. (#600, #1330)
- MenuBar: Fixed minor rendering issues on the right size when resizing a window very small and using rounded window corners.
@@ -349,19 +363,19 @@ Other Changes:
- Columns: Columns width is no longer lost when dragging a column to the right side of the window, until releasing the mouse button you have a chance to save them. (#1499, #125). [@ggtucker]
- Columns: Fixed dragging when using a same of columns multiple times in the frame. (#125)
- Indent(), Unindent(): Allow passing negative values.
-- ColorEdit4(): Made IsItemActive() return true when picker popup is active. (#1489)
+- ColorEdit4(): Made IsItemActive() return true when picker pop-up is active. (#1489)
- ColorEdit4(): Tweaked tooltip so that the color button aligns more correctly with text.
- ColorEdit4(): Support drag and drop. Color buttons can be used as drag sources, and ColorEdit widgets as drag targets. (#143)
-- ColorPicker4(): Fixed continously returning true when holding mouse button on the sat/value/alpha locations. We only return true on value change. (#1489)
+- ColorPicker4(): Fixed continuously returning true when holding mouse button on the sat/value/alpha locations. We only return true on value change. (#1489)
- NewFrame(): using literal strings in the most-frequently firing IM_ASSERT expressions to increase the odd of programmers seeing them (especially those who don't use a debugger).
- NewFrame() now asserts if neither Render or EndFrame have been called. Exposed EndFrame(). Made it legal to call EndFrame() more than one. (#1423)
-- ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from stratch.
+- ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from scratch.
- ImFont: Added GetDebugName() helper.
- ImFontAtlas: Added missing Thai punctuation in the GetGlyphRangesThai() ranges. (#1396) [@nProtect]
- ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags.
- ImDrawList: Added ImDrawList::AddImageRounded() helper. (#845) [@thedmd]
-- ImDrawList: Refactored to make ImDrawList independant of ImGui. Removed static variable in PathArcToFast() which caused linking issues to some.
-- ImDrawList: Exposed ImDrawCornerFlags, replaced occurences of ~0 with an explicit ImDrawCornerFlags_All. NB: Inversed BotLeft (prev 1<<3, now 1<<2) and BotRight (prev 1<<2, now 1<<3).
+- ImDrawList: Refactored to make ImDrawList independent of ImGui. Removed static variable in PathArcToFast() which caused linking issues to some.
+- ImDrawList: Exposed ImDrawCornerFlags, replaced occurrences of ~0 with an explicit ImDrawCornerFlags_All. NB: Inversed BotLeft (prev 1<<3, now 1<<2) and BotRight (prev 1<<2, now 1<<3).
- ImVector: Added ImVector::push_front() helper.
- ImVector: Added ImVector::contains() helper.
- ImVector: insert() uses grow_capacity() instead of using grow policy inconsistent with push_back().
@@ -375,9 +389,9 @@ Other Changes:
- Demo: Added ShowFontSelector() showing loaded fonts.
- Demo: Added ShowStyleSelector() to select among default styles. (#707)
- Demo: Renamed the emblematic ShowTestWindow() function to ShowDemoWindow().
-- Demo: Style Editor: Added a "Simplified settings" sections with checkboxes for border size and frame rounding. (#707, #1019)
+- Demo: Style Editor: Added a "Simplified settings" sections with check-boxes for border size and frame rounding. (#707, #1019)
- Demo: Style Editor: Added combo box to select stock styles and select current font when multiple are loaded. (#707)
-- Demo: Style Editor: Using local storage so Save/Revert button makes more sense without code passing its storage. Aadded horizontal scroll bar. Fixed Save/Revert button to be always accessible. (#1211)
+- Demo: Style Editor: Using local storage so Save/Revert button makes more sense without code passing its storage. Added horizontal scroll bar. Fixed Save/Revert button to be always accessible. (#1211)
- Demo: Console: Fixed context menu issue. (#1404)
- Demo: Console: Fixed incorrect positioning which was hidden by a minor scroll issue (this would affect people who copied the Console code as is).
- Demo: Constrained Resize: Added more test cases. (#1417)
@@ -414,7 +428,7 @@ Other Changes:
- Combo, InputFloat, InputInt: Made the small button on the right side align properly with the equivalent colored button of ColorEdit4().
- IO: Tweaked logic for `io.WantCaptureMouse` so it now outputs false when e.g. hovering over void while an InputText() is active. (#621) [@pdoane]
- IO: Fixed `io.WantTextInput` from mistakenly outputting true when an activated Drag or Slider was previously turned into an InputText(). (#1317)
-- Misc: Added flags to `IsItemHovered()`, `IsWindowHovered()` to access advanced hovering-test behavior. Generally useful for popups and drag'n drop behaviors: (relates to ~#439, #1013, #143, #925)
+- Misc: Added flags to `IsItemHovered()`, `IsWindowHovered()` to access advanced hovering-test behavior. Generally useful for pop-ups and drag and drop behaviors: (relates to ~#439, #1013, #143, #925)
- `ImGuiHoveredFlags_AllowWhenBlockedByPopup`
- `ImGuiHoveredFlags_AllowWhenBlockedByActiveItem`
- `ImGuiHoveredFlags_AllowWhenOverlapped`
@@ -422,10 +436,10 @@ Other Changes:
- Input: Added `IsMousePosValid()` helper.
- Input: Added `GetKeyPressedAmount()` to easily measure press count when the repeat rate is faster than the frame rate.
- Input/Focus: Disabled TAB and Shift+TAB when CTRL key is held.
-- Checkbox: Now rendering a tick mark instead of a full square.
+- CheckBox: Now rendering a tick mark instead of a full square.
- ColorEdit4: Added "Copy as..." option in context menu. (#346)
- ColorPicker: Improved ColorPicker hue wheel color interpolation. (#1313) [@thevaber]
-- ColorButton: Reduced bordering artefact that would be particularly visible with an opaque Col_FrameBg and FrameRounding enabled.
+- ColorButton: Reduced bordering artifact that would be particularly visible with an opaque Col_FrameBg and FrameRounding enabled.
- ColorButton: Fixed rendering color button with a checkerboard if the transparency comes from the global style.Alpha and not from the actual source color.
- TreeNode: Added `ImGuiTreeNodeFlags_FramePadding` flag to conveniently create a tree node with full padding at the beginning of a line, without having to call `AlignTextToFramePadding()`.
- Trees: Fixed calling `SetNextTreeNodeOpen()` on a collapsed window leaking to the first tree node item of the next frame.
@@ -438,7 +452,7 @@ Other Changes:
- Windows: Fixed calling `Begin()` more than once per frame setting `window_just_activated_by_user` which in turn would set enable the Appearing condition for that frame.
- Windows: The implicit "Debug" window now uses a "Debug##Default" identifier instead of "Debug" to allow user creating a window called "Debug" without losing their custom flags.
- Windows: Made the `ImGuiWindowFlags_NoMove` flag properly inherited from parent to child. In a setup with ParentWindow (no flag) -> Child (NoMove) -> SubChild (no flag), the user won't be able to move the parent window by clicking on SubChild. (#1381)
-- Popups: Popups can be closed with a right-click anywhere, without altering focus under the popup. (~#439)
+- Popups: Pop-ups can be closed with a right-click anywhere, without altering focus under the pop-up. (~#439)
- Popups: `BeginPopupContextItem()`, `BeginPopupContextWindow()` are now setup to allow reopening a context menu by right-clicking again. (~#439)
- Popups: `BeginPopupContextItem()` now supports a NULL string identifier and uses the last item ID if available.
- Popups: Added `OpenPopupOnItemClick()` helper which mimic `BeginPopupContextItem()` but doesn't do the BeginPopup().
@@ -481,7 +495,7 @@ Beta Navigation Branch:
- Nav: MainMenuBar now releases focus when user gets out of the menu layer. (#787)
- Nav: When applying focus to a window with only menus, the menu layer is automatically activated. (#787)
- Nav: Added `ImGuiNavInput_KeyMenu` (~Alt key) aside from ImGuiNavInput_PadMenu input as it is one differentiator of pad vs keyboard that was detrimental to the keyboard experience. Although isn't officially supported, it makes the current experience better. (#787)
-- Nav: Move requests now wrap vertically inside Menus and Popups. (#787)
+- Nav: Move requests now wrap vertically inside Menus and Pop-ups. (#787)
- Nav: Allow to collapse tree nodes with NavLeft and open them with NavRight. (#787, #1079).
- Nav: It's now possible to navigate sibling of a menu-bar while navigating inside one of their child. If a Left<>Right navigation request fails to find a match we forward the request to the root menu. (#787, #126)
- Nav: Fixed `SetItemDefaultFocus` from stealing default focus when we are initializing default focus for a menu bar layer. (#787)
@@ -508,7 +522,7 @@ Work on dear imgui has been gradually resuming. It means that fixes and new feat
- Renamed `ImGuiCol_Columns***` enums to `ImGuiCol_Separator***`. Kept redirection enums (will obsolete).
- Renamed `ImGuiSetCond***` types and enums to `ImGuiCond***`. Kept redirection enums (will obsolete).
- Renamed `GetStyleColName()` to `GetStyleColorName()` for consistency. Unlikely to be used by end-user!
-- Added `PushStyleColor(ImGuiCol idx, ImU32 col)` overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix.
+- Added `PushStyleColor(ImGuiCol idx, ImU32 col)` overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicitly to fix.
- Marked the weird `IMGUI_ONCE_UPON_A_FRAME` helper macro as obsolete. Prefer using the more explicit `ImGuiOnceUponAFrame`.
- Changed `ColorEdit4(const char* label, float col[4], bool show_alpha = true)` signature to `ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)`, where flags 0x01 is a safe no-op (hello dodgy backward compatibility!). The new `ColorEdit4`/`ColorPicker4` functions have lots of available flags! Check and run the demo window, under "Color/Picker Widgets", to understand the various new options.
- Changed signature of `ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)` to `ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))`. This function was rarely used and was very dodgy (no explicit ID!).
@@ -539,15 +553,15 @@ Other Changes:
- Columns: Dragging a column preserve its width by default. (#913) [@ggtucker]
- Columns: Fixed first column appearing wider than others. (#1266)
- Columns: Fixed allocating space on the right-most side with the assumption of a vertical scrollbar. The space is only allocated when needed. (#125, #913, #893, #1138)
-- Columns: Fixed the right-most column from registering its content width to the parent window, which led to various issues when using auto-resizing window or e.g. horizonal scrolling. (#519, #125, #913)
+- Columns: Fixed the right-most column from registering its content width to the parent window, which led to various issues when using auto-resizing window or e.g. horizontal scrolling. (#519, #125, #913)
- Columns: Refactored some of the columns code internally toward a better API (not yet exposed) + minor optimizations. (#913) [@ggtucker, @ocornut]
-- Popups: Most popups windows can be moved by the user after appearing (if they don't have explicit positions provided by caller, or e.g. sub-menu popup). The previous restriction was totally arbitrary. (#1252)
+- Popups: Most pop-ups windows can be moved by the user after appearing (if they don't have explicit positions provided by caller, or e.g. sub-menu pop-up). The previous restriction was totally arbitrary. (#1252)
- Tooltip: `SetTooltip()` is expanded immediately into a window, honoring current font / styling setting. Add internal mechanism to override tooltips. (#862)
- PlotHistogram: bars are drawn based on zero-line, so negative values are going under. (#828)
- Scrolling: Fixed return values of `GetScrollMaxX()`, `GetScrollMaxY()` when both scrollbars were enabled. Tweak demo to display more data. (#1271) [@degracode]
- Scrolling: Fixes for Vertical Scrollbar not automatically getting enabled if enabled Horizontal Scrollbar straddle the vertical limit. (#1271, #246)
- Scrolling: `SetScrollHere()`, `SetScrollFromPosY()`: Fixed Y scroll aiming when Horizontal Scrollbar is enabled. (#665).
-- [Windows] Clipboard: Fixed not closing win32 clipboard on early open failure path. (#1264)
+- [Windows] Clipboard: Fixed not closing Win32 clipboard on early open failure path. (#1264)
- Removed an unnecessary dependency on int64_t which failed on some older compilers.
- Demo: Rearranged everything under Widgets in a more consistent way.
- Demo: Columns: Added Horizontal Scrolling demo. Tweaked another Columns demo. (#519, #125, #913)
@@ -576,7 +590,7 @@ Other Changes:
- InputText(): Got rid of individual OSX-specific options in ImGuiIO, added a single io.OSXBehaviors flag. (#473, #650)
- InputText(): Fixed pressing home key on last character when it isn't a trailing \n (#588, #815)
- InputText(): Fixed state corruption/crash bug in stb_textedit.h redo logic when exhausting undo/redo char buffer. (#715. #681)
-- InputTextMultiline(): Fixed Ctrl+DownArrow moving scrolling out of bounds.
+- InputTextMultiline(): Fixed CTRL+DownArrow moving scrolling out of bounds.
- InputTextMultiline(): Scrollbar fix for when input and latched internal buffers differs in a way that affects vertical scrollbar existence. (#725)
- ImFormatString(): Fixed an overflow handling bug with implementation of vsnprintf() that do not return -1. (#793)
- BeginChild(const char*) now applies stack id to provided label, consistent with other widgets. (#894, #713)
@@ -603,7 +617,7 @@ Other Changes:
- Word-wrapping: Fixed a bug where we never wrapped after a 1 character word. [@sronsse]
- Word-wrapping: Fixed TextWrapped() overriding wrap position if one is already set. (#690)
- Word-wrapping: Fixed incorrect testing for negative wrap coordinates, they are perfectly legal. (#706)
-- ImGuiListClipper: fixed automatic-height calc path dumbly having user display element 0 twice. (#661, #716)
+- ImGuiListClipper: Fixed automatic-height calc path dumbly having user display element 0 twice. (#661, #716)
- ImGuiListClipper: Fix to behave within column. (#661, #662, #716)
- ImDrawList: Renamed ImDrawList::PathFill() to ImDrawList::PathFillConvex() for clarity. (BREAKING API)
- Columns: End() avoid calling Columns(1) if no columns set is open, not sure why it wasn't the case already (pros: faster, cons: exercise less code).
@@ -659,7 +673,7 @@ Breaking Changes:
- Renamed `SetNextTreeNodeOpened()` to `SetNextTreeNodeOpen()` for consistency, no redirection.
- Removed confusing set of `GetInternalState()`, `GetInternalStateSize()`, `SetInternalState()` functions. Now using `CreateContext()`, `DestroyContext()`, `GetCurrentContext()`, `SetCurrentContext()`. If you were using multiple contexts the change should be obvious and trivial.
- Obsoleted old signature of `CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false)`, as extra parameters were badly designed and rarely used. Most uses were using 1 parameter and shouldn't affect you. You can replace the "default_open = true" flag in new API with `CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen)`.
-- Changed `ImDrawList::PushClipRect(ImVec4 rect)` to `ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false)`. Note that higher-level `ImGui::PushClipRect()` is preferable because it will clip at logic/widget level, whereas `ImDrawList::PushClipRect()` only affect your renderer.
+- Changed `ImDrawList::PushClipRect(ImVec4 rect)` to `ImDraw::PushClipRect(ImVec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false)`. Note that higher-level `ImGui::PushClipRect()` is preferable because it will clip at logic/widget level, whereas `ImDrawList::PushClipRect()` only affect your renderer.
- Title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore (see #655). If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you. However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar.
This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color. (Or If this is confusing, just pick the RGB value from title bar from an old screenshot and apply this as TitleBg/TitleBgActive. Or you may just create TitleBgActive from a tweaked TitleBg color.)
@@ -677,7 +691,7 @@ Other changes:
- Added PushClipRect()/PopClipRect() (previously part of imgui_internal.h). Changed ImDrawList::PushClipRect() prototype. (#610)
- Added IsRootWindowOrAnyChildHovered() helper. (#615)
- Added TreeNodeEx() functions. (#581, #600, #190)
-- Added ImGuiTreeNodeFlags_Selected flag to display treenode as "selected". (#581, #190)
+- Added ImGuiTreeNodeFlags_Selected flag to display TreeNode as "selected". (#581, #190)
- Added ImGuiTreeNodeFlags_AllowOverlapMode flag. (#600)
- Added ImGuiTreeNodeFlags_NoTreePushOnOpen flag (#590).
- Added ImGuiTreeNodeFlags_NoAutoOpenOnLog flag (previously private).
@@ -694,9 +708,9 @@ Other changes:
- Fixed MenuBar missing lower border when borders are enabled.
- InputText(): Fixed clipping of cursor rendering in case it gets out of the box (which can be forced w/ ImGuiInputTextFlags_NoHorizontalScroll. (#601)
- Style: Changed default IndentSpacing from 22 to 21. (#581, #324)
-- Style: Fixed TitleBg/TitleBgActive color being rendered above WindowBg color, which was inconsistent and causing visual artefact. (#655)
+- Style: Fixed TitleBg/TitleBgActive color being rendered above WindowBg color, which was inconsistent and causing visual artifact. (#655)
This broke the meaning of TitleBg and TitleBgActive. Only affect values where Alpha<1.0f. Fixed default theme. Read comments in "API BREAKING CHANGES" section to convert.
-- Relative rendering of order of Child windows creation is preserved, to allow more control with overlapping childs. (#595)
+- Relative rendering of order of Child windows creation is preserved, to allow more control with overlapping children. (#595)
- Fixed GetWindowContentRegionMax() being off by ScrollbarSize amount when explicit SizeContents is set.
- Indent(), Unindent(): optional non-default indenting width. (#324, #581)
- Bullet(), BulletText(): Slightly bigger. Less polygons.
@@ -705,8 +719,8 @@ Other changes:
- BeginGroup(): fixed using within Columns set. (#630)
- Fixed a lag in reading the currently hovered window when dragging a window. (#635)
- Obsoleted 4 parameters version of CollapsingHeader(). Refactored code into TreeNodeBehavior. (#600, #579)
-- Scrollbar: minor fix for top-right rounding of scrollbar background when window has menubar but no title bar.
-- MenuItem(): checkmark render in disabled color when menu item is disabled.
+- Scrollbar: minor fix for top-right rounding of scrollbar background when window has menu bar but no title bar.
+- MenuItem(): the check mark renders in disabled color when menu item is disabled.
- Fixed clipping rectangle floating point representation to ensure renderer-side float point operations yield correct results in typical DirectX/GL settings. (#582, 597)
- Fixed GetFrontMostModalRootWindow(), fixing missing fade-out when a combo pop was used stacked over a modal window. (#604)
- ImDrawList: Added AddQuad(), AddQuadFilled() helpers.
@@ -715,7 +729,7 @@ Other changes:
- ImFont: Added AddRemapChar() helper. (#609)
- ImFontConfig: Clarified persistence requirement of GlyphRanges array. (#651)
- ImGuiStorage: Added bool helper functions for completeness.
-- AddFontFromMemoryCompressedTTF(): Fix font config propagation. (#587)
+- AddFontFromMemoryCompressedTTF(): Fix ImFontConfig propagation. (#587)
- Renamed majority of use of the word "opened" to "open" for clarity. Renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(). (#625, #579)
- Examples: OpenGL3: Saving/restoring glActiveTexture() state. (#602)
- Examples: DirectX9: save/restore all device state.
@@ -723,7 +737,7 @@ Other changes:
- Examples: DirectX10/X11: Apply depth-stencil state (no use of depth buffer). (#640, #636)
- Examples: DirectX11/X11: Added comments on removing dependency on D3DCompiler. (#638)
- Examples: SDL: Initialize video+timer subsystem only.
-- Examples: Apple/iOS: lowered xcode project deployment target from 10.7 to 10.11. (#598, #575)
+- Examples: Apple/iOS: lowered XCode project deployment target from 10.7 to 10.11. (#598, #575)
-----------------------------------------------------------------------
@@ -733,7 +747,7 @@ Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.48
Breaking Changes:
- Consistently honoring exact width passed to PushItemWidth() (when positive), previously it would add extra FramePadding.x*2 over that width. Some hand-tuned layout may be affected slightly. (#346)
-- Style: removed `style.WindowFillAlphaDefault` which was confusing and redundant, baked alpha into `ImGuiCol_WindowBg` color. If you had a custom WindowBg color but didn't change WindowFillAlphaDefault, multiply WindowBg alpha component by 0.7. Renamed `ImGuiCol_TooltipBg` to `ImGuiCol_PopupBG`, applies to other types of popups. `bg_alpha` parameter of 5-parameters version of Begin() is an override. (#337)
+- Style: removed `style.WindowFillAlphaDefault` which was confusing and redundant, baked alpha into `ImGuiCol_WindowBg` color. If you had a custom WindowBg color but didn't change WindowFillAlphaDefault, multiply WindowBg alpha component by 0.7. Renamed `ImGuiCol_TooltipBg` to `ImGuiCol_PopupBG`, applies to other types of pop-ups. `bg_alpha` parameter of 5-parameters version of Begin() is an override. (#337)
- InputText(): Added BufTextLen field in ImGuiTextEditCallbackData. Requesting user to update it if the buffer is modified in the callback. Added a temporary length-check assert to minimize panic for the 3 people using the callback. (#541)
- Renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). (#340)
@@ -742,7 +756,7 @@ Other Changes:
- Consistently honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. Some hand-tuned layout may be affected slightly. (#346)
- Fixed clipping of child windows within parent not taking account of child outer clipping boundaries (including scrollbar, etc.). (#506)
- TextUnformatted(): Fixed rare crash bug with large blurb of text (2k+) not finished with a '\n' and fully above the clipping Y line. (#535)
-- IO: Added 'KeySuper' field to hold Cmd keyboard modifiers for OS X. Updated all examples accordingly. (#473)
+- IO: Added 'KeySuper' field to hold CMD keyboard modifiers for OS X. Updated all examples accordingly. (#473)
- Added ImGuiWindowFlags_ForceVerticalScrollbar, ImGuiWindowFlags_ForceHorizontalScrollbar flags. (#476)
- Added IM_COL32 macros to generate a U32 packed color, convenient for direct use of ImDrawList api. (#346)
- Added GetFontTexUvWhitePixel() helper, convenient for direct use of ImDrawList api.
@@ -753,11 +767,11 @@ Other Changes:
- Fixed InputTextMultiLine(), ListBox(), BeginChildFrame(), ProgressBar(): outer frame not honoring bordering. (#462, #503)
- Fixed Image(), ImageButtion() rendering a rectangle 1 px too large on each axis. (#457)
- SetItemAllowOverlap(): Promoted from imgui_internal.h to public imgui.h api. (#517)
-- Combo(): Right-most button stays highlighted when popup is open.
-- Combo(): Display popup above if there's isn't enough space below / or select largest side. (#505)
+- Combo(): Right-most button stays highlighted when pop-up is open.
+- Combo(): Display pop-up above if there's isn't enough space below / or select largest side. (#505)
- DragFloat(), SliderFloat(), InputFloat(): fixed cases of erroneously returning true repeatedly after a text input modification (e.g. "0.0" --> "0.000" would keep returning true). (#564)
- DragFloat(): Always apply value when mouse is held/widget active, so that an always-reseting variable (e.g. non saved local) can be passed.
-- InputText(): OS X friendly behaviors: Word movement uses Alt key; Shortcuts uses Cmd key; Double-clicking text select a single word; Jumping to next word sets cursor to end of current word instead of beginning of current word. (@zhiayang), (#473)
+- InputText(): OS X friendly behaviors: Word movement uses ALT key; Shortcuts uses CMD key; Double-clicking text select a single word; Jumping to next word sets cursor to end of current word instead of beginning of current word. (@zhiayang), (#473)
- InputText(): Added BufTextLen in ImGuiTextEditCallbackData. Requesting user to maintain it if buffer is modified. Zero-ing structure properly before use. (#541)
- CheckboxFlags(): Added support for testing/setting multiple flags at the same time. (@DMartinek) (#555)
- TreeNode(), CollapsingHeader() fixed not being able to use "##" sequence in a formatted label.
@@ -776,7 +790,7 @@ Other Changes:
- ImDrawList: Allow AddText(ImFont\* font, float font_size, ...) variant to take NULL/0.0f as default.
- ImFontAtlas: heuristic increase default texture width up for large number of glyphs. (#491)
- ImTextBuffer: Fixed empty() helper which was utterly broken.
-- Metrics: allow to inspect individual triangles in drawcalls.
+- Metrics: allow to inspect individual triangles in draw calls.
- Demo: added more draw primitives in the Custom Rendering example. (#457)
- Demo: extra comments and example for PushItemWidth(-1) patterns.
- Demo: InputText password demo filters out blanks. (#515)
@@ -791,7 +805,7 @@ Other Changes:
- Examples: SDL2+OpenGL3: Fix context creation options. Made ImGui_ImplSdlGL3_NewFrame() signature match GL2 one. (#468, #463)
- Examples: SDL2+OpenGL2/3: Fix for high-dpi displays. (@nickgravelyn)
- Various extra comments and clarification in the code.
-- Various other fixes and optimisations.
+- Various other fixes and optimizations.
-----------------------------------------------------------------------
diff --git a/README.md b/README.md
index ee163691..76ca6dff 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Dear ImGui is a bloat-free graphical user interface library for C++. It outputs
Dear ImGui is designed to enable fast iterations and to empower programmers to create content creation tools and visualization / debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and lacks certain features normally found in more high-level libraries.
-Dear ImGui is particularly suited to integration in games engine (for tooling), realtime 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard.
+Dear ImGui is particularly suited to integration in games engine (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard.
Dear ImGui is self-contained within a few files that you can easily copy and compile into your application/engine:
- imgui.cpp
@@ -98,7 +98,7 @@ Demo Binaries
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20180407.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20180407.zip) (Windows binaries, Dear ImGui 1.60 built 2018/04/07, 5 executables)
-The demo applications are unfortunately not yet DPI aware so expect some blurryness on a 4K screen. For DPI awareness you can load/reload your font at different scale, and scale your Style with `style.ScaleAllSizes()`.
+The demo applications are unfortunately not yet DPI aware so expect some blurriness on a 4K screen. For DPI awareness you can load/reload your font at different scale, and scale your Style with `style.ScaleAllSizes()`.
Bindings
--------
@@ -204,7 +204,7 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This
- [A presentation by Rickard Gustafsson and Johannes Algelind](http://www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%20Computer%20Graphics/IMGUI.pdf).
- [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/).
- [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861).
-- [Nicolas Guillemot's CppCon'16 flashtalk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k).
+- [Nicolas Guillemot's CppCon'16 flash-talk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k).
- [Thierry Excoffier's Zero Memory Widget](http://perso.univ-lyon1.fr/thierry.excoffier/ZMW/).
See the [Links page](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to different languages and frameworks.
@@ -249,9 +249,9 @@ See the FAQ in imgui.cpp for answers.
You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad`).
-You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC using Synergy 1.x. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui).
+You can share your computer mouse seamlessly with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the preferred solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC using Synergy 1.x. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui).
-For touch inputs, you can increase the hit box of widgets (via the _style.TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimising for screen real-estate and precision.
+For touch inputs, you can increase the hit box of widgets (via the _style.TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimizing for screen real-estate and precision.
Can you create elaborate/serious tools with Dear ImGui?
@@ -261,7 +261,7 @@ Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might
Can you reskin the look of Dear ImGui?
-You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. Below is a screenshot from [LumixEngine](https://github.com/nem0/LumixEngine) with custom colors + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged):
+You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimized to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. Below is a screenshot from [LumixEngine](https://github.com/nem0/LumixEngine) with custom colors + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged):
![LumixEngine](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v151/lumix-201710-rearranged.png)
diff --git a/TODO.txt b/TODO.txt
index 918f3b58..280d6638 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -183,7 +183,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tree node: tweak color scheme to distinguish headers from selected tree node (#581)
- tree node: leaf/non-leaf highlight mismatch.
-!- settings: expose enough to save/load .ini from RAM instead of fopen
- settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes?
- settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437)
- stb: add defines to disable stb implementations
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index 80326bca..055d352d 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -22,7 +22,8 @@ int main(int, char**)
al_register_event_source(queue, al_get_keyboard_event_source());
al_register_event_source(queue, al_get_mouse_event_source());
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index ea9093fa..cd59bcfe 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -114,7 +114,8 @@ int main(int, char**)
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index 7fa16e98..1137b15a 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -130,7 +130,8 @@ int main(int, char**)
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp
index f35a0cca..d96ad08c 100644
--- a/examples/directx12_example/main.cpp
+++ b/examples/directx12_example/main.cpp
@@ -286,7 +286,8 @@ int main(int, char**)
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index aae63733..8dd66814 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -75,7 +75,8 @@ int main(int, char**)
return 0;
}
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
diff --git a/examples/imgui_impl_dx9.cpp b/examples/imgui_impl_dx9.cpp
index 931e5148..4e3ae8e7 100644
--- a/examples/imgui_impl_dx9.cpp
+++ b/examples/imgui_impl_dx9.cpp
@@ -11,6 +11,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
@@ -66,7 +67,16 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
return;
- // Copy and convert all vertices into a single contiguous buffer
+ // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
+ D3DMATRIX last_world, last_view, last_projection;
+ g_pd3dDevice->GetTransform(D3DTS_WORLD, &last_world);
+ g_pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
+ g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
+
+ // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format.
+ // FIXME-OPT: This is a waste of resource, the ideal is to use imconfig.h and
+ // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
+ // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
CUSTOMVERTEX* vtx_dst;
ImDrawIdx* idx_dst;
if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
@@ -82,7 +92,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
vtx_dst->pos[0] = vtx_src->pos.x;
vtx_dst->pos[1] = vtx_src->pos.y;
vtx_dst->pos[2] = 0.0f;
- vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
+ vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000) >> 16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
vtx_dst->uv[0] = vtx_src->uv.x;
vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
@@ -106,7 +116,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
vp.MaxZ = 1.0f;
g_pd3dDevice->SetViewport(&vp);
- // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
+ // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient)
g_pd3dDevice->SetPixelShader(NULL);
g_pd3dDevice->SetVertexShader(NULL);
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
@@ -118,6 +128,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
@@ -172,6 +183,11 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
vtx_offset += cmd_list->VtxBuffer.Size;
}
+ // Restore the DX9 transform
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection);
+
// Restore the DX9 state
d3d9_state_block->Apply();
d3d9_state_block->Release();
diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp
index 817a2872..b8ac728b 100644
--- a/examples/marmalade_example/main.cpp
+++ b/examples/marmalade_example/main.cpp
@@ -16,7 +16,8 @@ int main(int, char**)
{
IwGxInit();
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
diff --git a/examples/null_example/main.cpp b/examples/null_example/main.cpp
index 482d689b..547ed3c1 100644
--- a/examples/null_example/main.cpp
+++ b/examples/null_example/main.cpp
@@ -4,6 +4,7 @@
int main(int, char**)
{
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp
index 2c67b0b8..a0f86a3c 100644
--- a/examples/opengl2_example/main.cpp
+++ b/examples/opengl2_example/main.cpp
@@ -27,7 +27,8 @@ int main(int, char**)
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp
index 50b364c6..0563e1da 100644
--- a/examples/opengl3_example/main.cpp
+++ b/examples/opengl3_example/main.cpp
@@ -32,7 +32,8 @@ int main(int, char**)
glfwSwapInterval(1); // Enable vsync
gl3wInit();
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp
index b6518b9f..1ba1bf06 100644
--- a/examples/sdl_opengl2_example/main.cpp
+++ b/examples/sdl_opengl2_example/main.cpp
@@ -34,7 +34,8 @@ int main(int, char**)
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_SetSwapInterval(1); // Enable vsync
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp
index 88557fe9..1314f859 100644
--- a/examples/sdl_opengl3_example/main.cpp
+++ b/examples/sdl_opengl3_example/main.cpp
@@ -34,7 +34,8 @@ int main(int, char**)
SDL_GL_SetSwapInterval(1); // Enable vsync
gl3wInit();
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp
index 07efda97..6a4950e9 100644
--- a/examples/vulkan_example/main.cpp
+++ b/examples/vulkan_example/main.cpp
@@ -343,7 +343,8 @@ int main(int, char**)
ImGui_ImplVulkan_WindowData* wd = &g_WindowData;
SetupVulkanWindowData(wd, surface, w, h);
- // Setup ImGui binding
+ // Setup Dear ImGui binding
+ IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
diff --git a/imconfig.h b/imconfig.h
index 191807d6..6f839f31 100644
--- a/imconfig.h
+++ b/imconfig.h
@@ -8,6 +8,7 @@
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ dear imgui is used, which include
// the imgui*.cpp files but also _any_ of your code that uses imgui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
+// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//-----------------------------------------------------------------------------
#pragma once
diff --git a/imgui.cpp b/imgui.cpp
index cdc0f89d..832108c1 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -266,6 +266,7 @@
- 2018/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2018/XX/XX (1.XX) - removed io.DisplayVisibleMin, io.DisplayVisibleMax settings (it was used to clip within the DisplayMin..DisplayMax range, I don't know of anyone using it)
+ - 2018/04/28 (1.61) - obsoleted InputFloat() functions taking an optional "int decimal_precision" in favor of an equivalent and more flexible "const char* format", consistent with other functions. Kept redirection functions (will obsolete).
- 2018/04/09 (1.61) - IM_DELETE() helper function added in 1.60 doesn't clear the input _pointer_ reference, more consistent with expectation and allows passing r-value.
- 2018/03/20 (1.60) - Renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, _not_ used by core and only honored by some binding ahead of merging the Nav branch).
- 2018/03/12 (1.60) - Removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered as the closing cross uses regular button colors now.
@@ -729,22 +730,15 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* wind
static ImGuiWindowSettings* AddWindowSettings(const char* name);
-static void LoadIniSettingsFromDisk(const char* ini_filename);
-static void LoadIniSettingsFromMemory(const char* buf);
-static void SaveIniSettingsToDisk(const char* ini_filename);
-static void SaveIniSettingsToMemory(ImVector& out_buf);
-static void MarkIniSettingsDirty(ImGuiWindow* window);
-
static void ClosePopupToLevel(int remaining);
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data);
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false);
-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 inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format);
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);
+static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format);
namespace ImGui
{
@@ -1456,7 +1450,7 @@ FILE* ImFileOpen(const char* filename, const char* mode)
// Load file content into memory
// Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree()
-void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size, int padding_bytes)
+void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size, int padding_bytes)
{
IM_ASSERT(filename && file_open_mode);
if (out_file_size)
@@ -1473,14 +1467,14 @@ void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int*
return NULL;
}
- int file_size = (int)file_size_signed;
- void* file_data = ImGui::MemAlloc((size_t)(file_size + padding_bytes));
+ size_t file_size = (size_t)file_size_signed;
+ void* file_data = ImGui::MemAlloc(file_size + padding_bytes);
if (file_data == NULL)
{
fclose(f);
return NULL;
}
- if (fread(file_data, 1, (size_t)file_size, f) != (size_t)file_size)
+ if (fread(file_data, 1, file_size, f) != file_size)
{
fclose(f);
ImGui::MemFree(file_data);
@@ -2655,6 +2649,20 @@ void ImGui::SetCurrentContext(ImGuiContext* ctx)
#endif
}
+// Helper function to verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit
+// If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. you may see different structures from what imgui.cpp sees which is highly problematic.
+bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert)
+{
+ bool error = false;
+ if (strcmp(version, IMGUI_VERSION)!=0) { error = true; IM_ASSERT(strcmp(version,IMGUI_VERSION)==0 && "Mismatch version string!"); }
+ if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); }
+ if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); }
+ if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); }
+ if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); }
+ if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); }
+ return !error;
+}
+
void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data)
{
GImAllocatorAllocFunc = alloc_func;
@@ -3824,7 +3832,7 @@ void ImGui::NewFrameUpdateHoveredWindowAndCaptureFlags()
g.IO.WantCaptureKeyboard = true;
// Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible
- g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0;
+ g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false;
}
void ImGui::NewFrame()
@@ -3879,20 +3887,27 @@ void ImGui::NewFrame()
}
}
- // Load settings on first frame
+ // Load settings on first frame (if not explicitly loaded manually before)
if (!g.SettingsLoaded)
{
IM_ASSERT(g.SettingsWindows.empty());
- LoadIniSettingsFromDisk(g.IO.IniFilename);
+ if (g.IO.IniFilename)
+ LoadIniSettingsFromDisk(g.IO.IniFilename);
g.SettingsLoaded = true;
}
- // Save settings (with a delay so we don't spam disk too much)
+ // Save settings (with a delay after the last modification, so we don't spam disk too much)
if (g.SettingsDirtyTimer > 0.0f)
{
g.SettingsDirtyTimer -= g.IO.DeltaTime;
if (g.SettingsDirtyTimer <= 0.0f)
- SaveIniSettingsToDisk(g.IO.IniFilename);
+ {
+ if (g.IO.IniFilename != NULL)
+ SaveIniSettingsToDisk(g.IO.IniFilename);
+ else
+ g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
+ g.SettingsDirtyTimer = 0.0f;
+ }
}
g.Time += g.IO.DeltaTime;
@@ -4122,7 +4137,6 @@ void ImGui::Initialize(ImGuiContext* context)
{
ImGuiContext& g = *context;
IM_ASSERT(!g.Initialized && !g.SettingsLoaded);
- g.LogClipboard = IM_NEW(ImGuiTextBuffer)();
// Add .ini handle for ImGuiWindow type
ImGuiSettingsHandler ini_handler;
@@ -4159,19 +4173,18 @@ void ImGui::DestroyPlatformWindows()
// This function is merely here to free heap allocations.
void ImGui::Shutdown(ImGuiContext* context)
{
- ImGuiContext& g = *context;
-
// The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame)
+ ImGuiContext& g = *context;
if (g.IO.Fonts && g.FontAtlasOwnedByContext)
IM_DELETE(g.IO.Fonts);
g.IO.Fonts = NULL;
- // Cleanup of other data are conditional on actually having initialize ImGui.
+ // Cleanup of other data are conditional on actually having initialized ImGui.
if (!g.Initialized)
return;
// Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file)
- if (g.SettingsLoaded)
+ if (g.SettingsLoaded && g.IO.IniFilename != NULL)
SaveIniSettingsToDisk(g.IO.IniFilename);
// Destroy platform windows
@@ -4217,9 +4230,7 @@ void ImGui::Shutdown(ImGuiContext* context)
fclose(g.LogFile);
g.LogFile = NULL;
}
- if (g.LogClipboard)
- IM_DELETE(g.LogClipboard);
- g.LogClipboard = NULL;
+ g.LogClipboard.clear();
g.Initialized = false;
}
@@ -4243,14 +4254,13 @@ static ImGuiWindowSettings* AddWindowSettings(const char* name)
return settings;
}
-static void LoadIniSettingsFromDisk(const char* ini_filename)
+void ImGui::LoadIniSettingsFromDisk(const char* ini_filename)
{
- if (!ini_filename)
- return;
- char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", NULL, +1);
+ size_t file_data_size = 0;
+ char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size);
if (!file_data)
return;
- LoadIniSettingsFromMemory(file_data);
+ LoadIniSettingsFromMemory(file_data, (size_t)file_data_size);
ImGui::MemFree(file_data);
}
@@ -4265,13 +4275,21 @@ ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name)
}
// Zero-tolerance, no error reporting, cheap .ini parsing
-static void LoadIniSettingsFromMemory(const char* buf_readonly)
+void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
{
- // For convenience and to make the code simpler, we'll write zero terminators inside the buffer. So let's create a writable copy.
- char* buf = ImStrdup(buf_readonly);
- char* buf_end = buf + strlen(buf);
-
ImGuiContext& g = *GImGui;
+ IM_ASSERT(g.Initialized);
+ IM_ASSERT(g.SettingsLoaded == false && g.FrameCount == 0);
+
+ // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter).
+ // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy..
+ if (ini_size == 0)
+ ini_size = strlen(ini_data);
+ char* buf = (char*)ImGui::MemAlloc(ini_size + 1);
+ char* buf_end = buf + ini_size;
+ memcpy(buf, ini_data, ini_size);
+ buf[ini_size] = 0;
+
void* entry_data = NULL;
ImGuiSettingsHandler* entry_handler = NULL;
@@ -4304,7 +4322,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly)
*type_end = 0; // Overwrite first ']'
name_start++; // Skip second '['
}
- entry_handler = ImGui::FindSettingsHandler(type_start);
+ entry_handler = FindSettingsHandler(type_start);
entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL;
}
else if (entry_handler != NULL && entry_data != NULL)
@@ -4318,37 +4336,37 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly)
g.SettingsLoaded = true;
}
-static void SaveIniSettingsToDisk(const char* ini_filename)
+void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
{
ImGuiContext& g = *GImGui;
g.SettingsDirtyTimer = 0.0f;
if (!ini_filename)
return;
- ImVector buf;
- SaveIniSettingsToMemory(buf);
-
+ size_t ini_data_size = 0;
+ const char* ini_data = SaveIniSettingsToMemory(&ini_data_size);
FILE* f = ImFileOpen(ini_filename, "wt");
if (!f)
return;
- fwrite(buf.Data, sizeof(char), (size_t)buf.Size, f);
+ fwrite(ini_data, sizeof(char), ini_data_size, f);
fclose(f);
}
-static void SaveIniSettingsToMemory(ImVector& out_buf)
+// Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer
+const char* ImGui::SaveIniSettingsToMemory(size_t* out_size)
{
ImGuiContext& g = *GImGui;
g.SettingsDirtyTimer = 0.0f;
-
- ImGuiTextBuffer buf;
+ g.SettingsIniData.Buf.resize(0);
+ g.SettingsIniData.Buf.push_back(0);
for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
{
ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n];
- handler->WriteAllFn(&g, handler, &buf);
+ handler->WriteAllFn(&g, handler, &g.SettingsIniData);
}
-
- buf.Buf.pop_back(); // Remove extra zero-terminator used by ImGuiTextBuffer
- out_buf.swap(buf.Buf);
+ if (out_size)
+ *out_size = (size_t)g.SettingsIniData.size();
+ return g.SettingsIniData.c_str();
}
void ImGui::MarkIniSettingsDirty()
@@ -4358,7 +4376,7 @@ void ImGui::MarkIniSettingsDirty()
g.SettingsDirtyTimer = g.IO.IniSavingRate;
}
-static void MarkIniSettingsDirty(ImGuiWindow* window)
+void ImGui::MarkIniSettingsDirty(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
@@ -4777,7 +4795,7 @@ void ImGui::LogText(const char* fmt, ...)
if (g.LogFile)
vfprintf(g.LogFile, fmt, args);
else
- g.LogClipboard->appendfv(fmt, args);
+ g.LogClipboard.appendfv(fmt, args);
va_end(args);
}
@@ -8864,10 +8882,10 @@ void ImGui::LogFinish()
fclose(g.LogFile);
g.LogFile = NULL;
}
- if (g.LogClipboard->size() > 1)
+ if (g.LogClipboard.size() > 1)
{
- SetClipboardText(g.LogClipboard->begin());
- g.LogClipboard->clear();
+ SetClipboardText(g.LogClipboard.begin());
+ g.LogClipboard.clear();
}
g.LogEnabled = false;
}
@@ -9332,70 +9350,53 @@ void ImGui::BulletText(const char* fmt, ...)
va_end(args);
}
-static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size)
+static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
{
- if (data_type == ImGuiDataType_Int)
- 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)
-{
- if (data_type == ImGuiDataType_Int)
- {
- if (decimal_precision < 0)
- ImFormatString(buf, buf_size, "%d", *(int*)data_ptr);
- else
- ImFormatString(buf, buf_size, "%.*d", decimal_precision, *(int*)data_ptr);
- }
- else if (data_type == ImGuiDataType_Float)
- {
- if (decimal_precision < 0)
- ImFormatString(buf, buf_size, "%f", *(float*)data_ptr); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits?
- 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);
- }
+ if (data_type == ImGuiDataType_Int32 || data_type == ImGuiDataType_Uint32)
+ return ImFormatString(buf, buf_size, format, *(const int*)data_ptr);
+ if (data_type == ImGuiDataType_Float)
+ return ImFormatString(buf, buf_size, format, *(const float*)data_ptr);
+ if (data_type == ImGuiDataType_Double)
+ return ImFormatString(buf, buf_size, format, *(const double*)data_ptr);
+ IM_ASSERT(0);
+ return 0;
}
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 (data_type == ImGuiDataType_Int32)
{
- if (op == '+') *(int*)output = *(int*)arg1 + *(const int*)arg2;
- else if (op == '-') *(int*)output = *(int*)arg1 - *(const int*)arg2;
+ if (op == '+') *(int*)output = *(const int*)arg1 + *(const int*)arg2;
+ else if (op == '-') *(int*)output = *(const int*)arg1 - *(const int*)arg2;
+ }
+ else if (data_type == ImGuiDataType_Uint32)
+ {
+ if (op == '+') *(unsigned int*)output = *(const unsigned int*)arg1 + *(const unsigned int*)arg2;
+ else if (op == '-') *(unsigned int*)output = *(const unsigned int*)arg1 - *(const unsigned int*)arg2;
}
else if (data_type == ImGuiDataType_Float)
{
- if (op == '+') *(float*)output = *(float*)arg1 + *(const float*)arg2;
- else if (op == '-') *(float*)output = *(float*)arg1 - *(const float*)arg2;
+ if (op == '+') *(float*)output = *(const float*)arg1 + *(const float*)arg2;
+ else if (op == '-') *(float*)output = *(const 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;
+ if (op == '+') *(double*)output = *(const double*)arg1 + *(const double*)arg2;
+ else if (op == '-') *(double*)output = *(const double*)arg1 - *(const double*)arg2;
}
}
static size_t GDataTypeSize[ImGuiDataType_COUNT] =
{
sizeof(int),
+ sizeof(unsigned int),
sizeof(float),
sizeof(double)
};
// 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..
+// NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess..
static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format)
{
while (ImCharIsSpace((unsigned int)*buf))
@@ -9422,7 +9423,9 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
IM_ASSERT(GDataTypeSize[data_type] <= sizeof(data_backup));
memcpy(data_backup, data_ptr, GDataTypeSize[data_type]);
- if (data_type == ImGuiDataType_Int)
+ int arg1i = 0;
+ float arg1f = 0.0f;
+ if (data_type == ImGuiDataType_Int32)
{
if (!scalar_format)
scalar_format = "%d";
@@ -9431,18 +9434,31 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
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 integer constant
+ if (op == '+') { if (sscanf(buf, "%d", &arg1i)) *v = (int)(arg0i + arg1i); } // Add (use "+-" to subtract)
+ else if (op == '*') { if (sscanf(buf, "%f", &arg1f)) *v = (int)(arg0i * arg1f); } // Multiply
+ else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (int)(arg0i / arg1f); } // Divide
+ else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign integer constant
+ }
+ else if (data_type == ImGuiDataType_Uint32)
+ {
+ if (!scalar_format)
+ scalar_format = "%u";
+ ImU32* v = (unsigned int*)data_ptr;
+ ImU32 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
+ if (op == '+') { if (sscanf(buf, "%d", &arg1i)) *v = (ImU32)(arg0i + arg1f); } // Add (use "+-" to subtract)
+ else if (op == '*') { if (sscanf(buf, "%f", &arg1f)) *v = (ImU32)(arg0i * arg1f); } // Multiply
+ else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (ImU32)(arg0i / arg1f); }// Divide
+ 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;
- float arg0f = *v, arg1f = 0.0f;
+ float arg0f = *v;
if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1)
return false;
if (sscanf(buf, scalar_format, &arg1f) < 1)
@@ -9454,9 +9470,9 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
}
else if (data_type == ImGuiDataType_Double)
{
- scalar_format = "%lf";
+ scalar_format = "%lf"; // scanf differentiate float/double unlike printf which forces everything to double because of ellipsis
double* v = (double*)data_ptr;
- double arg0f = *v, arg1f = 0.0f;
+ double arg0f = *v;
if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1)
return false;
if (sscanf(buf, scalar_format, &arg1f) < 1)
@@ -9471,7 +9487,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
// Create text input in place of a slider (when CTRL+Clicking on slider)
// FIXME: Logic is messy and confusing.
-bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision)
+bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
@@ -9483,41 +9499,83 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label
SetHoveredID(0);
FocusableItemUnregister(window);
- char buf[32];
- DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf));
- bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
+ char fmt_buf[32];
+ char data_buf[32];
+ format = ParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf));
+ DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, data_ptr, format);
+ ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal);
+ bool value_changed = InputTextEx(label, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags);
if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget
{
- IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible)
+ IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID
g.ScalarAsInputTextId = g.ActiveId;
SetHoveredID(id);
}
- if (text_value_changed)
- return DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL);
+ if (value_changed)
+ return DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialText.begin(), data_type, data_ptr, NULL);
return false;
}
+const char* ImGui::ParseFormatTrimDecorationsLeading(const char* fmt)
+{
+ while (char c = fmt[0])
+ {
+ if (c == '%' && fmt[1] != '%')
+ return fmt;
+ else if (c == '%')
+ fmt++;
+ fmt++;
+ }
+ return fmt;
+}
+
+// Extract the format out of a format string with leading or trailing decorations
+// fmt = "blah blah" -> return fmt
+// fmt = "%.3f" -> return fmt
+// fmt = "hello %.3f" -> return fmt + 6
+// fmt = "%.3f hello" -> return buf written with "%.3f"
+const char* ImGui::ParseFormatTrimDecorations(const char* fmt, char* buf, int buf_size)
+{
+ // We don't use strchr() because our strings are usually very short and often start with '%'
+ const char* fmt_start = ParseFormatTrimDecorationsLeading(fmt);
+ if (fmt_start[0] != '%')
+ return fmt;
+ fmt = fmt_start;
+ while (char c = *fmt++)
+ {
+ if (c >= 'A' && c <= 'Z' && (c != 'L')) // L is a type modifier, other letters qualify as types aka end of the format
+ break;
+ if (c >= 'a' && c <= 'z' && (c != 'h' && c != 'j' && c != 'l' && c != 't' && c != 'w' && c != 'z')) // h/j/l/t/w/z are type modifiers, other letters qualify as types aka end of the format
+ break;
+ }
+ if (fmt[0] == 0) // If we only have leading decoration, we don't need to copy the data.
+ return fmt_start;
+ ImStrncpy(buf, fmt_start, ImMin((int)(fmt + 1 - fmt_start), buf_size));
+ return buf;
+}
+
// Parse display precision back from the display format string
+// FIXME: This is still used by some navigation code path to infer a minimum tweak step, but we should aim to rework widgets so it isn't needed.
int ImGui::ParseFormatPrecision(const char* fmt, int default_precision)
{
- int precision = default_precision;
- while ((fmt = strchr(fmt, '%')) != NULL)
- {
+ fmt = ParseFormatTrimDecorationsLeading(fmt);
+ if (fmt[0] != '%')
+ return default_precision;
+ fmt++;
+ while (*fmt >= '0' && *fmt <= '9')
fmt++;
- if (fmt[0] == '%') { fmt++; continue; } // Ignore "%%"
- while (*fmt >= '0' && *fmt <= '9')
- fmt++;
- if (*fmt == '.')
- {
- fmt = ImAtoi(fmt + 1, &precision);
- if (precision < 0 || precision > 10)
- precision = default_precision;
- }
- if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation
- precision = -1;
- break;
+ int precision = INT_MAX;
+ if (*fmt == '.')
+ {
+ fmt = ImAtoi(fmt + 1, &precision);
+ if (precision < 0 || precision > 99)
+ precision = default_precision;
}
- return precision;
+ if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation
+ precision = -1;
+ if ((*fmt == 'g' || *fmt == 'G') && precision == INT_MAX)
+ precision = -1;
+ return (precision == INT_MAX) ? default_precision : precision;
}
static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
@@ -9526,22 +9584,11 @@ static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision);
}
-float ImGui::RoundScalar(float value, int decimal_precision)
+float ImGui::RoundScalarWithFormat(const char* format, float value)
{
- // Round past decimal precision
- // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
- // FIXME: Investigate better rounding methods
- if (decimal_precision < 0)
- return value;
- const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision);
- bool negative = value < 0.0f;
- value = fabsf(value);
- float remainder = fmodf(value, min_step);
- if (remainder <= min_step*0.5f)
- value -= remainder;
- else
- value += (min_step - remainder);
- return negative ? -value : value;
+ char buf[64];
+ ImFormatString(buf, IM_ARRAYSIZE(buf), ParseFormatTrimDecorationsLeading(format), value);
+ return (float)atof(buf);
}
static inline float SliderBehaviorCalcRatioFromValue(float v, float v_min, float v_max, float power, float linear_zero_pos)
@@ -9569,7 +9616,7 @@ static inline float SliderBehaviorCalcRatioFromValue(float v, float v_min, float
return (v_clamped - v_min) / (v_max - v_min);
}
-bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags)
+bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, const char* format, float power, ImGuiSliderFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
@@ -9582,11 +9629,12 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f);
const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0;
+ const bool is_decimal = ParseFormatPrecision(format, 3) > 0;
const float grab_padding = 2.0f;
const float slider_sz = is_horizontal ? (frame_bb.GetWidth() - grab_padding * 2.0f) : (frame_bb.GetHeight() - grab_padding * 2.0f);
float grab_sz;
- if (decimal_precision != 0)
+ if (is_decimal)
grab_sz = ImMin(style.GrabMinSize, slider_sz);
else
grab_sz = ImMin(ImMax(1.0f * (slider_sz / ((v_min < v_max ? v_max - v_min : v_min - v_max) + 1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit
@@ -9641,7 +9689,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
else if (delta != 0.0f)
{
clicked_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos);
- if (decimal_precision == 0 && !is_non_linear)
+ if (!is_decimal && !is_non_linear)
{
if (fabsf(v_max - v_min) <= 100.0f || IsNavInputDown(ImGuiNavInput_TweakSlow))
delta = ((delta < 0.0f) ? -1.0f : +1.0f) / (v_max - v_min); // Gamepad/keyboard tweak speeds in integer steps
@@ -9696,7 +9744,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
}
// Round past decimal precision
- new_value = RoundScalar(new_value, decimal_precision);
+ new_value = RoundScalarWithFormat(format, new_value);
if (*v != new_value)
{
*v = new_value;
@@ -9721,11 +9769,11 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
}
// Use power!=1.0 for logarithmic sliders.
-// Adjust display_format to decorate the value with a prefix or a suffix.
+// Adjust format to decorate the value with a prefix or a suffix.
// "%.3f" 1.234
// "%5.2f secs" 01.23 secs
// "Gold: %.0f" Gold: 1
-bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, float power)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -9748,9 +9796,8 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
}
const bool hovered = ItemHoverable(frame_bb, id);
- if (!display_format)
- display_format = "%.3f";
- int decimal_precision = ParseFormatPrecision(display_format, 3);
+ if (!format)
+ format = "%.3f";
// Tabbing or CTRL-clicking on Slider turns it into an input box
bool start_text_input = false;
@@ -9768,15 +9815,15 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
}
}
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
- return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision);
+ return InputScalarAsWidgetReplacement(frame_bb, id, label, ImGuiDataType_Float, v, format);
// Actual slider behavior + render grab
ItemSize(total_bb, style.FramePadding.y);
- const bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision);
+ const bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, format, power);
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64];
- const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
+ const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), format, *v);
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.5f));
if (label_size.x > 0.0f)
@@ -9785,7 +9832,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
return value_changed;
}
-bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format, float power)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -9804,9 +9851,8 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
return false;
const bool hovered = ItemHoverable(frame_bb, id);
- if (!display_format)
- display_format = "%.3f";
- int decimal_precision = ParseFormatPrecision(display_format, 3);
+ if (!format)
+ format = "%.3f";
if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavInputId == id)
{
@@ -9817,12 +9863,12 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
}
// Actual slider behavior + render grab
- bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, ImGuiSliderFlags_Vertical);
+ bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, format, power, ImGuiSliderFlags_Vertical);
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
// For the vertical slider we allow centered text to overlap the frame padding
char value_buf[64];
- char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
+ char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), format, *v);
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.0f));
if (label_size.x > 0.0f)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
@@ -9838,28 +9884,28 @@ bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, fl
return value_changed;
}
-bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format)
+bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* format)
{
- if (!display_format)
- display_format = "%.0f";
+ if (!format)
+ format = "%.0f";
float v_f = (float)*v;
- bool value_changed = SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f);
+ bool value_changed = SliderFloat(label, &v_f, (float)v_min, (float)v_max, format, 1.0f);
*v = (int)v_f;
return value_changed;
}
-bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format)
+bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format)
{
- if (!display_format)
- display_format = "%.0f";
+ if (!format)
+ format = "%.0f";
float v_f = (float)*v;
- bool value_changed = VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f);
+ bool value_changed = VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, format, 1.0f);
*v = (int)v_f;
return value_changed;
}
// Add multiple sliders on 1 line for compact edition of multiple components
-bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* format, float power)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -9873,7 +9919,7 @@ bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_mi
for (int i = 0; i < components; i++)
{
PushID(i);
- value_changed |= SliderFloat("##v", &v[i], v_min, v_max, display_format, power);
+ value_changed |= SliderFloat("##v", &v[i], v_min, v_max, format, power);
SameLine(0, g.Style.ItemInnerSpacing.x);
PopID();
PopItemWidth();
@@ -9886,22 +9932,22 @@ bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_mi
return value_changed;
}
-bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power)
+bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, float power)
{
- return SliderFloatN(label, v, 2, v_min, v_max, display_format, power);
+ return SliderFloatN(label, v, 2, v_min, v_max, format, power);
}
-bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power)
+bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, float power)
{
- return SliderFloatN(label, v, 3, v_min, v_max, display_format, power);
+ return SliderFloatN(label, v, 3, v_min, v_max, format, power);
}
-bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power)
+bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, float power)
{
- return SliderFloatN(label, v, 4, v_min, v_max, display_format, power);
+ return SliderFloatN(label, v, 4, v_min, v_max, format, power);
}
-bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format)
+bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* format)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -9915,7 +9961,7 @@ bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int
for (int i = 0; i < components; i++)
{
PushID(i);
- value_changed |= SliderInt("##v", &v[i], v_min, v_max, display_format);
+ value_changed |= SliderInt("##v", &v[i], v_min, v_max, format);
SameLine(0, g.Style.ItemInnerSpacing.x);
PopID();
PopItemWidth();
@@ -9928,22 +9974,22 @@ bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int
return value_changed;
}
-bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format)
+bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format)
{
- return SliderIntN(label, v, 2, v_min, v_max, display_format);
+ return SliderIntN(label, v, 2, v_min, v_max, format);
}
-bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format)
+bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format)
{
- return SliderIntN(label, v, 3, v_min, v_max, display_format);
+ return SliderIntN(label, v, 3, v_min, v_max, format);
}
-bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format)
+bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format)
{
- return SliderIntN(label, v, 4, v_min, v_max, display_format);
+ return SliderIntN(label, v, 4, v_min, v_max, format);
}
-bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power)
+bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, const char* format, float power)
{
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
@@ -9953,8 +9999,6 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s
RenderNavHighlight(frame_bb, id);
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding);
- bool value_changed = false;
-
// Process interacting with the drag
if (g.ActiveId == id)
{
@@ -9963,75 +10007,80 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s
else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated)
ClearActiveID();
}
- if (g.ActiveId == id)
+ if (g.ActiveId != id)
+ return false;
+
+ // Default tweak speed
+ if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX)
+ v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio;
+
+ if (g.ActiveIdIsJustActivated)
{
- if (g.ActiveIdIsJustActivated)
+ // Lock current value on click
+ g.DragCurrentValue = *v;
+ g.DragLastMouseDelta = ImVec2(0.f, 0.f);
+ }
+
+ const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f);
+ float adjust_delta = 0.0f;
+ if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid())
+ {
+ adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x;
+ if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f)
+ adjust_delta *= g.DragSpeedScaleFast;
+ if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f)
+ adjust_delta *= g.DragSpeedScaleSlow;
+ g.DragLastMouseDelta.x = mouse_drag_delta.x;
+ }
+ if (g.ActiveIdSource == ImGuiInputSource_Nav)
+ {
+ int decimal_precision = ParseFormatPrecision(format, 3);
+ adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x;
+ v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
+ }
+ adjust_delta *= v_speed;
+
+ // Avoid applying the saturation when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300
+ float v_cur = g.DragCurrentValue;
+ if (v_min < v_max && ((v_cur >= v_max && adjust_delta > 0.0f) || (v_cur <= v_min && adjust_delta < 0.0f)))
+ adjust_delta = 0.0f;
+
+ if (fabsf(adjust_delta) > 0.0f)
+ {
+ if (fabsf(power - 1.0f) > 0.001f)
{
- // Lock current value on click
- g.DragCurrentValue = *v;
- g.DragLastMouseDelta = ImVec2(0.f, 0.f);
+ // Logarithmic curve on both side of 0.0
+ float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur;
+ float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f;
+ float v1 = powf(v0_abs, 1.0f / power) + (adjust_delta * v0_sign);
+ float v1_abs = v1 >= 0.0f ? v1 : -v1;
+ float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line
+ v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign
+ }
+ else
+ {
+ v_cur += adjust_delta;
}
- if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX)
- v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio;
+ // Clamp
+ if (v_min < v_max)
+ v_cur = ImClamp(v_cur, v_min, v_max);
+ g.DragCurrentValue = v_cur;
+ }
- float v_cur = g.DragCurrentValue;
- const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f);
- float adjust_delta = 0.0f;
- if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid())
- {
- adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x;
- if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f)
- adjust_delta *= g.DragSpeedScaleFast;
- if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f)
- adjust_delta *= g.DragSpeedScaleSlow;
- g.DragLastMouseDelta.x = mouse_drag_delta.x;
- }
- if (g.ActiveIdSource == ImGuiInputSource_Nav)
- {
- adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x;
- if (v_min < v_max && ((v_cur >= v_max && adjust_delta > 0.0f) || (v_cur <= v_min && adjust_delta < 0.0f))) // This is to avoid applying the saturation when already past the limits
- adjust_delta = 0.0f;
- v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
- }
- adjust_delta *= v_speed;
-
- if (fabsf(adjust_delta) > 0.0f)
- {
- if (fabsf(power - 1.0f) > 0.001f)
- {
- // Logarithmic curve on both side of 0.0
- float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur;
- float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f;
- float v1 = powf(v0_abs, 1.0f / power) + (adjust_delta * v0_sign);
- float v1_abs = v1 >= 0.0f ? v1 : -v1;
- float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line
- v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign
- }
- else
- {
- v_cur += adjust_delta;
- }
-
- // Clamp
- if (v_min < v_max)
- v_cur = ImClamp(v_cur, v_min, v_max);
- g.DragCurrentValue = v_cur;
- }
-
- // Round to user desired precision, then apply
- v_cur = RoundScalar(v_cur, decimal_precision);
- if (*v != v_cur)
- {
- *v = v_cur;
- value_changed = true;
- }
+ // Round to user desired precision, then apply
+ bool value_changed = false;
+ v_cur = RoundScalarWithFormat(format, v_cur);
+ if (*v != v_cur)
+ {
+ *v = v_cur;
+ value_changed = true;
}
return value_changed;
}
-bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, float power)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -10055,9 +10104,8 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f
}
const bool hovered = ItemHoverable(frame_bb, id);
- if (!display_format)
- display_format = "%.3f";
- int decimal_precision = ParseFormatPrecision(display_format, 3);
+ if (!format)
+ format = "%.3f";
// Tabbing or CTRL-clicking on Drag turns it into an input box
bool start_text_input = false;
@@ -10075,15 +10123,15 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f
}
}
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
- return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision);
+ return InputScalarAsWidgetReplacement(frame_bb, id, label, ImGuiDataType_Float, v, format);
// Actual drag behavior
ItemSize(total_bb, style.FramePadding.y);
- const bool value_changed = DragBehavior(frame_bb, id, v, v_speed, v_min, v_max, decimal_precision, power);
+ const bool value_changed = DragBehavior(frame_bb, id, v, v_speed, v_min, v_max, format, power);
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64];
- const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
+ const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), format, *v);
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.5f));
if (label_size.x > 0.0f)
@@ -10092,7 +10140,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f
return value_changed;
}
-bool ImGui::DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* format, float power)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -10106,7 +10154,7 @@ bool ImGui::DragFloatN(const char* label, float* v, int components, float v_spee
for (int i = 0; i < components; i++)
{
PushID(i);
- value_changed |= DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power);
+ value_changed |= DragFloat("##v", &v[i], v_speed, v_min, v_max, format, power);
SameLine(0, g.Style.ItemInnerSpacing.x);
PopID();
PopItemWidth();
@@ -10119,22 +10167,22 @@ bool ImGui::DragFloatN(const char* label, float* v, int components, float v_spee
return value_changed;
}
-bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, float power)
{
- return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power);
+ return DragFloatN(label, v, 2, v_speed, v_min, v_max, format, power);
}
-bool ImGui::DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, float power)
{
- return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power);
+ return DragFloatN(label, v, 3, v_speed, v_min, v_max, format, power);
}
-bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* display_format, float power)
+bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, float power)
{
- return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power);
+ return DragFloatN(label, v, 4, v_speed, v_min, v_max, format, power);
}
-bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* display_format, const char* display_format_max, float power)
+bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, float power)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -10145,10 +10193,10 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu
BeginGroup();
PushMultiItemsWidths(2);
- bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power);
+ bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), format, power);
PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x);
- value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power);
+ value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, format_max ? format_max : format, power);
PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x);
@@ -10160,17 +10208,17 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu
}
// NB: v_speed is float to allow adjusting the drag speed with more precision
-bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format)
+bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* format)
{
- if (!display_format)
- display_format = "%.0f";
+ if (!format)
+ format = "%.0f";
float v_f = (float)*v;
- bool value_changed = DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format);
+ bool value_changed = DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, format);
*v = (int)v_f;
return value_changed;
}
-bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format)
+bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* format)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -10184,7 +10232,7 @@ bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, i
for (int i = 0; i < components; i++)
{
PushID(i);
- value_changed |= DragInt("##v", &v[i], v_speed, v_min, v_max, display_format);
+ value_changed |= DragInt("##v", &v[i], v_speed, v_min, v_max, format);
SameLine(0, g.Style.ItemInnerSpacing.x);
PopID();
PopItemWidth();
@@ -10197,22 +10245,22 @@ bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, i
return value_changed;
}
-bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format)
+bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format)
{
- return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format);
+ return DragIntN(label, v, 2, v_speed, v_min, v_max, format);
}
-bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format)
+bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format)
{
- return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format);
+ return DragIntN(label, v, 3, v_speed, v_min, v_max, format);
}
-bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format)
+bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format)
{
- return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format);
+ return DragIntN(label, v, 4, v_speed, v_min, v_max, format);
}
-bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* display_format, const char* display_format_max)
+bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -10223,10 +10271,10 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_
BeginGroup();
PushMultiItemsWidths(2);
- bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format);
+ bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), format);
PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x);
- value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, display_format_max ? display_format_max : display_format);
+ value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, format_max ? format_max : format);
PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x);
@@ -11136,8 +11184,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
{
if (cancel_edit)
{
- // Restore initial value
- if (is_editable)
+ // Restore initial value. Only return true if restoring to the initial value changes the current buffer contents.
+ if (is_editable && strncmp(buf, edit_state.InitialText.Data, buf_size) != 0)
{
ImStrncpy(buf, edit_state.InitialText.Data, buf_size);
value_changed = true;
@@ -11433,7 +11481,7 @@ bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, co
return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data);
}
-// NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument)
+// NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "format" argument)
bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags)
{
ImGuiWindow* window = GetCurrentWindow();
@@ -11442,84 +11490,74 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
- const ImVec2 label_size = CalcTextSize(label, NULL, true);
-
- BeginGroup();
- PushID(label);
- const ImVec2 button_sz = ImVec2(GetFrameHeight(), GetFrameHeight());
- if (step_ptr)
- PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2));
char buf[64];
- DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf));
+ DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, data_ptr, scalar_format);
bool value_changed = false;
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
- value_changed = DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format);
- // Step buttons
if (step_ptr)
{
+ const float button_size = GetFrameHeight();
+
+ BeginGroup(); // The only purpose of the group here is to allow the caller to query item data e.g. IsItemActive()
+ PushID(label);
+ PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2));
+ if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) // PushId(label) + "" gives us the expected ID from outside point of view
+ value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialText.Data, data_type, data_ptr, scalar_format);
PopItemWidth();
+
+ // Step buttons
SameLine(0, style.ItemInnerSpacing.x);
- if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups))
+ if (ButtonEx("-", ImVec2(button_size, button_size), ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups))
{
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))
+ if (ButtonEx("+", ImVec2(button_size, button_size), ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups))
{
DataTypeApplyOp(data_type, '+', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr);
value_changed = true;
}
- }
- PopID();
-
- if (label_size.x > 0)
- {
SameLine(0, style.ItemInnerSpacing.x);
- RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label);
- ItemSize(label_size, style.FramePadding.y);
+ TextUnformatted(label, FindRenderedTextEnd(label));
+
+ PopID();
+ EndGroup();
+ }
+ else
+ {
+ if (InputText(label, buf, IM_ARRAYSIZE(buf), extra_flags))
+ value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialText.Data, data_type, data_ptr, scalar_format);
}
- EndGroup();
return value_changed;
}
-bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags)
+bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags extra_flags)
{
extra_flags |= ImGuiInputTextFlags_CharsScientific;
- 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);
- }
+ return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), format, extra_flags);
}
-bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* display_format, ImGuiInputTextFlags extra_flags)
+bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* 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);
+ return InputScalarEx(label, ImGuiDataType_Double, (void*)v, (void*)(step>0.0 ? &step : NULL), (void*)(step_fast>0.0 ? &step_fast : NULL), format, extra_flags);
}
bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags extra_flags)
{
// 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 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), scalar_format, extra_flags);
+ const char* format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d";
+ return InputScalarEx(label, ImGuiDataType_Int32, (void*)v, (void*)(step>0 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), format, extra_flags);
}
-bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags)
+bool ImGui::InputFloatN(const char* label, float* v, int components, const char* format, ImGuiInputTextFlags extra_flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -11533,7 +11571,7 @@ bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal
for (int i = 0; i < components; i++)
{
PushID(i);
- value_changed |= InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags);
+ value_changed |= InputFloat("##v", &v[i], 0, 0, format, extra_flags);
SameLine(0, g.Style.ItemInnerSpacing.x);
PopID();
PopItemWidth();
@@ -11546,20 +11584,55 @@ bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal
return value_changed;
}
+bool ImGui::InputFloat2(const char* label, float v[2], const char* format, ImGuiInputTextFlags extra_flags)
+{
+ return InputFloatN(label, v, 2, format, extra_flags);
+}
+
+bool ImGui::InputFloat3(const char* label, float v[3], const char* format, ImGuiInputTextFlags extra_flags)
+{
+ return InputFloatN(label, v, 3, format, extra_flags);
+}
+
+bool ImGui::InputFloat4(const char* label, float v[4], const char* format, ImGuiInputTextFlags extra_flags)
+{
+ return InputFloatN(label, v, 4, format, extra_flags);
+}
+
+// Prefer using "const char* format" directly, which is more flexible and consistent with other API.
+#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
+bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags)
+{
+ char format[16] = "%f";
+ if (decimal_precision >= 0)
+ ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision);
+ return InputFloat(label, v, step, step_fast, format, extra_flags);
+}
+
bool ImGui::InputFloat2(const char* label, float v[2], int decimal_precision, ImGuiInputTextFlags extra_flags)
{
- return InputFloatN(label, v, 2, decimal_precision, extra_flags);
+ char format[16] = "%f";
+ if (decimal_precision >= 0)
+ ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision);
+ return InputFloatN(label, v, 2, format, extra_flags);
}
bool ImGui::InputFloat3(const char* label, float v[3], int decimal_precision, ImGuiInputTextFlags extra_flags)
{
- return InputFloatN(label, v, 3, decimal_precision, extra_flags);
+ char format[16] = "%f";
+ if (decimal_precision >= 0)
+ ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision);
+ return InputFloatN(label, v, 3, format, extra_flags);
}
bool ImGui::InputFloat4(const char* label, float v[4], int decimal_precision, ImGuiInputTextFlags extra_flags)
{
- return InputFloatN(label, v, 4, decimal_precision, extra_flags);
+ char format[16] = "%f";
+ if (decimal_precision >= 0)
+ ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision);
+ return InputFloatN(label, v, 4, format, extra_flags);
}
+#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS
bool ImGui::InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags)
{
@@ -11873,8 +11946,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
selected = false;
// Hovering selectable with mouse updates NavId accordingly so navigation can be resumed with gamepad/keyboard (this doesn't happen on most widgets)
- if (pressed || hovered)// && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f))
- if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerActiveMask)
+ if (pressed || hovered)
+ if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent)
{
g.NavDisableHighlight = true;
SetNavID(id, window->DC.NavLayerCurrent);
@@ -12487,15 +12560,15 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags)
ImGuiColorEditFlags opts = g.ColorEditOptions;
if (allow_opt_inputs)
{
- if (RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB;
- if (RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV;
- if (RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX;
+ if (RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) != 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB;
+ if (RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) != 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV;
+ if (RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) != 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX;
}
if (allow_opt_datatype)
{
if (allow_opt_inputs) Separator();
- if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8;
- if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float;
+ if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) != 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8;
+ if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) != 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float;
}
if (allow_opt_inputs || allow_opt_datatype)
@@ -13893,14 +13966,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*)(intptr_t)payload.Data, data, data_size);
+ memcpy(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*)(intptr_t)payload.Data, data, data_size);
+ memcpy(payload.Data, data, data_size);
}
else
{
diff --git a/imgui.h b/imgui.h
index a9950da6..38b776a3 100644
--- a/imgui.h
+++ b/imgui.h
@@ -16,26 +16,26 @@
#include "imconfig.h"
#endif
-#include // FLT_MAX
-#include // va_list
-#include // ptrdiff_t, NULL
-#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp
+#include // FLT_MAX
+#include // va_list
+#include // ptrdiff_t, NULL
+#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp
-#define IMGUI_VERSION "1.61 WIP"
-#define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch
+// Version
+#define IMGUI_VERSION "1.61 WIP"
+#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert))
+#define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch
-// Define attributes of all API symbols declarations, e.g. for DLL under Windows.
+// Define attributes of all API symbols declarations (e.g. for DLL under Windows)
#ifndef IMGUI_API
#define IMGUI_API
#endif
-// Define assertion handler.
+// Helpers
#ifndef IM_ASSERT
#include
-#define IM_ASSERT(_EXPR) assert(_EXPR)
+#define IM_ASSERT(_EXPR) assert(_EXPR)
#endif
-
-// Helpers
#if defined(__clang__) || defined(__GNUC__)
#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) // Apply printf-style warnings to user functions.
#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0)))
@@ -61,7 +61,7 @@ struct ImDrawVert; // A single vertex (20 bytes by default, ove
struct ImFont; // Runtime data for a single font within a parent ImFontAtlas
struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
struct ImFontConfig; // Configuration data when adding a font or merging fonts
-struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4
+struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*obsolete* please avoid using)
struct ImGuiIO; // Main configuration and I/O between your application and ImGui
struct ImGuiOnceUponAFrame; // Simple helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro
struct ImGuiStorage; // Simple custom key value storage
@@ -117,27 +117,27 @@ typedef unsigned long long ImU64; // 64-bit unsigned integer
struct ImVec2
{
- float x, y;
- ImVec2() { x = y = 0.0f; }
+ float x, y;
+ ImVec2() { x = y = 0.0f; }
ImVec2(float _x, float _y) { x = _x; y = _y; }
- float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine.
-#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2.
- IM_VEC2_CLASS_EXTRA
+ float operator[] (size_t i) const { IM_ASSERT(i <= 1); return (&x)[i]; } // We very rarely use this [] operator, the assert overhead is fine.
+#ifdef IM_VEC2_CLASS_EXTRA
+ IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2.
#endif
};
struct ImVec4
{
- float x, y, z, w;
- ImVec4() { x = y = z = w = 0.0f; }
+ float x, y, z, w;
+ ImVec4() { x = y = z = w = 0.0f; }
ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
-#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4.
- IM_VEC4_CLASS_EXTRA
+#ifdef IM_VEC4_CLASS_EXTRA
+ IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
#endif
};
// ImGui end-user API
-// In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types)
+// In a namespace so that user can add extra functions in your own separate file (please don't modify imgui.cpp/.h)
namespace ImGui
{
// Context creation and access
@@ -147,6 +147,7 @@ namespace ImGui
IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = destroy current context
IMGUI_API ImGuiContext* GetCurrentContext();
IMGUI_API void SetCurrentContext(ImGuiContext* ctx);
+ IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert);
// Main
IMGUI_API ImGuiIO& GetIO();
@@ -340,42 +341,42 @@ namespace ImGui
// Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds)
// For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x
// Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision).
- IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound
- IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f);
- IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f);
- IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f);
- IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", const char* display_format_max = NULL, float power = 1.0f);
- IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_min >= v_max we have no bound
- IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f");
- IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f");
- IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f");
- IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL);
+ IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound
+ IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
+ IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
+ IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
+ IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", const char* format_max = NULL, float power = 1.0f);
+ IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%.0f"); // If v_min >= v_max we have no bound
+ IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%.0f");
+ IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%.0f");
+ IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%.0f");
+ IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%.0f", const char* format_max = NULL);
// Widgets: Input with Keyboard
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
- IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
- IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
- IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
- IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
+ IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0);
+ IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0);
+ IMGUI_API bool InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0);
+ IMGUI_API bool InputFloat4(const char* label, float v[4], const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0);
IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0);
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);
+ IMGUI_API bool InputDouble(const char* label, double* v, double step = 0.0f, double step_fast = 0.0f, const char* 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
- IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
- IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
- IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
+ IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); // adjust 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
+ IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
+ IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
+ IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f);
- IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
- IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f");
- IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f");
- IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f");
- IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
- IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f");
+ IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format = "%.0f");
+ IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format = "%.0f");
+ IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format = "%.0f");
+ IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format = "%.0f");
+ IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
+ IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format = "%.0f");
// Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little colored preview square that can be left-clicked to open a picker, and right-clicked to open an option menu.)
// Note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can the pass the address of a first float element out of a contiguous structure, e.g. &myvector.x
@@ -411,9 +412,9 @@ namespace ImGui
IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper.
IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
- IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards.
+ IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. if the function return true, you can output elements then call ListBoxFooter() afterwards.
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // "
- IMGUI_API void ListBoxFooter(); // terminate the scrolling region
+ IMGUI_API void ListBoxFooter(); // terminate the scrolling region. only call ListBoxFooter() if ListBoxHeader() returned true!
// Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace)
IMGUI_API void Value(const char* prefix, bool b);
@@ -546,13 +547,12 @@ namespace ImGui
IMGUI_API const char* GetClipboardText();
IMGUI_API void SetClipboardText(const char* text);
- // (Optional) Platform/OS interface for multi-viewport support
- IMGUI_API ImGuiPlatformIO& GetPlatformIO(); // platform/renderer functions, for back-end to setup + viewports list.
- IMGUI_API ImGuiViewport* GetMainViewport(); // shortcut to == GetPlatformIO().MainViewport == GetPlatformIO().Viewports[0]
- IMGUI_API void UpdatePlatformWindows(); // call in main loop. will call CreateWindow/ResizeWindow/etc. platform functions for each secondary viewport, and DestroyWindow for each inactive viewport.
- IMGUI_API void RenderPlatformWindowsDefault(void* platform_arg = NULL, void* renderer_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport. may be reimplemented by user for custom rendering needs.
- IMGUI_API void DestroyPlatformWindows(); // call DestroyWindow platform functions for all viewports. call from back-end Shutdown() if you need to close platform windows before imgui shutdown. otherwise will be called by DestroyContext().
- IMGUI_API ImGuiViewport* FindViewportByPlatformHandle(void* platform_handle); // this is a helper for back-ends. the type platform_handle is decided by the back-end (e.g. HWND, MyWindow*, GLFWwindow* etc.)
+ // Settings/.Ini Utilities
+ // The disk functions are automatically called if io.IniFilename != NULL (default is "imgui.ini"). Set io.IniFilename to NULL to load/save manually.
+ IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename).
+ IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source.
+ IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename);
+ IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean.
// Memory Utilities
// All those functions are not reliant on the current context.
@@ -561,6 +561,14 @@ namespace ImGui
IMGUI_API void* MemAlloc(size_t size);
IMGUI_API void MemFree(void* ptr);
+ // (Optional) Platform/OS interface for multi-viewport support
+ IMGUI_API ImGuiPlatformIO& GetPlatformIO(); // platform/renderer functions, for back-end to setup + viewports list.
+ IMGUI_API ImGuiViewport* GetMainViewport(); // shortcut to == GetPlatformIO().MainViewport == GetPlatformIO().Viewports[0]
+ IMGUI_API void UpdatePlatformWindows(); // call in main loop. will call CreateWindow/ResizeWindow/etc. platform functions for each secondary viewport, and DestroyWindow for each inactive viewport.
+ IMGUI_API void RenderPlatformWindowsDefault(void* platform_arg = NULL, void* renderer_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport. may be reimplemented by user for custom rendering needs.
+ IMGUI_API void DestroyPlatformWindows(); // call DestroyWindow platform functions for all viewports. call from back-end Shutdown() if you need to close platform windows before imgui shutdown. otherwise will be called by DestroyContext().
+ IMGUI_API ImGuiViewport* FindViewportByPlatformHandle(void* platform_handle); // this is a helper for back-ends. the type platform_handle is decided by the back-end (e.g. HWND, MyWindow*, GLFWwindow* etc.)
+
} // namespace ImGui
// Flags for ImGui::Begin()
@@ -708,7 +716,7 @@ enum ImGuiDragDropFlags_
ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery.
};
-// Standard Drag and Drop payload types. You can define you own payload types using 12-characters long strings. Types starting with '_' are defined by Dear ImGui.
+// Standard Drag and Drop payload types. You can define you own payload types using short strings. Types starting with '_' are defined by Dear ImGui.
#define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3]: Standard type for colors, without alpha. User code may use this type.
#define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4]: Standard type for colors. User code may use this type.
@@ -861,10 +869,10 @@ enum ImGuiCol_
ImGuiCol_PlotHistogram,
ImGuiCol_PlotHistogramHovered,
ImGuiCol_TextSelectedBg,
- ImGuiCol_ModalWindowDarkening, // darken/colorize entire screen behind a modal window, when one is active
+ ImGuiCol_ModalWindowDarkening, // Darken/colorize entire screen behind a modal window, when one is active
ImGuiCol_DragDropTarget,
- ImGuiCol_NavHighlight, // gamepad/keyboard: current highlighted item
- ImGuiCol_NavWindowingHighlight, // gamepad/keyboard: when holding NavMenu to focus/move/resize windows
+ ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item
+ ImGuiCol_NavWindowingHighlight, // Gamepad/keyboard: when holding NavMenu to focus/move/resize windows
ImGuiCol_COUNT
// Obsolete names (will be removed)
@@ -1025,11 +1033,11 @@ struct ImGuiIO
//------------------------------------------------------------------
ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc.
- ImGuiBackendFlags BackendFlags; // = 0 // Set ImGuiBackendFlags_ enum. Set by imgui_impl_xxx files or custom back-end.
+ ImGuiBackendFlags BackendFlags; // = 0 // Set ImGuiBackendFlags_ enum. Set by imgui_impl_xxx files or custom back-end to communicate features supported by the back-end.
ImVec2 DisplaySize; // // Main display size. Used e.g. to clamp windows positions. This is the default viewport. Use BeginViewport() for other viewports.
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
- float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds.
- const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving.
+ float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
+ const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory.
const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified).
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
@@ -1060,9 +1068,12 @@ struct ImGuiIO
void* ClipboardUserData;
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
- // [OBSOLETE] Rendering function, will be automatically called in Render(). Please call your rendering function yourself now! You can obtain the ImDrawData* by calling ImGui::GetDrawData() after Render().
- // See example applications if you are unsure of how to implement this.
+ // [OBSOLETE] Rendering function, will be automatically called in Render(). Please call your rendering function yourself now!
+ // You can obtain the ImDrawData* by calling ImGui::GetDrawData() after Render(). See example applications if you are unsure of how to implement this.
void (*RenderDrawListsFn)(ImDrawData* data);
+#else
+ // This is only here to keep ImGuiIO the same size, so that IMGUI_DISABLE_OBSOLETE_FUNCTIONS can exceptionally be used outside of imconfig.h.
+ void* RenderDrawListsFnDummy;
#endif
//------------------------------------------------------------------
@@ -1097,6 +1108,7 @@ struct ImGuiIO
bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, imgui will use the keyboard inputs, do not dispatch them to your main game/application (in both cases, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.).
bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active).
bool WantSetMousePos; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled.
+ bool WantSaveIniSettings; // If io.IniFilename == NULL, this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. IMPORTANT: You need to clear io.WantSaveIniSettings yourself.
bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag.
bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events).
float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames
@@ -1135,6 +1147,11 @@ struct ImGuiIO
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui
{
+ // OBSOLETED in 1.61 (from Apr 2018)
+ bool InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags = 0); // Use the 'const char* format' version instead of 'decimal_precision'!
+ bool InputFloat2(const char* label, float v[2], int decimal_precision, ImGuiInputTextFlags extra_flags = 0);
+ bool InputFloat3(const char* label, float v[3], int decimal_precision, ImGuiInputTextFlags extra_flags = 0);
+ bool InputFloat4(const char* label, float v[4], int decimal_precision, ImGuiInputTextFlags extra_flags = 0);
// OBSOLETED in 1.60 (from Dec 2017)
static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); }
static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); }
@@ -1388,7 +1405,7 @@ struct ImGuiSizeCallbackData
struct ImGuiPayload
{
// Members
- const void* Data; // Data (copied and owned by dear imgui)
+ void* Data; // Data (copied and owned by dear imgui)
int DataSize; // Data size
// [Internal]
diff --git a/imgui_demo.cpp b/imgui_demo.cpp
index cf5c9564..1482ca17 100644
--- a/imgui_demo.cpp
+++ b/imgui_demo.cpp
@@ -336,18 +336,20 @@ void ImGui::ShowDemoWindow(bool* p_open)
{
static char str0[128] = "Hello, world!";
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");
ImGui::InputInt("input int", &i0);
ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
+ static float f0 = 0.001f;
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");
+
+ static float f1 = 1.e10f;
+ ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e");
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 };
@@ -1297,10 +1299,12 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Button("LEVERAGE\nBUZZWORD", size);
ImGui::SameLine();
- ImGui::ListBoxHeader("List", size);
- ImGui::Selectable("Selected", true);
- ImGui::Selectable("Not Selected", false);
- ImGui::ListBoxFooter();
+ if (ImGui::ListBoxHeader("List", size))
+ {
+ ImGui::Selectable("Selected", true);
+ ImGui::Selectable("Not Selected", false);
+ ImGui::ListBoxFooter();
+ }
ImGui::TreePop();
}
@@ -1706,14 +1710,14 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Text("ImGui");
ImGui::Button("Apple");
static float foo = 1.0f;
- ImGui::InputFloat("red", &foo, 0.05f, 0, 3);
+ ImGui::InputFloat("red", &foo, 0.05f, 0, "%.3f");
ImGui::Text("An extra line here.");
ImGui::NextColumn();
ImGui::Text("Sailor");
ImGui::Button("Corniflower");
static float bar = 1.0f;
- ImGui::InputFloat("blue", &bar, 0.05f, 0, 3);
+ ImGui::InputFloat("blue", &bar, 0.05f, 0, "%.3f");
ImGui::NextColumn();
if (ImGui::CollapsingHeader("Category A")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn();
@@ -2285,7 +2289,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base+n));
draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50));
- font->RenderChar(draw_list, cell_size, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string.
+ if (glyph)
+ font->RenderChar(draw_list, cell_size, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string.
if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2))
{
ImGui::BeginTooltip();
diff --git a/imgui_draw.cpp b/imgui_draw.cpp
index c76ea79f..e67d5519 100644
--- a/imgui_draw.cpp
+++ b/imgui_draw.cpp
@@ -244,8 +244,6 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
- //colors[ImGuiCol_TextHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
- //colors[ImGuiCol_TextActive] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.98f);
@@ -1543,7 +1541,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
{
- int data_size = 0;
+ size_t data_size = 0;
void* data = ImFileLoadToMemory(filename, "rb", &data_size, 0);
if (!data)
{
@@ -1558,7 +1556,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels);
}
- return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges);
+ return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
}
// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build().
@@ -1776,19 +1774,34 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
buf_packedchars_n += range.num_chars;
}
- // Pack
+ // Gather the sizes of all rectangle we need
tmp.Rects = buf_rects + buf_rects_n;
tmp.RectsCount = font_glyphs_count;
buf_rects_n += font_glyphs_count;
stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV);
int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects);
IM_ASSERT(n == font_glyphs_count);
+
+ // Detect missing glyphs and replace them with a zero-sized box instead of relying on the default glyphs
+ // This allows us merging overlapping icon fonts more easily.
+ int rect_i = 0;
+ for (int range_i = 0; range_i < tmp.RangesCount; range_i++)
+ for (int char_i = 0; char_i < tmp.Ranges[range_i].num_chars; char_i++, rect_i++)
+ if (stbtt_FindGlyphIndex(&tmp.FontInfo, tmp.Ranges[range_i].first_unicode_codepoint_in_range + char_i) == 0)
+ tmp.Rects[rect_i].w = tmp.Rects[rect_i].h = 0;
+
+ // Pack
stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n);
// Extend texture height
+ // Also mark missing glyphs as non-packed so we don't attempt to render into them
for (int i = 0; i < n; i++)
+ {
+ if (tmp.Rects[i].w == 0 && tmp.Rects[i].h == 0)
+ tmp.Rects[i].was_packed = 0;
if (tmp.Rects[i].was_packed)
atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h);
+ }
}
IM_ASSERT(buf_rects_n == total_glyphs_count);
IM_ASSERT(buf_packedchars_n == total_glyphs_count);
diff --git a/imgui_internal.h b/imgui_internal.h
index c7bdad91..a0b6f2f9 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -96,7 +96,7 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons
// Helpers: Misc
IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings
-IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0);
+IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size = NULL, int padding_bytes = 0);
IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode);
static inline bool ImCharIsSpace(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
@@ -246,7 +246,8 @@ enum ImGuiPlotType
enum ImGuiDataType
{
- ImGuiDataType_Int,
+ ImGuiDataType_Int32,
+ ImGuiDataType_Uint32,
ImGuiDataType_Float,
ImGuiDataType_Double,
ImGuiDataType_COUNT
@@ -720,14 +721,15 @@ struct ImGuiContext
// Settings
bool SettingsLoaded;
- float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero
- ImVector SettingsWindows; // .ini settings for ImGuiWindow
+ float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero
+ ImGuiTextBuffer SettingsIniData; // In memory .ini settings
ImVector SettingsHandlers; // List of .ini settings handlers
+ ImVector SettingsWindows; // ImGuiWindow .ini settings entries (parsed from the last loaded .ini file and maintained on saving)
// Logging
bool LogEnabled;
FILE* LogFile; // If != NULL log to stdout/ file
- ImGuiTextBuffer* LogClipboard; // Else log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
+ ImGuiTextBuffer LogClipboard; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
int LogStartDepth;
int LogAutoExpandMaxDepth;
@@ -831,7 +833,6 @@ struct ImGuiContext
LogEnabled = false;
LogFile = NULL;
- LogClipboard = NULL;
LogStartDepth = 0;
LogAutoExpandMaxDepth = 2;
@@ -1085,6 +1086,7 @@ namespace ImGui
// Settings
IMGUI_API void MarkIniSettingsDirty();
+ IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window);
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
@@ -1161,19 +1163,19 @@ namespace ImGui
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
- IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0);
- IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power);
- IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format);
+ IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, const char* format, float power, ImGuiSliderFlags flags = 0);
+ IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* format, float power);
+ IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* format);
- IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power);
- IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power);
- IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format);
+ IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, const char* format, float power);
+ IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* format, float power);
+ IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* format);
IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
- IMGUI_API bool InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags);
+ IMGUI_API bool InputFloatN(const char* label, float* v, int components, const char* format, ImGuiInputTextFlags extra_flags);
IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags);
- IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags);
- IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision);
+ IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* format, ImGuiInputTextFlags extra_flags = 0);
+ IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format);
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags);
@@ -1184,8 +1186,10 @@ namespace ImGui
IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);
- IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value);
- IMGUI_API float RoundScalar(float value, int decimal_precision);
+ IMGUI_API const char* ParseFormatTrimDecorationsLeading(const char* format);
+ IMGUI_API const char* ParseFormatTrimDecorations(const char* format, char* buf, int buf_size);
+ IMGUI_API int ParseFormatPrecision(const char* format, int default_value);
+ IMGUI_API float RoundScalarWithFormat(const char* format, float value);
// Shade functions (write over already created vertices)
IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1);
diff --git a/misc/fonts/README.txt b/misc/fonts/README.txt
index f7468f02..9ef6811e 100644
--- a/misc/fonts/README.txt
+++ b/misc/fonts/README.txt
@@ -49,8 +49,9 @@ In this document:
io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges);
// Usage, e.g.
- ImGui::Text("%s Search", ICON_FA_SEARCH);
-
+ ImGui::Button(ICON_FA_SEARCH " Search"); // C string literals can be concatenated at compilation time, this is the same as "A" "B" becoming "AB"
+ ImGui::Text("%s among %d items", ICON_FA_SEARCH, count);
+
See Links below for other icons fonts and related tools.
diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp
index 8235ac5f..f7233bc3 100644
--- a/misc/freetype/imgui_freetype.cpp
+++ b/misc/freetype/imgui_freetype.cpp
@@ -182,6 +182,8 @@ namespace
bool FreeTypeFont::CalcGlyphInfo(uint32_t codepoint, GlyphInfo &glyph_info, FT_Glyph& ft_glyph, FT_BitmapGlyph& ft_bitmap)
{
uint32_t glyph_index = FT_Get_Char_Index(FreetypeFace, codepoint);
+ if (glyph_index == 0)
+ return false;
FT_Error error = FT_Load_Glyph(FreetypeFace, glyph_index, FreetypeLoadFlags);
if (error)
return false;
diff --git a/stb_textedit.h b/stb_textedit.h
index 7324fb6b..270153c1 100644
--- a/stb_textedit.h
+++ b/stb_textedit.h
@@ -1,4 +1,4 @@
-// [ImGui] this is a slightly modified version of stb_truetype.h 1.9. Those changes would need to be pushed into nothings/sb
+// [ImGui] this is a slightly modified version of stb_textedit.h 1.9. Those changes would need to be pushed into nothings/stb
// [ImGui] - fixed linestart handler when over last character of multi-line buffer + simplified existing code (#588, #815)
// [ImGui] - fixed a state corruption/crash bug in stb_text_redo and stb_textedit_discard_redo (#715)
// [ImGui] - fixed a crash bug in stb_textedit_discard_redo (#681)