diff --git a/cyberarm_engine.gemspec b/cyberarm_engine.gemspec index 5a4b1a9..1ff25fc 100644 --- a/cyberarm_engine.gemspec +++ b/cyberarm_engine.gemspec @@ -27,7 +27,6 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = %w[lib assets] - spec.add_dependency "clipboard", "~> 1.3" spec.add_dependency "excon", "~> 0.88" spec.add_dependency "gosu", "~> 1.1" spec.add_dependency "gosu_more_drawables", "~> 0.3" diff --git a/lib/cyberarm_engine.rb b/lib/cyberarm_engine.rb index f56f080..e24ff41 100644 --- a/lib/cyberarm_engine.rb +++ b/lib/cyberarm_engine.rb @@ -8,7 +8,6 @@ end require "json" require "excon" require "gosu_more_drawables" -require "clipboard" require_relative "cyberarm_engine/version" require_relative "cyberarm_engine/stats" diff --git a/lib/cyberarm_engine/text.rb b/lib/cyberarm_engine/text.rb index 1853090..e632088 100644 --- a/lib/cyberarm_engine/text.rb +++ b/lib/cyberarm_engine/text.rb @@ -22,19 +22,21 @@ module CyberarmEngine else @color = Gosu::Color::WHITE end - @mode = options[:mode] || :default + @mode = options[:mode] || :default @alignment = options[:alignment] || nil @border = options[:border] @border = true if options[:border].nil? @border_size = options[:border_size] || 1 @border_alpha = options[:border_alpha] || 30 - @border_color = options[:border_color] + @border_color = options[:border_color] || Gosu::Color::BLACK @shadow = options[:shadow] @shadow_size = options[:shadow_size] || 2 @shadow_alpha = options[:shadow_alpha] || 30 - @shadow_color = options[:shadow_color] + @shadow_color = options[:shadow_color] || Gosu::Color::BLACK + + @static = options[:static] || (options[:static].nil? || options[:static] == false ? false : true) @textobject = check_cache(@size, @font) @@ -84,46 +86,49 @@ module CyberarmEngine end def text=(string) - @rendered_border = nil + invalidate_cache! if @text != string @text = string end def factor_x=(n) - @rendered_border = nil + invalidate_cache! if @factor_x != n @factor_x = n end def factor_y=(n) - @rendered_border = nil + invalidate_cache! if @factor_y != n @factor_y = n end def color=(color) - @rendered_border = nil + old_color = @color + if color @color = color.is_a?(Gosu::Color) ? color : Gosu::Color.new(color) else raise "color cannot be nil" end + + invalidate_cache! if old_color != color end def border=(boolean) - @rendered_border = nil + invalidate_cache! if @border != boolean @border = boolean end def border_size=(n) - @rendered_border = nil + invalidate_cache! if @border_size != n @border_size = n end def border_alpha=(n) - @rendered_border = nil + invalidate_cache! if @border_alpha != n @border_alpha = n end def border_color=(n) - @rendered_border = nil + invalidate_cache! if @border_color != n @border_color = n end @@ -132,11 +137,27 @@ module CyberarmEngine end def text_width(text = @text) - textobject.text_width(text) + @border_size + @shadow_size + spacing = 0 + spacing += @border_size if @border + spacing += @shadow_size if @shadow + + if text == @text && @static && @gosu_cached_text_image + @gosu_cached_text_image&.width + spacing + else + textobject.text_width(text) + spacing + end end def markup_width(text = @text) - textobject.markup_width(text) + @border_size + @shadow_size + spacing = 0 + spacing += @border_size if @border + spacing += @shadow_size if @shadow + + if text == @text && @static && @gosu_cached_text_image + @gosu_cached_text_image&.width + spacing + else + textobject.markup_width(text) + spacing + end end def height(text = @text) @@ -148,39 +169,72 @@ module CyberarmEngine end def draw(method = :draw_markup) - if @border && !ARGV.join.include?("--no-border") - border_alpha = @color.alpha <= 30 ? @color.alpha : @border_alpha - border_color = @border_color || Gosu::Color.rgba(@color.red, @color.green, @color.blue, - border_alpha) - white = Gosu::Color::WHITE + if @static + if @border && !@cached_text_border_image + _x = @border_size + _y = @border_size + _width = method == :draw_markup ? text_width : markup_width + img = Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font) - _x = @border_size - _y = @border_size - _width = method == :draw_markup ? text_width : markup_width + @cached_text_border_image = Gosu.render((_width + (@border_size * 2)).ceil, (height + (@border_size * 2)).ceil) do + img.draw(-_x, 0, @z, @factor_x, @factor_y, @border_color, @mode) + img.draw(-_x, -_y, @z, @factor_x, @factor_y, @border_color, @mode) - @rendered_border ||= Gosu.render((_width + (border_size * 2)).ceil, (height + (@border_size * 2)).ceil) do - @textobject.send(method, @text, _x - @border_size, _y, @z, @factor_x, @factor_y, white, @mode) - @textobject.send(method, @text, _x - @border_size, _y - @border_size, @z, @factor_x, @factor_y, white, @mode) + img.draw(0, -_y, @z, @factor_x, @factor_y, @border_color, @mode) + img.draw(_x, -_y, @z, @factor_x, @factor_y, @border_color, @mode) - @textobject.send(method, @text, _x, _y - @border_size, @z, @factor_x, @factor_y, white, @mode) - @textobject.send(method, @text, _x + @border_size, _y - @border_size, @z, @factor_x, @factor_y, white, @mode) + img.draw(_x, 0, @z, @factor_x, @factor_y, @border_color, @mode) + img.draw(_x, _y, @z, @factor_x, @factor_y, @border_color, @mode) - @textobject.send(method, @text, _x, _y + @border_size, @z, @factor_x, @factor_y, white, @mode) - @textobject.send(method, @text, _x - @border_size, _y + @border_size, @z, @factor_x, @factor_y, white, @mode) - - @textobject.send(method, @text, _x + @border_size, _y, @z, @factor_x, @factor_y, white, @mode) - @textobject.send(method, @text, _x + @border_size, _y + @border_size, @z, @factor_x, @factor_y, white, @mode) + img.draw(0, _y, @z, @factor_x, @factor_y, @border_color, @mode) + img.draw(-_x, _y, @z, @factor_x, @factor_y, @border_color, @mode) + end end - @rendered_border.draw(@x - @border_size, @y - @border_size, @z, @factor_x, @factor_y, border_color) - end + @cached_text_shadow_image ||= Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font) if @shadow - if @shadow - shadow_color = @shadow_color || Gosu::Color.rgba(@color.red, @color.green, @color.blue, @shadow_alpha) - @textobject.send(method, @text, @x + @shadow_size, @y + @shadow_size, @z, @factor_x, @factor_y, shadow_color, @mode) - end + @gosu_cached_text_image ||= Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font) - @textobject.send(method, @text, @x, @y, @z, @factor_x, @factor_y, @color, @mode) + @cached_text_border_image.draw(@x, @y, @z, @factor_x, @factor_y, @border_color, @mode) if @border + + @cached_text_shadow_image.draw(@x + @shadow_size, @y + @shadow_size, @z, @factor_x, @factor_y, @shadow_color, @mode) if @shadow + + @gosu_cached_text_image.draw(@x, @y, @z, @factor_x, @factor_y, @color, @mode) + else + if @border && !ARGV.join.include?("--no-border") + border_alpha = @color.alpha <= 30 ? @color.alpha : @border_alpha + border_color = @border_color || Gosu::Color.rgba(@color.red, @color.green, @color.blue, + border_alpha) + white = Gosu::Color::WHITE + + _x = @border_size + _y = @border_size + _width = method == :draw_markup ? text_width : markup_width + + @cached_text_border_image ||= Gosu.render((_width + (border_size * 2)).ceil, (height + (@border_size * 2)).ceil) do + @textobject.send(method, @text, _x - @border_size, _y, @z, @factor_x, @factor_y, white, @mode) + @textobject.send(method, @text, _x - @border_size, _y - @border_size, @z, @factor_x, @factor_y, white, @mode) + + @textobject.send(method, @text, _x, _y - @border_size, @z, @factor_x, @factor_y, white, @mode) + @textobject.send(method, @text, _x + @border_size, _y - @border_size, @z, @factor_x, @factor_y, white, @mode) + + @textobject.send(method, @text, _x, _y + @border_size, @z, @factor_x, @factor_y, white, @mode) + @textobject.send(method, @text, _x - @border_size, _y + @border_size, @z, @factor_x, @factor_y, white, @mode) + + @textobject.send(method, @text, _x + @border_size, _y, @z, @factor_x, @factor_y, white, @mode) + @textobject.send(method, @text, _x + @border_size, _y + @border_size, @z, @factor_x, @factor_y, white, @mode) + end + + @cached_text_border_image.draw(@x - @border_size, @y - @border_size, @z, @factor_x, @factor_y, border_color) + end + + if @shadow + shadow_color = @shadow_color || Gosu::Color.rgba(@color.red, @color.green, @color.blue, @shadow_alpha) + @textobject.send(method, @text, @x + @shadow_size, @y + @shadow_size, @z, @factor_x, @factor_y, shadow_color, @mode) + end + + @textobject.send(method, @text, @x, @y, @z, @factor_x, @factor_y, @color, @mode) + end end def alpha=(n) @@ -193,5 +247,11 @@ module CyberarmEngine def update end + + def invalidate_cache! + @cached_text_border_image = nil + @cached_text_shadow_image = nil + @gosu_cached_text_image = nil + end end end diff --git a/lib/cyberarm_engine/ui/elements/edit_line.rb b/lib/cyberarm_engine/ui/elements/edit_line.rb index 665998d..3abab84 100644 --- a/lib/cyberarm_engine/ui/elements/edit_line.rb +++ b/lib/cyberarm_engine/ui/elements/edit_line.rb @@ -1,6 +1,20 @@ module CyberarmEngine class Element class EditLine < Button + class TextInput < Gosu::TextInput + def filter=(filter) + @filter = filter + end + + def filter(text_in) + if @filter + @filter.call(text_in) + else + text_in + end + end + end + def initialize(text, options = {}, block = nil) @filter = options.delete(:filter) super(text, options, block) @@ -14,18 +28,11 @@ module CyberarmEngine @caret_last_interval = Gosu.milliseconds @show_caret = true - @text_input = Gosu::TextInput.new + @text_input = TextInput.new + @text_input.filter = @filter @text_input.text = text @last_text_value = text - if @filter && @filter.respond_to?(:call) - @text_input.instance_variable_set(:@filter, @filter) - - def @text_input.filter(text_in) - @filter.call(text_in) - end - end - @offset_x = 0 @offset_y = 0 @@ -98,20 +105,20 @@ module CyberarmEngine @text_input.caret_pos = @text_input.text.length when Gosu::KB_C - if @text_input.selection_start < @text_input.caret_pos - Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos]) - else - Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start]) - end + Gosu.clipboard = if @text_input.selection_start < @text_input.caret_pos + @text_input.text[@text_input.selection_start...@text_input.caret_pos] + else + @text_input.text[@text_input.caret_pos...@text_input.selection_start] + end when Gosu::KB_X chars = @text_input.text.chars if @text_input.selection_start < @text_input.caret_pos - Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos]) + Gosu.clipboard = @text_input.text[@text_input.selection_start...@text_input.caret_pos] chars.slice!(@text_input.selection_start, @text_input.caret_pos) else - Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start]) + Gosu.clipboard = @text_input.text[@text_input.caret_pos...@text_input.selection_start] chars.slice!(@text_input.caret_pos, @text_input.selection_start) end @@ -119,10 +126,9 @@ module CyberarmEngine when Gosu::KB_V if instance_of?(EditLine) # EditLine assumes a single line of text - @text_input.text = @text_input.text.insert(@text_input.caret_pos, - Clipboard.paste.encode("UTF-8").gsub("\n", "")) + @text_input.insert_text(Gosu.clipboard.encode("UTF-8").gsub("\n", "")) else - @text_input.text = @text_input.text.insert(@text_input.caret_pos, Clipboard.paste.encode("UTF-8")) + @text_input.insert_text(Gosu.clipboard.encode("UTF-8")) end end end @@ -180,7 +186,7 @@ module CyberarmEngine 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)]) + @text.x + @text.width(@text_input.text[0...@text_input.send(method)]) - @style.border_thickness_left end end diff --git a/lib/cyberarm_engine/ui/elements/text_block.rb b/lib/cyberarm_engine/ui/elements/text_block.rb index aae0b4b..d24c03d 100644 --- a/lib/cyberarm_engine/ui/elements/text_block.rb +++ b/lib/cyberarm_engine/ui/elements/text_block.rb @@ -7,6 +7,7 @@ module CyberarmEngine @text = Text.new( text, font: @options[:font], z: @z, color: @options[:color], size: @options[:text_size], shadow: @options[:text_shadow], + static: @options[:text_static], shadow_size: @options[:text_shadow_size], shadow_color: @options[:text_shadow_color], border: @options[:text_border], @@ -64,6 +65,10 @@ module CyberarmEngine end end + if is_a?(Button) + @text.y = @y + height / 2 - @text.height / 2 + end + update_background end diff --git a/lib/cyberarm_engine/ui/theme.rb b/lib/cyberarm_engine/ui/theme.rb index 2b420ad..b5fc300 100644 --- a/lib/cyberarm_engine/ui/theme.rb +++ b/lib/cyberarm_engine/ui/theme.rb @@ -102,7 +102,8 @@ module CyberarmEngine caret_color: Gosu::Color::WHITE, caret_interval: 500, selection_color: Gosu::Color.rgba(255, 128, 50, 200), - text_align: :left + text_align: :left, + text_static: false # static text causes issues correctly displaying caret position }, Image: { # < Element