cyberarm_engine 0.24.2 → 0.24.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 294097836d861784fb91a7545e332296b77edae06130318a067c7d92a92bb0a4
4
- data.tar.gz: 6e345593db98b441f6e02b5dd4d1da4b1f6b7df668d0d8deedcf9422ad1d66ea
3
+ metadata.gz: 863d7306cdc75ec88c4ee4fc80f963a685106bb139b1d94edf83381fe2cd1a01
4
+ data.tar.gz: 6eae0b303c0e192d5842d859f5c694f3f19ace8195f2fc7519fd59e82626cba5
5
5
  SHA512:
6
- metadata.gz: 05c353bddf8d57cd9f7dc89c969022c496bde452fff8e732eaa61d0680bfcd6bd88377ecc6d8417d171eff2e999088578e77cad4e0a0a99c9562c1f87c52549f
7
- data.tar.gz: b18674b78249fe48a3dc78b23680277125f1662bfbb18eb85182bb5a7fb614deaa5a74c8ebb76439b2728f1f57257a94933db908b8d723146898ab003ca261c2
6
+ metadata.gz: fbf4bdb02a1c2bd51e3721258bd83d2e0960b0c2c49e7a31e9797bcf169adac418e681970b3ac1831501d50036f9301e715061ecdbeb7e8a2f1d13a642782e5a
7
+ data.tar.gz: e9a76f04bac85f67c4b8f9d81131a52f53eb0849f637cadad11699a1514a985a1af0942180ed4e10124897813063cc129efdc755190bf4932305ef945576e3a6
@@ -27,9 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = %w[lib assets]
29
29
 
30
- spec.add_dependency "excon", "~> 0.88"
31
30
  spec.add_dependency "gosu", "~> 1.1"
32
- spec.add_dependency "gosu_more_drawables", "~> 0.3"
33
31
  # spec.add_dependency "ffi", :platforms => [:mswin, :mingw] # Required by Clipboard on Windows
34
32
 
35
33
  spec.add_development_dependency "bundler", "~> 2.2"
@@ -1,3 +1,5 @@
1
+ require "excon"
2
+
1
3
  module CyberarmEngine
2
4
  module Cache
3
5
  class DownloadManager
@@ -115,11 +115,11 @@ module CyberarmEngine
115
115
  @padding = 2
116
116
  @text_size = 16
117
117
 
118
- @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true)
119
- @avg_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding + @height / 2 - @text_size / 2, z: z, size: @text_size, border: true)
120
- @min_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @height - (@text_size + @padding / 2), z: z, size: @text_size, border: true)
118
+ @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true, static: true)
119
+ @avg_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding + @height / 2 - @text_size / 2, z: z, size: @text_size, border: true, static: true)
120
+ @min_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @height - (@text_size + @padding / 2), z: z, size: @text_size, border: true, static: true)
121
121
 
122
- @timings_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true)
122
+ @data_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true, static: true)
123
123
 
124
124
  @frame_stats = []
125
125
  @graphs = {
@@ -146,10 +146,15 @@ module CyberarmEngine
146
146
  slice += 1
147
147
  end
148
148
 
149
+ max_node = CyberarmEngine::Stats.frames.select(&:complete?).map { |f| f.frame_timing.duration }.max
150
+ scale = 1
151
+ scale = (@height - @padding).to_f / max_node
152
+ scale = 1 if scale > 1
153
+
149
154
  nodes.each_with_index do |cluster, i|
150
155
  break if cluster.empty?
151
156
 
152
- @graphs[:frame_timings] << CyberarmEngine::Vector.new(@position.x + @padding + 1 * i, (@position.y + @height - @padding) - cluster.max)
157
+ @graphs[:frame_timings] << CyberarmEngine::Vector.new(@position.x + @padding + 1 * i, (@position.y + @height - @padding) - cluster.max * scale)
153
158
  end
154
159
  end
155
160
 
@@ -159,9 +164,9 @@ module CyberarmEngine
159
164
 
160
165
  calculate_graphs
161
166
 
162
- @max_timing_label.text = "Max: #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
163
- @avg_timing_label.text = "Avg: #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
164
- @min_timing_label.text = "Min: #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
167
+ @max_timing_label.text = "<c=d44>Max:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
168
+ @avg_timing_label.text = "<c=f80>Avg:</c> #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
169
+ @min_timing_label.text = "<c=0d0>Min:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
165
170
 
166
171
  Gosu.draw_rect(@position.x, @position.y, @width, @height, 0xaa_222222, @position.z)
167
172
  Gosu.draw_rect(@position.x + @padding, @position.y + @padding, @width - @padding * 2, @height - @padding * 2, 0xaa_222222, @position.z)
@@ -173,19 +178,22 @@ module CyberarmEngine
173
178
  @min_timing_label.draw
174
179
 
175
180
  # TODO: Make this optional
176
- draw_timings
181
+ draw_timings_and_counters
177
182
  end
178
183
 
179
184
  def draw_graphs
180
185
  Gosu.draw_path(@graphs[:frame_timings], Gosu::Color::WHITE, Float::INFINITY)
181
186
  end
182
187
 
183
- def draw_timings
188
+ def draw_timings_and_counters
184
189
  frame = @frame_stats.last
185
190
 
186
- @timings_label.text = "#{frame.attempted_multitiming? ? "<c=d00>Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }</c>\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
187
- Gosu.draw_rect(@timings_label.x - @padding, @timings_label.y - @padding, @timings_label.width + @padding * 2, @timings_label.height + @padding * 2, 0xdd_222222, @position.z)
188
- @timings_label.draw
191
+ @data_label.text = "<c=f8f>COUNTERS:</c>\n#{frame.counters.map { |t, v| "#{t}: #{v}" }.join("\n")}\n\n"\
192
+ "<c=f80>TIMINGS:</c>\n#{frame.attempted_multitiming? ? "<c=d00>Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }</c>\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
193
+ Gosu.draw_rect(@data_label.x - @padding, @data_label.y - @padding, @data_label.width + @padding * 2, @data_label.height + @padding * 2, 0xdd_222222, @position.z)
194
+ @data_label.draw
195
+
196
+ # puts "Recalcs this frame: #{frame.counters[:gui_recalculations]} [dt: #{(CyberarmEngine::Window.dt * 1000).round} ms]" if frame.counters[:gui_recalculations] && frame.counters[:gui_recalculations].positive?
189
197
  end
190
198
  end
191
199
  end
@@ -8,12 +8,8 @@ module CyberarmEngine
8
8
  container(CyberarmEngine::Element::Stack, options, &block)
9
9
  end
10
10
 
11
- # TODO: Remove in version 0.16.0+
12
- def label(text, options = {}, &block)
13
- options[:parent] = element_parent
14
- options[:theme] = current_theme
15
-
16
- add_element(Element::TextBlock.new(text, options, block))
11
+ def menu(options = {}, &block)
12
+ container(CyberarmEngine::Element::Menu, options, &block)
17
13
  end
18
14
 
19
15
  [
@@ -27,72 +23,79 @@ module CyberarmEngine
27
23
  "Link"
28
24
  ].each do |const|
29
25
  define_method(:"#{const.downcase}") do |text, options = {}, &block|
30
- options[:parent] = element_parent
31
- options[:theme] = current_theme
26
+ options[:parent] ||= element_parent
27
+ options[:theme] ||= current_theme
32
28
 
33
29
  add_element(Element.const_get(const).new(text, options, block))
34
30
  end
35
31
  end
36
32
 
37
33
  def button(text, options = {}, &block)
38
- options[:parent] = element_parent
39
- options[:theme] = current_theme
34
+ options[:parent] ||= element_parent
35
+ options[:theme] ||= current_theme
40
36
 
41
37
  add_element(Element::Button.new(text, options, block) { block.call if block.is_a?(Proc) })
42
38
  end
43
39
 
44
40
  def list_box(options = {}, &block)
45
- options[:parent] = element_parent
46
- options[:theme] = current_theme
41
+ options[:parent] ||= element_parent
42
+ options[:theme] ||= current_theme
47
43
 
48
44
  add_element(Element::ListBox.new(options, block) { block.call if block.is_a?(Proc) })
49
45
  end
50
46
 
47
+ def menu_item(text, options = {}, &block)
48
+ options[:parent] ||= element_parent
49
+ options[:theme] ||= current_theme
50
+
51
+ add_element(Element::MenuItem.new(text, options, block) { block.call if block.is_a?(Proc) })
52
+ end
53
+
51
54
  def edit_line(text, options = {}, &block)
52
- options[:parent] = element_parent
53
- options[:theme] = current_theme
55
+ options[:parent] ||= element_parent
56
+ options[:theme] ||= current_theme
54
57
 
55
58
  add_element(Element::EditLine.new(text, options, block))
56
59
  end
57
60
 
58
61
  def edit_box(text, options = {}, &block)
59
- options[:parent] = element_parent
60
- options[:theme] = current_theme
62
+ options[:parent] ||= element_parent
63
+ options[:theme] ||= current_theme
61
64
 
62
65
  add_element(Element::EditBox.new(text, options, block))
63
66
  end
64
67
 
65
68
  def toggle_button(options = {}, &block)
66
- options[:parent] = element_parent
67
- options[:theme] = current_theme
69
+ options[:parent] ||= element_parent
70
+ options[:theme] ||= current_theme
68
71
 
69
72
  add_element(Element::ToggleButton.new(options, block))
70
73
  end
71
74
 
72
75
  def check_box(text, options = {}, &block)
73
- options[:parent] = element_parent
74
- options[:theme] = current_theme
76
+ options[:parent] ||= element_parent
77
+ options[:theme] ||= current_theme
75
78
 
76
79
  add_element(Element::CheckBox.new(text, options, block))
77
80
  end
78
81
 
79
82
  def image(path, options = {}, &block)
80
- options[:parent] = element_parent
81
- options[:theme] = current_theme
83
+ options[:parent] ||= element_parent
84
+ options[:theme] ||= current_theme
82
85
 
83
86
  add_element(Element::Image.new(path, options, block))
84
87
  end
85
88
 
86
89
  def progress(options = {}, &block)
87
- options[:parent] = element_parent
88
- options[:theme] = current_theme
90
+ options[:parent] ||= element_parent
91
+ options[:theme] ||= current_theme
89
92
 
90
93
  add_element(Element::Progress.new(options, block))
91
94
  end
92
95
 
93
96
  def slider(options = {}, &block)
94
- options[:parent] = element_parent
95
- options[:theme] = current_theme
97
+ options[:parent] ||= element_parent
98
+ options[:theme] ||= current_theme
96
99
 
97
100
  add_element(Element::Slider.new(options, block))
98
101
  end
@@ -102,7 +105,7 @@ module CyberarmEngine
102
105
  end
103
106
 
104
107
  def theme(theme)
105
- element_parent.options[:theme] = theme
108
+ element_parent.options[:theme] ||= theme
106
109
  end
107
110
 
108
111
  def current_theme
@@ -120,8 +123,8 @@ module CyberarmEngine
120
123
  end
121
124
 
122
125
  private def container(klass, options = {}, &block)
123
- options[:parent] = element_parent
124
- options[:theme] = current_theme
126
+ options[:parent] ||= element_parent
127
+ options[:theme] ||= current_theme
125
128
 
126
129
  _container = klass.new(options, block)
127
130
 
@@ -129,7 +132,7 @@ module CyberarmEngine
129
132
  CyberarmEngine::Element::Container.current_container = _container
130
133
 
131
134
  _container.build
132
- _container.parent.add(_container)
135
+ _container.parent.add(_container) unless _container.is_a?(CyberarmEngine::Element::Menu)
133
136
 
134
137
  CyberarmEngine::Element::Container.current_container = old_parent
135
138
 
@@ -180,9 +180,7 @@ module CyberarmEngine
180
180
 
181
181
  return if self.is_a?(ToolTip)
182
182
 
183
- if old_width != width || old_height != height
184
- root.gui_state.request_recalculate
185
- end
183
+ root.gui_state.request_recalculate if old_width != width || old_height != height
186
184
 
187
185
  stylize
188
186
  end
@@ -197,6 +195,10 @@ module CyberarmEngine
197
195
 
198
196
  event(:mouse_wheel_up)
199
197
  event(:mouse_wheel_down)
198
+ event(:scroll_jump_to_top)
199
+ event(:scroll_jump_to_end)
200
+ event(:scroll_page_up)
201
+ event(:scroll_page_down)
200
202
 
201
203
  event(:enter)
202
204
  event(:hover)
@@ -329,8 +331,7 @@ module CyberarmEngine
329
331
  end
330
332
 
331
333
  def debug_draw
332
- # FIXME
333
- return# if const_defined?(GUI_DEBUG_ONLY_ELEMENT) && self.class == GUI_DEBUG_ONLY_ELEMENT
334
+ return if CyberarmEngine.const_defined?("GUI_DEBUG_ONLY_ELEMENT") && self.class == GUI_DEBUG_ONLY_ELEMENT
334
335
 
335
336
  Gosu.draw_line(
336
337
  x, y, @debug_color,
@@ -348,7 +349,7 @@ module CyberarmEngine
348
349
  Float::INFINITY
349
350
  )
350
351
  Gosu.draw_line(
351
- x, outer_height, @debug_color,
352
+ x, y + outer_height, @debug_color,
352
353
  x, y, @debug_color,
353
354
  Float::INFINITY
354
355
  )
@@ -573,7 +574,7 @@ module CyberarmEngine
573
574
  end
574
575
 
575
576
  def recalculate_if_size_changed
576
- if !is_a?(ToolTip) && (@old_width != width || @old_height != height)
577
+ if @parent && !is_a?(ToolTip) && (@old_width != width || @old_height != height)
577
578
  root.gui_state.request_recalculate
578
579
 
579
580
  @old_width = width
@@ -624,7 +625,19 @@ module CyberarmEngine
624
625
  end
625
626
 
626
627
  def recalculate
627
- raise "#{self.class}#recalculate was not overridden!"
628
+ old_width = width
629
+ old_height = height
630
+
631
+ stylize
632
+ layout
633
+
634
+ root.gui_state.request_recalculate if @parent && !is_a?(ToolTip) && (width != old_width || height != old_height)
635
+ root.gui_state.request_repaint if width != old_width || height != old_height
636
+
637
+ root.gui_state.menu.recalculate if root.gui_state.menu && root.gui_state.menu.parent == self
638
+ end
639
+
640
+ def layout
628
641
  end
629
642
 
630
643
  def reposition
@@ -34,7 +34,7 @@ module CyberarmEngine
34
34
  @text.draw
35
35
  end
36
36
 
37
- def recalculate
37
+ def layout
38
38
  unless @enabled
39
39
  @style.background_canvas.background = @style.disabled[:background]
40
40
  @text.color = @style.disabled[:color]
@@ -4,7 +4,7 @@ module CyberarmEngine
4
4
  include Common
5
5
 
6
6
  attr_accessor :stroke_color, :fill_color
7
- attr_reader :children, :gui_state, :scroll_position
7
+ attr_reader :children, :gui_state, :scroll_position, :scroll_target_position
8
8
 
9
9
  def self.current_container
10
10
  @@current_container
@@ -49,9 +49,7 @@ module CyberarmEngine
49
49
  root.gui_state.request_recalculate_for(self) if @children.delete(element)
50
50
  end
51
51
 
52
- def clear(&block)
53
- @children.clear
54
-
52
+ def append(&block)
55
53
  old_container = CyberarmEngine::Element::Container.current_container
56
54
 
57
55
  CyberarmEngine::Element::Container.current_container = self
@@ -62,7 +60,9 @@ module CyberarmEngine
62
60
  root.gui_state.request_recalculate_for(self)
63
61
  end
64
62
 
65
- def append(&block)
63
+ def clear(&block)
64
+ @children.clear
65
+
66
66
  old_container = CyberarmEngine::Element::Container.current_container
67
67
 
68
68
  CyberarmEngine::Element::Container.current_container = self
@@ -95,7 +95,7 @@ module CyberarmEngine
95
95
  end
96
96
 
97
97
  def update
98
- update_scroll
98
+ update_scroll if @style.scroll
99
99
  @children.each(&:update)
100
100
  end
101
101
 
@@ -128,23 +128,16 @@ module CyberarmEngine
128
128
  end
129
129
 
130
130
  def update_scroll
131
- dt = window.dt > 1 ? 1.0 : window.dt
132
-
133
- scroll_x_diff = (@scroll_target_position.x - @scroll_position.x)
134
- scroll_y_diff = (@scroll_target_position.y - @scroll_position.y)
135
-
136
- @scroll_position.x += (scroll_x_diff * @scroll_speed * 0.25 * dt).round
137
- @scroll_position.y += (scroll_y_diff * @scroll_speed * 0.25 * dt).round
138
-
139
- @scroll_position.x = @scroll_target_position.x if scroll_x_diff.abs < 1.0
140
- @scroll_position.y = @scroll_target_position.y if scroll_y_diff.abs < 1.0
131
+ dt = window.dt.clamp(0.000001, 0.025)
132
+ @scroll_position.x += (((@scroll_target_position.x - @scroll_position.x) * (@scroll_speed / 4.0) * 0.98) * dt).round
133
+ @scroll_position.y += (((@scroll_target_position.y - @scroll_position.y) * (@scroll_speed / 4.0) * 0.98) * dt).round
141
134
 
142
135
  # Scrolled PAST top
143
136
  if @scroll_position.y > 0
144
137
  @scroll_target_position.y = 0
145
138
 
146
139
  # Scrolled PAST bottom
147
- elsif @scroll_position.y.abs > max_scroll_height
140
+ elsif @scroll_position.y < -max_scroll_height
148
141
  @scroll_target_position.y = -max_scroll_height
149
142
  end
150
143
 
@@ -158,20 +151,24 @@ module CyberarmEngine
158
151
  end
159
152
 
160
153
  def recalculate
154
+ return if @in_recalculate
155
+
156
+ @in_recalculate = true
157
+
161
158
  @current_position = Vector.new(@style.margin_left + @style.padding_left, @style.margin_top + @style.padding_top)
162
159
 
163
160
  return unless visible?
164
161
 
165
- Stats.frame.increment(:gui_recalculations)
166
-
167
- stylize
162
+ Stats.frame&.increment(:gui_recalculations)
168
163
 
169
164
  # s = Gosu.milliseconds
170
165
 
166
+ stylize
171
167
  layout
172
168
 
173
- old_width = @width
174
- old_height = @height
169
+ # Old sizes MUST be determined AFTER call to layout
170
+ old_width = width
171
+ old_height = height
175
172
 
176
173
  @cached_scroll_width = nil
177
174
  @cached_scroll_height = nil
@@ -214,6 +211,7 @@ module CyberarmEngine
214
211
  end
215
212
  end
216
213
 
214
+ # t = Gosu.milliseconds
217
215
  # Move children to parent after positioning
218
216
  @children.each do |child|
219
217
  child.x += (@x + @style.border_thickness_left) - style.margin_left
@@ -223,35 +221,30 @@ module CyberarmEngine
223
221
  child.recalculate
224
222
  child.reposition # TODO: Implement top,bottom,left,center, and right positioning
225
223
 
226
- Stats.frame.increment(:gui_recalculations)
224
+ Stats.frame&.increment(:gui_recalculations)
227
225
 
228
226
  update_child_element_visibity(child)
229
227
  end
230
-
231
- # puts "TOOK: #{Gosu.milliseconds - s}ms to recalculate #{self.class}:0x#{self.object_id.to_s(16)}"
228
+ # puts "TOOK: #{Gosu.milliseconds - t}ms to recalculate #{self.class}:0x#{self.object_id.to_s(16)}'s #{@children.count} children"
232
229
 
233
230
  update_background
234
231
 
235
232
  # Fixes resized container scrolled past bottom
236
- self.scroll_top = -@scroll_position.y
237
- @scroll_target_position.y = @scroll_position.y
233
+ if old_height != @height
234
+ self.scroll_top = -@scroll_position.y
235
+ @scroll_target_position.y = @scroll_position.y
236
+ end
238
237
 
239
238
  # Fixes resized container that is scrolled down from being stuck overscrolled when resized
240
239
  if scroll_height < height
241
240
  @scroll_target_position.y = 0
242
241
  end
243
242
 
244
- # NOTE: Experiment for removing need to explicitly call gui_state#recalculate at least 3 times for layout to layout...
245
- if old_width != @width || old_height != @height
246
- if @parent
247
- root.gui_state.request_recalculate_for(@parent)
248
- else
249
- root.gui_state.request_recalculate
250
- end
251
- end
252
-
253
- root.gui_state.request_repaint if @width != old_width || @height != old_height
254
243
  recalculate_if_size_changed
244
+
245
+ # puts "TOOK: #{Gosu.milliseconds - s}ms to recalculate #{self.class}:0x#{self.object_id.to_s(16)}"
246
+
247
+ @in_recalculate = false
255
248
  end
256
249
 
257
250
  def layout
@@ -337,6 +330,44 @@ module CyberarmEngine
337
330
  return :handled
338
331
  end
339
332
 
333
+ def scroll_jump_to_top(sender, x, y)
334
+ return unless @style.scroll
335
+
336
+ @scroll_position.y = 0
337
+ @scroll_target_position.y = 0
338
+
339
+ return :handled
340
+ end
341
+
342
+ def scroll_jump_to_end(sender, x, y)
343
+ return unless @style.scroll
344
+
345
+ @scroll_position.y = -max_scroll_height
346
+ @scroll_target_position.y = -max_scroll_height
347
+
348
+ return :handled
349
+ end
350
+
351
+ def scroll_page_up(sender, x, y)
352
+ return unless @style.scroll
353
+
354
+ @scroll_position.y += height
355
+ @scroll_position.y = 0 if @scroll_position.y > 0
356
+ @scroll_target_position.y = @scroll_position.y
357
+
358
+ return :handled
359
+ end
360
+
361
+ def scroll_page_down(sender, x, y)
362
+ return unless @style.scroll
363
+
364
+ @scroll_position.y -= height
365
+ @scroll_position.y = -max_scroll_height if @scroll_position.y < -max_scroll_height
366
+ @scroll_target_position.y = @scroll_position.y
367
+
368
+ return :handled
369
+ end
370
+
340
371
  def scroll_top
341
372
  @scroll_position.y
342
373
  end
@@ -278,7 +278,7 @@ module CyberarmEngine
278
278
  :handled
279
279
  end
280
280
 
281
- def recalculate
281
+ def layout
282
282
  super
283
283
 
284
284
  @width = dimensional_size(@style.width, :width) || default(:width)
@@ -27,7 +27,7 @@ module CyberarmEngine
27
27
  :handled
28
28
  end
29
29
 
30
- def recalculate
30
+ def layout
31
31
  _width = dimensional_size(@style.width, :width)
32
32
  _height = dimensional_size(@style.height, :height)
33
33
 
@@ -12,21 +12,7 @@ module CyberarmEngine
12
12
 
13
13
  @style.background_canvas.background = default(:background)
14
14
 
15
- # TODO: "Clean Up" into own class?
16
- @menu = Stack.new(parent: self, 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
-
21
- @y = @__list_box.y - height if @y + height > window.height
22
- end
23
- @menu.instance_variable_set(:"@__list_box", self)
24
-
25
- def @menu.recalculate
26
- super
27
-
28
- recalculate_menu
29
- end
15
+ @menu = Menu.new(parent: self, theme: @options[:theme])
30
16
 
31
17
  self.choose = @choose
32
18
  end
@@ -40,7 +26,13 @@ module CyberarmEngine
40
26
 
41
27
  def choose=(item)
42
28
  valid = @items.detect { |i| i == item }
43
- raise "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}" unless valid
29
+
30
+ unless valid
31
+ warn "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}"
32
+ item = @items.first
33
+
34
+ raise "No items list" unless item
35
+ end
44
36
 
45
37
  @choose = item
46
38
 
@@ -62,39 +54,25 @@ module CyberarmEngine
62
54
  end
63
55
 
64
56
  def show_menu
65
- @menu.clear
66
-
67
- @menu.style.width = width
68
-
69
- @items.each do |item|
70
- next if item == self.value
71
-
72
- btn = Button.new(
73
- item,
74
- {
75
- parent: @menu,
76
- width: 1.0,
77
- theme: @options[:theme],
78
- margin: 0,
79
- border_color: 0x00ffffff
80
- },
81
- proc do
57
+ @menu.clear do
58
+
59
+ @menu.style.width = width
60
+
61
+ @items.each do |item|
62
+ # prevent already selected item from appearing in list
63
+ # NOTE: Remove this? Might be kinda confusing...
64
+ next if item == self.value
65
+
66
+ root.gui_state.menu_item(item, width: 1.0, margin: 0, border_color: 0x00ffffff) do
82
67
  self.choose = item
83
68
  @block&.call(self.value)
84
69
  end
85
- )
86
-
87
- @menu.add(btn)
70
+ end
88
71
  end
89
- recalculate
90
72
 
91
- root.gui_state.show_menu(@menu)
92
- end
93
-
94
- def recalculate
95
- super
73
+ recalculate
96
74
 
97
- @menu.recalculate
75
+ @menu.show
98
76
  end
99
77
  end
100
78
  end
@@ -0,0 +1,27 @@
1
+ module CyberarmEngine
2
+ class Element
3
+ class Menu < Stack
4
+ def recalculate
5
+ super
6
+
7
+ recalculate_menu
8
+ end
9
+
10
+ def recalculate_menu
11
+ # FIXME: properly find scrollable parent, if any.
12
+ parent_scroll_top = parent&.parent ? parent.parent.scroll_top : 0
13
+
14
+ @x = @parent.x
15
+ @y = parent_scroll_top + @parent.y + @parent.height
16
+
17
+ @y = (parent_scroll_top + @parent.y) - height if @y + height > window.height
18
+ end
19
+
20
+ def show
21
+ recalculate
22
+
23
+ root.gui_state.show_menu(self)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,6 @@
1
+ module CyberarmEngine
2
+ class Element
3
+ class MenuItem < Button
4
+ end
5
+ end
6
+ end
@@ -19,7 +19,7 @@ module CyberarmEngine
19
19
  @fraction_background.draw
20
20
  end
21
21
 
22
- def recalculate
22
+ def layout
23
23
  _width = dimensional_size(@style.width, :width)
24
24
  _height = dimensional_size(@style.height, :height)
25
25
  @width = _width
@@ -33,7 +33,7 @@ module CyberarmEngine
33
33
  end
34
34
  end
35
35
 
36
- attr_reader :step_size, :value
36
+ attr_reader :value
37
37
  attr_accessor :range, :step_size
38
38
 
39
39
  def initialize(options = {}, block = nil)
@@ -38,16 +38,13 @@ module CyberarmEngine
38
38
  end
39
39
  end
40
40
 
41
- def recalculate
41
+ def layout
42
42
  unless @enabled
43
43
  @text.color = @style.disabled[:color]
44
44
  else
45
45
  @text.color = @style.color
46
46
  end
47
47
 
48
- old_width = @width
49
- old_height = @height
50
-
51
48
  @width = 0
52
49
  @height = 0
53
50
 
@@ -91,9 +88,6 @@ module CyberarmEngine
91
88
  end
92
89
 
93
90
  update_background
94
-
95
- root.gui_state.request_repaint if @width != old_width || @height != old_height
96
- recalculate_if_size_changed
97
91
  end
98
92
 
99
93
  def handle_text_wrapping(max_width)
@@ -7,8 +7,6 @@ module CyberarmEngine
7
7
  if options.dig(:theme, :ToggleButton, :checkmark_image)
8
8
  options[:theme][:ToggleButton][:image_width] ||= options[:theme][:TextBlock][:text_size]
9
9
  super(get_image(options.dig(:theme, :ToggleButton, :checkmark_image)), options, block)
10
-
11
- @_image = @image
12
10
  else
13
11
  super(options[:checkmark], options, block)
14
12
  end
@@ -16,10 +14,8 @@ module CyberarmEngine
16
14
  @value = options[:checked] || false
17
15
 
18
16
  if @value
19
- @image = @_image if @_image
20
17
  @raw_text = @options[:checkmark]
21
18
  else
22
- @image = nil
23
19
  @raw_text = ""
24
20
  end
25
21
  end
@@ -32,6 +28,14 @@ module CyberarmEngine
32
28
  :handled
33
29
  end
34
30
 
31
+ def render
32
+ if @image
33
+ draw_image if @value
34
+ else
35
+ draw_text
36
+ end
37
+ end
38
+
35
39
  def recalculate
36
40
  super
37
41
  return if @image
@@ -49,10 +53,8 @@ module CyberarmEngine
49
53
  @value = boolean
50
54
 
51
55
  if boolean
52
- @image = @_image if @_image
53
56
  @raw_text = @options[:checkmark]
54
57
  else
55
- @image = nil
56
58
  @raw_text = ""
57
59
  end
58
60
 
@@ -38,6 +38,10 @@ module CyberarmEngine
38
38
  @tip = Element::ToolTip.new("", parent: @root_container, z: Float::INFINITY, theme: current_theme)
39
39
  end
40
40
 
41
+ def menu
42
+ @menu
43
+ end
44
+
41
45
  # throws :blur event to focused element and sets GuiState focused element
42
46
  # Does NOT throw :focus event at element or set element as focused
43
47
  def focus=(element)
@@ -50,6 +54,24 @@ module CyberarmEngine
50
54
  end
51
55
 
52
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
+
53
75
  super
54
76
 
55
77
  if @menu
@@ -63,8 +85,7 @@ module CyberarmEngine
63
85
  @tip.draw
64
86
  end
65
87
 
66
- # FIXME
67
- if false# defined?(GUI_DEBUG)
88
+ if CyberarmEngine.const_defined?("GUI_DEBUG")
68
89
  Gosu.flush
69
90
 
70
91
  @root_container.debug_draw
@@ -78,24 +99,6 @@ module CyberarmEngine
78
99
  end
79
100
 
80
101
  def update
81
- Stats.frame.start_timing(:gui_element_recalculate_requests)
82
-
83
- # puts "PENDING REQUESTS: #{@pending_element_recalculate_requests.size}" if @pending_element_recalculate_requests.size.positive?
84
- @pending_element_recalculate_requests.each(&:recalculate)
85
- @pending_element_recalculate_requests.clear
86
-
87
- Stats.frame.end_timing(:gui_element_recalculate_requests)
88
-
89
- if @pending_recalculate_request
90
- Stats.frame.start_timing(:gui_recalculate)
91
-
92
- @root_container.recalculate
93
-
94
- @pending_recalculate_request = false
95
-
96
- Stats.frame.end_timing(:gui_recalculate)
97
- end
98
-
99
102
  if @pending_focus_request
100
103
  @pending_focus_request = false
101
104
 
@@ -186,6 +189,14 @@ module CyberarmEngine
186
189
  redirect_mouse_wheel(:up)
187
190
  when Gosu::MS_WHEEL_DOWN
188
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)
189
200
  end
190
201
 
191
202
  @focus.button_up(id) if @focus.respond_to?(:button_up)
@@ -251,7 +262,15 @@ module CyberarmEngine
251
262
  end
252
263
 
253
264
  def redirect_mouse_wheel(button)
254
- @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if @mouse_over
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)
255
274
  end
256
275
 
257
276
  # Schedule a full GUI recalculation on next update
@@ -208,6 +208,17 @@ module CyberarmEngine
208
208
  fraction_background: [0xffc75e61, 0xffe26623],
209
209
  border_thickness: 1,
210
210
  border_color: [0xffd59674, 0xffff8746]
211
+ },
212
+ Menu: { # < Stack
213
+ width: 200,
214
+ border_color: 0xaa_efefef,
215
+ border_thickness: 1
216
+ },
217
+
218
+ MenuItem: { # < Button
219
+ width: 1.0,
220
+ text_left: :left,
221
+ margin: 0
211
222
  }
212
223
  }.freeze
213
224
  end
@@ -1,4 +1,4 @@
1
1
  module CyberarmEngine
2
2
  NAME = "InDev".freeze
3
- VERSION = "0.24.2".freeze
3
+ VERSION = "0.24.3".freeze
4
4
  end
@@ -6,7 +6,6 @@ else
6
6
  require "gosu"
7
7
  end
8
8
  require "json"
9
- require "excon"
10
9
 
11
10
  require_relative "cyberarm_engine/version"
12
11
  require_relative "cyberarm_engine/stats"
@@ -62,6 +61,8 @@ require_relative "cyberarm_engine/ui/elements/check_box"
62
61
  require_relative "cyberarm_engine/ui/elements/radio"
63
62
  require_relative "cyberarm_engine/ui/elements/progress"
64
63
  require_relative "cyberarm_engine/ui/elements/slider"
64
+ require_relative "cyberarm_engine/ui/elements/menu"
65
+ require_relative "cyberarm_engine/ui/elements/menu_item"
65
66
 
66
67
  require_relative "cyberarm_engine/game_state"
67
68
  require_relative "cyberarm_engine/ui/gui_state"
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyberarm_engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.2
4
+ version: 0.24.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyberarm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-29 00:00:00.000000000 Z
11
+ date: 2024-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: excon
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '0.88'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '0.88'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: gosu
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -38,20 +24,6 @@ dependencies:
38
24
  - - "~>"
39
25
  - !ruby/object:Gem::Version
40
26
  version: '1.1'
41
- - !ruby/object:Gem::Dependency
42
- name: gosu_more_drawables
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.3'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.3'
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: bundler
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -174,6 +146,8 @@ files:
174
146
  - lib/cyberarm_engine/ui/elements/flow.rb
175
147
  - lib/cyberarm_engine/ui/elements/image.rb
176
148
  - lib/cyberarm_engine/ui/elements/list_box.rb
149
+ - lib/cyberarm_engine/ui/elements/menu.rb
150
+ - lib/cyberarm_engine/ui/elements/menu_item.rb
177
151
  - lib/cyberarm_engine/ui/elements/progress.rb
178
152
  - lib/cyberarm_engine/ui/elements/radio.rb
179
153
  - lib/cyberarm_engine/ui/elements/slider.rb