nuklear 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }