diff --git a/lib/cyberarm_engine.rb b/lib/cyberarm_engine.rb index 41727c5..3952397 100644 --- a/lib/cyberarm_engine.rb +++ b/lib/cyberarm_engine.rb @@ -8,6 +8,7 @@ require "json" require "gosu_more_drawables" require_relative "cyberarm_engine/version" +require_relative "cyberarm_engine/stats" require_relative "cyberarm_engine/common" diff --git a/lib/cyberarm_engine/stats.rb b/lib/cyberarm_engine/stats.rb new file mode 100644 index 0000000..9a9205a --- /dev/null +++ b/lib/cyberarm_engine/stats.rb @@ -0,0 +1,21 @@ +module CyberarmEngine + class Stats + @@hash = { + gui_recalculations_last_frame: 0 + } + + def self.get(key) + @@hash.dig(key) + end + + def self.increment(key, n) + @@hash[key] += n + end + + def self.clear + @@hash.each do |key, value| + @@hash[key] = 0 + end + end + end +end \ No newline at end of file diff --git a/lib/cyberarm_engine/text.rb b/lib/cyberarm_engine/text.rb index 0dbeea9..2c11693 100644 --- a/lib/cyberarm_engine/text.rb +++ b/lib/cyberarm_engine/text.rb @@ -9,7 +9,7 @@ module CyberarmEngine @text = text.to_s || "" @options = options @size = options[:size] || 18 - @font = options[:font] || "sans-serif"#Gosu.default_font_name + @font = options[:font] || Gosu.default_font_name @x = options[:x] || 0 @y = options[:y] || 0 @z = options[:z] || 1025 @@ -98,12 +98,12 @@ module CyberarmEngine @shadow_color = n end - def width - textobject.text_width(@text) + def width(text = @text) + textobject.text_width(text) end - def height - @text.lines.count > 0 ? (@text.lines.count) * textobject.height : @textobject.height + def height(text = @text) + text.lines.count > 0 ? (text.lines.count) * textobject.height : @textobject.height end def draw diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb index 272aecc..58a4b81 100644 --- a/lib/cyberarm_engine/ui/element.rb +++ b/lib/cyberarm_engine/ui/element.rb @@ -219,7 +219,7 @@ module CyberarmEngine raise "dimension must be either :width or :height" unless dimension == :width || dimension == :height if size && size.is_a?(Numeric) if size.between?(0.0, 1.0) - ((@parent.send(:"content_#{dimension}") - self.send(:"noncontent_#{dimension}") - 1) * size).round + ((@parent.send(:"content_#{dimension}") - self.send(:"noncontent_#{dimension}")) * size).round else size end @@ -246,6 +246,8 @@ module CyberarmEngine end def root + return self if is_root? + unless @root && @root.parent.nil? @root = parent @@ -279,5 +281,9 @@ module CyberarmEngine def value=(value) raise "#{self.class}#value= was not overridden!" end + + def to_s + "#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} value=#{ value.is_a?(String) ? "\"#{value}\"" : value }" + end end end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/elements/check_box.rb b/lib/cyberarm_engine/ui/elements/check_box.rb index fa4aacc..47958dc 100644 --- a/lib/cyberarm_engine/ui/elements/check_box.rb +++ b/lib/cyberarm_engine/ui/elements/check_box.rb @@ -2,7 +2,7 @@ module CyberarmEngine class Element class CheckBox < Flow def initialize(text, options, block = nil) - super({}, block = nil) + super(options, block) options[:toggled] = options[:checked] @toggle_button = ToggleButton.new(options) diff --git a/lib/cyberarm_engine/ui/elements/container.rb b/lib/cyberarm_engine/ui/elements/container.rb index 87a6d13..35058f3 100644 --- a/lib/cyberarm_engine/ui/elements/container.rb +++ b/lib/cyberarm_engine/ui/elements/container.rb @@ -22,13 +22,13 @@ module CyberarmEngine def build @block.call(self) if @block - recalculate + root.gui_state.request_recalculate end def add(element) @children << element - recalculate + root.gui_state.request_recalculate end def clear(&block) @@ -41,7 +41,6 @@ module CyberarmEngine $__current_container__ = old_container - recalculate root.gui_state.request_recalculate end @@ -75,6 +74,9 @@ module CyberarmEngine def recalculate @current_position = Vector.new(@style.margin_left + @style.padding_left, @style.margin_top + @style.padding_top) return unless visible? + + Stats.increment(:gui_recalculations_last_frame, 1) + stylize layout @@ -92,7 +94,6 @@ module CyberarmEngine @height = _height ? _height : (@children.map {|c| c.y + c.outer_height}.max || 0).round end - # Move child to parent after positioning @children.each do |child| child.x += (@x + @style.border_thickness_left) - style.margin_left @@ -101,6 +102,8 @@ module CyberarmEngine child.stylize child.recalculate child.reposition # TODO: Implement top,bottom,left,center, and right positioning + + Stats.increment(:gui_recalculations_last_frame, 1) end update_background @@ -110,13 +113,13 @@ module CyberarmEngine raise "Not overridden" end - # TODO: Fix @max_width no longer exists def max_width - @max_width ? @max_width : window.width - (@parent ? @parent.style.margin_right + @style.margin_right : @style.margin_right) + _width = dimensional_size(@style.width, :width) + _width ? outer_width : window.width - (@parent ? @parent.style.margin_right + @style.margin_right : @style.margin_right) end - # TODO: Fix container automatic width (0.0..1.0) not considered def fits_on_line?(element) # Flow + p [@options[:id], @width] if @options[:id] @current_position.x + element.outer_width <= max_width && @current_position.x + element.outer_width <= window.width end @@ -175,6 +178,25 @@ module CyberarmEngine def value @children.map {|c| c.class}.join(", ") end + + def to_s + "#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} children=#{@children.size}" + end + + def write_tree(indent = "", index = 0) + puts self + + indent = indent + " " + @children.each_with_index do |child, i| + print "#{indent}#{i}: " + + if child.is_a?(Container) + child.write_tree(indent) + else + puts child + end + end + end end end end diff --git a/lib/cyberarm_engine/ui/elements/edit_line.rb b/lib/cyberarm_engine/ui/elements/edit_line.rb index 62c66a1..df74162 100644 --- a/lib/cyberarm_engine/ui/elements/edit_line.rb +++ b/lib/cyberarm_engine/ui/elements/edit_line.rb @@ -100,6 +100,22 @@ module CyberarmEngine end end + def caret_position + text_input_position_for(:caret_pos) + end + + def selection_start_position + text_input_position_for(:selection_start) + end + + def text_input_position_for(method) + if @type == :password + @text.x + @text.width(default(:password_character) * @text_input.text[0..@text_input.send(method)].length) + else + @text.x + @text.width(@text_input.text[0..@text_input.send(method)]) + end + end + def left_mouse_button(sender, x, y) super window.text_input = @text_input @@ -141,22 +157,6 @@ module CyberarmEngine return :handled end - def caret_position - text_input_position_for(:caret_pos) - end - - def selection_start_position - text_input_position_for(:selection_start) - end - - def text_input_position_for(method) - if @type == :password - @text.x + @text.textobject.text_width(default(:password_character) * @text_input.text[0..@text_input.send(method)].length) - else - @text.x + @text.textobject.text_width(@text_input.text[0..@text_input.send(method)]) - end - end - def recalculate super diff --git a/lib/cyberarm_engine/ui/elements/flow.rb b/lib/cyberarm_engine/ui/elements/flow.rb index 76ce972..9574f5c 100644 --- a/lib/cyberarm_engine/ui/elements/flow.rb +++ b/lib/cyberarm_engine/ui/elements/flow.rb @@ -1,8 +1,6 @@ module CyberarmEngine class Element class Flow < Container - include Common - def layout @children.each do |child| if fits_on_line?(child) diff --git a/lib/cyberarm_engine/ui/elements/slider.rb b/lib/cyberarm_engine/ui/elements/slider.rb index 91cd67a..7850819 100644 --- a/lib/cyberarm_engine/ui/elements/slider.rb +++ b/lib/cyberarm_engine/ui/elements/slider.rb @@ -52,16 +52,20 @@ module CyberarmEngine @width = _width @height = _height - @handle.x = @x + @style.border_thickness_left + @style.padding_left - @handle.y = @y + @style.border_thickness_top + @style.padding_top + position_handle @handle.recalculate @handle.update_background - # pp @handle.height - update_background end + def position_handle + @handle.x = @x + @style.padding_left + @style.border_thickness_left + + ((content_width - @handle.outer_width) * (@value - @range.min) / (@range.max - @range.min).to_f) + + @handle.y = @y + @style.border_thickness_top + @style.padding_top + end + def draw super @@ -82,13 +86,9 @@ module CyberarmEngine end def handle_dragged_to(x, y) - puts - pp x, y, @handle.width, content_width - @ratio = ((x - @handle.width) - @x) / content_width + @ratio = ((x - @handle.width / 2) - @x) / (content_width - @handle.outer_width) - # p [@ratio, @value] self.value = @ratio.clamp(0.0, 1.0) * (@range.max - @range.min) + @range.min - end def value @@ -97,9 +97,7 @@ module CyberarmEngine def value=(n) @value = n - @handle.x = @x + @style.padding_left + @style.border_thickness_left + - (content_width * (@value - @range.min) / (@range.max - @range.min).to_f) - + position_handle @handle.recalculate publish(:changed, @value) diff --git a/lib/cyberarm_engine/ui/elements/stack.rb b/lib/cyberarm_engine/ui/elements/stack.rb index 3d01c0c..ae93925 100644 --- a/lib/cyberarm_engine/ui/elements/stack.rb +++ b/lib/cyberarm_engine/ui/elements/stack.rb @@ -1,8 +1,6 @@ module CyberarmEngine class Element class Stack < Container - include Common - def layout @children.each do |child| move_to_next_line(child) diff --git a/lib/cyberarm_engine/ui/gui_state.rb b/lib/cyberarm_engine/ui/gui_state.rb index 9f3e82d..b45185b 100644 --- a/lib/cyberarm_engine/ui/gui_state.rb +++ b/lib/cyberarm_engine/ui/gui_state.rb @@ -51,6 +51,7 @@ module CyberarmEngine def update if @pending_recalculate_request + @root_container.recalculate @root_container.recalculate @pending_recalculate_request = false end @@ -104,6 +105,8 @@ module CyberarmEngine redirect_mouse_button(:middle) when Gosu::MsRight redirect_mouse_button(:right) + when Gosu::KbF5 + request_recalculate end end diff --git a/lib/cyberarm_engine/ui/theme.rb b/lib/cyberarm_engine/ui/theme.rb index ed5f1e9..2a26e65 100644 --- a/lib/cyberarm_engine/ui/theme.rb +++ b/lib/cyberarm_engine/ui/theme.rb @@ -88,7 +88,7 @@ module CyberarmEngine caret_width: 2, caret_color: Gosu::Color::WHITE, caret_interval: 500, - selection_color: Gosu::Color::GREEN, + selection_color: Gosu::Color.rgba(255, 128, 50, 200), }, Image: { # < Element diff --git a/lib/cyberarm_engine/window.rb b/lib/cyberarm_engine/window.rb index c166903..d1be708 100644 --- a/lib/cyberarm_engine/window.rb +++ b/lib/cyberarm_engine/window.rb @@ -34,6 +34,8 @@ module CyberarmEngine end def update + Stats.clear + current_state.update if current_state @last_frame_time = Gosu.milliseconds-@current_frame_time @current_frame_time = Gosu.milliseconds