cyberarm_engine 0.19.0 → 0.19.1

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/LICENSE.txt +21 -21
  7. data/README.md +74 -74
  8. data/Rakefile +10 -10
  9. data/bin/console +14 -14
  10. data/bin/setup +8 -8
  11. data/cyberarm_engine.gemspec +39 -39
  12. data/lib/cyberarm_engine/animator.rb +219 -219
  13. data/lib/cyberarm_engine/background.rb +179 -179
  14. data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
  15. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  16. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  17. data/lib/cyberarm_engine/cache/download_manager.rb +121 -121
  18. data/lib/cyberarm_engine/cache.rb +4 -4
  19. data/lib/cyberarm_engine/common.rb +113 -113
  20. data/lib/cyberarm_engine/config_file.rb +46 -46
  21. data/lib/cyberarm_engine/console/command.rb +157 -157
  22. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  23. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  24. data/lib/cyberarm_engine/console.rb +248 -248
  25. data/lib/cyberarm_engine/game_object.rb +248 -248
  26. data/lib/cyberarm_engine/game_state.rb +97 -97
  27. data/lib/cyberarm_engine/model/material.rb +21 -21
  28. data/lib/cyberarm_engine/model/model_object.rb +131 -131
  29. data/lib/cyberarm_engine/model/parser.rb +74 -74
  30. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  31. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  32. data/lib/cyberarm_engine/model.rb +212 -212
  33. data/lib/cyberarm_engine/model_cache.rb +31 -31
  34. data/lib/cyberarm_engine/opengl/light.rb +50 -50
  35. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  36. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -38
  37. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  38. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -164
  39. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +298 -298
  40. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -22
  41. data/lib/cyberarm_engine/opengl/shader.rb +406 -406
  42. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  43. data/lib/cyberarm_engine/opengl.rb +28 -28
  44. data/lib/cyberarm_engine/ray.rb +56 -56
  45. data/lib/cyberarm_engine/stats.rb +21 -21
  46. data/lib/cyberarm_engine/text.rb +197 -197
  47. data/lib/cyberarm_engine/timer.rb +23 -23
  48. data/lib/cyberarm_engine/transform.rb +296 -296
  49. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  50. data/lib/cyberarm_engine/ui/dsl.rb +139 -139
  51. data/lib/cyberarm_engine/ui/element.rb +488 -488
  52. data/lib/cyberarm_engine/ui/elements/button.rb +97 -97
  53. data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
  54. data/lib/cyberarm_engine/ui/elements/container.rb +256 -256
  55. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
  56. data/lib/cyberarm_engine/ui/elements/edit_line.rb +263 -263
  57. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  58. data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
  59. data/lib/cyberarm_engine/ui/elements/list_box.rb +88 -82
  60. data/lib/cyberarm_engine/ui/elements/progress.rb +51 -51
  61. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  62. data/lib/cyberarm_engine/ui/elements/slider.rb +104 -104
  63. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  64. data/lib/cyberarm_engine/ui/elements/text_block.rb +162 -162
  65. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +65 -65
  66. data/lib/cyberarm_engine/ui/event.rb +54 -54
  67. data/lib/cyberarm_engine/ui/gui_state.rb +256 -256
  68. data/lib/cyberarm_engine/ui/style.rb +49 -49
  69. data/lib/cyberarm_engine/ui/theme.rb +207 -207
  70. data/lib/cyberarm_engine/vector.rb +293 -293
  71. data/lib/cyberarm_engine/version.rb +4 -4
  72. data/lib/cyberarm_engine/window.rb +120 -120
  73. data/lib/cyberarm_engine.rb +71 -71
  74. metadata +3 -3
@@ -1,488 +1,488 @@
1
- module CyberarmEngine
2
- class Element
3
- include Theme
4
- include Event
5
- include Common
6
-
7
- attr_accessor :x, :y, :z, :enabled, :tip
8
- attr_reader :parent, :options, :style, :event_handler, :background_canvas, :border_canvas
9
-
10
- def initialize(options = {}, block = nil)
11
- @parent = options.delete(:parent) # parent Container (i.e. flow/stack)
12
- options = theme_defaults(options)
13
- @options = options
14
- @block = block
15
-
16
- @focus = @options[:focus].nil? ? false : @options[:focus]
17
- @enabled = @options[:enabled].nil? ? true : @options[:enabled]
18
- @visible = @options[:visible].nil? ? true : @options[:visible]
19
- @tip = @options[:tip] || ""
20
-
21
- @debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]
22
-
23
- @style = Style.new(options)
24
-
25
- @root ||= nil
26
- @gui_state ||= nil
27
-
28
- @x = @style.x
29
- @y = @style.y
30
- @z = @style.z
31
-
32
- @width = 0
33
- @height = 0
34
-
35
- @style.width = default(:width) || nil
36
- @style.height = default(:height) || nil
37
-
38
- @style.background_canvas = Background.new
39
- @style.background_nine_slice_canvas = BackgroundNineSlice.new
40
- @style.border_canvas = BorderCanvas.new(element: self)
41
-
42
- @style_event = :default
43
-
44
- stylize
45
-
46
- default_events
47
-
48
- root.gui_state.request_focus(self) if @options[:autofocus]
49
- end
50
-
51
- def stylize
52
- set_static_position
53
-
54
- set_padding
55
- set_margin
56
-
57
- set_background
58
- set_background_nine_slice
59
-
60
- set_border_thickness
61
- set_border_color
62
- end
63
-
64
- def safe_style_fetch(*args)
65
- @style.hash.dig(@style_event, *args) || @style.hash.dig(:default, *args) || default(*args)
66
- end
67
-
68
- def set_static_position
69
- @x = @style.x if @style.x != 0
70
- @y = @style.y if @style.y != 0
71
- end
72
-
73
- def set_background
74
- @style.background = safe_style_fetch(:background)
75
-
76
- @style.background_canvas.background = @style.background
77
- end
78
-
79
- def set_background_nine_slice
80
- @style.background_nine_slice = safe_style_fetch(:background_nine_slice)
81
-
82
- @style.background_nine_slice_mode = safe_style_fetch(:background_nine_slice_mode) || :stretch
83
- @style.background_nine_slice_color = safe_style_fetch(:background_nine_slice_color) || Gosu::Color::WHITE
84
- @style.background_nine_slice_canvas.color = @style.background_nine_slice_color
85
-
86
- @style.background_nine_slice_from_edge = safe_style_fetch(:background_nine_slice_from_edge)
87
-
88
- @style.background_nine_slice_left = safe_style_fetch(:background_nine_slice_left) || @style.background_nine_slice_from_edge
89
- @style.background_nine_slice_top = safe_style_fetch(:background_nine_slice_top) || @style.background_nine_slice_from_edge
90
- @style.background_nine_slice_right = safe_style_fetch(:background_nine_slice_right) || @style.background_nine_slice_from_edge
91
- @style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom) || @style.background_nine_slice_from_edge
92
- end
93
-
94
- def set_border_thickness
95
- @style.border_thickness = safe_style_fetch(:border_thickness)
96
-
97
- @style.border_thickness_left = safe_style_fetch(:border_thickness_left) || @style.border_thickness
98
- @style.border_thickness_right = safe_style_fetch(:border_thickness_right) || @style.border_thickness
99
- @style.border_thickness_top = safe_style_fetch(:border_thickness_top) || @style.border_thickness
100
- @style.border_thickness_bottom = safe_style_fetch(:border_thickness_bottom) || @style.border_thickness
101
- end
102
-
103
- def set_border_color
104
- @style.border_color = safe_style_fetch(:border_color)
105
-
106
- @style.border_color_left = safe_style_fetch(:border_color_left) || @style.border_color
107
- @style.border_color_right = safe_style_fetch(:border_color_right) || @style.border_color
108
- @style.border_color_top = safe_style_fetch(:border_color_top) || @style.border_color
109
- @style.border_color_bottom = safe_style_fetch(:border_color_bottom) || @style.border_color
110
-
111
- @style.border_canvas.color = [
112
- @style.border_color_top,
113
- @style.border_color_right,
114
- @style.border_color_bottom,
115
- @style.border_color_left
116
- ]
117
- end
118
-
119
- def set_padding
120
- @style.padding = safe_style_fetch(:padding)
121
-
122
- @style.padding_left = safe_style_fetch(:padding_left) || @style.padding
123
- @style.padding_right = safe_style_fetch(:padding_right) || @style.padding
124
- @style.padding_top = safe_style_fetch(:padding_top) || @style.padding
125
- @style.padding_bottom = safe_style_fetch(:padding_bottom) || @style.padding
126
- end
127
-
128
- def set_margin
129
- @style.margin = safe_style_fetch(:margin)
130
-
131
- @style.margin_left = safe_style_fetch(:margin_left) || @style.margin
132
- @style.margin_right = safe_style_fetch(:margin_right) || @style.margin
133
- @style.margin_top = safe_style_fetch(:margin_top) || @style.margin
134
- @style.margin_bottom = safe_style_fetch(:margin_bottom) || @style.margin
135
- end
136
-
137
- def update_styles(event = :default)
138
- old_width = width
139
- old_height = height
140
-
141
- _style = @style.send(event)
142
- @style_event = event
143
-
144
- if @text.is_a?(CyberarmEngine::Text)
145
- @text.color = _style&.dig(:color) || @style.default[:color]
146
- @text.swap_font(_style&.dig(:text_size) || @style.default[:text_size], _style&.dig(:font) || @style.default[:font])
147
- end
148
-
149
- return if self.is_a?(ToolTip)
150
-
151
- if old_width != width || old_height != height
152
- (root&.gui_state || @gui_state).request_recalculate
153
- else
154
- stylize
155
- end
156
- end
157
-
158
- def default_events
159
- %i[left middle right].each do |button|
160
- event(:"#{button}_mouse_button")
161
- event(:"released_#{button}_mouse_button")
162
- event(:"clicked_#{button}_mouse_button")
163
- event(:"holding_#{button}_mouse_button")
164
- end
165
-
166
- event(:mouse_wheel_up)
167
- event(:mouse_wheel_down)
168
-
169
- event(:enter)
170
- event(:hover)
171
- event(:leave)
172
-
173
- event(:focus)
174
- event(:blur)
175
-
176
- event(:changed)
177
- end
178
-
179
- def enter(_sender)
180
- @focus = false unless window.button_down?(Gosu::MsLeft)
181
-
182
- if !@enabled
183
- update_styles(:disabled)
184
- elsif @focus
185
- update_styles(:active)
186
- else
187
- update_styles(:hover)
188
- end
189
-
190
- :handled
191
- end
192
-
193
- def left_mouse_button(_sender, _x, _y)
194
- @focus = true
195
-
196
- unless @enabled
197
- update_styles(:disabled)
198
- else
199
- update_styles(:active)
200
- end
201
-
202
- window.current_state.focus = self
203
-
204
- :handled
205
- end
206
-
207
- def released_left_mouse_button(sender, _x, _y)
208
- enter(sender)
209
-
210
- :handled
211
- end
212
-
213
- def clicked_left_mouse_button(_sender, _x, _y)
214
- @block&.call(self) if @enabled && !self.is_a?(Container)
215
-
216
- :handled
217
- end
218
-
219
- def leave(_sender)
220
- if @enabled
221
- update_styles
222
- else
223
- update_styles(:disabled)
224
- end
225
-
226
- :handled
227
- end
228
-
229
- def blur(_sender)
230
- @focus = false
231
-
232
- if @enabled
233
- update_styles
234
- else
235
- update_styles(:disabled)
236
- end
237
-
238
- :handled
239
- end
240
-
241
- def enabled?
242
- @enabled
243
- end
244
-
245
- def visible?
246
- @visible
247
- end
248
-
249
- def toggle
250
- @visible = !@visible
251
- root.gui_state.request_recalculate
252
- end
253
-
254
- def show
255
- bool = visible?
256
- @visible = true
257
- root.gui_state.request_recalculate unless bool
258
- end
259
-
260
- def hide
261
- bool = visible?
262
- @visible = false
263
- root.gui_state.request_recalculate if bool
264
- end
265
-
266
- def draw
267
- return unless visible?
268
-
269
- @style.background_canvas.draw
270
- @style.background_nine_slice_canvas.draw
271
- @style.border_canvas.draw
272
-
273
- Gosu.clip_to(@x, @y, width, height) do
274
- render
275
- end
276
- end
277
-
278
- def debug_draw
279
- return if defined?(GUI_DEBUG_ONLY_ELEMENT) && self.class == GUI_DEBUG_ONLY_ELEMENT
280
-
281
- Gosu.draw_line(
282
- x, y, @debug_color,
283
- x + outer_width, y, @debug_color,
284
- Float::INFINITY
285
- )
286
- Gosu.draw_line(
287
- x + outer_width, y, @debug_color,
288
- x + outer_width, y + outer_height, @debug_color,
289
- Float::INFINITY
290
- )
291
- Gosu.draw_line(
292
- x + outer_width, y + outer_height, @debug_color,
293
- x, y + outer_height, @debug_color,
294
- Float::INFINITY
295
- )
296
- Gosu.draw_line(
297
- x, outer_height, @debug_color,
298
- x, y, @debug_color,
299
- Float::INFINITY
300
- )
301
- end
302
-
303
- def update
304
- end
305
-
306
- def button_down(id)
307
- end
308
-
309
- def button_up(id)
310
- end
311
-
312
- def draggable?(_button)
313
- false
314
- end
315
-
316
- def render
317
- end
318
-
319
- def hit?(x, y)
320
- x.between?(@x, @x + width) &&
321
- y.between?(@y, @y + height)
322
- end
323
-
324
- def width
325
- if visible?
326
- inner_width + @width
327
- else
328
- 0
329
- end
330
- end
331
-
332
- def content_width
333
- @width
334
- end
335
-
336
- def noncontent_width
337
- (inner_width + outer_width) - width
338
- end
339
-
340
- def outer_width
341
- @style.margin_left + width + @style.margin_right
342
- end
343
-
344
- def inner_width
345
- (@style.border_thickness_left + @style.padding_left) + (@style.padding_right + @style.border_thickness_right)
346
- end
347
-
348
- def height
349
- if visible?
350
- inner_height + @height
351
- else
352
- 0
353
- end
354
- end
355
-
356
- def content_height
357
- @height
358
- end
359
-
360
- def noncontent_height
361
- (inner_height + outer_height) - height
362
- end
363
-
364
- def outer_height
365
- @style.margin_top + height + @style.margin_bottom
366
- end
367
-
368
- def inner_height
369
- (@style.border_thickness_top + @style.padding_top) + (@style.padding_bottom + @style.border_thickness_bottom)
370
- end
371
-
372
- def scroll_width
373
- @children.sum(&:width) + noncontent_width
374
- end
375
-
376
- def scroll_height
377
- @children.sum(&:height) + noncontent_height
378
- end
379
-
380
- def max_scroll_width
381
- scroll_width - width
382
- end
383
-
384
- def max_scroll_height
385
- scroll_height - height
386
- end
387
-
388
- def dimensional_size(size, dimension)
389
- raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)
390
-
391
- if size.is_a?(Numeric) && size.between?(0.0, 1.0)
392
- (@parent.send(:"content_#{dimension}") * size).round - send(:"noncontent_#{dimension}").round
393
- else
394
- size
395
- end
396
- end
397
-
398
- def background=(_background)
399
- @style.background_canvas.background = _background
400
- update_background
401
- end
402
-
403
- def update_background
404
- @style.background_canvas.x = @x
405
- @style.background_canvas.y = @y
406
- @style.background_canvas.z = @z
407
- @style.background_canvas.width = width
408
- @style.background_canvas.height = height
409
-
410
- @style.background_canvas.update
411
- update_background_nine_slice
412
- @style.border_canvas.update
413
- end
414
-
415
- def background_nine_slice=(_image_path)
416
- @style.background_nine_slice_canvas.image = _image_path
417
- update_background_nine_slice
418
- end
419
-
420
- def update_background_nine_slice
421
- @style.background_nine_slice_canvas.x = @x
422
- @style.background_nine_slice_canvas.y = @y
423
- @style.background_nine_slice_canvas.z = @z
424
- @style.background_nine_slice_canvas.width = width
425
- @style.background_nine_slice_canvas.height = height
426
-
427
- @style.background_nine_slice_canvas.mode = @style.background_nine_slice_mode
428
-
429
- @style.background_nine_slice_canvas.color = @style.background_nine_slice_color
430
-
431
- @style.background_nine_slice_canvas.left = @style.background_nine_slice_left
432
- @style.background_nine_slice_canvas.top = @style.background_nine_slice_top
433
- @style.background_nine_slice_canvas.right = @style.background_nine_slice_right
434
- @style.background_nine_slice_canvas.bottom = @style.background_nine_slice_bottom
435
-
436
- @style.background_nine_slice_canvas.image = @style.background_nine_slice
437
- end
438
-
439
- def root
440
- return self if is_root?
441
-
442
- unless @root && @root.parent.nil?
443
- @root = parent
444
-
445
- loop do
446
- break unless @root&.parent
447
-
448
- @root = @root.parent
449
- end
450
- end
451
-
452
- @root
453
- end
454
-
455
- def is_root?
456
- @gui_state != nil
457
- end
458
-
459
- def focus(_)
460
- warn "#{self.class}#focus was not overridden!"
461
-
462
- :handled
463
- end
464
-
465
- def recalculate
466
- raise "#{self.class}#recalculate was not overridden!"
467
- end
468
-
469
- def reposition
470
- end
471
-
472
- def value
473
- raise "#{self.class}#value was not overridden!"
474
- end
475
-
476
- def value=(_value)
477
- raise "#{self.class}#value= was not overridden!"
478
- end
479
-
480
- def to_s
481
- "#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} value=#{value.is_a?(String) ? "\"#{value}\"" : value}"
482
- end
483
-
484
- def inspect
485
- to_s
486
- end
487
- end
488
- end
1
+ module CyberarmEngine
2
+ class Element
3
+ include Theme
4
+ include Event
5
+ include Common
6
+
7
+ attr_accessor :x, :y, :z, :enabled, :tip
8
+ attr_reader :parent, :options, :style, :event_handler, :background_canvas, :border_canvas
9
+
10
+ def initialize(options = {}, block = nil)
11
+ @parent = options.delete(:parent) # parent Container (i.e. flow/stack)
12
+ options = theme_defaults(options)
13
+ @options = options
14
+ @block = block
15
+
16
+ @focus = @options[:focus].nil? ? false : @options[:focus]
17
+ @enabled = @options[:enabled].nil? ? true : @options[:enabled]
18
+ @visible = @options[:visible].nil? ? true : @options[:visible]
19
+ @tip = @options[:tip] || ""
20
+
21
+ @debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]
22
+
23
+ @style = Style.new(options)
24
+
25
+ @root ||= nil
26
+ @gui_state ||= nil
27
+
28
+ @x = @style.x
29
+ @y = @style.y
30
+ @z = @style.z
31
+
32
+ @width = 0
33
+ @height = 0
34
+
35
+ @style.width = default(:width) || nil
36
+ @style.height = default(:height) || nil
37
+
38
+ @style.background_canvas = Background.new
39
+ @style.background_nine_slice_canvas = BackgroundNineSlice.new
40
+ @style.border_canvas = BorderCanvas.new(element: self)
41
+
42
+ @style_event = :default
43
+
44
+ stylize
45
+
46
+ default_events
47
+
48
+ root.gui_state.request_focus(self) if @options[:autofocus]
49
+ end
50
+
51
+ def stylize
52
+ set_static_position
53
+
54
+ set_padding
55
+ set_margin
56
+
57
+ set_background
58
+ set_background_nine_slice
59
+
60
+ set_border_thickness
61
+ set_border_color
62
+ end
63
+
64
+ def safe_style_fetch(*args)
65
+ @style.hash.dig(@style_event, *args) || @style.hash.dig(:default, *args) || default(*args)
66
+ end
67
+
68
+ def set_static_position
69
+ @x = @style.x if @style.x != 0
70
+ @y = @style.y if @style.y != 0
71
+ end
72
+
73
+ def set_background
74
+ @style.background = safe_style_fetch(:background)
75
+
76
+ @style.background_canvas.background = @style.background
77
+ end
78
+
79
+ def set_background_nine_slice
80
+ @style.background_nine_slice = safe_style_fetch(:background_nine_slice)
81
+
82
+ @style.background_nine_slice_mode = safe_style_fetch(:background_nine_slice_mode) || :stretch
83
+ @style.background_nine_slice_color = safe_style_fetch(:background_nine_slice_color) || Gosu::Color::WHITE
84
+ @style.background_nine_slice_canvas.color = @style.background_nine_slice_color
85
+
86
+ @style.background_nine_slice_from_edge = safe_style_fetch(:background_nine_slice_from_edge)
87
+
88
+ @style.background_nine_slice_left = safe_style_fetch(:background_nine_slice_left) || @style.background_nine_slice_from_edge
89
+ @style.background_nine_slice_top = safe_style_fetch(:background_nine_slice_top) || @style.background_nine_slice_from_edge
90
+ @style.background_nine_slice_right = safe_style_fetch(:background_nine_slice_right) || @style.background_nine_slice_from_edge
91
+ @style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom) || @style.background_nine_slice_from_edge
92
+ end
93
+
94
+ def set_border_thickness
95
+ @style.border_thickness = safe_style_fetch(:border_thickness)
96
+
97
+ @style.border_thickness_left = safe_style_fetch(:border_thickness_left) || @style.border_thickness
98
+ @style.border_thickness_right = safe_style_fetch(:border_thickness_right) || @style.border_thickness
99
+ @style.border_thickness_top = safe_style_fetch(:border_thickness_top) || @style.border_thickness
100
+ @style.border_thickness_bottom = safe_style_fetch(:border_thickness_bottom) || @style.border_thickness
101
+ end
102
+
103
+ def set_border_color
104
+ @style.border_color = safe_style_fetch(:border_color)
105
+
106
+ @style.border_color_left = safe_style_fetch(:border_color_left) || @style.border_color
107
+ @style.border_color_right = safe_style_fetch(:border_color_right) || @style.border_color
108
+ @style.border_color_top = safe_style_fetch(:border_color_top) || @style.border_color
109
+ @style.border_color_bottom = safe_style_fetch(:border_color_bottom) || @style.border_color
110
+
111
+ @style.border_canvas.color = [
112
+ @style.border_color_top,
113
+ @style.border_color_right,
114
+ @style.border_color_bottom,
115
+ @style.border_color_left
116
+ ]
117
+ end
118
+
119
+ def set_padding
120
+ @style.padding = safe_style_fetch(:padding)
121
+
122
+ @style.padding_left = safe_style_fetch(:padding_left) || @style.padding
123
+ @style.padding_right = safe_style_fetch(:padding_right) || @style.padding
124
+ @style.padding_top = safe_style_fetch(:padding_top) || @style.padding
125
+ @style.padding_bottom = safe_style_fetch(:padding_bottom) || @style.padding
126
+ end
127
+
128
+ def set_margin
129
+ @style.margin = safe_style_fetch(:margin)
130
+
131
+ @style.margin_left = safe_style_fetch(:margin_left) || @style.margin
132
+ @style.margin_right = safe_style_fetch(:margin_right) || @style.margin
133
+ @style.margin_top = safe_style_fetch(:margin_top) || @style.margin
134
+ @style.margin_bottom = safe_style_fetch(:margin_bottom) || @style.margin
135
+ end
136
+
137
+ def update_styles(event = :default)
138
+ old_width = width
139
+ old_height = height
140
+
141
+ _style = @style.send(event)
142
+ @style_event = event
143
+
144
+ if @text.is_a?(CyberarmEngine::Text)
145
+ @text.color = _style&.dig(:color) || @style.default[:color]
146
+ @text.swap_font(_style&.dig(:text_size) || @style.default[:text_size], _style&.dig(:font) || @style.default[:font])
147
+ end
148
+
149
+ return if self.is_a?(ToolTip)
150
+
151
+ if old_width != width || old_height != height
152
+ (root&.gui_state || @gui_state).request_recalculate
153
+ else
154
+ stylize
155
+ end
156
+ end
157
+
158
+ def default_events
159
+ %i[left middle right].each do |button|
160
+ event(:"#{button}_mouse_button")
161
+ event(:"released_#{button}_mouse_button")
162
+ event(:"clicked_#{button}_mouse_button")
163
+ event(:"holding_#{button}_mouse_button")
164
+ end
165
+
166
+ event(:mouse_wheel_up)
167
+ event(:mouse_wheel_down)
168
+
169
+ event(:enter)
170
+ event(:hover)
171
+ event(:leave)
172
+
173
+ event(:focus)
174
+ event(:blur)
175
+
176
+ event(:changed)
177
+ end
178
+
179
+ def enter(_sender)
180
+ @focus = false unless window.button_down?(Gosu::MsLeft)
181
+
182
+ if !@enabled
183
+ update_styles(:disabled)
184
+ elsif @focus
185
+ update_styles(:active)
186
+ else
187
+ update_styles(:hover)
188
+ end
189
+
190
+ :handled
191
+ end
192
+
193
+ def left_mouse_button(_sender, _x, _y)
194
+ @focus = true
195
+
196
+ unless @enabled
197
+ update_styles(:disabled)
198
+ else
199
+ update_styles(:active)
200
+ end
201
+
202
+ window.current_state.focus = self
203
+
204
+ :handled
205
+ end
206
+
207
+ def released_left_mouse_button(sender, _x, _y)
208
+ enter(sender)
209
+
210
+ :handled
211
+ end
212
+
213
+ def clicked_left_mouse_button(_sender, _x, _y)
214
+ @block&.call(self) if @enabled && !self.is_a?(Container)
215
+
216
+ :handled
217
+ end
218
+
219
+ def leave(_sender)
220
+ if @enabled
221
+ update_styles
222
+ else
223
+ update_styles(:disabled)
224
+ end
225
+
226
+ :handled
227
+ end
228
+
229
+ def blur(_sender)
230
+ @focus = false
231
+
232
+ if @enabled
233
+ update_styles
234
+ else
235
+ update_styles(:disabled)
236
+ end
237
+
238
+ :handled
239
+ end
240
+
241
+ def enabled?
242
+ @enabled
243
+ end
244
+
245
+ def visible?
246
+ @visible
247
+ end
248
+
249
+ def toggle
250
+ @visible = !@visible
251
+ root.gui_state.request_recalculate
252
+ end
253
+
254
+ def show
255
+ bool = visible?
256
+ @visible = true
257
+ root.gui_state.request_recalculate unless bool
258
+ end
259
+
260
+ def hide
261
+ bool = visible?
262
+ @visible = false
263
+ root.gui_state.request_recalculate if bool
264
+ end
265
+
266
+ def draw
267
+ return unless visible?
268
+
269
+ @style.background_canvas.draw
270
+ @style.background_nine_slice_canvas.draw
271
+ @style.border_canvas.draw
272
+
273
+ Gosu.clip_to(@x, @y, width, height) do
274
+ render
275
+ end
276
+ end
277
+
278
+ def debug_draw
279
+ return if defined?(GUI_DEBUG_ONLY_ELEMENT) && self.class == GUI_DEBUG_ONLY_ELEMENT
280
+
281
+ Gosu.draw_line(
282
+ x, y, @debug_color,
283
+ x + outer_width, y, @debug_color,
284
+ Float::INFINITY
285
+ )
286
+ Gosu.draw_line(
287
+ x + outer_width, y, @debug_color,
288
+ x + outer_width, y + outer_height, @debug_color,
289
+ Float::INFINITY
290
+ )
291
+ Gosu.draw_line(
292
+ x + outer_width, y + outer_height, @debug_color,
293
+ x, y + outer_height, @debug_color,
294
+ Float::INFINITY
295
+ )
296
+ Gosu.draw_line(
297
+ x, outer_height, @debug_color,
298
+ x, y, @debug_color,
299
+ Float::INFINITY
300
+ )
301
+ end
302
+
303
+ def update
304
+ end
305
+
306
+ def button_down(id)
307
+ end
308
+
309
+ def button_up(id)
310
+ end
311
+
312
+ def draggable?(_button)
313
+ false
314
+ end
315
+
316
+ def render
317
+ end
318
+
319
+ def hit?(x, y)
320
+ x.between?(@x, @x + width) &&
321
+ y.between?(@y, @y + height)
322
+ end
323
+
324
+ def width
325
+ if visible?
326
+ inner_width + @width
327
+ else
328
+ 0
329
+ end
330
+ end
331
+
332
+ def content_width
333
+ @width
334
+ end
335
+
336
+ def noncontent_width
337
+ (inner_width + outer_width) - width
338
+ end
339
+
340
+ def outer_width
341
+ @style.margin_left + width + @style.margin_right
342
+ end
343
+
344
+ def inner_width
345
+ (@style.border_thickness_left + @style.padding_left) + (@style.padding_right + @style.border_thickness_right)
346
+ end
347
+
348
+ def height
349
+ if visible?
350
+ inner_height + @height
351
+ else
352
+ 0
353
+ end
354
+ end
355
+
356
+ def content_height
357
+ @height
358
+ end
359
+
360
+ def noncontent_height
361
+ (inner_height + outer_height) - height
362
+ end
363
+
364
+ def outer_height
365
+ @style.margin_top + height + @style.margin_bottom
366
+ end
367
+
368
+ def inner_height
369
+ (@style.border_thickness_top + @style.padding_top) + (@style.padding_bottom + @style.border_thickness_bottom)
370
+ end
371
+
372
+ def scroll_width
373
+ @children.sum(&:width) + noncontent_width
374
+ end
375
+
376
+ def scroll_height
377
+ @children.sum(&:height) + noncontent_height
378
+ end
379
+
380
+ def max_scroll_width
381
+ scroll_width - width
382
+ end
383
+
384
+ def max_scroll_height
385
+ scroll_height - height
386
+ end
387
+
388
+ def dimensional_size(size, dimension)
389
+ raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)
390
+
391
+ if size.is_a?(Numeric) && size.between?(0.0, 1.0)
392
+ (@parent.send(:"content_#{dimension}") * size).round - send(:"noncontent_#{dimension}").round
393
+ else
394
+ size
395
+ end
396
+ end
397
+
398
+ def background=(_background)
399
+ @style.background_canvas.background = _background
400
+ update_background
401
+ end
402
+
403
+ def update_background
404
+ @style.background_canvas.x = @x
405
+ @style.background_canvas.y = @y
406
+ @style.background_canvas.z = @z
407
+ @style.background_canvas.width = width
408
+ @style.background_canvas.height = height
409
+
410
+ @style.background_canvas.update
411
+ update_background_nine_slice
412
+ @style.border_canvas.update
413
+ end
414
+
415
+ def background_nine_slice=(_image_path)
416
+ @style.background_nine_slice_canvas.image = _image_path
417
+ update_background_nine_slice
418
+ end
419
+
420
+ def update_background_nine_slice
421
+ @style.background_nine_slice_canvas.x = @x
422
+ @style.background_nine_slice_canvas.y = @y
423
+ @style.background_nine_slice_canvas.z = @z
424
+ @style.background_nine_slice_canvas.width = width
425
+ @style.background_nine_slice_canvas.height = height
426
+
427
+ @style.background_nine_slice_canvas.mode = @style.background_nine_slice_mode
428
+
429
+ @style.background_nine_slice_canvas.color = @style.background_nine_slice_color
430
+
431
+ @style.background_nine_slice_canvas.left = @style.background_nine_slice_left
432
+ @style.background_nine_slice_canvas.top = @style.background_nine_slice_top
433
+ @style.background_nine_slice_canvas.right = @style.background_nine_slice_right
434
+ @style.background_nine_slice_canvas.bottom = @style.background_nine_slice_bottom
435
+
436
+ @style.background_nine_slice_canvas.image = @style.background_nine_slice
437
+ end
438
+
439
+ def root
440
+ return self if is_root?
441
+
442
+ unless @root && @root.parent.nil?
443
+ @root = parent
444
+
445
+ loop do
446
+ break unless @root&.parent
447
+
448
+ @root = @root.parent
449
+ end
450
+ end
451
+
452
+ @root
453
+ end
454
+
455
+ def is_root?
456
+ @gui_state != nil
457
+ end
458
+
459
+ def focus(_)
460
+ warn "#{self.class}#focus was not overridden!"
461
+
462
+ :handled
463
+ end
464
+
465
+ def recalculate
466
+ raise "#{self.class}#recalculate was not overridden!"
467
+ end
468
+
469
+ def reposition
470
+ end
471
+
472
+ def value
473
+ raise "#{self.class}#value was not overridden!"
474
+ end
475
+
476
+ def value=(_value)
477
+ raise "#{self.class}#value= was not overridden!"
478
+ end
479
+
480
+ def to_s
481
+ "#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} value=#{value.is_a?(String) ? "\"#{value}\"" : value}"
482
+ end
483
+
484
+ def inspect
485
+ to_s
486
+ end
487
+ end
488
+ end