mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-16 17:53:14 +02:00
Merge branch 'master' into docking
# Conflicts: # docs/CHANGELOG.txt # examples/imgui_impl_dx10.cpp # examples/imgui_impl_dx10.h # examples/imgui_impl_dx11.cpp # examples/imgui_impl_dx11.h # examples/imgui_impl_dx12.cpp # examples/imgui_impl_dx12.h # examples/imgui_impl_dx9.cpp # examples/imgui_impl_dx9.h # examples/imgui_impl_metal.h # examples/imgui_impl_metal.mm # examples/imgui_impl_opengl3.cpp # examples/imgui_impl_opengl3.h # examples/imgui_impl_vulkan.cpp # imgui.cpp # imgui.h # imgui_internal.h
This commit is contained in:
257
imgui.cpp
257
imgui.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.74 WIP
|
||||
// dear imgui, v1.74
|
||||
// (main code and documentation)
|
||||
|
||||
// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code.
|
||||
@ -29,12 +29,12 @@ DOCUMENTATION
|
||||
- MISSION STATEMENT
|
||||
- END-USER 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!)
|
||||
- FREQUENTLY ASKED QUESTIONS (FAQ)
|
||||
- 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] CONTEXT AND MEMORY ALLOCATORS
|
||||
// [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 (Color functions)
|
||||
// [SECTION] ImGuiStorage
|
||||
@ -120,8 +121,8 @@ CODE
|
||||
PROGRAMMER GUIDE
|
||||
================
|
||||
|
||||
READ FIRST:
|
||||
|
||||
READ FIRST
|
||||
----------
|
||||
- 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
|
||||
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.
|
||||
- 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)
|
||||
- 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.
|
||||
@ -152,8 +153,8 @@ CODE
|
||||
likely be a comment about it. Please report any issue to the GitHub page!
|
||||
- Try to keep your copy of dear imgui reasonably up to date.
|
||||
|
||||
GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE:
|
||||
|
||||
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.
|
||||
- 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).
|
||||
@ -165,7 +166,8 @@ 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.
|
||||
|
||||
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).
|
||||
|
||||
// Application init: create a dear imgui context, setup some options, load fonts
|
||||
@ -201,8 +203,7 @@ CODE
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
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
|
||||
ImGui::CreateContext();
|
||||
@ -256,8 +257,8 @@ CODE
|
||||
// Shutdown
|
||||
ImGui::DestroyContext();
|
||||
|
||||
HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE:
|
||||
|
||||
HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
|
||||
---------------------------------------------
|
||||
void void MyImGuiRenderFunction(ImDrawData* draw_data)
|
||||
{
|
||||
// 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));
|
||||
|
||||
// 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);
|
||||
}
|
||||
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!
|
||||
|
||||
USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS
|
||||
|
||||
------------------------------------------
|
||||
- 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!
|
||||
- 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/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/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.
|
||||
@ -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/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal.
|
||||
- 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore.
|
||||
If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you.
|
||||
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.
|
||||
- 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.
|
||||
@ -758,7 +757,7 @@ CODE
|
||||
Q: How can I easily use icons in my application?
|
||||
Q: How can I load multiple fonts?
|
||||
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
|
||||
==============
|
||||
@ -1100,7 +1099,7 @@ ImGuiIO::ImGuiIO()
|
||||
// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message
|
||||
void ImGuiIO::AddInputCharacter(unsigned int c)
|
||||
{
|
||||
if (c > 0 && c < 0x10000)
|
||||
if (c > 0 && c <= IM_UNICODE_CODEPOINT_MAX)
|
||||
InputQueueCharacters.push_back((ImWchar)c);
|
||||
}
|
||||
|
||||
@ -1110,7 +1109,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
|
||||
{
|
||||
unsigned int c = 0;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
@ -1225,7 +1224,7 @@ const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
||||
|
||||
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;
|
||||
while (*str++) 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).
|
||||
// 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.
|
||||
#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
|
||||
#ifdef IMGUI_USE_STB_SPRINTF
|
||||
#define STB_SPRINTF_IMPLEMENTATION
|
||||
#include "imstb_sprintf.h"
|
||||
#include "stb_sprintf.h"
|
||||
#endif
|
||||
|
||||
#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;
|
||||
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)
|
||||
// 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;
|
||||
}
|
||||
|
||||
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__)
|
||||
// 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 mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1;
|
||||
ImVector<ImWchar> buf;
|
||||
@ -1425,42 +1434,48 @@ FILE* ImFileOpen(const char* filename, const char* mode)
|
||||
#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()
|
||||
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)
|
||||
*out_file_size = 0;
|
||||
|
||||
FILE* f;
|
||||
if ((f = ImFileOpen(filename, file_open_mode)) == NULL)
|
||||
ImFileHandle f;
|
||||
if ((f = ImFileOpen(filename, mode)) == 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;
|
||||
}
|
||||
|
||||
size_t file_size = (size_t)file_size_signed;
|
||||
void* file_data = IM_ALLOC(file_size + padding_bytes);
|
||||
if (file_data == NULL)
|
||||
{
|
||||
fclose(f);
|
||||
ImFileClose(f);
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
if (padding_bytes > 0)
|
||||
memset((void*)(((char*)file_data) + file_size), 0, (size_t)padding_bytes);
|
||||
|
||||
fclose(f);
|
||||
ImFileClose(f);
|
||||
if (out_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)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// 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/
|
||||
// We handle UTF-8 decoding error by skipping forward.
|
||||
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)
|
||||
{
|
||||
*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 (*str < 0xc2) return 2;
|
||||
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)
|
||||
{
|
||||
*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 (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3;
|
||||
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)
|
||||
{
|
||||
*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 (*str > 0xf4) 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);
|
||||
if (c == 0)
|
||||
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 = 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);
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c < 0x10000)
|
||||
if (c <= IM_UNICODE_CODEPOINT_MAX)
|
||||
char_count++;
|
||||
}
|
||||
return char_count;
|
||||
@ -4071,9 +4086,12 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
g.SettingsWindows.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.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'.
|
||||
// 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.
|
||||
// (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:
|
||||
// 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.
|
||||
@ -6111,7 +6129,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Handle manual resize: Resize Grips, Borders, Gamepad
|
||||
int border_held = -1;
|
||||
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));
|
||||
if (handle_borders_and_resize_grips && !window->Collapsed)
|
||||
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_start(args, fmt);
|
||||
if (g.LogFile)
|
||||
vfprintf(g.LogFile, fmt, args);
|
||||
else
|
||||
{
|
||||
g.LogBuffer.Buf.resize(0);
|
||||
g.LogBuffer.appendfv(fmt, args);
|
||||
ImFileWrite(g.LogBuffer.c_str(), sizeof(char), (ImU64)g.LogBuffer.size(), g.LogFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
g.LogBuffer.appendfv(fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@ -9899,8 +9923,11 @@ void ImGui::LogToTTY(int auto_open_depth)
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.LogEnabled)
|
||||
return;
|
||||
IM_UNUSED(auto_open_depth);
|
||||
#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
|
||||
LogBegin(ImGuiLogType_TTY, auto_open_depth);
|
||||
g.LogFile = stdout;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (!filename || !filename[0])
|
||||
return;
|
||||
FILE* f = ImFileOpen(filename, "ab");
|
||||
if (f == NULL)
|
||||
ImFileHandle f = ImFileOpen(filename, "ab");
|
||||
if (!f)
|
||||
{
|
||||
IM_ASSERT(0);
|
||||
return;
|
||||
@ -9955,10 +9982,12 @@ void ImGui::LogFinish()
|
||||
switch (g.LogType)
|
||||
{
|
||||
case ImGuiLogType_TTY:
|
||||
#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
|
||||
fflush(g.LogFile);
|
||||
#endif
|
||||
break;
|
||||
case ImGuiLogType_File:
|
||||
fclose(g.LogFile);
|
||||
ImFileClose(g.LogFile);
|
||||
break;
|
||||
case ImGuiLogType_Buffer:
|
||||
break;
|
||||
@ -9984,7 +10013,11 @@ void ImGui::LogButtons()
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
PushID("LogButtons");
|
||||
#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
|
||||
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_clipboard = Button("Log To Clipboard"); SameLine();
|
||||
PushAllowKeyboardFocus(false);
|
||||
@ -10117,18 +10150,12 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
|
||||
line_end[-1] = 0;
|
||||
const char* name_end = line_end - 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;
|
||||
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_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;
|
||||
const char* ini_data = SaveIniSettingsToMemory(&ini_data_size);
|
||||
FILE* f = ImFileOpen(ini_filename, "wt");
|
||||
ImFileHandle f = ImFileOpen(ini_filename, "wt");
|
||||
if (!f)
|
||||
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
|
||||
@ -14767,7 +14794,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
static bool show_windows_rects = false;
|
||||
static int show_windows_rect_type = WRT_WorkRect;
|
||||
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;
|
||||
|
||||
// Basic info
|
||||
@ -14821,9 +14848,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
return;
|
||||
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
|
||||
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);
|
||||
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 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);
|
||||
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)
|
||||
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.
|
||||
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.
|
||||
while (clipper.Step())
|
||||
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);
|
||||
ImVec2 triangles_pos[3];
|
||||
ImVec2 triangle[3];
|
||||
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",
|
||||
(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);
|
||||
if (fg_draw_list && ImGui::IsItemHovered())
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -15031,7 +15090,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
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();
|
||||
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::TreePop();
|
||||
@ -15195,7 +15254,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user