mirror of
https://github.com/cyberarm/cyberarm_engine.git
synced 2025-12-17 13:32:34 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 97296b080c | |||
| ca73a2d8e8 | |||
| 0a62e5180a | |||
| 31e909eb30 | |||
| 300e7c4e59 | |||
| be98fe47ad | |||
| a75afaf47a | |||
| d81df5f4e2 | |||
| f2ea0d9942 | |||
| 08d068f156 | |||
| a4d02038c3 | |||
| 37bdd6ef23 | |||
| 24bd769a32 | |||
| 2be5733bc1 | |||
| c8734ae98b | |||
| c35d587419 | |||
| 153871e7f3 | |||
| cf91d4a083 | |||
| 35ad687d4c | |||
| 54802e1254 | |||
| 6cf4cd73dd | |||
| 5e5f8ba7ea | |||
| 63a51d9d2f | |||
| 6af384536a | |||
| c1b25d2045 | |||
| a915a25699 | |||
| 0aa9b59316 |
@@ -27,8 +27,8 @@ Gem::Specification.new do |spec|
|
|||||||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||||
spec.require_paths = %w[lib assets]
|
spec.require_paths = %w[lib assets]
|
||||||
|
|
||||||
spec.add_dependency "clipboard", "~> 1.3.5"
|
spec.add_dependency "clipboard", "~> 1.3"
|
||||||
spec.add_dependency "excon", "~> 0.78.0"
|
spec.add_dependency "excon", "~> 0.88"
|
||||||
spec.add_dependency "gosu", "~> 1.1"
|
spec.add_dependency "gosu", "~> 1.1"
|
||||||
spec.add_dependency "gosu_more_drawables", "~> 0.3"
|
spec.add_dependency "gosu_more_drawables", "~> 0.3"
|
||||||
# spec.add_dependency "ffi", :platforms => [:mswin, :mingw] # Required by Clipboard on Windows
|
# spec.add_dependency "ffi", :platforms => [:mswin, :mingw] # Required by Clipboard on Windows
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ require_relative "cyberarm_engine/transform"
|
|||||||
require_relative "cyberarm_engine/ray"
|
require_relative "cyberarm_engine/ray"
|
||||||
require_relative "cyberarm_engine/background"
|
require_relative "cyberarm_engine/background"
|
||||||
require_relative "cyberarm_engine/background_nine_slice"
|
require_relative "cyberarm_engine/background_nine_slice"
|
||||||
|
require_relative "cyberarm_engine/background_image"
|
||||||
require_relative "cyberarm_engine/animator"
|
require_relative "cyberarm_engine/animator"
|
||||||
|
|
||||||
require_relative "cyberarm_engine/text"
|
require_relative "cyberarm_engine/text"
|
||||||
|
|||||||
93
lib/cyberarm_engine/background_image.rb
Normal file
93
lib/cyberarm_engine/background_image.rb
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
module CyberarmEngine
|
||||||
|
class BackgroundImage
|
||||||
|
include CyberarmEngine::Common
|
||||||
|
attr_accessor :x, :y, :z, :mode
|
||||||
|
attr_reader :image, :width, :height, :color
|
||||||
|
|
||||||
|
def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :fill, color: Gosu::Color::WHITE)
|
||||||
|
@image_path = image_path
|
||||||
|
@image = get_image(image_path) if image_path
|
||||||
|
|
||||||
|
@x = x
|
||||||
|
@y = y
|
||||||
|
@z = z
|
||||||
|
@width = width
|
||||||
|
@height = height
|
||||||
|
|
||||||
|
@mode = mode
|
||||||
|
|
||||||
|
@color = color
|
||||||
|
|
||||||
|
@cached_tiling = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def image=(image_path)
|
||||||
|
@cached_tiling = nil if image_path != @image_path
|
||||||
|
@image_path = image_path
|
||||||
|
@image = image_path ? get_image(image_path) : image_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def width=(n)
|
||||||
|
@cached_tiling = nil if @width != n
|
||||||
|
@width = n
|
||||||
|
end
|
||||||
|
|
||||||
|
def height=(n)
|
||||||
|
@cached_tiling = nil if @height != n
|
||||||
|
@height = n
|
||||||
|
end
|
||||||
|
|
||||||
|
def color=(c)
|
||||||
|
@cached_tiling = nil if @color != c
|
||||||
|
@color = c
|
||||||
|
end
|
||||||
|
|
||||||
|
def width_scale
|
||||||
|
(@width.to_f / @image.width).abs
|
||||||
|
end
|
||||||
|
|
||||||
|
def height_scale
|
||||||
|
(@height.to_f / @image.height).abs
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
return unless @image
|
||||||
|
|
||||||
|
Gosu.clip_to(@x, @y, @width, @height) do
|
||||||
|
send(:"draw_#{mode}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_stretch
|
||||||
|
@image.draw(@x, @y, @z, width_scale, height_scale, @color)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_tiled
|
||||||
|
@cached_tiling ||= Gosu.record(@width, @height) do
|
||||||
|
height_scale.ceil.times do |y|
|
||||||
|
width_scale.ceil.times do |x|
|
||||||
|
@image.draw(x * @image.width, y * @image.height, @z, 1, 1, @color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@cached_tiling.draw(@x, @y, @z)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_fill
|
||||||
|
if @width * width_scale > height * height_scale
|
||||||
|
draw_fill_width
|
||||||
|
else
|
||||||
|
draw_fill_height
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_fill_width
|
||||||
|
@image.draw(@x, @y, @z, width_scale, width_scale, @color)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_fill_height
|
||||||
|
@image.draw(@x, @y, @z, height_scale, height_scale, @color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -95,7 +95,7 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def window
|
def window
|
||||||
$window
|
CyberarmEngine::Window.instance
|
||||||
end
|
end
|
||||||
|
|
||||||
def control_down?
|
def control_down?
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ module CyberarmEngine
|
|||||||
attr_reader :alpha
|
attr_reader :alpha
|
||||||
|
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
$window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
|
window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
|
||||||
|
|
||||||
@options = options
|
@options = options
|
||||||
@image = options[:image] ? image(options[:image]) : nil
|
@image = options[:image] ? image(options[:image]) : nil
|
||||||
@@ -55,9 +55,9 @@ module CyberarmEngine
|
|||||||
|
|
||||||
if $debug
|
if $debug
|
||||||
show_debug_heading
|
show_debug_heading
|
||||||
$window.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
|
Gosu.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
|
||||||
if @debug_text.text != ""
|
if @debug_text.text != ""
|
||||||
$window.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
|
Gosu.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
|
||||||
Gosu::Color.rgba(0, 0, 0, 200), 9999)
|
Gosu::Color.rgba(0, 0, 0, 200), 9999)
|
||||||
@debug_text.draw
|
@debug_text.draw
|
||||||
end
|
end
|
||||||
@@ -102,13 +102,13 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def _x_visible
|
def _x_visible
|
||||||
x.between?(($window.width / 2) - @world_center_point.x, ($window.width / 2) + @world_center_point.x) ||
|
x.between?((window.width / 2) - @world_center_point.x, (window.width / 2) + @world_center_point.x) ||
|
||||||
x.between?((@world_center_point.x - $window.width / 2), ($window.width / 2) + @world_center_point.x)
|
x.between?((@world_center_point.x - window.width / 2), (window.width / 2) + @world_center_point.x)
|
||||||
end
|
end
|
||||||
|
|
||||||
def _y_visible
|
def _y_visible
|
||||||
y.between?(($window.height / 2) - @world_center_point.y, ($window.height / 2) + @world_center_point.y) ||
|
y.between?((window.height / 2) - @world_center_point.y, (window.height / 2) + @world_center_point.y) ||
|
||||||
y.between?(@world_center_point.y - ($window.height / 2), ($window.height / 2) + @world_center_point.y)
|
y.between?(@world_center_point.y - (window.height / 2), (window.height / 2) + @world_center_point.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
def heading(ahead_by = 100, _object = nil, angle_only = false)
|
def heading(ahead_by = 100, _object = nil, angle_only = false)
|
||||||
@@ -153,10 +153,6 @@ module CyberarmEngine
|
|||||||
@color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, int)
|
@color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, int)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_rect(x, y, width, height, color, z = 0)
|
|
||||||
$window.draw_rect(x, y, width, height, color, z)
|
|
||||||
end
|
|
||||||
|
|
||||||
def button_up(id)
|
def button_up(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -190,12 +186,12 @@ module CyberarmEngine
|
|||||||
# Duplication... so DRY.
|
# Duplication... so DRY.
|
||||||
def each_circle_collision(object, _resolve_with = :width, &block)
|
def each_circle_collision(object, _resolve_with = :width, &block)
|
||||||
if object.class != Class && object.instance_of?(object.class)
|
if object.class != Class && object.instance_of?(object.class)
|
||||||
$window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
|
window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
|
||||||
distance = Gosu.distance(x, y, object.x, object.y)
|
distance = Gosu.distance(x, y, object.x, object.y)
|
||||||
block.call(o, object) if distance <= radius + object.radius && block
|
block.call(o, object) if distance <= radius + object.radius && block
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
list = $window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
list = window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
||||||
list.each do |o|
|
list.each do |o|
|
||||||
next if self == o
|
next if self == o
|
||||||
|
|
||||||
@@ -206,9 +202,9 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
if $window.current_state
|
if window.current_state
|
||||||
$window.current_state.game_objects.each do |o|
|
window.current_state.game_objects.each do |o|
|
||||||
$window.current_state.game_objects.delete(o) if o.is_a?(self.class) && o == self
|
window.current_state.game_objects.delete(o) if o.is_a?(self.class) && o == self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -220,13 +216,13 @@ module CyberarmEngine
|
|||||||
|
|
||||||
def self.each_circle_collision(object, _resolve_with = :width, &block)
|
def self.each_circle_collision(object, _resolve_with = :width, &block)
|
||||||
if object.class != Class && object.instance_of?(object.class)
|
if object.class != Class && object.instance_of?(object.class)
|
||||||
$window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
|
window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
|
||||||
distance = Gosu.distance(o.x, o.y, object.x, object.y)
|
distance = Gosu.distance(o.x, o.y, object.x, object.y)
|
||||||
block.call(o, object) if distance <= o.radius + object.radius && block
|
block.call(o, object) if distance <= o.radius + object.radius && block
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
lista = $window.current_state.game_objects.select { |i| i.instance_of?(self) }
|
lista = window.current_state.game_objects.select { |i| i.instance_of?(self) }
|
||||||
listb = $window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
listb = window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
||||||
lista.product(listb).each do |o, o2|
|
lista.product(listb).each do |o, o2|
|
||||||
next if o == o2
|
next if o == o2
|
||||||
|
|
||||||
@@ -238,9 +234,9 @@ module CyberarmEngine
|
|||||||
|
|
||||||
def self.destroy_all
|
def self.destroy_all
|
||||||
INSTANCES.clear
|
INSTANCES.clear
|
||||||
if $window.current_state
|
if window.current_state
|
||||||
$window.current_state.game_objects.each do |o|
|
window.current_state.game_objects.each do |o|
|
||||||
$window.current_state.game_objects.delete(o) if o.is_a?(self.class)
|
window.current_state.game_objects.delete(o) if o.is_a?(self.class)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ module CyberarmEngine
|
|||||||
@options = options
|
@options = options
|
||||||
@game_objects = []
|
@game_objects = []
|
||||||
@global_pause = false
|
@global_pause = false
|
||||||
$window.text_input = nil unless options[:preserve_text_input]
|
window.text_input = nil unless options[:preserve_text_input]
|
||||||
|
|
||||||
@down_keys = {}
|
@down_keys = {}
|
||||||
end
|
end
|
||||||
@@ -30,48 +30,23 @@ module CyberarmEngine
|
|||||||
@game_objects.each(&:update)
|
@game_objects.each(&:update)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_bounding_box(box)
|
def needs_redraw?
|
||||||
x = box.x
|
true
|
||||||
y = box.y
|
|
||||||
max_x = box.max_x
|
|
||||||
max_y = box.max_y
|
|
||||||
|
|
||||||
color = Gosu::Color.rgba(255, 127, 64, 240)
|
|
||||||
|
|
||||||
# pipe = 4
|
|
||||||
# Gosu.draw_rect(x-width, y-height, x+(width*2), y+(height*2), color, Float::INFINITY)
|
|
||||||
# puts "BB render: #{x}:#{y} w:#{x.abs+width} h:#{y.abs+height}"
|
|
||||||
# Gosu.draw_rect(x, y, x.abs+width, y.abs+height, color, Float::INFINITY)
|
|
||||||
|
|
||||||
# TOP LEFT to BOTTOM LEFT
|
|
||||||
$window.draw_line(
|
|
||||||
x, y, color,
|
|
||||||
x, max_y, color,
|
|
||||||
Float::INFINITY
|
|
||||||
)
|
|
||||||
# BOTTOM LEFT to BOTTOM RIGHT
|
|
||||||
$window.draw_line(
|
|
||||||
x, max_y, color,
|
|
||||||
max_x, max_y, color,
|
|
||||||
Float::INFINITY
|
|
||||||
)
|
|
||||||
# BOTTOM RIGHT to TOP RIGHT
|
|
||||||
$window.draw_line(
|
|
||||||
max_x, max_y, color,
|
|
||||||
max_x, y, color,
|
|
||||||
Float::INFINITY
|
|
||||||
)
|
|
||||||
# TOP RIGHT to TOP LEFT
|
|
||||||
$window.draw_line(
|
|
||||||
max_x, y, color,
|
|
||||||
x, y, color,
|
|
||||||
Float::INFINITY
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def drop(filename)
|
||||||
@options.clear
|
end
|
||||||
@game_objects.clear
|
|
||||||
|
def gamepad_connected(index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gamepad_disconnected(index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gain_focus
|
||||||
|
end
|
||||||
|
|
||||||
|
def lose_focus
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_down(id)
|
def button_down(id)
|
||||||
@@ -90,6 +65,54 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def close
|
||||||
|
window.close!
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_bounding_box(box)
|
||||||
|
x = box.x
|
||||||
|
y = box.y
|
||||||
|
max_x = box.max_x
|
||||||
|
max_y = box.max_y
|
||||||
|
|
||||||
|
color = Gosu::Color.rgba(255, 127, 64, 240)
|
||||||
|
|
||||||
|
# pipe = 4
|
||||||
|
# Gosu.draw_rect(x-width, y-height, x+(width*2), y+(height*2), color, Float::INFINITY)
|
||||||
|
# puts "BB render: #{x}:#{y} w:#{x.abs+width} h:#{y.abs+height}"
|
||||||
|
# Gosu.draw_rect(x, y, x.abs+width, y.abs+height, color, Float::INFINITY)
|
||||||
|
|
||||||
|
# TOP LEFT to BOTTOM LEFT
|
||||||
|
Gosu.draw_line(
|
||||||
|
x, y, color,
|
||||||
|
x, max_y, color,
|
||||||
|
Float::INFINITY
|
||||||
|
)
|
||||||
|
# BOTTOM LEFT to BOTTOM RIGHT
|
||||||
|
Gosu.draw_line(
|
||||||
|
x, max_y, color,
|
||||||
|
max_x, max_y, color,
|
||||||
|
Float::INFINITY
|
||||||
|
)
|
||||||
|
# BOTTOM RIGHT to TOP RIGHT
|
||||||
|
Gosu.draw_line(
|
||||||
|
max_x, max_y, color,
|
||||||
|
max_x, y, color,
|
||||||
|
Float::INFINITY
|
||||||
|
)
|
||||||
|
# TOP RIGHT to TOP LEFT
|
||||||
|
Gosu.draw_line(
|
||||||
|
max_x, y, color,
|
||||||
|
x, y, color,
|
||||||
|
Float::INFINITY
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@options.clear
|
||||||
|
@game_objects.clear
|
||||||
|
end
|
||||||
|
|
||||||
def add_game_object(object)
|
def add_game_object(object)
|
||||||
@game_objects << object
|
@game_objects << object
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@bounding_box_renderer = BoundingBoxRenderer.new
|
@bounding_box_renderer = BoundingBoxRenderer.new
|
||||||
@opengl_renderer = OpenGLRenderer.new(width: $window.width, height: $window.height)
|
@opengl_renderer = OpenGLRenderer.new(width: CyberarmEngine::Window.instance.width, height: CyberarmEngine::Window.instance.height)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw(camera, lights, entities)
|
def draw(camera, lights, entities)
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ module CyberarmEngine
|
|||||||
when :left
|
when :left
|
||||||
@x = 0 + BUTTON_PADDING
|
@x = 0 + BUTTON_PADDING
|
||||||
when :center
|
when :center
|
||||||
@x = ($window.width / 2) - (@textobject.text_width(@text) / 2)
|
@x = (CyberarmEngine::Window.instance.width / 2) - (@textobject.text_width(@text) / 2)
|
||||||
when :right
|
when :right
|
||||||
@x = $window.width - BUTTON_PADDING - @textobject.text_width(@text)
|
@x = CyberarmEngine::Window.instance.width - BUTTON_PADDING - @textobject.text_width(@text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
private def element_parent
|
private def element_parent
|
||||||
$__current_container__
|
CyberarmEngine::Element::Container.current_container
|
||||||
end
|
end
|
||||||
|
|
||||||
private def container(klass, options = {}, &block)
|
private def container(klass, options = {}, &block)
|
||||||
@@ -126,12 +126,12 @@ module CyberarmEngine
|
|||||||
_container = klass.new(options, block)
|
_container = klass.new(options, block)
|
||||||
|
|
||||||
old_parent = element_parent
|
old_parent = element_parent
|
||||||
$__current_container__ = _container
|
CyberarmEngine::Element::Container.current_container = _container
|
||||||
|
|
||||||
_container.build
|
_container.build
|
||||||
_container.parent.add(_container)
|
_container.parent.add(_container)
|
||||||
|
|
||||||
$__current_container__ = old_parent
|
CyberarmEngine::Element::Container.current_container = old_parent
|
||||||
|
|
||||||
_container
|
_container
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module CyberarmEngine
|
|||||||
include Event
|
include Event
|
||||||
include Common
|
include Common
|
||||||
|
|
||||||
attr_accessor :x, :y, :z, :enabled, :tip
|
attr_accessor :x, :y, :z, :tip, :element_visible
|
||||||
attr_reader :parent, :options, :style, :event_handler, :background_canvas, :border_canvas
|
attr_reader :parent, :options, :style, :event_handler, :background_canvas, :border_canvas
|
||||||
|
|
||||||
def initialize(options = {}, block = nil)
|
def initialize(options = {}, block = nil)
|
||||||
@@ -13,9 +13,9 @@ module CyberarmEngine
|
|||||||
@options = options
|
@options = options
|
||||||
@block = block
|
@block = block
|
||||||
|
|
||||||
@focus = @options[:focus].nil? ? false : @options[:focus]
|
@focus = !@options.key?(:focus) ? false : @options[:focus]
|
||||||
@enabled = @options[:enabled].nil? ? true : @options[:enabled]
|
@enabled = !@options.key?(:enabled) ? true : @options[:enabled]
|
||||||
@visible = @options[:visible].nil? ? true : @options[:visible]
|
@visible = !@options.key?(:visible) ? true : @options[:visible]
|
||||||
@tip = @options[:tip] || ""
|
@tip = @options[:tip] || ""
|
||||||
|
|
||||||
@debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]
|
@debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]
|
||||||
@@ -24,6 +24,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
@root ||= nil
|
@root ||= nil
|
||||||
@gui_state ||= nil
|
@gui_state ||= nil
|
||||||
|
@element_visible = true
|
||||||
|
|
||||||
@x = @style.x
|
@x = @style.x
|
||||||
@y = @style.y
|
@y = @style.y
|
||||||
@@ -37,6 +38,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
@style.background_canvas = Background.new
|
@style.background_canvas = Background.new
|
||||||
@style.background_nine_slice_canvas = BackgroundNineSlice.new
|
@style.background_nine_slice_canvas = BackgroundNineSlice.new
|
||||||
|
@style.background_image_canvas = BackgroundImage.new
|
||||||
@style.border_canvas = BorderCanvas.new(element: self)
|
@style.border_canvas = BorderCanvas.new(element: self)
|
||||||
|
|
||||||
@style_event = :default
|
@style_event = :default
|
||||||
@@ -51,11 +53,15 @@ module CyberarmEngine
|
|||||||
def stylize
|
def stylize
|
||||||
set_static_position
|
set_static_position
|
||||||
|
|
||||||
|
set_color
|
||||||
|
set_font
|
||||||
|
|
||||||
set_padding
|
set_padding
|
||||||
set_margin
|
set_margin
|
||||||
|
|
||||||
set_background
|
set_background
|
||||||
set_background_nine_slice
|
set_background_nine_slice
|
||||||
|
set_background_image
|
||||||
|
|
||||||
set_border_thickness
|
set_border_thickness
|
||||||
set_border_color
|
set_border_color
|
||||||
@@ -70,6 +76,15 @@ module CyberarmEngine
|
|||||||
@y = @style.y if @style.y != 0
|
@y = @style.y if @style.y != 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_color
|
||||||
|
@style.color = safe_style_fetch(:color)
|
||||||
|
@text&.color = @style.color
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_font
|
||||||
|
@text&.swap_font(safe_style_fetch(:text_size), safe_style_fetch(:font))
|
||||||
|
end
|
||||||
|
|
||||||
def set_background
|
def set_background
|
||||||
@style.background = safe_style_fetch(:background)
|
@style.background = safe_style_fetch(:background)
|
||||||
|
|
||||||
@@ -91,6 +106,14 @@ module CyberarmEngine
|
|||||||
@style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom) || @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
|
end
|
||||||
|
|
||||||
|
def set_background_image
|
||||||
|
@style.background_image = safe_style_fetch(:background_image)
|
||||||
|
@style.background_image_mode = safe_style_fetch(:background_image_mode) || :stretch
|
||||||
|
@style.background_image_color = safe_style_fetch(:background_image_color) || Gosu::Color::WHITE
|
||||||
|
@style.background_image_canvas.mode = @style.background_image_mode
|
||||||
|
@style.background_image_canvas.color = @style.background_image_color
|
||||||
|
end
|
||||||
|
|
||||||
def set_border_thickness
|
def set_border_thickness
|
||||||
@style.border_thickness = safe_style_fetch(:border_thickness)
|
@style.border_thickness = safe_style_fetch(:border_thickness)
|
||||||
|
|
||||||
@@ -138,14 +161,8 @@ module CyberarmEngine
|
|||||||
old_width = width
|
old_width = width
|
||||||
old_height = height
|
old_height = height
|
||||||
|
|
||||||
_style = @style.send(event)
|
|
||||||
@style_event = event
|
@style_event = event
|
||||||
|
|
||||||
if @text.is_a?(CyberarmEngine::Text)
|
|
||||||
@text.color = _style&.dig(:color) || @style.default[:color]
|
|
||||||
@text.swap_font(_style&.dig(:text_size) || @style.default[:text_size], _style&.dig(:font) || @style.default[:font])
|
|
||||||
end
|
|
||||||
|
|
||||||
return if self.is_a?(ToolTip)
|
return if self.is_a?(ToolTip)
|
||||||
|
|
||||||
if old_width != width || old_height != height
|
if old_width != width || old_height != height
|
||||||
@@ -238,6 +255,14 @@ module CyberarmEngine
|
|||||||
:handled
|
:handled
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enabled=(boolean)
|
||||||
|
@enabled = boolean
|
||||||
|
|
||||||
|
recalculate
|
||||||
|
|
||||||
|
@enabled
|
||||||
|
end
|
||||||
|
|
||||||
def enabled?
|
def enabled?
|
||||||
@enabled
|
@enabled
|
||||||
end
|
end
|
||||||
@@ -246,6 +271,10 @@ module CyberarmEngine
|
|||||||
@visible
|
@visible
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def element_visible?
|
||||||
|
@element_visible
|
||||||
|
end
|
||||||
|
|
||||||
def toggle
|
def toggle
|
||||||
@visible = !@visible
|
@visible = !@visible
|
||||||
root.gui_state.request_recalculate
|
root.gui_state.request_recalculate
|
||||||
@@ -265,14 +294,14 @@ module CyberarmEngine
|
|||||||
|
|
||||||
def draw
|
def draw
|
||||||
return unless visible?
|
return unless visible?
|
||||||
|
return unless element_visible?
|
||||||
|
|
||||||
@style.background_canvas.draw
|
@style.background_canvas.draw
|
||||||
@style.background_nine_slice_canvas.draw
|
@style.background_nine_slice_canvas.draw
|
||||||
|
@style.background_image_canvas.draw
|
||||||
@style.border_canvas.draw
|
@style.border_canvas.draw
|
||||||
|
|
||||||
Gosu.clip_to(@x, @y, width, height) do
|
render
|
||||||
render
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def debug_draw
|
def debug_draw
|
||||||
@@ -370,29 +399,75 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def scroll_width
|
def scroll_width
|
||||||
@children.sum(&:width) + noncontent_width
|
@children.sum(&:outer_width)
|
||||||
end
|
end
|
||||||
|
|
||||||
def scroll_height
|
def scroll_height
|
||||||
@children.sum(&:height) + noncontent_height
|
if is_a?(CyberarmEngine::Element::Flow)
|
||||||
|
return 0 if @children.size.zero?
|
||||||
|
|
||||||
|
pairs_ = []
|
||||||
|
sorted_children_ = @children.sort_by(&:y)
|
||||||
|
a_ = []
|
||||||
|
y_position_ = sorted_children_.first.y
|
||||||
|
|
||||||
|
sorted_children_.each do |child|
|
||||||
|
unless child.y == y_position_
|
||||||
|
y_position_ = child.y
|
||||||
|
pairs_ << a_
|
||||||
|
a_ = []
|
||||||
|
end
|
||||||
|
|
||||||
|
a_ << child
|
||||||
|
end
|
||||||
|
|
||||||
|
pairs_ << a_ unless pairs_.last == a_
|
||||||
|
|
||||||
|
pairs_.sum { |pair| pair.map(&:outer_height).max } + @style.padding_bottom + @style.border_thickness_bottom
|
||||||
|
else
|
||||||
|
@children.sum(&:outer_height) + @style.padding_bottom + @style.border_thickness_bottom
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_scroll_width
|
def max_scroll_width
|
||||||
scroll_width - width
|
scroll_width - outer_width
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_scroll_height
|
def max_scroll_height
|
||||||
scroll_height - height
|
scroll_height - outer_height
|
||||||
end
|
end
|
||||||
|
|
||||||
def dimensional_size(size, dimension)
|
def dimensional_size(size, dimension)
|
||||||
raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)
|
raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)
|
||||||
|
|
||||||
if size.is_a?(Numeric) && size.between?(0.0, 1.0)
|
new_size = if size.is_a?(Numeric) && size.between?(0.0, 1.0)
|
||||||
(@parent.send(:"content_#{dimension}") * size).round - send(:"noncontent_#{dimension}").round
|
(@parent.send(:"content_#{dimension}") * size).floor - send(:"noncontent_#{dimension}").floor
|
||||||
else
|
else
|
||||||
size
|
size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if @parent && @style.fill # Handle fill behavior
|
||||||
|
fill_siblings = @parent.children.select { |c| c.style.fill }.count.to_f # include self since we're dividing
|
||||||
|
|
||||||
|
if dimension == :width && @parent.is_a?(Flow)
|
||||||
|
space_available_width = ((@parent.content_width - (@parent.children.reject { |c| c.style.fill }).map(&:outer_width).sum) / fill_siblings)
|
||||||
|
space_available_width = space_available_width.nan? ? 0 : space_available_width.floor # The parent element might not have its dimensions, yet.
|
||||||
|
|
||||||
|
return space_available_width - noncontent_width
|
||||||
|
|
||||||
|
elsif dimension == :height && @parent.is_a?(Stack)
|
||||||
|
space_available_height = ((@parent.content_height - (@parent.children.reject { |c| c.style.fill }).map(&:outer_height).sum) / fill_siblings)
|
||||||
|
space_available_height = space_available_height.nan? ? 0 : space_available_height.floor # The parent element might not have its dimensions, yet.
|
||||||
|
|
||||||
|
return space_available_height - noncontent_height
|
||||||
|
end
|
||||||
|
|
||||||
|
else # Handle min_width/height and max_width/height
|
||||||
|
return @style.send(:"min_#{dimension}") if @style.send(:"min_#{dimension}") && new_size < @style.send(:"min_#{dimension}")
|
||||||
|
return @style.send(:"max_#{dimension}") if @style.send(:"max_#{dimension}") && new_size > @style.send(:"max_#{dimension}")
|
||||||
|
end
|
||||||
|
|
||||||
|
new_size
|
||||||
end
|
end
|
||||||
|
|
||||||
def background=(_background)
|
def background=(_background)
|
||||||
@@ -409,6 +484,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
@style.background_canvas.update
|
@style.background_canvas.update
|
||||||
update_background_nine_slice
|
update_background_nine_slice
|
||||||
|
update_background_image
|
||||||
@style.border_canvas.update
|
@style.border_canvas.update
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -436,6 +512,24 @@ module CyberarmEngine
|
|||||||
@style.background_nine_slice_canvas.image = @style.background_nine_slice
|
@style.background_nine_slice_canvas.image = @style.background_nine_slice
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def background_image=(image_path)
|
||||||
|
@style.background_image = image_path.is_a?(Gosu::Image) ? image_path : get_image(image_path)
|
||||||
|
update_background_image
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_background_image
|
||||||
|
@style.background_image_canvas.x = @x
|
||||||
|
@style.background_image_canvas.y = @y
|
||||||
|
@style.background_image_canvas.z = @z
|
||||||
|
@style.background_image_canvas.width = width
|
||||||
|
@style.background_image_canvas.height = height
|
||||||
|
|
||||||
|
@style.background_image_canvas.mode = @style.background_image_mode
|
||||||
|
@style.background_image_canvas.color = @style.background_image_color
|
||||||
|
|
||||||
|
@style.background_image_canvas.image = @style.background_image
|
||||||
|
end
|
||||||
|
|
||||||
def root
|
def root
|
||||||
return self if is_root?
|
return self if is_root?
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ module CyberarmEngine
|
|||||||
@scale_y = 1
|
@scale_y = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@width = _width || @image.width.round * @scale_x
|
@width = _width || @image.width.floor * @scale_x
|
||||||
@height = _height || @image.height.round * @scale_y
|
@height = _height || @image.height.floor * @scale_y
|
||||||
|
|
||||||
update_background
|
update_background
|
||||||
else
|
else
|
||||||
@@ -86,9 +86,12 @@ module CyberarmEngine
|
|||||||
|
|
||||||
old_width = width
|
old_width = width
|
||||||
old_height = height
|
old_height = height
|
||||||
recalculate
|
|
||||||
|
|
||||||
root.gui_state.request_recalculate if old_width != width || old_height != height
|
if old_width != width || old_height != height
|
||||||
|
root.gui_state.request_recalculate
|
||||||
|
else
|
||||||
|
recalculate
|
||||||
|
end
|
||||||
|
|
||||||
publish(:changed, self.value)
|
publish(:changed, self.value)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,6 +6,16 @@ module CyberarmEngine
|
|||||||
attr_accessor :stroke_color, :fill_color
|
attr_accessor :stroke_color, :fill_color
|
||||||
attr_reader :children, :gui_state, :scroll_position
|
attr_reader :children, :gui_state, :scroll_position
|
||||||
|
|
||||||
|
def self.current_container
|
||||||
|
@@current_container
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.current_container=(container)
|
||||||
|
raise ArgumentError, "Expected container to an an instance of CyberarmEngine::Element::Container, got #{container.class}" unless container.is_a?(CyberarmEngine::Element::Container)
|
||||||
|
|
||||||
|
@@current_container = container
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(options = {}, block = nil)
|
def initialize(options = {}, block = nil)
|
||||||
@gui_state = options.delete(:gui_state)
|
@gui_state = options.delete(:gui_state)
|
||||||
super
|
super
|
||||||
@@ -35,29 +45,34 @@ module CyberarmEngine
|
|||||||
def clear(&block)
|
def clear(&block)
|
||||||
@children.clear
|
@children.clear
|
||||||
|
|
||||||
old_container = $__current_container__
|
old_container = CyberarmEngine::Element::Container.current_container
|
||||||
|
|
||||||
$__current_container__ = self
|
CyberarmEngine::Element::Container.current_container = self
|
||||||
block.call(self) if block
|
block.call(self) if block
|
||||||
|
|
||||||
$__current_container__ = old_container
|
CyberarmEngine::Element::Container.current_container = old_container
|
||||||
|
|
||||||
root.gui_state.request_recalculate
|
root.gui_state.request_recalculate
|
||||||
end
|
end
|
||||||
|
|
||||||
def apend(&block)
|
def append(&block)
|
||||||
old_container = $__current_container__
|
old_container = CyberarmEngine::Element::Container.current_container
|
||||||
|
|
||||||
$__current_container__ = self
|
CyberarmEngine::Element::Container.current_container = self
|
||||||
block.call(self) if block
|
block.call(self) if block
|
||||||
|
|
||||||
$__current_container__ = old_container
|
CyberarmEngine::Element::Container.current_container = old_container
|
||||||
|
|
||||||
root.gui_state.request_recalculate
|
root.gui_state.request_recalculate
|
||||||
end
|
end
|
||||||
|
|
||||||
def render
|
def render
|
||||||
Gosu.clip_to(@x, @y, width, height) do
|
Gosu.clip_to(
|
||||||
|
@x + @style.border_thickness_left + @style.padding_left,
|
||||||
|
@y + @style.border_thickness_top + @style.padding_top,
|
||||||
|
content_width + 1,
|
||||||
|
content_height + 1
|
||||||
|
) do
|
||||||
@children.each(&:draw)
|
@children.each(&:draw)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -103,6 +118,8 @@ module CyberarmEngine
|
|||||||
|
|
||||||
stylize
|
stylize
|
||||||
|
|
||||||
|
# s = Gosu.milliseconds
|
||||||
|
|
||||||
layout
|
layout
|
||||||
|
|
||||||
if is_root?
|
if is_root?
|
||||||
@@ -115,8 +132,8 @@ module CyberarmEngine
|
|||||||
_width = dimensional_size(@style.width, :width)
|
_width = dimensional_size(@style.width, :width)
|
||||||
_height = dimensional_size(@style.height, :height)
|
_height = dimensional_size(@style.height, :height)
|
||||||
|
|
||||||
@width = _width || (@children.map { |c| c.x + c.outer_width }.max || 0).round
|
@width = _width || (@children.map { |c| c.x + c.outer_width }.max || 0).floor
|
||||||
@height = _height || (@children.map { |c| c.y + c.outer_height }.max || 0).round
|
@height = _height || (@children.map { |c| c.y + c.outer_height }.max || 0).floor
|
||||||
end
|
end
|
||||||
|
|
||||||
# Move child to parent after positioning
|
# Move child to parent after positioning
|
||||||
@@ -129,8 +146,13 @@ module CyberarmEngine
|
|||||||
child.reposition # TODO: Implement top,bottom,left,center, and right positioning
|
child.reposition # TODO: Implement top,bottom,left,center, and right positioning
|
||||||
|
|
||||||
Stats.increment(:gui_recalculations_last_frame, 1)
|
Stats.increment(:gui_recalculations_last_frame, 1)
|
||||||
|
|
||||||
|
child.element_visible = child.x >= @x - child.width && child.x <= @x + width &&
|
||||||
|
child.y >= @y - child.height && child.y <= @y + height
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# puts "TOOK: #{Gosu.milliseconds - s}ms to recalculate #{self.class}:0x#{self.object_id.to_s(16)}"
|
||||||
|
|
||||||
update_background
|
update_background
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -139,12 +161,14 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def max_width
|
def max_width
|
||||||
_width = dimensional_size(@style.width, :width)
|
# _width = dimensional_size(@style.width, :width)
|
||||||
if _width
|
# if _width
|
||||||
outer_width
|
# outer_width
|
||||||
else
|
# else
|
||||||
window.width - (@parent ? @parent.style.margin_right + @style.margin_right : @style.margin_right)
|
# window.width - (@parent ? @parent.style.margin_right + @style.margin_right : @style.margin_right)
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
outer_width
|
||||||
end
|
end
|
||||||
|
|
||||||
def fits_on_line?(element) # Flow
|
def fits_on_line?(element) # Flow
|
||||||
@@ -194,7 +218,8 @@ module CyberarmEngine
|
|||||||
if @scroll_position.y < 0
|
if @scroll_position.y < 0
|
||||||
@scroll_position.y += @scroll_speed
|
@scroll_position.y += @scroll_speed
|
||||||
@scroll_position.y = 0 if @scroll_position.y > 0
|
@scroll_position.y = 0 if @scroll_position.y > 0
|
||||||
recalculate
|
|
||||||
|
root.gui_state.request_recalculate_for(self)
|
||||||
|
|
||||||
return :handled
|
return :handled
|
||||||
end
|
end
|
||||||
@@ -208,7 +233,8 @@ module CyberarmEngine
|
|||||||
if @scroll_position.y.abs < max_scroll_height
|
if @scroll_position.y.abs < max_scroll_height
|
||||||
@scroll_position.y -= @scroll_speed
|
@scroll_position.y -= @scroll_speed
|
||||||
@scroll_position.y = -max_scroll_height if @scroll_position.y.abs > max_scroll_height
|
@scroll_position.y = -max_scroll_height if @scroll_position.y.abs > max_scroll_height
|
||||||
recalculate
|
|
||||||
|
root.gui_state.request_recalculate_for(self)
|
||||||
|
|
||||||
return :handled
|
return :handled
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def row_at(y)
|
def row_at(y)
|
||||||
((y - @text.y) / @text.textobject.height).round
|
((y - @text.y) / @text.textobject.height).floor
|
||||||
end
|
end
|
||||||
|
|
||||||
def column_at(x, y)
|
def column_at(x, y)
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ module CyberarmEngine
|
|||||||
@scale_y = 1
|
@scale_y = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@width = _width || @image.width.round * @scale_x
|
@width = _width || @image.width.floor * @scale_x
|
||||||
@height = _height || @image.height.round * @scale_y
|
@height = _height || @image.height.floor * @scale_y
|
||||||
|
|
||||||
update_background
|
update_background
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ module CyberarmEngine
|
|||||||
@menu.define_singleton_method(:recalculate_menu) do
|
@menu.define_singleton_method(:recalculate_menu) do
|
||||||
@x = @__list_box.x
|
@x = @__list_box.x
|
||||||
@y = @__list_box.y + @__list_box.height
|
@y = @__list_box.y + @__list_box.height
|
||||||
|
|
||||||
|
@y = @__list_box.y - height if @y + height > window.height
|
||||||
end
|
end
|
||||||
@menu.instance_variable_set(:"@__list_box", self)
|
@menu.instance_variable_set(:"@__list_box", self)
|
||||||
|
|
||||||
@@ -29,6 +31,13 @@ module CyberarmEngine
|
|||||||
self.choose = @choose
|
self.choose = @choose
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render
|
||||||
|
super
|
||||||
|
|
||||||
|
w = @text.textobject.text_width("▼")
|
||||||
|
@text.textobject.draw_text("▼", @x + content_width - w, @y + @style.padding_top, @z, 1, 1, @text.color)
|
||||||
|
end
|
||||||
|
|
||||||
def choose=(item)
|
def choose=(item)
|
||||||
valid = @items.detect { |i| i == item }
|
valid = @items.detect { |i| i == item }
|
||||||
raise "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}" unless valid
|
raise "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}" unless valid
|
||||||
@@ -47,7 +56,7 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def clicked_left_mouse_button(_sender, _x, _y)
|
def clicked_left_mouse_button(_sender, _x, _y)
|
||||||
@block&.call(self.value) if @enabled
|
# @block&.call(self.value) if @enabled
|
||||||
|
|
||||||
:handled
|
:handled
|
||||||
end
|
end
|
||||||
@@ -56,6 +65,8 @@ module CyberarmEngine
|
|||||||
@menu.clear
|
@menu.clear
|
||||||
|
|
||||||
@items.each do |item|
|
@items.each do |item|
|
||||||
|
next if item == self.value
|
||||||
|
|
||||||
btn = Button.new(
|
btn = Button.new(
|
||||||
item,
|
item,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
module CyberarmEngine
|
module CyberarmEngine
|
||||||
class Element
|
class Element
|
||||||
class Progress < Element
|
class Progress < Element
|
||||||
|
attr_reader :type
|
||||||
|
|
||||||
def initialize(options = {}, block = nil)
|
def initialize(options = {}, block = nil)
|
||||||
super(options, block)
|
super(options, block)
|
||||||
|
|
||||||
|
@animation_speed = options[:animation_speed] || 3_000
|
||||||
|
@marquee_width = options[:marquee_width] || 0.25
|
||||||
|
@marquee_offset = 0
|
||||||
|
@marquee_animation_time = Gosu.milliseconds
|
||||||
|
@type = options[:type] || :linear
|
||||||
@fraction_background = Background.new(background: @style.fraction_background)
|
@fraction_background = Background.new(background: @style.fraction_background)
|
||||||
self.value = options[:fraction] || 0.0
|
self.value = options[:fraction] || 0.0
|
||||||
end
|
end
|
||||||
@@ -24,15 +31,45 @@ module CyberarmEngine
|
|||||||
def update_background
|
def update_background
|
||||||
super
|
super
|
||||||
|
|
||||||
@fraction_background.x = @style.border_thickness_left + @style.padding_left + @x
|
@fraction_background.x = (@style.border_thickness_left + @style.padding_left + @x) + @marquee_offset
|
||||||
@fraction_background.y = @style.border_thickness_top + @style.padding_top + @y
|
@fraction_background.y = @style.border_thickness_top + @style.padding_top + @y
|
||||||
@fraction_background.z = @z
|
@fraction_background.z = @z
|
||||||
@fraction_background.width = @width * @fraction
|
@fraction_background.width = @width * (@type == :marquee ? @marquee_width : @fraction)
|
||||||
@fraction_background.height = @height
|
@fraction_background.height = @height
|
||||||
|
|
||||||
@fraction_background.background = @style.fraction_background
|
@fraction_background.background = @style.fraction_background
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
super
|
||||||
|
|
||||||
|
return unless @type == :marquee
|
||||||
|
|
||||||
|
marquee_width = @width * @marquee_width
|
||||||
|
range = @width + marquee_width
|
||||||
|
|
||||||
|
@marquee_offset = (@width * (Gosu.milliseconds - @marquee_animation_time) / @animation_speed) - marquee_width
|
||||||
|
@marquee_animation_time = Gosu.milliseconds if @marquee_offset > range
|
||||||
|
|
||||||
|
update_background
|
||||||
|
end
|
||||||
|
|
||||||
|
def type=(type)
|
||||||
|
@type = type
|
||||||
|
|
||||||
|
case type
|
||||||
|
when :linear
|
||||||
|
@marquee_offset = 0
|
||||||
|
when :marquee
|
||||||
|
@marquee_offset = 0
|
||||||
|
@marquee_animation_time = Gosu.milliseconds
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Only types :linear and :marquee are supported"
|
||||||
|
end
|
||||||
|
|
||||||
|
update_background
|
||||||
|
end
|
||||||
|
|
||||||
def value
|
def value
|
||||||
@fraction
|
@fraction
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,7 +18,14 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render
|
def render
|
||||||
@text.draw
|
# Gosu.clip_to is too expensive to always use so check if we actually need it.
|
||||||
|
if @text.width > width || @text.height > height
|
||||||
|
Gosu.clip_to(@x, @y, width, height) do
|
||||||
|
@text.draw
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@text.draw
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def recalculate
|
def recalculate
|
||||||
@@ -36,8 +43,8 @@ module CyberarmEngine
|
|||||||
|
|
||||||
handle_text_wrapping(_width)
|
handle_text_wrapping(_width)
|
||||||
|
|
||||||
@width = _width || @text.width.round
|
@width = _width || @text.width.floor
|
||||||
@height = _height || @text.height.round
|
@height = _height || @text.height.floor
|
||||||
|
|
||||||
@text.y = @style.border_thickness_top + @style.padding_top + @y
|
@text.y = @style.border_thickness_top + @style.padding_top + @y
|
||||||
@text.z = @z + 3
|
@text.z = @z + 3
|
||||||
@@ -47,8 +54,8 @@ module CyberarmEngine
|
|||||||
when :left
|
when :left
|
||||||
@text.x = @style.border_thickness_left + @style.padding_left + @x
|
@text.x = @style.border_thickness_left + @style.padding_left + @x
|
||||||
when :center
|
when :center
|
||||||
@text.x = if @text.width <= outer_width
|
@text.x = if @text.width <= width
|
||||||
@x + outer_width / 2 - @text.width / 2
|
@x + width / 2 - @text.width / 2
|
||||||
else # Act as left aligned
|
else # Act as left aligned
|
||||||
@style.border_thickness_left + @style.padding_left + @x
|
@style.border_thickness_left + @style.padding_left + @x
|
||||||
end
|
end
|
||||||
@@ -61,46 +68,64 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle_text_wrapping(max_width)
|
def handle_text_wrapping(max_width)
|
||||||
max_width ||= @parent&.width
|
max_width ||= @parent&.content_width
|
||||||
max_width ||= @x - (window.width + noncontent_width)
|
max_width ||= @x - (window.width + noncontent_width)
|
||||||
wrap_behavior = style.text_wrap
|
wrap_behavior = style.text_wrap
|
||||||
copy = @raw_text.to_s.dup
|
copy = @raw_text.to_s.dup
|
||||||
|
|
||||||
if line_width(copy[0]) <= max_width && line_width(copy) > max_width && wrap_behavior != :none
|
# Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
|
||||||
breaks = []
|
if wrap_behavior != :none && line_width(copy[0]) <= max_width && line_width(copy) > max_width
|
||||||
|
breaks = [] # list of indexes to insert a line break
|
||||||
line_start = 0
|
line_start = 0
|
||||||
line_end = copy.length
|
line_end = copy.length
|
||||||
|
|
||||||
while line_start != copy.length
|
stalled = false
|
||||||
if line_width(copy[line_start...line_end]) > max_width
|
stalled_interations = 0
|
||||||
line_end = ((line_end - line_start) / 2.0)
|
max_stalled_iterations = 10
|
||||||
line_end = 1.0 if line_end <= 1
|
checked_copy_length = line_width(copy[line_start..line_end])
|
||||||
elsif line_end < copy.length && line_width(copy[line_start...line_end + 1]) < max_width
|
|
||||||
# To small, grow!
|
|
||||||
# TODO: find a more efficient way
|
|
||||||
line_end += 1
|
|
||||||
|
|
||||||
else # FOUND IT!
|
# find length of lines
|
||||||
entering_line_end = line_end.floor
|
while line_width(copy[line_start..line_end]) > max_width && stalled_interations < max_stalled_iterations
|
||||||
max_reach = line_end.floor - line_start < 63 ? line_end.floor - line_start : 63
|
search_start = line_start
|
||||||
reach = 0
|
search_end = line_end
|
||||||
|
|
||||||
if wrap_behavior == :word_wrap
|
# Perform a binary search to find length of line
|
||||||
max_reach.times do |i|
|
while search_start < search_end
|
||||||
reach = i
|
midpoint = ((search_start.to_f + search_end) / 2.0).floor
|
||||||
break if copy[line_end.floor - i].to_s.match(/[[:punct:]]| /)
|
|
||||||
|
if line_width(copy[line_start..midpoint]) > max_width
|
||||||
|
search_end = midpoint
|
||||||
|
else
|
||||||
|
search_start = midpoint + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if wrap_behavior == :word_wrap
|
||||||
|
word_search_end = search_end
|
||||||
|
failed = false
|
||||||
|
|
||||||
|
until(copy[word_search_end].to_s.match(/[[:punct:]]| /))
|
||||||
|
word_search_end -= 1
|
||||||
|
|
||||||
|
if word_search_end <= 1 || word_search_end < line_start
|
||||||
|
failed = true
|
||||||
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
# puts "Max width: #{max_width}/#{line_width(@raw_text)} Reach: {#{reach}/#{max_reach}} Line Start: #{line_start}/#{line_end.floor} (#{copy.length}|#{@raw_text.length}) [#{entering_line_end}] '#{copy}' {#{copy[line_start...line_end]}}"
|
|
||||||
line_end = line_end.floor - reach + 1 if reach != max_reach # Add +1 to walk in front of punctuation
|
|
||||||
end
|
end
|
||||||
|
|
||||||
breaks << line_end.floor
|
line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
|
||||||
line_start = line_end.floor
|
else
|
||||||
line_end = copy.length
|
line_start = search_end
|
||||||
|
|
||||||
break if entering_line_end == copy.length || reach == max_reach
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
breaks << line_start
|
||||||
|
|
||||||
|
# Prevent locking up due to outer while loop text width < max_width check not being satisfied.
|
||||||
|
stalled = checked_copy_length == line_width(copy[line_start..line_end])
|
||||||
|
checked_copy_length = line_width(copy[line_start..line_end])
|
||||||
|
|
||||||
|
stalled_interations += 1 if stalled
|
||||||
|
stalled_interations = 0 unless stalled
|
||||||
end
|
end
|
||||||
|
|
||||||
breaks.each_with_index do |pos, index|
|
breaks.each_with_index do |pos, index|
|
||||||
@@ -124,9 +149,12 @@ module CyberarmEngine
|
|||||||
|
|
||||||
old_width = width
|
old_width = width
|
||||||
old_height = height
|
old_height = height
|
||||||
recalculate
|
|
||||||
|
|
||||||
root.gui_state.request_recalculate if old_width != width || old_height != height
|
if old_width != width || old_height != height
|
||||||
|
root.gui_state.request_recalculate
|
||||||
|
else
|
||||||
|
recalculate
|
||||||
|
end
|
||||||
|
|
||||||
publish(:changed, self.value)
|
publish(:changed, self.value)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
@root_container = Element::Stack.new(gui_state: self)
|
@root_container = Element::Stack.new(gui_state: self)
|
||||||
@game_objects << @root_container
|
@game_objects << @root_container
|
||||||
$__current_container__ = @root_container
|
CyberarmEngine::Element::Container.current_container = @root_container
|
||||||
|
|
||||||
@active_width = window.width
|
@active_width = window.width
|
||||||
@active_height = window.height
|
@active_height = window.height
|
||||||
@@ -25,6 +25,7 @@ module CyberarmEngine
|
|||||||
@last_mouse_pos = nil
|
@last_mouse_pos = nil
|
||||||
@dragging_element = nil
|
@dragging_element = nil
|
||||||
@pending_recalculate_request = false
|
@pending_recalculate_request = false
|
||||||
|
@pending_element_recalculate_requests = []
|
||||||
|
|
||||||
@menu = nil
|
@menu = nil
|
||||||
@min_drag_distance = 0
|
@min_drag_distance = 0
|
||||||
@@ -56,6 +57,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
if @tip.value.length.positive?
|
if @tip.value.length.positive?
|
||||||
Gosu.flush
|
Gosu.flush
|
||||||
|
|
||||||
@tip.draw
|
@tip.draw
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -75,6 +77,9 @@ module CyberarmEngine
|
|||||||
@pending_recalculate_request = false
|
@pending_recalculate_request = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@pending_element_recalculate_requests.each(&:recalculate)
|
||||||
|
@pending_element_recalculate_requests.clear
|
||||||
|
|
||||||
if @pending_focus_request
|
if @pending_focus_request
|
||||||
@pending_focus_request = false
|
@pending_focus_request = false
|
||||||
|
|
||||||
@@ -85,6 +90,8 @@ module CyberarmEngine
|
|||||||
@menu&.update
|
@menu&.update
|
||||||
super
|
super
|
||||||
|
|
||||||
|
return unless window.has_focus?
|
||||||
|
|
||||||
new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
|
new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
|
||||||
new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
|
new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
|
||||||
|
|
||||||
@@ -130,10 +137,6 @@ module CyberarmEngine
|
|||||||
@active_height = window.height
|
@active_height = window.height
|
||||||
end
|
end
|
||||||
|
|
||||||
def tool_tip_delay
|
|
||||||
250 # ms
|
|
||||||
end
|
|
||||||
|
|
||||||
def button_down(id)
|
def button_down(id)
|
||||||
super
|
super
|
||||||
|
|
||||||
@@ -170,6 +173,10 @@ module CyberarmEngine
|
|||||||
@focus.button_up(id) if @focus.respond_to?(:button_up)
|
@focus.button_up(id) if @focus.respond_to?(:button_up)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tool_tip_delay
|
||||||
|
@tip.style.delay || 250 # ms
|
||||||
|
end
|
||||||
|
|
||||||
def redirect_mouse_button(button)
|
def redirect_mouse_button(button)
|
||||||
hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
|
hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
|
||||||
|
|
||||||
@@ -231,6 +238,13 @@ module CyberarmEngine
|
|||||||
@pending_recalculate_request = true
|
@pending_recalculate_request = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def request_recalculate_for(element)
|
||||||
|
# element is already queued
|
||||||
|
return if @pending_element_recalculate_requests.detect { |e| e == element }
|
||||||
|
|
||||||
|
@pending_element_recalculate_requests << element
|
||||||
|
end
|
||||||
|
|
||||||
def request_focus(element)
|
def request_focus(element)
|
||||||
@pending_focus_request = true
|
@pending_focus_request = true
|
||||||
@pending_focus_element = element
|
@pending_focus_element = element
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ module CyberarmEngine
|
|||||||
},
|
},
|
||||||
|
|
||||||
ToolTip: { # < TextBlock
|
ToolTip: { # < TextBlock
|
||||||
|
delay: 100, # ms
|
||||||
color: Gosu::Color::WHITE,
|
color: Gosu::Color::WHITE,
|
||||||
padding_top: 4,
|
padding_top: 4,
|
||||||
padding_bottom: 4,
|
padding_bottom: 4,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module CyberarmEngine
|
module CyberarmEngine
|
||||||
NAME = "InDev".freeze
|
NAME = "InDev".freeze
|
||||||
VERSION = "0.19.1".freeze
|
VERSION = "0.21.0".freeze
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,21 +8,33 @@ module CyberarmEngine
|
|||||||
|
|
||||||
attr_accessor :show_cursor
|
attr_accessor :show_cursor
|
||||||
attr_writer :exit_on_opengl_error
|
attr_writer :exit_on_opengl_error
|
||||||
attr_reader :last_frame_time
|
attr_reader :last_frame_time, :states
|
||||||
|
|
||||||
def self.now
|
def self.now
|
||||||
Gosu.milliseconds
|
Gosu.milliseconds
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.dt
|
def self.dt
|
||||||
$window.last_frame_time / 1000.0
|
instance.last_frame_time / 1000.0
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.instance=(window)
|
||||||
|
raise ArgumentError, "Expected window to be a subclass of CyberarmEngine::Window, got: #{window.class}" unless window.is_a?(CyberarmEngine::Window)
|
||||||
|
|
||||||
|
@@instance = window
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.instance
|
||||||
|
@@instance
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false)
|
def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false)
|
||||||
@show_cursor = false
|
@show_cursor = false
|
||||||
|
@has_focus = false
|
||||||
|
|
||||||
super(width, height, fullscreen: fullscreen, update_interval: update_interval, resizable: resizable, borderless: borderless)
|
super(width, height, fullscreen: fullscreen, update_interval: update_interval, resizable: resizable, borderless: borderless)
|
||||||
$window = self
|
Window.instance = self
|
||||||
|
|
||||||
@last_frame_time = Gosu.milliseconds - 1
|
@last_frame_time = Gosu.milliseconds - 1
|
||||||
@current_frame_time = Gosu.milliseconds
|
@current_frame_time = Gosu.milliseconds
|
||||||
self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.language}"
|
self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.language}"
|
||||||
@@ -34,13 +46,14 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
current_state.draw if current_state
|
current_state&.draw
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
Stats.clear
|
Stats.clear
|
||||||
|
|
||||||
current_state.update if current_state
|
current_state&.update
|
||||||
|
|
||||||
@last_frame_time = Gosu.milliseconds - @current_frame_time
|
@last_frame_time = Gosu.milliseconds - @current_frame_time
|
||||||
@current_frame_time = Gosu.milliseconds
|
@current_frame_time = Gosu.milliseconds
|
||||||
end
|
end
|
||||||
@@ -49,6 +62,48 @@ module CyberarmEngine
|
|||||||
@show_cursor
|
@show_cursor
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def needs_redraw?
|
||||||
|
current_state ? current_state.needs_redraw? : true
|
||||||
|
end
|
||||||
|
|
||||||
|
def drop(filename)
|
||||||
|
current_state&.drop(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gamepad_connected(index)
|
||||||
|
current_state&.gamepad_connected(index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gamepad_disconnected(index)
|
||||||
|
current_state&.gamepad_disconnected(index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gain_focus
|
||||||
|
@has_focus = true
|
||||||
|
|
||||||
|
current_state&.gain_focus
|
||||||
|
end
|
||||||
|
|
||||||
|
def lose_focus
|
||||||
|
@has_focus = false
|
||||||
|
|
||||||
|
current_state&.lose_focus
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_down(id)
|
||||||
|
super
|
||||||
|
current_state&.button_down(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_up(id)
|
||||||
|
super
|
||||||
|
current_state&.button_up(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def close
|
||||||
|
current_state ? current_state.close : super
|
||||||
|
end
|
||||||
|
|
||||||
def dt
|
def dt
|
||||||
@last_frame_time / 1000.0
|
@last_frame_time / 1000.0
|
||||||
end
|
end
|
||||||
@@ -61,16 +116,6 @@ module CyberarmEngine
|
|||||||
@exit_on_opengl_error
|
@exit_on_opengl_error
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_down(id)
|
|
||||||
super
|
|
||||||
current_state.button_down(id) if current_state
|
|
||||||
end
|
|
||||||
|
|
||||||
def button_up(id)
|
|
||||||
super
|
|
||||||
current_state.button_up(id) if current_state
|
|
||||||
end
|
|
||||||
|
|
||||||
def push_state(klass, options = {})
|
def push_state(klass, options = {})
|
||||||
options = { setup: true }.merge(options)
|
options = { setup: true }.merge(options)
|
||||||
|
|
||||||
@@ -108,6 +153,10 @@ module CyberarmEngine
|
|||||||
@states.shift
|
@states.shift
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_focus?
|
||||||
|
@has_focus
|
||||||
|
end
|
||||||
|
|
||||||
# Sourced from https://gist.github.com/ippa/662583
|
# Sourced from https://gist.github.com/ippa/662583
|
||||||
def draw_circle(cx, cy, r, z = 9999, color = Gosu::Color::GREEN, step = 10)
|
def draw_circle(cx, cy, r, z = 9999, color = Gosu::Color::GREEN, step = 10)
|
||||||
0.step(360, step) do |a1|
|
0.step(360, step) do |a1|
|
||||||
|
|||||||
Reference in New Issue
Block a user