1058#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
1059#define _CRT_SECURE_NO_WARNINGS
1062#ifndef IMGUI_DEFINE_MATH_OPERATORS
1063#define IMGUI_DEFINE_MATH_OPERATORS
1067#ifndef IMGUI_DISABLE
1068#include "imgui_internal.h"
1075#if defined(_WIN32) && !defined(_MSC_VER) && !defined(IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)
1076#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
1080#if defined(_WIN32) && defined(IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) && defined(IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
1081#define IMGUI_DISABLE_WIN32_FUNCTIONS
1083#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
1084#ifndef WIN32_LEAN_AND_MEAN
1085#define WIN32_LEAN_AND_MEAN
1095#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
1097#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
1098#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
1099#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS
1104#if defined(__APPLE__)
1105#include <TargetConditionals.h>
1110#pragma warning (disable: 4127)
1111#pragma warning (disable: 4996)
1112#if defined(_MSC_VER) && _MSC_VER >= 1922
1113#pragma warning (disable: 5054)
1115#pragma warning (disable: 26451)
1116#pragma warning (disable: 26495)
1117#pragma warning (disable: 26812)
1121#if defined(__clang__)
1122#if __has_warning("-Wunknown-warning-option")
1123#pragma clang diagnostic ignored "-Wunknown-warning-option"
1125#pragma clang diagnostic ignored "-Wunknown-pragmas"
1126#pragma clang diagnostic ignored "-Wold-style-cast"
1127#pragma clang diagnostic ignored "-Wfloat-equal"
1128#pragma clang diagnostic ignored "-Wformat-nonliteral"
1129#pragma clang diagnostic ignored "-Wexit-time-destructors"
1130#pragma clang diagnostic ignored "-Wglobal-constructors"
1131#pragma clang diagnostic ignored "-Wsign-conversion"
1132#pragma clang diagnostic ignored "-Wformat-pedantic"
1133#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
1134#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
1135#pragma clang diagnostic ignored "-Wdouble-promotion"
1136#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
1137#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
1138#elif defined(__GNUC__)
1140#pragma GCC diagnostic ignored "-Wpragmas"
1141#pragma GCC diagnostic ignored "-Wunused-function"
1142#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
1143#pragma GCC diagnostic ignored "-Wformat"
1144#pragma GCC diagnostic ignored "-Wdouble-promotion"
1145#pragma GCC diagnostic ignored "-Wconversion"
1146#pragma GCC diagnostic ignored "-Wformat-nonliteral"
1147#pragma GCC diagnostic ignored "-Wstrict-overflow"
1148#pragma GCC diagnostic ignored "-Wclass-memaccess"
1152#define IMGUI_DEBUG_NAV_SCORING 0
1153#define IMGUI_DEBUG_NAV_RECTS 0
1156static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f;
1157static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f;
1159static const float NAV_ACTIVATE_HIGHLIGHT_TIMER = 0.10f;
1162static const float WINDOWS_HOVER_PADDING = 4.0f;
1163static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f;
1164static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 0.70f;
1167static const ImVec2 TOOLTIP_DEFAULT_OFFSET_MOUSE = ImVec2(16, 10);
1168static const ImVec2 TOOLTIP_DEFAULT_OFFSET_TOUCH = ImVec2(0, -20);
1169static const ImVec2 TOOLTIP_DEFAULT_PIVOT_TOUCH = ImVec2(0.5f, 1.0f);
1172static const float DOCKING_TRANSPARENT_PAYLOAD_ALPHA = 0.50f;
1178static void SetCurrentWindow(ImGuiWindow* window);
1179static ImGuiWindow* CreateNewWindow(
const char* name, ImGuiWindowFlags flags);
1180static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window);
1182static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window);
1185static void WindowSettingsHandler_ClearAll(ImGuiContext*, ImGuiSettingsHandler*);
1186static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*,
const char* name);
1187static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*,
void* entry,
const char* line);
1188static void WindowSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSettingsHandler*);
1189static void WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf);
1192static const char* Platform_GetClipboardTextFn_DefaultImpl(ImGuiContext* ctx);
1193static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext* ctx,
const char* text);
1194static void Platform_SetImeDataFn_DefaultImpl(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data);
1195static bool Platform_OpenInShellFn_DefaultImpl(ImGuiContext* ctx,
const char* path);
1200static void ItemHandleShortcut(ImGuiID
id);
1203static void NavUpdate();
1204static void NavUpdateWindowing();
1205static void NavUpdateWindowingOverlay();
1206static void NavUpdateCancelRequest();
1207static void NavUpdateCreateMoveRequest();
1208static void NavUpdateCreateTabbingRequest();
1209static float NavUpdatePageUpPageDown();
1210static inline void NavUpdateAnyRequestFlag();
1211static void NavUpdateCreateWrappingRequest();
1212static void NavEndFrame();
1213static bool NavScoreItem(ImGuiNavItemData* result);
1214static void NavApplyItemToResult(ImGuiNavItemData* result);
1215static void NavProcessItem();
1216static void NavProcessItemForTabbingRequest(ImGuiID
id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags);
1217static ImGuiInputSource NavCalcPreferredRefPosSource();
1218static ImVec2 NavCalcPreferredRefPos();
1219static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
1220static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
1221static void NavRestoreLayer(ImGuiNavLayer layer);
1222static int FindWindowFocusIndex(ImGuiWindow* window);
1225static void ErrorCheckNewFrameSanityChecks();
1226static void ErrorCheckEndFrameSanityChecks();
1227static void UpdateDebugToolItemPicker();
1228static void UpdateDebugToolStackQueries();
1229static void UpdateDebugToolFlashStyleColor();
1232static void UpdateKeyboardInputs();
1233static void UpdateMouseInputs();
1234static void UpdateMouseWheel();
1235static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt);
1238static void UpdateSettings();
1239static int UpdateWindowManualResize(ImGuiWindow* window,
const ImVec2& size_auto_fit,
int* border_hovered,
int* border_held,
int resize_grip_count, ImU32 resize_grip_col[4],
const ImRect& visibility_rect);
1240static void RenderWindowOuterBorders(ImGuiWindow* window);
1241static void RenderWindowDecorations(ImGuiWindow* window,
const ImRect& title_bar_rect,
bool title_bar_is_highlight,
bool handle_borders_and_resize_grips,
int resize_grip_count,
const ImU32 resize_grip_col[4],
float resize_grip_draw_size);
1242static void RenderWindowTitleBarContents(ImGuiWindow* window,
const ImRect& title_bar_rect,
const char* name,
bool* p_open);
1243static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
1244static void RenderDimmedBackgrounds();
1245static void SetLastItemDataForWindow(ImGuiWindow* window,
const ImRect& rect);
1249static ImGuiViewportP* AddUpdateViewport(ImGuiWindow* window, ImGuiID
id,
const ImVec2& platform_pos,
const ImVec2& size, ImGuiViewportFlags flags);
1250static void DestroyViewport(ImGuiViewportP* viewport);
1251static void UpdateViewportsNewFrame();
1252static void UpdateViewportsEndFrame();
1253static void WindowSelectViewport(ImGuiWindow* window);
1254static void WindowSyncOwnedViewport(ImGuiWindow* window, ImGuiWindow* parent_window_in_stack);
1255static bool UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* host_viewport);
1256static bool UpdateTryMergeWindowIntoHostViewports(ImGuiWindow* window);
1257static bool GetWindowAlwaysWantOwnViewport(ImGuiWindow* window);
1258static int FindPlatformMonitorForPos(
const ImVec2& pos);
1259static int FindPlatformMonitorForRect(
const ImRect& r);
1260static void UpdateViewportPlatformMonitor(ImGuiViewportP* viewport);
1295#ifndef IMGUI_DISABLE_DEFAULT_ALLOCATORS
1296static void* MallocWrapper(
size_t size,
void* user_data) { IM_UNUSED(user_data);
return malloc(size); }
1297static void FreeWrapper(
void* ptr,
void* user_data) { IM_UNUSED(user_data); free(ptr); }
1299static void* MallocWrapper(
size_t size,
void* user_data) { IM_UNUSED(user_data); IM_UNUSED(size); IM_ASSERT(0);
return NULL; }
1300static void FreeWrapper(
void* ptr,
void* user_data) { IM_UNUSED(user_data); IM_UNUSED(ptr); IM_ASSERT(0); }
1302static ImGuiMemAllocFunc GImAllocatorAllocFunc = MallocWrapper;
1303static ImGuiMemFreeFunc GImAllocatorFreeFunc = FreeWrapper;
1304static void* GImAllocatorUserData = NULL;
1310ImGuiStyle::ImGuiStyle()
1313 DisabledAlpha = 0.60f;
1314 WindowPadding = ImVec2(8,8);
1315 WindowRounding = 0.0f;
1316 WindowBorderSize = 1.0f;
1317 WindowMinSize = ImVec2(32,32);
1318 WindowTitleAlign = ImVec2(0.0f,0.5f);
1319 WindowMenuButtonPosition = ImGuiDir_Left;
1320 ChildRounding = 0.0f;
1321 ChildBorderSize = 1.0f;
1322 PopupRounding = 0.0f;
1323 PopupBorderSize = 1.0f;
1324 FramePadding = ImVec2(4,3);
1325 FrameRounding = 0.0f;
1326 FrameBorderSize = 0.0f;
1327 ItemSpacing = ImVec2(8,4);
1328 ItemInnerSpacing = ImVec2(4,4);
1329 CellPadding = ImVec2(4,2);
1330 TouchExtraPadding = ImVec2(0,0);
1331 IndentSpacing = 21.0f;
1332 ColumnsMinSpacing = 6.0f;
1333 ScrollbarSize = 14.0f;
1334 ScrollbarRounding = 9.0f;
1335 GrabMinSize = 12.0f;
1336 GrabRounding = 0.0f;
1337 LogSliderDeadzone = 4.0f;
1339 TabBorderSize = 0.0f;
1340 TabMinWidthForCloseButton = 0.0f;
1341 TabBarBorderSize = 1.0f;
1342 TabBarOverlineSize = 2.0f;
1343 TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f);
1344 TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);
1345 ColorButtonPosition = ImGuiDir_Right;
1346 ButtonTextAlign = ImVec2(0.5f,0.5f);
1347 SelectableTextAlign = ImVec2(0.0f,0.0f);
1348 SeparatorTextBorderSize = 3.0f;
1349 SeparatorTextAlign = ImVec2(0.0f,0.5f);
1350 SeparatorTextPadding = ImVec2(20.0f,3.f);
1351 DisplayWindowPadding = ImVec2(19,19);
1352 DisplaySafeAreaPadding = ImVec2(3,3);
1353 DockingSeparatorSize = 2.0f;
1354 MouseCursorScale = 1.0f;
1355 AntiAliasedLines =
true;
1356 AntiAliasedLinesUseTex =
true;
1357 AntiAliasedFill =
true;
1358 CurveTessellationTol = 1.25f;
1359 CircleTessellationMaxError = 0.30f;
1362 HoverStationaryDelay = 0.15f;
1363 HoverDelayShort = 0.15f;
1364 HoverDelayNormal = 0.40f;
1365 HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled;
1366 HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_AllowWhenDisabled;
1369 ImGui::StyleColorsDark(
this);
1374void ImGuiStyle::ScaleAllSizes(
float scale_factor)
1376 WindowPadding = ImTrunc(WindowPadding * scale_factor);
1377 WindowRounding = ImTrunc(WindowRounding * scale_factor);
1378 WindowMinSize = ImTrunc(WindowMinSize * scale_factor);
1379 ChildRounding = ImTrunc(ChildRounding * scale_factor);
1380 PopupRounding = ImTrunc(PopupRounding * scale_factor);
1381 FramePadding = ImTrunc(FramePadding * scale_factor);
1382 FrameRounding = ImTrunc(FrameRounding * scale_factor);
1383 ItemSpacing = ImTrunc(ItemSpacing * scale_factor);
1384 ItemInnerSpacing = ImTrunc(ItemInnerSpacing * scale_factor);
1385 CellPadding = ImTrunc(CellPadding * scale_factor);
1386 TouchExtraPadding = ImTrunc(TouchExtraPadding * scale_factor);
1387 IndentSpacing = ImTrunc(IndentSpacing * scale_factor);
1388 ColumnsMinSpacing = ImTrunc(ColumnsMinSpacing * scale_factor);
1389 ScrollbarSize = ImTrunc(ScrollbarSize * scale_factor);
1390 ScrollbarRounding = ImTrunc(ScrollbarRounding * scale_factor);
1391 GrabMinSize = ImTrunc(GrabMinSize * scale_factor);
1392 GrabRounding = ImTrunc(GrabRounding * scale_factor);
1393 LogSliderDeadzone = ImTrunc(LogSliderDeadzone * scale_factor);
1394 TabRounding = ImTrunc(TabRounding * scale_factor);
1395 TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImTrunc(TabMinWidthForCloseButton * scale_factor) : FLT_MAX;
1396 TabBarOverlineSize = ImTrunc(TabBarOverlineSize * scale_factor);
1397 SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
1398 DockingSeparatorSize = ImTrunc(DockingSeparatorSize * scale_factor);
1399 DisplayWindowPadding = ImTrunc(DisplayWindowPadding * scale_factor);
1400 DisplaySafeAreaPadding = ImTrunc(DisplaySafeAreaPadding * scale_factor);
1401 MouseCursorScale = ImTrunc(MouseCursorScale * scale_factor);
1407 memset(
this, 0,
sizeof(*
this));
1408 IM_STATIC_ASSERT(IM_ARRAYSIZE(ImGuiIO::MouseDown) == ImGuiMouseButton_COUNT && IM_ARRAYSIZE(ImGuiIO::MouseClicked) == ImGuiMouseButton_COUNT);
1411 ConfigFlags = ImGuiConfigFlags_None;
1412 BackendFlags = ImGuiBackendFlags_None;
1413 DisplaySize = ImVec2(-1.0f, -1.0f);
1414 DeltaTime = 1.0f / 60.0f;
1415 IniSavingRate = 5.0f;
1416 IniFilename =
"imgui.ini";
1417 LogFilename =
"imgui_log.txt";
1418#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1419 for (
int i = 0; i < ImGuiKey_COUNT; i++)
1425 FontGlobalScale = 1.0f;
1427 FontAllowUserScaling =
false;
1428 DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
1431 ConfigNavSwapGamepadButtons =
false;
1432 ConfigNavMoveSetMousePos =
false;
1433 ConfigNavCaptureKeyboard =
true;
1434 ConfigNavEscapeClearFocusItem =
true;
1435 ConfigNavEscapeClearFocusWindow =
false;
1436 ConfigNavCursorVisibleAuto =
true;
1437 ConfigNavCursorVisibleAlways =
false;
1440 ConfigDockingNoSplit =
false;
1441 ConfigDockingWithShift =
false;
1442 ConfigDockingAlwaysTabBar =
false;
1443 ConfigDockingTransparentPayload =
false;
1446 ConfigViewportsNoAutoMerge =
false;
1447 ConfigViewportsNoTaskBarIcon =
false;
1448 ConfigViewportsNoDecoration =
true;
1449 ConfigViewportsNoDefaultParent =
false;
1452 MouseDrawCursor =
false;
1454 ConfigMacOSXBehaviors =
true;
1456 ConfigMacOSXBehaviors =
false;
1458 ConfigInputTrickleEventQueue =
true;
1459 ConfigInputTextCursorBlink =
true;
1460 ConfigInputTextEnterKeepActive =
false;
1461 ConfigDragClickToInputText =
false;
1462 ConfigWindowsResizeFromEdges =
true;
1463 ConfigWindowsMoveFromTitleBarOnly =
false;
1464 ConfigScrollbarScrollByPage =
true;
1465 ConfigMemoryCompactTimer = 60.0f;
1466 ConfigDebugIsDebuggerPresent =
false;
1467 ConfigDebugHighlightIdConflicts =
true;
1468 ConfigDebugBeginReturnValueOnce =
false;
1469 ConfigDebugBeginReturnValueLoop =
false;
1471 ConfigErrorRecovery =
true;
1472 ConfigErrorRecoveryEnableAssert =
true;
1473 ConfigErrorRecoveryEnableDebugLog =
true;
1474 ConfigErrorRecoveryEnableTooltip =
true;
1477 MouseDoubleClickTime = 0.30f;
1478 MouseDoubleClickMaxDist = 6.0f;
1479 MouseDragThreshold = 6.0f;
1480 KeyRepeatDelay = 0.275f;
1481 KeyRepeatRate = 0.050f;
1485 BackendPlatformName = BackendRendererName = NULL;
1486 BackendPlatformUserData = BackendRendererUserData = BackendLanguageUserData = NULL;
1489 MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
1490 MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX);
1491 MouseSource = ImGuiMouseSource_Mouse;
1492 for (
int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
1493 for (
int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; }
1494 AppAcceptingEvents =
true;
1495 BackendUsingLegacyKeyArrays = (ImS8)-1;
1496 BackendUsingLegacyNavInputArray =
true;
1503void ImGuiIO::AddInputCharacter(
unsigned int c)
1505 IM_ASSERT(Ctx != NULL);
1506 ImGuiContext&
g = *Ctx;
1507 if (c == 0 || !AppAcceptingEvents)
1511 e.Type = ImGuiInputEventType_Text;
1512 e.Source = ImGuiInputSource_Keyboard;
1513 e.EventId =
g.InputEventsNextEventId++;
1515 g.InputEventsQueue.push_back(e);
1520void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
1522 if ((c == 0 && InputQueueSurrogate == 0) || !AppAcceptingEvents)
1525 if ((c & 0xFC00) == 0xD800)
1527 if (InputQueueSurrogate != 0)
1528 AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
1529 InputQueueSurrogate = c;
1534 if (InputQueueSurrogate != 0)
1536 if ((c & 0xFC00) != 0xDC00)
1538 AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
1542#if IM_UNICODE_CODEPOINT_MAX == 0xFFFF
1543 cp = IM_UNICODE_CODEPOINT_INVALID;
1545 cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000);
1549 InputQueueSurrogate = 0;
1551 AddInputCharacter((
unsigned)cp);
1554void ImGuiIO::AddInputCharactersUTF8(
const char* utf8_chars)
1556 if (!AppAcceptingEvents)
1558 while (*utf8_chars != 0)
1562 AddInputCharacter(c);
1567void ImGuiIO::ClearEventsQueue()
1569 IM_ASSERT(Ctx != NULL);
1570 ImGuiContext&
g = *Ctx;
1571 g.InputEventsQueue.clear();
1575void ImGuiIO::ClearInputKeys()
1577#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1578 memset(KeysDown, 0,
sizeof(KeysDown));
1580 for (
int n = 0; n < IM_ARRAYSIZE(KeysData); n++)
1582 if (ImGui::IsMouseKey((ImGuiKey)(n + ImGuiKey_KeysData_OFFSET)))
1584 KeysData[n].Down =
false;
1585 KeysData[n].DownDuration = -1.0f;
1586 KeysData[n].DownDurationPrev = -1.0f;
1588 KeyCtrl = KeyShift = KeyAlt = KeySuper =
false;
1589 KeyMods = ImGuiMod_None;
1590 InputQueueCharacters.resize(0);
1593void ImGuiIO::ClearInputMouse()
1595 for (ImGuiKey key = ImGuiKey_Mouse_BEGIN; key < ImGuiKey_Mouse_END; key = (ImGuiKey)(key + 1))
1597 ImGuiKeyData* key_data = &KeysData[key - ImGuiKey_KeysData_OFFSET];
1598 key_data->Down =
false;
1599 key_data->DownDuration = -1.0f;
1600 key_data->DownDurationPrev = -1.0f;
1602 MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
1603 for (
int n = 0; n < IM_ARRAYSIZE(MouseDown); n++)
1605 MouseDown[n] =
false;
1606 MouseDownDuration[n] = MouseDownDurationPrev[n] = -1.0f;
1608 MouseWheel = MouseWheelH = 0.0f;
1613#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
1614void ImGuiIO::ClearInputCharacters()
1616 InputQueueCharacters.resize(0);
1620static ImGuiInputEvent* FindLatestInputEvent(ImGuiContext* ctx, ImGuiInputEventType type,
int arg = -1)
1622 ImGuiContext&
g = *ctx;
1623 for (
int n =
g.InputEventsQueue.Size - 1; n >= 0; n--)
1625 ImGuiInputEvent*
e = &
g.InputEventsQueue[n];
1626 if (
e->Type != type)
1628 if (type == ImGuiInputEventType_Key &&
e->Key.Key != arg)
1630 if (type == ImGuiInputEventType_MouseButton &&
e->MouseButton.Button != arg)
1643void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key,
bool down,
float analog_value)
1646 IM_ASSERT(Ctx != NULL);
1647 if (key == ImGuiKey_None || !AppAcceptingEvents)
1649 ImGuiContext&
g = *Ctx;
1650 IM_ASSERT(ImGui::IsNamedKeyOrMod(key));
1651 IM_ASSERT(ImGui::IsAliasKey(key) ==
false);
1654 if (
g.IO.ConfigMacOSXBehaviors)
1656 if (key == ImGuiMod_Super) { key = ImGuiMod_Ctrl; }
1657 else if (key == ImGuiMod_Ctrl) { key = ImGuiMod_Super; }
1658 else if (key == ImGuiKey_LeftSuper) { key = ImGuiKey_LeftCtrl; }
1659 else if (key == ImGuiKey_RightSuper){ key = ImGuiKey_RightCtrl; }
1660 else if (key == ImGuiKey_LeftCtrl) { key = ImGuiKey_LeftSuper; }
1661 else if (key == ImGuiKey_RightCtrl) { key = ImGuiKey_RightSuper; }
1665#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1666 IM_ASSERT((BackendUsingLegacyKeyArrays == -1 || BackendUsingLegacyKeyArrays == 0) &&
"Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
1667 if (BackendUsingLegacyKeyArrays == -1)
1668 for (
int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
1669 IM_ASSERT(KeyMap[n] == -1 &&
"Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
1670 BackendUsingLegacyKeyArrays = 0;
1672 if (ImGui::IsGamepadKey(key))
1673 BackendUsingLegacyNavInputArray =
false;
1676 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_Key, (
int)key);
1677 const ImGuiKeyData* key_data = ImGui::GetKeyData(&
g, key);
1678 const bool latest_key_down = latest_event ? latest_event->Key.Down : key_data->Down;
1679 const float latest_key_analog = latest_event ? latest_event->Key.AnalogValue : key_data->AnalogValue;
1680 if (latest_key_down == down && latest_key_analog == analog_value)
1685 e.Type = ImGuiInputEventType_Key;
1686 e.Source = ImGui::IsGamepadKey(key) ? ImGuiInputSource_Gamepad : ImGuiInputSource_Keyboard;
1687 e.EventId =
g.InputEventsNextEventId++;
1690 e.Key.AnalogValue = analog_value;
1691 g.InputEventsQueue.push_back(e);
1694void ImGuiIO::AddKeyEvent(ImGuiKey key,
bool down)
1696 if (!AppAcceptingEvents)
1698 AddKeyAnalogEvent(key, down, down ? 1.0f : 0.0f);
1704void ImGuiIO::SetKeyEventNativeData(ImGuiKey key,
int native_keycode,
int native_scancode,
int native_legacy_index)
1706 if (key == ImGuiKey_None)
1708 IM_ASSERT(ImGui::IsNamedKey(key));
1709 IM_ASSERT(native_legacy_index == -1 || ImGui::IsLegacyKey((ImGuiKey)native_legacy_index));
1710 IM_UNUSED(native_keycode);
1711 IM_UNUSED(native_scancode);
1714#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1715 const int legacy_key = (native_legacy_index != -1) ? native_legacy_index : native_keycode;
1716 if (!ImGui::IsLegacyKey((ImGuiKey)legacy_key))
1718 KeyMap[legacy_key] = key;
1719 KeyMap[key] = legacy_key;
1722 IM_UNUSED(native_legacy_index);
1727void ImGuiIO::SetAppAcceptingEvents(
bool accepting_events)
1729 AppAcceptingEvents = accepting_events;
1733void ImGuiIO::AddMousePosEvent(
float x,
float y)
1735 IM_ASSERT(Ctx != NULL);
1736 ImGuiContext&
g = *Ctx;
1737 if (!AppAcceptingEvents)
1741 ImVec2 pos((x > -FLT_MAX) ? ImFloor(x) : x, (y > -FLT_MAX) ? ImFloor(y) : y);
1744 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_MousePos);
1745 const ImVec2 latest_pos = latest_event ? ImVec2(latest_event->MousePos.PosX, latest_event->MousePos.PosY) :
g.IO.MousePos;
1746 if (latest_pos.x == pos.x && latest_pos.y == pos.y)
1750 e.Type = ImGuiInputEventType_MousePos;
1751 e.Source = ImGuiInputSource_Mouse;
1752 e.EventId =
g.InputEventsNextEventId++;
1753 e.MousePos.PosX = pos.x;
1754 e.MousePos.PosY = pos.y;
1755 e.MousePos.MouseSource =
g.InputEventsNextMouseSource;
1756 g.InputEventsQueue.push_back(e);
1759void ImGuiIO::AddMouseButtonEvent(
int mouse_button,
bool down)
1761 IM_ASSERT(Ctx != NULL);
1762 ImGuiContext&
g = *Ctx;
1763 IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT);
1764 if (!AppAcceptingEvents)
1768 if (ConfigMacOSXBehaviors && mouse_button == 0 && MouseCtrlLeftAsRightClick)
1773 MouseCtrlLeftAsRightClick =
false;
1777 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_MouseButton, (
int)mouse_button);
1778 const bool latest_button_down = latest_event ? latest_event->MouseButton.Down :
g.IO.MouseDown[mouse_button];
1779 if (latest_button_down == down)
1785 if (ConfigMacOSXBehaviors && mouse_button == 0 && down)
1787 const ImGuiInputEvent* latest_super_event = FindLatestInputEvent(&
g, ImGuiInputEventType_Key, (
int)ImGuiMod_Super);
1788 if (latest_super_event ? latest_super_event->Key.Down :
g.IO.KeySuper)
1790 IMGUI_DEBUG_LOG_IO(
"[io] Super+Left Click aliased into Right Click\n");
1791 MouseCtrlLeftAsRightClick =
true;
1792 AddMouseButtonEvent(1,
true);
1798 e.Type = ImGuiInputEventType_MouseButton;
1799 e.Source = ImGuiInputSource_Mouse;
1800 e.EventId =
g.InputEventsNextEventId++;
1801 e.MouseButton.Button = mouse_button;
1802 e.MouseButton.Down = down;
1803 e.MouseButton.MouseSource =
g.InputEventsNextMouseSource;
1804 g.InputEventsQueue.push_back(e);
1808void ImGuiIO::AddMouseWheelEvent(
float wheel_x,
float wheel_y)
1810 IM_ASSERT(Ctx != NULL);
1811 ImGuiContext&
g = *Ctx;
1814 if (!AppAcceptingEvents || (wheel_x == 0.0f && wheel_y == 0.0f))
1818 e.Type = ImGuiInputEventType_MouseWheel;
1819 e.Source = ImGuiInputSource_Mouse;
1820 e.EventId =
g.InputEventsNextEventId++;
1821 e.MouseWheel.WheelX = wheel_x;
1822 e.MouseWheel.WheelY = wheel_y;
1823 e.MouseWheel.MouseSource =
g.InputEventsNextMouseSource;
1824 g.InputEventsQueue.push_back(e);
1829void ImGuiIO::AddMouseSourceEvent(ImGuiMouseSource source)
1831 IM_ASSERT(Ctx != NULL);
1832 ImGuiContext&
g = *Ctx;
1833 g.InputEventsNextMouseSource = source;
1836void ImGuiIO::AddMouseViewportEvent(ImGuiID viewport_id)
1838 IM_ASSERT(Ctx != NULL);
1839 ImGuiContext&
g = *Ctx;
1841 if (!AppAcceptingEvents)
1845 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_MouseViewport);
1846 const ImGuiID latest_viewport_id = latest_event ? latest_event->MouseViewport.HoveredViewportID :
g.IO.MouseHoveredViewport;
1847 if (latest_viewport_id == viewport_id)
1851 e.Type = ImGuiInputEventType_MouseViewport;
1852 e.Source = ImGuiInputSource_Mouse;
1853 e.MouseViewport.HoveredViewportID = viewport_id;
1854 g.InputEventsQueue.push_back(e);
1857void ImGuiIO::AddFocusEvent(
bool focused)
1859 IM_ASSERT(Ctx != NULL);
1860 ImGuiContext&
g = *Ctx;
1863 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_Focus);
1864 const bool latest_focused = latest_event ? latest_event->AppFocused.Focused : !
g.IO.AppFocusLost;
1865 if (latest_focused == focused || (ConfigDebugIgnoreFocusLoss && !focused))
1869 e.Type = ImGuiInputEventType_Focus;
1870 e.EventId =
g.InputEventsNextEventId++;
1871 e.AppFocused.Focused = focused;
1872 g.InputEventsQueue.push_back(e);
1875ImGuiPlatformIO::ImGuiPlatformIO()
1878 memset(
this, 0,
sizeof(*
this));
1879 Platform_LocaleDecimalPoint =
'.';
1888 IM_ASSERT(num_segments > 0);
1891 float p_closest_dist2 = FLT_MAX;
1892 float t_step = 1.0f / (float)num_segments;
1893 for (
int i_step = 1; i_step <= num_segments; i_step++)
1897 float dist2 = ImLengthSqr(p - p_line);
1898 if (dist2 < p_closest_dist2)
1901 p_closest_dist2 = dist2;
1909static void ImBezierCubicClosestPointCasteljauStep(
const ImVec2& p, ImVec2& p_closest, ImVec2& p_last,
float& p_closest_dist2,
float x1,
float y1,
float x2,
float y2,
float x3,
float y3,
float x4,
float y4,
float tess_tol,
int level)
1913 float d2 = ((x2 - x4) * dy - (y2 - y4) * dx);
1914 float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
1915 d2 = (d2 >= 0) ? d2 : -d2;
1916 d3 = (d3 >= 0) ? d3 : -d3;
1917 if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy))
1919 ImVec2 p_current(x4, y4);
1921 float dist2 = ImLengthSqr(p - p_line);
1922 if (dist2 < p_closest_dist2)
1925 p_closest_dist2 = dist2;
1929 else if (level < 10)
1931 float x12 = (x1 + x2)*0.5f, y12 = (y1 + y2)*0.5f;
1932 float x23 = (x2 + x3)*0.5f, y23 = (y2 + y3)*0.5f;
1933 float x34 = (x3 + x4)*0.5f, y34 = (y3 + y4)*0.5f;
1934 float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f;
1935 float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f;
1936 float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f;
1937 ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
1938 ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
1946 IM_ASSERT(tess_tol > 0.0f);
1949 float p_closest_dist2 = FLT_MAX;
1950 ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y,
p3.x,
p3.y,
p4.x,
p4.y, tess_tol, 0);
1957 ImVec2 ab_dir = b - a;
1958 float dot = ap.x * ab_dir.x + ap.y * ab_dir.y;
1961 float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y;
1962 if (dot > ab_len_sqr)
1964 return a + ab_dir * dot / ab_len_sqr;
1969 bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f;
1970 bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f;
1971 bool b3 = ((p.x - a.x) * (c.y - a.y) - (p.y - a.y) * (c.x - a.x)) < 0.0f;
1972 return ((b1 == b2) && (b2 == b3));
1980 const float denom = v0.x * v1.y - v1.x * v0.y;
1981 out_v = (v2.x * v1.y - v1.x * v2.y) / denom;
1982 out_w = (v0.x * v2.y - v2.x * v0.y) / denom;
1983 out_u = 1.0f - out_v - out_w;
1991 float dist2_ab = ImLengthSqr(p - proj_ab);
1992 float dist2_bc = ImLengthSqr(p - proj_bc);
1993 float dist2_ca = ImLengthSqr(p - proj_ca);
1994 float m = ImMin(dist2_ab, ImMin(dist2_bc, dist2_ca));
2010 while ((d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; }
2017 while (count > 0 && (d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; count--; }
2026 strncpy(dst, src, count - 1);
2032 size_t len = strlen(str);
2033 void* buf = IM_ALLOC(len + 1);
2034 return (
char*)memcpy(buf, (
const void*)str, len + 1);
2039 size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
2040 size_t src_size = strlen(src) + 1;
2041 if (dst_buf_size < src_size)
2044 dst = (
char*)IM_ALLOC(src_size);
2046 *p_dst_size = src_size;
2048 return (
char*)memcpy(dst, (
const void*)src, src_size);
2053 const char* p = (
const char*)memchr(str, (
int)c, str_end - str);
2068 const char* p = (
const char*)memchr(str,
'\n', str_end - str);
2069 return p ? p : str_end;
2072const char*
ImStrbol(
const char* buf_mid_line,
const char* buf_begin)
2074 while (buf_mid_line > buf_begin && buf_mid_line[-1] !=
'\n')
2076 return buf_mid_line;
2079const char*
ImStristr(
const char* haystack,
const char* haystack_end,
const char* needle,
const char* needle_end)
2082 needle_end = needle + strlen(needle);
2084 const char un0 = (char)ImToUpper(*needle);
2085 while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end))
2087 if (ImToUpper(*haystack) == un0)
2089 const char* b = needle + 1;
2090 for (
const char* a = haystack + 1; b < needle_end; a++, b++)
2091 if (ImToUpper(*a) != ImToUpper(*b))
2093 if (b == needle_end)
2105 while (p[0] ==
' ' || p[0] ==
'\t')
2110 while (p > p_start && (p[-1] ==
' ' || p[-1] ==
'\t'))
2113 memmove(buf, p_start, p - p_start);
2114 buf[p - p_start] = 0;
2119 while (str[0] ==
' ' || str[0] ==
'\t')
2127#ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
2133#ifdef IMGUI_USE_STB_SPRINTF
2134#ifndef IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION
2135#define STB_SPRINTF_IMPLEMENTATION
2137#ifdef IMGUI_STB_SPRINTF_FILENAME
2138#include IMGUI_STB_SPRINTF_FILENAME
2140#include "stb_sprintf.h"
2144#if defined(_MSC_VER) && !defined(vsnprintf)
2145#define vsnprintf _vsnprintf
2151 va_start(args, fmt);
2152#ifdef IMGUI_USE_STB_SPRINTF
2153 int w = stbsp_vsnprintf(buf, (
int)buf_size, fmt, args);
2155 int w = vsnprintf(buf, buf_size, fmt, args);
2160 if (w == -1 || w >= (
int)buf_size)
2161 w = (int)buf_size - 1;
2168#ifdef IMGUI_USE_STB_SPRINTF
2169 int w = stbsp_vsnprintf(buf, (
int)buf_size, fmt, args);
2171 int w = vsnprintf(buf, buf_size, fmt, args);
2175 if (w == -1 || w >= (
int)buf_size)
2176 w = (int)buf_size - 1;
2185 va_start(args, fmt);
2197 if (fmt[0] ==
'%' && fmt[1] ==
's' && fmt[2] == 0)
2199 const char* buf = va_arg(args,
const char*);
2203 if (out_buf_end) { *out_buf_end = buf + strlen(buf); }
2205 else if (fmt[0] ==
'%' && fmt[1] ==
'.' && fmt[2] ==
'*' && fmt[3] ==
's' && fmt[4] == 0)
2207 int buf_len = va_arg(args,
int);
2208 const char* buf = va_arg(args,
const char*);
2212 buf_len = ImMin(buf_len, 6);
2215 *out_buf_end = buf + buf_len;
2220 *out_buf =
g.TempBuffer.Data;
2221 if (out_buf_end) { *out_buf_end =
g.TempBuffer.Data + buf_len; }
2228static const ImU32 GCrc32LookupTable[256] =
2230 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,
2231 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,
2232 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
2233 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,
2234 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01,
2235 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,
2236 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
2237 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD,
2238 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,
2239 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,
2240 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79,
2241 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,
2242 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,
2243 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
2244 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,
2245 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D,
2251ImGuiID
ImHashData(
const void* data_p,
size_t data_size, ImGuiID seed)
2254 const unsigned char* data = (
const unsigned char*)data_p;
2255 const ImU32* crc32_lut = GCrc32LookupTable;
2256 while (data_size-- != 0)
2257 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *data++];
2267ImGuiID
ImHashStr(
const char* data_p,
size_t data_size, ImGuiID seed)
2271 const unsigned char* data = (
const unsigned char*)data_p;
2272 const ImU32* crc32_lut = GCrc32LookupTable;
2275 while (data_size-- != 0)
2277 unsigned char c = *data++;
2278 if (c ==
'#' && data_size >= 2 && data[0] ==
'#' && data[1] ==
'#')
2280 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
2285 while (
unsigned char c = *data++)
2287 if (c ==
'#' && data[0] ==
'#' && data[1] ==
'#')
2289 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
2300#ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
2304#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
2307 const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
2308 const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
2312 wchar_t local_temp_stack[FILENAME_MAX];
2313 ImVector<wchar_t> local_temp_heap;
2314 if (filename_wsize + mode_wsize > IM_ARRAYSIZE(local_temp_stack))
2315 local_temp_heap.resize(filename_wsize + mode_wsize);
2316 wchar_t* filename_wbuf = local_temp_heap.Data ? local_temp_heap.Data : local_temp_stack;
2317 wchar_t* mode_wbuf = filename_wbuf + filename_wsize;
2318 ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_wbuf, filename_wsize);
2319 ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, mode_wbuf, mode_wsize);
2320 return ::_wfopen(filename_wbuf, mode_wbuf);
2322 return fopen(filename, mode);
2328ImU64
ImFileGetSize(ImFileHandle f) {
long off = 0, sz = 0;
return ((off = ftell(f)) != -1 && !fseek(f, 0, SEEK_END) && (sz = ftell(f)) != -1 && !fseek(f, off, SEEK_SET)) ? (ImU64)sz : (ImU64)-1; }
2329ImU64
ImFileRead(
void* data, ImU64 sz, ImU64 count, ImFileHandle f) {
return fread(data, (
size_t)sz, (
size_t)count, f); }
2330ImU64
ImFileWrite(
const void* data, ImU64 sz, ImU64 count, ImFileHandle f) {
return fwrite(data, (
size_t)sz, (
size_t)count, f); }
2336void*
ImFileLoadToMemory(
const char* filename,
const char* mode,
size_t* out_file_size,
int padding_bytes)
2338 IM_ASSERT(filename && mode);
2343 if ((f =
ImFileOpen(filename, mode)) == NULL)
2347 if (file_size == (
size_t)-1)
2353 void* file_data = IM_ALLOC(file_size + padding_bytes);
2354 if (file_data == NULL)
2359 if (
ImFileRead(file_data, 1, file_size, f) != file_size)
2365 if (padding_bytes > 0)
2366 memset((
void*)(((
char*)file_data) + file_size), 0, (
size_t)padding_bytes);
2370 *out_file_size = file_size;
2379IM_MSVC_RUNTIME_CHECKS_OFF
2386 static const char lengths[32] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0 };
2387 static const int masks[] = { 0x00, 0x7f, 0x1f, 0x0f, 0x07 };
2388 static const uint32_t mins[] = { 0x400000, 0, 0x80, 0x800, 0x10000 };
2389 static const int shiftc[] = { 0, 18, 12, 6, 0 };
2390 static const int shifte[] = { 0, 6, 4, 2, 0 };
2391 int len = lengths[*(
const unsigned char*)in_text >> 3];
2392 int wanted = len + (len ? 0 : 1);
2394 if (in_text_end == NULL)
2395 in_text_end = in_text + wanted;
2400 s[0] = in_text + 0 < in_text_end ? in_text[0] : 0;
2401 s[1] = in_text + 1 < in_text_end ? in_text[1] : 0;
2402 s[2] = in_text + 2 < in_text_end ? in_text[2] : 0;
2403 s[3] = in_text + 3 < in_text_end ? in_text[3] : 0;
2406 *out_char = (uint32_t)(s[0] & masks[len]) << 18;
2407 *out_char |= (uint32_t)(s[1] & 0x3f) << 12;
2408 *out_char |= (uint32_t)(s[2] & 0x3f) << 6;
2409 *out_char |= (uint32_t)(s[3] & 0x3f) << 0;
2410 *out_char >>= shiftc[len];
2414 e = (*out_char < mins[len]) << 6;
2415 e |= ((*out_char >> 11) == 0x1b) << 7;
2416 e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8;
2417 e |= (s[1] & 0xc0) >> 2;
2418 e |= (s[2] & 0xc0) >> 4;
2429 wanted = ImMin(wanted, !!s[0] + !!s[1] + !!s[2] + !!s[3]);
2430 *out_char = IM_UNICODE_CODEPOINT_INVALID;
2436int ImTextStrFromUtf8(ImWchar* buf,
int buf_size,
const char* in_text,
const char* in_text_end,
const char** in_text_remaining)
2438 ImWchar* buf_out = buf;
2439 ImWchar* buf_end = buf + buf_size;
2440 while (buf_out < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text)
2444 *buf_out++ = (ImWchar)c;
2447 if (in_text_remaining)
2448 *in_text_remaining = in_text;
2449 return (
int)(buf_out - buf);
2455 while ((!in_text_end || in_text < in_text_end) && *in_text)
2465static inline int ImTextCharToUtf8_inline(
char* buf,
int buf_size,
unsigned int c)
2474 if (buf_size < 2)
return 0;
2475 buf[0] = (char)(0xc0 + (c >> 6));
2476 buf[1] = (char)(0x80 + (c & 0x3f));
2481 if (buf_size < 3)
return 0;
2482 buf[0] = (char)(0xe0 + (c >> 12));
2483 buf[1] = (char)(0x80 + ((c >> 6) & 0x3f));
2484 buf[2] = (char)(0x80 + ((c ) & 0x3f));
2489 if (buf_size < 4)
return 0;
2490 buf[0] = (char)(0xf0 + (c >> 18));
2491 buf[1] = (char)(0x80 + ((c >> 12) & 0x3f));
2492 buf[2] = (char)(0x80 + ((c >> 6) & 0x3f));
2493 buf[3] = (char)(0x80 + ((c ) & 0x3f));
2502 int count = ImTextCharToUtf8_inline(out_buf, 5, c);
2510 unsigned int unused = 0;
2516 if (c < 0x80)
return 1;
2517 if (c < 0x800)
return 2;
2518 if (c < 0x10000)
return 3;
2519 if (c <= 0x10FFFF)
return 4;
2523int ImTextStrToUtf8(
char* out_buf,
int out_buf_size,
const ImWchar* in_text,
const ImWchar* in_text_end)
2525 char* buf_p = out_buf;
2526 const char* buf_end = out_buf + out_buf_size;
2527 while (buf_p < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text)
2529 unsigned int c = (
unsigned int)(*in_text++);
2533 buf_p += ImTextCharToUtf8_inline(buf_p, (
int)(buf_end - buf_p - 1), c);
2536 return (
int)(buf_p - out_buf);
2541 int bytes_count = 0;
2542 while ((!in_text_end || in_text < in_text_end) && *in_text)
2544 unsigned int c = (
unsigned int)(*in_text++);
2555 while (in_text_curr > in_text_start)
2558 if ((*in_text_curr & 0xC0) != 0x80)
2559 return in_text_curr;
2561 return in_text_start;
2566 if (in_text_end == NULL)
2567 in_text_end = in_text + strlen(in_text);
2569 while (in_text < in_text_end)
2571 const char* line_end = (
const char*)memchr(in_text,
'\n', in_text_end - in_text);
2572 in_text = line_end ? line_end + 1 : in_text_end;
2578IM_MSVC_RUNTIME_CHECKS_RESTORE
2587 float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f;
2588 int r = ImLerp((
int)(col_a >> IM_COL32_R_SHIFT) & 0xFF, (
int)(col_b >> IM_COL32_R_SHIFT) & 0xFF,
t);
2589 int g = ImLerp((
int)(col_a >> IM_COL32_G_SHIFT) & 0xFF, (
int)(col_b >> IM_COL32_G_SHIFT) & 0xFF,
t);
2590 int b = ImLerp((
int)(col_a >> IM_COL32_B_SHIFT) & 0xFF, (
int)(col_b >> IM_COL32_B_SHIFT) & 0xFF,
t);
2591 return IM_COL32(r,
g, b, 0xFF);
2594ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in)
2596 float s = 1.0f / 255.0f;
2598 ((in >> IM_COL32_R_SHIFT) & 0xFF) * s,
2599 ((in >> IM_COL32_G_SHIFT) & 0xFF) * s,
2600 ((in >> IM_COL32_B_SHIFT) & 0xFF) * s,
2601 ((in >> IM_COL32_A_SHIFT) & 0xFF) * s);
2604ImU32 ImGui::ColorConvertFloat4ToU32(
const ImVec4& in)
2607 out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)) << IM_COL32_R_SHIFT;
2608 out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << IM_COL32_G_SHIFT;
2609 out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << IM_COL32_B_SHIFT;
2610 out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << IM_COL32_A_SHIFT;
2616void ImGui::ColorConvertRGBtoHSV(
float r,
float g,
float b,
float& out_h,
float& out_s,
float& out_v)
2630 const float chroma = r - (
g < b ?
g : b);
2631 out_h = ImFabs(K + (
g - b) / (6.f * chroma + 1e-20f));
2632 out_s = chroma / (r + 1e-20f);
2638void ImGui::ColorConvertHSVtoRGB(
float h,
float s,
float v,
float& out_r,
float& out_g,
float& out_b)
2643 out_r = out_g = out_b = v;
2647 h = ImFmod(h, 1.0f) / (60.0f / 360.0f);
2649 float f = h - (float)i;
2650 float p = v * (1.0f - s);
2651 float q = v * (1.0f - s * f);
2652 float t = v * (1.0f - s * (1.0f - f));
2656 case 0: out_r = v; out_g =
t; out_b = p;
break;
2657 case 1: out_r = q; out_g = v; out_b = p;
break;
2658 case 2: out_r = p; out_g = v; out_b =
t;
break;
2659 case 3: out_r = p; out_g = q; out_b = v;
break;
2660 case 4: out_r =
t; out_g = p; out_b = v;
break;
2661 case 5:
default: out_r = v; out_g = p; out_b = q;
break;
2671ImGuiStoragePair*
ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key)
2673 ImGuiStoragePair* in_p = in_begin;
2674 for (
size_t count = (
size_t)(in_end - in_p); count > 0; )
2676 size_t count2 = count >> 1;
2677 ImGuiStoragePair* mid = in_p + count2;
2681 count -= count2 + 1;
2691IM_MSVC_RUNTIME_CHECKS_OFF
2692static int IMGUI_CDECL PairComparerByID(
const void* lhs,
const void* rhs)
2695 ImGuiID lhs_v = ((
const ImGuiStoragePair*)lhs)->key;
2696 ImGuiID rhs_v = ((
const ImGuiStoragePair*)rhs)->key;
2697 return (lhs_v > rhs_v ? +1 : lhs_v < rhs_v ? -1 : 0);
2701void ImGuiStorage::BuildSortByKey()
2703 ImQsort(Data.Data, (
size_t)Data.Size,
sizeof(ImGuiStoragePair), PairComparerByID);
2706int ImGuiStorage::GetInt(ImGuiID key,
int default_val)
const
2708 ImGuiStoragePair* it =
ImLowerBound(
const_cast<ImGuiStoragePair*
>(Data.Data),
const_cast<ImGuiStoragePair*
>(Data.Data + Data.Size), key);
2709 if (it == Data.Data + Data.Size || it->key != key)
2714bool ImGuiStorage::GetBool(ImGuiID key,
bool default_val)
const
2716 return GetInt(key, default_val ? 1 : 0) != 0;
2719float ImGuiStorage::GetFloat(ImGuiID key,
float default_val)
const
2721 ImGuiStoragePair* it =
ImLowerBound(
const_cast<ImGuiStoragePair*
>(Data.Data),
const_cast<ImGuiStoragePair*
>(Data.Data + Data.Size), key);
2722 if (it == Data.Data + Data.Size || it->key != key)
2727void* ImGuiStorage::GetVoidPtr(ImGuiID key)
const
2729 ImGuiStoragePair* it =
ImLowerBound(
const_cast<ImGuiStoragePair*
>(Data.Data),
const_cast<ImGuiStoragePair*
>(Data.Data + Data.Size), key);
2730 if (it == Data.Data + Data.Size || it->key != key)
2736int* ImGuiStorage::GetIntRef(ImGuiID key,
int default_val)
2738 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2739 if (it == Data.Data + Data.Size || it->key != key)
2740 it = Data.insert(it, ImGuiStoragePair(key, default_val));
2744bool* ImGuiStorage::GetBoolRef(ImGuiID key,
bool default_val)
2746 return (
bool*)GetIntRef(key, default_val ? 1 : 0);
2749float* ImGuiStorage::GetFloatRef(ImGuiID key,
float default_val)
2751 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2752 if (it == Data.Data + Data.Size || it->key != key)
2753 it = Data.insert(it, ImGuiStoragePair(key, default_val));
2757void** ImGuiStorage::GetVoidPtrRef(ImGuiID key,
void* default_val)
2759 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2760 if (it == Data.Data + Data.Size || it->key != key)
2761 it = Data.insert(it, ImGuiStoragePair(key, default_val));
2766void ImGuiStorage::SetInt(ImGuiID key,
int val)
2768 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2769 if (it == Data.Data + Data.Size || it->key != key)
2770 Data.insert(it, ImGuiStoragePair(key, val));
2775void ImGuiStorage::SetBool(ImGuiID key,
bool val)
2777 SetInt(key, val ? 1 : 0);
2780void ImGuiStorage::SetFloat(ImGuiID key,
float val)
2782 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2783 if (it == Data.Data + Data.Size || it->key != key)
2784 Data.insert(it, ImGuiStoragePair(key, val));
2789void ImGuiStorage::SetVoidPtr(ImGuiID key,
void* val)
2791 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2792 if (it == Data.Data + Data.Size || it->key != key)
2793 Data.insert(it, ImGuiStoragePair(key, val));
2798void ImGuiStorage::SetAllInt(
int v)
2800 for (
int i = 0; i < Data.Size; i++)
2803IM_MSVC_RUNTIME_CHECKS_RESTORE
2810ImGuiTextFilter::ImGuiTextFilter(
const char* default_filter)
2816 ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf));
2821bool ImGuiTextFilter::Draw(
const char* label,
float width)
2824 ImGui::SetNextItemWidth(width);
2825 bool value_changed = ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf));
2828 return value_changed;
2831void ImGuiTextFilter::ImGuiTextRange::split(
char separator, ImVector<ImGuiTextRange>* out)
const
2835 const char* we = wb;
2838 if (*we == separator)
2840 out->push_back(ImGuiTextRange(wb, we));
2846 out->push_back(ImGuiTextRange(wb, we));
2849void ImGuiTextFilter::Build()
2852 ImGuiTextRange input_range(InputBuf, InputBuf + strlen(InputBuf));
2853 input_range.split(
',', &Filters);
2856 for (ImGuiTextRange& f : Filters)
2858 while (f.b < f.e && ImCharIsBlankA(f.b[0]))
2860 while (f.e > f.b && ImCharIsBlankA(f.e[-1]))
2869bool ImGuiTextFilter::PassFilter(
const char* text,
const char* text_end)
const
2871 if (Filters.Size == 0)
2875 text = text_end =
"";
2877 for (
const ImGuiTextRange& f : Filters)
2884 if (
ImStristr(text, text_end, f.b + 1, f.e) != NULL)
2890 if (
ImStristr(text, text_end, f.b, f.e) != NULL)
2909#if defined(__GNUC__) || defined(__clang__)
2910#define va_copy(dest, src) __builtin_va_copy(dest, src)
2912#define va_copy(dest, src) (dest = src)
2916char ImGuiTextBuffer::EmptyString[1] = { 0 };
2918void ImGuiTextBuffer::append(
const char* str,
const char* str_end)
2920 int len = str_end ? (int)(str_end - str) : (int)strlen(str);
2923 const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
2924 const int needed_sz = write_off + len;
2925 if (write_off + len >= Buf.Capacity)
2927 int new_capacity = Buf.Capacity * 2;
2928 Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity);
2931 Buf.resize(needed_sz);
2932 memcpy(&Buf[write_off - 1], str, (
size_t)len);
2933 Buf[write_off - 1 + len] = 0;
2936void ImGuiTextBuffer::appendf(
const char* fmt, ...)
2939 va_start(args, fmt);
2940 appendfv(fmt, args);
2945void ImGuiTextBuffer::appendfv(
const char* fmt, va_list args)
2958 const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
2959 const int needed_sz = write_off + len;
2960 if (write_off + len >= Buf.Capacity)
2962 int new_capacity = Buf.Capacity * 2;
2963 Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity);
2966 Buf.resize(needed_sz);
2967 ImFormatStringV(&Buf[write_off - 1], (
size_t)len + 1, fmt, args_copy);
2971void ImGuiTextIndex::append(
const char* base,
int old_size,
int new_size)
2973 IM_ASSERT(old_size >= 0 && new_size >= old_size && new_size >= EndOffset);
2974 if (old_size == new_size)
2976 if (EndOffset == 0 || base[EndOffset - 1] ==
'\n')
2977 LineOffsets.push_back(EndOffset);
2978 const char* base_end = base + new_size;
2979 for (
const char* p = base + old_size; (p = (
const char*)memchr(p,
'\n', base_end - p)) != 0; )
2981 LineOffsets.push_back((
int)(intptr_t)(p - base));
2982 EndOffset = ImMax(EndOffset, new_size);
2991static bool GetSkipItemForListClipping()
2994 return (
g.CurrentTable ?
g.CurrentTable->HostSkipItems :
g.CurrentWindow->SkipItems);
2997static void ImGuiListClipper_SortAndFuseRanges(ImVector<ImGuiListClipperRange>&
ranges,
int offset = 0)
2999 if (
ranges.Size - offset <= 1)
3003 for (
int sort_end =
ranges.Size - offset - 1; sort_end > 0; --sort_end)
3004 for (
int i = offset; i < sort_end + offset; ++i)
3009 for (
int i = 1 + offset; i <
ranges.Size; i++)
3011 IM_ASSERT(!
ranges[i].PosToIndexConvert && !
ranges[i - 1].PosToIndexConvert);
3021static void ImGuiListClipper_SeekCursorAndSetupPrevLine(
float pos_y,
float line_height)
3027 ImGuiWindow* window =
g.CurrentWindow;
3028 float off_y = pos_y - window->DC.CursorPos.y;
3029 window->DC.CursorPos.y = pos_y;
3030 window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y -
g.Style.ItemSpacing.y);
3031 window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height;
3032 window->DC.PrevLineSize.y = (line_height -
g.Style.ItemSpacing.y);
3033 if (ImGuiOldColumns* columns = window->DC.CurrentColumns)
3034 columns->LineMinY = window->DC.CursorPos.y;
3035 if (ImGuiTable* table =
g.CurrentTable)
3037 if (table->IsInsideRow)
3038 ImGui::TableEndRow(table);
3039 table->RowPosY2 = window->DC.CursorPos.y;
3040 const int row_increase = (int)((off_y / line_height) + 0.5f);
3042 table->RowBgColorCounter += row_increase;
3046ImGuiListClipper::ImGuiListClipper()
3048 memset(
this, 0,
sizeof(*
this));
3051ImGuiListClipper::~ImGuiListClipper()
3056void ImGuiListClipper::Begin(
int items_count,
float items_height)
3059 Ctx = ImGui::GetCurrentContext();
3061 ImGuiContext&
g = *Ctx;
3062 ImGuiWindow* window =
g.CurrentWindow;
3063 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Begin(%d,%.2f) in '%s'\n", items_count, items_height, window->Name);
3065 if (ImGuiTable* table =
g.CurrentTable)
3066 if (table->IsInsideRow)
3067 ImGui::TableEndRow(table);
3069 StartPosY = window->DC.CursorPos.y;
3070 ItemsHeight = items_height;
3071 ItemsCount = items_count;
3076 if (++
g.ClipperTempDataStacked >
g.ClipperTempData.Size)
3077 g.ClipperTempData.resize(
g.ClipperTempDataStacked, ImGuiListClipperData());
3078 ImGuiListClipperData* data = &
g.ClipperTempData[
g.ClipperTempDataStacked - 1];
3080 data->LossynessOffset = window->DC.CursorStartPosLossyness.y;
3082 StartSeekOffsetY = data->LossynessOffset;
3085void ImGuiListClipper::End()
3087 if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
3090 ImGuiContext&
g = *Ctx;
3091 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: End() in '%s'\n",
g.CurrentWindow->Name);
3092 if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
3093 SeekCursorForItem(ItemsCount);
3096 IM_ASSERT(data->ListClipper ==
this);
3097 data->StepNo = data->Ranges.Size;
3098 if (--
g.ClipperTempDataStacked > 0)
3100 data = &
g.ClipperTempData[
g.ClipperTempDataStacked - 1];
3101 data->ListClipper->TempData = data;
3108void ImGuiListClipper::IncludeItemsByIndex(
int item_begin,
int item_end)
3110 ImGuiListClipperData* data = (ImGuiListClipperData*)TempData;
3111 IM_ASSERT(DisplayStart < 0);
3112 IM_ASSERT(item_begin <= item_end);
3113 if (item_begin < item_end)
3114 data->Ranges.push_back(ImGuiListClipperRange::FromIndices(item_begin, item_end));
3119void ImGuiListClipper::SeekCursorForItem(
int item_n)
3124 float pos_y = (float)((
double)StartPosY + StartSeekOffsetY + (double)item_n * ItemsHeight);
3125 ImGuiListClipper_SeekCursorAndSetupPrevLine(pos_y, ItemsHeight);
3128static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
3130 ImGuiContext&
g = *clipper->Ctx;
3131 ImGuiWindow* window =
g.CurrentWindow;
3132 ImGuiListClipperData* data = (ImGuiListClipperData*)clipper->TempData;
3133 IM_ASSERT(data != NULL &&
"Called ImGuiListClipper::Step() too many times, or before ImGuiListClipper::Begin() ?");
3135 ImGuiTable* table =
g.CurrentTable;
3136 if (table && table->IsInsideRow)
3137 ImGui::TableEndRow(table);
3140 if (clipper->ItemsCount == 0 || GetSkipItemForListClipping())
3145 if (data->StepNo == 0 && table != NULL && !table->IsUnfrozenRows)
3147 clipper->DisplayStart = data->ItemsFrozen;
3148 clipper->DisplayEnd = ImMin(data->ItemsFrozen + 1, clipper->ItemsCount);
3149 if (clipper->DisplayStart < clipper->DisplayEnd)
3150 data->ItemsFrozen++;
3155 bool calc_clipping =
false;
3156 if (data->StepNo == 0)
3158 clipper->StartPosY = window->DC.CursorPos.y;
3159 if (clipper->ItemsHeight <= 0.0f)
3162 data->Ranges.push_front(ImGuiListClipperRange::FromIndices(data->ItemsFrozen, data->ItemsFrozen + 1));
3163 clipper->DisplayStart = ImMax(data->Ranges[0].Min, data->ItemsFrozen);
3164 clipper->DisplayEnd = ImMin(data->Ranges[0].Max, clipper->ItemsCount);
3168 calc_clipping =
true;
3172 if (clipper->ItemsHeight <= 0.0f)
3174 IM_ASSERT(data->StepNo == 1);
3176 IM_ASSERT(table->RowPosY1 == clipper->StartPosY && table->RowPosY2 == window->DC.CursorPos.y);
3178 clipper->ItemsHeight = (window->DC.CursorPos.y - clipper->StartPosY) / (
float)(clipper->DisplayEnd - clipper->DisplayStart);
3179 bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
3180 if (affected_by_floating_point_precision)
3181 clipper->ItemsHeight = window->DC.PrevLineSize.y +
g.Style.ItemSpacing.y;
3182 if (clipper->ItemsHeight == 0.0f && clipper->ItemsCount == INT_MAX)
3184 IM_ASSERT(clipper->ItemsHeight > 0.0f &&
"Unable to calculate item height! First item hasn't moved the cursor vertically!");
3185 calc_clipping =
true;
3189 const int already_submitted = clipper->DisplayEnd;
3193 clipper->StartSeekOffsetY = (double)data->LossynessOffset - data->ItemsFrozen * (
double)clipper->ItemsHeight;
3198 data->Ranges.push_back(ImGuiListClipperRange::FromIndices(0, clipper->ItemsCount));
3203 const bool is_nav_request = (
g.NavMoveScoringItems &&
g.NavWindow &&
g.NavWindow->RootWindowForNav == window->RootWindowForNav);
3205 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(
g.NavScoringNoClipRect.Min.y,
g.NavScoringNoClipRect.Max.y, 0, 0));
3206 if (is_nav_request && (
g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) &&
g.NavTabbingDir == -1)
3207 data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount));
3210 ImRect nav_rect_abs = ImGui::WindowRectRelToAbs(window, window->NavRectRel[0]);
3211 if (
g.NavId != 0 && window->NavLastIds[0] ==
g.NavId)
3212 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(nav_rect_abs.Min.y, nav_rect_abs.Max.y, 0, 0));
3215 float min_y = window->ClipRect.Min.y;
3216 float max_y = window->ClipRect.Max.y;
3219 ImGuiBoxSelectState* bs = &
g.BoxSelectState;
3220 if (bs->IsActive && bs->Window == window)
3225 min_y -=
g.Style.ItemSpacing.y;
3226 max_y +=
g.Style.ItemSpacing.y;
3230 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(bs->UnclipRect.Min.y, bs->UnclipRect.Max.y, 0, 0));
3233 const int off_min = (is_nav_request &&
g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0;
3234 const int off_max = (is_nav_request &&
g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0;
3235 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, off_min, off_max));
3242 for (ImGuiListClipperRange& range : data->Ranges)
3243 if (range.PosToIndexConvert)
3245 int m1 = (int)(((
double)range.Min - window->DC.CursorPos.y - data->LossynessOffset) / clipper->ItemsHeight);
3246 int m2 = (int)((((
double)range.Max - window->DC.CursorPos.y - data->LossynessOffset) / clipper->ItemsHeight) + 0.999999f);
3247 range.Min = ImClamp(already_submitted + m1 + range.PosToIndexOffsetMin, already_submitted, clipper->ItemsCount - 1);
3248 range.Max = ImClamp(already_submitted + m2 + range.PosToIndexOffsetMax, range.Min + 1, clipper->ItemsCount);
3249 range.PosToIndexConvert =
false;
3251 ImGuiListClipper_SortAndFuseRanges(data->Ranges, data->StepNo);
3255 while (data->StepNo < data->Ranges.Size)
3257 clipper->DisplayStart = ImMax(data->Ranges[data->StepNo].Min, already_submitted);
3258 clipper->DisplayEnd = ImMin(data->Ranges[data->StepNo].Max, clipper->ItemsCount);
3259 if (clipper->DisplayStart > already_submitted)
3260 clipper->SeekCursorForItem(clipper->DisplayStart);
3262 if (clipper->DisplayStart == clipper->DisplayEnd && data->StepNo < data->Ranges.Size)
3269 if (clipper->ItemsCount < INT_MAX)
3270 clipper->SeekCursorForItem(clipper->ItemsCount);
3275bool ImGuiListClipper::Step()
3277 ImGuiContext&
g = *Ctx;
3278 bool need_items_height = (ItemsHeight <= 0.0f);
3279 bool ret = ImGuiListClipper_StepInternal(
this);
3280 if (ret && (DisplayStart == DisplayEnd))
3282 if (
g.CurrentTable &&
g.CurrentTable->IsUnfrozenRows ==
false)
3283 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): inside frozen table row.\n");
3284 if (need_items_height && ItemsHeight > 0.0f)
3285 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): computed ItemsHeight: %.2f.\n", ItemsHeight);
3288 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): display %d to %d.\n", DisplayStart, DisplayEnd);
3292 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): End.\n");
3302ImGuiStyle& ImGui::GetStyle()
3304 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
3308ImU32 ImGui::GetColorU32(ImGuiCol idx,
float alpha_mul)
3310 ImGuiStyle& style =
GImGui->Style;
3311 ImVec4 c = style.Colors[idx];
3312 c.w *= style.Alpha * alpha_mul;
3313 return ColorConvertFloat4ToU32(c);
3316ImU32 ImGui::GetColorU32(
const ImVec4& col)
3318 ImGuiStyle& style =
GImGui->Style;
3321 return ColorConvertFloat4ToU32(c);
3324const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx)
3326 ImGuiStyle& style =
GImGui->Style;
3327 return style.Colors[idx];
3330ImU32 ImGui::GetColorU32(ImU32 col,
float alpha_mul)
3332 ImGuiStyle& style =
GImGui->Style;
3333 alpha_mul *= style.Alpha;
3334 if (alpha_mul >= 1.0f)
3336 ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT;
3337 a = (ImU32)(a * alpha_mul);
3338 return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT);
3342void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col)
3345 ImGuiColorMod backup;
3347 backup.BackupValue =
g.Style.Colors[idx];
3348 g.ColorStack.push_back(backup);
3349 if (
g.DebugFlashStyleColorIdx != idx)
3350 g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
3353void ImGui::PushStyleColor(ImGuiCol idx,
const ImVec4& col)
3356 ImGuiColorMod backup;
3358 backup.BackupValue =
g.Style.Colors[idx];
3359 g.ColorStack.push_back(backup);
3360 if (
g.DebugFlashStyleColorIdx != idx)
3361 g.Style.Colors[idx] = col;
3364void ImGui::PopStyleColor(
int count)
3367 if (
g.ColorStack.Size < count)
3369 IM_ASSERT_USER_ERROR(0,
"Calling PopStyleColor() too many times!");
3370 count =
g.ColorStack.Size;
3374 ImGuiColorMod& backup =
g.ColorStack.back();
3375 g.Style.Colors[backup.Col] = backup.BackupValue;
3376 g.ColorStack.pop_back();
3381static const ImGuiCol GWindowDockStyleColors[ImGuiWindowDockStyleCol_COUNT] =
3383 ImGuiCol_Text, ImGuiCol_TabHovered, ImGuiCol_Tab, ImGuiCol_TabSelected, ImGuiCol_TabSelectedOverline, ImGuiCol_TabDimmed, ImGuiCol_TabDimmedSelected, ImGuiCol_TabDimmedSelectedOverline,
3386static const ImGuiDataVarInfo GStyleVarInfo[] =
3388 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, Alpha) },
3389 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) },
3390 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowPadding) },
3391 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowRounding) },
3392 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) },
3393 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowMinSize) },
3394 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) },
3395 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildRounding) },
3396 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) },
3397 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupRounding) },
3398 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) },
3399 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, FramePadding) },
3400 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameRounding) },
3401 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) },
3402 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemSpacing) },
3403 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) },
3404 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, IndentSpacing) },
3405 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, CellPadding) },
3406 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) },
3407 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) },
3408 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) },
3409 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) },
3410 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) },
3411 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBorderSize) },
3412 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) },
3413 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarOverlineSize) },
3414 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)},
3415 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},
3416 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) },
3417 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) },
3418 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)},
3419 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) },
3420 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) },
3421 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DockingSeparatorSize) },
3424const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx)
3426 IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT);
3428 return &GStyleVarInfo[idx];
3431void ImGui::PushStyleVar(ImGuiStyleVar idx,
float val)
3434 const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
3435 if (var_info->Type != ImGuiDataType_Float || var_info->Count != 1)
3437 IM_ASSERT_USER_ERROR(0,
"Calling PushStyleVar() variant with wrong type!");
3440 float* pvar = (
float*)var_info->GetVarPtr(&
g.Style);
3441 g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
3445void ImGui::PushStyleVarX(ImGuiStyleVar idx,
float val_x)
3448 const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
3449 if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2)
3451 IM_ASSERT_USER_ERROR(0,
"Calling PushStyleVar() variant with wrong type!");
3454 ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&
g.Style);
3455 g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
3459void ImGui::PushStyleVarY(ImGuiStyleVar idx,
float val_y)
3462 const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
3463 if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2)
3465 IM_ASSERT_USER_ERROR(0,
"Calling PushStyleVar() variant with wrong type!");
3468 ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&
g.Style);
3469 g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
3473void ImGui::PushStyleVar(ImGuiStyleVar idx,
const ImVec2& val)
3476 const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
3477 if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2)
3479 IM_ASSERT_USER_ERROR(0,
"Calling PushStyleVar() variant with wrong type!");
3482 ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&
g.Style);
3483 g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
3487void ImGui::PopStyleVar(
int count)
3490 if (
g.StyleVarStack.Size < count)
3492 IM_ASSERT_USER_ERROR(0,
"Calling PopStyleVar() too many times!");
3493 count =
g.StyleVarStack.Size;
3498 ImGuiStyleMod& backup =
g.StyleVarStack.back();
3499 const ImGuiDataVarInfo* info = GetStyleVarInfo(backup.VarIdx);
3500 void* data = info->GetVarPtr(&
g.Style);
3501 if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((
float*)data)[0] = backup.BackupFloat[0]; }
3502 else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((
float*)data)[0] = backup.BackupFloat[0]; ((
float*)data)[1] = backup.BackupFloat[1]; }
3503 g.StyleVarStack.pop_back();
3508const char* ImGui::GetStyleColorName(ImGuiCol idx)
3513 case ImGuiCol_Text:
return "Text";
3514 case ImGuiCol_TextDisabled:
return "TextDisabled";
3515 case ImGuiCol_WindowBg:
return "WindowBg";
3516 case ImGuiCol_ChildBg:
return "ChildBg";
3517 case ImGuiCol_PopupBg:
return "PopupBg";
3518 case ImGuiCol_Border:
return "Border";
3519 case ImGuiCol_BorderShadow:
return "BorderShadow";
3520 case ImGuiCol_FrameBg:
return "FrameBg";
3521 case ImGuiCol_FrameBgHovered:
return "FrameBgHovered";
3522 case ImGuiCol_FrameBgActive:
return "FrameBgActive";
3523 case ImGuiCol_TitleBg:
return "TitleBg";
3524 case ImGuiCol_TitleBgActive:
return "TitleBgActive";
3525 case ImGuiCol_TitleBgCollapsed:
return "TitleBgCollapsed";
3526 case ImGuiCol_MenuBarBg:
return "MenuBarBg";
3527 case ImGuiCol_ScrollbarBg:
return "ScrollbarBg";
3528 case ImGuiCol_ScrollbarGrab:
return "ScrollbarGrab";
3529 case ImGuiCol_ScrollbarGrabHovered:
return "ScrollbarGrabHovered";
3530 case ImGuiCol_ScrollbarGrabActive:
return "ScrollbarGrabActive";
3531 case ImGuiCol_CheckMark:
return "CheckMark";
3532 case ImGuiCol_SliderGrab:
return "SliderGrab";
3533 case ImGuiCol_SliderGrabActive:
return "SliderGrabActive";
3534 case ImGuiCol_Button:
return "Button";
3535 case ImGuiCol_ButtonHovered:
return "ButtonHovered";
3536 case ImGuiCol_ButtonActive:
return "ButtonActive";
3537 case ImGuiCol_Header:
return "Header";
3538 case ImGuiCol_HeaderHovered:
return "HeaderHovered";
3539 case ImGuiCol_HeaderActive:
return "HeaderActive";
3540 case ImGuiCol_Separator:
return "Separator";
3541 case ImGuiCol_SeparatorHovered:
return "SeparatorHovered";
3542 case ImGuiCol_SeparatorActive:
return "SeparatorActive";
3543 case ImGuiCol_ResizeGrip:
return "ResizeGrip";
3544 case ImGuiCol_ResizeGripHovered:
return "ResizeGripHovered";
3545 case ImGuiCol_ResizeGripActive:
return "ResizeGripActive";
3546 case ImGuiCol_TabHovered:
return "TabHovered";
3547 case ImGuiCol_Tab:
return "Tab";
3548 case ImGuiCol_TabSelected:
return "TabSelected";
3549 case ImGuiCol_TabSelectedOverline:
return "TabSelectedOverline";
3550 case ImGuiCol_TabDimmed:
return "TabDimmed";
3551 case ImGuiCol_TabDimmedSelected:
return "TabDimmedSelected";
3552 case ImGuiCol_TabDimmedSelectedOverline:
return "TabDimmedSelectedOverline";
3553 case ImGuiCol_DockingPreview:
return "DockingPreview";
3554 case ImGuiCol_DockingEmptyBg:
return "DockingEmptyBg";
3555 case ImGuiCol_PlotLines:
return "PlotLines";
3556 case ImGuiCol_PlotLinesHovered:
return "PlotLinesHovered";
3557 case ImGuiCol_PlotHistogram:
return "PlotHistogram";
3558 case ImGuiCol_PlotHistogramHovered:
return "PlotHistogramHovered";
3559 case ImGuiCol_TableHeaderBg:
return "TableHeaderBg";
3560 case ImGuiCol_TableBorderStrong:
return "TableBorderStrong";
3561 case ImGuiCol_TableBorderLight:
return "TableBorderLight";
3562 case ImGuiCol_TableRowBg:
return "TableRowBg";
3563 case ImGuiCol_TableRowBgAlt:
return "TableRowBgAlt";
3564 case ImGuiCol_TextLink:
return "TextLink";
3565 case ImGuiCol_TextSelectedBg:
return "TextSelectedBg";
3566 case ImGuiCol_DragDropTarget:
return "DragDropTarget";
3567 case ImGuiCol_NavCursor:
return "NavCursor";
3568 case ImGuiCol_NavWindowingHighlight:
return "NavWindowingHighlight";
3569 case ImGuiCol_NavWindowingDimBg:
return "NavWindowingDimBg";
3570 case ImGuiCol_ModalWindowDimBg:
return "ModalWindowDimBg";
3584const char* ImGui::FindRenderedTextEnd(
const char* text,
const char* text_end)
3586 const char* text_display_end = text;
3588 text_end = (
const char*)-1;
3590 while (text_display_end < text_end && *text_display_end !=
'\0' && (text_display_end[0] !=
'#' || text_display_end[1] !=
'#'))
3592 return text_display_end;
3597void ImGui::RenderText(ImVec2 pos,
const char* text,
const char* text_end,
bool hide_text_after_hash)
3600 ImGuiWindow* window =
g.CurrentWindow;
3603 const char* text_display_end;
3604 if (hide_text_after_hash)
3606 text_display_end = FindRenderedTextEnd(text, text_end);
3611 text_end = text + strlen(text);
3612 text_display_end = text_end;
3615 if (text != text_display_end)
3617 window->DrawList->AddText(
g.Font,
g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
3619 LogRenderedText(&pos, text, text_display_end);
3623void ImGui::RenderTextWrapped(ImVec2 pos,
const char* text,
const char* text_end,
float wrap_width)
3626 ImGuiWindow* window =
g.CurrentWindow;
3629 text_end = text + strlen(text);
3631 if (text != text_end)
3633 window->DrawList->AddText(
g.Font,
g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
3635 LogRenderedText(&pos, text, text_end);
3644void ImGui::RenderTextClippedEx(ImDrawList* draw_list,
const ImVec2& pos_min,
const ImVec2& pos_max,
const char* text,
const char* text_display_end,
const ImVec2* text_size_if_known,
const ImVec2& align,
const ImRect* clip_rect)
3647 ImVec2 pos = pos_min;
3648 const ImVec2 text_size = text_size_if_known ? *text_size_if_known :
CalcTextSize(text, text_display_end,
false, 0.0f);
3650 const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
3651 const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
3652 bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
3654 need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y);
3657 if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x);
3658 if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y);
3663 ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
3664 draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect);
3668 draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL);
3672void ImGui::RenderTextClipped(
const ImVec2& pos_min,
const ImVec2& pos_max,
const char* text,
const char* text_end,
const ImVec2* text_size_if_known,
const ImVec2& align,
const ImRect* clip_rect)
3675 const char* text_display_end = FindRenderedTextEnd(text, text_end);
3676 const int text_len = (int)(text_display_end - text);
3681 ImGuiWindow* window =
g.CurrentWindow;
3682 RenderTextClippedEx(window->DrawList, pos_min, pos_max, text, text_display_end, text_size_if_known, align, clip_rect);
3684 LogRenderedText(&pos_min, text, text_display_end);
3690void ImGui::RenderTextEllipsis(ImDrawList* draw_list,
const ImVec2& pos_min,
const ImVec2& pos_max,
float clip_max_x,
float ellipsis_max_x,
const char* text,
const char* text_end_full,
const ImVec2* text_size_if_known)
3693 if (text_end_full == NULL)
3694 text_end_full = FindRenderedTextEnd(text);
3695 const ImVec2 text_size = text_size_if_known ? *text_size_if_known :
CalcTextSize(text, text_end_full,
false, 0.0f);
3701 if (text_size.x > pos_max.x - pos_min.x)
3708 const ImFont* font = draw_list->_Data->Font;
3709 const float font_size = draw_list->_Data->FontSize;
3710 const float font_scale = draw_list->_Data->FontScale;
3711 const char* text_end_ellipsis = NULL;
3712 const float ellipsis_width = font->EllipsisWidth * font_scale;
3715 const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_width) - pos_min.x, 1.0f);
3716 float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
3717 if (text == text_end_ellipsis && text_end_ellipsis < text_end_full)
3721 text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x;
3723 while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1]))
3726 text_end_ellipsis--;
3727 text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x;
3731 RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
3732 ImVec2 ellipsis_pos = ImTrunc(ImVec2(pos_min.x + text_size_clipped_x, pos_min.y));
3733 if (ellipsis_pos.x + ellipsis_width <= ellipsis_max_x)
3734 for (
int i = 0; i < font->EllipsisCharCount; i++, ellipsis_pos.x += font->EllipsisCharStep * font_scale)
3735 font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar);
3739 RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_full, &text_size, ImVec2(0.0f, 0.0f));
3743 LogRenderedText(&pos_min, text, text_end_full);
3747void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col,
bool borders,
float rounding)
3750 ImGuiWindow* window =
g.CurrentWindow;
3751 window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding);
3752 const float border_size =
g.Style.FrameBorderSize;
3753 if (borders && border_size > 0.0f)
3755 window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size);
3756 window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
3760void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max,
float rounding)
3763 ImGuiWindow* window =
g.CurrentWindow;
3764 const float border_size =
g.Style.FrameBorderSize;
3765 if (border_size > 0.0f)
3767 window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size);
3768 window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
3772void ImGui::RenderNavCursor(
const ImRect& bb, ImGuiID
id, ImGuiNavRenderCursorFlags flags)
3777 if (!
g.NavCursorVisible && !(flags & ImGuiNavRenderCursorFlags_AlwaysDraw))
3779 if (
id ==
g.LastItemData.ID && (
g.LastItemData.ItemFlags & ImGuiItemFlags_NoNav))
3781 ImGuiWindow* window =
g.CurrentWindow;
3782 if (window->DC.NavHideHighlightOneFrame)
3785 float rounding = (flags & ImGuiNavRenderCursorFlags_NoRounding) ? 0.0f :
g.Style.FrameRounding;
3786 ImRect display_rect = bb;
3787 display_rect.ClipWith(window->ClipRect);
3788 const float thickness = 2.0f;
3789 if (flags & ImGuiNavRenderCursorFlags_Compact)
3791 window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness);
3795 const float distance = 3.0f + thickness * 0.5f;
3796 display_rect.Expand(ImVec2(distance, distance));
3797 bool fully_visible = window->ClipRect.Contains(display_rect);
3799 window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
3800 window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavCursor), rounding, 0, thickness);
3802 window->DrawList->PopClipRect();
3806void ImGui::RenderMouseCursor(ImVec2 base_pos,
float base_scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow)
3809 if (mouse_cursor <= ImGuiMouseCursor_None || mouse_cursor >= ImGuiMouseCursor_COUNT)
3810 mouse_cursor = ImGuiMouseCursor_Arrow;
3811 ImFontAtlas* font_atlas =
g.DrawListSharedData.Font->ContainerAtlas;
3812 for (ImGuiViewportP* viewport :
g.Viewports)
3815 ImVec2 offset,
size, uv[4];
3816 if (!font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2]))
3818 const ImVec2 pos = base_pos - offset;
3819 const float scale = base_scale * viewport->DpiScale;
3820 if (!viewport->GetMainRect().Overlaps(ImRect(pos, pos + ImVec2(
size.x + 2,
size.y + 2) * scale)))
3822 ImDrawList* draw_list = GetForegroundDrawList(viewport);
3823 ImTextureID tex_id = font_atlas->TexID;
3824 draw_list->PushTextureID(tex_id);
3825 draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow);
3826 draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow);
3827 draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border);
3828 draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill);
3829 draw_list->PopTextureID();
3839ImGuiContext* ImGui::GetCurrentContext()
3844void ImGui::SetCurrentContext(ImGuiContext* ctx)
3846#ifdef IMGUI_SET_CURRENT_CONTEXT_FUNC
3847 IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx);
3853void ImGui::SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func,
void* user_data)
3855 GImAllocatorAllocFunc = alloc_func;
3856 GImAllocatorFreeFunc = free_func;
3857 GImAllocatorUserData = user_data;
3861void ImGui::GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func,
void** p_user_data)
3863 *p_alloc_func = GImAllocatorAllocFunc;
3864 *p_free_func = GImAllocatorFreeFunc;
3865 *p_user_data = GImAllocatorUserData;
3868ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas)
3870 ImGuiContext* prev_ctx = GetCurrentContext();
3871 ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas);
3872 SetCurrentContext(ctx);
3874 if (prev_ctx != NULL)
3875 SetCurrentContext(prev_ctx);
3879void ImGui::DestroyContext(ImGuiContext* ctx)
3881 ImGuiContext* prev_ctx = GetCurrentContext();
3884 SetCurrentContext(ctx);
3886 SetCurrentContext((prev_ctx != ctx) ? prev_ctx : NULL);
3891static const ImGuiLocEntry GLocalizationEntriesEnUS[] =
3893 { ImGuiLocKey_VersionStr,
"Dear ImGui " IMGUI_VERSION
" (" IM_STRINGIFY(IMGUI_VERSION_NUM)
")" },
3894 { ImGuiLocKey_TableSizeOne,
"Size column to fit###SizeOne" },
3895 { ImGuiLocKey_TableSizeAllFit,
"Size all columns to fit###SizeAll" },
3896 { ImGuiLocKey_TableSizeAllDefault,
"Size all columns to default###SizeAll" },
3897 { ImGuiLocKey_TableResetOrder,
"Reset order###ResetOrder" },
3898 { ImGuiLocKey_WindowingMainMenuBar,
"(Main menu bar)" },
3899 { ImGuiLocKey_WindowingPopup,
"(Popup)" },
3900 { ImGuiLocKey_WindowingUntitled,
"(Untitled)" },
3901 { ImGuiLocKey_OpenLink_s,
"Open '%s'" },
3902 { ImGuiLocKey_CopyLink,
"Copy Link###CopyLink" },
3903 { ImGuiLocKey_DockingHideTabBar,
"Hide tab bar###HideTabBar" },
3904 { ImGuiLocKey_DockingHoldShiftToDock,
"Hold SHIFT to enable Docking window." },
3905 { ImGuiLocKey_DockingDragToUndockOrMoveNode,
"Click and drag to move or undock whole node." },
3908ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
3911 InputTextState.Ctx =
this;
3913 Initialized =
false;
3914 ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
3915 FontAtlasOwnedByContext = shared_font_atlas ? false :
true;
3917 FontSize = FontBaseSize = FontScale = CurrentDpiScale = 0.0f;
3918 IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
3921 FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1;
3922 WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild =
false;
3923 GcCompactAll =
false;
3924 TestEngineHookItems =
false;
3926 memset(ContextName, 0,
sizeof(ContextName));
3928 InputEventsNextMouseSource = ImGuiMouseSource_Mouse;
3929 InputEventsNextEventId = 1;
3931 WindowsActiveCount = 0;
3932 CurrentWindow = NULL;
3933 HoveredWindow = NULL;
3934 HoveredWindowUnderMovingWindow = NULL;
3935 HoveredWindowBeforeClear = NULL;
3936 MovingWindow = NULL;
3937 WheelingWindow = NULL;
3938 WheelingWindowStartFrame = WheelingWindowScrolledFrame = -1;
3939 WheelingWindowReleaseTimer = 0.0f;
3941 DebugDrawIdConflicts = 0;
3942 DebugHookIdInfo = 0;
3943 HoveredId = HoveredIdPreviousFrame = 0;
3944 HoveredIdPreviousFrameItemCount = 0;
3945 HoveredIdAllowOverlap =
false;
3946 HoveredIdIsDisabled =
false;
3947 HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
3948 ItemUnclipByLog =
false;
3950 ActiveIdIsAlive = 0;
3951 ActiveIdTimer = 0.0f;
3952 ActiveIdIsJustActivated =
false;
3953 ActiveIdAllowOverlap =
false;
3954 ActiveIdNoClearOnFocusLoss =
false;
3955 ActiveIdHasBeenPressedBefore =
false;
3956 ActiveIdHasBeenEditedBefore =
false;
3957 ActiveIdHasBeenEditedThisFrame =
false;
3958 ActiveIdFromShortcut =
false;
3959 ActiveIdClickOffset = ImVec2(-1, -1);
3960 ActiveIdWindow = NULL;
3961 ActiveIdSource = ImGuiInputSource_None;
3962 ActiveIdMouseButton = -1;
3963 ActiveIdPreviousFrame = 0;
3964 ActiveIdPreviousFrameIsAlive =
false;
3965 ActiveIdPreviousFrameHasBeenEditedBefore =
false;
3966 ActiveIdPreviousFrameWindow = NULL;
3968 LastActiveIdTimer = 0.0f;
3970 LastKeyboardKeyPressTime = LastKeyModsChangeTime = LastKeyModsChangeFromNoneTime = -1.0;
3972 ActiveIdUsingNavDirMask = 0x00;
3973 ActiveIdUsingAllKeyboardKeys =
false;
3975 CurrentFocusScopeId = 0;
3976 CurrentItemFlags = ImGuiItemFlags_None;
3977 DebugShowGroupRects =
false;
3979 CurrentViewport = NULL;
3980 MouseViewport = MouseLastHoveredViewport = NULL;
3981 PlatformLastFocusedViewportId = 0;
3982 ViewportCreatedCount = PlatformWindowsCreatedCount = 0;
3983 ViewportFocusedStampCount = 0;
3985 NavCursorVisible =
false;
3986 NavHighlightItemUnderNav =
false;
3987 NavMousePosDirty =
false;
3988 NavIdIsAlive =
false;
3991 NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0;
3992 NavLayer = ImGuiNavLayer_Main;
3993 NavNextActivateId = 0;
3994 NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
3995 NavHighlightActivatedId = 0;
3996 NavHighlightActivatedTimer = 0.0f;
3997 NavInputSource = ImGuiInputSource_Keyboard;
3998 NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
3999 NavCursorHideFrames = 0;
4001 NavAnyRequest =
false;
4002 NavInitRequest =
false;
4003 NavInitRequestFromMove =
false;
4004 NavMoveSubmitted =
false;
4005 NavMoveScoringItems =
false;
4006 NavMoveForwardToNextFrame =
false;
4007 NavMoveFlags = ImGuiNavMoveFlags_None;
4008 NavMoveScrollFlags = ImGuiScrollFlags_None;
4009 NavMoveKeyMods = ImGuiMod_None;
4010 NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None;
4011 NavScoringDebugCount = 0;
4013 NavTabbingCounter = 0;
4015 NavJustMovedFromFocusScopeId = NavJustMovedToId = NavJustMovedToFocusScopeId = 0;
4016 NavJustMovedToKeyMods = ImGuiMod_None;
4017 NavJustMovedToIsTabbing =
false;
4018 NavJustMovedToHasSelectionData =
false;
4022 ConfigNavWindowingKeyNext = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiKey_Tab);
4023 ConfigNavWindowingKeyPrev = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab);
4024 NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
4025 NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
4026 NavWindowingToggleLayer =
false;
4027 NavWindowingToggleKey = ImGuiKey_None;
4031 DragDropActive = DragDropWithinSource = DragDropWithinTarget =
false;
4032 DragDropSourceFlags = ImGuiDragDropFlags_None;
4033 DragDropSourceFrameCount = -1;
4034 DragDropMouseButton = -1;
4035 DragDropTargetId = 0;
4036 DragDropAcceptFlags = ImGuiDragDropFlags_None;
4037 DragDropAcceptIdCurrRectSurface = 0.0f;
4038 DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0;
4039 DragDropAcceptFrameCount = -1;
4040 DragDropHoldJustPressedId = 0;
4041 memset(DragDropPayloadBufLocal, 0,
sizeof(DragDropPayloadBufLocal));
4043 ClipperTempDataStacked = 0;
4045 CurrentTable = NULL;
4046 TablesTempDataStacked = 0;
4047 CurrentTabBar = NULL;
4048 CurrentMultiSelect = NULL;
4049 MultiSelectTempDataStacked = 0;
4051 HoverItemDelayId = HoverItemDelayIdPreviousFrame = HoverItemUnlockedStationaryId = HoverWindowUnlockedStationaryId = 0;
4052 HoverItemDelayTimer = HoverItemDelayClearTimer = 0.0f;
4054 MouseCursor = ImGuiMouseCursor_Arrow;
4055 MouseStationaryTimer = 0.0f;
4058 memset(&DataTypeZeroValue, 0,
sizeof(DataTypeZeroValue));
4059 BeginMenuDepth = BeginComboDepth = 0;
4060 ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
4061 ColorEditCurrentID = ColorEditSavedID = 0;
4062 ColorEditSavedHue = ColorEditSavedSat = 0.0f;
4063 ColorEditSavedColor = 0;
4064 WindowResizeRelativeMode =
false;
4065 ScrollbarSeekMode = 0;
4066 ScrollbarClickDeltaToGrabCenter = 0.0f;
4067 SliderGrabClickOffset = 0.0f;
4068 SliderCurrentAccum = 0.0f;
4069 SliderCurrentAccumDirty =
false;
4070 DragCurrentAccumDirty =
false;
4071 DragCurrentAccum = 0.0f;
4072 DragSpeedDefaultRatio = 1.0f / 100.0f;
4073 DisabledAlphaBackup = 0.0f;
4074 DisabledStackSize = 0;
4075 TooltipOverrideCount = 0;
4076 TooltipPreviousWindow = NULL;
4078 PlatformImeData.InputPos = ImVec2(0.0f, 0.0f);
4079 PlatformImeDataPrev.InputPos = ImVec2(-1.0f, -1.0f);
4080 PlatformImeViewport = 0;
4082 DockNodeWindowMenuHandler = NULL;
4084 SettingsLoaded =
false;
4085 SettingsDirtyTimer = 0.0f;
4088 memset(LocalizationTable, 0,
sizeof(LocalizationTable));
4091 LogType = ImGuiLogType_None;
4092 LogNextPrefix = LogNextSuffix = NULL;
4094 LogLinePosY = FLT_MAX;
4095 LogLineFirstItem =
false;
4097 LogDepthToExpand = LogDepthToExpandDefault = 2;
4099 ErrorCallback = NULL;
4100 ErrorCallbackUserData = NULL;
4102 ErrorCountCurrentFrame = 0;
4103 StackSizesInBeginForCurrentWindow = NULL;
4105 DebugDrawIdConflictsCount = 0;
4106 DebugLogFlags = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_OutputToTTY;
4108 DebugLogSkippedErrors = 0;
4109 DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None;
4110 DebugLogAutoDisableFrames = 0;
4111 DebugLocateFrames = 0;
4112 DebugBeginReturnValueCullDepth = -1;
4113 DebugItemPickerActive =
false;
4114 DebugItemPickerMouseButton = ImGuiMouseButton_Left;
4115 DebugItemPickerBreakId = 0;
4116 DebugFlashStyleColorTime = 0.0f;
4117 DebugFlashStyleColorIdx = ImGuiCol_COUNT;
4118 DebugHoveredDockNode = NULL;
4121 DebugBreakInWindow = 0;
4122 DebugBreakInTable = 0;
4123 DebugBreakInLocateId =
false;
4124 DebugBreakKeyChord = ImGuiKey_Pause;
4125 DebugBreakInShortcutRouting = ImGuiKey_None;
4127 memset(FramerateSecPerFrame, 0,
sizeof(FramerateSecPerFrame));
4128 FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
4129 FramerateSecPerFrameAccum = 0.0f;
4130 WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
4131 memset(TempKeychordName, 0,
sizeof(TempKeychordName));
4134void ImGui::Initialize()
4137 IM_ASSERT(!
g.Initialized && !
g.SettingsLoaded);
4141 ImGuiSettingsHandler ini_handler;
4142 ini_handler.TypeName =
"Window";
4143 ini_handler.TypeHash =
ImHashStr(
"Window");
4144 ini_handler.ClearAllFn = WindowSettingsHandler_ClearAll;
4145 ini_handler.ReadOpenFn = WindowSettingsHandler_ReadOpen;
4146 ini_handler.ReadLineFn = WindowSettingsHandler_ReadLine;
4147 ini_handler.ApplyAllFn = WindowSettingsHandler_ApplyAll;
4148 ini_handler.WriteAllFn = WindowSettingsHandler_WriteAll;
4149 AddSettingsHandler(&ini_handler);
4151 TableSettingsAddSettingsHandler();
4154 LocalizeRegisterEntries(GLocalizationEntriesEnUS, IM_ARRAYSIZE(GLocalizationEntriesEnUS));
4157 g.PlatformIO.Platform_GetClipboardTextFn = Platform_GetClipboardTextFn_DefaultImpl;
4158 g.PlatformIO.Platform_SetClipboardTextFn = Platform_SetClipboardTextFn_DefaultImpl;
4159 g.PlatformIO.Platform_OpenInShellFn = Platform_OpenInShellFn_DefaultImpl;
4160 g.PlatformIO.Platform_SetImeDataFn = Platform_SetImeDataFn_DefaultImpl;
4163 ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)();
4166 viewport->PlatformWindowCreated =
true;
4167 viewport->Flags = ImGuiViewportFlags_OwnedByApp;
4168 g.Viewports.push_back(viewport);
4169 g.TempBuffer.resize(1024 * 3 + 1, 0);
4170 g.ViewportCreatedCount++;
4171 g.PlatformIO.Viewports.push_back(
g.Viewports[0]);
4174 for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
4175 if ((key >= ImGuiKey_0 && key <= ImGuiKey_9) || (key >= ImGuiKey_A && key <= ImGuiKey_Z) || (key >= ImGuiKey_Keypad0 && key <= ImGuiKey_Keypad9)
4176 || key == ImGuiKey_Tab || key == ImGuiKey_Space || key == ImGuiKey_Apostrophe || key == ImGuiKey_Comma || key == ImGuiKey_Minus || key == ImGuiKey_Period
4177 || key == ImGuiKey_Slash || key == ImGuiKey_Semicolon || key == ImGuiKey_Equal || key == ImGuiKey_LeftBracket || key == ImGuiKey_RightBracket || key == ImGuiKey_GraveAccent
4178 || key == ImGuiKey_KeypadDecimal || key == ImGuiKey_KeypadDivide || key == ImGuiKey_KeypadMultiply || key == ImGuiKey_KeypadSubtract || key == ImGuiKey_KeypadAdd || key == ImGuiKey_KeypadEqual)
4179 g.KeysMayBeCharInput.SetBit(key);
4181#ifdef IMGUI_HAS_DOCK
4183 DockContextInitialize(&
g);
4186 g.Initialized =
true;
4190void ImGui::Shutdown()
4193 IM_ASSERT_USER_ERROR(
g.IO.BackendPlatformUserData == NULL,
"Forgot to shutdown Platform backend?");
4194 IM_ASSERT_USER_ERROR(
g.IO.BackendRendererUserData == NULL,
"Forgot to shutdown Renderer backend?");
4197 if (
g.IO.Fonts &&
g.FontAtlasOwnedByContext)
4199 g.IO.Fonts->Locked =
false;
4200 IM_DELETE(
g.IO.Fonts);
4203 g.DrawListSharedData.TempBuffer.clear();
4210 if (
g.SettingsLoaded &&
g.IO.IniFilename != NULL)
4211 SaveIniSettingsToDisk(
g.IO.IniFilename);
4214 DestroyPlatformWindows();
4217 DockContextShutdown(&
g);
4219 CallContextHooks(&
g, ImGuiContextHookType_Shutdown);
4222 g.Windows.clear_delete();
4223 g.WindowsFocusOrder.clear();
4224 g.WindowsTempSortBuffer.clear();
4225 g.CurrentWindow = NULL;
4226 g.CurrentWindowStack.clear();
4227 g.WindowsById.Clear();
4229 g.HoveredWindow =
g.HoveredWindowUnderMovingWindow = NULL;
4230 g.ActiveIdWindow =
g.ActiveIdPreviousFrameWindow = NULL;
4231 g.MovingWindow = NULL;
4233 g.KeysRoutingTable.Clear();
4235 g.ColorStack.clear();
4236 g.StyleVarStack.clear();
4237 g.FontStack.clear();
4238 g.OpenPopupStack.clear();
4239 g.BeginPopupStack.clear();
4240 g.TreeNodeStack.clear();
4242 g.CurrentViewport =
g.MouseViewport =
g.MouseLastHoveredViewport = NULL;
4243 g.Viewports.clear_delete();
4246 g.CurrentTabBarStack.clear();
4247 g.ShrinkWidthBuffer.clear();
4249 g.ClipperTempData.clear_destruct();
4252 g.TablesTempData.clear_destruct();
4253 g.DrawChannelsTempMergeBuffer.clear();
4255 g.MultiSelectStorage.Clear();
4256 g.MultiSelectTempData.clear_destruct();
4258 g.ClipboardHandlerData.clear();
4259 g.MenusIdSubmittedThisFrame.clear();
4260 g.InputTextState.ClearFreeMemory();
4261 g.InputTextDeactivatedState.ClearFreeMemory();
4263 g.SettingsWindows.clear();
4264 g.SettingsHandlers.clear();
4268#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
4269 if (
g.LogFile != stdout)
4274 g.LogBuffer.clear();
4275 g.DebugLogBuf.clear();
4276 g.DebugLogIndex.clear();
4278 g.Initialized =
false;
4282ImGuiID ImGui::AddContextHook(ImGuiContext* ctx,
const ImGuiContextHook* hook)
4284 ImGuiContext&
g = *ctx;
4285 IM_ASSERT(hook->Callback != NULL && hook->HookId == 0 && hook->Type != ImGuiContextHookType_PendingRemoval_);
4286 g.Hooks.push_back(*hook);
4287 g.Hooks.back().HookId = ++
g.HookIdNext;
4288 return g.HookIdNext;
4292void ImGui::RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_id)
4294 ImGuiContext&
g = *ctx;
4295 IM_ASSERT(hook_id != 0);
4296 for (ImGuiContextHook& hook :
g.Hooks)
4297 if (hook.HookId == hook_id)
4298 hook.Type = ImGuiContextHookType_PendingRemoval_;
4303void ImGui::CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType hook_type)
4305 ImGuiContext&
g = *ctx;
4306 for (ImGuiContextHook& hook :
g.Hooks)
4307 if (hook.Type == hook_type)
4308 hook.Callback(&
g, &hook);
4317ImGuiWindow::ImGuiWindow(ImGuiContext* ctx,
const char* name) : DrawListInst(NULL)
4319 memset(
this, 0,
sizeof(*
this));
4322 NameBufLen = (int)strlen(name) + 1;
4324 IDStack.push_back(ID);
4325 ViewportAllowPlatformMonitorExtend = -1;
4326 ViewportPos = ImVec2(FLT_MAX, FLT_MAX);
4327 MoveId = GetID(
"#MOVE");
4328 TabId = GetID(
"#TAB");
4329 ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
4330 ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
4331 AutoFitFramesX = AutoFitFramesY = -1;
4332 AutoPosLastDirection = ImGuiDir_None;
4333 SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = 0;
4334 SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
4335 LastFrameActive = -1;
4336 LastFrameJustFocused = -1;
4337 LastTimeActive = -1.0f;
4338 FontWindowScale = FontDpiScale = 1.0f;
4339 SettingsOffset = -1;
4341 DrawList = &DrawListInst;
4342 DrawList->_Data = &Ctx->DrawListSharedData;
4343 DrawList->_OwnerName = Name;
4344 NavPreferredScoringPosRel[0] = NavPreferredScoringPosRel[1] = ImVec2(FLT_MAX, FLT_MAX);
4345 IM_PLACEMENT_NEW(&WindowClass) ImGuiWindowClass();
4348ImGuiWindow::~ImGuiWindow()
4350 IM_ASSERT(DrawList == &DrawListInst);
4352 ColumnsStorage.clear_destruct();
4355static void SetCurrentWindow(ImGuiWindow* window)
4358 g.CurrentWindow = window;
4359 g.StackSizesInBeginForCurrentWindow =
g.CurrentWindow ? &
g.CurrentWindowStack.back().StackSizesInBegin : NULL;
4360 g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ?
g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL;
4363 g.FontSize =
g.DrawListSharedData.FontSize = window->CalcFontSize();
4364 g.FontScale =
g.DrawListSharedData.FontScale =
g.FontSize /
g.Font->FontSize;
4365 ImGui::NavUpdateCurrentWindowIsScrollPushableX();
4369void ImGui::GcCompactTransientMiscBuffers()
4372 g.ItemFlagsStack.clear();
4373 g.GroupStack.clear();
4374 g.MultiSelectTempDataStacked = 0;
4375 g.MultiSelectTempData.clear_destruct();
4376 TableGcCompactSettings();
4383void ImGui::GcCompactTransientWindowBuffers(ImGuiWindow* window)
4385 window->MemoryCompacted =
true;
4386 window->MemoryDrawListIdxCapacity = window->DrawList->IdxBuffer.Capacity;
4387 window->MemoryDrawListVtxCapacity = window->DrawList->VtxBuffer.Capacity;
4388 window->IDStack.clear();
4389 window->DrawList->_ClearFreeMemory();
4390 window->DC.ChildWindows.clear();
4391 window->DC.ItemWidthStack.clear();
4392 window->DC.TextWrapPosStack.clear();
4395void ImGui::GcAwakeTransientWindowBuffers(ImGuiWindow* window)
4399 window->MemoryCompacted =
false;
4400 window->DrawList->IdxBuffer.reserve(window->MemoryDrawListIdxCapacity);
4401 window->DrawList->VtxBuffer.reserve(window->MemoryDrawListVtxCapacity);
4402 window->MemoryDrawListIdxCapacity = window->MemoryDrawListVtxCapacity = 0;
4405void ImGui::SetActiveID(ImGuiID
id, ImGuiWindow* window)
4410 if (
g.ActiveId != 0)
4415 if (
g.MovingWindow != NULL &&
g.ActiveId ==
g.MovingWindow->MoveId)
4417 IMGUI_DEBUG_LOG_ACTIVEID(
"SetActiveID() cancel MovingWindow\n");
4418 g.MovingWindow = NULL;
4424 if (
g.InputTextState.ID ==
g.ActiveId)
4425 InputTextDeactivateHook(
g.ActiveId);
4429 g.ActiveIdIsJustActivated = (
g.ActiveId !=
id);
4430 if (
g.ActiveIdIsJustActivated)
4432 IMGUI_DEBUG_LOG_ACTIVEID(
"SetActiveID() old:0x%08X (window \"%s\") -> new:0x%08X (window \"%s\")\n",
g.ActiveId,
g.ActiveIdWindow ?
g.ActiveIdWindow->Name :
"",
id, window ? window->Name :
"");
4433 g.ActiveIdTimer = 0.0f;
4434 g.ActiveIdHasBeenPressedBefore =
false;
4435 g.ActiveIdHasBeenEditedBefore =
false;
4436 g.ActiveIdMouseButton = -1;
4439 g.LastActiveId =
id;
4440 g.LastActiveIdTimer = 0.0f;
4444 g.ActiveIdAllowOverlap =
false;
4445 g.ActiveIdNoClearOnFocusLoss =
false;
4446 g.ActiveIdWindow = window;
4447 g.ActiveIdHasBeenEditedThisFrame =
false;
4448 g.ActiveIdFromShortcut =
false;
4451 g.ActiveIdIsAlive =
id;
4452 g.ActiveIdSource = (
g.NavActivateId ==
id ||
g.NavJustMovedToId ==
id) ?
g.NavInputSource : ImGuiInputSource_Mouse;
4453 IM_ASSERT(
g.ActiveIdSource != ImGuiInputSource_None);
4458 g.ActiveIdUsingNavDirMask = 0x00;
4459 g.ActiveIdUsingAllKeyboardKeys =
false;
4462void ImGui::ClearActiveID()
4464 SetActiveID(0, NULL);
4467void ImGui::SetHoveredID(ImGuiID
id)
4471 g.HoveredIdAllowOverlap =
false;
4472 if (
id != 0 &&
g.HoveredIdPreviousFrame !=
id)
4473 g.HoveredIdTimer =
g.HoveredIdNotActiveTimer = 0.0f;
4476ImGuiID ImGui::GetHoveredID()
4479 return g.HoveredId ?
g.HoveredId :
g.HoveredIdPreviousFrame;
4482void ImGui::MarkItemEdited(ImGuiID
id)
4487 if (
g.LastItemData.ItemFlags & ImGuiItemFlags_NoMarkEdited)
4489 if (
g.ActiveId ==
id ||
g.ActiveId == 0)
4491 g.ActiveIdHasBeenEditedThisFrame =
true;
4492 g.ActiveIdHasBeenEditedBefore =
true;
4497 IM_ASSERT(
g.DragDropActive ||
g.ActiveId ==
id ||
g.ActiveId == 0 ||
g.ActiveIdPreviousFrame ==
id || (
g.CurrentMultiSelect != NULL &&
g.BoxSelectState.IsActive));
4500 g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
4503bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
4509 if (ImGuiWindow* focused_root_window =
g.NavWindow->RootWindowDockTree)
4510 if (focused_root_window->WasActive && focused_root_window != window->RootWindowDockTree)
4514 bool want_inhibit =
false;
4515 if (focused_root_window->Flags & ImGuiWindowFlags_Modal)
4516 want_inhibit =
true;
4517 else if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup))
4518 want_inhibit =
true;
4522 if (!IsWindowWithinBeginStackOf(window->RootWindow, focused_root_window))
4527 if (window->Viewport !=
g.MouseViewport)
4528 if (
g.MovingWindow == NULL || window->RootWindowDockTree !=
g.MovingWindow->RootWindowDockTree)
4534static inline float CalcDelayFromHoveredFlags(ImGuiHoveredFlags flags)
4537 if (flags & ImGuiHoveredFlags_DelayNormal)
4538 return g.Style.HoverDelayNormal;
4539 if (flags & ImGuiHoveredFlags_DelayShort)
4540 return g.Style.HoverDelayShort;
4544static ImGuiHoveredFlags ApplyHoverFlagsForTooltip(ImGuiHoveredFlags user_flags, ImGuiHoveredFlags shared_flags)
4547 if (user_flags & (ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal))
4548 shared_flags &= ~(ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal);
4549 return user_flags | shared_flags;
4555bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
4558 ImGuiWindow* window =
g.CurrentWindow;
4559 IM_ASSERT_USER_ERROR((flags & ~ImGuiHoveredFlags_AllowedMaskForIsItemHovered) == 0,
"Invalid flags for IsItemHovered()!");
4561 if (
g.NavHighlightItemUnderNav &&
g.NavCursorVisible && !(flags & ImGuiHoveredFlags_NoNavOverride))
4563 if (!IsItemFocused())
4565 if ((
g.LastItemData.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
4568 if (flags & ImGuiHoveredFlags_ForTooltip)
4569 flags = ApplyHoverFlagsForTooltip(flags,
g.Style.HoverFlagsForTooltipNav);
4574 ImGuiItemStatusFlags status_flags =
g.LastItemData.StatusFlags;
4575 if (!(status_flags & ImGuiItemStatusFlags_HoveredRect))
4578 if (flags & ImGuiHoveredFlags_ForTooltip)
4579 flags = ApplyHoverFlagsForTooltip(flags,
g.Style.HoverFlagsForTooltipMouse);
4587 if (
g.HoveredWindow != window && (status_flags & ImGuiItemStatusFlags_HoveredWindow) == 0)
4588 if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByWindow) == 0)
4592 const ImGuiID
id =
g.LastItemData.ID;
4593 if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0)
4594 if (
g.ActiveId != 0 &&
g.ActiveId !=
id && !
g.ActiveIdAllowOverlap)
4595 if (
g.ActiveId != window->MoveId &&
g.ActiveId != window->TabId)
4600 if (!IsWindowContentHoverable(window, flags) && !(
g.LastItemData.ItemFlags & ImGuiItemFlags_NoWindowHoverableCheck))
4604 if ((
g.LastItemData.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
4610 if (
id == window->MoveId && window->WriteAccessed)
4614 if ((
g.LastItemData.ItemFlags & ImGuiItemFlags_AllowOverlap) &&
id != 0)
4615 if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByItem) == 0)
4616 if (
g.HoveredIdPreviousFrame !=
g.LastItemData.ID)
4622 const float delay = CalcDelayFromHoveredFlags(flags);
4623 if (delay > 0.0f || (flags & ImGuiHoveredFlags_Stationary))
4625 ImGuiID hover_delay_id = (
g.LastItemData.ID != 0) ?
g.LastItemData.ID : window->GetIDFromPos(
g.LastItemData.Rect.Min);
4626 if ((flags & ImGuiHoveredFlags_NoSharedDelay) && (
g.HoverItemDelayIdPreviousFrame != hover_delay_id))
4627 g.HoverItemDelayTimer = 0.0f;
4628 g.HoverItemDelayId = hover_delay_id;
4633 if ((flags & ImGuiHoveredFlags_Stationary) != 0 &&
g.HoverItemUnlockedStationaryId != hover_delay_id)
4636 if (
g.HoverItemDelayTimer < delay)
4649bool ImGui::ItemHoverable(
const ImRect& bb, ImGuiID
id, ImGuiItemFlags item_flags)
4652 ImGuiWindow* window =
g.CurrentWindow;
4655#ifndef IMGUI_DISABLE_DEBUG_TOOLS
4656 if (
id != 0 &&
g.HoveredIdPreviousFrame ==
id && (item_flags & ImGuiItemFlags_AllowDuplicateId) == 0)
4658 g.HoveredIdPreviousFrameItemCount++;
4659 if (
g.DebugDrawIdConflicts ==
id)
4660 window->DrawList->AddRect(bb.Min - ImVec2(1,1), bb.Max + ImVec2(1,1), IM_COL32(255, 0, 0, 255), 0.0f, ImDrawFlags_None, 2.0f);
4664 if (
g.HoveredWindow != window)
4666 if (!IsMouseHoveringRect(bb.Min, bb.Max))
4669 if (
g.HoveredId != 0 &&
g.HoveredId !=
id && !
g.HoveredIdAllowOverlap)
4671 if (
g.ActiveId != 0 &&
g.ActiveId !=
id && !
g.ActiveIdAllowOverlap)
4672 if (!
g.ActiveIdFromShortcut)
4676 if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
4678 g.HoveredIdIsDisabled =
true;
4687 if (
g.DragDropActive &&
g.DragDropPayload.SourceId ==
id && !(
g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover))
4694 if (item_flags & ImGuiItemFlags_AllowOverlap)
4696 g.HoveredIdAllowOverlap =
true;
4697 if (
g.HoveredIdPreviousFrame !=
id)
4703 if (
id ==
g.LastItemData.ID && (
g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasShortcut) &&
g.ActiveId !=
id)
4704 if (IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_DelayNormal))
4705 SetTooltip(
"%s", GetKeyChordName(
g.LastItemData.Shortcut));
4709 if (item_flags & ImGuiItemFlags_Disabled)
4712 if (
g.ActiveId ==
id &&
id != 0)
4714 g.HoveredIdIsDisabled =
true;
4718#ifndef IMGUI_DISABLE_DEBUG_TOOLS
4725 if (
g.DebugItemPickerActive &&
g.HoveredIdPreviousFrame ==
id)
4726 GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
4727 if (
g.DebugItemPickerBreakId ==
id)
4732 if (
g.NavHighlightItemUnderNav && (item_flags & ImGuiItemFlags_NoNavDisableMouseHover) == 0)
4740bool ImGui::IsClippedEx(
const ImRect& bb, ImGuiID
id)
4743 ImGuiWindow* window =
g.CurrentWindow;
4744 if (!bb.Overlaps(window->ClipRect))
4745 if (
id == 0 || (
id !=
g.ActiveId &&
id !=
g.ActiveIdPreviousFrame &&
id !=
g.NavId &&
id !=
g.NavActivateId))
4746 if (!
g.ItemUnclipByLog)
4753void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags,
const ImRect& item_rect)
4756 g.LastItemData.ID = item_id;
4757 g.LastItemData.ItemFlags = in_flags;
4758 g.LastItemData.StatusFlags = item_flags;
4759 g.LastItemData.Rect =
g.LastItemData.NavRect = item_rect;
4762float ImGui::CalcWrapWidthForPos(
const ImVec2& pos,
float wrap_pos_x)
4764 if (wrap_pos_x < 0.0f)
4768 ImGuiWindow* window =
g.CurrentWindow;
4769 if (wrap_pos_x == 0.0f)
4776 wrap_pos_x = window->WorkRect.Max.x;
4778 else if (wrap_pos_x > 0.0f)
4780 wrap_pos_x += window->Pos.x - window->Scroll.x;
4783 return ImMax(wrap_pos_x - pos.x, 1.0f);
4787void* ImGui::MemAlloc(
size_t size)
4789 void* ptr = (*GImAllocatorAllocFunc)(
size, GImAllocatorUserData);
4790#ifndef IMGUI_DISABLE_DEBUG_TOOLS
4791 if (ImGuiContext* ctx =
GImGui)
4792 DebugAllocHook(&ctx->DebugAllocInfo, ctx->FrameCount, ptr, size);
4798void ImGui::MemFree(
void* ptr)
4800#ifndef IMGUI_DISABLE_DEBUG_TOOLS
4802 if (ImGuiContext* ctx =
GImGui)
4803 DebugAllocHook(&ctx->DebugAllocInfo, ctx->FrameCount, ptr, (
size_t)-1);
4805 return (*GImAllocatorFreeFunc)(ptr, GImAllocatorUserData);
4809void ImGui::DebugAllocHook(ImGuiDebugAllocInfo* info,
int frame_count,
void* ptr,
size_t size)
4811 ImGuiDebugAllocEntry* entry = &info->LastEntriesBuf[info->LastEntriesIdx];
4813 if (entry->FrameCount != frame_count)
4815 info->LastEntriesIdx = (info->LastEntriesIdx + 1) % IM_ARRAYSIZE(info->LastEntriesBuf);
4816 entry = &info->LastEntriesBuf[info->LastEntriesIdx];
4817 entry->FrameCount = frame_count;
4818 entry->AllocCount = entry->FreeCount = 0;
4820 if (size != (
size_t)-1)
4822 entry->AllocCount++;
4823 info->TotalAllocCount++;
4829 info->TotalFreeCount++;
4834const char* ImGui::GetClipboardText()
4837 return g.PlatformIO.Platform_GetClipboardTextFn ?
g.PlatformIO.Platform_GetClipboardTextFn(&
g) :
"";
4840void ImGui::SetClipboardText(
const char* text)
4843 if (
g.PlatformIO.Platform_SetClipboardTextFn != NULL)
4844 g.PlatformIO.Platform_SetClipboardTextFn(&
g, text);
4847const char* ImGui::GetVersion()
4849 return IMGUI_VERSION;
4852ImGuiIO& ImGui::GetIO()
4854 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
4859ImGuiIO& ImGui::GetIOEx(ImGuiContext* ctx)
4861 IM_ASSERT(ctx != NULL);
4865ImGuiPlatformIO& ImGui::GetPlatformIO()
4867 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext()?");
4868 return GImGui->PlatformIO;
4872ImDrawData* ImGui::GetDrawData()
4875 ImGuiViewportP* viewport =
g.Viewports[0];
4876 return viewport->DrawDataP.Valid ? &viewport->DrawDataP : NULL;
4879double ImGui::GetTime()
4884int ImGui::GetFrameCount()
4886 return GImGui->FrameCount;
4889static ImDrawList* GetViewportBgFgDrawList(ImGuiViewportP* viewport,
size_t drawlist_no,
const char* drawlist_name)
4893 IM_ASSERT(drawlist_no < IM_ARRAYSIZE(viewport->BgFgDrawLists));
4894 ImDrawList* draw_list = viewport->BgFgDrawLists[drawlist_no];
4895 if (draw_list == NULL)
4897 draw_list = IM_NEW(ImDrawList)(&
g.DrawListSharedData);
4898 draw_list->_OwnerName = drawlist_name;
4899 viewport->BgFgDrawLists[drawlist_no] = draw_list;
4903 if (viewport->BgFgDrawListsLastFrame[drawlist_no] !=
g.FrameCount)
4905 draw_list->_ResetForNewFrame();
4906 draw_list->PushTextureID(
g.IO.Fonts->TexID);
4907 draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size,
false);
4908 viewport->BgFgDrawListsLastFrame[drawlist_no] =
g.FrameCount;
4913ImDrawList* ImGui::GetBackgroundDrawList(ImGuiViewport* viewport)
4915 if (viewport == NULL)
4916 viewport =
GImGui->CurrentWindow->Viewport;
4917 return GetViewportBgFgDrawList((ImGuiViewportP*)viewport, 0,
"##Background");
4920ImDrawList* ImGui::GetForegroundDrawList(ImGuiViewport* viewport)
4922 if (viewport == NULL)
4923 viewport =
GImGui->CurrentWindow->Viewport;
4924 return GetViewportBgFgDrawList((ImGuiViewportP*)viewport, 1,
"##Foreground");
4927ImDrawListSharedData* ImGui::GetDrawListSharedData()
4929 return &
GImGui->DrawListSharedData;
4932void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
4938 FocusWindow(window);
4939 SetActiveID(window->MoveId, window);
4940 if (
g.IO.ConfigNavCursorVisibleAuto)
4941 g.NavCursorVisible =
false;
4942 g.ActiveIdClickOffset =
g.IO.MouseClickedPos[0] - window->RootWindowDockTree->Pos;
4943 g.ActiveIdNoClearOnFocusLoss =
true;
4944 SetActiveIdUsingAllKeyboardKeys();
4946 bool can_move_window =
true;
4947 if ((window->Flags & ImGuiWindowFlags_NoMove) || (window->RootWindowDockTree->Flags & ImGuiWindowFlags_NoMove))
4948 can_move_window =
false;
4949 if (ImGuiDockNode* node = window->DockNodeAsHost)
4950 if (node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove))
4951 can_move_window =
false;
4952 if (can_move_window)
4953 g.MovingWindow = window;
4957void ImGui::StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node,
bool undock)
4960 bool can_undock_node =
false;
4961 if (undock && node != NULL && node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove) == 0 && (node->MergedFlags & ImGuiDockNodeFlags_NoUndocking) == 0)
4966 ImGuiDockNode* root_node = DockNodeGetRootNode(node);
4967 if (root_node->OnlyNodeWithWindows != node || root_node->CentralNode != NULL)
4968 can_undock_node =
true;
4971 const bool clicked = IsMouseClicked(0);
4972 const bool dragging = IsMouseDragging(0);
4973 if (can_undock_node && dragging)
4974 DockContextQueueUndockNode(&
g, node);
4975 else if (!can_undock_node && (clicked || dragging) &&
g.MovingWindow != window)
4976 StartMouseMovingWindow(window);
4984void ImGui::UpdateMouseMovingWindowNewFrame()
4987 if (
g.MovingWindow != NULL)
4991 KeepAliveID(
g.ActiveId);
4992 IM_ASSERT(
g.MovingWindow &&
g.MovingWindow->RootWindowDockTree);
4993 ImGuiWindow* moving_window =
g.MovingWindow->RootWindowDockTree;
4996 const bool window_disappared = (!moving_window->WasActive && !moving_window->Active);
4997 if (
g.IO.MouseDown[0] && IsMousePosValid(&
g.IO.MousePos) && !window_disappared)
4999 ImVec2 pos =
g.IO.MousePos -
g.ActiveIdClickOffset;
5000 if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
5002 SetWindowPos(moving_window, pos, ImGuiCond_Always);
5003 if (moving_window->Viewport && moving_window->ViewportOwned)
5005 moving_window->Viewport->Pos = pos;
5006 moving_window->Viewport->UpdateWorkRect();
5009 FocusWindow(
g.MovingWindow);
5013 if (!window_disappared)
5017 if (
g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
5018 UpdateTryMergeWindowIntoHostViewport(moving_window,
g.MouseViewport);
5021 if (moving_window->Viewport && !IsDragDropPayloadBeingAccepted())
5022 g.MouseViewport = moving_window->Viewport;
5025 if (moving_window->Viewport)
5026 moving_window->Viewport->Flags &= ~ImGuiViewportFlags_NoInputs;
5029 g.MovingWindow = NULL;
5036 if (
g.ActiveIdWindow &&
g.ActiveIdWindow->MoveId ==
g.ActiveId)
5038 KeepAliveID(
g.ActiveId);
5039 if (!
g.IO.MouseDown[0])
5048void ImGui::UpdateMouseMovingWindowEndFrame()
5051 if (
g.ActiveId != 0 || (
g.HoveredId != 0 && !
g.HoveredIdIsDisabled))
5055 if (
g.NavWindow &&
g.NavWindow->Appearing)
5060 if (
g.IO.MouseClicked[0])
5064 ImGuiWindow* root_window =
g.HoveredWindow ?
g.HoveredWindow->RootWindow : NULL;
5065 const bool is_closed_popup = root_window && (root_window->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(root_window->PopupId, ImGuiPopupFlags_AnyPopupLevel);
5067 if (root_window != NULL && !is_closed_popup)
5069 StartMouseMovingWindow(
g.HoveredWindow);
5072 if (
g.IO.ConfigWindowsMoveFromTitleBarOnly)
5073 if (!(root_window->Flags & ImGuiWindowFlags_NoTitleBar) || root_window->DockIsActive)
5074 if (!root_window->TitleBarRect().Contains(
g.IO.MouseClickedPos[0]))
5075 g.MovingWindow = NULL;
5079 if (
g.HoveredIdIsDisabled)
5080 g.MovingWindow = NULL;
5082 else if (root_window == NULL &&
g.NavWindow != NULL)
5085 FocusWindow(NULL, ImGuiFocusRequestFlags_UnlessBelowModal);
5092 if (
g.IO.MouseClicked[1] &&
g.HoveredId == 0)
5096 ImGuiWindow* modal = GetTopMostPopupModal();
5097 bool hovered_window_above_modal =
g.HoveredWindow && (modal == NULL || IsWindowAbove(
g.HoveredWindow, modal));
5098 ClosePopupsOverWindow(hovered_window_above_modal ?
g.HoveredWindow : modal, true);
5104static void TranslateWindow(ImGuiWindow* window,
const ImVec2& delta)
5106 window->Pos += delta;
5107 window->ClipRect.Translate(delta);
5108 window->OuterRectClipped.Translate(delta);
5109 window->InnerRect.Translate(delta);
5110 window->DC.CursorPos += delta;
5111 window->DC.CursorStartPos += delta;
5112 window->DC.CursorMaxPos += delta;
5113 window->DC.IdealMaxPos += delta;
5116static void ScaleWindow(ImGuiWindow* window,
float scale)
5118 ImVec2 origin = window->Viewport->Pos;
5119 window->Pos = ImFloor((window->Pos - origin) * scale + origin);
5120 window->Size = ImTrunc(window->Size * scale);
5121 window->SizeFull = ImTrunc(window->SizeFull * scale);
5122 window->ContentSize = ImTrunc(window->ContentSize * scale);
5125static bool IsWindowActiveAndVisible(ImGuiWindow* window)
5127 return (window->Active) && (!window->Hidden);
5131void ImGui::UpdateHoveredWindowAndCaptureFlags()
5138 g.WindowsHoverPadding = ImMax(
g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING));
5144 bool clear_hovered_windows =
false;
5145 FindHoveredWindowEx(
g.IO.MousePos,
false, &
g.HoveredWindow, &
g.HoveredWindowUnderMovingWindow);
5146 IM_ASSERT(
g.HoveredWindow == NULL ||
g.HoveredWindow ==
g.MovingWindow ||
g.HoveredWindow->Viewport ==
g.MouseViewport);
5147 g.HoveredWindowBeforeClear =
g.HoveredWindow;
5150 ImGuiWindow* modal_window = GetTopMostPopupModal();
5151 if (modal_window &&
g.HoveredWindow && !IsWindowWithinBeginStackOf(
g.HoveredWindow->RootWindow, modal_window))
5152 clear_hovered_windows =
true;
5155 if (io.ConfigFlags & ImGuiConfigFlags_NoMouse)
5156 clear_hovered_windows =
true;
5160 const bool has_open_popup = (
g.OpenPopupStack.Size > 0);
5161 const bool has_open_modal = (modal_window != NULL);
5162 int mouse_earliest_down = -1;
5163 bool mouse_any_down =
false;
5164 for (
int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
5166 if (io.MouseClicked[i])
5168 io.MouseDownOwned[i] = (
g.HoveredWindow != NULL) || has_open_popup;
5169 io.MouseDownOwnedUnlessPopupClose[i] = (
g.HoveredWindow != NULL) || has_open_modal;
5171 mouse_any_down |= io.MouseDown[i];
5172 if (io.MouseDown[i] || io.MouseReleased[i])
5173 if (mouse_earliest_down == -1 || io.MouseClickedTime[i] < io.MouseClickedTime[mouse_earliest_down])
5174 mouse_earliest_down = i;
5176 const bool mouse_avail = (mouse_earliest_down == -1) || io.MouseDownOwned[mouse_earliest_down];
5177 const bool mouse_avail_unless_popup_close = (mouse_earliest_down == -1) || io.MouseDownOwnedUnlessPopupClose[mouse_earliest_down];
5181 const bool mouse_dragging_extern_payload =
g.DragDropActive && (
g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
5182 if (!mouse_avail && !mouse_dragging_extern_payload)
5183 clear_hovered_windows =
true;
5185 if (clear_hovered_windows)
5186 g.HoveredWindow =
g.HoveredWindowUnderMovingWindow = NULL;
5190 if (
g.WantCaptureMouseNextFrame != -1)
5192 io.WantCaptureMouse = io.WantCaptureMouseUnlessPopupClose = (
g.WantCaptureMouseNextFrame != 0);
5196 io.WantCaptureMouse = (mouse_avail && (
g.HoveredWindow != NULL || mouse_any_down)) || has_open_popup;
5197 io.WantCaptureMouseUnlessPopupClose = (mouse_avail_unless_popup_close && (
g.HoveredWindow != NULL || mouse_any_down)) || has_open_modal;
5201 io.WantCaptureKeyboard =
false;
5202 if ((io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) == 0)
5204 if ((
g.ActiveId != 0) || (modal_window != NULL))
5205 io.WantCaptureKeyboard =
true;
5206 else if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && io.ConfigNavCaptureKeyboard)
5207 io.WantCaptureKeyboard =
true;
5209 if (
g.WantCaptureKeyboardNextFrame != -1)
5210 io.WantCaptureKeyboard = (
g.WantCaptureKeyboardNextFrame != 0);
5213 io.WantTextInput = (
g.WantTextInputNextFrame != -1) ? (
g.WantTextInputNextFrame != 0) :
false;
5217static void SetupDrawListSharedData()
5220 ImRect virtual_space(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
5221 for (ImGuiViewportP* viewport :
g.Viewports)
5222 virtual_space.Add(viewport->GetMainRect());
5223 g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4();
5224 g.DrawListSharedData.CurveTessellationTol =
g.Style.CurveTessellationTol;
5225 g.DrawListSharedData.SetCircleTessellationMaxError(
g.Style.CircleTessellationMaxError);
5226 g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
5227 if (
g.Style.AntiAliasedLines)
5228 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
5229 if (
g.Style.AntiAliasedLinesUseTex && !(
g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedLines))
5230 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex;
5231 if (
g.Style.AntiAliasedFill)
5232 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
5233 if (
g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
5234 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset;
5237void ImGui::NewFrame()
5239 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
5244 for (
int n =
g.Hooks.Size - 1; n >= 0; n--)
5245 if (
g.Hooks[n].Type == ImGuiContextHookType_PendingRemoval_)
5246 g.Hooks.erase(&
g.Hooks[n]);
5248 CallContextHooks(&
g, ImGuiContextHookType_NewFramePre);
5251 g.ConfigFlagsLastFrame =
g.ConfigFlagsCurrFrame;
5252 ErrorCheckNewFrameSanityChecks();
5253 g.ConfigFlagsCurrFrame =
g.IO.ConfigFlags;
5258 g.Time +=
g.IO.DeltaTime;
5259 g.WithinFrameScope =
true;
5261 g.TooltipOverrideCount = 0;
5262 g.WindowsActiveCount = 0;
5263 g.MenusIdSubmittedThisFrame.resize(0);
5266 g.FramerateSecPerFrameAccum +=
g.IO.DeltaTime -
g.FramerateSecPerFrame[
g.FramerateSecPerFrameIdx];
5267 g.FramerateSecPerFrame[
g.FramerateSecPerFrameIdx] =
g.IO.DeltaTime;
5268 g.FramerateSecPerFrameIdx = (
g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(
g.FramerateSecPerFrame);
5269 g.FramerateSecPerFrameCount = ImMin(
g.FramerateSecPerFrameCount + 1, IM_ARRAYSIZE(
g.FramerateSecPerFrame));
5270 g.IO.Framerate = (
g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (
g.FramerateSecPerFrameAccum / (
float)
g.FramerateSecPerFrameCount)) : FLT_MAX;
5273 g.InputEventsTrail.resize(0);
5274 UpdateInputEvents(
g.IO.ConfigInputTrickleEventQueue);
5277 UpdateViewportsNewFrame();
5281 g.IO.Fonts->Locked =
true;
5282 SetupDrawListSharedData();
5283 SetCurrentFont(GetDefaultFont());
5284 IM_ASSERT(
g.Font->IsLoaded());
5287 for (ImGuiViewportP* viewport :
g.Viewports)
5289 viewport->DrawData = NULL;
5290 viewport->DrawDataP.Valid =
false;
5294 if (
g.DragDropActive &&
g.DragDropPayload.SourceId ==
g.ActiveId)
5295 KeepAliveID(
g.DragDropPayload.SourceId);
5298 if (!
g.IO.ConfigDebugHighlightIdConflicts || !
g.IO.KeyCtrl)
5299 g.DebugDrawIdConflicts = 0;
5300 if (
g.IO.ConfigDebugHighlightIdConflicts &&
g.HoveredIdPreviousFrameItemCount > 1)
5301 g.DebugDrawIdConflicts =
g.HoveredIdPreviousFrame;
5304 if (!
g.HoveredIdPreviousFrame)
5305 g.HoveredIdTimer = 0.0f;
5306 if (!
g.HoveredIdPreviousFrame || (
g.HoveredId &&
g.ActiveId ==
g.HoveredId))
5307 g.HoveredIdNotActiveTimer = 0.0f;
5309 g.HoveredIdTimer +=
g.IO.DeltaTime;
5310 if (
g.HoveredId &&
g.ActiveId !=
g.HoveredId)
5311 g.HoveredIdNotActiveTimer +=
g.IO.DeltaTime;
5312 g.HoveredIdPreviousFrame =
g.HoveredId;
5313 g.HoveredIdPreviousFrameItemCount = 0;
5315 g.HoveredIdAllowOverlap =
false;
5316 g.HoveredIdIsDisabled =
false;
5321 if (
g.ActiveId != 0 &&
g.ActiveIdIsAlive !=
g.ActiveId &&
g.ActiveIdPreviousFrame ==
g.ActiveId)
5323 IMGUI_DEBUG_LOG_ACTIVEID(
"NewFrame(): ClearActiveID() because it isn't marked alive anymore!\n");
5329 g.ActiveIdTimer +=
g.IO.DeltaTime;
5330 g.LastActiveIdTimer +=
g.IO.DeltaTime;
5331 g.ActiveIdPreviousFrame =
g.ActiveId;
5332 g.ActiveIdPreviousFrameWindow =
g.ActiveIdWindow;
5333 g.ActiveIdPreviousFrameHasBeenEditedBefore =
g.ActiveIdHasBeenEditedBefore;
5334 g.ActiveIdIsAlive = 0;
5335 g.ActiveIdHasBeenEditedThisFrame =
false;
5336 g.ActiveIdPreviousFrameIsAlive =
false;
5337 g.ActiveIdIsJustActivated =
false;
5338 if (
g.TempInputId != 0 &&
g.ActiveId !=
g.TempInputId)
5340 if (
g.ActiveId == 0)
5342 g.ActiveIdUsingNavDirMask = 0x00;
5343 g.ActiveIdUsingAllKeyboardKeys =
false;
5349 if (
g.HoverItemDelayId != 0 &&
g.MouseStationaryTimer >=
g.Style.HoverStationaryDelay)
5350 g.HoverItemUnlockedStationaryId =
g.HoverItemDelayId;
5351 else if (
g.HoverItemDelayId == 0)
5352 g.HoverItemUnlockedStationaryId = 0;
5353 if (
g.HoveredWindow != NULL &&
g.MouseStationaryTimer >=
g.Style.HoverStationaryDelay)
5354 g.HoverWindowUnlockedStationaryId =
g.HoveredWindow->ID;
5355 else if (
g.HoveredWindow == NULL)
5356 g.HoverWindowUnlockedStationaryId = 0;
5359 g.HoverItemDelayIdPreviousFrame =
g.HoverItemDelayId;
5360 if (
g.HoverItemDelayId != 0)
5362 g.HoverItemDelayTimer +=
g.IO.DeltaTime;
5363 g.HoverItemDelayClearTimer = 0.0f;
5364 g.HoverItemDelayId = 0;
5366 else if (
g.HoverItemDelayTimer > 0.0f)
5370 g.HoverItemDelayClearTimer +=
g.IO.DeltaTime;
5371 if (
g.HoverItemDelayClearTimer >= ImMax(0.25f,
g.IO.DeltaTime * 2.0f))
5372 g.HoverItemDelayTimer =
g.HoverItemDelayClearTimer = 0.0f;
5376 g.DragDropAcceptIdPrev =
g.DragDropAcceptIdCurr;
5377 g.DragDropAcceptIdCurr = 0;
5378 g.DragDropAcceptIdCurrRectSurface = FLT_MAX;
5379 g.DragDropWithinSource =
false;
5380 g.DragDropWithinTarget =
false;
5381 g.DragDropHoldJustPressedId = 0;
5382 g.TooltipPreviousWindow = NULL;
5389 UpdateKeyboardInputs();
5400 UpdateMouseInputs();
5404 DockContextNewFrameUpdateUndocking(&
g);
5407 IM_ASSERT(
g.WindowsFocusOrder.Size <=
g.Windows.Size);
5408 const float memory_compact_start_time = (
g.GcCompactAll ||
g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)
g.Time -
g.IO.ConfigMemoryCompactTimer;
5409 for (ImGuiWindow* window :
g.Windows)
5411 window->WasActive = window->Active;
5412 window->Active =
false;
5413 window->WriteAccessed =
false;
5414 window->BeginCountPreviousFrame = window->BeginCount;
5415 window->BeginCount = 0;
5418 if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time)
5419 GcCompactTransientWindowBuffers(window);
5425 UpdateHoveredWindowAndCaptureFlags();
5428 UpdateMouseMovingWindowNewFrame();
5431 if (GetTopMostPopupModal() != NULL || (
g.NavWindowingTarget != NULL &&
g.NavWindowingHighlightAlpha > 0.0f))
5432 g.DimBgRatio = ImMin(
g.DimBgRatio +
g.IO.DeltaTime * 6.0f, 1.0f);
5434 g.DimBgRatio = ImMax(
g.DimBgRatio -
g.IO.DeltaTime * 10.0f, 0.0f);
5436 g.MouseCursor = ImGuiMouseCursor_Arrow;
5437 g.WantCaptureMouseNextFrame =
g.WantCaptureKeyboardNextFrame =
g.WantTextInputNextFrame = -1;
5440 g.PlatformImeDataPrev =
g.PlatformImeData;
5441 g.PlatformImeData.WantVisible =
false;
5447 for (
int i = 0; i <
g.TablesLastTimeActive.Size; i++)
5448 if (
g.TablesLastTimeActive[i] >= 0.0f &&
g.TablesLastTimeActive[i] < memory_compact_start_time)
5449 TableGcCompactTransientBuffers(
g.Tables.GetByIndex(i));
5450 for (ImGuiTableTempData& table_temp_data :
g.TablesTempData)
5451 if (table_temp_data.LastTimeActive >= 0.0f && table_temp_data.LastTimeActive < memory_compact_start_time)
5452 TableGcCompactTransientBuffers(&table_temp_data);
5454 GcCompactTransientMiscBuffers();
5455 g.GcCompactAll =
false;
5458 if (
g.NavWindow && !