1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153 |
- {
- FreePascal bindings for ImGui
- Copyright (C) 2023 Coldzer0 <Coldzer0 [at] protonmail.ch>
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
- the Free Software Foundation, version 3 of the License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU LESSER GENERAL PUBLIC LICENSE for more details.
- }
- Unit PasImGui.SDL2;
- {$IFDEF FPC}
- {$mode objfpc}{$H+}{$J-}
- {$PackRecords C}
- {$ENDIF}
- {$Define SDL_HINT_IME_SHOW_UI}
- {$Define SDL_HINT_MOUSE_AUTO_CAPTURE}
- {$Define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH}
- {$Define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE}
- Interface
- Uses
- {$IfDef MSWINDOWS}
- Windows,
- {$EndIf}
- SDL2,
- PasImGui,
- PasImGui.Enums,
- PasImGui.Types;
- Function ImGui_ImplSDL2_InitForOpenGL_Pas(window: PSDL_Window;
- sdl_gl_context: Pointer): Boolean;
- Function ImGui_ImplSDL2_ProcessEvent_Pas(event: PSDL_Event): Boolean;
- Procedure ImGui_ImplSDL2_NewFrame_Pas();
- Procedure ImGui_ImplSDL2_Shutdown_Pas();
- Type
- PImGui_ImplSDL2_Data = ^ImGui_ImplSDL2_Data;
- ImGui_ImplSDL2_Data = Record
- Window: PSDL_Window;
- Renderer: PSDL_Renderer;
- Time: Uint64;
- MouseWindowID: Uint32;
- MouseButtonsDown: Integer;
- MouseCursors: Array [0..Ord(ImGuiMouseCursor_COUNT) - 1] Of PSDL_Cursor;
- LastMouseCursor: PSDL_Cursor;
- PendingMouseLeaveFrame: Integer;
- ClipboardTextData: Pansichar;
- MouseCanUseGlobalState: Boolean;
- MouseCanReportHoveredViewport: Boolean;
- UseVulkan: Boolean;
- WantUpdateMonitors: Boolean;
- End;
- PImGui_ImplSDL2_ViewportData = ^ImGui_ImplSDL2_ViewportData;
- ImGui_ImplSDL2_ViewportData = Record
- Window: PSDL_Window;
- WindowID: Uint32;
- WindowOwned: Boolean;
- GLContext: TSDL_GLContext;
- End;
- Implementation
- Uses
- SysUtils;
- // Done
- Function ImGui_ImplSDL2_GetBackendData(): PImGui_ImplSDL2_Data;
- Begin
- If ImGui.GetCurrentContext() <> nil Then
- Result := PImGui_ImplSDL2_Data(ImGui.GetIO()^.BackendPlatformUserData)
- Else
- Result := nil;
- End;
- //--------------------------------------------------------------------------------------------------------
- // MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
- // This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
- // If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
- //--------------------------------------------------------------------------------------------------------
- // Done
- Procedure ImGui_ImplSDL2_CreateWindow(viewport: PImGuiViewport); Cdecl;
- Var
- bd: PImGui_ImplSDL2_Data;
- main_viewport: PImGuiViewport;
- main_viewport_data, vd: PImGui_ImplSDL2_ViewportData;
- use_opengl: Boolean;
- backup_context: TSDL_GLContext;
- sdl_flags: Uint32;
- info: TSDL_SysWMinfo;
- Begin
- Initialize(info);
- bd := ImGui_ImplSDL2_GetBackendData();
- vd := AllocMem(SizeOf(ImGui_ImplSDL2_ViewportData));
- viewport^.PlatformUserData := vd;
- main_viewport := ImGui.GetMainViewport();
- main_viewport_data := main_viewport^.PlatformUserData;
- // Share GL resources with main context
- use_opengl := (main_viewport_data^.GLContext <> nil);
- backup_context := nil;
- If use_opengl Then
- Begin
- backup_context := SDL_GL_GetCurrentContext();
- SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
- SDL_GL_MakeCurrent(main_viewport_data^.Window, main_viewport_data^.GLContext);
- End;
- sdl_flags := 0;
- If use_opengl Then
- sdl_flags := sdl_flags Or SDL_WINDOW_OPENGL;
- { TODO: SDL Unit needs update - Time : 11/7/2023 7:26:01 PM }
- //if bd^.UseVulkan then
- // sdl_flags := sdl_flags or SDL_WINDOW_VULKAN;
- sdl_flags := sdl_flags Or (SDL_GetWindowFlags(bd^.Window) And
- SDL_WINDOW_ALLOW_HIGHDPI);
- sdl_flags := sdl_flags Or SDL_WINDOW_HIDDEN;
- If Ord(viewport^.Flags And ImGuiViewportFlags_NoDecoration) <> 0 Then
- sdl_flags := sdl_flags Or SDL_WINDOW_BORDERLESS
- Else
- sdl_flags := sdl_flags Or SDL_WINDOW_RESIZABLE;
- {$IfNDef MSWINDOWS}
- if Ord(viewport^.Flags and ImGuiViewportFlags_NoTaskBarIcon) <> 0 then
- sdl_flags := sdl_flags or SDL_WINDOW_SKIP_TASKBAR;
- {$EndIf}
- If SDL_VERSION_ATLEAST(2, 0, 5) Then
- Begin
- If Ord(viewport^.Flags And ImGuiViewportFlags_TopMost) <> 0 Then
- sdl_flags := sdl_flags Or SDL_WINDOW_ALWAYS_ON_TOP;
- End;
- vd^.Window := SDL_CreateWindow('No Title Yet', Trunc(viewport^.Pos.x),
- Trunc(viewport^.Pos.y), Trunc(viewport^.Size.x), Trunc(viewport^.Size.y),
- sdl_flags);
- vd^.WindowOwned := True;
- If use_opengl Then
- Begin
- vd^.GLContext := SDL_GL_CreateContext(vd^.Window);
- SDL_GL_SetSwapInterval(0);
- End;
- If use_opengl And (backup_context <> nil) Then
- SDL_GL_MakeCurrent(vd^.Window, backup_context);
- viewport^.PlatformHandle := vd^.Window;
- viewport^.PlatformHandleRaw := nil;
- FillByte(info, SizeOf(TSDL_SysWMinfo), 0);
- SDL_VERSION(info.version);
- If SDL_GetWindowWMInfo(vd^.window, @info) = SDL_TRUE Then
- Begin
- {$IfDef MSWINDOWS}
- viewport^.PlatformHandleRaw := {%H-}Pointer(info.win.window);
- {$ElseIf defined(DARWIN)}
- viewport^.PlatformHandleRaw = {%H-}
- Pointer(info.cocoa.window);
- {$EndIf}
- End;
- End;
- // Done
- Procedure ImGui_ImplSDL2_DestroyWindow(viewport: PImGuiViewport); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- If vd <> nil Then
- Begin
- If (vd^.GLContext <> nil) And vd^.WindowOwned Then
- SDL_GL_DeleteContext(vd^.GLContext);
- If (vd^.Window <> nil) And vd^.WindowOwned Then
- SDL_DestroyWindow(vd^.Window);
- vd^.GLContext := nil;
- vd^.Window := nil;
- Freemem(vd);
- End;
- viewport^.PlatformHandle := nil;
- viewport^.PlatformUserData := nil;
- End;
- // Done
- Procedure ImGui_ImplSDL2_ShowWindow(viewport: PImGuiViewport); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- {$IfDef MSWINDOWS}
- _hwnd: Windows.HWND;
- ex_style: LONG;
- {$EndIf}
- Begin
- vd := viewport^.PlatformUserData;
- {$IfDef MSWINDOWS}
- _hwnd := {%H-}Windows.HWND(viewport^.PlatformHandleRaw);
- // SDL hack: Hide icon from task bar
- // 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.
- If Ord(viewport^.Flags And ImGuiViewportFlags_NoTaskBarIcon) <> 0 Then
- Begin
- ex_style := GetWindowLong(_hwnd, GWL_EXSTYLE);
- ex_style := ex_style And Not WS_EX_APPWINDOW;
- ex_style := ex_style Or WS_EX_TOOLWINDOW;
- SetWindowLong(_hwnd, GWL_EXSTYLE, ex_style);
- End;
- // SDL hack: SDL always activate/focus windows :/
- If Ord(viewport^.Flags And ImGuiViewportFlags_NoFocusOnAppearing) <> 0 Then
- Begin
- ShowWindow(_hwnd, SW_SHOWNA);
- Exit;
- End;
- {$EndIf}
- SDL_ShowWindow(vd^.Window);
- End;
- // Done
- Function ImGui_ImplSDL2_GetWindowPos(viewport: PImGuiViewport): ImVec2; Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- x, y: Integer;
- Begin
- vd := viewport^.PlatformUserData;
- x := 0;
- y := 0;
- SDL_GetWindowPosition(vd^.Window, @x, @y);
- Result := ImVec2.New(Single(x), Single(y));
- End;
- // Done
- Procedure ImGui_ImplSDL2_SetWindowPos(viewport: PImGuiViewport; pos: ImVec2); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- SDL_SetWindowPosition(vd^.Window, Trunc(pos.x), Trunc(pos.y));
- End;
- // Done
- Function ImGui_ImplSDL2_GetWindowSize(viewport: PImGuiViewport): ImVec2; Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- w, h: Integer;
- Begin
- vd := viewport^.PlatformUserData;
- w := 0;
- h := 0;
- SDL_GetWindowSize(vd^.Window, @w, @h);
- Result := ImVec2.New(Single(w), Single(h));
- End;
- // Done
- Procedure ImGui_ImplSDL2_SetWindowSize(viewport: PImGuiViewport; size: ImVec2); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- SDL_SetWindowSize(vd^.Window, Trunc(size.x), Trunc(size.y));
- End;
- // Done
- Procedure ImGui_ImplSDL2_SetWindowTitle(viewport: PImGuiViewport; title: PChar); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- SDL_SetWindowTitle(vd^.Window, title);
- End;
- // Done
- Procedure ImGui_ImplSDL2_SetWindowAlpha(viewport: PImGuiViewport; alpha: Single); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- SDL_SetWindowOpacity(vd^.Window, alpha);
- End;
- // Done
- Procedure ImGui_ImplSDL2_SetWindowFocus(viewport: PImGuiViewport); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- SDL_RaiseWindow(vd^.Window);
- End;
- // Done
- Function ImGui_ImplSDL2_GetWindowFocus(viewport: PImGuiViewport): Boolean; Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- Result := Ord(SDL_GetWindowFlags(vd^.Window) And SDL_WINDOW_INPUT_FOCUS) <> 0;
- End;
- // Done
- Function ImGui_ImplSDL2_GetWindowMinimized(viewport: PImGuiViewport): Boolean; Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- Result := Ord(SDL_GetWindowFlags(vd^.Window) And SDL_WINDOW_MINIMIZED) <> 0;
- End;
- // Done
- Procedure ImGui_ImplSDL2_RenderWindow(viewport: PImGuiViewport;
- render_arg: Pointer); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- If vd^.GLContext <> nil Then
- SDL_GL_MakeCurrent(vd^.Window, vd^.GLContext);
- End;
- // Done
- Procedure ImGui_ImplSDL2_SwapBuffers(viewport: PImGuiViewport;
- render_arg: Pointer); Cdecl;
- Var
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- vd := viewport^.PlatformUserData;
- If vd^.GLContext <> nil Then
- Begin
- SDL_GL_MakeCurrent(vd^.Window, vd^.GLContext);
- SDL_GL_SwapWindow(vd^.Window);
- End;
- End;
- // Done
- Procedure ImGui_ImplSDL2_InitPlatformInterface(window: PSDL_Window;
- sdl_gl_context: Pointer);
- Var
- platform_io: PImGuiPlatformIO;
- main_viewport: PImGuiViewport;
- vd: PImGui_ImplSDL2_ViewportData;
- Begin
- platform_io := ImGui.GetPlatformIO();
- platform_io^.Platform_CreateWindow := @ImGui_ImplSDL2_CreateWindow;
- platform_io^.Platform_DestroyWindow := @ImGui_ImplSDL2_DestroyWindow;
- platform_io^.Platform_ShowWindow := @ImGui_ImplSDL2_ShowWindow;
- platform_io^.Platform_SetWindowPos := @ImGui_ImplSDL2_SetWindowPos;
- platform_io^.Platform_GetWindowPos := @ImGui_ImplSDL2_GetWindowPos;
- platform_io^.Platform_SetWindowSize := @ImGui_ImplSDL2_SetWindowSize;
- platform_io^.Platform_GetWindowSize := @ImGui_ImplSDL2_GetWindowSize;
- platform_io^.Platform_SetWindowFocus := @ImGui_ImplSDL2_SetWindowFocus;
- platform_io^.Platform_GetWindowFocus := @ImGui_ImplSDL2_GetWindowFocus;
- platform_io^.Platform_GetWindowMinimized := @ImGui_ImplSDL2_GetWindowMinimized;
- platform_io^.Platform_SetWindowTitle := @ImGui_ImplSDL2_SetWindowTitle;
- platform_io^.Platform_RenderWindow := @ImGui_ImplSDL2_RenderWindow;
- platform_io^.Platform_SwapBuffers := @ImGui_ImplSDL2_SwapBuffers;
- If SDL_VERSION_ATLEAST(2, 0, 5) Then
- Begin
- platform_io^.Platform_SetWindowAlpha := @ImGui_ImplSDL2_SetWindowAlpha;
- End;
- {$IfDef SDL_HAS_VULKAN}
- platform_io^.Platform_CreateVkSurface := ImGui_ImplSDL2_CreateVkSurface;
- {$EndIf}
- // Register main window handle (which is owned by the main application, not by us)
- // 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.
- main_viewport := ImGui.GetMainViewport();
- vd := AllocMem(SizeOf(ImGui_ImplSDL2_ViewportData));
- vd^.Window := window;
- vd^.WindowID := SDL_GetWindowID(window);
- vd^.WindowOwned := False;
- vd^.GLContext := sdl_gl_context;
- main_viewport^.PlatformUserData := vd;
- main_viewport^.PlatformHandle := vd^.Window;
- End;
- // Done
- Procedure ImGui_ImplSDL2_ShutdownPlatformInterface;
- Begin
- ImGui.DestroyPlatformWindows();
- End;
- //------------------------------------------------------------------------------
- // Frame Generation
- //------------------------------------------------------------------------------
- // Done
- Function ImGui_ImplSDL2_GetClipboardText(user_data: Pointer): PChar; Cdecl;
- Var
- bd: PImGui_ImplSDL2_Data;
- Begin
- bd := ImGui_ImplSDL2_GetBackendData();
- If bd^.ClipboardTextData <> nil Then
- SDL_free(bd^.ClipboardTextData);
- bd^.ClipboardTextData := SDL_GetClipboardText();
- Result := bd^.ClipboardTextData;
- End;
- // Done
- Procedure ImGui_ImplSDL2_SetClipboardText(user_data: Pointer; Text: PChar); Cdecl;
- Begin
- SDL_SetClipboardText(Text);
- End;
- // Done
- // Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
- Procedure ImGui_ImplSDL2_SetPlatformImeData(viewport: PImGuiViewport;
- Data: PImGuiPlatformImeData); Cdecl;
- Var
- r: TSDL_Rect;
- Begin
- If Data^.WantVisible Then
- Begin
- r.x := Trunc(Data^.InputPos.x - viewport^.Pos.x);
- r.y := Trunc(Data^.InputPos.y - viewport^.Pos.y + Data^.InputLineHeight);
- r.w := 1;
- r.h := Integer(Data^.InputLineHeight);
- SDL_SetTextInputRect(@r);
- End;
- End;
- // Done
- Function ImGui_ImplSDL2_KeycodeToImGuiKey(keycode: TSDL_KeyCode): ImGuiKey;
- Begin
- Case keycode Of
- SDLK_TAB: Result := ImGuiKey_Tab;
- SDLK_LEFT: Result := ImGuiKey_LeftArrow;
- SDLK_RIGHT: Result := ImGuiKey_RightArrow;
- SDLK_UP: Result := ImGuiKey_UpArrow;
- SDLK_DOWN: Result := ImGuiKey_DownArrow;
- SDLK_PAGEUP: Result := ImGuiKey_PageUp;
- SDLK_PAGEDOWN: Result := ImGuiKey_PageDown;
- SDLK_HOME: Result := ImGuiKey_Home;
- SDLK_END: Result := ImGuiKey_End;
- SDLK_INSERT: Result := ImGuiKey_Insert;
- SDLK_DELETE: Result := ImGuiKey_Delete;
- SDLK_BACKSPACE: Result := ImGuiKey_Backspace;
- SDLK_SPACE: Result := ImGuiKey_Space;
- SDLK_RETURN: Result := ImGuiKey_Enter;
- SDLK_ESCAPE: Result := ImGuiKey_Escape;
- SDLK_QUOTE: Result := ImGuiKey_Apostrophe;
- SDLK_COMMA: Result := ImGuiKey_Comma;
- SDLK_MINUS: Result := ImGuiKey_Minus;
- SDLK_PERIOD: Result := ImGuiKey_Period;
- SDLK_SLASH: Result := ImGuiKey_Slash;
- SDLK_SEMICOLON: Result := ImGuiKey_Semicolon;
- SDLK_EQUALS: Result := ImGuiKey_Equal;
- SDLK_LEFTBRACKET: Result := ImGuiKey_LeftBracket;
- SDLK_BACKSLASH: Result := ImGuiKey_Backslash;
- SDLK_RIGHTBRACKET: Result := ImGuiKey_RightBracket;
- SDLK_BACKQUOTE: Result := ImGuiKey_GraveAccent;
- SDLK_CAPSLOCK: Result := ImGuiKey_CapsLock;
- SDLK_SCROLLLOCK: Result := ImGuiKey_ScrollLock;
- SDLK_NUMLOCKCLEAR: Result := ImGuiKey_NumLock;
- SDLK_PRINTSCREEN: Result := ImGuiKey_PrintScreen;
- SDLK_PAUSE: Result := ImGuiKey_Pause;
- SDLK_KP_0: Result := ImGuiKey_Keypad0;
- SDLK_KP_1: Result := ImGuiKey_Keypad1;
- SDLK_KP_2: Result := ImGuiKey_Keypad2;
- SDLK_KP_3: Result := ImGuiKey_Keypad3;
- SDLK_KP_4: Result := ImGuiKey_Keypad4;
- SDLK_KP_5: Result := ImGuiKey_Keypad5;
- SDLK_KP_6: Result := ImGuiKey_Keypad6;
- SDLK_KP_7: Result := ImGuiKey_Keypad7;
- SDLK_KP_8: Result := ImGuiKey_Keypad8;
- SDLK_KP_9: Result := ImGuiKey_Keypad9;
- SDLK_KP_PERIOD: Result := ImGuiKey_KeypadDecimal;
- SDLK_KP_DIVIDE: Result := ImGuiKey_KeypadDivide;
- SDLK_KP_MULTIPLY: Result := ImGuiKey_KeypadMultiply;
- SDLK_KP_MINUS: Result := ImGuiKey_KeypadSubtract;
- SDLK_KP_PLUS: Result := ImGuiKey_KeypadAdd;
- SDLK_KP_ENTER: Result := ImGuiKey_KeypadEnter;
- SDLK_KP_EQUALS: Result := ImGuiKey_KeypadEqual;
- SDLK_LCTRL: Result := ImGuiKey_LeftCtrl;
- SDLK_LSHIFT: Result := ImGuiKey_LeftShift;
- SDLK_LALT: Result := ImGuiKey_LeftAlt;
- SDLK_LGUI: Result := ImGuiKey_LeftSuper;
- SDLK_RCTRL: Result := ImGuiKey_RightCtrl;
- SDLK_RSHIFT: Result := ImGuiKey_RightShift;
- SDLK_RALT: Result := ImGuiKey_RightAlt;
- SDLK_RGUI: Result := ImGuiKey_RightSuper;
- SDLK_APPLICATION: Result := ImGuiKey_Menu;
- SDLK_0: Result := ImGuiKey_0;
- SDLK_1: Result := ImGuiKey_1;
- SDLK_2: Result := ImGuiKey_2;
- SDLK_3: Result := ImGuiKey_3;
- SDLK_4: Result := ImGuiKey_4;
- SDLK_5: Result := ImGuiKey_5;
- SDLK_6: Result := ImGuiKey_6;
- SDLK_7: Result := ImGuiKey_7;
- SDLK_8: Result := ImGuiKey_8;
- SDLK_9: Result := ImGuiKey_9;
- SDLK_a: Result := ImGuiKey_A;
- SDLK_b: Result := ImGuiKey_B;
- SDLK_c: Result := ImGuiKey_C;
- SDLK_d: Result := ImGuiKey_D;
- SDLK_e: Result := ImGuiKey_E;
- SDLK_f: Result := ImGuiKey_F;
- SDLK_g: Result := ImGuiKey_G;
- SDLK_h: Result := ImGuiKey_H;
- SDLK_i: Result := ImGuiKey_I;
- SDLK_j: Result := ImGuiKey_J;
- SDLK_k: Result := ImGuiKey_K;
- SDLK_l: Result := ImGuiKey_L;
- SDLK_m: Result := ImGuiKey_M;
- SDLK_n: Result := ImGuiKey_N;
- SDLK_o: Result := ImGuiKey_O;
- SDLK_p: Result := ImGuiKey_P;
- SDLK_q: Result := ImGuiKey_Q;
- SDLK_r: Result := ImGuiKey_R;
- SDLK_s: Result := ImGuiKey_S;
- SDLK_t: Result := ImGuiKey_T;
- SDLK_u: Result := ImGuiKey_U;
- SDLK_v: Result := ImGuiKey_V;
- SDLK_w: Result := ImGuiKey_W;
- SDLK_x: Result := ImGuiKey_X;
- SDLK_y: Result := ImGuiKey_Y;
- SDLK_z: Result := ImGuiKey_Z;
- SDLK_F1: Result := ImGuiKey_F1;
- SDLK_F2: Result := ImGuiKey_F2;
- SDLK_F3: Result := ImGuiKey_F3;
- SDLK_F4: Result := ImGuiKey_F4;
- SDLK_F5: Result := ImGuiKey_F5;
- SDLK_F6: Result := ImGuiKey_F6;
- SDLK_F7: Result := ImGuiKey_F7;
- SDLK_F8: Result := ImGuiKey_F8;
- SDLK_F9: Result := ImGuiKey_F9;
- SDLK_F10: Result := ImGuiKey_F10;
- SDLK_F11: Result := ImGuiKey_F11;
- SDLK_F12: Result := ImGuiKey_F12;
- Else
- Result := ImGuiKey_None;
- End;
- End;
- // Done
- Procedure ImGui_ImplSDL2_UpdateKeyModifiers(sdl_key_mods: TSDL_KeyMod);
- Begin
- ImGui.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods And KMOD_CTRL) <> 0);
- ImGui.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods And KMOD_SHIFT) <> 0);
- ImGui.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods And KMOD_ALT) <> 0);
- ImGui.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods And KMOD_GUI) <> 0);
- End;
- // FIXME
- Function ImGui_ImplSDL2_Init(window: PSDL_Window; renderer: PSDL_Renderer;
- sdl_gl_context: Pointer): Boolean;
- Var
- io: PImGuiIO;
- bd: PImGui_ImplSDL2_Data;
- main_viewport: PImGuiViewport;
- mouse_can_use_global_state: Boolean;
- sdl_backend: Pansichar;
- I: Integer;
- info: TSDL_SysWMinfo;
- Const
- global_mouse_whitelist: Array[0..4] Of
- Pansichar = ('windows', 'cocoa', 'x11', 'DIVE', 'VMAN');
- Begin
- io := ImGui.GetIO();
- Assert(io^.BackendPlatformUserData = nil, 'Already initialized a platform backend!');
- // Check and store if we are on a SDL backend that supports global mouse position
- // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
- mouse_can_use_global_state := False;
- sdl_backend := SDL_GetCurrentVideoDriver();
- For I := 0 To High(global_mouse_whitelist) Do
- Begin
- If StrIComp(sdl_backend, global_mouse_whitelist[I]) = 0 Then
- Begin
- mouse_can_use_global_state := True;
- Break; // Break the loop early if a match is found
- End;
- End;
- // Setup backend capabilities flags
- bd := AllocMem(SizeOf(ImGui_ImplSDL2_Data));
- io^.BackendPlatformUserData := bd;
- io^.BackendPlatformName := PAnsiChar('imgui_impl_sdl2_pascal');
- // We can honor GetMouseCursor() values (optional)
- io^.BackendFlags := io^.BackendFlags Or ImGuiBackendFlags_HasMouseCursors;
- // We can honor io.WantSetMousePos requests (optional, rarely used)
- io^.BackendFlags := io^.BackendFlags Or ImGuiBackendFlags_HasSetMousePos;
- If mouse_can_use_global_state Then
- Begin
- // We can create multi-viewports on the Platform side (optional)
- io^.BackendFlags := io^.BackendFlags Or ImGuiBackendFlags_PlatformHasViewports;
- End;
- bd^.Window := window;
- bd^.Renderer := renderer;
- // SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
- // We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
- bd^.MouseCanUseGlobalState := mouse_can_use_global_state;
- {$IfnDef DARWIN}
- bd^.MouseCanReportHoveredViewport := bd^.MouseCanUseGlobalState;
- {$ELSE}
- bd^.MouseCanReportHoveredViewport := False;
- {$EndIf}
- bd^.WantUpdateMonitors := True;
- io^.SetClipboardTextFn := @ImGui_ImplSDL2_SetClipboardText;
- io^.GetClipboardTextFn := @ImGui_ImplSDL2_GetClipboardText;
- io^.ClipboardUserData := nil;
- io^.SetPlatformImeDataFn := @ImGui_ImplSDL2_SetPlatformImeData;
- // Load mouse cursors
- bd^.MouseCursors[Ord(ImGuiMouseCursor_Arrow)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_TextInput)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_ResizeAll)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_ResizeNS)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_ResizeEW)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_ResizeNESW)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_ResizeNWSE)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_Hand)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
- bd^.MouseCursors[Ord(ImGuiMouseCursor_NotAllowed)] := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
- main_viewport := ImGui.GetMainViewport();
- main_viewport^.PlatformHandle := window;
- main_viewport^.PlatformHandleRaw := nil;
- FillByte(info, SizeOf(TSDL_SysWMinfo), 0);
- SDL_VERSION(info.version);
- If SDL_GetWindowWMInfo(window, @info) = SDL_TRUE Then
- Begin
- {$IfDef MSWINDOWS}
- main_viewport^.PlatformHandleRaw := Pointer(info.win.window);
- {$ElseIf defined(DARWIN)}
- main_viewport^.PlatformHandleRaw = Pointer(info.cocoa.window);
- {$EndIf}
- End;
- // From 2.0.5 only
- {$IfDef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH}
- If SDL_VERSION_ATLEAST(2, 0, 5) Then
- SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, '1');
- {$EndIf}
- // From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
- {$IfDef SDL_HINT_IME_SHOW_UI}
- If SDL_VERSION_ATLEAST(2, 0, 22) Then
- SDL_SetHint(SDL_HINT_IME_SHOW_UI, '1');
- {$ENDIF}
- // From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
- {$IfDef SDL_HINT_MOUSE_AUTO_CAPTURE}
- If SDL_VERSION_ATLEAST(2, 0, 22) Then
- SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, '0');
- {$EndIf}
- If (Ord(io^.ConfigFlags And ImGuiConfigFlags_ViewportsEnable) <> 0) And
- (Ord(io^.BackendFlags And ImGuiBackendFlags_PlatformHasViewports) <> 0) Then
- Begin
- ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context);
- End;
- Result := True;
- End;
- // Done
- Function ImGui_ImplSDL2_InitForOpenGL_Pas(window: PSDL_Window;
- sdl_gl_context: Pointer): Boolean;
- Begin
- Result := ImGui_ImplSDL2_Init(window, nil, sdl_gl_context);
- End;
- // FIXME: Note that doesn't update with DPI/Scaling
- // change only as SDL2 doesn't have an event for it (SDL3 has).
- Procedure ImGui_ImplSDL2_UpdateMonitors;
- Var
- platform_io: PImGuiPlatformIO;
- bd: PImGui_ImplSDL2_Data;
- display_count, n: Integer;
- monitor: ImGuiPlatformMonitor;
- r: TSDL_Rect;
- dpi: Single;
- Begin
- bd := ImGui_ImplSDL2_GetBackendData();
- platform_io := ImGui.GetPlatformIO();
- platform_io^.Monitors.Size := 0;
- bd^.WantUpdateMonitors := False;
- display_count := SDL_GetNumVideoDisplays();
- platform_io^.Monitors.Capacity := display_count;
- For n := 0 To Pred(display_count) Do
- Begin
- FillChar(monitor, SizeOf(ImGuiPlatformMonitor), 0);
- SDL_GetDisplayBounds(n, @r);
- monitor.WorkPos := ImVec2.New(Single(r.x), Single(r.y));
- monitor.WorkSize := ImVec2.New(Single(r.w), Single(r.h));
- monitor.MainPos := monitor.WorkPos;
- monitor.MainSize := monitor.WorkSize;
- If SDL_VERSION_ATLEAST(2, 0, 5) Then
- Begin
- SDL_GetDisplayUsableBounds(n, @r);
- monitor.WorkPos := ImVec2.New(Single(r.x), Single(r.y));
- monitor.WorkSize := ImVec2.New(Single(r.w), Single(r.h));
- End;
- If SDL_VERSION_ATLEAST(2, 0, 4) Then
- Begin
- // FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale,
- // ignoring OS configuration. We may want to set
- // DpiScale to cocoa_window.backingScaleFactor here.
- dpi := 0.0;
- If Not Boolean(SDL_GetDisplayDPI(n, @dpi, nil, nil)) Then
- monitor.DpiScale := dpi / 96.0;
- End;
- monitor.PlatformHandle := Pointer(UIntPtr(n));
- If platform_io^.Monitors.Data = nil Then
- Begin
- platform_io^.Monitors.Data := AllocMem(SizeOf(ImGuiPlatformMonitor) * 8);
- platform_io^.Monitors.Capacity := 8;
- End;
- platform_io^.Monitors.Data[n] := monitor;
- Inc(platform_io^.Monitors.Size, 1);
- End;
- End;
- // Done
- Procedure ImGui_ImplSDL2_UpdateMouseData;
- Var
- bd: PImGui_ImplSDL2_Data;
- io: PImGuiIO;
- focused_window: PSDL_Window;
- is_app_focused: Boolean;
- mouse_x, mouse_y, window_x, window_y: Integer;
- mouse_viewport_id: ImGuiID;
- mouse_viewport: PImGuiViewport;
- mouse_btn: TSDL_bool;
- sdl_mouse_window: PSDL_Window;
- Begin
- bd := ImGui_ImplSDL2_GetBackendData;
- io := ImGui.GetIO;
- // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
- {$IfDef SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE}
- // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
- mouse_btn := SDL_FALSE;
- If bd^.MouseButtonsDown <> 0 Then
- mouse_btn := SDL_TRUE;
- SDL_CaptureMouse(mouse_btn);
- focused_window := SDL_GetKeyboardFocus;
- is_app_focused := (focused_window <> nil) And
- ((bd^.Window = focused_window) Or
- (ImGui.FindViewportByPlatformHandle(focused_window) <> nil));
- {$ELSE}
- focused_window := bd^.Window;
- // SDL 2.0.3 and non-windowed systems: single-viewport only
- is_app_focused := (SDL_GetWindowFlags(bd^.Window) And SDL_WINDOW_INPUT_FOCUS) <> 0;
- {$EndIf}
- If is_app_focused Then
- Begin
- // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
- If io^.WantSetMousePos Then
- Begin
- {$IfDef SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE}
- If Ord(io^.ConfigFlags And ImGuiConfigFlags_ViewportsEnable) <> 0 Then
- SDL_WarpMouseGlobal(Trunc(io^.MousePos.x), Trunc(io^.MousePos.y))
- Else
- {$EndIf}
- SDL_WarpMouseInWindow(bd^.Window, Trunc(io^.MousePos.x),
- Trunc(io^.MousePos.y));
- End;
- // (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
- If bd^.MouseCanUseGlobalState And (bd^.MouseButtonsDown = 0) Then
- Begin
- // Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
- // 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)
- SDL_GetGlobalMouseState(@mouse_x, @mouse_y);
- If Ord(io^.ConfigFlags And ImGuiConfigFlags_ViewportsEnable) = 0 Then
- Begin
- SDL_GetWindowPosition(focused_window, @window_x, @window_y);
- Dec(mouse_x, window_x);
- Dec(mouse_y, window_y);
- End;
- ImGui.AddMousePosEvent(Single(mouse_x), Single(mouse_y));
- End;
- End;
- // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
- // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear ImGui will ignore this field and infer the information using its flawed heuristic.
- // - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
- // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
- // for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
- // by the backend, and use its flawed heuristic to guess the viewport behind.
- // - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
- If Ord(io^.BackendFlags And ImGuiBackendFlags_HasMouseHoveredViewport) <> 0 Then
- Begin
- mouse_viewport_id := 0;
- sdl_mouse_window := SDL_GetWindowFromID(bd^.MouseWindowID);
- If sdl_mouse_window <> nil Then
- Begin
- mouse_viewport := ImGui.FindViewportByPlatformHandle(sdl_mouse_window);
- If mouse_viewport <> nil Then
- Begin
- mouse_viewport_id := mouse_viewport^.ID;
- End;
- End;
- ImGui.AddMouseViewportEvent(mouse_viewport_id);
- End;
- End;
- // Done
- Procedure ImGui_ImplSDL2_UpdateMouseCursor;
- Var
- io: PImGuiIO;
- bd: PImGui_ImplSDL2_Data;
- imgui_cursor: ImGuiMouseCursor;
- expected_cursor: PSDL_Cursor;
- Begin
- io := ImGui.GetIO;
- If Ord(io^.ConfigFlags And ImGuiConfigFlags_NoMouseCursorChange) <> 0 Then
- Exit;
- bd := ImGui_ImplSDL2_GetBackendData;
- imgui_cursor := ImGui.GetMouseCursor;
- If io^.MouseDrawCursor Or (imgui_cursor = ImGuiMouseCursor_None) Then
- Begin
- // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
- SDL_ShowCursor(Ord(SDL_FALSE));
- End
- Else
- Begin
- // Show OS mouse cursor
- expected_cursor := bd^.MouseCursors[Ord(imgui_cursor)];
- If expected_cursor = nil Then
- expected_cursor := bd^.MouseCursors[Ord(ImGuiMouseCursor_Arrow)];
- If bd^.LastMouseCursor <> expected_cursor Then
- Begin
- SDL_SetCursor(expected_cursor);
- // SDL function doesn't have an early out (see #6113)
- bd^.LastMouseCursor := expected_cursor;
- End;
- SDL_ShowCursor(Ord(SDL_TRUE));
- End;
- End;
- { TODO: Implement this ^_^ - Time : 11/8/2023 1:06:27 AM }
- Procedure ImGui_ImplSDL2_UpdateGamepads;
- Begin
- { TODO: Implement this :V - Time : 11/9/2023 5:12:29 PM }
- End;
- // Done
- Procedure ImGui_ImplSDL2_NewFrame_Pas();
- Var
- io: PImGuiIO;
- bd: PImGui_ImplSDL2_Data;
- w, h: Integer;
- display_w, display_h: Integer;
- frequency, current_time: Uint64;
- Begin
- bd := ImGui_ImplSDL2_GetBackendData();
- Assert(bd <> nil, 'Did you call ImGui_ImplSDL2_Init()?');
- io := imgui.GetIO();
- // Setup display size (every frame to accommodate for window resizing)
- SDL_GetWindowSize(bd^.Window, @w, @h);
- If Ord(SDL_GetWindowFlags(bd^.Window) And SDL_WINDOW_MINIMIZED) <> 0 Then
- Begin
- w := 0;
- h := 0;
- End;
- If bd^.Renderer <> nil Then
- SDL_GetRendererOutputSize(bd^.Renderer, @display_w, @display_h)
- Else
- SDL_GL_GetDrawableSize(bd^.Window, @display_w, @display_h);
- io^.DisplaySize := ImVec2.New(Single(w), Single(h));
- If (w > 0) And (h > 0) Then
- io^.DisplayFramebufferScale :=
- ImVec2.New(Single(display_w) / w, Single(display_h) / h);
- // Update monitors
- If bd^.WantUpdateMonitors Then
- ImGui_ImplSDL2_UpdateMonitors();
- // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
- // (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value.
- // Happens in VMs and Emscripten, see #6189, #6114, #3644)
- frequency := SDL_GetPerformanceFrequency;
- current_time := SDL_GetPerformanceCounter;
- If current_time <= bd^.Time Then
- current_time := bd^.Time + 1;
- If bd^.Time > 0 Then
- io^.DeltaTime := Single(double(current_time - bd^.Time) / frequency)
- Else
- io^.DeltaTime := Single(1.0 / 60.0);
- bd^.Time := current_time;
- If ((bd^.PendingMouseLeaveFrame > 0) And (bd^.PendingMouseLeaveFrame >=
- ImGui.GetFrameCount()) And (bd^.MouseButtonsDown = 0)) Then
- Begin
- bd^.MouseWindowID := 0;
- bd^.PendingMouseLeaveFrame := 0;
- ImGui.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
- End;
- // Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
- // Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rygorous,
- // but testing for payload reduces noise and potential side-effects.
- If (bd^.MouseCanReportHoveredViewport And (ImGui.GetDragDropPayload() = nil)) Then
- io^.BackendFlags := io^.BackendFlags Or ImGuiBackendFlags_HasMouseHoveredViewport
- Else
- io^.BackendFlags := io^.BackendFlags And Not
- ImGuiBackendFlags_HasMouseHoveredViewport;
- ImGui_ImplSDL2_UpdateMouseData();
- ImGui_ImplSDL2_UpdateMouseCursor();
- // Update game controllers (if enabled and available)
- ImGui_ImplSDL2_UpdateGamepads();
- End;
- // Done
- Procedure ImGui_ImplSDL2_Shutdown_Pas();
- Var
- platform_io: PImGuiPlatformIO;
- bd: PImGui_ImplSDL2_Data;
- io: PImGuiIO;
- cursor_n: Integer;
- Begin
- bd := ImGui_ImplSDL2_GetBackendData();
- Assert(bd <> nil, 'No platform backend to shutdown, or already shutdown?');
- io := imgui.GetIO();
- ImGui_ImplSDL2_ShutdownPlatformInterface();
- If bd^.ClipboardTextData <> nil Then
- SDL_free(bd^.ClipboardTextData);
- For cursor_n := 0 To Pred(Ord(ImGuiMouseCursor_COUNT)) Do
- Begin
- SDL_FreeCursor(bd^.MouseCursors[cursor_n]);
- End;
- bd^.LastMouseCursor := nil;
- io^.BackendPlatformName := nil;
- io^.BackendPlatformUserData := nil;
- io^.BackendFlags := io^.BackendFlags And Not
- (ImGuiBackendFlags_HasMouseCursors Or ImGuiBackendFlags_HasSetMousePos Or
- ImGuiBackendFlags_HasGamepad Or ImGuiBackendFlags_PlatformHasViewports Or
- ImGuiBackendFlags_HasMouseHoveredViewport);
- // Free Allocated Monitors
- platform_io := ImGui.GetPlatformIO();
- platform_io^.Monitors.Size := 0;
- platform_io^.Monitors.Capacity := 0;
- Freemem(platform_io^.Monitors.Data);
- platform_io^.Monitors.Data := nil;
- Freemem(bd);
- End;
- // Done
- Function ImGui_ImplSDL2_ProcessEvent_Pas(event: PSDL_Event): Boolean;
- Var
- ImKey: ImGuiKey;
- mouse_pos: ImVec2;
- window_x, window_y: Integer;
- wheel_x, wheel_y: Single;
- MouseSrc: ImGuiMouseSource;
- mouse_button: Integer;
- bd: PImGui_ImplSDL2_Data;
- io: PImGuiIO;
- window_event: Uint8;
- viewport: PImGuiViewport;
- Begin
- Result := False;
- io := ImGui.GetIO();
- bd := ImGui_ImplSDL2_GetBackendData();
- Case event^.type_ Of
- SDL_MOUSEMOTION:
- Begin
- mouse_pos := ImVec2.New(Single(event^.motion.x), Single(event^.motion.y));
- If Int64(io^.ConfigFlags And ImGuiConfigFlags_ViewportsEnable) <> 0 Then
- Begin
- SDL_GetWindowPosition(SDL_GetWindowFromID(event^.motion.windowID),
- @window_x, @window_y);
- mouse_pos.x += window_x;
- mouse_pos.y += window_y;
- End;
- If event^.motion.which = SDL_TOUCH_MOUSEID Then
- ImGui.AddMouseSourceEvent(ImGuiMouseSource_TouchScreen)
- Else
- ImGui.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
- ImGui.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
- Result := True;
- End;
- SDL_MOUSEWHEEL:
- Begin
- wheel_x := -Single(event^.wheel.x);
- wheel_y := Single(event^.wheel.y);
- If event^.wheel.which = SDL_TOUCH_MOUSEID Then
- MouseSrc := ImGuiMouseSource_TouchScreen
- Else
- MouseSrc := ImGuiMouseSource_Mouse;
- ImGui.AddMouseSourceEvent(MouseSrc);
- ImGui.AddMouseWheelEvent(wheel_x, wheel_y);
- Result := True;
- End;
- SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP:
- Begin
- mouse_button := -1;
- If (event^.button.button = SDL_BUTTON_LEFT) Then
- mouse_button := 0;
- If (event^.button.button = SDL_BUTTON_RIGHT) Then
- mouse_button := 1;
- If (event^.button.button = SDL_BUTTON_MIDDLE) Then
- mouse_button := 2;
- If (event^.button.button = SDL_BUTTON_X1) Then
- mouse_button := 3;
- If (event^.button.button = SDL_BUTTON_X2) Then
- mouse_button := 4;
- If (mouse_button = -1) Then
- Exit;
- If event^.wheel.which = SDL_TOUCH_MOUSEID Then
- MouseSrc := ImGuiMouseSource_TouchScreen
- Else
- MouseSrc := ImGuiMouseSource_Mouse;
- ImGui.AddMouseSourceEvent(MouseSrc);
- ImGui.AddMouseButtonEvent(mouse_button, (event^.type_ = SDL_MOUSEBUTTONDOWN));
- If (event^.type_ = SDL_MOUSEBUTTONDOWN) Then
- bd^.MouseButtonsDown := bd^.MouseButtonsDown Or (1 Shl mouse_button)
- Else
- bd^.MouseButtonsDown := bd^.MouseButtonsDown And Not (1 Shl mouse_button);
- Result := True;
- End;
- SDL_TEXTINPUT:
- Begin
- ImGui.AddInputCharactersUTF8(event^.Text.Text);
- Result := True;
- End;
- SDL_KEYDOWN, SDL_KEYUP:
- Begin
- ImGui_ImplSDL2_UpdateKeyModifiers(event^.key.keysym.mod_);
- ImKey := ImGui_ImplSDL2_KeycodeToImGuiKey(event^.key.keysym.sym);
- ImGui.AddKeyEvent(ImKey, (event^.type_ = SDL_KEYDOWN));
- // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
- ImGui.SetKeyEventNativeData(ImKey, event^.key.keysym.sym,
- event^.key.keysym.scancode, event^.key.keysym.scancode);
- Result := True;
- End;
- // SDL_VERSION_ATLEAST(2,0,9) >> SDL_DISPLAYEVENT
- SDL_DISPLAYEVENT:
- Begin
- bd^.WantUpdateMonitors := True;
- Result := True;
- End;
- SDL_WINDOWEVENT:
- Begin
- // - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER
- // event on every mouse move, but the final ENTER tends to be right.
- // - However we won't get a correct LEAVE event for a captured window.
- // - In some cases, when detaching a window from main viewport SDL may
- // send SDL_WINDOWEVENT_ENTER one frame too late,
- // causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag
- // operation by clear mouse position. This is why
- // we delay process the SDL_WINDOWEVENT_LEAVE events by one frame.
- // See issue #5012 for details.
- window_event := event^.window.event;
- If window_event = SDL_WINDOWEVENT_ENTER Then
- Begin
- bd^.MouseWindowID := event^.window.windowID;
- bd^.PendingMouseLeaveFrame := 0;
- End;
- If window_event = SDL_WINDOWEVENT_LEAVE Then
- bd^.PendingMouseLeaveFrame := ImGui.GetFrameCount() + 1;
- If window_event = SDL_WINDOWEVENT_FOCUS_GAINED Then
- ImGui.AddFocusEvent(True)
- Else If window_event = SDL_WINDOWEVENT_FOCUS_LOST Then
- ImGui.AddFocusEvent(False);
- If (window_event = SDL_WINDOWEVENT_CLOSE) Or (window_event =
- SDL_WINDOWEVENT_MOVED) Or (window_event = SDL_WINDOWEVENT_RESIZED) Then
- Begin
- viewport := ImGui.FindViewportByPlatformHandle(
- SDL_GetWindowFromID(event^.window.windowID));
- If viewport <> nil Then
- Begin
- If window_event = SDL_WINDOWEVENT_CLOSE Then
- viewport^.PlatformRequestClose := True;
- If window_event = SDL_WINDOWEVENT_MOVED Then
- viewport^.PlatformRequestMove := True;
- If window_event = SDL_WINDOWEVENT_RESIZED Then
- viewport^.PlatformRequestResize := True;
- Exit(True);
- End;
- End;
- Result := True;
- End;
- Else
- Result := False;
- End;
- End;
- End.
|