imgui-bindings 0.1.14-x64-mingw → 0.1.16-x64-mingw
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog +385 -377
- data/LICENSE.txt +1 -1
- data/README.md +121 -121
- data/lib/imgui.dll +0 -0
- data/lib/imgui.rb +460 -165
- data/lib/imgui_impl_glfw.rb +511 -511
- data/lib/imgui_impl_opengl2.rb +212 -212
- data/lib/imgui_impl_opengl3.rb +1 -1
- data/lib/imgui_impl_raylib.rb +2 -1
- data/lib/imgui_impl_sdl2.rb +409 -409
- data/lib/imgui_impl_sdlrenderer.rb +200 -200
- data/lib/imgui_internal.rb +49 -49
- data/lib/imnodes.dll +0 -0
- data/lib/imnodes.rb +161 -161
- metadata +3 -6
data/lib/imgui_impl_sdl2.rb
CHANGED
@@ -1,409 +1,409 @@
|
|
1
|
-
require 'ffi'
|
2
|
-
require 'sdl2'
|
3
|
-
require_relative 'imgui'
|
4
|
-
|
5
|
-
module ImGui
|
6
|
-
|
7
|
-
@@g_BackendPlatformName = FFI::MemoryPointer.from_string("imgui_impl_sdl")
|
8
|
-
|
9
|
-
# ImGui::GetCurrentContext().address => ImGui_ImplSDL2_Data
|
10
|
-
@@g_BackendData = Hash.new
|
11
|
-
|
12
|
-
# [INTERNAL]
|
13
|
-
class ImGui_ImplSDL2_Data
|
14
|
-
attr_accessor :window, :renderer, :time, :mouseButtonsDown, :mouseCursors, :clipboardTextData, :mouseCanUseGlobalState
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@window = nil # SDL_Window*
|
18
|
-
@renderer = nil # SDL_Renderer*
|
19
|
-
@time = 0.0 # Uint64
|
20
|
-
@mouseButtonsDown = 0 # int
|
21
|
-
@mouseCursors = Array.new(ImGuiMouseCursor_COUNT) { 0 } # SDL_Cursor*
|
22
|
-
@clipboardTextData = nil # char*
|
23
|
-
@mouseCanUseGlobalState = false # bool
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
28
|
-
# It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
29
|
-
# FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
|
30
|
-
# FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
31
|
-
# [INTERNAL]
|
32
|
-
def self.ImGui_ImplSDL2_GetBackendData()
|
33
|
-
if ImGui::GetCurrentContext() != nil
|
34
|
-
@@g_BackendData[ImGui::GetCurrentContext().address]
|
35
|
-
else
|
36
|
-
nil
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# [TODO] Support ClipboardText
|
41
|
-
# g_ClipboardTextData
|
42
|
-
# ImplSDL2_GetClipboardText
|
43
|
-
# ImplSDL2_SetClipboardText
|
44
|
-
|
45
|
-
# [INTERNAL]
|
46
|
-
def self.ImGui_ImplSDL2_GetClipboardText(user_data)
|
47
|
-
bd = ImGui_ImplSDL2_GetBackendData()
|
48
|
-
SDL.free(bd.clipboardTextData) if bd.clipboardTextData
|
49
|
-
bd.clipboardTextData = SDL.GetClipboardText()
|
50
|
-
return bd.clipboardTextData
|
51
|
-
end
|
52
|
-
|
53
|
-
# [INTERNAL]
|
54
|
-
def self.ImGui_ImplSDL2_SetClipboardText(user_data, text)
|
55
|
-
SDL.SetClipboardText(text)
|
56
|
-
end
|
57
|
-
|
58
|
-
# [INTERNAL]
|
59
|
-
def self.ImGui_ImplSDL2_KeyToImGuiKey(key)
|
60
|
-
case key
|
61
|
-
when SDL::SDLK_TAB then ImGuiKey_Tab
|
62
|
-
when SDL::SDLK_LEFT then ImGuiKey_LeftArrow
|
63
|
-
when SDL::SDLK_RIGHT then ImGuiKey_RightArrow
|
64
|
-
when SDL::SDLK_UP then ImGuiKey_UpArrow
|
65
|
-
when SDL::SDLK_DOWN then ImGuiKey_DownArrow
|
66
|
-
when SDL::SDLK_PAGEUP then ImGuiKey_PageUp
|
67
|
-
when SDL::SDLK_PAGEDOWN then ImGuiKey_PageDown
|
68
|
-
when SDL::SDLK_HOME then ImGuiKey_Home
|
69
|
-
when SDL::SDLK_END then ImGuiKey_End
|
70
|
-
when SDL::SDLK_INSERT then ImGuiKey_Insert
|
71
|
-
when SDL::SDLK_DELETE then ImGuiKey_Delete
|
72
|
-
when SDL::SDLK_BACKSPACE then ImGuiKey_Backspace
|
73
|
-
when SDL::SDLK_SPACE then ImGuiKey_Space
|
74
|
-
when SDL::SDLK_RETURN then ImGuiKey_Enter
|
75
|
-
when SDL::SDLK_ESCAPE then ImGuiKey_Escape
|
76
|
-
when SDL::SDLK_QUOTE then ImGuiKey_Apostrophe
|
77
|
-
when SDL::SDLK_COMMA then ImGuiKey_Comma
|
78
|
-
when SDL::SDLK_MINUS then ImGuiKey_Minus
|
79
|
-
when SDL::SDLK_PERIOD then ImGuiKey_Period
|
80
|
-
when SDL::SDLK_SLASH then ImGuiKey_Slash
|
81
|
-
when SDL::SDLK_SEMICOLON then ImGuiKey_Semicolon
|
82
|
-
when SDL::SDLK_EQUALS then ImGuiKey_Equal
|
83
|
-
when SDL::SDLK_LEFTBRACKET then ImGuiKey_LeftBracket
|
84
|
-
when SDL::SDLK_BACKSLASH then ImGuiKey_Backslash
|
85
|
-
when SDL::SDLK_RIGHTBRACKET then ImGuiKey_RightBracket
|
86
|
-
when SDL::SDLK_BACKQUOTE then ImGuiKey_GraveAccent
|
87
|
-
when SDL::SDLK_CAPSLOCK then ImGuiKey_CapsLock
|
88
|
-
when SDL::SDLK_SCROLLLOCK then ImGuiKey_ScrollLock
|
89
|
-
when SDL::SDLK_NUMLOCKCLEAR then ImGuiKey_NumLock
|
90
|
-
when SDL::SDLK_PRINTSCREEN then ImGuiKey_PrintScreen
|
91
|
-
when SDL::SDLK_PAUSE then ImGuiKey_Pause
|
92
|
-
when SDL::SDLK_KP_0 then ImGuiKey_Keypad0
|
93
|
-
when SDL::SDLK_KP_1 then ImGuiKey_Keypad1
|
94
|
-
when SDL::SDLK_KP_2 then ImGuiKey_Keypad2
|
95
|
-
when SDL::SDLK_KP_3 then ImGuiKey_Keypad3
|
96
|
-
when SDL::SDLK_KP_4 then ImGuiKey_Keypad4
|
97
|
-
when SDL::SDLK_KP_5 then ImGuiKey_Keypad5
|
98
|
-
when SDL::SDLK_KP_6 then ImGuiKey_Keypad6
|
99
|
-
when SDL::SDLK_KP_7 then ImGuiKey_Keypad7
|
100
|
-
when SDL::SDLK_KP_8 then ImGuiKey_Keypad8
|
101
|
-
when SDL::SDLK_KP_9 then ImGuiKey_Keypad9
|
102
|
-
when SDL::SDLK_KP_PERIOD then ImGuiKey_KeypadDecimal
|
103
|
-
when SDL::SDLK_KP_DIVIDE then ImGuiKey_KeypadDivide
|
104
|
-
when SDL::SDLK_KP_MULTIPLY then ImGuiKey_KeypadMultiply
|
105
|
-
when SDL::SDLK_KP_MINUS then ImGuiKey_KeypadSubtract
|
106
|
-
when SDL::SDLK_KP_PLUS then ImGuiKey_KeypadAdd
|
107
|
-
when SDL::SDLK_KP_ENTER then ImGuiKey_KeypadEnter
|
108
|
-
when SDL::SDLK_KP_EQUALS then ImGuiKey_KeypadEqual
|
109
|
-
when SDL::SDLK_LCTRL then ImGuiKey_LeftCtrl
|
110
|
-
when SDL::SDLK_LSHIFT then ImGuiKey_LeftShift
|
111
|
-
when SDL::SDLK_LALT then ImGuiKey_LeftAlt
|
112
|
-
when SDL::SDLK_LGUI then ImGuiKey_LeftSuper
|
113
|
-
when SDL::SDLK_RCTRL then ImGuiKey_RightCtrl
|
114
|
-
when SDL::SDLK_RSHIFT then ImGuiKey_RightShift
|
115
|
-
when SDL::SDLK_RALT then ImGuiKey_RightAlt
|
116
|
-
when SDL::SDLK_RGUI then ImGuiKey_RightSuper
|
117
|
-
when SDL::SDLK_APPLICATION then ImGuiKey_Menu
|
118
|
-
when SDL::SDLK_0 then ImGuiKey_0
|
119
|
-
when SDL::SDLK_1 then ImGuiKey_1
|
120
|
-
when SDL::SDLK_2 then ImGuiKey_2
|
121
|
-
when SDL::SDLK_3 then ImGuiKey_3
|
122
|
-
when SDL::SDLK_4 then ImGuiKey_4
|
123
|
-
when SDL::SDLK_5 then ImGuiKey_5
|
124
|
-
when SDL::SDLK_6 then ImGuiKey_6
|
125
|
-
when SDL::SDLK_7 then ImGuiKey_7
|
126
|
-
when SDL::SDLK_8 then ImGuiKey_8
|
127
|
-
when SDL::SDLK_9 then ImGuiKey_9
|
128
|
-
when SDL::SDLK_a then ImGuiKey_A
|
129
|
-
when SDL::SDLK_b then ImGuiKey_B
|
130
|
-
when SDL::SDLK_c then ImGuiKey_C
|
131
|
-
when SDL::SDLK_d then ImGuiKey_D
|
132
|
-
when SDL::SDLK_e then ImGuiKey_E
|
133
|
-
when SDL::SDLK_f then ImGuiKey_F
|
134
|
-
when SDL::SDLK_g then ImGuiKey_G
|
135
|
-
when SDL::SDLK_h then ImGuiKey_H
|
136
|
-
when SDL::SDLK_i then ImGuiKey_I
|
137
|
-
when SDL::SDLK_j then ImGuiKey_J
|
138
|
-
when SDL::SDLK_k then ImGuiKey_K
|
139
|
-
when SDL::SDLK_l then ImGuiKey_L
|
140
|
-
when SDL::SDLK_m then ImGuiKey_M
|
141
|
-
when SDL::SDLK_n then ImGuiKey_N
|
142
|
-
when SDL::SDLK_o then ImGuiKey_O
|
143
|
-
when SDL::SDLK_p then ImGuiKey_P
|
144
|
-
when SDL::SDLK_q then ImGuiKey_Q
|
145
|
-
when SDL::SDLK_r then ImGuiKey_R
|
146
|
-
when SDL::SDLK_s then ImGuiKey_S
|
147
|
-
when SDL::SDLK_t then ImGuiKey_T
|
148
|
-
when SDL::SDLK_u then ImGuiKey_U
|
149
|
-
when SDL::SDLK_v then ImGuiKey_V
|
150
|
-
when SDL::SDLK_w then ImGuiKey_W
|
151
|
-
when SDL::SDLK_x then ImGuiKey_X
|
152
|
-
when SDL::SDLK_y then ImGuiKey_Y
|
153
|
-
when SDL::SDLK_z then ImGuiKey_Z
|
154
|
-
when SDL::SDLK_F1 then ImGuiKey_F1
|
155
|
-
when SDL::SDLK_F2 then ImGuiKey_F2
|
156
|
-
when SDL::SDLK_F3 then ImGuiKey_F3
|
157
|
-
when SDL::SDLK_F4 then ImGuiKey_F4
|
158
|
-
when SDL::SDLK_F5 then ImGuiKey_F5
|
159
|
-
when SDL::SDLK_F6 then ImGuiKey_F6
|
160
|
-
when SDL::SDLK_F7 then ImGuiKey_F7
|
161
|
-
when SDL::SDLK_F8 then ImGuiKey_F8
|
162
|
-
when SDL::SDLK_F9 then ImGuiKey_F9
|
163
|
-
when SDL::SDLK_F10 then ImGuiKey_F10
|
164
|
-
when SDL::SDLK_F11 then ImGuiKey_F11
|
165
|
-
when SDL::SDLK_F12 then ImGuiKey_F12
|
166
|
-
else ImGuiKey_None
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
# [INTERNAL]
|
171
|
-
def self.ImGui_ImplSDL2_UpdateKeyModifiers(sdl_key_mods)
|
172
|
-
io = ImGuiIO.new(ImGui::GetIO())
|
173
|
-
io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & SDL::KMOD_CTRL) != 0)
|
174
|
-
io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & SDL::KMOD_SHIFT) != 0)
|
175
|
-
io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & SDL::KMOD_ALT) != 0)
|
176
|
-
io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & SDL::KMOD_GUI) != 0)
|
177
|
-
end
|
178
|
-
|
179
|
-
# You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
180
|
-
# - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
181
|
-
# - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
182
|
-
# Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
183
|
-
# 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.
|
184
|
-
def self.ImplSDL2_ProcessEvent(event)
|
185
|
-
io = ImGuiIO.new(ImGui::GetIO())
|
186
|
-
bd = ImGui_ImplSDL2_GetBackendData()
|
187
|
-
|
188
|
-
case event[:type]
|
189
|
-
|
190
|
-
when SDL::MOUSEMOTION
|
191
|
-
io.AddMousePosEvent(event[:motion][:x].to_f, event[:motion][:y].to_f)
|
192
|
-
return true
|
193
|
-
|
194
|
-
when SDL::MOUSEWHEEL
|
195
|
-
wheel_x = (event[:wheel][:x] > 0) ? 1.0 : (event[:wheel][:x] < 0) ? -1.0 : 0.0
|
196
|
-
wheel_y = (event[:wheel][:y] > 0) ? 1.0 : (event[:wheel][:y] < 0) ? -1.0 : 0.0
|
197
|
-
io.AddMouseWheelEvent(wheel_x, wheel_y)
|
198
|
-
return true
|
199
|
-
|
200
|
-
when SDL::MOUSEBUTTONDOWN, SDL::MOUSEBUTTONUP
|
201
|
-
mouse_button = -1
|
202
|
-
mouse_button = 0 if event[:button][:button] == SDL::BUTTON_LEFT
|
203
|
-
mouse_button = 1 if event[:button][:button] == SDL::BUTTON_RIGHT
|
204
|
-
mouse_button = 2 if event[:button][:button] == SDL::BUTTON_MIDDLE
|
205
|
-
if mouse_button != -1
|
206
|
-
io.AddMouseButtonEvent(mouse_button, event[:type] == SDL::MOUSEBUTTONDOWN)
|
207
|
-
bd.mouseButtonsDown = (event[:type] == SDL::MOUSEBUTTONDOWN) ? (bd.mouseButtonsDown | (1 << mouse_button)) : (bd.mouseButtonsDown & ~(1 << mouse_button))
|
208
|
-
return true
|
209
|
-
end
|
210
|
-
|
211
|
-
when SDL::TEXTINPUT
|
212
|
-
io.AddInputCharactersUTF8(event[:text][:text])
|
213
|
-
return true
|
214
|
-
|
215
|
-
when SDL::KEYDOWN, SDL::KEYUP
|
216
|
-
ImGui_ImplSDL2_UpdateKeyModifiers(event[:key][:keysym][:mod])
|
217
|
-
key = ImGui_ImplSDL2_KeyToImGuiKey(event[:key][:keysym][:sym])
|
218
|
-
io.AddKeyEvent(key, (event[:type] == SDL::KEYDOWN))
|
219
|
-
io.SetKeyEventNativeData(key, event[:key][:keysym][:sym], event[:key][:keysym][:scancode], event[:key][:keysym][:scancode]) # To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
220
|
-
return true
|
221
|
-
|
222
|
-
when SDL::WINDOWEVENT
|
223
|
-
io.AddMousePosEvent(-Float::MAX, -Float::MAX) if event[:window][:event] == SDL::WINDOWEVENT_LEAVE
|
224
|
-
|
225
|
-
if event[:window][:event] == SDL::WINDOWEVENT_FOCUS_GAINED
|
226
|
-
io.AddFocusEvent(true)
|
227
|
-
elsif event[:window][:event] == SDL::WINDOWEVENT_FOCUS_LOST
|
228
|
-
io.AddFocusEvent(false)
|
229
|
-
end
|
230
|
-
return true
|
231
|
-
|
232
|
-
end
|
233
|
-
|
234
|
-
return false
|
235
|
-
end
|
236
|
-
|
237
|
-
def self.ImplSDL2_Init(window, renderer)
|
238
|
-
|
239
|
-
# Check and store if we are on a SDL backend that supports global mouse position
|
240
|
-
# ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
|
241
|
-
mouse_can_use_global_state = false
|
242
|
-
sdl_backend = SDL.GetCurrentVideoDriver().read_string
|
243
|
-
global_mouse_whitelist = ["windows", "cocoa", "x11", "DIVE", "VMAN"]
|
244
|
-
global_mouse_whitelist.each do |platform|
|
245
|
-
mouse_can_use_global_state = true if sdl_backend == platform
|
246
|
-
end
|
247
|
-
|
248
|
-
# Setup backend capabilities flags
|
249
|
-
bd = ImGui_ImplSDL2_Data.new
|
250
|
-
@@g_BackendData[ImGui::GetCurrentContext().address] = bd
|
251
|
-
|
252
|
-
io = ImGuiIO.new(ImGui::GetIO())
|
253
|
-
io[:BackendPlatformName] = @@g_BackendPlatformName
|
254
|
-
io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional)
|
255
|
-
io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used)
|
256
|
-
|
257
|
-
bd.window = window
|
258
|
-
bd.renderer = renderer
|
259
|
-
bd.mouseCanUseGlobalState = mouse_can_use_global_state
|
260
|
-
|
261
|
-
# [TODO] Support ClipboardText : pass callbacks as Proc or something
|
262
|
-
# io[:SetClipboardTextFn] = ImGui_ImplSDL2_SetClipboardText
|
263
|
-
# io[:GetClipboardTextFn] = ImGui_ImplSDL2_GetClipboardText
|
264
|
-
io[:ClipboardUserData] = nil
|
265
|
-
|
266
|
-
# Load mouse cursors
|
267
|
-
bd.mouseCursors[ImGuiMouseCursor_Arrow] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_ARROW)
|
268
|
-
bd.mouseCursors[ImGuiMouseCursor_TextInput] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_IBEAM)
|
269
|
-
bd.mouseCursors[ImGuiMouseCursor_ResizeAll] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZEALL)
|
270
|
-
bd.mouseCursors[ImGuiMouseCursor_ResizeNS] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENS)
|
271
|
-
bd.mouseCursors[ImGuiMouseCursor_ResizeEW] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZEWE)
|
272
|
-
bd.mouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENESW)
|
273
|
-
bd.mouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENWSE)
|
274
|
-
bd.mouseCursors[ImGuiMouseCursor_Hand] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_HAND)
|
275
|
-
bd.mouseCursors[ImGuiMouseCursor_NotAllowed] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_NO)
|
276
|
-
|
277
|
-
# Set platform dependent data in viewport
|
278
|
-
case RbConfig::CONFIG['host_os']
|
279
|
-
when /mswin|msys|mingw|cygwin/
|
280
|
-
info = SDL::SysWMinfo_win.new
|
281
|
-
SDL.GetVersion(info[:version])
|
282
|
-
if SDL.GetWindowWMInfo(window, info) == SDL::TRUE
|
283
|
-
viewport = ImGuiViewport.new(ImGui::GetMainViewport())
|
284
|
-
viewport[:PlatformHandleRaw] = info[:info][:win][:window]
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
# Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
|
289
|
-
# Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
|
290
|
-
# (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
|
291
|
-
# It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
|
292
|
-
# you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED)
|
293
|
-
if defined?(SDL::HINT_MOUSE_FOCUS_CLICKTHROUGH)
|
294
|
-
SDL.SetHint(SDL::HINT_MOUSE_FOCUS_CLICKTHROUGH, "1")
|
295
|
-
end
|
296
|
-
|
297
|
-
return true
|
298
|
-
end
|
299
|
-
|
300
|
-
def self.ImplSDL2_Shutdown()
|
301
|
-
io = ImGuiIO.new(ImGui::GetIO())
|
302
|
-
bd = ImGui_ImplSDL2_GetBackendData()
|
303
|
-
|
304
|
-
SDL.free(bd.clipboardTextData) if bd.clipboardTextData
|
305
|
-
|
306
|
-
ImGuiMouseCursor_COUNT.times do |cursor_n|
|
307
|
-
SDL.FreeCursor(bd.mouseCursors[cursor_n])
|
308
|
-
bd.mouseCursors[cursor_n] = nil
|
309
|
-
end
|
310
|
-
|
311
|
-
io[:BackendPlatformName] = nil
|
312
|
-
io[:BackendPlatformUserData] = nil
|
313
|
-
@@g_BackendData[ImGui::GetCurrentContext()] = nil
|
314
|
-
end
|
315
|
-
|
316
|
-
# [INTERNAL]
|
317
|
-
def self.ImplSDL2_UpdateMouseData()
|
318
|
-
bd = ImGui_ImplSDL2_GetBackendData()
|
319
|
-
io = ImGuiIO.new(ImGui::GetIO())
|
320
|
-
|
321
|
-
SDL.CaptureMouse(bd.mouseButtonsDown != 0 ? SDL::TRUE : SDL::FALSE)
|
322
|
-
focused_window = SDL.GetKeyboardFocus()
|
323
|
-
is_app_focused = (bd.window == focused_window)
|
324
|
-
if is_app_focused
|
325
|
-
# (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
326
|
-
if io[:WantSetMousePos]
|
327
|
-
SDL.WarpMouseInWindow(bd.window, io[:MousePos][:x].to_i, io[:MousePos][:y].to_i)
|
328
|
-
end
|
329
|
-
|
330
|
-
# (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
331
|
-
if bd.mouseCanUseGlobalState && bd.mouseButtonsDown == 0
|
332
|
-
wx = FFI::MemoryPointer.new(:int)
|
333
|
-
wy = FFI::MemoryPointer.new(:int)
|
334
|
-
mx = FFI::MemoryPointer.new(:int)
|
335
|
-
my = FFI::MemoryPointer.new(:int)
|
336
|
-
SDL.GetGlobalMouseState(mx, my)
|
337
|
-
SDL.GetWindowPosition(bd.window, wx, wy)
|
338
|
-
io.AddMousePosEvent(mx.read(:int).to_f - wx.read(:int).to_f, my.read(:int).to_f - wy.read(:int).to_f)
|
339
|
-
end
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
# [INTERNAL]
|
344
|
-
def self.ImplSDL2_UpdateMouseCursor()
|
345
|
-
io = ImGuiIO.new(ImGui::GetIO())
|
346
|
-
return if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange)
|
347
|
-
bd = ImGui_ImplSDL2_GetBackendData()
|
348
|
-
|
349
|
-
imgui_cursor = ImGui::GetMouseCursor()
|
350
|
-
if io[:MouseDrawCursor] || imgui_cursor == ImGuiMouseCursor_None
|
351
|
-
# Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
352
|
-
SDL.ShowCursor(SDL::FALSE)
|
353
|
-
else
|
354
|
-
# Show OS mouse cursor
|
355
|
-
SDL.SetCursor(bd.mouseCursors[imgui_cursor] ? bd.mouseCursors[imgui_cursor] : bd.mouseCursors[ImGuiMouseCursor_Arrow])
|
356
|
-
SDL.ShowCursor(SDL::TRUE)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
#
|
361
|
-
# [TODO] Support ImplSDL2_UpdateGamepads
|
362
|
-
#
|
363
|
-
|
364
|
-
def self.ImplSDL2_NewFrame()
|
365
|
-
bd = ImGui_ImplSDL2_GetBackendData()
|
366
|
-
io = ImGuiIO.new(ImGui::GetIO())
|
367
|
-
|
368
|
-
# Setup display size (every frame to accommodate for window resizing)
|
369
|
-
w = ' ' * 4
|
370
|
-
h = ' ' * 4
|
371
|
-
display_w = ' ' * 4
|
372
|
-
display_h = ' ' * 4
|
373
|
-
SDL.GetWindowSize(bd.window, w, h)
|
374
|
-
w = w.unpack1('L')
|
375
|
-
h = h.unpack1('L')
|
376
|
-
|
377
|
-
if (SDL.GetWindowFlags(bd.window) & SDL::WINDOW_MINIMIZED) != 0
|
378
|
-
w = h = 0
|
379
|
-
end
|
380
|
-
if bd.renderer != nil
|
381
|
-
SDL.GetRendererOutputSize(bd.renderer, display_w, display_h)
|
382
|
-
else
|
383
|
-
SDL.GL_GetDrawableSize(bd.window, display_w, display_h)
|
384
|
-
end
|
385
|
-
display_w = display_w.unpack1('L')
|
386
|
-
display_h = display_h.unpack1('L')
|
387
|
-
|
388
|
-
io[:DisplaySize] = ImVec2.create(w.to_f, h.to_f)
|
389
|
-
|
390
|
-
if w > 0 && h > 0
|
391
|
-
io[:DisplayFramebufferScale][:x] = display_w.to_f / w
|
392
|
-
io[:DisplayFramebufferScale][:y] = display_h.to_f / h
|
393
|
-
end
|
394
|
-
|
395
|
-
# Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
396
|
-
frequency = SDL.GetPerformanceFrequency()
|
397
|
-
current_time = SDL.GetPerformanceCounter()
|
398
|
-
|
399
|
-
io[:DeltaTime] = bd.time > 0 ? ((current_time - bd.time).to_f / frequency) : (1.0/60.0)
|
400
|
-
bd.time = current_time
|
401
|
-
|
402
|
-
ImplSDL2_UpdateMouseData()
|
403
|
-
ImplSDL2_UpdateMouseCursor()
|
404
|
-
|
405
|
-
# [TODO] update gamepads
|
406
|
-
# ImGui_ImplSDL2_UpdateGamepads()
|
407
|
-
end
|
408
|
-
|
409
|
-
end
|
1
|
+
require 'ffi'
|
2
|
+
require 'sdl2'
|
3
|
+
require_relative 'imgui'
|
4
|
+
|
5
|
+
module ImGui
|
6
|
+
|
7
|
+
@@g_BackendPlatformName = FFI::MemoryPointer.from_string("imgui_impl_sdl")
|
8
|
+
|
9
|
+
# ImGui::GetCurrentContext().address => ImGui_ImplSDL2_Data
|
10
|
+
@@g_BackendData = Hash.new
|
11
|
+
|
12
|
+
# [INTERNAL]
|
13
|
+
class ImGui_ImplSDL2_Data
|
14
|
+
attr_accessor :window, :renderer, :time, :mouseButtonsDown, :mouseCursors, :clipboardTextData, :mouseCanUseGlobalState
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@window = nil # SDL_Window*
|
18
|
+
@renderer = nil # SDL_Renderer*
|
19
|
+
@time = 0.0 # Uint64
|
20
|
+
@mouseButtonsDown = 0 # int
|
21
|
+
@mouseCursors = Array.new(ImGuiMouseCursor_COUNT) { 0 } # SDL_Cursor*
|
22
|
+
@clipboardTextData = nil # char*
|
23
|
+
@mouseCanUseGlobalState = false # bool
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
28
|
+
# It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
29
|
+
# FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
|
30
|
+
# FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
31
|
+
# [INTERNAL]
|
32
|
+
def self.ImGui_ImplSDL2_GetBackendData()
|
33
|
+
if ImGui::GetCurrentContext() != nil
|
34
|
+
@@g_BackendData[ImGui::GetCurrentContext().address]
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# [TODO] Support ClipboardText
|
41
|
+
# g_ClipboardTextData
|
42
|
+
# ImplSDL2_GetClipboardText
|
43
|
+
# ImplSDL2_SetClipboardText
|
44
|
+
|
45
|
+
# [INTERNAL]
|
46
|
+
def self.ImGui_ImplSDL2_GetClipboardText(user_data)
|
47
|
+
bd = ImGui_ImplSDL2_GetBackendData()
|
48
|
+
SDL.free(bd.clipboardTextData) if bd.clipboardTextData
|
49
|
+
bd.clipboardTextData = SDL.GetClipboardText()
|
50
|
+
return bd.clipboardTextData
|
51
|
+
end
|
52
|
+
|
53
|
+
# [INTERNAL]
|
54
|
+
def self.ImGui_ImplSDL2_SetClipboardText(user_data, text)
|
55
|
+
SDL.SetClipboardText(text)
|
56
|
+
end
|
57
|
+
|
58
|
+
# [INTERNAL]
|
59
|
+
def self.ImGui_ImplSDL2_KeyToImGuiKey(key)
|
60
|
+
case key
|
61
|
+
when SDL::SDLK_TAB then ImGuiKey_Tab
|
62
|
+
when SDL::SDLK_LEFT then ImGuiKey_LeftArrow
|
63
|
+
when SDL::SDLK_RIGHT then ImGuiKey_RightArrow
|
64
|
+
when SDL::SDLK_UP then ImGuiKey_UpArrow
|
65
|
+
when SDL::SDLK_DOWN then ImGuiKey_DownArrow
|
66
|
+
when SDL::SDLK_PAGEUP then ImGuiKey_PageUp
|
67
|
+
when SDL::SDLK_PAGEDOWN then ImGuiKey_PageDown
|
68
|
+
when SDL::SDLK_HOME then ImGuiKey_Home
|
69
|
+
when SDL::SDLK_END then ImGuiKey_End
|
70
|
+
when SDL::SDLK_INSERT then ImGuiKey_Insert
|
71
|
+
when SDL::SDLK_DELETE then ImGuiKey_Delete
|
72
|
+
when SDL::SDLK_BACKSPACE then ImGuiKey_Backspace
|
73
|
+
when SDL::SDLK_SPACE then ImGuiKey_Space
|
74
|
+
when SDL::SDLK_RETURN then ImGuiKey_Enter
|
75
|
+
when SDL::SDLK_ESCAPE then ImGuiKey_Escape
|
76
|
+
when SDL::SDLK_QUOTE then ImGuiKey_Apostrophe
|
77
|
+
when SDL::SDLK_COMMA then ImGuiKey_Comma
|
78
|
+
when SDL::SDLK_MINUS then ImGuiKey_Minus
|
79
|
+
when SDL::SDLK_PERIOD then ImGuiKey_Period
|
80
|
+
when SDL::SDLK_SLASH then ImGuiKey_Slash
|
81
|
+
when SDL::SDLK_SEMICOLON then ImGuiKey_Semicolon
|
82
|
+
when SDL::SDLK_EQUALS then ImGuiKey_Equal
|
83
|
+
when SDL::SDLK_LEFTBRACKET then ImGuiKey_LeftBracket
|
84
|
+
when SDL::SDLK_BACKSLASH then ImGuiKey_Backslash
|
85
|
+
when SDL::SDLK_RIGHTBRACKET then ImGuiKey_RightBracket
|
86
|
+
when SDL::SDLK_BACKQUOTE then ImGuiKey_GraveAccent
|
87
|
+
when SDL::SDLK_CAPSLOCK then ImGuiKey_CapsLock
|
88
|
+
when SDL::SDLK_SCROLLLOCK then ImGuiKey_ScrollLock
|
89
|
+
when SDL::SDLK_NUMLOCKCLEAR then ImGuiKey_NumLock
|
90
|
+
when SDL::SDLK_PRINTSCREEN then ImGuiKey_PrintScreen
|
91
|
+
when SDL::SDLK_PAUSE then ImGuiKey_Pause
|
92
|
+
when SDL::SDLK_KP_0 then ImGuiKey_Keypad0
|
93
|
+
when SDL::SDLK_KP_1 then ImGuiKey_Keypad1
|
94
|
+
when SDL::SDLK_KP_2 then ImGuiKey_Keypad2
|
95
|
+
when SDL::SDLK_KP_3 then ImGuiKey_Keypad3
|
96
|
+
when SDL::SDLK_KP_4 then ImGuiKey_Keypad4
|
97
|
+
when SDL::SDLK_KP_5 then ImGuiKey_Keypad5
|
98
|
+
when SDL::SDLK_KP_6 then ImGuiKey_Keypad6
|
99
|
+
when SDL::SDLK_KP_7 then ImGuiKey_Keypad7
|
100
|
+
when SDL::SDLK_KP_8 then ImGuiKey_Keypad8
|
101
|
+
when SDL::SDLK_KP_9 then ImGuiKey_Keypad9
|
102
|
+
when SDL::SDLK_KP_PERIOD then ImGuiKey_KeypadDecimal
|
103
|
+
when SDL::SDLK_KP_DIVIDE then ImGuiKey_KeypadDivide
|
104
|
+
when SDL::SDLK_KP_MULTIPLY then ImGuiKey_KeypadMultiply
|
105
|
+
when SDL::SDLK_KP_MINUS then ImGuiKey_KeypadSubtract
|
106
|
+
when SDL::SDLK_KP_PLUS then ImGuiKey_KeypadAdd
|
107
|
+
when SDL::SDLK_KP_ENTER then ImGuiKey_KeypadEnter
|
108
|
+
when SDL::SDLK_KP_EQUALS then ImGuiKey_KeypadEqual
|
109
|
+
when SDL::SDLK_LCTRL then ImGuiKey_LeftCtrl
|
110
|
+
when SDL::SDLK_LSHIFT then ImGuiKey_LeftShift
|
111
|
+
when SDL::SDLK_LALT then ImGuiKey_LeftAlt
|
112
|
+
when SDL::SDLK_LGUI then ImGuiKey_LeftSuper
|
113
|
+
when SDL::SDLK_RCTRL then ImGuiKey_RightCtrl
|
114
|
+
when SDL::SDLK_RSHIFT then ImGuiKey_RightShift
|
115
|
+
when SDL::SDLK_RALT then ImGuiKey_RightAlt
|
116
|
+
when SDL::SDLK_RGUI then ImGuiKey_RightSuper
|
117
|
+
when SDL::SDLK_APPLICATION then ImGuiKey_Menu
|
118
|
+
when SDL::SDLK_0 then ImGuiKey_0
|
119
|
+
when SDL::SDLK_1 then ImGuiKey_1
|
120
|
+
when SDL::SDLK_2 then ImGuiKey_2
|
121
|
+
when SDL::SDLK_3 then ImGuiKey_3
|
122
|
+
when SDL::SDLK_4 then ImGuiKey_4
|
123
|
+
when SDL::SDLK_5 then ImGuiKey_5
|
124
|
+
when SDL::SDLK_6 then ImGuiKey_6
|
125
|
+
when SDL::SDLK_7 then ImGuiKey_7
|
126
|
+
when SDL::SDLK_8 then ImGuiKey_8
|
127
|
+
when SDL::SDLK_9 then ImGuiKey_9
|
128
|
+
when SDL::SDLK_a then ImGuiKey_A
|
129
|
+
when SDL::SDLK_b then ImGuiKey_B
|
130
|
+
when SDL::SDLK_c then ImGuiKey_C
|
131
|
+
when SDL::SDLK_d then ImGuiKey_D
|
132
|
+
when SDL::SDLK_e then ImGuiKey_E
|
133
|
+
when SDL::SDLK_f then ImGuiKey_F
|
134
|
+
when SDL::SDLK_g then ImGuiKey_G
|
135
|
+
when SDL::SDLK_h then ImGuiKey_H
|
136
|
+
when SDL::SDLK_i then ImGuiKey_I
|
137
|
+
when SDL::SDLK_j then ImGuiKey_J
|
138
|
+
when SDL::SDLK_k then ImGuiKey_K
|
139
|
+
when SDL::SDLK_l then ImGuiKey_L
|
140
|
+
when SDL::SDLK_m then ImGuiKey_M
|
141
|
+
when SDL::SDLK_n then ImGuiKey_N
|
142
|
+
when SDL::SDLK_o then ImGuiKey_O
|
143
|
+
when SDL::SDLK_p then ImGuiKey_P
|
144
|
+
when SDL::SDLK_q then ImGuiKey_Q
|
145
|
+
when SDL::SDLK_r then ImGuiKey_R
|
146
|
+
when SDL::SDLK_s then ImGuiKey_S
|
147
|
+
when SDL::SDLK_t then ImGuiKey_T
|
148
|
+
when SDL::SDLK_u then ImGuiKey_U
|
149
|
+
when SDL::SDLK_v then ImGuiKey_V
|
150
|
+
when SDL::SDLK_w then ImGuiKey_W
|
151
|
+
when SDL::SDLK_x then ImGuiKey_X
|
152
|
+
when SDL::SDLK_y then ImGuiKey_Y
|
153
|
+
when SDL::SDLK_z then ImGuiKey_Z
|
154
|
+
when SDL::SDLK_F1 then ImGuiKey_F1
|
155
|
+
when SDL::SDLK_F2 then ImGuiKey_F2
|
156
|
+
when SDL::SDLK_F3 then ImGuiKey_F3
|
157
|
+
when SDL::SDLK_F4 then ImGuiKey_F4
|
158
|
+
when SDL::SDLK_F5 then ImGuiKey_F5
|
159
|
+
when SDL::SDLK_F6 then ImGuiKey_F6
|
160
|
+
when SDL::SDLK_F7 then ImGuiKey_F7
|
161
|
+
when SDL::SDLK_F8 then ImGuiKey_F8
|
162
|
+
when SDL::SDLK_F9 then ImGuiKey_F9
|
163
|
+
when SDL::SDLK_F10 then ImGuiKey_F10
|
164
|
+
when SDL::SDLK_F11 then ImGuiKey_F11
|
165
|
+
when SDL::SDLK_F12 then ImGuiKey_F12
|
166
|
+
else ImGuiKey_None
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# [INTERNAL]
|
171
|
+
def self.ImGui_ImplSDL2_UpdateKeyModifiers(sdl_key_mods)
|
172
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
173
|
+
io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & SDL::KMOD_CTRL) != 0)
|
174
|
+
io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & SDL::KMOD_SHIFT) != 0)
|
175
|
+
io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & SDL::KMOD_ALT) != 0)
|
176
|
+
io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & SDL::KMOD_GUI) != 0)
|
177
|
+
end
|
178
|
+
|
179
|
+
# You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
180
|
+
# - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
181
|
+
# - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
182
|
+
# Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
183
|
+
# 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.
|
184
|
+
def self.ImplSDL2_ProcessEvent(event)
|
185
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
186
|
+
bd = ImGui_ImplSDL2_GetBackendData()
|
187
|
+
|
188
|
+
case event[:type]
|
189
|
+
|
190
|
+
when SDL::MOUSEMOTION
|
191
|
+
io.AddMousePosEvent(event[:motion][:x].to_f, event[:motion][:y].to_f)
|
192
|
+
return true
|
193
|
+
|
194
|
+
when SDL::MOUSEWHEEL
|
195
|
+
wheel_x = (event[:wheel][:x] > 0) ? 1.0 : (event[:wheel][:x] < 0) ? -1.0 : 0.0
|
196
|
+
wheel_y = (event[:wheel][:y] > 0) ? 1.0 : (event[:wheel][:y] < 0) ? -1.0 : 0.0
|
197
|
+
io.AddMouseWheelEvent(wheel_x, wheel_y)
|
198
|
+
return true
|
199
|
+
|
200
|
+
when SDL::MOUSEBUTTONDOWN, SDL::MOUSEBUTTONUP
|
201
|
+
mouse_button = -1
|
202
|
+
mouse_button = 0 if event[:button][:button] == SDL::BUTTON_LEFT
|
203
|
+
mouse_button = 1 if event[:button][:button] == SDL::BUTTON_RIGHT
|
204
|
+
mouse_button = 2 if event[:button][:button] == SDL::BUTTON_MIDDLE
|
205
|
+
if mouse_button != -1
|
206
|
+
io.AddMouseButtonEvent(mouse_button, event[:type] == SDL::MOUSEBUTTONDOWN)
|
207
|
+
bd.mouseButtonsDown = (event[:type] == SDL::MOUSEBUTTONDOWN) ? (bd.mouseButtonsDown | (1 << mouse_button)) : (bd.mouseButtonsDown & ~(1 << mouse_button))
|
208
|
+
return true
|
209
|
+
end
|
210
|
+
|
211
|
+
when SDL::TEXTINPUT
|
212
|
+
io.AddInputCharactersUTF8(event[:text][:text])
|
213
|
+
return true
|
214
|
+
|
215
|
+
when SDL::KEYDOWN, SDL::KEYUP
|
216
|
+
ImGui_ImplSDL2_UpdateKeyModifiers(event[:key][:keysym][:mod])
|
217
|
+
key = ImGui_ImplSDL2_KeyToImGuiKey(event[:key][:keysym][:sym])
|
218
|
+
io.AddKeyEvent(key, (event[:type] == SDL::KEYDOWN))
|
219
|
+
io.SetKeyEventNativeData(key, event[:key][:keysym][:sym], event[:key][:keysym][:scancode], event[:key][:keysym][:scancode]) # To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
220
|
+
return true
|
221
|
+
|
222
|
+
when SDL::WINDOWEVENT
|
223
|
+
io.AddMousePosEvent(-Float::MAX, -Float::MAX) if event[:window][:event] == SDL::WINDOWEVENT_LEAVE
|
224
|
+
|
225
|
+
if event[:window][:event] == SDL::WINDOWEVENT_FOCUS_GAINED
|
226
|
+
io.AddFocusEvent(true)
|
227
|
+
elsif event[:window][:event] == SDL::WINDOWEVENT_FOCUS_LOST
|
228
|
+
io.AddFocusEvent(false)
|
229
|
+
end
|
230
|
+
return true
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
return false
|
235
|
+
end
|
236
|
+
|
237
|
+
def self.ImplSDL2_Init(window, renderer)
|
238
|
+
|
239
|
+
# Check and store if we are on a SDL backend that supports global mouse position
|
240
|
+
# ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
|
241
|
+
mouse_can_use_global_state = false
|
242
|
+
sdl_backend = SDL.GetCurrentVideoDriver().read_string
|
243
|
+
global_mouse_whitelist = ["windows", "cocoa", "x11", "DIVE", "VMAN"]
|
244
|
+
global_mouse_whitelist.each do |platform|
|
245
|
+
mouse_can_use_global_state = true if sdl_backend == platform
|
246
|
+
end
|
247
|
+
|
248
|
+
# Setup backend capabilities flags
|
249
|
+
bd = ImGui_ImplSDL2_Data.new
|
250
|
+
@@g_BackendData[ImGui::GetCurrentContext().address] = bd
|
251
|
+
|
252
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
253
|
+
io[:BackendPlatformName] = @@g_BackendPlatformName
|
254
|
+
io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional)
|
255
|
+
io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used)
|
256
|
+
|
257
|
+
bd.window = window
|
258
|
+
bd.renderer = renderer
|
259
|
+
bd.mouseCanUseGlobalState = mouse_can_use_global_state
|
260
|
+
|
261
|
+
# [TODO] Support ClipboardText : pass callbacks as Proc or something
|
262
|
+
# io[:SetClipboardTextFn] = ImGui_ImplSDL2_SetClipboardText
|
263
|
+
# io[:GetClipboardTextFn] = ImGui_ImplSDL2_GetClipboardText
|
264
|
+
io[:ClipboardUserData] = nil
|
265
|
+
|
266
|
+
# Load mouse cursors
|
267
|
+
bd.mouseCursors[ImGuiMouseCursor_Arrow] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_ARROW)
|
268
|
+
bd.mouseCursors[ImGuiMouseCursor_TextInput] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_IBEAM)
|
269
|
+
bd.mouseCursors[ImGuiMouseCursor_ResizeAll] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZEALL)
|
270
|
+
bd.mouseCursors[ImGuiMouseCursor_ResizeNS] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENS)
|
271
|
+
bd.mouseCursors[ImGuiMouseCursor_ResizeEW] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZEWE)
|
272
|
+
bd.mouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENESW)
|
273
|
+
bd.mouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENWSE)
|
274
|
+
bd.mouseCursors[ImGuiMouseCursor_Hand] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_HAND)
|
275
|
+
bd.mouseCursors[ImGuiMouseCursor_NotAllowed] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_NO)
|
276
|
+
|
277
|
+
# Set platform dependent data in viewport
|
278
|
+
case RbConfig::CONFIG['host_os']
|
279
|
+
when /mswin|msys|mingw|cygwin/
|
280
|
+
info = SDL::SysWMinfo_win.new
|
281
|
+
SDL.GetVersion(info[:version])
|
282
|
+
if SDL.GetWindowWMInfo(window, info) == SDL::TRUE
|
283
|
+
viewport = ImGuiViewport.new(ImGui::GetMainViewport())
|
284
|
+
viewport[:PlatformHandleRaw] = info[:info][:win][:window]
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
# Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
|
289
|
+
# Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
|
290
|
+
# (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
|
291
|
+
# It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
|
292
|
+
# you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED)
|
293
|
+
if defined?(SDL::HINT_MOUSE_FOCUS_CLICKTHROUGH)
|
294
|
+
SDL.SetHint(SDL::HINT_MOUSE_FOCUS_CLICKTHROUGH, "1")
|
295
|
+
end
|
296
|
+
|
297
|
+
return true
|
298
|
+
end
|
299
|
+
|
300
|
+
def self.ImplSDL2_Shutdown()
|
301
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
302
|
+
bd = ImGui_ImplSDL2_GetBackendData()
|
303
|
+
|
304
|
+
SDL.free(bd.clipboardTextData) if bd.clipboardTextData
|
305
|
+
|
306
|
+
ImGuiMouseCursor_COUNT.times do |cursor_n|
|
307
|
+
SDL.FreeCursor(bd.mouseCursors[cursor_n])
|
308
|
+
bd.mouseCursors[cursor_n] = nil
|
309
|
+
end
|
310
|
+
|
311
|
+
io[:BackendPlatformName] = nil
|
312
|
+
io[:BackendPlatformUserData] = nil
|
313
|
+
@@g_BackendData[ImGui::GetCurrentContext()] = nil
|
314
|
+
end
|
315
|
+
|
316
|
+
# [INTERNAL]
|
317
|
+
def self.ImplSDL2_UpdateMouseData()
|
318
|
+
bd = ImGui_ImplSDL2_GetBackendData()
|
319
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
320
|
+
|
321
|
+
SDL.CaptureMouse(bd.mouseButtonsDown != 0 ? SDL::TRUE : SDL::FALSE)
|
322
|
+
focused_window = SDL.GetKeyboardFocus()
|
323
|
+
is_app_focused = (bd.window == focused_window)
|
324
|
+
if is_app_focused
|
325
|
+
# (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
326
|
+
if io[:WantSetMousePos]
|
327
|
+
SDL.WarpMouseInWindow(bd.window, io[:MousePos][:x].to_i, io[:MousePos][:y].to_i)
|
328
|
+
end
|
329
|
+
|
330
|
+
# (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
331
|
+
if bd.mouseCanUseGlobalState && bd.mouseButtonsDown == 0
|
332
|
+
wx = FFI::MemoryPointer.new(:int)
|
333
|
+
wy = FFI::MemoryPointer.new(:int)
|
334
|
+
mx = FFI::MemoryPointer.new(:int)
|
335
|
+
my = FFI::MemoryPointer.new(:int)
|
336
|
+
SDL.GetGlobalMouseState(mx, my)
|
337
|
+
SDL.GetWindowPosition(bd.window, wx, wy)
|
338
|
+
io.AddMousePosEvent(mx.read(:int).to_f - wx.read(:int).to_f, my.read(:int).to_f - wy.read(:int).to_f)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
# [INTERNAL]
|
344
|
+
def self.ImplSDL2_UpdateMouseCursor()
|
345
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
346
|
+
return if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange)
|
347
|
+
bd = ImGui_ImplSDL2_GetBackendData()
|
348
|
+
|
349
|
+
imgui_cursor = ImGui::GetMouseCursor()
|
350
|
+
if io[:MouseDrawCursor] || imgui_cursor == ImGuiMouseCursor_None
|
351
|
+
# Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
352
|
+
SDL.ShowCursor(SDL::FALSE)
|
353
|
+
else
|
354
|
+
# Show OS mouse cursor
|
355
|
+
SDL.SetCursor(bd.mouseCursors[imgui_cursor] ? bd.mouseCursors[imgui_cursor] : bd.mouseCursors[ImGuiMouseCursor_Arrow])
|
356
|
+
SDL.ShowCursor(SDL::TRUE)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
#
|
361
|
+
# [TODO] Support ImplSDL2_UpdateGamepads
|
362
|
+
#
|
363
|
+
|
364
|
+
def self.ImplSDL2_NewFrame()
|
365
|
+
bd = ImGui_ImplSDL2_GetBackendData()
|
366
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
367
|
+
|
368
|
+
# Setup display size (every frame to accommodate for window resizing)
|
369
|
+
w = ' ' * 4
|
370
|
+
h = ' ' * 4
|
371
|
+
display_w = ' ' * 4
|
372
|
+
display_h = ' ' * 4
|
373
|
+
SDL.GetWindowSize(bd.window, w, h)
|
374
|
+
w = w.unpack1('L')
|
375
|
+
h = h.unpack1('L')
|
376
|
+
|
377
|
+
if (SDL.GetWindowFlags(bd.window) & SDL::WINDOW_MINIMIZED) != 0
|
378
|
+
w = h = 0
|
379
|
+
end
|
380
|
+
if bd.renderer != nil
|
381
|
+
SDL.GetRendererOutputSize(bd.renderer, display_w, display_h)
|
382
|
+
else
|
383
|
+
SDL.GL_GetDrawableSize(bd.window, display_w, display_h)
|
384
|
+
end
|
385
|
+
display_w = display_w.unpack1('L')
|
386
|
+
display_h = display_h.unpack1('L')
|
387
|
+
|
388
|
+
io[:DisplaySize] = ImVec2.create(w.to_f, h.to_f)
|
389
|
+
|
390
|
+
if w > 0 && h > 0
|
391
|
+
io[:DisplayFramebufferScale][:x] = display_w.to_f / w
|
392
|
+
io[:DisplayFramebufferScale][:y] = display_h.to_f / h
|
393
|
+
end
|
394
|
+
|
395
|
+
# Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
396
|
+
frequency = SDL.GetPerformanceFrequency()
|
397
|
+
current_time = SDL.GetPerformanceCounter()
|
398
|
+
|
399
|
+
io[:DeltaTime] = bd.time > 0 ? ((current_time - bd.time).to_f / frequency) : (1.0/60.0)
|
400
|
+
bd.time = current_time
|
401
|
+
|
402
|
+
ImplSDL2_UpdateMouseData()
|
403
|
+
ImplSDL2_UpdateMouseCursor()
|
404
|
+
|
405
|
+
# [TODO] update gamepads
|
406
|
+
# ImGui_ImplSDL2_UpdateGamepads()
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|