Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_win32.cpp
#	imgui.cpp
features/sdl_renderer3_multiviewports
ocornut ago%!(EXTRA string=2 years)
commit bb2fb74645
  1. 9
      backends/imgui_impl_win32.cpp
  2. 6
      docs/CHANGELOG.txt
  3. 257
      imgui.cpp
  4. 8
      imgui.h
  5. 4
      imgui_demo.cpp
  6. 24
      imgui_draw.cpp
  7. 18
      imgui_internal.h
  8. 22
      imgui_tables.cpp
  9. 68
      imgui_widgets.cpp

@ -41,6 +41,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window. // 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
// 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218) // 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218)
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702) // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702)
@ -731,10 +732,14 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
int vk = (int)wParam; int vk = (int)wParam;
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED)) if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
vk = IM_VK_KEYPAD_ENTER; vk = IM_VK_KEYPAD_ENTER;
// Submit key event
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk); const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
const int scancode = (int)LOBYTE(HIWORD(lParam)); const int scancode = (int)LOBYTE(HIWORD(lParam));
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
if (key == ImGuiKey_PrintScreen && !is_key_down)
ImGui_ImplWin32_AddKeyEvent(key, true, vk, scancode);
// Submit key event
if (key != ImGuiKey_None) if (key != ImGuiKey_None)
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode); ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);

@ -78,6 +78,8 @@ Other changes:
- Tables: Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein] - Tables: Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein]
- Tables: Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong - Tables: Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong
in some situations, causing the earlier to be visible underneath when alpha is not 1.0f. in some situations, causing the earlier to be visible underneath when alpha is not 1.0f.
- TabBar: Fixed position of unsaved document marker (ImGuiTabItemFlags_UnsavedDocument) which was
accidentally offset in 1.89.9. (#6862) [@alektron]
- Fonts: 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer. - Fonts: 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer.
This is because our layout/font system currently doesn't fully support non-integer sizes. Until This is because our layout/font system currently doesn't fully support non-integer sizes. Until
it does, this has been a common pitfall leading to more or less subtle issues. (#3164, #3309, #6800) it does, this has been a common pitfall leading to more or less subtle issues. (#3164, #3309, #6800)
@ -93,12 +95,16 @@ Other changes:
- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously - MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
register contents size in a way that would affect the scrolling layer. register contents size in a way that would affect the scrolling layer.
Was most often noticable when using an horizontal scrollbar. (#6789) Was most often noticable when using an horizontal scrollbar. (#6789)
- Misc: Most text functions also treat "%.*s" (along with "%s") specially to avoid formatting. (#3466, #6846)
- IO: Setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) [@bertaye] - IO: Setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) [@bertaye]
- ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] - ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl]
- ImVector: Added find_index() helper. - ImVector: Added find_index() helper.
- Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99]
- Backends: Win32: Added support for keyboard codepage conversion for when application - Backends: Win32: Added support for keyboard codepage conversion for when application
is compiled in MBCS mode and using a non-Unicode window. (#6785, #6782, #5725, #5961) [@sneakyevil] is compiled in MBCS mode and using a non-Unicode window. (#6785, #6782, #5725, #5961) [@sneakyevil]
- Backends: Win32: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows
doesn't emit it (same behavior as GLFW/SDL). (#6859) [@thedmd, @SuperWangKai]
- Internals: Renamed ImFloor() to ImTrunc(). Renamed ImFloorSigned() to ImFloor(). (#6861)
Docking+Viewports Branch: Docking+Viewports Branch:

@ -1240,31 +1240,31 @@ ImGuiStyle::ImGuiStyle()
// Important: This operation is lossy because we round all sizes to integer. If you need to change your scale multiples, call this over a freshly initialized ImGuiStyle structure rather than scaling multiple times. // Important: This operation is lossy because we round all sizes to integer. If you need to change your scale multiples, call this over a freshly initialized ImGuiStyle structure rather than scaling multiple times.
void ImGuiStyle::ScaleAllSizes(float scale_factor) void ImGuiStyle::ScaleAllSizes(float scale_factor)
{ {
WindowPadding = ImFloor(WindowPadding * scale_factor); WindowPadding = ImTrunc(WindowPadding * scale_factor);
WindowRounding = ImFloor(WindowRounding * scale_factor); WindowRounding = ImTrunc(WindowRounding * scale_factor);
WindowMinSize = ImFloor(WindowMinSize * scale_factor); WindowMinSize = ImTrunc(WindowMinSize * scale_factor);
ChildRounding = ImFloor(ChildRounding * scale_factor); ChildRounding = ImTrunc(ChildRounding * scale_factor);
PopupRounding = ImFloor(PopupRounding * scale_factor); PopupRounding = ImTrunc(PopupRounding * scale_factor);
FramePadding = ImFloor(FramePadding * scale_factor); FramePadding = ImTrunc(FramePadding * scale_factor);
FrameRounding = ImFloor(FrameRounding * scale_factor); FrameRounding = ImTrunc(FrameRounding * scale_factor);
ItemSpacing = ImFloor(ItemSpacing * scale_factor); ItemSpacing = ImTrunc(ItemSpacing * scale_factor);
ItemInnerSpacing = ImFloor(ItemInnerSpacing * scale_factor); ItemInnerSpacing = ImTrunc(ItemInnerSpacing * scale_factor);
CellPadding = ImFloor(CellPadding * scale_factor); CellPadding = ImTrunc(CellPadding * scale_factor);
TouchExtraPadding = ImFloor(TouchExtraPadding * scale_factor); TouchExtraPadding = ImTrunc(TouchExtraPadding * scale_factor);
IndentSpacing = ImFloor(IndentSpacing * scale_factor); IndentSpacing = ImTrunc(IndentSpacing * scale_factor);
ColumnsMinSpacing = ImFloor(ColumnsMinSpacing * scale_factor); ColumnsMinSpacing = ImTrunc(ColumnsMinSpacing * scale_factor);
ScrollbarSize = ImFloor(ScrollbarSize * scale_factor); ScrollbarSize = ImTrunc(ScrollbarSize * scale_factor);
ScrollbarRounding = ImFloor(ScrollbarRounding * scale_factor); ScrollbarRounding = ImTrunc(ScrollbarRounding * scale_factor);
GrabMinSize = ImFloor(GrabMinSize * scale_factor); GrabMinSize = ImTrunc(GrabMinSize * scale_factor);
GrabRounding = ImFloor(GrabRounding * scale_factor); GrabRounding = ImTrunc(GrabRounding * scale_factor);
LogSliderDeadzone = ImFloor(LogSliderDeadzone * scale_factor); LogSliderDeadzone = ImTrunc(LogSliderDeadzone * scale_factor);
TabRounding = ImFloor(TabRounding * scale_factor); TabRounding = ImTrunc(TabRounding * scale_factor);
TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImFloor(TabMinWidthForCloseButton * scale_factor) : FLT_MAX; TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImTrunc(TabMinWidthForCloseButton * scale_factor) : FLT_MAX;
SeparatorTextPadding = ImFloor(SeparatorTextPadding * scale_factor); SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
DockingSeparatorSize = ImFloor(DockingSeparatorSize * scale_factor); DockingSeparatorSize = ImTrunc(DockingSeparatorSize * scale_factor);
DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor); DisplayWindowPadding = ImTrunc(DisplayWindowPadding * scale_factor);
DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor); DisplaySafeAreaPadding = ImTrunc(DisplaySafeAreaPadding * scale_factor);
MouseCursorScale = ImFloor(MouseCursorScale * scale_factor); MouseCursorScale = ImTrunc(MouseCursorScale * scale_factor);
} }
ImGuiIO::ImGuiIO() ImGuiIO::ImGuiIO()
@ -1565,7 +1565,7 @@ void ImGuiIO::AddMousePosEvent(float x, float y)
return; return;
// Apply same flooring as UpdateMouseInputs() // Apply same flooring as UpdateMouseInputs()
ImVec2 pos((x > -FLT_MAX) ? ImFloorSigned(x) : x, (y > -FLT_MAX) ? ImFloorSigned(y) : y); ImVec2 pos((x > -FLT_MAX) ? ImFloor(x) : x, (y > -FLT_MAX) ? ImFloor(y) : y);
// Filter duplicate // Filter duplicate
const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MousePos); const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MousePos);
@ -1977,21 +1977,9 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...)
{ {
ImGuiContext& g = *GImGui;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) ImFormatStringToTempBufferV(out_buf, out_buf_end, fmt, args);
{
const char* buf = va_arg(args, const char*); // Skip formatting when using "%s"
*out_buf = buf;
if (out_buf_end) { *out_buf_end = buf + strlen(buf); }
}
else
{
int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args);
*out_buf = g.TempBuffer.Data;
if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; }
}
va_end(args); va_end(args);
} }
@ -2004,6 +1992,13 @@ void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end,
*out_buf = buf; *out_buf = buf;
if (out_buf_end) { *out_buf_end = buf + strlen(buf); } if (out_buf_end) { *out_buf_end = buf + strlen(buf); }
} }
else if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 's' && fmt[4] == 0)
{
int buf_len = va_arg(args, int); // Skip formatting when using "%.*s"
const char* buf = va_arg(args, const char*);
*out_buf = buf;
*out_buf_end = buf + buf_len; // Disallow not passing 'out_buf_end' here. User is expected to use it.
}
else else
{ {
int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args); int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args);
@ -2096,8 +2091,9 @@ ImFileHandle ImFileOpen(const char* filename, const char* mode)
// Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32! // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0); const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0); const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
ImVector<wchar_t> buf; ImGuiContext& g = *GImGui;
buf.resize(filename_wsize + mode_wsize); g.TempBuffer.reserve((filename_wsize + mode_wsize) * sizeof(wchar_t));
wchar_t* buf = (wchar_t*)(void*)g.TempBuffer.Data;
::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize); ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize);
::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize); ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize);
return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]); return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]);
@ -3491,7 +3487,7 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
// Render text, render ellipsis // Render text, render ellipsis
RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f)); RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
ImVec2 ellipsis_pos = ImFloor(ImVec2(pos_min.x + text_size_clipped_x, pos_min.y)); ImVec2 ellipsis_pos = ImTrunc(ImVec2(pos_min.x + text_size_clipped_x, pos_min.y));
if (ellipsis_pos.x + ellipsis_width <= ellipsis_max_x) if (ellipsis_pos.x + ellipsis_width <= ellipsis_max_x)
for (int i = 0; i < font->EllipsisCharCount; i++, ellipsis_pos.x += font->EllipsisCharStep * font_scale) for (int i = 0; i < font->EllipsisCharCount; i++, ellipsis_pos.x += font->EllipsisCharStep * font_scale)
font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar); font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar);
@ -4323,17 +4319,24 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
// IM_ALLOC() == ImGui::MemAlloc() // IM_ALLOC() == ImGui::MemAlloc()
void* ImGui::MemAlloc(size_t size) void* ImGui::MemAlloc(size_t size)
{ {
void* ptr = (*GImAllocatorAllocFunc)(size, GImAllocatorUserData);
if (ImGuiContext* ctx = GImGui) if (ImGuiContext* ctx = GImGui)
{
ctx->IO.MetricsActiveAllocations++; ctx->IO.MetricsActiveAllocations++;
return (*GImAllocatorAllocFunc)(size, GImAllocatorUserData); //printf("[%05d] MemAlloc(%d) -> 0x%p\n", ctx->FrameCount, size, ptr);
}
return ptr;
} }
// IM_FREE() == ImGui::MemFree() // IM_FREE() == ImGui::MemFree()
void ImGui::MemFree(void* ptr) void ImGui::MemFree(void* ptr)
{ {
if (ptr) if (ptr != NULL)
if (ImGuiContext* ctx = GImGui) if (ImGuiContext* ctx = GImGui)
{
ctx->IO.MetricsActiveAllocations--; ctx->IO.MetricsActiveAllocations--;
//printf("[%05d] MemFree(0x%p)\n", ctx->FrameCount, ptr);
}
return (*GImAllocatorFreeFunc)(ptr, GImAllocatorUserData); return (*GImAllocatorFreeFunc)(ptr, GImAllocatorUserData);
} }
@ -4624,9 +4627,9 @@ static void ScaleWindow(ImGuiWindow* window, float scale)
{ {
ImVec2 origin = window->Viewport->Pos; ImVec2 origin = window->Viewport->Pos;
window->Pos = ImFloor((window->Pos - origin) * scale + origin); window->Pos = ImFloor((window->Pos - origin) * scale + origin);
window->Size = ImFloor(window->Size * scale); window->Size = ImTrunc(window->Size * scale);
window->SizeFull = ImFloor(window->SizeFull * scale); window->SizeFull = ImTrunc(window->SizeFull * scale);
window->ContentSize = ImFloor(window->ContentSize * scale); window->ContentSize = ImTrunc(window->ContentSize * scale);
} }
static bool IsWindowActiveAndVisible(ImGuiWindow* window) static bool IsWindowActiveAndVisible(ImGuiWindow* window)
@ -5337,6 +5340,7 @@ void ImGui::EndFrame()
g.IO.Fonts->Locked = false; g.IO.Fonts->Locked = false;
// Clear Input data for next frame // Clear Input data for next frame
g.IO.MousePosPrev = g.IO.MousePos;
g.IO.AppFocusLost = false; g.IO.AppFocusLost = false;
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
g.IO.InputQueueCharacters.resize(0); g.IO.InputQueueCharacters.resize(0);
@ -5436,7 +5440,7 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
// FIXME: Investigate using ceilf or e.g. // FIXME: Investigate using ceilf or e.g.
// - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c // - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
// - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html // - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html
text_size.x = IM_FLOOR(text_size.x + 0.99999f); text_size.x = IM_TRUNC(text_size.x + 0.99999f);
return text_size; return text_size;
} }
@ -5671,7 +5675,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
// Size // Size
const ImVec2 content_avail = GetContentRegionAvail(); const ImVec2 content_avail = GetContentRegionAvail();
ImVec2 size = ImFloor(size_arg); ImVec2 size = ImTrunc(size_arg);
const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00);
if (size.x <= 0.0f) if (size.x <= 0.0f)
size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too many issues) size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too many issues)
@ -5827,9 +5831,9 @@ static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settin
window->ViewportId = settings->ViewportId; window->ViewportId = settings->ViewportId;
window->ViewportPos = ImVec2(settings->ViewportPos.x, settings->ViewportPos.y); window->ViewportPos = ImVec2(settings->ViewportPos.x, settings->ViewportPos.y);
} }
window->Pos = ImFloor(ImVec2(settings->Pos.x + window->ViewportPos.x, settings->Pos.y + window->ViewportPos.y)); window->Pos = ImTrunc(ImVec2(settings->Pos.x + window->ViewportPos.x, settings->Pos.y + window->ViewportPos.y));
if (settings->Size.x > 0 && settings->Size.y > 0) if (settings->Size.x > 0 && settings->Size.y > 0)
window->Size = window->SizeFull = ImFloor(ImVec2(settings->Size.x, settings->Size.y)); window->Size = window->SizeFull = ImTrunc(ImVec2(settings->Size.x, settings->Size.y));
window->Collapsed = settings->Collapsed; window->Collapsed = settings->Collapsed;
window->DockId = settings->DockId; window->DockId = settings->DockId;
window->DockOrder = settings->DockOrder; window->DockOrder = settings->DockOrder;
@ -5944,8 +5948,8 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& s
g.NextWindowData.SizeCallback(&data); g.NextWindowData.SizeCallback(&data);
new_size = data.DesiredSize; new_size = data.DesiredSize;
} }
new_size.x = IM_FLOOR(new_size.x); new_size.x = IM_TRUNC(new_size.x);
new_size.y = IM_FLOOR(new_size.y); new_size.y = IM_TRUNC(new_size.y);
} }
// Minimum size // Minimum size
@ -5973,10 +5977,10 @@ static void CalcWindowContentSizes(ImGuiWindow* window, ImVec2* content_size_cur
return; return;
} }
content_size_current->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x); content_size_current->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_TRUNC(window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
content_size_current->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y); content_size_current->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_TRUNC(window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
content_size_ideal->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(ImMax(window->DC.CursorMaxPos.x, window->DC.IdealMaxPos.x) - window->DC.CursorStartPos.x); content_size_ideal->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_TRUNC(ImMax(window->DC.CursorMaxPos.x, window->DC.IdealMaxPos.x) - window->DC.CursorStartPos.x);
content_size_ideal->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(ImMax(window->DC.CursorMaxPos.y, window->DC.IdealMaxPos.y) - window->DC.CursorStartPos.y); content_size_ideal->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_TRUNC(ImMax(window->DC.CursorMaxPos.y, window->DC.IdealMaxPos.y) - window->DC.CursorStartPos.y);
} }
static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_contents) static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_contents)
@ -6133,8 +6137,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
bool ret_auto_fit = false; bool ret_auto_fit = false;
const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0; const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0;
const float grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f)); const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
const float grip_hover_inner_size = IM_FLOOR(grip_draw_size * 0.75f); const float grip_hover_inner_size = IM_TRUNC(grip_draw_size * 0.75f);
const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f; const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f;
ImRect clamp_rect = visibility_rect; ImRect clamp_rect = visibility_rect;
@ -6250,7 +6254,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
g.NavWindowingToggleLayer = false; g.NavWindowingToggleLayer = false;
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive); resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
ImVec2 accum_floored = ImFloor(g.NavWindowingAccumDeltaSize); ImVec2 accum_floored = ImTrunc(g.NavWindowingAccumDeltaSize);
if (accum_floored.x != 0.0f || accum_floored.y != 0.0f) if (accum_floored.x != 0.0f || accum_floored.y != 0.0f)
{ {
// FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck. // FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck.
@ -6268,7 +6272,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
} }
if (pos_target.x != FLT_MAX) if (pos_target.x != FLT_MAX)
{ {
window->Pos = ImFloor(pos_target); window->Pos = ImTrunc(pos_target);
MarkIniSettingsDirty(window); MarkIniSettingsDirty(window);
} }
@ -6408,8 +6412,8 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
ImGuiDockNode* node = window->DockNode; ImGuiDockNode* node = window->DockNode;
if (window->DockIsActive && node->IsHiddenTabBar() && !node->IsNoTabBar()) if (window->DockIsActive && node->IsHiddenTabBar() && !node->IsNoTabBar())
{ {
float unhide_sz_draw = ImFloor(g.FontSize * 0.70f); float unhide_sz_draw = ImTrunc(g.FontSize * 0.70f);
float unhide_sz_hit = ImFloor(g.FontSize * 0.55f); float unhide_sz_hit = ImTrunc(g.FontSize * 0.55f);
ImVec2 p = node->Pos; ImVec2 p = node->Pos;
ImRect r(p, p + ImVec2(unhide_sz_hit, unhide_sz_hit)); ImRect r(p, p + ImVec2(unhide_sz_hit, unhide_sz_hit));
ImGuiID unhide_id = window->GetID("#UNHIDE"); ImGuiID unhide_id = window->GetID("#UNHIDE");
@ -7032,7 +7036,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
ClampWindowPos(window, visibility_rect); ClampWindowPos(window, visibility_rect);
} }
} }
window->Pos = ImFloor(window->Pos); window->Pos = ImTrunc(window->Pos);
// Lock window rounding for the frame (so that altering them doesn't cause inconsistencies) // Lock window rounding for the frame (so that altering them doesn't cause inconsistencies)
// Large values tend to lead to variety of artifacts and are not recommended. // Large values tend to lead to variety of artifacts and are not recommended.
@ -7074,7 +7078,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
int border_held = -1; int border_held = -1;
ImU32 resize_grip_col[4] = {}; ImU32 resize_grip_col[4] = {};
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it. const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f)); const float resize_grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
if (handle_borders_and_resize_grips && !window->Collapsed) if (handle_borders_and_resize_grips && !window->Collapsed)
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect)) if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true; use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
@ -7155,17 +7159,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Affected by window/frame border size. Used by: // Affected by window/frame border size. Used by:
// - Begin() initial clip rect // - Begin() initial clip rect
float top_border_size = (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); float top_border_size = (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize);
window->InnerClipRect.Min.x = ImFloorSigned(0.5f + window->InnerRect.Min.x + ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize)); window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(ImTrunc(window->WindowPadding.x * 0.5f), window->WindowBorderSize));
window->InnerClipRect.Min.y = ImFloorSigned(0.5f + window->InnerRect.Min.y + top_border_size); window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + top_border_size);
window->InnerClipRect.Max.x = ImFloorSigned(0.5f + window->InnerRect.Max.x - ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize)); window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(ImTrunc(window->WindowPadding.x * 0.5f), window->WindowBorderSize));
window->InnerClipRect.Max.y = ImFloorSigned(0.5f + window->InnerRect.Max.y - window->WindowBorderSize); window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - window->WindowBorderSize);
window->InnerClipRect.ClipWithFull(host_rect); window->InnerClipRect.ClipWithFull(host_rect);
// Default item width. Make it proportional to window size if window manually resizes // Default item width. Make it proportional to window size if window manually resizes
if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize))
window->ItemWidthDefault = ImFloor(window->Size.x * 0.65f); window->ItemWidthDefault = ImTrunc(window->Size.x * 0.65f);
else else
window->ItemWidthDefault = ImFloor(g.FontSize * 16.0f); window->ItemWidthDefault = ImTrunc(g.FontSize * 16.0f);
// SCROLLING // SCROLLING
@ -7227,8 +7231,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
const bool allow_scrollbar_y = !(flags & ImGuiWindowFlags_NoScrollbar); const bool allow_scrollbar_y = !(flags & ImGuiWindowFlags_NoScrollbar);
const float work_rect_size_x = (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : ImMax(allow_scrollbar_x ? window->ContentSize.x : 0.0f, window->Size.x - window->WindowPadding.x * 2.0f - (window->DecoOuterSizeX1 + window->DecoOuterSizeX2))); const float work_rect_size_x = (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : ImMax(allow_scrollbar_x ? window->ContentSize.x : 0.0f, window->Size.x - window->WindowPadding.x * 2.0f - (window->DecoOuterSizeX1 + window->DecoOuterSizeX2)));
const float work_rect_size_y = (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : ImMax(allow_scrollbar_y ? window->ContentSize.y : 0.0f, window->Size.y - window->WindowPadding.y * 2.0f - (window->DecoOuterSizeY1 + window->DecoOuterSizeY2))); const float work_rect_size_y = (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : ImMax(allow_scrollbar_y ? window->ContentSize.y : 0.0f, window->Size.y - window->WindowPadding.y * 2.0f - (window->DecoOuterSizeY1 + window->DecoOuterSizeY2)));
window->WorkRect.Min.x = ImFloor(window->InnerRect.Min.x - window->Scroll.x + ImMax(window->WindowPadding.x, window->WindowBorderSize)); window->WorkRect.Min.x = ImTrunc(window->InnerRect.Min.x - window->Scroll.x + ImMax(window->WindowPadding.x, window->WindowBorderSize));
window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize)); window->WorkRect.Min.y = ImTrunc(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize));
window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x; window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y; window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
window->ParentWorkRect = window->WorkRect; window->ParentWorkRect = window->WorkRect;
@ -7991,7 +7995,7 @@ void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond)
// Set // Set
const ImVec2 old_pos = window->Pos; const ImVec2 old_pos = window->Pos;
window->Pos = ImFloor(pos); window->Pos = ImTrunc(pos);
ImVec2 offset = window->Pos - old_pos; ImVec2 offset = window->Pos - old_pos;
if (offset.x == 0.0f && offset.y == 0.0f) if (offset.x == 0.0f && offset.y == 0.0f)
return; return;
@ -8037,11 +8041,11 @@ void ImGui::SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond con
if (size.x <= 0.0f) if (size.x <= 0.0f)
window->AutoFitOnlyGrows = false; window->AutoFitOnlyGrows = false;
else else
window->SizeFull.x = IM_FLOOR(size.x); window->SizeFull.x = IM_TRUNC(size.x);
if (size.y <= 0.0f) if (size.y <= 0.0f)
window->AutoFitOnlyGrows = false; window->AutoFitOnlyGrows = false;
else else
window->SizeFull.y = IM_FLOOR(size.y); window->SizeFull.y = IM_TRUNC(size.y);
if (old_size.x != window->SizeFull.x || old_size.y != window->SizeFull.y) if (old_size.x != window->SizeFull.x || old_size.y != window->SizeFull.y)
MarkIniSettingsDirty(window); MarkIniSettingsDirty(window);
} }
@ -8157,7 +8161,7 @@ void ImGui::SetNextWindowContentSize(const ImVec2& size)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize; g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize;
g.NextWindowData.ContentSizeVal = ImFloor(size); g.NextWindowData.ContentSizeVal = ImTrunc(size);
} }
void ImGui::SetNextWindowScroll(const ImVec2& scroll) void ImGui::SetNextWindowScroll(const ImVec2& scroll)
@ -9256,7 +9260,7 @@ static void ImGui::UpdateMouseInputs()
// Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well) // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well)
if (IsMousePosValid(&io.MousePos)) if (IsMousePosValid(&io.MousePos))
io.MousePos = g.MouseLastValidPos = ImFloorSigned(io.MousePos); io.MousePos = g.MouseLastValidPos = ImFloor(io.MousePos);
// If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta
if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev)) if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev))
@ -9275,7 +9279,6 @@ static void ImGui::UpdateMouseInputs()
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)
g.NavDisableMouseHover = false; g.NavDisableMouseHover = false;
io.MousePosPrev = io.MousePos;
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{ {
io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f; io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f;
@ -9415,8 +9418,8 @@ void ImGui::UpdateMouseWheel()
{ {
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
SetWindowPos(window, window->Pos + offset, 0); SetWindowPos(window, window->Pos + offset, 0);
window->Size = ImFloor(window->Size * scale); window->Size = ImTrunc(window->Size * scale);
window->SizeFull = ImFloor(window->SizeFull * scale); window->SizeFull = ImTrunc(window->SizeFull * scale);
} }
return; return;
} }
@ -9452,14 +9455,14 @@ void ImGui::UpdateMouseWheel()
{ {
LockWheelingWindow(window, wheel.x); LockWheelingWindow(window, wheel.x);
float max_step = window->InnerRect.GetWidth() * 0.67f; float max_step = window->InnerRect.GetWidth() * 0.67f;
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step)); float scroll_step = ImTrunc(ImMin(2 * window->CalcFontSize(), max_step));
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step); SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
} }
if (do_scroll[ImGuiAxis_Y]) if (do_scroll[ImGuiAxis_Y])
{ {
LockWheelingWindow(window, wheel.y); LockWheelingWindow(window, wheel.y);
float max_step = window->InnerRect.GetHeight() * 0.67f; float max_step = window->InnerRect.GetHeight() * 0.67f;
float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step)); float scroll_step = ImTrunc(ImMin(5 * window->CalcFontSize(), max_step));
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step); SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
} }
} }
@ -10133,8 +10136,8 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
//if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x; window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x;
window->DC.CursorPosPrevLine.y = line_y1; window->DC.CursorPosPrevLine.y = line_y1;
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line window->DC.CursorPos.x = IM_TRUNC(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line
window->DC.CursorPos.y = IM_FLOOR(line_y1 + line_height + g.Style.ItemSpacing.y); // Next line window->DC.CursorPos.y = IM_TRUNC(line_y1 + line_height + g.Style.ItemSpacing.y); // Next line
window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y); window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
@ -10365,8 +10368,8 @@ void ImGui::PushMultiItemsWidths(int components, float w_full)
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
const float w_item_one = ImMax(1.0f, IM_FLOOR((w_full - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components)); const float w_item_one = ImMax(1.0f, IM_TRUNC((w_full - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components));
const float w_item_last = ImMax(1.0f, IM_FLOOR(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components - 1))); const float w_item_last = ImMax(1.0f, IM_TRUNC(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components - 1)));
window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); // Backup current width window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); // Backup current width
window->DC.ItemWidthStack.push_back(w_item_last); window->DC.ItemWidthStack.push_back(w_item_last);
for (int i = 0; i < components - 2; i++) for (int i = 0; i < components - 2; i++)
@ -10398,7 +10401,7 @@ float ImGui::CalcItemWidth()
float region_max_x = GetContentRegionMaxAbs().x; float region_max_x = GetContentRegionMaxAbs().x;
w = ImMax(1.0f, region_max_x - window->DC.CursorPos.x + w); w = ImMax(1.0f, region_max_x - window->DC.CursorPos.x + w);
} }
w = IM_FLOOR(w); w = IM_TRUNC(w);
return w; return w;
} }
@ -10620,7 +10623,7 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
} }
scroll[axis] = scroll_target - center_ratio * (window->SizeFull[axis] - decoration_size[axis]); scroll[axis] = scroll_target - center_ratio * (window->SizeFull[axis] - decoration_size[axis]);
} }
scroll[axis] = IM_FLOOR(ImMax(scroll[axis], 0.0f)); scroll[axis] = IM_TRUNC(ImMax(scroll[axis], 0.0f));
if (!window->Collapsed && !window->SkipItems) if (!window->Collapsed && !window->SkipItems)
scroll[axis] = ImMin(scroll[axis], window->ScrollMax[axis]); scroll[axis] = ImMin(scroll[axis], window->ScrollMax[axis]);
} }
@ -10675,7 +10678,7 @@ ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGui
else if (((flags & ImGuiScrollFlags_KeepVisibleCenterX) && !fully_visible_x) || (flags & ImGuiScrollFlags_AlwaysCenterX)) else if (((flags & ImGuiScrollFlags_KeepVisibleCenterX) && !fully_visible_x) || (flags & ImGuiScrollFlags_AlwaysCenterX))
{ {
if (can_be_fully_visible_x) if (can_be_fully_visible_x)
SetScrollFromPosX(window, ImFloor((item_rect.Min.x + item_rect.Max.x) * 0.5f) - window->Pos.x, 0.5f); SetScrollFromPosX(window, ImTrunc((item_rect.Min.x + item_rect.Max.x) * 0.5f) - window->Pos.x, 0.5f);
else else
SetScrollFromPosX(window, item_rect.Min.x - window->Pos.x, 0.0f); SetScrollFromPosX(window, item_rect.Min.x - window->Pos.x, 0.0f);
} }
@ -10690,7 +10693,7 @@ ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGui
else if (((flags & ImGuiScrollFlags_KeepVisibleCenterY) && !fully_visible_y) || (flags & ImGuiScrollFlags_AlwaysCenterY)) else if (((flags & ImGuiScrollFlags_KeepVisibleCenterY) && !fully_visible_y) || (flags & ImGuiScrollFlags_AlwaysCenterY))
{ {
if (can_be_fully_visible_y) if (can_be_fully_visible_y)
SetScrollFromPosY(window, ImFloor((item_rect.Min.y + item_rect.Max.y) * 0.5f) - window->Pos.y, 0.5f); SetScrollFromPosY(window, ImTrunc((item_rect.Min.y + item_rect.Max.y) * 0.5f) - window->Pos.y, 0.5f);
else else
SetScrollFromPosY(window, item_rect.Min.y - window->Pos.y, 0.0f); SetScrollFromPosY(window, item_rect.Min.y - window->Pos.y, 0.0f);
} }
@ -10775,7 +10778,7 @@ void ImGui::SetScrollY(float scroll_y)
void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio) void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio)
{ {
IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f); IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
window->ScrollTarget.x = IM_FLOOR(local_x - window->DecoOuterSizeX1 - window->DecoInnerSizeX1 + window->Scroll.x); // Convert local position to scroll offset window->ScrollTarget.x = IM_TRUNC(local_x - window->DecoOuterSizeX1 - window->DecoInnerSizeX1 + window->Scroll.x); // Convert local position to scroll offset
window->ScrollTargetCenterRatio.x = center_x_ratio; window->ScrollTargetCenterRatio.x = center_x_ratio;
window->ScrollTargetEdgeSnapDist.x = 0.0f; window->ScrollTargetEdgeSnapDist.x = 0.0f;
} }
@ -10783,7 +10786,7 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x
void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio) void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
{ {
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
window->ScrollTarget.y = IM_FLOOR(local_y - window->DecoOuterSizeY1 - window->DecoInnerSizeY1 + window->Scroll.y); // Convert local position to scroll offset window->ScrollTarget.y = IM_TRUNC(local_y - window->DecoOuterSizeY1 - window->DecoInnerSizeY1 + window->Scroll.y); // Convert local position to scroll offset
window->ScrollTargetCenterRatio.y = center_y_ratio; window->ScrollTargetCenterRatio.y = center_y_ratio;
window->ScrollTargetEdgeSnapDist.y = 0.0f; window->ScrollTargetEdgeSnapDist.y = 0.0f;
} }
@ -12063,7 +12066,7 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
} }
ImVec2 pos = ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); ImVec2 pos = ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight()));
ImGuiViewport* viewport = window->Viewport; ImGuiViewport* viewport = window->Viewport;
return ImFloor(ImClamp(pos, viewport->Pos, viewport->Pos + viewport->Size)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta. return ImTrunc(ImClamp(pos, viewport->Pos, viewport->Pos + viewport->Size)); // ImTrunc() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta.
} }
} }
@ -12206,9 +12209,9 @@ static void ImGui::NavUpdate()
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY && move_dir != ImGuiDir_None) if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY && move_dir != ImGuiDir_None)
{ {
if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right)
SetScrollX(window, ImFloor(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed)); SetScrollX(window, ImTrunc(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
if (move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) if (move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down)
SetScrollY(window, ImFloor(window->Scroll.y + ((move_dir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed)); SetScrollY(window, ImTrunc(window->Scroll.y + ((move_dir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed));
} }
// *Normal* Manual scroll with LStick // *Normal* Manual scroll with LStick
@ -12218,9 +12221,9 @@ static void ImGui::NavUpdate()
const ImVec2 scroll_dir = GetKeyMagnitude2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown); const ImVec2 scroll_dir = GetKeyMagnitude2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown);
const float tweak_factor = IsKeyDown(ImGuiKey_NavGamepadTweakSlow) ? 1.0f / 10.0f : IsKeyDown(ImGuiKey_NavGamepadTweakFast) ? 10.0f : 1.0f; const float tweak_factor = IsKeyDown(ImGuiKey_NavGamepadTweakSlow) ? 1.0f / 10.0f : IsKeyDown(ImGuiKey_NavGamepadTweakFast) ? 10.0f : 1.0f;
if (scroll_dir.x != 0.0f && window->ScrollbarX) if (scroll_dir.x != 0.0f && window->ScrollbarX)
SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed * tweak_factor)); SetScrollX(window, ImTrunc(window->Scroll.x + scroll_dir.x * scroll_speed * tweak_factor));
if (scroll_dir.y != 0.0f) if (scroll_dir.y != 0.0f)
SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed * tweak_factor)); SetScrollY(window, ImTrunc(window->Scroll.y + scroll_dir.y * scroll_speed * tweak_factor));
} }
} }
@ -12912,7 +12915,7 @@ static void ImGui::NavUpdateWindowing()
const float move_step = NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); const float move_step = NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
g.NavWindowingAccumDeltaPos += nav_move_dir * move_step; g.NavWindowingAccumDeltaPos += nav_move_dir * move_step;
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
ImVec2 accum_floored = ImFloor(g.NavWindowingAccumDeltaPos); ImVec2 accum_floored = ImTrunc(g.NavWindowingAccumDeltaPos);
if (accum_floored.x != 0.0f || accum_floored.y != 0.0f) if (accum_floored.x != 0.0f || accum_floored.y != 0.0f)
{ {
ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindowDockTree; ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindowDockTree;
@ -14343,7 +14346,7 @@ static void ImGui::UpdateViewportsNewFrame()
// FIXME-VIEWPORT: This currently creates a resizing feedback loop when a window is straddling a DPI transition border. // FIXME-VIEWPORT: This currently creates a resizing feedback loop when a window is straddling a DPI transition border.
// (Minor: since our sizes do not perfectly linearly scale, deferring the click offset scale until we know the actual window scale ratio may get us slightly more precise mouse positioning.) // (Minor: since our sizes do not perfectly linearly scale, deferring the click offset scale until we know the actual window scale ratio may get us slightly more precise mouse positioning.)
//if (g.MovingWindow != NULL && g.MovingWindow->Viewport == viewport) //if (g.MovingWindow != NULL && g.MovingWindow->Viewport == viewport)
// g.ActiveIdClickOffset = ImFloor(g.ActiveIdClickOffset * scale_factor); // g.ActiveIdClickOffset = ImTrunc(g.ActiveIdClickOffset * scale_factor);
} }
viewport->DpiScale = new_dpi_scale; viewport->DpiScale = new_dpi_scale;
} }
@ -15744,11 +15747,11 @@ static ImVec2 FixLargeWindowsWhenUndocking(const ImVec2& size, ImGuiViewport* re
return size; return size;
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImVec2 max_size = ImFloor(ref_viewport->WorkSize * 0.90f); ImVec2 max_size = ImTrunc(ref_viewport->WorkSize * 0.90f);
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
{ {
const ImGuiPlatformMonitor* monitor = ImGui::GetViewportPlatformMonitor(ref_viewport); const ImGuiPlatformMonitor* monitor = ImGui::GetViewportPlatformMonitor(ref_viewport);
max_size = ImFloor(monitor->WorkSize * 0.90f); max_size = ImTrunc(monitor->WorkSize * 0.90f);
} }
return ImMin(size, max_size); return ImMin(size, max_size);
} }
@ -17115,12 +17118,12 @@ void ImGui::DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& po
if (size_new_desired[axis] > 0.0f && size_new_desired[axis] <= w_avail * 0.5f) if (size_new_desired[axis] > 0.0f && size_new_desired[axis] <= w_avail * 0.5f)
{ {
size_new[axis] = size_new_desired[axis]; size_new[axis] = size_new_desired[axis];
size_old[axis] = IM_FLOOR(w_avail - size_new[axis]); size_old[axis] = IM_TRUNC(w_avail - size_new[axis]);
} }
else else
{ {
size_new[axis] = IM_FLOOR(w_avail * 0.5f); size_new[axis] = IM_TRUNC(w_avail * 0.5f);
size_old[axis] = IM_FLOOR(w_avail - size_new[axis]); size_old[axis] = IM_TRUNC(w_avail - size_new[axis]);
} }
// Position each node // Position each node
@ -17147,21 +17150,21 @@ bool ImGui::DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir
ImVec2 off; // Distance from edge or center ImVec2 off; // Distance from edge or center
if (outer_docking) if (outer_docking)
{ {
//hs_w = ImFloor(ImClamp(parent_smaller_axis - hs_for_central_nodes * 4.0f, g.FontSize * 0.5f, g.FontSize * 8.0f)); //hs_w = ImTrunc(ImClamp(parent_smaller_axis - hs_for_central_nodes * 4.0f, g.FontSize * 0.5f, g.FontSize * 8.0f));
//hs_h = ImFloor(hs_w * 0.15f); //hs_h = ImTrunc(hs_w * 0.15f);
//off = ImVec2(ImFloor(parent.GetWidth() * 0.5f - GetFrameHeightWithSpacing() * 1.4f - hs_h), ImFloor(parent.GetHeight() * 0.5f - GetFrameHeightWithSpacing() * 1.4f - hs_h)); //off = ImVec2(ImTrunc(parent.GetWidth() * 0.5f - GetFrameHeightWithSpacing() * 1.4f - hs_h), ImTrunc(parent.GetHeight() * 0.5f - GetFrameHeightWithSpacing() * 1.4f - hs_h));
hs_w = ImFloor(hs_for_central_nodes * 1.50f); hs_w = ImTrunc(hs_for_central_nodes * 1.50f);
hs_h = ImFloor(hs_for_central_nodes * 0.80f); hs_h = ImTrunc(hs_for_central_nodes * 0.80f);
off = ImVec2(ImFloor(parent.GetWidth() * 0.5f - hs_h), ImFloor(parent.GetHeight() * 0.5f - hs_h)); off = ImTrunc(ImVec2(parent.GetWidth() * 0.5f - hs_h, parent.GetHeight() * 0.5f - hs_h));
} }
else else
{ {
hs_w = ImFloor(hs_for_central_nodes); hs_w = ImTrunc(hs_for_central_nodes);
hs_h = ImFloor(hs_for_central_nodes * 0.90f); hs_h = ImTrunc(hs_for_central_nodes * 0.90f);
off = ImVec2(ImFloor(hs_w * 2.40f), ImFloor(hs_w * 2.40f)); off = ImTrunc(ImVec2(hs_w * 2.40f, hs_w * 2.40f));
} }
ImVec2 c = ImFloor(parent.GetCenter()); ImVec2 c = ImTrunc(parent.GetCenter());
if (dir == ImGuiDir_None) { out_r = ImRect(c.x - hs_w, c.y - hs_w, c.x + hs_w, c.y + hs_w); } if (dir == ImGuiDir_None) { out_r = ImRect(c.x - hs_w, c.y - hs_w, c.x + hs_w, c.y + hs_w); }
else if (dir == ImGuiDir_Up) { out_r = ImRect(c.x - hs_w, c.y - off.y - hs_h, c.x + hs_w, c.y - off.y + hs_h); } else if (dir == ImGuiDir_Up) { out_r = ImRect(c.x - hs_w, c.y - off.y - hs_h, c.x + hs_w, c.y - off.y + hs_h); }
else if (dir == ImGuiDir_Down) { out_r = ImRect(c.x - hs_w, c.y + off.y - hs_h, c.x + hs_w, c.y + off.y + hs_h); } else if (dir == ImGuiDir_Down) { out_r = ImRect(c.x - hs_w, c.y + off.y - hs_h, c.x + hs_w, c.y + off.y + hs_h); }
@ -17175,7 +17178,7 @@ bool ImGui::DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir
if (!outer_docking) if (!outer_docking)
{ {
// Custom hit testing for the 5-way selection, designed to reduce flickering when moving diagonally between sides // Custom hit testing for the 5-way selection, designed to reduce flickering when moving diagonally between sides
hit_r.Expand(ImFloor(hs_w * 0.30f)); hit_r.Expand(ImTrunc(hs_w * 0.30f));
ImVec2 mouse_delta = (*test_mouse_pos - c); ImVec2 mouse_delta = (*test_mouse_pos - c);
float mouse_delta_len2 = ImLengthSqr(mouse_delta); float mouse_delta_len2 = ImLengthSqr(mouse_delta);
float r_threshold_center = hs_w * 1.4f; float r_threshold_center = hs_w * 1.4f;
@ -17428,8 +17431,8 @@ void ImGui::DockNodeTreeSplit(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImG
size_avail = ImMax(size_avail, g.Style.WindowMinSize[split_axis] * 2.0f); size_avail = ImMax(size_avail, g.Style.WindowMinSize[split_axis] * 2.0f);
IM_ASSERT(size_avail > 0.0f); // If you created a node manually with DockBuilderAddNode(), you need to also call DockBuilderSetNodeSize() before splitting. IM_ASSERT(size_avail > 0.0f); // If you created a node manually with DockBuilderAddNode(), you need to also call DockBuilderSetNodeSize() before splitting.
child_0->SizeRef = child_1->SizeRef = parent_node->Size; child_0->SizeRef = child_1->SizeRef = parent_node->Size;
child_0->SizeRef[split_axis] = ImFloor(size_avail * split_ratio); child_0->SizeRef[split_axis] = ImTrunc(size_avail * split_ratio);
child_1->SizeRef[split_axis] = ImFloor(size_avail - child_0->SizeRef[split_axis]); child_1->SizeRef[split_axis] = ImTrunc(size_avail - child_0->SizeRef[split_axis]);
DockNodeMoveWindows(parent_node->ChildNodes[split_inheritor_child_idx], parent_node); DockNodeMoveWindows(parent_node->ChildNodes[split_inheritor_child_idx], parent_node);
DockSettingsRenameNodeReferences(parent_node->ID, parent_node->ChildNodes[split_inheritor_child_idx]->ID); DockSettingsRenameNodeReferences(parent_node->ID, parent_node->ChildNodes[split_inheritor_child_idx]->ID);
@ -17534,10 +17537,10 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si
// Size allocation policy // Size allocation policy
// 1) The first 0..WindowMinSize[axis]*2 are allocated evenly to both windows. // 1) The first 0..WindowMinSize[axis]*2 are allocated evenly to both windows.
const float size_min_each = ImFloor(ImMin(size_avail, g.Style.WindowMinSize[axis] * 2.0f) * 0.5f); const float size_min_each = ImTrunc(ImMin(size_avail, g.Style.WindowMinSize[axis] * 2.0f) * 0.5f);
// FIXME: Blocks 2) and 3) are essentially doing nearly the same thing. // FIXME: Blocks 2) and 3) are essentially doing nearly the same thing.
// Difference are: write-back to SizeRef; application of a minimum size; rounding before ImFloor() // Difference are: write-back to SizeRef; application of a minimum size; rounding before ImTrunc()
// Clarify and rework differences between Size & SizeRef and purpose of WantLockSizeOnce // Clarify and rework differences between Size & SizeRef and purpose of WantLockSizeOnce
// 2) Process locked absolute size (during a splitter resize we preserve the child of nodes not touching the splitter edge) // 2) Process locked absolute size (during a splitter resize we preserve the child of nodes not touching the splitter edge)
@ -17558,7 +17561,7 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si
// FIXME-DOCK: We cannot honor the requested size, so apply ratio. // FIXME-DOCK: We cannot honor the requested size, so apply ratio.
// Currently this path will only be taken if code programmatically sets WantLockSizeOnce // Currently this path will only be taken if code programmatically sets WantLockSizeOnce
float split_ratio = child_0_size[axis] / (child_0_size[axis] + child_1_size[axis]); float split_ratio = child_0_size[axis] / (child_0_size[axis] + child_1_size[axis]);
child_0_size[axis] = child_0->SizeRef[axis] = ImFloor(size_avail * split_ratio); child_0_size[axis] = child_0->SizeRef[axis] = ImTrunc(size_avail * split_ratio);
child_1_size[axis] = child_1->SizeRef[axis] = (size_avail - child_0_size[axis]); child_1_size[axis] = child_1->SizeRef[axis] = (size_avail - child_0_size[axis]);
IM_ASSERT(child_0->SizeRef[axis] > 0.0f && child_1->SizeRef[axis] > 0.0f); IM_ASSERT(child_0->SizeRef[axis] > 0.0f && child_1->SizeRef[axis] > 0.0f);
} }
@ -17578,7 +17581,7 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si
{ {
// 4) Otherwise distribute according to the relative ratio of each SizeRef value // 4) Otherwise distribute according to the relative ratio of each SizeRef value
float split_ratio = child_0->SizeRef[axis] / (child_0->SizeRef[axis] + child_1->SizeRef[axis]); float split_ratio = child_0->SizeRef[axis] / (child_0->SizeRef[axis] + child_1->SizeRef[axis]);
child_0_size[axis] = ImMax(size_min_each, ImFloor(size_avail * split_ratio + 0.5f)); child_0_size[axis] = ImMax(size_min_each, ImTrunc(size_avail * split_ratio + 0.5f));
child_1_size[axis] = (size_avail - child_0_size[axis]); child_1_size[axis] = (size_avail - child_0_size[axis]);
} }
@ -17860,7 +17863,7 @@ ImGuiID ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags
} }
const ImVec2 content_avail = GetContentRegionAvail(); const ImVec2 content_avail = GetContentRegionAvail();
ImVec2 size = ImFloor(size_arg); ImVec2 size = ImTrunc(size_arg);
if (size.x <= 0.0f) if (size.x <= 0.0f)
size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues)
if (size.y <= 0.0f) if (size.y <= 0.0f)
@ -19131,8 +19134,8 @@ void ImGui::DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP*
ImRect thumb_r = thumb_window->Rect(); ImRect thumb_r = thumb_window->Rect();
ImRect title_r = thumb_window->TitleBarRect(); ImRect title_r = thumb_window->TitleBarRect();
thumb_r = ImRect(ImFloor(off + thumb_r.Min * scale), ImFloor(off + thumb_r.Max * scale)); thumb_r = ImRect(ImTrunc(off + thumb_r.Min * scale), ImTrunc(off + thumb_r.Max * scale));
title_r = ImRect(ImFloor(off + title_r.Min * scale), ImFloor(off + ImVec2(title_r.Max.x, title_r.Min.y) * scale) + ImVec2(0,5)); // Exaggerate title bar height title_r = ImRect(ImTrunc(off + title_r.Min * scale), ImTrunc(off + ImVec2(title_r.Max.x, title_r.Min.y) * scale) + ImVec2(0,5)); // Exaggerate title bar height
thumb_r.ClipWithFull(bb); thumb_r.ClipWithFull(bb);
title_r.ClipWithFull(bb); title_r.ClipWithFull(bb);
const bool window_is_focused = (g.NavWindow && thumb_window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight); const bool window_is_focused = (g.NavWindow && thumb_window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight);
@ -20126,8 +20129,8 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
// Draw bounding boxes // Draw bounding boxes
if (show_aabb) if (show_aabb)
{ {
out_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255, 0, 255, 255)); // In pink: clipping rectangle submitted to GPU out_draw_list->AddRect(ImTrunc(clip_rect.Min), ImTrunc(clip_rect.Max), IM_COL32(255, 0, 255, 255)); // In pink: clipping rectangle submitted to GPU
out_draw_list->AddRect(ImFloor(vtxs_rect.Min), ImFloor(vtxs_rect.Max), IM_COL32(0, 255, 255, 255)); // In cyan: bounding box of triangles out_draw_list->AddRect(ImTrunc(vtxs_rect.Min), ImTrunc(vtxs_rect.Max), IM_COL32(0, 255, 255, 255)); // In cyan: bounding box of triangles
} }
out_draw_list->Flags = backup_flags; out_draw_list->Flags = backup_flags;
} }

@ -24,7 +24,7 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.90 WIP" #define IMGUI_VERSION "1.90 WIP"
#define IMGUI_VERSION_NUM 18992 #define IMGUI_VERSION_NUM 18993
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch
@ -686,9 +686,9 @@ namespace ImGui
IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
// Tooltips: helpers for showing a tooltip when hovering an item // Tooltips: helpers for showing a tooltip when hovering an item
// - BeginItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_Tooltip) && BeginTooltip())' idiom. // - BeginItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_ForTooltip) && BeginTooltip())' idiom.
// - SetItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_Tooltip)) { SetTooltip(...); }' idiom. // - SetItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_ForTooltip)) { SetTooltip(...); }' idiom.
// - Where 'ImGuiHoveredFlags_Tooltip' itself is a shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on active input type. For mouse it defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'. // - Where 'ImGuiHoveredFlags_ForTooltip' itself is a shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on active input type. For mouse it defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'.
IMGUI_API bool BeginItemTooltip(); // begin/append a tooltip window if preceding item was hovered. IMGUI_API bool BeginItemTooltip(); // begin/append a tooltip window if preceding item was hovered.
IMGUI_API void SetItemTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip if preceeding item was hovered. override any previous call to SetTooltip(). IMGUI_API void SetItemTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip if preceeding item was hovered. override any previous call to SetTooltip().
IMGUI_API void SetItemTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); IMGUI_API void SetItemTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);

@ -893,9 +893,9 @@ static void ShowDemoWindowWidgets()
"flags for a specific tooltip instance."); "flags for a specific tooltip instance.");
// The following examples are passed for documentation purpose but may not be useful to most users. // The following examples are passed for documentation purpose but may not be useful to most users.
// Passing ImGuiHoveredFlags_Tooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from // Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from
// 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or gamepad/keyboard is being used. // 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or gamepad/keyboard is being used.
// With default settings, ImGuiHoveredFlags_Tooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary. // With default settings, ImGuiHoveredFlags_ForTooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary.
ImGui::Button("Manual", sz); ImGui::Button("Manual", sz);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
ImGui::SetTooltip("I am a manually emitted tooltip."); ImGui::SetTooltip("I am a manually emitted tooltip.");

@ -135,7 +135,7 @@ namespace IMGUI_STB_NAMESPACE
#define STBTT_sqrt(x) ImSqrt(x) #define STBTT_sqrt(x) ImSqrt(x)
#define STBTT_pow(x,y) ImPow(x,y) #define STBTT_pow(x,y) ImPow(x,y)
#define STBTT_fabs(x) ImFabs(x) #define STBTT_fabs(x) ImFabs(x)
#define STBTT_ifloor(x) ((int)ImFloorSigned(x)) #define STBTT_ifloor(x) ((int)ImFloor(x))
#define STBTT_iceil(x) ((int)ImCeil(x)) #define STBTT_iceil(x) ((int)ImCeil(x))
#define STBTT_STATIC #define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
@ -1197,8 +1197,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f); const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f);
const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f); const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f);
const int a_min_sample = a_is_reverse ? (int)ImFloorSigned(a_min_sample_f) : (int)ImCeil(a_min_sample_f); const int a_min_sample = a_is_reverse ? (int)ImFloor(a_min_sample_f) : (int)ImCeil(a_min_sample_f);
const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloorSigned(a_max_sample_f); const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloor(a_max_sample_f);
const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0); const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0);
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
@ -2227,7 +2227,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
if (font_cfg.Name[0] == '\0') if (font_cfg.Name[0] == '\0')
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels); ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels);
font_cfg.EllipsisChar = (ImWchar)0x0085; font_cfg.EllipsisChar = (ImWchar)0x0085;
font_cfg.GlyphOffset.y = 1.0f * IM_FLOOR(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units font_cfg.GlyphOffset.y = 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault(); const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
@ -2669,8 +2669,8 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
int unscaled_ascent, unscaled_descent, unscaled_line_gap; int unscaled_ascent, unscaled_descent, unscaled_line_gap;
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
const float ascent = ImFloor(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1)); const float ascent = ImTrunc(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1));
const float descent = ImFloor(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1)); const float descent = ImTrunc(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1));
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
const float font_off_x = cfg.GlyphOffset.x; const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
@ -2879,7 +2879,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
// - Note that using io.FontGlobalScale or SetWindowFontScale(), with are legacy-ish, partially supported features, can still lead to unrounded sizes. // - Note that using io.FontGlobalScale or SetWindowFontScale(), with are legacy-ish, partially supported features, can still lead to unrounded sizes.
// - We may support it better later and remove this rounding. // - We may support it better later and remove this rounding.
for (ImFontConfig& cfg : atlas->ConfigData) for (ImFontConfig& cfg : atlas->ConfigData)
cfg.SizePixels = ImFloor(cfg.SizePixels); cfg.SizePixels = ImTrunc(cfg.SizePixels);
// Register texture region for mouse cursors or standard white pixels // Register texture region for mouse cursors or standard white pixels
if (atlas->PackIdMouseCursors < 0) if (atlas->PackIdMouseCursors < 0)
@ -3406,7 +3406,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX); advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
if (advance_x != advance_x_original) if (advance_x != advance_x_original)
{ {
float char_off_x = cfg->PixelSnapH ? ImFloor((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f; float char_off_x = cfg->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
x0 += char_off_x; x0 += char_off_x;
x1 += char_off_x; x1 += char_off_x;
} }
@ -3674,8 +3674,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
if (glyph->Colored) if (glyph->Colored)
col |= ~IM_COL32_A_MASK; col |= ~IM_COL32_A_MASK;
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
float x = IM_FLOOR(pos.x); float x = IM_TRUNC(pos.x);
float y = IM_FLOOR(pos.y); float y = IM_TRUNC(pos.y);
draw_list->PrimReserve(6, 4); draw_list->PrimReserve(6, 4);
draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
} }
@ -3687,8 +3687,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect // Align to be pixel perfect
float x = IM_FLOOR(pos.x); float x = IM_TRUNC(pos.x);
float y = IM_FLOOR(pos.y); float y = IM_TRUNC(pos.y);
if (y > clip_rect.w) if (y > clip_rect.w)
return; return;

@ -82,7 +82,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
#endif #endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloorSigned() #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloor()
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h #pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h #pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wold-style-cast"
@ -281,10 +281,13 @@ namespace ImStb
#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8 #define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose #define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 #define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
#define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds #define IM_TRUNC(_VAL) ((float)(int)(_VAL)) // ImTrunc() is not inlined in MSVC debug builds
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // #define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
#define IM_STRINGIFY_HELPER(_X) #_X #define IM_STRINGIFY_HELPER(_X) #_X
#define IM_STRINGIFY(_X) IM_STRINGIFY_HELPER(_X) // Preprocessor idiom to stringify e.g. an integer. #define IM_STRINGIFY(_X) IM_STRINGIFY_HELPER(_X) // Preprocessor idiom to stringify e.g. an integer.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
#define IM_FLOOR IM_TRUNC
#endif
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
#ifdef _MSC_VER #ifdef _MSC_VER
@ -448,7 +451,6 @@ IM_MSVC_RUNTIME_CHECKS_OFF
#define ImAcos(X) acosf(X) #define ImAcos(X) acosf(X)
#define ImAtan2(Y, X) atan2f((Y), (X)) #define ImAtan2(Y, X) atan2f((Y), (X))
#define ImAtof(STR) atof(STR) #define ImAtof(STR) atof(STR)
//#define ImFloorStd(X) floorf(X) // We use our own, see ImFloor() and ImFloorSigned()
#define ImCeil(X) ceilf(X) #define ImCeil(X) ceilf(X)
static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
static inline double ImPow(double x, double y) { return pow(x, y); } static inline double ImPow(double x, double y) { return pow(x, y); }
@ -486,10 +488,10 @@ static inline float ImSaturate(float f)
static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); } static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); } static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; }
static inline float ImFloor(float f) { return (float)(int)(f); } static inline float ImTrunc(float f) { return (float)(int)(f); }
static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() static inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } static inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
static inline ImVec2 ImFloorSigned(const ImVec2& v) { return ImVec2(ImFloorSigned(v.x), ImFloorSigned(v.y)); } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; } static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
@ -562,7 +564,7 @@ struct IMGUI_API ImRect
void TranslateY(float dy) { Min.y += dy; Max.y += dy; } void TranslateY(float dy) { Min.y += dy; Max.y += dy; }
void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display.
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
void Floor() { Min.x = IM_FLOOR(Min.x); Min.y = IM_FLOOR(Min.y); Max.x = IM_FLOOR(Max.x); Max.y = IM_FLOOR(Max.y); } void Floor() { Min.x = IM_TRUNC(Min.x); Min.y = IM_TRUNC(Min.y); Max.x = IM_TRUNC(Max.x); Max.y = IM_TRUNC(Max.y); }
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); } ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
}; };

@ -937,7 +937,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (column->Flags & ImGuiTableColumnFlags_WidthStretch) if (column->Flags & ImGuiTableColumnFlags_WidthStretch)
{ {
float weight_ratio = column->StretchWeight / stretch_sum_weights; float weight_ratio = column->StretchWeight / stretch_sum_weights;
column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, table->MinColumnWidth) + 0.01f); column->WidthRequest = IM_TRUNC(ImMax(width_avail_for_stretched_columns * weight_ratio, table->MinColumnWidth) + 0.01f);
width_remaining_for_stretched_columns -= column->WidthRequest; width_remaining_for_stretched_columns -= column->WidthRequest;
} }
@ -947,7 +947,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
column->Flags |= ImGuiTableColumnFlags_NoDirectResize_; column->Flags |= ImGuiTableColumnFlags_NoDirectResize_;
// Assign final width, record width in case we will need to shrink // Assign final width, record width in case we will need to shrink
column->WidthGiven = ImFloor(ImMax(column->WidthRequest, table->MinColumnWidth)); column->WidthGiven = ImTrunc(ImMax(column->WidthRequest, table->MinColumnWidth));
table->ColumnsGivenWidth += column->WidthGiven; table->ColumnsGivenWidth += column->WidthGiven;
} }
@ -1042,7 +1042,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter. // - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter.
column->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1; column->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1;
column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max
column->ItemWidth = ImFloor(column->WidthGiven * 0.65f); column->ItemWidth = ImTrunc(column->WidthGiven * 0.65f);
column->ClipRect.Min.x = column->MinX; column->ClipRect.Min.x = column->MinX;
column->ClipRect.Min.y = work_rect.Min.y; column->ClipRect.Min.y = work_rect.Min.y;
column->ClipRect.Max.x = column->MaxX; //column->WorkMaxX; column->ClipRect.Max.x = column->MaxX; //column->WorkMaxX;
@ -1378,7 +1378,7 @@ void ImGui::EndTable()
{ {
ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; ImGuiTableColumn* column = &table->Columns[table->ResizedColumn];
const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS); const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS);
const float new_width = ImFloor(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f); const float new_width = ImTrunc(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f);
table->ResizedColumnNextWidth = new_width; table->ResizedColumnNextWidth = new_width;
} }
@ -2981,7 +2981,7 @@ void ImGui::TableHeader(const char* label)
const float ARROW_SCALE = 0.65f; const float ARROW_SCALE = 0.65f;
if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort)) if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort))
{ {
w_arrow = ImFloor(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x); w_arrow = ImTrunc(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x);
if (column->SortOrder > 0) if (column->SortOrder > 0)
{ {
ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1); ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1);
@ -3955,7 +3955,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFl
// Set state for first column // Set state for first column
// We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect // We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect
const float column_padding = g.Style.ItemSpacing.x; const float column_padding = g.Style.ItemSpacing.x;
const float half_clip_extend_x = ImFloor(ImMax(window->WindowPadding.x * 0.5f, window->WindowBorderSize)); const float half_clip_extend_x = ImTrunc(ImMax(window->WindowPadding.x * 0.5f, window->WindowBorderSize));
const float max_1 = window->WorkRect.Max.x + column_padding - ImMax(column_padding - window->WindowPadding.x, 0.0f); const float max_1 = window->WorkRect.Max.x + column_padding - ImMax(column_padding - window->WindowPadding.x, 0.0f);
const float max_2 = window->WorkRect.Max.x + half_clip_extend_x; const float max_2 = window->WorkRect.Max.x + half_clip_extend_x;
columns->OffMinX = window->DC.Indent.x - column_padding + ImMax(column_padding - window->WindowPadding.x, 0.0f); columns->OffMinX = window->DC.Indent.x - column_padding + ImMax(column_padding - window->WindowPadding.x, 0.0f);
@ -4002,7 +4002,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFl
float width = offset_1 - offset_0; float width = offset_1 - offset_0;
PushItemWidth(width * 0.65f); PushItemWidth(width * 0.65f);
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f); window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = IM_TRUNC(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding; window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding;
window->WorkRect.Max.y = window->ContentRegionRect.Max.y; window->WorkRect.Max.y = window->ContentRegionRect.Max.y;
} }
@ -4018,7 +4018,7 @@ void ImGui::NextColumn()
if (columns->Count == 1) if (columns->Count == 1)
{ {
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = IM_TRUNC(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
IM_ASSERT(columns->Current == 0); IM_ASSERT(columns->Current == 0);
return; return;
} }
@ -4050,7 +4050,7 @@ void ImGui::NextColumn()
window->DC.IsSameLine = false; window->DC.IsSameLine = false;
columns->LineMinY = columns->LineMaxY; columns->LineMinY = columns->LineMaxY;
} }
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = IM_TRUNC(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
window->DC.CursorPos.y = columns->LineMinY; window->DC.CursorPos.y = columns->LineMinY;
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = 0.0f; window->DC.CurrLineTextBaseOffset = 0.0f;
@ -4114,7 +4114,7 @@ void ImGui::EndColumns()
// Draw column // Draw column
const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
const float xi = IM_FLOOR(x); const float xi = IM_TRUNC(x);
window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col);
} }
@ -4135,7 +4135,7 @@ void ImGui::EndColumns()
window->ParentWorkRect = columns->HostBackupParentWorkRect; window->ParentWorkRect = columns->HostBackupParentWorkRect;
window->DC.CurrentColumns = NULL; window->DC.CurrentColumns = NULL;
window->DC.ColumnsOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = IM_TRUNC(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
NavUpdateCurrentWindowIsScrollPushableX(); NavUpdateCurrentWindowIsScrollPushableX();
} }

@ -808,7 +808,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)
ImRect bb_interact = bb; ImRect bb_interact = bb;
const float area_to_visible_ratio = window->OuterRectClipped.GetArea() / bb.GetArea(); const float area_to_visible_ratio = window->OuterRectClipped.GetArea() / bb.GetArea();
if (area_to_visible_ratio < 1.5f) if (area_to_visible_ratio < 1.5f)
bb_interact.Expand(ImFloor(bb_interact.GetSize() * -0.25f)); bb_interact.Expand(ImTrunc(bb_interact.GetSize() * -0.25f));
// Tweak 2: We intentionally allow interaction when clipped so that a mechanical Alt,Right,Activate sequence can always close a window. // Tweak 2: We intentionally allow interaction when clipped so that a mechanical Alt,Right,Activate sequence can always close a window.
// (this isn't the common behavior of buttons, but it doesn't affect the user because navigation tends to keep items visible in scrolling layer). // (this isn't the common behavior of buttons, but it doesn't affect the user because navigation tends to keep items visible in scrolling layer).
@ -944,7 +944,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
const bool allow_interaction = (alpha >= 1.0f); const bool allow_interaction = (alpha >= 1.0f);
ImRect bb = bb_frame; ImRect bb = bb_frame;
bb.Expand(ImVec2(-ImClamp(IM_FLOOR((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp(IM_FLOOR((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f))); bb.Expand(ImVec2(-ImClamp(IM_TRUNC((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp(IM_TRUNC((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f)));
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight(); const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight();
@ -1140,12 +1140,12 @@ bool ImGui::Checkbox(const char* label, bool* v)
{ {
// Undocumented tristate/mixed/indeterminate checkbox (#2644) // Undocumented tristate/mixed/indeterminate checkbox (#2644)
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox) // This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f))); ImVec2 pad(ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)), ImMax(1.0f, IM_TRUNC(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding); window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
} }
else if (*v) else if (*v)
{ {
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); const float pad = ImMax(1.0f, IM_TRUNC(square_sz / 6.0f));
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
} }
@ -1240,7 +1240,7 @@ bool ImGui::RadioButton(const char* label, bool active)
window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), num_segment); window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), num_segment);
if (active) if (active)
{ {
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); const float pad = ImMax(1.0f, IM_TRUNC(square_sz / 6.0f));
window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark)); window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark));
} }
@ -1490,14 +1490,14 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
const float separator_thickness = style.SeparatorTextBorderSize; const float separator_thickness = style.SeparatorTextBorderSize;
const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness)); const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness));
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y)); const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
const float text_baseline_y = ImFloor((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImFloor((style.SeparatorTextSize - label_size.y) * 0.5f)); const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f));
ItemSize(min_size, text_baseline_y); ItemSize(min_size, text_baseline_y);
if (!ItemAdd(bb, id)) if (!ItemAdd(bb, id))
return; return;
const float sep1_x1 = pos.x; const float sep1_x1 = pos.x;
const float sep2_x2 = bb.Max.x; const float sep2_x2 = bb.Max.x;
const float seps_y = ImFloor((bb.Min.y + bb.Max.y) * 0.5f + 0.99999f); const float seps_y = ImTrunc((bb.Min.y + bb.Max.y) * 0.5f + 0.99999f);
const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f); const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f);
const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN
@ -1645,7 +1645,7 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc
width_excess = 0.0f; width_excess = 0.0f;
for (int n = 0; n < count; n++) for (int n = 0; n < count; n++)
{ {
float width_rounded = ImFloor(items[n].Width); float width_rounded = ImTrunc(items[n].Width);
width_excess += items[n].Width - width_rounded; width_excess += items[n].Width - width_rounded;
items[n].Width = width_rounded; items[n].Width = width_rounded;
} }
@ -4897,9 +4897,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const float scroll_increment_x = inner_size.x * 0.25f; const float scroll_increment_x = inner_size.x * 0.25f;
const float visible_width = inner_size.x - style.FramePadding.x; const float visible_width = inner_size.x - style.FramePadding.x;
if (cursor_offset.x < state->ScrollX) if (cursor_offset.x < state->ScrollX)
state->ScrollX = IM_FLOOR(ImMax(0.0f, cursor_offset.x - scroll_increment_x)); state->ScrollX = IM_TRUNC(ImMax(0.0f, cursor_offset.x - scroll_increment_x));
else if (cursor_offset.x - visible_width >= state->ScrollX) else if (cursor_offset.x - visible_width >= state->ScrollX)
state->ScrollX = IM_FLOOR(cursor_offset.x - visible_width + scroll_increment_x); state->ScrollX = IM_TRUNC(cursor_offset.x - visible_width + scroll_increment_x);
} }
else else
{ {
@ -4949,7 +4949,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
else else
{ {
ImVec2 rect_size = InputTextCalcTextSizeW(&g, p, text_selected_end, &p, NULL, true); ImVec2 rect_size = InputTextCalcTextSizeW(&g, p, text_selected_end, &p, NULL, true);
if (rect_size.x <= 0.0f) rect_size.x = IM_FLOOR(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines if (rect_size.x <= 0.0f) rect_size.x = IM_TRUNC(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines
ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn)); ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn));
rect.ClipWith(clip_rect); rect.ClipWith(clip_rect);
if (rect.Overlaps(clip_rect)) if (rect.Overlaps(clip_rect))
@ -4972,7 +4972,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{ {
state->CursorAnim += io.DeltaTime; state->CursorAnim += io.DeltaTime;
bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f; bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f;
ImVec2 cursor_screen_pos = ImFloor(draw_pos + cursor_offset - draw_scroll); ImVec2 cursor_screen_pos = ImTrunc(draw_pos + cursor_offset - draw_scroll);
ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f); ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text)); draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text));
@ -5202,8 +5202,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
if ((flags & (ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) if ((flags & (ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
{ {
// RGB/HSV 0..255 Sliders // RGB/HSV 0..255 Sliders
const float w_item_one = ImMax(1.0f, IM_FLOOR((w_inputs - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components)); const float w_item_one = ImMax(1.0f, IM_TRUNC((w_inputs - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components));
const float w_item_last = ImMax(1.0f, IM_FLOOR(w_inputs - (w_item_one + style.ItemInnerSpacing.x) * (components - 1))); const float w_item_last = ImMax(1.0f, IM_TRUNC(w_inputs - (w_item_one + style.ItemInnerSpacing.x) * (components - 1)));
const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x); const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
static const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; static const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
@ -5447,7 +5447,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
float sv_picker_size = ImMax(bars_width * 1, width - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float sv_picker_size = ImMax(bars_width * 1, width - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box
float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x;
float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x;
float bars_triangles_half_sz = IM_FLOOR(bars_width * 0.20f); float bars_triangles_half_sz = IM_TRUNC(bars_width * 0.20f);
float backup_initial_col[4]; float backup_initial_col[4];
memcpy(backup_initial_col, col, components * sizeof(float)); memcpy(backup_initial_col, col, components * sizeof(float));
@ -6180,8 +6180,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
{ {
// Framed header expand a little outside the default padding, to the edge of InnerClipRect // Framed header expand a little outside the default padding, to the edge of InnerClipRect
// (FIXME: May remove this at some point and make InnerClipRect align with WindowPadding.x instead of WindowPadding.x*0.5f) // (FIXME: May remove this at some point and make InnerClipRect align with WindowPadding.x instead of WindowPadding.x*0.5f)
frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); frame_bb.Min.x -= IM_TRUNC(window->WindowPadding.x * 0.5f - 1.0f);
frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); frame_bb.Max.x += IM_TRUNC(window->WindowPadding.x * 0.5f);
} }
const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapser arrow width + Spacing const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapser arrow width + Spacing
@ -6512,8 +6512,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
{ {
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x; const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
const float spacing_y = style.ItemSpacing.y; const float spacing_y = style.ItemSpacing.y;
const float spacing_L = IM_FLOOR(spacing_x * 0.50f); const float spacing_L = IM_TRUNC(spacing_x * 0.50f);
const float spacing_U = IM_FLOOR(spacing_y * 0.50f); const float spacing_U = IM_TRUNC(spacing_y * 0.50f);
bb.Min.x -= spacing_L; bb.Min.x -= spacing_L;
bb.Min.y -= spacing_U; bb.Min.y -= spacing_U;
bb.Max.x += (spacing_x - spacing_L); bb.Max.x += (spacing_x - spacing_L);
@ -6858,7 +6858,7 @@ bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
// Size default to hold ~7.25 items. // Size default to hold ~7.25 items.
// Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. // Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
ImVec2 size = ImFloor(CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.25f + style.FramePadding.y * 2.0f)); ImVec2 size = ImTrunc(CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.25f + style.FramePadding.y * 2.0f));
ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
@ -6912,7 +6912,7 @@ bool ImGui::ListBox(const char* label, int* current_item, const char* (*getter)(
if (height_in_items < 0) if (height_in_items < 0)
height_in_items = ImMin(items_count, 7); height_in_items = ImMin(items_count, 7);
float height_in_items_f = height_in_items + 0.25f; float height_in_items_f = height_in_items + 0.25f;
ImVec2 size(0.0f, ImFloor(GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f)); ImVec2 size(0.0f, ImTrunc(GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f));
if (!BeginListBox(label, size)) if (!BeginListBox(label, size))
return false; return false;
@ -7444,15 +7444,15 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
// Menu inside an horizontal menu bar // Menu inside an horizontal menu bar
// Selectable extend their highlight by half ItemSpacing in each direction. // Selectable extend their highlight by half ItemSpacing in each direction.
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin() // For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
popup_pos = ImVec2(pos.x - 1.0f - IM_FLOOR(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight()); popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight());
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f);
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
float w = label_size.x; float w = label_size.x;
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, label_size.y)); pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, label_size.y));
RenderText(text_pos, label); RenderText(text_pos, label);
PopStyleVar(); PopStyleVar();
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
} }
else else
{ {
@ -7461,7 +7461,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. // Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f; float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
@ -7638,14 +7638,14 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
// Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
// Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark. // Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark.
float w = label_size.x; float w = label_size.x;
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f);
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
pressed = Selectable("", selected, selectable_flags, ImVec2(w, 0.0f)); pressed = Selectable("", selected, selectable_flags, ImVec2(w, 0.0f));
PopStyleVar(); PopStyleVar();
if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible)
RenderText(text_pos, label); RenderText(text_pos, label);
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
} }
else else
{ {
@ -7654,7 +7654,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. // Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f; float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f; float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f;
float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y)); pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y));
@ -7801,8 +7801,8 @@ bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags)
ImGuiTabBar* tab_bar = g.TabBars.GetOrAddByKey(id); ImGuiTabBar* tab_bar = g.TabBars.GetOrAddByKey(id);
ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontSize + g.Style.FramePadding.y * 2); ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontSize + g.Style.FramePadding.y * 2);
tab_bar->ID = id; tab_bar->ID = id;
tab_bar->SeparatorMinX = tab_bar->BarRect.Min.x - IM_FLOOR(window->WindowPadding.x * 0.5f); tab_bar->SeparatorMinX = tab_bar->BarRect.Min.x - IM_TRUNC(window->WindowPadding.x * 0.5f);
tab_bar->SeparatorMaxX = tab_bar->BarRect.Max.x + IM_FLOOR(window->WindowPadding.x * 0.5f); tab_bar->SeparatorMaxX = tab_bar->BarRect.Max.x + IM_TRUNC(window->WindowPadding.x * 0.5f);
return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused); return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused);
} }
@ -8069,7 +8069,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
for (int tab_n = shrink_data_offset; tab_n < shrink_data_offset + shrink_data_count; tab_n++) for (int tab_n = shrink_data_offset; tab_n < shrink_data_offset + shrink_data_count; tab_n++)
{ {
ImGuiTabItem* tab = &tab_bar->Tabs[g.ShrinkWidthBuffer[tab_n].Index]; ImGuiTabItem* tab = &tab_bar->Tabs[g.ShrinkWidthBuffer[tab_n].Index];
float shrinked_width = IM_FLOOR(g.ShrinkWidthBuffer[tab_n].Width); float shrinked_width = IM_TRUNC(g.ShrinkWidthBuffer[tab_n].Width);
if (shrinked_width < 0.0f) if (shrinked_width < 0.0f)
continue; continue;
@ -8700,7 +8700,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
const bool is_central_section = (tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0; const bool is_central_section = (tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0;
size.x = tab->Width; size.x = tab->Width;
if (is_central_section) if (is_central_section)
window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(IM_FLOOR(tab->Offset - tab_bar->ScrollingAnim), 0.0f); window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(IM_TRUNC(tab->Offset - tab_bar->ScrollingAnim), 0.0f);
else else
window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(tab->Offset, 0.0f); window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(tab->Offset, 0.0f);
ImVec2 pos = window->DC.CursorPos; ImVec2 pos = window->DC.CursorPos;
@ -8806,7 +8806,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
if (hovered && g.HoveredIdNotActiveTimer > TOOLTIP_DELAY && bb.GetWidth() < tab->ContentWidth) if (hovered && g.HoveredIdNotActiveTimer > TOOLTIP_DELAY && bb.GetWidth() < tab->ContentWidth)
{ {
// Enlarge tab display when hovering // Enlarge tab display when hovering
bb.Max.x = bb.Min.x + IM_FLOOR(ImLerp(bb.GetWidth(), tab->ContentWidth, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f))); bb.Max.x = bb.Min.x + IM_TRUNC(ImLerp(bb.GetWidth(), tab->ContentWidth, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f)));
display_draw_list = GetForegroundDrawList(window); display_draw_list = GetForegroundDrawList(window);
TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive)); TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive));
} }
@ -8993,7 +8993,7 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
} }
else if (unsaved_marker_visible) else if (unsaved_marker_visible)
{ {
const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz) + g.Style.FramePadding * 2.0f); const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz));
RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text)); RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text));
} }

Loading…
Cancel
Save