cyberarm_engine 0.24.1 → 0.24.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13965f76fa986349341ba09e3219e26ea668b03ba5f73ff62f34631a8e70b4fe
4
- data.tar.gz: d5d4e839727bc95d667bf7c08b0995b89830db66fa038edd15072b2cf3d90773
3
+ metadata.gz: 863d7306cdc75ec88c4ee4fc80f963a685106bb139b1d94edf83381fe2cd1a01
4
+ data.tar.gz: 6eae0b303c0e192d5842d859f5c694f3f19ace8195f2fc7519fd59e82626cba5
5
5
  SHA512:
6
- metadata.gz: 994f8908dd69bf8e6f400ba08cc0f29ae0d32baa545d3da3c38bf75b3420c9fdd6df807e89720a274a7149bdf6eb18946541c341d2089b00151f58c1401c4183
7
- data.tar.gz: 95431b3371bcbfca6bcb70e3e4486affc62ede532a0e32c74c335f1b2e02b84d5fb5c42028ab619181d19e15962b92126917a0c195facac24c5d55228b0d99ca
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"
@@ -163,7 +163,7 @@ module CyberarmEngine
163
163
  elsif background.is_a?(Range)
164
164
  set([background.begin, background.begin, background.end, background.end])
165
165
  else
166
- raise ArgumentError, "background '#{background}' of type '#{background.class}' was not able to be processed"
166
+ raise ArgumentError, "background '#{background.inspect}' of type '#{background.class}' was not able to be processed"
167
167
  end
168
168
  end
169
169
  end
@@ -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
 
@@ -71,8 +71,19 @@ module CyberarmEngine
71
71
  root.gui_state.request_repaint
72
72
  end
73
73
 
74
- def safe_style_fetch(*args)
75
- @style.hash.dig(@style_event, *args) || @style.hash.dig(:default, *args) || default(*args)
74
+ def safe_style_fetch(key, fallback_key = nil)
75
+ # Attempt to return value for requested key
76
+ v = @style.hash.dig(@style_event, key)
77
+ return v if v
78
+
79
+ # Attempt to return overriding value
80
+ if fallback_key
81
+ v = @style.hash.dig(@style_event, fallback_key)
82
+ return v if v
83
+ end
84
+
85
+ # Fallback to default style
86
+ @style.hash.dig(:default, key) || default(key)
76
87
  end
77
88
 
78
89
  def set_static_position
@@ -104,10 +115,10 @@ module CyberarmEngine
104
115
 
105
116
  @style.background_nine_slice_from_edge = safe_style_fetch(:background_nine_slice_from_edge)
106
117
 
107
- @style.background_nine_slice_left = safe_style_fetch(:background_nine_slice_left) || @style.background_nine_slice_from_edge
108
- @style.background_nine_slice_top = safe_style_fetch(:background_nine_slice_top) || @style.background_nine_slice_from_edge
109
- @style.background_nine_slice_right = safe_style_fetch(:background_nine_slice_right) || @style.background_nine_slice_from_edge
110
- @style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom) || @style.background_nine_slice_from_edge
118
+ @style.background_nine_slice_left = safe_style_fetch(:background_nine_slice_left, :background_nine_slice_from_edge)
119
+ @style.background_nine_slice_top = safe_style_fetch(:background_nine_slice_top, :background_nine_slice_from_edge)
120
+ @style.background_nine_slice_right = safe_style_fetch(:background_nine_slice_right, :background_nine_slice_from_edge)
121
+ @style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom, :background_nine_slice_from_edge)
111
122
  end
112
123
 
113
124
  def set_background_image
@@ -121,19 +132,19 @@ module CyberarmEngine
121
132
  def set_border_thickness
122
133
  @style.border_thickness = safe_style_fetch(:border_thickness)
123
134
 
124
- @style.border_thickness_left = safe_style_fetch(:border_thickness_left) || @style.border_thickness
125
- @style.border_thickness_right = safe_style_fetch(:border_thickness_right) || @style.border_thickness
126
- @style.border_thickness_top = safe_style_fetch(:border_thickness_top) || @style.border_thickness
127
- @style.border_thickness_bottom = safe_style_fetch(:border_thickness_bottom) || @style.border_thickness
135
+ @style.border_thickness_left = safe_style_fetch(:border_thickness_left, :border_thickness)
136
+ @style.border_thickness_right = safe_style_fetch(:border_thickness_right, :border_thickness)
137
+ @style.border_thickness_top = safe_style_fetch(:border_thickness_top, :border_thickness)
138
+ @style.border_thickness_bottom = safe_style_fetch(:border_thickness_bottom, :border_thickness)
128
139
  end
129
140
 
130
141
  def set_border_color
131
142
  @style.border_color = safe_style_fetch(:border_color)
132
143
 
133
- @style.border_color_left = safe_style_fetch(:border_color_left) || @style.border_color
134
- @style.border_color_right = safe_style_fetch(:border_color_right) || @style.border_color
135
- @style.border_color_top = safe_style_fetch(:border_color_top) || @style.border_color
136
- @style.border_color_bottom = safe_style_fetch(:border_color_bottom) || @style.border_color
144
+ @style.border_color_left = safe_style_fetch(:border_color_left, :border_color)
145
+ @style.border_color_right = safe_style_fetch(:border_color_right, :border_color)
146
+ @style.border_color_top = safe_style_fetch(:border_color_top, :border_color)
147
+ @style.border_color_bottom = safe_style_fetch(:border_color_bottom, :border_color)
137
148
 
138
149
  @style.border_canvas.color = [
139
150
  @style.border_color_top,
@@ -146,19 +157,19 @@ module CyberarmEngine
146
157
  def set_padding
147
158
  @style.padding = safe_style_fetch(:padding)
148
159
 
149
- @style.padding_left = safe_style_fetch(:padding_left) || @style.padding
150
- @style.padding_right = safe_style_fetch(:padding_right) || @style.padding
151
- @style.padding_top = safe_style_fetch(:padding_top) || @style.padding
152
- @style.padding_bottom = safe_style_fetch(:padding_bottom) || @style.padding
160
+ @style.padding_left = safe_style_fetch(:padding_left, :padding)
161
+ @style.padding_right = safe_style_fetch(:padding_right, :padding)
162
+ @style.padding_top = safe_style_fetch(:padding_top, :padding)
163
+ @style.padding_bottom = safe_style_fetch(:padding_bottom, :padding)
153
164
  end
154
165
 
155
166
  def set_margin
156
167
  @style.margin = safe_style_fetch(:margin)
157
168
 
158
- @style.margin_left = safe_style_fetch(:margin_left) || @style.margin
159
- @style.margin_right = safe_style_fetch(:margin_right) || @style.margin
160
- @style.margin_top = safe_style_fetch(:margin_top) || @style.margin
161
- @style.margin_bottom = safe_style_fetch(:margin_bottom) || @style.margin
169
+ @style.margin_left = safe_style_fetch(:margin_left, :margin)
170
+ @style.margin_right = safe_style_fetch(:margin_right, :margin)
171
+ @style.margin_top = safe_style_fetch(:margin_top, :margin)
172
+ @style.margin_bottom = safe_style_fetch(:margin_bottom, :margin)
162
173
  end
163
174
 
164
175
  def update_styles(event = :default)
@@ -169,9 +180,7 @@ module CyberarmEngine
169
180
 
170
181
  return if self.is_a?(ToolTip)
171
182
 
172
- if old_width != width || old_height != height
173
- root.gui_state.request_recalculate
174
- end
183
+ root.gui_state.request_recalculate if old_width != width || old_height != height
175
184
 
176
185
  stylize
177
186
  end
@@ -186,6 +195,10 @@ module CyberarmEngine
186
195
 
187
196
  event(:mouse_wheel_up)
188
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)
189
202
 
190
203
  event(:enter)
191
204
  event(:hover)
@@ -318,8 +331,7 @@ module CyberarmEngine
318
331
  end
319
332
 
320
333
  def debug_draw
321
- # FIXME
322
- 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
323
335
 
324
336
  Gosu.draw_line(
325
337
  x, y, @debug_color,
@@ -337,7 +349,7 @@ module CyberarmEngine
337
349
  Float::INFINITY
338
350
  )
339
351
  Gosu.draw_line(
340
- x, outer_height, @debug_color,
352
+ x, y + outer_height, @debug_color,
341
353
  x, y, @debug_color,
342
354
  Float::INFINITY
343
355
  )
@@ -562,7 +574,7 @@ module CyberarmEngine
562
574
  end
563
575
 
564
576
  def recalculate_if_size_changed
565
- if !is_a?(ToolTip) && (@old_width != width || @old_height != height)
577
+ if @parent && !is_a?(ToolTip) && (@old_width != width || @old_height != height)
566
578
  root.gui_state.request_recalculate
567
579
 
568
580
  @old_width = width
@@ -613,7 +625,19 @@ module CyberarmEngine
613
625
  end
614
626
 
615
627
  def recalculate
616
- 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
617
641
  end
618
642
 
619
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.1".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.1
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-01-18 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