Class: Hokusai::Blocks::Text

Inherits:
Hokusai::Block show all
Defined in:
ui/src/hokusai/blocks/text.rb

Instance Attribute Summary collapse

Attributes inherited from Hokusai::Block

#node, #provides, #publisher

Instance Method Summary collapse

Methods inherited from Hokusai::Block

#children, #children?, compile, computed, computed!, #draw, #draw_with, #dump, #emit, #initialize, inject, inject!, #method_missing, mount, #on_resize, provide, provides, style, styles_get, template, template_from_file, template_get, #update, use, uses

Constructor Details

This class inherits a constructor from Hokusai::Block

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Hokusai::Block

Instance Attribute Details

#click_positionObject

Returns the value of attribute click_position.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def click_position
  @click_position
end

#hover_positionObject

Returns the value of attribute hover_position.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def hover_position
  @hover_position
end

#last_char_indexObject

Returns the value of attribute last_char_index.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def last_char_index
  @last_char_index
end

#last_clampingObject

Returns the value of attribute last_clamping.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def last_clamping
  @last_clamping
end

#last_contentObject

Returns the value of attribute last_content.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def last_content
  @last_content
end

#last_cursor_offsetObject

Returns the value of attribute last_cursor_offset.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def last_cursor_offset
  @last_cursor_offset
end

#last_heightObject

Returns the value of attribute last_height.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def last_height
  @last_height
end

#last_widthObject

Returns the value of attribute last_width.



32
33
34
# File 'ui/src/hokusai/blocks/text.rb', line 32

def last_width
  @last_width
end

Instance Method Details

#after_updatedObject



184
185
186
# File 'ui/src/hokusai/blocks/text.rb', line 184

def after_updated
  node.meta.set_prop(:height, last_height)
end

#clamp(text, width) ⇒ Object



188
189
190
191
192
193
194
195
# File 'ui/src/hokusai/blocks/text.rb', line 188

def clamp(text, width)
  if markdown
    clamping = Hokusai.fonts.active.clamp_markdown(text, size.to_i, width - size.to_f - padding.right)
    clamping
  else
    Hokusai.fonts.active.clamp(text, size.to_i, width - size.to_f, padding.right)
  end
end

#clear_click_position(_) ⇒ Object



54
55
56
# File 'ui/src/hokusai/blocks/text.rb', line 54

def clear_click_position(_)
  self.click_position = nil
end

#internal_render(clamping, canvas) ⇒ Object



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
92
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'ui/src/hokusai/blocks/text.rb', line 58

def internal_render(clamping, canvas)
  iterator = Hokusai::Util::ClampingIterator.new(clamping, canvas.x + padding.left, canvas.y + padding.top)
  boundary = panel_height || canvas.y + canvas.height
  offset_y = panel_offset || 0.0

  boundary += panel_top if panel_top
  hovered = false
  link_hovered = false

  draw_with do |commands|
    iterator.on_draw do |text, x, y, group|
      if selector = selection
        if cursor_offset&.zero? && !selector.started
          selector.cursor = [x, y + offset_y, 0.0, size.to_f]

          self.last_cursor_offset = cursor_offset
        end
      end

      if hover_position
        cx, cy = hover_position

        if cx > x && cx <= x + group.width && cy > y && cy <= y + size && y > (panel_top || 0.0)
          hovered = true
        end
      end


      commands.text(text, x, y) do |command|
        command.color = color
        command.size = size
        command.font = font unless font.nil?

        if group.respond_to?(:bold?)
          
          unless group.normal?
            command.bold = group.bold?
            command.italic = group.italics?

            if group.link? && hovered
              cx, cy = hover_position

              if cx > x && cx <= x + group.width && cy > y && cy <= y + size
                link_hovered = true
              end
            end

            if group.link? && click_position
              cx, cy = click_position

              if cx > x && cx <= x + group.width && cy > y && cy <= y + size && cy > (panel_top || 0)
                # that's a click
                case RbConfig::CONFIG['host_os']
                when /darwin/
                  system("open #{group.link}")
                when /linux/
                  system("xdg-open #{group.link}")
                end

                self.click_position = nil
              end
            end

            command.color = Hokusai::Color.new(50, 110, 188) if group.link?
          end
        end
      end
    end

    iterator.on_draw_selection do |x, y, width, height|
      # commands.rect(x, y, width, height) do |command|
      #   command.color = selection_color
      # end
    end

    iterator.on_selection_change do |start, stop|
      emit("selected", start, stop)
    end

    iterator.on_cursor_change do |x, y, w, h|
      selection.cursor = [x, y + offset_y, w, h] if selection
    end

    iterator.on_char do |char, hitbox, offset|
      unless selection.nil?
        if cursor_offset && offset == cursor_offset - 1 && (last_cursor_offset != cursor_offset || last_content != content)
          selection.cursor = [hitbox.move_x_right(2), hitbox.y + offset_y, hitbox.width, hitbox.height]

          self.last_cursor_offset = cursor_offset
        end

        unless click_position.nil?
          click_x, click_y = click_position

          rect = Hokusai::Rect.new(hitbox.move_x_right, hitbox.y, hitbox.width, hitbox.height)

          if rect.includes_x?(click_x) && hitbox.includes_y?(click_y)
            selection.cursor = [hitbox.move_x_right(2), hitbox.y + offset_y, hitbox.width, hitbox.height]

            if offset + 1 != last_cursor_offset
              emit("select_offset", offset + 1)
              self.last_cursor_offset = offset + 1
            end

            self.click_position = nil
          end
        end
      end
    end

    while segment = iterator.next
      segment.draw(size, [canvas.y, boundary], selection: selection)
    end
  end

  if link_hovered
    Hokusai.set_mouse_cursor(:pointer)
  elsif hovered
    Hokusai.set_mouse_cursor(:ibeam)
  elsif hover_position
    Hokusai.set_mouse_cursor(:default)
  end

  iterator.height
end

#render(canvas) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'ui/src/hokusai/blocks/text.rb', line 197

def render(canvas)
  if Hokusai.can_render(canvas)
    unless last_content == content && last_width == canvas.width
      # self.last_clamping&.free
      self.last_clamping = clamp(content, canvas.width - (padding.left + padding.right))
      self.last_width = canvas.width
      self.last_content = content
    end

    height = internal_render(last_clamping, canvas)
    self.last_content = last_content
    
    new_height = height + padding.bottom + padding.top
    new_height -= size if markdown

    emit("height_updated", new_height) unless last_height == new_height

    self.last_height = new_height

    yield canvas
  end
end

#set_click_position(event) ⇒ Object



50
51
52
# File 'ui/src/hokusai/blocks/text.rb', line 50

def set_click_position(event)
  self.click_position = [event.pos.x, event.pos.y]
end

#set_hover_position(event) ⇒ Object



36
37
38
# File 'ui/src/hokusai/blocks/text.rb', line 36

def set_hover_position(event)
  self.hover_position = [event.pos.x, event.pos.y]
end

#unset_hover_position(event) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'ui/src/hokusai/blocks/text.rb', line 40

def unset_hover_position(event)
  if !event.state.set
    Hokusai.set_mouse_cursor(:default)

    event.state.set = true
  end

  self.hover_position = nil
end