lib/cyberarm_engine/ui/elements/label.rb in cyberarm_engine-0.14.0 vs lib/cyberarm_engine/ui/elements/label.rb in cyberarm_engine-0.15.0

- old
+ new

@@ -2,51 +2,130 @@ class Element class Label < Element def initialize(text, options = {}, block = nil) super(options, block) - @text = Text.new(text, font: @options[:font], z: @z, color: @options[:color], size: @options[:text_size], shadow: @options[:text_shadow]) + @text = Text.new( + text, font: @options[:font], z: @z, color: @options[:color], + size: @options[:text_size], shadow: @options[:text_shadow], + shadow_size: @options[:text_shadow_size], + shadow_color: @options[:text_shadow_color] + ) + + @raw_text = text end def render @text.draw end - def clicked_left_mouse_button(sender, x, y) - @block.call(self) if @block + def clicked_left_mouse_button(_sender, _x, _y) + @block&.call(self) # return :handled end def recalculate - @width, @height = 0, 0 + @width = 0 + @height = 0 - _width = dimensional_size(@style.width, :width) - _height= dimensional_size(@style.height,:height) + _width = dimensional_size(@style.width, :width) + _height = dimensional_size(@style.height, :height) - @width = _width ? _width : @text.width.round - @height= _height ? _height : @text.height.round + handle_text_wrapping(_width) - @text.x = @style.border_thickness_left + @style.padding_left + @x - @text.y = @style.border_thickness_top + @style.padding_top + @y + @width = _width || @text.width.round + @height = _height || @text.height.round + + @text.y = @style.border_thickness_top + @style.padding_top + @y @text.z = @z + 3 + if (text_alignment = @options[:text_align]) + case text_alignment + when :left + @text.x = @style.border_thickness_left + @style.padding_left + @x + when :center + @text.x = if @text.width <= outer_width + @x + outer_width / 2 - @text.width / 2 + else # Act as left aligned + @style.border_thickness_left + @style.padding_left + @x + end + when :right + @text.x = @x + outer_width - (@text.width + @style.border_thickness_right + @style.padding_right) + end + end + update_background end + def handle_text_wrapping(max_width) + max_width ||= @parent&.width + max_width ||= @x - (window.width + noncontent_width) + wrap_behavior = style.text_wrap + copy = @raw_text.to_s.dup + + if max_width >= line_width(copy[0]) && line_width(copy) > max_width && wrap_behavior != :none + breaks = [] + line_start = 0 + line_end = copy.length + + while line_start != copy.length + if line_width(copy[line_start...line_end]) > max_width + line_end = ((line_end - line_start) / 2.0) + 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! + entering_line_end = line_end.floor + max_reach = line_end.floor - line_start < 63 ? line_end.floor - line_start : 63 + reach = 0 + + if wrap_behavior == :word_wrap + max_reach.times do |i| + reach = i + break if copy[line_end.floor - i].to_s.match(/[[:punct:]]| /) + 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 + + breaks << line_end.floor + line_start = line_end.floor + line_end = copy.length + + break if entering_line_end == copy.length || reach == max_reach + end + end + + breaks.each_with_index do |pos, index| + copy.insert(pos + index, "\n") if pos + index >= 0 && pos + index < copy.length + end + end + + @text.text = copy + end + + def line_width(text) + (@x + @text.textobject.markup_width(text) + noncontent_width) + end + def value - @text.text + @raw_text end def value=(value) - @text.text = value + @raw_text = value.to_s.chomp - old_width, old_height = width, height + old_width = width + old_height = height recalculate root.gui_state.request_recalculate if old_width != width || old_height != height publish(:changed, self.value) end end end -end \ No newline at end of file +end