mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Refactor: moved LockWheelingWindow(), FindBestWheelingWindow(), UpdateMouseWheel() to INPUTS section
This commit is contained in:
parent
f9ab2a0e9f
commit
f83da768b6
304
imgui.cpp
304
imgui.cpp
@ -4446,156 +4446,6 @@ static void ImGui::UpdateMouseInputs()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LockWheelingWindow(ImGuiWindow* window, float wheel_amount)
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
if (window)
|
|
||||||
g.WheelingWindowReleaseTimer = ImMin(g.WheelingWindowReleaseTimer + ImAbs(wheel_amount) * WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER, WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER);
|
|
||||||
else
|
|
||||||
g.WheelingWindowReleaseTimer = 0.0f;
|
|
||||||
if (g.WheelingWindow == window)
|
|
||||||
return;
|
|
||||||
IMGUI_DEBUG_LOG_IO("LockWheelingWindow() \"%s\"\n", window ? window->Name : "NULL");
|
|
||||||
g.WheelingWindow = window;
|
|
||||||
g.WheelingWindowRefMousePos = g.IO.MousePos;
|
|
||||||
if (window == NULL)
|
|
||||||
{
|
|
||||||
g.WheelingWindowStartFrame = -1;
|
|
||||||
g.WheelingAxisAvg = ImVec2(0.0f, 0.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImGuiWindow* FindBestWheelingWindow(const ImVec2& wheel)
|
|
||||||
{
|
|
||||||
// For each axis, find window in the hierarchy that may want to use scrolling
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
ImGuiWindow* windows[2] = { NULL, NULL };
|
|
||||||
for (int axis = 0; axis < 2; axis++)
|
|
||||||
if (wheel[axis] != 0.0f)
|
|
||||||
for (ImGuiWindow* window = windows[axis] = g.HoveredWindow; window->Flags & ImGuiWindowFlags_ChildWindow; window = windows[axis] = window->ParentWindow)
|
|
||||||
{
|
|
||||||
// Bubble up into parent window if:
|
|
||||||
// - a child window doesn't allow any scrolling.
|
|
||||||
// - a child window has the ImGuiWindowFlags_NoScrollWithMouse flag.
|
|
||||||
//// - a child window doesn't need scrolling because it is already at the edge for the direction we are going in (FIXME-WIP)
|
|
||||||
const bool has_scrolling = (window->ScrollMax[axis] != 0.0f);
|
|
||||||
const bool inputs_disabled = (window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs);
|
|
||||||
//const bool scrolling_past_limits = (wheel_v < 0.0f) ? (window->Scroll[axis] <= 0.0f) : (window->Scroll[axis] >= window->ScrollMax[axis]);
|
|
||||||
if (has_scrolling && !inputs_disabled) // && !scrolling_past_limits)
|
|
||||||
break; // select this window
|
|
||||||
}
|
|
||||||
if (windows[0] == NULL && windows[1] == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// If there's only one window or only one axis then there's no ambiguity
|
|
||||||
if (windows[0] == windows[1] || windows[0] == NULL || windows[1] == NULL)
|
|
||||||
return windows[1] ? windows[1] : windows[0];
|
|
||||||
|
|
||||||
// If candidate are different windows we need to decide which one to prioritize
|
|
||||||
// - First frame: only find a winner if one axis is zero.
|
|
||||||
// - Subsequent frames: only find a winner when one is more than the other.
|
|
||||||
if (g.WheelingWindowStartFrame == -1)
|
|
||||||
g.WheelingWindowStartFrame = g.FrameCount;
|
|
||||||
if ((g.WheelingWindowStartFrame == g.FrameCount && wheel.x != 0.0f && wheel.y != 0.0f) || (g.WheelingAxisAvg.x == g.WheelingAxisAvg.y))
|
|
||||||
{
|
|
||||||
g.WheelingWindowWheelRemainder = wheel;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return (g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? windows[0] : windows[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::UpdateMouseWheel()
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
|
|
||||||
// Reset the locked window if we move the mouse or after the timer elapses.
|
|
||||||
// FIXME: Ideally we could refactor to have one timer for "changing window w/ same axis" and a shorter timer for "changing window or axis w/ other axis" (#3795)
|
|
||||||
if (g.WheelingWindow != NULL)
|
|
||||||
{
|
|
||||||
g.WheelingWindowReleaseTimer -= g.IO.DeltaTime;
|
|
||||||
if (IsMousePosValid() && ImLengthSqr(g.IO.MousePos - g.WheelingWindowRefMousePos) > g.IO.MouseDragThreshold * g.IO.MouseDragThreshold)
|
|
||||||
g.WheelingWindowReleaseTimer = 0.0f;
|
|
||||||
if (g.WheelingWindowReleaseTimer <= 0.0f)
|
|
||||||
LockWheelingWindow(NULL, 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImVec2 wheel;
|
|
||||||
wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_None) ? g.IO.MouseWheelH : 0.0f;
|
|
||||||
wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_None) ? g.IO.MouseWheel : 0.0f;
|
|
||||||
|
|
||||||
//IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y);
|
|
||||||
ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
|
|
||||||
if (!mouse_window || mouse_window->Collapsed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Zoom / Scale window
|
|
||||||
// FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned.
|
|
||||||
if (wheel.y != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
|
|
||||||
{
|
|
||||||
LockWheelingWindow(mouse_window, wheel.y);
|
|
||||||
ImGuiWindow* window = mouse_window;
|
|
||||||
const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
|
|
||||||
const float scale = new_font_scale / window->FontWindowScale;
|
|
||||||
window->FontWindowScale = new_font_scale;
|
|
||||||
if (window == window->RootWindow)
|
|
||||||
{
|
|
||||||
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
|
|
||||||
SetWindowPos(window, window->Pos + offset, 0);
|
|
||||||
window->Size = ImFloor(window->Size * scale);
|
|
||||||
window->SizeFull = ImFloor(window->SizeFull * scale);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (g.IO.KeyCtrl)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Mouse wheel scrolling
|
|
||||||
// As a standard behavior holding SHIFT while using Vertical Mouse Wheel triggers Horizontal scroll instead
|
|
||||||
// (we avoid doing it on OSX as it the OS input layer handles this already)
|
|
||||||
const bool swap_axis = g.IO.KeyShift && !g.IO.ConfigMacOSXBehaviors;
|
|
||||||
if (swap_axis)
|
|
||||||
{
|
|
||||||
wheel.x = wheel.y;
|
|
||||||
wheel.y = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maintain a rough average of moving magnitude on both axises
|
|
||||||
// FIXME: should by based on wall clock time rather than frame-counter
|
|
||||||
g.WheelingAxisAvg.x = ImExponentialMovingAverage(g.WheelingAxisAvg.x, ImAbs(wheel.x), 30);
|
|
||||||
g.WheelingAxisAvg.y = ImExponentialMovingAverage(g.WheelingAxisAvg.y, ImAbs(wheel.y), 30);
|
|
||||||
|
|
||||||
// In the rare situation where FindBestWheelingWindow() had to defer first frame of wheeling due to ambiguous main axis, reinject it now.
|
|
||||||
wheel += g.WheelingWindowWheelRemainder;
|
|
||||||
g.WheelingWindowWheelRemainder = ImVec2(0.0f, 0.0f);
|
|
||||||
if (wheel.x == 0.0f && wheel.y == 0.0f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Mouse wheel scrolling: find target and apply
|
|
||||||
// - don't renew lock if axis doesn't apply on the window.
|
|
||||||
// - select a main axis when both axises are being moved.
|
|
||||||
if (ImGuiWindow* window = (g.WheelingWindow ? g.WheelingWindow : FindBestWheelingWindow(wheel)))
|
|
||||||
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
|
|
||||||
{
|
|
||||||
bool do_scroll[2] = { wheel.x != 0.0f && window->ScrollMax.x != 0.0f, wheel.y != 0.0f && window->ScrollMax.y != 0.0f };
|
|
||||||
if (do_scroll[ImGuiAxis_X] && do_scroll[ImGuiAxis_Y])
|
|
||||||
do_scroll[(g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? ImGuiAxis_Y : ImGuiAxis_X] = false;
|
|
||||||
if (do_scroll[ImGuiAxis_X])
|
|
||||||
{
|
|
||||||
LockWheelingWindow(window, wheel.x);
|
|
||||||
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
|
||||||
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
|
|
||||||
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
|
||||||
}
|
|
||||||
if (do_scroll[ImGuiAxis_Y])
|
|
||||||
{
|
|
||||||
LockWheelingWindow(window, wheel.y);
|
|
||||||
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
|
||||||
float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
|
|
||||||
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
||||||
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||||
{
|
{
|
||||||
@ -7922,6 +7772,10 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
|||||||
// - GetMouseCursor()
|
// - GetMouseCursor()
|
||||||
// - SetMouseCursor()
|
// - SetMouseCursor()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
// - LockWheelingWindow [Internal]
|
||||||
|
// - FindBestWheelingWindow [Internal]
|
||||||
|
// - UpdateMouseWheel() [Internal]
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
// - SetNextFrameWantCaptureKeyboard()
|
// - SetNextFrameWantCaptureKeyboard()
|
||||||
// - SetNextFrameWantCaptureMouse()
|
// - SetNextFrameWantCaptureMouse()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -8506,6 +8360,156 @@ void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type)
|
|||||||
g.MouseCursor = cursor_type;
|
g.MouseCursor = cursor_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void LockWheelingWindow(ImGuiWindow* window, float wheel_amount)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (window)
|
||||||
|
g.WheelingWindowReleaseTimer = ImMin(g.WheelingWindowReleaseTimer + ImAbs(wheel_amount) * WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER, WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER);
|
||||||
|
else
|
||||||
|
g.WheelingWindowReleaseTimer = 0.0f;
|
||||||
|
if (g.WheelingWindow == window)
|
||||||
|
return;
|
||||||
|
IMGUI_DEBUG_LOG_IO("LockWheelingWindow() \"%s\"\n", window ? window->Name : "NULL");
|
||||||
|
g.WheelingWindow = window;
|
||||||
|
g.WheelingWindowRefMousePos = g.IO.MousePos;
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
g.WheelingWindowStartFrame = -1;
|
||||||
|
g.WheelingAxisAvg = ImVec2(0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImGuiWindow* FindBestWheelingWindow(const ImVec2& wheel)
|
||||||
|
{
|
||||||
|
// For each axis, find window in the hierarchy that may want to use scrolling
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* windows[2] = { NULL, NULL };
|
||||||
|
for (int axis = 0; axis < 2; axis++)
|
||||||
|
if (wheel[axis] != 0.0f)
|
||||||
|
for (ImGuiWindow* window = windows[axis] = g.HoveredWindow; window->Flags & ImGuiWindowFlags_ChildWindow; window = windows[axis] = window->ParentWindow)
|
||||||
|
{
|
||||||
|
// Bubble up into parent window if:
|
||||||
|
// - a child window doesn't allow any scrolling.
|
||||||
|
// - a child window has the ImGuiWindowFlags_NoScrollWithMouse flag.
|
||||||
|
//// - a child window doesn't need scrolling because it is already at the edge for the direction we are going in (FIXME-WIP)
|
||||||
|
const bool has_scrolling = (window->ScrollMax[axis] != 0.0f);
|
||||||
|
const bool inputs_disabled = (window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs);
|
||||||
|
//const bool scrolling_past_limits = (wheel_v < 0.0f) ? (window->Scroll[axis] <= 0.0f) : (window->Scroll[axis] >= window->ScrollMax[axis]);
|
||||||
|
if (has_scrolling && !inputs_disabled) // && !scrolling_past_limits)
|
||||||
|
break; // select this window
|
||||||
|
}
|
||||||
|
if (windows[0] == NULL && windows[1] == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// If there's only one window or only one axis then there's no ambiguity
|
||||||
|
if (windows[0] == windows[1] || windows[0] == NULL || windows[1] == NULL)
|
||||||
|
return windows[1] ? windows[1] : windows[0];
|
||||||
|
|
||||||
|
// If candidate are different windows we need to decide which one to prioritize
|
||||||
|
// - First frame: only find a winner if one axis is zero.
|
||||||
|
// - Subsequent frames: only find a winner when one is more than the other.
|
||||||
|
if (g.WheelingWindowStartFrame == -1)
|
||||||
|
g.WheelingWindowStartFrame = g.FrameCount;
|
||||||
|
if ((g.WheelingWindowStartFrame == g.FrameCount && wheel.x != 0.0f && wheel.y != 0.0f) || (g.WheelingAxisAvg.x == g.WheelingAxisAvg.y))
|
||||||
|
{
|
||||||
|
g.WheelingWindowWheelRemainder = wheel;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? windows[0] : windows[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by NewFrame()
|
||||||
|
void ImGui::UpdateMouseWheel()
|
||||||
|
{
|
||||||
|
// Reset the locked window if we move the mouse or after the timer elapses.
|
||||||
|
// FIXME: Ideally we could refactor to have one timer for "changing window w/ same axis" and a shorter timer for "changing window or axis w/ other axis" (#3795)
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (g.WheelingWindow != NULL)
|
||||||
|
{
|
||||||
|
g.WheelingWindowReleaseTimer -= g.IO.DeltaTime;
|
||||||
|
if (IsMousePosValid() && ImLengthSqr(g.IO.MousePos - g.WheelingWindowRefMousePos) > g.IO.MouseDragThreshold * g.IO.MouseDragThreshold)
|
||||||
|
g.WheelingWindowReleaseTimer = 0.0f;
|
||||||
|
if (g.WheelingWindowReleaseTimer <= 0.0f)
|
||||||
|
LockWheelingWindow(NULL, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 wheel;
|
||||||
|
wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_None) ? g.IO.MouseWheelH : 0.0f;
|
||||||
|
wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_None) ? g.IO.MouseWheel : 0.0f;
|
||||||
|
|
||||||
|
//IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y);
|
||||||
|
ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
|
||||||
|
if (!mouse_window || mouse_window->Collapsed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Zoom / Scale window
|
||||||
|
// FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned.
|
||||||
|
if (wheel.y != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
|
||||||
|
{
|
||||||
|
LockWheelingWindow(mouse_window, wheel.y);
|
||||||
|
ImGuiWindow* window = mouse_window;
|
||||||
|
const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
|
||||||
|
const float scale = new_font_scale / window->FontWindowScale;
|
||||||
|
window->FontWindowScale = new_font_scale;
|
||||||
|
if (window == window->RootWindow)
|
||||||
|
{
|
||||||
|
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
|
||||||
|
SetWindowPos(window, window->Pos + offset, 0);
|
||||||
|
window->Size = ImFloor(window->Size * scale);
|
||||||
|
window->SizeFull = ImFloor(window->SizeFull * scale);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g.IO.KeyCtrl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Mouse wheel scrolling
|
||||||
|
// As a standard behavior holding SHIFT while using Vertical Mouse Wheel triggers Horizontal scroll instead
|
||||||
|
// (we avoid doing it on OSX as it the OS input layer handles this already)
|
||||||
|
const bool swap_axis = g.IO.KeyShift && !g.IO.ConfigMacOSXBehaviors;
|
||||||
|
if (swap_axis)
|
||||||
|
{
|
||||||
|
wheel.x = wheel.y;
|
||||||
|
wheel.y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maintain a rough average of moving magnitude on both axises
|
||||||
|
// FIXME: should by based on wall clock time rather than frame-counter
|
||||||
|
g.WheelingAxisAvg.x = ImExponentialMovingAverage(g.WheelingAxisAvg.x, ImAbs(wheel.x), 30);
|
||||||
|
g.WheelingAxisAvg.y = ImExponentialMovingAverage(g.WheelingAxisAvg.y, ImAbs(wheel.y), 30);
|
||||||
|
|
||||||
|
// In the rare situation where FindBestWheelingWindow() had to defer first frame of wheeling due to ambiguous main axis, reinject it now.
|
||||||
|
wheel += g.WheelingWindowWheelRemainder;
|
||||||
|
g.WheelingWindowWheelRemainder = ImVec2(0.0f, 0.0f);
|
||||||
|
if (wheel.x == 0.0f && wheel.y == 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Mouse wheel scrolling: find target and apply
|
||||||
|
// - don't renew lock if axis doesn't apply on the window.
|
||||||
|
// - select a main axis when both axises are being moved.
|
||||||
|
if (ImGuiWindow* window = (g.WheelingWindow ? g.WheelingWindow : FindBestWheelingWindow(wheel)))
|
||||||
|
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
|
||||||
|
{
|
||||||
|
bool do_scroll[2] = { wheel.x != 0.0f && window->ScrollMax.x != 0.0f, wheel.y != 0.0f && window->ScrollMax.y != 0.0f };
|
||||||
|
if (do_scroll[ImGuiAxis_X] && do_scroll[ImGuiAxis_Y])
|
||||||
|
do_scroll[(g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? ImGuiAxis_Y : ImGuiAxis_X] = false;
|
||||||
|
if (do_scroll[ImGuiAxis_X])
|
||||||
|
{
|
||||||
|
LockWheelingWindow(window, wheel.x);
|
||||||
|
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
||||||
|
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
|
||||||
|
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
||||||
|
}
|
||||||
|
if (do_scroll[ImGuiAxis_Y])
|
||||||
|
{
|
||||||
|
LockWheelingWindow(window, wheel.y);
|
||||||
|
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
||||||
|
float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
|
||||||
|
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui::SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard)
|
void ImGui::SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
Loading…
Reference in New Issue
Block a user