imgui 1.0.0

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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +273 -0
  4. data/Rakefile +97 -0
  5. data/api/v1.json +53 -0
  6. data/ext/CMakeLists.txt +128 -0
  7. data/ext/Rakefile +31 -0
  8. data/ext/backend_function_bridge.cpp +180 -0
  9. data/ext/backend_function_bridge.h +40 -0
  10. data/ext/build_cimgui.rb +59 -0
  11. data/ext/extconf.rb +25 -0
  12. data/ext/glfw_vulkan_bridge.cpp +14 -0
  13. data/ext/imgui_ruby_build_config.h +17 -0
  14. data/ext/imgui_ruby_glfw.cpp +73 -0
  15. data/ext/imgui_ruby_sdl3.cpp +70 -0
  16. data/ext/imgui_ruby_wgpu.cpp +75 -0
  17. data/ext/install_cimgui.rb +25 -0
  18. data/ext/webgpu_function_bridge.cpp +245 -0
  19. data/generator/api_emitter.rb +164 -0
  20. data/generator/emitter.rb +317 -0
  21. data/generator/generate.rb +47 -0
  22. data/generator/native-dependencies.yml +88 -0
  23. data/generator/native_dependency_lock.rb +78 -0
  24. data/generator/native_dependency_snapshot.rb +159 -0
  25. data/generator/overrides.yml +11 -0
  26. data/generator/type_mapper.rb +112 -0
  27. data/generator/update_vendor.rb +30 -0
  28. data/lib/imgui/api.rb +88 -0
  29. data/lib/imgui/api_generated.rb +1633 -0
  30. data/lib/imgui/api_support.rb +144 -0
  31. data/lib/imgui/backends/glfw.rb +75 -0
  32. data/lib/imgui/backends/opengl3.rb +44 -0
  33. data/lib/imgui/backends/sdl3.rb +133 -0
  34. data/lib/imgui/backends/wgpu.rb +176 -0
  35. data/lib/imgui/backends.rb +60 -0
  36. data/lib/imgui/draw_data.rb +43 -0
  37. data/lib/imgui/dsl.rb +311 -0
  38. data/lib/imgui/dsl_support.rb +107 -0
  39. data/lib/imgui/easy_loop.rb +25 -0
  40. data/lib/imgui/errors.rb +11 -0
  41. data/lib/imgui/fonts.rb +46 -0
  42. data/lib/imgui/io.rb +91 -0
  43. data/lib/imgui/layout.rb +138 -0
  44. data/lib/imgui/memory_pool.rb +18 -0
  45. data/lib/imgui/native/enums.rb +2251 -0
  46. data/lib/imgui/native/functions.rb +1470 -0
  47. data/lib/imgui/native/structs.rb +1926 -0
  48. data/lib/imgui/native/typedefs.rb +93 -0
  49. data/lib/imgui/native.rb +130 -0
  50. data/lib/imgui/plot/api.rb +273 -0
  51. data/lib/imgui/plot/native/enums.rb +593 -0
  52. data/lib/imgui/plot/native/functions.rb +749 -0
  53. data/lib/imgui/plot/native/structs.rb +363 -0
  54. data/lib/imgui/plot/native/typedefs.rb +79 -0
  55. data/lib/imgui/plot.rb +13 -0
  56. data/lib/imgui/struct_value.rb +33 -0
  57. data/lib/imgui/style.rb +44 -0
  58. data/lib/imgui/value.rb +104 -0
  59. data/lib/imgui/version.rb +5 -0
  60. data/lib/imgui/widgets.rb +187 -0
  61. data/lib/imgui.rb +30 -0
  62. data/rakelib/platform_gem.rake +54 -0
  63. data/rakelib/source_gem.rake +75 -0
  64. metadata +129 -0
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated by `rake generate`. Do not edit it manually.
4
+
5
+
6
+ module ImGui
7
+ module Native
8
+ typedef :pointer, :ImBitArrayForNamedKeys
9
+ typedef :pointer, :ImBitArrayPtr
10
+ callback :ImDrawCallback, [:pointer, :pointer], :void
11
+ typedef :int, :ImDrawFlags
12
+ typedef :ushort, :ImDrawIdx
13
+ typedef :int, :ImDrawListFlags
14
+ typedef :pointer, :ImFileHandle
15
+ typedef :int, :ImFontAtlasFlags
16
+ typedef :int, :ImGuiActivateFlags
17
+ typedef :int, :ImGuiBackendFlags
18
+ typedef :int, :ImGuiButtonFlags
19
+ typedef :int, :ImGuiChildFlags
20
+ typedef :int, :ImGuiCol
21
+ typedef :int, :ImGuiColorEditFlags
22
+ typedef :int, :ImGuiComboFlags
23
+ typedef :int, :ImGuiCond
24
+ typedef :int, :ImGuiConfigFlags
25
+ callback :ImGuiContextHookCallback, [:pointer, :pointer], :void
26
+ typedef :int, :ImGuiDataAuthority
27
+ typedef :int, :ImGuiDataType
28
+ typedef :int, :ImGuiDebugLogFlags
29
+ typedef :int, :ImGuiDockNodeFlags
30
+ typedef :int, :ImGuiDragDropFlags
31
+ callback :ImGuiErrorCallback, [:pointer, :pointer, :string], :void
32
+ typedef :int, :ImGuiFocusRequestFlags
33
+ typedef :int, :ImGuiFocusedFlags
34
+ typedef :int, :ImGuiHoveredFlags
35
+ typedef :uint, :ImGuiID
36
+ typedef :int, :ImGuiInputFlags
37
+ callback :ImGuiInputTextCallback, [:pointer], :int
38
+ typedef :int, :ImGuiInputTextFlags
39
+ typedef :int, :ImGuiItemFlags
40
+ typedef :int, :ImGuiItemStatusFlags
41
+ typedef :int, :ImGuiKeyChord
42
+ typedef :pointer, :ImGuiKeyRoutingIndex
43
+ typedef :int, :ImGuiLayoutType
44
+ typedef :int, :ImGuiLogFlags
45
+ callback :ImGuiMemAllocFunc, [:size_t, :pointer], :pointer
46
+ callback :ImGuiMemFreeFunc, [:pointer, :pointer], :void
47
+ typedef :int, :ImGuiMouseButton
48
+ typedef :int, :ImGuiMouseCursor
49
+ typedef :int, :ImGuiMultiSelectFlags
50
+ typedef :int, :ImGuiNavMoveFlags
51
+ typedef :int, :ImGuiNavRenderCursorFlags
52
+ typedef :int, :ImGuiNextItemDataFlags
53
+ typedef :int, :ImGuiNextWindowDataFlags
54
+ typedef :int, :ImGuiOldColumnFlags
55
+ typedef :int, :ImGuiPopupFlags
56
+ typedef :int, :ImGuiScrollFlags
57
+ typedef :int, :ImGuiSelectableFlags
58
+ typedef :pointer, :ImGuiSelectionUserData
59
+ typedef :int, :ImGuiSeparatorFlags
60
+ callback :ImGuiSizeCallback, [:pointer], :void
61
+ typedef :int, :ImGuiSliderFlags
62
+ typedef :int, :ImGuiStyleVar
63
+ typedef :int, :ImGuiTabBarFlags
64
+ typedef :int, :ImGuiTabItemFlags
65
+ typedef :int, :ImGuiTableBgTarget
66
+ typedef :int, :ImGuiTableColumnFlags
67
+ typedef :pointer, :ImGuiTableColumnIdx
68
+ typedef :ushort, :ImGuiTableDrawChannelIdx
69
+ typedef :int, :ImGuiTableFlags
70
+ typedef :int, :ImGuiTableRowFlags
71
+ typedef :int, :ImGuiTextFlags
72
+ typedef :int, :ImGuiTooltipFlags
73
+ typedef :int, :ImGuiTreeNodeFlags
74
+ typedef :int, :ImGuiTypingSelectFlags
75
+ typedef :int, :ImGuiViewportFlags
76
+ typedef :int, :ImGuiWindowFlags
77
+ typedef :int, :ImGuiWindowRefreshFlags
78
+ typedef :int, :ImPoolIdx
79
+ typedef :pointer, :ImS16
80
+ typedef :pointer, :ImS32
81
+ typedef :pointer, :ImS64
82
+ typedef :char, :ImS8
83
+ typedef :pointer, :ImStbTexteditState
84
+ typedef :ulong_long, :ImTextureID
85
+ typedef :ushort, :ImU16
86
+ typedef :uint, :ImU32
87
+ typedef :ulong_long, :ImU64
88
+ typedef :uchar, :ImU8
89
+ typedef :ushort, :ImWchar
90
+ typedef :ushort, :ImWchar16
91
+ typedef :uint, :ImWchar32
92
+ end
93
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+
5
+ module ImGui
6
+ module Native
7
+ extend FFI::Library
8
+
9
+ LIBRARY_BASENAME = "cimgui_ruby"
10
+
11
+ class << self
12
+ alias ffi_attach_function attach_function
13
+
14
+ attr_reader :loaded_path
15
+
16
+ def attach_function(*signature)
17
+ ruby_name = signature.fetch(0)
18
+ function_signatures[ruby_name] = signature
19
+ registered_function_names << ruby_name unless registered_function_names.include?(ruby_name)
20
+ define_lazy_function(ruby_name)
21
+ end
22
+
23
+ def load!(path: nil)
24
+ return loaded_path if loaded?
25
+
26
+ failures = []
27
+ library_candidates(path).each do |candidate|
28
+ begin
29
+ ffi_lib candidate
30
+ @loaded_path = candidate
31
+ return loaded_path
32
+ rescue LoadError, FFI::NotFoundError => error
33
+ failures << "#{candidate}: #{error.message.lines.first&.strip}"
34
+ end
35
+ end
36
+
37
+ message = <<~MESSAGE
38
+ Unable to load #{library_filename}.
39
+ Set IMGUI_RUBY_LIB to the compiled library, install the platform-specific
40
+ imgui-ruby gem, or build the source gem with CMake and a C++17 compiler.
41
+ Tried:
42
+ #{failures.map { |failure| " - #{failure}" }.join("\n")}
43
+ MESSAGE
44
+ raise LibraryLoadError, message
45
+ end
46
+
47
+ def loaded?
48
+ !@loaded_path.nil?
49
+ end
50
+
51
+ def registered_functions
52
+ registered_function_names.dup.freeze
53
+ end
54
+
55
+ def bind_all!
56
+ load!
57
+ function_signatures.keys.each { |name| bind_function!(name) }
58
+ true
59
+ end
60
+
61
+ def library_candidates(explicit_path = nil)
62
+ requested = explicit_path || ENV["IMGUI_RUBY_LIB"]
63
+ candidates = []
64
+ candidates << File.expand_path(requested) if requested && !requested.empty?
65
+
66
+ candidates.concat(vendored_library_candidates)
67
+ candidates.concat([LIBRARY_BASENAME, "lib#{LIBRARY_BASENAME}"])
68
+ candidates.uniq
69
+ end
70
+
71
+ def library_filename
72
+ "lib#{LIBRARY_BASENAME}.#{FFI::Platform::LIBSUFFIX}"
73
+ end
74
+
75
+ private
76
+
77
+ def function_signatures
78
+ @function_signatures ||= {}
79
+ end
80
+
81
+ def registered_function_names
82
+ @registered_function_names ||= []
83
+ end
84
+
85
+ def define_lazy_function(ruby_name)
86
+ define_singleton_method(ruby_name) do |*arguments|
87
+ load!
88
+ bind_function!(ruby_name)
89
+ public_send(ruby_name, *arguments)
90
+ end
91
+ end
92
+
93
+ def bind_function!(ruby_name)
94
+ signature = function_signatures.fetch(ruby_name)
95
+ singleton_class.send(:remove_method, ruby_name)
96
+ ffi_attach_function(*signature)
97
+ function_signatures.delete(ruby_name)
98
+ rescue FFI::NotFoundError => error
99
+ define_lazy_function(ruby_name)
100
+ raise MissingSymbolError, "#{ruby_name} is not exported by #{loaded_path}: #{error.message}"
101
+ end
102
+
103
+ def vendored_library_candidates
104
+ vendor_root = File.expand_path("../../vendor", __dir__)
105
+ platforms = ["#{FFI::Platform::ARCH}-#{FFI::Platform::OS}"]
106
+ if FFI::Platform::ARCH == "aarch64"
107
+ platforms << "arm64-#{FFI::Platform::OS}"
108
+ end
109
+ filenames = [library_filename]
110
+ filenames << "#{LIBRARY_BASENAME}.dll" if FFI::Platform.windows?
111
+
112
+ vendor_roots = [vendor_root]
113
+ $LOAD_PATH.each do |load_path|
114
+ vendor_roots << File.join(load_path, "imgui", "vendor")
115
+ end
116
+
117
+ vendor_roots.uniq.flat_map do |root|
118
+ filenames.flat_map do |filename|
119
+ platforms.map { |platform| File.join(root, platform, filename) } + [File.join(root, filename)]
120
+ end
121
+ end.select { |candidate| File.file?(candidate) }
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ require_relative "native/typedefs"
128
+ require_relative "native/enums"
129
+ require_relative "native/structs"
130
+ require_relative "native/functions"
@@ -0,0 +1,273 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImPlot
4
+ class Error < ImGui::Error; end
5
+ class NoContextError < Error; end
6
+
7
+ class << self
8
+ def create_context
9
+ ImGui.__send__(:guard_context!)
10
+ context = ImGui::Native.ImPlot_CreateContext
11
+ raise Error, "cimplot returned a null context" if null_pointer?(context)
12
+
13
+ context
14
+ end
15
+
16
+ def destroy_context(context = nil)
17
+ context ||= current_context
18
+ return if context.nil?
19
+
20
+ ImGui.__send__(:guard_context!)
21
+ ImGui::Native.ImPlot_DestroyContext(context)
22
+ nil
23
+ end
24
+
25
+ def current_context
26
+ context = ImGui::Native.ImPlot_GetCurrentContext
27
+ null_pointer?(context) ? nil : context
28
+ end
29
+
30
+ def current_context=(context)
31
+ ImGui.__send__(:guard_context!)
32
+ ImGui::Native.ImPlot_SetCurrentContext(context)
33
+ context
34
+ end
35
+
36
+ def plot(title, size: [-1, 0], flags: 0, &block)
37
+ plot_guard!
38
+ opened = ImGui::Native.ImPlot_BeginPlot(title.to_s, ImGui::StructValue.vec2(size), Integer(flags))
39
+ plot_scope(:plot, :ImPlot_EndPlot, opened, &block)
40
+ end
41
+
42
+ def subplots(title, rows:, columns:, size: [-1, 0], flags: 0, row_ratios: nil, column_ratios: nil, &block)
43
+ plot_guard!
44
+ row_pointer = optional_float_array(row_ratios, rows)
45
+ column_pointer = optional_float_array(column_ratios, columns)
46
+ opened = ImGui::Native.ImPlot_BeginSubplots(
47
+ title.to_s,
48
+ Integer(rows),
49
+ Integer(columns),
50
+ ImGui::StructValue.vec2(size),
51
+ Integer(flags),
52
+ row_pointer,
53
+ column_pointer
54
+ )
55
+ plot_scope(:subplots, :ImPlot_EndSubplots, opened, &block)
56
+ end
57
+
58
+ def setup_axes(x_label = nil, y_label = nil, x_flags: 0, y_flags: 0)
59
+ plot_guard!
60
+ ImGui::Native.ImPlot_SetupAxes(x_label&.to_s, y_label&.to_s, Integer(x_flags), Integer(y_flags))
61
+ end
62
+
63
+ def setup_axis(axis, label = nil, flags: 0)
64
+ plot_guard!
65
+ ImGui::Native.ImPlot_SetupAxis(Integer(axis), label&.to_s, Integer(flags))
66
+ end
67
+
68
+ def setup_axis_limits(axis, minimum, maximum, condition: 0)
69
+ plot_guard!
70
+ ImGui::Native.ImPlot_SetupAxisLimits(Integer(axis), Float(minimum), Float(maximum), Integer(condition))
71
+ end
72
+
73
+ def setup_axes_limits(x_minimum, x_maximum, y_minimum, y_maximum, condition: 0)
74
+ plot_guard!
75
+ ImGui::Native.ImPlot_SetupAxesLimits(
76
+ Float(x_minimum),
77
+ Float(x_maximum),
78
+ Float(y_minimum),
79
+ Float(y_maximum),
80
+ Integer(condition)
81
+ )
82
+ end
83
+
84
+ def plot_line(label, values, xs: nil, x_scale: 1.0, x_start: 0.0, flags: 0, offset: 0)
85
+ plot_series(:ImPlot_PlotLine, label, values, xs, x_scale, x_start, flags, offset)
86
+ end
87
+
88
+ def plot_scatter(label, values, xs: nil, x_scale: 1.0, x_start: 0.0, flags: 0, offset: 0)
89
+ plot_series(:ImPlot_PlotScatter, label, values, xs, x_scale, x_start, flags, offset)
90
+ end
91
+
92
+ def plot_stairs(label, values, xs: nil, x_scale: 1.0, x_start: 0.0, flags: 0, offset: 0)
93
+ plot_series(:ImPlot_PlotStairs, label, values, xs, x_scale, x_start, flags, offset)
94
+ end
95
+
96
+ def plot_bars(label, values, xs: nil, bar_size: 0.67, shift: 0.0, flags: 0, offset: 0)
97
+ plot_guard!
98
+ ys = double_array(values)
99
+ stride = FFI.type_size(:double)
100
+ if xs
101
+ x_values = double_array(xs, expected: values.length)
102
+ return ImGui::Native.ImPlot_PlotBars_doublePtrdoublePtr(
103
+ label.to_s, x_values, ys, values.length, Float(bar_size), Integer(flags), Integer(offset), stride
104
+ )
105
+ end
106
+
107
+ ImGui::Native.ImPlot_PlotBars_doublePtrInt(
108
+ label.to_s, ys, values.length, Float(bar_size), Float(shift), Integer(flags), Integer(offset), stride
109
+ )
110
+ end
111
+
112
+ def plot_histogram(label, values, bins: Bin::Sturges, bar_scale: 1.0, range: nil, flags: 0)
113
+ plot_guard!
114
+ data = double_array(values)
115
+ native_range = plot_range(range)
116
+ ImGui::Native.ImPlot_PlotHistogram_doublePtr(
117
+ label.to_s,
118
+ data,
119
+ values.length,
120
+ Integer(bins),
121
+ Float(bar_scale),
122
+ native_range,
123
+ Integer(flags)
124
+ )
125
+ end
126
+
127
+ def style_color(index, color)
128
+ plot_guard!
129
+ ImGui::Native.ImPlot_PushStyleColor_Vec4(Integer(index), ImGui::StructValue.vec4(color))
130
+ pushed = true
131
+ return manual_plot_push(:style_color, :ImPlot_PopStyleColor, [1]) unless block_given?
132
+
133
+ yield
134
+ ensure
135
+ ImGui::Native.ImPlot_PopStyleColor(1) if pushed && block_given?
136
+ end
137
+
138
+ def style_var(index, value)
139
+ plot_guard!
140
+ if value.is_a?(Array)
141
+ ImGui::Native.ImPlot_PushStyleVar_Vec2(Integer(index), ImGui::StructValue.vec2(value))
142
+ else
143
+ ImGui::Native.ImPlot_PushStyleVar_Float(Integer(index), Float(value))
144
+ end
145
+ pushed = true
146
+ return manual_plot_push(:style_var, :ImPlot_PopStyleVar, [1]) unless block_given?
147
+
148
+ yield
149
+ ensure
150
+ ImGui::Native.ImPlot_PopStyleVar(1) if pushed && block_given?
151
+ end
152
+
153
+ def end_plot
154
+ close_plot_scope(:plot)
155
+ end
156
+
157
+ def end_subplots
158
+ close_plot_scope(:subplots)
159
+ end
160
+
161
+ def pop_style_color
162
+ close_plot_scope(:style_color)
163
+ end
164
+
165
+ def pop_style_var
166
+ close_plot_scope(:style_var)
167
+ end
168
+
169
+ private
170
+
171
+ def plot_series(prefix, label, values, xs, x_scale, x_start, flags, offset)
172
+ plot_guard!
173
+ ys = double_array(values)
174
+ stride = FFI.type_size(:double)
175
+ if xs
176
+ x_values = double_array(xs, expected: values.length)
177
+ function = "#{prefix}_doublePtrdoublePtr".to_sym
178
+ return ImGui::Native.public_send(
179
+ function, label.to_s, x_values, ys, values.length, Integer(flags), Integer(offset), stride
180
+ )
181
+ end
182
+
183
+ function = "#{prefix}_doublePtrInt".to_sym
184
+ ImGui::Native.public_send(
185
+ function,
186
+ label.to_s,
187
+ ys,
188
+ values.length,
189
+ Float(x_scale),
190
+ Float(x_start),
191
+ Integer(flags),
192
+ Integer(offset),
193
+ stride
194
+ )
195
+ end
196
+
197
+ def plot_scope(kind, end_function, opened)
198
+ unless block_given?
199
+ plot_scope_stack << [kind, end_function, []] if opened
200
+ return opened
201
+ end
202
+ return false unless opened
203
+
204
+ begin
205
+ yield
206
+ ensure
207
+ ImGui::Native.public_send(end_function)
208
+ end
209
+ end
210
+
211
+ def manual_plot_push(kind, pop_function, arguments)
212
+ plot_scope_stack << [kind, pop_function, arguments]
213
+ true
214
+ end
215
+
216
+ def close_plot_scope(expected)
217
+ plot_guard!
218
+ scope = plot_scope_stack.pop
219
+ unless scope&.first == expected
220
+ plot_scope_stack << scope if scope
221
+ raise ImGui::StackError, "expected #{expected} scope, found #{scope&.first || "none"}"
222
+ end
223
+
224
+ ImGui::Native.public_send(scope.fetch(1), *scope.fetch(2))
225
+ end
226
+
227
+ def plot_scope_stack
228
+ Thread.current.thread_variable_get(:imgui_ruby_plot_scope_stack) || begin
229
+ stack = []
230
+ Thread.current.thread_variable_set(:imgui_ruby_plot_scope_stack, stack)
231
+ stack
232
+ end
233
+ end
234
+
235
+ def plot_guard!
236
+ ImGui.__send__(:guard_context!)
237
+ raise NoContextError, "create an ImPlot context before plotting" unless current_context
238
+ end
239
+
240
+ def double_array(values, expected: nil)
241
+ array = Array(values)
242
+ raise ArgumentError, "expected #{expected} values" if expected && array.length != expected
243
+ raise ArgumentError, "plot data cannot be empty" if array.empty?
244
+
245
+ pointer = FFI::MemoryPointer.new(:double, array.length)
246
+ pointer.write_array_of_double(array.map { |value| Float(value) })
247
+ pointer
248
+ end
249
+
250
+ def optional_float_array(values, expected)
251
+ return nil if values.nil?
252
+
253
+ array = Array(values)
254
+ raise ArgumentError, "expected #{expected} ratios" unless array.length == expected
255
+
256
+ pointer = FFI::MemoryPointer.new(:float, array.length)
257
+ pointer.write_array_of_float(array.map { |value| Float(value) })
258
+ pointer
259
+ end
260
+
261
+ def plot_range(value)
262
+ minimum, maximum = value ? Array(value) : [0.0, 0.0]
263
+ range = ImGui::Native::ImPlotRange.new
264
+ range[:Min] = Float(minimum)
265
+ range[:Max] = Float(maximum)
266
+ range
267
+ end
268
+
269
+ def null_pointer?(pointer)
270
+ pointer.nil? || pointer.respond_to?(:null?) && pointer.null?
271
+ end
272
+ end
273
+ end