mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 03:19:12 +08:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_dx9.cpp # backends/imgui_impl_sdl.cpp # backends/imgui_impl_win32.cpp # imgui.cpp # imgui_internal.h # imgui_widgets.cpp
This commit is contained in:
commit
e7577d570e
@ -13,6 +13,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857).
|
||||
// 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file.
|
||||
// 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer.
|
||||
// 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
@ -145,6 +146,11 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
IDirect3DStateBlock9* d3d9_state_block = NULL;
|
||||
if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
|
||||
return;
|
||||
if (d3d9_state_block->Capture() < 0)
|
||||
{
|
||||
d3d9_state_block->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
|
||||
D3DMATRIX last_world, last_view, last_projection;
|
||||
|
@ -20,6 +20,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
|
||||
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
|
||||
// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
|
||||
// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
|
||||
@ -213,8 +214,14 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, void* sdl_gl_context)
|
||||
g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
||||
g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
||||
|
||||
// Check and store if we are on Wayland
|
||||
g_MouseCanUseGlobalState = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) != 0;
|
||||
// Check and store if we are on a SDL backend that supports global mouse position
|
||||
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
|
||||
const char* sdl_backend = SDL_GetCurrentVideoDriver();
|
||||
const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
|
||||
g_MouseCanUseGlobalState = false;
|
||||
for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
|
||||
if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
|
||||
g_MouseCanUseGlobalState = true;
|
||||
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize.
|
||||
// 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer.
|
||||
// 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions().
|
||||
// 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation.
|
||||
@ -358,7 +359,7 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
|
||||
|
||||
err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0);
|
||||
check_vk_result(err);
|
||||
p_buffer_size = new_size;
|
||||
p_buffer_size = req.size;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
|
||||
@ -446,9 +447,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
ImDrawVert* vtx_dst = NULL;
|
||||
ImDrawIdx* idx_dst = NULL;
|
||||
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst));
|
||||
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst));
|
||||
check_vk_result(err);
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst));
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst));
|
||||
check_vk_result(err);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
|
@ -34,6 +34,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
|
||||
// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
|
||||
// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
|
||||
// 2021-01-25: Inputs: Dynamically loading XInput DLL.
|
||||
@ -212,6 +213,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
static void ImGui_ImplWin32_UpdateMousePos()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(g_hWnd != 0);
|
||||
|
||||
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// (When multi-viewports are enabled, all imgui positions are same as OS positions)
|
||||
@ -456,6 +458,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
if (wParam < 256)
|
||||
io.KeysDown[wParam] = 0;
|
||||
return 0;
|
||||
case WM_KILLFOCUS:
|
||||
memset(io.KeysDown, 0, sizeof(io.KeysDown));
|
||||
return 0;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 0 && wParam < 0x10000)
|
||||
|
@ -107,9 +107,21 @@ Breaking Changes:
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Scrolling: Fix scroll tracking with e.g. SetScrollHereX/Y() when WindowPadding < ItemSpacing.
|
||||
- Scrolling: Fix scroll snapping on edge of scroll region when both scrollbars are enabled.
|
||||
- Tables: Expose TableSetColumnEnabled() in public api. (#3935)
|
||||
- Drags, Sliders, Inputs: Specifying a NULL format to Float functions default them to "%.3f" to be
|
||||
consistent with the compile-time default. (#3922)
|
||||
- DragScalar: Add default value for v_speed argument to match higher-level functions. (#3922) [@eliasdaler]
|
||||
- Backends: SDL: Rework global mouse pos availability check listing supported platforms explicitly,
|
||||
effectively fixing mouse access on Raspberry Pi. (#2837, #3950) [@lethal-guitar, @hinxx]
|
||||
- Backends: Win32: Clearing keyboard down array when losing focus (WM_KILLFOCUS). (#2062, #3532, #3961)
|
||||
[@1025798851]
|
||||
- Backends: DirectX9: calling IDirect3DStateBlock9::Capture() after CreateStateBlock() which appears to
|
||||
workaround/fix state restoring issues. Unknown exactly why so, but bit of a cargo-cult fix. (#3857)
|
||||
- Backends: Vulkan: Fix mapped memory Vulkan validation error when buffer sizes are not multiple of
|
||||
VkPhysicalDeviceLimits::nonCoherentAtomSize. (#3957) [@AgentX1994]
|
||||
- Examples: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881)
|
||||
- Docs: Improvements to minor mistakes in documentation comments (#3923) [@ANF-Studios]
|
||||
|
||||
|
||||
|
@ -253,7 +253,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
return;
|
||||
@ -326,7 +326,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
info.pSwapchains = &wd->Swapchain;
|
||||
info.pImageIndices = &wd->FrameIndex;
|
||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
return;
|
||||
|
@ -245,7 +245,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
return;
|
||||
@ -318,7 +318,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
||||
info.pSwapchains = &wd->Swapchain;
|
||||
info.pImageIndices = &wd->FrameIndex;
|
||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
g_SwapChainRebuild = true;
|
||||
return;
|
||||
|
@ -90,21 +90,24 @@ int main(int, char**)
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// Main loop
|
||||
MSG msg;
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
while (msg.message != WM_QUIT)
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Poll and handle messages (inputs, window resize, etc.)
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
MSG msg;
|
||||
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
continue;
|
||||
if (msg.message == WM_QUIT)
|
||||
done = true;
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplDX10_NewFrame();
|
||||
|
@ -95,21 +95,24 @@ int main(int, char**)
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// Main loop
|
||||
MSG msg;
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
while (msg.message != WM_QUIT)
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Poll and handle messages (inputs, window resize, etc.)
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
MSG msg;
|
||||
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
continue;
|
||||
if (msg.message == WM_QUIT)
|
||||
done = true;
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
|
@ -129,21 +129,24 @@ int main(int, char**)
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// Main loop
|
||||
MSG msg;
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
while (msg.message != WM_QUIT)
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Poll and handle messages (inputs, window resize, etc.)
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
MSG msg;
|
||||
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
continue;
|
||||
if (msg.message == WM_QUIT)
|
||||
done = true;
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplDX12_NewFrame();
|
||||
|
@ -88,21 +88,24 @@ int main(int, char**)
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// Main loop
|
||||
MSG msg;
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
while (msg.message != WM_QUIT)
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Poll and handle messages (inputs, window resize, etc.)
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
MSG msg;
|
||||
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
continue;
|
||||
if (msg.message == WM_QUIT)
|
||||
done = true;
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplDX9_NewFrame();
|
||||
|
58
imgui.cpp
58
imgui.cpp
@ -1167,11 +1167,18 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
|
||||
if (InputQueueSurrogate != 0)
|
||||
{
|
||||
if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate
|
||||
{
|
||||
InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID);
|
||||
else if (IM_UNICODE_CODEPOINT_MAX == (0xFFFF)) // Codepoint will not fit in ImWchar (extra parenthesis around 0xFFFF somehow fixes -Wunreachable-code with Clang)
|
||||
cp = IM_UNICODE_CODEPOINT_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if IM_UNICODE_CODEPOINT_MAX == 0xFFFF
|
||||
cp = IM_UNICODE_CODEPOINT_INVALID; // Codepoint will not fit in ImWchar
|
||||
#else
|
||||
cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000);
|
||||
#endif
|
||||
}
|
||||
|
||||
InputQueueSurrogate = 0;
|
||||
}
|
||||
InputQueueCharacters.push_back(cp);
|
||||
@ -5452,8 +5459,9 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& s
|
||||
if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize)))
|
||||
{
|
||||
ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window);
|
||||
const float decoration_up_height = window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight();
|
||||
new_size = ImMax(new_size, g.Style.WindowMinSize);
|
||||
new_size.y = ImMax(new_size.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
|
||||
new_size.y = ImMax(new_size.y, decoration_up_height + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
|
||||
}
|
||||
return new_size;
|
||||
}
|
||||
@ -5482,9 +5490,9 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiStyle& style = g.Style;
|
||||
ImVec2 size_decorations = ImVec2(0.0f, window->TitleBarHeight() + window->MenuBarHeight());
|
||||
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
ImVec2 size_pad = window->WindowPadding * 2.0f;
|
||||
ImVec2 size_desired = size_contents + size_pad + size_decorations;
|
||||
ImVec2 size_desired = size_contents + size_pad + ImVec2(0.0f, decoration_up_height);
|
||||
if (window->Flags & ImGuiWindowFlags_Tooltip)
|
||||
{
|
||||
// Tooltip always resize
|
||||
@ -5511,8 +5519,8 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
|
||||
// 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.
|
||||
ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit);
|
||||
bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - size_decorations.x < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - size_decorations.y < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||
bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - 0.0f < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - decoration_up_height < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||
if (will_have_scrollbar_x)
|
||||
size_auto_fit.y += style.ScrollbarSize;
|
||||
if (will_have_scrollbar_y)
|
||||
@ -7715,7 +7723,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Check user IM_ASSERT macro
|
||||
// (IF YOU GET A WARNING OR COMPILE ERROR HERE: it means you assert macro is incorrectly defined!
|
||||
// (IF YOU GET A WARNING OR COMPILE ERROR HERE: it means your assert macro is incorrectly defined!
|
||||
// If your macro uses multiple statements, it NEEDS to be surrounded by a 'do { ... } while (0)' block.
|
||||
// This is a common C/C++ idiom to allow multiple statements macros to be used in control flow blocks.)
|
||||
// #define IM_ASSERT(EXPR) if (SomeCode(EXPR)) SomeMoreCode(); // Wrong!
|
||||
@ -8439,24 +8447,29 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
|
||||
ImVec2 scroll = window->Scroll;
|
||||
if (window->ScrollTarget.x < FLT_MAX)
|
||||
{
|
||||
float decoration_total_width = window->ScrollbarSizes.x;
|
||||
float center_x_ratio = window->ScrollTargetCenterRatio.x;
|
||||
float scroll_target_x = window->ScrollTarget.x;
|
||||
float snap_x_min = 0.0f;
|
||||
float snap_x_max = window->ScrollMax.x + window->Size.x;
|
||||
if (window->ScrollTargetEdgeSnapDist.x > 0.0f)
|
||||
{
|
||||
float snap_x_min = 0.0f;
|
||||
float snap_x_max = window->ScrollMax.x + window->SizeFull.x - decoration_total_width;
|
||||
scroll_target_x = CalcScrollEdgeSnap(scroll_target_x, snap_x_min, snap_x_max, window->ScrollTargetEdgeSnapDist.x, center_x_ratio);
|
||||
scroll.x = scroll_target_x - center_x_ratio * (window->SizeFull.x - window->ScrollbarSizes.x);
|
||||
}
|
||||
scroll.x = scroll_target_x - center_x_ratio * (window->SizeFull.x - decoration_total_width);
|
||||
}
|
||||
if (window->ScrollTarget.y < FLT_MAX)
|
||||
{
|
||||
float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
float decoration_total_height = window->TitleBarHeight() + window->MenuBarHeight() + window->ScrollbarSizes.y;
|
||||
float center_y_ratio = window->ScrollTargetCenterRatio.y;
|
||||
float scroll_target_y = window->ScrollTarget.y;
|
||||
float snap_y_min = 0.0f;
|
||||
float snap_y_max = window->ScrollMax.y + window->Size.y - decoration_up_height;
|
||||
if (window->ScrollTargetEdgeSnapDist.y > 0.0f)
|
||||
{
|
||||
float snap_y_min = 0.0f;
|
||||
float snap_y_max = window->ScrollMax.y + window->SizeFull.y - decoration_total_height;
|
||||
scroll_target_y = CalcScrollEdgeSnap(scroll_target_y, snap_y_min, snap_y_max, window->ScrollTargetEdgeSnapDist.y, center_y_ratio);
|
||||
scroll.y = scroll_target_y - center_y_ratio * (window->SizeFull.y - window->ScrollbarSizes.y - decoration_up_height);
|
||||
}
|
||||
scroll.y = scroll_target_y - center_y_ratio * (window->SizeFull.y - decoration_total_height);
|
||||
}
|
||||
scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f));
|
||||
scroll.y = IM_FLOOR(ImMax(scroll.y, 0.0f));
|
||||
@ -8569,7 +8582,8 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x
|
||||
void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
|
||||
{
|
||||
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
|
||||
local_y -= window->TitleBarHeight() + window->MenuBarHeight(); // FIXME: Would be nice to have a more standardized access to our scrollable/client rect
|
||||
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); // FIXME: Would be nice to have a more standardized access to our scrollable/client rect;
|
||||
local_y -= decoration_up_height;
|
||||
window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y); // Convert local position to scroll offset
|
||||
window->ScrollTargetCenterRatio.y = center_y_ratio;
|
||||
window->ScrollTargetEdgeSnapDist.y = 0.0f;
|
||||
@ -8592,7 +8606,7 @@ void ImGui::SetScrollHereX(float center_x_ratio)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float spacing_x = g.Style.ItemSpacing.x;
|
||||
float spacing_x = ImMax(window->WindowPadding.x, g.Style.ItemSpacing.x);
|
||||
float target_pos_x = ImLerp(window->DC.LastItemRect.Min.x - spacing_x, window->DC.LastItemRect.Max.x + spacing_x, center_x_ratio);
|
||||
SetScrollFromPosX(window, target_pos_x - window->Pos.x, center_x_ratio); // Convert from absolute to local pos
|
||||
|
||||
@ -8605,7 +8619,7 @@ void ImGui::SetScrollHereY(float center_y_ratio)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float spacing_y = g.Style.ItemSpacing.y;
|
||||
float spacing_y = ImMax(window->WindowPadding.y, g.Style.ItemSpacing.y);
|
||||
float target_pos_y = ImLerp(window->DC.CursorPosPrevLine.y - spacing_y, window->DC.CursorPosPrevLine.y + window->DC.PrevLineSize.y + spacing_y, center_y_ratio);
|
||||
SetScrollFromPosY(window, target_pos_y - window->Pos.y, center_y_ratio); // Convert from absolute to local pos
|
||||
|
||||
@ -11517,10 +11531,10 @@ static void ImGui::UpdateViewportsNewFrame()
|
||||
// Update/copy monitor info
|
||||
UpdateViewportPlatformMonitor(viewport);
|
||||
|
||||
// Lock down space taken by menu bars and status bars, reset the offset for fucntions like BeginMainMenuBar() to alter them again.
|
||||
viewport->WorkOffsetMin = viewport->CurrWorkOffsetMin;
|
||||
viewport->WorkOffsetMax = viewport->CurrWorkOffsetMax;
|
||||
viewport->CurrWorkOffsetMin = viewport->CurrWorkOffsetMax = ImVec2(0.0f, 0.0f);
|
||||
// Lock down space taken by menu bars and status bars, reset the offset for functions like BeginMainMenuBar() to alter them again.
|
||||
viewport->WorkOffsetMin = viewport->BuildWorkOffsetMin;
|
||||
viewport->WorkOffsetMax = viewport->BuildWorkOffsetMax;
|
||||
viewport->BuildWorkOffsetMin = viewport->BuildWorkOffsetMax = ImVec2(0.0f, 0.0f);
|
||||
viewport->UpdateWorkRect();
|
||||
|
||||
// Reset alpha every frame. Users of transparency (docking) needs to request a lower alpha back.
|
||||
|
3
imgui.h
3
imgui.h
@ -62,7 +62,7 @@ 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.83 WIP"
|
||||
#define IMGUI_VERSION_NUM 18201
|
||||
#define IMGUI_VERSION_NUM 18202
|
||||
#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
|
||||
@ -733,6 +733,7 @@ namespace ImGui
|
||||
IMGUI_API int TableGetRowIndex(); // return current row index.
|
||||
IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.
|
||||
IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.
|
||||
IMGUI_API void TableSetColumnEnabled(int column_n, bool v);// change enabled/disabled state of a column, set to false to hide the column. Note that end-user can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)
|
||||
IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
|
||||
|
||||
// Legacy Columns API (2020: prefer using Tables!)
|
||||
|
@ -2895,6 +2895,8 @@ static void ShowDemoWindowLayout()
|
||||
{
|
||||
for (int item = 0; item < 100; item++)
|
||||
{
|
||||
if (item > 0)
|
||||
ImGui::SameLine();
|
||||
if (enable_track && item == track_item)
|
||||
{
|
||||
ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item);
|
||||
@ -2904,7 +2906,6 @@ static void ShowDemoWindowLayout()
|
||||
{
|
||||
ImGui::Text("Item %d", item);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
}
|
||||
float scroll_x = ImGui::GetScrollX();
|
||||
|
@ -1337,15 +1337,22 @@ struct ImGuiViewportP : public ImGuiViewport
|
||||
ImVec2 LastRendererSize;
|
||||
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
|
||||
ImVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f.
|
||||
ImVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f.
|
||||
|
||||
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(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; }
|
||||
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]); }
|
||||
void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
|
||||
|
||||
// Calculate work rect pos/size given a set of offset (we have 1 pair of offset for rect locked from last frame data, and 1 pair for currently building rect)
|
||||
ImVec2 CalcWorkRectPos(const ImVec2& off_min) const { return ImVec2(Pos.x + off_min.x, Pos.y + off_min.y); }
|
||||
ImVec2 CalcWorkRectSize(const ImVec2& off_min, const ImVec2& off_max) const { return ImVec2(ImMax(0.0f, Size.x - off_min.x + off_max.x), ImMax(0.0f, Size.y - off_min.y + off_max.y)); }
|
||||
void UpdateWorkRect() { WorkPos = CalcWorkRectPos(WorkOffsetMin); WorkSize = CalcWorkRectSize(WorkOffsetMin, WorkOffsetMax); } // Update public fields
|
||||
|
||||
// Helpers to retrieve ImRect (we don't need to store BuildWorkRect as every access tend to change it, hence the code asymmetry)
|
||||
ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
||||
ImRect GetWorkRect() const { return ImRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); }
|
||||
ImRect GetBuildWorkRect() const { ImVec2 pos = CalcWorkRectPos(BuildWorkOffsetMin); ImVec2 size = CalcWorkRectSize(BuildWorkOffsetMin, BuildWorkOffsetMax); return ImRect(pos.x, pos.y, pos.x + size.x, pos.y + size.y); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2533,6 +2540,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
|
||||
IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags);
|
||||
|
||||
// Gamepad/Keyboard Navigation
|
||||
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
|
||||
@ -2633,7 +2641,6 @@ 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.
|
||||
|
@ -8,6 +8,7 @@ Index of this file:
|
||||
// [SECTION] Commentary
|
||||
// [SECTION] Header mess
|
||||
// [SECTION] Tables: Main code
|
||||
// [SECTION] Tables: Simple accessors
|
||||
// [SECTION] Tables: Row changes
|
||||
// [SECTION] Tables: Columns changes
|
||||
// [SECTION] Tables: Columns width management
|
||||
@ -235,6 +236,19 @@ Index of this file:
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Tables: Main code
|
||||
//-----------------------------------------------------------------------------
|
||||
// - TableFixFlags() [Internal]
|
||||
// - TableFindByID() [Internal]
|
||||
// - BeginTable()
|
||||
// - BeginTableEx() [Internal]
|
||||
// - TableBeginInitMemory() [Internal]
|
||||
// - TableBeginApplyRequests() [Internal]
|
||||
// - TableSetupColumnFlags() [Internal]
|
||||
// - TableUpdateLayout() [Internal]
|
||||
// - TableUpdateBorders() [Internal]
|
||||
// - EndTable()
|
||||
// - TableSetupColumn()
|
||||
// - TableSetupScrollFreeze()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Configuration
|
||||
static const int TABLE_DRAW_CHANNEL_BG0 = 0;
|
||||
@ -1430,6 +1444,20 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Tables: Simple accessors
|
||||
//-----------------------------------------------------------------------------
|
||||
// - TableGetColumnCount()
|
||||
// - TableGetColumnName()
|
||||
// - TableGetColumnName() [Internal]
|
||||
// - TableSetColumnEnabled() [Internal]
|
||||
// - TableGetColumnFlags()
|
||||
// - TableGetCellBgRect() [Internal]
|
||||
// - TableGetColumnResizeID() [Internal]
|
||||
// - TableGetHoveredColumn() [Internal]
|
||||
// - TableSetBgColor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int ImGui::TableGetColumnCount()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -1458,6 +1486,9 @@ const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n)
|
||||
return &table->ColumnsNames.Buf[column->NameOffset];
|
||||
}
|
||||
|
||||
// Request enabling/disabling a column (often perceived as "showing/hiding" from users point of view)
|
||||
// Note that end-user can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)
|
||||
// Request will be applied during next layout, which happens on the first call to TableNextRow() after BeginTable()
|
||||
// For the getter you can use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsEnabled)
|
||||
void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
|
||||
{
|
||||
@ -2673,18 +2704,19 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
|
||||
// Write output
|
||||
table->SortSpecsMulti.resize(table->SortSpecsCount <= 1 ? 0 : table->SortSpecsCount);
|
||||
ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &table->SortSpecsSingle : table->SortSpecsMulti.Data;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
if (column->SortOrder == -1)
|
||||
continue;
|
||||
IM_ASSERT(column->SortOrder < table->SortSpecsCount);
|
||||
ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder];
|
||||
sort_spec->ColumnUserID = column->UserID;
|
||||
sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n;
|
||||
sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder;
|
||||
sort_spec->SortDirection = column->SortDirection;
|
||||
}
|
||||
if (sort_specs != NULL)
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
if (column->SortOrder == -1)
|
||||
continue;
|
||||
IM_ASSERT(column->SortOrder < table->SortSpecsCount);
|
||||
ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder];
|
||||
sort_spec->ColumnUserID = column->UserID;
|
||||
sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n;
|
||||
sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder;
|
||||
sort_spec->SortDirection = column->SortDirection;
|
||||
}
|
||||
table->SortSpecs.Specs = sort_specs;
|
||||
table->SortSpecs.SpecsCount = table->SortSpecsCount;
|
||||
table->SortSpecs.SpecsDirty = true; // Mark as dirty for user
|
||||
|
@ -6604,7 +6604,7 @@ void ImGui::EndMenuBar()
|
||||
IM_ASSERT(window->DC.MenuBarAppending);
|
||||
PopClipRect();
|
||||
PopID();
|
||||
window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->MenuBarRect().Min.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos.
|
||||
window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->Pos.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos.
|
||||
g.GroupStack.back().EmitItem = false;
|
||||
EndGroup(); // Restore position on layer 0
|
||||
window->DC.LayoutType = ImGuiLayoutType_Vertical;
|
||||
@ -6612,45 +6612,67 @@ void ImGui::EndMenuBar()
|
||||
window->DC.MenuBarAppending = false;
|
||||
}
|
||||
|
||||
// Important: calling order matters!
|
||||
// FIXME: Somehow overlapping with docking tech.
|
||||
// FIXME: The "rect-cut" aspect of this could be formalized into a lower-level helper (rect-cut: https://halt.software/dead-simple-layouts)
|
||||
bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, ImGuiDir dir, float axis_size, ImGuiWindowFlags window_flags)
|
||||
{
|
||||
IM_ASSERT(dir != ImGuiDir_None);
|
||||
|
||||
ImGuiWindow* bar_window = FindWindowByName(name);
|
||||
ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)(viewport_p ? viewport_p : GetMainViewport());
|
||||
if (bar_window == NULL || bar_window->BeginCount == 0)
|
||||
{
|
||||
// Calculate and set window size/position
|
||||
ImRect avail_rect = viewport->GetBuildWorkRect();
|
||||
ImGuiAxis axis = (dir == ImGuiDir_Up || dir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X;
|
||||
ImVec2 pos = avail_rect.Min;
|
||||
if (dir == ImGuiDir_Right || dir == ImGuiDir_Down)
|
||||
pos[axis] = avail_rect.Max[axis] - axis_size;
|
||||
ImVec2 size = avail_rect.GetSize();
|
||||
size[axis] = axis_size;
|
||||
SetNextWindowPos(pos);
|
||||
SetNextWindowSize(size);
|
||||
|
||||
// Report our size into work area (for next frame) using actual window size
|
||||
if (dir == ImGuiDir_Up || dir == ImGuiDir_Left)
|
||||
viewport->BuildWorkOffsetMin[axis] += axis_size;
|
||||
else if (dir == ImGuiDir_Down || dir == ImGuiDir_Right)
|
||||
viewport->BuildWorkOffsetMax[axis] -= axis_size;
|
||||
}
|
||||
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking;
|
||||
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
|
||||
bool is_open = Begin(name, NULL, window_flags);
|
||||
PopStyleVar(2);
|
||||
|
||||
return is_open;
|
||||
}
|
||||
|
||||
bool ImGui::BeginMainMenuBar()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport();
|
||||
ImGuiWindow* menu_bar_window = FindWindowByName("##MainMenuBar");
|
||||
|
||||
// Notify of viewport change so GetFrameHeight() can be accurate in case of DPI change
|
||||
SetCurrentViewport(NULL, viewport);
|
||||
|
||||
// For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set.
|
||||
// FIXME: This could be generalized as an opt-in way to clamp window->DC.CursorStartPos to avoid SafeArea?
|
||||
// FIXME: Consider removing support for safe area down the line... it's messy. Nowadays consoles have support for TV calibration in OS settings.
|
||||
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(g.Style.DisplaySafeAreaPadding.x, ImMax(g.Style.DisplaySafeAreaPadding.y - g.Style.FramePadding.y, 0.0f));
|
||||
|
||||
// Get our rectangle at the top of the work area
|
||||
if (menu_bar_window == NULL || menu_bar_window->BeginCount == 0)
|
||||
{
|
||||
// Set window position
|
||||
SetCurrentViewport(NULL, viewport);
|
||||
float height = GetFrameHeight();
|
||||
ImVec2 menu_bar_pos = viewport->Pos + viewport->CurrWorkOffsetMin;
|
||||
ImVec2 menu_bar_size = ImVec2(viewport->Size.x - viewport->CurrWorkOffsetMin.x + viewport->CurrWorkOffsetMax.x, height);
|
||||
SetNextWindowPos(menu_bar_pos);
|
||||
SetNextWindowSize(menu_bar_size);
|
||||
|
||||
// Report our size into work area
|
||||
viewport->CurrWorkOffsetMin.y += height;
|
||||
}
|
||||
|
||||
// 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.
|
||||
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);
|
||||
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar;
|
||||
float height = GetFrameHeight();
|
||||
bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags);
|
||||
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
|
||||
if (!is_open)
|
||||
{
|
||||
|
||||
if (is_open)
|
||||
BeginMenuBar();
|
||||
else
|
||||
End();
|
||||
return false;
|
||||
}
|
||||
return true; //-V1020
|
||||
return is_open;
|
||||
}
|
||||
|
||||
void ImGui::EndMainMenuBar()
|
||||
|
Loading…
Reference in New Issue
Block a user