mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-05 20:48:46 +02:00
Viewport, Platform, Examples: Changes to resizing flow + restored support for Platform events affecting the ImGui windows (so Decorated windows are functional). (#1542, #1042) ..
SDL: Added platform move/resize/close support. GLFW: Added platform move/resize support. Moved Close to use callback for consistency. Win32: Vulkan: Fixed resize support. Naming is WIP "PlatforrmRequestXXX" is too ambiguous. Basically we either have a ImGui->Platform flow or a Platform->ImGui flow. Working a bigger refactor now.
This commit is contained in:
@ -310,6 +310,24 @@ struct ImGuiPlatformDataGlfw
|
||||
~ImGuiPlatformDataGlfw() { IM_ASSERT(Window == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
viewport->PlatformRequestClose = true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
viewport->PlatformRequestMove = true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
viewport->PlatformRequestResize = true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_CreateViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiPlatformDataGlfw* data = IM_NEW(ImGuiPlatformDataGlfw)();
|
||||
@ -324,6 +342,9 @@ static void ImGui_ImplGlfw_CreateViewport(ImGuiViewport* viewport)
|
||||
data->WindowOwned = true;
|
||||
viewport->PlatformHandle = (void*)data->Window;
|
||||
ImGui_ImplGlfw_InstallCallbacks(data->Window);
|
||||
glfwSetWindowCloseCallback(data->Window, ImGui_ImplGlfw_WindowCloseCallback);
|
||||
glfwSetWindowPosCallback(data->Window, ImGui_ImplGlfw_WindowPosCallback);
|
||||
glfwSetWindowSizeCallback(data->Window, ImGui_ImplGlfw_WindowSizeCallback);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_DestroyViewport(ImGuiViewport* viewport)
|
||||
@ -431,9 +452,6 @@ static void ImGui_ImplGlfw_RenderViewport(ImGuiViewport* viewport)
|
||||
ImGuiPlatformDataGlfw* data = (ImGuiPlatformDataGlfw*)viewport->PlatformUserData;
|
||||
if (g_ClientApi == GlfwClientApi_OpenGL)
|
||||
glfwMakeContextCurrent(data->Window);
|
||||
|
||||
if (glfwWindowShouldClose(data->Window))
|
||||
viewport->PlatformRequestClose = true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport)
|
||||
|
@ -100,6 +100,21 @@ bool ImGui_ImplSDL2_ProcessEvent(SDL_Event* event)
|
||||
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
|
||||
return true;
|
||||
}
|
||||
// Multi-viewport support
|
||||
case SDL_WINDOWEVENT:
|
||||
Uint8 window_event = event->window.event;
|
||||
if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID)))
|
||||
{
|
||||
if (window_event == SDL_WINDOWEVENT_CLOSE)
|
||||
viewport->PlatformRequestClose = true;
|
||||
if (window_event == SDL_WINDOWEVENT_MOVED)
|
||||
viewport->PlatformRequestMove = true;
|
||||
if (window_event == SDL_WINDOWEVENT_RESIZED)
|
||||
viewport->PlatformRequestResize = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -288,7 +303,8 @@ static void ImGui_ImplSDL2_CreateViewport(ImGuiViewport* viewport)
|
||||
sdl_flags |= SDL_WINDOW_HIDDEN;
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
|
||||
data->Window = SDL_CreateWindow("No Title Yet", 0, 0, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
|
||||
data->Window = SDL_CreateWindow("No Title Yet",
|
||||
(int)viewport->PlatformOsDesktopPos.x, (int)viewport->PlatformOsDesktopPos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
|
||||
if (main_viewport_data->GLContext)
|
||||
data->GLContext = SDL_GL_CreateContext(data->Window);
|
||||
viewport->PlatformHandle = (void*)data->Window;
|
||||
@ -328,7 +344,7 @@ static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
|
||||
ex_style &= ~WS_EX_APPWINDOW;
|
||||
ex_style |= WS_EX_TOOLWINDOW;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
}
|
||||
|
||||
// SDL hack: SDL always activate/focus windows :/
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
@ -336,7 +352,7 @@ static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
|
||||
::ShowWindow(hwnd, SW_SHOWNA);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_ShowWindow(data->Window);
|
||||
|
@ -1108,8 +1108,9 @@ static void ImGui_ImplVulkan_DestroyViewport(ImGuiViewport* viewport)
|
||||
static void ImGui_ImplVulkan_ResizeViewport(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGuiPlatformDataVulkan* data = (ImGuiPlatformDataVulkan*)viewport->RendererUserData;
|
||||
ImGui_ImplVulkan_WindowData* wd = &data->WindowData;
|
||||
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, (int)size.x, (int)size.y);
|
||||
if (data == NULL) // This is NULL for the main viewport (which is left to the user/app to handle)
|
||||
return;
|
||||
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &data->WindowData, g_Allocator, (int)size.x, (int)size.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_RenderViewport(ImGuiViewport* viewport)
|
||||
|
@ -356,11 +356,10 @@ float ImGui_ImplWin32_GetDpiScaleForRect(int x1, int y1, int x2, int y2)
|
||||
struct ImGuiPlatformDataWin32
|
||||
{
|
||||
HWND Hwnd;
|
||||
bool ExternalResize;
|
||||
DWORD DwStyle;
|
||||
DWORD DwExStyle;
|
||||
|
||||
ImGuiPlatformDataWin32() { Hwnd = NULL; ExternalResize = false; DwStyle = DwExStyle = 0; }
|
||||
ImGuiPlatformDataWin32() { Hwnd = NULL; DwStyle = DwExStyle = 0; }
|
||||
~ImGuiPlatformDataWin32() { IM_ASSERT(Hwnd == NULL); }
|
||||
};
|
||||
|
||||
@ -386,12 +385,11 @@ static void ImGui_ImplWin32_CreateViewport(ImGuiViewport* viewport)
|
||||
// Create window
|
||||
RECT rect = { (LONG)viewport->PlatformOsDesktopPos.x, (LONG)viewport->PlatformOsDesktopPos.y, (LONG)(viewport->PlatformOsDesktopPos.x + viewport->Size.x), (LONG)(viewport->PlatformOsDesktopPos.y + viewport->Size.y) };
|
||||
::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle);
|
||||
data->ExternalResize = true;
|
||||
data->Hwnd = ::CreateWindowExA(
|
||||
data->DwExStyle, "ImGui Platform", "No Title Yet", data->DwStyle, // Style, class name, window name
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
|
||||
g_hWnd, NULL, ::GetModuleHandle(NULL), NULL); // Parent window, Menu, Instance, Param
|
||||
data->ExternalResize = false;
|
||||
viewport->PlatformRequestResize = false;
|
||||
viewport->PlatformHandle = data->Hwnd;
|
||||
}
|
||||
|
||||
@ -417,12 +415,10 @@ static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Hwnd != 0);
|
||||
data->ExternalResize = true;
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
::ShowWindow(data->Hwnd, SW_SHOWNA);
|
||||
else
|
||||
::ShowWindow(data->Hwnd, SW_SHOW);
|
||||
data->ExternalResize = false;
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplWin32_GetWindowPos(ImGuiViewport* viewport)
|
||||
@ -456,11 +452,9 @@ static void ImGui_ImplWin32_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Hwnd != 0);
|
||||
data->ExternalResize = true;
|
||||
RECT rect = { 0, 0, (LONG)size.x, (LONG)size.y };
|
||||
::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle); // Client to Screen
|
||||
::SetWindowPos(data->Hwnd, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||
data->ExternalResize = false;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
@ -489,27 +483,22 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
|
||||
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd))
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData;
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
viewport->PlatformRequestClose = true;
|
||||
return 0;
|
||||
case WM_MOVE:
|
||||
viewport->PlatformOsDesktopPos = ImVec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam));
|
||||
viewport->PlatformRequestMove = true;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
viewport->PlatformRequestResize = true;
|
||||
break;
|
||||
case WM_NCHITTEST:
|
||||
// Let mouse pass-through the window, this is used while e.g. dragging a window, we creates a temporary overlay but want the cursor to aim behind our overlay.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoInputs)
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
if (!data->ExternalResize)
|
||||
viewport->PlatformRequestResize = true;
|
||||
if (io.RendererInterface.ResizeViewport)
|
||||
io.RendererInterface.ResizeViewport(viewport, ImVec2((float)LOWORD(lParam), (float)HIWORD(lParam)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user