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,39 @@
1
+ module Nuklear
2
+ module UI
3
+ class Checkbox < Nuklear::UI::Base
4
+ attr_accessor :text
5
+
6
+ def initialize(text, checked: false, enabled: true, &block)
7
+ super enabled: enabled
8
+ @text = text
9
+ @checked = checked
10
+ on(true) { @checked = true }
11
+ on(false) { @checked = false }
12
+ if block_given?
13
+ on true, &block
14
+ on false, &block
15
+ end
16
+ end
17
+
18
+ def checked?
19
+ @checked
20
+ end
21
+
22
+ def checked=(checked)
23
+ @checked = checked
24
+ @last_event = checked
25
+ end
26
+
27
+ alias selected? checked?
28
+ alias selected= checked=
29
+
30
+ def to_command
31
+ [ :ui_checkbox, text, checked? ]
32
+ end
33
+
34
+ def result(event, context)
35
+ trigger event
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ module Nuklear
2
+ module UI
3
+ class Col < Base
4
+ include Nuklear::UI::Container
5
+ attr_accessor :width
6
+
7
+ def initialize(width:, **options)
8
+ super(**options)
9
+ self.width = width
10
+ end
11
+
12
+ def to_command
13
+ [:ui_layout_row_push, width]
14
+ end
15
+
16
+ def result(_, context)
17
+ run_commands(context)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module Nuklear
2
+ module UI
3
+ class ColorPicker < Base
4
+ attr_accessor :color
5
+ attr_reader :type
6
+
7
+ def initialize(color, type: :rgba, **options)
8
+ super(**options)
9
+ self.color = color
10
+ self.type = type
11
+ end
12
+
13
+ def type=(t)
14
+ case t
15
+ when :rgb, :rgba then @type = t
16
+ else raise ArgumentError, "invalid color picker type, must be :rgb or :rgba"
17
+ end
18
+ end
19
+
20
+ def to_command
21
+ [:ui_color_picker, color, type]
22
+ end
23
+
24
+ def result(color, context)
25
+ @color = color
26
+ trigger :color_changed
27
+ @last_event = nil
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,42 @@
1
+ module Nuklear
2
+ module UI
3
+ class ComboBox < Nuklear::UI::Base
4
+ include Nuklear::UI::Container
5
+
6
+ attr_accessor :text, :image, :color, :symbol, :width, :height
7
+
8
+ def initialize(text: nil, image: nil, color: nil, symbol: nil, width:, height:, **options)
9
+ super(**options)
10
+ self.text = text
11
+ self.image = image
12
+ self.color = color
13
+ self.symbol = symbol
14
+ self.width = width
15
+ self.height = height
16
+ end
17
+
18
+ def red; color.red; end
19
+ def red=(a); color.red = a; end
20
+ def green; color.green; end
21
+ def green=(a); color.green = a; end
22
+ def blue; color.blue; end
23
+ def blue=(a); color.blue = a; end
24
+ def alpha; color.alpha; end
25
+ def alpha=(a); color.alpha = a; end
26
+ def hue; color.hue; end
27
+ def hue=(a); color.hue = a; end
28
+ def saturation; color.saturation; end
29
+ def saturation=(a); color.saturation = a; end
30
+ def value; color.value; end
31
+ def value=(a); color.value = a; end
32
+
33
+ def to_command
34
+ [ :ui_combobox, text, color, symbol, image, width, height ]
35
+ end
36
+
37
+ def result(expanded, context)
38
+ run_commands(context) if expanded
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,80 @@
1
+ module Nuklear
2
+ module UI
3
+ module Container
4
+ def commands
5
+ @commands ||= []
6
+ end
7
+
8
+ def run_command(context, command)
9
+ if command.respond_to?(:to_command)
10
+ if !command.respond_to?(:enabled?) || command.enabled?
11
+ cmd = command.to_command
12
+ result = send(cmd[0], context, *cmd[1..-1]) do |ret|
13
+ command.result(ret, context) if command.respond_to?(:result)
14
+ end
15
+ command.result(result, context) if !result.nil? && command.respond_to?(:result)
16
+ end
17
+ elsif command.respond_to?(:[])
18
+ send(command[0], context, *command[1..-1])
19
+ else
20
+ raise "Unexpected command #{command.inspect}"
21
+ end
22
+ end
23
+
24
+ def run_commands(context)
25
+ commands.each do |command|
26
+ if command.respond_to?(:to_commands)
27
+ command.to_commands.each { |cmd| run_command(context, cmd) }
28
+ else
29
+ run_command(context, command)
30
+ end
31
+ end
32
+ end
33
+
34
+ def <<(other)
35
+ commands << other
36
+ end
37
+
38
+ # Iterates over every item in this container, and yields each item
39
+ # (starting with the container itself) to the block.
40
+ def traverse(&block)
41
+ yield self
42
+ commands.each do |item|
43
+ if item.respond_to?(:traverse)
44
+ item.traverse(&block)
45
+ else
46
+ yield item
47
+ end
48
+ end
49
+ end
50
+
51
+ # Traverses this container and any of its sub-containers, yielding each
52
+ # item to the block. Returns each item for which the block returned true.
53
+ def find(&block)
54
+ matches = []
55
+ traverse do |item|
56
+ matches << item if yield(item)
57
+ end
58
+ return matches
59
+ end
60
+
61
+ LayoutRowDynamic = Struct.new(:height, :ncols) do
62
+ def to_command
63
+ [ :ui_layout_row_dynamic, height, ncols ]
64
+ end
65
+ end
66
+
67
+ def layout_row_dynamic(height, ncols)
68
+ LayoutRowDynamic.new(height, ncols).tap { |row| commands << row }
69
+ end
70
+
71
+ def method_missing(name, *args)
72
+ if respond_to?(:"ui_#{name}")
73
+ commands << [:"ui_#{name}", *args]
74
+ else
75
+ super
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,48 @@
1
+ module Nuklear
2
+ module UI
3
+ class EditString < Nuklear::UI::Base
4
+ attr_accessor :flags, :max_length, :filter, :text
5
+
6
+ def initialize(text: "", flags: 0, max_length: 255, filter: nil, enabled: true)
7
+ super enabled: enabled
8
+ @text = text
9
+ @flags = Nuklear.parse_flags :edit, flags
10
+ @max_length = max_length
11
+ @filter = filter
12
+ @demand_focus = false
13
+ end
14
+
15
+ def demand_focus?
16
+ @demand_focus
17
+ end
18
+
19
+ def focus
20
+ @demand_focus = true
21
+ end
22
+
23
+ def to_commands
24
+ if demand_focus?
25
+ @demand_focus = false
26
+ [
27
+ [:ui_edit_focus, flags],
28
+ self,
29
+ ]
30
+ else
31
+ [self]
32
+ end
33
+ end
34
+
35
+ def to_command
36
+ [:ui_edit_string, flags, text, max_length, filter]
37
+ end
38
+
39
+ def result(result, context)
40
+ trigger(:activated) if (result & Nuklear::NK_EDIT_ACTIVATED) > 0
41
+ trigger(:deactivated) if (result & Nuklear::NK_EDIT_DEACTIVATED) > 0
42
+ trigger(:committed) if (result & Nuklear::NK_EDIT_COMMITED) > 0
43
+ trigger(:active) if (result & Nuklear::NK_EDIT_ACTIVE) > 0
44
+ trigger(:inactive) if (result & Nuklear::NK_EDIT_INACTIVE) > 0
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ module Nuklear
2
+ module UI
3
+ module Enableable
4
+ def enabled=(a)
5
+ @enabled = a
6
+ end
7
+
8
+ def disabled=(a)
9
+ self.enabled = !a
10
+ end
11
+
12
+ def enable
13
+ self.enabled = true
14
+ end
15
+
16
+ def disable
17
+ self.enabled = false
18
+ end
19
+
20
+ def enabled?
21
+ @enabled.nil? ? true : @enabled
22
+ end
23
+
24
+ def disabled?
25
+ !enabled?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ module Nuklear
2
+ module UI
3
+ module Events
4
+ def on(*events, &block)
5
+ events.each do |event|
6
+ event_listeners_for(event) << block
7
+ end
8
+ end
9
+
10
+ def event_listeners_for(event)
11
+ @event_listeners ||= {}
12
+ @event_listeners[event] ||= []
13
+ end
14
+
15
+ def trigger(event)
16
+ if event != @last_event # prevent triggering every frame
17
+ event_listeners_for(event).each { |listener| listener.call event }
18
+ @last_event = event
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ module Nuklear
2
+ module UI
3
+ class Group < Nuklear::UI::Base
4
+ include Nuklear::UI::Container
5
+
6
+ attr_accessor :title, :scroll_x, :scroll_y
7
+
8
+ def initialize(title = object_id.to_s, **options)
9
+ super(**options)
10
+ @scroll_x = @scroll_y = 0
11
+ self.title = title
12
+ end
13
+
14
+ def to_command
15
+ [ :ui_group, title, flags, scroll_x, scroll_y ]
16
+ end
17
+
18
+ def flags
19
+ 0
20
+ end
21
+
22
+ def result(new_state, context)
23
+ if new_state.kind_of?(Array)
24
+ @scroll_x, @scroll_y = new_state
25
+ else
26
+ run_commands(context)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ module Nuklear
2
+ module UI
3
+ class Label < Nuklear::UI::Base
4
+ include Nuklear::UI::TextAlign
5
+
6
+ attr_accessor :text, :color, :wrap, :align
7
+
8
+ def initialize(text, color: nil, wrap: false, align: :left, **options)
9
+ super(**options)
10
+ self.text = text
11
+ self.color = color
12
+ self.wrap = wrap
13
+ self.align = align
14
+ end
15
+
16
+ def to_command
17
+ [:ui_label, text, color, wrap, align_as_flags(align)]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,43 @@
1
+ module Nuklear
2
+ module UI
3
+ class Menu < Nuklear::UI::Base
4
+ include Nuklear::UI::Container
5
+ include Nuklear::UI::TextAlign
6
+
7
+ attr_accessor :title, :image, :symbol, :align, :width, :height
8
+
9
+ def initialize(enabled: true, title: nil, image: nil, symbol: nil,
10
+ align: :left, width:, height:)
11
+ super enabled: enabled
12
+ @title = title
13
+ @image = image
14
+ @symbol = symbol
15
+ @align = align
16
+ @width = width
17
+ @height = height
18
+ end
19
+
20
+ def to_command
21
+ [:ui_menu, {
22
+ id: object_id,
23
+ title: title,
24
+ image: image,
25
+ symbol: symbol,
26
+ align: align_as_flags(align),
27
+ width: width,
28
+ height: height
29
+ }
30
+ ]
31
+ end
32
+
33
+ def visible?
34
+ @visible
35
+ end
36
+
37
+ def result(visible, context)
38
+ @visible = visible
39
+ run_commands(context) if visible
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ module Nuklear
2
+ module UI
3
+ class MenuBar < Nuklear::UI::Base
4
+ include Nuklear::UI::Container
5
+
6
+ def initialize(enabled: true)
7
+ super enabled: enabled
8
+ end
9
+
10
+ def to_command
11
+ [:ui_menubar]
12
+ end
13
+
14
+ def result(visible, context)
15
+ run_commands(context) if visible
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ module Nuklear
2
+ module UI
3
+ class MenuItem < Nuklear::UI::Base
4
+ include Nuklear::UI::Container
5
+ include Nuklear::UI::TextAlign
6
+
7
+ attr_accessor :title, :image, :symbol, :align
8
+
9
+ def initialize(enabled: true, title: nil, image: nil, symbol: nil, align: :left, &block)
10
+ super enabled: enabled
11
+ @title = title
12
+ @image = image
13
+ @symbol = symbol
14
+ @align = align
15
+ on(:clicked, &block) if block_given?
16
+ end
17
+
18
+ def to_command
19
+ [:ui_menu_item, {
20
+ title: title,
21
+ image: image,
22
+ symbol: symbol,
23
+ align: align_as_flags(align)
24
+ }
25
+ ]
26
+ end
27
+
28
+ def result(clicked, context)
29
+ trigger(:clicked)
30
+ @last_event = nil # trigger event each time
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ module Nuklear
2
+ module UI
3
+ class Option < Nuklear::UI::Checkbox
4
+ def to_command
5
+ [ :ui_option, text, checked? ]
6
+ end
7
+
8
+ # Override #result to prevent user deselecting this option by clicking
9
+ # on it. Checkbox can be deselected, option cannot. Only choosing a
10
+ # competing option can cause it to be deselected, and doing that does
11
+ # not call #result. See Nuklear::UI::OptionGroup.
12
+ def result(event, context)
13
+ trigger event if event
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module Nuklear
2
+ module UI
3
+ class OptionGroup < Base
4
+ include Nuklear::UI::Container
5
+
6
+ def initialize(**options)
7
+ super(**options)
8
+ @options = []
9
+ end
10
+
11
+ def selection=(selected)
12
+ @options.each { |option| option.selected = (option == selected) }
13
+ end
14
+
15
+ def <<(other)
16
+ super other
17
+ @options << other
18
+ other.on(true) { self.selection = other }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ require 'nuklear/ui/window'
2
+
3
+ module Nuklear
4
+ module UI
5
+ class Popup < Nuklear::UI::Window
6
+ attr_accessor :type
7
+
8
+ def initialize(title, type: :static, enabled: false, **options)
9
+ super title, enabled: enabled, **options
10
+ self.type = type
11
+ on(:visible) { self.enabled = true }
12
+ on(:hidden) { self.enabled = false }
13
+ end
14
+
15
+ def to_command
16
+ [:ui_popup,
17
+ type == :dynamic ? NK_POPUP_DYNAMIC : NK_POPUP_STATIC,
18
+ title,
19
+ flags,
20
+ left,
21
+ top,
22
+ width,
23
+ height
24
+ ]
25
+ end
26
+
27
+ def visible?
28
+ @enabled
29
+ end
30
+
31
+ def result(visibility, context)
32
+ trigger(visibility)
33
+ run_commands(context) if visible?
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ module Nuklear
2
+ module UI
3
+ class Progress < Base
4
+ attr_accessor :current, :min, :max
5
+ attr_writer :modifiable
6
+
7
+ def initialize(enabled: true, min: 1, max: 100, current: 1, modifiable: true)
8
+ super enabled: enabled
9
+ @min = min
10
+ @max = max
11
+ @current = current
12
+ @modifiable = modifiable
13
+ on(:changed) { yield @current } if block_given?
14
+ end
15
+
16
+ def to_command
17
+ [:ui_progress, current, max, modifiable?]
18
+ end
19
+
20
+ def modifiable?
21
+ @modifiable
22
+ end
23
+
24
+ def result(x, context)
25
+ x = min if x < min
26
+ return unless x != @current
27
+ @current = x
28
+ trigger :changed
29
+ @last_event = nil
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module Nuklear
2
+ module UI
3
+ class Property < Base
4
+ attr_accessor :current, :min, :max, :step, :inc_per_pixel, :text
5
+
6
+ def initialize(enabled: true, text: '', min: 1, max: 100, current: 1, step: 1, inc_per_pixel: 1)
7
+ super enabled: enabled
8
+ @text = text
9
+ @min = min
10
+ @max = max
11
+ @current = current
12
+ @step = step
13
+ @inc_per_pixel = inc_per_pixel
14
+ on(:changed) { yield @current } if block_given?
15
+ end
16
+
17
+ def to_command
18
+ [:ui_property, text, min, current, max, step, inc_per_pixel]
19
+ end
20
+
21
+ def result(x, context)
22
+ @current = x
23
+ trigger :changed
24
+ @last_event = nil
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ module Nuklear
2
+ module UI
3
+ class Row < Base
4
+ include Nuklear::UI::Container
5
+ attr_accessor :height, :type, :width
6
+
7
+ def initialize(height:, width: nil, type: nil, **options)
8
+ super(**options)
9
+ self.type = type
10
+ self.height = height
11
+ self.width = width
12
+ raise ArgumentError, ":width is required if type is :static" if type == :static && width.nil?
13
+ end
14
+
15
+ def to_command
16
+ case type
17
+ when :dynamic then [:ui_layout_row_dynamic, height, commands.size]
18
+ when :static then [:ui_layout_row_static, height, width, commands.size]
19
+ else [:ui_layout_row_begin, type || :static, height, commands.size]
20
+ end
21
+ end
22
+
23
+ def result(_, context)
24
+ run_commands(context)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ module Nuklear
2
+ module UI
3
+ class SelectList < Nuklear::UI::Base
4
+ include Nuklear::UI::Container
5
+
6
+ attr_accessor :choices, :selection, :item_height, :width, :height
7
+
8
+ def initialize(choices, selection: choices[0], item_height:, width:, height:, **options)
9
+ super(**options)
10
+ self.choices = choices
11
+ self.selection = selection
12
+ self.item_height = item_height
13
+ self.width = width
14
+ self.height = height
15
+ on(:selection_changed) { yield self.selection } if block_given?
16
+ end
17
+
18
+ def to_command
19
+ [ :ui_combo, choices.index(selection) || 0, choices, item_height, width, height ]
20
+ end
21
+
22
+ def result(choice_index, context)
23
+ if @selection != choices[choice_index]
24
+ @selection = choices[choice_index]
25
+ trigger(:selection_changed)
26
+ @last_event = nil
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ module Nuklear
2
+ module UI
3
+ class Selectable < Nuklear::UI::Checkbox
4
+ include Nuklear::UI::TextAlign
5
+
6
+ attr_accessor :image, :text, :align
7
+
8
+ def initialize(text: nil, align: :left, image: nil, selected: false, **options, &block)
9
+ super(**options, &block)
10
+ self.selected = selected
11
+ @text = text
12
+ @image = image
13
+ @align = align
14
+ end
15
+
16
+ def to_command
17
+ [ :ui_selectable, image, text, selected?, align_as_flags(align) ]
18
+ end
19
+ end
20
+ end
21
+ end