mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-12 03:49:05 +08:00
Examples: DX11 + Win32: Initial attempt at implementing the viewport/platform api. (WIP/test API) (#1542)
This commit is contained in:
parent
735267d27c
commit
25349b31d7
@ -117,10 +117,12 @@ int main(int, char**)
|
||||
|
||||
// Setup ImGui binding
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.NavFlags |= ImGuiNavFlags_EnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
|
||||
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
//io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls
|
||||
|
||||
// Setup style
|
||||
ImGui::StyleColorsDark();
|
||||
@ -206,6 +208,9 @@ int main(int, char**)
|
||||
ImGui::Render();
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindows();
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2018-XX-XX: Platform: Added support for multiple windows via the ImGuiRendererInterface
|
||||
// 2018-XX-XX: DirectX11: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications).
|
||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
@ -26,6 +27,7 @@
|
||||
// DirectX data
|
||||
static ID3D11Device* g_pd3dDevice = NULL;
|
||||
static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
|
||||
static IDXGIFactory1* g_pFactory = NULL;
|
||||
static ID3D11Buffer* g_pVB = NULL;
|
||||
static ID3D11Buffer* g_pIB = NULL;
|
||||
static ID3D10Blob * g_pVertexShaderBlob = NULL;
|
||||
@ -46,6 +48,10 @@ struct VERTEX_CONSTANT_BUFFER
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX11_InitPlatformInterface();
|
||||
static void ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
|
||||
// Render function
|
||||
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
|
||||
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
@ -466,13 +472,29 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||
|
||||
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||
{
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
IDXGIAdapter* pDXGIAdapter = NULL;
|
||||
IDXGIFactory1* pFactory = NULL;
|
||||
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) != S_OK)
|
||||
return false;
|
||||
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) != S_OK)
|
||||
return false;
|
||||
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) != S_OK)
|
||||
return false;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
g_pd3dDevice = device;
|
||||
g_pd3dDeviceContext = device_context;
|
||||
g_pFactory = pFactory;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports)
|
||||
ImGui_ImplDX11_InitPlatformInterface();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
g_pd3dDevice = NULL;
|
||||
g_pd3dDeviceContext = NULL;
|
||||
@ -483,3 +505,121 @@ void ImGui_ImplDX11_NewFrame()
|
||||
if (!g_pFontSampler)
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
// Platform Windows
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "imgui_internal.h" // ImGuiViewport
|
||||
|
||||
struct ImGuiPlatformDataDx11
|
||||
{
|
||||
IDXGISwapChain* SwapChain;
|
||||
ID3D11RenderTargetView* RTView;
|
||||
|
||||
ImGuiPlatformDataDx11() { SwapChain = NULL; RTView = NULL; }
|
||||
~ImGuiPlatformDataDx11() { IM_ASSERT(SwapChain == NULL && RTView == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplDX11_CreateViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiPlatformDataDx11* data = IM_NEW(ImGuiPlatformDataDx11)();
|
||||
viewport->RendererUserData = data;
|
||||
|
||||
// FIXME-PLATFORM
|
||||
HWND hwnd = (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
// Create swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.BufferCount = 1;
|
||||
sd.OutputWindow = hwnd;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
sd.Flags = 0;
|
||||
|
||||
IM_ASSERT(data->SwapChain == NULL && data->RTView == NULL);
|
||||
g_pFactory->CreateSwapChain(g_pd3dDevice, &sd, &data->SwapChain);
|
||||
|
||||
// Create the render target
|
||||
if (data->SwapChain)
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer;
|
||||
data->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &data->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_DestroyViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
if (ImGuiPlatformDataDx11* data = (ImGuiPlatformDataDx11*)viewport->RendererUserData)
|
||||
{
|
||||
if (data->SwapChain)
|
||||
data->SwapChain->Release();
|
||||
data->SwapChain = NULL;
|
||||
if (data->RTView)
|
||||
data->RTView->Release();
|
||||
data->RTView = NULL;
|
||||
IM_DELETE(data);
|
||||
}
|
||||
viewport->RendererUserData = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_ResizeViewport(ImGuiViewport* viewport, int w, int h)
|
||||
{
|
||||
ImGuiPlatformDataDx11* data = (ImGuiPlatformDataDx11*)viewport->RendererUserData;
|
||||
if (data->RTView)
|
||||
{
|
||||
data->RTView->Release();
|
||||
data->RTView = NULL;
|
||||
}
|
||||
if (data->SwapChain)
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer = NULL;
|
||||
data->SwapChain->ResizeBuffers(0, w, h, DXGI_FORMAT_UNKNOWN, 0);
|
||||
data->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &data->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_RenderViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiPlatformDataDx11* data = (ImGuiPlatformDataDx11*)viewport->RendererUserData;
|
||||
ImVec4 clear_color = ImGui::GetStyle().Colors[ImGuiCol_WindowBg]; // FIXME-PLATFORM
|
||||
clear_color.w = 1.0f;
|
||||
g_pd3dDeviceContext->OMSetRenderTargets(1, &data->RTView, NULL);
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(data->RTView, (float*)&clear_color);
|
||||
ImGui_ImplDX11_RenderDrawData(&viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiPlatformDataDx11* data = (ImGuiPlatformDataDx11*)viewport->RendererUserData;
|
||||
data->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_InitPlatformInterface()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.RendererInterface.CreateViewport = ImGui_ImplDX11_CreateViewport;
|
||||
io.RendererInterface.DestroyViewport = ImGui_ImplDX11_DestroyViewport;
|
||||
io.RendererInterface.ResizeViewport = ImGui_ImplDX11_ResizeViewport;
|
||||
io.RendererInterface.RenderViewport = ImGui_ImplDX11_RenderViewport;
|
||||
io.RendererInterface.SwapBuffers = ImGui_ImplDX11_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(&io.RendererInterface, 0, sizeof(io.RendererInterface));
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,12 @@
|
||||
#include "imgui_impl_win32.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "imgui_internal.h" // FIXME-PLATFORM
|
||||
|
||||
// CHANGELOG
|
||||
// 2018-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformInterface
|
||||
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
|
||||
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
|
||||
// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set.
|
||||
@ -24,6 +28,10 @@ static INT64 g_Time = 0;
|
||||
static INT64 g_TicksPerSecond = 0;
|
||||
static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_;
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplWin32_InitPlatformInterface();
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
{
|
||||
@ -57,11 +65,21 @@ bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
io.ImeWindowHandle = g_hWnd; return true;
|
||||
io.ImeWindowHandle = g_hWnd;
|
||||
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = (void*)g_hWnd;
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports)
|
||||
ImGui_ImplWin32_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_Shutdown()
|
||||
{
|
||||
ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
g_hWnd = (HWND)0;
|
||||
}
|
||||
|
||||
@ -92,6 +110,42 @@ static void ImGui_ImplWin32_UpdateMouseCursor()
|
||||
}
|
||||
}
|
||||
|
||||
// This code supports multiple OS Windows mapped into different ImGui viewports,
|
||||
// So it is a little more complicated than your typical binding code (which only needs to set io.MousePos in your WM_MOUSEMOVE handler)
|
||||
// This is what imgui needs from the back-end to support multiple windows:
|
||||
// - io.MousePos = mouse position (e.g. io.MousePos == viewport->Pos when we are on the upper-left of our viewport)
|
||||
// - io.MousePosViewport = viewport which mouse position is based from (generally the focused/active/capturing viewport)
|
||||
// - io.MouseHoveredWindow = viewport which mouse is hovering, **regardless of it being the active/focused window**, **regardless of another window holding mouse captured**. [Optional]
|
||||
// This function overwrite the value of io.MousePos normally updated by the WM_MOUSEMOVE handler.
|
||||
// We keep the WM_MOUSEMOVE handling code so that WndProc function can be copied as-in in applications which do not need multiple OS windows support.
|
||||
static void ImGui_ImplWin32_UpdateMousePos()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
io.MousePosViewport = 0;
|
||||
io.MouseHoveredViewport = 0;
|
||||
|
||||
POINT pos;
|
||||
if (!::GetCursorPos(&pos))
|
||||
return;
|
||||
|
||||
// Our back-end can tell which window is under the mouse cursor (not every back-end can), so pass that info to imgui
|
||||
io.ConfigFlags |= ImGuiConfigFlags_PlatformHasMouseHoveredViewport;
|
||||
HWND hovered_hwnd = ::WindowFromPoint(pos);
|
||||
if (hovered_hwnd)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd))
|
||||
io.MouseHoveredViewport = viewport->ID;
|
||||
|
||||
// Convert mouse from screen position to window client position
|
||||
HWND focused_hwnd = ::GetActiveWindow();
|
||||
if (focused_hwnd != 0 && ::ScreenToClient(focused_hwnd, &pos))
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)focused_hwnd))
|
||||
{
|
||||
io.MousePos = ImVec2(viewport->Pos.x + (float)pos.x, viewport->Pos.y + (float)pos.y);
|
||||
io.MousePosViewport = viewport->ID;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@ -133,6 +187,8 @@ void ImGui_ImplWin32_NewFrame()
|
||||
ImGui_ImplWin32_UpdateMouseCursor();
|
||||
}
|
||||
|
||||
ImGui_ImplWin32_UpdateMousePos();
|
||||
|
||||
// Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application.
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
@ -213,3 +269,199 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
// Platform Windows
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiPlatformDataWin32
|
||||
{
|
||||
HWND Hwnd;
|
||||
bool ExternalResize;
|
||||
DWORD DwStyle;
|
||||
DWORD DwExStyle;
|
||||
|
||||
ImGuiPlatformDataWin32() { Hwnd = NULL; ExternalResize = false; DwStyle = DwExStyle = 0; }
|
||||
~ImGuiPlatformDataWin32() { IM_ASSERT(Hwnd == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplWin32_CreateViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiPlatformDataWin32* data = IM_NEW(ImGuiPlatformDataWin32)();
|
||||
viewport->PlatformUserData = data;
|
||||
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoDecoration)
|
||||
{
|
||||
data->DwStyle = WS_POPUP;
|
||||
data->DwExStyle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->DwStyle = WS_OVERLAPPEDWINDOW;
|
||||
data->DwExStyle = WS_EX_TOOLWINDOW;
|
||||
}
|
||||
|
||||
// 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->PlatformHandle = data->Hwnd;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_DestroyViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
if (ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData)
|
||||
{
|
||||
if (::GetCapture() == data->Hwnd)
|
||||
{
|
||||
// Transfer capture so if we started dragging from a window that later disappears, we'll still release the MOUSEUP event.
|
||||
::ReleaseCapture();
|
||||
::SetCapture(g_hWnd);
|
||||
}
|
||||
if (data->Hwnd)
|
||||
::DestroyWindow(data->Hwnd);
|
||||
data->Hwnd = NULL;
|
||||
IM_DELETE(data);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Hwnd != 0);
|
||||
POINT pos = { 0, 0 };
|
||||
::ClientToScreen(data->Hwnd, &pos);
|
||||
return ImVec2((float)pos.x, (float)pos.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Hwnd != 0);
|
||||
RECT rect = { (LONG)pos.x, (LONG)pos.y, (LONG)pos.x, (LONG)pos.y };
|
||||
::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle);
|
||||
::SetWindowPos(data->Hwnd, NULL, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplWin32_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Hwnd != 0);
|
||||
RECT rect;
|
||||
::GetClientRect(data->Hwnd, &rect);
|
||||
return ImVec2(float(rect.right - rect.left), float(rect.bottom - rect.top));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ImGuiPlatformDataWin32* data = (ImGuiPlatformDataWin32*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Hwnd != 0);
|
||||
::SetWindowTextA(data->Hwnd, title);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
|
||||
return true;
|
||||
|
||||
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));
|
||||
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, (int)LOWORD(lParam), (int)HIWORD(lParam));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_InitPlatformInterface()
|
||||
{
|
||||
WNDCLASSEX wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = ::GetModuleHandle(NULL);
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = NULL;
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = _T("ImGui Platform");
|
||||
wcex.hIconSm = NULL;
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.PlatformInterface.CreateViewport = ImGui_ImplWin32_CreateViewport;
|
||||
io.PlatformInterface.DestroyViewport = ImGui_ImplWin32_DestroyViewport;
|
||||
io.PlatformInterface.ShowWindow = ImGui_ImplWin32_ShowWindow;
|
||||
io.PlatformInterface.SetWindowPos = ImGui_ImplWin32_SetWindowPos;
|
||||
io.PlatformInterface.GetWindowPos = ImGui_ImplWin32_GetWindowPos;
|
||||
io.PlatformInterface.SetWindowSize = ImGui_ImplWin32_SetWindowSize;
|
||||
io.PlatformInterface.GetWindowSize = ImGui_ImplWin32_GetWindowSize;
|
||||
io.PlatformInterface.SetWindowTitle = ImGui_ImplWin32_SetWindowTitle;
|
||||
|
||||
// Register main window handle
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGuiPlatformDataWin32* data = IM_NEW(ImGuiPlatformDataWin32)();
|
||||
data->Hwnd = g_hWnd;
|
||||
main_viewport->PlatformUserData = data;
|
||||
main_viewport->PlatformHandle = (void*)data->Hwnd;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(&io.PlatformInterface, 0, sizeof(io.PlatformInterface));
|
||||
|
||||
::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(NULL));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user