From d0be03653ec39d506eb0b7b69bed08cabf7b460a Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Mon, 4 Mar 2019 12:13:39 -0600 Subject: [PATCH] Every element has a background and border, background and border support gradients. --- cyberarm_engine.gemspec | 6 +- lib/cyberarm_engine.rb | 5 + lib/cyberarm_engine/background.rb | 166 ++++++++++++++++++++++++ lib/cyberarm_engine/engine.rb | 2 - lib/cyberarm_engine/lib/bounding_box.rb | 124 ++++++++++++++++++ lib/cyberarm_engine/lib/vector.rb | 97 ++++++++++++++ lib/cyberarm_engine/ui/border_canvas.rb | 101 ++++++++++++++ lib/cyberarm_engine/ui/button.rb | 29 ++--- lib/cyberarm_engine/ui/check_box.rb | 2 +- lib/cyberarm_engine/ui/container.rb | 21 +-- lib/cyberarm_engine/ui/dsl.rb | 2 +- lib/cyberarm_engine/ui/edit_line.rb | 37 ++---- lib/cyberarm_engine/ui/element.rb | 90 ++++++++++--- lib/cyberarm_engine/ui/image.rb | 4 +- lib/cyberarm_engine/ui/label.rb | 10 +- lib/cyberarm_engine/ui/theme.rb | 11 +- lib/cyberarm_engine/version.rb | 1 + 17 files changed, 605 insertions(+), 103 deletions(-) create mode 100644 lib/cyberarm_engine/background.rb create mode 100644 lib/cyberarm_engine/lib/bounding_box.rb create mode 100644 lib/cyberarm_engine/lib/vector.rb create mode 100644 lib/cyberarm_engine/ui/border_canvas.rb diff --git a/cyberarm_engine.gemspec b/cyberarm_engine.gemspec index 6aac5f2..ad4a828 100644 --- a/cyberarm_engine.gemspec +++ b/cyberarm_engine.gemspec @@ -9,9 +9,9 @@ Gem::Specification.new do |spec| spec.authors = ["Cyberarm"] spec.email = ["matthewlikesrobots@gmail.com"] - spec.summary = %q{TODO: Write a short summary, because RubyGems requires one.} - spec.description = %q{TODO: Write a longer description or delete this line.} - spec.homepage = "TODO: Put your gem's website or public repo URL here." + spec.summary = %q{Make games quickly and easily with gosu} + spec.description = %q{Yet another game making framework around gosu} + spec.homepage = "https://github.com/cyberarm/cyberarm_engine" spec.license = "MIT" # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' diff --git a/lib/cyberarm_engine.rb b/lib/cyberarm_engine.rb index 3c5dd8f..a8a7f7b 100644 --- a/lib/cyberarm_engine.rb +++ b/lib/cyberarm_engine.rb @@ -7,12 +7,17 @@ require_relative "cyberarm_engine/common" require_relative "cyberarm_engine/game_object" require_relative "cyberarm_engine/engine" +require_relative "cyberarm_engine/lib/bounding_box" +require_relative "cyberarm_engine/lib/vector" +require_relative "cyberarm_engine/background" + require_relative "cyberarm_engine/objects/text" require_relative "cyberarm_engine/objects/timer" require_relative "cyberarm_engine/objects/multi_line_text" require_relative "cyberarm_engine/ui/theme" require_relative "cyberarm_engine/ui/event" +require_relative "cyberarm_engine/ui/border_canvas" require_relative "cyberarm_engine/ui/element" require_relative "cyberarm_engine/ui/label" require_relative "cyberarm_engine/ui/button" diff --git a/lib/cyberarm_engine/background.rb b/lib/cyberarm_engine/background.rb new file mode 100644 index 0000000..bbddc50 --- /dev/null +++ b/lib/cyberarm_engine/background.rb @@ -0,0 +1,166 @@ +require "gosu" + +module CyberarmEngine + class Background + attr_accessor :x, :y, :z, :width, :height, :angle, :debug + attr_reader :background + def initialize(x: 0, y: 0, z: 0, width: 0, height: 0, background: Gosu::Color::BLACK, angle: 0, debug: false) + @x,@y,@z = x,y,z + @width,@height = width,height + @debug = debug + + @paint = Paint.new(background) + @angle = angle + + @top_left = Vector.new(@x, @y) + @top_right = Vector.new(@x + @width, @y) + @bottom_left = Vector.new(@x, @y + @height) + @bottom_right = Vector.new(@x + @width, @y + @height) + end + + def draw + Gosu.clip_to(@x, @y, @width, @height) do + Gosu.draw_quad( + @top_left.x, @top_left.y, @paint.top_left, + @top_right.x, @top_right.y, @paint.top_right, + @bottom_right.x, @bottom_right.y, @paint.bottom_right, + @bottom_left.x, @bottom_left.y, @paint.bottom_left, + @z + ) + end + + debug_outline if @debug + end + + def update + origin_x = (@x + (@width/2)) + origin_y = (@y + (@height/2)) + + points = [ + @top_left = Vector.new(@x, @y), + @top_right = Vector.new(@x + @width, @y), + @bottom_left = Vector.new(@x, @y + @height), + @bottom_right = Vector.new(@x + @width, @y + @height) + ] + + [@top_left, @top_right, @bottom_left, @bottom_right].each do |vector| + temp_x = vector.x - origin_x + temp_y = vector.y - origin_y + + # 90 is up here, while gosu uses 0 for up. + radians = (@angle + 90).gosu_to_radians + vector.x = (@x + (@width/2)) + ((temp_x * Math.cos(radians)) - (temp_y * Math.sin(radians))) + vector.y = (@y + (@height/2)) + ((temp_x * Math.sin(radians)) + (temp_y * Math.cos(radians))) + end + + # [ + # [:top, @top_left, @top_right], + # [:right, @top_right, @bottom_right], + # [:bottom, @bottom_right, @bottom_left], + # [:left, @bottom_left, @top_left] + # ].each do |edge| + # points.each do |point| + # puts "#{edge.first} -> #{shortest_distance(point, edge[1], edge[2])}" + # end + # end + end + + def shortest_distance(point, la, lb) + a = la.x - lb.x + b = la.y - lb.y + c = Gosu.distance(la.x, la.y, lb.x, lb.y) + p a,b,c + d = (a * point.x + b * point.y + c).abs / (Math.sqrt(a * a + b * b)) + puts "Distance: #{d}" + exit! + return d + end + + def debug_outline + # Top + Gosu.draw_line( + @x, @y, Gosu::Color::RED, + @x + @width, @y, Gosu::Color::RED, + @z + ) + + # Right + Gosu.draw_line( + @x + @width, @y, Gosu::Color::RED, + @x + @width, @y + @height, Gosu::Color::RED, + @z + ) + + # Bottom + Gosu.draw_line( + @x + @width, @y + @height, Gosu::Color::RED, + @x, @y + @height, Gosu::Color::RED, + @z + ) + + # Left + Gosu.draw_line( + @x, @y + @height, Gosu::Color::RED, + @x, @y, Gosu::Color::RED, + @z + ) + end + + def background=(_background) + @paint.set(_background) + update + end + + def angle=(n) + @angle = n + update + end + end + + class Paint + attr_accessor :top_left, :top_right, :bottom_left, :bottom_right + def initialize(background) + set(background) + end + + def set(background) + @background = background + + + if background.is_a?(Numeric) + @top_left = background + @top_right = background + @bottom_left = background + @bottom_right = background + elsif background.is_a?(Gosu::Color) + @top_left = background + @top_right = background + @bottom_left = background + @bottom_right = background + elsif background.is_a?(Array) + if background.size == 1 + set(background.first) + elsif background.size == 2 + @top_left = background.first + @top_right = background.last + @bottom_left = background.first + @bottom_right = background.last + elsif background.size == 4 + @top_left = background[0] + @top_right = background[1] + @bottom_left = background[2] + @bottom_right = background[3] + else + raise ArgumentError, "background array was empty or had wrong number of elements (expected 2 or 4 elements)" + end + elsif background.is_a?(Hash) + @top_left = background[:top_left] + @top_right = background[:top_right] + @bottom_left = background[:bottom_left] + @bottom_right = background[:bottom_right] + else + raise ArgumentError, "background '#{background}' of type '#{background.class}' was not able to be processed" + end + end + end +end \ No newline at end of file diff --git a/lib/cyberarm_engine/engine.rb b/lib/cyberarm_engine/engine.rb index f45de64..75426b5 100644 --- a/lib/cyberarm_engine/engine.rb +++ b/lib/cyberarm_engine/engine.rb @@ -1,6 +1,4 @@ module CyberarmEngine - Vector = Struct.new(:x, :y, :z, :weight) - class Engine < Gosu::Window attr_accessor :show_cursor attr_reader :current_state, :last_frame_time diff --git a/lib/cyberarm_engine/lib/bounding_box.rb b/lib/cyberarm_engine/lib/bounding_box.rb new file mode 100644 index 0000000..954954f --- /dev/null +++ b/lib/cyberarm_engine/lib/bounding_box.rb @@ -0,0 +1,124 @@ +module CyberarmEngine + class BoundingBox + attr_accessor :min, :max + + def initialize(minx = 0, miny = 0, minz = 0, maxx = 0, maxy = 0, maxz = 0) + @min = Vector.new(minx, miny, minz) + @max = Vector.new(maxx, maxy, maxz) + end + + def ==(other) + @min == other.min && + @max == other.max + end + + # returns a new bounding box that includes both bounding boxes + def union(other) + temp = BoundingBox.new + temp.min.x = [@min.x, other.min.x].min + temp.min.y = [@min.y, other.min.y].min + temp.min.z = [@min.z, other.min.z].min + + temp.max.x = [@max.x, other.max.x].max + temp.max.y = [@max.y, other.max.y].max + temp.max.z = [@max.z, other.max.z].max + + return temp + end + + # returns the difference between both bounding boxes + def difference(other) + temp = BoundingBox.new + temp.min = @min - other.min + temp.max = @max - other.max + + return temp + end + + # returns whether both bounding boxes intersect + def intersect?(other) + (@min.x <= other.max.x && @max.x >= other.min.x) && + (@min.y <= other.max.y && @max.y >= other.min.y) && + (@min.z <= other.max.z && @max.z >= other.min.z) + end + + # does this bounding box envelop other bounding box? (inclusive of border) + def contains?(other) + other.min.x >= min.x && other.min.y >= min.y && other.min.z >= min.z && + other.max.x <= max.x && other.max.y <= max.y && other.max.z <= max.z + end + + # returns whether the vector is inside of the bounding box + def point?(vector) + vector.x.between?(@min.x, @max.x) && + vector.y.between?(@min.y, @max.y) && + vector.z.between?(@min.z, @max.z) + end + + def volume + width * height * depth + end + + def width + @max.x - @min.x + end + + def height + @max.y - @min.y + end + + def depth + @max.z - @min.z + end + + def normalize(entity) + temp = BoundingBox.new + temp.min.x = @min.x.to_f * entity.scale + temp.min.y = @min.y.to_f * entity.scale + temp.min.z = @min.z.to_f * entity.scale + + temp.max.x = @max.x.to_f * entity.scale + temp.max.y = @max.y.to_f * entity.scale + temp.max.z = @max.z.to_f * entity.scale + + return temp + end + + def normalize_with_offset(entity) + temp = BoundingBox.new + temp.min.x = @min.x.to_f * entity.scale + entity.position.x + temp.min.y = @min.y.to_f * entity.scale + entity.position.y + temp.min.z = @min.z.to_f * entity.scale + entity.position.z + + temp.max.x = @max.x.to_f * entity.scale + entity.position.x + temp.max.y = @max.y.to_f * entity.scale + entity.position.y + temp.max.z = @max.z.to_f * entity.scale + entity.position.z + + return temp + end + + def +(other) + box = BoundingBox.new + box.min = self.min + other.min + box.min = self.max + other.max + + return box + end + + def -(other) + box = BoundingBox.new + box.min = self.min - other.min + box.min = self.max - other.max + + return box + end + + def sum + @min.sum + @max.sum + end + + def clone + BoundingBox.new(@min.x, @min.y, @min.z, @max.x, @max.y, @max.z) + end + end +end \ No newline at end of file diff --git a/lib/cyberarm_engine/lib/vector.rb b/lib/cyberarm_engine/lib/vector.rb new file mode 100644 index 0000000..cde3c32 --- /dev/null +++ b/lib/cyberarm_engine/lib/vector.rb @@ -0,0 +1,97 @@ +module CyberarmEngine + class Vector + + def initialize(x = 0, y = 0, z = 0, weight = 0) + @x, @y, @z, @weight = x, y, z, weight + end + + def x; @x; end + def x=(n); @x = n; end + + def y; @y; end + def y=(n); @y = n; end + + def z; @z; end + def z=(n); @z = n; end + + def weight; @weight; end + def weight=(n); @weight = n; end + + # def xy=(nx, ny); @x = nx; @y = ny; end + # def xyz=(nx, ny, nz); @x = nx; @y = ny; @z = nz; end + # def xyzw=(nx, ny, nz, nw); @x = nx; @y = ny; @z = nz; @weight = nw; end + + def ==(other) + if other.is_a?(Numeric) + @x == other && + @y == other && + @z == other && + @weight == other + else + @x == other.x && + @y == other.y && + @z == other.z && + @weight == other.weight + end + end + + def +(other) + Vector.new( + @x + other.x, + @y + other.y, + @z + other.z, + @weight + other.weight + ) + end + + def -(other) + Vector.new( + @x - other.x, + @y - other.y, + @z - other.z, + @weight - other.weight + ) + end + + def *(other) + Vector.new( + @x * other.x, + @y * other.y, + @z * other.z, + @weight * other.weight + ) + end + + def /(other) + # Endeavors to prevent division by zero + Vector.new( + @x == 0 || other.x == 0 ? 0 : @x / other.x, + @y == 0 || other.y == 0 ? 0 : @y / other.y, + @z == 0 || other.z == 0 ? 0 : @z / other.z, + @weight == 0 || other.weight == 0 ? 0 : @weight / other.weight + ) + end + + # returns magnitude of Vector, ignoring #weight + def magnitude + Math.sqrt((@x * @x) + (@y * @y) + (@z * @z)) + end + + def normalized + mag = magnitude + self / Vector.new(mag, mag, mag) + end + + def sum + @x + @y + @z + @weight + end + + def to_a + [@x, @y, @z, @weight] + end + + def to_s + "X: #{@x}, Y: #{@y}, Z: #{@z}, Weight: #{@weight}" + end + end +end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/border_canvas.rb b/lib/cyberarm_engine/ui/border_canvas.rb new file mode 100644 index 0000000..39873a1 --- /dev/null +++ b/lib/cyberarm_engine/ui/border_canvas.rb @@ -0,0 +1,101 @@ +module CyberarmEngine + class BorderCanvas + attr_reader :element, :top, :right, :bottom, :left + def initialize(element:) + @element = element + + @top = Background.new + @right = Background.new + @bottom = Background.new + @left = Background.new + end + + def color=(color) + if color.is_a?(Numeric) + @top.background = color + @right.background = color + @bottom.background = color + @left.background = color + + elsif color.is_a?(Gosu::Color) + @top.background = color + @right.background = color + @bottom.background = color + @left.background = color + + elsif color.is_a?(Array) + if color.size == 1 + color=color.first + + elsif color.size == 2 + @top.background = color.first + @right.background = color.first + @bottom.background = color.last + @left.background = color.last + + elsif color.size == 4 + @top.background = color[0] + @right.background = color[1] + @bottom.background = color[2] + @left.background = color[3] + else + raise ArgumentError, "color array was empty or had wrong number of elements (expected 2 or 4 elements)" + end + + elsif color.is_a?(Hash) + @top.background = color[:top] + @right.background = color[:right] + @bottom.background = color[:bottom] + @left.background = color[:left] + else + raise ArgumentError, "color '#{color}' of type '#{color.class}' was not able to be processed" + end + end + + def draw + @top.draw + @right.draw + @bottom.draw + @left.draw + end + + def update + # TOP + @top.x = @element.x# + @element.border_thickness_left + @top.y = @element.y + @top.z = @element.z + + @top.width = @element.width + @top.height = @element.border_thickness_top + + # RIGHT + @right.x = @element.x + @element.width + @right.y = @element.y + @element.border_thickness_top + @right.z = @element.z + + @right.width = -@element.border_thickness_right + @right.height = @element.height - @element.border_thickness_top + + # BOTTOM + @bottom.x = @element.x + @bottom.y = @element.y + @element.height + @bottom.z = @element.z + + @bottom.width = @element.width - @element.border_thickness_right + @bottom.height = -@element.border_thickness_bottom + + # LEFT + @left.x = @element.x + @left.y = @element.y + @left.z = @element.z + + @left.width = @element.border_thickness_left + @left.height = @element.height - @element.border_thickness_bottom + + @top.update + @right.update + @bottom.update + @left.update + end + end +end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/button.rb b/lib/cyberarm_engine/ui/button.rb index fcbe931..e9b9f1f 100644 --- a/lib/cyberarm_engine/ui/button.rb +++ b/lib/cyberarm_engine/ui/button.rb @@ -1,8 +1,13 @@ module CyberarmEngine class Button < Label - def draw + def initialize(text, options = {}, block = nil) + super(text, options, block) + + @background_canvas.background = @options[:interactive_background] + end + + def render draw_text - draw_button end def draw_text @@ -10,12 +15,12 @@ module CyberarmEngine end def enter(sender) - @background = @options[:interactive_hover_background] + @background_canvas.background = @options[:interactive_hover_background] @text.color = @options[:interactive_stroke] end def left_mouse_button(sender, x, y) - @background = @options[:interactive_active_background] + @background_canvas.background = @options[:interactive_active_background] @text.color = @options[:interactive_active_stroke] end @@ -24,26 +29,12 @@ module CyberarmEngine end def leave(sender) - @background = @options[:interactive_background] + @background_canvas.background = @options[:interactive_background] @text.color = @options[:interactive_stroke] end def clicked_left_mouse_button(sender, x, y) @block.call(self) if @block end - - def draw_button - $window.draw_rect(@x, @y, width, height, @options[:element_background], @z+1) - - @background ||= @options[:interactive_background] - $window.draw_rect( - @x + @options[:interactive_border_size], - @y + @options[:interactive_border_size], - width - (@options[:interactive_border_size]*2), - height- (@options[:interactive_border_size]*2), - @background, - @z+2 - ) - end end end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/check_box.rb b/lib/cyberarm_engine/ui/check_box.rb index 77dddc2..4d06607 100644 --- a/lib/cyberarm_engine/ui/check_box.rb +++ b/lib/cyberarm_engine/ui/check_box.rb @@ -31,7 +31,7 @@ module CyberarmEngine @label._toggle_button(@toggle_button) @label.define_singleton_method(:holding_left_mouse_button) do |sender, x, y| - @_toggle_button.holding_left_mouse_button(sender, x, y) + @_toggle_button.left_mouse_button(sender, x, y) end @label.define_singleton_method(:released_left_mouse_button) do |sender, x, y| diff --git a/lib/cyberarm_engine/ui/container.rb b/lib/cyberarm_engine/ui/container.rb index f0ad32d..85835a8 100644 --- a/lib/cyberarm_engine/ui/container.rb +++ b/lib/cyberarm_engine/ui/container.rb @@ -2,20 +2,17 @@ module CyberarmEngine class Container < Element include Common - attr_accessor :stroke_color, :fill_color, :background_color, :x, :y, :z, :width, :height + attr_accessor :stroke_color, :fill_color attr_reader :children attr_reader :scroll_x, :scroll_y def initialize(options = {}, block = nil) super - @origin_x, @origin_x = @x, @x - @origin_width, @origin_height = @width, @height @scroll_x, @scroll_y = 0, 0 @scroll_speed = 10 @text_color = options[:text_color] || Element::THEME[:stroke] - @background_color = Element::THEME[:background] @children = [] @@ -35,12 +32,8 @@ module CyberarmEngine recalculate end - def draw - # Gosu.clip_to(@x, @y, @width, @height) do - background - + def render @children.each(&:draw) - # end end def update @@ -59,10 +52,6 @@ module CyberarmEngine @theme[:fill] = color end - def background - Gosu.draw_rect(@x, @y, @width, @height, @background_color, @z) - end - def hit_element?(x, y) @children.reverse_each do |child| case child @@ -83,8 +72,8 @@ module CyberarmEngine layout - @width = @max_width ? @max_width : (@children.map {|c| c.x + c.width }.max + @margin_right || 0) - @height = @max_height ? @max_height : (@children.map {|c| c.y + c.height}.max + @margin_bottom || 0) + @width = @max_width ? @max_width : (@children.map {|c| c.x + c.width }.max + @margin_right || 0).round + @height = @max_height ? @max_height : (@children.map {|c| c.y + c.height}.max + @margin_bottom || 0).round # Move child to parent after positioning @children.each do |child| @@ -94,6 +83,8 @@ module CyberarmEngine # Fix child being displaced child.recalculate end + + update_background # puts unless @parent # puts "<#{self.class} X: #{@x}, Y: #{@y}, width: #{@width}, height: #{@height} (children: #{@children.count}) [#{children.first.class}]" end diff --git a/lib/cyberarm_engine/ui/dsl.rb b/lib/cyberarm_engine/ui/dsl.rb index d63c765..430e9f7 100644 --- a/lib/cyberarm_engine/ui/dsl.rb +++ b/lib/cyberarm_engine/ui/dsl.rb @@ -73,7 +73,7 @@ module CyberarmEngine end def background(color = Gosu::Color::NONE) - @containers.last.background_color = color + @containers.last.background = color end # Foreground color, e.g. Text diff --git a/lib/cyberarm_engine/ui/edit_line.rb b/lib/cyberarm_engine/ui/edit_line.rb index aca158f..dd1ec87 100644 --- a/lib/cyberarm_engine/ui/edit_line.rb +++ b/lib/cyberarm_engine/ui/edit_line.rb @@ -19,13 +19,9 @@ module CyberarmEngine return self end - def draw - Gosu.clip_to(@x, @y, width, height) do + def render draw_text - Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z + 40) if @show_caret - end - - draw_button + Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z + 40) if @focus && @show_caret end def update @@ -42,41 +38,23 @@ module CyberarmEngine end end - def button_up(id) - case id - when Gosu::MsLeft - if mouse_over? - @focus = !@focus - - if @focus - $window.text_input = @text_input - else - $window.text_input = nil - end - @block.call(self) if @block - end - end - end - def clicked_left_mouse_button(sender, x, y) + @focus = true window.current_state.focus=self window.text_input = @text_input @block.call(self) if @block end def blur(sender) + @focus = false window.text_input = nil end def caret_position - if $window.text_input && $window.text_input == @text_input - if @type == :password - @text.x + @text.textobject.text_width(@options[:edit_line_password_character] * @text_input.text[0..@text_input.caret_pos].length) - else - @text.x + @text.textobject.text_width(@text_input.text[0..@text_input.caret_pos]) - end + if @type == :password + @text.x + @text.textobject.text_width(@options[:edit_line_password_character] * @text_input.text[0..@text_input.caret_pos].length) else - 0 + @text.x + @text.textobject.text_width(@text_input.text[0..@text_input.caret_pos]) end end @@ -84,6 +62,7 @@ module CyberarmEngine super @width = @options[:edit_line_width] + update_background end def value diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb index 460ab21..2bf4aeb 100644 --- a/lib/cyberarm_engine/ui/element.rb +++ b/lib/cyberarm_engine/ui/element.rb @@ -5,7 +5,11 @@ module CyberarmEngine include Common attr_accessor :x, :y, :z, :width, :height, :enabled - attr_reader :parent, :options, :event_handler + attr_reader :parent, :options, :event_handler, :background_canvas, :border_canvas + + attr_reader :border_thickness, :border_thickness_left, :border_thickness_right, :border_thickness_top, :border_thickness_bottom + attr_reader :border_color, :border_color_left, :border_color_right, :border_color_top, :border_color_bottom + attr_reader :padding, :padding_left, :padding_right, :padding_top, :padding_bottom attr_reader :margin, :margin_left, :margin_right, :margin_top, :margin_bottom @@ -15,6 +19,9 @@ module CyberarmEngine @options = options @block = block + @background_canvas = Background.new + @border_canvas = BorderCanvas.new(element: self) + @x = options.dig(:x) @y = options.dig(:y) @z = options.dig(:z) @@ -25,17 +32,14 @@ module CyberarmEngine @width = options.dig(:width) @height = options.dig(:height) + set_border_thickness(options.dig(:border_thickness)) + set_padding(options.dig(:padding)) - @padding_left = options.dig(:padding_left) || @padding - @padding_right = options.dig(:padding_right) || @padding - @padding_top = options.dig(:padding_top) || @padding - @padding_bottom = options.dig(:padding_bottom) || @padding set_margin(options.dig(:margin)) - @margin_left = options.dig(:margin_left) || @margin - @margin_right = options.dig(:margin_right) || @margin - @margin_top = options.dig(:margin_top) || @margin - @margin_bottom = options.dig(:margin_bottom) || @margin + + set_background(options.dig(:background)) + set_border_color(options.dig(:border_color)) raise "#{self.class} 'x' must be a number" unless @x.is_a?(Numeric) raise "#{self.class} 'y' must be a number" unless @y.is_a?(Numeric) @@ -54,22 +58,47 @@ module CyberarmEngine default_events end + def set_background(background) + @background = background + @background_canvas.background = background + end + + def set_border_thickness(border_thickness) + @border_thickness = border_thickness + + @border_thickness_left = options.dig(:border_thickness_left) || @border_thickness + @border_thickness_right = options.dig(:border_thickness_right) || @border_thickness + @border_thickness_top = options.dig(:border_thickness_top) || @border_thickness + @border_thickness_bottom = options.dig(:border_thickness_bottom) || @border_thickness + end + + def set_border_color(color) + @border_color = color + + @border_color_left = options.dig(:border_color_left) || @border_color + @border_color_right = options.dig(:border_color_right) || @border_color + @border_color_top = options.dig(:border_color_top) || @border_color + @border_color_bottom = options.dig(:border_color_bottom) || @border_color + + @border_canvas.color = color + end + def set_padding(padding) @padding = padding - @padding_left = padding - @padding_right = padding - @padding_top = padding - @padding_bottom = padding + @padding_left = options.dig(:padding_left) || @padding + @padding_right = options.dig(:padding_right) || @padding + @padding_top = options.dig(:padding_top) || @padding + @padding_bottom = options.dig(:padding_bottom) || @padding end def set_margin(margin) @margin = margin - @margin_left = margin - @margin_right = margin - @margin_top = margin - @margin_bottom = margin + @margin_left = options.dig(:margin_left) || @margin + @margin_right = options.dig(:margin_right) || @margin + @margin_top = options.dig(:margin_top) || @margin + @margin_bottom = options.dig(:margin_bottom) || @margin end def default_events @@ -95,6 +124,9 @@ module CyberarmEngine end def draw + @background_canvas.draw + @border_canvas.draw + render end def update @@ -106,17 +138,37 @@ module CyberarmEngine def button_up(id) end + def render + end + def hit?(x, y) x.between?(@x, @x + width) && y.between?(@y, @y + height) end def width - @padding_left + @width + @padding_right + @border_thickness_left + @padding_left + @width + @padding_right + @border_thickness_right end def height - @padding_top + @height + @padding_bottom + @border_thickness_top + @padding_top + @height + @padding_bottom + @border_thickness_bottom + end + + def background=(_background) + @background_canvas.background=(_background) + update_background + end + + def update_background + @background_canvas.x = @x + @background_canvas.y = @y + @background_canvas.z = @z + @background_canvas.width = width + @background_canvas.height = height + + @background_canvas.update + + @border_canvas.update end def recalculate diff --git a/lib/cyberarm_engine/ui/image.rb b/lib/cyberarm_engine/ui/image.rb index ef21085..77230d9 100644 --- a/lib/cyberarm_engine/ui/image.rb +++ b/lib/cyberarm_engine/ui/image.rb @@ -22,9 +22,7 @@ module CyberarmEngine raise "Scale Y" unless @scale_y.is_a?(Numeric) end - def draw - $window.draw_rect(@x, @y, width, height, @options[:fill], @z+1) - + def render @image.draw(@x + @padding_left, @y + @padding_top, @z + 2, @scale_x, @scale_y) # TODO: Add color support? end diff --git a/lib/cyberarm_engine/ui/label.rb b/lib/cyberarm_engine/ui/label.rb index 64ebeaa..de4a546 100644 --- a/lib/cyberarm_engine/ui/label.rb +++ b/lib/cyberarm_engine/ui/label.rb @@ -8,9 +8,7 @@ module CyberarmEngine return self end - def draw - $window.draw_rect(@x, @y, width, height, @options[:fill], @z+1) - + def render @text.draw end @@ -24,12 +22,14 @@ module CyberarmEngine end def recalculate - @width = @text.width - @height= @text.height + @width = @text.width.round + @height= @text.height.round @text.x = @padding_left + @x @text.y = @padding_top + @y @text.z = @z + 3 + + update_background end def value diff --git a/lib/cyberarm_engine/ui/theme.rb b/lib/cyberarm_engine/ui/theme.rb index f4df881..00b7cd2 100644 --- a/lib/cyberarm_engine/ui/theme.rb +++ b/lib/cyberarm_engine/ui/theme.rb @@ -10,23 +10,22 @@ module CyberarmEngine } THEME = { - stroke: Gosu::Color::WHITE, - fill: Gosu::Color::NONE, + color: Gosu::Color::WHITE, background: Gosu::Color::NONE, checkmark: "√", # √ margin: 10, padding: 5, - - element_background: Gosu::Color.rgb(12,12,12), + border_thickness: 2, + border_color: [Gosu::Color.rgb(12,12,12)], + border_radius: 0, interactive_stroke: Gosu::Color::WHITE, interactive_active_stroke: Gosu::Color::GRAY, - interactive_background: Gosu::Color::GRAY, + interactive_background: [Gosu::Color::GRAY, Gosu::Color::RED], interactive_hover_background: Gosu::Color.rgb(100, 100, 100), interactive_active_background: Gosu::Color.rgb(50, 50, 50), - interactive_border_size: 1, edit_line_width: 200, edit_line_password_character: "•", # • diff --git a/lib/cyberarm_engine/version.rb b/lib/cyberarm_engine/version.rb index ba40af5..48b837f 100644 --- a/lib/cyberarm_engine/version.rb +++ b/lib/cyberarm_engine/version.rb @@ -1,3 +1,4 @@ module CyberarmEngine + NAME = "InDev" VERSION = "0.1.0" end