1 2 // Copyright Marcelo S. N. Mancini(Hipreme) 2020. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 module imgui_backend.impl_sdl; 8 // // SDL 9 import bindbc.sdl; 10 11 /// Whether to use the implemetation defined in D, or link against compiled ImGUI backend. 12 version(CIMGUI_USER_DEFINED_IMPLEMENTATION_SDL) 13 { 14 import bindbc.cimgui; 15 import core.stdc.string : memset, strncpy, strncmp; 16 version(Windows) 17 { 18 version(CIMGUI_VIEWPORT_BRANCH) 19 { 20 pragma(lib, "user32"); 21 import core.sys.windows.windows : GetWindowLong, LONG, HWND, SetWindowLong, 22 ShowWindow, SW_SHOWNA, GWL_EXSTYLE, WS_EX_APPWINDOW, WS_EX_TOOLWINDOW; 23 } 24 } 25 26 // // dear imgui: Platform Binding for SDL2 27 // // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 28 // // (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) 29 // // (Requires: SDL 2.0. Prefer SDL 2.0.4+ for full feature support.) 30 31 // // Implemented features: 32 // // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 33 // // [X] Platform: Clipboard support. 34 // // [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. igIsKeyPressed(SDL_SCANCODE_SPACE). 35 // // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 36 // // Missing features: 37 // // [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. 38 39 // // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 40 // // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 41 // // https://github.com/ocornut/imgui 42 43 // // CHANGELOG 44 // // (minor and older changes stripped away, please see git history for details) 45 // // 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends. 46 // // 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). 47 // // 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). 48 // // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. 49 // // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. 50 // // 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). 51 // // 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. 52 // // 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls. 53 // // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 54 // // 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. 55 // // 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. 56 // // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 57 // // 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples. 58 // // 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter. 59 // // 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText). 60 // // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag. 61 // // 2018-02-16: Inputs: Added support for mouse cursors, honoring igGetMouseCursor() value. 62 // // 2018-02-06: Misc: Removed call to igShutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 63 // // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 64 // // 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). 65 // // 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. 66 // // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 67 // // 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. 68 // // 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. 69 // // 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). 70 // // 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. 71 72 enum SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE = sdlSupport >= SDLSupport.sdl204; 73 enum SDL_HAS_WINDOW_ALPHA = sdlSupport >= SDLSupport.sdl205; 74 enum SDL_HAS_ALWAYS_ON_TOP = sdlSupport >= SDLSupport.sdl205; 75 enum SDL_HAS_USABLE_DISPLAY_BOUNDS = sdlSupport >= SDLSupport.sdl205; 76 enum SDL_HAS_PER_MONITOR_DPI = sdlSupport >= SDLSupport.sdl204; 77 enum SDL_HAS_VULKAN = sdlSupport >= SDLSupport.sdl206; 78 enum SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH = sdlSupport >= SDLSupport.sdl205; 79 80 static if(!SDL_HAS_VULKAN) 81 { 82 static const Uint32 SDL_WINDOW_VULKAN = 0x10000000; 83 } 84 85 86 87 // // Data 88 static SDL_Window* g_Window = null; 89 static Uint64 g_Time = 0; 90 static bool[3] g_MousePressed = [false, false, false]; 91 static SDL_Cursor*[ImGuiMouseCursor_COUNT] g_MouseCursors; 92 static char* g_ClipboardTextData = null; 93 static bool g_MouseCanUseGlobalState = true; 94 95 //Must be an enum right now because I don't wish to bother at vulkan, PR's are welcome to adapting it 96 enum g_UseVulkan = false; 97 98 99 enum MAP_BUTTON_SDL(ImGuiIO* io,SDL_GameController* game_controller, ulong NAV_NO, SDL_GameControllerButton BUTTON_NO) 100 { 101 io.NavInputs[NAV_NO] = (SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0) ? 1.0f : 0.0f; 102 } 103 enum MAP_ANALOG_SDL(ImGuiIO* io, SDL_GameController* game_controller, ulong NAV_NO, SDL_GameControllerAxis AXIS_NO, int V0, int V1) 104 { 105 float vn = cast(float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / cast(float)(V1 - V0); 106 if (vn > 1.0f) 107 vn = 1.0f; 108 if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) 109 io.NavInputs[NAV_NO] = vn; 110 } 111 112 113 /// SDL_gamecontroller.h suggests using this value. 114 enum thumb_dead_zone = 8000; 115 116 117 extern(C++) static const (char)* ImGui_ImplSDL2_GetClipboardText(void*) 118 { 119 if (g_ClipboardTextData) 120 SDL_free(g_ClipboardTextData); 121 g_ClipboardTextData = SDL_GetClipboardText(); 122 return g_ClipboardTextData; 123 } 124 125 126 extern(C++) static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text) 127 { 128 SDL_SetClipboardText(text); 129 } 130 131 // // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 132 // // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 133 // // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 134 // // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 135 // // If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. 136 bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) 137 { 138 ImGuiIO* io = igGetIO(); 139 140 switch (event.type) 141 { 142 case SDL_MOUSEWHEEL: 143 { 144 if (event.wheel.x > 0) io.MouseWheelH += 1; 145 if (event.wheel.x < 0) io.MouseWheelH -= 1; 146 if (event.wheel.y > 0) io.MouseWheel += 1; 147 if (event.wheel.y < 0) io.MouseWheel -= 1; 148 return true; 149 } 150 case SDL_MOUSEBUTTONDOWN: 151 { 152 if (event.button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; 153 if (event.button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; 154 if (event.button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; 155 return true; 156 } 157 case SDL_TEXTINPUT: 158 { 159 ImGuiIO_AddInputCharactersUTF8(io, cast(const (char)*)event.text.text); 160 return true; 161 } 162 case SDL_KEYDOWN: 163 case SDL_KEYUP: 164 { 165 int key = event.key.keysym.scancode; 166 IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); 167 io.KeysDown[key] = (event.type == SDL_KEYDOWN); 168 io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); 169 io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); 170 io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); 171 version(Windows) 172 { 173 io.KeySuper = false; 174 } 175 else 176 { 177 io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); 178 } 179 return true; 180 } 181 version(CIMGUI_VIEWPORT_BRANCH) 182 { 183 case SDL_WINDOWEVENT: 184 Uint8 window_event = event.window.event; 185 if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED) 186 if (ImGuiViewport* viewport = igFindViewportByPlatformHandle(cast(void*)SDL_GetWindowFromID(event.window.windowID))) 187 { 188 if (window_event == SDL_WINDOWEVENT_CLOSE) 189 viewport.PlatformRequestClose = true; 190 if (window_event == SDL_WINDOWEVENT_MOVED) 191 viewport.PlatformRequestMove = true; 192 if (window_event == SDL_WINDOWEVENT_RESIZED) 193 viewport.PlatformRequestResize = true; 194 return true; 195 } 196 break; 197 } 198 default:break; 199 } 200 return false; 201 } 202 203 static bool ImGui_ImplSDL2_Init(SDL_Window* window, void* sdl_gl_context) 204 { 205 g_Window = window; 206 207 // Setup back-end capabilities flags 208 ImGuiIO* io = igGetIO(); 209 io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 210 211 //Viewport specific code 212 static if(SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE) 213 { 214 io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; 215 } 216 else //This code was deleted on viewport branch 217 { 218 io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 219 } 220 io.BackendPlatformName = "imgui_impl_sdl"; 221 222 // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. 223 io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; 224 io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; 225 io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; 226 io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; 227 io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; 228 io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; 229 io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; 230 io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; 231 io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; 232 io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; 233 io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE; 234 io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE; 235 io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE; 236 io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN; 237 io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE; 238 io.KeyMap[ImGuiKey_KeyPadEnter] = SDL_SCANCODE_KP_ENTER; 239 io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A; 240 io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C; 241 io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V; 242 io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X; 243 io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y; 244 io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z; 245 246 io.SetClipboardTextFn = &ImGui_ImplSDL2_SetClipboardText; 247 io.GetClipboardTextFn = &ImGui_ImplSDL2_GetClipboardText; 248 io.ClipboardUserData = null; 249 250 // Load mouse cursors 251 g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); 252 g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); 253 g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); 254 g_MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); 255 g_MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); 256 g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); 257 g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); 258 g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); 259 g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); 260 261 // Check and store if we are on Wayland 262 g_MouseCanUseGlobalState = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) != 0; 263 264 version(CIMGUI_VIEWPORT_BRANCH) 265 { 266 ImGuiViewport* main_viewport = igGetMainViewport(); 267 main_viewport.PlatformHandle = cast(void*)window; 268 } 269 270 version(Windows) 271 { 272 SDL_SysWMinfo wmInfo; 273 SDL_VERSION(&wmInfo.version_); 274 version(CIMGUI_VIEWPORT_BRANCH) 275 { 276 if(SDL_GetWindowWMInfo(window, &wmInfo)) 277 { 278 main_viewport.PlatformHandleRaw = wmInfo.info.win.window; 279 } 280 } 281 else 282 { 283 SDL_GetWindowWMInfo(window, &wmInfo); 284 //io.ImeWindowHandle = wmInfo.info.win.window; 285 } 286 } 287 288 version(CIMGUI_VIEWPORT_BRANCH) 289 { 290 ImGui_ImplSDL2_UpdateMonitors(); 291 // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports. 292 // We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of static if(ef to avoid unused-function warnings.) 293 if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)) 294 { 295 ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context); 296 } 297 } 298 else 299 { 300 cast(void)window; 301 } 302 return true; 303 } 304 305 bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context) 306 { 307 cast(void)sdl_gl_context; // Viewport branch will need this. 308 return ImGui_ImplSDL2_Init(window, sdl_gl_context); 309 } 310 311 bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) 312 { 313 static if(!SDL_HAS_VULKAN) 314 { 315 IM_ASSERT(0, "Unsupported"); 316 } 317 return ImGui_ImplSDL2_Init(window, null); 318 } 319 320 bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) 321 { 322 version(Windows){} 323 else 324 { 325 IM_ASSERT(0, "Unsupported"); 326 } 327 return ImGui_ImplSDL2_Init(window, null); 328 } 329 330 bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window) 331 { 332 return ImGui_ImplSDL2_Init(window, null); 333 } 334 335 void ImGui_ImplSDL2_Shutdown() 336 { 337 version(CIMGUI_VIEWPORT_BRANCH) 338 ImGui_ImplSDL2_ShutdownPlatformInterface(); 339 g_Window = null; 340 // Destroy last known clipboard data 341 if (g_ClipboardTextData) 342 SDL_free(g_ClipboardTextData); 343 g_ClipboardTextData = null; 344 345 // Destroy SDL mouse cursors 346 for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) 347 SDL_FreeCursor(g_MouseCursors[cursor_n]); 348 memset(cast(void*)g_MouseCursors, 0, g_MouseCursors.sizeof); 349 } 350 351 static void ImGui_ImplSDL2_UpdateMousePosAndButtons() 352 { 353 ImGuiIO* io = igGetIO(); 354 // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 355 version(CIMGUI_VIEWPORT_BRANCH) 356 { 357 io.MouseHoveredViewport = 0; 358 if (io.WantSetMousePos) 359 { 360 static if(SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE) 361 { 362 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 363 SDL_WarpMouseGlobal(cast(int)io.MousePos.x, cast(int)io.MousePos.y); 364 else 365 SDL_WarpMouseInWindow(g_Window, cast(int)io.MousePos.x, cast(int)io.MousePos.y); 366 } 367 else 368 SDL_WarpMouseInWindow(g_Window, cast(int)io.MousePos.x, cast(int)io.MousePos.y); 369 } 370 else 371 io.MousePos = ImVec2(-igGET_FLT_MAX(), -igGET_FLT_MAX()); 372 } 373 else 374 { 375 if (io.WantSetMousePos) 376 SDL_WarpMouseInWindow(g_Window, cast(int)io.MousePos.x, cast(int)io.MousePos.y); 377 else 378 io.MousePos = ImVec2(-igGET_FLT_MAX(), -igGET_FLT_MAX()); 379 } 380 381 int mx, my; 382 Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); 383 io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON!SDL_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. 384 io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON!SDL_BUTTON_RIGHT) != 0; 385 io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON!SDL_BUTTON_MIDDLE) != 0; 386 g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; 387 388 static if(SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE) 389 { 390 version(CIMGUI_VIEWPORT_BRANCH) //Mantaining compatibility with non docking branch 391 { 392 if (g_MouseCanUseGlobalState) 393 { 394 // SDL 2.0.4 and later has SDL_GetGlobalMouseState() and SDL_CaptureMouse() 395 int mouse_x_global, mouse_y_global; 396 SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global); 397 398 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 399 { 400 // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) 401 if (SDL_Window* focused_window = SDL_GetKeyboardFocus()) 402 if (igFindViewportByPlatformHandle(cast(void*)focused_window) != null) 403 io.MousePos = ImVec2(cast(float)mouse_x_global, cast(float)mouse_y_global); 404 } 405 else 406 { 407 // Single-viewport mode: mouse position in client window coordinatesio.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) 408 if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) 409 { 410 int window_x, window_y; 411 SDL_GetWindowPosition(g_Window, &window_x, &window_y); 412 io.MousePos = ImVec2(cast(float)(mouse_x_global - window_x), cast(float)(mouse_y_global - window_y)); 413 } 414 } 415 } 416 else 417 { 418 if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) 419 io.MousePos = ImVec2(cast(float)mx, cast(float)my); 420 } 421 422 } 423 else 424 { 425 SDL_Window* focused_window = SDL_GetKeyboardFocus(); 426 if (g_Window == focused_window) 427 { 428 if (g_MouseCanUseGlobalState) 429 { 430 // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) 431 // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. 432 // Won't use this workaround when on Wayland, as there is no global mouse position. 433 int wx, wy; 434 SDL_GetWindowPosition(focused_window, &wx, &wy); 435 SDL_GetGlobalMouseState(&mx, &my); 436 mx -= wx; 437 my -= wy; 438 } 439 io.MousePos = ImVec2(cast(float)mx, cast(float)my); 440 } 441 } 442 // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor. 443 // The function is only supported from SDL 2.0.4 (released Jan 2016) 444 bool any_mouse_button_down = igIsAnyMouseDown(); 445 SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE); 446 } 447 else 448 { 449 if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) 450 io.MousePos = ImVec2(cast(float)mx, cast(float)my); 451 } 452 } 453 454 static void ImGui_ImplSDL2_UpdateMouseCursor() 455 { 456 ImGuiIO* io = igGetIO(); 457 if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 458 return; 459 460 ImGuiMouseCursor imgui_cursor = igGetMouseCursor(); 461 if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) 462 { 463 // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 464 SDL_ShowCursor(SDL_FALSE); 465 } 466 else 467 { 468 // Show OS mouse cursor 469 SDL_SetCursor(g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); 470 SDL_ShowCursor(SDL_TRUE); 471 } 472 } 473 474 static void ImGui_ImplSDL2_UpdateGamepads() 475 { 476 ImGuiIO* io = igGetIO(); 477 memset(cast(void*)io.NavInputs, 0, io.NavInputs.sizeof); 478 if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) 479 return; 480 481 // Get gamepad 482 SDL_GameController* game_controller = SDL_GameControllerOpen(0); 483 if (!game_controller) 484 { 485 io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; 486 return; 487 } 488 489 // Update gamepad inputs 490 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_Activate, SDL_CONTROLLER_BUTTON_A); // Cross / A 491 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_Cancel, SDL_CONTROLLER_BUTTON_B); // Circle / B 492 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_Menu, SDL_CONTROLLER_BUTTON_X); // Square / X 493 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_Input, SDL_CONTROLLER_BUTTON_Y); // Triangle / Y 494 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_DpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); // D-Pad Left 495 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_DpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); // D-Pad Right 496 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_DpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); // D-Pad Up 497 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_DpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); // D-Pad Down 498 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_FocusPrev, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB 499 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_FocusNext, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB 500 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_TweakSlow, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB 501 MAP_BUTTON_SDL(io,game_controller,ImGuiNavInput_TweakFast, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB 502 MAP_ANALOG_SDL(io,game_controller,ImGuiNavInput_LStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32_768); 503 MAP_ANALOG_SDL(io,game_controller,ImGuiNavInput_LStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32_767); 504 MAP_ANALOG_SDL(io,game_controller,ImGuiNavInput_LStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32_767); 505 MAP_ANALOG_SDL(io,game_controller,ImGuiNavInput_LStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32_767); 506 507 io.BackendFlags |= ImGuiBackendFlags_HasGamepad; 508 } 509 510 void ImGui_ImplSDL2_NewFrame(SDL_Window* window) 511 { 512 ImGuiIO* io = igGetIO(); 513 IM_ASSERT(ImFontAtlas_IsBuilt(io.Fonts), "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); 514 515 // Setup display size (every frame to accommodate for window resizing) 516 int w, h; 517 int display_w, display_h; 518 SDL_GetWindowSize(window, &w, &h); 519 if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) 520 w = h = 0; 521 SDL_GL_GetDrawableSize(window, &display_w, &display_h); 522 io.DisplaySize = ImVec2(cast(float)w, cast(float)h); 523 if (w > 0 && h > 0) 524 io.DisplayFramebufferScale = ImVec2(cast(float)display_w / w, cast(float)display_h / h); 525 526 // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) 527 static if(staticBinding) //Won't be supporting it any early 528 { 529 static Uint64 frequency = SDL_GetPerformanceFrequency(); 530 } 531 else 532 { 533 Uint64 frequency = SDL_GetPerformanceFrequency(); 534 } 535 Uint64 current_time = SDL_GetPerformanceCounter(); 536 io.DeltaTime = g_Time > 0 ? cast(float)(cast(double)(current_time - g_Time) / frequency) : cast(float)(1.0f / 60.0f); 537 g_Time = current_time; 538 539 ImGui_ImplSDL2_UpdateMousePosAndButtons(); 540 ImGui_ImplSDL2_UpdateMouseCursor(); 541 542 // Update game controllers (if enabled and available) 543 ImGui_ImplSDL2_UpdateGamepads(); 544 } 545 546 //Starting viewport branch support 547 version(CIMGUI_VIEWPORT_BRANCH) 548 { 549 static void ImGui_ImplSDL2_UpdateMonitors() 550 { 551 ImGuiPlatformIO* platform_io = igGetPlatformIO(); 552 ImVector_resize!ImVector_ImGuiPlatformMonitor(platform_io.Monitors, 0); //ImVector function, should be probably implemented 553 int display_count = SDL_GetNumVideoDisplays(); 554 for (int n = 0; n < display_count; n++) 555 { 556 // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime. 557 ImGuiPlatformMonitor monitor; 558 SDL_Rect r; 559 SDL_GetDisplayBounds(n, &r); 560 monitor.MainPos = monitor.WorkPos = ImVec2(cast(float)r.x, cast(float)r.y); 561 monitor.MainSize = monitor.WorkSize = ImVec2(cast(float)r.w, cast(float)r.h); 562 static if(SDL_HAS_USABLE_DISPLAY_BOUNDS) 563 { 564 SDL_GetDisplayUsableBounds(n, &r); 565 monitor.WorkPos = ImVec2(cast(float)r.x, cast(float)r.y); 566 monitor.WorkSize = ImVec2(cast(float)r.w, cast(float)r.h); 567 } 568 static if(SDL_HAS_PER_MONITOR_DPI) 569 { 570 float dpi = 0.0f; 571 if (!SDL_GetDisplayDPI(n, &dpi, null, null)) 572 monitor.DpiScale = dpi / 96.0f; 573 } 574 ImVector_push_back!ImVector_ImGuiPlatformMonitor(platform_io.Monitors, monitor); 575 } 576 } 577 578 extern(C) struct ImGuiViewportDataSDL2 579 { 580 SDL_Window* Window; 581 Uint32 WindowID; 582 bool WindowOwned; 583 SDL_GLContext GLContext; 584 585 // ~this() 586 // { 587 // IM_ASSERT(Window == null && GLContext == null, "Null Reference"); 588 // } 589 } 590 591 extern(C++) static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport) 592 { 593 //ImGuiViewportDataSDL2* data = IM_NEW!ImGuiViewportDataSDL2; 594 595 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)igMemAlloc(ImGuiViewportDataSDL2.sizeof); 596 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 597 598 599 ImGuiViewport* main_viewport = igGetMainViewport(); 600 ImGuiViewportDataSDL2* main_viewport_data = cast(ImGuiViewportDataSDL2*)main_viewport.PlatformUserData; 601 602 // Share GL resources with main context 603 bool use_opengl = (main_viewport_data.GLContext != null); 604 SDL_GLContext backup_context = null; 605 if (use_opengl) 606 { 607 backup_context = SDL_GL_GetCurrentContext(); 608 SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); 609 SDL_GL_MakeCurrent(main_viewport_data.Window, main_viewport_data.GLContext); 610 } 611 612 Uint32 sdl_flags = 0; 613 sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (g_UseVulkan ? SDL_WINDOW_VULKAN : 0); 614 sdl_flags |= SDL_GetWindowFlags(g_Window) & SDL_WINDOW_ALLOW_HIGHDPI; 615 sdl_flags |= SDL_WINDOW_HIDDEN; 616 sdl_flags |= (viewport.Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0; 617 sdl_flags |= (viewport.Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE; 618 version(Windows) 619 { 620 // See SDL hack in ImGui_ImplSDL2_ShowWindow(). 621 sdl_flags |= (viewport.Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0; 622 } 623 static if(SDL_HAS_ALWAYS_ON_TOP) 624 { 625 sdl_flags |= (viewport.Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; 626 } 627 //Should declare SDL_WindowFlags as an uint 628 data.Window = SDL_CreateWindow("No Title Yet".ptr, cast(int)viewport.Pos.x, cast(int)viewport.Pos.y, cast(int)viewport.Size.x, cast(int)viewport.Size.y, cast(SDL_WindowFlags)sdl_flags); 629 data.WindowOwned = true; 630 if (use_opengl) 631 { 632 data.GLContext = SDL_GL_CreateContext(data.Window); 633 SDL_GL_SetSwapInterval(0); 634 } 635 if (use_opengl && backup_context) 636 SDL_GL_MakeCurrent(data.Window, backup_context); 637 638 viewport.PlatformHandle = cast(void*)data.Window; 639 version(Windows) 640 { 641 SDL_SysWMinfo info; 642 SDL_VERSION(&info.version_); 643 if (SDL_GetWindowWMInfo(data.Window, &info)) 644 viewport.PlatformHandleRaw = info.info.win.window; 645 } 646 viewport.PlatformUserData = data; 647 } 648 649 extern(C++) static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport) 650 { 651 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 652 if (ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData) 653 { 654 if (data.GLContext && data.WindowOwned) 655 SDL_GL_DeleteContext(data.GLContext); 656 if (data.Window && data.WindowOwned) 657 SDL_DestroyWindow(data.Window); 658 data.GLContext = null; 659 data.Window = null; 660 IM_DELETE(data); 661 } 662 viewport.PlatformUserData = viewport.PlatformHandle = null; 663 } 664 665 extern(C++) static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport) 666 { 667 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 668 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 669 version(Windows) 670 { 671 HWND hwnd = cast(HWND)viewport.PlatformHandleRaw; 672 673 // SDL hack: Hide icon from task bar 674 // Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition. 675 if (viewport.Flags & ImGuiViewportFlags_NoTaskBarIcon) 676 { 677 LONG ex_style = GetWindowLong(hwnd, GWL_EXSTYLE); 678 ex_style &= ~WS_EX_APPWINDOW; 679 ex_style |= WS_EX_TOOLWINDOW; 680 SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); 681 } 682 683 // SDL hack: SDL always activate/focus windows :/ 684 if (viewport.Flags & ImGuiViewportFlags_NoFocusOnAppearing) 685 { 686 ShowWindow(hwnd, SW_SHOWNA); 687 return; 688 } 689 } 690 691 SDL_ShowWindow(data.Window); 692 } 693 694 extern(C) static void ImGui_ImplSDL2_GetWindowPos(ImGuiViewport* viewport, ImVec2* _out_vec) 695 { 696 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 697 int x = 0, y = 0; 698 SDL_GetWindowPosition(data.Window, &x, &y); 699 _out_vec.x = cast(float)x; 700 _out_vec.y = cast(float)y; 701 } 702 703 extern(C++) static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) 704 { 705 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 706 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 707 SDL_SetWindowPosition(data.Window, cast(int)pos.x, cast(int)pos.y); 708 } 709 710 extern(C) static void ImGui_ImplSDL2_GetWindowSize(ImGuiViewport* viewport, ImVec2* _out_vec) 711 { 712 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 713 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 714 int w = 0, h = 0; 715 SDL_GetWindowSize(data.Window, &w, &h); 716 _out_vec.x = cast(float)w; 717 _out_vec.y = cast(float)h; 718 } 719 720 extern(C++) static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) 721 { 722 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 723 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 724 SDL_SetWindowSize(data.Window, cast(int)size.x, cast(int)size.y); 725 } 726 727 extern(C++) static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const (char)* title) 728 { 729 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 730 SDL_SetWindowTitle(data.Window, title); 731 } 732 733 static if(SDL_HAS_WINDOW_ALPHA) 734 { 735 extern(C++) static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha) 736 { 737 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 738 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 739 SDL_SetWindowOpacity(data.Window, alpha); 740 } 741 } 742 743 extern(C++) static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport) 744 { 745 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 746 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 747 SDL_RaiseWindow(data.Window); 748 } 749 750 extern(C++) static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport) 751 { 752 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 753 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 754 return (SDL_GetWindowFlags(data.Window) & SDL_WINDOW_INPUT_FOCUS) != 0; 755 } 756 757 extern(C++) static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport) 758 { 759 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 760 return (SDL_GetWindowFlags(data.Window) & SDL_WINDOW_MINIMIZED) != 0; 761 } 762 763 extern(C++) static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*) 764 { 765 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 766 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 767 if (data.GLContext) 768 SDL_GL_MakeCurrent(data.Window, data.GLContext); 769 } 770 771 extern(C++) static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*) 772 { 773 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 774 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 775 if (data.GLContext) 776 { 777 SDL_GL_MakeCurrent(data.Window, data.GLContext); 778 SDL_GL_SwapWindow(data.Window); 779 } 780 } 781 782 static if(SDL_HAS_VULKAN && g_UseVulkan) 783 { 784 import bindbc.vulkan; //Don't know if it is already there 785 extern(C) static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface) 786 { 787 //ImGuiViewport* viewport = &viewportp._ImGuiViewport; 788 ImGuiViewportDataSDL2* data = cast(ImGuiViewportDataSDL2*)viewport.PlatformUserData; 789 cast(void)vk_allocator; 790 SDL_bool ret = SDL_Vulkan_CreateSurface(data.Window, cast(VkInstance)vk_instance, cast(VkSurfaceKHR*)out_vk_surface); 791 return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY 792 } 793 } 794 extern(C++) static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context) 795 { 796 // Register platform interface (will be coupled with a renderer interface) 797 798 ImGuiPlatformIO* platform_io = igGetPlatformIO(); 799 800 platform_io.Platform_CreateWindow = &ImGui_ImplSDL2_CreateWindow; 801 platform_io.Platform_DestroyWindow = &ImGui_ImplSDL2_DestroyWindow; 802 platform_io.Platform_ShowWindow = &ImGui_ImplSDL2_ShowWindow; 803 platform_io.Platform_SetWindowPos = &ImGui_ImplSDL2_SetWindowPos; 804 805 ImGuiPlatformIO_Set_Platform_GetWindowPos(platform_io, &ImGui_ImplSDL2_GetWindowPos); 806 // platform_io.Platform_GetWindowPos = &ImGui_ImplSDL2_GetWindowPos; 807 platform_io.Platform_SetWindowSize = &ImGui_ImplSDL2_SetWindowSize; 808 // platform_io.Platform_GetWindowSize = &ImGui_ImplSDL2_GetWindowSize; 809 ImGuiPlatformIO_Set_Platform_GetWindowSize(platform_io, &ImGui_ImplSDL2_GetWindowSize); 810 platform_io.Platform_SetWindowFocus = &ImGui_ImplSDL2_SetWindowFocus; 811 platform_io.Platform_GetWindowFocus = &ImGui_ImplSDL2_GetWindowFocus; 812 platform_io.Platform_GetWindowMinimized = &ImGui_ImplSDL2_GetWindowMinimized; 813 platform_io.Platform_SetWindowTitle = &ImGui_ImplSDL2_SetWindowTitle; 814 platform_io.Platform_RenderWindow = &ImGui_ImplSDL2_RenderWindow; 815 platform_io.Platform_SwapBuffers = &ImGui_ImplSDL2_SwapBuffers; 816 static if(SDL_HAS_WINDOW_ALPHA) 817 { 818 platform_io.Platform_SetWindowAlpha = &ImGui_ImplSDL2_SetWindowAlpha; 819 } 820 static if(SDL_HAS_VULKAN && g_UseVulkan) 821 { 822 platform_io.Platform_CreateVkSurface = &ImGui_ImplSDL2_CreateVkSurface; 823 } 824 825 // SDL2 by default doesn't pass mouse clicks to the application when the click focused a window. This is getting in the way of our interactions and we disable that behavior. 826 static if(SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH) 827 { 828 SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); 829 } 830 831 // Register main window handle (which is owned by the main application, not by us) 832 // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports. 833 ImGuiViewport* main_viewport = igGetMainViewport(); 834 ImGuiViewportDataSDL2* data = IM_NEW!ImGuiViewportDataSDL2; 835 data.Window = window; 836 data.WindowID = SDL_GetWindowID(window); 837 data.WindowOwned = false; 838 data.GLContext = sdl_gl_context; 839 main_viewport.PlatformUserData = data; 840 main_viewport.PlatformHandle = data.Window; 841 842 } 843 844 static void ImGui_ImplSDL2_ShutdownPlatformInterface() 845 { 846 } 847 848 } 849 } 850 else // CIMGUI_USER_DEFINED_IMPLEMENTATION_SDL 851 // binds functions dynamically 852 { 853 import bindbc.loader : SharedLib, bindSymbol; 854 extern(C) @nogc nothrow 855 { 856 alias pImGui_ImplSDL2_InitForOpenGL = bool function(SDL_Window* window,void* sdl_gl_context); 857 alias pImGui_ImplSDL2_InitForVulkan = bool function(SDL_Window* window); 858 alias pImGui_ImplSDL2_InitForD3D = bool function(SDL_Window* window); 859 alias pImGui_ImplSDL2_InitForMetal = bool function(SDL_Window* window); 860 alias pImGui_ImplSDL2_Shutdown = void function(); 861 alias pImGui_ImplSDL2_NewFrame = void function(SDL_Window* window); 862 alias pImGui_ImplSDL2_ProcessEvent = bool function(const SDL_Event* event); 863 } 864 865 __gshared 866 { 867 pImGui_ImplSDL2_InitForOpenGL ImGui_ImplSDL2_InitForOpenGL; 868 pImGui_ImplSDL2_InitForVulkan ImGui_ImplSDL2_InitForVulkan; 869 pImGui_ImplSDL2_InitForD3D ImGui_ImplSDL2_InitForD3D; 870 pImGui_ImplSDL2_InitForMetal ImGui_ImplSDL2_InitForMetal; 871 pImGui_ImplSDL2_Shutdown ImGui_ImplSDL2_Shutdown; 872 pImGui_ImplSDL2_NewFrame ImGui_ImplSDL2_NewFrame; 873 pImGui_ImplSDL2_ProcessEvent ImGui_ImplSDL2_ProcessEvent; 874 } 875 void bindSDLImgui(SharedLib lib) 876 { 877 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForOpenGL, "ImGui_ImplSDL2_InitForOpenGL"); 878 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForVulkan, "ImGui_ImplSDL2_InitForVulkan"); 879 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForD3D, "ImGui_ImplSDL2_InitForD3D"); 880 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForMetal, "ImGui_ImplSDL2_InitForMetal"); 881 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_Shutdown, "ImGui_ImplSDL2_Shutdown"); 882 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_NewFrame, "ImGui_ImplSDL2_NewFrame"); 883 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_ProcessEvent, "ImGui_ImplSDL2_ProcessEvent"); 884 } 885 886 }