diff --git a/lib/cyberarm_engine/engine.rb b/lib/cyberarm_engine/engine.rb index c071b21..80c3219 100644 --- a/lib/cyberarm_engine/engine.rb +++ b/lib/cyberarm_engine/engine.rb @@ -65,7 +65,11 @@ module CyberarmEngine end def previous_state - state = @states[@states.size-2] + if @states.size > 1 && state = @states[@states.size-2] + return state + else + return nil + end end def pop_state diff --git a/lib/cyberarm_engine/game_state.rb b/lib/cyberarm_engine/game_state.rb index c2e6179..ebc2b0a 100644 --- a/lib/cyberarm_engine/game_state.rb +++ b/lib/cyberarm_engine/game_state.rb @@ -3,7 +3,7 @@ module CyberarmEngine include Common include DSL - attr_accessor :options, :global_pause, :active_container, :active_grid + attr_accessor :options, :global_pause attr_reader :game_objects, :containers def initialize(options={}) diff --git a/lib/cyberarm_engine/ui/button.rb b/lib/cyberarm_engine/ui/button.rb index 3251549..447d653 100644 --- a/lib/cyberarm_engine/ui/button.rb +++ b/lib/cyberarm_engine/ui/button.rb @@ -14,10 +14,10 @@ module CyberarmEngine if mouse_over? && $window.button_down?(Gosu::MsLeft) $window.draw_rect( - relative_x+@options[:interactive_border_size], - relative_y+@options[:interactive_border_size], - width-(@options[:interactive_border_size]*2), - height-(@options[:interactive_border_size]*2), + relative_x + @options[:interactive_border_size], + relative_y + @options[:interactive_border_size], + width - (@options[:interactive_border_size]*2), + height- (@options[:interactive_border_size]*2), @options[:interactive_active_background], @z+2 ) @@ -25,10 +25,10 @@ module CyberarmEngine @text.color = @options[:interactive_active_stroke] elsif mouse_over? $window.draw_rect( - relative_x+@options[:interactive_border_size], - relative_y+@options[:interactive_border_size], - width-(@options[:interactive_border_size]*2), - height-(@options[:interactive_border_size]*2), + relative_x + @options[:interactive_border_size], + relative_y + @options[:interactive_border_size], + width - (@options[:interactive_border_size]*2), + height- (@options[:interactive_border_size]*2), @options[:interactive_hover_background], @z+2 ) @@ -36,10 +36,10 @@ module CyberarmEngine @text.color = @options[:interactive_stroke] else $window.draw_rect( - relative_x+@options[:interactive_border_size], - relative_y+@options[:interactive_border_size], - width-(@options[:interactive_border_size]*2), - height-(@options[:interactive_border_size]*2), + relative_x + @options[:interactive_border_size], + relative_y + @options[:interactive_border_size], + width - (@options[:interactive_border_size]*2), + height- (@options[:interactive_border_size]*2), @options[:interactive_background], @z+2 ) diff --git a/lib/cyberarm_engine/ui/container.rb b/lib/cyberarm_engine/ui/container.rb index 987bef7..b460f98 100644 --- a/lib/cyberarm_engine/ui/container.rb +++ b/lib/cyberarm_engine/ui/container.rb @@ -3,7 +3,7 @@ module CyberarmEngine include Common attr_accessor :stroke_color, :fill_color, :background_color, :x, :y, :z, :width, :height - attr_reader :elements, :children, :options + attr_reader :elements, :children, :options, :parent attr_reader :scroll_x, :scroll_y, :internal_width, :internal_height attr_reader :origin_x, :origin_y, :origin_width, :origin_height @@ -35,6 +35,8 @@ module CyberarmEngine @scroll_x, @scroll_y = 0, 0 @scroll_speed = 10 + @layout = options[:layout] || :match_parent # or :wrap_content + @block = block @options = options @@ -61,6 +63,7 @@ module CyberarmEngine @elements << container recalculate + @internal_height+=container.height end def add(element) @@ -91,36 +94,54 @@ module CyberarmEngine case id when Gosu::MsWheelUp - scroll_down + scroll_down if mouse_over? && active_container when Gosu::MsWheelDown - scroll_up + scroll_up if mouse_over? && active_container end - @elements.each do |e| - if true#e.active_element - puts "REACHED" - e.button_up(id) - end - end - - end - - def scroll_up - @scroll_y += @scroll_speed - @scroll_y = 0 if @scroll_y > 0 + @elements.each {|e| if e.active_element; e.button_up(id) end } if mouse_over? && active_container end def scroll_down - @scroll_y -= @scroll_speed - if $window.height - @internal_height > 0 - @scroll_y = 0 - else - @scroll_y = @height - @internal_height if @scroll_y <= @height - @internal_height + return if @height == @internal_height + + puts "ROOT down #{$window.current_state.containers.first.scroll_y}" + puts "#{@scroll_y} -> internal_height: #{@internal_height}, height: #{@height}, #{@y}" + + @scroll_y += @scroll_speed + if @scroll_y > 0 + @scroll_y = 0 + @parent.scroll_down if @parent end end + def scroll_up + return if @height == @internal_height + + puts "ROOT UP #{$window.current_state.containers.first.scroll_y}" + @scroll_y -= @scroll_speed + puts "#{@scroll_y} -> internal_height: #{@internal_height}, height: #{@height}, #{@y}" + + if @scroll_y < @height - @internal_height + @scroll_y = @height - @internal_height + @parent.scroll_up if @parent + end + end + + def deep_scroll_y + scroll = @scroll_y + + arch = @parent if parent + while(arch) + scroll += arch.scroll_y + arch = arch.parent + end + + return scroll + end + def mouse_over? - $window.mouse_x.between?(@x, @x + @width) && $window.mouse_y.between?(@y, @y + @height) + $window.mouse_x.between?(@x + @scroll_x, (@x + @scroll_x) + @width) && $window.mouse_y.between?(@y + @scroll_y, (@y + @scroll_y) + @height) end def theme @@ -136,18 +157,17 @@ module CyberarmEngine end def background - Gosu.draw_rect(@x, @y, @width, @height, @background_color, @z) unless active_container + Gosu.draw_rect(@x, @y, @width, @height, @background_color, @z) end - def active_container(children = @children) - active = false + def active_container + active = true - children.each do |child| - if child.mouse_over? - if child.children.count == 0 - active = true - else - child.active_container(child.children) + if mouse_over? + @children.each do |child| + if child.mouse_over? + active = false + break end end end @@ -161,23 +181,35 @@ module CyberarmEngine def recalculate raise "mode was not defined!" unless @mode - # puts "<#{self.class}:#{self.object_id}> X: #{@x}, Y: #{@y}, width: #{@width}, height: #{@height} (children: #{@children.count}, parents: #{@parent&.children&.count})" - - @packing_x = 0 - @packing_y = 0 if @parent neighbors = @parent.children.size > 0 ? @parent.children.size : 1 + if @layout == :match_parent - if @mode == :flow - @width = @parent.width / neighbors - @height = @parent.height - else # :stack - @width = @parent.width / neighbors - @height = @parent.height / neighbors + if @mode == :flow + @width = @parent.width + @height = @parent.height / neighbors + else # :stack + @width = @parent.width / neighbors + @height = @parent.height + end + else # :wrap_content + raise "Not implemented" end + else + @width = $window.width + @height = $window.height end + + position_elements + puts "<#{self.class} X: #{@x}, Y: #{@y}, width: #{@width}, height: #{@height}, internal_width: #{@internal_width}, internal_height: #{@internal_height} (children: #{@children.count})" + end + + def position_elements + @packing_x = 0 + @packing_y = 0 + widest_element = nil last_element = nil @@ -197,10 +229,10 @@ module CyberarmEngine margin = element.margin if defined?(element.margin) case @mode when :flow - @internal_width += element.width + margin unless @origin_width.nonzero? + @internal_width += element.width + margin unless @origin_width.nonzero? @internal_height = element.height + margin if element.height + margin > @internal_height + margin unless @origin_height.nonzero? when :stack - @internal_width = element.width + margin if element.width + margin > @internal_width + margin unless @origin_width.nonzero? + @internal_width = element.width + margin if element.width + margin > @internal_width + margin unless @origin_width.nonzero? @internal_height += element.height + margin unless @origin_height.nonzero? end end @@ -208,8 +240,10 @@ module CyberarmEngine # @internal_width = @width if @width < @internal_width # @internal_height = @height if @height < @internal_height - @internal_width += widest_element.margin if widest_element && !@origin_width.nonzero? - @internal_height += last_element.margin if last_element && !@origin_height.nonzero? + # @internal_width += widest_element.margin if widest_element && !@origin_width.nonzero? + # @internal_height += last_element.margin if last_element && !@origin_height.nonzero? + + @children.each(&:recalculate) end def flow(element) diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb index 7b4d449..94114ba 100644 --- a/lib/cyberarm_engine/ui/element.rb +++ b/lib/cyberarm_engine/ui/element.rb @@ -75,11 +75,9 @@ module CyberarmEngine end def mouse_over? - if $window.mouse_x.between?(relative_x, relative_x + width) - if $window.mouse_y.between?(relative_y, relative_y + height) - true - end - end + @parent.mouse_over? && + $window.mouse_x.between?(relative_x, relative_x + width) && + $window.mouse_y.between?(relative_y, relative_y + height) end def active_element diff --git a/lib/cyberarm_engine/ui/label.rb b/lib/cyberarm_engine/ui/label.rb index 9bf5ba8..1fc128c 100644 --- a/lib/cyberarm_engine/ui/label.rb +++ b/lib/cyberarm_engine/ui/label.rb @@ -18,7 +18,6 @@ module CyberarmEngine case id when Gosu::MsLeft if mouse_over? - puts "HI" @block.call(self) if @block end end