nuklear 0.1.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 (102) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +29 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +196 -0
  8. data/Rakefile +26 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/examples/arial.ttf +0 -0
  12. data/examples/calculator.rb +102 -0
  13. data/examples/hello_nuklear.rb +182 -0
  14. data/examples/lib/opengl_font.rb +32 -0
  15. data/examples/lib/opengl_init.rb +4 -0
  16. data/examples/lib/sdl2_init.rb +6 -0
  17. data/examples/lib/sdl2_input.rb +81 -0
  18. data/examples/lib/window.rb +47 -0
  19. data/ext/freetype/extconf.rb +26 -0
  20. data/ext/nuklear/extconf.rb +14 -0
  21. data/ext/nuklear/nkrb.c +79 -0
  22. data/ext/nuklear/nkrb.h +89 -0
  23. data/ext/nuklear/nkrb_buffer.c +80 -0
  24. data/ext/nuklear/nkrb_context.c +241 -0
  25. data/ext/nuklear/nkrb_font.c +80 -0
  26. data/ext/nuklear/nkrb_renderer.c +114 -0
  27. data/ext/nuklear/nkrb_style.c +61 -0
  28. data/ext/nuklear/nkrb_style_color.c +126 -0
  29. data/ext/nuklear/nkrb_style_image.c +32 -0
  30. data/ext/nuklear/nkrb_ui.c +32 -0
  31. data/ext/nuklear/nkrb_ui_builder.c +29 -0
  32. data/ext/nuklear/nkrb_ui_button.c +55 -0
  33. data/ext/nuklear/nkrb_ui_color_picker.c +20 -0
  34. data/ext/nuklear/nkrb_ui_combo.c +73 -0
  35. data/ext/nuklear/nkrb_ui_container.c +7 -0
  36. data/ext/nuklear/nkrb_ui_edit_string.c +38 -0
  37. data/ext/nuklear/nkrb_ui_group.c +27 -0
  38. data/ext/nuklear/nkrb_ui_label.c +30 -0
  39. data/ext/nuklear/nkrb_ui_layout.c +125 -0
  40. data/ext/nuklear/nkrb_ui_menu.c +49 -0
  41. data/ext/nuklear/nkrb_ui_menu_item.c +30 -0
  42. data/ext/nuklear/nkrb_ui_menubar.c +18 -0
  43. data/ext/nuklear/nkrb_ui_popup.c +24 -0
  44. data/ext/nuklear/nkrb_ui_progress.c +19 -0
  45. data/ext/nuklear/nkrb_ui_property.c +20 -0
  46. data/ext/nuklear/nkrb_ui_selectables.c +53 -0
  47. data/ext/nuklear/nkrb_ui_slider.c +19 -0
  48. data/ext/nuklear/nkrb_ui_tree.c +29 -0
  49. data/ext/nuklear/nkrb_ui_widget.c +7 -0
  50. data/ext/nuklear/nkrb_ui_window.c +43 -0
  51. data/ext/nuklear/nuklear.h +23378 -0
  52. data/ext/nuklear_renderer_opengl2/KHR/khrplatform.h +285 -0
  53. data/ext/nuklear_renderer_opengl2/extconf.rb +13 -0
  54. data/ext/nuklear_renderer_opengl2/glad.c +1432 -0
  55. data/ext/nuklear_renderer_opengl2/glad.h +2747 -0
  56. data/ext/nuklear_renderer_opengl2/nuklear_renderer_opengl2.c +197 -0
  57. data/ext/nuklear_renderer_opengl4/KHR/khrplatform.h +285 -0
  58. data/ext/nuklear_renderer_opengl4/extconf.rb +13 -0
  59. data/ext/nuklear_renderer_opengl4/glad.c +1782 -0
  60. data/ext/nuklear_renderer_opengl4/glad.h +3687 -0
  61. data/ext/nuklear_renderer_opengl4/nuklear_renderer_opengl4.c +255 -0
  62. data/lib/nuklear/context.rb +49 -0
  63. data/lib/nuklear/dsl.rb +46 -0
  64. data/lib/nuklear/event_buffer.rb +23 -0
  65. data/lib/nuklear/renderer/opengl24.rb +13 -0
  66. data/lib/nuklear/renderer.rb +108 -0
  67. data/lib/nuklear/style/color.rb +24 -0
  68. data/lib/nuklear/style/image.rb +9 -0
  69. data/lib/nuklear/style.rb +8 -0
  70. data/lib/nuklear/test_case.rb +30 -0
  71. data/lib/nuklear/ui/base.rb +34 -0
  72. data/lib/nuklear/ui/button.rb +77 -0
  73. data/lib/nuklear/ui/checkbox.rb +39 -0
  74. data/lib/nuklear/ui/col.rb +21 -0
  75. data/lib/nuklear/ui/color_picker.rb +31 -0
  76. data/lib/nuklear/ui/combo_box.rb +42 -0
  77. data/lib/nuklear/ui/container.rb +80 -0
  78. data/lib/nuklear/ui/edit_string.rb +48 -0
  79. data/lib/nuklear/ui/enableable.rb +29 -0
  80. data/lib/nuklear/ui/events.rb +23 -0
  81. data/lib/nuklear/ui/group.rb +31 -0
  82. data/lib/nuklear/ui/label.rb +21 -0
  83. data/lib/nuklear/ui/menu.rb +43 -0
  84. data/lib/nuklear/ui/menu_bar.rb +19 -0
  85. data/lib/nuklear/ui/menu_item.rb +34 -0
  86. data/lib/nuklear/ui/option.rb +17 -0
  87. data/lib/nuklear/ui/option_group.rb +22 -0
  88. data/lib/nuklear/ui/popup.rb +37 -0
  89. data/lib/nuklear/ui/progress.rb +33 -0
  90. data/lib/nuklear/ui/property.rb +28 -0
  91. data/lib/nuklear/ui/row.rb +28 -0
  92. data/lib/nuklear/ui/select_list.rb +31 -0
  93. data/lib/nuklear/ui/selectable.rb +21 -0
  94. data/lib/nuklear/ui/slider.rb +26 -0
  95. data/lib/nuklear/ui/text_align.rb +14 -0
  96. data/lib/nuklear/ui/tree.rb +62 -0
  97. data/lib/nuklear/ui/window.rb +175 -0
  98. data/lib/nuklear/ui.rb +33 -0
  99. data/lib/nuklear/version.rb +3 -0
  100. data/lib/nuklear.rb +26 -0
  101. data/nuklear.gemspec +41 -0
  102. metadata +233 -0
@@ -0,0 +1,81 @@
1
+ require 'sdl2'
2
+
3
+ module Examples
4
+ module SDL2Input
5
+ def process_sdl2_events(nuklear_ctx, escape_keys: [SDL2::Key::ESCAPE])
6
+ while event = ::SDL2::Event.poll
7
+ case event
8
+ # TODO touch events
9
+ # when SDL2::Event::FingerMotion
10
+ # when SDL2::Event::FingerDown
11
+ # when SDL2::Event::FingerUp
12
+ when ::SDL2::Event::TextInput then nuklear_ctx.trigger(:glyph, event.text)
13
+ when ::SDL2::Event::MouseMotion then nuklear_ctx.trigger(:motion, event.x, event.y, event.xrel, event.yrel)
14
+ when ::SDL2::Event::MouseWheel then nuklear_ctx.trigger(:scroll, event.x, event.y)
15
+ when ::SDL2::Event::MouseButtonDown, ::SDL2::Event::MouseButtonUp
16
+ is_down = event.kind_of?(::SDL2::Event::MouseButtonDown)
17
+ if event.button == 1 and event.clicks > 1
18
+ nuklear_ctx.trigger(:button, :double, event.x, event.y, is_down)
19
+ else
20
+ case event.button
21
+ # SDL_BUTTON_LEFT seems to be not defined
22
+ when 1 then nuklear_ctx.trigger(:button, :left, event.x, event.y, is_down)
23
+ when 2 then nuklear_ctx.trigger(:button, :middle, event.x, event.y, is_down)
24
+ when 3 then nuklear_ctx.trigger(:button, :right, event.x, event.y, is_down)
25
+ else yield event if block_given?
26
+ end
27
+ end
28
+ when ::SDL2::Event::Window
29
+ case event.event
30
+ when ::SDL2::Event::Window::FOCUS_GAINED then @focused = true
31
+ when ::SDL2::Event::Window::FOCUS_LOST then @focused = false
32
+ end
33
+ when ::SDL2::Event::KeyDown, ::SDL2::Event::KeyUp
34
+ is_down = event.kind_of?(::SDL2::Event::KeyDown)
35
+ case event.sym
36
+ when ::SDL2::Key::LSHIFT, ::SDL2::Key::RSHIFT then nuklear_ctx.trigger(:key, :shift, is_down)
37
+ when ::SDL2::Key::DELETE then nuklear_ctx.trigger(:key, :del, is_down)
38
+ when ::SDL2::Key::RETURN then nuklear_ctx.trigger(:key, :enter, is_down)
39
+ when ::SDL2::Key::TAB then nuklear_ctx.trigger(:key, :tab, is_down)
40
+ when ::SDL2::Key::BACKSPACE then nuklear_ctx.trigger(:key, :backspace, is_down)
41
+ when ::SDL2::Key::HOME then nuklear_ctx.trigger(:key, :text_start, is_down)
42
+ nuklear_ctx.trigger(:key, :scroll_start, is_down)
43
+ when ::SDL2::Key::END then nuklear_ctx.trigger(:key, :text_end, is_down)
44
+ nuklear_ctx.trigger(:key, :scroll_end, is_down)
45
+ when ::SDL2::Key::PAGEDOWN then nuklear_ctx.trigger(:key, :scroll_down, is_down)
46
+ when ::SDL2::Key::PAGEUP then nuklear_ctx.trigger(:key, :scroll_up, is_down)
47
+ when ::SDL2::Key::Z then nuklear_ctx.trigger(:key, :text_undo, is_down && (event.mod & ::SDL2::Key::Mod::CTRL > 0))
48
+ when ::SDL2::Key::R then nuklear_ctx.trigger(:key, :text_redo, is_down && (event.mod & ::SDL2::Key::Mod::CTRL > 0))
49
+ when ::SDL2::Key::C then nuklear_ctx.trigger(:key, :copy, is_down && (event.mod & ::SDL2::Key::Mod::CTRL > 0))
50
+ when ::SDL2::Key::V then nuklear_ctx.trigger(:key, :paste, is_down && (event.mod & ::SDL2::Key::Mod::CTRL > 0))
51
+ when ::SDL2::Key::X then nuklear_ctx.trigger(:key, :cut, is_down && (event.mod & ::SDL2::Key::Mod::CTRL > 0))
52
+ when ::SDL2::Key::B then nuklear_ctx.trigger(:key, :text_line_start, is_down && (event.mod & ::SDL2::Key::Mod::CTRL > 0))
53
+ when ::SDL2::Key::E then nuklear_ctx.trigger(:key, :text_line_end, is_down && (event.mod & ::SDL2::Key::Mod::CTRL > 0))
54
+ when ::SDL2::Key::UP then nuklear_ctx.trigger(:key, :up, is_down)
55
+ when ::SDL2::Key::DOWN then nuklear_ctx.trigger(:key, :down, is_down)
56
+ when ::SDL2::Key::LEFT
57
+ if event.mod & ::SDL2::Key::Mod::CTRL > 0 then nuklear_ctx.trigger(:key, :text_word_left, is_down)
58
+ else nuklear_ctx.trigger(:key, :left, is_down)
59
+ end
60
+ when ::SDL2::Key::RIGHT
61
+ if event.mod & ::SDL2::Key::Mod::CTRL > 0 then nuklear_ctx.trigger(:key, :text_word_right, is_down)
62
+ else nuklear_ctx.trigger(:key, :right, is_down)
63
+ end
64
+ end
65
+
66
+ yield event if block_given? && escape_keys.include?(event.sym)
67
+ when SDL2::Event::Quit then exit
68
+ when SDL2::Event::KeyDown
69
+ case event.sym
70
+ when SDL2::Key::C
71
+ if (event.mod & SDL2::Key::Mod::CTRL) > 0
72
+ exit
73
+ end
74
+ end
75
+ else
76
+ yield event if block_given?
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,47 @@
1
+ require_relative 'sdl2_input'
2
+ require 'nuklear/nuklear_renderer_opengl2'
3
+
4
+ module Examples
5
+ class Window
6
+ include Examples::SDL2Input
7
+ attr_reader :nuklear_context
8
+
9
+ def initialize(title = "Example", left: 0, top: 0, width: 640, height: 480, hidden: false)
10
+ flags = SDL2::Window::Flags::OPENGL |
11
+ SDL2::Window::Flags::ALLOW_HIGHDPI |
12
+ SDL2::Window::Flags::RESIZABLE
13
+ flags = flags | SDL2::Window::Flags::HIDDEN if hidden
14
+ @handle = SDL2::Window.create title, left, top, width, height, flags
15
+ @gl = SDL2::GL::Context.create(@handle)
16
+ @focused = false
17
+ glViewport(0, 0, *renderable_size)
18
+ glClearColor(0, 0, 0, 0)
19
+ end
20
+
21
+ def close
22
+ @handle.destroy
23
+ end
24
+
25
+ def frame
26
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
27
+ process_sdl2_events(@nuklear_context)
28
+ yield # do app specific stuff
29
+ @handle.gl_swap
30
+ end
31
+
32
+ def focused?
33
+ @focused
34
+ end
35
+
36
+ def nuklear_context=(ctx)
37
+ @nuklear_context = ctx
38
+ @nuklear_context.renderer = Nuklear::Renderer::OpenGL2.new(@nuklear_context)
39
+ @nuklear_context.renderer.window_size = @handle.size
40
+ @nuklear_context.renderer.drawable_size = renderable_size
41
+ end
42
+
43
+ def renderable_size
44
+ @handle.gl_drawable_size
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,26 @@
1
+ require 'fileutils'
2
+ require 'mini_portile2'
3
+ include FileUtils
4
+
5
+ root = File.expand_path('../..')
6
+ $freetype = MiniPortile.new('freetype', '2.7.0')
7
+ $freetype.target = File.expand_path('ports', root)
8
+ $freetype.files = ['http://download.savannah.gnu.org/releases/freetype/freetype-2.7.tar.gz']
9
+ $freetype.configure_options << 'CFLAGS=-fPIC'
10
+ checkpoint = File.expand_path("ports/.#{$freetype.name}-#{$freetype.version}.installed", root)
11
+
12
+ unless File.exist?(checkpoint)
13
+ $freetype.cook
14
+ touch checkpoint
15
+ end
16
+
17
+ if $CFLAGS
18
+ $CFLAGS << ' ' << `sh #{$freetype.path}/bin/freetype-config --cflags --static`.chomp
19
+ `sh #{$freetype.path}/bin/freetype-config --libs --static`.chomp.shellsplit.each do |arg|
20
+ case arg
21
+ when /\A-L(.+)\z/ then $LIBPATH << $1
22
+ when /\A-l./ then $libs << ' ' << arg.shellescape
23
+ else $LDFLAGS << ' ' << arg.shellescape
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ require 'mkmf'
2
+ # require_relative '../freetype/extconf'
3
+
4
+ $CFLAGS << ' -DNK_INCLUDE_VERTEX_BUFFER_OUTPUT=1'
5
+ $CFLAGS << ' -DNK_INCLUDE_FONT_BAKING=1'
6
+ $CFLAGS << ' -DNK_INCLUDE_DEFAULT_FONT=1'
7
+ $CFLAGS << ' -DNK_INCLUDE_COMMAND_USERDATA=1'
8
+ $CFLAGS << ' -DNK_BUTTON_TRIGGER_ON_RELEASE=1'
9
+ $CFLAGS << ' -DNK_ZERO_COMMAND_MEMORY=1'
10
+ $CFLAGS << ' -DNK_INCLUDE_FIXED_TYPES=1'
11
+ $CFLAGS << ' -DNK_INCLUDE_DEFAULT_ALLOCATOR=1'
12
+ $CFLAGS << ' -DNK_INCLUDE_STANDARD_IO=1'
13
+
14
+ create_makefile('nuklear/nuklear')
@@ -0,0 +1,79 @@
1
+ #define NK_IMPLEMENTATION
2
+ #include "nkrb.h"
3
+
4
+ VALUE mNuklear = Qnil;
5
+
6
+ void Init_nuklear(void) {
7
+ mNuklear = rb_define_module("Nuklear");
8
+
9
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_BORDER"), INT2FIX(NK_WINDOW_BORDER));
10
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_MOVABLE"), INT2FIX(NK_WINDOW_MOVABLE));
11
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_SCALABLE"), INT2FIX(NK_WINDOW_SCALABLE));
12
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_CLOSABLE"), INT2FIX(NK_WINDOW_CLOSABLE));
13
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_MINIMIZABLE"), INT2FIX(NK_WINDOW_MINIMIZABLE));
14
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_NO_SCROLLBAR"), INT2FIX(NK_WINDOW_NO_SCROLLBAR));
15
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_TITLE"), INT2FIX(NK_WINDOW_TITLE));
16
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_SCROLL_AUTO_HIDE"), INT2FIX(NK_WINDOW_SCROLL_AUTO_HIDE));
17
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_BACKGROUND"), INT2FIX(NK_WINDOW_BACKGROUND));
18
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_SCALE_LEFT"), INT2FIX(NK_WINDOW_SCALE_LEFT));
19
+ rb_const_set(mNuklear, rb_intern("NK_WINDOW_NO_INPUT"), INT2FIX(NK_WINDOW_NO_INPUT));
20
+
21
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_DEFAULT"), INT2FIX(NK_EDIT_DEFAULT));
22
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_READ_ONLY"), INT2FIX(NK_EDIT_READ_ONLY));
23
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_AUTO_SELECT"), INT2FIX(NK_EDIT_AUTO_SELECT));
24
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_SIG_ENTER"), INT2FIX(NK_EDIT_SIG_ENTER));
25
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_ALLOW_TAB"), INT2FIX(NK_EDIT_ALLOW_TAB));
26
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_NO_CURSOR"), INT2FIX(NK_EDIT_NO_CURSOR));
27
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_SELECTABLE"), INT2FIX(NK_EDIT_SELECTABLE));
28
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_CLIPBOARD"), INT2FIX(NK_EDIT_CLIPBOARD));
29
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_CTRL_ENTER_NEWLINE"), INT2FIX(NK_EDIT_CTRL_ENTER_NEWLINE));
30
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_NO_HORIZONTAL_SCROLL"), INT2FIX(NK_EDIT_NO_HORIZONTAL_SCROLL));
31
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_ALWAYS_INSERT_MODE"), INT2FIX(NK_EDIT_ALWAYS_INSERT_MODE));
32
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_MULTILINE"), INT2FIX(NK_EDIT_MULTILINE));
33
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_GOTO_END_ON_ACTIVATE"), INT2FIX(NK_EDIT_GOTO_END_ON_ACTIVATE));
34
+
35
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_SIMPLE"), INT2FIX(NK_EDIT_SIMPLE));
36
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_FIELD"), INT2FIX(NK_EDIT_FIELD));
37
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_BOX"), INT2FIX(NK_EDIT_BOX));
38
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_EDITOR"), INT2FIX(NK_EDIT_EDITOR));
39
+
40
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_ACTIVE"), INT2FIX(NK_EDIT_ACTIVE));
41
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_INACTIVE"), INT2FIX(NK_EDIT_INACTIVE));
42
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_ACTIVATED"), INT2FIX(NK_EDIT_ACTIVATED));
43
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_DEACTIVATED"), INT2FIX(NK_EDIT_DEACTIVATED));
44
+ rb_const_set(mNuklear, rb_intern("NK_EDIT_COMMITED"), INT2FIX(NK_EDIT_COMMITED));
45
+
46
+ rb_const_set(mNuklear, rb_intern("NK_STYLE_ITEM_COLOR"), INT2FIX(NK_STYLE_ITEM_COLOR));
47
+ rb_const_set(mNuklear, rb_intern("NK_STYLE_ITEM_IMAGE"), INT2FIX(NK_STYLE_ITEM_IMAGE));
48
+
49
+ rb_const_set(mNuklear, rb_intern("NK_MINIMIZED"), INT2FIX(NK_MINIMIZED));
50
+ rb_const_set(mNuklear, rb_intern("NK_MAXIMIZED"), INT2FIX(NK_MAXIMIZED));
51
+
52
+ rb_const_set(mNuklear, rb_intern("NK_TREE_NODE"), INT2FIX(NK_TREE_NODE));
53
+ rb_const_set(mNuklear, rb_intern("NK_TREE_TAB"), INT2FIX(NK_TREE_TAB));
54
+
55
+ rb_const_set(mNuklear, rb_intern("NK_DYNAMIC"), INT2FIX(NK_DYNAMIC));
56
+ rb_const_set(mNuklear, rb_intern("NK_STATIC"), INT2FIX(NK_STATIC));
57
+
58
+ rb_const_set(mNuklear, rb_intern("NK_POPUP_DYNAMIC"), INT2FIX(NK_POPUP_DYNAMIC));
59
+ rb_const_set(mNuklear, rb_intern("NK_POPUP_STATIC"), INT2FIX(NK_POPUP_STATIC));
60
+
61
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_ALIGN_LEFT"), INT2FIX(NK_TEXT_ALIGN_LEFT));
62
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_ALIGN_CENTERED"), INT2FIX(NK_TEXT_ALIGN_CENTERED));
63
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_ALIGN_RIGHT"), INT2FIX(NK_TEXT_ALIGN_RIGHT));
64
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_ALIGN_TOP"), INT2FIX(NK_TEXT_ALIGN_TOP));
65
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_ALIGN_MIDDLE"), INT2FIX(NK_TEXT_ALIGN_MIDDLE));
66
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_ALIGN_BOTTOM"), INT2FIX(NK_TEXT_ALIGN_BOTTOM));
67
+
68
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_LEFT"), INT2FIX(NK_TEXT_LEFT));
69
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_CENTERED"), INT2FIX(NK_TEXT_CENTERED));
70
+ rb_const_set(mNuklear, rb_intern("NK_TEXT_RIGHT"), INT2FIX(NK_TEXT_RIGHT));
71
+
72
+ nkrb_context_init();
73
+ nkrb_font_init();
74
+ nkrb_buffer_init();
75
+ nkrb_renderer_init();
76
+ nkrb_style_init();
77
+ nkrb_ui_builder_init();
78
+ nkrb_ui_init();
79
+ }
@@ -0,0 +1,89 @@
1
+ #ifndef NUKLEAR_RUBY_H
2
+ #define NUKLEAR_RUBY_H
3
+
4
+ #include "nuklear.h"
5
+ #include <ruby.h>
6
+
7
+ #define ASSIGN_STYLE_AS_IMAGE(left, style) \
8
+ if (style->type == NK_STYLE_ITEM_IMAGE) \
9
+ left = style->data.image; \
10
+ else \
11
+ rb_raise(rb_eArgError, "expected an image here");
12
+
13
+ #define ASSIGN_STYLE_AS_COLOR(left, style) \
14
+ if (style->type == NK_STYLE_ITEM_COLOR) \
15
+ left = style->data.color; \
16
+ else \
17
+ rb_raise(rb_eArgError, "expected a color here");
18
+
19
+
20
+ #define SET_RSYMBOL(symbol, rsymbol) \
21
+ if (!NIL_P(rsymbol)) { \
22
+ if (SYM2ID(rsymbol) == rb_intern("x")) symbol = NK_SYMBOL_X; \
23
+ else if (SYM2ID(rsymbol) == rb_intern("underscore")) symbol = NK_SYMBOL_UNDERSCORE; \
24
+ else if (SYM2ID(rsymbol) == rb_intern("circle_solid")) symbol = NK_SYMBOL_CIRCLE_SOLID; \
25
+ else if (SYM2ID(rsymbol) == rb_intern("circle_outline")) symbol = NK_SYMBOL_CIRCLE_OUTLINE; \
26
+ else if (SYM2ID(rsymbol) == rb_intern("rect_solid")) symbol = NK_SYMBOL_RECT_SOLID; \
27
+ else if (SYM2ID(rsymbol) == rb_intern("rect_outline")) symbol = NK_SYMBOL_RECT_OUTLINE; \
28
+ else if (SYM2ID(rsymbol) == rb_intern("triangle_up")) symbol = NK_SYMBOL_TRIANGLE_UP; \
29
+ else if (SYM2ID(rsymbol) == rb_intern("triangle_down")) symbol = NK_SYMBOL_TRIANGLE_DOWN; \
30
+ else if (SYM2ID(rsymbol) == rb_intern("triangle_left")) symbol = NK_SYMBOL_TRIANGLE_LEFT; \
31
+ else if (SYM2ID(rsymbol) == rb_intern("triangle_right")) symbol = NK_SYMBOL_TRIANGLE_RIGHT; \
32
+ else if (SYM2ID(rsymbol) == rb_intern("plus")) symbol = NK_SYMBOL_PLUS; \
33
+ else if (SYM2ID(rsymbol) == rb_intern("minus")) symbol = NK_SYMBOL_MINUS; \
34
+ else if (SYM2ID(rsymbol) == rb_intern("max")) symbol = NK_SYMBOL_MAX; \
35
+ else rb_raise(rb_eArgError, "Symbol must be :x, :underscore, :circle_solid, :circle_outline"\
36
+ ", :rect_solid, :rect_outline, :triangle_up, :triangle_down, " \
37
+ ":triangle_left, :triangle_right, :plus, :minus or :max."); \
38
+ }
39
+
40
+
41
+ void nkrb_context_init(void);
42
+ void nkrb_font_init(void);
43
+ void nkrb_buffer_init(void);
44
+ void nkrb_renderer_init(void);
45
+ void nkrb_ui_builder_init(void);
46
+ void nkrb_ui_init(void);
47
+ void nkrb_ui_button_init(void);
48
+ void nkrb_ui_checkbox_init(void);
49
+ void nkrb_ui_color_picker_init(void);
50
+ void nkrb_ui_combo_init(void);
51
+ void nkrb_ui_group_init(void);
52
+ void nkrb_ui_label_init(void);
53
+ void nkrb_ui_layout_init(void);
54
+ void nkrb_ui_edit_string_init(void);
55
+ void nkrb_ui_menu_init(void);
56
+ void nkrb_ui_menubar_init(void);
57
+ void nkrb_ui_menu_item_init(void);
58
+ void nkrb_ui_popup_init(void);
59
+ void nkrb_ui_progress_init(void);
60
+ void nkrb_ui_property_init(void);
61
+ void nkrb_ui_slider_init(void);
62
+ void nkrb_ui_tree_init(void);
63
+ void nkrb_ui_widget_init(void);
64
+ void nkrb_ui_window_init(void);
65
+ void nkrb_ui_container_init(void);
66
+ void nkrb_style_init(void);
67
+ void nkrb_style_color_init(void);
68
+ void nkrb_style_image_init(void);
69
+ struct nk_user_font *nkrb_font_to_nk(VALUE self);
70
+ struct nk_context *nkrb_context_get(VALUE context);
71
+ struct nk_style_item *nkrb_style_item(VALUE value);
72
+ void nkrb_style_item_free(struct nk_style_item *item);
73
+ VALUE nkrb_font_get_null(VALUE value);
74
+ void instance_eval_block(VALUE self);
75
+ void assign_button_style_from_ruby(struct nk_style_button *style, VALUE rstyle);
76
+
77
+ extern VALUE mNuklear;
78
+ extern VALUE cNuklearContext;
79
+ extern VALUE cNuklearFont;
80
+ extern VALUE cNuklearBuffer;
81
+ extern VALUE cNuklearUIBuilder;
82
+ extern VALUE mNuklearUIContainer;
83
+ extern VALUE mNuklearUI;
84
+ extern VALUE cNuklearUIWidget;
85
+ extern VALUE mNuklearStyle;
86
+ extern VALUE cNuklearStyleColor;
87
+ extern VALUE cNuklearStyleImage;
88
+
89
+ #endif // NUKLEAR_RUBY_H
@@ -0,0 +1,80 @@
1
+ #include "nkrb.h"
2
+
3
+ VALUE cNuklearBuffer = Qnil;
4
+
5
+ void nkrb_buffer_dynamic_free(struct nk_buffer *buf) {
6
+ // need to let nk free the buffer contents, then free the buffer itself.
7
+ nk_buffer_free(buf);
8
+ free(buf);
9
+ }
10
+
11
+ void nkrb_buffer_managed_free(struct nk_buffer *buf) {
12
+ // the buffer memory is managed elsewhere, and will be freed elsewhere.
13
+ // We only need to free the buffer itself.
14
+ free(buf);
15
+ }
16
+
17
+ void nkrb_buffer_fixed_free(struct nk_buffer *buf) {
18
+ // need to free the memory we allocated ourselves, then free the buffer
19
+ // itself.
20
+ free(nk_buffer_memory(buf));
21
+ free(buf);
22
+ }
23
+
24
+ VALUE nkrb_buffer_new(int argc, VALUE* argv, VALUE module) {
25
+ VALUE rsize = Qnil;
26
+ VALUE rptr = Qnil;
27
+ rb_scan_args(argc, argv, "02", &rsize, &rptr); // optional rsize, rptr
28
+ void (*freefn)(struct nk_buffer *buf) = NULL;
29
+
30
+ struct nk_buffer *buf = malloc(sizeof(struct nk_buffer));
31
+ nk_size size = 0; // if size is 0, the buffer will be dynamic.
32
+ if (!NIL_P(rsize)) size = (nk_size) NUM2INT(rsize);
33
+
34
+ if (size) {
35
+ void *mem = NULL;
36
+ if (!NIL_P(rptr)) {
37
+ // we were passed a pointer; we will treat it as a 64 bit unsigned in
38
+ // ruby, and a void * in c. We will not zero the user-provided buffer.
39
+ mem = (void *) NUM2ULL(rptr);
40
+ freefn = nkrb_buffer_managed_free;
41
+ } else {
42
+ // we were not passed a pointer; we will allocate a buffer of the
43
+ // requested size and use that. We will zero the uninitialized memory.
44
+ mem = malloc(size);
45
+ memset(mem, 0, size);
46
+ freefn = nkrb_buffer_fixed_free;
47
+ }
48
+ nk_buffer_init_fixed(buf, mem, size);
49
+ } else {
50
+ nk_buffer_init_default(buf);
51
+ freefn = nkrb_buffer_dynamic_free;
52
+ }
53
+ VALUE result = Data_Wrap_Struct(cNuklearBuffer, NULL, freefn, buf);
54
+ return result;
55
+ }
56
+
57
+ VALUE nkrb_buffer_size(VALUE self) {
58
+ struct nk_buffer *buf = NULL;
59
+ Data_Get_Struct(self, struct nk_buffer, buf);
60
+ return ULONG2NUM(nk_buffer_total(buf));
61
+ }
62
+
63
+ VALUE nkrb_buffer_to_ptr(VALUE self) {
64
+ struct nk_buffer *buf = NULL;
65
+ Data_Get_Struct(self, struct nk_buffer, buf);
66
+ VALUE cFiddle = rb_const_get(rb_cObject, rb_intern("Fiddle"));
67
+ VALUE cPointer = rb_const_get(cFiddle, rb_intern("Pointer"));
68
+ VALUE fiddleptr = rb_funcall(cPointer, rb_intern("new"), 2,
69
+ ULONG2NUM((unsigned long) nk_buffer_memory(buf)),
70
+ nkrb_buffer_size(self));
71
+ return fiddleptr;
72
+ }
73
+
74
+ void nkrb_buffer_init(void) {
75
+ cNuklearBuffer = rb_define_class_under(mNuklear, "Buffer", rb_cObject);
76
+
77
+ rb_define_module_function(cNuklearBuffer, "new", nkrb_buffer_new, -1);
78
+ rb_define_method(cNuklearBuffer, "size", nkrb_buffer_size, 0);
79
+ rb_define_method(cNuklearBuffer, "to_ptr", nkrb_buffer_to_ptr, 0);
80
+ }
@@ -0,0 +1,241 @@
1
+ #include "nkrb.h"
2
+
3
+ #define VALUE_TO_NK(value, varname) \
4
+ struct nk_context *varname = NULL; \
5
+ Data_Get_Struct(value, struct nk_context, varname);
6
+
7
+ VALUE cNuklearContext = Qnil;
8
+ VALUE cNuklearContextEventSink = Qnil;
9
+
10
+ void nkrb_context_free(struct nk_context *ctx) {
11
+ nk_free(ctx);
12
+ free(ctx);
13
+ }
14
+
15
+ struct nk_context *nkrb_context_get(VALUE context) {
16
+ VALUE_TO_NK(context, ctx);
17
+ return ctx;
18
+ }
19
+
20
+ VALUE nkrb_context_alloc(VALUE self) {
21
+ struct nk_context *ctx = malloc(sizeof(struct nk_context));
22
+ memset(ctx, 0, sizeof(struct nk_context));
23
+ return Data_Wrap_Struct(self, NULL, nkrb_context_free, ctx);
24
+ }
25
+
26
+ void set_default_style(struct nk_context *ctx) {
27
+ struct nk_color table[NK_COLOR_COUNT];
28
+ table[NK_COLOR_TEXT] = nk_rgba(210, 210, 210, 255);
29
+ table[NK_COLOR_WINDOW] = nk_rgba( 57, 67, 71, 215);
30
+ table[NK_COLOR_HEADER] = nk_rgba( 51, 51, 56, 220);
31
+ table[NK_COLOR_BORDER] = nk_rgba( 46, 46, 46, 255);
32
+ table[NK_COLOR_BUTTON] = nk_rgba( 48, 83, 111, 255);
33
+ table[NK_COLOR_BUTTON_HOVER] = nk_rgba( 58, 93, 121, 255);
34
+ table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba( 63, 98, 126, 255);
35
+ table[NK_COLOR_TOGGLE] = nk_rgba( 50, 58, 61, 255);
36
+ table[NK_COLOR_TOGGLE_HOVER] = nk_rgba( 45, 53, 56, 255);
37
+ table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba( 48, 83, 111, 255);
38
+ table[NK_COLOR_SELECT] = nk_rgba( 57, 67, 61, 255);
39
+ table[NK_COLOR_SELECT_ACTIVE] = nk_rgba( 48, 83, 111, 255);
40
+ table[NK_COLOR_SLIDER] = nk_rgba( 50, 58, 61, 255);
41
+ table[NK_COLOR_SLIDER_CURSOR] = nk_rgba( 48, 83, 111, 245);
42
+ table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba( 53, 88, 116, 255);
43
+ table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba( 58, 93, 121, 255);
44
+ table[NK_COLOR_PROPERTY] = nk_rgba( 50, 58, 61, 255);
45
+ table[NK_COLOR_EDIT] = nk_rgba( 50, 58, 61, 225);
46
+ table[NK_COLOR_EDIT_CURSOR] = nk_rgba(210, 210, 210, 255);
47
+ table[NK_COLOR_COMBO] = nk_rgba( 50, 58, 61, 255);
48
+ table[NK_COLOR_CHART] = nk_rgba( 50, 58, 61, 255);
49
+ table[NK_COLOR_CHART_COLOR] = nk_rgba( 48, 83, 111, 255);
50
+ table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba(255, 0, 0, 255);
51
+ table[NK_COLOR_SCROLLBAR] = nk_rgba( 50, 58, 61, 255);
52
+ table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba( 48, 83, 111, 255);
53
+ table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba( 53, 88, 116, 255);
54
+ table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba( 58, 93, 121, 255);
55
+ table[NK_COLOR_TAB_HEADER] = nk_rgba( 48, 83, 111, 255);
56
+ nk_style_from_table(ctx, table);
57
+ }
58
+
59
+ VALUE nkrb_context_initialize(VALUE context, VALUE font) {
60
+ struct nk_context *ctx = nkrb_context_get(context);
61
+ if (nk_init_default(ctx, nkrb_font_to_nk(font)) == 0) {
62
+ rb_raise(rb_eStandardError, "Failed to initialize Nuklear context");
63
+ }
64
+ set_default_style(ctx);
65
+ VALUE event_sink = rb_funcall(cNuklearContextEventSink, rb_intern("new"), 1, context);
66
+ rb_ivar_set(context, rb_intern("@event_sink"), event_sink);
67
+ rb_ivar_set(context, rb_intern("@font"), font);
68
+ rb_ivar_set(context, rb_intern("@null"), nkrb_font_get_null(font));
69
+ rb_ivar_set(context, rb_intern("@ui_builder"), rb_funcall(cNuklearUIBuilder, rb_intern("new"), 1, context));
70
+
71
+ return context;
72
+ }
73
+
74
+ VALUE nkrb_context_set_user_data(VALUE self, VALUE userdata) {
75
+ VALUE_TO_NK(self, ctx);
76
+ // maybe come back to this, might be able to access user data later on through context
77
+ // nk_set_user_data(ctx, userdata);
78
+ rb_ivar_set(self, rb_intern("@userdata"), userdata);
79
+ return userdata;
80
+ }
81
+
82
+ VALUE nkrb_context_get_user_data(VALUE self) {
83
+ return rb_ivar_get(self, rb_intern("@userdata"));
84
+ }
85
+
86
+ VALUE nkrb_context_tick(VALUE self) {
87
+ VALUE_TO_NK(self, ctx);
88
+ nk_input_begin(ctx);
89
+ rb_funcall(self, rb_intern("process_pending_events"), 0);
90
+ nk_input_end(ctx);
91
+ rb_funcall(self, rb_intern("paint"), 0);
92
+ nk_clear(ctx);
93
+ return self;
94
+ }
95
+
96
+ VALUE rb_nkrb_event_sink_initialize(VALUE self, VALUE context) {
97
+ rb_ivar_set(self, rb_intern("@context"), context);
98
+ return self;
99
+ }
100
+
101
+ VALUE nkrb_event_sink_motion(VALUE self, VALUE rx, VALUE ry, VALUE rxrel, VALUE ryrel) {
102
+ VALUE_TO_NK(rb_ivar_get(self, rb_intern("@context")), ctx);
103
+ if (ctx->input.mouse.grabbed) {
104
+ int x = (int) ctx->input.mouse.prev.x, y = (int) ctx->input.mouse.prev.y;
105
+ nk_input_motion(ctx, x + FIX2INT(rxrel), y + FIX2INT(ryrel));
106
+ } else {
107
+ nk_input_motion(ctx, FIX2INT(rx), FIX2INT(ry));
108
+ }
109
+ return self;
110
+ }
111
+
112
+ VALUE nkrb_event_sink_key(VALUE self, VALUE keys, VALUE down) {
113
+ VALUE_TO_NK(rb_ivar_get(self, rb_intern("@context")), ctx);
114
+ ID keys_id = SYM2ID(keys);
115
+ int is_down = RTEST(down) ? 1 : 0;
116
+
117
+ if (keys_id == rb_intern("shift")) nk_input_key(ctx, NK_KEY_SHIFT, is_down);
118
+ else if (keys_id == rb_intern("ctrl")) nk_input_key(ctx, NK_KEY_CTRL, is_down);
119
+ else if (keys_id == rb_intern("del")) nk_input_key(ctx, NK_KEY_DEL, is_down);
120
+ else if (keys_id == rb_intern("enter")) nk_input_key(ctx, NK_KEY_ENTER, is_down);
121
+ else if (keys_id == rb_intern("tab")) nk_input_key(ctx, NK_KEY_TAB, is_down);
122
+ else if (keys_id == rb_intern("backspace")) nk_input_key(ctx, NK_KEY_BACKSPACE, is_down);
123
+ else if (keys_id == rb_intern("copy")) nk_input_key(ctx, NK_KEY_COPY, is_down);
124
+ else if (keys_id == rb_intern("cut")) nk_input_key(ctx, NK_KEY_CUT, is_down);
125
+ else if (keys_id == rb_intern("paste")) nk_input_key(ctx, NK_KEY_PASTE, is_down);
126
+ else if (keys_id == rb_intern("up")) nk_input_key(ctx, NK_KEY_UP, is_down);
127
+ else if (keys_id == rb_intern("down")) nk_input_key(ctx, NK_KEY_DOWN, is_down);
128
+ else if (keys_id == rb_intern("left")) nk_input_key(ctx, NK_KEY_LEFT, is_down);
129
+ else if (keys_id == rb_intern("right")) nk_input_key(ctx, NK_KEY_RIGHT, is_down);
130
+
131
+ /* Shortcuts: text field */
132
+ else if (keys_id == rb_intern("text_insert_mode")) nk_input_key(ctx, NK_KEY_TEXT_INSERT_MODE, is_down);
133
+ else if (keys_id == rb_intern("text_replace_mode")) nk_input_key(ctx, NK_KEY_TEXT_REPLACE_MODE, is_down);
134
+ else if (keys_id == rb_intern("text_reset_mode")) nk_input_key(ctx, NK_KEY_TEXT_RESET_MODE, is_down);
135
+ else if (keys_id == rb_intern("text_line_start")) nk_input_key(ctx, NK_KEY_TEXT_LINE_START, is_down);
136
+ else if (keys_id == rb_intern("text_line_end")) nk_input_key(ctx, NK_KEY_TEXT_LINE_END, is_down);
137
+ else if (keys_id == rb_intern("text_start")) nk_input_key(ctx, NK_KEY_TEXT_START, is_down);
138
+ else if (keys_id == rb_intern("text_end")) nk_input_key(ctx, NK_KEY_TEXT_END, is_down);
139
+ else if (keys_id == rb_intern("text_undo")) nk_input_key(ctx, NK_KEY_TEXT_UNDO, is_down);
140
+ else if (keys_id == rb_intern("text_redo")) nk_input_key(ctx, NK_KEY_TEXT_REDO, is_down);
141
+ else if (keys_id == rb_intern("text_select_all")) nk_input_key(ctx, NK_KEY_TEXT_SELECT_ALL, is_down);
142
+ else if (keys_id == rb_intern("text_word_left")) nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, is_down);
143
+ else if (keys_id == rb_intern("text_word_right")) nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, is_down);
144
+
145
+ /* Shortcuts: scrollbar */
146
+ else if (keys_id == rb_intern("scroll_start")) nk_input_key(ctx, NK_KEY_SCROLL_START, is_down);
147
+ else if (keys_id == rb_intern("scroll_end")) nk_input_key(ctx, NK_KEY_SCROLL_END, is_down);
148
+ else if (keys_id == rb_intern("scroll_down")) nk_input_key(ctx, NK_KEY_SCROLL_DOWN, is_down);
149
+ else if (keys_id == rb_intern("scroll_up")) nk_input_key(ctx, NK_KEY_SCROLL_UP, is_down);
150
+ else if (keys_id == rb_intern("max")) nk_input_key(ctx, NK_KEY_MAX, is_down);
151
+ else {
152
+ VALUE s = rb_funcall(keys, rb_intern("inspect"), 0);
153
+ rb_raise(rb_eArgError, "Invalid key symbol: %s", StringValueCStr(s));
154
+ }
155
+
156
+ return self;
157
+ }
158
+
159
+ VALUE nkrb_event_sink_button(VALUE self, VALUE buttons, VALUE rx, VALUE ry, VALUE down) {
160
+ VALUE_TO_NK(rb_ivar_get(self, rb_intern("@context")), ctx);
161
+ ID buttons_id = SYM2ID(buttons);
162
+ int is_down = RTEST(down) ? 1 : 0;
163
+ int x = FIX2INT(rx), y = FIX2INT(ry);
164
+
165
+ if (buttons_id == rb_intern("left")) nk_input_button(ctx, NK_BUTTON_LEFT, x, y, is_down);
166
+ if (buttons_id == rb_intern("middle")) nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, is_down);
167
+ if (buttons_id == rb_intern("right")) nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, is_down);
168
+ if (buttons_id == rb_intern("double")) nk_input_button(ctx, NK_BUTTON_DOUBLE, x, y, is_down);
169
+ if (buttons_id == rb_intern("max")) nk_input_button(ctx, NK_BUTTON_MAX, x, y, is_down);
170
+
171
+ return self;
172
+ }
173
+
174
+ VALUE nkrb_event_sink_scroll(VALUE self, VALUE x, VALUE y) {
175
+ VALUE_TO_NK(rb_ivar_get(self, rb_intern("@context")), ctx);
176
+ struct nk_vec2 vec;
177
+ vec.x = (float) NUM2DBL(x);
178
+ vec.y = (float) NUM2DBL(y);
179
+ nk_input_scroll(ctx, vec);
180
+ return self;
181
+ }
182
+
183
+ VALUE nkrb_event_sink_char(VALUE self, VALUE chr) {
184
+ VALUE_TO_NK(rb_ivar_get(self, rb_intern("@context")), ctx);
185
+ int ch = FIX2INT(rb_funcall(chr, rb_intern("ord"), 0));
186
+ nk_input_char(ctx, ch);
187
+ return self;
188
+ }
189
+
190
+ VALUE nkrb_event_sink_glyph(VALUE self, VALUE chr) {
191
+ VALUE_TO_NK(rb_ivar_get(self, rb_intern("@context")), ctx);
192
+ nk_glyph glyph;
193
+ int len = (int) RSTRING_LEN(chr);
194
+ if (len < NK_UTF_SIZE) {
195
+ if (len > 0) {
196
+ int i;
197
+ for (i = 0; i < len; i++) {
198
+ int ch = FIX2INT(rb_funcall(rb_funcall(chr, rb_intern("[]"), 1, INT2FIX(i)),
199
+ rb_intern("ord"), 0));
200
+ nk_input_char(ctx, ch);
201
+ }
202
+ } else {
203
+ rb_raise(rb_eArgError, "input is empty");
204
+ }
205
+ } else {
206
+ memcpy(glyph, StringValuePtr(chr), NK_UTF_SIZE);
207
+ nk_input_glyph(ctx, glyph);
208
+ }
209
+ return self;
210
+ }
211
+
212
+ // VALUE nkrb_event_sink_unicode(VALUE self, VALUE ch) {
213
+ //
214
+ // }
215
+
216
+ VALUE nkrb_context_ui(VALUE self) {
217
+ VALUE ui = rb_ivar_get(self, rb_intern("@ui_builder"));
218
+ rb_need_block();
219
+ rb_funcall_with_block(ui, rb_intern("instance_eval"), 0, NULL, rb_block_proc());
220
+ return ui;
221
+ }
222
+
223
+ void nkrb_context_init(void) {
224
+ cNuklearContext = rb_define_class_under(mNuklear, "Context", rb_cObject);
225
+ rb_define_alloc_func(cNuklearContext, nkrb_context_alloc);
226
+ rb_define_method(cNuklearContext, "user_data=", nkrb_context_set_user_data, 1);
227
+ rb_define_method(cNuklearContext, "user_data", nkrb_context_get_user_data, 0);
228
+ rb_define_method(cNuklearContext, "initialize", nkrb_context_initialize, 1);
229
+ rb_define_method(cNuklearContext, "tick", nkrb_context_tick, 0);
230
+ rb_define_method(cNuklearContext, "ui", nkrb_context_ui, 0);
231
+
232
+ cNuklearContextEventSink = rb_define_class_under(cNuklearContext, "EventSink", rb_cObject);
233
+ rb_define_method(cNuklearContextEventSink, "initialize", rb_nkrb_event_sink_initialize, 1);
234
+ rb_define_method(cNuklearContextEventSink, "motion", nkrb_event_sink_motion, 4);
235
+ rb_define_method(cNuklearContextEventSink, "key", nkrb_event_sink_key, 2);
236
+ rb_define_method(cNuklearContextEventSink, "button", nkrb_event_sink_button, 4);
237
+ rb_define_method(cNuklearContextEventSink, "scroll", nkrb_event_sink_scroll, 2);
238
+ rb_define_method(cNuklearContextEventSink, "char", nkrb_event_sink_char, 1);
239
+ rb_define_method(cNuklearContextEventSink, "glyph", nkrb_event_sink_glyph, 1);
240
+ // rb_define_method(cNuklearContextEventSink, "unicode", nkrb_event_sink_unicode, 1);
241
+ }