mirror of
https://github.com/ocornut/imgui.git
synced 2026-05-25 00:16:32 +08:00
Merge branch 'master' into docking w/ custom fix in Scrollbar()
# Conflicts: # backends/imgui_impl_win32.cpp # imgui.cpp
This commit is contained in:
@@ -639,6 +639,7 @@ void ImGui_ImplSDLGPU3_DestroyDeviceObjects()
|
||||
if (bd->VertexShader) { SDL_ReleaseGPUShader(v->Device, bd->VertexShader); bd->VertexShader = nullptr; }
|
||||
if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->Device, bd->FragmentShader); bd->FragmentShader = nullptr; }
|
||||
if (bd->TexSamplerLinear) { SDL_ReleaseGPUSampler(v->Device, bd->TexSamplerLinear); bd->TexSamplerLinear = nullptr; }
|
||||
if (bd->TexSamplerNearest) { SDL_ReleaseGPUSampler(v->Device, bd->TexSamplerNearest); bd->TexSamplerNearest = nullptr; }
|
||||
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->Device, bd->Pipeline); bd->Pipeline = nullptr; }
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-01-28: Inputs: Minor optimization not submitting gamepad input if packet number has not changed (reworked from 2025-09-23 attempt). (#9202, #8556)
|
||||
// 2026-01-26: [Docking] Fixed an issue from 1.90.5 where newly appearing windows that are not parented to the main viewport don't have task bar icon appear before the windows was explicited refocused. (#7354, #8669)
|
||||
// 2025-12-03: Inputs: handle WM_IME_CHAR/WM_IME_COMPOSITION messages to support Unicode inputs on MBCS (non-Unicode) Windows. (#9099, #3653, #5961)
|
||||
// 2025-10-19: Inputs: Revert previous change to allow for io.ClearInputKeys() on focus-out not losing gamepad state.
|
||||
@@ -142,6 +143,7 @@ struct ImGui_ImplWin32_Data
|
||||
HMODULE XInputDLL;
|
||||
PFN_XInputGetCapabilities XInputGetCapabilities;
|
||||
PFN_XInputGetState XInputGetState;
|
||||
DWORD XInputPacketNumber;
|
||||
#endif
|
||||
|
||||
ImGui_ImplWin32_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
@@ -423,6 +425,9 @@ static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io)
|
||||
if (!bd->HasGamepad || bd->XInputGetState == nullptr || bd->XInputGetState(0, &xinput_state) != ERROR_SUCCESS)
|
||||
return;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
if (bd->XInputPacketNumber != 0 && bd->XInputPacketNumber == xinput_state.dwPacketNumber)
|
||||
return;
|
||||
bd->XInputPacketNumber = xinput_state.dwPacketNumber;
|
||||
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0); }
|
||||
@@ -877,6 +882,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hwnd, UINT msg, WPA
|
||||
case WM_SETFOCUS:
|
||||
case WM_KILLFOCUS:
|
||||
io.AddFocusEvent(msg == WM_SETFOCUS);
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
bd->XInputPacketNumber = 0; // FIXME: Technically, calling io.ClearInputKeys() directly would require this as well.
|
||||
#endif
|
||||
return 0;
|
||||
case WM_INPUTLANGCHANGE:
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||
|
||||
@@ -172,6 +172,10 @@ Other Changes:
|
||||
- Fixed remote/shortcut InputText() not teleporting mouse cursor when
|
||||
nav cursor is visible and `io.ConfigNavMoveSetMousePos` is enabled.
|
||||
- Fixed a looping/wrapping issue when done in menu layer. (#9178)
|
||||
- Fixed speed scale for resizing/moving with keyboard/gamepad. We incorrectly
|
||||
used io.DisplayFramebufferScale (very old code), effectively making those
|
||||
actions faster on macOS/iOS retina screens.
|
||||
(changed this to use a style scale factor that's not fully formalized yet)
|
||||
- Scrollbar: fixed a codepath leading to a divide-by-zero (which would not be
|
||||
noticeable by user but detected by sanitizers). (#9089) [@judicaelclair]
|
||||
- InvisibleButton: allow calling with size (0,0) to fit to available content
|
||||
@@ -180,6 +184,8 @@ Other Changes:
|
||||
nesting a tooltip in a disabled block. (#9180, #7640) [@RegimantasSimkus]
|
||||
- Added GetItemFlags() in public API for consistency and to expose generic
|
||||
flags of last submitted item. (#9127)
|
||||
- Log/Capture: fixed erroneously injecting extra carriage returns in output
|
||||
buffer when ItemSpacing.y > FramePadding.y + 1.
|
||||
- Images:
|
||||
- Added style.ImageRounding, ImGuiStyleVar_ImageRounding to configure
|
||||
rounding of Image() widgets. (#2942, #845)
|
||||
@@ -198,6 +204,8 @@ Other Changes:
|
||||
- Debug Log: fixed incorrectly printing characters in IO log when submitting
|
||||
non-ASCII values to `io.AddInputCharacter()`. (#9099)
|
||||
- Debug Log: can output to debugger on Windows. (#5855)
|
||||
- Demo:
|
||||
- Slightly improve Selectable() demos. (#9193)
|
||||
- Backends:
|
||||
- DirectX10: added `SamplerNearest` in `ImGui_ImplDX10_RenderState`.
|
||||
(+renamed `SamplerDefault` to `SamplerLinear`, which was tagged as beta API)
|
||||
@@ -221,6 +229,8 @@ Other Changes:
|
||||
devices. (#8784) [@FelixStach]
|
||||
- Win32: handle `WM_IME_CHAR`/`WM_IME_COMPOSITION` to support Unicode inputs on
|
||||
MBCS (non-Unicode) Windows. (#9099, #3653, #5961) [@ulhc, @ocornut, @Othereum]
|
||||
- Win32: minor optimization not submitting gamepad input if packet number has not
|
||||
changed (reworked previous 1.92.4). (#9202, #8556) [@AhmedSamyMousa, @MidTerm-CN]
|
||||
- Examples:
|
||||
- Win32+DirectX12: ignore seemingly incorrect `D3D12_MESSAGE_ID_FENCE_ZERO_WAIT`
|
||||
warning on startups on some setups. (#9084, #9093) [@RT2Code, @LeoGautheron]
|
||||
|
||||
@@ -7330,7 +7330,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, int* border_hove
|
||||
if (nav_resize_dir.x != 0.0f || nav_resize_dir.y != 0.0f)
|
||||
{
|
||||
const float NAV_RESIZE_SPEED = 600.0f;
|
||||
const float resize_step = NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y);
|
||||
const float resize_step = NAV_RESIZE_SPEED * g.IO.DeltaTime * GetScale();
|
||||
g.NavWindowingAccumDeltaSize += nav_resize_dir * resize_step;
|
||||
g.NavWindowingAccumDeltaSize = ImMax(g.NavWindowingAccumDeltaSize, clamp_rect.Min - window->Pos - window->Size); // We need Pos+Size >= clmap_rect.Min, so Size >= clmap_rect.Min - Pos, so size_delta >= clmap_rect.Min - window->Pos - window->Size
|
||||
g.NavWindowingToggleLayer = false;
|
||||
@@ -7486,10 +7486,12 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
||||
bg_col = 0;
|
||||
if (bg_col & IM_COL32_A_MASK)
|
||||
{
|
||||
ImRect bg_rect(window->Pos + ImVec2(0, window->TitleBarHeight), window->Pos + window->Size);
|
||||
ImDrawFlags bg_rounding_flags = (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom;
|
||||
ImDrawList* bg_draw_list = window->DockIsActive ? window->DockNode->HostWindow->DrawList : window->DrawList;
|
||||
if (window->DockIsActive)
|
||||
bg_draw_list->ChannelsSetCurrent(DOCKING_HOST_DRAW_CHANNEL_BG);
|
||||
bg_draw_list->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom);
|
||||
bg_draw_list->AddRectFilled(bg_rect.Min, bg_rect.Max, bg_col, window_rounding, bg_rounding_flags);
|
||||
if (window->DockIsActive)
|
||||
bg_draw_list->ChannelsSetCurrent(DOCKING_HOST_DRAW_CHANNEL_FG);
|
||||
}
|
||||
@@ -11121,6 +11123,8 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
||||
#endif
|
||||
|
||||
// Remaining events will be processed on the next frame
|
||||
// FIXME-MULTITHREADING: io.AddKeyEvent() etc. calls are mostly thread-safe apart from the fact they push to this
|
||||
// queue which may be resized here. Could potentially rework this to narrow down the section needing a mutex? (#5772)
|
||||
if (event_n == g.InputEventsQueue.Size)
|
||||
g.InputEventsQueue.resize(0);
|
||||
else
|
||||
@@ -13477,6 +13481,7 @@ void ImGui::BringWindowToFocusFront(ImGuiWindow* window)
|
||||
}
|
||||
|
||||
// Note technically focus related but rather adjacent and close to BringWindowToFocusFront()
|
||||
// FIXME-FOCUS: Could opt-in/opt-out enable modal check like in FocusWindow().
|
||||
void ImGui::BringWindowToDisplayFront(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -15245,7 +15250,7 @@ static void ImGui::NavUpdateWindowing()
|
||||
if (nav_move_dir.x != 0.0f || nav_move_dir.y != 0.0f)
|
||||
{
|
||||
const float NAV_MOVE_SPEED = 800.0f;
|
||||
const float move_step = NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
||||
const float move_step = NAV_MOVE_SPEED * io.DeltaTime * GetScale();
|
||||
g.NavWindowingAccumDeltaPos += nav_move_dir * move_step;
|
||||
g.NavHighlightItemUnderNav = true;
|
||||
ImVec2 accum_floored = ImTrunc(g.NavWindowingAccumDeltaPos);
|
||||
@@ -15800,7 +15805,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
|
||||
if (!text_end)
|
||||
text_end = FindRenderedTextEnd(text, text_end);
|
||||
|
||||
const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + g.Style.FramePadding.y + 1);
|
||||
const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + ImMax(g.Style.FramePadding.y, g.Style.ItemSpacing.y) + 1);
|
||||
if (ref_pos)
|
||||
g.LogLinePosY = ref_pos->y;
|
||||
if (log_new_line)
|
||||
|
||||
@@ -1966,7 +1966,7 @@ enum ImGuiColorEditFlags_
|
||||
ImGuiColorEditFlags_NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview.
|
||||
ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker).
|
||||
ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small color square preview instead.
|
||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
|
||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target/source. ColorButton: disable drag and drop source.
|
||||
ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)
|
||||
ImGuiColorEditFlags_NoColorMarkers = 1 << 11, // // ColorEdit: disable rendering R/G/B/A color marker. May also be disabled globally by setting style.ColorMarkerSize = 0.
|
||||
|
||||
|
||||
+43
-10
@@ -2395,15 +2395,45 @@ static void DemoWindowWidgetsSelectables()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more items on the same line");
|
||||
if (ImGui::TreeNode("Rendering more items on the same line"))
|
||||
IMGUI_DEMO_MARKER("Widgets/Selectables/Multiple items on the same line");
|
||||
if (ImGui::TreeNode("Multiple items on the same line"))
|
||||
{
|
||||
// (1) Using SetNextItemAllowOverlap()
|
||||
// (2) Using the Selectable() override that takes "bool* p_selected" parameter, the bool value is toggled automatically.
|
||||
static bool selected[3] = { false, false, false };
|
||||
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(); ImGui::SmallButton("Link 1");
|
||||
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(); ImGui::SmallButton("Link 2");
|
||||
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(); ImGui::SmallButton("Link 3");
|
||||
// (1)
|
||||
// - Using SetNextItemAllowOverlap()
|
||||
// - Using the Selectable() override that takes "bool* p_selected" parameter, the bool value is toggled automatically.
|
||||
{
|
||||
static bool selected[3] = {};
|
||||
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(); ImGui::SmallButton("Link 1");
|
||||
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("hello.cpp", &selected[1]); ImGui::SameLine(); ImGui::SmallButton("Link 2");
|
||||
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("hello.h", &selected[2]); ImGui::SameLine(); ImGui::SmallButton("Link 3");
|
||||
}
|
||||
|
||||
// (2)
|
||||
// - Using ImGuiSelectableFlags_AllowOverlap is a shortcut for calling SetNextItemAllowOverlap()
|
||||
// - No visible label, display contents inside the selectable bounds.
|
||||
// - We don't maintain actual selection in this example to keep things simple.
|
||||
ImGui::Spacing();
|
||||
{
|
||||
static bool checked[5] = {};
|
||||
static int selected_n = 0;
|
||||
const float color_marker_w = ImGui::CalcTextSize("x").x;
|
||||
for (int n = 0; n < 5; n++)
|
||||
{
|
||||
ImGui::PushID(n);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
if (ImGui::Selectable("##selectable", selected_n == n, ImGuiSelectableFlags_AllowOverlap))
|
||||
selected_n = n;
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGui::Checkbox("##check", &checked[n]);
|
||||
ImGui::SameLine();
|
||||
ImVec4 color((n & 1) ? 1.0f : 0.2f, (n & 2) ? 1.0f : 0.2f, 0.2f, 1.0f);
|
||||
ImGui::ColorButton("##color", color, ImGuiColorEditFlags_NoTooltip, ImVec2(color_marker_w, 0));
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Some label");
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
@@ -2454,13 +2484,14 @@ static void DemoWindowWidgetsSelectables()
|
||||
if (winning_state)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f + 0.5f * cosf(time * 2.0f), 0.5f + 0.5f * sinf(time * 3.0f)));
|
||||
|
||||
const float size = ImGui::CalcTextSize("Sailor").x;
|
||||
for (int y = 0; y < 4; y++)
|
||||
for (int x = 0; x < 4; x++)
|
||||
{
|
||||
if (x > 0)
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(y * 4 + x);
|
||||
if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(50, 50)))
|
||||
if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(size, size)))
|
||||
{
|
||||
// Toggle clicked cell + toggle neighbors
|
||||
selected[y][x] ^= 1;
|
||||
@@ -2483,7 +2514,9 @@ static void DemoWindowWidgetsSelectables()
|
||||
"By default, Selectables uses style.SelectableTextAlign but it can be overridden on a per-item "
|
||||
"basis using PushStyleVar(). You'll probably want to always keep your default situation to "
|
||||
"left-align otherwise it becomes difficult to layout multiple items on a same line");
|
||||
|
||||
static bool selected[3 * 3] = { true, false, true, false, true, false, true, false, true };
|
||||
const float size = ImGui::CalcTextSize("(1.0,1.0)").x;
|
||||
for (int y = 0; y < 3; y++)
|
||||
{
|
||||
for (int x = 0; x < 3; x++)
|
||||
@@ -2493,7 +2526,7 @@ static void DemoWindowWidgetsSelectables()
|
||||
sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y);
|
||||
if (x > 0) ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment);
|
||||
ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(80, 80));
|
||||
ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(size, size));
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3384,6 +3384,7 @@ namespace ImGui
|
||||
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
|
||||
IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx);
|
||||
IMGUI_API ImGuiPlatformIO& GetPlatformIO(ImGuiContext* ctx);
|
||||
inline float GetScale() { ImGuiContext& g = *GImGui; return g.Style._MainScale; } // FIXME-DPI: I don't want to formalize this just yet. Because reasons. Please don't use.
|
||||
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
|
||||
inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; }
|
||||
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
|
||||
|
||||
+3
-14
@@ -988,20 +988,8 @@ void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
|
||||
// Calculate scrollbar bounding box
|
||||
ImRect bb = GetWindowScrollbarRect(window, axis);
|
||||
ImDrawFlags rounding_corners = ImDrawFlags_RoundCornersNone;
|
||||
if (axis == ImGuiAxis_X)
|
||||
{
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomLeft;
|
||||
if (!window->ScrollbarY)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar))
|
||||
rounding_corners |= ImDrawFlags_RoundCornersTopRight;
|
||||
if (!window->ScrollbarX)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
ImRect host_rect = (window->DockIsActive ? window->DockNode->HostWindow : window)->Rect();
|
||||
ImDrawFlags rounding_corners = CalcRoundingFlagsForRectInRect(bb, host_rect, g.Style.WindowBorderSize);
|
||||
float size_visible = window->InnerRect.Max[axis] - window->InnerRect.Min[axis];
|
||||
float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f;
|
||||
ImS64 scroll = (ImS64)window->Scroll[axis];
|
||||
@@ -6491,6 +6479,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
}
|
||||
|
||||
// Initialize/override default color options
|
||||
// FIXME: Could be moved to a simple IO field.
|
||||
void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
Reference in New Issue
Block a user