diff --git a/lib/cyberarm_engine.rb b/lib/cyberarm_engine.rb index daa0dff..8edd35a 100644 --- a/lib/cyberarm_engine.rb +++ b/lib/cyberarm_engine.rb @@ -23,6 +23,7 @@ require_relative "cyberarm_engine/vector" require_relative "cyberarm_engine/transform" require_relative "cyberarm_engine/ray" require_relative "cyberarm_engine/background" +require_relative "cyberarm_engine/background_nine_slice" require_relative "cyberarm_engine/animator" require_relative "cyberarm_engine/text" diff --git a/lib/cyberarm_engine/background_nine_slice.rb b/lib/cyberarm_engine/background_nine_slice.rb index c178301..2dfcc3d 100644 --- a/lib/cyberarm_engine/background_nine_slice.rb +++ b/lib/cyberarm_engine/background_nine_slice.rb @@ -1,10 +1,11 @@ module CyberarmEngine class BackgroundNineSlice include CyberarmEngine::Common - attr_accessor :x, :y, :z, :width, :height + attr_accessor :x, :y, :z, :width, :height, :left, :top, :right, :bottom, :mode, :color + attr_reader :image - def initialize(image_path:, x: 0, y: 0, z: 0, width: 64, height: 64, mode: :tiled, left: 4, top: 4, right: 56, bottom: 56) - @image = get_image(image_path) + def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :tiled, left: 1, top: 1, right: 1, bottom: 1, color: Gosu::Color::WHITE) + @image = get_image(image_path) if image_path @x = x @y = y @@ -20,10 +21,20 @@ module CyberarmEngine @right = right @bottom = bottom - nine_slice + @color = color + + nine_slice if @image + end + + def image=(image_path) + old_image = @image + @image = image_path ? get_image(image_path) : image_path + nine_slice if @image && old_image != @image end def nine_slice + # pp [@left, @top, @right, @bottom, @image.width] + @segment_top_left = @image.subimage(0, 0, @left, @top) @segment_top_right = @image.subimage(@image.width - @right, 0, @right, @top) @@ -56,71 +67,73 @@ module CyberarmEngine end def width_scale - scale = (@width - (@image.width - (@left + @right))).to_f / (@image.width - (@left + @right)) + scale = (@width.to_f - (@left + @right)) / (@image.width - (@left + @right)) scale.abs end def height_scale - scale = (@height - (@image.height - (@top + @bottom))).to_f / (@image.height - (@top + @bottom)) + scale = (@height - (@top + @bottom)).to_f / (@image.height - (@top + @bottom)) scale.abs end def draw + return unless @image && @segment_top_left + @mode == :tiled ? draw_tiled : draw_stretched end def draw_stretched - @segment_top_left.draw(@x, @y, @z) - @segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale) # SCALE X - @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z) + @segment_top_left.draw(@x, @y, @z, 1, 1, @color) + @segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale, 1, @color) # SCALE X + @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color) - @segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale) # SCALE Y - @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z) - @segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale) # SCALE X - @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z) - @segment_left.draw(@x, @y + @top, @z, 1, height_scale) # SCALE Y - @segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale) # SCALE X and SCALE Y + @segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale, @color) # SCALE Y + @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color) + @segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale, 1, @color) # SCALE X + @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color) + @segment_left.draw(@x, @y + @top, @z, 1, height_scale, @color) # SCALE Y + @segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale, @color) # SCALE X and SCALE Y end def draw_tiled - @segment_top_left.draw(@x, @y, @z) + @segment_top_left.draw(@x, @y, @z, 1, 1, @color) - p [width_scale, height_scale] + # p [width_scale, height_scale] Gosu.clip_to(@x + @segment_top_left.width, @y, @segment_top.width * width_scale, @segment_top.height) do width_scale.ceil.times do |i| - @segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z) # SCALE X + @segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z, 1, 1, @color) # SCALE X end end - @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z) + @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color) Gosu.clip_to(@x + @width - @segment_top_right.width, @y + @top, @segment_right.width, @segment_right.height * height_scale) do height_scale.ceil.times do |i| - @segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z) # SCALE Y + @segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z, 1, 1, @color) # SCALE Y end end - @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z) + @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color) Gosu.clip_to(@x + @segment_top_left.width, @y + @height - @segment_bottom.height, @segment_top.width * width_scale, @segment_bottom.height) do width_scale.ceil.times do |i| - @segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z) # SCALE X + @segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z, 1, 1, @color) # SCALE X end end - @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z) + @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color) Gosu.clip_to(@x, @y + @top, @segment_left.width, @segment_left.height * height_scale) do height_scale.ceil.times do |i| - @segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z) # SCALE Y + @segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z, 1, 1, @color) # SCALE Y end end Gosu.clip_to(@x + @segment_top_left.width, @y + @segment_top.height, @width - (@segment_left.width + @segment_right.width), @height - (@segment_top.height + @segment_bottom.height)) do height_scale.ceil.times do |y| width_scale.ceil.times do |x| - @segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z) # SCALE X and SCALE Y + @segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z, 1, 1, @color) # SCALE X and SCALE Y end end end diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb index 81b6282..5dd2992 100644 --- a/lib/cyberarm_engine/ui/element.rb +++ b/lib/cyberarm_engine/ui/element.rb @@ -36,7 +36,8 @@ module CyberarmEngine @style.height = default(:height) || nil @style.background_canvas = Background.new - @style.border_canvas = BorderCanvas.new(element: self) + @style.background_nine_slice_canvas = BackgroundNineSlice.new + @style.border_canvas = BorderCanvas.new(element: self) @style_event = :default @@ -54,6 +55,7 @@ module CyberarmEngine set_margin set_background + set_background_nine_slice set_border_thickness set_border_color @@ -74,6 +76,21 @@ module CyberarmEngine @style.background_canvas.background = @style.background end + def set_background_nine_slice + @style.background_nine_slice = safe_style_fetch(:background_nine_slice) + + @style.background_nine_slice_mode = safe_style_fetch(:background_nine_slice_mode) || :stretch + @style.background_nine_slice_color = safe_style_fetch(:background_nine_slice_color) || Gosu::Color::WHITE + @style.background_nine_slice_canvas.color = @style.background_nine_slice_color + + @style.background_nine_slice_from_edge = safe_style_fetch(:background_nine_slice_from_edge) + + @style.background_nine_slice_left = safe_style_fetch(:background_nine_slice_left) || @style.background_nine_slice_from_edge + @style.background_nine_slice_top = safe_style_fetch(:background_nine_slice_top) || @style.background_nine_slice_from_edge + @style.background_nine_slice_right = safe_style_fetch(:background_nine_slice_right) || @style.background_nine_slice_from_edge + @style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom) || @style.background_nine_slice_from_edge + end + def set_border_thickness @style.border_thickness = safe_style_fetch(:border_thickness) @@ -250,6 +267,7 @@ module CyberarmEngine return unless visible? @style.background_canvas.draw + @style.background_nine_slice_canvas.draw @style.border_canvas.draw Gosu.clip_to(@x, @y, width, height) do @@ -390,10 +408,34 @@ module CyberarmEngine @style.background_canvas.height = height @style.background_canvas.update - + update_background_nine_slice @style.border_canvas.update end + def background_nine_slice=(_image_path) + @style.background_nine_slice_canvas.image = _image_path + update_background_nine_slice + end + + def update_background_nine_slice + @style.background_nine_slice_canvas.x = @x + @style.background_nine_slice_canvas.y = @y + @style.background_nine_slice_canvas.z = @z + @style.background_nine_slice_canvas.width = width + @style.background_nine_slice_canvas.height = height + + @style.background_nine_slice_canvas.mode = @style.background_nine_slice_mode + + @style.background_nine_slice_canvas.color = @style.background_nine_slice_color + + @style.background_nine_slice_canvas.left = @style.background_nine_slice_left + @style.background_nine_slice_canvas.top = @style.background_nine_slice_top + @style.background_nine_slice_canvas.right = @style.background_nine_slice_right + @style.background_nine_slice_canvas.bottom = @style.background_nine_slice_bottom + + @style.background_nine_slice_canvas.image = @style.background_nine_slice + end + def root return self if is_root? diff --git a/lib/cyberarm_engine/ui/event.rb b/lib/cyberarm_engine/ui/event.rb index 29c1b1d..4a95c7d 100644 --- a/lib/cyberarm_engine/ui/event.rb +++ b/lib/cyberarm_engine/ui/event.rb @@ -15,12 +15,19 @@ module CyberarmEngine return unless enabled? - return :handled if respond_to?(event) && (send(event, self, *args) == :handled) + was_handled = false + + was_handled = true if respond_to?(event) && (send(event, self, *args) == :handled) @event_handler[event].reverse_each do |handler| - return :handled if handler.call(self, *args) == :handled + if handler.call(self, *args) == :handled + was_handled = true + break + end end + return :handled if was_handled + parent.publish(event, *args) if parent nil end