Class: CyberarmEngine::Element::TextBlock

Inherits:
CyberarmEngine::Element show all
Defined in:
lib/cyberarm_engine/ui/elements/text_block.rb

Direct Known Subclasses

Banner, Button, Caption, Inscription, Link, Para, Subtitle, Tagline, Title, ToolTip

Constant Summary

Constants included from Theme

Theme::THEME

Instance Attribute Summary

Attributes inherited from CyberarmEngine::Element

#background_canvas, #border_canvas, #element_visible, #event_handler, #options, #parent, #style, #tip, #x, #y, #z

Instance Method Summary collapse

Methods inherited from CyberarmEngine::Element

#background=, #background_image=, #background_nine_slice=, #blur, #button_down, #button_up, #child_of?, #clicked_left_mouse_button, #content_height, #content_width, #debug_draw, #default_events, #dimensional_size, #draggable?, #draw, #element_visible?, #enabled=, #enabled?, #enter, #focus, #focused?, #height, #hide, #hit?, #inner_height, #inner_width, #inspect, #is_root?, #leave, #left_mouse_button, #max_scroll_height, #max_scroll_width, #noncontent_height, #noncontent_width, #outer_height, #outer_width, #parent_of?, #recalculate, #recalculate_if_size_changed, #released_left_mouse_button, #reposition, #root, #safe_style_fetch, #scroll_height, #scroll_width, #set_background, #set_background_image, #set_background_nine_slice, #set_border_color, #set_border_thickness, #set_color, #set_font, #set_margin, #set_padding, #set_static_position, #show, #space_available_height, #space_available_width, #stylize, #to_s, #toggle, #update_background, #update_background_image, #update_background_nine_slice, #update_styles, #visible?, #width

Methods included from Common

#alt_down?, #control_down?, #current_state, #darken, #draw_rect, #fill, #find_element_by_tag, #get_asset, #get_image, #get_sample, #get_song, #lighten, #opacity, #pop_state, #previous_state, #push_state, #shift_down?, #shift_state, #show_cursor, #show_cursor=, #window

Methods included from CyberarmEngine::Event

#event, #publish, #subscribe, #unsubscribe

Methods included from Theme

#deep_merge, #default, #theme_defaults

Constructor Details

#initialize(text, options = {}, block = nil) ⇒ TextBlock

Returns a new instance of TextBlock.



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 4

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],
          static: @options[:text_static],
          shadow_size: @options[:text_shadow_size],
          shadow_color: @options[:text_shadow_color],
          border: @options[:text_border],
          border_size: @options[:text_border_size],
          border_color: @options[:text_border_color]
  )

  @raw_text = text
end

Instance Method Details

#handle_text_wrapping(max_width) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 93

def handle_text_wrapping(max_width)
  max_width ||= @parent&.content_width
  max_width ||= @x - (window.width + noncontent_width)
  wrap_behavior = style.text_wrap
  copy = @raw_text.to_s.dup

  # Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
  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_end = copy.length

    stalled = false
    stalled_interations = 0
    max_stalled_iterations = 10
    checked_copy_length = line_width(copy[line_start..line_end])

    # find length of lines
    while line_width(copy[line_start..line_end]) > max_width && stalled_interations < max_stalled_iterations
      search_start = line_start
      search_end = line_end

      # Perform a binary search to find length of line
      while search_start < search_end
        midpoint = ((search_start.to_f + search_end) / 2.0).floor

        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

        line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
      else
        line_start = search_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

    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

#layoutObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 41

def layout
  unless @enabled
    @text.color = @style.disabled[:color]
  else
    @text.color = @style.color
  end

  @width  = 0
  @height = 0

  _width  = dimensional_size(@style.width,  :width)
  _height = dimensional_size(@style.height, :height)

  handle_text_wrapping(_width)

  @width  = _width  || @text.width.floor
  @height = _height || @text.height.floor

  @text.y = @style.border_thickness_top + @style.padding_top + @y
  @text.z = @z + 3

  if (text_alignment = @options[:text_align] || @options[:text_h_align])
    case text_alignment
    when :left
      @text.x = @style.border_thickness_left + @style.padding_left + @x
    when :center
      @text.x = if @text.width <= width
                  @x + 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

  if (vertical_alignment = @options[:text_v_align])
    case vertical_alignment
    when :center
      @text.y = if @text.height <= height
                  @y + height / 2 - @text.height / 2
                else
                  @style.border_thickness_top + @style.padding_top + @y
                end
    when :bottom
      @text.y = @y + outer_height - (@text.height + @style.border_thickness_bottom + @style.padding_bottom)
    end
  end

  update_background
end

#line_width(text) ⇒ Object



162
163
164
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 162

def line_width(text)
  (@text.textobject.markup_width(text.to_s) + noncontent_width)
end

#renderObject



30
31
32
33
34
35
36
37
38
39
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 30

def render
  # 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

#updateObject



21
22
23
24
25
26
27
28
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 21

def update
  super

  if @text.textobject.name != safe_style_fetch(:font)
    set_font
    root.gui_state.request_recalculate
  end
end

#valueObject



166
167
168
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 166

def value
  @raw_text
end

#value=(value) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/cyberarm_engine/ui/elements/text_block.rb', line 170

def value=(value)
  old_value = @raw_text
  @raw_text = value.to_s.chomp

  old_width = width
  old_height = height

  if old_width != width || old_height != height
    root.gui_state.request_recalculate
  else
    recalculate
  end

  root.gui_state.request_repaint if old_value != @raw_text

  publish(:changed, self.value)
end