mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-06 13:08:47 +02:00
Merge branch 'viewport' into docking
# Conflicts: # imgui.h
This commit is contained in:
134
imgui.cpp
134
imgui.cpp
@ -43,6 +43,7 @@ DOCUMENTATION
|
||||
- How can I load multiple fonts?
|
||||
- How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
||||
- How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
|
||||
- How can I use Dear ImGui on a platform that doesn't have a mouse or a keyboard? (input share, remoting, gamepad)
|
||||
- I integrated Dear ImGui in my engine and the text or lines are blurry..
|
||||
- I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..
|
||||
- How can I help?
|
||||
@ -835,6 +836,21 @@ CODE
|
||||
- You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create your own ImDrawListSharedData,
|
||||
and then call your rendered code with your own ImDrawList or ImDrawData data.
|
||||
|
||||
Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)
|
||||
A: - You can control Dear ImGui with a gamepad. Read about navigation in "Using gamepad/keyboard navigation controls".
|
||||
(short version: map gamepad inputs into the io.NavInputs[] array + set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad)
|
||||
- You can share your computer mouse seamlessly with your console/tablet/phone using Synergy (https://symless.com/synergy)
|
||||
This is the preferred solution for developer productivity.
|
||||
In particular, the "micro-synergy-client" repository (https://github.com/symless/micro-synergy-client) has simple
|
||||
and portable source code (uSynergy.c/.h) for a small embeddable client that you can use on any platform to connect
|
||||
to your host computer, based on the Synergy 1.x protocol. Make sure you download the Synergy 1 server on your computer.
|
||||
Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-like protocols.
|
||||
- You may also use a third party solution such as Remote ImGui (https://github.com/JordiRos/remoteimgui) which sends
|
||||
the vertices to render over the local network, allowing you to use Dear ImGui even on a screen-less machine.
|
||||
- For touch inputs, you can increase the hit box of widgets (via the style.TouchPadding setting) to accommodate
|
||||
for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimizing
|
||||
for screen real-estate and precision.
|
||||
|
||||
Q: I integrated Dear ImGui in my engine and the text or lines are blurry..
|
||||
A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f).
|
||||
Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension.
|
||||
@ -1123,6 +1139,7 @@ ImGuiIO::ImGuiIO()
|
||||
|
||||
// Platform Functions
|
||||
BackendPlatformName = BackendRendererName = NULL;
|
||||
BackendPlatformUserData = BackendRendererUserData = BackendLanguageUserData = NULL;
|
||||
GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations
|
||||
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
|
||||
ClipboardUserData = NULL;
|
||||
@ -4249,6 +4266,8 @@ bool ImGui::IsMousePosValid(const ImVec2* mouse_pos)
|
||||
return mouse_pos->x >= MOUSE_INVALID && mouse_pos->y >= MOUSE_INVALID;
|
||||
}
|
||||
|
||||
// Return the delta from the initial clicking position.
|
||||
// This is locked and return 0.0f until the mouse moves past a distance threshold at least once.
|
||||
// NB: This is only valid if IsMousePosValid(). Back-ends in theory should always keep mouse position valid when dragging even outside the client window.
|
||||
ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold)
|
||||
{
|
||||
@ -4428,6 +4447,10 @@ static bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size
|
||||
child_window->ChildId = id;
|
||||
child_window->AutoFitChildAxises = auto_fit_axises;
|
||||
|
||||
// Set the cursor to handle case where the user called SetNextWindowPos()+BeginChild() manually.
|
||||
// While this is not really documented/defined, it seems that the expected thing to do.
|
||||
parent_window->DC.CursorPos = child_window->Pos;
|
||||
|
||||
// Process navigation-in immediately so NavInit can run on first frame
|
||||
if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayerActiveMask != 0 || child_window->DC.NavHasScroll))
|
||||
{
|
||||
@ -6673,10 +6696,10 @@ ImVec2 ImGui::GetCursorScreenPos()
|
||||
return window->DC.CursorPos;
|
||||
}
|
||||
|
||||
void ImGui::SetCursorScreenPos(const ImVec2& screen_pos)
|
||||
void ImGui::SetCursorScreenPos(const ImVec2& pos)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.CursorPos = screen_pos;
|
||||
window->DC.CursorPos = pos;
|
||||
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos);
|
||||
}
|
||||
|
||||
@ -6714,12 +6737,12 @@ void ImGui::SetScrollY(float scroll_y)
|
||||
window->ScrollTargetCenterRatio.y = 0.0f;
|
||||
}
|
||||
|
||||
void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio)
|
||||
void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio)
|
||||
{
|
||||
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
|
||||
window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y);
|
||||
window->ScrollTarget.y = (float)(int)(local_y + window->Scroll.y);
|
||||
window->ScrollTargetCenterRatio.y = center_y_ratio;
|
||||
}
|
||||
|
||||
@ -7875,7 +7898,8 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
|
||||
window->ViewportId = window->Viewport->ID;
|
||||
}
|
||||
|
||||
// Called by imgui at the end of the main loop, after EndFrame()
|
||||
// Called by user at the end of the main loop, after EndFrame()
|
||||
// This will handle the creation/update of all OS windows via function defined in the ImGuiPlatformIO api.
|
||||
void ImGui::UpdatePlatformWindows()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -7903,34 +7927,34 @@ void ImGui::UpdatePlatformWindows()
|
||||
if (viewport->LastFrameActive < g.FrameCount)
|
||||
continue;
|
||||
|
||||
// New windows that appears directly in a new viewport won't always have a size on their frame
|
||||
// New windows that appears directly in a new viewport won't always have a size on their first frame
|
||||
if (viewport->Size.x <= 0 || viewport->Size.y <= 0)
|
||||
continue;
|
||||
|
||||
// Update common viewport flags for owned viewports
|
||||
if (viewport->Window != NULL)
|
||||
if (ImGuiWindow* window = viewport->Window)
|
||||
{
|
||||
ImGuiViewportFlags flags = viewport->Flags & ~(ImGuiViewportFlags_TopMost | ImGuiViewportFlags_NoTaskBarIcon | ImGuiViewportFlags_NoDecoration);
|
||||
if (viewport->Window->Flags & ImGuiWindowFlags_Tooltip)
|
||||
if (window->Flags & ImGuiWindowFlags_Tooltip)
|
||||
flags |= ImGuiViewportFlags_TopMost;
|
||||
if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsNoTaskBarIcon) != 0 || (viewport->Window->Flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0)
|
||||
if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsNoTaskBarIcon) != 0 || (window->Flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0)
|
||||
flags |= ImGuiViewportFlags_NoTaskBarIcon;
|
||||
if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsDecoration) == 0 || (viewport->Window->Flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0)
|
||||
if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsDecoration) == 0 || (window->Flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0)
|
||||
flags |= ImGuiViewportFlags_NoDecoration;
|
||||
viewport->Flags = flags;
|
||||
}
|
||||
|
||||
// Create window
|
||||
bool is_new_window = (viewport->PlatformWindowCreated == false);
|
||||
if (is_new_window)
|
||||
bool is_new_platform_window = (viewport->PlatformWindowCreated == false);
|
||||
if (is_new_platform_window)
|
||||
{
|
||||
//IMGUI_DEBUG_LOG("Create Platform Window %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
|
||||
g.PlatformIO.Platform_CreateWindow(viewport);
|
||||
if (g.PlatformIO.Renderer_CreateWindow != NULL)
|
||||
g.PlatformIO.Renderer_CreateWindow(viewport);
|
||||
viewport->LastNameHash = 0;
|
||||
viewport->LastPlatformPos = viewport->LastPlatformSize = ImVec2(FLT_MAX, FLT_MAX); // By clearing those we'll enforce a call to Platform_SetWindowPos/Platform_SetWindowSize before Platform_ShowWindow
|
||||
viewport->LastRendererSize = viewport->Size;
|
||||
viewport->LastPlatformPos = viewport->LastPlatformSize = ImVec2(FLT_MAX, FLT_MAX); // By clearing those we'll enforce a call to Platform_SetWindowPos/Size below, before Platform_ShowWindow (FIXME: Is that necessary?)
|
||||
viewport->LastRendererSize = viewport->Size; // We don't need to call Renderer_SetWindowSize() as it is expected Renderer_CreateWindow() already did it.
|
||||
viewport->PlatformWindowCreated = true;
|
||||
}
|
||||
|
||||
@ -7953,29 +7977,32 @@ void ImGui::UpdatePlatformWindows()
|
||||
if (viewport->LastNameHash != title_hash)
|
||||
{
|
||||
char title_end_backup_c = *title_end;
|
||||
*title_end = 0; // Cut existing buffer short instead of doing an alloc/free
|
||||
*title_end = 0; // Cut existing buffer short instead of doing an alloc/free, no small gain.
|
||||
g.PlatformIO.Platform_SetWindowTitle(viewport, title_begin);
|
||||
*title_end = title_end_backup_c;
|
||||
viewport->LastNameHash = title_hash;
|
||||
}
|
||||
}
|
||||
|
||||
// Update alpha
|
||||
// Update alpha (if it changed)
|
||||
if (viewport->LastAlpha != viewport->Alpha && g.PlatformIO.Platform_SetWindowAlpha)
|
||||
g.PlatformIO.Platform_SetWindowAlpha(viewport, viewport->Alpha);
|
||||
viewport->LastAlpha = viewport->Alpha;
|
||||
|
||||
// Show window. On startup ensure platform window don't get focus
|
||||
if (is_new_window)
|
||||
if (is_new_platform_window)
|
||||
{
|
||||
if (g.FrameCount < 3) // Give a few frames for the application to stabilize (nested contents may lead to viewport being created a few frames late)
|
||||
// On startup ensure new platform window don't steal focus (give it a few frames, as nested contents may lead to viewport being created a few frames late)
|
||||
if (g.FrameCount < 3)
|
||||
viewport->Flags |= ImGuiViewportFlags_NoFocusOnAppearing;
|
||||
g.PlatformIO.Platform_ShowWindow(viewport);
|
||||
}
|
||||
|
||||
// Even without focus, we assume the window becomes front-most. This is used by our platform z-order heuristic when io.MouseHoveredViewport is not available.
|
||||
if (is_new_window && viewport->LastFrontMostStampCount != g.WindowsFrontMostStampCount)
|
||||
viewport->LastFrontMostStampCount = ++g.WindowsFrontMostStampCount;
|
||||
// Show window
|
||||
g.PlatformIO.Platform_ShowWindow(viewport);
|
||||
|
||||
// Even without focus, we assume the window becomes front-most.
|
||||
// This is useful for our platform z-order heuristic when io.MouseHoveredViewport is not available.
|
||||
if (viewport->LastFrontMostStampCount != g.WindowsFrontMostStampCount)
|
||||
viewport->LastFrontMostStampCount = ++g.WindowsFrontMostStampCount;
|
||||
}
|
||||
|
||||
// Clear request flags
|
||||
viewport->PlatformRequestClose = viewport->PlatformRequestMove = viewport->PlatformRequestResize = false;
|
||||
@ -8002,6 +8029,34 @@ void ImGui::UpdatePlatformWindows()
|
||||
}
|
||||
}
|
||||
|
||||
// This is a default/basic function for performing the rendering/swap of multiple Platform Windows.
|
||||
// Custom renderers may prefer to not call this function at all, and instead iterate the publicly exposed platform data and handle rendering/sync themselves.
|
||||
// The Render/Swap functions stored in ImGuiPlatformIO are merely here to allow for this helper to exist, but you can do it yourself:
|
||||
//
|
||||
// ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
// for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
// MyRenderFunction(platform_io.Viewports[i], my_args);
|
||||
// for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
// MySwapBufferFunction(platform_io.Viewports[i], my_args);
|
||||
//
|
||||
void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* renderer_render_arg)
|
||||
{
|
||||
// Skip the main viewport (index 0), which is always fully handled by the application!
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
{
|
||||
ImGuiViewport* viewport = platform_io.Viewports[i];
|
||||
if (platform_io.Platform_RenderWindow) platform_io.Platform_RenderWindow(viewport, platform_render_arg);
|
||||
if (platform_io.Renderer_RenderWindow) platform_io.Renderer_RenderWindow(viewport, renderer_render_arg);
|
||||
}
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
{
|
||||
ImGuiViewport* viewport = platform_io.Viewports[i];
|
||||
if (platform_io.Platform_SwapBuffers) platform_io.Platform_SwapBuffers(viewport, platform_render_arg);
|
||||
if (platform_io.Renderer_SwapBuffers) platform_io.Renderer_SwapBuffers(viewport, renderer_render_arg);
|
||||
}
|
||||
}
|
||||
|
||||
static int ImGui::FindPlatformMonitorForPos(const ImVec2& pos)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -8043,37 +8098,6 @@ static int ImGui::FindPlatformMonitorForRect(const ImRect& rect)
|
||||
return best_monitor_n;
|
||||
}
|
||||
|
||||
// This is a default/basic function for performing the rendering/swap of multiple platform windows.
|
||||
// Custom renderers may prefer to not call this function at all, and instead iterate the publicly exposed platform data and handle rendering/sync themselves.
|
||||
// The Render/Swap functions stored in ImGuiPlatformIO are merely here to allow for this helper to exist, but you can do it yourself:
|
||||
//
|
||||
// ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
// for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
// MyRenderFunction(platform_io.Viewports[i], my_args);
|
||||
// for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
// MySwapBufferFunction(platform_io.Viewports[i], my_args);
|
||||
//
|
||||
void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* renderer_render_arg)
|
||||
{
|
||||
if (!(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
return;
|
||||
|
||||
// Skip the main viewport (index 0), which is always fully handled by the application!
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
{
|
||||
ImGuiViewport* viewport = platform_io.Viewports[i];
|
||||
if (platform_io.Platform_RenderWindow) platform_io.Platform_RenderWindow(viewport, platform_render_arg);
|
||||
if (platform_io.Renderer_RenderWindow) platform_io.Renderer_RenderWindow(viewport, renderer_render_arg);
|
||||
}
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
{
|
||||
ImGuiViewport* viewport = platform_io.Viewports[i];
|
||||
if (platform_io.Platform_SwapBuffers) platform_io.Platform_SwapBuffers(viewport, platform_render_arg);
|
||||
if (platform_io.Renderer_SwapBuffers) platform_io.Renderer_SwapBuffers(viewport, renderer_render_arg);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
Reference in New Issue
Block a user