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 10 enum CIMGUI_USER_DEFINED_IMPLEMENTATION = true; 11 import bindbc.sdl; 12 13 static if(CIMGUI_USER_DEFINED_IMPLEMENTATION) 14 { 15 import bindbc.cimgui; 16 import core.stdc.string : memset, strncpy, strncmp; 17 version(Windows) 18 { 19 static if(CIMGUI_VIEWPORT_BRANCH) 20 { 21 pragma(lib, "user32"); 22 import core.sys.windows.windows : GetWindowLong, LONG, HWND, SetWindowLong, 23 ShowWindow, SW_SHOWNA, GWL_EXSTYLE, WS_EX_APPWINDOW, WS_EX_TOOLWINDOW; 24 } 25 } 26 27 // // dear imgui: Platform Binding for SDL2 28 // // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 29 // // (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) 30 // // (Requires: SDL 2.0. Prefer SDL 2.0.4+ for full feature support.) 31 32 // // Implemented features: 33 // // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 34 // // [X] Platform: Clipboard support. 35 // // [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. igIsKeyPressed(SDL_SCANCODE_SPACE). 36 // // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 37 // // Missing features: 38 // // [ ] 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. 39 40 // // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 41 // // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 42 // // https://github.com/ocornut/imgui 43 44 // // CHANGELOG 45 // // (minor and older changes stripped away, please see git history for details) 46 // // 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends. 47 // // 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). 48 // // 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). 49 // // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. 50 // // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. 51 // // 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). 52 // // 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. 53 // // 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls. 54 // // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 55 // // 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. 56 // // 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. 57 // // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 58 // // 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples. 59 // // 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter. 60 // // 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText). 61 // // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag. 62 // // 2018-02-16: Inputs: Added support for mouse cursors, honoring igGetMouseCursor() value. 63 // // 2018-02-06: Misc: Removed call to igShutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 64 // // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 65 // // 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). 66 // // 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. 67 // // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 68 // // 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. 69 // // 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. 70 // // 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). 71 // // 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. 72 73 enum SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE = sdlSupport >= SDLSupport.sdl204; 74 enum SDL_HAS_WINDOW_ALPHA = sdlSupport >= SDLSupport.sdl205; 75 enum SDL_HAS_ALWAYS_ON_TOP = sdlSupport >= SDLSupport.sdl205; 76 enum SDL_HAS_USABLE_DISPLAY_BOUNDS = sdlSupport >= SDLSupport.sdl205; 77 enum SDL_HAS_PER_MONITOR_DPI = sdlSupport >= SDLSupport.sdl204; 78 enum SDL_HAS_VULKAN = sdlSupport >= SDLSupport.sdl206; 79 enum SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH = sdlSupport >= SDLSupport.sdl205; 80 81 static if(!SDL_HAS_VULKAN) 82 { 83 static const Uint32 SDL_WINDOW_VULKAN = 0x10000000; 84 } 85 86 87 88 // // Data 89 static SDL_Window* g_Window = null; 90 static Uint64 g_Time = 0; 91 static bool[3] g_MousePressed = [false, false, false]; 92 static SDL_Cursor*[ImGuiMouseCursor_COUNT] g_MouseCursors; 93 static char* g_ClipboardTextData = null; 94 static bool g_MouseCanUseGlobalState = true; 95 96 //Must be an enum right now because I don't wish to bother at vulkan, PR's are welcome to adapting it 97 enum g_UseVulkan = false; 98 99 100 enum MAP_BUTTON_SDL(ImGuiIO* io,SDL_GameController* game_controller, ulong NAV_NO, SDL_GameControllerButton BUTTON_NO) 101 { 102 io.NavInputs[NAV_NO] = (SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0) ? 1.0f : 0.0f; 103 } 104 enum MAP_ANALOG_SDL(ImGuiIO* io, SDL_GameController* game_controller, ulong NAV_NO, SDL_GameControllerAxis AXIS_NO, int V0, int V1) 105 { 106 float vn = cast(float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / cast(float)(V1 - V0); 107 if (vn > 1.0f) 108 vn = 1.0f; 109 if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) 110 io.NavInputs[NAV_NO] = vn; 111 } 112 113 114 /// SDL_gamecontroller.h suggests using this value. 115 enum thumb_dead_zone = 8000; 116 117 118 extern(C) static const (char)* ImGui_ImplSDL2_GetClipboardText(void*) 119 { 120 if (g_ClipboardTextData) 121 SDL_free(g_ClipboardTextData); 122 g_ClipboardTextData = SDL_GetClipboardText(); 123 return g_ClipboardTextData; 124 } 125 126 127 extern(C) static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text) 128 { 129 SDL_SetClipboardText(text); 130 } 131 132 // // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 133 // // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 134 // // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 135 // // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 136 // // 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. 137 bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) 138 { 139 ImGuiIO* io = igGetIO(); 140 141 switch (event.type) 142 { 143 case SDL_MOUSEWHEEL: 144 { 145 if (event.wheel.x > 0) io.MouseWheelH += 1; 146 if (event.wheel.x < 0) io.MouseWheelH -= 1; 147 if (event.wheel.y > 0) io.MouseWheel += 1; 148 if (event.wheel.y < 0) io.MouseWheel -= 1; 149 return true; 150 } 151 case SDL_MOUSEBUTTONDOWN: 152 { 153 if (event.button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; 154 if (event.button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; 155 if (event.button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; 156 return true; 157 } 158 case SDL_TEXTINPUT: 159 { 160 ImGuiIO_AddInputCharactersUTF8(io, cast(const (char)*)event.text.text); 161 return true; 162 } 163 case SDL_KEYDOWN: 164 case SDL_KEYUP: 165 { 166 int key = event.key.keysym.scancode; 167 IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); 168 io.KeysDown[key] = (event.type == SDL_KEYDOWN); 169 io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); 170 io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); 171 io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); 172 version(Windows) 173 { 174 io.KeySuper = false; 175 } 176 else 177 { 178 io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); 179 } 180 return true; 181 } 182 static if(CIMGUI_VIEWPORT_BRANCH) 183 { 184 case SDL_WINDOWEVENT: 185 Uint8 window_event = event.window.event; 186 if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED) 187 if (ImGuiViewport* viewport = igFindViewportByPlatformHandle(cast(void*)SDL_GetWindowFromID(event.window.windowID))) 188 { 189 if (window_event == SDL_WINDOWEVENT_CLOSE) 190 viewport.PlatformRequestClose = true; 191 if (window_event == SDL_WINDOWEVENT_MOVED) 192 viewport.PlatformRequestMove = true; 193 if (window_event == SDL_WINDOWEVENT_RESIZED) 194 viewport.PlatformRequestResize = true; 195 return true; 196 } 197 break; 198 } 199 default:break; 200 } 201 return false; 202 } 203 204 static bool ImGui_ImplSDL2_Init(SDL_Window* window, void* sdl_gl_context) 205 { 206 g_Window = window; 207 208 // Setup back-end capabilities flags 209 ImGuiIO* io = igGetIO(); 210 io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 211 212 //Viewport specific code 213 static if(SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE) 214 { 215 io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; 216 } 217 else //This code was deleted on viewport branch 218 { 219 io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 220 } 221 io.BackendPlatformName = "imgui_impl_sdl"; 222 223 // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. 224 io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; 225 io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; 226 io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; 227 io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; 228 io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; 229 io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; 230 io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; 231 io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; 232 io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; 233 io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; 234 io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE; 235 io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE; 236 io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE; 237 io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN; 238 io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE; 239 io.KeyMap[ImGuiKey_KeyPadEnter] = SDL_SCANCODE_KP_ENTER; 240 io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A; 241 io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C; 242 io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V; 243 io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X; 244 io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y; 245 io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z; 246 247 io.SetClipboardTextFn = &ImGui_ImplSDL2_SetClipboardText; 248 io.GetClipboardTextFn = &ImGui_ImplSDL2_GetClipboardText; 249 io.ClipboardUserData = null; 250 251 // Load mouse cursors 252 g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); 253 g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); 254 g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); 255 g_MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); 256 g_MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); 257 g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); 258 g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); 259 g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); 260 g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); 261 262 // Check and store if we are on Wayland 263 g_MouseCanUseGlobalState = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) != 0; 264 265 static if(CIMGUI_VIEWPORT_BRANCH) 266 { 267 ImGuiViewport* main_viewport = igGetMainViewport(); 268 main_viewport.PlatformHandle = cast(void*)window; 269 } 270 271 version(Windows) 272 { 273 SDL_SysWMinfo wmInfo; 274 SDL_VERSION(&wmInfo.version_); 275 static if(CIMGUI_VIEWPORT_BRANCH) 276 { 277 if(SDL_GetWindowWMInfo(window, &wmInfo)) 278 { 279 main_viewport.PlatformHandleRaw = wmInfo.info.win.window; 280 } 281 } 282 else 283 { 284 SDL_GetWindowWMInfo(window, &wmInfo); 285 //io.ImeWindowHandle = wmInfo.info.win.window; 286 } 287 } 288 289 static if(CIMGUI_VIEWPORT_BRANCH) 290 { 291 ImGui_ImplSDL2_UpdateMonitors(); 292 // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports. 293 // We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of static if(ef to avoid unused-function warnings.) 294 if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)) 295 { 296 ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context); 297 } 298 } 299 else 300 { 301 cast(void)window; 302 } 303 return true; 304 } 305 306 bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context) 307 { 308 cast(void)sdl_gl_context; // Viewport branch will need this. 309 return ImGui_ImplSDL2_Init(window, sdl_gl_context); 310 } 311 312 bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) 313 { 314 static if(!SDL_HAS_VULKAN) 315 { 316 IM_ASSERT(0, "Unsupported"); 317 } 318 return ImGui_ImplSDL2_Init(window, null); 319 } 320 321 bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) 322 { 323 version(Windows){} 324 else 325 { 326 IM_ASSERT(0, "Unsupported"); 327 } 328 return ImGui_ImplSDL2_Init(window, null); 329 } 330 331 bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window) 332 { 333 return ImGui_ImplSDL2_Init(window, null); 334 } 335 336 void ImGui_ImplSDL2_Shutdown() 337 { 338 static if(CIMGUI_VIEWPORT_BRANCH) 339 ImGui_ImplSDL2_ShutdownPlatformInterface(); 340 g_Window = null; 341 // Destroy last known clipboard data 342 if (g_ClipboardTextData) 343 SDL_free(g_ClipboardTextData); 344 g_ClipboardTextData = null; 345 346 // Destroy SDL mouse cursors 347 for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) 348 SDL_FreeCursor(g_MouseCursors[cursor_n]); 349 memset(cast(void*)g_MouseCursors, 0, g_MouseCursors.sizeof); 350 } 351 352 static void ImGui_ImplSDL2_UpdateMousePosAndButtons() 353 { 354 ImGuiIO* io = igGetIO(); 355 // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 356 static if(!CIMGUI_VIEWPORT_BRANCH) 357 { 358 if (io.WantSetMousePos) 359 SDL_WarpMouseInWindow(g_Window, cast(int)io.MousePos.x, cast(int)io.MousePos.y); 360 else 361 io.MousePos = ImVec2(-igGET_FLT_MAX(), -igGET_FLT_MAX()); 362 } 363 else 364 { 365 io.MouseHoveredViewport = 0; 366 if (io.WantSetMousePos) 367 { 368 static if(SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE) 369 { 370 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 371 SDL_WarpMouseGlobal(cast(int)io.MousePos.x, cast(int)io.MousePos.y); 372 else 373 SDL_WarpMouseInWindow(g_Window, cast(int)io.MousePos.x, cast(int)io.MousePos.y); 374 } 375 else 376 SDL_WarpMouseInWindow(g_Window, cast(int)io.MousePos.x, cast(int)io.MousePos.y); 377 } 378 else 379 io.MousePos = ImVec2(-igGET_FLT_MAX(), -igGET_FLT_MAX()); 380 } 381 382 int mx, my; 383 Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); 384 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. 385 io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON!SDL_BUTTON_RIGHT) != 0; 386 io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON!SDL_BUTTON_MIDDLE) != 0; 387 g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; 388 389 static if(SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE) 390 { 391 static if(!CIMGUI_VIEWPORT_BRANCH) //Mantaining compatibility with non docking branch 392 { 393 SDL_Window* focused_window = SDL_GetKeyboardFocus(); 394 if (g_Window == focused_window) 395 { 396 if (g_MouseCanUseGlobalState) 397 { 398 // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) 399 // 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. 400 // Won't use this workaround when on Wayland, as there is no global mouse position. 401 int wx, wy; 402 SDL_GetWindowPosition(focused_window, &wx, &wy); 403 SDL_GetGlobalMouseState(&mx, &my); 404 mx -= wx; 405 my -= wy; 406 } 407 io.MousePos = ImVec2(cast(float)mx, cast(float)my); 408 } 409 } 410 else 411 { 412 if (g_MouseCanUseGlobalState) 413 { 414 // SDL 2.0.4 and later has SDL_GetGlobalMouseState() and SDL_CaptureMouse() 415 int mouse_x_global, mouse_y_global; 416 SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global); 417 418 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 419 { 420 // 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) 421 if (SDL_Window* focused_window = SDL_GetKeyboardFocus()) 422 if (igFindViewportByPlatformHandle(cast(void*)focused_window) != null) 423 io.MousePos = ImVec2(cast(float)mouse_x_global, cast(float)mouse_y_global); 424 } 425 else 426 { 427 // 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) 428 if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) 429 { 430 int window_x, window_y; 431 SDL_GetWindowPosition(g_Window, &window_x, &window_y); 432 io.MousePos = ImVec2(cast(float)(mouse_x_global - window_x), cast(float)(mouse_y_global - window_y)); 433 } 434 } 435 } 436 else 437 { 438 if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) 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 static if(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 //Uses DLL 851 { 852 import bindbc.loader : SharedLib, bindSymbol; 853 extern(C) @nogc nothrow 854 { 855 alias pImGui_ImplSDL2_InitForOpenGL = bool function(SDL_Window* window,void* sdl_gl_context); 856 alias pImGui_ImplSDL2_InitForVulkan = bool function(SDL_Window* window); 857 alias pImGui_ImplSDL2_InitForD3D = bool function(SDL_Window* window); 858 alias pImGui_ImplSDL2_InitForMetal = bool function(SDL_Window* window); 859 alias pImGui_ImplSDL2_Shutdown = void function(); 860 alias pImGui_ImplSDL2_NewFrame = void function(SDL_Window* window); 861 alias pImGui_ImplSDL2_ProcessEvent = bool function(const SDL_Event* event); 862 } 863 864 __gshared 865 { 866 pImGui_ImplSDL2_InitForOpenGL ImGui_ImplSDL2_InitForOpenGL; 867 pImGui_ImplSDL2_InitForVulkan ImGui_ImplSDL2_InitForVulkan; 868 pImGui_ImplSDL2_InitForD3D ImGui_ImplSDL2_InitForD3D; 869 pImGui_ImplSDL2_InitForMetal ImGui_ImplSDL2_InitForMetal; 870 pImGui_ImplSDL2_Shutdown ImGui_ImplSDL2_Shutdown; 871 pImGui_ImplSDL2_NewFrame ImGui_ImplSDL2_NewFrame; 872 pImGui_ImplSDL2_ProcessEvent ImGui_ImplSDL2_ProcessEvent; 873 } 874 void bindSDLImgui(SharedLib lib) 875 { 876 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForOpenGL, "ImGui_ImplSDL2_InitForOpenGL"); 877 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForVulkan, "ImGui_ImplSDL2_InitForVulkan"); 878 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForD3D, "ImGui_ImplSDL2_InitForD3D"); 879 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_InitForMetal, "ImGui_ImplSDL2_InitForMetal"); 880 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_Shutdown, "ImGui_ImplSDL2_Shutdown"); 881 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_NewFrame, "ImGui_ImplSDL2_NewFrame"); 882 lib.bindSymbol(cast(void**)&ImGui_ImplSDL2_ProcessEvent, "ImGui_ImplSDL2_ProcessEvent"); 883 } 884 885 }