Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_glfw.cpp
#	imgui.cpp
This commit is contained in:
ocornut 2023-12-20 23:57:19 +01:00
commit 4aa81116a5
17 changed files with 145 additions and 40 deletions

View File

@ -25,6 +25,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2023-12-19: Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to register canvas selector and auto-resize GLFW window.
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys.
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
@ -152,6 +153,9 @@ struct ImGui_ImplGlfw_Data
bool InstalledCallbacks;
bool CallbacksChainForAllWindows;
bool WantUpdateMonitors;
#ifdef __EMSCRIPTEN__
const char* CanvasSelector;
#endif
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
GLFWwindowfocusfun PrevUserCallbackWindowFocus;
@ -923,6 +927,43 @@ void ImGui_ImplGlfw_NewFrame()
ImGui_ImplGlfw_UpdateGamepads();
}
#ifdef __EMSCRIPTEN__
static EM_BOOL ImGui_ImplGlfw_OnCanvasSizeChange(int event_type, const EmscriptenUiEvent* event, void* user_data)
{
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
double canvas_width, canvas_height;
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
return true;
}
static EM_BOOL ImGui_ImplEmscripten_FullscreenChangeCallback(int event_type, const EmscriptenFullscreenChangeEvent* event, void* user_data)
{
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
double canvas_width, canvas_height;
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
return true;
}
// 'canvas_selector' is a CSS selector. The event listener is applied to the first element that matches the query.
// STRING MUST PERSIST FOR THE APPLICATION DURATION. PLEASE USE A STRING LITERAL OR ENSURE POINTER WILL STAY VALID.
void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector)
{
IM_ASSERT(canvas_selector != nullptr);
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplGlfw_InitForXXX()?");
bd->CanvasSelector = canvas_selector;
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, bd, false, ImGui_ImplGlfw_OnCanvasSizeChange);
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, bd, false, ImGui_ImplEmscripten_FullscreenChangeCallback);
// Change the size of the GLFW window according to the size of the canvas
ImGui_ImplGlfw_OnCanvasSizeChange(EMSCRIPTEN_EVENT_RESIZE, {}, bd);
}
#endif
//--------------------------------------------------------------------------------------------------------
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
@ -1264,7 +1305,7 @@ static void ImGui_ImplGlfw_ShutdownPlatformInterface()
//-----------------------------------------------------------------------------
// WndProc hook (declared here because we will need access to ImGui_ImplGlfw_ViewportData)
// WndProc hook (declared here because we will need access to ImGui_ImplGlfw_ViewportData)
#ifdef _WIN32
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
{

View File

@ -35,6 +35,11 @@ IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool ins
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
// Emscripten related initialization phase methods
#ifdef __EMSCRIPTEN__
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector);
#endif
// GLFW callbacks install
// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.

View File

@ -812,7 +812,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
err = vkQueueSubmit(v->Queue, 1, &end_info, VK_NULL_HANDLE);
check_vk_result(err);
err = vkDeviceWaitIdle(v->Device);
err = vkQueueWaitIdle(v->Queue);
check_vk_result(err);
vkDestroyBuffer(v->Device, upload_buffer, v->Allocator);
@ -1049,6 +1049,7 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator);
ImGui_ImplVulkan_DestroyFontsTexture();
if (bd->FontCommandBuffer) { vkFreeCommandBuffers(v->Device, bd->FontCommandPool, 1, &bd->FontCommandBuffer); bd->FontCommandBuffer = VK_NULL_HANDLE; }
if (bd->FontCommandPool) { vkDestroyCommandPool(v->Device, bd->FontCommandPool, v->Allocator); bd->FontCommandPool = VK_NULL_HANDLE; }
if (bd->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = VK_NULL_HANDLE; }
if (bd->ShaderModuleFrag) { vkDestroyShaderModule(v->Device, bd->ShaderModuleFrag, v->Allocator); bd->ShaderModuleFrag = VK_NULL_HANDLE; }

View File

@ -50,6 +50,7 @@ Breaking changes:
Prefer using ImGuiListClipper which can return non-contiguous ranges.
- Internals, Columns: commented out legacy ImGuiColumnsFlags_XXX symbols redirecting
to ImGuiOldColumnsFlags_XXX, obsoleted from imgui_internal.h in 1.80.
- Commented out obsolete ImGuiKey_KeyPadEnter redirection to ImGuiKey_KeypadEnter. (#2625, #7143)
Other changes:
@ -61,6 +62,7 @@ Other changes:
speed asymetry when (incorrectly) attempting to scroll by non-integer amount. (#6677)
- Nav, IO: SetNextFrameWantCaptureKeyboard(false) calls are not overrided back to true when
navigation is enabled. SetNextFrameWantCaptureKeyboard() is always higher priority. (#6997)
- Nav: Activation can also be performed with Keypad Enter. (#5606)
- Drag and Drop: Fixed drop target highlight on items temporarily pushing a widened clip rect
(namely Selectables and Treenodes using SpanAllColumn flag) so the highlight properly covers
all columns. (#7049, #4281, #3272)
@ -70,9 +72,11 @@ Other changes:
to allow passing through multiple widgets easily. (#3092, #5759, #787)
- DragScalarN, SliderScalarN, InputScalarN, PushMultiItemsWidths: improve multi-components
width computation to better distribute the error. (#7120, #7121) [@Nahor]
- ColorEdit4: Layout tweaks for very small sizes. (#7120, #7121)
- Menus: Tweaked hover slack logic, adding a timer to avoid situations where a slow vertical
movements toward another parent BeginMenu() can keep the wrong child menu open. (#6671, #6926)
- Debug Tools: Added DebugFlashStyleColor() to identify a style color. Added to Style Editor.
- Debug Tools: Debug Log: Hide its own clipper log to reduce noise in the output.
- Misc: Added IMGUI_USER_H_FILENAME to change the path included when using
IMGUI_INCLUDE_IMGUI_USER_H. (#7039) [@bryceberger]
- Misc: Rework debug display of texture id in Metrics window to avoid compile-error when
@ -82,8 +86,12 @@ Other changes:
like most printf implementations. (#7016, #3466, #6846) [@codefrog2002]
- Misc: Renamed some defines in imstb_textedit.h to avoid conflicts when using unity/jumbo builds
on a codebase where another copy of the library is used.
- Backends: GLFW, Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to
register canvas selector and auto-resize GLFW window. (#6751) [@Traveller23, @ypujante]
- Backends: Vulkan: Fixed mismatching allocator passed to vkCreateCommandPool() vs
vkDestroyCommandPool(). (#7075) [@FoonTheRaccoon]
- Examples: GLFW+Emscripten: Fixed examples not consistently resizing according to host canvas.
(#6751) [@Traveller23, @ypujante]
-----------------------------------------------------------------------

View File

@ -76,6 +76,7 @@ int main(int, char**)
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOther(window, true);
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
ImGui_ImplWGPU_Init(wgpu_device, 3, wgpu_preferred_fmt, WGPUTextureFormat_Undefined);
// Load Fonts

View File

@ -59,7 +59,7 @@ endif
CPPFLAGS += -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
#CPPFLAGS += -g
CPPFLAGS += -Wall -Wformat -Os $(EMS)
# LDFLAGS += --shell-file ../libs/emscripten/shell_minimal.html
LDFLAGS += --shell-file ../libs/emscripten/shell_minimal.html
LDFLAGS += $(EMS)
##---------------------------------------------------------------------

View File

@ -96,6 +96,9 @@ int main(int, char**)
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
#ifdef __EMSCRIPTEN__
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
#endif
ImGui_ImplOpenGL3_Init(glsl_version);
// Load Fonts

View File

@ -47,6 +47,12 @@ int main(int, char**)
// Setup window
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);

View File

@ -41,6 +41,12 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync

View File

@ -68,6 +68,12 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync

View File

@ -38,6 +38,11 @@ int main(int, char**)
// Create window with SDL_Renderer graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
if (renderer == nullptr)
{

View File

@ -385,6 +385,11 @@ int main(int, char**)
// Create window with Vulkan graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
ImVector<const char*> extensions;
uint32_t extensions_count = 0;

View File

@ -432,9 +432,10 @@ CODE
- likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2023/12/06 (1.90.1) - removed CalcListClipping() marked obsolete in 1.86. Prefer using ImGuiListClipper which can return non-contiguous ranges.
- 2023/12/05 (1.90.1) - imgui_freetype: commented out ImGuiFreeType::BuildFontAtlas() obsoleted in 1.81. prefer using #define IMGUI_ENABLE_FREETYPE or see commented code for manual calls.
- 2023/12/05 (1.90.1) - internals,columns: commented out legacy ImGuiColumnsFlags_XXX symbols redirecting to ImGuiOldColumnsFlags_XXX, obsoleted from imgui_internal.h in 1.80.
- 2023/12/19 (1.90.1) - commented out obsolete ImGuiKey_KeyPadEnter redirection to ImGuiKey_KeypadEnter.
- 2023/11/06 (1.90.1) - removed CalcListClipping() marked obsolete in 1.86. Prefer using ImGuiListClipper which can return non-contiguous ranges.
- 2023/11/05 (1.90.1) - imgui_freetype: commented out ImGuiFreeType::BuildFontAtlas() obsoleted in 1.81. prefer using #define IMGUI_ENABLE_FREETYPE or see commented code for manual calls.
- 2023/11/05 (1.90.1) - internals,columns: commented out legacy ImGuiColumnsFlags_XXX symbols redirecting to ImGuiOldColumnsFlags_XXX, obsoleted from imgui_internal.h in 1.80.
- 2023/11/09 (1.90.0) - removed IM_OFFSETOF() macro in favor of using offsetof() available in C++11. Kept redirection define (will obsolete).
- 2023/11/07 (1.90.0) - removed BeginChildFrame()/EndChildFrame() in favor of using BeginChild() with the ImGuiChildFlags_FrameStyle flag. kept inline redirection function (will obsolete).
those functions were merely PushStyle/PopStyle helpers, the removal isn't so much motivated by needing to add the feature in BeginChild(), but by the necessity to avoid BeginChildFrame() signature mismatching BeginChild() signature and features.
@ -4982,7 +4983,7 @@ void ImGui::NewFrame()
g.DebugLocateId = 0;
if (g.DebugLogClipperAutoDisableFrames > 0 && --g.DebugLogClipperAutoDisableFrames == 0)
{
DebugLog("(Auto-disabled ImGuiDebugLogFlags_EventClipper to avoid spamming)\n");
DebugLog("(Debug Log: Auto-disabled ImGuiDebugLogFlags_EventClipper after 2 frames)\n");
g.DebugLogFlags &= ~ImGuiDebugLogFlags_EventClipper;
}
@ -6825,7 +6826,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Add to focus scope stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
PushFocusScope(window->ID);
if ((flags & ImGuiWindowFlags_NavFlattened) == 0)
PushFocusScope(window->ID);
window->NavRootFocusScopeId = g.CurrentFocusScopeId;
g.CurrentWindow = NULL;
@ -7586,7 +7588,8 @@ void ImGui::End()
EndColumns();
if (!(window->Flags & ImGuiWindowFlags_DockNodeHost)) // Pop inner window clip rectangle
PopClipRect();
PopFocusScope();
if ((window->Flags & ImGuiWindowFlags_NavFlattened) == 0)
PopFocusScope();
// Stop logging
if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging
@ -8194,7 +8197,7 @@ void ImGui::SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const I
window->HitTestHoleOffset = ImVec2ih(pos - window->Pos);
}
void ImGui::SetWindowHiddendAndSkipItemsForCurrentFrame(ImGuiWindow* window)
void ImGui::SetWindowHiddenAndSkipItemsForCurrentFrame(ImGuiWindow* window)
{
window->Hidden = window->SkipItems = true;
window->HiddenFramesCanSkipItems = 1;
@ -10260,6 +10263,7 @@ void ImGuiStackSizes::CompareWithContextState(ImGuiContext* ctx)
// Advance cursor given item size for layout.
// Register minimum needed size so it can extend the bounding box used for auto-fit calculation.
// See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different.
// THIS IS IN THE PERFORMANCE CRITICAL PATH.
void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
{
ImGuiContext& g = *GImGui;
@ -10299,6 +10303,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
// Declare item bounding box for clipping and interaction.
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction.
// THIS IS IN THE PERFORMANCE CRITICAL PATH (UNTIL THE CLIPPING TEST AND EARLY-RETURN)
bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGuiItemFlags extra_flags)
{
ImGuiContext& g = *GImGui;
@ -10313,11 +10318,11 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
g.LastItemData.StatusFlags = ImGuiItemStatusFlags_None;
// Note: we don't copy 'g.NextItemData.SelectionUserData' to an hypothetical g.LastItemData.SelectionUserData: since the former is not cleared.
// Directional navigation processing
if (id != 0)
{
KeepAliveID(id);
// Directional navigation processing
// Runs prior to clipping early-out
// (a) So that NavInitRequest can be honored, for newly opened windows to select a default widget
// (b) So that we can scroll up/down past clipped items. This adds a small O(N) cost to regular navigation requests
@ -10329,18 +10334,16 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
// If we crash on a NULL g.NavWindow we need to fix the bug elsewhere.
if (!(g.LastItemData.InFlags & ImGuiItemFlags_NoNav))
{
// FIMXE-NAV: investigate changing the window tests into a simple 'if (g.NavFocusScopeId == g.CurrentFocusScopeId)' test.
window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent);
if (g.NavId == id || g.NavAnyRequest)
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
NavProcessItem();
}
// [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something".
// Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something".
// READ THE FAQ: https://dearimgui.com/faq
IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!");
}
// Lightweight clear of SetNextItemXXX data.
g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
g.NextItemData.ItemFlags = ImGuiItemFlags_None;
@ -10350,7 +10353,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
#endif
// Clipping test
// (FIXME: This is a modified copy of IsClippedEx() so we can reuse the is_rect_visible value)
// (this is a modified copy of IsClippedEx() so we can reuse the is_rect_visible value)
//const bool is_clipped = IsClippedEx(bb, id);
//if (is_clipped)
// return false;
@ -10362,12 +10365,20 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
// [DEBUG]
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
if (id != 0 && id == g.DebugLocateId)
DebugLocateItemResolveWithLastItem();
#endif
if (id != 0)
{
if (id == g.DebugLocateId)
DebugLocateItemResolveWithLastItem();
// [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something".
// Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something".
// READ THE FAQ: https://dearimgui.com/faq
IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!");
}
//if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
//if ((g.LastItemData.InFlags & ImGuiItemFlags_NoNav) == 0)
// window->DrawList->AddRect(g.LastItemData.NavRect.Min, g.LastItemData.NavRect.Max, IM_COL32(255,255,0,255)); // [DEBUG]
#endif
// We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
if (is_rect_visible)
@ -10518,10 +10529,10 @@ void ImGui::PushMultiItemsWidths(int components, float w_full)
for (int i = components - 1; i > 0; i--)
{
float next_split = IM_TRUNC(w_items * i / components);
window->DC.ItemWidthStack.push_back(prev_split - next_split);
window->DC.ItemWidthStack.push_back(ImMax(prev_split - next_split, 1.0f));
prev_split = next_split;
}
window->DC.ItemWidth = prev_split;
window->DC.ItemWidth = ImMax(prev_split, 1.0f);
g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
}
@ -11023,7 +11034,7 @@ bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags ext
if (window->Active)
{
// Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one.
SetWindowHiddendAndSkipItemsForCurrentFrame(window);
SetWindowHiddenAndSkipItemsForCurrentFrame(window);
ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount);
}
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDocking;
@ -11971,6 +11982,8 @@ void ImGui::NavProcessItemForTabbingRequest(ImGuiID id, ImGuiItemFlags item_flag
if ((move_flags & ImGuiNavMoveFlags_FocusApi) == 0)
if (g.NavLayer != g.CurrentWindow->DC.NavLayerCurrent)
return;
if (g.NavFocusScopeId != g.CurrentFocusScopeId)
return;
// - Can always land on an item when using API call.
// - Tabbing with _NavEnableKeyboard (space/enter/arrows): goes through every item.
@ -12317,8 +12330,8 @@ static void ImGui::NavUpdate()
{
const bool activate_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Space)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadActivate));
const bool activate_pressed = activate_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Space, false)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadActivate, false)));
const bool input_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Enter)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadInput));
const bool input_pressed = input_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Enter, false)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadInput, false)));
const bool input_down = (nav_keyboard_active && (IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_KeypadEnter))) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadInput));
const bool input_pressed = input_down && ((nav_keyboard_active && (IsKeyPressed(ImGuiKey_Enter, false) || IsKeyPressed(ImGuiKey_KeypadEnter, false))) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadInput, false)));
if (g.ActiveId == 0 && activate_pressed)
{
g.NavActivateId = g.NavId;
@ -13217,7 +13230,7 @@ bool ImGui::BeginTooltipHidden()
{
ImGuiContext& g = *GImGui;
bool ret = Begin("##Tooltip_Hidden", NULL, ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize);
SetWindowHiddendAndSkipItemsForCurrentFrame(g.CurrentWindow);
SetWindowHiddenAndSkipItemsForCurrentFrame(g.CurrentWindow);
return ret;
}
@ -19944,7 +19957,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
#else
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key >= 0 && key < 512 && GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
//Text("Legacy raw:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key++) { if (io.KeysDown[key]) { SameLine(); Text("\"%s\" %d", GetKeyName(key), key); } }
#endif
Text("Keys down:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !IsKeyDown(key)) continue; SameLine(); Text(IsNamedKey(key) ? "\"%s\"" : "\"%s\" %d", GetKeyName(key), key); SameLine(); Text("(%.02f)", GetKeyData(key)->DownDuration); }
@ -20722,6 +20735,9 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
SetClipboardText(g.DebugLogBuf.c_str());
BeginChild("##log", ImVec2(0.0f, 0.0f), ImGuiChildFlags_Border, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
const ImGuiDebugLogFlags backup_log_flags = g.DebugLogFlags;
g.DebugLogFlags &= ~ImGuiDebugLogFlags_EventClipper;
ImGuiListClipper clipper;
clipper.Begin(g.DebugLogIndex.size());
while (clipper.Step())
@ -20729,10 +20745,10 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
{
const char* line_begin = g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no);
const char* line_end = g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no);
TextUnformatted(line_begin, line_end);
TextUnformatted(line_begin, line_end); // Display line
ImRect text_rect = g.LastItemData.Rect;
if (IsItemHovered())
for (const char* p = line_begin; p <= line_end - 10; p++)
for (const char* p = line_begin; p <= line_end - 10; p++) // Search for 0x???????? identifiers
{
ImGuiID id = 0;
if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1)
@ -20745,6 +20761,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
p += 10;
}
}
g.DebugLogFlags = backup_log_flags;
if (GetScrollY() >= GetScrollMaxY())
SetScrollHereY(1.0f);
EndChild();

View File

@ -1051,7 +1051,7 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,
// [Internal]
ImGuiWindowFlags_NavFlattened = 1 << 23, // [BETA] On child window: allow gamepad/keyboard navigation to cross over parent border to this child or between sibling child windows.
ImGuiWindowFlags_NavFlattened = 1 << 23, // [BETA] On child window: share focus scope, allow gamepad/keyboard navigation to cross over parent border to this child or between sibling child windows.
ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild()
ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip()
ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup()
@ -1494,7 +1494,7 @@ enum ImGuiKey : int
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiKey_ModCtrl = ImGuiMod_Ctrl, ImGuiKey_ModShift = ImGuiMod_Shift, ImGuiKey_ModAlt = ImGuiMod_Alt, ImGuiKey_ModSuper = ImGuiMod_Super, // Renamed in 1.89
ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter, // Renamed in 1.87
//ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter, // Renamed in 1.87
#endif
};
@ -2243,7 +2243,7 @@ struct ImGuiIO
IMGUI_API void ClearEventsQueue(); // Clear all incoming events.
IMGUI_API void ClearInputKeys(); // Clear current keyboard/mouse/gamepad state + current frame text input buffer. Equivalent to releasing all keys/buttons.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
IMGUI_API void ClearInputCharacters(); // [Obsolete] Clear the current frame text input buffer. Now included within ClearInputKeys().
IMGUI_API void ClearInputCharacters(); // [Obsoleted in 1.89.8] Clear the current frame text input buffer. Now included within ClearInputKeys().
#endif
//------------------------------------------------------------------

View File

@ -6172,7 +6172,7 @@ static void ShowDemoWindowInputs()
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
ImGuiKey start_key = ImGuiKey_NamedKey_BEGIN;
#else
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key >= 0 && key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
ImGuiKey start_key = (ImGuiKey)0;
#endif
ImGui::Text("Keys down:"); for (ImGuiKey key = start_key; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !ImGui::IsKeyDown(key)) continue; ImGui::SameLine(); ImGui::Text((key < ImGuiKey_NamedKey_BEGIN) ? "\"%s\"" : "\"%s\" %d", ImGui::GetKeyName(key), key); }

View File

@ -3152,7 +3152,7 @@ namespace ImGui
IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0);
IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0);
IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size);
IMGUI_API void SetWindowHiddendAndSkipItemsForCurrentFrame(ImGuiWindow* window);
IMGUI_API void SetWindowHiddenAndSkipItemsForCurrentFrame(ImGuiWindow* window);
inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
inline ImVec2 WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p) { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); }

View File

@ -3931,8 +3931,8 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
if (c < 0x20)
{
bool pass = false;
pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput));
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
pass |= (c == '\t') && (flags & ImGuiInputTextFlags_AllowTabInput) != 0;
if (!pass)
return false;
apply_named_filters = false; // Override named filters below so newline and tabs can still be inserted.
@ -5134,10 +5134,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const float square_sz = GetFrameHeight();
const float w_full = CalcItemWidth();
const float w_button = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x);
const float w_inputs = w_full - w_button;
const char* label_display_end = FindRenderedTextEnd(label);
float w_full = CalcItemWidth();
g.NextItemData.ClearFlags();
BeginGroup();
@ -5171,6 +5169,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0;
const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0;
const int components = alpha ? 4 : 3;
const float w_button = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x);
const float w_inputs = ImMax(w_full - w_button, 1.0f);
w_full = w_inputs + w_button;
// Convert to the formats we need
float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f };
@ -5218,7 +5219,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
if (n > 0)
SameLine(0, style.ItemInnerSpacing.x);
float next_split = IM_TRUNC(w_items * (n + 1) / components);
SetNextItemWidth(next_split - prev_split);
SetNextItemWidth(ImMax(next_split - prev_split, 1.0f));
prev_split = next_split;
// FIXME: When ImGuiColorEditFlags_HDR flag is passed HS values snap in weird ways when SV values go below 0.