cyberarm_engine 0.14.0 → 0.18.0

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