diff --git a/lib/cyberarm_engine/stats.rb b/lib/cyberarm_engine/stats.rb
index a993609..6c3091b 100644
--- a/lib/cyberarm_engine/stats.rb
+++ b/lib/cyberarm_engine/stats.rb
@@ -115,11 +115,11 @@ module CyberarmEngine
@padding = 2
@text_size = 16
- @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true)
- @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)
- @min_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @height - (@text_size + @padding / 2), z: z, size: @text_size, border: true)
+ @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true, static: true)
+ @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)
+ @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)
- @timings_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true)
+ @data_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true, static: true)
@frame_stats = []
@graphs = {
@@ -159,9 +159,9 @@ module CyberarmEngine
calculate_graphs
- @max_timing_label.text = "Max: #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
- @avg_timing_label.text = "Avg: #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
- @min_timing_label.text = "Min: #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
+ @max_timing_label.text = "Max: #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
+ @avg_timing_label.text = "Avg: #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
+ @min_timing_label.text = "Min: #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
Gosu.draw_rect(@position.x, @position.y, @width, @height, 0xaa_222222, @position.z)
Gosu.draw_rect(@position.x + @padding, @position.y + @padding, @width - @padding * 2, @height - @padding * 2, 0xaa_222222, @position.z)
@@ -173,19 +173,20 @@ module CyberarmEngine
@min_timing_label.draw
# TODO: Make this optional
- draw_timings
+ draw_timings_and_counters
end
def draw_graphs
Gosu.draw_path(@graphs[:frame_timings], Gosu::Color::WHITE, Float::INFINITY)
end
- def draw_timings
+ def draw_timings_and_counters
frame = @frame_stats.last
- @timings_label.text = "#{frame.attempted_multitiming? ? "Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
- 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)
- @timings_label.draw
+ @data_label.text = "COUNTERS:\n#{frame.counters.map { |t, v| "#{t}: #{v}" }.join("\n")}\n\n"\
+ "TIMINGS:\n#{frame.attempted_multitiming? ? "Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
+ 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)
+ @data_label.draw
end
end
end
diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb
index 0d5bb3a..29aaf74 100644
--- a/lib/cyberarm_engine/ui/element.rb
+++ b/lib/cyberarm_engine/ui/element.rb
@@ -197,6 +197,10 @@ module CyberarmEngine
event(:mouse_wheel_up)
event(:mouse_wheel_down)
+ event(:scroll_jump_to_top)
+ event(:scroll_jump_to_end)
+ event(:scroll_page_up)
+ event(:scroll_page_down)
event(:enter)
event(:hover)
diff --git a/lib/cyberarm_engine/ui/elements/container.rb b/lib/cyberarm_engine/ui/elements/container.rb
index 14d2b70..7e8093a 100644
--- a/lib/cyberarm_engine/ui/elements/container.rb
+++ b/lib/cyberarm_engine/ui/elements/container.rb
@@ -4,7 +4,7 @@ module CyberarmEngine
include Common
attr_accessor :stroke_color, :fill_color
- attr_reader :children, :gui_state, :scroll_position
+ attr_reader :children, :gui_state, :scroll_position, :scroll_target_position
def self.current_container
@@current_container
@@ -95,7 +95,7 @@ module CyberarmEngine
end
def update
- update_scroll
+ update_scroll if @style.scroll
@children.each(&:update)
end
@@ -128,23 +128,16 @@ module CyberarmEngine
end
def update_scroll
- dt = window.dt > 1 ? 1.0 : window.dt
-
- scroll_x_diff = (@scroll_target_position.x - @scroll_position.x)
- scroll_y_diff = (@scroll_target_position.y - @scroll_position.y)
-
- @scroll_position.x += (scroll_x_diff * @scroll_speed * 0.25 * dt).round
- @scroll_position.y += (scroll_y_diff * @scroll_speed * 0.25 * dt).round
-
- @scroll_position.x = @scroll_target_position.x if scroll_x_diff.abs < 1.0
- @scroll_position.y = @scroll_target_position.y if scroll_y_diff.abs < 1.0
+ dt = window.dt.clamp(0.000001, 0.025)
+ @scroll_position.x += (((@scroll_target_position.x - @scroll_position.x) * (@scroll_speed / 4.0) * 0.98) * dt).round
+ @scroll_position.y += (((@scroll_target_position.y - @scroll_position.y) * (@scroll_speed / 4.0) * 0.98) * dt).round
# Scrolled PAST top
if @scroll_position.y > 0
@scroll_target_position.y = 0
# Scrolled PAST bottom
- elsif @scroll_position.y.abs > max_scroll_height
+ elsif @scroll_position.y < -max_scroll_height
@scroll_target_position.y = -max_scroll_height
end
@@ -162,7 +155,7 @@ module CyberarmEngine
return unless visible?
- Stats.frame.increment(:gui_recalculations)
+ Stats.frame&.increment(:gui_recalculations)
stylize
@@ -233,8 +226,10 @@ module CyberarmEngine
update_background
# Fixes resized container scrolled past bottom
- self.scroll_top = -@scroll_position.y
- @scroll_target_position.y = @scroll_position.y
+ if old_height != @height
+ self.scroll_top = -@scroll_position.y
+ @scroll_target_position.y = @scroll_position.y
+ end
# Fixes resized container that is scrolled down from being stuck overscrolled when resized
if scroll_height < height
@@ -337,6 +332,44 @@ module CyberarmEngine
return :handled
end
+ def scroll_jump_to_top(sender, x, y)
+ return unless @style.scroll
+
+ @scroll_position.y = 0
+ @scroll_target_position.y = 0
+
+ return :handled
+ end
+
+ def scroll_jump_to_end(sender, x, y)
+ return unless @style.scroll
+
+ @scroll_position.y = -max_scroll_height
+ @scroll_target_position.y = -max_scroll_height
+
+ return :handled
+ end
+
+ def scroll_page_up(sender, x, y)
+ return unless @style.scroll
+
+ @scroll_position.y += height
+ @scroll_position.y = 0 if @scroll_position.y > 0
+ @scroll_target_position.y = @scroll_position.y
+
+ return :handled
+ end
+
+ def scroll_page_down(sender, x, y)
+ return unless @style.scroll
+
+ @scroll_position.y -= height
+ @scroll_position.y = -max_scroll_height if @scroll_position.y < -max_scroll_height
+ @scroll_target_position.y = @scroll_position.y
+
+ return :handled
+ end
+
def scroll_top
@scroll_position.y
end
diff --git a/lib/cyberarm_engine/ui/elements/list_box.rb b/lib/cyberarm_engine/ui/elements/list_box.rb
index 71cdb19..c763509 100644
--- a/lib/cyberarm_engine/ui/elements/list_box.rb
+++ b/lib/cyberarm_engine/ui/elements/list_box.rb
@@ -16,9 +16,9 @@ module CyberarmEngine
@menu = Stack.new(parent: self, theme: @options[:theme])
@menu.define_singleton_method(:recalculate_menu) do
@x = @__list_box.x
- @y = @__list_box.y + @__list_box.height
+ @y = parent.parent.scroll_top + @__list_box.y + @__list_box.height
- @y = @__list_box.y - height if @y + height > window.height
+ @y = (parent.parent.scroll_top + @__list_box.y) - height if @y + height > window.height
end
@menu.instance_variable_set(:"@__list_box", self)
diff --git a/lib/cyberarm_engine/ui/gui_state.rb b/lib/cyberarm_engine/ui/gui_state.rb
index e4ddfb8..1e037fe 100644
--- a/lib/cyberarm_engine/ui/gui_state.rb
+++ b/lib/cyberarm_engine/ui/gui_state.rb
@@ -186,6 +186,14 @@ module CyberarmEngine
redirect_mouse_wheel(:up)
when Gosu::MS_WHEEL_DOWN
redirect_mouse_wheel(:down)
+ when Gosu::KB_HOME
+ redirect_scroll_jump_to(:top)
+ when Gosu::KB_END
+ redirect_scroll_jump_to(:end)
+ when Gosu::KB_PAGE_UP
+ redirect_scroll_page(:up)
+ when Gosu::KB_PAGE_DOWN
+ redirect_scroll_page(:down)
end
@focus.button_up(id) if @focus.respond_to?(:button_up)
@@ -251,7 +259,15 @@ module CyberarmEngine
end
def redirect_mouse_wheel(button)
- @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if @mouse_over
+ @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
+ end
+
+ def redirect_scroll_jump_to(edge)
+ @mouse_over.publish(:"scroll_jump_to_#{edge}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
+ end
+
+ def redirect_scroll_page(edge)
+ @mouse_over.publish(:"scroll_page_#{edge}", window.mouse_x, window.mouse_y) if (@mouse_over && !@menu) || (@mouse_over && @mouse_over == @menu)
end
# Schedule a full GUI recalculation on next update