cyberarm_engine 0.24.3 → 0.24.5

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 (93) 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/Gemfile.lock +24 -0
  7. data/LICENSE.txt +21 -21
  8. data/README.md +74 -74
  9. data/Rakefile +10 -10
  10. data/assets/shaders/fragment/g_buffer.glsl +30 -30
  11. data/assets/shaders/fragment/lighting.glsl +115 -69
  12. data/assets/shaders/include/light_struct.glsl +11 -11
  13. data/assets/shaders/include/material_struct.glsl +16 -16
  14. data/assets/shaders/vertex/g_buffer.glsl +28 -28
  15. data/assets/shaders/vertex/lighting.glsl +24 -24
  16. data/bin/console +14 -14
  17. data/bin/setup +8 -8
  18. data/cyberarm_engine.gemspec +36 -36
  19. data/lib/cyberarm_engine/animator.rb +219 -219
  20. data/lib/cyberarm_engine/background.rb +180 -179
  21. data/lib/cyberarm_engine/background_image.rb +93 -93
  22. data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
  23. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  24. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  25. data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
  26. data/lib/cyberarm_engine/cache.rb +4 -4
  27. data/lib/cyberarm_engine/common.rb +128 -128
  28. data/lib/cyberarm_engine/config_file.rb +46 -46
  29. data/lib/cyberarm_engine/console/command.rb +157 -157
  30. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  31. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  32. data/lib/cyberarm_engine/console.rb +248 -248
  33. data/lib/cyberarm_engine/game_object.rb +244 -244
  34. data/lib/cyberarm_engine/game_state.rb +124 -124
  35. data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +97 -97
  36. data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
  37. data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
  38. data/lib/cyberarm_engine/model/material.rb +21 -21
  39. data/lib/cyberarm_engine/model/{model_object.rb → mesh.rb} +131 -131
  40. data/lib/cyberarm_engine/model/parser.rb +74 -74
  41. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  42. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  43. data/lib/cyberarm_engine/model.rb +216 -213
  44. data/lib/cyberarm_engine/model_cache.rb +31 -31
  45. data/lib/cyberarm_engine/notification.rb +82 -82
  46. data/lib/cyberarm_engine/notification_manager.rb +241 -241
  47. data/lib/cyberarm_engine/opengl/light.rb +52 -50
  48. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  49. data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -38
  50. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  51. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -165
  52. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -304
  53. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
  54. data/lib/cyberarm_engine/opengl/shader.rb +408 -406
  55. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  56. data/lib/cyberarm_engine/opengl.rb +53 -40
  57. data/lib/cyberarm_engine/ray.rb +56 -56
  58. data/lib/cyberarm_engine/stats.rb +200 -200
  59. data/lib/cyberarm_engine/text.rb +260 -260
  60. data/lib/cyberarm_engine/timer.rb +23 -23
  61. data/lib/cyberarm_engine/transform.rb +296 -296
  62. data/lib/cyberarm_engine/trees/aabb_node.rb +126 -0
  63. data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -0
  64. data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -0
  65. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  66. data/lib/cyberarm_engine/ui/dsl.rb +142 -142
  67. data/lib/cyberarm_engine/ui/element.rb +662 -662
  68. data/lib/cyberarm_engine/ui/elements/button.rb +100 -100
  69. data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
  70. data/lib/cyberarm_engine/ui/elements/container.rb +404 -410
  71. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
  72. data/lib/cyberarm_engine/ui/elements/edit_line.rb +297 -297
  73. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  74. data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
  75. data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
  76. data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
  77. data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
  78. data/lib/cyberarm_engine/ui/elements/progress.rb +93 -93
  79. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  80. data/lib/cyberarm_engine/ui/elements/slider.rb +107 -107
  81. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  82. data/lib/cyberarm_engine/ui/elements/text_block.rb +216 -216
  83. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +67 -67
  84. data/lib/cyberarm_engine/ui/event.rb +54 -54
  85. data/lib/cyberarm_engine/ui/gui_state.rb +321 -321
  86. data/lib/cyberarm_engine/ui/style.rb +50 -50
  87. data/lib/cyberarm_engine/ui/theme.rb +225 -225
  88. data/lib/cyberarm_engine/vector.rb +312 -312
  89. data/lib/cyberarm_engine/version.rb +4 -4
  90. data/lib/cyberarm_engine/window.rb +195 -195
  91. data/lib/cyberarm_engine.rb +70 -78
  92. data/mrbgem.rake +29 -29
  93. metadata +8 -7
@@ -1,321 +1,321 @@
1
- module CyberarmEngine
2
- class GuiState < GameState
3
- include Common
4
- include DSL
5
-
6
- def initialize(options = {})
7
- @options = options
8
- @game_objects = []
9
- @global_pause = false
10
-
11
- @down_keys = {}
12
-
13
- @root_container = Element::Stack.new(gui_state: self)
14
- @game_objects << @root_container
15
- CyberarmEngine::Element::Container.current_container = @root_container
16
-
17
- @active_width = window.width
18
- @active_height = window.height
19
-
20
- @menu = nil
21
- @focus = nil
22
- @mouse_over = nil
23
- @mouse_down_on = {}
24
- @mouse_down_position = {}
25
- @last_mouse_pos = nil
26
- @dragging_element = nil
27
- @pending_recalculate_request = false
28
- @pending_element_recalculate_requests = []
29
-
30
- @needs_repaint = false
31
-
32
- @menu = nil
33
- @min_drag_distance = 0
34
- @mouse_pos = Vector.new
35
- end
36
-
37
- def post_setup
38
- @tip = Element::ToolTip.new("", parent: @root_container, z: Float::INFINITY, theme: current_theme)
39
- end
40
-
41
- def menu
42
- @menu
43
- end
44
-
45
- # throws :blur event to focused element and sets GuiState focused element
46
- # Does NOT throw :focus event at element or set element as focused
47
- def focus=(element)
48
- @focus.publish(:blur) if @focus && element && @focus != element
49
- @focus = element
50
- end
51
-
52
- def focused
53
- @focus
54
- end
55
-
56
- def draw
57
- Stats.frame.start_timing(:gui_element_recalculate_requests)
58
-
59
- # puts "PENDING REQUESTS: #{@pending_element_recalculate_requests.size}" if @pending_element_recalculate_requests.size.positive?
60
- @pending_element_recalculate_requests.each(&:recalculate)
61
- @pending_element_recalculate_requests.clear
62
-
63
- Stats.frame.end_timing(:gui_element_recalculate_requests)
64
-
65
- if @pending_recalculate_request
66
- Stats.frame.start_timing(:gui_recalculate)
67
-
68
- @root_container.recalculate
69
-
70
- @pending_recalculate_request = false
71
-
72
- Stats.frame.end_timing(:gui_recalculate)
73
- end
74
-
75
- super
76
-
77
- if @menu
78
- Gosu.flush
79
- @menu.draw
80
- end
81
-
82
- if @tip && @tip.value.length.positive?
83
- Gosu.flush
84
-
85
- @tip.draw
86
- end
87
-
88
- if CyberarmEngine.const_defined?("GUI_DEBUG")
89
- Gosu.flush
90
-
91
- @root_container.debug_draw
92
- end
93
-
94
- @needs_repaint = false
95
- end
96
-
97
- def needs_repaint?
98
- @needs_repaint
99
- end
100
-
101
- def update
102
- if @pending_focus_request
103
- @pending_focus_request = false
104
-
105
- self.focus = @pending_focus_element
106
- @pending_focus_element.publish(:focus)
107
- end
108
-
109
- @menu&.update
110
-
111
- super
112
-
113
- if @active_width != window.width || @active_height != window.height
114
- request_recalculate
115
- @root_container.publish(:window_size_changed)
116
- end
117
-
118
- @active_width = window.width
119
- @active_height = window.height
120
-
121
- return unless window.has_focus?
122
- return unless window.current_state == self
123
-
124
- new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
125
- new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
126
-
127
- if new_mouse_over
128
- new_mouse_over.publish(:enter) if new_mouse_over != @mouse_over
129
- new_mouse_over.publish(:hover)
130
- # puts "#{new_mouse_over.class}[#{new_mouse_over.value}]: #{new_mouse_over.x}:#{new_mouse_over.y} #{new_mouse_over.width}:#{new_mouse_over.height}" if new_mouse_over != @mouse_over
131
- end
132
- @mouse_over.publish(:leave) if @mouse_over && new_mouse_over != @mouse_over
133
- @mouse_over = new_mouse_over
134
-
135
- redirect_holding_mouse_button(:left) if @mouse_over && Gosu.button_down?(Gosu::MS_LEFT)
136
- redirect_holding_mouse_button(:middle) if @mouse_over && Gosu.button_down?(Gosu::MS_MIDDLE)
137
- redirect_holding_mouse_button(:right) if @mouse_over && Gosu.button_down?(Gosu::MS_RIGHT)
138
-
139
- if Vector.new(window.mouse_x, window.mouse_y) == @last_mouse_pos
140
- if @mouse_over && (Gosu.milliseconds - @mouse_moved_at) > tool_tip_delay
141
- @tip.value = @mouse_over.tip if @mouse_over
142
- @tip.x = window.mouse_x
143
- @tip.x = 0 if @tip.x < 0
144
- @tip.x = window.width - @tip.width if @tip.x + @tip.width > window.width
145
- @tip.y = window.mouse_y - (@tip.height + 5)
146
- @tip.y = 0 if @tip.y < 0
147
- @tip.y = window.height - @tip.height if @tip.y + @tip.height > window.height
148
- @tip.update
149
- @tip.recalculate
150
- else
151
- @tip.value = ""
152
- end
153
- else
154
- @mouse_moved_at = Gosu.milliseconds
155
- end
156
-
157
- @last_mouse_pos = Vector.new(window.mouse_x, window.mouse_y)
158
- @mouse_pos = @last_mouse_pos.clone
159
- end
160
-
161
- def button_down(id)
162
- super
163
-
164
- case id
165
- when Gosu::MS_LEFT
166
- redirect_mouse_button(:left)
167
- when Gosu::MS_MIDDLE
168
- redirect_mouse_button(:middle)
169
- when Gosu::MS_RIGHT
170
- redirect_mouse_button(:right)
171
- when Gosu::KB_F5
172
- request_recalculate
173
- end
174
-
175
- @focus.button_down(id) if @focus.respond_to?(:button_down)
176
- end
177
-
178
- def button_up(id)
179
- super
180
-
181
- case id
182
- when Gosu::MS_LEFT
183
- redirect_released_mouse_button(:left)
184
- when Gosu::MS_MIDDLE
185
- redirect_released_mouse_button(:middle)
186
- when Gosu::MS_RIGHT
187
- redirect_released_mouse_button(:right)
188
- when Gosu::MS_WHEEL_UP
189
- redirect_mouse_wheel(:up)
190
- when Gosu::MS_WHEEL_DOWN
191
- redirect_mouse_wheel(:down)
192
- when Gosu::KB_HOME
193
- redirect_scroll_jump_to(:top)
194
- when Gosu::KB_END
195
- redirect_scroll_jump_to(:end)
196
- when Gosu::KB_PAGE_UP
197
- redirect_scroll_page(:up)
198
- when Gosu::KB_PAGE_DOWN
199
- redirect_scroll_page(:down)
200
- end
201
-
202
- @focus.button_up(id) if @focus.respond_to?(:button_up)
203
-
204
- # Prevents menu from popping back up if the listbox is clicked to hide it.
205
- @hid_menu_for = nil
206
- end
207
-
208
- def tool_tip_delay
209
- @tip.style.delay || 250 # ms
210
- end
211
-
212
- def redirect_mouse_button(button)
213
- hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
214
-
215
- if @focus && @mouse_over != @focus
216
- @focus.publish(:blur)
217
- @focus = nil
218
- end
219
-
220
- if @mouse_over && @hid_menu_for != @mouse_over
221
- @mouse_down_position[button] = Vector.new(window.mouse_x, window.mouse_y)
222
- @mouse_down_on[button] = @mouse_over
223
-
224
- @mouse_over.publish(:"#{button}_mouse_button", window.mouse_x, window.mouse_y)
225
- else
226
- @mouse_down_position[button] = nil
227
- @mouse_down_on[button] = nil
228
- end
229
- end
230
-
231
- def redirect_released_mouse_button(button)
232
- hide_menu if @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
233
-
234
- if @mouse_over && @hid_menu_for != @mouse_over
235
- @mouse_over.publish(:"released_#{button}_mouse_button", window.mouse_x, window.mouse_y)
236
- if @mouse_over == @mouse_down_on[button]
237
- @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x,
238
- window.mouse_y)
239
- end
240
- end
241
-
242
- if @dragging_element
243
- @dragging_element.publish(:end_drag, window.mouse_x, window.mouse_y, button)
244
- @dragging_element = nil
245
- end
246
-
247
- @mouse_down_position[button] = nil
248
- @mouse_down_on[button] = nil
249
- end
250
-
251
- def redirect_holding_mouse_button(button)
252
- if !@dragging_element && @mouse_down_on[button] && @mouse_down_on[button].draggable?(button) && @mouse_pos.distance(@mouse_down_position[button]) > @min_drag_distance
253
- @dragging_element = @mouse_down_on[button]
254
- @dragging_element.publish(:begin_drag, window.mouse_x, window.mouse_y, button)
255
- end
256
-
257
- if @dragging_element
258
- @dragging_element.publish(:drag_update, window.mouse_x, window.mouse_y, button) if @dragging_element
259
- elsif @mouse_over
260
- @mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y)
261
- end
262
- end
263
-
264
- def redirect_mouse_wheel(button)
265
- @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
266
- end
267
-
268
- def redirect_scroll_jump_to(edge)
269
- @mouse_over.publish(:"scroll_jump_to_#{edge}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
270
- end
271
-
272
- def redirect_scroll_page(edge)
273
- @mouse_over.publish(:"scroll_page_#{edge}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
274
- end
275
-
276
- # Schedule a full GUI recalculation on next update
277
- def request_recalculate
278
- @pending_recalculate_request = true
279
- end
280
-
281
- def request_recalculate_for(element)
282
- # element is already queued
283
- return if @pending_element_recalculate_requests.detect { |e| e == element }
284
-
285
- @pending_element_recalculate_requests << element
286
- end
287
-
288
- def request_focus(element)
289
- @pending_focus_request = true
290
- @pending_focus_element = element
291
- end
292
-
293
- def request_repaint
294
- # puts caller[0..4]
295
- # puts
296
- @needs_repaint = true
297
- end
298
-
299
- def show_menu(list_box)
300
- @menu = list_box
301
- end
302
-
303
- def hide_menu
304
- return unless @menu
305
-
306
- request_repaint
307
-
308
- @hid_menu_for = @menu.parent
309
- @menu = nil
310
- end
311
-
312
- def to_s
313
- # "#{self.class} children=#{@children.map { |c| c.to_s }}"
314
- @root_container.to_s
315
- end
316
-
317
- def inspect
318
- to_s
319
- end
320
- end
321
- end
1
+ module CyberarmEngine
2
+ class GuiState < GameState
3
+ include Common
4
+ include DSL
5
+
6
+ def initialize(options = {})
7
+ @options = options
8
+ @game_objects = []
9
+ @global_pause = false
10
+
11
+ @down_keys = {}
12
+
13
+ @root_container = Element::Stack.new(gui_state: self)
14
+ @game_objects << @root_container
15
+ CyberarmEngine::Element::Container.current_container = @root_container
16
+
17
+ @active_width = window.width
18
+ @active_height = window.height
19
+
20
+ @menu = nil
21
+ @focus = nil
22
+ @mouse_over = nil
23
+ @mouse_down_on = {}
24
+ @mouse_down_position = {}
25
+ @last_mouse_pos = nil
26
+ @dragging_element = nil
27
+ @pending_recalculate_request = false
28
+ @pending_element_recalculate_requests = []
29
+
30
+ @needs_repaint = false
31
+
32
+ @menu = nil
33
+ @min_drag_distance = 0
34
+ @mouse_pos = Vector.new
35
+ end
36
+
37
+ def post_setup
38
+ @tip = Element::ToolTip.new("", parent: @root_container, z: Float::INFINITY, theme: current_theme)
39
+ end
40
+
41
+ def menu
42
+ @menu
43
+ end
44
+
45
+ # throws :blur event to focused element and sets GuiState focused element
46
+ # Does NOT throw :focus event at element or set element as focused
47
+ def focus=(element)
48
+ @focus.publish(:blur) if @focus && element && @focus != element
49
+ @focus = element
50
+ end
51
+
52
+ def focused
53
+ @focus
54
+ end
55
+
56
+ def draw
57
+ Stats.frame.start_timing(:gui_element_recalculate_requests)
58
+
59
+ # puts "PENDING REQUESTS: #{@pending_element_recalculate_requests.size}" if @pending_element_recalculate_requests.size.positive?
60
+ @pending_element_recalculate_requests.each(&:recalculate)
61
+ @pending_element_recalculate_requests.clear
62
+
63
+ Stats.frame.end_timing(:gui_element_recalculate_requests)
64
+
65
+ if @pending_recalculate_request
66
+ Stats.frame.start_timing(:gui_recalculate)
67
+
68
+ @root_container.recalculate
69
+
70
+ @pending_recalculate_request = false
71
+
72
+ Stats.frame.end_timing(:gui_recalculate)
73
+ end
74
+
75
+ super
76
+
77
+ if @menu
78
+ Gosu.flush
79
+ @menu.draw
80
+ end
81
+
82
+ if @tip && @tip.value.length.positive?
83
+ Gosu.flush
84
+
85
+ @tip.draw
86
+ end
87
+
88
+ if CyberarmEngine.const_defined?("GUI_DEBUG")
89
+ Gosu.flush
90
+
91
+ @root_container.debug_draw
92
+ end
93
+
94
+ @needs_repaint = false
95
+ end
96
+
97
+ def needs_repaint?
98
+ @needs_repaint
99
+ end
100
+
101
+ def update
102
+ if @pending_focus_request
103
+ @pending_focus_request = false
104
+
105
+ self.focus = @pending_focus_element
106
+ @pending_focus_element.publish(:focus)
107
+ end
108
+
109
+ @menu&.update
110
+
111
+ super
112
+
113
+ if @active_width != window.width || @active_height != window.height
114
+ request_recalculate
115
+ @root_container.publish(:window_size_changed)
116
+ end
117
+
118
+ @active_width = window.width
119
+ @active_height = window.height
120
+
121
+ return unless window.has_focus?
122
+ return unless window.current_state == self
123
+
124
+ new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
125
+ new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
126
+
127
+ if new_mouse_over
128
+ new_mouse_over.publish(:enter) if new_mouse_over != @mouse_over
129
+ new_mouse_over.publish(:hover)
130
+ # puts "#{new_mouse_over.class}[#{new_mouse_over.value}]: #{new_mouse_over.x}:#{new_mouse_over.y} #{new_mouse_over.width}:#{new_mouse_over.height}" if new_mouse_over != @mouse_over
131
+ end
132
+ @mouse_over.publish(:leave) if @mouse_over && new_mouse_over != @mouse_over
133
+ @mouse_over = new_mouse_over
134
+
135
+ redirect_holding_mouse_button(:left) if @mouse_over && Gosu.button_down?(Gosu::MS_LEFT)
136
+ redirect_holding_mouse_button(:middle) if @mouse_over && Gosu.button_down?(Gosu::MS_MIDDLE)
137
+ redirect_holding_mouse_button(:right) if @mouse_over && Gosu.button_down?(Gosu::MS_RIGHT)
138
+
139
+ if Vector.new(window.mouse_x, window.mouse_y) == @last_mouse_pos
140
+ if @mouse_over && (Gosu.milliseconds - @mouse_moved_at) > tool_tip_delay
141
+ @tip.value = @mouse_over.tip if @mouse_over
142
+ @tip.x = window.mouse_x
143
+ @tip.x = 0 if @tip.x < 0
144
+ @tip.x = window.width - @tip.width if @tip.x + @tip.width > window.width
145
+ @tip.y = window.mouse_y - (@tip.height + 5)
146
+ @tip.y = 0 if @tip.y < 0
147
+ @tip.y = window.height - @tip.height if @tip.y + @tip.height > window.height
148
+ @tip.update
149
+ @tip.recalculate
150
+ else
151
+ @tip.value = ""
152
+ end
153
+ else
154
+ @mouse_moved_at = Gosu.milliseconds
155
+ end
156
+
157
+ @last_mouse_pos = Vector.new(window.mouse_x, window.mouse_y)
158
+ @mouse_pos = @last_mouse_pos.clone
159
+ end
160
+
161
+ def button_down(id)
162
+ super
163
+
164
+ case id
165
+ when Gosu::MS_LEFT
166
+ redirect_mouse_button(:left)
167
+ when Gosu::MS_MIDDLE
168
+ redirect_mouse_button(:middle)
169
+ when Gosu::MS_RIGHT
170
+ redirect_mouse_button(:right)
171
+ when Gosu::KB_F5
172
+ request_recalculate
173
+ end
174
+
175
+ @focus.button_down(id) if @focus.respond_to?(:button_down)
176
+ end
177
+
178
+ def button_up(id)
179
+ super
180
+
181
+ case id
182
+ when Gosu::MS_LEFT
183
+ redirect_released_mouse_button(:left)
184
+ when Gosu::MS_MIDDLE
185
+ redirect_released_mouse_button(:middle)
186
+ when Gosu::MS_RIGHT
187
+ redirect_released_mouse_button(:right)
188
+ when Gosu::MS_WHEEL_UP
189
+ redirect_mouse_wheel(:up)
190
+ when Gosu::MS_WHEEL_DOWN
191
+ redirect_mouse_wheel(:down)
192
+ when Gosu::KB_HOME
193
+ redirect_scroll_jump_to(:top)
194
+ when Gosu::KB_END
195
+ redirect_scroll_jump_to(:end)
196
+ when Gosu::KB_PAGE_UP
197
+ redirect_scroll_page(:up)
198
+ when Gosu::KB_PAGE_DOWN
199
+ redirect_scroll_page(:down)
200
+ end
201
+
202
+ @focus.button_up(id) if @focus.respond_to?(:button_up)
203
+
204
+ # Prevents menu from popping back up if the listbox is clicked to hide it.
205
+ @hid_menu_for = nil
206
+ end
207
+
208
+ def tool_tip_delay
209
+ @tip.style.delay || 250 # ms
210
+ end
211
+
212
+ def redirect_mouse_button(button)
213
+ hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
214
+
215
+ if @focus && @mouse_over != @focus
216
+ @focus.publish(:blur)
217
+ @focus = nil
218
+ end
219
+
220
+ if @mouse_over && @hid_menu_for != @mouse_over
221
+ @mouse_down_position[button] = Vector.new(window.mouse_x, window.mouse_y)
222
+ @mouse_down_on[button] = @mouse_over
223
+
224
+ @mouse_over.publish(:"#{button}_mouse_button", window.mouse_x, window.mouse_y)
225
+ else
226
+ @mouse_down_position[button] = nil
227
+ @mouse_down_on[button] = nil
228
+ end
229
+ end
230
+
231
+ def redirect_released_mouse_button(button)
232
+ hide_menu if @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
233
+
234
+ if @mouse_over && @hid_menu_for != @mouse_over
235
+ @mouse_over.publish(:"released_#{button}_mouse_button", window.mouse_x, window.mouse_y)
236
+ if @mouse_over == @mouse_down_on[button]
237
+ @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x,
238
+ window.mouse_y)
239
+ end
240
+ end
241
+
242
+ if @dragging_element
243
+ @dragging_element.publish(:end_drag, window.mouse_x, window.mouse_y, button)
244
+ @dragging_element = nil
245
+ end
246
+
247
+ @mouse_down_position[button] = nil
248
+ @mouse_down_on[button] = nil
249
+ end
250
+
251
+ def redirect_holding_mouse_button(button)
252
+ if !@dragging_element && @mouse_down_on[button] && @mouse_down_on[button].draggable?(button) && @mouse_pos.distance(@mouse_down_position[button]) > @min_drag_distance
253
+ @dragging_element = @mouse_down_on[button]
254
+ @dragging_element.publish(:begin_drag, window.mouse_x, window.mouse_y, button)
255
+ end
256
+
257
+ if @dragging_element
258
+ @dragging_element.publish(:drag_update, window.mouse_x, window.mouse_y, button) if @dragging_element
259
+ elsif @mouse_over
260
+ @mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y)
261
+ end
262
+ end
263
+
264
+ def redirect_mouse_wheel(button)
265
+ @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
266
+ end
267
+
268
+ def redirect_scroll_jump_to(edge)
269
+ @mouse_over.publish(:"scroll_jump_to_#{edge}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
270
+ end
271
+
272
+ def redirect_scroll_page(edge)
273
+ @mouse_over.publish(:"scroll_page_#{edge}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
274
+ end
275
+
276
+ # Schedule a full GUI recalculation on next update
277
+ def request_recalculate
278
+ @pending_recalculate_request = true
279
+ end
280
+
281
+ def request_recalculate_for(element)
282
+ # element is already queued
283
+ return if @pending_element_recalculate_requests.detect { |e| e == element }
284
+
285
+ @pending_element_recalculate_requests << element
286
+ end
287
+
288
+ def request_focus(element)
289
+ @pending_focus_request = true
290
+ @pending_focus_element = element
291
+ end
292
+
293
+ def request_repaint
294
+ # puts caller[0..4]
295
+ # puts
296
+ @needs_repaint = true
297
+ end
298
+
299
+ def show_menu(list_box)
300
+ @menu = list_box
301
+ end
302
+
303
+ def hide_menu
304
+ return unless @menu
305
+
306
+ request_repaint
307
+
308
+ @hid_menu_for = @menu.parent
309
+ @menu = nil
310
+ end
311
+
312
+ def to_s
313
+ # "#{self.class} children=#{@children.map { |c| c.to_s }}"
314
+ @root_container.to_s
315
+ end
316
+
317
+ def inspect
318
+ to_s
319
+ end
320
+ end
321
+ end