mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-03 21:59:15 +08:00
Merge branch 'master' into docking (incl glfw use of GLFW_VERSION_COMBINED)
Note switched from GLFW_VERSION_REVISION * 10 to GLFW_VERSION_REVISION * 1
This commit is contained in:
commit
375ae5dce4
31
.github/workflows/static-analysis.yml
vendored
31
.github/workflows/static-analysis.yml
vendored
@ -44,34 +44,3 @@ jobs:
|
||||
pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1
|
||||
pvs-studio-analyzer analyze -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log
|
||||
plog-converter -a 'GA:1,2;OP:1' -d V1071 -t errorfile -w pvs-studio.log
|
||||
|
||||
Discord-CI:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: [PVS-Studio]
|
||||
if: always()
|
||||
steps:
|
||||
- uses: dearimgui/github_discord_notifier@latest
|
||||
with:
|
||||
discord-webhook: ${{ secrets.DISCORD_CI_WEBHOOK }}
|
||||
github-token: ${{ github.token }}
|
||||
action-task: discord-jobs
|
||||
discord-filter: "'{{ github.branch }}'.match(/master|docking/g) != null && '{{ run.conclusion }}' != '{{ last_run.conclusion }}'"
|
||||
discord-username: GitHub Actions
|
||||
discord-job-new-failure-message: ''
|
||||
discord-job-fixed-failure-message: ''
|
||||
discord-job-new-failure-embed: |
|
||||
{
|
||||
"title": "`{{ job.name }}` job is failing on `{{ github.branch }}`!",
|
||||
"description": "Commit [{{ github.context.payload.head_commit.title }}]({{ github.context.payload.head_commit.url }}) pushed to [{{ github.branch }}]({{ github.branch_url }}) broke static analysis [{{ job.name }}]({{ job.url }}) job.\nFailing steps: {{ failing_steps }}",
|
||||
"url": "{{ job.url }}",
|
||||
"color": "0xFF0000",
|
||||
"timestamp": "{{ run.updated_at }}"
|
||||
}
|
||||
discord-job-fixed-failure-embed: |
|
||||
{
|
||||
"title": "`{{ github.branch }}` branch is no longer failing!",
|
||||
"description": "Static analysis failures were fixed on [{{ github.branch }}]({{ github.branch_url }}) branch.",
|
||||
"color": "0x00FF00",
|
||||
"url": "{{ github.context.payload.head_commit.url }}",
|
||||
"timestamp": "{{ run.completed_at }}"
|
||||
}
|
||||
|
@ -608,7 +608,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
|
||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||
// If you would like to use this DX12 sample code but remove this dependency you can:
|
||||
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||
// 1) compile once, save the compiled shader blobs into a file or source code and assign them to psoDesc.VS/PS [preferred solution]
|
||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||
|
||||
@ -657,7 +657,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
}";
|
||||
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_5_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||
return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() };
|
||||
|
||||
// Create the input layout
|
||||
@ -691,7 +691,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
}
|
||||
psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() };
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position.
|
||||
@ -82,27 +83,29 @@
|
||||
#include <GLFW/glfw3native.h> // for glfwGetCocoaWindow()
|
||||
#endif
|
||||
|
||||
#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING
|
||||
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED
|
||||
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity
|
||||
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale
|
||||
#define GLFW_HAS_VULKAN (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface
|
||||
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwFocusWindow
|
||||
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
||||
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
||||
#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION * 10 >= 3310) // 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553
|
||||
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
|
||||
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
|
||||
// We gather version tests as define in order to easily see which features are version-dependent.
|
||||
#define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION)
|
||||
#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_COMBINED >= 3200) // 3.2+ GLFW_FLOATING
|
||||
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_HOVERED
|
||||
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwSetWindowOpacity
|
||||
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorContentScale
|
||||
#define GLFW_HAS_VULKAN (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwCreateWindowSurface
|
||||
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwFocusWindow
|
||||
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
||||
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
||||
#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_COMBINED >= 3301) // 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553
|
||||
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
|
||||
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
|
||||
#else
|
||||
#define GLFW_HAS_NEW_CURSORS (0)
|
||||
#define GLFW_HAS_NEW_CURSORS (0)
|
||||
#endif
|
||||
#ifdef GLFW_MOUSE_PASSTHROUGH // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2020-07-17 (passthrough)
|
||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_MOUSE_PASSTHROUGH
|
||||
#ifdef GLFW_MOUSE_PASSTHROUGH // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2020-07-17 (passthrough)
|
||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_MOUSE_PASSTHROUGH
|
||||
#else
|
||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (0)
|
||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (0)
|
||||
#endif
|
||||
#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetGamepadState() new api
|
||||
#define GLFW_HAS_GET_KEY_NAME (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwGetKeyName()
|
||||
#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetGamepadState() new api
|
||||
#define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName()
|
||||
|
||||
// GLFW data
|
||||
enum GlfwClientApi
|
||||
@ -328,7 +331,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
|
||||
|
||||
static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
||||
{
|
||||
#if GLFW_HAS_GET_KEY_NAME && !defined(__EMSCRIPTEN__)
|
||||
#if GLFW_HAS_GETKEYNAME && !defined(__EMSCRIPTEN__)
|
||||
// GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult.
|
||||
// (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently)
|
||||
// See https://github.com/glfw/glfw/issues/1502 for details.
|
||||
@ -495,6 +498,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
//printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED);
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplGlfw_Data* bd = IM_NEW(ImGui_ImplGlfw_Data)();
|
||||
@ -535,6 +539,9 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
#endif
|
||||
#if (GLFW_VERSION_COMBINED >= 3300) // Eat errors (see #5785)
|
||||
(void)glfwGetError(NULL);
|
||||
#endif
|
||||
glfwSetErrorCallback(prev_error_callback);
|
||||
|
||||
|
@ -144,7 +144,8 @@ Breaking changes:
|
||||
- always uses style.FramePadding for padding, to be consistent with other buttons. You may use PushStyleVar() to alter this.
|
||||
- As always we are keeping a redirection function available (will obsolete later).
|
||||
- Removed the bizarre legacy default argument for 'TreePush(const void* ptr = NULL)'. (#1057)
|
||||
Must always pass a pointer value explicitly, NULL is ok.
|
||||
Must always pass a pointer value explicitly, NULL/nullptr is ok but require cast, e.g. TreePush((void*)nullptr);
|
||||
If you used TreePush() replace with TreePush((void*)NULL);
|
||||
- Commented out redirecting functions/enums names that were marked obsolete in 1.77 and 1.78 (June 2020): (#3361)
|
||||
- DragScalar(), DragScalarN(), DragFloat(), DragFloat2(), DragFloat3(), DragFloat4()
|
||||
- SliderScalar(), SliderScalarN(), SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4()
|
||||
@ -202,6 +203,7 @@ Other Changes:
|
||||
bar boundaries (bug in 1.88). (#5652).
|
||||
- Tabs: Enforcing minimum size of 1.0f, fixed asserting on zero-tab widths. (#5572)
|
||||
- Window: Fixed a potential crash when appending to a child window. (#5515, #3496, #4797) [@rokups]
|
||||
- Window: Fixed an issue where uncollapsed a window would show a scrollbar for a frame.
|
||||
- IO: Added ImGuiMod_Shortcut which is ImGuiMod_Super on Mac and ImGuiMod_Ctrl otherwise. (#456)
|
||||
- IO: Added ImGuiKey_MouseXXX aliases for mouse buttons/wheel so all operations done on ImGuiKey
|
||||
can apply to mouse data as well. (#4921)
|
||||
@ -220,6 +222,8 @@ Other Changes:
|
||||
- Menus, Nav: Fixed not being able to close a menu with Left arrow when parent is not a popup. (#5730)
|
||||
- Menus, Nav: Fixed using left/right navigation when appending to an existing menu (multiple
|
||||
BeginMenu() call with same names). (#1207)
|
||||
- Menus: Fixed a one-frame issue where SetNextWindowXXX data are not consumed by a BeginMenu()
|
||||
returning false (specifically )
|
||||
- Nav: Fixed moving/resizing window with gamepad or keyboard when running at very high framerate.
|
||||
- Nav: Pressing Space/GamepadFaceDown on a repeating button uses the same repeating rate as a mouse hold.
|
||||
- Nav: Fixed an issue opening a menu with Right key from a non-menu window.
|
||||
@ -243,6 +247,7 @@ Other Changes:
|
||||
- Examples: Added all SDL examples to default VS solution.
|
||||
- Examples: Win32: Always use RegisterClassW() to ensure windows are Unicode. (#5725)
|
||||
- Backends: GLFW: Honor GLFW_CURSOR_DISABLED by not setting mouse position. (#5625) [@scorpion-26]
|
||||
- Backends: GLFW: Add glfwGetError() call on GLFW 3.3 to inhibit missing mouse cursor errors. (#5785) [@mitchellh]
|
||||
- Backends: SDL: Disable SDL 2.0.22 new "auto capture" which prevents drag and drop across windows
|
||||
(e.g. for multi-viewport support) and don't capture mouse when drag and dropping. (#5710)
|
||||
- Backends: Win32: Convert WM_CHAR values with MultiByteToWideChar() when window class was
|
||||
|
@ -108,11 +108,6 @@
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
||||
// This adds a small runtime cost which is why it is not enabled by default.
|
||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
|
105
imgui.cpp
105
imgui.cpp
@ -65,7 +65,7 @@ CODE
|
||||
// [SECTION] MISC HELPERS/UTILITIES (Color functions)
|
||||
// [SECTION] ImGuiStorage
|
||||
// [SECTION] ImGuiTextFilter
|
||||
// [SECTION] ImGuiTextBuffer
|
||||
// [SECTION] ImGuiTextBuffer, ImGuiTextIndex
|
||||
// [SECTION] ImGuiListClipper
|
||||
// [SECTION] STYLING
|
||||
// [SECTION] RENDER HELPERS
|
||||
@ -401,7 +401,7 @@ CODE
|
||||
the ImGuiKey_ModXXX were introduced in 1.87 and mostly used by backends.
|
||||
the ImGuiModFlags_XXX have been exposed in imgui.h but not really used by any public api only by third-party extensions.
|
||||
exceptionally commenting out the older ImGuiKeyModFlags_XXX names ahead of obsolescence schedule to reduce confusion and because they were not meant to be used anyway.
|
||||
- 2022/09/12 (1.89) - removed the bizarre legacy default argument for 'TreePush(const void* ptr = NULL)', always pass a pointer value explicitly, NULL is ok.
|
||||
- 2022/09/12 (1.89) - removed the bizarre legacy default argument for 'TreePush(const void* ptr = NULL)', always pass a pointer value explicitly. NULL/nullptr is ok but require cast, e.g. TreePush((void*)nullptr);
|
||||
- 2022/09/05 (1.89) - commented out redirecting functions/enums names that were marked obsolete in 1.77 and 1.78 (June 2020):
|
||||
- DragScalar(), DragScalarN(), DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(): For old signatures ending with (..., const char* format, float power = 1.0f) -> use (..., format ImGuiSliderFlags_Logarithmic) if power != 1.0f.
|
||||
- SliderScalar(), SliderScalarN(), SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4(): For old signatures ending with (..., const char* format, float power = 1.0f) -> use (..., format ImGuiSliderFlags_Logarithmic) if power != 1.0f.
|
||||
@ -868,7 +868,6 @@ CODE
|
||||
#include "imgui_internal.h"
|
||||
|
||||
// System includes
|
||||
#include <ctype.h> // toupper
|
||||
#include <stdio.h> // vsnprintf, sscanf, printf
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
@ -1670,14 +1669,14 @@ ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c,
|
||||
int ImStricmp(const char* str1, const char* str2)
|
||||
{
|
||||
int d;
|
||||
while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; }
|
||||
while ((d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; }
|
||||
return d;
|
||||
}
|
||||
|
||||
int ImStrnicmp(const char* str1, const char* str2, size_t count)
|
||||
{
|
||||
int d = 0;
|
||||
while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; }
|
||||
while (count > 0 && (d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; count--; }
|
||||
return d;
|
||||
}
|
||||
|
||||
@ -1744,14 +1743,14 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char
|
||||
if (!needle_end)
|
||||
needle_end = needle + strlen(needle);
|
||||
|
||||
const char un0 = (char)toupper(*needle);
|
||||
const char un0 = (char)ImToUpper(*needle);
|
||||
while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end))
|
||||
{
|
||||
if (toupper(*haystack) == un0)
|
||||
if (ImToUpper(*haystack) == un0)
|
||||
{
|
||||
const char* b = needle + 1;
|
||||
for (const char* a = haystack + 1; b < needle_end; a++, b++)
|
||||
if (toupper(*a) != toupper(*b))
|
||||
if (ImToUpper(*a) != ImToUpper(*b))
|
||||
break;
|
||||
if (b == needle_end)
|
||||
return haystack;
|
||||
@ -2515,7 +2514,7 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImGuiTextBuffer
|
||||
// [SECTION] ImGuiTextBuffer, ImGuiTextIndex
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// On some platform vsnprintf() takes va_list by reference and modifies it.
|
||||
@ -2583,6 +2582,20 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args)
|
||||
va_end(args_copy);
|
||||
}
|
||||
|
||||
void ImGuiTextIndex::append(const char* base, int old_size, int new_size)
|
||||
{
|
||||
IM_ASSERT(old_size >= 0 && new_size >= old_size && new_size >= EndOffset);
|
||||
if (old_size == new_size)
|
||||
return;
|
||||
if (EndOffset == 0 || base[EndOffset - 1] == '\n')
|
||||
LineOffsets.push_back(EndOffset);
|
||||
const char* base_end = base + new_size;
|
||||
for (const char* p = base + old_size; (p = (const char*)memchr(p, '\n', base_end - p)) != 0; )
|
||||
if (++p < base_end) // Don't push a trailing offset on last \n
|
||||
LineOffsets.push_back((int)(intptr_t)(p - base));
|
||||
EndOffset = ImMax(EndOffset, new_size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImGuiListClipper
|
||||
// This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed
|
||||
@ -3797,8 +3810,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
||||
// [DEBUG] Item Picker tool!
|
||||
// We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making
|
||||
// the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered
|
||||
// items if we perform the test in ItemAdd(), but that would incur a small runtime cost.
|
||||
// #define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX in imconfig.h if you want this check to also be performed in ItemAdd().
|
||||
// items if we performed the test in ItemAdd(), but that would incur a small runtime cost.
|
||||
if (g.DebugItemPickerActive && g.HoveredIdPreviousFrame == id)
|
||||
GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
|
||||
if (g.DebugItemPickerBreakId == id)
|
||||
@ -3811,6 +3823,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: This is inlined/duplicated in ItemAdd()
|
||||
bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -4993,6 +5006,7 @@ void ImGui::Shutdown()
|
||||
}
|
||||
g.LogBuffer.clear();
|
||||
g.DebugLogBuf.clear();
|
||||
g.DebugLogIndex.clear();
|
||||
|
||||
g.Initialized = false;
|
||||
}
|
||||
@ -5614,7 +5628,7 @@ bool ImGui::IsAnyItemFocused()
|
||||
bool ImGui::IsItemVisible()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.CurrentWindow->ClipRect.Overlaps(g.LastItemData.Rect);
|
||||
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) != 0;
|
||||
}
|
||||
|
||||
bool ImGui::IsItemEdited()
|
||||
@ -6168,7 +6182,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x);
|
||||
if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y);
|
||||
ImGuiID resize_grip_id = window->GetID(resize_grip_n); // == GetWindowResizeCornerID()
|
||||
KeepAliveID(resize_grip_id);
|
||||
ItemAdd(resize_rect, resize_grip_id, NULL, ImGuiItemFlags_NoNav);
|
||||
ButtonBehavior(resize_rect, resize_grip_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
|
||||
//GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255));
|
||||
if (hovered || held)
|
||||
@ -6204,7 +6218,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
bool hovered, held;
|
||||
ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_HOVER_PADDING);
|
||||
ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID()
|
||||
KeepAliveID(border_id);
|
||||
ItemAdd(border_rect, border_id, NULL, ImGuiItemFlags_NoNav);
|
||||
ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
|
||||
//GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
|
||||
if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held)
|
||||
@ -6869,6 +6883,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
||||
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
||||
|
||||
bool use_current_size_for_scrollbar_x = window_just_created;
|
||||
bool use_current_size_for_scrollbar_y = window_just_created;
|
||||
|
||||
// Collapse window by double-clicking on title bar
|
||||
// At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse) && !window->DockIsActive)
|
||||
@ -6880,6 +6897,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
if (window->WantCollapseToggle)
|
||||
{
|
||||
window->Collapsed = !window->Collapsed;
|
||||
if (!window->Collapsed)
|
||||
use_current_size_for_scrollbar_y = true;
|
||||
MarkIniSettingsDirty(window);
|
||||
}
|
||||
}
|
||||
@ -6893,8 +6912,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// Calculate auto-fit size, handle automatic resize
|
||||
const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSizeIdeal);
|
||||
bool use_current_size_for_scrollbar_x = window_just_created;
|
||||
bool use_current_size_for_scrollbar_y = window_just_created;
|
||||
if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed)
|
||||
{
|
||||
// Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc.
|
||||
@ -9285,25 +9302,19 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
// to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick).
|
||||
// We intentionally don't check if g.NavWindow != NULL because g.NavAnyRequest should only be set when it is non null.
|
||||
// If we crash on a NULL g.NavWindow we need to fix the bug elsewhere.
|
||||
window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent);
|
||||
if (g.NavId == id || g.NavAnyRequest)
|
||||
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
|
||||
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
|
||||
NavProcessItem();
|
||||
if (!(g.LastItemData.InFlags & ImGuiItemFlags_NoNav))
|
||||
{
|
||||
window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent);
|
||||
if (g.NavId == id || g.NavAnyRequest)
|
||||
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
|
||||
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
|
||||
NavProcessItem();
|
||||
}
|
||||
|
||||
// [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something".
|
||||
// Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something".
|
||||
// READ THE FAQ: https://dearimgui.org/faq
|
||||
IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!");
|
||||
|
||||
// [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd()
|
||||
#ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
if (id == g.DebugItemPickerBreakId)
|
||||
{
|
||||
IM_DEBUG_BREAK();
|
||||
g.DebugItemPickerBreakId = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
|
||||
|
||||
@ -9313,12 +9324,21 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
#endif
|
||||
|
||||
// Clipping test
|
||||
const bool is_clipped = IsClippedEx(bb, id);
|
||||
if (is_clipped)
|
||||
return false;
|
||||
// (FIXME: This is a modified copy of IsClippedEx() so we can reuse the is_rect_visible value)
|
||||
//const bool is_clipped = IsClippedEx(bb, id);
|
||||
//if (is_clipped)
|
||||
// return false;
|
||||
const bool is_rect_visible = bb.Overlaps(window->ClipRect);
|
||||
if (!is_rect_visible)
|
||||
if (id == 0 || (id != g.ActiveId && id != g.NavId))
|
||||
if (!g.LogEnabled)
|
||||
return false;
|
||||
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
|
||||
|
||||
// We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
|
||||
if (is_rect_visible)
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Visible;
|
||||
if (IsMouseHoveringRect(bb.Min, bb.Max))
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect;
|
||||
return true;
|
||||
@ -10818,7 +10838,7 @@ static void ImGui::NavProcessItem()
|
||||
if (is_tab_stop || (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi))
|
||||
NavProcessItemForTabbingRequest(id);
|
||||
}
|
||||
else if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav)))
|
||||
else if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & ImGuiItemFlags_Disabled))
|
||||
{
|
||||
ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
|
||||
if (!is_tabbing)
|
||||
@ -19092,7 +19112,7 @@ void ImGui::DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int wi
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] DEBUG LOG
|
||||
// [SECTION] DEBUG LOG WINDOW
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImGui::DebugLog(const char* fmt, ...)
|
||||
@ -19111,6 +19131,7 @@ void ImGui::DebugLogV(const char* fmt, va_list args)
|
||||
g.DebugLogBuf.appendfv(fmt, args);
|
||||
if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTTY)
|
||||
IMGUI_DEBUG_PRINTF("%s", g.DebugLogBuf.begin() + old_size);
|
||||
g.DebugLogIndex.append(g.DebugLogBuf.c_str(), old_size, g.DebugLogBuf.size());
|
||||
}
|
||||
|
||||
void ImGui::ShowDebugLogWindow(bool* p_open)
|
||||
@ -19137,12 +19158,24 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
|
||||
SameLine(); CheckboxFlags("Viewport", &g.DebugLogFlags, ImGuiDebugLogFlags_EventViewport);
|
||||
|
||||
if (SmallButton("Clear"))
|
||||
{
|
||||
g.DebugLogBuf.clear();
|
||||
g.DebugLogIndex.clear();
|
||||
}
|
||||
SameLine();
|
||||
if (SmallButton("Copy"))
|
||||
SetClipboardText(g.DebugLogBuf.c_str());
|
||||
BeginChild("##log", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
TextUnformatted(g.DebugLogBuf.begin(), g.DebugLogBuf.end()); // FIXME-OPT: Could use a line index, but TextUnformatted() has a semi-decent fast path for large text.
|
||||
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(g.DebugLogIndex.size());
|
||||
while (clipper.Step())
|
||||
for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++)
|
||||
{
|
||||
const char* line_begin = g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no);
|
||||
const char* line_end = g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no);
|
||||
TextUnformatted(line_begin, line_end);
|
||||
}
|
||||
if (GetScrollY() >= GetScrollMaxY())
|
||||
SetScrollHereY(1.0f);
|
||||
EndChild();
|
||||
|
12
imgui.h
12
imgui.h
@ -23,7 +23,7 @@
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
|
||||
#define IMGUI_VERSION "1.89 WIP"
|
||||
#define IMGUI_VERSION_NUM 18832
|
||||
#define IMGUI_VERSION_NUM 18833
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
@ -520,7 +520,7 @@ namespace ImGui
|
||||
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
||||
IMGUI_API bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
||||
|
||||
// Widgets: Combo Box
|
||||
// Widgets: Combo Box (Dropdown)
|
||||
// - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items.
|
||||
// - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. This is analogous to how ListBox are created.
|
||||
IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0);
|
||||
@ -1404,8 +1404,9 @@ enum ImGuiSortDirection_
|
||||
ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc.
|
||||
};
|
||||
|
||||
// Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87)
|
||||
// Keys value >= 512 are named keys (>= 1.87)
|
||||
// A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value)
|
||||
// All our named keys are >= 512. Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87)
|
||||
// Since >= 1.89 we increased typing (went from int to enum), some legacy code may need a cast to ImGuiKey.
|
||||
enum ImGuiKey : int
|
||||
{
|
||||
// Keyboard
|
||||
@ -2089,6 +2090,7 @@ struct ImGuiIO
|
||||
|
||||
// Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame.
|
||||
// This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent().
|
||||
// Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512.
|
||||
bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow.
|
||||
@ -3226,7 +3228,7 @@ namespace ImGui
|
||||
// OBSOLETED in 1.81 (from February 2021)
|
||||
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items
|
||||
static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); }
|
||||
static inline void ListBoxFooter() { EndListBox(); }
|
||||
static inline void ListBoxFooter() { EndListBox(); }
|
||||
// OBSOLETED in 1.79 (from August 2020)
|
||||
static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry!
|
||||
|
||||
|
@ -1142,6 +1142,7 @@ static void ShowDemoWindowWidgets()
|
||||
IMGUI_DEMO_MARKER("Widgets/Combo");
|
||||
if (ImGui::TreeNode("Combo"))
|
||||
{
|
||||
// Combo Boxes are also called "Dropdown" in other systems
|
||||
// Expose flags as checkbox for the demo
|
||||
static ImGuiComboFlags flags = 0;
|
||||
ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft);
|
||||
|
@ -312,6 +312,7 @@ namespace ImStb
|
||||
// - Helper: ImSpan<>, ImSpanAllocator<>
|
||||
// - Helper: ImPool<>
|
||||
// - Helper: ImChunkStream<>
|
||||
// - Helper: ImGuiTextIndex
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Helpers: Hashing
|
||||
@ -345,6 +346,7 @@ IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end
|
||||
IMGUI_API void ImStrTrimBlanks(char* str);
|
||||
IMGUI_API const char* ImStrSkipBlank(const char* str);
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
|
||||
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
@ -703,6 +705,20 @@ struct ImChunkStream
|
||||
|
||||
};
|
||||
|
||||
// Helper: ImGuiTextIndex<>
|
||||
// Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API.
|
||||
struct ImGuiTextIndex
|
||||
{
|
||||
ImVector<int> LineOffsets;
|
||||
int EndOffset = 0; // Because we don't own text buffer we need to maintain EndOffset (may bake in LineOffsets?)
|
||||
|
||||
void clear() { LineOffsets.clear(); EndOffset = 0; }
|
||||
int size() { return LineOffsets.Size; }
|
||||
const char* get_line_begin(const char* base, int n) { return base + LineOffsets[n]; }
|
||||
const char* get_line_end(const char* base, int n) { return base + (n + 1 < LineOffsets.Size ? (LineOffsets[n + 1] - 1) : EndOffset); }
|
||||
void append(const char* base, int old_size, int new_size);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImDrawList support
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -808,6 +824,7 @@ enum ImGuiItemStatusFlags_
|
||||
ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set.
|
||||
ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing.
|
||||
ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
|
||||
ImGuiItemStatusFlags_Visible = 1 << 9, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()).
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
ImGuiItemStatusFlags_Openable = 1 << 20, // Item is an openable (e.g. TreeNode)
|
||||
@ -843,7 +860,7 @@ enum ImGuiButtonFlagsPrivate_
|
||||
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
|
||||
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
|
||||
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
|
||||
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated
|
||||
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used everytime an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags)
|
||||
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
|
||||
ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold,
|
||||
ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease,
|
||||
@ -2043,6 +2060,7 @@ struct ImGuiContext
|
||||
// Debug Tools
|
||||
ImGuiDebugLogFlags DebugLogFlags;
|
||||
ImGuiTextBuffer DebugLogBuf;
|
||||
ImGuiTextIndex DebugLogIndex;
|
||||
bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker())
|
||||
ImU8 DebugItemPickerMouseButton;
|
||||
ImGuiID DebugItemPickerBreakId; // Will call IM_DEBUG_BREAK() when encountering this ID
|
||||
|
@ -1171,8 +1171,8 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
|
||||
|
||||
ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent);
|
||||
ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit);
|
||||
ItemAdd(hit_rect, column_id, NULL, ImGuiItemFlags_NoNav);
|
||||
//GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100));
|
||||
KeepAliveID(column_id);
|
||||
|
||||
bool hovered = false, held = false;
|
||||
bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus);
|
||||
@ -4022,8 +4022,7 @@ void ImGui::EndColumns()
|
||||
const ImGuiID column_id = columns->ID + ImGuiID(n);
|
||||
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
|
||||
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
|
||||
KeepAliveID(column_id);
|
||||
if (IsClippedEx(column_hit_rect, column_id)) // FIXME: Can be removed or replaced with a lower-level test
|
||||
if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav))
|
||||
continue;
|
||||
|
||||
bool hovered = false, held = false;
|
||||
|
@ -41,7 +41,6 @@ Index of this file:
|
||||
#include "imgui_internal.h"
|
||||
|
||||
// System includes
|
||||
#include <ctype.h> // toupper
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
#else
|
||||
@ -932,8 +931,6 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
KeepAliveID(id);
|
||||
|
||||
const float bb_frame_width = bb_frame.GetWidth();
|
||||
const float bb_frame_height = bb_frame.GetHeight();
|
||||
if (bb_frame_width <= 0.0f || bb_frame_height <= 0.0f)
|
||||
@ -965,6 +962,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
|
||||
bool held = false;
|
||||
bool hovered = false;
|
||||
ItemAdd(bb_frame, id, NULL, ImGuiItemFlags_NoNav);
|
||||
ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
|
||||
|
||||
const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v);
|
||||
@ -1484,11 +1482,7 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
const ImGuiItemFlags item_flags_backup = g.CurrentItemFlags;
|
||||
g.CurrentItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus;
|
||||
bool item_add = ItemAdd(bb, id);
|
||||
g.CurrentItemFlags = item_flags_backup;
|
||||
if (!item_add)
|
||||
if (!ItemAdd(bb, id, NULL, ImGuiItemFlags_NoNav))
|
||||
return false;
|
||||
|
||||
bool hovered, held;
|
||||
@ -1759,7 +1753,7 @@ bool ImGui::BeginComboPreview()
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiComboPreviewData* preview_data = &g.ComboPreviewData;
|
||||
|
||||
if (window->SkipItems || !window->ClipRect.Overlaps(g.LastItemData.Rect)) // FIXME: Because we don't have a ImGuiItemStatusFlags_Visible flag to test last ItemAdd() result
|
||||
if (window->SkipItems || !(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible))
|
||||
return false;
|
||||
IM_ASSERT(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag?
|
||||
if (!window->ClipRect.Contains(preview_data->PreviewRect)) // Narrower test (optional)
|
||||
@ -6844,7 +6838,7 @@ void ImGui::EndMenuBar()
|
||||
// To do so we claim focus back, restore NavId and then process the movement request for yet another frame.
|
||||
// This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering)
|
||||
const ImGuiNavLayer layer = ImGuiNavLayer_Menu;
|
||||
IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check
|
||||
IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check (FIXME: Seems unnecessary)
|
||||
FocusWindow(window);
|
||||
SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
|
||||
g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection.
|
||||
@ -6978,9 +6972,9 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
|
||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||
// The first menu in a hierarchy isn't so hovering doesn't get across (otherwise e.g. resizing borders with ImGuiButtonFlags_FlattenChildren would react), but top-most BeginMenu() will bypass that limitation.
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
if (window->Flags & ImGuiWindowFlags_ChildMenu)
|
||||
flags |= ImGuiWindowFlags_ChildWindow;
|
||||
window_flags |= ImGuiWindowFlags_ChildWindow;
|
||||
|
||||
// If a menu with same the ID was already submitted, we will append to it, matching the behavior of Begin().
|
||||
// We are relying on a O(N) search - so O(N log N) over the frame - which seems like the most efficient for the expected small amount of BeginMenu() calls per frame.
|
||||
@ -6988,7 +6982,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
if (g.MenusIdSubmittedThisFrame.contains(id))
|
||||
{
|
||||
if (menu_is_open)
|
||||
menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
else
|
||||
g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values
|
||||
return menu_is_open;
|
||||
@ -7125,23 +7119,23 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
PopID();
|
||||
|
||||
if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size)
|
||||
if (want_open && !menu_is_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size)
|
||||
{
|
||||
// Don't recycle same menu level in the same frame, first close the other menu and yield for a frame.
|
||||
// Don't reopen/recycle same menu level in the same frame, first close the other menu and yield for a frame.
|
||||
OpenPopup(label);
|
||||
return false;
|
||||
}
|
||||
|
||||
menu_is_open |= want_open;
|
||||
if (want_open)
|
||||
else if (want_open)
|
||||
{
|
||||
menu_is_open = true;
|
||||
OpenPopup(label);
|
||||
}
|
||||
|
||||
if (menu_is_open)
|
||||
{
|
||||
ImGuiLastItemData last_item_in_parent = g.LastItemData;
|
||||
SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: misleading: the value will serve as reference for FindBestWindowPosForPopup(), not actual pos.
|
||||
PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding
|
||||
menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
PopStyleVar();
|
||||
if (menu_is_open)
|
||||
{
|
||||
@ -7218,7 +7212,8 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
|
||||
pressed = Selectable("", selected, selectable_flags, ImVec2(w, 0.0f));
|
||||
PopStyleVar();
|
||||
RenderText(text_pos, label);
|
||||
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible)
|
||||
RenderText(text_pos, label);
|
||||
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
}
|
||||
else
|
||||
@ -7232,17 +7227,20 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
|
||||
RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
||||
if (icon_w > 0.0f)
|
||||
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
if (shortcut_w > 0.0f)
|
||||
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible)
|
||||
{
|
||||
PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
||||
PopStyleColor();
|
||||
RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
||||
if (icon_w > 0.0f)
|
||||
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
if (shortcut_w > 0.0f)
|
||||
{
|
||||
PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
||||
PopStyleColor();
|
||||
}
|
||||
if (selected)
|
||||
RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
||||
}
|
||||
if (selected)
|
||||
RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
||||
}
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
|
||||
if (!enabled)
|
||||
@ -8119,7 +8117,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
if (p_open && !*p_open)
|
||||
{
|
||||
ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus);
|
||||
ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -8202,7 +8200,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
// and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'.
|
||||
if (tab_appearing && (!tab_bar_appearing || tab_is_new))
|
||||
{
|
||||
ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus);
|
||||
ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav);
|
||||
if (is_tab_button)
|
||||
return false;
|
||||
return tab_contents_visible;
|
||||
|
Loading…
Reference in New Issue
Block a user