|
@@ -1,4 +1,4 @@
|
|
-// dear imgui, v1.74 WIP
|
|
|
|
|
|
+// dear imgui, v1.74
|
|
// (main code and documentation)
|
|
// (main code and documentation)
|
|
|
|
|
|
// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code.
|
|
// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code.
|
|
@@ -29,12 +29,12 @@ DOCUMENTATION
|
|
- MISSION STATEMENT
|
|
- MISSION STATEMENT
|
|
- END-USER GUIDE
|
|
- END-USER GUIDE
|
|
- PROGRAMMER GUIDE
|
|
- PROGRAMMER GUIDE
|
|
- - Read first.
|
|
|
|
- - How to update to a newer version of Dear ImGui.
|
|
|
|
- - Getting started with integrating Dear ImGui in your code/engine.
|
|
|
|
- - This is how a simple application may look like (2 variations).
|
|
|
|
- - This is how a simple rendering function may look like.
|
|
|
|
- - Using gamepad/keyboard navigation controls.
|
|
|
|
|
|
+ - READ FIRST
|
|
|
|
+ - HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
|
|
|
|
+ - GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE
|
|
|
|
+ - HOW A SIMPLE APPLICATION MAY LOOK LIKE (2 variations)
|
|
|
|
+ - HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
|
|
|
|
+ - USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS
|
|
- API BREAKING CHANGES (read me when you update!)
|
|
- API BREAKING CHANGES (read me when you update!)
|
|
- FREQUENTLY ASKED QUESTIONS (FAQ)
|
|
- FREQUENTLY ASKED QUESTIONS (FAQ)
|
|
- Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
|
|
- Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
|
|
@@ -45,7 +45,8 @@ CODE
|
|
// [SECTION] FORWARD DECLARATIONS
|
|
// [SECTION] FORWARD DECLARATIONS
|
|
// [SECTION] CONTEXT AND MEMORY ALLOCATORS
|
|
// [SECTION] CONTEXT AND MEMORY ALLOCATORS
|
|
// [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
|
|
// [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
|
|
-// [SECTION] MISC HELPERS/UTILITIES (Maths, String, Format, Hash, File functions)
|
|
|
|
|
|
+// [SECTION] MISC HELPERS/UTILITIES (Geomtry, String, Format, Hash, File functions)
|
|
|
|
+// [SECTION] MISC HELPERS/UTILITIES (File functions)
|
|
// [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
|
|
// [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
|
|
// [SECTION] MISC HELPERS/UTILITIES (Color functions)
|
|
// [SECTION] MISC HELPERS/UTILITIES (Color functions)
|
|
// [SECTION] ImGuiStorage
|
|
// [SECTION] ImGuiStorage
|
|
@@ -120,8 +121,8 @@ CODE
|
|
PROGRAMMER GUIDE
|
|
PROGRAMMER GUIDE
|
|
================
|
|
================
|
|
|
|
|
|
- READ FIRST:
|
|
|
|
-
|
|
|
|
|
|
+ READ FIRST
|
|
|
|
+ ----------
|
|
- Remember to read the FAQ (https://www.dearimgui.org/faq)
|
|
- Remember to read the FAQ (https://www.dearimgui.org/faq)
|
|
- Your code creates the UI, if your code doesn't run the UI is gone! The UI can be highly dynamic, there are no construction
|
|
- Your code creates the UI, if your code doesn't run the UI is gone! The UI can be highly dynamic, there are no construction
|
|
or destruction steps, less superfluous data retention on your side, less state duplication, less state synchronization, less bugs.
|
|
or destruction steps, less superfluous data retention on your side, less state duplication, less state synchronization, less bugs.
|
|
@@ -142,8 +143,8 @@ CODE
|
|
However, imgui_internal.h can optionally export math operators for ImVec2/ImVec4, which we use in this codebase.
|
|
However, imgui_internal.h can optionally export math operators for ImVec2/ImVec4, which we use in this codebase.
|
|
- C++: pay attention that ImVector<> manipulates plain-old-data and does not honor construction/destruction (avoid using it in your code!).
|
|
- C++: pay attention that ImVector<> manipulates plain-old-data and does not honor construction/destruction (avoid using it in your code!).
|
|
|
|
|
|
- HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI:
|
|
|
|
-
|
|
|
|
|
|
+ HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
|
|
|
|
+ ----------------------------------------------
|
|
- Overwrite all the sources files except for imconfig.h (if you have made modification to your copy of imconfig.h)
|
|
- Overwrite all the sources files except for imconfig.h (if you have made modification to your copy of imconfig.h)
|
|
- Or maintain your own branch where you have imconfig.h modified.
|
|
- Or maintain your own branch where you have imconfig.h modified.
|
|
- Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes.
|
|
- Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes.
|
|
@@ -152,8 +153,8 @@ CODE
|
|
likely be a comment about it. Please report any issue to the GitHub page!
|
|
likely be a comment about it. Please report any issue to the GitHub page!
|
|
- Try to keep your copy of dear imgui reasonably up to date.
|
|
- Try to keep your copy of dear imgui reasonably up to date.
|
|
|
|
|
|
- GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE:
|
|
|
|
-
|
|
|
|
|
|
+ GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE
|
|
|
|
+ ---------------------------------------------------------------
|
|
- Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library.
|
|
- Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library.
|
|
- Add the Dear ImGui source files to your projects or using your preferred build system.
|
|
- Add the Dear ImGui source files to your projects or using your preferred build system.
|
|
It is recommended you build and statically link the .cpp files as part of your project and not as shared library (DLL).
|
|
It is recommended you build and statically link the .cpp files as part of your project and not as shared library (DLL).
|
|
@@ -165,7 +166,8 @@ CODE
|
|
- Refer to the bindings and demo applications in the examples/ folder for instruction on how to setup your code.
|
|
- Refer to the bindings and demo applications in the examples/ folder for instruction on how to setup your code.
|
|
- If you are running over a standard OS with a common graphics API, you should be able to use unmodified imgui_impl_*** files from the examples/ folder.
|
|
- If you are running over a standard OS with a common graphics API, you should be able to use unmodified imgui_impl_*** files from the examples/ folder.
|
|
|
|
|
|
- HOW A SIMPLE APPLICATION MAY LOOK LIKE:
|
|
|
|
|
|
+ HOW A SIMPLE APPLICATION MAY LOOK LIKE
|
|
|
|
+ --------------------------------------
|
|
EXHIBIT 1: USING THE EXAMPLE BINDINGS (imgui_impl_XXX.cpp files from the examples/ folder).
|
|
EXHIBIT 1: USING THE EXAMPLE BINDINGS (imgui_impl_XXX.cpp files from the examples/ folder).
|
|
|
|
|
|
// Application init: create a dear imgui context, setup some options, load fonts
|
|
// Application init: create a dear imgui context, setup some options, load fonts
|
|
@@ -201,8 +203,7 @@ CODE
|
|
ImGui_ImplWin32_Shutdown();
|
|
ImGui_ImplWin32_Shutdown();
|
|
ImGui::DestroyContext();
|
|
ImGui::DestroyContext();
|
|
|
|
|
|
- HOW A SIMPLE APPLICATION MAY LOOK LIKE:
|
|
|
|
- EXHIBIT 2: IMPLEMENTING CUSTOM BINDING / CUSTOM ENGINE.
|
|
|
|
|
|
+ EXHIBIT 2: IMPLEMENTING CUSTOM BINDING / CUSTOM ENGINE
|
|
|
|
|
|
// Application init: create a dear imgui context, setup some options, load fonts
|
|
// Application init: create a dear imgui context, setup some options, load fonts
|
|
ImGui::CreateContext();
|
|
ImGui::CreateContext();
|
|
@@ -256,8 +257,8 @@ CODE
|
|
// Shutdown
|
|
// Shutdown
|
|
ImGui::DestroyContext();
|
|
ImGui::DestroyContext();
|
|
|
|
|
|
- HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE:
|
|
|
|
-
|
|
|
|
|
|
+ HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
|
|
|
|
+ ---------------------------------------------
|
|
void void MyImGuiRenderFunction(ImDrawData* draw_data)
|
|
void void MyImGuiRenderFunction(ImDrawData* draw_data)
|
|
{
|
|
{
|
|
// TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
|
|
// TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
|
|
@@ -294,7 +295,7 @@ CODE
|
|
MyEngineScissor((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y));
|
|
MyEngineScissor((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y));
|
|
|
|
|
|
// Render 'pcmd->ElemCount/3' indexed triangles.
|
|
// Render 'pcmd->ElemCount/3' indexed triangles.
|
|
- // By default the indices ImDrawIdx are 16-bits, you can change them to 32-bits in imconfig.h if your engine doesn't support 16-bits indices.
|
|
|
|
|
|
+ // By default the indices ImDrawIdx are 16-bit, you can change them to 32-bit in imconfig.h if your engine doesn't support 16-bit indices.
|
|
MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer, vtx_buffer);
|
|
MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer, vtx_buffer);
|
|
}
|
|
}
|
|
idx_buffer += pcmd->ElemCount;
|
|
idx_buffer += pcmd->ElemCount;
|
|
@@ -309,7 +310,7 @@ CODE
|
|
- Refer to the FAQ for more information. Amusingly, it is called a FAQ because people frequently run into the same issues!
|
|
- Refer to the FAQ for more information. Amusingly, it is called a FAQ because people frequently run into the same issues!
|
|
|
|
|
|
USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS
|
|
USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS
|
|
-
|
|
|
|
|
|
+ ------------------------------------------
|
|
- The gamepad/keyboard navigation is fairly functional and keeps being improved.
|
|
- The gamepad/keyboard navigation is fairly functional and keeps being improved.
|
|
- Gamepad support is particularly useful to use dear imgui on a console system (e.g. PS4, Switch, XB1) without a mouse!
|
|
- Gamepad support is particularly useful to use dear imgui on a console system (e.g. PS4, Switch, XB1) without a mouse!
|
|
- You can ask questions and report issues at https://github.com/ocornut/imgui/issues/787
|
|
- You can ask questions and report issues at https://github.com/ocornut/imgui/issues/787
|
|
@@ -363,6 +364,9 @@ CODE
|
|
- 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
|
- 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
|
|
|
|
|
|
|
|
|
|
|
+ - 2019/11/21 (1.74) - ImFontAtlas::AddCustomRectRegular() now requires an ID larger than 0x110000 (instead of 0x10000) to conform with supporting Unicode planes 1-16 in a future update. ID below 0x110000 will now assert.
|
|
|
|
+ - 2019/11/19 (1.74) - renamed IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS to IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS for consistency.
|
|
|
|
+ - 2019/11/19 (1.74) - renamed IMGUI_DISABLE_MATH_FUNCTIONS to IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS for consistency.
|
|
- 2019/10/22 (1.74) - removed redirecting functions/enums that were marked obsolete in 1.52 (October 2017): Begin() (5 arguments signature), IsRootWindowOrAnyChildHovered(), AlignFirstTextHeightToWidgets(), SetNextWindowPosCenter(), ImFont::Glyph. See docs/Changelog.txt or grep this log for details and new names, or see how they were implemented until 1.73.
|
|
- 2019/10/22 (1.74) - removed redirecting functions/enums that were marked obsolete in 1.52 (October 2017): Begin() (5 arguments signature), IsRootWindowOrAnyChildHovered(), AlignFirstTextHeightToWidgets(), SetNextWindowPosCenter(), ImFont::Glyph. See docs/Changelog.txt or grep this log for details and new names, or see how they were implemented until 1.73.
|
|
- 2019/10/14 (1.74) - inputs: Fixed a miscalculation in the keyboard/mouse "typematic" repeat delay/rate calculation, used by keys and e.g. repeating mouse buttons as well as the GetKeyPressedAmount() function.
|
|
- 2019/10/14 (1.74) - inputs: Fixed a miscalculation in the keyboard/mouse "typematic" repeat delay/rate calculation, used by keys and e.g. repeating mouse buttons as well as the GetKeyPressedAmount() function.
|
|
if you were using a non-default value for io.KeyRepeatRate (previous default was 0.250), you can add +io.KeyRepeatDelay to it to compensate for the fix.
|
|
if you were using a non-default value for io.KeyRepeatRate (previous default was 0.250), you can add +io.KeyRepeatDelay to it to compensate for the fix.
|
|
@@ -481,14 +485,9 @@ CODE
|
|
- 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc.
|
|
- 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc.
|
|
- 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal.
|
|
- 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal.
|
|
- 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore.
|
|
- 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore.
|
|
- If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you.
|
|
|
|
- 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.
|
|
|
|
- ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col)
|
|
|
|
- {
|
|
|
|
- float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)), k = title_bg_col.w / new_a;
|
|
|
|
- return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a);
|
|
|
|
- }
|
|
|
|
|
|
+ If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you, otherwise if <1.0f you need 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:
|
|
|
|
+ ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col) { float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)), k = title_bg_col.w / new_a; return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a); }
|
|
If this is confusing, 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.
|
|
If this is confusing, 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.
|
|
- 2016/05/07 (1.49) - removed confusing set of GetInternalState(), GetInternalStateSize(), SetInternalState() functions. Now using CreateContext(), DestroyContext(), GetCurrentContext(), SetCurrentContext().
|
|
- 2016/05/07 (1.49) - removed confusing set of GetInternalState(), GetInternalStateSize(), SetInternalState() functions. Now using CreateContext(), DestroyContext(), GetCurrentContext(), SetCurrentContext().
|
|
- 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection.
|
|
- 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection.
|
|
@@ -758,7 +757,7 @@ CODE
|
|
Q: How can I easily use icons in my application?
|
|
Q: How can I easily use icons in my application?
|
|
Q: How can I load multiple fonts?
|
|
Q: How can I load multiple fonts?
|
|
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
|
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
|
- >> See https://www.dearimgui.org/faq and misc/fonts/README.txt
|
|
|
|
|
|
+ >> See https://www.dearimgui.org/faq and docs/FONTS.txt
|
|
|
|
|
|
Q&A: Community
|
|
Q&A: Community
|
|
==============
|
|
==============
|
|
@@ -1100,7 +1099,7 @@ ImGuiIO::ImGuiIO()
|
|
// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message
|
|
// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message
|
|
void ImGuiIO::AddInputCharacter(unsigned int c)
|
|
void ImGuiIO::AddInputCharacter(unsigned int c)
|
|
{
|
|
{
|
|
- if (c > 0 && c < 0x10000)
|
|
|
|
|
|
+ if (c > 0 && c <= IM_UNICODE_CODEPOINT_MAX)
|
|
InputQueueCharacters.push_back((ImWchar)c);
|
|
InputQueueCharacters.push_back((ImWchar)c);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1110,7 +1109,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
|
|
{
|
|
{
|
|
unsigned int c = 0;
|
|
unsigned int c = 0;
|
|
utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL);
|
|
utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL);
|
|
- if (c > 0 && c < 0x10000)
|
|
|
|
|
|
+ if (c > 0 && c <= IM_UNICODE_CODEPOINT_MAX)
|
|
InputQueueCharacters.push_back((ImWchar)c);
|
|
InputQueueCharacters.push_back((ImWchar)c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1121,7 +1120,7 @@ void ImGuiIO::ClearInputCharacters()
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
-// [SECTION] MISC HELPERS/UTILITIES (Maths, String, Format, Hash, File functions)
|
|
|
|
|
|
+// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions)
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p)
|
|
ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p)
|
|
@@ -1225,7 +1224,7 @@ const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
|
|
|
|
|
int ImStrlenW(const ImWchar* str)
|
|
int ImStrlenW(const ImWchar* str)
|
|
{
|
|
{
|
|
- //return (int)wcslen((const wchar_t*)str); // FIXME-OPT: Could use this when wchar_t are 16-bits
|
|
|
|
|
|
+ //return (int)wcslen((const wchar_t*)str); // FIXME-OPT: Could use this when wchar_t are 16-bit
|
|
int n = 0;
|
|
int n = 0;
|
|
while (*str++) n++;
|
|
while (*str++) n++;
|
|
return n;
|
|
return n;
|
|
@@ -1293,12 +1292,16 @@ const char* ImStrSkipBlank(const char* str)
|
|
// A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size).
|
|
// A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size).
|
|
// Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm.
|
|
// Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm.
|
|
// B) When buf==NULL vsnprintf() will return the output size.
|
|
// B) When buf==NULL vsnprintf() will return the output size.
|
|
-#ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
|
|
|
|
|
|
+#ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
|
|
|
|
|
|
|
|
+// We support stb_sprintf which is much faster (see: https://github.com/nothings/stb/blob/master/stb_sprintf.h)
|
|
|
|
+// You may set IMGUI_USE_STB_SPRINTF to use our default wrapper, or set IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
|
|
|
|
+// and setup the wrapper yourself. (FIXME-OPT: Some of our high-level operations such as ImGuiTextBuffer::appendfv() are
|
|
|
|
+// designed using two-passes worst case, which probably could be improved using the stbsp_vsprintfcb() function.)
|
|
//#define IMGUI_USE_STB_SPRINTF
|
|
//#define IMGUI_USE_STB_SPRINTF
|
|
#ifdef IMGUI_USE_STB_SPRINTF
|
|
#ifdef IMGUI_USE_STB_SPRINTF
|
|
#define STB_SPRINTF_IMPLEMENTATION
|
|
#define STB_SPRINTF_IMPLEMENTATION
|
|
-#include "imstb_sprintf.h"
|
|
|
|
|
|
+#include "stb_sprintf.h"
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#if defined(_MSC_VER) && !defined(vsnprintf)
|
|
#if defined(_MSC_VER) && !defined(vsnprintf)
|
|
@@ -1337,7 +1340,7 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
|
|
buf[w] = 0;
|
|
buf[w] = 0;
|
|
return w;
|
|
return w;
|
|
}
|
|
}
|
|
-#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
|
|
|
|
|
|
+#endif // #ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
|
|
|
|
|
|
// CRC32 needs a 1KB lookup table (not cache friendly)
|
|
// CRC32 needs a 1KB lookup table (not cache friendly)
|
|
// Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily:
|
|
// Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily:
|
|
@@ -1409,10 +1412,16 @@ ImU32 ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
|
|
return ~crc;
|
|
return ~crc;
|
|
}
|
|
}
|
|
|
|
|
|
-FILE* ImFileOpen(const char* filename, const char* mode)
|
|
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
+// [SECTION] MISC HELPERS/UTILITIES (File functions)
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
+
|
|
|
|
+// Default file functions
|
|
|
|
+#ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
|
|
|
+ImFileHandle ImFileOpen(const char* filename, const char* mode)
|
|
{
|
|
{
|
|
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
|
|
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
|
|
- // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. Converting both strings from UTF-8 to wchar format (using a single allocation, because we can)
|
|
|
|
|
|
+ // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.
|
|
const int filename_wsize = ImTextCountCharsFromUtf8(filename, NULL) + 1;
|
|
const int filename_wsize = ImTextCountCharsFromUtf8(filename, NULL) + 1;
|
|
const int mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1;
|
|
const int mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1;
|
|
ImVector<ImWchar> buf;
|
|
ImVector<ImWchar> buf;
|
|
@@ -1425,42 +1434,48 @@ FILE* ImFileOpen(const char* filename, const char* mode)
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
-// Load file content into memory
|
|
|
|
|
|
+// We should in theory be using fseeko()/ftello() with off_t and _fseeki64()/_ftelli64() with __int64, waiting for the PR that does that in a very portable pre-C++11 zero-warnings way.
|
|
|
|
+bool ImFileClose(ImFileHandle f) { return fclose(f) == 0; }
|
|
|
|
+ImU64 ImFileGetSize(ImFileHandle f) { long off = 0, sz = 0; return ((off = ftell(f)) != -1 && !fseek(f, 0, SEEK_END) && (sz = ftell(f)) != -1 && !fseek(f, off, SEEK_SET)) ? (ImU64)sz : (ImU64)-1; }
|
|
|
|
+ImU64 ImFileRead(void* data, ImU64 sz, ImU64 count, ImFileHandle f) { return fread(data, (size_t)sz, (size_t)count, f); }
|
|
|
|
+ImU64 ImFileWrite(const void* data, ImU64 sz, ImU64 count, ImFileHandle f) { return fwrite(data, (size_t)sz, (size_t)count, f); }
|
|
|
|
+#endif // #ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
|
|
|
+
|
|
|
|
+// Helper: Load file content into memory
|
|
// Memory allocated with IM_ALLOC(), must be freed by user using IM_FREE() == ImGui::MemFree()
|
|
// Memory allocated with IM_ALLOC(), must be freed by user using IM_FREE() == ImGui::MemFree()
|
|
-void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size, int padding_bytes)
|
|
|
|
|
|
+void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size, int padding_bytes)
|
|
{
|
|
{
|
|
- IM_ASSERT(filename && file_open_mode);
|
|
|
|
|
|
+ IM_ASSERT(filename && mode);
|
|
if (out_file_size)
|
|
if (out_file_size)
|
|
*out_file_size = 0;
|
|
*out_file_size = 0;
|
|
|
|
|
|
- FILE* f;
|
|
|
|
- if ((f = ImFileOpen(filename, file_open_mode)) == NULL)
|
|
|
|
|
|
+ ImFileHandle f;
|
|
|
|
+ if ((f = ImFileOpen(filename, mode)) == NULL)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
- long file_size_signed;
|
|
|
|
- if (fseek(f, 0, SEEK_END) || (file_size_signed = ftell(f)) == -1 || fseek(f, 0, SEEK_SET))
|
|
|
|
|
|
+ size_t file_size = (size_t)ImFileGetSize(f);
|
|
|
|
+ if (file_size == (size_t)-1)
|
|
{
|
|
{
|
|
- fclose(f);
|
|
|
|
|
|
+ ImFileClose(f);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- size_t file_size = (size_t)file_size_signed;
|
|
|
|
void* file_data = IM_ALLOC(file_size + padding_bytes);
|
|
void* file_data = IM_ALLOC(file_size + padding_bytes);
|
|
if (file_data == NULL)
|
|
if (file_data == NULL)
|
|
{
|
|
{
|
|
- fclose(f);
|
|
|
|
|
|
+ ImFileClose(f);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
- if (fread(file_data, 1, file_size, f) != file_size)
|
|
|
|
|
|
+ if (ImFileRead(file_data, 1, file_size, f) != file_size)
|
|
{
|
|
{
|
|
- fclose(f);
|
|
|
|
|
|
+ ImFileClose(f);
|
|
IM_FREE(file_data);
|
|
IM_FREE(file_data);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
if (padding_bytes > 0)
|
|
if (padding_bytes > 0)
|
|
memset((void*)(((char*)file_data) + file_size), 0, (size_t)padding_bytes);
|
|
memset((void*)(((char*)file_data) + file_size), 0, (size_t)padding_bytes);
|
|
|
|
|
|
- fclose(f);
|
|
|
|
|
|
+ ImFileClose(f);
|
|
if (out_file_size)
|
|
if (out_file_size)
|
|
*out_file_size = file_size;
|
|
*out_file_size = file_size;
|
|
|
|
|
|
@@ -1471,7 +1486,7 @@ void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_
|
|
// [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
|
|
// [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
-// Convert UTF-8 to 32-bits character, process single character input.
|
|
|
|
|
|
+// Convert UTF-8 to 32-bit character, process single character input.
|
|
// Based on stb_from_utf8() from github.com/nothings/stb/
|
|
// Based on stb_from_utf8() from github.com/nothings/stb/
|
|
// We handle UTF-8 decoding error by skipping forward.
|
|
// We handle UTF-8 decoding error by skipping forward.
|
|
int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end)
|
|
int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end)
|
|
@@ -1486,7 +1501,7 @@ int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char*
|
|
}
|
|
}
|
|
if ((*str & 0xe0) == 0xc0)
|
|
if ((*str & 0xe0) == 0xc0)
|
|
{
|
|
{
|
|
- *out_char = 0xFFFD; // will be invalid but not end of string
|
|
|
|
|
|
+ *out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
|
|
if (in_text_end && in_text_end - (const char*)str < 2) return 1;
|
|
if (in_text_end && in_text_end - (const char*)str < 2) return 1;
|
|
if (*str < 0xc2) return 2;
|
|
if (*str < 0xc2) return 2;
|
|
c = (unsigned int)((*str++ & 0x1f) << 6);
|
|
c = (unsigned int)((*str++ & 0x1f) << 6);
|
|
@@ -1497,7 +1512,7 @@ int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char*
|
|
}
|
|
}
|
|
if ((*str & 0xf0) == 0xe0)
|
|
if ((*str & 0xf0) == 0xe0)
|
|
{
|
|
{
|
|
- *out_char = 0xFFFD; // will be invalid but not end of string
|
|
|
|
|
|
+ *out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
|
|
if (in_text_end && in_text_end - (const char*)str < 3) return 1;
|
|
if (in_text_end && in_text_end - (const char*)str < 3) return 1;
|
|
if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3;
|
|
if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3;
|
|
if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below
|
|
if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below
|
|
@@ -1511,7 +1526,7 @@ int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char*
|
|
}
|
|
}
|
|
if ((*str & 0xf8) == 0xf0)
|
|
if ((*str & 0xf8) == 0xf0)
|
|
{
|
|
{
|
|
- *out_char = 0xFFFD; // will be invalid but not end of string
|
|
|
|
|
|
+ *out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
|
|
if (in_text_end && in_text_end - (const char*)str < 4) return 1;
|
|
if (in_text_end && in_text_end - (const char*)str < 4) return 1;
|
|
if (*str > 0xf4) return 4;
|
|
if (*str > 0xf4) return 4;
|
|
if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 4;
|
|
if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 4;
|
|
@@ -1542,7 +1557,7 @@ int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const cha
|
|
in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
|
|
in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
|
|
if (c == 0)
|
|
if (c == 0)
|
|
break;
|
|
break;
|
|
- if (c < 0x10000) // FIXME: Losing characters that don't fit in 2 bytes
|
|
|
|
|
|
+ if (c <= IM_UNICODE_CODEPOINT_MAX) // FIXME: Losing characters that don't fit in 2 bytes
|
|
*buf_out++ = (ImWchar)c;
|
|
*buf_out++ = (ImWchar)c;
|
|
}
|
|
}
|
|
*buf_out = 0;
|
|
*buf_out = 0;
|
|
@@ -1560,7 +1575,7 @@ int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end)
|
|
in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
|
|
in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
|
|
if (c == 0)
|
|
if (c == 0)
|
|
break;
|
|
break;
|
|
- if (c < 0x10000)
|
|
|
|
|
|
+ if (c <= IM_UNICODE_CODEPOINT_MAX)
|
|
char_count++;
|
|
char_count++;
|
|
}
|
|
}
|
|
return char_count;
|
|
return char_count;
|
|
@@ -4071,9 +4086,12 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|
g.SettingsWindows.clear();
|
|
g.SettingsWindows.clear();
|
|
g.SettingsHandlers.clear();
|
|
g.SettingsHandlers.clear();
|
|
|
|
|
|
- if (g.LogFile && g.LogFile != stdout)
|
|
|
|
|
|
+ if (g.LogFile)
|
|
{
|
|
{
|
|
- fclose(g.LogFile);
|
|
|
|
|
|
+#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
|
|
|
|
+ if (g.LogFile != stdout)
|
|
|
|
+#endif
|
|
|
|
+ ImFileClose(g.LogFile);
|
|
g.LogFile = NULL;
|
|
g.LogFile = NULL;
|
|
}
|
|
}
|
|
g.LogBuffer.clear();
|
|
g.LogBuffer.clear();
|
|
@@ -4139,7 +4157,7 @@ static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* d
|
|
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer back-end, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
|
|
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer back-end, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
|
|
// Most example back-ends already support this from 1.71. Pre-1.71 back-ends won't.
|
|
// Most example back-ends already support this from 1.71. Pre-1.71 back-ends won't.
|
|
// Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them.
|
|
// Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them.
|
|
- // (B) Or handle 32-bits indices in your renderer back-end, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
|
|
|
|
|
|
+ // (B) Or handle 32-bit indices in your renderer back-end, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
|
|
// Most example back-ends already support this. For example, the OpenGL example code detect index size at compile-time:
|
|
// Most example back-ends already support this. For example, the OpenGL example code detect index size at compile-time:
|
|
// glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
|
// glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
|
// Your own engine or render API may use different parameters or function calls to specify index sizes.
|
|
// Your own engine or render API may use different parameters or function calls to specify index sizes.
|
|
@@ -6111,7 +6129,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
// Handle manual resize: Resize Grips, Borders, Gamepad
|
|
// Handle manual resize: Resize Grips, Borders, Gamepad
|
|
int border_held = -1;
|
|
int border_held = -1;
|
|
ImU32 resize_grip_col[4] = {};
|
|
ImU32 resize_grip_col[4] = {};
|
|
- const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // 4
|
|
|
|
|
|
+ const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
|
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
|
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
|
if (handle_borders_and_resize_grips && !window->Collapsed)
|
|
if (handle_borders_and_resize_grips && !window->Collapsed)
|
|
if (UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
|
|
if (UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
|
|
@@ -9820,9 +9838,15 @@ void ImGui::LogText(const char* fmt, ...)
|
|
va_list args;
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
va_start(args, fmt);
|
|
if (g.LogFile)
|
|
if (g.LogFile)
|
|
- vfprintf(g.LogFile, fmt, args);
|
|
|
|
|
|
+ {
|
|
|
|
+ g.LogBuffer.Buf.resize(0);
|
|
|
|
+ g.LogBuffer.appendfv(fmt, args);
|
|
|
|
+ ImFileWrite(g.LogBuffer.c_str(), sizeof(char), (ImU64)g.LogBuffer.size(), g.LogFile);
|
|
|
|
+ }
|
|
else
|
|
else
|
|
|
|
+ {
|
|
g.LogBuffer.appendfv(fmt, args);
|
|
g.LogBuffer.appendfv(fmt, args);
|
|
|
|
+ }
|
|
va_end(args);
|
|
va_end(args);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -9899,8 +9923,11 @@ void ImGui::LogToTTY(int auto_open_depth)
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
if (g.LogEnabled)
|
|
if (g.LogEnabled)
|
|
return;
|
|
return;
|
|
|
|
+ IM_UNUSED(auto_open_depth);
|
|
|
|
+#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
|
|
LogBegin(ImGuiLogType_TTY, auto_open_depth);
|
|
LogBegin(ImGuiLogType_TTY, auto_open_depth);
|
|
g.LogFile = stdout;
|
|
g.LogFile = stdout;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
// Start logging/capturing text output to given file
|
|
// Start logging/capturing text output to given file
|
|
@@ -9917,8 +9944,8 @@ void ImGui::LogToFile(int auto_open_depth, const char* filename)
|
|
filename = g.IO.LogFilename;
|
|
filename = g.IO.LogFilename;
|
|
if (!filename || !filename[0])
|
|
if (!filename || !filename[0])
|
|
return;
|
|
return;
|
|
- FILE* f = ImFileOpen(filename, "ab");
|
|
|
|
- if (f == NULL)
|
|
|
|
|
|
+ ImFileHandle f = ImFileOpen(filename, "ab");
|
|
|
|
+ if (!f)
|
|
{
|
|
{
|
|
IM_ASSERT(0);
|
|
IM_ASSERT(0);
|
|
return;
|
|
return;
|
|
@@ -9955,10 +9982,12 @@ void ImGui::LogFinish()
|
|
switch (g.LogType)
|
|
switch (g.LogType)
|
|
{
|
|
{
|
|
case ImGuiLogType_TTY:
|
|
case ImGuiLogType_TTY:
|
|
|
|
+#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
|
|
fflush(g.LogFile);
|
|
fflush(g.LogFile);
|
|
|
|
+#endif
|
|
break;
|
|
break;
|
|
case ImGuiLogType_File:
|
|
case ImGuiLogType_File:
|
|
- fclose(g.LogFile);
|
|
|
|
|
|
+ ImFileClose(g.LogFile);
|
|
break;
|
|
break;
|
|
case ImGuiLogType_Buffer:
|
|
case ImGuiLogType_Buffer:
|
|
break;
|
|
break;
|
|
@@ -9984,7 +10013,11 @@ void ImGui::LogButtons()
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
PushID("LogButtons");
|
|
PushID("LogButtons");
|
|
|
|
+#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
|
|
const bool log_to_tty = Button("Log To TTY"); SameLine();
|
|
const bool log_to_tty = Button("Log To TTY"); SameLine();
|
|
|
|
+#else
|
|
|
|
+ const bool log_to_tty = false;
|
|
|
|
+#endif
|
|
const bool log_to_file = Button("Log To File"); SameLine();
|
|
const bool log_to_file = Button("Log To File"); SameLine();
|
|
const bool log_to_clipboard = Button("Log To Clipboard"); SameLine();
|
|
const bool log_to_clipboard = Button("Log To Clipboard"); SameLine();
|
|
PushAllowKeyboardFocus(false);
|
|
PushAllowKeyboardFocus(false);
|
|
@@ -10117,18 +10150,12 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
|
|
line_end[-1] = 0;
|
|
line_end[-1] = 0;
|
|
const char* name_end = line_end - 1;
|
|
const char* name_end = line_end - 1;
|
|
const char* type_start = line + 1;
|
|
const char* type_start = line + 1;
|
|
- char* type_end = (char*)(intptr_t)ImStrchrRange(type_start, name_end, ']');
|
|
|
|
|
|
+ char* type_end = (char*)(void*)ImStrchrRange(type_start, name_end, ']');
|
|
const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL;
|
|
const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL;
|
|
if (!type_end || !name_start)
|
|
if (!type_end || !name_start)
|
|
- {
|
|
|
|
- name_start = type_start; // Import legacy entries that have no type
|
|
|
|
- type_start = "Window";
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- *type_end = 0; // Overwrite first ']'
|
|
|
|
- name_start++; // Skip second '['
|
|
|
|
- }
|
|
|
|
|
|
+ continue;
|
|
|
|
+ *type_end = 0; // Overwrite first ']'
|
|
|
|
+ name_start++; // Skip second '['
|
|
entry_handler = FindSettingsHandler(type_start);
|
|
entry_handler = FindSettingsHandler(type_start);
|
|
entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL;
|
|
entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL;
|
|
}
|
|
}
|
|
@@ -10152,11 +10179,11 @@ void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
|
|
|
|
|
|
size_t ini_data_size = 0;
|
|
size_t ini_data_size = 0;
|
|
const char* ini_data = SaveIniSettingsToMemory(&ini_data_size);
|
|
const char* ini_data = SaveIniSettingsToMemory(&ini_data_size);
|
|
- FILE* f = ImFileOpen(ini_filename, "wt");
|
|
|
|
|
|
+ ImFileHandle f = ImFileOpen(ini_filename, "wt");
|
|
if (!f)
|
|
if (!f)
|
|
return;
|
|
return;
|
|
- fwrite(ini_data, sizeof(char), ini_data_size, f);
|
|
|
|
- fclose(f);
|
|
|
|
|
|
+ ImFileWrite(ini_data, sizeof(char), ini_data_size, f);
|
|
|
|
+ ImFileClose(f);
|
|
}
|
|
}
|
|
|
|
|
|
// Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer
|
|
// Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer
|
|
@@ -14767,7 +14794,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
static bool show_windows_rects = false;
|
|
static bool show_windows_rects = false;
|
|
static int show_windows_rect_type = WRT_WorkRect;
|
|
static int show_windows_rect_type = WRT_WorkRect;
|
|
static bool show_windows_begin_order = false;
|
|
static bool show_windows_begin_order = false;
|
|
- static bool show_drawcmd_clip_rects = true;
|
|
|
|
|
|
+ static bool show_drawcmd_details = true;
|
|
static bool show_docking_nodes = false;
|
|
static bool show_docking_nodes = false;
|
|
|
|
|
|
// Basic info
|
|
// Basic info
|
|
@@ -14821,9 +14848,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
return;
|
|
return;
|
|
|
|
|
|
if (window && !window->WasActive)
|
|
if (window && !window->WasActive)
|
|
- ImGui::Text("(Note: owning Window is inactive: DrawList is not being rendered!)");
|
|
|
|
|
|
+ ImGui::TextDisabled("Warning: owning Window is inactive. This DrawList is not being rendered!");
|
|
|
|
|
|
- int elem_offset = 0;
|
|
|
|
|
|
+ unsigned int elem_offset = 0;
|
|
for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++)
|
|
for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++)
|
|
{
|
|
{
|
|
if (pcmd->UserCallback == NULL && pcmd->ElemCount == 0)
|
|
if (pcmd->UserCallback == NULL && pcmd->ElemCount == 0)
|
|
@@ -14833,45 +14860,77 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData);
|
|
ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
+
|
|
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
|
|
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
|
|
char buf[300];
|
|
char buf[300];
|
|
- ImFormatString(buf, IM_ARRAYSIZE(buf), "Draw %4d triangles, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
|
|
|
|
- pcmd->ElemCount/3, (void*)(intptr_t)pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
|
|
|
|
|
|
+ ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd: %4d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
|
|
|
|
+ pcmd->ElemCount/3, (void*)(intptr_t)pcmd->TextureId,
|
|
|
|
+ pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
|
|
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
|
|
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
|
|
- if (show_drawcmd_clip_rects && fg_draw_list && ImGui::IsItemHovered())
|
|
|
|
|
|
+ if (show_drawcmd_details && fg_draw_list && ImGui::IsItemHovered())
|
|
{
|
|
{
|
|
ImRect clip_rect = pcmd->ClipRect;
|
|
ImRect clip_rect = pcmd->ClipRect;
|
|
ImRect vtxs_rect;
|
|
ImRect vtxs_rect;
|
|
- for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
|
|
|
|
|
|
+ for (unsigned int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
|
|
vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
|
|
vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
|
|
- clip_rect.Floor(); fg_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,0,255,255));
|
|
|
|
- vtxs_rect.Floor(); fg_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,255,0,255));
|
|
|
|
|
|
+ fg_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255,0,255,255));
|
|
|
|
+ fg_draw_list->AddRect(ImFloor(vtxs_rect.Min), ImFloor(vtxs_rect.Max), IM_COL32(255,255,0,255));
|
|
}
|
|
}
|
|
if (!pcmd_node_open)
|
|
if (!pcmd_node_open)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
+ // Calculate approximate coverage area (touched pixel count)
|
|
|
|
+ // This will be in pixels squared as long there's no post-scaling happening to the renderer output.
|
|
|
|
+ float total_area = 0.0f;
|
|
|
|
+ for (unsigned int base_idx = elem_offset; base_idx < (elem_offset + pcmd->ElemCount); base_idx += 3)
|
|
|
|
+ {
|
|
|
|
+ ImVec2 triangle[3];
|
|
|
|
+ for (int n = 0; n < 3; n++)
|
|
|
|
+ triangle[n] = draw_list->VtxBuffer[idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n)].pos;
|
|
|
|
+ total_area += ImTriangleArea(triangle[0], triangle[1], triangle[2]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Display vertex information summary. Hover to get all triangles drawn in wire-frame
|
|
|
|
+ ImFormatString(buf, IM_ARRAYSIZE(buf), "Mesh: ElemCount: %d, VtxOffset: +%d, IdxOffset: +%d, Area: ~%0.f px", pcmd->ElemCount, pcmd->VtxOffset, pcmd->IdxOffset, total_area);
|
|
|
|
+ ImGui::Selectable(buf);
|
|
|
|
+ if (fg_draw_list && ImGui::IsItemHovered() && show_drawcmd_details)
|
|
|
|
+ {
|
|
|
|
+ // Draw wire-frame version of everything
|
|
|
|
+ ImDrawListFlags backup_flags = fg_draw_list->Flags;
|
|
|
|
+ fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
|
|
|
|
+ ImRect clip_rect = pcmd->ClipRect;
|
|
|
|
+ fg_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255, 0, 255, 255));
|
|
|
|
+ for (unsigned int base_idx = elem_offset; base_idx < (elem_offset + pcmd->ElemCount); base_idx += 3)
|
|
|
|
+ {
|
|
|
|
+ ImVec2 triangle[3];
|
|
|
|
+ for (int n = 0; n < 3; n++)
|
|
|
|
+ triangle[n] = draw_list->VtxBuffer[idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n)].pos;
|
|
|
|
+ fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), true, 1.0f);
|
|
|
|
+ }
|
|
|
|
+ fg_draw_list->Flags = backup_flags;
|
|
|
|
+ }
|
|
|
|
+
|
|
// Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted.
|
|
// Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted.
|
|
- ImGui::Text("ElemCount: %d, ElemCount/3: %d, VtxOffset: +%d, IdxOffset: +%d", pcmd->ElemCount, pcmd->ElemCount/3, pcmd->VtxOffset, pcmd->IdxOffset);
|
|
|
|
ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible.
|
|
ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible.
|
|
while (clipper.Step())
|
|
while (clipper.Step())
|
|
for (int prim = clipper.DisplayStart, idx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++)
|
|
for (int prim = clipper.DisplayStart, idx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++)
|
|
{
|
|
{
|
|
char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf);
|
|
char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf);
|
|
- ImVec2 triangles_pos[3];
|
|
|
|
|
|
+ ImVec2 triangle[3];
|
|
for (int n = 0; n < 3; n++, idx_i++)
|
|
for (int n = 0; n < 3; n++, idx_i++)
|
|
{
|
|
{
|
|
- int vtx_i = idx_buffer ? idx_buffer[idx_i] : idx_i;
|
|
|
|
- ImDrawVert& v = draw_list->VtxBuffer[vtx_i];
|
|
|
|
- triangles_pos[n] = v.pos;
|
|
|
|
|
|
+ ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[idx_i] : idx_i];
|
|
|
|
+ triangle[n] = v.pos;
|
|
buf_p += ImFormatString(buf_p, buf_end - buf_p, "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n",
|
|
buf_p += ImFormatString(buf_p, buf_end - buf_p, "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n",
|
|
- (n == 0) ? "elem" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
|
|
|
|
|
|
+ (n == 0) ? "Vert:" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
|
|
}
|
|
}
|
|
|
|
+
|
|
ImGui::Selectable(buf, false);
|
|
ImGui::Selectable(buf, false);
|
|
if (fg_draw_list && ImGui::IsItemHovered())
|
|
if (fg_draw_list && ImGui::IsItemHovered())
|
|
{
|
|
{
|
|
ImDrawListFlags backup_flags = fg_draw_list->Flags;
|
|
ImDrawListFlags backup_flags = fg_draw_list->Flags;
|
|
- fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles.
|
|
|
|
- fg_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f);
|
|
|
|
|
|
+ fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
|
|
|
|
+ fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255,255,0,255), true, 1.0f);
|
|
fg_draw_list->Flags = backup_flags;
|
|
fg_draw_list->Flags = backup_flags;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -15031,7 +15090,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
ImGui::PushID(tab);
|
|
ImGui::PushID(tab);
|
|
if (ImGui::SmallButton("<")) { TabBarQueueChangeTabOrder(tab_bar, tab, -1); } ImGui::SameLine(0, 2);
|
|
if (ImGui::SmallButton("<")) { TabBarQueueChangeTabOrder(tab_bar, tab, -1); } ImGui::SameLine(0, 2);
|
|
if (ImGui::SmallButton(">")) { TabBarQueueChangeTabOrder(tab_bar, tab, +1); } ImGui::SameLine();
|
|
if (ImGui::SmallButton(">")) { TabBarQueueChangeTabOrder(tab_bar, tab, +1); } ImGui::SameLine();
|
|
- ImGui::Text("%02d%c Tab 0x%08X '%s'", tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, tab->Window ? tab->Window->Name : "N/A");
|
|
|
|
|
|
+ ImGui::Text("%02d%c Tab 0x%08X '%s'", tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, (tab->Window || tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "");
|
|
ImGui::PopID();
|
|
ImGui::PopID();
|
|
}
|
|
}
|
|
ImGui::TreePop();
|
|
ImGui::TreePop();
|
|
@@ -15195,7 +15254,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
}
|
|
}
|
|
ImGui::Unindent();
|
|
ImGui::Unindent();
|
|
}
|
|
}
|
|
- ImGui::Checkbox("Show clipping rectangle when hovering ImDrawCmd node", &show_drawcmd_clip_rects);
|
|
|
|
|
|
+ ImGui::Checkbox("Show details when hovering ImDrawCmd node", &show_drawcmd_details);
|
|
ImGui::TreePop();
|
|
ImGui::TreePop();
|
|
}
|
|
}
|
|
|
|
|