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