Update imgui to 1.81 + docking.

This commit is contained in:
Bartosz Taudul 2021-02-11 00:30:41 +01:00
parent 26a8ec3909
commit f0e1d77ebc
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
20 changed files with 1099 additions and 571 deletions

View File

@ -53,7 +53,7 @@
//#define IMGUI_USE_WCHAR32
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
@ -63,6 +63,15 @@
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
// #define IMGUI_USE_STB_SPRINTF
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
// On Windows you may use vcpkg with 'vcpkg install freetype' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE
//---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
//#define IMGUI_ENABLE_STB_TRUETYPE
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80
// dear imgui, v1.81
// (main code and documentation)
// Help:
@ -240,7 +240,7 @@ CODE
// After we have created the texture, store its pointer/identifier (_in whichever format your engine uses_) in 'io.Fonts->TexID'.
// This will be passed back to your via the renderer. Basically ImTextureID == void*. Read FAQ for details about ImTextureID.
MyTexture* texture = MyEngine::CreateTextureFromMemoryPixels(pixels, width, height, TEXTURE_TYPE_RGBA32)
io.Fonts->TexID = (void*)texture;
io.Fonts->SetTexID((void*)texture);
// Application main loop
while (true)
@ -311,10 +311,11 @@ CODE
// We are using scissoring to clip some objects. All low-level graphics API should supports it.
// - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches
// (some elements visible outside their bounds) but you can fix that once everything else works!
// - Clipping coordinates are provided in imgui coordinates space (from draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize)
// In a single viewport application, draw_data->DisplayPos will always be (0,0) and draw_data->DisplaySize will always be == io.DisplaySize.
// However, in the interest of supporting multi-viewport applications in the future (see 'viewport' branch on github),
// always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space.
// - Clipping coordinates are provided in imgui coordinates space:
// - For a given viewport, draw_data->DisplayPos == viewport->Pos and draw_data->DisplaySize == viewport->Size
// - In a single viewport application, draw_data->DisplayPos == (0,0) and draw_data->DisplaySize == io.DisplaySize, but always use GetMainViewport()->Pos/Size instead of hardcoding those values.
// - In the interest of supporting multi-viewport applications (see 'docking' branch on github),
// always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space.
// - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min)
ImVec2 pos = draw_data->DisplayPos;
MyEngineScissor((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y));
@ -384,7 +385,13 @@ CODE
- 2020/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2020/12/21 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.63 (August 2018):
- 2021/02/03 (1.81) - renamed ListBoxHeader(const char* label, ImVec2 size) to BeginListBox(). Kept inline redirection function (will obsolete).
- removed ListBoxHeader(const char* label, int items_count, int height_in_items = -1) in favor of specifying size. Kept inline redirection function (will obsolete).
- renamed ListBoxFooter() to EndListBox(). Kept inline redirection function (will obsolete).
- 2021/01/26 (1.81) - removed ImGuiFreeType::BuildFontAtlas(). Kept inline redirection function. Prefer using '#define IMGUI_ENABLE_FREETYPE', but there's a runtime selection path available too. The shared extra flags parameters (very rarely used) are now stored in ImFontAtlas::FontBuilderFlags.
- renamed ImFontConfig::RasterizerFlags (used by FreeType) to ImFontConfig::FontBuilderFlags.
- renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API.
- 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.63 (August 2018):
- ImGui::IsItemDeactivatedAfterChange() -> use ImGui::IsItemDeactivatedAfterEdit().
- ImGuiCol_ModalWindowDarkening -> use ImGuiCol_ModalWindowDimBg
- ImGuiInputTextCallback -> use ImGuiTextEditCallback
@ -627,9 +634,9 @@ CODE
- 2015/01/11 (1.30) - big font/image API change! now loads TTF file. allow for multiple fonts. no need for a PNG loader.
- 2015/01/11 (1.30) - removed GetDefaultFontData(). uses io.Fonts->GetTextureData*() API to retrieve uncompressed pixels.
- old: const void* png_data; unsigned int png_size; ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); [..Upload texture to GPU..];
- new: unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); [..Upload texture to GPU..]; io.Fonts->TexId = YourTexIdentifier;
- new: unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); [..Upload texture to GPU..]; io.Fonts->SetTexID(YourTexIdentifier);
you now have more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. It is now recommended that you sample the font texture with bilinear interpolation.
- 2015/01/11 (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID.
- 2015/01/11 (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to call io.Fonts->SetTexID()
- 2015/01/11 (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix)
- 2015/01/11 (1.30) - removed ImGui::IsItemFocused() in favor of ImGui::IsItemActive() which handles all widgets
- 2014/12/10 (1.18) - removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver)
@ -1167,7 +1174,7 @@ void ImGuiIO::ClearInputCharacters()
ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments)
{
IM_ASSERT(num_segments > 0); // Use ImBezierClosestPointCasteljau()
IM_ASSERT(num_segments > 0); // Use ImBezierCubicClosestPointCasteljau()
ImVec2 p_last = p1;
ImVec2 p_closest;
float p_closest_dist2 = FLT_MAX;
@ -3400,11 +3407,23 @@ void ImGui::DestroyContext(ImGuiContext* ctx)
}
// No specific ordering/dependency support, will see as needed
void ImGui::AddContextHook(ImGuiContext* ctx, const ImGuiContextHook* hook)
ImGuiID ImGui::AddContextHook(ImGuiContext* ctx, const ImGuiContextHook* hook)
{
ImGuiContext& g = *ctx;
IM_ASSERT(hook->Callback != NULL);
IM_ASSERT(hook->Callback != NULL && hook->HookId == 0 && hook->Type != ImGuiContextHookType_PendingRemoval_);
g.Hooks.push_back(*hook);
g.Hooks.back().HookId = ++g.HookIdNext;
return g.HookIdNext;
}
// Deferred removal, avoiding issue with changing vector while iterating it
void ImGui::RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_id)
{
ImGuiContext& g = *ctx;
IM_ASSERT(hook_id != 0);
for (int n = 0; n < g.Hooks.Size; n++)
if (g.Hooks[n].HookId == hook_id)
g.Hooks[n].Type = ImGuiContextHookType_PendingRemoval_;
}
// Call context hooks (used by e.g. test engine)
@ -3433,7 +3452,8 @@ ImGuiPlatformIO& ImGui::GetPlatformIO()
ImDrawData* ImGui::GetDrawData()
{
ImGuiContext& g = *GImGui;
return g.Viewports[0]->DrawDataP.Valid ? &g.Viewports[0]->DrawDataP : NULL;
ImGuiViewportP* viewport = g.Viewports[0];
return viewport->DrawDataP.Valid ? &viewport->DrawDataP : NULL;
}
double ImGui::GetTime()
@ -3460,12 +3480,12 @@ static ImDrawList* GetViewportDrawList(ImGuiViewportP* viewport, size_t drawlist
}
// Our ImDrawList system requires that there is always a command
if (viewport->LastFrameDrawLists[drawlist_no] != g.FrameCount)
if (viewport->DrawListsLastFrame[drawlist_no] != g.FrameCount)
{
draw_list->_ResetForNewFrame();
draw_list->PushTextureID(g.IO.Fonts->TexID);
draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
viewport->LastFrameDrawLists[drawlist_no] = g.FrameCount;
viewport->DrawListsLastFrame[drawlist_no] = g.FrameCount;
}
return draw_list;
}
@ -3477,8 +3497,8 @@ ImDrawList* ImGui::GetBackgroundDrawList(ImGuiViewport* viewport)
ImDrawList* ImGui::GetBackgroundDrawList()
{
ImGuiWindow* window = GImGui->CurrentWindow;
return GetBackgroundDrawList(window->Viewport);
ImGuiContext& g = *GImGui;
return GetBackgroundDrawList(g.CurrentWindow->Viewport);
}
ImDrawList* ImGui::GetForegroundDrawList(ImGuiViewport* viewport)
@ -3488,8 +3508,8 @@ ImDrawList* ImGui::GetForegroundDrawList(ImGuiViewport* viewport)
ImDrawList* ImGui::GetForegroundDrawList()
{
ImGuiWindow* window = GImGui->CurrentWindow;
return GetForegroundDrawList(window->Viewport);
ImGuiContext& g = *GImGui;
return GetForegroundDrawList(g.CurrentWindow->Viewport);
}
ImDrawListSharedData* ImGui::GetDrawListSharedData()
@ -3568,7 +3588,10 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
MarkIniSettingsDirty(moving_window);
SetWindowPos(moving_window, pos, ImGuiCond_Always);
if (moving_window->ViewportOwned) // Synchronize viewport immediately because some overlays may relies on clipping rectangle before we Begin() into the window.
{
moving_window->Viewport->Pos = pos;
moving_window->Viewport->UpdateWorkRect();
}
}
FocusWindow(g.MovingWindow);
}
@ -3614,7 +3637,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (g.NavWindow && g.NavWindow->Appearing)
return;
// Click on void to focus window and start moving
// Click on empty space to focus window and start moving
// (after we're done with all our widgets, so e.g. clicking on docking tab-bar which have set HoveredId already and not get us here!)
if (g.IO.MouseClicked[0])
{
@ -3944,6 +3967,12 @@ void ImGui::NewFrame()
{
IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
ImGuiContext& g = *GImGui;
// Remove pending delete hooks before frame start.
// This deferred removal avoid issues of removal while iterating the hook vector
for (int n = g.Hooks.Size - 1; n >= 0; n--)
if (g.Hooks[n].Type == ImGuiContextHookType_PendingRemoval_)
g.Hooks.erase(&g.Hooks[n]);
CallContextHooks(&g, ImGuiContextHookType_NewFramePre);
@ -3978,7 +4007,7 @@ void ImGui::NewFrame()
ImRect virtual_space(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
for (int n = 0; n < g.Viewports.Size; n++)
virtual_space.Add(g.Viewports[n]->GetMainRect());
g.DrawListSharedData.ClipRectFullscreen = ImVec4(virtual_space.Min.x, virtual_space.Min.y, virtual_space.Max.x, virtual_space.Max.y);
g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4();
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
g.DrawListSharedData.SetCircleSegmentMaxError(g.Style.CircleSegmentMaxError);
g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
@ -4192,19 +4221,19 @@ void ImGui::Initialize(ImGuiContext* context)
TableSettingsInstallHandler(context);
#endif // #ifdef IMGUI_HAS_TABLE
#ifdef IMGUI_HAS_DOCK
// Create default viewport
ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)();
viewport->ID = IMGUI_VIEWPORT_DEFAULT_ID;
viewport->Idx = 0;
viewport->PlatformWindowCreated = true;
viewport->Flags = ImGuiViewportFlags_OwnedByApp;
g.Viewports.push_back(viewport);
g.PlatformIO.MainViewport = g.Viewports[0]; // Make it accessible in public-facing GetPlatformIO() immediately (before the first call to EndFrame)
g.PlatformIO.Viewports.push_back(g.Viewports[0]);
// Extensions
#ifdef IMGUI_HAS_DOCK
// Initialize Docking
DockContextInitialize(&g);
#endif // #ifdef IMGUI_HAS_DOCK
#endif
g.Initialized = true;
}
@ -4365,8 +4394,9 @@ static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* d
static void AddWindowToDrawData(ImGuiWindow* window, int layer)
{
ImGuiContext& g = *GImGui;
ImGuiViewportP* viewport = window->Viewport;
g.IO.MetricsRenderWindows++;
AddDrawListToDrawData(&window->Viewport->DrawDataBuilder.Layers[layer], window->DrawList);
AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[layer], window->DrawList);
for (int i = 0; i < window->DC.ChildWindows.Size; i++)
{
ImGuiWindow* child = window->DC.ChildWindows[i];
@ -4409,6 +4439,7 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVector<ImDrawList*
// it earlier in the pipeline, rather than pretend to hide the data at the end of the pipeline.
const bool is_minimized = (viewport->Flags & ImGuiViewportFlags_Minimized) != 0;
ImGuiIO& io = ImGui::GetIO();
ImDrawData* draw_data = &viewport->DrawDataP;
viewport->DrawData = draw_data; // Make publicly accessible
draw_data->Valid = true;
@ -4417,7 +4448,7 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVector<ImDrawList*
draw_data->TotalVtxCount = draw_data->TotalIdxCount = 0;
draw_data->DisplayPos = viewport->Pos;
draw_data->DisplaySize = is_minimized ? ImVec2(0.0f, 0.0f) : viewport->Size;
draw_data->FramebufferScale = ImGui::GetIO().DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis?
draw_data->FramebufferScale = io.DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis?
draw_data->OwnerViewport = viewport;
for (int n = 0; n < draw_lists->Size; n++)
{
@ -4662,8 +4693,9 @@ void ImGui::Render()
AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport));
SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]);
g.IO.MetricsRenderVertices += viewport->DrawData->TotalVtxCount;
g.IO.MetricsRenderIndices += viewport->DrawData->TotalIdxCount;
ImDrawData* draw_data = viewport->DrawData;
g.IO.MetricsRenderVertices += draw_data->TotalVtxCount;
g.IO.MetricsRenderIndices += draw_data->TotalIdxCount;
}
CallContextHooks(&g, ImGuiContextHookType_RenderPost);
@ -4688,7 +4720,11 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
// Round
text_size.x = IM_FLOOR(text_size.x + 0.95f);
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
// FIXME: Investigate using ceilf or e.g.
// - 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
text_size.x = IM_FLOOR(text_size.x + 0.99999f);
return text_size;
}
@ -5231,6 +5267,7 @@ void ImGui::EndChild()
}
}
g.WithinEndChild = false;
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
}
// Helper to create a child window / scrolling region that looks like a normal widget frame.
@ -5275,7 +5312,7 @@ ImGuiWindow* ImGui::FindWindowByName(const char* name)
static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings)
{
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
window->ViewportPos = main_viewport->Pos;
if (settings->ViewportId)
{
@ -5301,7 +5338,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags)
g.WindowsById.SetVoidPtr(window->ID, window);
// Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window.
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
window->Pos = main_viewport->Pos + ImVec2(60, 60);
window->ViewportPos = main_viewport->Pos;
@ -5429,7 +5466,7 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
const int monitor_idx = window->ViewportAllowPlatformMonitorExtend;
if (monitor_idx >= 0 && monitor_idx < g.PlatformIO.Monitors.Size)
avail_size = g.PlatformIO.Monitors[monitor_idx].WorkSize;
ImVec2 size_auto_fit = ImClamp(size_desired, size_min, ImMax(size_min, avail_size - g.Style.DisplaySafeAreaPadding * 2.0f));
ImVec2 size_auto_fit = ImClamp(size_desired, size_min, ImMax(size_min, avail_size - style.DisplaySafeAreaPadding * 2.0f));
// When the window cannot fit all contents (either because of constraints, either because screen is too small),
// we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding.
@ -5889,7 +5926,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
const ImVec2 text_size = CalcTextSize(name, NULL, true) + ImVec2(marker_size_x, 0.0f);
// As a nice touch we try to ensure that centered title text doesn't get affected by visibility of Close/Collapse button,
// while uncentered title text will still reach edges correct.
// while uncentered title text will still reach edges correctly.
if (pad_l > style.FramePadding.x)
pad_l += g.Style.ItemInnerSpacing.x;
if (pad_r > style.FramePadding.x)
@ -5903,8 +5940,9 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
}
ImRect layout_r(title_bar_rect.Min.x + pad_l, title_bar_rect.Min.y, title_bar_rect.Max.x - pad_r, title_bar_rect.Max.y);
ImRect clip_r(layout_r.Min.x, layout_r.Min.y, layout_r.Max.x + g.Style.ItemInnerSpacing.x, layout_r.Max.y);
//if (g.IO.KeyCtrl) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
ImRect clip_r(layout_r.Min.x, layout_r.Min.y, ImMin(layout_r.Max.x + g.Style.ItemInnerSpacing.x, title_bar_rect.Max.x), layout_r.Max.y);
//if (g.IO.KeyShift) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
//if (g.IO.KeyCtrl) window->DrawList->AddRect(clip_r.Min, clip_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
RenderTextClipped(layout_r.Min, layout_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_r);
if (flags & ImGuiWindowFlags_UnsavedDocument)
{
@ -6319,6 +6357,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
viewport_rect_changed = true;
window->Viewport->Size = window->Size;
}
window->Viewport->UpdateWorkRect();
// The viewport may have changed monitor since the global update in UpdateViewportsNewFrame()
// Either a SetNextWindowPos() call in the current frame or a SetWindowPos() call in the previous frame may have this effect.
@ -6391,7 +6430,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if (window->Viewport->PlatformMonitor == -1)
{
// Fallback for "lost" window (e.g. a monitor disconnected): we move the window back over the main viewport
SetWindowPos(window, g.Viewports[0]->Pos + style.DisplayWindowPadding, ImGuiCond_Always);
const ImGuiViewport* main_viewport = GetMainViewport();
SetWindowPos(window, main_viewport->Pos + style.DisplayWindowPadding, ImGuiCond_Always);
}
else
{
@ -6445,6 +6485,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Viewport->Pos = window->Pos;
if (!window->Viewport->PlatformRequestResize)
window->Viewport->Size = window->Size;
window->Viewport->UpdateWorkRect();
viewport_rect = window->Viewport->GetMainRect();
}
@ -6682,7 +6723,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
RenderWindowTitleBarContents(window, title_bar_rect, name, p_open);
RenderWindowTitleBarContents(window, ImRect(title_bar_rect.Min.x + window->WindowBorderSize, title_bar_rect.Min.y, title_bar_rect.Max.x - window->WindowBorderSize, title_bar_rect.Max.y), name, p_open);
// Clear hit test shape every frame
window->HitTestHoleSize.x = window->HitTestHoleSize.y = 0;
@ -7040,15 +7081,15 @@ void ImGui::PopButtonRepeat()
void ImGui::PushTextWrapPos(float wrap_pos_x)
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.TextWrapPosStack.push_back(window->DC.TextWrapPos);
window->DC.TextWrapPos = wrap_pos_x;
window->DC.TextWrapPosStack.push_back(wrap_pos_x);
}
void ImGui::PopTextWrapPos()
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.TextWrapPos = window->DC.TextWrapPosStack.back();
window->DC.TextWrapPosStack.pop_back();
window->DC.TextWrapPos = window->DC.TextWrapPosStack.empty() ? -1.0f : window->DC.TextWrapPosStack.back();
}
bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent)
@ -7195,6 +7236,7 @@ void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond)
ImVec2 offset = window->Pos - old_pos;
window->DC.CursorPos += offset; // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
window->DC.CursorMaxPos += offset; // And more importantly we need to offset CursorMaxPos/CursorStartPos this so ContentSize calculation doesn't get affected.
window->DC.IdealMaxPos += offset;
window->DC.CursorStartPos += offset;
}
@ -7696,6 +7738,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size; monitor_n++)
{
ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[monitor_n];
IM_UNUSED(mon);
IM_ASSERT(mon.MainSize.x > 0.0f && mon.MainSize.y > 0.0f && "Monitor main bounds not setup properly.");
IM_ASSERT(ImRect(mon.MainPos, mon.MainPos + mon.MainSize).Contains(ImRect(mon.WorkPos, mon.WorkPos + mon.WorkSize)) && "Monitor work bounds not setup properly. If you don't have work area information, just copy MainPos/MainSize into them.");
IM_ASSERT(mon.DpiScale != 0.0f);
@ -8093,12 +8136,13 @@ void ImGui::SetNextItemWidth(float item_width)
g.NextItemData.Width = item_width;
}
// FIXME: Remove the == 0.0f behavior?
void ImGui::PushItemWidth(float item_width)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); // Backup current width
window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width);
window->DC.ItemWidthStack.push_back(window->DC.ItemWidth);
g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
}
@ -8109,18 +8153,19 @@ void ImGui::PushMultiItemsWidths(int components, float w_full)
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_last = ImMax(1.0f, IM_FLOOR(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(w_item_last);
for (int i = 0; i < components - 1; i++)
for (int i = 0; i < components - 2; i++)
window->DC.ItemWidthStack.push_back(w_item_one);
window->DC.ItemWidth = window->DC.ItemWidthStack.back();
window->DC.ItemWidth = (components == 1) ? w_item_last : w_item_one;
g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
}
void ImGui::PopItemWidth()
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.ItemWidth = window->DC.ItemWidthStack.back();
window->DC.ItemWidthStack.pop_back();
window->DC.ItemWidth = window->DC.ItemWidthStack.empty() ? window->ItemWidthDefault : window->DC.ItemWidthStack.back();
}
// Calculate default item width given value passed to PushItemWidth() or SetNextItemWidth().
@ -8266,7 +8311,7 @@ void ImGui::BeginGroup()
window->DC.CursorMaxPos = window->DC.CursorPos;
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
if (g.LogEnabled)
g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
}
void ImGui::EndGroup()
@ -8287,7 +8332,7 @@ void ImGui::EndGroup()
window->DC.CurrLineSize = group_data.BackupCurrLineSize;
window->DC.CurrLineTextBaseOffset = group_data.BackupCurrLineTextBaseOffset;
if (g.LogEnabled)
g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
if (!group_data.EmitItem)
{
@ -8853,8 +8898,8 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla
// FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window.
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0)
{
ImGuiViewportP* viewport = window->WasActive ? window->Viewport : (ImGuiViewportP*)GetMainViewport(); // FIXME-VIEWPORT: What may be our reference viewport?
SetNextWindowPos(viewport->GetMainRect().GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f));
const ImGuiViewport* viewport = window->WasActive ? window->Viewport : GetMainViewport(); // FIXME-VIEWPORT: What may be our reference viewport?
SetNextWindowPos(viewport->GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f));
}
flags |= ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking;
@ -9040,8 +9085,7 @@ ImRect ImGui::GetWindowAllowedExtentRect(ImGuiWindow* window)
else
{
// Use the full viewport area (not work area) for popups
r_screen.Min = window->Viewport->Pos;
r_screen.Max = window->Viewport->Pos + window->Viewport->Size;
r_screen = window->Viewport->GetMainRect();
}
ImVec2 padding = g.Style.DisplaySafeAreaPadding;
r_screen.Expand(ImVec2((r_screen.GetWidth() > padding.x * 2) ? -padding.x : 0.0f, (r_screen.GetHeight() > padding.y * 2) ? -padding.y : 0.0f));
@ -9051,13 +9095,14 @@ ImRect ImGui::GetWindowAllowedExtentRect(ImGuiWindow* window)
ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
ImRect r_outer = GetWindowAllowedExtentRect(window);
if (window->Flags & ImGuiWindowFlags_ChildMenu)
{
// Child menus typically request _any_ position within the parent menu item, and then we move the new menu outside the parent bounds.
// This is how we end up with child menus appearing (most-commonly) on the right of the parent menu.
ImGuiWindow* parent_window = window->ParentWindow;
float horizontal_overlap = g.Style.ItemInnerSpacing.x; // We want some overlap to convey the relative depth of each menu (currently the amount of overlap is hard-coded to style.ItemSpacing.x).
ImRect r_outer = GetWindowAllowedExtentRect(window);
ImRect r_avoid;
if (parent_window->DC.MenuBarAppending)
r_avoid = ImRect(-FLT_MAX, parent_window->ClipRect.Min.y, FLT_MAX, parent_window->ClipRect.Max.y); // Avoid parent menu-bar. If we wanted multi-line menu-bar, we may instead want to have the calling window setup e.g. a NextWindowData.PosConstraintAvoidRect field
@ -9067,7 +9112,6 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
}
if (window->Flags & ImGuiWindowFlags_Popup)
{
ImRect r_outer = GetWindowAllowedExtentRect(window);
ImRect r_avoid = ImRect(window->Pos.x - 1, window->Pos.y - 1, window->Pos.x + 1, window->Pos.y + 1);
return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Default);
}
@ -9076,7 +9120,6 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
// Position tooltip (always follows mouse)
float sc = g.Style.MouseCursorScale;
ImVec2 ref_pos = NavCalcPreferredRefPos();
ImRect r_outer = GetWindowAllowedExtentRect(window);
ImRect r_avoid;
if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos))
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
@ -9490,8 +9533,8 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
// When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item.
const ImRect& rect_rel = g.NavWindow->NavRectRel[g.NavLayer];
ImVec2 pos = g.NavWindow->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()));
ImRect visible_rect = g.NavWindow->Viewport->GetMainRect();
return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta.
ImGuiViewport* viewport = g.NavWindow->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.
}
}
@ -10234,9 +10277,9 @@ void ImGui::NavUpdateWindowingOverlay()
if (g.NavWindowingListWindow == NULL)
g.NavWindowingListWindow = FindWindowByName("###NavWindowingList");
ImGuiViewportP* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ (ImGuiViewportP*)GetMainViewport();
const ImGuiViewport* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ GetMainViewport();
SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX));
SetNextWindowPos(viewport->Pos + viewport->Size * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--)
@ -10587,54 +10630,63 @@ void ImGui::LogText(const char* fmt, ...)
// Internal version that takes a position to decide on newline placement and pad items according to their depth.
// We split text into individual lines to add current tree level padding
// FIXME: This code is a little complicated perhaps, considering simplifying the whole system.
void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
const char* prefix = g.LogNextPrefix;
const char* suffix = g.LogNextSuffix;
g.LogNextPrefix = g.LogNextSuffix = NULL;
if (!text_end)
text_end = FindRenderedTextEnd(text, text_end);
const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + 1);
const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + g.Style.FramePadding.y + 1);
if (ref_pos)
g.LogLinePosY = ref_pos->y;
if (log_new_line)
{
LogText(IM_NEWLINE);
g.LogLineFirstItem = true;
}
const char* text_remaining = text;
if (g.LogDepthRef > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth
if (prefix)
LogRenderedText(ref_pos, prefix, prefix + strlen(prefix)); // Calculate end ourself to ensure "##" are included here.
// Re-adjust padding if we have popped out of our starting depth
if (g.LogDepthRef > window->DC.TreeDepth)
g.LogDepthRef = window->DC.TreeDepth;
const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
const char* text_remaining = text;
for (;;)
{
// Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry.
// We don't add a trailing \n to allow a subsequent item on the same line to be captured.
// Split the string. Each new line (after a '\n') is followed by indentation corresponding to the current depth of our log entry.
// We don't add a trailing \n yet to allow a subsequent item on the same line to be captured.
const char* line_start = text_remaining;
const char* line_end = ImStreolRange(line_start, text_end);
const bool is_first_line = (line_start == text);
const bool is_last_line = (line_end == text_end);
if (!is_last_line || (line_start != line_end))
if (line_start != line_end || !is_last_line)
{
const int char_count = (int)(line_end - line_start);
if (log_new_line || !is_first_line)
LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, line_start);
else if (g.LogLineFirstItem)
LogText("%*s%.*s", tree_depth * 4, "", char_count, line_start);
else
LogText(" %.*s", char_count, line_start);
const int line_length = (int)(line_end - line_start);
const int indentation = g.LogLineFirstItem ? tree_depth * 4 : 1;
LogText("%*s%.*s", indentation, "", line_length, line_start);
g.LogLineFirstItem = false;
if (*line_end == '\n')
{
LogText(IM_NEWLINE);
g.LogLineFirstItem = true;
}
}
else if (log_new_line)
{
// An empty "" string at a different Y position should output a carriage return.
LogText(IM_NEWLINE);
break;
}
if (is_last_line)
break;
text_remaining = line_end + 1;
}
if (suffix)
LogRenderedText(ref_pos, suffix, suffix + strlen(suffix));
}
// Start logging/capturing text output
@ -10647,12 +10699,21 @@ void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth)
IM_ASSERT(g.LogBuffer.empty());
g.LogEnabled = true;
g.LogType = type;
g.LogNextPrefix = g.LogNextSuffix = NULL;
g.LogDepthRef = window->DC.TreeDepth;
g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault);
g.LogLinePosY = FLT_MAX;
g.LogLineFirstItem = true;
}
// Important: doesn't copy underlying data, use carefully (prefix/suffix must be in scope at the time of the next LogRenderedText)
void ImGui::LogSetNextTextDecoration(const char* prefix, const char* suffix)
{
ImGuiContext& g = *GImGui;
g.LogNextPrefix = prefix;
g.LogNextSuffix = suffix;
}
void ImGui::LogToTTY(int auto_open_depth)
{
ImGuiContext& g = *GImGui;
@ -11235,13 +11296,14 @@ static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImG
return true;
}
// FIXME: handle 0 to N host viewports
static bool ImGui::UpdateTryMergeWindowIntoHostViewports(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
return UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]);
}
// Translate imgui windows when a Host Viewport has been moved
// Translate Dear ImGui windows when a Host Viewport has been moved
// (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!)
void ImGui::TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos)
{
@ -11332,7 +11394,7 @@ static void ImGui::UpdateViewportsNewFrame()
main_viewport_pos = main_viewport->Pos; // Preserve last pos/size when minimized (FIXME: We don't do the same for Size outside of the viewport path)
main_viewport_size = main_viewport->Size;
}
AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_pos, main_viewport_size, ImGuiViewportFlags_CanHostOtherWindows);
AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_pos, main_viewport_size, ImGuiViewportFlags_OwnedByApp | ImGuiViewportFlags_CanHostOtherWindows);
g.CurrentDpiScale = 0.0f;
g.CurrentViewport = NULL;
@ -11372,6 +11434,7 @@ static void ImGui::UpdateViewportsNewFrame()
// We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities.
if (!(viewport->Flags & ImGuiViewportFlags_Minimized) && platform_funcs_available)
{
// Viewport->WorkPos and WorkSize will be updated below
if (viewport->PlatformRequestMove)
viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport);
if (viewport->PlatformRequestResize)
@ -11386,6 +11449,7 @@ static void ImGui::UpdateViewportsNewFrame()
viewport->WorkOffsetMin = viewport->CurrWorkOffsetMin;
viewport->WorkOffsetMax = viewport->CurrWorkOffsetMax;
viewport->CurrWorkOffsetMin = viewport->CurrWorkOffsetMax = ImVec2(0.0f, 0.0f);
viewport->UpdateWorkRect();
// Reset alpha every frame. Users of transparency (docking) needs to request a lower alpha back.
viewport->Alpha = 1.0f;
@ -11477,7 +11541,6 @@ static void ImGui::UpdateViewportsNewFrame()
static void ImGui::UpdateViewportsEndFrame()
{
ImGuiContext& g = *GImGui;
g.PlatformIO.MainViewport = g.Viewports[0];
g.PlatformIO.Viewports.resize(0);
for (int i = 0; i < g.Viewports.Size; i++)
{
@ -11501,6 +11564,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
ImGuiContext& g = *GImGui;
IM_ASSERT(id != 0);
flags |= ImGuiViewportFlags_IsPlatformWindow;
if (window != NULL)
{
if (g.MovingWindow && g.MovingWindow->RootWindow == window)
@ -11548,6 +11612,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
viewport->Window = window;
viewport->LastFrameActive = g.FrameCount;
viewport->UpdateWorkRect();
IM_ASSERT(window == NULL || viewport->ID == window->ID);
if (window != NULL)
@ -11564,7 +11629,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
window->ViewportAllowPlatformMonitorExtend = -1;
// Restore main viewport if multi-viewport is not supported by the backend
ImGuiViewportP* main_viewport = g.Viewports[0];
ImGuiViewportP* main_viewport = (ImGuiViewportP*)(void*)GetMainViewport();
if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable))
{
SetWindowViewport(window, main_viewport);
@ -11778,7 +11843,7 @@ void ImGui::UpdatePlatformWindows()
// This is useful for our platform z-order heuristic when io.MouseHoveredViewport is not available.
if (viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount)
viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount;
}
}
// Clear request flags
viewport->ClearRequestFlags();
@ -11799,8 +11864,14 @@ void ImGui::UpdatePlatformWindows()
}
// Store a tag so we can infer z-order easily from all our windows
if (focused_viewport && focused_viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount)
focused_viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount;
// We compare PlatformLastFocusedViewportId so newly created viewports with _NoFocusOnAppearing flag
// will keep the front most stamp instead of losing it back to their parent viewport.
if (focused_viewport && g.PlatformLastFocusedViewportId != focused_viewport->ID)
{
if (focused_viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount)
focused_viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount;
g.PlatformLastFocusedViewportId = focused_viewport->ID;
}
}
}
@ -13344,7 +13415,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
}
// Register a hit-test hole in the window unless we are currently dragging a window that is compatible with our dockspace
const ImGuiDockNode* central_node = node->CentralNode;
ImGuiDockNode* central_node = node->CentralNode;
const bool central_node_hole = node->IsRootNode() && host_window && (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0 && central_node != NULL && central_node->IsEmpty();
bool central_node_hole_register_hit_test_hole = central_node_hole;
if (central_node_hole)
@ -13353,14 +13424,22 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
central_node_hole_register_hit_test_hole = false;
if (central_node_hole_register_hit_test_hole)
{
// Add a little padding to match the "resize from edges" behavior and allow grabbing the splitter easily.
// We add a little padding to match the "resize from edges" behavior and allow grabbing the splitter easily.
// (But we only add it if there's something else on the other side of the hole, otherwise for e.g. fullscreen
// covering passthru node we'd have a gap on the edge not covered by the hole)
IM_ASSERT(node->IsDockSpace()); // We cannot pass this flag without the DockSpace() api. Testing this because we also setup the hole in host_window->ParentNode
ImRect central_hole(central_node->Pos, central_node->Pos + central_node->Size);
central_hole.Expand(ImVec2(-WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS, -WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS));
if (central_node_hole && !central_hole.IsInverted())
ImGuiDockNode* root_node = DockNodeGetRootNode(central_node);
ImRect root_rect(root_node->Pos, root_node->Pos + root_node->Size);
ImRect hole_rect(central_node->Pos, central_node->Pos + central_node->Size);
if (hole_rect.Min.x > root_rect.Min.x) { hole_rect.Min.x += WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS; }
if (hole_rect.Max.x < root_rect.Max.x) { hole_rect.Max.x -= WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS; }
if (hole_rect.Min.y > root_rect.Min.y) { hole_rect.Min.y += WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS; }
if (hole_rect.Max.y < root_rect.Max.y) { hole_rect.Max.y -= WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS; }
//GetForegroundDrawList()->AddRect(hole_rect.Min, hole_rect.Max, IM_COL32(255, 0, 0, 255));
if (central_node_hole && !hole_rect.IsInverted())
{
SetWindowHitTestHole(host_window, central_hole.Min, central_hole.Max - central_hole.Min);
SetWindowHitTestHole(host_window->ParentWindow, central_hole.Min, central_hole.Max - central_hole.Min);
SetWindowHitTestHole(host_window, hole_rect.Min, hole_rect.Max - hole_rect.Min);
SetWindowHitTestHole(host_window->ParentWindow, hole_rect.Min, hole_rect.Max - hole_rect.Min);
}
}
@ -13484,7 +13563,8 @@ bool ImGui::DockNodeBeginAmendTabBar(ImGuiDockNode* node)
Begin(node->HostWindow->Name);
PushOverrideID(node->ID);
bool ret = BeginTabBarEx(node->TabBar, node->TabBar->BarRect, node->TabBar->Flags, node);
IM_ASSERT(ret);
IM_UNUSED(ret);
IM_ASSERT(ret);
return true;
}
@ -14164,6 +14244,7 @@ void ImGui::DockNodeTreeSplit(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImG
child_1->SizeRef[split_axis] = ImFloor(size_avail - child_0->SizeRef[split_axis]);
DockNodeMoveWindows(parent_node->ChildNodes[split_inheritor_child_idx], parent_node);
DockSettingsRenameNodeReferences(parent_node->ID, parent_node->ChildNodes[split_inheritor_child_idx]->ID);
DockNodeTreeUpdatePosSize(parent_node, parent_node->Pos, parent_node->Size);
// Flags transfer (e.g. this is where we transfer the ImGuiDockNodeFlags_CentralNode property)
@ -14374,7 +14455,7 @@ void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node)
/*
// [DEBUG] Render limits
ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport());
ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport());
for (int n = 0; n < 2; n++)
if (axis == ImGuiAxis_X)
draw_list->AddLine(ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y), ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y + node->ChildNodes[n]->Size.y), IM_COL32(255, 0, 255, 255), 3.0f);
@ -14402,7 +14483,7 @@ void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node)
for (int touching_node_n = 0; touching_node_n < touching_nodes[side_n].Size; touching_node_n++)
{
ImGuiDockNode* touching_node = touching_nodes[side_n][touching_node_n];
//ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport());
//ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport());
//draw_list->AddRect(touching_node->Pos, touching_node->Pos + touching_node->Size, IM_COL32(255, 128, 0, 255));
while (touching_node->ParentNode != node)
{
@ -14618,13 +14699,13 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags fla
// The limitation with this call is that your window won't have a menu bar.
// Even though we could pass window flags, it would also require the user to be able to call BeginMenuBar() somehow meaning we can't Begin/End in a single function.
// But you can also use BeginMainMenuBar(). If you really want a menu bar inside the same window as the one hosting the dockspace, you will need to copy this code somewhere and tweak it.
ImGuiID ImGui::DockSpaceOverViewport(ImGuiViewport* viewport, ImGuiDockNodeFlags dockspace_flags, const ImGuiWindowClass* window_class)
ImGuiID ImGui::DockSpaceOverViewport(const ImGuiViewport* viewport, ImGuiDockNodeFlags dockspace_flags, const ImGuiWindowClass* window_class)
{
if (viewport == NULL)
viewport = GetMainViewport();
SetNextWindowPos(viewport->GetWorkPos());
SetNextWindowSize(viewport->GetWorkSize());
SetNextWindowPos(viewport->WorkPos);
SetNextWindowSize(viewport->WorkSize);
SetNextWindowViewport(viewport->ID);
ImGuiWindowFlags host_window_flags = 0;
@ -14789,7 +14870,10 @@ void ImGui::DockBuilderRemoveNodeChildNodes(ImGuiID root_id)
if (root_id != 0)
DockContextQueueNotifyRemovedNode(ctx, node);
if (root_node)
{
DockNodeMoveWindows(root_node, node);
DockSettingsRenameNodeReferences(node->ID, root_node->ID);
}
nodes_to_remove.push_back(node);
}
}
@ -15724,7 +15808,7 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
#ifndef IMGUI_DISABLE_METRICS_WINDOW
static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb)
void ImGui::DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
@ -15736,27 +15820,24 @@ static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewp
for (int i = 0; i != g.Windows.Size; i++)
{
ImGuiWindow* thumb_window = g.Windows[i];
if (!thumb_window->WasActive || ((thumb_window->Flags & ImGuiWindowFlags_ChildWindow)))
continue;
if (thumb_window->SkipItems && (thumb_window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME-DOCK: Skip hidden docked windows. Identify those betters.
if (!thumb_window->WasActive || (thumb_window->Flags & ImGuiWindowFlags_ChildWindow))
continue;
if (thumb_window->Viewport != viewport)
continue;
ImRect thumb_r = thumb_window->Rect();
ImRect title_r = thumb_window->TitleBarRect();
ImRect thumb_r_scaled = ImRect(ImFloor(off + thumb_r.Min * scale), ImFloor(off + thumb_r.Max * scale));
ImRect title_r_scaled = 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
thumb_r_scaled.ClipWithFull(bb);
title_r_scaled.ClipWithFull(bb);
thumb_r = ImRect(ImFloor(off + thumb_r.Min * scale), ImFloor(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
thumb_r.ClipWithFull(bb);
title_r.ClipWithFull(bb);
const bool window_is_focused = (g.NavWindow && thumb_window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight);
window->DrawList->AddRectFilled(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_WindowBg, alpha_mul));
window->DrawList->AddRectFilled(title_r_scaled.Min, title_r_scaled.Max, ImGui::GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg, alpha_mul));
window->DrawList->AddRect(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul));
if (ImGuiWindow* window_for_title = GetWindowForTitleDisplay(thumb_window))
window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r_scaled.Min, ImGui::GetColorU32(ImGuiCol_Text, alpha_mul), window_for_title->Name, ImGui::FindRenderedTextEnd(window_for_title->Name));
window->DrawList->AddRectFilled(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_WindowBg, alpha_mul));
window->DrawList->AddRectFilled(title_r.Min, title_r.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg, alpha_mul));
window->DrawList->AddRect(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_Border, alpha_mul));
window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r.Min, GetColorU32(ImGuiCol_Text, alpha_mul), thumb_window->Name, FindRenderedTextEnd(thumb_window->Name));
}
draw_list->AddRect(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul));
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border, alpha_mul));
}
static void RenderViewportsThumbnails()
@ -15766,24 +15847,27 @@ static void RenderViewportsThumbnails()
// We don't display full monitor bounds (we could, but it often looks awkward), instead we display just enough to cover all of our viewports.
float SCALE = 1.0f / 8.0f;
ImRect bb_full;
//for (int n = 0; n < g.PlatformIO.Monitors.Size; n++)
// bb_full.Add(GetPlatformMonitorMainRect(g.PlatformIO.Monitors[n]));
ImRect bb_full(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
for (int n = 0; n < g.Viewports.Size; n++)
bb_full.Add(g.Viewports[n]->GetMainRect());
ImVec2 p = window->DC.CursorPos;
ImVec2 off = p - bb_full.Min * SCALE;
//for (int n = 0; n < g.PlatformIO.Monitors.Size; n++)
// window->DrawList->AddRect(off + g.PlatformIO.Monitors[n].MainPos * SCALE, off + (g.PlatformIO.Monitors[n].MainPos + g.PlatformIO.Monitors[n].MainSize) * SCALE, ImGui::GetColorU32(ImGuiCol_Border));
for (int n = 0; n < g.Viewports.Size; n++)
{
ImGuiViewportP* viewport = g.Viewports[n];
ImRect viewport_draw_bb(off + (viewport->Pos) * SCALE, off + (viewport->Pos + viewport->Size) * SCALE);
RenderViewportThumbnail(window->DrawList, viewport, viewport_draw_bb);
ImGui::DebugRenderViewportThumbnail(window->DrawList, viewport, viewport_draw_bb);
}
ImGui::Dummy(bb_full.GetSize() * SCALE);
}
static int IMGUI_CDECL ViewportComparerByFrontMostStampCount(const void* lhs, const void* rhs)
{
const ImGuiViewportP* a = *(const ImGuiViewportP* const *)lhs;
const ImGuiViewportP* b = *(const ImGuiViewportP* const *)rhs;
return b->LastFrontMostStampCount - a->LastFrontMostStampCount;
}
// Avoid naming collision with imgui_demo.cpp's HelpMarker() for unity builds.
static void MetricsHelpMarker(const char* desc)
{
@ -15942,16 +16026,41 @@ void ImGui::ShowMetricsWindow(bool* p_open)
TreePop();
}
// Contents
// Windows
DebugNodeWindowsList(&g.Windows, "Windows");
//DebugNodeWindowsList(&g.WindowsFocusOrder, "WindowsFocusOrder");
// DrawLists
int drawlist_count = 0;
for (int viewport_i = 0; viewport_i < g.Viewports.Size; viewport_i++)
drawlist_count += g.Viewports[viewport_i]->DrawDataBuilder.GetDrawListCount();
if (TreeNode("DrawLists", "DrawLists (%d)", drawlist_count))
{
for (int viewport_i = 0; viewport_i < g.Viewports.Size; viewport_i++)
{
ImGuiViewportP* viewport = g.Viewports[viewport_i];
bool viewport_has_drawlist = false;
for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++)
for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++)
{
if (!viewport_has_drawlist)
Text("Active DrawLists in Viewport #%d, ID: 0x%08X", viewport->Idx, viewport->ID);
viewport_has_drawlist = true;
DebugNodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList");
}
}
TreePop();
}
// Viewports
if (TreeNode("Viewports", "Viewports (%d)", g.Viewports.Size))
{
Indent(GetTreeNodeToLabelSpacing());
RenderViewportsThumbnails();
Unindent(GetTreeNodeToLabelSpacing());
bool open = TreeNode("Monitors", "Monitors (%d)", g.PlatformIO.Monitors.Size);
ImGui::SameLine();
SameLine();
MetricsHelpMarker("Dear ImGui uses monitor data:\n- to query DPI settings on a per monitor basis\n- to position popup/tooltips so they don't straddle monitors.");
if (open)
{
@ -15965,6 +16074,19 @@ void ImGui::ShowMetricsWindow(bool* p_open)
}
TreePop();
}
if (TreeNode("Inferred order (front-to-back)"))
{
static ImVector<ImGuiViewportP*> viewports;
viewports.resize(g.Viewports.Size);
memcpy(viewports.Data, g.Viewports.Data, g.Viewports.size_in_bytes());
if (viewports.Size > 1)
ImQsort(viewports.Data, viewports.Size, sizeof(ImGuiViewport*), ViewportComparerByFrontMostStampCount);
for (int i = 0; i < viewports.Size; i++)
BulletText("Viewport #%d, ID: 0x%08X, FrontMostStampCount = %08d, Window: \"%s\"", viewports[i]->Idx, viewports[i]->ID, viewports[i]->LastFrontMostStampCount, viewports[i]->Window ? viewports[i]->Window->Name : "N/A");
TreePop();
}
for (int i = 0; i < g.Viewports.Size; i++)
DebugNodeViewport(g.Viewports[i]);
TreePop();
@ -16058,14 +16180,14 @@ void ImGui::ShowMetricsWindow(bool* p_open)
#endif // #ifdef IMGUI_HAS_TABLE
#ifdef IMGUI_HAS_DOCK
if (ImGui::TreeNode("SettingsDocking", "Settings packed data: Docking"))
if (TreeNode("SettingsDocking", "Settings packed data: Docking"))
{
ImGuiDockContext* dc = &g.DockContext;
ImGui::Text("In SettingsWindows:");
Text("In SettingsWindows:");
for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
if (settings->DockId != 0)
ImGui::BulletText("Window '%s' -> DockId %08X", settings->GetName(), settings->DockId);
ImGui::Text("In SettingsNodes:");
BulletText("Window '%s' -> DockId %08X", settings->GetName(), settings->DockId);
Text("In SettingsNodes:");
for (int n = 0; n < dc->NodesSettings.Size; n++)
{
ImGuiDockNodeSettings* settings = &dc->NodesSettings[n];
@ -16077,9 +16199,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
else if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->SelectedWindowId))
selected_tab_name = window_settings->GetName();
}
ImGui::BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings->ID, settings->ParentNodeId, settings->SelectedWindowId, selected_tab_name ? selected_tab_name : settings->SelectedWindowId ? "N/A" : "");
BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings->ID, settings->ParentNodeId, settings->SelectedWindowId, selected_tab_name ? selected_tab_name : settings->SelectedWindowId ? "N/A" : "");
}
ImGui::TreePop();
TreePop();
}
#endif // #ifdef IMGUI_HAS_DOCK
@ -16190,7 +16312,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
char buf[64] = "";
char* p = buf;
ImGuiDockNode* node = g.HoveredDockNode;
ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport());
ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport());
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode() ? " *CentralNode*" : "");
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "WindowClass: %08X\n", node->WindowClass.ClassId);
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y);
@ -16462,12 +16584,21 @@ void ImGui::DebugNodeViewport(ImGuiViewportP* viewport)
viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y,
viewport->WorkOffsetMin.x, viewport->WorkOffsetMin.y, viewport->WorkOffsetMax.x, viewport->WorkOffsetMax.y,
viewport->PlatformMonitor, viewport->DpiScale * 100.0f);
if (viewport->Idx > 0) { SameLine(); if (SmallButton("Reset Pos")) { viewport->Pos = ImVec2(200,200); if (viewport->Window) viewport->Window->Pos = ImVec2(200,200); } }
BulletText("Flags: 0x%04X =%s%s%s%s%s%s%s", viewport->Flags,
(flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : "", (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "",
(flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "", (flags & ImGuiViewportFlags_NoInputs) ? " NoInputs" : "",
(flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "", (flags & ImGuiViewportFlags_Minimized) ? " Minimized" : "",
(flags & ImGuiViewportFlags_NoAutoMerge) ? " NoAutoMerge" : "");
if (viewport->Idx > 0) { SameLine(); if (SmallButton("Reset Pos")) { viewport->Pos = ImVec2(200, 200); viewport->UpdateWorkRect(); if (viewport->Window) viewport->Window->Pos = viewport->Pos; } }
BulletText("Flags: 0x%04X =%s%s%s%s%s%s%s%s%s%s%s%s", viewport->Flags,
//(flags & ImGuiViewportFlags_IsPlatformWindow) ? " IsPlatformWindow" : "", // Omitting because it is the standard
(flags & ImGuiViewportFlags_IsPlatformMonitor) ? " IsPlatformMonitor" : "",
(flags & ImGuiViewportFlags_OwnedByApp) ? " OwnedByApp" : "",
(flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "",
(flags & ImGuiViewportFlags_NoTaskBarIcon) ? " NoTaskBarIcon" : "",
(flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "",
(flags & ImGuiViewportFlags_NoFocusOnClick) ? " NoFocusOnClick" : "",
(flags & ImGuiViewportFlags_NoInputs) ? " NoInputs" : "",
(flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "",
(flags & ImGuiViewportFlags_TopMost) ? " TopMost" : "",
(flags & ImGuiViewportFlags_Minimized) ? " Minimized" : "",
(flags & ImGuiViewportFlags_NoAutoMerge) ? " NoAutoMerge" : "",
(flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : "");
for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++)
for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++)
DebugNodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList");

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80
// dear imgui, v1.81
// (headers)
// Help:
@ -31,7 +31,8 @@ Index of this file:
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
// [SECTION] Platform interface for multi-viewport support (ImGuiPlatformIO, ImGuiPlatformMonitor, ImGuiViewportFlags, ImGuiViewport)
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
// [SECTION] Platform interface for multi-viewport support (ImGuiPlatformIO, ImGuiPlatformMonitor)
*/
@ -59,8 +60,8 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.80"
#define IMGUI_VERSION_NUM 18000
#define IMGUI_VERSION "1.81"
#define IMGUI_VERSION_NUM 18100
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
@ -128,6 +129,7 @@ struct ImDrawListSplitter; // Helper to split a draw list into differen
struct ImDrawVert; // A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT)
struct ImFont; // Runtime data for a single font within a parent ImFontAtlas
struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
struct ImFontBuilderIO; // Opaque interface to a font builder (stb_truetype or FreeType).
struct ImFontConfig; // Configuration data when adding a font or merging fonts
struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data
@ -147,7 +149,7 @@ struct ImGuiTableSortSpecs; // Sorting specifications for a table (often
struct ImGuiTableColumnSortSpecs; // Sorting specification for one column of a table
struct ImGuiTextBuffer; // Helper to hold and append into a text buffer (~string builder)
struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]")
struct ImGuiViewport; // Viewport (generally ~1 per window to output to at the OS level. Need per-platform support to use multiple viewports)
struct ImGuiViewport; // A Platform Window (always 1 unless multi-viewport are enabled. One per platform window to output to). In the future may represent Platform Monitor
struct ImGuiWindowClass; // Window class (rare/advanced uses: provide hints to the platform backend via altered viewport flags and parent/child info)
// Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file)
@ -325,11 +327,11 @@ namespace ImGui
IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags=0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. NB: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that! Please read the FAQ!
IMGUI_API ImDrawList* GetWindowDrawList(); // get draw list associated to the current window, to append your own drawing primitives
IMGUI_API float GetWindowDpiScale(); // get DPI scale currently associated to the current window's viewport.
IMGUI_API ImGuiViewport*GetWindowViewport(); // get viewport currently associated to the current window.
IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList API)
IMGUI_API ImVec2 GetWindowSize(); // get current window size
IMGUI_API float GetWindowWidth(); // get current window width (shortcut for GetWindowSize().x)
IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y)
IMGUI_API ImGuiViewport*GetWindowViewport(); // get viewport currently associated to the current window.
// Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin).
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0, 0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc.
@ -386,7 +388,7 @@ namespace ImGui
IMGUI_API void PopButtonRepeat();
// Parameters stacks (current window)
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side). 0.0f = default to ~2/3 of windows width,
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side).
IMGUI_API void PopItemWidth();
IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side)
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
@ -425,8 +427,8 @@ namespace ImGui
IMGUI_API void SetCursorPosX(float local_x); // GetWindowPos() + GetCursorPos() == GetCursorScreenPos() etc.)
IMGUI_API void SetCursorPosY(float local_y); //
IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position in window coordinates
IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates (0..io.DisplaySize) or natural OS coordinates when using multiple viewport. Useful to work with ImDrawList API.
IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates (0..io.DisplaySize) or natural OS coordinates when using multiple viewport.
IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute coordinates (useful to work with ImDrawList API). generally top-left == GetMainViewport()->Pos == (0,0) in single viewport mode, and bottom-right == GetMainViewport()->Pos+Size == io.DisplaySize in single-viewport mode.
IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute coordinates
IMGUI_API void AlignTextToFramePadding(); // vertically align upcoming text baseline to FramePadding.y so that it will align properly to regularly framed items (call if you have text on a line before a framed item)
IMGUI_API float GetTextLineHeight(); // ~ FontSize
IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text)
@ -483,7 +485,7 @@ namespace ImGui
// Widgets: Combo Box
// - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items.
// - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose.
// - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. This is analogous to how ListBox are created.
IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0);
IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true!
IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1);
@ -590,14 +592,18 @@ namespace ImGui
IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper.
// Widgets: List Boxes
// - FIXME: To be consistent with all the newer API, ListBoxHeader/ListBoxFooter should in reality be called BeginListBox/EndListBox. Will rename them.
// - This is essentially a thin wrapper to using BeginChild/EndChild with some stylistic changes.
// - The BeginListBox()/EndListBox() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() or any items.
// - The simplified/old ListBox() api are helpers over BeginListBox()/EndListBox() which are kept available for convenience purpose. This is analoguous to how Combos are created.
// - Choose frame width: size.x > 0.0f: custom / size.x < 0.0f or -FLT_MIN: right-align / size.x = 0.0f (default): use current ItemWidth
// - Choose frame height: size.y > 0.0f: custom / size.y < 0.0f or -FLT_MIN: bottom-align / size.y = 0.0f (default): arbitrary default height which can fit ~7 items
IMGUI_API bool BeginListBox(const char* label, const ImVec2& size = ImVec2(0, 0)); // open a framed scrolling region
IMGUI_API void EndListBox(); // only call EndListBox() if BeginListBox() returned true!
IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)); // use if you want to reimplement ListBox() will custom data or interactions. if the function return true, you can output elements then call ListBoxFooter() afterwards.
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // "
IMGUI_API void ListBoxFooter(); // terminate the scrolling region. only call ListBoxFooter() if ListBoxHeader() returned true!
// Widgets: Data Plotting
// - Consider using ImPlot (https://github.com/epezent/implot)
IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
IMGUI_API void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0));
IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
@ -754,7 +760,7 @@ namespace ImGui
// - Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details.
// - DockSpace() needs to be submitted _before_ any window they can host. If you use a dockspace, submit it early in your app.
IMGUI_API void DockSpace(ImGuiID id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL);
IMGUI_API ImGuiID DockSpaceOverViewport(ImGuiViewport* viewport = NULL, ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL);
IMGUI_API ImGuiID DockSpaceOverViewport(const ImGuiViewport* viewport = NULL, ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL);
IMGUI_API void SetNextWindowDockID(ImGuiID dock_id, ImGuiCond cond = 0); // set next window dock id (FIXME-DOCK)
IMGUI_API void SetNextWindowClass(const ImGuiWindowClass* window_class); // set next window class (rare/advanced uses: provide hints to the platform backend via altered viewport flags and parent/child info)
IMGUI_API ImGuiID GetWindowDockID();
@ -810,6 +816,12 @@ namespace ImGui
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area.
// Viewports
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
// - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports.
// - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode.
IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport.
// Miscellaneous Utilities
IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped.
IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side.
@ -893,7 +905,7 @@ namespace ImGui
// Read comments around the ImGuiPlatformIO structure for more details.
// Note: You may use GetWindowViewport() to get the current viewport of the current window.
IMGUI_API ImGuiPlatformIO& GetPlatformIO(); // platform/renderer functions, for backend to setup + viewports list.
IMGUI_API ImGuiViewport* GetMainViewport(); // main viewport. same as GetPlatformIO().MainViewport == GetPlatformIO().Viewports[0].
IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport. In the future in "no main platform window" mode we will direct this to primary monitor.
IMGUI_API void UpdatePlatformWindows(); // call in main loop. will call CreateWindow/ResizeWindow/etc. platform functions for each secondary viewport, and DestroyWindow for each inactive viewport.
IMGUI_API void RenderPlatformWindowsDefault(void* platform_render_arg = NULL, void* renderer_render_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport which doesn't have the ImGuiViewportFlags_Minimized flag set. May be reimplemented by user for custom rendering needs.
IMGUI_API void DestroyPlatformWindows(); // call DestroyWindow platform functions for all viewports. call from backend Shutdown() if you need to close platform windows before imgui shutdown. otherwise will be called by DestroyContext().
@ -1128,7 +1140,7 @@ enum ImGuiTableFlags_
ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width.
ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible.
ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.
ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overriden by TableSetupColumn().
ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overridden by TableSetupColumn().
// Sizing Extra Options
ImGuiTableFlags_NoHostExtendX = 1 << 16, // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
ImGuiTableFlags_NoHostExtendY = 1 << 17, // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
@ -1806,7 +1818,7 @@ struct ImGuiIO
ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc.
ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend.
ImVec2 DisplaySize; // <unset> // Main display size, in pixels. This is for the default viewport.
ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size)
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory.
@ -2064,6 +2076,10 @@ struct ImGuiTableSortSpecs
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui
{
// OBSOLETED in 1.81 (from February 2021)
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items
static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); }
static inline void ListBoxFooter() { EndListBox(); }
// OBSOLETED in 1.79 (from August 2020)
static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry!
// OBSOLETED in 1.78 (from June 2020)
@ -2430,7 +2446,8 @@ enum ImDrawListFlags_
// Each dear imgui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to
// access the current window draw list and draw custom primitives.
// You can interleave normal ImGui:: calls and adding primitives to the current draw list.
// All positions are generally in pixel coordinates (generally top-left at 0,0, bottom-right at io.DisplaySize, unless multiple viewports are used), but you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well)
// In single viewport mode, top-left is == GetMainViewport()->Pos (generally 0,0), bottom-right is == GetMainViewport()->Pos+Size (generally io.DisplaySize).
// You are totally free to apply whatever transformation matrix to want to the data (depending on the use of the transformation you may want to apply it to ClipRect as well!)
// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects.
struct ImDrawList
{
@ -2505,9 +2522,9 @@ struct ImDrawList
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } // Note: Anti-aliased filling requires points to be in clockwise order.
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); _Path.Size = 0; }
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 10);
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All);
// Advanced
@ -2557,19 +2574,18 @@ struct ImDrawList
struct ImDrawData
{
bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.
ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here.
int CmdListsCount; // Number of ImDrawList* to render
int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size
int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
ImVec2 DisplayPos; // Upper-left position of the viewport to render (== upper-left of the orthogonal projection matrix to use)
ImVec2 DisplaySize; // Size of the viewport to render (== io.DisplaySize for the main viewport) (DisplayPos + DisplaySize == lower-right of the orthogonal projection matrix to use)
ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here.
ImVec2 DisplayPos; // Top-left position of the viewport to render (== top-left of the orthogonal projection matrix to use) (== GetMainViewport()->Pos for the main viewport, == (0.0) in most single-viewport applications)
ImVec2 DisplaySize; // Size of the viewport to render (== GetMainViewport()->Size for the main viewport, == io.DisplaySize in most single-viewport applications)
ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Based on io.DisplayFramebufferScale. Generally (1,1) on normal display, (2,2) on OSX with Retina display.
ImGuiViewport* OwnerViewport; // Viewport carrying the ImDrawData instance, might be of use to the renderer (generally not).
// Functions
ImDrawData() { Valid = false; Clear(); }
~ImDrawData() { Clear(); }
void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; DisplayPos = DisplaySize = FramebufferScale = ImVec2(0.f, 0.f); OwnerViewport = NULL; } // The ImDrawList are owned by ImGuiContext!
ImDrawData() { Clear(); }
void Clear() { memset(this, 0, sizeof(*this)); } // The ImDrawList are owned by ImGuiContext!
IMGUI_API void DeIndexAllBuffers(); // Helper to convert all buffers from indexed to non-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
IMGUI_API void ScaleClipRects(const ImVec2& fb_scale); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than Dear ImGui expects, or if there is a difference between your window resolution and framebuffer resolution.
};
@ -2585,8 +2601,8 @@ struct ImFontConfig
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
int FontNo; // 0 // Index of font within TTF/OTF file
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal so you can reduce this to 2 to save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. This is not really useful as we don't use sub-pixel positions on the Y axis.
bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
@ -2594,7 +2610,7 @@ struct ImFontConfig
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
unsigned int RasterizerFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one.
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable.
ImWchar EllipsisChar; // -1 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
@ -2609,8 +2625,9 @@ struct ImFontConfig
// (Note: some language parsers may fail to convert the 31+1 bitfield members, in this case maybe drop store a single u32 or we can rework this)
struct ImFontGlyph
{
unsigned int Codepoint : 31; // 0x0000..0xFFFF
unsigned int Visible : 1; // Flag to allow early out when rendering
unsigned int Colored : 1; // Flag to indicate glyph is colored and should generally ignore tinting (make it usable with no shift on little-endian as this is used in loops)
unsigned int Visible : 1; // Flag to indicate glyph has no visible pixels (e.g. space). Allow early out when rendering.
unsigned int Codepoint : 30; // 0x0000..0x10FFFF
float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in)
float X0, Y0, X1, Y1; // Glyph corners
float U0, V0, U1, V1; // Texture coordinates
@ -2754,6 +2771,10 @@ struct ImFontAtlas
ImVector<ImFontConfig> ConfigData; // Configuration data
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
// [Internal] Font builder
const ImFontBuilderIO* FontBuilderIO; // Opaque interface to a font builder (default to stb_truetype, can be changed to use FreeType by defining IMGUI_ENABLE_FREETYPE).
unsigned int FontBuilderFlags; // Shared flags (for all fonts) for custom font builder. THIS IS BUILD IMPLEMENTATION DEPENDENT. Per-font override is also available in ImFontConfig.
// [Internal] Packing data
int PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors
int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines
@ -2817,6 +2838,68 @@ struct ImFont
IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last);
};
//-----------------------------------------------------------------------------
// [SECTION] Viewports
//-----------------------------------------------------------------------------
// Flags stored in ImGuiViewport::Flags, giving indications to the platform backends.
enum ImGuiViewportFlags_
{
ImGuiViewportFlags_None = 0,
ImGuiViewportFlags_IsPlatformWindow = 1 << 0, // Represent a Platform Window
ImGuiViewportFlags_IsPlatformMonitor = 1 << 1, // Represent a Platform Monitor (unused yet)
ImGuiViewportFlags_OwnedByApp = 1 << 2, // Platform Window: is created/managed by the application (rather than a dear imgui backend)
ImGuiViewportFlags_NoDecoration = 1 << 3, // Platform Window: Disable platform decorations: title bar, borders, etc. (generally set all windows, but if ImGuiConfigFlags_ViewportsDecoration is set we only set this on popups/tooltips)
ImGuiViewportFlags_NoTaskBarIcon = 1 << 4, // Platform Window: Disable platform task bar icon (generally set on popups/tooltips, or all windows if ImGuiConfigFlags_ViewportsNoTaskBarIcon is set)
ImGuiViewportFlags_NoFocusOnAppearing = 1 << 5, // Platform Window: Don't take focus when created.
ImGuiViewportFlags_NoFocusOnClick = 1 << 6, // Platform Window: Don't take focus when clicked on.
ImGuiViewportFlags_NoInputs = 1 << 7, // Platform Window: Make mouse pass through so we can drag this window while peaking behind it.
ImGuiViewportFlags_NoRendererClear = 1 << 8, // Platform Window: Renderer doesn't need to clear the framebuffer ahead (because we will fill it entirely).
ImGuiViewportFlags_TopMost = 1 << 9, // Platform Window: Display on top (for tooltips only).
ImGuiViewportFlags_Minimized = 1 << 10, // Platform Window: Window is minimized, can skip render. When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport.
ImGuiViewportFlags_NoAutoMerge = 1 << 11, // Platform Window: Avoid merging this window into another host window. This can only be set via ImGuiWindowClass viewport flags override (because we need to now ahead if we are going to create a viewport in the first place!).
ImGuiViewportFlags_CanHostOtherWindows = 1 << 12 // Main viewport: can host multiple imgui windows (secondary viewports are associated to a single window).
};
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
// - With multi-viewport enabled, we extend this concept to have multiple active viewports.
// - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode.
// - About Main Area vs Work Area:
// - Main Area = entire viewport.
// - Work Area = entire viewport minus sections used by main menu bars (for platform windows), or by task bar (for platform monitor).
// - Windows are generally trying to stay within the Work Area of their host viewport.
struct ImGuiViewport
{
ImGuiID ID; // Unique identifier for the viewport
ImGuiViewportFlags Flags; // See ImGuiViewportFlags_
ImVec2 Pos; // Main Area: Position of the viewport (Dear Imgui coordinates are the same as OS desktop/native coordinates)
ImVec2 Size; // Main Area: Size of the viewport.
ImVec2 WorkPos; // Work Area: Position of the viewport minus task bars, menus bars, status bars (>= Pos)
ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size)
float DpiScale; // 1.0f = 96 DPI = No extra scale.
ImGuiID ParentViewportId; // (Advanced) 0: no parent. Instruct the platform backend to setup a parent/child relationship between platform windows.
ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame().
// Our design separate the Renderer and Platform backends to facilitate combining default backends with each others.
// When our create your own backend for a custom engine, it is possible that both Renderer and Platform will be handled
// by the same system and you may not need to use all the UserData/Handle fields.
// The library never uses those fields, they are merely storage to facilitate backend implementation.
void* RendererUserData; // void* to hold custom data structure for the renderer (e.g. swap chain, framebuffers etc.). generally set by your Renderer_CreateWindow function.
void* PlatformUserData; // void* to hold custom data structure for the OS / platform (e.g. windowing info, render context). generally set by your Platform_CreateWindow function.
void* PlatformHandle; // void* for FindViewportByPlatformHandle(). (e.g. suggested to use natural platform handle such as HWND, GLFWWindow*, SDL_Window*)
void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (e.g. the HWND) when using an abstraction layer like GLFW or SDL (where PlatformHandle would be a SDL_Window*)
bool PlatformRequestMove; // Platform window requested move (e.g. window was moved by the OS / host window manager, authoritative position will be OS window position)
bool PlatformRequestResize; // Platform window requested resize (e.g. window was resized by the OS / host window manager, authoritative size will be OS window size)
bool PlatformRequestClose; // Platform window requested closure (e.g. window was moved by the OS / host window manager, e.g. pressing ALT-F4)
ImGuiViewport() { memset(this, 0, sizeof(*this)); }
~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); }
// Helpers
ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
ImVec2 GetWorkCenter() const { return ImVec2(WorkPos.x + WorkSize.x * 0.5f, WorkPos.y + WorkSize.y * 0.5f); }
};
//-----------------------------------------------------------------------------
// [SECTION] Platform interface for multi-viewport support
//-----------------------------------------------------------------------------
@ -2925,7 +3008,6 @@ struct ImGuiPlatformIO
// Viewports list (the list is updated by calling ImGui::EndFrame or ImGui::Render)
// (in the future we will attempt to organize this feature to remove the need for a "main viewport")
ImGuiViewport* MainViewport; // Guaranteed to be == Viewports[0]
ImVector<ImGuiViewport*> Viewports; // Main viewports, followed by all secondary viewports.
ImGuiPlatformIO() { memset(this, 0, sizeof(*this)); } // Zero clear
};
@ -2940,57 +3022,7 @@ struct ImGuiPlatformMonitor
ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0, 0); DpiScale = 1.0f; }
};
// Flags stored in ImGuiViewport::Flags, giving indications to the platform backends.
enum ImGuiViewportFlags_
{
ImGuiViewportFlags_None = 0,
ImGuiViewportFlags_NoDecoration = 1 << 0, // Platform Window: Disable platform decorations: title bar, borders, etc. (generally set all windows, but if ImGuiConfigFlags_ViewportsDecoration is set we only set this on popups/tooltips)
ImGuiViewportFlags_NoTaskBarIcon = 1 << 1, // Platform Window: Disable platform task bar icon (generally set on popups/tooltips, or all windows if ImGuiConfigFlags_ViewportsNoTaskBarIcon is set)
ImGuiViewportFlags_NoFocusOnAppearing = 1 << 2, // Platform Window: Don't take focus when created.
ImGuiViewportFlags_NoFocusOnClick = 1 << 3, // Platform Window: Don't take focus when clicked on.
ImGuiViewportFlags_NoInputs = 1 << 4, // Platform Window: Make mouse pass through so we can drag this window while peaking behind it.
ImGuiViewportFlags_NoRendererClear = 1 << 5, // Platform Window: Renderer doesn't need to clear the framebuffer ahead (because we will fill it entirely).
ImGuiViewportFlags_TopMost = 1 << 6, // Platform Window: Display on top (for tooltips only).
ImGuiViewportFlags_Minimized = 1 << 7, // Platform Window: Window is minimized, can skip render. When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport.
ImGuiViewportFlags_NoAutoMerge = 1 << 8, // Platform Window: Avoid merging this window into another host window. This can only be set via ImGuiWindowClass viewport flags override (because we need to now ahead if we are going to create a viewport in the first place!).
ImGuiViewportFlags_CanHostOtherWindows = 1 << 9 // Main viewport: can host multiple imgui windows (secondary viewports are associated to a single window).
};
// The viewports created and managed by Dear ImGui. The role of the platform backend is to create the platform/OS windows corresponding to each viewport.
// - Main Area = entire viewport.
// - Work Area = entire viewport minus sections optionally used by menu bars, status bars. Some positioning code will prefer to use this. Window are also trying to stay within this area.
struct ImGuiViewport
{
ImGuiID ID; // Unique identifier for the viewport
ImGuiViewportFlags Flags; // See ImGuiViewportFlags_
ImVec2 Pos; // Main Area: Position of the viewport (the imgui coordinates are the same as OS desktop/native coordinates)
ImVec2 Size; // Main Area: Size of the viewport.
ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!)
ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height).
float DpiScale; // 1.0f = 96 DPI = No extra scale.
ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame().
ImGuiID ParentViewportId; // (Advanced) 0: no parent. Instruct the platform backend to setup a parent/child relationship between platform windows.
// Our design separate the Renderer and Platform backends to facilitate combining default backends with each others.
// When our create your own backend for a custom engine, it is possible that both Renderer and Platform will be handled
// by the same system and you may not need to use all the UserData/Handle fields.
// The library never uses those fields, they are merely storage to facilitate backend implementation.
void* RendererUserData; // void* to hold custom data structure for the renderer (e.g. swap chain, framebuffers etc.). generally set by your Renderer_CreateWindow function.
void* PlatformUserData; // void* to hold custom data structure for the OS / platform (e.g. windowing info, render context). generally set by your Platform_CreateWindow function.
void* PlatformHandle; // void* for FindViewportByPlatformHandle(). (e.g. suggested to use natural platform handle such as HWND, GLFWWindow*, SDL_Window*)
void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (e.g. the HWND) when using an abstraction layer like GLFW or SDL (where PlatformHandle would be a SDL_Window*)
bool PlatformRequestMove; // Platform window requested move (e.g. window was moved by the OS / host window manager, authoritative position will be OS window position)
bool PlatformRequestResize; // Platform window requested resize (e.g. window was resized by the OS / host window manager, authoritative size will be OS window size)
bool PlatformRequestClose; // Platform window requested closure (e.g. window was moved by the OS / host window manager, e.g. pressing ALT-F4)
ImGuiViewport() { ID = 0; Flags = 0; DpiScale = 0.0f; DrawData = NULL; ParentViewportId = 0; RendererUserData = PlatformUserData = PlatformHandle = PlatformHandleRaw = NULL; PlatformRequestMove = PlatformRequestResize = PlatformRequestClose = false; }
~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); }
// Access work-area rectangle with GetWorkXXX functions (see comments above)
ImVec2 GetCenter() { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
ImVec2 GetWorkPos() { return ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); }
ImVec2 GetWorkSize() { return ImVec2(Size.x - WorkOffsetMin.x + WorkOffsetMax.x, Size.y - WorkOffsetMin.y + WorkOffsetMax.y); } // This not clamped
};
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80
// dear imgui, v1.81
// (demo code)
// Help:
@ -63,8 +63,9 @@ Index of this file:
// [SECTION] Example App: Long Text / ShowExampleAppLongText()
// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize()
// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize()
// [SECTION] Example App: Simple Overlay / ShowExampleAppSimpleOverlay()
// [SECTION] Example App: Manipulating Window Titles / ShowExampleAppWindowTitles()
// [SECTION] Example App: Simple overlay / ShowExampleAppSimpleOverlay()
// [SECTION] Example App: Fullscreen window / ShowExampleAppFullscreen()
// [SECTION] Example App: Manipulating window titles / ShowExampleAppWindowTitles()
// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering()
// [SECTION] Example App: Docking, DockSpace / ShowExampleAppDockSpace()
// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments()
@ -170,6 +171,7 @@ static void ShowExampleAppLongText(bool* p_open);
static void ShowExampleAppAutoResize(bool* p_open);
static void ShowExampleAppConstrainedResize(bool* p_open);
static void ShowExampleAppSimpleOverlay(bool* p_open);
static void ShowExampleAppFullscreen(bool* p_open);
static void ShowExampleAppWindowTitles(bool* p_open);
static void ShowExampleAppCustomRendering(bool* p_open);
static void ShowExampleMenuFile();
@ -273,6 +275,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
static bool show_app_auto_resize = false;
static bool show_app_constrained_resize = false;
static bool show_app_simple_overlay = false;
static bool show_app_fullscreen = false;
static bool show_app_window_titles = false;
static bool show_app_custom_rendering = false;
@ -288,6 +291,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize);
if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize);
if (show_app_simple_overlay) ShowExampleAppSimpleOverlay(&show_app_simple_overlay);
if (show_app_fullscreen) ShowExampleAppFullscreen(&show_app_fullscreen);
if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles);
if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering);
@ -333,8 +337,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
// We specify a default position/size in case there's no data in the .ini file.
// We only do it to make the demo applications a little more welcoming, but typically this isn't required.
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(ImVec2(main_viewport->GetWorkPos().x + 650, main_viewport->GetWorkPos().y + 20), ImGuiCond_FirstUseEver);
const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver);
// Main body of the Demo window starts here.
@ -372,6 +376,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize);
ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize);
ImGui::MenuItem("Simple overlay", NULL, &show_app_simple_overlay);
ImGui::MenuItem("Fullscreen window", NULL, &show_app_fullscreen);
ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles);
ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering);
ImGui::MenuItem("Dockspace", NULL, &show_app_dockspace);
@ -640,13 +645,12 @@ static void ShowDemoWindowWidgets()
{
// Using the _simplified_ one-liner Combo() api here
// See "Combo" section for examples of how to use the more complete BeginCombo()/EndCombo() api.
// See "Combo" section for examples of how to use the more flexible BeginCombo()/EndCombo() api.
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIIIIII", "JJJJ", "KKKKKKK" };
static int item_current = 0;
ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items));
ImGui::SameLine(); HelpMarker(
"Refer to the \"Combo\" section below for an explanation of the full BeginCombo/EndCombo API, "
"and demonstration of various flags.\n");
"Using the simplified one-liner Combo API here.\nRefer to the \"Combo\" section below for an explanation of how to use the more flexible and general BeginCombo/EndCombo API.");
}
{
@ -745,14 +749,13 @@ static void ShowDemoWindowWidgets()
}
{
// List box
// Using the _simplified_ one-liner ListBox() api here
// See "List boxes" section for examples of how to use the more flexible BeginListBox()/EndListBox() api.
const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" };
static int item_current = 1;
ImGui::ListBox("listbox\n(single select)", &item_current, items, IM_ARRAYSIZE(items), 4);
//static int listbox_item_current2 = 2;
//ImGui::SetNextItemWidth(-1);
//ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
ImGui::ListBox("listbox", &item_current, items, IM_ARRAYSIZE(items), 4);
ImGui::SameLine(); HelpMarker(
"Using the simplified one-liner ListBox API here.\nRefer to the \"List boxes\" section below for an explanation of how to use the more flexible and general BeginListBox/EndListBox API.");
}
ImGui::TreePop();
@ -1065,7 +1068,7 @@ static void ShowDemoWindowWidgets()
// (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively
// stored in the object itself, etc.)
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
static int item_current_idx = 0; // Here our selection data is an index.
static int item_current_idx = 0; // Here we store our selection data as an index.
const char* combo_label = items[item_current_idx]; // Label to preview before opening the combo (technically it could be anything)
if (ImGui::BeginCombo("combo 1", combo_label, flags))
{
@ -1098,6 +1101,48 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
if (ImGui::TreeNode("List boxes"))
{
// Using the generic BeginListBox() API, you have full control over how to display the combo contents.
// (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively
// stored in the object itself, etc.)
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
static int item_current_idx = 0; // Here we store our selection data as an index.
if (ImGui::BeginListBox("listbox 1"))
{
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
{
const bool is_selected = (item_current_idx == n);
if (ImGui::Selectable(items[n], is_selected))
item_current_idx = n;
// Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
if (is_selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndListBox();
}
// Custom size: use all width, 5 items tall
ImGui::Text("Full-width:");
if (ImGui::BeginListBox("##listbox 2", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing())))
{
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
{
const bool is_selected = (item_current_idx == n);
if (ImGui::Selectable(items[n], is_selected))
item_current_idx = n;
// Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
if (is_selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndListBox();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Selectables"))
{
// Selectable() has 2 overloads:
@ -2616,11 +2661,11 @@ static void ShowDemoWindowLayout()
ImGui::Button("LEVERAGE\nBUZZWORD", size);
ImGui::SameLine();
if (ImGui::ListBoxHeader("List", size))
if (ImGui::BeginListBox("List", size))
{
ImGui::Selectable("Selected", true);
ImGui::Selectable("Not Selected", false);
ImGui::ListBoxFooter();
ImGui::EndListBox();
}
ImGui::TreePop();
@ -3205,7 +3250,7 @@ static void ShowDemoWindowPopups()
{
if (ImGui::Selectable("Set to zero")) value = 0.0f;
if (ImGui::Selectable("Set to PI")) value = 3.1415f;
ImGui::SetNextItemWidth(-1);
ImGui::SetNextItemWidth(-FLT_MIN);
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
ImGui::EndPopup();
}
@ -3246,9 +3291,6 @@ static void ShowDemoWindowPopups()
// Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
//ImVec2 parent_pos = ImGui::GetWindowPos();
//ImVec2 parent_size = ImGui::GetWindowSize();
//ImVec2 center(parent_pos.x + parent_size.x * 0.5f, parent_pos.y + parent_size.y * 0.5f);
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize))
@ -4311,7 +4353,7 @@ static void ShowDemoWindowTables()
ImGui::TableHeadersRow();
ImGui::TableNextColumn();
ImGui::Text("A0 Cell 0");
ImGui::Text("A0 Row 0");
{
float rows_height = TEXT_BASE_HEIGHT * 2;
if (ImGui::BeginTable("table_nested2", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
@ -4322,21 +4364,21 @@ static void ShowDemoWindowTables()
ImGui::TableNextRow(ImGuiTableRowFlags_None, rows_height);
ImGui::TableNextColumn();
ImGui::Text("B0 Cell 0");
ImGui::Text("B0 Row 0");
ImGui::TableNextColumn();
ImGui::Text("B0 Cell 1");
ImGui::Text("B1 Row 0");
ImGui::TableNextRow(ImGuiTableRowFlags_None, rows_height);
ImGui::TableNextColumn();
ImGui::Text("B1 Cell 0");
ImGui::Text("B0 Row 1");
ImGui::TableNextColumn();
ImGui::Text("B1 Cell 1");
ImGui::Text("B1 Row 1");
ImGui::EndTable();
}
}
ImGui::TableNextColumn(); ImGui::Text("A0 Cell 1");
ImGui::TableNextColumn(); ImGui::Text("A1 Cell 0");
ImGui::TableNextColumn(); ImGui::Text("A1 Cell 1");
ImGui::TableNextColumn(); ImGui::Text("A1 Row 0");
ImGui::TableNextColumn(); ImGui::Text("A0 Row 1");
ImGui::TableNextColumn(); ImGui::Text("A1 Row 1");
ImGui::EndTable();
}
ImGui::TreePop();
@ -7016,28 +7058,30 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
}
//-----------------------------------------------------------------------------
// [SECTION] Example App: Simple Overlay / ShowExampleAppSimpleOverlay()
// [SECTION] Example App: Simple overlay / ShowExampleAppSimpleOverlay()
//-----------------------------------------------------------------------------
// Demonstrate creating a simple static window with no decoration
// + a context-menu to choose which corner of the screen to use.
static void ShowExampleAppSimpleOverlay(bool* p_open)
{
// FIXME-VIEWPORT: Select a default viewport
const float DISTANCE = 10.0f;
static int corner = 0;
ImGuiIO& io = ImGui::GetIO();
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
if (corner != -1)
{
window_flags |= ImGuiWindowFlags_NoMove;
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImVec2 work_area_pos = viewport->GetWorkPos(); // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any!
ImVec2 work_area_size = viewport->GetWorkSize();
ImVec2 window_pos = ImVec2((corner & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE));
ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
const float PAD = 10.0f;
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImVec2 work_pos = viewport->WorkPos; // Use work area to avoid menu-bar/task-bar, if any!
ImVec2 work_size = viewport->WorkSize;
ImVec2 window_pos, window_pos_pivot;
window_pos.x = (corner & 1) ? (work_pos.x + work_size.x - PAD) : (work_pos.x + PAD);
window_pos.y = (corner & 2) ? (work_pos.y + work_size.y - PAD) : (work_pos.y + PAD);
window_pos_pivot.x = (corner & 1) ? 1.0f : 0.0f;
window_pos_pivot.y = (corner & 2) ? 1.0f : 0.0f;
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
ImGui::SetNextWindowViewport(viewport->ID);
window_flags |= ImGuiWindowFlags_NoMove;
}
ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background
if (ImGui::Begin("Example: Simple overlay", p_open, window_flags))
@ -7062,6 +7106,42 @@ static void ShowExampleAppSimpleOverlay(bool* p_open)
ImGui::End();
}
//-----------------------------------------------------------------------------
// [SECTION] Example App: Fullscreen window / ShowExampleAppFullscreen()
//-----------------------------------------------------------------------------
// Demonstrate creating a window covering the entire screen/viewport
static void ShowExampleAppFullscreen(bool* p_open)
{
static bool use_work_area = true;
static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings;
// We demonstrate using the full viewport area or the work area (without menu-bars, task-bars etc.)
// Based on your use case you may want one of the other.
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(use_work_area ? viewport->WorkPos : viewport->Pos);
ImGui::SetNextWindowSize(use_work_area ? viewport->WorkSize : viewport->Size);
if (ImGui::Begin("Example: Fullscreen window", p_open, flags))
{
ImGui::Checkbox("Use work area instead of main area", &use_work_area);
ImGui::SameLine();
HelpMarker("Main Area = entire viewport,\nWork Area = entire viewport minus sections used by the main menu bars, task bars etc.\n\nEnable the main-menu bar in Examples menu to see the difference.");
ImGui::CheckboxFlags("ImGuiWindowFlags_NoBackground", &flags, ImGuiWindowFlags_NoBackground);
ImGui::CheckboxFlags("ImGuiWindowFlags_NoDecoration", &flags, ImGuiWindowFlags_NoDecoration);
ImGui::Indent();
ImGui::CheckboxFlags("ImGuiWindowFlags_NoTitleBar", &flags, ImGuiWindowFlags_NoTitleBar);
ImGui::CheckboxFlags("ImGuiWindowFlags_NoCollapse", &flags, ImGuiWindowFlags_NoCollapse);
ImGui::CheckboxFlags("ImGuiWindowFlags_NoScrollbar", &flags, ImGuiWindowFlags_NoScrollbar);
ImGui::Unindent();
if (p_open && ImGui::Button("Close this window"))
*p_open = false;
}
ImGui::End();
}
//-----------------------------------------------------------------------------
// [SECTION] Example App: Manipulating Window Titles / ShowExampleAppWindowTitles()
//-----------------------------------------------------------------------------
@ -7071,16 +7151,19 @@ static void ShowExampleAppSimpleOverlay(bool* p_open)
// Read FAQ section "How can I have multiple widgets with the same label?" for details.
static void ShowExampleAppWindowTitles(bool*)
{
const ImGuiViewport* viewport = ImGui::GetMainViewport();
const ImVec2 base_pos = viewport->Pos;
// By default, Windows are uniquely identified by their title.
// You can use the "##" and "###" markers to manipulate the display/ID.
// Using "##" to display same title but have unique identifier.
ImGui::SetNextWindowPos(ImVec2(100, 100), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 100), ImGuiCond_FirstUseEver);
ImGui::Begin("Same title as another window##1");
ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique.");
ImGui::End();
ImGui::SetNextWindowPos(ImVec2(100, 200), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 200), ImGuiCond_FirstUseEver);
ImGui::Begin("Same title as another window##2");
ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique.");
ImGui::End();
@ -7088,7 +7171,7 @@ static void ShowExampleAppWindowTitles(bool*)
// Using "###" to display a changing title but keep a static identifier "AnimatedTitle"
char buf[128];
sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime() / 0.25f) & 3], ImGui::GetFrameCount());
ImGui::SetNextWindowPos(ImVec2(100, 300), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 300), ImGuiCond_FirstUseEver);
ImGui::Begin(buf);
ImGui::Text("This window has a changing title.");
ImGui::End();
@ -7151,7 +7234,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
static bool curve_segments_override = false;
static int curve_segments_override_v = 8;
static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 100.0f, "%.0f");
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12);
ImGui::Checkbox("##circlesegmentoverride", &circle_segments_override);
@ -7168,6 +7251,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
const ImDrawCornerFlags corners_none = 0;
const ImDrawCornerFlags corners_all = ImDrawCornerFlags_All;
const ImDrawCornerFlags corners_tl_br = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight;
const float rounding = sz / 5.0f;
const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
const int curve_segments = curve_segments_override ? curve_segments_override_v : 0;
float x = p.x + 4.0f;
@ -7179,8 +7263,8 @@ static void ShowExampleAppCustomRendering(bool* p_open)
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_all, th); x += sz + spacing; // Square with all rounded corners
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle
//draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
@ -7368,9 +7452,9 @@ void ShowExampleAppDockSpace(bool* p_open)
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
if (opt_fullscreen)
{
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->GetWorkPos());
ImGui::SetNextWindowSize(viewport->GetWorkSize());
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
@ -7749,19 +7833,20 @@ void ShowExampleAppDocuments(bool* p_open)
{
if (!ImGui::IsPopupOpen("Save?"))
ImGui::OpenPopup("Save?");
if (ImGui::BeginPopupModal("Save?"))
if (ImGui::BeginPopupModal("Save?", NULL, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::Text("Save change to the following items?");
ImGui::SetNextItemWidth(-1.0f);
if (ImGui::ListBoxHeader("##", close_queue_unsaved_documents, 6))
float item_height = ImGui::GetTextLineHeightWithSpacing();
if (ImGui::BeginChildFrame(ImGui::GetID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height)))
{
for (int n = 0; n < close_queue.Size; n++)
if (close_queue[n]->Dirty)
ImGui::Text("%s", close_queue[n]->Name);
ImGui::ListBoxFooter();
ImGui::EndChildFrame();
}
if (ImGui::Button("Yes", ImVec2(80, 0)))
ImVec2 button_size(ImGui::GetFontSize() * 7.0f, 0.0f);
if (ImGui::Button("Yes", button_size))
{
for (int n = 0; n < close_queue.Size; n++)
{
@ -7773,7 +7858,7 @@ void ShowExampleAppDocuments(bool* p_open)
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("No", ImVec2(80, 0)))
if (ImGui::Button("No", button_size))
{
for (int n = 0; n < close_queue.Size; n++)
close_queue[n]->DoForceClose();
@ -7781,7 +7866,7 @@ void ShowExampleAppDocuments(bool* p_open)
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(80, 0)))
if (ImGui::Button("Cancel", button_size))
{
close_queue.clear();
ImGui::CloseCurrentPopup();

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80
// dear imgui, v1.81
// (drawing and font code)
/*
@ -32,7 +32,11 @@ Index of this file:
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include "imgui_internal.h"
#ifdef IMGUI_ENABLE_FREETYPE
#include "misc/freetype/imgui_freetype.h"
#endif
#include <stdio.h> // vsnprintf, sscanf, printf
#if !defined(alloca)
@ -118,7 +122,7 @@ namespace IMGUI_STB_NAMESPACE
#endif
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in another compilation unit
#define STBRP_STATIC
#define STBRP_ASSERT(x) do { IM_ASSERT(x); } while (0)
#define STBRP_SORT ImQsort
@ -131,8 +135,9 @@ namespace IMGUI_STB_NAMESPACE
#endif
#endif
#ifdef IMGUI_ENABLE_STB_TRUETYPE
#ifndef STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in another compilation unit
#define STBTT_malloc(x,u) ((void)(u), IM_ALLOC(x))
#define STBTT_free(x,u) ((void)(u), IM_FREE(x))
#define STBTT_assert(x) do { IM_ASSERT(x); } while(0)
@ -153,6 +158,7 @@ namespace IMGUI_STB_NAMESPACE
#include "imstb_truetype.h"
#endif
#endif
#endif // IMGUI_ENABLE_STB_TRUETYPE
#if defined(__GNUC__)
#pragma GCC diagnostic pop
@ -383,8 +389,8 @@ void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
CircleSegmentMaxError = max_error;
for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++)
{
const float radius = i + 1.0f;
const int segment_count = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError);
const float radius = (float)i;
const int segment_count = (i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0;
CircleSegmentCounts[i] = (ImU8)ImMin(segment_count, 255);
}
}
@ -1018,11 +1024,12 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12)
{
if (radius == 0.0f || a_min_of_12 > a_max_of_12)
if (radius == 0.0f)
{
_Path.push_back(center);
return;
}
IM_ASSERT(a_min_of_12 <= a_max_of_12);
// For legacy reason the PathArcToFast() always takes angles where 2*PI is represented by 12,
// but it is possible to set IM_DRAWLIST_ARCFAST_TESSELATION_MULTIPLIER to a higher value. This should compile to a no-op otherwise.
@ -1046,6 +1053,7 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
_Path.push_back(center);
return;
}
IM_ASSERT(a_min <= a_max);
// Note that we are adding a point at both a_min and a_max.
// If you are trying to draw a full closed circle you don't want the overlapping points!
@ -1284,7 +1292,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
if (num_segments <= 0)
{
// Automatic segment count
const int radius_idx = (int)radius - 1;
const int radius_idx = (int)radius;
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else
@ -1314,7 +1322,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col,
if (num_segments <= 0)
{
// Automatic segment count
const int radius_idx = (int)radius - 1;
const int radius_idx = (int)radius;
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else
@ -1716,25 +1724,13 @@ void ImGui::ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int ve
ImFontConfig::ImFontConfig()
{
FontData = NULL;
FontDataSize = 0;
memset(this, 0, sizeof(*this));
FontDataOwnedByAtlas = true;
FontNo = 0;
SizePixels = 0.0f;
OversampleH = 3; // FIXME: 2 may be a better default?
OversampleV = 1;
PixelSnapH = false;
GlyphExtraSpacing = ImVec2(0.0f, 0.0f);
GlyphOffset = ImVec2(0.0f, 0.0f);
GlyphRanges = NULL;
GlyphMinAdvanceX = 0.0f;
GlyphMaxAdvanceX = FLT_MAX;
MergeMode = false;
RasterizerFlags = 0x00;
RasterizerMultiply = 1.0f;
EllipsisChar = (ImWchar)-1;
memset(Name, 0, sizeof(Name));
DstFont = NULL;
}
//-----------------------------------------------------------------------------
@ -1791,17 +1787,8 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3
ImFontAtlas::ImFontAtlas()
{
Locked = false;
Flags = ImFontAtlasFlags_None;
TexID = (ImTextureID)NULL;
TexDesiredWidth = 0;
memset(this, 0, sizeof(*this));
TexGlyphPadding = 1;
TexPixelsAlpha8 = NULL;
TexPixelsRGBA32 = NULL;
TexWidth = TexHeight = 0;
TexUvScale = ImVec2(0.0f, 0.0f);
TexUvWhitePixel = ImVec2(0.0f, 0.0f);
PackIdMouseCursors = PackIdLines = -1;
}
@ -2087,7 +2074,26 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou
bool ImFontAtlas::Build()
{
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
return ImFontAtlasBuildWithStbTruetype(this);
// Select builder
// - Note that we do not reassign to atlas->FontBuilderIO, since it is likely to point to static data which
// may mess with some hot-reloading schemes. If you need to assign to this (for dynamic selection) AND are
// using a hot-reloading scheme that messes up static data, store your own instance of ImFontBuilderIO somewhere
// and point to it instead of pointing directly to return value of the GetBuilderXXX functions.
const ImFontBuilderIO* builder_io = FontBuilderIO;
if (builder_io == NULL)
{
#ifdef IMGUI_ENABLE_FREETYPE
builder_io = ImGuiFreeType::GetBuilderForFreeType();
#elif defined(IMGUI_ENABLE_STB_TRUETYPE)
builder_io = ImFontAtlasGetBuilderForStbTruetype();
#else
IM_ASSERT(0); // Invalid Build function
#endif
}
// Build
return builder_io->FontBuilder_Build(this);
}
void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor)
@ -2107,6 +2113,7 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
data[i] = table[data[i]];
}
#ifdef IMGUI_ENABLE_STB_TRUETYPE
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
struct ImFontBuildSrcData
@ -2144,7 +2151,7 @@ static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector<int>*
out->push_back((int)(((it - it_begin) << 5) + bit_n));
}
bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
@ -2397,6 +2404,15 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
return true;
}
const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype()
{
static ImFontBuilderIO io;
io.FontBuilder_Build = ImFontAtlasBuildWithStbTruetype;
return &io;
}
#endif // IMGUI_ENABLE_STB_TRUETYPE
void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
{
if (!font_config->MergeMode)
@ -2439,7 +2455,7 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
}
}
void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value)
void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value)
{
IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth);
IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight);
@ -2449,6 +2465,16 @@ void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int x, int y,
out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : 0x00;
}
void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value)
{
IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth);
IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight);
unsigned int* out_pixel = atlas->TexPixelsRGBA32 + x + (y * atlas->TexWidth);
for (int off_y = 0; off_y < h; off_y++, out_pixel += atlas->TexWidth, in_str += w)
for (int off_x = 0; off_x < w; off_x++)
out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : IM_COL32_BLACK_TRANS;
}
static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
{
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors);
@ -2461,15 +2487,30 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
const int x_for_white = r->X;
const int x_for_black = r->X + FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
if (atlas->TexPixelsAlpha8 != NULL)
{
ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
}
else
{
ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', IM_COL32_WHITE);
ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', IM_COL32_WHITE);
}
}
else
{
// Render 4 white pixels
IM_ASSERT(r->Width == 2 && r->Height == 2);
const int offset = (int)r->X + (int)r->Y * w;
atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
if (atlas->TexPixelsAlpha8 != NULL)
{
atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
}
else
{
atlas->TexPixelsRGBA32[offset] = atlas->TexPixelsRGBA32[offset + 1] = atlas->TexPixelsRGBA32[offset + w] = atlas->TexPixelsRGBA32[offset + w + 1] = IM_COL32_WHITE;
}
}
atlas->TexUvWhitePixel = ImVec2((r->X + 0.5f) * atlas->TexUvScale.x, (r->Y + 0.5f) * atlas->TexUvScale.y);
}
@ -2492,10 +2533,30 @@ static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
// Write each slice
IM_ASSERT(pad_left + line_width + pad_right == r->Width && y < r->Height); // Make sure we're inside the texture bounds before we start writing pixels
unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)];
memset(write_ptr, 0x00, pad_left);
memset(write_ptr + pad_left, 0xFF, line_width);
memset(write_ptr + pad_left + line_width, 0x00, pad_right);
if (atlas->TexPixelsAlpha8 != NULL)
{
unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)];
for (unsigned int i = 0; i < pad_left; i++)
*(write_ptr + i) = 0x00;
for (unsigned int i = 0; i < line_width; i++)
*(write_ptr + pad_left + i) = 0xFF;
for (unsigned int i = 0; i < pad_right; i++)
*(write_ptr + pad_left + line_width + i) = 0x00;
}
else
{
unsigned int* write_ptr = &atlas->TexPixelsRGBA32[r->X + ((r->Y + y) * atlas->TexWidth)];
for (unsigned int i = 0; i < pad_left; i++)
*(write_ptr + i) = IM_COL32_BLACK_TRANS;
for (unsigned int i = 0; i < line_width; i++)
*(write_ptr + pad_left + i) = IM_COL32_WHITE;
for (unsigned int i = 0; i < pad_right; i++)
*(write_ptr + pad_left + line_width + i) = IM_COL32_BLACK_TRANS;
}
// Calculate UVs for this line
ImVec2 uv0 = ImVec2((float)(r->X + pad_left - 1), (float)(r->Y + y)) * atlas->TexUvScale;
@ -2530,7 +2591,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
{
// Render into our custom data blocks
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL);
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL || atlas->TexPixelsRGBA32 != NULL);
ImFontAtlasBuildRenderDefaultTexData(atlas);
ImFontAtlasBuildRenderLinesTexData(atlas);
@ -3012,6 +3073,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
ImFontGlyph& glyph = Glyphs.back();
glyph.Codepoint = (unsigned int)codepoint;
glyph.Visible = (x0 != x1) && (y0 != y1);
glyph.Colored = false;
glyph.X0 = x0;
glyph.Y0 = y0;
glyph.X1 = x1;
@ -3262,6 +3324,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
const ImFontGlyph* glyph = FindGlyph(c);
if (!glyph || !glyph->Visible)
return;
if (glyph->Colored)
col |= ~IM_COL32_A_MASK;
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
pos.x = IM_FLOOR(pos.x);
pos.y = IM_FLOOR(pos.y);
@ -3324,6 +3388,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx;
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
while (s < text_end)
{
if (word_wrap_enabled)
@ -3429,14 +3495,17 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
}
}
// Support for untinted glyphs
ImU32 glyph_col = glyph->Colored ? col_untinted : col;
// We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here:
{
idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2);
idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3);
vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1;
vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1;
vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2;
vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2;
vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = glyph_col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1;
vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = glyph_col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1;
vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = glyph_col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2;
vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = glyph_col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2;
vtx_write += 4;
vtx_current_idx += 4;
idx_write += 6;

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80
// dear imgui, v1.81
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -29,7 +29,8 @@ Index of this file:
// [SECTION] ImGuiWindowTempData, ImGuiWindow
// [SECTION] Tab bar, Tab item support
// [SECTION] Table support
// [SECTION] Internal API
// [SECTION] ImGui internal API
// [SECTION] ImFontAtlas internal API
// [SECTION] Test Engine specific hooks (imgui_test_engine)
*/
@ -83,6 +84,12 @@ Index of this file:
#error Use IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS
#endif
// Enable stb_truetype by default unless FreeType is enabled.
// You can compile with both by defining both IMGUI_ENABLE_FREETYPE and IMGUI_ENABLE_STB_TRUETYPE together.
#ifndef IMGUI_ENABLE_FREETYPE
#define IMGUI_ENABLE_STB_TRUETYPE
#endif
//-----------------------------------------------------------------------------
// [SECTION] Forward declarations
//-----------------------------------------------------------------------------
@ -622,6 +629,7 @@ struct IMGUI_API ImChunkStream
//-----------------------------------------------------------------------------
// ImDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value.
// FIXME: the minimum number of auto-segment may be undesirably high for very small radiuses (e.g. 1.0f)
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 12
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((int)((IM_PI * 2.0f) / ImAcos(((_RAD) - (_MAXERROR)) / (_RAD))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX)
@ -645,7 +653,7 @@ struct IMGUI_API ImDrawListSharedData
// [Internal] Lookup tables
ImVec2 ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER]; // FIXME: Bake rounded corners fill/borders in atlas
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius (array index + 1) before we calculate it dynamically (to avoid calculation overhead)
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead)
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas
ImDrawListSharedData();
@ -656,8 +664,9 @@ struct ImDrawDataBuilder
{
ImVector<ImDrawList*> Layers[2]; // Global layers for: regular, tooltip
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); }
void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); }
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); }
void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); }
int GetDrawListCount() const { int count = 0; for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) count += Layers[n].Size; return count; }
IMGUI_API void FlattenIntoSingleLayer();
};
@ -1284,41 +1293,40 @@ struct ImGuiDockContext
// [SECTION] Viewport support
//-----------------------------------------------------------------------------
#ifdef IMGUI_HAS_VIEWPORT
// ImGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!)
// Note that every instance of ImGuiViewport is in fact a ImGuiViewportP.
// Every instance of ImGuiViewport is in fact a ImGuiViewportP.
struct ImGuiViewportP : public ImGuiViewport
{
int Idx;
int LastFrameActive; // Last frame number this viewport was activated by a window
int LastFrameDrawLists[2]; // Last frame number the background (0) and foreground (1) draw lists were used
int LastFrontMostStampCount; // Last stamp number from when a window hosted by this viewport was made front-most (by comparing this value between two viewport we have an implicit viewport z-order
int LastFrameActive; // Last frame number this viewport was activated by a window
int LastFrontMostStampCount;// Last stamp number from when a window hosted by this viewport was made front-most (by comparing this value between two viewport we have an implicit viewport z-order
ImGuiID LastNameHash;
ImVec2 LastPos;
float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent)
float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent)
float LastAlpha;
short PlatformMonitor;
bool PlatformWindowCreated;
ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set)
ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set)
int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used
ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
ImDrawData DrawDataP;
ImDrawDataBuilder DrawDataBuilder;
ImVec2 LastPlatformPos;
ImVec2 LastPlatformSize;
ImVec2 LastRendererSize;
ImVec2 CurrWorkOffsetMin; // Work area top-left offset being increased during the frame
ImVec2 CurrWorkOffsetMax; // Work area bottom-right offset being decreased during the frame
ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!)
ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height).
ImVec2 CurrWorkOffsetMin; // Work Area: Offset being built/increased during current frame
ImVec2 CurrWorkOffsetMax; // Work Area: Offset being built/decreased during current frame
ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameDrawLists[0] = LastFrameDrawLists[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
ImGuiViewportP() { Idx = -1; LastFrameActive = DrawListsLastFrame[0] = DrawListsLastFrame[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); }
ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
ImRect GetWorkRect() const { return ImRect(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y, Pos.x + Size.x + WorkOffsetMax.x, Pos.y + Size.y + WorkOffsetMax.y); }
ImRect GetWorkRect() const { return ImRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); }
void UpdateWorkRect() { WorkPos = ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); WorkSize = ImVec2(ImMax(0.0f, Size.x - WorkOffsetMin.x + WorkOffsetMax.x), ImMax(0.0f, Size.y - WorkOffsetMin.y + WorkOffsetMax.y)); }
void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
};
#endif // #ifdef IMGUI_HAS_VIEWPORT
//-----------------------------------------------------------------------------
// [SECTION] Settings support
//-----------------------------------------------------------------------------
@ -1406,10 +1414,11 @@ struct IMGUI_API ImGuiStackSizes
//-----------------------------------------------------------------------------
typedef void (*ImGuiContextHookCallback)(ImGuiContext* ctx, ImGuiContextHook* hook);
enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown };
enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown, ImGuiContextHookType_PendingRemoval_ };
struct ImGuiContextHook
{
ImGuiID HookId; // A unique ID assigned by AddContextHook()
ImGuiContextHookType Type;
ImGuiID Owner;
ImGuiContextHookCallback Callback;
@ -1518,6 +1527,7 @@ struct ImGuiContext
ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport()
ImGuiViewportP* MouseViewport;
ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag.
ImGuiID PlatformLastFocusedViewportId;
int ViewportFrontMostStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter
// Gamepad/keyboard Navigation
@ -1651,12 +1661,15 @@ struct ImGuiContext
ImChunkStream<ImGuiWindowSettings> SettingsWindows; // ImGuiWindow .ini settings entries
ImChunkStream<ImGuiTableSettings> SettingsTables; // ImGuiTable .ini settings entries
ImVector<ImGuiContextHook> Hooks; // Hooks for extensions (e.g. test engine)
ImGuiID HookIdNext; // Next available HookId
// Capture/Logging
bool LogEnabled; // Currently capturing
ImGuiLogType LogType; // Capture target
ImFileHandle LogFile; // If != NULL log to stdout/ file
ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
const char* LogNextPrefix;
const char* LogNextSuffix;
float LogLinePosY;
bool LogLineFirstItem;
int LogDepthRef;
@ -1736,6 +1749,7 @@ struct ImGuiContext
CurrentDpiScale = 0.0f;
CurrentViewport = NULL;
MouseViewport = MouseLastHoveredViewport = NULL;
PlatformLastFocusedViewportId = 0;
ViewportFrontMostStampCount = 0;
NavWindow = NULL;
@ -1810,9 +1824,11 @@ struct ImGuiContext
SettingsLoaded = false;
SettingsDirtyTimer = 0.0f;
HookIdNext = 0;
LogEnabled = false;
LogType = ImGuiLogType_None;
LogNextPrefix = LogNextSuffix = NULL;
LogFile = NULL;
LogLinePosY = FLT_MAX;
LogLineFirstItem = false;
@ -1885,10 +1901,10 @@ struct IMGUI_API ImGuiWindowTempData
// Local parameters stacks
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
ImGuiItemFlags ItemFlags; // == g.ItemFlagsStack.back()
float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
ImVector<float> ItemWidthStack;
ImVector<float> TextWrapPosStack;
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
float TextWrapPos; // Current text wrap pos.
ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
ImVector<float> TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos)
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
};
@ -2303,7 +2319,7 @@ struct ImGuiTable
ImGuiTableColumnIdx FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset)
ImGuiTableColumnIdx RowCellDataCurrent; // Index of current RowCellData[] entry in current row
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing accross columns after the freezing line. Index within DrawSplitter.Channels[]
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
@ -2317,7 +2333,7 @@ struct ImGuiTable
bool IsResetAllRequest;
bool IsResetDisplayOrderRequest;
bool IsUnfrozenRows; // Set when we got past the frozen row.
bool IsDefaultSizingPolicy; // Set if user didn't explicitely set a sizing policy in BeginTable()
bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable()
bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
@ -2366,7 +2382,7 @@ struct ImGuiTableSettings
#endif // #ifdef IMGUI_HAS_TABLE
//-----------------------------------------------------------------------------
// [SECTION] Internal API
// [SECTION] ImGui internal API
// No guarantee of forward compatibility here!
//-----------------------------------------------------------------------------
@ -2416,13 +2432,14 @@ namespace ImGui
IMGUI_API void UpdateMouseMovingWindowEndFrame();
// Generic context hooks
IMGUI_API void AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook);
IMGUI_API ImGuiID AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook);
IMGUI_API void RemoveContextHook(ImGuiContext* context, ImGuiID hook_to_remove);
IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type);
// Viewports
IMGUI_API void TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos);
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport);
IMGUI_API void TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos);
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport);
// Settings
IMGUI_API void MarkIniSettingsDirty();
@ -2478,6 +2495,8 @@ namespace ImGui
// Logging/Capture
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
// Popups, Modals, Tooltips
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
@ -2591,6 +2610,7 @@ namespace ImGui
// Tables: Candidates for public API
IMGUI_API void TableOpenContextMenu(int column_n = -1);
IMGUI_API void TableSetColumnEnabled(int column_n, bool enabled);
IMGUI_API void TableSetColumnWidth(int column_n, float width);
IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. Return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered.
@ -2665,7 +2685,6 @@ namespace ImGui
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0);
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
// Render helpers (those functions don't access any ImGui state!)
IMGUI_API void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale = 1.0f);
@ -2767,18 +2786,31 @@ namespace ImGui
IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings);
IMGUI_API void DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label);
IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport);
IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb);
} // namespace ImGui
// ImFontAtlas internals
IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int atlas_x, int atlas_y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
//-----------------------------------------------------------------------------
// [SECTION] ImFontAtlas internal API
//-----------------------------------------------------------------------------
// This structure is likely to evolve as we add support for incremental atlas updates
struct ImFontBuilderIO
{
bool (*FontBuilder_Build)(ImFontAtlas* atlas);
};
// Helper for font builder
IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype();
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
//-----------------------------------------------------------------------------
// [SECTION] Test Engine specific hooks (imgui_test_engine)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80
// dear imgui, v1.81
// (tables and columns code)
/*
@ -126,12 +126,12 @@ Index of this file:
// - with Table policy ImGuiTableFlags_SizingFixedSame --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is max of all contents width
// - with Table policy ImGuiTableFlags_SizingStretchSame --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is 1.0f
// - with Table policy ImGuiTableFlags_SizingStretchWeight --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is proportional to contents
// Default Width and default Weight can be overriden when calling TableSetupColumn().
// Default Width and default Weight can be overridden when calling TableSetupColumn().
//-----------------------------------------------------------------------------
// About mixing Fixed/Auto and Stretch columns together:
// - the typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
// - using mixed policies with ScrollX does not make much sense, as using Stretch columns with ScrollX does not make much sense in the first place!
// that is, unless 'inner_width' is passed to BeginTable() to explicitely provide a total width to layout columns in.
// that is, unless 'inner_width' is passed to BeginTable() to explicitly provide a total width to layout columns in.
// - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the maximum contents width.
// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths.
//-----------------------------------------------------------------------------
@ -1367,7 +1367,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
// Assert when passing a width or weight if policy is entirely left to default, to avoid storing width into weight and vice-versa.
// Give a grace to users of ImGuiTableFlags_ScrollX.
if (table->IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0)
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitely in either Table or Column.");
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
// When passing a width automatically enforce WidthFixed policy
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable)
@ -1460,6 +1460,21 @@ const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n)
return &table->ColumnsNames.Buf[column->NameOffset];
}
// For the getter you can use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsEnabled)
void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL);
if (!table)
return;
if (column_n < 0)
column_n = table->CurrentColumn;
IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount);
ImGuiTableColumn* column = &table->Columns[column_n];
column->IsEnabledNextFrame = enabled;
}
// We allow querying for an extra column in order to poll the IsHovered state of the right-most section
ImGuiTableColumnFlags ImGui::TableGetColumnFlags(int column_n)
{
@ -1639,6 +1654,10 @@ void ImGui::TableEndRow(ImGuiTable* table)
if (table->CurrentColumn != -1)
TableEndCell(table);
// Logging
if (g.LogEnabled)
LogRenderedText(NULL, "|");
// Position cursor at the bottom of our row so it can be used for e.g. clipping calculation. However it is
// likely that the next call to TableBeginCell() will reposition the cursor to take account of vertical padding.
window->DC.CursorPos.y = table->RowPosY2;
@ -1875,6 +1894,14 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
table->DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
}
// Logging
ImGuiContext& g = *GImGui;
if (g.LogEnabled && !column->IsSkipItems)
{
LogRenderedText(&window->DC.CursorPos, "|");
g.LogLinePosY = FLT_MAX;
}
}
// [Internal] Called by TableNextRow()/TableSetColumnIndex()/TableNextColumn()

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80
// dear imgui, v1.81
// (widgets code)
/*
@ -692,6 +692,9 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
if (g.LogEnabled)
LogSetNextTextDecoration("[", "]");
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
// Automatically close popups
@ -1104,10 +1107,11 @@ bool ImGui::Checkbox(const char* label, bool* v)
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
}
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled)
LogRenderedText(&total_bb.Min, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
if (label_size.x > 0.0f)
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
@ -1205,10 +1209,11 @@ bool ImGui::RadioButton(const char* label, bool active)
window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize);
}
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled)
LogRenderedText(&total_bb.Min, active ? "(x)" : "( )");
LogRenderedText(&label_pos, active ? "(x)" : "( )");
if (label_size.x > 0.0f)
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
return pressed;
@ -1392,7 +1397,8 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
// Draw
window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator));
if (g.LogEnabled)
LogRenderedText(&bb.Min, "--------------------------------");
LogRenderedText(&bb.Min, "--------------------------------\n");
}
if (columns)
{
@ -1583,7 +1589,12 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
}
RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding);
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
RenderTextClipped(frame_bb.Min + style.FramePadding, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f));
{
ImVec2 preview_pos = frame_bb.Min + style.FramePadding;
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(preview_pos, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f));
}
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
@ -2333,6 +2344,8 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (label_size.x > 0.0f)
@ -2596,7 +2609,7 @@ template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
{
if (v_min == v_max)
return (TYPE)0.0f;
return v_min;
const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
TYPE result;
@ -2945,6 +2958,8 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (label_size.x > 0.0f)
@ -3860,9 +3875,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]);
PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding);
PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize);
PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding);
PopStyleVar(3);
bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove);
PopStyleVar(2);
PopStyleColor();
if (!child_visible)
{
@ -3872,6 +3886,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
draw_window = g.CurrentWindow; // Child window
draw_window->DC.NavLayerActiveMaskNext |= (1 << draw_window->DC.NavLayerCurrent); // This is to ensure that EndChild() will display a navigation highlight so we can "enter" into it.
draw_window->DC.CursorPos += style.FramePadding;
inner_size.x -= draw_window->ScrollbarSizes.x;
}
else
@ -4032,7 +4047,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Edit in progress
const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + state->ScrollX;
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize * 0.5f));
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontSize * 0.5f));
const bool is_osx = io.ConfigMacOSXBehaviors;
if (select_all || (hovered && !is_osx && io.MouseDoubleClicked[0]))
@ -4481,10 +4496,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll))
{
const float scroll_increment_x = inner_size.x * 0.25f;
const float visible_width = inner_size.x - style.FramePadding.x;
if (cursor_offset.x < state->ScrollX)
state->ScrollX = IM_FLOOR(ImMax(0.0f, cursor_offset.x - scroll_increment_x));
else if (cursor_offset.x - inner_size.x >= state->ScrollX)
state->ScrollX = IM_FLOOR(cursor_offset.x - inner_size.x + scroll_increment_x);
else if (cursor_offset.x - visible_width >= state->ScrollX)
state->ScrollX = IM_FLOOR(cursor_offset.x - visible_width + scroll_increment_x);
}
else
{
@ -4592,14 +4608,17 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (is_multiline)
{
Dummy(text_size);
Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y));
EndChild();
EndGroup();
}
// Log as text
if (g.LogEnabled && (!is_password || is_displaying_hint))
{
LogSetNextTextDecoration("{", "}");
LogRenderedText(&draw_pos, buf_display, buf_display_end);
}
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
@ -5806,19 +5825,10 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
text_pos.x -= text_offset_x;
if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton)
frame_bb.Max.x -= g.FontSize + style.FramePadding.x;
if (g.LogEnabled)
{
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
const char log_prefix[] = "\n##";
const char log_suffix[] = "##";
LogRenderedText(&text_pos, log_prefix, log_prefix + 3);
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
LogRenderedText(&text_pos, log_suffix, log_suffix + 2);
}
else
{
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
}
LogSetNextTextDecoration("###", "###");
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
}
else
{
@ -5834,7 +5844,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
else if (!is_leaf)
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
if (g.LogEnabled)
LogRenderedText(&text_pos, ">");
LogSetNextTextDecoration(">", NULL);
RenderText(text_pos, label, label_end, false);
}
@ -5985,7 +5995,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
ItemSize(size, 0.0f);
// Fill horizontal space
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitely right-aligned sizes not visibly match other widgets.
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitly right-aligned sizes not visibly match other widgets.
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x;
const float max_x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
@ -6124,18 +6134,14 @@ bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags
//-------------------------------------------------------------------------
// [SECTION] Widgets: ListBox
//-------------------------------------------------------------------------
// - BeginListBox()
// - EndListBox()
// - ListBox()
// - ListBoxHeader()
// - ListBoxFooter()
//-------------------------------------------------------------------------
// FIXME: This is an old API. We should redesign some of it, rename ListBoxHeader->BeginListBox, ListBoxFooter->EndListBox
// and promote using them over existing ListBox() functions, similarly to change with combo boxes.
//-------------------------------------------------------------------------
// FIXME: In principle this function should be called BeginListBox(). We should rename it after re-evaluating if we want to keep the same signature.
// Helper to calculate the size of a listbox and display a label on the right.
// Tip: To have a list filling the entire window width, PushItemWidth(-1) and pass an non-visible label e.g. "##empty"
bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
// Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty"
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height).
bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
@ -6146,12 +6152,12 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
const ImGuiID id = GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
// Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
// Size default to hold ~7.25 items.
// 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 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
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));
window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy.
g.NextItemData.ClearFlags();
if (!IsRectVisible(bb.Min, bb.Max))
@ -6161,50 +6167,41 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
return false;
}
// FIXME-OPT: We could omit the BeginGroup() if label_size.x but would need to omit the EndGroup() as well.
BeginGroup();
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
if (label_size.x > 0.0f)
{
ImVec2 label_pos = ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y);
RenderText(label_pos, label);
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, label_pos + label_size);
}
BeginChildFrame(id, frame_bb.GetSize());
return true;
}
// FIXME: In principle this function should be called EndListBox(). We should rename it after re-evaluating if we want to keep the same signature.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// OBSOLETED in 1.81 (from February 2021)
bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items)
{
// Size default to hold ~7.25 items.
// We add +25% worth of item height to allow the user to see at a glance if there are more items up/down, without looking at the scrollbar.
// We don't add this extra bit if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size.
// I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution.
if (height_in_items < 0)
height_in_items = ImMin(items_count, 7);
const ImGuiStyle& style = GetStyle();
float height_in_items_f = (height_in_items < items_count) ? (height_in_items + 0.25f) : (height_in_items + 0.00f);
// We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild().
// If height_in_items == -1, default height is maximum 7.
ImGuiContext& g = *GImGui;
float height_in_items_f = (height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f;
ImVec2 size;
size.x = 0.0f;
size.y = ImFloor(GetTextLineHeightWithSpacing() * height_in_items_f + style.FramePadding.y * 2.0f);
return ListBoxHeader(label, size);
size.y = GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f;
return BeginListBox(label, size);
}
#endif
// FIXME: In principle this function should be called EndListBox(). We should rename it after re-evaluating if we want to keep the same signature.
void ImGui::ListBoxFooter()
void ImGui::EndListBox()
{
ImGuiWindow * window = GetCurrentWindow();
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) && "Mismatched ListBoxHeader/ListBoxFooter calls. Did you test the return value of ListBoxHeader()?");
ImGuiWindow* parent_window = window->ParentWindow;
const ImRect bb = parent_window->DC.LastItemRect;
const ImGuiStyle& style = GetStyle();
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) && "Mismatched BeginListBox/EndListBox calls. Did you test the return value of BeginListBox?");
EndChildFrame();
// Redeclare item size so that it includes the label (we have stored the full size in LastItemRect)
// We call SameLine() to restore DC.CurrentLine* data
SameLine();
parent_window->DC.CursorPos = bb.Min;
ItemSize(bb, style.FramePadding.y);
EndGroup();
EndGroup(); // This is only required to be able to do IsItemXXX query on the whole ListBox including label
}
bool ImGui::ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_items)
@ -6213,25 +6210,35 @@ bool ImGui::ListBox(const char* label, int* current_item, const char* const item
return value_changed;
}
// This is merely a helper around BeginListBox(), EndListBox().
// Considering using those directly to submit custom data or store selection differently.
bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items)
{
if (!ListBoxHeader(label, items_count, height_in_items))
ImGuiContext& g = *GImGui;
// Calculate size from "height_in_items"
if (height_in_items < 0)
height_in_items = ImMin(items_count, 7);
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));
if (!BeginListBox(label, size))
return false;
// Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper.
ImGuiContext& g = *GImGui;
// Assume all items have even height (= 1 line of text). If you need items of different height,
// you can create a custom version of ListBox() in your code without using the clipper.
bool value_changed = false;
ImGuiListClipper clipper;
clipper.Begin(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to.
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{
const bool item_selected = (i == *current_item);
const char* item_text;
if (!items_getter(data, i, &item_text))
item_text = "*Unknown item*";
PushID(i);
const bool item_selected = (i == *current_item);
if (Selectable(item_text, item_selected))
{
*current_item = i;
@ -6241,7 +6248,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
SetItemDefaultFocus();
PopID();
}
ListBoxFooter();
EndListBox();
if (value_changed)
MarkItemEdited(g.CurrentWindow->DC.LastItemId);
@ -6523,7 +6530,7 @@ bool ImGui::BeginMenuBar()
clip_rect.ClipWith(window->OuterRectClipped);
PushClipRect(clip_rect.Min, clip_rect.Max, false);
// We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analoguous here, maybe a BeginGroupEx() with flags).
// We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analogous here, maybe a BeginGroupEx() with flags).
window->DC.CursorPos = window->DC.CursorMaxPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
@ -6575,7 +6582,7 @@ void ImGui::EndMenuBar()
bool ImGui::BeginMainMenuBar()
{
ImGuiContext& g = *GImGui;
ImGuiViewportP* viewport = g.Viewports[0];
ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport();
ImGuiWindow* menu_bar_window = FindWindowByName("##MainMenuBar");
// For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set.
@ -6585,7 +6592,8 @@ bool ImGui::BeginMainMenuBar()
if (menu_bar_window == NULL || menu_bar_window->BeginCount == 0)
{
// Set window position
// We don't attempt to calculate our height ahead, as it depends on the per-viewport font size. However menu-bar will affect the minimum window size so we'll get the right height.
// We don't attempt to calculate our height ahead, as it depends on the per-viewport font size.
// However menu-bar will affect the minimum window size so we'll get the right height.
ImVec2 menu_bar_pos = viewport->Pos + viewport->CurrWorkOffsetMin;
ImVec2 menu_bar_size = ImVec2(viewport->Size.x - viewport->CurrWorkOffsetMin.x + viewport->CurrWorkOffsetMax.x, 1.0f);
SetNextWindowPos(menu_bar_pos);
@ -6595,7 +6603,7 @@ bool ImGui::BeginMainMenuBar()
// Create window
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint, however the presence of a menu-bar will give us the minimum height we want.
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint, however the presence of a menu-bar will give us the minimum height we want.
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar;
bool is_open = Begin("##MainMenuBar", NULL, window_flags) && BeginMenuBar();
PopStyleVar(2);
@ -6780,7 +6788,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
if (menu_is_open)
{
SetNextWindowPos(popup_pos, ImGuiCond_Always);
SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: this is super misleading! The value will serve as reference for FindBestWindowPosForPopup(), not actual pos.
menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
}
else
@ -7305,6 +7313,7 @@ static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, I
{
if (docked_window != NULL)
{
IM_UNUSED(tab_bar);
IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode);
ImGuiID id = ImHashStr(label);
KeepAliveID(id);

View File

@ -4302,7 +4302,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
int winding = 0;
orig[0] = x;
//orig[1] = y; // [DEAR IMGUI] commmented double assignment
//orig[1] = y; // [DEAR IMGUI] commented double assignment
// make sure y never passes through a vertex of the shape
y_frac = (float) STBTT_fmod(y, 1.0f);

View File

@ -0,0 +1,30 @@
# imgui_freetype
Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer).
<br>by @vuhdo, @mikesart, @ocornut.
### Usage
1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype`, `vcpkg integrate install`).
2. Add imgui_freetype.h/cpp alongside your project files.
3. Add `#define IMGUI_ENABLE_FREETYPE` in your [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) file
### About Gamma Correct Blending
FreeType assumes blending in linear space rather than gamma space.
See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
The default Dear ImGui styles will be impacted by this change (alpha values will need tweaking).
### Testbed for toying with settings (for developers)
See https://gist.github.com/ocornut/b3a9ecf13502fd818799a452969649ad
### Known issues
- Oversampling settins are ignored but also not so much necessary with the higher quality rendering.
### Comparaison
Small, thin anti-aliased fonts are typically benefiting a lots from Freetype's hinting:
![comparing_font_rasterizers](https://user-images.githubusercontent.com/8225057/107550178-fef87f00-6bd0-11eb-8d09-e2edb2f0ccfc.gif)

View File

@ -1,25 +1,31 @@
// dear imgui: wrapper to use FreeType (instead of stb_truetype)
// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
// (code)
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained and v0.60+ by @ocornut.
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut.
// Changelog:
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
// - v0.52: (2017/09/26) fixes for imgui internal changes.
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement).
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member.
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
// - v0.63: (2020/06/04) fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'.
// renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
// 2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
// 2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
// 2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
// 2019/01/10: re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
// 2018/06/08: added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
// 2018/02/04: moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
// 2018/01/22: fix for addition of ImFontAtlas::TexUvscale member.
// 2017/10/22: minor inconsequential change to match change in master (removed an unnecessary statement).
// 2017/09/26: fixes for imgui internal changes.
// 2017/08/26: cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
// 2017/08/16: imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
// Gamma Correct Blending:
// FreeType assumes blending in linear space rather than gamma space.
// See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
// For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
// The default imgui styles will be impacted by this change (alpha values will need tweaking).
// About Gamma Correct Blending:
// - FreeType assumes blending in linear space rather than gamma space.
// - See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
@ -41,6 +47,23 @@
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#endif
//-------------------------------------------------------------------------
// Data
//-------------------------------------------------------------------------
// Default memory allocators
static void* ImGuiFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
static void ImGuiFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
// Current memory allocators
static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFreeTypeDefaultAllocFunc;
static void (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc;
static void* GImGuiFreeTypeAllocatorUserData = NULL;
//-------------------------------------------------------------------------
// Code
//-------------------------------------------------------------------------
namespace
{
// Glyph metrics:
@ -74,7 +97,7 @@ namespace
// | |
// |------------- advanceX ----------->|
/// A structure that describe a glyph.
// A structure that describe a glyph.
struct GlyphInfo
{
int Width; // Glyph's width in pixels.
@ -82,6 +105,7 @@ namespace
FT_Int OffsetX; // The distance from the origin ("pen position") to the left of the glyph.
FT_Int OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0.
float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0.
bool IsColored;
};
// Font parameters and metrics.
@ -104,7 +128,7 @@ namespace
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
~FreeTypeFont() { CloseFont(); }
// [Internals]
@ -118,7 +142,7 @@ namespace
// From SDL_ttf: Handy routines for converting from fixed point
#define FT_CEIL(X) (((X + 63) & -64) / 64)
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags)
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
{
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
if (error != 0)
@ -131,26 +155,29 @@ namespace
SetPixelHeight((uint32_t)cfg.SizePixels);
// Convert to FreeType flags (NB: Bold and Oblique are processed separately)
UserFlags = cfg.RasterizerFlags | extra_user_flags;
UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags;
LoadFlags = FT_LOAD_NO_BITMAP;
if (UserFlags & ImGuiFreeType::NoHinting)
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoHinting)
LoadFlags |= FT_LOAD_NO_HINTING;
if (UserFlags & ImGuiFreeType::NoAutoHint)
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoAutoHint)
LoadFlags |= FT_LOAD_NO_AUTOHINT;
if (UserFlags & ImGuiFreeType::ForceAutoHint)
if (UserFlags & ImGuiFreeTypeBuilderFlags_ForceAutoHint)
LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
if (UserFlags & ImGuiFreeType::LightHinting)
if (UserFlags & ImGuiFreeTypeBuilderFlags_LightHinting)
LoadFlags |= FT_LOAD_TARGET_LIGHT;
else if (UserFlags & ImGuiFreeType::MonoHinting)
else if (UserFlags & ImGuiFreeTypeBuilderFlags_MonoHinting)
LoadFlags |= FT_LOAD_TARGET_MONO;
else
LoadFlags |= FT_LOAD_TARGET_NORMAL;
if (UserFlags & ImGuiFreeType::Monochrome)
if (UserFlags & ImGuiFreeTypeBuilderFlags_Monochrome)
RenderMode = FT_RENDER_MODE_MONO;
else
RenderMode = FT_RENDER_MODE_NORMAL;
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
LoadFlags |= FT_LOAD_COLOR;
return true;
}
@ -200,9 +227,9 @@ namespace
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE);
// Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
if (UserFlags & ImGuiFreeType::Bold)
if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold)
FT_GlyphSlot_Embolden(slot);
if (UserFlags & ImGuiFreeType::Oblique)
if (UserFlags & ImGuiFreeTypeBuilderFlags_Oblique)
{
FT_GlyphSlot_Oblique(slot);
//FT_BBox bbox;
@ -227,11 +254,12 @@ namespace
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
return ft_bitmap;
}
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
{
IM_ASSERT(ft_bitmap != NULL);
const uint32_t w = ft_bitmap->width;
@ -246,13 +274,14 @@ namespace
if (multiply_table == NULL)
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
memcpy(dst, src, w);
for (uint32_t x = 0; x < w; x++)
dst[x] = IM_COL32(255, 255, 255, src[x]);
}
else
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
for (uint32_t x = 0; x < w; x++)
dst[x] = multiply_table[src[x]];
dst[x] = IM_COL32(255, 255, 255, multiply_table[src[x]]);
}
break;
}
@ -268,11 +297,38 @@ namespace
{
if ((x & 7) == 0)
bits = *bits_ptr++;
dst[x] = (bits & 0x80) ? color1 : color0;
dst[x] = IM_COL32(255, 255, 255, (bits & 0x80) ? color1 : color0);
}
}
break;
}
case FT_PIXEL_MODE_BGRA:
{
// FIXME: Converting pre-multiplied alpha to straight. Doesn't smell good.
#define DE_MULTIPLY(color, alpha) (ImU32)(255.0f * (float)color / (float)alpha + 0.5f)
if (multiply_table == NULL)
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
for (uint32_t x = 0; x < w; x++)
{
uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
dst[x] = IM_COL32(DE_MULTIPLY(r, a), DE_MULTIPLY(g, a), DE_MULTIPLY(b, a), a);
}
}
else
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
{
for (uint32_t x = 0; x < w; x++)
{
uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
dst[x] = IM_COL32(multiply_table[DE_MULTIPLY(r, a)], multiply_table[DE_MULTIPLY(g, a)], multiply_table[DE_MULTIPLY(b, a)], multiply_table[a]);
}
}
}
#undef DE_MULTIPLY
break;
}
default:
IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!");
}
@ -296,7 +352,9 @@ struct ImFontBuildSrcGlyphFT
{
GlyphInfo Info;
uint32_t Codepoint;
unsigned char* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
unsigned int* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
ImFontBuildSrcGlyphFT() { memset(this, 0, sizeof(*this)); }
};
struct ImFontBuildSrcDataFT
@ -320,7 +378,7 @@ struct ImFontBuildDstDataFT
ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
};
bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
@ -334,6 +392,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
atlas->ClearTexData();
// Temporary storage for building
bool src_load_color = false;
ImVector<ImFontBuildSrcDataFT> src_tmp_array;
ImVector<ImFontBuildDstDataFT> dst_tmp_array;
src_tmp_array.resize(atlas->ConfigData.Size);
@ -363,6 +422,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
return false;
// Measure highest codepoints
src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
@ -414,7 +474,6 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
if (entries_32 & ((ImU32)1 << bit_n))
{
ImFontBuildSrcGlyphFT src_glyph;
memset(&src_glyph, 0, sizeof(src_glyph));
src_glyph.Codepoint = (ImWchar)(((it - it_begin) << 5) + bit_n);
//src_glyph.GlyphIndex = 0; // FIXME-OPT: We had this info in the previous step and lost it..
src_tmp.GlyphsList.push_back(src_glyph);
@ -476,7 +535,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
IM_ASSERT(ft_bitmap);
// Allocate new temporary chunk if needed
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height;
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4;
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE)
{
buf_bitmap_current_used_bytes = 0;
@ -484,9 +543,9 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
}
// Blit rasterized pixels to our temporary buffer and keep a pointer to it.
src_glyph.BitmapData = buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes;
src_glyph.BitmapData = (unsigned int*)(buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes);
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width * 1, multiply_enabled ? multiply_table : NULL);
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : NULL);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding);
@ -533,8 +592,16 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
// 7. Allocate texture
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight);
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
if (src_load_color)
{
atlas->TexPixelsRGBA32 = (unsigned int*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight * 4);
memset(atlas->TexPixelsRGBA32, 0, atlas->TexWidth * atlas->TexHeight * 4);
}
else
{
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight);
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
}
// 8. Copy rasterized font characters back into the main texture
// 9. Setup ImFont and glyphs for runtime
@ -574,10 +641,21 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
// Blit from temporary buffer to final texture
size_t blit_src_stride = (size_t)src_glyph.Info.Width;
size_t blit_dst_stride = (size_t)atlas->TexWidth;
unsigned char* blit_src = src_glyph.BitmapData;
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
for (int y = info.Height; y > 0; y--, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
memcpy(blit_dst, blit_src, blit_src_stride);
unsigned int* blit_src = src_glyph.BitmapData;
if (atlas->TexPixelsAlpha8 != NULL)
{
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
for (int x = 0; x < info.Width; x++)
blit_dst[x] = (unsigned char)((blit_src[x] >> IM_COL32_A_SHIFT) & 0xFF);
}
else
{
unsigned int* blit_dst = atlas->TexPixelsRGBA32 + (ty * blit_dst_stride) + tx;
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
for (int x = 0; x < info.Width; x++)
blit_dst[x] = blit_src[x];
}
// Register glyph
float x0 = info.OffsetX + font_off_x;
@ -589,6 +667,10 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX);
IM_ASSERT(dst_font->Glyphs.back().Codepoint == src_glyph.Codepoint);
if (src_glyph.Info.IsColored)
dst_font->Glyphs.back().Colored = true;
}
src_tmp.Rects = NULL;
@ -605,50 +687,41 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
return true;
}
// Default memory allocators
static void* ImFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
static void ImFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
// Current memory allocators
static void* (*GImFreeTypeAllocFunc)(size_t size, void* user_data) = ImFreeTypeDefaultAllocFunc;
static void (*GImFreeTypeFreeFunc)(void* ptr, void* user_data) = ImFreeTypeDefaultFreeFunc;
static void* GImFreeTypeAllocatorUserData = NULL;
// FreeType memory allocation callbacks
static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
{
return GImFreeTypeAllocFunc((size_t)size, GImFreeTypeAllocatorUserData);
return GImGuiFreeTypeAllocFunc((size_t)size, GImGuiFreeTypeAllocatorUserData);
}
static void FreeType_Free(FT_Memory /*memory*/, void* block)
{
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
}
static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
{
// Implement realloc() as we don't ask user to provide it.
if (block == NULL)
return GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
return GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
if (new_size == 0)
{
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
return NULL;
}
if (new_size > cur_size)
{
void* new_block = GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
void* new_block = GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
memcpy(new_block, block, (size_t)cur_size);
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
return new_block;
}
return block;
}
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
{
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
FT_MemoryRec_ memory_rec = {};
@ -666,15 +739,22 @@ bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
// If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
FT_Add_Default_Modules(ft_library);
bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags);
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
FT_Done_Library(ft_library);
return ret;
}
const ImFontBuilderIO* ImGuiFreeType::GetBuilderForFreeType()
{
static ImFontBuilderIO io;
io.FontBuilder_Build = ImFontAtlasBuildWithFreeType;
return &io;
}
void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
{
GImFreeTypeAllocFunc = alloc_func;
GImFreeTypeFreeFunc = free_func;
GImFreeTypeAllocatorUserData = user_data;
GImGuiFreeTypeAllocFunc = alloc_func;
GImGuiFreeTypeFreeFunc = free_func;
GImGuiFreeTypeAllocatorUserData = user_data;
}

View File

@ -0,0 +1,49 @@
// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
// (headers)
#pragma once
#include "imgui.h" // IMGUI_API
// Forward declarations
struct ImFontAtlas;
struct ImFontBuilderIO;
// Hinting greatly impacts visuals (and glyph sizes).
// - By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
// - When disabled, FreeType generates blurrier glyphs, more or less matches the stb_truetype.h
// - The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
// - The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
// You can set those flags globaly in ImFontAtlas::FontBuilderFlags
// You can set those flags on a per font basis in ImFontConfig::FontBuilderFlags
enum ImGuiFreeTypeBuilderFlags
{
ImGuiFreeTypeBuilderFlags_NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
ImGuiFreeTypeBuilderFlags_NoAutoHint = 1 << 1, // Disable auto-hinter.
ImGuiFreeTypeBuilderFlags_ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter.
ImGuiFreeTypeBuilderFlags_LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
ImGuiFreeTypeBuilderFlags_MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
ImGuiFreeTypeBuilderFlags_Bold = 1 << 5, // Styling: Should we artificially embolden the font?
ImGuiFreeTypeBuilderFlags_Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style?
ImGuiFreeTypeBuilderFlags_Monochrome = 1 << 7, // Disable anti-aliasing. Combine this with MonoHinting for best results!
ImGuiFreeTypeBuilderFlags_LoadColor = 1 << 8 // Enable FreeType color-layered glyphs
};
namespace ImGuiFreeType
{
// This is automatically assigned when using '#define IMGUI_ENABLE_FREETYPE'.
// If you need to dynamically select between multiple builders:
// - you can manually assign this builder with 'atlas->FontBuilderIO = ImGuiFreeType::GetBuilderForFreeType()'
// - prefer deep-copying this into your own ImFontBuilderIO instance if you use hot-reloading that messes up static data.
IMGUI_API const ImFontBuilderIO* GetBuilderForFreeType();
// Override allocators. By default ImGuiFreeType will use IM_ALLOC()/IM_FREE()
// However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired.
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
// Obsolete names (will be removed soon)
// Prefer using '#define IMGUI_ENABLE_FREETYPE'
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); }
#endif
}

View File

@ -1,6 +1,6 @@
CFLAGS +=
CXXFLAGS := $(CFLAGS) -std=c++17
DEFINES += -DIMGUI_IMPL_OPENGL_LOADER_GL3W
DEFINES += -DIMGUI_IMPL_OPENGL_LOADER_GL3W -DIMGUI_ENABLE_FREETYPE
INCLUDES := $(shell pkg-config --cflags glfw3 freetype2 capstone) -I../../../imgui -I../../libs/gl3w
LIBS := $(shell pkg-config --libs glfw3 freetype2 capstone) -lpthread -ldl

View File

@ -56,7 +56,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;IMGUI_ENABLE_FREETYPE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\libs\gl3w;..\..\..\imgui;..\..\..\vcpkg\vcpkg\installed\x64-windows-static\include;..\..\..\vcpkg\vcpkg\installed\x64-windows-static\include\capstone;$(VcpkgCurrentInstalledDir)\include\capstone;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
@ -82,7 +82,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;IMGUI_ENABLE_FREETYPE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\libs\gl3w;..\..\..\imgui;..\..\..\vcpkg\vcpkg\installed\x64-windows-static\include;..\..\..\vcpkg\vcpkg\installed\x64-windows-static\include\capstone;$(VcpkgCurrentInstalledDir)\include\capstone;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ConformanceMode>true</ConformanceMode>
@ -112,6 +112,7 @@
<ClCompile Include="..\..\..\imgui\imgui_draw.cpp" />
<ClCompile Include="..\..\..\imgui\imgui_tables.cpp" />
<ClCompile Include="..\..\..\imgui\imgui_widgets.cpp" />
<ClCompile Include="..\..\..\imgui\misc\freetype\imgui_freetype.cpp" />
<ClCompile Include="..\..\..\nfd\nfd_common.c" />
<ClCompile Include="..\..\..\nfd\nfd_win.cpp" />
<ClCompile Include="..\..\..\server\TracyBadVersion.cpp" />
@ -159,7 +160,6 @@
<ClCompile Include="..\..\..\zstd\zstd_opt.c" />
<ClCompile Include="..\..\libs\gl3w\GL\gl3w.c" />
<ClCompile Include="..\..\src\HttpRequest.cpp" />
<ClCompile Include="..\..\src\imgui_freetype.cpp" />
<ClCompile Include="..\..\src\imgui_impl_glfw.cpp" />
<ClCompile Include="..\..\src\imgui_impl_opengl3.cpp" />
<ClCompile Include="..\..\src\main.cpp" />
@ -187,6 +187,7 @@
<ClInclude Include="..\..\..\imgui\imstb_rectpack.h" />
<ClInclude Include="..\..\..\imgui\imstb_textedit.h" />
<ClInclude Include="..\..\..\imgui\imstb_truetype.h" />
<ClInclude Include="..\..\..\imgui\misc\freetype\imgui_freetype.h" />
<ClInclude Include="..\..\..\nfd\common.h" />
<ClInclude Include="..\..\..\nfd\nfd.h" />
<ClInclude Include="..\..\..\nfd\nfd_common.h" />
@ -267,7 +268,6 @@
<ClInclude Include="..\..\src\FontAwesomeSolid.hpp" />
<ClInclude Include="..\..\src\HttpRequest.hpp" />
<ClInclude Include="..\..\src\icon.hpp" />
<ClInclude Include="..\..\src\imgui_freetype.h" />
<ClInclude Include="..\..\src\imgui_impl_glfw.h" />
<ClInclude Include="..\..\src\imgui_impl_opengl3.h" />
<ClInclude Include="..\..\src\NativeWindow.hpp" />

View File

@ -22,6 +22,9 @@
<Filter Include="zstd">
<UniqueIdentifier>{c67291b2-9e67-4915-b80f-6891ceb683a3}</UniqueIdentifier>
</Filter>
<Filter Include="imgui\freetype">
<UniqueIdentifier>{1a9a9fea-82b2-41df-9d0e-ef4b00ed1213}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\common\tracy_lz4.cpp">
@ -60,9 +63,6 @@
<ClCompile Include="..\..\..\server\TracyBadVersion.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\src\imgui_freetype.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\winmain.cpp">
<Filter>src</Filter>
</ClCompile>
@ -216,6 +216,9 @@
<ClCompile Include="..\..\..\imgui\imgui_tables.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\..\imgui\misc\freetype\imgui_freetype.cpp">
<Filter>imgui\freetype</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\common\tracy_lz4.hpp">
@ -323,9 +326,6 @@
<ClInclude Include="..\..\src\Cousine.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\src\imgui_freetype.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyBuzzAnim.hpp">
<Filter>server</Filter>
</ClInclude>
@ -521,6 +521,9 @@
<ClInclude Include="..\..\..\server\TracySortedVector.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\imgui\misc\freetype\imgui_freetype.h">
<Filter>imgui\freetype</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Natvis Include="DebugVis.natvis" />

View File

@ -1,36 +0,0 @@
// dear imgui: wrapper to use FreeType (instead of stb_truetype)
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut
#pragma once
#include "imgui.h" // IMGUI_API, ImFontAtlas
namespace ImGuiFreeType
{
// Hinting greatly impacts visuals (and glyph sizes).
// When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
// The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
// The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
// You can set those flags on a per font basis in ImFontConfig::RasterizerFlags.
// Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts.
enum RasterizerFlags
{
// By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
NoAutoHint = 1 << 1, // Disable auto-hinter.
ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter.
LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
Bold = 1 << 5, // Styling: Should we artificially embolden the font?
Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style?
Monochrome = 1 << 7 // Disable anti-aliasing. Combine this with MonoHinting for best results!
};
IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);
// By default ImGuiFreeType will use IM_ALLOC()/IM_FREE().
// However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired:
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
}

View File

@ -1,5 +1,5 @@
// dear imgui: Platform Backend for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..)
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.)
@ -273,6 +273,11 @@ bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks)
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan);
}
bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks)
{
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Unknown);
}
void ImGui_ImplGlfw_Shutdown()
{
ImGui_ImplGlfw_ShutdownPlatformInterface();

View File

@ -1,5 +1,5 @@
// dear imgui: Platform Backend for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..)
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
// Implemented features:
@ -28,6 +28,7 @@ struct GLFWmonitor;
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();

View File

@ -481,7 +481,7 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Store our identifier
io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture;
io.Fonts->SetTexID((ImTextureID)(intptr_t)g_FontTexture);
// Restore state
glBindTexture(GL_TEXTURE_2D, last_texture);
@ -495,7 +495,7 @@ void ImGui_ImplOpenGL3_DestroyFontsTexture()
{
ImGuiIO& io = ImGui::GetIO();
glDeleteTextures(1, &g_FontTexture);
io.Fonts->TexID = 0;
io.Fonts->SetTexID(0);
g_FontTexture = 0;
}
}

View File

@ -44,7 +44,7 @@
#include "../../server/TracyVersion.hpp"
#include "../../server/IconsFontAwesome5.h"
#include "imgui_freetype.h"
#include "misc/freetype/imgui_freetype.h"
#include "Arimo.hpp"
#include "Cousine.hpp"
#include "FontAwesomeSolid.hpp"
@ -317,16 +317,18 @@ int main( int argc, char** argv )
ICON_MIN_FA, ICON_MAX_FA,
0
};
ImFontConfig configBasic;
configBasic.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting;
ImFontConfig configMerge;
configMerge.MergeMode = true;
configMerge.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting;
io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Arimo_compressed_data, tracy::Arimo_compressed_size, 15.0f * dpiScale, nullptr, rangesBasic );
io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Arimo_compressed_data, tracy::Arimo_compressed_size, 15.0f * dpiScale, &configBasic, rangesBasic );
io.Fonts->AddFontFromMemoryCompressedTTF( tracy::FontAwesomeSolid_compressed_data, tracy::FontAwesomeSolid_compressed_size, 14.0f * dpiScale, &configMerge, rangesIcons );
fixedWidth = io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Cousine_compressed_data, tracy::Cousine_compressed_size, 14.0f * dpiScale );
bigFont = io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Arimo_compressed_data, tracy::Cousine_compressed_size, 20.0f * dpiScale );
smallFont = io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Arimo_compressed_data, tracy::Cousine_compressed_size, 10.0f * dpiScale );
ImGuiFreeType::BuildFontAtlas( io.Fonts, ImGuiFreeType::LightHinting );
fixedWidth = io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Cousine_compressed_data, tracy::Cousine_compressed_size, 14.0f * dpiScale, &configBasic );
bigFont = io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Arimo_compressed_data, tracy::Cousine_compressed_size, 20.0f * dpiScale, &configBasic );
smallFont = io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Arimo_compressed_data, tracy::Cousine_compressed_size, 10.0f * dpiScale, &configBasic );
ImGui::StyleColorsDark();
auto& style = ImGui::GetStyle();