cyberarm_engine 0.14.0 → 0.18.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -1
  4. data/README.md +5 -4
  5. data/Rakefile +1 -1
  6. data/assets/textures/default.png +0 -0
  7. data/assets/textures/logo.png +0 -0
  8. data/cyberarm_engine.gemspec +11 -9
  9. data/lib/cyberarm_engine.rb +19 -7
  10. data/lib/cyberarm_engine/animator.rb +13 -11
  11. data/lib/cyberarm_engine/background.rb +19 -15
  12. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  13. data/lib/cyberarm_engine/bounding_box.rb +18 -18
  14. data/lib/cyberarm_engine/builtin/intro_state.rb +128 -0
  15. data/lib/cyberarm_engine/cache.rb +4 -0
  16. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  17. data/lib/cyberarm_engine/common.rb +18 -13
  18. data/lib/cyberarm_engine/config_file.rb +2 -2
  19. data/lib/cyberarm_engine/game_object.rb +63 -72
  20. data/lib/cyberarm_engine/game_state.rb +11 -3
  21. data/lib/cyberarm_engine/model.rb +207 -0
  22. data/lib/cyberarm_engine/model/material.rb +21 -0
  23. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  24. data/lib/cyberarm_engine/model/parser.rb +74 -0
  25. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  26. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  27. data/lib/cyberarm_engine/model_cache.rb +31 -0
  28. data/lib/cyberarm_engine/opengl.rb +28 -0
  29. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  30. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  31. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  32. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  33. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  34. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  35. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  36. data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
  37. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  38. data/lib/cyberarm_engine/ray.rb +5 -5
  39. data/lib/cyberarm_engine/stats.rb +2 -2
  40. data/lib/cyberarm_engine/text.rb +51 -27
  41. data/lib/cyberarm_engine/timer.rb +1 -1
  42. data/lib/cyberarm_engine/transform.rb +43 -20
  43. data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
  44. data/lib/cyberarm_engine/ui/dsl.rb +45 -12
  45. data/lib/cyberarm_engine/ui/element.rb +211 -61
  46. data/lib/cyberarm_engine/ui/elements/button.rb +72 -42
  47. data/lib/cyberarm_engine/ui/elements/check_box.rb +5 -2
  48. data/lib/cyberarm_engine/ui/elements/container.rb +81 -29
  49. data/lib/cyberarm_engine/ui/elements/edit_box.rb +175 -2
  50. data/lib/cyberarm_engine/ui/elements/edit_line.rb +139 -48
  51. data/lib/cyberarm_engine/ui/elements/flow.rb +1 -1
  52. data/lib/cyberarm_engine/ui/elements/image.rb +32 -12
  53. data/lib/cyberarm_engine/ui/elements/list_box.rb +78 -2
  54. data/lib/cyberarm_engine/ui/elements/progress.rb +5 -5
  55. data/lib/cyberarm_engine/ui/elements/radio.rb +1 -1
  56. data/lib/cyberarm_engine/ui/elements/slider.rb +13 -16
  57. data/lib/cyberarm_engine/ui/elements/stack.rb +1 -1
  58. data/lib/cyberarm_engine/ui/elements/text_block.rb +153 -0
  59. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +27 -19
  60. data/lib/cyberarm_engine/ui/event.rb +7 -7
  61. data/lib/cyberarm_engine/ui/gui_state.rb +88 -16
  62. data/lib/cyberarm_engine/ui/style.rb +23 -11
  63. data/lib/cyberarm_engine/ui/theme.rb +95 -21
  64. data/lib/cyberarm_engine/vector.rb +33 -30
  65. data/lib/cyberarm_engine/version.rb +2 -2
  66. data/lib/cyberarm_engine/window.rb +35 -18
  67. metadata +70 -18
  68. data/lib/cyberarm_engine/ui/elements/label.rb +0 -52
@@ -2,28 +2,41 @@ module CyberarmEngine
2
2
  class Element
3
3
  class EditLine < Button
4
4
  def initialize(text, options = {}, block = nil)
5
+ @filter = options.delete(:filter)
5
6
  super(text, options, block)
6
7
 
7
8
  @type = default(:type)
8
9
 
9
10
  @caret_width = default(:caret_width)
10
- @caret_height= @text.height
11
+ @caret_height = @text.textobject.height
11
12
  @caret_color = default(:caret_color)
12
13
  @caret_interval = default(:caret_interval)
13
14
  @caret_last_interval = Gosu.milliseconds
14
- @show_caret = true
15
+ @show_caret = true
15
16
 
16
17
  @text_input = Gosu::TextInput.new
17
18
  @text_input.text = text
19
+ @last_text_value = text
20
+
21
+ if @filter && @filter.respond_to?(:call)
22
+ @text_input.instance_variable_set(:@filter, @filter)
23
+
24
+ def @text_input.filter(text_in)
25
+ @filter.call(text_in)
26
+ end
27
+ end
18
28
 
19
29
  @offset_x = 0
30
+ @offset_y = 0
20
31
 
21
- return self
32
+ event(:begin_drag)
33
+ event(:drag_update)
34
+ event(:end_drag)
22
35
  end
23
36
 
24
37
  def render
25
- Gosu.clip_to(@text.x, @text.y, @style.width, @text.height) do
26
- Gosu.translate(-@offset_x, 0) do
38
+ Gosu.clip_to(@text.x, @text.y, @width, @height) do
39
+ Gosu.translate(-@offset_x, -@offset_y) do
27
40
  draw_selection
28
41
  draw_caret if @focus && @show_caret
29
42
  draw_text
@@ -31,6 +44,10 @@ module CyberarmEngine
31
44
  end
32
45
  end
33
46
 
47
+ def draw_text
48
+ @text.draw(:draw_text)
49
+ end
50
+
34
51
  def draw_caret
35
52
  Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z)
36
53
  end
@@ -42,10 +59,20 @@ module CyberarmEngine
42
59
  end
43
60
 
44
61
  def update
45
- if @type == :password
46
- @text.text = default(:password_character) * @text_input.text.length
47
- else
48
- @text.text = @text_input.text
62
+ @style_event = :active if @focus
63
+
64
+ @text.text = if @type == :password
65
+ default(:password_character) * @text_input.text.length
66
+ else
67
+ @text_input.text
68
+ end
69
+
70
+ if @last_text_value != value
71
+ @last_text_value = value
72
+ @show_caret = true
73
+ @caret_last_interval = Gosu.milliseconds
74
+
75
+ publish(:changed, value)
49
76
  end
50
77
 
51
78
  if Gosu.milliseconds >= @caret_last_interval + @caret_interval
@@ -57,15 +84,60 @@ module CyberarmEngine
57
84
  keep_caret_visible
58
85
  end
59
86
 
60
- def move_caret_to_mouse(mouse_x)
61
- 1.upto(@text.text.length) do |i|
62
- if mouse_x < @text.x + @text.textobject.text_width(@text.text[0...i])
63
- @text_input.caret_pos = @text_input.selection_start = i - 1;
64
- return
87
+ def button_down(id)
88
+ handle_keyboard_shortcuts(id)
89
+ end
90
+
91
+ def handle_keyboard_shortcuts(id)
92
+ return unless @focus && @enabled
93
+
94
+ if Gosu.button_down?(Gosu::KB_LEFT_CONTROL) || Gosu.button_down?(Gosu::KB_RIGHT_CONTROL)
95
+ case id
96
+ when Gosu::KB_A
97
+ @text_input.selection_start = 0
98
+ @text_input.caret_pos = @text_input.text.length
99
+
100
+ when Gosu::KB_C
101
+ if @text_input.selection_start < @text_input.caret_pos
102
+ Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos])
103
+ else
104
+ Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start])
105
+ end
106
+
107
+ when Gosu::KB_X
108
+ chars = @text_input.text.chars
109
+
110
+ if @text_input.selection_start < @text_input.caret_pos
111
+ Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos])
112
+ chars.slice!(@text_input.selection_start, @text_input.caret_pos)
113
+ else
114
+ Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start])
115
+ chars.slice!(@text_input.caret_pos, @text_input.selection_start)
116
+ end
117
+
118
+ @text_input.text = chars.join
119
+
120
+ when Gosu::KB_V
121
+ if instance_of?(EditLine) # EditLine assumes a single line of text
122
+ @text_input.text = @text_input.text.insert(@text_input.caret_pos,
123
+ Clipboard.paste.encode("UTF-8").gsub("\n", ""))
124
+ else
125
+ @text_input.text = @text_input.text.insert(@text_input.caret_pos, Clipboard.paste.encode("UTF-8"))
126
+ end
65
127
  end
66
128
  end
129
+ end
67
130
 
68
- @text_input.caret_pos = @text_input.selection_start = @text_input.text.length
131
+ def caret_position_under_mouse(mouse_x)
132
+ 1.upto(@text.text.length) do |i|
133
+ return i - 1 if mouse_x < @text.x - @offset_x + @text.width(@text.text[0...i])
134
+ end
135
+
136
+ @text_input.text.length
137
+ end
138
+
139
+ def move_caret_to_mouse(mouse_x, _mouse_y)
140
+ @text_input.caret_pos = @text_input.selection_start = caret_position_under_mouse(mouse_x)
69
141
  end
70
142
 
71
143
  def keep_caret_visible
@@ -74,25 +146,21 @@ module CyberarmEngine
74
146
  @last_text ||= "/\\"
75
147
  @last_pos ||= -1
76
148
 
77
- puts "caret pos: #{caret_pos}, width: #{@width}, offset: #{@offset_x}" if (@last_text != @text.text) || (@last_pos != caret_pos)
78
-
79
149
  @last_text = @text.text
80
150
  @last_pos = caret_pos
81
151
 
82
-
83
152
  if caret_pos.between?(@offset_x, @width + @offset_x)
84
153
  # Do nothing
85
154
 
86
155
  elsif caret_pos < @offset_x
87
- if caret_pos > @width
88
- @offset_x = caret_pos + @width
89
- else
90
- @offset_x = 0
91
- end
156
+ @offset_x = if caret_pos > @width
157
+ caret_pos + @width
158
+ else
159
+ 0
160
+ end
92
161
 
93
162
  elsif caret_pos > @width
94
163
  @offset_x = caret_pos - @width
95
- puts "triggered"
96
164
 
97
165
  else
98
166
  # Reset to Zero
@@ -110,9 +178,9 @@ module CyberarmEngine
110
178
 
111
179
  def text_input_position_for(method)
112
180
  if @type == :password
113
- @text.x + @text.width(default(:password_character) * @text_input.text[0..@text_input.send(method)].length)
181
+ @text.x + @text.width(default(:password_character) * @text_input.text[0...@text_input.send(method)].length)
114
182
  else
115
- @text.x + @text.width(@text_input.text[0..@text_input.send(method)])
183
+ @text.x + @text.width(@text_input.text[0...@text_input.send(method)])
116
184
  end
117
185
  end
118
186
 
@@ -123,38 +191,57 @@ module CyberarmEngine
123
191
  @caret_last_interval = Gosu.milliseconds
124
192
  @show_caret = true
125
193
 
126
- move_caret_to_mouse(x)
194
+ move_caret_to_mouse(x, y)
127
195
 
128
- return :handled
196
+ :handled
129
197
  end
130
198
 
131
- def enter(sender)
132
- if @focus
133
- @style.background_canvas.background = default(:active, :background)
134
- @text.color = default(:active, :color)
135
- else
136
- @style.background_canvas.background = default(:hover, :background)
137
- @text.color = default(:hover, :color)
138
- end
199
+ def focus(sender)
200
+ super
201
+
202
+ window.text_input = @text_input
203
+ @text_input.caret_pos = @text_input.selection_start = @text_input.text.length
139
204
 
140
- return :handled
205
+ :handled
141
206
  end
142
207
 
143
- def leave(sender)
144
- unless @focus
145
- super
146
- end
208
+ def enter(sender)
209
+ _has_focus = @focus
210
+
211
+ super
212
+
213
+ @focus = _has_focus
147
214
 
148
- return :handled
215
+ :handled
149
216
  end
150
217
 
151
- def blur(sender)
152
- @focus = false
153
- @style.background_canvas.background = default(:background)
154
- @text.color = default(:color)
218
+ def blur(_sender)
219
+ super
155
220
  window.text_input = nil
156
221
 
157
- return :handled
222
+ :handled
223
+ end
224
+
225
+ def draggable?(button)
226
+ button == :left
227
+ end
228
+
229
+ def begin_drag(_sender, x, _y, _button)
230
+ @drag_start = x
231
+ @offset_drag_start = @offset_x
232
+ @drag_caret_position = @text_input.caret_pos
233
+
234
+ :handled
235
+ end
236
+
237
+ def drag_update(_sender, x, _y, _button)
238
+ @text_input.caret_pos = caret_position_under_mouse(x)
239
+
240
+ :handled
241
+ end
242
+
243
+ def end_drag(_sender, _x, _y, _button)
244
+ :handled
158
245
  end
159
246
 
160
247
  def recalculate
@@ -167,6 +254,10 @@ module CyberarmEngine
167
254
  def value
168
255
  @text_input.text
169
256
  end
257
+
258
+ def value=(string)
259
+ @text_input.text = string
260
+ end
170
261
  end
171
262
  end
172
- end
263
+ end
@@ -12,4 +12,4 @@ module CyberarmEngine
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -1,12 +1,15 @@
1
1
  module CyberarmEngine
2
2
  class Element
3
3
  class Image < Element
4
- def initialize(path, options = {}, block = nil)
4
+ def initialize(path_or_image, options = {}, block = nil)
5
5
  super(options, block)
6
- @path = path
6
+ @path = path_or_image if path_or_image.is_a?(String)
7
7
 
8
- @image = Gosu::Image.new(path, retro: @options[:image_retro])
9
- @scale_x, @scale_y = 1, 1
8
+ @image = Gosu::Image.new(path_or_image, retro: @options[:retro], tileable: @options[:tileable]) if @path
9
+ @image = path_or_image unless @path
10
+
11
+ @scale_x = 1
12
+ @scale_y = 1
10
13
  end
11
14
 
12
15
  def render
@@ -14,18 +17,19 @@ module CyberarmEngine
14
17
  @style.border_thickness_left + @style.padding_left + @x,
15
18
  @style.border_thickness_top + @style.padding_top + @y,
16
19
  @z + 2,
17
- @scale_x, @scale_y) # TODO: Add color support?
20
+ @scale_x, @scale_y, @style.color
21
+ )
18
22
  end
19
23
 
20
- def clicked_left_mouse_button(sender, x, y)
24
+ def clicked_left_mouse_button(_sender, _x, _y)
21
25
  @block.call(self) if @block
22
26
 
23
- return :handled
27
+ :handled
24
28
  end
25
29
 
26
30
  def recalculate
27
31
  _width = dimensional_size(@style.width, :width)
28
- _height= dimensional_size(@style.height,:height)
32
+ _height = dimensional_size(@style.height, :height)
29
33
 
30
34
  if _width && _height
31
35
  @scale_x = _width.to_f / @image.width
@@ -37,16 +41,32 @@ module CyberarmEngine
37
41
  @scale_y = _height.to_f / @image.height
38
42
  @scale_x = @scale_y
39
43
  else
40
- @scale_x, @scale_y = 1, 1
44
+ @scale_x = 1
45
+ @scale_y = 1
41
46
  end
42
47
 
43
- @width = _width ? _width : @image.width.round * @scale_x
44
- @height= _height ? _height : @image.height.round * @scale_y
48
+ @width = _width || @image.width.round * @scale_x
49
+ @height = _height || @image.height.round * @scale_y
50
+
51
+ update_background
45
52
  end
46
53
 
47
54
  def value
55
+ @image
56
+ end
57
+
58
+ def value=(path_or_image, retro: false, tileable: false)
59
+ @path = path_or_image if path_or_image.is_a?(String)
60
+
61
+ @image = Gosu::Image.new(path_or_image, retro: retro, tileable: tileable) if @path
62
+ @image = path_or_image unless @path
63
+
64
+ recalculate
65
+ end
66
+
67
+ def path
48
68
  @path
49
69
  end
50
70
  end
51
71
  end
52
- end
72
+ end
@@ -1,6 +1,82 @@
1
1
  module CyberarmEngine
2
2
  class Element
3
- class ListBox < Element
3
+ class ListBox < Button
4
+ attr_accessor :items
5
+ attr_reader :choose
6
+
7
+ def initialize(options = {}, block = nil)
8
+ @items = options[:items] || []
9
+ @choose = options[:choose] || @items.first
10
+
11
+ super(@choose, options, block)
12
+
13
+ @style.background_canvas.background = default(:background)
14
+
15
+ # TODO: "Clean Up" into own class?
16
+ @menu = Stack.new(parent: parent, width: @options[:width], theme: @options[:theme])
17
+ @menu.define_singleton_method(:recalculate_menu) do
18
+ @x = @__list_box.x
19
+ @y = @__list_box.y + @__list_box.height
20
+ end
21
+ @menu.instance_variable_set(:"@__list_box", self)
22
+
23
+ def @menu.recalculate
24
+ super
25
+
26
+ recalculate_menu
27
+ end
28
+
29
+ self.choose = @choose
30
+ end
31
+
32
+ def choose=(item)
33
+ valid = @items.detect { |i| i == item }
34
+ raise "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}" unless valid
35
+
36
+ @choose = item
37
+
38
+ self.value = item.to_s
39
+
40
+ recalculate
41
+ end
42
+
43
+ def released_left_mouse_button(_sender, _x, _y)
44
+ show_menu
45
+
46
+ :handled
47
+ end
48
+
49
+ def show_menu
50
+ @menu.clear
51
+
52
+ @items.each do |item|
53
+ btn = Button.new(
54
+ item,
55
+ {
56
+ parent: @menu,
57
+ width: 1.0,
58
+ theme: @options[:theme],
59
+ margin: 0,
60
+ border_color: 0x00ffffff
61
+ },
62
+ proc do
63
+ self.choose = item
64
+ @block&.call(item)
65
+ end
66
+ )
67
+
68
+ @menu.add(btn)
69
+ end
70
+ recalculate
71
+
72
+ root.gui_state.show_menu(@menu)
73
+ end
74
+
75
+ def recalculate
76
+ super
77
+
78
+ @menu.recalculate
79
+ end
4
80
  end
5
81
  end
6
- end
82
+ end