Compare commits

23 Commits

Author SHA1 Message Date
a75afaf47a Added support for UI to have background_images, fixed TextBlock text overdrawing 2022-04-25 20:12:10 -05:00
d81df5f4e2 Moved min_width/height, max_width/height and fill control from Container into Element#dimensional_size so any element can use them 2022-04-25 16:48:17 -05:00
f2ea0d9942 Maybe final container fill mode fix? 2022-04-04 13:26:40 -05:00
08d068f156 Fixed weirdness for Container dynamic fill mode 2022-04-04 10:08:39 -05:00
a4d02038c3 Fixes for Container's calculating fill size and for Flow's max_width 2022-04-03 13:06:10 -05:00
37bdd6ef23 Added support for min/max width/height and for fill which dynamically sets elements width/height to the max available width for Flow parents and height for Stack parents 2022-04-03 11:07:31 -05:00
24bd769a32 Bump version 2022-03-05 14:43:50 -06:00
2be5733bc1 Fixed Container not considering padding when clipping render area 2022-01-29 10:08:33 -06:00
c8734ae98b Container child elements that are not visible are no longer drawn 2021-12-24 17:00:02 -06:00
c35d587419 Fixed passing nil for :enabled state as boolean causing it to be set as true instead of false 2021-12-22 14:58:17 -06:00
153871e7f3 Improved performance a touch: fixed never clearing list of elements to recalculate unless a full gui recalcuate occurred, don't recalculate button/text if a full gui recalculate is requested, fixed typo: apend -> append 2021-12-16 22:09:56 -06:00
cf91d4a083 Merge branch 'master' of https://github.com/cyberarm/cyberarm_engine 2021-12-03 15:33:38 -06:00
35ad687d4c Reducce cpu usage by not using clip_to for each and every element 2021-12-03 15:33:32 -06:00
54802e1254 Added support 'marquee' style progress bars i.e. non-linear progress bar with scrolling bar 2021-12-02 08:15:39 -06:00
6cf4cd73dd Fixed toggling Element enabled state not visually shown 2021-11-18 15:37:57 -06:00
5e5f8ba7ea Added set_color and set_font to Element- fixes image elements unable to change their color when hovered, fixes hovered text changing its color incorrectly 2021-11-18 13:11:02 -06:00
63a51d9d2f Improved scroll_height calculation to adapt to how Flow's flow 2021-11-18 11:58:11 -06:00
6af384536a Fixed locking up when performing text wrapping due to text width check not being satisfied 2021-11-17 22:30:30 -06:00
c1b25d2045 Fixed centered text with unequal margins/paddings/border thicknesses being offset, fixed text wrapping using parents #width (which includes padding and margins) instead of the correct #content_width (which is only the parents content width; which the text is part of) 2021-11-17 17:23:48 -06:00
a915a25699 Updated required gems, reimplemented text wrapping to use a proper binary search and correct inserting newlines in the wrong spot for certain text lengths 2021-11-16 23:35:49 -06:00
0aa9b59316 Containers that need to be recalculated but will not affect their current size can request to have themselves directly recalculated on the next update (fixes scrolling triggering many unneed recalculations), list_box now excludes the currently selected item from the menu, probably fixed list_box callback being called twice instead of the correct once. 2021-11-15 10:17:49 -06:00
d2bf406d29 Bump version 2021-09-23 14:36:19 -05:00
f82c101728 Fixed ListBox sometimes returning self in callback instead of self.value 2021-09-23 14:35:46 -05:00
11 changed files with 321 additions and 69 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -0,0 +1,55 @@
module CyberarmEngine
class BackgroundImage
include CyberarmEngine::Common
attr_accessor :x, :y, :z, :width, :height, :mode, :color
attr_reader :image
def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :fill, color: Gosu::Color::WHITE)
@image = get_image(image_path) if image_path
@x = x
@y = y
@z = z
@width = width
@height = height
@mode = mode
@color = color
end
def image=(image_path)
@image = image_path ? get_image(image_path) : image_path
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
send(:"draw_#{mode}")
end
def draw_stretch
@image.draw(@x, @y, @z, width_scale, height_scale, @color)
end
def draw_tiled
raise NotImplementedError
end
def draw_fill
if @width * width_scale > height * height_scale
@image.draw(@x, @y, @z, width_scale, width_scale, @color)
else
@image.draw(@x, @y, @z, height_scale, height_scale, @color)
end
end
end
end

View File

@@ -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,71 @@ 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).round - send(:"noncontent_#{dimension}").round
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).round
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).round
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 +480,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 +508,26 @@ 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)
pp @style.background_image_canvas.image
@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?

View File

@@ -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

View File

@@ -45,7 +45,7 @@ module CyberarmEngine
root.gui_state.request_recalculate root.gui_state.request_recalculate
end end
def apend(&block) def append(&block)
old_container = $__current_container__ old_container = $__current_container__
$__current_container__ = self $__current_container__ = self
@@ -57,7 +57,12 @@ module CyberarmEngine
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 +108,8 @@ module CyberarmEngine
stylize stylize
# s = Gosu.milliseconds
layout layout
if is_root? if is_root?
@@ -129,8 +136,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 +151,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 +208,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 +223,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

View File

@@ -46,10 +46,18 @@ module CyberarmEngine
:handled :handled
end end
def clicked_left_mouse_button(_sender, _x, _y)
# @block&.call(self.value) if @enabled
:handled
end
def show_menu def show_menu
@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,
{ {
@@ -61,7 +69,7 @@ module CyberarmEngine
}, },
proc do proc do
self.choose = item self.choose = item
@block&.call(item) @block&.call(self.value)
end end
) )

View File

@@ -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

View File

@@ -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
@@ -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

View File

@@ -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
@@ -231,6 +236,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

View File

@@ -1,4 +1,4 @@
module CyberarmEngine module CyberarmEngine
NAME = "InDev".freeze NAME = "InDev".freeze
VERSION = "0.19.0".freeze VERSION = "0.20.0".freeze
end end