1026#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
1027#define _CRT_SECURE_NO_WARNINGS
1030#ifndef IMGUI_DEFINE_MATH_OPERATORS
1031#define IMGUI_DEFINE_MATH_OPERATORS
1035#ifndef IMGUI_DISABLE
1036#include "imgui_internal.h"
1043#if defined(_WIN32) && !defined(_MSC_VER) && !defined(IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)
1044#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
1048#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)
1049#define IMGUI_DISABLE_WIN32_FUNCTIONS
1051#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
1052#ifndef WIN32_LEAN_AND_MEAN
1053#define WIN32_LEAN_AND_MEAN
1063#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
1065#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
1066#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
1067#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS
1072#if defined(__APPLE__)
1073#include <TargetConditionals.h>
1078#pragma warning (disable: 4127)
1079#pragma warning (disable: 4996)
1080#if defined(_MSC_VER) && _MSC_VER >= 1922
1081#pragma warning (disable: 5054)
1083#pragma warning (disable: 26451)
1084#pragma warning (disable: 26495)
1085#pragma warning (disable: 26812)
1089#if defined(__clang__)
1090#if __has_warning("-Wunknown-warning-option")
1091#pragma clang diagnostic ignored "-Wunknown-warning-option"
1093#pragma clang diagnostic ignored "-Wunknown-pragmas"
1094#pragma clang diagnostic ignored "-Wold-style-cast"
1095#pragma clang diagnostic ignored "-Wfloat-equal"
1096#pragma clang diagnostic ignored "-Wformat-nonliteral"
1097#pragma clang diagnostic ignored "-Wexit-time-destructors"
1098#pragma clang diagnostic ignored "-Wglobal-constructors"
1099#pragma clang diagnostic ignored "-Wsign-conversion"
1100#pragma clang diagnostic ignored "-Wformat-pedantic"
1101#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
1102#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
1103#pragma clang diagnostic ignored "-Wdouble-promotion"
1104#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
1105#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
1106#elif defined(__GNUC__)
1108#pragma GCC diagnostic ignored "-Wpragmas"
1109#pragma GCC diagnostic ignored "-Wunused-function"
1110#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
1111#pragma GCC diagnostic ignored "-Wformat"
1112#pragma GCC diagnostic ignored "-Wdouble-promotion"
1113#pragma GCC diagnostic ignored "-Wconversion"
1114#pragma GCC diagnostic ignored "-Wformat-nonliteral"
1115#pragma GCC diagnostic ignored "-Wstrict-overflow"
1116#pragma GCC diagnostic ignored "-Wclass-memaccess"
1120#define IMGUI_DEBUG_NAV_SCORING 0
1121#define IMGUI_DEBUG_NAV_RECTS 0
1124static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f;
1125static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f;
1127static const float NAV_ACTIVATE_HIGHLIGHT_TIMER = 0.10f;
1130static const float WINDOWS_HOVER_PADDING = 4.0f;
1131static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f;
1132static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 0.70f;
1135static const ImVec2 TOOLTIP_DEFAULT_OFFSET = ImVec2(16, 10);
1138static const float DOCKING_TRANSPARENT_PAYLOAD_ALPHA = 0.50f;
1144static void SetCurrentWindow(ImGuiWindow* window);
1145static ImGuiWindow* CreateNewWindow(
const char* name, ImGuiWindowFlags flags);
1146static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window);
1148static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window);
1151static void WindowSettingsHandler_ClearAll(ImGuiContext*, ImGuiSettingsHandler*);
1152static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*,
const char* name);
1153static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*,
void* entry,
const char* line);
1154static void WindowSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSettingsHandler*);
1155static void WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf);
1158static const char* GetClipboardTextFn_DefaultImpl(
void* user_data_ctx);
1159static void SetClipboardTextFn_DefaultImpl(
void* user_data_ctx,
const char* text);
1160static void PlatformSetImeDataFn_DefaultImpl(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data);
1161static bool PlatformOpenInShellFn_DefaultImpl(ImGuiContext* ctx,
const char* path);
1166static void ItemHandleShortcut(ImGuiID
id);
1169static void NavUpdate();
1170static void NavUpdateWindowing();
1171static void NavUpdateWindowingOverlay();
1172static void NavUpdateCancelRequest();
1173static void NavUpdateCreateMoveRequest();
1174static void NavUpdateCreateTabbingRequest();
1175static float NavUpdatePageUpPageDown();
1176static inline void NavUpdateAnyRequestFlag();
1177static void NavUpdateCreateWrappingRequest();
1178static void NavEndFrame();
1179static bool NavScoreItem(ImGuiNavItemData* result);
1180static void NavApplyItemToResult(ImGuiNavItemData* result);
1181static void NavProcessItem();
1182static void NavProcessItemForTabbingRequest(ImGuiID
id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags);
1183static ImVec2 NavCalcPreferredRefPos();
1184static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
1185static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
1186static void NavRestoreLayer(ImGuiNavLayer layer);
1187static int FindWindowFocusIndex(ImGuiWindow* window);
1190static void ErrorCheckNewFrameSanityChecks();
1191static void ErrorCheckEndFrameSanityChecks();
1192static void UpdateDebugToolItemPicker();
1193static void UpdateDebugToolStackQueries();
1194static void UpdateDebugToolFlashStyleColor();
1197static void UpdateKeyboardInputs();
1198static void UpdateMouseInputs();
1199static void UpdateMouseWheel();
1200static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt);
1203static void UpdateSettings();
1204static 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);
1205static void RenderWindowOuterBorders(ImGuiWindow* window);
1206static 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);
1207static void RenderWindowTitleBarContents(ImGuiWindow* window,
const ImRect& title_bar_rect,
const char* name,
bool* p_open);
1208static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
1209static void RenderDimmedBackgrounds();
1210static void SetLastItemDataForWindow(ImGuiWindow* window,
const ImRect& rect);
1214static ImGuiViewportP* AddUpdateViewport(ImGuiWindow* window, ImGuiID
id,
const ImVec2& platform_pos,
const ImVec2& size, ImGuiViewportFlags flags);
1215static void DestroyViewport(ImGuiViewportP* viewport);
1216static void UpdateViewportsNewFrame();
1217static void UpdateViewportsEndFrame();
1218static void WindowSelectViewport(ImGuiWindow* window);
1219static void WindowSyncOwnedViewport(ImGuiWindow* window, ImGuiWindow* parent_window_in_stack);
1220static bool UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* host_viewport);
1221static bool UpdateTryMergeWindowIntoHostViewports(ImGuiWindow* window);
1222static bool GetWindowAlwaysWantOwnViewport(ImGuiWindow* window);
1223static int FindPlatformMonitorForPos(
const ImVec2& pos);
1224static int FindPlatformMonitorForRect(
const ImRect& r);
1225static void UpdateViewportPlatformMonitor(ImGuiViewportP* viewport);
1260#ifndef IMGUI_DISABLE_DEFAULT_ALLOCATORS
1261static void* MallocWrapper(
size_t size,
void* user_data) { IM_UNUSED(user_data);
return malloc(size); }
1262static void FreeWrapper(
void* ptr,
void* user_data) { IM_UNUSED(user_data); free(ptr); }
1264static void* MallocWrapper(
size_t size,
void* user_data) { IM_UNUSED(user_data); IM_UNUSED(size); IM_ASSERT(0);
return NULL; }
1265static void FreeWrapper(
void* ptr,
void* user_data) { IM_UNUSED(user_data); IM_UNUSED(ptr); IM_ASSERT(0); }
1267static ImGuiMemAllocFunc GImAllocatorAllocFunc = MallocWrapper;
1268static ImGuiMemFreeFunc GImAllocatorFreeFunc = FreeWrapper;
1269static void* GImAllocatorUserData = NULL;
1275ImGuiStyle::ImGuiStyle()
1278 DisabledAlpha = 0.60f;
1279 WindowPadding = ImVec2(8,8);
1280 WindowRounding = 0.0f;
1281 WindowBorderSize = 1.0f;
1282 WindowMinSize = ImVec2(32,32);
1283 WindowTitleAlign = ImVec2(0.0f,0.5f);
1284 WindowMenuButtonPosition = ImGuiDir_Left;
1285 ChildRounding = 0.0f;
1286 ChildBorderSize = 1.0f;
1287 PopupRounding = 0.0f;
1288 PopupBorderSize = 1.0f;
1289 FramePadding = ImVec2(4,3);
1290 FrameRounding = 0.0f;
1291 FrameBorderSize = 0.0f;
1292 ItemSpacing = ImVec2(8,4);
1293 ItemInnerSpacing = ImVec2(4,4);
1294 CellPadding = ImVec2(4,2);
1295 TouchExtraPadding = ImVec2(0,0);
1296 IndentSpacing = 21.0f;
1297 ColumnsMinSpacing = 6.0f;
1298 ScrollbarSize = 14.0f;
1299 ScrollbarRounding = 9.0f;
1300 GrabMinSize = 12.0f;
1301 GrabRounding = 0.0f;
1302 LogSliderDeadzone = 4.0f;
1304 TabBorderSize = 0.0f;
1305 TabMinWidthForCloseButton = 0.0f;
1306 TabBarBorderSize = 1.0f;
1307 TabBarOverlineSize = 2.0f;
1308 TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f);
1309 TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);
1310 ColorButtonPosition = ImGuiDir_Right;
1311 ButtonTextAlign = ImVec2(0.5f,0.5f);
1312 SelectableTextAlign = ImVec2(0.0f,0.0f);
1313 SeparatorTextBorderSize = 3.0f;
1314 SeparatorTextAlign = ImVec2(0.0f,0.5f);
1315 SeparatorTextPadding = ImVec2(20.0f,3.f);
1316 DisplayWindowPadding = ImVec2(19,19);
1317 DisplaySafeAreaPadding = ImVec2(3,3);
1318 DockingSeparatorSize = 2.0f;
1319 MouseCursorScale = 1.0f;
1320 AntiAliasedLines =
true;
1321 AntiAliasedLinesUseTex =
true;
1322 AntiAliasedFill =
true;
1323 CurveTessellationTol = 1.25f;
1324 CircleTessellationMaxError = 0.30f;
1327 HoverStationaryDelay = 0.15f;
1328 HoverDelayShort = 0.15f;
1329 HoverDelayNormal = 0.40f;
1330 HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled;
1331 HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_AllowWhenDisabled;
1334 ImGui::StyleColorsDark(
this);
1339void ImGuiStyle::ScaleAllSizes(
float scale_factor)
1341 WindowPadding = ImTrunc(WindowPadding * scale_factor);
1342 WindowRounding = ImTrunc(WindowRounding * scale_factor);
1343 WindowMinSize = ImTrunc(WindowMinSize * scale_factor);
1344 ChildRounding = ImTrunc(ChildRounding * scale_factor);
1345 PopupRounding = ImTrunc(PopupRounding * scale_factor);
1346 FramePadding = ImTrunc(FramePadding * scale_factor);
1347 FrameRounding = ImTrunc(FrameRounding * scale_factor);
1348 ItemSpacing = ImTrunc(ItemSpacing * scale_factor);
1349 ItemInnerSpacing = ImTrunc(ItemInnerSpacing * scale_factor);
1350 CellPadding = ImTrunc(CellPadding * scale_factor);
1351 TouchExtraPadding = ImTrunc(TouchExtraPadding * scale_factor);
1352 IndentSpacing = ImTrunc(IndentSpacing * scale_factor);
1353 ColumnsMinSpacing = ImTrunc(ColumnsMinSpacing * scale_factor);
1354 ScrollbarSize = ImTrunc(ScrollbarSize * scale_factor);
1355 ScrollbarRounding = ImTrunc(ScrollbarRounding * scale_factor);
1356 GrabMinSize = ImTrunc(GrabMinSize * scale_factor);
1357 GrabRounding = ImTrunc(GrabRounding * scale_factor);
1358 LogSliderDeadzone = ImTrunc(LogSliderDeadzone * scale_factor);
1359 TabRounding = ImTrunc(TabRounding * scale_factor);
1360 TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImTrunc(TabMinWidthForCloseButton * scale_factor) : FLT_MAX;
1361 TabBarOverlineSize = ImTrunc(TabBarOverlineSize * scale_factor);
1362 SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
1363 DockingSeparatorSize = ImTrunc(DockingSeparatorSize * scale_factor);
1364 DisplayWindowPadding = ImTrunc(DisplayWindowPadding * scale_factor);
1365 DisplaySafeAreaPadding = ImTrunc(DisplaySafeAreaPadding * scale_factor);
1366 MouseCursorScale = ImTrunc(MouseCursorScale * scale_factor);
1372 memset(
this, 0,
sizeof(*
this));
1373 IM_STATIC_ASSERT(IM_ARRAYSIZE(ImGuiIO::MouseDown) == ImGuiMouseButton_COUNT && IM_ARRAYSIZE(ImGuiIO::MouseClicked) == ImGuiMouseButton_COUNT);
1376 ConfigFlags = ImGuiConfigFlags_None;
1377 BackendFlags = ImGuiBackendFlags_None;
1378 DisplaySize = ImVec2(-1.0f, -1.0f);
1379 DeltaTime = 1.0f / 60.0f;
1380 IniSavingRate = 5.0f;
1381 IniFilename =
"imgui.ini";
1382 LogFilename =
"imgui_log.txt";
1383#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1384 for (
int i = 0; i < ImGuiKey_COUNT; i++)
1390 FontGlobalScale = 1.0f;
1392 FontAllowUserScaling =
false;
1393 DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
1396 ConfigDockingNoSplit =
false;
1397 ConfigDockingWithShift =
false;
1398 ConfigDockingAlwaysTabBar =
false;
1399 ConfigDockingTransparentPayload =
false;
1402 ConfigViewportsNoAutoMerge =
false;
1403 ConfigViewportsNoTaskBarIcon =
false;
1404 ConfigViewportsNoDecoration =
true;
1405 ConfigViewportsNoDefaultParent =
false;
1408 MouseDrawCursor =
false;
1410 ConfigMacOSXBehaviors =
true;
1412 ConfigMacOSXBehaviors =
false;
1414 ConfigNavSwapGamepadButtons =
false;
1415 ConfigInputTrickleEventQueue =
true;
1416 ConfigInputTextCursorBlink =
true;
1417 ConfigInputTextEnterKeepActive =
false;
1418 ConfigDragClickToInputText =
false;
1419 ConfigWindowsResizeFromEdges =
true;
1420 ConfigWindowsMoveFromTitleBarOnly =
false;
1421 ConfigMemoryCompactTimer = 60.0f;
1422 ConfigDebugBeginReturnValueOnce =
false;
1423 ConfigDebugBeginReturnValueLoop =
false;
1426 MouseDoubleClickTime = 0.30f;
1427 MouseDoubleClickMaxDist = 6.0f;
1428 MouseDragThreshold = 6.0f;
1429 KeyRepeatDelay = 0.275f;
1430 KeyRepeatRate = 0.050f;
1434 BackendPlatformName = BackendRendererName = NULL;
1435 BackendPlatformUserData = BackendRendererUserData = BackendLanguageUserData = NULL;
1436 PlatformOpenInShellUserData = NULL;
1437 PlatformLocaleDecimalPoint =
'.';
1440 MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
1441 MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX);
1442 MouseSource = ImGuiMouseSource_Mouse;
1443 for (
int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
1444 for (
int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; }
1445 AppAcceptingEvents =
true;
1446 BackendUsingLegacyKeyArrays = (ImS8)-1;
1447 BackendUsingLegacyNavInputArray =
true;
1454void ImGuiIO::AddInputCharacter(
unsigned int c)
1456 IM_ASSERT(Ctx != NULL);
1457 ImGuiContext&
g = *Ctx;
1458 if (c == 0 || !AppAcceptingEvents)
1462 e.Type = ImGuiInputEventType_Text;
1463 e.Source = ImGuiInputSource_Keyboard;
1464 e.EventId =
g.InputEventsNextEventId++;
1466 g.InputEventsQueue.push_back(e);
1471void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
1473 if ((c == 0 && InputQueueSurrogate == 0) || !AppAcceptingEvents)
1476 if ((c & 0xFC00) == 0xD800)
1478 if (InputQueueSurrogate != 0)
1479 AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
1480 InputQueueSurrogate = c;
1485 if (InputQueueSurrogate != 0)
1487 if ((c & 0xFC00) != 0xDC00)
1489 AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
1493#if IM_UNICODE_CODEPOINT_MAX == 0xFFFF
1494 cp = IM_UNICODE_CODEPOINT_INVALID;
1496 cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000);
1500 InputQueueSurrogate = 0;
1502 AddInputCharacter((
unsigned)cp);
1505void ImGuiIO::AddInputCharactersUTF8(
const char* utf8_chars)
1507 if (!AppAcceptingEvents)
1509 while (*utf8_chars != 0)
1513 AddInputCharacter(c);
1518void ImGuiIO::ClearEventsQueue()
1520 IM_ASSERT(Ctx != NULL);
1521 ImGuiContext&
g = *Ctx;
1522 g.InputEventsQueue.clear();
1526void ImGuiIO::ClearInputKeys()
1528#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1529 memset(KeysDown, 0,
sizeof(KeysDown));
1531 for (
int n = 0; n < IM_ARRAYSIZE(KeysData); n++)
1533 if (ImGui::IsMouseKey((ImGuiKey)(n + ImGuiKey_KeysData_OFFSET)))
1535 KeysData[n].Down =
false;
1536 KeysData[n].DownDuration = -1.0f;
1537 KeysData[n].DownDurationPrev = -1.0f;
1539 KeyCtrl = KeyShift = KeyAlt = KeySuper =
false;
1540 KeyMods = ImGuiMod_None;
1541 InputQueueCharacters.resize(0);
1544void ImGuiIO::ClearInputMouse()
1546 for (ImGuiKey key = ImGuiKey_Mouse_BEGIN; key < ImGuiKey_Mouse_END; key = (ImGuiKey)(key + 1))
1548 ImGuiKeyData* key_data = &KeysData[key - ImGuiKey_KeysData_OFFSET];
1549 key_data->Down =
false;
1550 key_data->DownDuration = -1.0f;
1551 key_data->DownDurationPrev = -1.0f;
1553 MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
1554 for (
int n = 0; n < IM_ARRAYSIZE(MouseDown); n++)
1556 MouseDown[n] =
false;
1557 MouseDownDuration[n] = MouseDownDurationPrev[n] = -1.0f;
1559 MouseWheel = MouseWheelH = 0.0f;
1564#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
1565void ImGuiIO::ClearInputCharacters()
1567 InputQueueCharacters.resize(0);
1571static ImGuiInputEvent* FindLatestInputEvent(ImGuiContext* ctx, ImGuiInputEventType type,
int arg = -1)
1573 ImGuiContext&
g = *ctx;
1574 for (
int n =
g.InputEventsQueue.Size - 1; n >= 0; n--)
1576 ImGuiInputEvent*
e = &
g.InputEventsQueue[n];
1577 if (
e->Type != type)
1579 if (type == ImGuiInputEventType_Key &&
e->Key.Key != arg)
1581 if (type == ImGuiInputEventType_MouseButton &&
e->MouseButton.Button != arg)
1594void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key,
bool down,
float analog_value)
1597 IM_ASSERT(Ctx != NULL);
1598 if (key == ImGuiKey_None || !AppAcceptingEvents)
1600 ImGuiContext&
g = *Ctx;
1601 IM_ASSERT(ImGui::IsNamedKeyOrMod(key));
1602 IM_ASSERT(ImGui::IsAliasKey(key) ==
false);
1605 if (
g.IO.ConfigMacOSXBehaviors)
1607 if (key == ImGuiMod_Super) { key = ImGuiMod_Ctrl; }
1608 else if (key == ImGuiMod_Ctrl) { key = ImGuiMod_Super; }
1609 else if (key == ImGuiKey_LeftSuper) { key = ImGuiKey_LeftCtrl; }
1610 else if (key == ImGuiKey_RightSuper){ key = ImGuiKey_RightCtrl; }
1611 else if (key == ImGuiKey_LeftCtrl) { key = ImGuiKey_LeftSuper; }
1612 else if (key == ImGuiKey_RightCtrl) { key = ImGuiKey_RightSuper; }
1616#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1617 IM_ASSERT((BackendUsingLegacyKeyArrays == -1 || BackendUsingLegacyKeyArrays == 0) &&
"Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
1618 if (BackendUsingLegacyKeyArrays == -1)
1619 for (
int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
1620 IM_ASSERT(KeyMap[n] == -1 &&
"Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
1621 BackendUsingLegacyKeyArrays = 0;
1623 if (ImGui::IsGamepadKey(key))
1624 BackendUsingLegacyNavInputArray =
false;
1627 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_Key, (
int)key);
1628 const ImGuiKeyData* key_data = ImGui::GetKeyData(&
g, key);
1629 const bool latest_key_down = latest_event ? latest_event->Key.Down : key_data->Down;
1630 const float latest_key_analog = latest_event ? latest_event->Key.AnalogValue : key_data->AnalogValue;
1631 if (latest_key_down == down && latest_key_analog == analog_value)
1636 e.Type = ImGuiInputEventType_Key;
1637 e.Source = ImGui::IsGamepadKey(key) ? ImGuiInputSource_Gamepad : ImGuiInputSource_Keyboard;
1638 e.EventId =
g.InputEventsNextEventId++;
1641 e.Key.AnalogValue = analog_value;
1642 g.InputEventsQueue.push_back(e);
1645void ImGuiIO::AddKeyEvent(ImGuiKey key,
bool down)
1647 if (!AppAcceptingEvents)
1649 AddKeyAnalogEvent(key, down, down ? 1.0f : 0.0f);
1655void ImGuiIO::SetKeyEventNativeData(ImGuiKey key,
int native_keycode,
int native_scancode,
int native_legacy_index)
1657 if (key == ImGuiKey_None)
1659 IM_ASSERT(ImGui::IsNamedKey(key));
1660 IM_ASSERT(native_legacy_index == -1 || ImGui::IsLegacyKey((ImGuiKey)native_legacy_index));
1661 IM_UNUSED(native_keycode);
1662 IM_UNUSED(native_scancode);
1665#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1666 const int legacy_key = (native_legacy_index != -1) ? native_legacy_index : native_keycode;
1667 if (!ImGui::IsLegacyKey((ImGuiKey)legacy_key))
1669 KeyMap[legacy_key] = key;
1670 KeyMap[key] = legacy_key;
1673 IM_UNUSED(native_legacy_index);
1678void ImGuiIO::SetAppAcceptingEvents(
bool accepting_events)
1680 AppAcceptingEvents = accepting_events;
1684void ImGuiIO::AddMousePosEvent(
float x,
float y)
1686 IM_ASSERT(Ctx != NULL);
1687 ImGuiContext&
g = *Ctx;
1688 if (!AppAcceptingEvents)
1692 ImVec2 pos((x > -FLT_MAX) ? ImFloor(x) : x, (y > -FLT_MAX) ? ImFloor(y) : y);
1695 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_MousePos);
1696 const ImVec2 latest_pos = latest_event ? ImVec2(latest_event->MousePos.PosX, latest_event->MousePos.PosY) :
g.IO.MousePos;
1697 if (latest_pos.x == pos.x && latest_pos.y == pos.y)
1701 e.Type = ImGuiInputEventType_MousePos;
1702 e.Source = ImGuiInputSource_Mouse;
1703 e.EventId =
g.InputEventsNextEventId++;
1704 e.MousePos.PosX = pos.x;
1705 e.MousePos.PosY = pos.y;
1706 e.MousePos.MouseSource =
g.InputEventsNextMouseSource;
1707 g.InputEventsQueue.push_back(e);
1710void ImGuiIO::AddMouseButtonEvent(
int mouse_button,
bool down)
1712 IM_ASSERT(Ctx != NULL);
1713 ImGuiContext&
g = *Ctx;
1714 IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT);
1715 if (!AppAcceptingEvents)
1719 if (ConfigMacOSXBehaviors && mouse_button == 0 && MouseCtrlLeftAsRightClick)
1724 MouseCtrlLeftAsRightClick =
false;
1728 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_MouseButton, (
int)mouse_button);
1729 const bool latest_button_down = latest_event ? latest_event->MouseButton.Down :
g.IO.MouseDown[mouse_button];
1730 if (latest_button_down == down)
1736 if (ConfigMacOSXBehaviors && mouse_button == 0 && down)
1738 const ImGuiInputEvent* latest_super_event = FindLatestInputEvent(&
g, ImGuiInputEventType_Key, (
int)ImGuiMod_Super);
1739 if (latest_super_event ? latest_super_event->Key.Down :
g.IO.KeySuper)
1741 IMGUI_DEBUG_LOG_IO(
"[io] Super+Left Click aliased into Right Click\n");
1742 MouseCtrlLeftAsRightClick =
true;
1743 AddMouseButtonEvent(1,
true);
1749 e.Type = ImGuiInputEventType_MouseButton;
1750 e.Source = ImGuiInputSource_Mouse;
1751 e.EventId =
g.InputEventsNextEventId++;
1752 e.MouseButton.Button = mouse_button;
1753 e.MouseButton.Down = down;
1754 e.MouseButton.MouseSource =
g.InputEventsNextMouseSource;
1755 g.InputEventsQueue.push_back(e);
1759void ImGuiIO::AddMouseWheelEvent(
float wheel_x,
float wheel_y)
1761 IM_ASSERT(Ctx != NULL);
1762 ImGuiContext&
g = *Ctx;
1765 if (!AppAcceptingEvents || (wheel_x == 0.0f && wheel_y == 0.0f))
1769 e.Type = ImGuiInputEventType_MouseWheel;
1770 e.Source = ImGuiInputSource_Mouse;
1771 e.EventId =
g.InputEventsNextEventId++;
1772 e.MouseWheel.WheelX = wheel_x;
1773 e.MouseWheel.WheelY = wheel_y;
1774 e.MouseWheel.MouseSource =
g.InputEventsNextMouseSource;
1775 g.InputEventsQueue.push_back(e);
1780void ImGuiIO::AddMouseSourceEvent(ImGuiMouseSource source)
1782 IM_ASSERT(Ctx != NULL);
1783 ImGuiContext&
g = *Ctx;
1784 g.InputEventsNextMouseSource = source;
1787void ImGuiIO::AddMouseViewportEvent(ImGuiID viewport_id)
1789 IM_ASSERT(Ctx != NULL);
1790 ImGuiContext&
g = *Ctx;
1792 if (!AppAcceptingEvents)
1796 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_MouseViewport);
1797 const ImGuiID latest_viewport_id = latest_event ? latest_event->MouseViewport.HoveredViewportID :
g.IO.MouseHoveredViewport;
1798 if (latest_viewport_id == viewport_id)
1802 e.Type = ImGuiInputEventType_MouseViewport;
1803 e.Source = ImGuiInputSource_Mouse;
1804 e.MouseViewport.HoveredViewportID = viewport_id;
1805 g.InputEventsQueue.push_back(e);
1808void ImGuiIO::AddFocusEvent(
bool focused)
1810 IM_ASSERT(Ctx != NULL);
1811 ImGuiContext&
g = *Ctx;
1814 const ImGuiInputEvent* latest_event = FindLatestInputEvent(&
g, ImGuiInputEventType_Focus);
1815 const bool latest_focused = latest_event ? latest_event->AppFocused.Focused : !
g.IO.AppFocusLost;
1816 if (latest_focused == focused || (ConfigDebugIgnoreFocusLoss && !focused))
1820 e.Type = ImGuiInputEventType_Focus;
1821 e.EventId =
g.InputEventsNextEventId++;
1822 e.AppFocused.Focused = focused;
1823 g.InputEventsQueue.push_back(e);
1832 IM_ASSERT(num_segments > 0);
1835 float p_closest_dist2 = FLT_MAX;
1836 float t_step = 1.0f / (float)num_segments;
1837 for (
int i_step = 1; i_step <= num_segments; i_step++)
1841 float dist2 = ImLengthSqr(p - p_line);
1842 if (dist2 < p_closest_dist2)
1845 p_closest_dist2 = dist2;
1853static 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)
1857 float d2 = ((x2 - x4) * dy - (y2 - y4) * dx);
1858 float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
1859 d2 = (d2 >= 0) ? d2 : -d2;
1860 d3 = (d3 >= 0) ? d3 : -d3;
1861 if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy))
1863 ImVec2 p_current(x4, y4);
1865 float dist2 = ImLengthSqr(p - p_line);
1866 if (dist2 < p_closest_dist2)
1869 p_closest_dist2 = dist2;
1873 else if (level < 10)
1875 float x12 = (x1 + x2)*0.5f, y12 = (y1 + y2)*0.5f;
1876 float x23 = (x2 + x3)*0.5f, y23 = (y2 + y3)*0.5f;
1877 float x34 = (x3 + x4)*0.5f, y34 = (y3 + y4)*0.5f;
1878 float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f;
1879 float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f;
1880 float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f;
1881 ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
1882 ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
1890 IM_ASSERT(tess_tol > 0.0f);
1893 float p_closest_dist2 = FLT_MAX;
1894 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);
1901 ImVec2 ab_dir = b - a;
1902 float dot = ap.x * ab_dir.x + ap.y * ab_dir.y;
1905 float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y;
1906 if (dot > ab_len_sqr)
1908 return a + ab_dir * dot / ab_len_sqr;
1913 bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f;
1914 bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f;
1915 bool b3 = ((p.x - a.x) * (c.y - a.y) - (p.y - a.y) * (c.x - a.x)) < 0.0f;
1916 return ((b1 == b2) && (b2 == b3));
1924 const float denom = v0.x * v1.y - v1.x * v0.y;
1925 out_v = (v2.x * v1.y - v1.x * v2.y) / denom;
1926 out_w = (v0.x * v2.y - v2.x * v0.y) / denom;
1927 out_u = 1.0f - out_v - out_w;
1935 float dist2_ab = ImLengthSqr(p - proj_ab);
1936 float dist2_bc = ImLengthSqr(p - proj_bc);
1937 float dist2_ca = ImLengthSqr(p - proj_ca);
1938 float m = ImMin(dist2_ab, ImMin(dist2_bc, dist2_ca));
1954 while ((d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; }
1961 while (count > 0 && (d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; count--; }
1970 strncpy(dst, src, count - 1);
1976 size_t len = strlen(str);
1977 void* buf = IM_ALLOC(len + 1);
1978 return (
char*)memcpy(buf, (
const void*)str, len + 1);
1983 size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
1984 size_t src_size = strlen(src) + 1;
1985 if (dst_buf_size < src_size)
1988 dst = (
char*)IM_ALLOC(src_size);
1990 *p_dst_size = src_size;
1992 return (
char*)memcpy(dst, (
const void*)src, src_size);
1997 const char* p = (
const char*)memchr(str, (
int)c, str_end - str);
2012 const char* p = (
const char*)memchr(str,
'\n', str_end - str);
2013 return p ? p : str_end;
2016const ImWchar*
ImStrbolW(
const ImWchar* buf_mid_line,
const ImWchar* buf_begin)
2018 while (buf_mid_line > buf_begin && buf_mid_line[-1] !=
'\n')
2020 return buf_mid_line;
2023const char*
ImStristr(
const char* haystack,
const char* haystack_end,
const char* needle,
const char* needle_end)
2026 needle_end = needle + strlen(needle);
2028 const char un0 = (char)ImToUpper(*needle);
2029 while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end))
2031 if (ImToUpper(*haystack) == un0)
2033 const char* b = needle + 1;
2034 for (
const char* a = haystack + 1; b < needle_end; a++, b++)
2035 if (ImToUpper(*a) != ImToUpper(*b))
2037 if (b == needle_end)
2049 while (p[0] ==
' ' || p[0] ==
'\t')
2054 while (p > p_start && (p[-1] ==
' ' || p[-1] ==
'\t'))
2057 memmove(buf, p_start, p - p_start);
2058 buf[p - p_start] = 0;
2063 while (str[0] ==
' ' || str[0] ==
'\t')
2071#ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
2077#ifdef IMGUI_USE_STB_SPRINTF
2078#ifndef IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION
2079#define STB_SPRINTF_IMPLEMENTATION
2081#ifdef IMGUI_STB_SPRINTF_FILENAME
2082#include IMGUI_STB_SPRINTF_FILENAME
2084#include "stb_sprintf.h"
2088#if defined(_MSC_VER) && !defined(vsnprintf)
2089#define vsnprintf _vsnprintf
2095 va_start(args, fmt);
2096#ifdef IMGUI_USE_STB_SPRINTF
2097 int w = stbsp_vsnprintf(buf, (
int)buf_size, fmt, args);
2099 int w = vsnprintf(buf, buf_size, fmt, args);
2104 if (w == -1 || w >= (
int)buf_size)
2105 w = (int)buf_size - 1;
2112#ifdef IMGUI_USE_STB_SPRINTF
2113 int w = stbsp_vsnprintf(buf, (
int)buf_size, fmt, args);
2115 int w = vsnprintf(buf, buf_size, fmt, args);
2119 if (w == -1 || w >= (
int)buf_size)
2120 w = (int)buf_size - 1;
2129 va_start(args, fmt);
2141 if (fmt[0] ==
'%' && fmt[1] ==
's' && fmt[2] == 0)
2143 const char* buf = va_arg(args,
const char*);
2147 if (out_buf_end) { *out_buf_end = buf + strlen(buf); }
2149 else if (fmt[0] ==
'%' && fmt[1] ==
'.' && fmt[2] ==
'*' && fmt[3] ==
's' && fmt[4] == 0)
2151 int buf_len = va_arg(args,
int);
2152 const char* buf = va_arg(args,
const char*);
2156 buf_len = ImMin(buf_len, 6);
2159 *out_buf_end = buf + buf_len;
2164 *out_buf =
g.TempBuffer.Data;
2165 if (out_buf_end) { *out_buf_end =
g.TempBuffer.Data + buf_len; }
2172static const ImU32 GCrc32LookupTable[256] =
2174 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,
2175 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,
2176 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
2177 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,
2178 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01,
2179 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,
2180 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
2181 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD,
2182 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,
2183 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,
2184 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79,
2185 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,
2186 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,
2187 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
2188 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,
2189 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D,
2195ImGuiID
ImHashData(
const void* data_p,
size_t data_size, ImGuiID seed)
2198 const unsigned char* data = (
const unsigned char*)data_p;
2199 const ImU32* crc32_lut = GCrc32LookupTable;
2200 while (data_size-- != 0)
2201 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *data++];
2211ImGuiID
ImHashStr(
const char* data_p,
size_t data_size, ImGuiID seed)
2215 const unsigned char* data = (
const unsigned char*)data_p;
2216 const ImU32* crc32_lut = GCrc32LookupTable;
2219 while (data_size-- != 0)
2221 unsigned char c = *data++;
2222 if (c ==
'#' && data_size >= 2 && data[0] ==
'#' && data[1] ==
'#')
2224 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
2229 while (
unsigned char c = *data++)
2231 if (c ==
'#' && data[0] ==
'#' && data[1] ==
'#')
2233 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
2244#ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
2248#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
2251 const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
2252 const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
2256 wchar_t local_temp_stack[FILENAME_MAX];
2257 ImVector<wchar_t> local_temp_heap;
2258 if (filename_wsize + mode_wsize > IM_ARRAYSIZE(local_temp_stack))
2259 local_temp_heap.resize(filename_wsize + mode_wsize);
2260 wchar_t* filename_wbuf = local_temp_heap.Data ? local_temp_heap.Data : local_temp_stack;
2261 wchar_t* mode_wbuf = filename_wbuf + filename_wsize;
2262 ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_wbuf, filename_wsize);
2263 ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, mode_wbuf, mode_wsize);
2264 return ::_wfopen(filename_wbuf, mode_wbuf);
2266 return fopen(filename, mode);
2272ImU64
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; }
2273ImU64
ImFileRead(
void* data, ImU64 sz, ImU64 count, ImFileHandle f) {
return fread(data, (
size_t)sz, (
size_t)count, f); }
2274ImU64
ImFileWrite(
const void* data, ImU64 sz, ImU64 count, ImFileHandle f) {
return fwrite(data, (
size_t)sz, (
size_t)count, f); }
2280void*
ImFileLoadToMemory(
const char* filename,
const char* mode,
size_t* out_file_size,
int padding_bytes)
2282 IM_ASSERT(filename && mode);
2287 if ((f =
ImFileOpen(filename, mode)) == NULL)
2291 if (file_size == (
size_t)-1)
2297 void* file_data = IM_ALLOC(file_size + padding_bytes);
2298 if (file_data == NULL)
2303 if (
ImFileRead(file_data, 1, file_size, f) != file_size)
2309 if (padding_bytes > 0)
2310 memset((
void*)(((
char*)file_data) + file_size), 0, (
size_t)padding_bytes);
2314 *out_file_size = file_size;
2323IM_MSVC_RUNTIME_CHECKS_OFF
2330 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 };
2331 static const int masks[] = { 0x00, 0x7f, 0x1f, 0x0f, 0x07 };
2332 static const uint32_t mins[] = { 0x400000, 0, 0x80, 0x800, 0x10000 };
2333 static const int shiftc[] = { 0, 18, 12, 6, 0 };
2334 static const int shifte[] = { 0, 6, 4, 2, 0 };
2335 int len = lengths[*(
const unsigned char*)in_text >> 3];
2336 int wanted = len + (len ? 0 : 1);
2338 if (in_text_end == NULL)
2339 in_text_end = in_text + wanted;
2344 s[0] = in_text + 0 < in_text_end ? in_text[0] : 0;
2345 s[1] = in_text + 1 < in_text_end ? in_text[1] : 0;
2346 s[2] = in_text + 2 < in_text_end ? in_text[2] : 0;
2347 s[3] = in_text + 3 < in_text_end ? in_text[3] : 0;
2350 *out_char = (uint32_t)(s[0] & masks[len]) << 18;
2351 *out_char |= (uint32_t)(s[1] & 0x3f) << 12;
2352 *out_char |= (uint32_t)(s[2] & 0x3f) << 6;
2353 *out_char |= (uint32_t)(s[3] & 0x3f) << 0;
2354 *out_char >>= shiftc[len];
2358 e = (*out_char < mins[len]) << 6;
2359 e |= ((*out_char >> 11) == 0x1b) << 7;
2360 e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8;
2361 e |= (s[1] & 0xc0) >> 2;
2362 e |= (s[2] & 0xc0) >> 4;
2373 wanted = ImMin(wanted, !!s[0] + !!s[1] + !!s[2] + !!s[3]);
2374 *out_char = IM_UNICODE_CODEPOINT_INVALID;
2380int ImTextStrFromUtf8(ImWchar* buf,
int buf_size,
const char* in_text,
const char* in_text_end,
const char** in_text_remaining)
2382 ImWchar* buf_out = buf;
2383 ImWchar* buf_end = buf + buf_size;
2384 while (buf_out < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text)
2388 *buf_out++ = (ImWchar)c;
2391 if (in_text_remaining)
2392 *in_text_remaining = in_text;
2393 return (
int)(buf_out - buf);
2399 while ((!in_text_end || in_text < in_text_end) && *in_text)
2409static inline int ImTextCharToUtf8_inline(
char* buf,
int buf_size,
unsigned int c)
2418 if (buf_size < 2)
return 0;
2419 buf[0] = (char)(0xc0 + (c >> 6));
2420 buf[1] = (char)(0x80 + (c & 0x3f));
2425 if (buf_size < 3)
return 0;
2426 buf[0] = (char)(0xe0 + (c >> 12));
2427 buf[1] = (char)(0x80 + ((c >> 6) & 0x3f));
2428 buf[2] = (char)(0x80 + ((c ) & 0x3f));
2433 if (buf_size < 4)
return 0;
2434 buf[0] = (char)(0xf0 + (c >> 18));
2435 buf[1] = (char)(0x80 + ((c >> 12) & 0x3f));
2436 buf[2] = (char)(0x80 + ((c >> 6) & 0x3f));
2437 buf[3] = (char)(0x80 + ((c ) & 0x3f));
2446 int count = ImTextCharToUtf8_inline(out_buf, 5, c);
2454 unsigned int unused = 0;
2460 if (c < 0x80)
return 1;
2461 if (c < 0x800)
return 2;
2462 if (c < 0x10000)
return 3;
2463 if (c <= 0x10FFFF)
return 4;
2467int ImTextStrToUtf8(
char* out_buf,
int out_buf_size,
const ImWchar* in_text,
const ImWchar* in_text_end)
2469 char* buf_p = out_buf;
2470 const char* buf_end = out_buf + out_buf_size;
2471 while (buf_p < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text)
2473 unsigned int c = (
unsigned int)(*in_text++);
2477 buf_p += ImTextCharToUtf8_inline(buf_p, (
int)(buf_end - buf_p - 1), c);
2480 return (
int)(buf_p - out_buf);
2485 int bytes_count = 0;
2486 while ((!in_text_end || in_text < in_text_end) && *in_text)
2488 unsigned int c = (
unsigned int)(*in_text++);
2499 while (in_text_curr > in_text_start)
2502 if ((*in_text_curr & 0xC0) != 0x80)
2503 return in_text_curr;
2505 return in_text_start;
2510 if (in_text_end == NULL)
2511 in_text_end = in_text + strlen(in_text);
2513 while (in_text < in_text_end)
2515 const char* line_end = (
const char*)memchr(in_text,
'\n', in_text_end - in_text);
2516 in_text = line_end ? line_end + 1 : in_text_end;
2522IM_MSVC_RUNTIME_CHECKS_RESTORE
2531 float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f;
2532 int r = ImLerp((
int)(col_a >> IM_COL32_R_SHIFT) & 0xFF, (
int)(col_b >> IM_COL32_R_SHIFT) & 0xFF,
t);
2533 int g = ImLerp((
int)(col_a >> IM_COL32_G_SHIFT) & 0xFF, (
int)(col_b >> IM_COL32_G_SHIFT) & 0xFF,
t);
2534 int b = ImLerp((
int)(col_a >> IM_COL32_B_SHIFT) & 0xFF, (
int)(col_b >> IM_COL32_B_SHIFT) & 0xFF,
t);
2535 return IM_COL32(r,
g, b, 0xFF);
2538ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in)
2540 float s = 1.0f / 255.0f;
2542 ((in >> IM_COL32_R_SHIFT) & 0xFF) * s,
2543 ((in >> IM_COL32_G_SHIFT) & 0xFF) * s,
2544 ((in >> IM_COL32_B_SHIFT) & 0xFF) * s,
2545 ((in >> IM_COL32_A_SHIFT) & 0xFF) * s);
2548ImU32 ImGui::ColorConvertFloat4ToU32(
const ImVec4& in)
2551 out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)) << IM_COL32_R_SHIFT;
2552 out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << IM_COL32_G_SHIFT;
2553 out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << IM_COL32_B_SHIFT;
2554 out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << IM_COL32_A_SHIFT;
2560void ImGui::ColorConvertRGBtoHSV(
float r,
float g,
float b,
float& out_h,
float& out_s,
float& out_v)
2574 const float chroma = r - (
g < b ?
g : b);
2575 out_h = ImFabs(K + (
g - b) / (6.f * chroma + 1e-20f));
2576 out_s = chroma / (r + 1e-20f);
2582void ImGui::ColorConvertHSVtoRGB(
float h,
float s,
float v,
float& out_r,
float& out_g,
float& out_b)
2587 out_r = out_g = out_b = v;
2591 h = ImFmod(h, 1.0f) / (60.0f / 360.0f);
2593 float f = h - (float)i;
2594 float p = v * (1.0f - s);
2595 float q = v * (1.0f - s * f);
2596 float t = v * (1.0f - s * (1.0f - f));
2600 case 0: out_r = v; out_g =
t; out_b = p;
break;
2601 case 1: out_r = q; out_g = v; out_b = p;
break;
2602 case 2: out_r = p; out_g = v; out_b =
t;
break;
2603 case 3: out_r = p; out_g = q; out_b = v;
break;
2604 case 4: out_r =
t; out_g = p; out_b = v;
break;
2605 case 5:
default: out_r = v; out_g = p; out_b = q;
break;
2615ImGuiStoragePair*
ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key)
2617 ImGuiStoragePair* in_p = in_begin;
2618 for (
size_t count = (
size_t)(in_end - in_p); count > 0; )
2620 size_t count2 = count >> 1;
2621 ImGuiStoragePair* mid = in_p + count2;
2625 count -= count2 + 1;
2635IM_MSVC_RUNTIME_CHECKS_OFF
2636static int IMGUI_CDECL PairComparerByID(
const void* lhs,
const void* rhs)
2639 ImGuiID lhs_v = ((
const ImGuiStoragePair*)lhs)->key;
2640 ImGuiID rhs_v = ((
const ImGuiStoragePair*)rhs)->key;
2641 return (lhs_v > rhs_v ? +1 : lhs_v < rhs_v ? -1 : 0);
2645void ImGuiStorage::BuildSortByKey()
2647 ImQsort(Data.Data, (
size_t)Data.Size,
sizeof(ImGuiStoragePair), PairComparerByID);
2650int ImGuiStorage::GetInt(ImGuiID key,
int default_val)
const
2652 ImGuiStoragePair* it =
ImLowerBound(
const_cast<ImGuiStoragePair*
>(Data.Data),
const_cast<ImGuiStoragePair*
>(Data.Data + Data.Size), key);
2653 if (it == Data.Data + Data.Size || it->key != key)
2658bool ImGuiStorage::GetBool(ImGuiID key,
bool default_val)
const
2660 return GetInt(key, default_val ? 1 : 0) != 0;
2663float ImGuiStorage::GetFloat(ImGuiID key,
float default_val)
const
2665 ImGuiStoragePair* it =
ImLowerBound(
const_cast<ImGuiStoragePair*
>(Data.Data),
const_cast<ImGuiStoragePair*
>(Data.Data + Data.Size), key);
2666 if (it == Data.Data + Data.Size || it->key != key)
2671void* ImGuiStorage::GetVoidPtr(ImGuiID key)
const
2673 ImGuiStoragePair* it =
ImLowerBound(
const_cast<ImGuiStoragePair*
>(Data.Data),
const_cast<ImGuiStoragePair*
>(Data.Data + Data.Size), key);
2674 if (it == Data.Data + Data.Size || it->key != key)
2680int* ImGuiStorage::GetIntRef(ImGuiID key,
int default_val)
2682 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2683 if (it == Data.Data + Data.Size || it->key != key)
2684 it = Data.insert(it, ImGuiStoragePair(key, default_val));
2688bool* ImGuiStorage::GetBoolRef(ImGuiID key,
bool default_val)
2690 return (
bool*)GetIntRef(key, default_val ? 1 : 0);
2693float* ImGuiStorage::GetFloatRef(ImGuiID key,
float default_val)
2695 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2696 if (it == Data.Data + Data.Size || it->key != key)
2697 it = Data.insert(it, ImGuiStoragePair(key, default_val));
2701void** ImGuiStorage::GetVoidPtrRef(ImGuiID key,
void* default_val)
2703 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2704 if (it == Data.Data + Data.Size || it->key != key)
2705 it = Data.insert(it, ImGuiStoragePair(key, default_val));
2710void ImGuiStorage::SetInt(ImGuiID key,
int val)
2712 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2713 if (it == Data.Data + Data.Size || it->key != key)
2714 Data.insert(it, ImGuiStoragePair(key, val));
2719void ImGuiStorage::SetBool(ImGuiID key,
bool val)
2721 SetInt(key, val ? 1 : 0);
2724void ImGuiStorage::SetFloat(ImGuiID key,
float val)
2726 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2727 if (it == Data.Data + Data.Size || it->key != key)
2728 Data.insert(it, ImGuiStoragePair(key, val));
2733void ImGuiStorage::SetVoidPtr(ImGuiID key,
void* val)
2735 ImGuiStoragePair* it =
ImLowerBound(Data.Data, Data.Data + Data.Size, key);
2736 if (it == Data.Data + Data.Size || it->key != key)
2737 Data.insert(it, ImGuiStoragePair(key, val));
2742void ImGuiStorage::SetAllInt(
int v)
2744 for (
int i = 0; i < Data.Size; i++)
2747IM_MSVC_RUNTIME_CHECKS_RESTORE
2754ImGuiTextFilter::ImGuiTextFilter(
const char* default_filter)
2760 ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf));
2765bool ImGuiTextFilter::Draw(
const char* label,
float width)
2768 ImGui::SetNextItemWidth(width);
2769 bool value_changed = ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf));
2772 return value_changed;
2775void ImGuiTextFilter::ImGuiTextRange::split(
char separator, ImVector<ImGuiTextRange>* out)
const
2779 const char* we = wb;
2782 if (*we == separator)
2784 out->push_back(ImGuiTextRange(wb, we));
2790 out->push_back(ImGuiTextRange(wb, we));
2793void ImGuiTextFilter::Build()
2796 ImGuiTextRange input_range(InputBuf, InputBuf + strlen(InputBuf));
2797 input_range.split(
',', &Filters);
2800 for (ImGuiTextRange& f : Filters)
2802 while (f.b < f.e && ImCharIsBlankA(f.b[0]))
2804 while (f.e > f.b && ImCharIsBlankA(f.e[-1]))
2813bool ImGuiTextFilter::PassFilter(
const char* text,
const char* text_end)
const
2815 if (Filters.Size == 0)
2819 text = text_end =
"";
2821 for (
const ImGuiTextRange& f : Filters)
2828 if (
ImStristr(text, text_end, f.b + 1, f.e) != NULL)
2834 if (
ImStristr(text, text_end, f.b, f.e) != NULL)
2853#if defined(__GNUC__) || defined(__clang__)
2854#define va_copy(dest, src) __builtin_va_copy(dest, src)
2856#define va_copy(dest, src) (dest = src)
2860char ImGuiTextBuffer::EmptyString[1] = { 0 };
2862void ImGuiTextBuffer::append(
const char* str,
const char* str_end)
2864 int len = str_end ? (int)(str_end - str) : (int)strlen(str);
2867 const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
2868 const int needed_sz = write_off + len;
2869 if (write_off + len >= Buf.Capacity)
2871 int new_capacity = Buf.Capacity * 2;
2872 Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity);
2875 Buf.resize(needed_sz);
2876 memcpy(&Buf[write_off - 1], str, (
size_t)len);
2877 Buf[write_off - 1 + len] = 0;
2880void ImGuiTextBuffer::appendf(
const char* fmt, ...)
2883 va_start(args, fmt);
2884 appendfv(fmt, args);
2889void ImGuiTextBuffer::appendfv(
const char* fmt, va_list args)
2902 const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
2903 const int needed_sz = write_off + len;
2904 if (write_off + len >= Buf.Capacity)
2906 int new_capacity = Buf.Capacity * 2;
2907 Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity);
2910 Buf.resize(needed_sz);
2911 ImFormatStringV(&Buf[write_off - 1], (
size_t)len + 1, fmt, args_copy);
2915void ImGuiTextIndex::append(
const char* base,
int old_size,
int new_size)
2917 IM_ASSERT(old_size >= 0 && new_size >= old_size && new_size >= EndOffset);
2918 if (old_size == new_size)
2920 if (EndOffset == 0 || base[EndOffset - 1] ==
'\n')
2921 LineOffsets.push_back(EndOffset);
2922 const char* base_end = base + new_size;
2923 for (
const char* p = base + old_size; (p = (
const char*)memchr(p,
'\n', base_end - p)) != 0; )
2925 LineOffsets.push_back((
int)(intptr_t)(p - base));
2926 EndOffset = ImMax(EndOffset, new_size);
2935static bool GetSkipItemForListClipping()
2938 return (
g.CurrentTable ?
g.CurrentTable->HostSkipItems :
g.CurrentWindow->SkipItems);
2941static void ImGuiListClipper_SortAndFuseRanges(ImVector<ImGuiListClipperRange>&
ranges,
int offset = 0)
2943 if (
ranges.Size - offset <= 1)
2947 for (
int sort_end =
ranges.Size - offset - 1; sort_end > 0; --sort_end)
2948 for (
int i = offset; i < sort_end + offset; ++i)
2953 for (
int i = 1 + offset; i <
ranges.Size; i++)
2955 IM_ASSERT(!
ranges[i].PosToIndexConvert && !
ranges[i - 1].PosToIndexConvert);
2965static void ImGuiListClipper_SeekCursorAndSetupPrevLine(
float pos_y,
float line_height)
2971 ImGuiWindow* window =
g.CurrentWindow;
2972 float off_y = pos_y - window->DC.CursorPos.y;
2973 window->DC.CursorPos.y = pos_y;
2974 window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y -
g.Style.ItemSpacing.y);
2975 window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height;
2976 window->DC.PrevLineSize.y = (line_height -
g.Style.ItemSpacing.y);
2977 if (ImGuiOldColumns* columns = window->DC.CurrentColumns)
2978 columns->LineMinY = window->DC.CursorPos.y;
2979 if (ImGuiTable* table =
g.CurrentTable)
2981 if (table->IsInsideRow)
2982 ImGui::TableEndRow(table);
2983 table->RowPosY2 = window->DC.CursorPos.y;
2984 const int row_increase = (int)((off_y / line_height) + 0.5f);
2986 table->RowBgColorCounter += row_increase;
2990ImGuiListClipper::ImGuiListClipper()
2992 memset(
this, 0,
sizeof(*
this));
2995ImGuiListClipper::~ImGuiListClipper()
3000void ImGuiListClipper::Begin(
int items_count,
float items_height)
3003 Ctx = ImGui::GetCurrentContext();
3005 ImGuiContext&
g = *Ctx;
3006 ImGuiWindow* window =
g.CurrentWindow;
3007 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Begin(%d,%.2f) in '%s'\n", items_count, items_height, window->Name);
3009 if (ImGuiTable* table =
g.CurrentTable)
3010 if (table->IsInsideRow)
3011 ImGui::TableEndRow(table);
3013 StartPosY = window->DC.CursorPos.y;
3014 ItemsHeight = items_height;
3015 ItemsCount = items_count;
3020 if (++
g.ClipperTempDataStacked >
g.ClipperTempData.Size)
3021 g.ClipperTempData.resize(
g.ClipperTempDataStacked, ImGuiListClipperData());
3022 ImGuiListClipperData* data = &
g.ClipperTempData[
g.ClipperTempDataStacked - 1];
3024 data->LossynessOffset = window->DC.CursorStartPosLossyness.y;
3026 StartSeekOffsetY = data->LossynessOffset;
3029void ImGuiListClipper::End()
3031 if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
3034 ImGuiContext&
g = *Ctx;
3035 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: End() in '%s'\n",
g.CurrentWindow->Name);
3036 if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
3037 SeekCursorForItem(ItemsCount);
3040 IM_ASSERT(data->ListClipper ==
this);
3041 data->StepNo = data->Ranges.Size;
3042 if (--
g.ClipperTempDataStacked > 0)
3044 data = &
g.ClipperTempData[
g.ClipperTempDataStacked - 1];
3045 data->ListClipper->TempData = data;
3052void ImGuiListClipper::IncludeItemsByIndex(
int item_begin,
int item_end)
3054 ImGuiListClipperData* data = (ImGuiListClipperData*)TempData;
3055 IM_ASSERT(DisplayStart < 0);
3056 IM_ASSERT(item_begin <= item_end);
3057 if (item_begin < item_end)
3058 data->Ranges.push_back(ImGuiListClipperRange::FromIndices(item_begin, item_end));
3063void ImGuiListClipper::SeekCursorForItem(
int item_n)
3068 float pos_y = (float)((
double)StartPosY + StartSeekOffsetY + (double)item_n * ItemsHeight);
3069 ImGuiListClipper_SeekCursorAndSetupPrevLine(pos_y, ItemsHeight);
3072static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
3074 ImGuiContext&
g = *clipper->Ctx;
3075 ImGuiWindow* window =
g.CurrentWindow;
3076 ImGuiListClipperData* data = (ImGuiListClipperData*)clipper->TempData;
3077 IM_ASSERT(data != NULL &&
"Called ImGuiListClipper::Step() too many times, or before ImGuiListClipper::Begin() ?");
3079 ImGuiTable* table =
g.CurrentTable;
3080 if (table && table->IsInsideRow)
3081 ImGui::TableEndRow(table);
3084 if (clipper->ItemsCount == 0 || GetSkipItemForListClipping())
3089 if (data->StepNo == 0 && table != NULL && !table->IsUnfrozenRows)
3091 clipper->DisplayStart = data->ItemsFrozen;
3092 clipper->DisplayEnd = ImMin(data->ItemsFrozen + 1, clipper->ItemsCount);
3093 if (clipper->DisplayStart < clipper->DisplayEnd)
3094 data->ItemsFrozen++;
3099 bool calc_clipping =
false;
3100 if (data->StepNo == 0)
3102 clipper->StartPosY = window->DC.CursorPos.y;
3103 if (clipper->ItemsHeight <= 0.0f)
3106 data->Ranges.push_front(ImGuiListClipperRange::FromIndices(data->ItemsFrozen, data->ItemsFrozen + 1));
3107 clipper->DisplayStart = ImMax(data->Ranges[0].Min, data->ItemsFrozen);
3108 clipper->DisplayEnd = ImMin(data->Ranges[0].Max, clipper->ItemsCount);
3112 calc_clipping =
true;
3116 if (clipper->ItemsHeight <= 0.0f)
3118 IM_ASSERT(data->StepNo == 1);
3120 IM_ASSERT(table->RowPosY1 == clipper->StartPosY && table->RowPosY2 == window->DC.CursorPos.y);
3122 clipper->ItemsHeight = (window->DC.CursorPos.y - clipper->StartPosY) / (
float)(clipper->DisplayEnd - clipper->DisplayStart);
3123 bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
3124 if (affected_by_floating_point_precision)
3125 clipper->ItemsHeight = window->DC.PrevLineSize.y +
g.Style.ItemSpacing.y;
3126 if (clipper->ItemsHeight == 0.0f && clipper->ItemsCount == INT_MAX)
3128 IM_ASSERT(clipper->ItemsHeight > 0.0f &&
"Unable to calculate item height! First item hasn't moved the cursor vertically!");
3129 calc_clipping =
true;
3133 const int already_submitted = clipper->DisplayEnd;
3137 clipper->StartSeekOffsetY = (double)data->LossynessOffset - data->ItemsFrozen * (
double)clipper->ItemsHeight;
3142 data->Ranges.push_back(ImGuiListClipperRange::FromIndices(0, clipper->ItemsCount));
3147 const bool is_nav_request = (
g.NavMoveScoringItems &&
g.NavWindow &&
g.NavWindow->RootWindowForNav == window->RootWindowForNav);
3149 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(
g.NavScoringNoClipRect.Min.y,
g.NavScoringNoClipRect.Max.y, 0, 0));
3150 if (is_nav_request && (
g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) &&
g.NavTabbingDir == -1)
3151 data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount));
3154 ImRect nav_rect_abs = ImGui::WindowRectRelToAbs(window, window->NavRectRel[0]);
3155 if (
g.NavId != 0 && window->NavLastIds[0] ==
g.NavId)
3156 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(nav_rect_abs.Min.y, nav_rect_abs.Max.y, 0, 0));
3159 float min_y = window->ClipRect.Min.y;
3160 float max_y = window->ClipRect.Max.y;
3163 ImGuiBoxSelectState* bs = &
g.BoxSelectState;
3164 if (bs->IsActive && bs->Window == window)
3169 min_y -=
g.Style.ItemSpacing.y;
3170 max_y +=
g.Style.ItemSpacing.y;
3174 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(bs->UnclipRect.Min.y, bs->UnclipRect.Max.y, 0, 0));
3177 const int off_min = (is_nav_request &&
g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0;
3178 const int off_max = (is_nav_request &&
g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0;
3179 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, off_min, off_max));
3186 for (ImGuiListClipperRange& range : data->Ranges)
3187 if (range.PosToIndexConvert)
3189 int m1 = (int)(((
double)range.Min - window->DC.CursorPos.y - data->LossynessOffset) / clipper->ItemsHeight);
3190 int m2 = (int)((((
double)range.Max - window->DC.CursorPos.y - data->LossynessOffset) / clipper->ItemsHeight) + 0.999999f);
3191 range.Min = ImClamp(already_submitted + m1 + range.PosToIndexOffsetMin, already_submitted, clipper->ItemsCount - 1);
3192 range.Max = ImClamp(already_submitted + m2 + range.PosToIndexOffsetMax, range.Min + 1, clipper->ItemsCount);
3193 range.PosToIndexConvert =
false;
3195 ImGuiListClipper_SortAndFuseRanges(data->Ranges, data->StepNo);
3199 while (data->StepNo < data->Ranges.Size)
3201 clipper->DisplayStart = ImMax(data->Ranges[data->StepNo].Min, already_submitted);
3202 clipper->DisplayEnd = ImMin(data->Ranges[data->StepNo].Max, clipper->ItemsCount);
3203 if (clipper->DisplayStart > already_submitted)
3204 clipper->SeekCursorForItem(clipper->DisplayStart);
3206 if (clipper->DisplayStart == clipper->DisplayEnd && data->StepNo < data->Ranges.Size)
3213 if (clipper->ItemsCount < INT_MAX)
3214 clipper->SeekCursorForItem(clipper->ItemsCount);
3219bool ImGuiListClipper::Step()
3221 ImGuiContext&
g = *Ctx;
3222 bool need_items_height = (ItemsHeight <= 0.0f);
3223 bool ret = ImGuiListClipper_StepInternal(
this);
3224 if (ret && (DisplayStart == DisplayEnd))
3226 if (
g.CurrentTable &&
g.CurrentTable->IsUnfrozenRows ==
false)
3227 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): inside frozen table row.\n");
3228 if (need_items_height && ItemsHeight > 0.0f)
3229 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): computed ItemsHeight: %.2f.\n", ItemsHeight);
3232 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): display %d to %d.\n", DisplayStart, DisplayEnd);
3236 IMGUI_DEBUG_LOG_CLIPPER(
"Clipper: Step(): End.\n");
3246ImGuiStyle& ImGui::GetStyle()
3248 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
3252ImU32 ImGui::GetColorU32(ImGuiCol idx,
float alpha_mul)
3254 ImGuiStyle& style =
GImGui->Style;
3255 ImVec4 c = style.Colors[idx];
3256 c.w *= style.Alpha * alpha_mul;
3257 return ColorConvertFloat4ToU32(c);
3260ImU32 ImGui::GetColorU32(
const ImVec4& col)
3262 ImGuiStyle& style =
GImGui->Style;
3265 return ColorConvertFloat4ToU32(c);
3268const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx)
3270 ImGuiStyle& style =
GImGui->Style;
3271 return style.Colors[idx];
3274ImU32 ImGui::GetColorU32(ImU32 col,
float alpha_mul)
3276 ImGuiStyle& style =
GImGui->Style;
3277 alpha_mul *= style.Alpha;
3278 if (alpha_mul >= 1.0f)
3280 ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT;
3281 a = (ImU32)(a * alpha_mul);
3282 return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT);
3286void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col)
3289 ImGuiColorMod backup;
3291 backup.BackupValue =
g.Style.Colors[idx];
3292 g.ColorStack.push_back(backup);
3293 if (
g.DebugFlashStyleColorIdx != idx)
3294 g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
3297void ImGui::PushStyleColor(ImGuiCol idx,
const ImVec4& col)
3300 ImGuiColorMod backup;
3302 backup.BackupValue =
g.Style.Colors[idx];
3303 g.ColorStack.push_back(backup);
3304 if (
g.DebugFlashStyleColorIdx != idx)
3305 g.Style.Colors[idx] = col;
3308void ImGui::PopStyleColor(
int count)
3311 if (
g.ColorStack.Size < count)
3313 IM_ASSERT_USER_ERROR(
g.ColorStack.Size > count,
"Calling PopStyleColor() too many times!");
3314 count =
g.ColorStack.Size;
3318 ImGuiColorMod& backup =
g.ColorStack.back();
3319 g.Style.Colors[backup.Col] = backup.BackupValue;
3320 g.ColorStack.pop_back();
3325static const ImGuiCol GWindowDockStyleColors[ImGuiWindowDockStyleCol_COUNT] =
3327 ImGuiCol_Text, ImGuiCol_TabHovered, ImGuiCol_Tab, ImGuiCol_TabSelected, ImGuiCol_TabSelectedOverline, ImGuiCol_TabDimmed, ImGuiCol_TabDimmedSelected, ImGuiCol_TabDimmedSelectedOverline,
3330static const ImGuiDataVarInfo GStyleVarInfo[] =
3332 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, Alpha) },
3333 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) },
3334 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowPadding) },
3335 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowRounding) },
3336 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) },
3337 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowMinSize) },
3338 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) },
3339 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildRounding) },
3340 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) },
3341 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupRounding) },
3342 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) },
3343 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, FramePadding) },
3344 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameRounding) },
3345 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) },
3346 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemSpacing) },
3347 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) },
3348 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, IndentSpacing) },
3349 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, CellPadding) },
3350 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) },
3351 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) },
3352 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) },
3353 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) },
3354 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) },
3355 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBorderSize) },
3356 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) },
3357 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarOverlineSize) },
3358 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)},
3359 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},
3360 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) },
3361 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) },
3362 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)},
3363 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) },
3364 { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) },
3365 { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DockingSeparatorSize) },
3368const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx)
3370 IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT);
3372 return &GStyleVarInfo[idx];
3375void ImGui::PushStyleVar(ImGuiStyleVar idx,
float val)
3378 const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
3379 if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1)
3381 float* pvar = (
float*)var_info->GetVarPtr(&
g.Style);
3382 g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
3386 IM_ASSERT_USER_ERROR(0,
"Calling PushStyleVar() variant with wrong type!");
3389void ImGui::PushStyleVar(ImGuiStyleVar idx,
const ImVec2& val)
3392 const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
3393 if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2)
3395 ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&
g.Style);
3396 g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
3400 IM_ASSERT_USER_ERROR(0,
"Calling PushStyleVar() variant with wrong type!");
3403void ImGui::PopStyleVar(
int count)
3406 if (
g.StyleVarStack.Size < count)
3408 IM_ASSERT_USER_ERROR(
g.StyleVarStack.Size > count,
"Calling PopStyleVar() too many times!");
3409 count =
g.StyleVarStack.Size;
3414 ImGuiStyleMod& backup =
g.StyleVarStack.back();
3415 const ImGuiDataVarInfo* info = GetStyleVarInfo(backup.VarIdx);
3416 void* data = info->GetVarPtr(&
g.Style);
3417 if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((
float*)data)[0] = backup.BackupFloat[0]; }
3418 else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((
float*)data)[0] = backup.BackupFloat[0]; ((
float*)data)[1] = backup.BackupFloat[1]; }
3419 g.StyleVarStack.pop_back();
3424const char* ImGui::GetStyleColorName(ImGuiCol idx)
3429 case ImGuiCol_Text:
return "Text";
3430 case ImGuiCol_TextDisabled:
return "TextDisabled";
3431 case ImGuiCol_WindowBg:
return "WindowBg";
3432 case ImGuiCol_ChildBg:
return "ChildBg";
3433 case ImGuiCol_PopupBg:
return "PopupBg";
3434 case ImGuiCol_Border:
return "Border";
3435 case ImGuiCol_BorderShadow:
return "BorderShadow";
3436 case ImGuiCol_FrameBg:
return "FrameBg";
3437 case ImGuiCol_FrameBgHovered:
return "FrameBgHovered";
3438 case ImGuiCol_FrameBgActive:
return "FrameBgActive";
3439 case ImGuiCol_TitleBg:
return "TitleBg";
3440 case ImGuiCol_TitleBgActive:
return "TitleBgActive";
3441 case ImGuiCol_TitleBgCollapsed:
return "TitleBgCollapsed";
3442 case ImGuiCol_MenuBarBg:
return "MenuBarBg";
3443 case ImGuiCol_ScrollbarBg:
return "ScrollbarBg";
3444 case ImGuiCol_ScrollbarGrab:
return "ScrollbarGrab";
3445 case ImGuiCol_ScrollbarGrabHovered:
return "ScrollbarGrabHovered";
3446 case ImGuiCol_ScrollbarGrabActive:
return "ScrollbarGrabActive";
3447 case ImGuiCol_CheckMark:
return "CheckMark";
3448 case ImGuiCol_SliderGrab:
return "SliderGrab";
3449 case ImGuiCol_SliderGrabActive:
return "SliderGrabActive";
3450 case ImGuiCol_Button:
return "Button";
3451 case ImGuiCol_ButtonHovered:
return "ButtonHovered";
3452 case ImGuiCol_ButtonActive:
return "ButtonActive";
3453 case ImGuiCol_Header:
return "Header";
3454 case ImGuiCol_HeaderHovered:
return "HeaderHovered";
3455 case ImGuiCol_HeaderActive:
return "HeaderActive";
3456 case ImGuiCol_Separator:
return "Separator";
3457 case ImGuiCol_SeparatorHovered:
return "SeparatorHovered";
3458 case ImGuiCol_SeparatorActive:
return "SeparatorActive";
3459 case ImGuiCol_ResizeGrip:
return "ResizeGrip";
3460 case ImGuiCol_ResizeGripHovered:
return "ResizeGripHovered";
3461 case ImGuiCol_ResizeGripActive:
return "ResizeGripActive";
3462 case ImGuiCol_TabHovered:
return "TabHovered";
3463 case ImGuiCol_Tab:
return "Tab";
3464 case ImGuiCol_TabSelected:
return "TabSelected";
3465 case ImGuiCol_TabSelectedOverline:
return "TabSelectedOverline";
3466 case ImGuiCol_TabDimmed:
return "TabDimmed";
3467 case ImGuiCol_TabDimmedSelected:
return "TabDimmedSelected";
3468 case ImGuiCol_TabDimmedSelectedOverline:
return "TabDimmedSelectedOverline";
3469 case ImGuiCol_DockingPreview:
return "DockingPreview";
3470 case ImGuiCol_DockingEmptyBg:
return "DockingEmptyBg";
3471 case ImGuiCol_PlotLines:
return "PlotLines";
3472 case ImGuiCol_PlotLinesHovered:
return "PlotLinesHovered";
3473 case ImGuiCol_PlotHistogram:
return "PlotHistogram";
3474 case ImGuiCol_PlotHistogramHovered:
return "PlotHistogramHovered";
3475 case ImGuiCol_TableHeaderBg:
return "TableHeaderBg";
3476 case ImGuiCol_TableBorderStrong:
return "TableBorderStrong";
3477 case ImGuiCol_TableBorderLight:
return "TableBorderLight";
3478 case ImGuiCol_TableRowBg:
return "TableRowBg";
3479 case ImGuiCol_TableRowBgAlt:
return "TableRowBgAlt";
3480 case ImGuiCol_TextLink:
return "TextLink";
3481 case ImGuiCol_TextSelectedBg:
return "TextSelectedBg";
3482 case ImGuiCol_DragDropTarget:
return "DragDropTarget";
3483 case ImGuiCol_NavHighlight:
return "NavHighlight";
3484 case ImGuiCol_NavWindowingHighlight:
return "NavWindowingHighlight";
3485 case ImGuiCol_NavWindowingDimBg:
return "NavWindowingDimBg";
3486 case ImGuiCol_ModalWindowDimBg:
return "ModalWindowDimBg";
3500const char* ImGui::FindRenderedTextEnd(
const char* text,
const char* text_end)
3502 const char* text_display_end = text;
3504 text_end = (
const char*)-1;
3506 while (text_display_end < text_end && *text_display_end !=
'\0' && (text_display_end[0] !=
'#' || text_display_end[1] !=
'#'))
3508 return text_display_end;
3513void ImGui::RenderText(ImVec2 pos,
const char* text,
const char* text_end,
bool hide_text_after_hash)
3516 ImGuiWindow* window =
g.CurrentWindow;
3519 const char* text_display_end;
3520 if (hide_text_after_hash)
3522 text_display_end = FindRenderedTextEnd(text, text_end);
3527 text_end = text + strlen(text);
3528 text_display_end = text_end;
3531 if (text != text_display_end)
3533 window->DrawList->AddText(
g.Font,
g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
3535 LogRenderedText(&pos, text, text_display_end);
3539void ImGui::RenderTextWrapped(ImVec2 pos,
const char* text,
const char* text_end,
float wrap_width)
3542 ImGuiWindow* window =
g.CurrentWindow;
3545 text_end = text + strlen(text);
3547 if (text != text_end)
3549 window->DrawList->AddText(
g.Font,
g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
3551 LogRenderedText(&pos, text, text_end);
3560void 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)
3563 ImVec2 pos = pos_min;
3564 const ImVec2 text_size = text_size_if_known ? *text_size_if_known :
CalcTextSize(text, text_display_end,
false, 0.0f);
3566 const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
3567 const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
3568 bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
3570 need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y);
3573 if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x);
3574 if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y);
3579 ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
3580 draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect);
3584 draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL);
3588void 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)
3591 const char* text_display_end = FindRenderedTextEnd(text, text_end);
3592 const int text_len = (int)(text_display_end - text);
3597 ImGuiWindow* window =
g.CurrentWindow;
3598 RenderTextClippedEx(window->DrawList, pos_min, pos_max, text, text_display_end, text_size_if_known, align, clip_rect);
3600 LogRenderedText(&pos_min, text, text_display_end);
3606void 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)
3609 if (text_end_full == NULL)
3610 text_end_full = FindRenderedTextEnd(text);
3611 const ImVec2 text_size = text_size_if_known ? *text_size_if_known :
CalcTextSize(text, text_end_full,
false, 0.0f);
3617 if (text_size.x > pos_max.x - pos_min.x)
3624 const ImFont* font = draw_list->_Data->Font;
3625 const float font_size = draw_list->_Data->FontSize;
3626 const float font_scale = draw_list->_Data->FontScale;
3627 const char* text_end_ellipsis = NULL;
3628 const float ellipsis_width = font->EllipsisWidth * font_scale;
3631 const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_width) - pos_min.x, 1.0f);
3632 float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
3633 if (text == text_end_ellipsis && text_end_ellipsis < text_end_full)
3637 text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x;
3639 while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1]))
3642 text_end_ellipsis--;
3643 text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x;
3647 RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
3648 ImVec2 ellipsis_pos = ImTrunc(ImVec2(pos_min.x + text_size_clipped_x, pos_min.y));
3649 if (ellipsis_pos.x + ellipsis_width <= ellipsis_max_x)
3650 for (
int i = 0; i < font->EllipsisCharCount; i++, ellipsis_pos.x += font->EllipsisCharStep * font_scale)
3651 font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar);
3655 RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_full, &text_size, ImVec2(0.0f, 0.0f));
3659 LogRenderedText(&pos_min, text, text_end_full);
3663void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col,
bool border,
float rounding)
3666 ImGuiWindow* window =
g.CurrentWindow;
3667 window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding);
3668 const float border_size =
g.Style.FrameBorderSize;
3669 if (border && border_size > 0.0f)
3671 window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size);
3672 window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
3676void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max,
float rounding)
3679 ImGuiWindow* window =
g.CurrentWindow;
3680 const float border_size =
g.Style.FrameBorderSize;
3681 if (border_size > 0.0f)
3683 window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size);
3684 window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
3688void ImGui::RenderNavHighlight(
const ImRect& bb, ImGuiID
id, ImGuiNavHighlightFlags flags)
3693 if (
g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw))
3695 ImGuiWindow* window =
g.CurrentWindow;
3696 if (window->DC.NavHideHighlightOneFrame)
3699 float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f :
g.Style.FrameRounding;
3700 ImRect display_rect = bb;
3701 display_rect.ClipWith(window->ClipRect);
3702 const float thickness = 2.0f;
3703 if (flags & ImGuiNavHighlightFlags_Compact)
3705 window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, 0, thickness);
3709 const float distance = 3.0f + thickness * 0.5f;
3710 display_rect.Expand(ImVec2(distance, distance));
3711 bool fully_visible = window->ClipRect.Contains(display_rect);
3713 window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
3714 window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, 0, thickness);
3716 window->DrawList->PopClipRect();
3720void ImGui::RenderMouseCursor(ImVec2 base_pos,
float base_scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow)
3723 IM_ASSERT(mouse_cursor > ImGuiMouseCursor_None && mouse_cursor < ImGuiMouseCursor_COUNT);
3724 ImFontAtlas* font_atlas =
g.DrawListSharedData.Font->ContainerAtlas;
3725 for (ImGuiViewportP* viewport :
g.Viewports)
3728 ImVec2 offset,
size, uv[4];
3729 if (!font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2]))
3731 const ImVec2 pos = base_pos - offset;
3732 const float scale = base_scale * viewport->DpiScale;
3733 if (!viewport->GetMainRect().Overlaps(ImRect(pos, pos + ImVec2(
size.x + 2,
size.y + 2) * scale)))
3735 ImDrawList* draw_list = GetForegroundDrawList(viewport);
3736 ImTextureID tex_id = font_atlas->TexID;
3737 draw_list->PushTextureID(tex_id);
3738 draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow);
3739 draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow);
3740 draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border);
3741 draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill);
3742 draw_list->PopTextureID();
3752ImGuiContext* ImGui::GetCurrentContext()
3757void ImGui::SetCurrentContext(ImGuiContext* ctx)
3759#ifdef IMGUI_SET_CURRENT_CONTEXT_FUNC
3760 IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx);
3766void ImGui::SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func,
void* user_data)
3768 GImAllocatorAllocFunc = alloc_func;
3769 GImAllocatorFreeFunc = free_func;
3770 GImAllocatorUserData = user_data;
3774void ImGui::GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func,
void** p_user_data)
3776 *p_alloc_func = GImAllocatorAllocFunc;
3777 *p_free_func = GImAllocatorFreeFunc;
3778 *p_user_data = GImAllocatorUserData;
3781ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas)
3783 ImGuiContext* prev_ctx = GetCurrentContext();
3784 ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas);
3785 SetCurrentContext(ctx);
3787 if (prev_ctx != NULL)
3788 SetCurrentContext(prev_ctx);
3792void ImGui::DestroyContext(ImGuiContext* ctx)
3794 ImGuiContext* prev_ctx = GetCurrentContext();
3797 SetCurrentContext(ctx);
3799 SetCurrentContext((prev_ctx != ctx) ? prev_ctx : NULL);
3804static const ImGuiLocEntry GLocalizationEntriesEnUS[] =
3806 { ImGuiLocKey_VersionStr,
"Dear ImGui " IMGUI_VERSION
" (" IM_STRINGIFY(IMGUI_VERSION_NUM)
")" },
3807 { ImGuiLocKey_TableSizeOne,
"Size column to fit###SizeOne" },
3808 { ImGuiLocKey_TableSizeAllFit,
"Size all columns to fit###SizeAll" },
3809 { ImGuiLocKey_TableSizeAllDefault,
"Size all columns to default###SizeAll" },
3810 { ImGuiLocKey_TableResetOrder,
"Reset order###ResetOrder" },
3811 { ImGuiLocKey_WindowingMainMenuBar,
"(Main menu bar)" },
3812 { ImGuiLocKey_WindowingPopup,
"(Popup)" },
3813 { ImGuiLocKey_WindowingUntitled,
"(Untitled)" },
3814 { ImGuiLocKey_CopyLink,
"Copy Link###CopyLink" },
3815 { ImGuiLocKey_DockingHideTabBar,
"Hide tab bar###HideTabBar" },
3816 { ImGuiLocKey_DockingHoldShiftToDock,
"Hold SHIFT to enable Docking window." },
3817 { ImGuiLocKey_DockingDragToUndockOrMoveNode,
"Click and drag to move or undock whole node." },
3820void ImGui::Initialize()
3823 IM_ASSERT(!
g.Initialized && !
g.SettingsLoaded);
3827 ImGuiSettingsHandler ini_handler;
3828 ini_handler.TypeName =
"Window";
3829 ini_handler.TypeHash =
ImHashStr(
"Window");
3830 ini_handler.ClearAllFn = WindowSettingsHandler_ClearAll;
3831 ini_handler.ReadOpenFn = WindowSettingsHandler_ReadOpen;
3832 ini_handler.ReadLineFn = WindowSettingsHandler_ReadLine;
3833 ini_handler.ApplyAllFn = WindowSettingsHandler_ApplyAll;
3834 ini_handler.WriteAllFn = WindowSettingsHandler_WriteAll;
3835 AddSettingsHandler(&ini_handler);
3837 TableSettingsAddSettingsHandler();
3840 LocalizeRegisterEntries(GLocalizationEntriesEnUS, IM_ARRAYSIZE(GLocalizationEntriesEnUS));
3843 g.IO.GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;
3844 g.IO.SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
3845 g.IO.ClipboardUserData = (
void*)&
g;
3846 g.IO.PlatformOpenInShellFn = PlatformOpenInShellFn_DefaultImpl;
3847 g.IO.PlatformSetImeDataFn = PlatformSetImeDataFn_DefaultImpl;
3850 ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)();
3853 viewport->PlatformWindowCreated =
true;
3854 viewport->Flags = ImGuiViewportFlags_OwnedByApp;
3855 g.Viewports.push_back(viewport);
3856 g.TempBuffer.resize(1024 * 3 + 1, 0);
3857 g.ViewportCreatedCount++;
3858 g.PlatformIO.Viewports.push_back(
g.Viewports[0]);
3861 for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
3862 if ((key >= ImGuiKey_0 && key <= ImGuiKey_9) || (key >= ImGuiKey_A && key <= ImGuiKey_Z) || (key >= ImGuiKey_Keypad0 && key <= ImGuiKey_Keypad9)
3863 || key == ImGuiKey_Tab || key == ImGuiKey_Space || key == ImGuiKey_Apostrophe || key == ImGuiKey_Comma || key == ImGuiKey_Minus || key == ImGuiKey_Period
3864 || key == ImGuiKey_Slash || key == ImGuiKey_Semicolon || key == ImGuiKey_Equal || key == ImGuiKey_LeftBracket || key == ImGuiKey_RightBracket || key == ImGuiKey_GraveAccent
3865 || key == ImGuiKey_KeypadDecimal || key == ImGuiKey_KeypadDivide || key == ImGuiKey_KeypadMultiply || key == ImGuiKey_KeypadSubtract || key == ImGuiKey_KeypadAdd || key == ImGuiKey_KeypadEqual)
3866 g.KeysMayBeCharInput.SetBit(key);
3868#ifdef IMGUI_HAS_DOCK
3870 DockContextInitialize(&
g);
3873 g.Initialized =
true;
3877void ImGui::Shutdown()
3880 IM_ASSERT_USER_ERROR(
g.IO.BackendPlatformUserData == NULL,
"Forgot to shutdown Platform backend?");
3881 IM_ASSERT_USER_ERROR(
g.IO.BackendRendererUserData == NULL,
"Forgot to shutdown Renderer backend?");
3884 if (
g.IO.Fonts &&
g.FontAtlasOwnedByContext)
3886 g.IO.Fonts->Locked =
false;
3887 IM_DELETE(
g.IO.Fonts);
3890 g.DrawListSharedData.TempBuffer.clear();
3897 if (
g.SettingsLoaded &&
g.IO.IniFilename != NULL)
3898 SaveIniSettingsToDisk(
g.IO.IniFilename);
3901 DestroyPlatformWindows();
3904 DockContextShutdown(&
g);
3906 CallContextHooks(&
g, ImGuiContextHookType_Shutdown);
3909 g.Windows.clear_delete();
3910 g.WindowsFocusOrder.clear();
3911 g.WindowsTempSortBuffer.clear();
3912 g.CurrentWindow = NULL;
3913 g.CurrentWindowStack.clear();
3914 g.WindowsById.Clear();
3916 g.HoveredWindow =
g.HoveredWindowUnderMovingWindow = NULL;
3917 g.ActiveIdWindow =
g.ActiveIdPreviousFrameWindow = NULL;
3918 g.MovingWindow = NULL;
3920 g.KeysRoutingTable.Clear();
3922 g.ColorStack.clear();
3923 g.StyleVarStack.clear();
3924 g.FontStack.clear();
3925 g.OpenPopupStack.clear();
3926 g.BeginPopupStack.clear();
3927 g.TreeNodeStack.clear();
3929 g.CurrentViewport =
g.MouseViewport =
g.MouseLastHoveredViewport = NULL;
3930 g.Viewports.clear_delete();
3933 g.CurrentTabBarStack.clear();
3934 g.ShrinkWidthBuffer.clear();
3936 g.ClipperTempData.clear_destruct();
3939 g.TablesTempData.clear_destruct();
3940 g.DrawChannelsTempMergeBuffer.clear();
3942 g.MultiSelectStorage.Clear();
3943 g.MultiSelectTempData.clear_destruct();
3945 g.ClipboardHandlerData.clear();
3946 g.MenusIdSubmittedThisFrame.clear();
3947 g.InputTextState.ClearFreeMemory();
3948 g.InputTextDeactivatedState.ClearFreeMemory();
3950 g.SettingsWindows.clear();
3951 g.SettingsHandlers.clear();
3955#ifndef IMGUI_DISABLE_TTY_FUNCTIONS
3956 if (
g.LogFile != stdout)
3961 g.LogBuffer.clear();
3962 g.DebugLogBuf.clear();
3963 g.DebugLogIndex.clear();
3965 g.Initialized =
false;
3969ImGuiID ImGui::AddContextHook(ImGuiContext* ctx,
const ImGuiContextHook* hook)
3971 ImGuiContext&
g = *ctx;
3972 IM_ASSERT(hook->Callback != NULL && hook->HookId == 0 && hook->Type != ImGuiContextHookType_PendingRemoval_);
3973 g.Hooks.push_back(*hook);
3974 g.Hooks.back().HookId = ++
g.HookIdNext;
3975 return g.HookIdNext;
3979void ImGui::RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_id)
3981 ImGuiContext&
g = *ctx;
3982 IM_ASSERT(hook_id != 0);
3983 for (ImGuiContextHook& hook :
g.Hooks)
3984 if (hook.HookId == hook_id)
3985 hook.Type = ImGuiContextHookType_PendingRemoval_;
3990void ImGui::CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType hook_type)
3992 ImGuiContext&
g = *ctx;
3993 for (ImGuiContextHook& hook :
g.Hooks)
3994 if (hook.Type == hook_type)
3995 hook.Callback(&
g, &hook);
4004ImGuiWindow::ImGuiWindow(ImGuiContext* ctx,
const char* name) : DrawListInst(NULL)
4006 memset(
this, 0,
sizeof(*
this));
4009 NameBufLen = (int)strlen(name) + 1;
4011 IDStack.push_back(ID);
4012 ViewportAllowPlatformMonitorExtend = -1;
4013 ViewportPos = ImVec2(FLT_MAX, FLT_MAX);
4014 MoveId = GetID(
"#MOVE");
4015 TabId = GetID(
"#TAB");
4016 ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
4017 ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
4018 AutoFitFramesX = AutoFitFramesY = -1;
4019 AutoPosLastDirection = ImGuiDir_None;
4020 SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = 0;
4021 SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
4022 LastFrameActive = -1;
4023 LastFrameJustFocused = -1;
4024 LastTimeActive = -1.0f;
4025 FontWindowScale = FontDpiScale = 1.0f;
4026 SettingsOffset = -1;
4028 DrawList = &DrawListInst;
4029 DrawList->_Data = &Ctx->DrawListSharedData;
4030 DrawList->_OwnerName = Name;
4031 NavPreferredScoringPosRel[0] = NavPreferredScoringPosRel[1] = ImVec2(FLT_MAX, FLT_MAX);
4032 IM_PLACEMENT_NEW(&WindowClass) ImGuiWindowClass();
4035ImGuiWindow::~ImGuiWindow()
4037 IM_ASSERT(DrawList == &DrawListInst);
4039 ColumnsStorage.clear_destruct();
4042static void SetCurrentWindow(ImGuiWindow* window)
4045 g.CurrentWindow = window;
4046 g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ?
g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL;
4049 g.FontSize =
g.DrawListSharedData.FontSize = window->CalcFontSize();
4050 g.FontScale =
g.FontSize /
g.Font->FontSize;
4051 ImGui::NavUpdateCurrentWindowIsScrollPushableX();
4055void ImGui::GcCompactTransientMiscBuffers()
4058 g.ItemFlagsStack.clear();
4059 g.GroupStack.clear();
4060 g.MultiSelectTempDataStacked = 0;
4061 g.MultiSelectTempData.clear_destruct();
4062 TableGcCompactSettings();
4069void ImGui::GcCompactTransientWindowBuffers(ImGuiWindow* window)
4071 window->MemoryCompacted =
true;
4072 window->MemoryDrawListIdxCapacity = window->DrawList->IdxBuffer.Capacity;
4073 window->MemoryDrawListVtxCapacity = window->DrawList->VtxBuffer.Capacity;
4074 window->IDStack.clear();
4075 window->DrawList->_ClearFreeMemory();
4076 window->DC.ChildWindows.clear();
4077 window->DC.ItemWidthStack.clear();
4078 window->DC.TextWrapPosStack.clear();
4081void ImGui::GcAwakeTransientWindowBuffers(ImGuiWindow* window)
4085 window->MemoryCompacted =
false;
4086 window->DrawList->IdxBuffer.reserve(window->MemoryDrawListIdxCapacity);
4087 window->DrawList->VtxBuffer.reserve(window->MemoryDrawListVtxCapacity);
4088 window->MemoryDrawListIdxCapacity = window->MemoryDrawListVtxCapacity = 0;
4091void ImGui::SetActiveID(ImGuiID
id, ImGuiWindow* window)
4096 if (
g.ActiveId != 0)
4101 if (
g.MovingWindow != NULL &&
g.ActiveId ==
g.MovingWindow->MoveId)
4103 IMGUI_DEBUG_LOG_ACTIVEID(
"SetActiveID() cancel MovingWindow\n");
4104 g.MovingWindow = NULL;
4110 if (
g.InputTextState.ID ==
g.ActiveId)
4111 InputTextDeactivateHook(
g.ActiveId);
4115 g.ActiveIdIsJustActivated = (
g.ActiveId !=
id);
4116 if (
g.ActiveIdIsJustActivated)
4118 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 :
"");
4119 g.ActiveIdTimer = 0.0f;
4120 g.ActiveIdHasBeenPressedBefore =
false;
4121 g.ActiveIdHasBeenEditedBefore =
false;
4122 g.ActiveIdMouseButton = -1;
4125 g.LastActiveId =
id;
4126 g.LastActiveIdTimer = 0.0f;
4130 g.ActiveIdAllowOverlap =
false;
4131 g.ActiveIdNoClearOnFocusLoss =
false;
4132 g.ActiveIdWindow = window;
4133 g.ActiveIdHasBeenEditedThisFrame =
false;
4134 g.ActiveIdFromShortcut =
false;
4137 g.ActiveIdIsAlive =
id;
4138 g.ActiveIdSource = (
g.NavActivateId ==
id ||
g.NavJustMovedToId ==
id) ?
g.NavInputSource : ImGuiInputSource_Mouse;
4139 IM_ASSERT(
g.ActiveIdSource != ImGuiInputSource_None);
4144 g.ActiveIdUsingNavDirMask = 0x00;
4145 g.ActiveIdUsingAllKeyboardKeys =
false;
4148void ImGui::ClearActiveID()
4150 SetActiveID(0, NULL);
4153void ImGui::SetHoveredID(ImGuiID
id)
4157 g.HoveredIdAllowOverlap =
false;
4158 if (
id != 0 &&
g.HoveredIdPreviousFrame !=
id)
4159 g.HoveredIdTimer =
g.HoveredIdNotActiveTimer = 0.0f;
4162ImGuiID ImGui::GetHoveredID()
4165 return g.HoveredId ?
g.HoveredId :
g.HoveredIdPreviousFrame;
4168void ImGui::MarkItemEdited(ImGuiID
id)
4173 if (
g.LockMarkEdited > 0)
4175 if (
g.ActiveId ==
id ||
g.ActiveId == 0)
4177 g.ActiveIdHasBeenEditedThisFrame =
true;
4178 g.ActiveIdHasBeenEditedBefore =
true;
4183 IM_ASSERT(
g.DragDropActive ||
g.ActiveId ==
id ||
g.ActiveId == 0 ||
g.ActiveIdPreviousFrame ==
id || (
g.CurrentMultiSelect != NULL &&
g.BoxSelectState.IsActive));
4186 g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
4189bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags)
4195 if (ImGuiWindow* focused_root_window =
g.NavWindow->RootWindowDockTree)
4196 if (focused_root_window->WasActive && focused_root_window != window->RootWindowDockTree)
4200 bool want_inhibit =
false;
4201 if (focused_root_window->Flags & ImGuiWindowFlags_Modal)
4202 want_inhibit =
true;
4203 else if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup))
4204 want_inhibit =
true;
4208 if (!IsWindowWithinBeginStackOf(window->RootWindow, focused_root_window))
4213 if (window->Viewport !=
g.MouseViewport)
4214 if (
g.MovingWindow == NULL || window->RootWindowDockTree !=
g.MovingWindow->RootWindowDockTree)
4220static inline float CalcDelayFromHoveredFlags(ImGuiHoveredFlags flags)
4223 if (flags & ImGuiHoveredFlags_DelayNormal)
4224 return g.Style.HoverDelayNormal;
4225 if (flags & ImGuiHoveredFlags_DelayShort)
4226 return g.Style.HoverDelayShort;
4230static ImGuiHoveredFlags ApplyHoverFlagsForTooltip(ImGuiHoveredFlags user_flags, ImGuiHoveredFlags shared_flags)
4233 if (user_flags & (ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal))
4234 shared_flags &= ~(ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal);
4235 return user_flags | shared_flags;
4241bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
4244 ImGuiWindow* window =
g.CurrentWindow;
4245 IM_ASSERT((flags & ~ImGuiHoveredFlags_AllowedMaskForIsItemHovered) == 0 &&
"Invalid flags for IsItemHovered()!");
4247 if (
g.NavDisableMouseHover && !
g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride))
4249 if ((
g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
4251 if (!IsItemFocused())
4254 if (flags & ImGuiHoveredFlags_ForTooltip)
4255 flags = ApplyHoverFlagsForTooltip(flags,
g.Style.HoverFlagsForTooltipNav);
4260 ImGuiItemStatusFlags status_flags =
g.LastItemData.StatusFlags;
4261 if (!(status_flags & ImGuiItemStatusFlags_HoveredRect))
4264 if (flags & ImGuiHoveredFlags_ForTooltip)
4265 flags = ApplyHoverFlagsForTooltip(flags,
g.Style.HoverFlagsForTooltipMouse);
4267 IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy)) == 0);
4275 if (
g.HoveredWindow != window && (status_flags & ImGuiItemStatusFlags_HoveredWindow) == 0)
4276 if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByWindow) == 0)
4280 const ImGuiID
id =
g.LastItemData.ID;
4281 if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0)
4282 if (
g.ActiveId != 0 &&
g.ActiveId !=
id && !
g.ActiveIdAllowOverlap)
4283 if (
g.ActiveId != window->MoveId &&
g.ActiveId != window->TabId)
4288 if (!IsWindowContentHoverable(window, flags) && !(
g.LastItemData.InFlags & ImGuiItemFlags_NoWindowHoverableCheck))
4292 if ((
g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
4298 if (
id == window->MoveId && window->WriteAccessed)
4302 if ((
g.LastItemData.InFlags & ImGuiItemFlags_AllowOverlap) &&
id != 0)
4303 if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByItem) == 0)
4304 if (
g.HoveredIdPreviousFrame !=
g.LastItemData.ID)
4310 const float delay = CalcDelayFromHoveredFlags(flags);
4311 if (delay > 0.0f || (flags & ImGuiHoveredFlags_Stationary))
4313 ImGuiID hover_delay_id = (
g.LastItemData.ID != 0) ?
g.LastItemData.ID : window->GetIDFromRectangle(
g.LastItemData.Rect);
4314 if ((flags & ImGuiHoveredFlags_NoSharedDelay) && (
g.HoverItemDelayIdPreviousFrame != hover_delay_id))
4315 g.HoverItemDelayTimer = 0.0f;
4316 g.HoverItemDelayId = hover_delay_id;
4321 if ((flags & ImGuiHoveredFlags_Stationary) != 0 &&
g.HoverItemUnlockedStationaryId != hover_delay_id)
4324 if (
g.HoverItemDelayTimer < delay)
4337bool ImGui::ItemHoverable(
const ImRect& bb, ImGuiID
id, ImGuiItemFlags item_flags)
4340 ImGuiWindow* window =
g.CurrentWindow;
4341 if (
g.HoveredWindow != window)
4343 if (!IsMouseHoveringRect(bb.Min, bb.Max))
4346 if (
g.HoveredId != 0 &&
g.HoveredId !=
id && !
g.HoveredIdAllowOverlap)
4348 if (
g.ActiveId != 0 &&
g.ActiveId !=
id && !
g.ActiveIdAllowOverlap)
4349 if (!
g.ActiveIdFromShortcut)
4353 if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
4355 g.HoveredIdIsDisabled =
true;
4364 if (
g.DragDropActive &&
g.DragDropPayload.SourceId ==
id && !(
g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover))
4371 if (item_flags & ImGuiItemFlags_AllowOverlap)
4373 g.HoveredIdAllowOverlap =
true;
4374 if (
g.HoveredIdPreviousFrame !=
id)
4380 if (
id ==
g.LastItemData.ID && (
g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasShortcut))
4381 if (IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_DelayNormal))
4382 SetTooltip(
"%s", GetKeyChordName(
g.LastItemData.Shortcut));
4386 if (item_flags & ImGuiItemFlags_Disabled)
4389 if (
g.ActiveId ==
id &&
id != 0)
4391 g.HoveredIdIsDisabled =
true;
4395#ifndef IMGUI_DISABLE_DEBUG_TOOLS
4402 if (
g.DebugItemPickerActive &&
g.HoveredIdPreviousFrame ==
id)
4403 GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
4404 if (
g.DebugItemPickerBreakId ==
id)
4409 if (
g.NavDisableMouseHover)
4417bool ImGui::IsClippedEx(
const ImRect& bb, ImGuiID
id)
4420 ImGuiWindow* window =
g.CurrentWindow;
4421 if (!bb.Overlaps(window->ClipRect))
4422 if (
id == 0 || (
id !=
g.ActiveId &&
id !=
g.ActiveIdPreviousFrame &&
id !=
g.NavId &&
id !=
g.NavActivateId))
4423 if (!
g.ItemUnclipByLog)
4430void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags,
const ImRect& item_rect)
4433 g.LastItemData.ID = item_id;
4434 g.LastItemData.InFlags = in_flags;
4435 g.LastItemData.StatusFlags = item_flags;
4436 g.LastItemData.Rect =
g.LastItemData.NavRect = item_rect;
4439float ImGui::CalcWrapWidthForPos(
const ImVec2& pos,
float wrap_pos_x)
4441 if (wrap_pos_x < 0.0f)
4445 ImGuiWindow* window =
g.CurrentWindow;
4446 if (wrap_pos_x == 0.0f)
4453 wrap_pos_x = window->WorkRect.Max.x;
4455 else if (wrap_pos_x > 0.0f)
4457 wrap_pos_x += window->Pos.x - window->Scroll.x;
4460 return ImMax(wrap_pos_x - pos.x, 1.0f);
4464void* ImGui::MemAlloc(
size_t size)
4466 void* ptr = (*GImAllocatorAllocFunc)(
size, GImAllocatorUserData);
4467#ifndef IMGUI_DISABLE_DEBUG_TOOLS
4468 if (ImGuiContext* ctx =
GImGui)
4469 DebugAllocHook(&ctx->DebugAllocInfo, ctx->FrameCount, ptr, size);
4475void ImGui::MemFree(
void* ptr)
4477#ifndef IMGUI_DISABLE_DEBUG_TOOLS
4479 if (ImGuiContext* ctx =
GImGui)
4480 DebugAllocHook(&ctx->DebugAllocInfo, ctx->FrameCount, ptr, (
size_t)-1);
4482 return (*GImAllocatorFreeFunc)(ptr, GImAllocatorUserData);
4486void ImGui::DebugAllocHook(ImGuiDebugAllocInfo* info,
int frame_count,
void* ptr,
size_t size)
4488 ImGuiDebugAllocEntry* entry = &info->LastEntriesBuf[info->LastEntriesIdx];
4490 if (entry->FrameCount != frame_count)
4492 info->LastEntriesIdx = (info->LastEntriesIdx + 1) % IM_ARRAYSIZE(info->LastEntriesBuf);
4493 entry = &info->LastEntriesBuf[info->LastEntriesIdx];
4494 entry->FrameCount = frame_count;
4495 entry->AllocCount = entry->FreeCount = 0;
4497 if (size != (
size_t)-1)
4499 entry->AllocCount++;
4500 info->TotalAllocCount++;
4506 info->TotalFreeCount++;
4511const char* ImGui::GetClipboardText()
4514 return g.IO.GetClipboardTextFn ?
g.IO.GetClipboardTextFn(
g.IO.ClipboardUserData) :
"";
4517void ImGui::SetClipboardText(
const char* text)
4520 if (
g.IO.SetClipboardTextFn)
4521 g.IO.SetClipboardTextFn(
g.IO.ClipboardUserData, text);
4524const char* ImGui::GetVersion()
4526 return IMGUI_VERSION;
4529ImGuiIO& ImGui::GetIO()
4531 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
4535ImGuiPlatformIO& ImGui::GetPlatformIO()
4537 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext()?");
4538 return GImGui->PlatformIO;
4542ImDrawData* ImGui::GetDrawData()
4545 ImGuiViewportP* viewport =
g.Viewports[0];
4546 return viewport->DrawDataP.Valid ? &viewport->DrawDataP : NULL;
4549double ImGui::GetTime()
4554int ImGui::GetFrameCount()
4556 return GImGui->FrameCount;
4559static ImDrawList* GetViewportBgFgDrawList(ImGuiViewportP* viewport,
size_t drawlist_no,
const char* drawlist_name)
4563 IM_ASSERT(drawlist_no < IM_ARRAYSIZE(viewport->BgFgDrawLists));
4564 ImDrawList* draw_list = viewport->BgFgDrawLists[drawlist_no];
4565 if (draw_list == NULL)
4567 draw_list = IM_NEW(ImDrawList)(&
g.DrawListSharedData);
4568 draw_list->_OwnerName = drawlist_name;
4569 viewport->BgFgDrawLists[drawlist_no] = draw_list;
4573 if (viewport->BgFgDrawListsLastFrame[drawlist_no] !=
g.FrameCount)
4575 draw_list->_ResetForNewFrame();
4576 draw_list->PushTextureID(
g.IO.Fonts->TexID);
4577 draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size,
false);
4578 viewport->BgFgDrawListsLastFrame[drawlist_no] =
g.FrameCount;
4583ImDrawList* ImGui::GetBackgroundDrawList(ImGuiViewport* viewport)
4585 if (viewport == NULL)
4586 viewport =
GImGui->CurrentWindow->Viewport;
4587 return GetViewportBgFgDrawList((ImGuiViewportP*)viewport, 0,
"##Background");
4590ImDrawList* ImGui::GetForegroundDrawList(ImGuiViewport* viewport)
4592 if (viewport == NULL)
4593 viewport =
GImGui->CurrentWindow->Viewport;
4594 return GetViewportBgFgDrawList((ImGuiViewportP*)viewport, 1,
"##Foreground");
4597ImDrawListSharedData* ImGui::GetDrawListSharedData()
4599 return &
GImGui->DrawListSharedData;
4602void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
4608 FocusWindow(window);
4609 SetActiveID(window->MoveId, window);
4610 g.NavDisableHighlight =
true;
4611 g.ActiveIdClickOffset =
g.IO.MouseClickedPos[0] - window->RootWindowDockTree->Pos;
4612 g.ActiveIdNoClearOnFocusLoss =
true;
4613 SetActiveIdUsingAllKeyboardKeys();
4615 bool can_move_window =
true;
4616 if ((window->Flags & ImGuiWindowFlags_NoMove) || (window->RootWindowDockTree->Flags & ImGuiWindowFlags_NoMove))
4617 can_move_window =
false;
4618 if (ImGuiDockNode* node = window->DockNodeAsHost)
4619 if (node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove))
4620 can_move_window =
false;
4621 if (can_move_window)
4622 g.MovingWindow = window;
4626void ImGui::StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node,
bool undock)
4629 bool can_undock_node =
false;
4630 if (undock && node != NULL && node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove) == 0 && (node->MergedFlags & ImGuiDockNodeFlags_NoUndocking) == 0)
4635 ImGuiDockNode* root_node = DockNodeGetRootNode(node);
4636 if (root_node->OnlyNodeWithWindows != node || root_node->CentralNode != NULL)
4637 can_undock_node =
true;
4640 const bool clicked = IsMouseClicked(0);
4641 const bool dragging = IsMouseDragging(0);
4642 if (can_undock_node && dragging)
4643 DockContextQueueUndockNode(&
g, node);
4644 else if (!can_undock_node && (clicked || dragging) &&
g.MovingWindow != window)
4645 StartMouseMovingWindow(window);
4653void ImGui::UpdateMouseMovingWindowNewFrame()
4656 if (
g.MovingWindow != NULL)
4660 KeepAliveID(
g.ActiveId);
4661 IM_ASSERT(
g.MovingWindow &&
g.MovingWindow->RootWindowDockTree);
4662 ImGuiWindow* moving_window =
g.MovingWindow->RootWindowDockTree;
4665 const bool window_disappared = (!moving_window->WasActive && !moving_window->Active);
4666 if (
g.IO.MouseDown[0] && IsMousePosValid(&
g.IO.MousePos) && !window_disappared)
4668 ImVec2 pos =
g.IO.MousePos -
g.ActiveIdClickOffset;
4669 if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
4671 SetWindowPos(moving_window, pos, ImGuiCond_Always);
4672 if (moving_window->Viewport && moving_window->ViewportOwned)
4674 moving_window->Viewport->Pos = pos;
4675 moving_window->Viewport->UpdateWorkRect();
4678 FocusWindow(
g.MovingWindow);
4682 if (!window_disappared)
4686 if (
g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
4687 UpdateTryMergeWindowIntoHostViewport(moving_window,
g.MouseViewport);
4690 if (moving_window->Viewport && !IsDragDropPayloadBeingAccepted())
4691 g.MouseViewport = moving_window->Viewport;
4694 if (moving_window->Viewport)
4695 moving_window->Viewport->Flags &= ~ImGuiViewportFlags_NoInputs;
4698 g.MovingWindow = NULL;
4705 if (
g.ActiveIdWindow &&
g.ActiveIdWindow->MoveId ==
g.ActiveId)
4707 KeepAliveID(
g.ActiveId);
4708 if (!
g.IO.MouseDown[0])
4716void ImGui::UpdateMouseMovingWindowEndFrame()
4719 if (
g.ActiveId != 0 ||
g.HoveredId != 0)
4723 if (
g.NavWindow &&
g.NavWindow->Appearing)
4728 if (
g.IO.MouseClicked[0])
4732 ImGuiWindow* root_window =
g.HoveredWindow ?
g.HoveredWindow->RootWindow : NULL;
4733 const bool is_closed_popup = root_window && (root_window->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(root_window->PopupId, ImGuiPopupFlags_AnyPopupLevel);
4735 if (root_window != NULL && !is_closed_popup)
4737 StartMouseMovingWindow(
g.HoveredWindow);
4740 if (
g.IO.ConfigWindowsMoveFromTitleBarOnly)
4741 if (!(root_window->Flags & ImGuiWindowFlags_NoTitleBar) || root_window->DockIsActive)
4742 if (!root_window->TitleBarRect().Contains(
g.IO.MouseClickedPos[0]))
4743 g.MovingWindow = NULL;
4746 if (
g.HoveredIdIsDisabled)
4747 g.MovingWindow = NULL;
4749 else if (root_window == NULL &&
g.NavWindow != NULL)
4752 FocusWindow(NULL, ImGuiFocusRequestFlags_UnlessBelowModal);
4759 if (
g.IO.MouseClicked[1])
4763 ImGuiWindow* modal = GetTopMostPopupModal();
4764 bool hovered_window_above_modal =
g.HoveredWindow && (modal == NULL || IsWindowAbove(
g.HoveredWindow, modal));
4765 ClosePopupsOverWindow(hovered_window_above_modal ?
g.HoveredWindow : modal, true);
4771static void TranslateWindow(ImGuiWindow* window,
const ImVec2& delta)
4773 window->Pos += delta;
4774 window->ClipRect.Translate(delta);
4775 window->OuterRectClipped.Translate(delta);
4776 window->InnerRect.Translate(delta);
4777 window->DC.CursorPos += delta;
4778 window->DC.CursorStartPos += delta;
4779 window->DC.CursorMaxPos += delta;
4780 window->DC.IdealMaxPos += delta;
4783static void ScaleWindow(ImGuiWindow* window,
float scale)
4785 ImVec2 origin = window->Viewport->Pos;
4786 window->Pos = ImFloor((window->Pos - origin) * scale + origin);
4787 window->Size = ImTrunc(window->Size * scale);
4788 window->SizeFull = ImTrunc(window->SizeFull * scale);
4789 window->ContentSize = ImTrunc(window->ContentSize * scale);
4792static bool IsWindowActiveAndVisible(ImGuiWindow* window)
4794 return (window->Active) && (!window->Hidden);
4798void ImGui::UpdateHoveredWindowAndCaptureFlags()
4805 g.WindowsHoverPadding = ImMax(
g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING));
4811 bool clear_hovered_windows =
false;
4812 FindHoveredWindowEx(
g.IO.MousePos,
false, &
g.HoveredWindow, &
g.HoveredWindowUnderMovingWindow);
4813 IM_ASSERT(
g.HoveredWindow == NULL ||
g.HoveredWindow ==
g.MovingWindow ||
g.HoveredWindow->Viewport ==
g.MouseViewport);
4814 g.HoveredWindowBeforeClear =
g.HoveredWindow;
4817 ImGuiWindow* modal_window = GetTopMostPopupModal();
4818 if (modal_window &&
g.HoveredWindow && !IsWindowWithinBeginStackOf(
g.HoveredWindow->RootWindow, modal_window))
4819 clear_hovered_windows =
true;
4822 if (io.ConfigFlags & ImGuiConfigFlags_NoMouse)
4823 clear_hovered_windows =
true;
4827 const bool has_open_popup = (
g.OpenPopupStack.Size > 0);
4828 const bool has_open_modal = (modal_window != NULL);
4829 int mouse_earliest_down = -1;
4830 bool mouse_any_down =
false;
4831 for (
int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
4833 if (io.MouseClicked[i])
4835 io.MouseDownOwned[i] = (
g.HoveredWindow != NULL) || has_open_popup;
4836 io.MouseDownOwnedUnlessPopupClose[i] = (
g.HoveredWindow != NULL) || has_open_modal;
4838 mouse_any_down |= io.MouseDown[i];
4839 if (io.MouseDown[i] || io.MouseReleased[i])
4840 if (mouse_earliest_down == -1 || io.MouseClickedTime[i] < io.MouseClickedTime[mouse_earliest_down])
4841 mouse_earliest_down = i;
4843 const bool mouse_avail = (mouse_earliest_down == -1) || io.MouseDownOwned[mouse_earliest_down];
4844 const bool mouse_avail_unless_popup_close = (mouse_earliest_down == -1) || io.MouseDownOwnedUnlessPopupClose[mouse_earliest_down];
4848 const bool mouse_dragging_extern_payload =
g.DragDropActive && (
g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
4849 if (!mouse_avail && !mouse_dragging_extern_payload)
4850 clear_hovered_windows =
true;
4852 if (clear_hovered_windows)
4853 g.HoveredWindow =
g.HoveredWindowUnderMovingWindow = NULL;
4857 if (
g.WantCaptureMouseNextFrame != -1)
4859 io.WantCaptureMouse = io.WantCaptureMouseUnlessPopupClose = (
g.WantCaptureMouseNextFrame != 0);
4863 io.WantCaptureMouse = (mouse_avail && (
g.HoveredWindow != NULL || mouse_any_down)) || has_open_popup;
4864 io.WantCaptureMouseUnlessPopupClose = (mouse_avail_unless_popup_close && (
g.HoveredWindow != NULL || mouse_any_down)) || has_open_modal;
4868 io.WantCaptureKeyboard = (
g.ActiveId != 0) || (modal_window != NULL);
4869 if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
4870 io.WantCaptureKeyboard =
true;
4871 if (
g.WantCaptureKeyboardNextFrame != -1)
4872 io.WantCaptureKeyboard = (
g.WantCaptureKeyboardNextFrame != 0);
4875 io.WantTextInput = (
g.WantTextInputNextFrame != -1) ? (
g.WantTextInputNextFrame != 0) :
false;
4879static void SetupDrawListSharedData()
4882 ImRect virtual_space(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
4883 for (ImGuiViewportP* viewport :
g.Viewports)
4884 virtual_space.Add(viewport->GetMainRect());
4885 g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4();
4886 g.DrawListSharedData.CurveTessellationTol =
g.Style.CurveTessellationTol;
4887 g.DrawListSharedData.SetCircleTessellationMaxError(
g.Style.CircleTessellationMaxError);
4888 g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
4889 if (
g.Style.AntiAliasedLines)
4890 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
4891 if (
g.Style.AntiAliasedLinesUseTex && !(
g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedLines))
4892 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex;
4893 if (
g.Style.AntiAliasedFill)
4894 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
4895 if (
g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
4896 g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset;
4899void ImGui::NewFrame()
4901 IM_ASSERT(
GImGui != NULL &&
"No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
4906 for (
int n =
g.Hooks.Size - 1; n >= 0; n--)
4907 if (
g.Hooks[n].Type == ImGuiContextHookType_PendingRemoval_)
4908 g.Hooks.erase(&
g.Hooks[n]);
4910 CallContextHooks(&
g, ImGuiContextHookType_NewFramePre);
4913 g.ConfigFlagsLastFrame =
g.ConfigFlagsCurrFrame;
4914 ErrorCheckNewFrameSanityChecks();
4915 g.ConfigFlagsCurrFrame =
g.IO.ConfigFlags;
4920 g.Time +=
g.IO.DeltaTime;
4921 g.WithinFrameScope =
true;
4923 g.TooltipOverrideCount = 0;
4924 g.WindowsActiveCount = 0;
4925 g.MenusIdSubmittedThisFrame.resize(0);
4928 g.FramerateSecPerFrameAccum +=
g.IO.DeltaTime -
g.FramerateSecPerFrame[
g.FramerateSecPerFrameIdx];
4929 g.FramerateSecPerFrame[
g.FramerateSecPerFrameIdx] =
g.IO.DeltaTime;
4930 g.FramerateSecPerFrameIdx = (
g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(
g.FramerateSecPerFrame);
4931 g.FramerateSecPerFrameCount = ImMin(
g.FramerateSecPerFrameCount + 1, IM_ARRAYSIZE(
g.FramerateSecPerFrame));
4932 g.IO.Framerate = (
g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (
g.FramerateSecPerFrameAccum / (
float)
g.FramerateSecPerFrameCount)) : FLT_MAX;
4935 g.InputEventsTrail.resize(0);
4936 UpdateInputEvents(
g.IO.ConfigInputTrickleEventQueue);
4939 UpdateViewportsNewFrame();
4943 g.IO.Fonts->Locked =
true;
4944 SetupDrawListSharedData();
4945 SetCurrentFont(GetDefaultFont());
4946 IM_ASSERT(
g.Font->IsLoaded());
4949 for (ImGuiViewportP* viewport :
g.Viewports)
4951 viewport->DrawData = NULL;
4952 viewport->DrawDataP.Valid =
false;
4956 if (
g.DragDropActive &&
g.DragDropPayload.SourceId ==
g.ActiveId)
4957 KeepAliveID(
g.DragDropPayload.SourceId);
4960 if (!
g.HoveredIdPreviousFrame)
4961 g.HoveredIdTimer = 0.0f;
4962 if (!
g.HoveredIdPreviousFrame || (
g.HoveredId &&
g.ActiveId ==
g.HoveredId))
4963 g.HoveredIdNotActiveTimer = 0.0f;
4965 g.HoveredIdTimer +=
g.IO.DeltaTime;
4966 if (
g.HoveredId &&
g.ActiveId !=
g.HoveredId)
4967 g.HoveredIdNotActiveTimer +=
g.IO.DeltaTime;
4968 g.HoveredIdPreviousFrame =
g.HoveredId;
4970 g.HoveredIdAllowOverlap =
false;
4971 g.HoveredIdIsDisabled =
false;
4976 if (
g.ActiveId != 0 &&
g.ActiveIdIsAlive !=
g.ActiveId &&
g.ActiveIdPreviousFrame ==
g.ActiveId)
4978 IMGUI_DEBUG_LOG_ACTIVEID(
"NewFrame(): ClearActiveID() because it isn't marked alive anymore!\n");
4984 g.ActiveIdTimer +=
g.IO.DeltaTime;
4985 g.LastActiveIdTimer +=
g.IO.DeltaTime;
4986 g.ActiveIdPreviousFrame =
g.ActiveId;
4987 g.ActiveIdPreviousFrameWindow =
g.ActiveIdWindow;
4988 g.ActiveIdPreviousFrameHasBeenEditedBefore =
g.ActiveIdHasBeenEditedBefore;
4989 g.ActiveIdIsAlive = 0;
4990 g.ActiveIdHasBeenEditedThisFrame =
false;
4991 g.ActiveIdPreviousFrameIsAlive =
false;
4992 g.ActiveIdIsJustActivated =
false;
4993 if (
g.TempInputId != 0 &&
g.ActiveId !=
g.TempInputId)
4995 if (
g.ActiveId == 0)
4997 g.ActiveIdUsingNavDirMask = 0x00;
4998 g.ActiveIdUsingAllKeyboardKeys =
false;
5004 if (
g.HoverItemDelayId != 0 &&
g.MouseStationaryTimer >=
g.Style.HoverStationaryDelay)
5005 g.HoverItemUnlockedStationaryId =
g.HoverItemDelayId;
5006 else if (
g.HoverItemDelayId == 0)
5007 g.HoverItemUnlockedStationaryId = 0;
5008 if (
g.HoveredWindow != NULL &&
g.MouseStationaryTimer >=
g.Style.HoverStationaryDelay)
5009 g.HoverWindowUnlockedStationaryId =
g.HoveredWindow->ID;
5010 else if (
g.HoveredWindow == NULL)
5011 g.HoverWindowUnlockedStationaryId = 0;
5014 g.HoverItemDelayIdPreviousFrame =
g.HoverItemDelayId;
5015 if (
g.HoverItemDelayId != 0)
5017 g.HoverItemDelayTimer +=
g.IO.DeltaTime;
5018 g.HoverItemDelayClearTimer = 0.0f;
5019 g.HoverItemDelayId = 0;
5021 else if (
g.HoverItemDelayTimer > 0.0f)
5025 g.HoverItemDelayClearTimer +=
g.IO.DeltaTime;
5026 if (
g.HoverItemDelayClearTimer >= ImMax(0.25f,
g.IO.DeltaTime * 2.0f))
5027 g.HoverItemDelayTimer =
g.HoverItemDelayClearTimer = 0.0f;
5031 g.DragDropAcceptIdPrev =
g.DragDropAcceptIdCurr;
5032 g.DragDropAcceptIdCurr = 0;
5033 g.DragDropAcceptIdCurrRectSurface = FLT_MAX;
5034 g.DragDropWithinSource =
false;
5035 g.DragDropWithinTarget =
false;
5036 g.DragDropHoldJustPressedId = 0;
5043 UpdateKeyboardInputs();
5054 UpdateMouseInputs();
5058 DockContextNewFrameUpdateUndocking(&
g);
5062 UpdateHoveredWindowAndCaptureFlags();
5065 UpdateMouseMovingWindowNewFrame();
5068 if (GetTopMostPopupModal() != NULL || (
g.NavWindowingTarget != NULL &&
g.NavWindowingHighlightAlpha > 0.0f))
5069 g.DimBgRatio = ImMin(
g.DimBgRatio +
g.IO.DeltaTime * 6.0f, 1.0f);
5071 g.DimBgRatio = ImMax(
g.DimBgRatio -
g.IO.DeltaTime * 10.0f, 0.0f);
5073 g.MouseCursor = ImGuiMouseCursor_Arrow;
5074 g.WantCaptureMouseNextFrame =
g.WantCaptureKeyboardNextFrame =
g.WantTextInputNextFrame = -1;
5077 g.PlatformImeDataPrev =
g.PlatformImeData;
5078 g.PlatformImeData.WantVisible =
false;
5084 IM_ASSERT(
g.WindowsFocusOrder.Size <=
g.Windows.Size);
5085 const float memory_compact_start_time = (
g.GcCompactAll ||
g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)
g.Time -
g.IO.ConfigMemoryCompactTimer;
5086 for (ImGuiWindow* window :
g.Windows)
5088 window->WasActive = window->Active;
5089 window->Active =
false;
5090 window->WriteAccessed =
false;
5091 window->BeginCountPreviousFrame = window->BeginCount;
5092 window->BeginCount = 0;
5095 if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time)
5096 GcCompactTransientWindowBuffers(window);
5100 for (
int i = 0; i <
g.TablesLastTimeActive.Size; i++)
5101 if (
g.TablesLastTimeActive[i] >= 0.0f &&
g.TablesLastTimeActive[i] < memory_compact_start_time)
5102 TableGcCompactTransientBuffers(
g.Tables.GetByIndex(i));
5103 for (ImGuiTableTempData& table_temp_data :
g.TablesTempData)
5104 if (table_temp_data.LastTimeActive >= 0.0f && table_temp_data.LastTimeActive < memory_compact_start_time)
5105 TableGcCompactTransientBuffers(&table_temp_data);
5107 GcCompactTransientMiscBuffers();
5108 g.GcCompactAll =
false;
5111 if (
g.NavWindow && !
g.NavWindow->WasActive)
5112 FocusTopMostWindowUnderOne(NULL, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild);
5116 g.CurrentWindowStack.resize(0);
5117 g.BeginPopupStack.resize(0);
5118 g.ItemFlagsStack.resize(0);
5119 g.ItemFlagsStack.push_back(ImGuiItemFlags_AutoClosePopups);
5120 g.CurrentItemFlags =
g.ItemFlagsStack.back();
5121 g.GroupStack.resize(0);
5124 DockContextNewFrameUpdateDocking(&
g);
5127#ifndef IMGUI_DISABLE_DEBUG_TOOLS
5128 UpdateDebugToolItemPicker();
5129 UpdateDebugToolStackQueries();
5130 UpdateDebugToolFlashStyleColor();
5131 if (
g.DebugLocateFrames > 0 && --
g.DebugLocateFrames == 0)
5133 g.DebugLocateId = 0;
5134 g.DebugBreakInLocateId =
false;
5136 if (
g.DebugLogAutoDisableFrames > 0 && --
g.DebugLogAutoDisableFrames == 0)
5138 DebugLog(
"(Debug Log: Auto-disabled some ImGuiDebugLogFlags after 2 frames)\n");
5139 g.DebugLogFlags &= ~g.DebugLogAutoDisableFlags;
5140 g.DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None;
5147 g.WithinFrameScopeWithImplicitWindow =
true;
5148 SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver);
5149 Begin(
"Debug##Default");
5150 IM_ASSERT(
g.CurrentWindow->IsFallbackWindow ==
true);
5154#ifndef IMGUI_DISABLE_DEBUG_TOOLS
5155 if (
g.IO.ConfigDebugBeginReturnValueLoop)
5156 g.DebugBeginReturnValueCullDepth = (
g.DebugBeginReturnValueCullDepth == -1) ? 0 : ((
g.DebugBeginReturnValueCullDepth + ((
g.FrameCount % 4) == 0 ? 1 : 0)) % 10);
5158 g.DebugBeginReturnValueCullDepth = -1;
5161 CallContextHooks(&
g, ImGuiContextHookType_NewFramePost);
5165static int IMGUI_CDECL ChildWindowComparer(
const void* lhs,
const void* rhs)
5167 const ImGuiWindow*
const a = *(
const ImGuiWindow*
const *)lhs;
5168 const ImGuiWindow*
const b = *(
const ImGuiWindow*
const *)rhs;
5169 if (
int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup))
5171 if (
int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip))
5173 return (a->BeginOrderWithinParent - b->BeginOrderWithinParent);
5176static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window)
5178 out_sorted_windows->push_back(window);
5181 int count = window->DC.ChildWindows.Size;
5182 ImQsort(window->DC.ChildWindows.Data, (
size_t)count,
sizeof(ImGuiWindow*), ChildWindowComparer);
5183 for (
int i = 0; i <
count; i++)
5185 ImGuiWindow* child = window->DC.ChildWindows[i];
5187 AddWindowToSortBuffer(out_sorted_windows, child);
5192static void AddWindowToDrawData(ImGuiWindow* window,
int layer)
5195 ImGuiViewportP* viewport = window->Viewport;
5196 IM_ASSERT(viewport != NULL);
5197 g.IO.MetricsRenderWindows++;
5198 if (window->DrawList->_Splitter._Count > 1)
5199 window->DrawList->ChannelsMerge();
5200 ImGui::AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[layer], window->DrawList);
5201 for (ImGuiWindow* child : window->DC.ChildWindows)
5202 if (IsWindowActiveAndVisible(child))
5203 AddWindowToDrawData(child, layer);
5206static inline int GetWindowDisplayLayer(ImGuiWindow* window)
5208 return (window->Flags & ImGuiWindowFlags_Tooltip) ? 1 : 0;
5212static inline void AddRootWindowToDrawData(ImGuiWindow* window)
5214 AddWindowToDrawData(window, GetWindowDisplayLayer(window));
5217static void FlattenDrawDataIntoSingleLayer(ImDrawDataBuilder* builder)
5219 int n = builder->Layers[0]->Size;
5221 for (
int i = 1; i < IM_ARRAYSIZE(builder->Layers); i++)
5222 full_size += builder->Layers[i]->Size;
5223 builder->Layers[0]->resize(full_size);
5224 for (
int layer_n = 1; layer_n < IM_ARRAYSIZE(builder->Layers); layer_n++)
5226 ImVector<ImDrawList*>* layer = builder->Layers[layer_n];
5229 memcpy(builder->Layers[0]->Data + n, layer->Data, layer->Size *
sizeof(ImDrawList*));
5235static void InitViewportDrawData(ImGuiViewportP* viewport)
5237 ImGuiIO& io = ImGui::GetIO();
5238 ImDrawData* draw_data = &viewport->DrawDataP;
5240 viewport->DrawData = draw_data;
5241 viewport->DrawDataBuilder.Layers[0] = &draw_data->CmdLists;
5242 viewport->DrawDataBuilder.Layers[1] = &viewport->DrawDataBuilder.LayerData1;
5243 viewport->DrawDataBuilder.Layers[0]->resize(0);
5244 viewport->DrawDataBuilder.Layers[1]->resize(0);
5251 const bool is_minimized = (viewport->Flags & ImGuiViewportFlags_IsMinimized) != 0;
5253 draw_data->Valid =
true;
5254 draw_data->CmdListsCount = 0;
5255 draw_data->TotalVtxCount = draw_data->TotalIdxCount = 0;
5256 draw_data->DisplayPos = viewport->Pos;
5257 draw_data->DisplaySize = is_minimized ? ImVec2(0.0f, 0.0f) : viewport->Size;
5258 draw_data->FramebufferScale = io.DisplayFramebufferScale;
5259 draw_data->OwnerViewport = viewport;
5268void ImGui::PushClipRect(
const ImVec2& clip_rect_min,
const ImVec2& clip_rect_max,
bool intersect_with_current_clip_rect)
5270 ImGuiWindow* window = GetCurrentWindow();
5271 window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect);
5272 window->ClipRect = window->DrawList->_ClipRectStack.back();
5275void ImGui::PopClipRect()
5277 ImGuiWindow* window = GetCurrentWindow();
5278 window->DrawList->PopClipRect();
5279 window->ClipRect = window->DrawList->_ClipRectStack.back();
5282static ImGuiWindow* FindFrontMostVisibleChildWindow(ImGuiWindow* window)
5284 for (
int n = window->DC.ChildWindows.Size - 1; n >= 0; n--)
5285 if (IsWindowActiveAndVisible(window->DC.ChildWindows[n]))
5286 return FindFrontMostVisibleChildWindow(window->DC.ChildWindows[n]);
5290static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col)
5292 if ((col & IM_COL32_A_MASK) == 0)
5295 ImGuiViewportP* viewport = window->Viewport;
5296 ImRect viewport_rect = viewport->GetMainRect();
5302 ImDrawList* draw_list = window->RootWindowDockTree->DrawList;
5303 draw_list->ChannelsMerge();
5304 if (draw_list->CmdBuffer.Size == 0)
5305 draw_list->AddDrawCmd();
5306 draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1),
false);
5307 draw_list->AddRectFilled(viewport_rect.Min, viewport_rect.Max, col);
5308 ImDrawCmd cmd = draw_list->CmdBuffer.back();
5309 IM_ASSERT(cmd.ElemCount == 6);
5310 draw_list->CmdBuffer.pop_back();
5311 draw_list->CmdBuffer.push_front(cmd);
5312 draw_list->AddDrawCmd();
5313 draw_list->PopClipRect();
5317 if (window->RootWindow->DockIsActive)
5319 ImDrawList* draw_list = FindFrontMostVisibleChildWindow(window->RootWindowDockTree)->DrawList;
5320 draw_list->ChannelsMerge();
5321 if (draw_list->CmdBuffer.Size == 0)
5322 draw_list->AddDrawCmd();
5323 draw_list->PushClipRect(viewport_rect.Min, viewport_rect.Max,
false);
5324 RenderRectFilledWithHole(draw_list, window->RootWindowDockTree->Rect(), window->RootWindow->Rect(), col, 0.0f);
5325 draw_list->PopClipRect();
5329ImGuiWindow* ImGui::FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* parent_window)
5332 ImGuiWindow* bottom_most_visible_window = parent_window;
5333 for (
int i = FindWindowDisplayIndex(parent_window); i >= 0; i--)
5335 ImGuiWindow* window =
g.Windows[i];
5336 if (window->Flags & ImGuiWindowFlags_ChildWindow)
5338 if (!IsWindowWithinBeginStackOf(window, parent_window))
5340 if (IsWindowActiveAndVisible(window) && GetWindowDisplayLayer(window) <= GetWindowDisplayLayer(parent_window))
5341 bottom_most_visible_window = window;
5343 return bottom_most_visible_window;
5348static void ImGui::RenderDimmedBackgrounds()
5351 ImGuiWindow* modal_window = GetTopMostAndVisiblePopupModal();
5352 if (
g.DimBgRatio <= 0.0f &&
g.NavWindowingHighlightAlpha <= 0.0f)
5354 const bool dim_bg_for_modal = (modal_window != NULL);
5355 const bool dim_bg_for_window_list = (
g.NavWindowingTargetAnim != NULL &&
g.NavWindowingTargetAnim->Active);
5356 if (!dim_bg_for_modal && !dim_bg_for_window_list)
5359 ImGuiViewport* viewports_already_dimmed[2] = { NULL, NULL };
5360 if (dim_bg_for_modal)
5363 ImGuiWindow* dim_behind_window = FindBottomMostVisibleWindowWithinBeginStack(modal_window);
5364 RenderDimmedBackgroundBehindWindow(dim_behind_window, GetColorU32(modal_window->DC.ModalDimBgColor,
g.DimBgRatio));
5365 viewports_already_dimmed[0] = modal_window->Viewport;
5367 else if (dim_bg_for_window_list)
5370 RenderDimmedBackgroundBehindWindow(
g.NavWindowingTargetAnim, GetColorU32(ImGuiCol_NavWindowingDimBg,
g.DimBgRatio));
5371 if (
g.NavWindowingListWindow != NULL &&
g.NavWindowingListWindow->Viewport &&
g.NavWindowingListWindow->Viewport !=
g.NavWindowingTargetAnim->Viewport)
5372 RenderDimmedBackgroundBehindWindow(
g.NavWindowingListWindow, GetColorU32(ImGuiCol_NavWindowingDimBg,
g.DimBgRatio));
5373 viewports_already_dimmed[0] =
g.NavWindowingTargetAnim->Viewport;
5374 viewports_already_dimmed[1] =
g.NavWindowingListWindow ?
g.NavWindowingListWindow->Viewport : NULL;
5377 ImGuiWindow* window =
g.NavWindowingTargetAnim;
5378 ImGuiViewport* viewport = window->Viewport;
5380 ImRect bb = window->Rect();
5381 bb.Expand(distance);
5382 if (bb.GetWidth() >= viewport->Size.x && bb.GetHeight() >= viewport->Size.y)
5383 bb.Expand(-distance - 1.0f);
5384 window->DrawList->ChannelsMerge();
5385 if (window->DrawList->CmdBuffer.Size == 0)
5386 window->DrawList->AddDrawCmd();
5387 window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size);
5388 window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight,
g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f);
5389 window->DrawList->PopClipRect();
5393 for (ImGuiViewportP* viewport :
g.Viewports)
5395 if (viewport == viewports_already_dimmed[0] || viewport == viewports_already_dimmed[1])
5397 if (modal_window && viewport->Window && IsWindowAbove(viewport->Window, modal_window))
5399 ImDrawList* draw_list = GetForegroundDrawList(viewport);
5400 const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg,
g.DimBgRatio);
5401 draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, dim_bg_col);
5406void ImGui::EndFrame()
5409 IM_ASSERT(
g.Initialized);
5412 if (
g.FrameCountEnded ==
g.FrameCount)
5414 IM_ASSERT(
g.WithinFrameScope &&
"Forgot to call ImGui::NewFrame()?");
5416 CallContextHooks(&
g, ImGuiContextHookType_EndFramePre);
5418 ErrorCheckEndFrameSanityChecks();