feat: update to 068e90b418b7da440a15db6495f2a37239d30bff

This commit is contained in:
2024-09-08 18:52:23 -05:00
parent c461e29eaa
commit 58b5f87a95
66 changed files with 41337 additions and 5176 deletions

View File

@@ -1,5 +1,5 @@
Dear ImGui Test Engine License (v1.03)
Copyright (c) 2018-2023 Omar Cornut
Dear ImGui Test Engine License (v1.04)
Copyright (c) 2018-2024 Omar Cornut
This document is a legal agreement ("License") between you ("Licensee") and
DISCO HELLO ("Licensor") that governs your use of Dear ImGui Test Engine ("Software").
@@ -31,9 +31,10 @@ information are available at the following URL: http://www.dearimgui.com/license
2.1. License scope
A limited and non-exclusive license is hereby granted, to the Licensee, to reproduce,
execute, publicly perform, and display, use, copy, modify, merge, distribute, or create
derivative works based on and/or derived from the Software ("Derivative Software").
A limited and non-exclusive worldwide license is hereby granted, to the Licensee,
to reproduce, execute, publicly perform, and display, use, copy, modify, merge,
distribute, or create derivative works based on and/or derived from the Software
("Derivative Software").
2.2. Right of distribution

View File

@@ -30,6 +30,7 @@ Index of this file:
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui.h"
#include "imgui_internal.h"
#include "imgui_te_engine.h"
#include "imgui_capture_tool.h"
#include "imgui_te_utils.h" // ImPathFindFilename, ImPathFindExtension, ImPathFixSeparatorsForCurrentOS, ImFileCreateDirectoryChain, ImOsOpenInShell
#include "thirdparty/Str/Str.h"
@@ -50,7 +51,10 @@ Index of this file:
#pragma warning (push)
#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration
#pragma warning (disable: 4457) // declaration of 'xx' hides function parameter
#else
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"// warning: 'sprintf' has been explicitly marked deprecated here
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
@@ -76,7 +80,9 @@ using namespace IMGUI_STB_NAMESPACE;
#ifdef _MSC_VER
#pragma warning (pop)
#else
#elif defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
@@ -365,7 +371,7 @@ ImGuiCaptureStatus ImGuiCaptureContext::CaptureUpdate(ImGuiCaptureArgs* args)
// FIXME-CAPTURE: Window width change may affect vertical content size if window contains text that wraps. To accurately position mouse cursor for capture we avoid horizontal resize.
// Instead window width should be set manually before capture, as it is simple to do and most of the time we already have a window of desired width.
//full_size.x = ImMax(window->SizeFull.x, window->ContentSize.x + (window->WindowPadding.x + window->WindowBorderSize) * 2);
full_size.y = ImMax(window->SizeFull.y, window->ContentSize.y + (window->WindowPadding.y + window->WindowBorderSize) * 2 + window->TitleBarHeight() + window->MenuBarHeight());
full_size.y = ImMax(window->SizeFull.y, window->ContentSize.y + (window->WindowPadding.y + window->WindowBorderSize) * 2 + window->DecoOuterSizeY1);
ImGui::SetWindowSize(window, full_size);
_HoveredWindow = g.HoveredWindow;
}
@@ -732,11 +738,10 @@ void ImGuiCaptureToolUI::_CaptureWindowsSelector(ImGuiCaptureContext* context, I
if (!allow_capture)
ImGui::BeginDisabled();
bool do_capture = ImGui::Button(label, button_sz);
do_capture |= io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_C));
do_capture |= io.KeyAlt && ImGui::IsKeyPressed(ImGuiKey_C);
if (!allow_capture)
ImGui::EndDisabled();
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Alternatively press Alt+C to capture selection.");
ImGui::SetItemTooltip("Alternatively press Alt+C to capture selection.");
if (do_capture && _InitializeOutputFile())
_StateIsCapturing = true;
}
@@ -889,8 +894,8 @@ void ImGuiCaptureToolUI::ShowCaptureToolWindow(ImGuiCaptureContext* context, boo
ImOsOpenInShell(OutputLastFilename);
if (!has_last_file_name)
ImGui::EndDisabled();
if (has_last_file_name && ImGui::IsItemHovered())
ImGui::SetTooltip("Open %s", OutputLastFilename);
if (has_last_file_name)
ImGui::SetItemTooltip("Open %s", OutputLastFilename);
ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
}
@@ -908,8 +913,7 @@ void ImGuiCaptureToolUI::ShowCaptureToolWindow(ImGuiCaptureContext* context, boo
ImPathFixSeparatorsForCurrentOS(output_dir);
ImOsOpenInShell(output_dir);
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Open %s/", output_dir);
ImGui::SetItemTooltip("Open %s/", output_dir);
}
const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
@@ -917,18 +921,16 @@ void ImGuiCaptureToolUI::ShowCaptureToolWindow(ImGuiCaptureContext* context, boo
ImGui::PushItemWidth(BUTTON_WIDTH);
ImGui::InputText("Output template", _OutputFileTemplate, IM_ARRAYSIZE(_OutputFileTemplate));
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Output template should contain one %%d (or variation of it) format variable. "
"Multiple captures will be saved with an increasing number to avoid overwriting same file.");
ImGui::SetItemTooltip(
"Output template should contain one %%d (or variation of it) format variable. "
"Multiple captures will be saved with an increasing number to avoid overwriting same file.");
_ShowEncoderConfigFields(context);
ImGui::DragFloat("Padding", &_CaptureArgs.InPadding, 0.1f, 0, 32, "%.0f");
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Extra padding around captured area.");
ImGui::SetItemTooltip("Extra padding around captured area.");
ImGui::DragInt("Video FPS", &_CaptureArgs.InRecordFPSTarget, 0.1f, 10, 100, "%d fps");
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Target FPS for video captures.");
ImGui::SetItemTooltip("Target FPS for video captures.");
if (ImGui::Button("Snap Windows To Grid", ImVec2(BUTTON_WIDTH, 0)))
_SnapWindowsToGrid(SnapGridSize);
@@ -945,13 +947,12 @@ void ImGuiCaptureToolUI::ShowCaptureToolWindow(ImGuiCaptureContext* context, boo
ImGui::BeginDisabled(!content_stitching_available);
ImGui::CheckboxFlags("Stitch full contents height", &_CaptureArgs.InFlags, ImGuiCaptureFlags_StitchAll);
ImGui::EndDisabled();
if (!content_stitching_available && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
ImGui::SetTooltip("Content stitching is not possible when using viewports.");
if (!content_stitching_available)
ImGui::SetItemTooltip("Content stitching is not possible when using viewports.");
ImGui::CheckboxFlags("Include other windows", &_CaptureArgs.InFlags, ImGuiCaptureFlags_IncludeOtherWindows);
ImGui::CheckboxFlags("Include tooltips & popups", &_CaptureArgs.InFlags, ImGuiCaptureFlags_IncludeTooltipsAndPopups);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Capture area will be expanded to include visible tooltips.");
ImGui::SetItemTooltip("Capture area will be expanded to include visible tooltips.");
ImGui::PopItemWidth();
ImGui::TreePop();
@@ -1024,8 +1025,7 @@ bool ImGuiCaptureToolUI::_ShowEncoderConfigFields(ImGuiCaptureContext* context)
const bool encoder_exe_missing = !ImFileExist(context->VideoCaptureEncoderPath);
if (encoder_exe_missing)
ImGui::ItemErrorFrame(IM_COL32(255, 0, 0, 255));
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Absolute or relative path to video encoder executable (e.g. \"path/to/ffmpeg.exe\"). Required for video recording.%s", encoder_exe_missing ? "\nFile does not exist!" : "");
ImGui::SetItemTooltip("Absolute or relative path to video encoder executable (e.g. \"path/to/ffmpeg.exe\"). Required for video recording.%s", encoder_exe_missing ? "\nFile does not exist!" : "");
}
struct CmdLineParamsInfo
@@ -1105,8 +1105,7 @@ bool ImGuiCaptureToolUI::_ShowEncoderConfigFields(ImGuiCaptureContext* context)
}
ImGui::EndCombo();
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("File extension for captured video file.");
ImGui::SetItemTooltip("File extension for captured video file.");
}
return modified;
}

View File

@@ -4,7 +4,7 @@
#pragma once
#include "imgui_te_utils.h" // ImFuncPtr
// Need "imgui_te_engine.h" included for ImFuncPtr
//-----------------------------------------------------------------------------
// Forward declarations

File diff suppressed because it is too large Load Diff

View File

@@ -90,7 +90,8 @@ struct IMGUI_API ImGuiTestRefDesc
char Buf[80];
const char* c_str() { return Buf; }
ImGuiTestRefDesc(const ImGuiTestRef& ref, const ImGuiTestItemInfo* item);
ImGuiTestRefDesc(const ImGuiTestRef& ref);
ImGuiTestRefDesc(const ImGuiTestRef& ref, const ImGuiTestItemInfo& item);
};
//-------------------------------------------------------------------------
@@ -114,6 +115,7 @@ enum ImGuiTestAction
};
// Generic flags for many ImGuiTestContext functions
// Some flags are only supported by a handful of functions. Check function headers for list of supported flags.
enum ImGuiTestOpFlags_
{
ImGuiTestOpFlags_None = 0,
@@ -122,11 +124,12 @@ enum ImGuiTestOpFlags_
ImGuiTestOpFlags_NoFocusWindow = 1 << 3, // Don't focus window when aiming at an item
ImGuiTestOpFlags_NoAutoUncollapse = 1 << 4, // Disable automatically uncollapsing windows (useful when specifically testing Collapsing behaviors)
ImGuiTestOpFlags_NoAutoOpenFullPath = 1 << 5, // Disable automatically opening intermediaries (e.g. ItemClick("Hello/OK") will automatically first open "Hello" if "OK" isn't found. Only works if ref is a string path.
ImGuiTestOpFlags_IsSecondAttempt = 1 << 6, // Used by recursing functions to indicate a second attempt
ImGuiTestOpFlags_MoveToEdgeL = 1 << 7, // Simple Dumb aiming helpers to test widget that care about clicking position. May need to replace will better functionalities.
ImGuiTestOpFlags_MoveToEdgeR = 1 << 8,
ImGuiTestOpFlags_MoveToEdgeU = 1 << 9,
ImGuiTestOpFlags_MoveToEdgeD = 1 << 10,
ImGuiTestOpFlags_NoYield = 1 << 6, // Don't yield (only supported by a few functions), in case you need to manage rigorous per-frame timing.
ImGuiTestOpFlags_IsSecondAttempt = 1 << 7, // Used by recursing functions to indicate a second attempt
ImGuiTestOpFlags_MoveToEdgeL = 1 << 8, // Simple Dumb aiming helpers to test widget that care about clicking position. May need to replace will better functionalities.
ImGuiTestOpFlags_MoveToEdgeR = 1 << 9,
ImGuiTestOpFlags_MoveToEdgeU = 1 << 10,
ImGuiTestOpFlags_MoveToEdgeD = 1 << 11,
};
// Advanced filtering for ItemActionAll()
@@ -176,6 +179,7 @@ struct IMGUI_API ImGuiTestGenericVars
int Count;
ImGuiID DockId;
ImGuiID OwnerId;
ImVec2 WindowSize;
ImGuiWindowFlags WindowFlags;
ImGuiTableFlags TableFlags;
ImGuiPopupFlags PopupFlags;
@@ -185,8 +189,8 @@ struct IMGUI_API ImGuiTestGenericVars
bool UseViewports;
float Width;
ImVec2 Pos;
ImVec2 Size;
ImVec2 Pivot;
ImVec2 ItemSize;
ImVec4 Color1, Color2;
// Generic unnamed storage
@@ -283,7 +287,6 @@ struct IMGUI_API ImGuiTestContext
// Yield, Timing
void Yield(int count = 1);
void YieldUntil(int frame_count);
void Sleep(float time_in_second); // Sleep for a given simulation time, unless in Fast mode
void SleepShort(); // Standard short delay of io.ActionDelayShort (~0.15f), unless in Fast mode.
void SleepStandard(); // Standard regular delay of io.ActionDelayStandard (~0.40f), unless in Fast mode.
@@ -297,12 +300,15 @@ struct IMGUI_API ImGuiTestContext
// - SetRef("//$FOCUSED"), ItemClick("Button") --> click "Button" in focused window.
// See https://github.com/ocornut/imgui_test_engine/wiki/Named-References about using ImGuiTestRef in all ImGuiTestContext functions.
// Note: SetRef() may take multiple frames to complete if specified ref is an item id.
// Note: SetRef() ignores current reference, so they are always absolute path.
void SetRef(ImGuiTestRef ref);
void SetRef(ImGuiWindow* window); // Shortcut to SetRef(window->Name) which works for ChildWindow (see code)
ImGuiTestRef GetRef();
// Windows
ImGuiTestItemInfo* WindowInfo(ImGuiTestRef window_ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
// - Use WindowInfo() to access path to child windows, since the paths are internally mangled.
// - SetRef(WindowInfo("Parent/Child")->Window) --> set ref to child window.
ImGuiTestItemInfo WindowInfo(ImGuiTestRef window_ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
void WindowClose(ImGuiTestRef window_ref);
void WindowCollapse(ImGuiTestRef window_ref, bool collapsed);
void WindowFocus(ImGuiTestRef window_ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
@@ -340,7 +346,7 @@ struct IMGUI_API ImGuiTestContext
// Mouse inputs
void MouseMove(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
void MouseMoveToPos(ImVec2 pos);
void MouseTeleportToPos(ImVec2 pos);
void MouseTeleportToPos(ImVec2 pos, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
void MouseClick(ImGuiMouseButton button = 0);
void MouseClickMulti(ImGuiMouseButton button, int count);
void MouseDoubleClick(ImGuiMouseButton button = 0);
@@ -400,10 +406,10 @@ struct IMGUI_API ImGuiTestContext
// Low-level queries
// - ItemInfo queries never returns a NULL pointer, instead they return an empty instance (info->IsEmpty(), info->ID == 0) and set contexted as errored.
// - You can use ImGuiTestOpFlags_NoError to do a query without marking context as errored. This is what ItemExists() does.
ImGuiTestItemInfo* ItemInfo(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
ImGuiTestItemInfo* ItemInfoOpenFullPath(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
ImGuiTestItemInfo ItemInfo(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
ImGuiTestItemInfo ItemInfoOpenFullPath(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
ImGuiID ItemInfoHandleWildcardSearch(const char* wildcard_prefix_start, const char* wildcard_prefix_end, const char* wildcard_suffix_start);
ImGuiTestItemInfo* ItemInfoNull();
ImGuiTestItemInfo ItemInfoNull() { return ImGuiTestItemInfo(); }
void GatherItems(ImGuiTestItemList* out_list, ImGuiTestRef parent, int depth = -1);
// Item/Widgets manipulation
@@ -428,12 +434,12 @@ struct IMGUI_API ImGuiTestContext
void ItemInputValue(ImGuiTestRef ref, float f);
void ItemInputValue(ImGuiTestRef ref, const char* str);
// Item/Widgets: Drag and Mouse operations
void ItemHold(ImGuiTestRef ref, float time);
void ItemHoldForFrames(ImGuiTestRef ref, int frames);
void ItemDragOverAndHold(ImGuiTestRef ref_src, ImGuiTestRef ref_dst);
void ItemDragAndDrop(ImGuiTestRef ref_src, ImGuiTestRef ref_dst, ImGuiMouseButton button = 0);
void ItemDragWithDelta(ImGuiTestRef ref_src, ImVec2 pos_delta);
// Item/Widgets: Helpers to easily read a value by selecting Slider/Drag/Input text, copying into clipboard and parsing it.
// - This requires the item to be selectable (we will later provide helpers that works in more general manner)
// - Original clipboard value is restored afterward.
bool ItemSelectAndReadValue(ImGuiTestRef ref, ImGuiDataType data_type, void* out_data, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
void ItemSelectAndReadValue(ImGuiTestRef ref, int* out_v);
void ItemSelectAndReadValue(ImGuiTestRef ref, float* out_v);
// Item/Widgets: Status query
bool ItemExists(ImGuiTestRef ref);
@@ -441,6 +447,13 @@ struct IMGUI_API ImGuiTestContext
bool ItemIsOpened(ImGuiTestRef ref);
void ItemVerifyCheckedIfAlive(ImGuiTestRef ref, bool checked);
// Item/Widgets: Drag and Mouse operations
void ItemHold(ImGuiTestRef ref, float time);
void ItemHoldForFrames(ImGuiTestRef ref, int frames);
void ItemDragOverAndHold(ImGuiTestRef ref_src, ImGuiTestRef ref_dst);
void ItemDragAndDrop(ImGuiTestRef ref_src, ImGuiTestRef ref_dst, ImGuiMouseButton button = 0);
void ItemDragWithDelta(ImGuiTestRef ref_src, ImVec2 pos_delta);
// Helpers for Tab Bars widgets
void TabClose(ImGuiTestRef ref);
bool TabBarCompareOrder(ImGuiTabBar* tab_bar, const char** tab_order);
@@ -493,15 +506,17 @@ struct IMGUI_API ImGuiTestContext
// Obsolete functions
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Obsoleted 2024/05/21
void YieldUntil(int frame_count) { while (FrameCount < frame_count) { Yield(); } }
// Obsoleted 2022/10/11
ImGuiID GetIDByInt(int n); // Prefer using "$$123"
ImGuiID GetIDByInt(int n, ImGuiTestRef seed_ref);
ImGuiID GetIDByPtr(void* p); // Prefer using "$$(ptr)0xFFFFFFFF"
ImGuiID GetIDByPtr(void* p, ImGuiTestRef seed_ref);
// Obsoleted 2022/09/26
void KeyModDown(ImGuiModFlags mods) { KeyDown(mods); }
void KeyModUp(ImGuiModFlags mods) { KeyUp(mods); }
void KeyModPress(ImGuiModFlags mods) { KeyPress(mods); }
//void KeyModDown(ImGuiModFlags mods) { KeyDown(mods); }
//void KeyModUp(ImGuiModFlags mods) { KeyUp(mods); }
//void KeyModPress(ImGuiModFlags mods) { KeyPress(mods); }
#endif
// [Internal]
@@ -604,6 +619,7 @@ template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, Im
// Floating point compares
#define IM_CHECK_FLOAT_EQ_EPS(_LHS, _RHS) IM_CHECK_LE(ImFabs(_LHS - (_RHS)), FLT_EPSILON) // Float Equal
#define IM_CHECK_FLOAT_NE_EPS(_LHS, _RHS) IM_CHECK_GT(ImFabs(_LHS - (_RHS)), FLT_EPSILON) // Float Not Equal
#define IM_CHECK_FLOAT_NEAR(_LHS, _RHS, _EPS) IM_CHECK_LE(ImFabs(_LHS - (_RHS)), _EPS)
#define IM_CHECK_FLOAT_NEAR_NO_RET(_LHS, _RHS, _E) IM_CHECK_LE_NO_RET(ImFabs(_LHS - (_RHS)), _E)

View File

@@ -592,17 +592,34 @@ void ImGuiTestEngine_ApplyInputToImGuiContext(ImGuiTestEngine* engine)
case ImGuiTestInputType_Key:
{
ImGuiKeyChord key_chord = input.KeyChord;
#if IMGUI_VERSION_NUM >= 19016
#if IMGUI_VERSION_NUM >= 19016 && IMGUI_VERSION_NUM < 19063
key_chord = ImGui::FixupKeyChord(&g, key_chord); // This will add ImGuiMod_Alt when pressing ImGuiKey_LeftAlt or ImGuiKey_LeftRight
#endif
#if IMGUI_VERSION_NUM >= 19063
key_chord = ImGui::FixupKeyChord(key_chord); // This will add ImGuiMod_Alt when pressing ImGuiKey_LeftAlt or ImGuiKey_LeftRight
#endif
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
ImGuiKeyChord mods = (key_chord & ImGuiMod_Mask_);
if (mods != 0x00)
{
// OSX conversion
#if IMGUI_VERSION_NUM >= 18912
#if IMGUI_VERSION_NUM >= 18912 && IMGUI_VERSION_NUM < 19063
if (mods & ImGuiMod_Shortcut)
mods = (mods & ~ImGuiMod_Shortcut) | (g.IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl);
#endif
#if IMGUI_VERSION_NUM >= 19063
// MacOS: swap Cmd(Super) and Ctrl WILL BE SWAPPED BACK BY io.AddKeyEvent()
if (g.IO.ConfigMacOSXBehaviors)
{
if ((mods & (ImGuiMod_Ctrl | ImGuiMod_Super)) == ImGuiMod_Super)
mods = (mods & ~ImGuiMod_Super) | ImGuiMod_Ctrl;
else if ((mods & (ImGuiMod_Ctrl | ImGuiMod_Super)) == ImGuiMod_Ctrl)
mods = (mods & ~ImGuiMod_Ctrl) | ImGuiMod_Super;
if (key == ImGuiKey_LeftSuper) { key = ImGuiKey_LeftCtrl; }
else if (key == ImGuiKey_LeftSuper) { key = ImGuiKey_RightCtrl; }
else if (key == ImGuiKey_LeftCtrl) { key = ImGuiKey_LeftSuper; }
else if (key == ImGuiKey_LeftCtrl) { key = ImGuiKey_RightSuper; }
}
#endif
// Submitting a ImGuiMod_XXX without associated key needs to add at least one of the key.
if (mods & ImGuiMod_Ctrl)
@@ -805,7 +822,7 @@ static void ImGuiTestEngine_PostNewFrame(ImGuiTestEngine* engine, ImGuiContext*
for (int task_n = 0; task_n < engine->InfoTasks.Size; task_n++)
{
ImGuiTestInfoTask* task = engine->InfoTasks[task_n];
if (task->FrameCount < engine->FrameCount - LOCATION_TASK_ELAPSE_FRAMES && task->Result.RefCount == 0)
if (task->FrameCount < engine->FrameCount - LOCATION_TASK_ELAPSE_FRAMES)
{
IM_DELETE(task);
engine->InfoTasks.erase(engine->InfoTasks.Data + task_n);
@@ -950,7 +967,7 @@ int ImGuiTestEngine_GetFrameCount(ImGuiTestEngine* engine)
const char* ImGuiTestEngine_GetStatusName(ImGuiTestStatus v)
{
static const char* names[ImGuiTestStatus_COUNT] = { "Success", "Queued", "Running", "Error", "Suspended" };
static const char* names[ImGuiTestStatus_COUNT] = { "Unknown", "Success", "Queued", "Running", "Error", "Suspended" };
IM_STATIC_ASSERT(IM_ARRAYSIZE(names) == ImGuiTestStatus_COUNT);
if (v >= 0 && v < IM_ARRAYSIZE(names))
return names[v];
@@ -1172,6 +1189,32 @@ ImGuiTest* ImGuiTestEngine_RegisterTest(ImGuiTestEngine* engine, const char* cat
return t;
}
void ImGuiTestEngine_UnregisterTest(ImGuiTestEngine* engine, ImGuiTest* test)
{
// Cannot unregister a running test. Please contact us if you need this.
if (engine->TestContext != NULL)
IM_ASSERT(engine->TestContext->Test != test);
// Remove from lists
bool found = engine->TestsAll.find_erase(test);
IM_ASSERT(found); // Calling ImGuiTestEngine_UnregisterTest() on an unknown test.
for (int n = 0; n < engine->TestsQueue.Size; n++)
{
ImGuiTestRunTask& task = engine->TestsQueue[n];
if (task.Test == test)
{
engine->TestsQueue.erase(&task);
n--;
}
}
if (engine->UiSelectAndScrollToTest == test)
engine->UiSelectAndScrollToTest = NULL;
if (engine->UiSelectedTest == test)
engine->UiSelectedTest = NULL;
IM_DELETE(test);
}
ImGuiPerfTool* ImGuiTestEngine_GetPerfTool(ImGuiTestEngine* engine)
{
return engine->PerfTool;
@@ -1297,8 +1340,9 @@ void ImGuiTestEngine_QueueTests(ImGuiTestEngine* engine, ImGuiTestGroup group, c
if (group != ImGuiTestGroup_Unknown && test->Group != group)
continue;
if (!ImGuiTestEngine_PassFilter(test, filter_str))
continue;
if (filter_str != NULL)
if (!ImGuiTestEngine_PassFilter(test, filter_str))
continue;
ImGuiTestEngine_QueueTest(engine, test, run_flags);
}
@@ -1386,8 +1430,10 @@ struct ImGuiTestContextUiContextBackup
IO = g.IO;
Style = g.Style;
DebugLogFlags = g.DebugLogFlags;
#if IMGUI_VERSION_NUM >= 18837
ConfigNavWindowingKeyNext = g.ConfigNavWindowingKeyNext;
ConfigNavWindowingKeyPrev = g.ConfigNavWindowingKeyPrev;
#endif
memset(IO.MouseDown, 0, sizeof(IO.MouseDown));
for (int n = 0; n < IM_ARRAYSIZE(IO.KeysData); n++)
IO.KeysData[n].Down = false;
@@ -1400,8 +1446,10 @@ struct ImGuiTestContextUiContextBackup
g.IO = IO;
g.Style = Style;
g.DebugLogFlags = DebugLogFlags;
#if IMGUI_VERSION_NUM >= 18837
g.ConfigNavWindowingKeyNext = ConfigNavWindowingKeyNext;
g.ConfigNavWindowingKeyPrev = ConfigNavWindowingKeyPrev;
#endif
}
void RestoreClipboardFuncs(ImGuiContext& g)
{
@@ -1517,19 +1565,12 @@ void ImGuiTestEngine_RunTest(ImGuiTestEngine* engine, ImGuiTestContext* parent_c
else
{
ctx->LogWarning("Child Test: '%s' '%s'..", test->Category, test->Name);
ctx->LogWarning("(ShareVars=%d ShareTestContext=%d)", (run_flags & ImGuiTestRunFlags_ShareVars) ? 1 : 0, (run_flags & ImGuiTestRunFlags_ShareTestContext) ? 1 : 0);
ctx->LogDebug("(ShareVars=%d ShareTestContext=%d)", (run_flags & ImGuiTestRunFlags_ShareVars) ? 1 : 0, (run_flags & ImGuiTestRunFlags_ShareTestContext) ? 1 : 0);
}
// Clear ImGui inputs to avoid key/mouse leaks from one test to another
ImGuiTestEngine_ClearInput(engine);
ctx->FrameCount = parent_ctx ? parent_ctx->FrameCount : 0;
ctx->ErrorCounter = 0;
ctx->SetRef("");
ctx->SetInputMode(ImGuiInputSource_Mouse);
ctx->UiContext->NavInputSource = ImGuiInputSource_Keyboard;
ctx->Clipboard.clear();
// Backup entire IO and style. Allows tests modifying them and not caring about restoring state.
ImGuiTestContextUiContextBackup backup_ui_context;
backup_ui_context.Backup(*ctx->UiContext);
@@ -1570,6 +1611,12 @@ void ImGuiTestEngine_RunTest(ImGuiTestEngine* engine, ImGuiTestContext* parent_c
ImGuiTestActiveFunc backup_active_func = ctx->ActiveFunc;
ctx->ActiveFunc = ImGuiTestActiveFunc_TestFunc;
ctx->FirstGuiFrame = (test->GuiFunc != NULL) ? true : false;
ctx->FrameCount = parent_ctx ? parent_ctx->FrameCount : 0;
ctx->ErrorCounter = 0;
ctx->SetRef("");
ctx->SetInputMode(ImGuiInputSource_Mouse);
ctx->UiContext->NavInputSource = ImGuiInputSource_Keyboard;
ctx->Clipboard.clear();
// Warm up GUI
// - We need one mandatory frame running GuiFunc before running TestFunc
@@ -2055,14 +2102,14 @@ void ImGuiTestEngineHook_Log(ImGuiContext* ui_ctx, const char* fmt, ...)
// Your custom assert code may optionally want to call this.
void ImGuiTestEngine_AssertLog(const char* expr, const char* file, const char* function, int line)
{
ImGuiTestEngine* engine = GImGuiTestEngine;
if (ImGuiTestContext* ctx = engine->TestContext)
{
ctx->LogError("Assert: '%s'", expr);
ctx->LogWarning("In %s:%d, function %s()", file, line, function);
if (ImGuiTest* test = ctx->Test)
ctx->LogWarning("While running test: %s %s", test->Category, test->Name);
}
if (ImGuiTestEngine* engine = GImGuiTestEngine)
if (ImGuiTestContext* ctx = engine->TestContext)
{
ctx->LogError("Assert: '%s'", expr);
ctx->LogWarning("In %s:%d, function %s()", file, line, function);
if (ImGuiTest* test = ctx->Test)
ctx->LogWarning("While running test: %s %s", test->Category, test->Name);
}
}
// Used by IM_CHECK_OP() macros

View File

@@ -7,7 +7,28 @@
#include "imgui.h"
#include "imgui_internal.h" // ImPool<>, ImRect, ImGuiItemStatusFlags, ImFormatString
#include "imgui_te_utils.h" // ImFuncPtr
#if defined(__clang__)
#pragma clang diagnostic push
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif
#ifdef Status // X11 headers
#undef Status
#endif
//-----------------------------------------------------------------------------
// Function Pointers
//-----------------------------------------------------------------------------
#if IMGUI_TEST_ENGINE_ENABLE_STD_FUNCTION
#include <functional>
#define ImFuncPtr(FUNC_TYPE) std::function<FUNC_TYPE>
#else
#define ImFuncPtr(FUNC_TYPE) FUNC_TYPE*
#endif
#include "imgui_capture_tool.h" // ImGuiScreenCaptureFunc
//-------------------------------------------------------------------------
@@ -70,12 +91,12 @@ enum ImGuiTestVerboseLevel : int
// Test status (stored in ImGuiTest)
enum ImGuiTestStatus : int
{
ImGuiTestStatus_Unknown = -1,
ImGuiTestStatus_Success = 0,
ImGuiTestStatus_Queued = 1,
ImGuiTestStatus_Running = 2,
ImGuiTestStatus_Error = 3,
ImGuiTestStatus_Suspended = 4,
ImGuiTestStatus_Unknown = 0,
ImGuiTestStatus_Success = 1,
ImGuiTestStatus_Queued = 2,
ImGuiTestStatus_Running = 3,
ImGuiTestStatus_Error = 4,
ImGuiTestStatus_Suspended = 5,
ImGuiTestStatus_COUNT
};
@@ -168,6 +189,7 @@ IMGUI_API ImGuiTestEngineIO& ImGuiTestEngine_GetIO(ImGuiTestEngine* engine);
// Macros: Register Test
#define IM_REGISTER_TEST(_ENGINE, _CATEGORY, _NAME) ImGuiTestEngine_RegisterTest(_ENGINE, _CATEGORY, _NAME, __FILE__, __LINE__)
IMGUI_API ImGuiTest* ImGuiTestEngine_RegisterTest(ImGuiTestEngine* engine, const char* category, const char* name, const char* src_file = NULL, int src_line = 0); // Prefer calling IM_REGISTER_TEST()
IMGUI_API void ImGuiTestEngine_UnregisterTest(ImGuiTestEngine* engine, ImGuiTest* test);
// Functions: Main
IMGUI_API void ImGuiTestEngine_QueueTest(ImGuiTestEngine* engine, ImGuiTest* test, ImGuiTestRunFlags run_flags = 0);
@@ -275,22 +297,20 @@ struct IMGUI_API ImGuiTestEngineIO
// Information about a given item or window, result of an ItemInfo() or WindowInfo() query
struct ImGuiTestItemInfo
{
int RefCount : 8; // User can increment this if they want to hold on the result pointer across frames, otherwise the task will be GC-ed.
ImGuiID ID = 0; // Item ID
char DebugLabel[32] = {}; // Shortened/truncated label for debugging and convenience purpose
ImGuiWindow* Window = NULL; // Item Window
unsigned int NavLayer : 1; // Nav layer of the item (ImGuiNavLayer)
int Depth : 16; // Depth from requested parent id. 0 == ID is immediate child of requested parent id.
int TimestampMain = -1; // Timestamp of main result (all fields)
int TimestampStatus = -1; // Timestamp of StatusFlags
ImGuiID ID = 0; // Item ID
int TimestampMain; // Timestamp of main result (all fields)
int TimestampStatus; // Timestamp of StatusFlags
ImGuiID ParentID = 0; // Item Parent ID (value at top of the ID stack)
ImGuiWindow* Window = NULL; // Item Window
ImRect RectFull = ImRect(); // Item Rectangle
ImRect RectClipped = ImRect(); // Item Rectangle (clipped with window->ClipRect at time of item submission)
ImGuiItemFlags InFlags = 0; // Item flags
ImGuiItemStatusFlags StatusFlags = 0; // Item Status flags (fully updated for some items only, compare TimestampStatus to FrameCount)
char DebugLabel[32] = {}; // Shortened label for debugging purpose
ImGuiTestItemInfo() { RefCount = 0; NavLayer = 0; Depth = 0; }
bool IsEmpty() const { return ID == 0; }
ImGuiTestItemInfo() { memset(this, 0, sizeof(*this)); }
};
// Result of an GatherItems() query
@@ -427,3 +447,9 @@ struct IMGUI_API ImGuiTestRunTask
};
//-------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

View File

@@ -138,7 +138,7 @@ struct ImGuiTestEngine
float OverrideDeltaTime = -1.0f; // Inject custom delta time into imgui context to simulate clock passing faster than wall clock time.
ImVector<ImGuiTest*> TestsAll;
ImVector<ImGuiTestRunTask> TestsQueue;
ImGuiTestContext* TestContext = NULL;
ImGuiTestContext* TestContext = NULL; // Running test context
ImVector<ImGuiTestInfoTask*>InfoTasks;
ImGuiTestGatherTask GatherTask;
ImGuiTestFindByLabelTask FindByLabelTask;

View File

@@ -435,8 +435,13 @@ static bool RenderMultiSelectFilter(ImGuiPerfTool* perf, const char* filter_hint
ImGui::SetTooltip("Hold CTRL to invert other items.\nHold SHIFT to close popup instantly.");
// Keep popup open for multiple actions if SHIFT is pressed.
#if IMGUI_VERSION_NUM >= 19094
if (!io.KeyShift)
ImGui::PushItemFlag(ImGuiItemFlags_AutoClosePopups, false);
#else
if (!io.KeyShift)
ImGui::PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);
#endif
if (ImGui::MenuItem("Show All"))
{
@@ -1050,8 +1055,6 @@ void ImGuiPerfTool::ShowPerfToolWindow(ImGuiTestEngine* engine, bool* p_open)
if (ImGui::IsWindowAppearing() && Empty())
LoadCSV();
ImGuiStyle& style = ImGui::GetStyle();
// -----------------------------------------------------------------------------------------------------------------
// Render utility buttons
// -----------------------------------------------------------------------------------------------------------------
@@ -1157,10 +1160,7 @@ void ImGuiPerfTool::ShowPerfToolWindow(ImGuiTestEngine* engine, bool* p_open)
ImGui::SetTooltip("Generate a report and open it in the browser.");
// Align help button to the right.
float help_pos = ImGui::GetWindowContentRegionMax().x - style.FramePadding.x * 2 - ImGui::CalcTextSize("(?)").x;
if (help_pos > ImGui::GetCursorPosX())
ImGui::SetCursorPosX(help_pos);
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImMax(0.0f, ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize("(?)").x));
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered())
{
@@ -1263,6 +1263,7 @@ void ImGuiPerfTool::ShowPerfToolWindow(ImGuiTestEngine* engine, bool* p_open)
{
#if IMGUI_TEST_ENGINE_ENABLE_IMPLOT
// Splitter between two following child windows is rendered first.
ImGuiStyle& style = ImGui::GetStyle();
float plot_height = 0.0f;
float& table_height = _InfoTableHeight;
ImGui::Splitter("splitter", &plot_height, &table_height, ImGuiAxis_Y, +1);
@@ -1843,7 +1844,7 @@ void RegisterTests_TestEnginePerfTool(ImGuiTestEngine* e)
ctx->WindowMove("", ImVec2(50, 50));
ctx->WindowResize("", ImVec2(1400, 900));
#if IMGUI_TEST_ENGINE_ENABLE_IMPLOT
ImGuiWindow* plot_child = ctx->WindowInfo("plot")->Window; // "plot/PerfTool" prior to implot 2023/08/21
ImGuiWindow* plot_child = ctx->WindowInfo("plot").Window; // "plot/PerfTool" prior to implot 2023/08/21
IM_CHECK(plot_child != NULL);
// Move legend to right side.
@@ -1910,7 +1911,7 @@ void RegisterTests_TestEnginePerfTool(ImGuiTestEngine* e)
#if IMGUI_TEST_ENGINE_ENABLE_IMPLOT
ctx->ItemDoubleClick("splitter"); // Hide info table
ImGuiWindow* plot_child = ctx->WindowInfo("plot")->Window; // "plot/PerfTool" prior to implot 2023/08/21
ImGuiWindow* plot_child = ctx->WindowInfo("plot").Window; // "plot/PerfTool" prior to implot 2023/08/21
IM_CHECK(plot_child != NULL);
// Move legend to right side.
@@ -1928,7 +1929,7 @@ void RegisterTests_TestEnginePerfTool(ImGuiTestEngine* e)
// Take a screenshot.
ImGuiCaptureArgs* args = ctx->CaptureArgs;
args->InCaptureRect = plot_child->Rect();
ctx->CaptureAddWindow(window->Name);
ctx->CaptureAddWindow(window->ID);
ctx->CaptureScreenshot(ImGuiCaptureFlags_HideMouseCursor);
ctx->ItemDragWithDelta("splitter", ImVec2(0, -180)); // Show info table
perf_report_image = args->InOutputFile;

View File

@@ -177,7 +177,11 @@ static void DrawTestLog(ImGuiTestEngine* e, ImGuiTest* test)
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32_WHITE);
break;
}
#if IMGUI_VERSION_NUM >= 19072
ImGui::DebugTextUnformattedWithLocateItem(line_start, line_end);
#else
ImGui::TextUnformatted(line_start, line_end);
#endif
ImGui::PopStyleColor();
ImGui::PushID(line_no);
@@ -277,13 +281,16 @@ static void ShowTestGroup(ImGuiTestEngine* e, ImGuiTestGroup group, Str* filter)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetFrameHeight() + style.ItemInnerSpacing.x);
//ImGui::Text("TESTS (%d)", engine->TestsAll.Size);
#if IMGUI_VERSION_NUM >= 18837
#if IMGUI_VERSION_NUM >= 19066
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_R, ImGuiInputFlags_Tooltip | ImGuiInputFlags_RouteFromRootWindow);
bool run = ImGui::Button("Run");
#elif IMGUI_VERSION_NUM >= 18837
bool run = ImGui::Button("Run") || ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_R);
#else
bool = ImGui::Button("Run");
#endif
#if IMGUI_VERSION_NUM > 18963
ImGui::SetItemTooltip("Ctrl+R");
#endif
#else
bool run = ImGui::Button("Run");
#endif
if (run)
{
@@ -320,7 +327,7 @@ static void ShowTestGroup(ImGuiTestEngine* e, ImGuiTestGroup group, Str* filter)
ImGui::SameLine();
const char* perflog_label = "Perf Tool";
float filter_width = ImGui::GetWindowContentRegionMax().x - ImGui::GetCursorPos().x;
float filter_width = ImGui::GetContentRegionAvail().x;
float perf_stress_factor_width = (30 * dpi_scale);
if (group == ImGuiTestGroup_Perfs)
{
@@ -329,6 +336,9 @@ static void ShowTestGroup(ImGuiTestEngine* e, ImGuiTestGroup group, Str* filter)
}
filter_width -= ImGui::CalcTextSize("(?)").x + style.ItemSpacing.x;
ImGui::SetNextItemWidth(ImMax(20.0f, filter_width));
#if IMGUI_VERSION_NUM >= 19066
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F, ImGuiInputFlags_Tooltip | ImGuiInputFlags_RouteFromRootWindow);
#endif
ImGui::InputText("##filter", filter);
ImGui::SameLine();
ImGui::TextDisabled("(?)");
@@ -354,6 +364,7 @@ static void ShowTestGroup(ImGuiTestEngine* e, ImGuiTestGroup group, Str* filter)
int tests_completed = 0;
int tests_succeeded = 0;
int tests_failed = 0;
ImVector<ImGuiTest*> tests_to_remove;
if (ImGui::BeginTable("Tests", 3, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_SizingFixedFit))
{
ImGui::TableSetupScrollFreeze(0, 1);
@@ -515,6 +526,11 @@ static void ShowTestGroup(ImGuiTestEngine* e, ImGuiTestGroup group, Str* filter)
if (ImGui::MenuItem("Clear log", NULL, false, !test_log->IsEmpty()))
test_log->Clear();
// [DEBUG] Simple way to exercise ImGuiTestEngine_UnregisterTest()
//ImGui::Separator();
//if (ImGui::MenuItem("Remove test"))
// tests_to_remove.push_back(test);
ImGui::EndPopup();
}
@@ -571,6 +587,10 @@ static void ShowTestGroup(ImGuiTestEngine* e, ImGuiTestGroup group, Str* filter)
ImGui::EndTable();
}
// Process removal
for (ImGuiTest* test : tests_to_remove)
ImGuiTestEngine_UnregisterTest(e, test);
// Display test status recap (colors match per-test run button colors defined above)
{
ImVec4 status_color;
@@ -750,22 +770,34 @@ static void ImGuiTestEngine_ShowTestTool(ImGuiTestEngine* engine, bool* p_open)
"- Cinematic: Run tests with pauses between actions (for e.g. tutorials)."
);
ImGui::SameLine();
//ImGui::Checkbox("Fast", &engine->IO.ConfigRunFast);
//ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
// (Would be good if we exposed horizontal layout mode..)
ImGui::Checkbox("Stop", &engine->IO.ConfigStopOnError);
ImGui::SetItemTooltip("Stop running tests when hitting an error.");
ImGui::SetItemTooltip("When hitting an error:\n- Stop running other tests.");
ImGui::SameLine();
ImGui::Checkbox("DbgBrk", &engine->IO.ConfigBreakOnError);
ImGui::SetItemTooltip("Break in debugger when hitting an error.");
ImGui::SetItemTooltip("When hitting an error:\n- Break in debugger.");
ImGui::SameLine();
ImGui::Checkbox("KeepGUI", &engine->IO.ConfigKeepGuiFunc);
ImGui::SetItemTooltip("Keep GUI function running after a test fails, or when a single queued test is finished.\nHold ESC to abort a running GUI function.");
ImGui::SameLine();
ImGui::Checkbox("Refocus", &engine->IO.ConfigRestoreFocusAfterTests);
ImGui::SetItemTooltip("Restore focus back after running tests.");
ImGui::Checkbox("Capture", &engine->IO.ConfigCaptureOnError);
ImGui::SetItemTooltip("When hitting an error:\n- Capture screen to PNG. Right-click filename in Test Log to open.");
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
ImGui::Checkbox("KeepGUI", &engine->IO.ConfigKeepGuiFunc);
ImGui::SetItemTooltip("After running single test or hitting an error:\n- Keep GUI function visible and interactive.\n- Hold ESC to abort a running GUI function.");
ImGui::SameLine();
bool keep_focus = !engine->IO.ConfigRestoreFocusAfterTests;
if (ImGui::Checkbox("KeepFocus", &keep_focus))
engine->IO.ConfigRestoreFocusAfterTests = !keep_focus;
ImGui::SetItemTooltip("After running tests:\n- Keep GUI current focus, instead of restoring focus to this window.");
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
ImGui::SetNextItemWidth(70 * dpi_scale);
if (ImGui::BeginCombo("##Verbose", ImGuiTestEngine_GetVerboseLevelName(engine->IO.ConfigVerboseLevel), ImGuiComboFlags_None))
{
@@ -775,6 +807,7 @@ static void ImGuiTestEngine_ShowTestTool(ImGuiTestEngine* engine, bool* p_open)
ImGui::EndCombo();
}
ImGui::SetItemTooltip("Verbose level.");
//ImGui::PopStyleVar();
ImGui::Separator();

View File

@@ -26,6 +26,9 @@
#include <sys/types.h>
#include <sys/stat.h> // stat()
#endif
#ifdef __APPLE__
#include <sys/sysctl.h>
#endif
#if defined(__linux) || defined(__linux__) || defined(__MACH__) || defined(__MSL__) || defined(__MINGW32__)
#include <pthread.h> // pthread_setname_np()
@@ -280,7 +283,7 @@ bool ImFileCreateDirectoryChain(const char* path, const char* path_end)
path_local[path_len] = 0;
#if defined(_WIN32)
ImVector<ImWchar> buf;
ImVector<wchar_t> buf;
#endif
// Modification of passed file_name allows us to avoid extra temporary memory allocation.
// strtok() pokes \0 into places where slashes are, we create a directory using directory_name and restore slash.
@@ -291,10 +294,11 @@ bool ImFileCreateDirectoryChain(const char* path, const char* path_end)
*(token - 1) = IM_DIR_SEPARATOR;
#if defined(_WIN32)
// Use ::CreateDirectoryW() because ::CreateDirectoryA() treat filenames in the local code-page instead of UTF-8.
const int filename_wsize = ImTextCountCharsFromUtf8(path_local, NULL) + 1;
// Use ::CreateDirectoryW() because ::CreateDirectoryA() treat filenames in the local code-page instead of UTF-8
// We cannot use ImWchar, which can be 32bits if IMGUI_USE_WCHAR32 (and CreateDirectoryW require 16bits wchar)
int filename_wsize = MultiByteToWideChar(CP_UTF8, 0, path_local, -1, NULL, 0);
buf.resize(filename_wsize);
ImTextStrFromUtf8(&buf[0], filename_wsize, path_local, NULL);
MultiByteToWideChar(CP_UTF8, 0, path_local, -1, &buf[0], filename_wsize);
if (!::CreateDirectoryW((wchar_t*)&buf[0], NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
#else
if (mkdir(path_local, S_IRWXU) != 0 && errno != EEXIST)
@@ -785,10 +789,11 @@ const ImBuildInfo* ImBuildGetCompilationInfo()
// CPU
#if defined(_M_X86) || defined(_M_IX86) || defined(__i386) || defined(__i386__) || defined(_X86_) || defined(_M_AMD64) || defined(_AMD64_) || defined(__x86_64__)
build_info.Cpu = (sizeof(size_t) == 4) ? "X86" : "X64";
#elif defined(__aarch64__)
#elif defined(__aarch64__) || (defined(_M_ARM64) && defined(_WIN64))
build_info.Cpu = "ARM64";
#elif defined(__EMSCRIPTEN__)
build_info.Cpu = "WebAsm";
#else
#error
build_info.Cpu = (sizeof(size_t) == 4) ? "Unknown32" : "Unknown64";
#endif
@@ -1000,6 +1005,27 @@ bool ImOsIsDebuggerPresent()
debugger_pid = atoi(tracer_pid);
}
return debugger_pid != 0;
#elif defined(__APPLE__)
// https://stackoverflow.com/questions/2200277/detecting-debugger-on-mac-os-x
int junk;
int mib[4];
struct kinfo_proc info;
size_t size;
// Initialize mib, which tells sysctl the info we want, in this case
// we're looking for information about a specific process ID.
info.kp_proc.p_flag = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = getpid();
size = sizeof(info);
junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
IM_ASSERT(junk == 0);
// We're being debugged if the P_TRACED flag is set.
return (info.kp_proc.p_flag & P_TRACED) != 0;
#else
// FIXME
return false;
@@ -1212,6 +1238,7 @@ void TableDiscardInstanceAndSettings(ImGuiID table_id)
// Helper to verify ImDrawData integrity of buffer count (broke before e.g. #6716)
void DrawDataVerifyMatchingBufferCount(ImDrawData* draw_data)
{
#if IMGUI_VERSION_NUM >= 18973
int total_vtx_count = 0;
int total_idx_count = 0;
for (ImDrawList* draw_list : draw_data->CmdLists)
@@ -1223,6 +1250,9 @@ void DrawDataVerifyMatchingBufferCount(ImDrawData* draw_data)
IM_UNUSED(total_idx_count);
IM_ASSERT(total_vtx_count == draw_data->TotalVtxCount);
IM_ASSERT(total_idx_count == draw_data->TotalIdxCount);
#else
IM_UNUSED(draw_data);
#endif
}
//-----------------------------------------------------------------------------

View File

@@ -13,17 +13,6 @@
#include "imgui.h" // ImGuiID, ImGuiKey
class Str; // Str<> from thirdparty/Str/Str.h
//-----------------------------------------------------------------------------
// Function Pointers
//-----------------------------------------------------------------------------
#if IMGUI_TEST_ENGINE_ENABLE_STD_FUNCTION
#include <functional>
#define ImFuncPtr(FUNC_TYPE) std::function<FUNC_TYPE>
#else
#define ImFuncPtr(FUNC_TYPE) FUNC_TYPE*
#endif
//-----------------------------------------------------------------------------
// Hashing Helpers
//-----------------------------------------------------------------------------