imgui-bindings 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +324 -311
- data/LICENSE.txt +0 -0
- data/README.md +117 -115
- data/lib/imgui.aarch64.so +0 -0
- data/lib/imgui.dll +0 -0
- data/lib/imgui.dylib +0 -0
- data/lib/imgui.rb +5076 -4789
- data/lib/imgui.x86_64.so +0 -0
- data/lib/imgui_impl_glfw.rb +511 -511
- data/lib/imgui_impl_opengl2.rb +212 -212
- 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.aarch64.so +0 -0
- data/lib/imnodes.dll +0 -0
- data/lib/imnodes.dylib +0 -0
- data/lib/imnodes.rb +161 -161
- data/lib/imnodes.x86_64.so +0 -0
- metadata +6 -2
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
|