Class: Clogs::Para

Inherits:
Drawable
  • Object
show all
Defined in:
lib/clogs/drawables/text.rb

Overview

A paragraph: the only text drawable with real geometry.

Instance Attribute Summary

Attributes inherited from Drawable

#abs_x, #abs_y, #children, #height, #parent, #shoes_linkable_id, #styles, #width, #x, #y

Instance Method Summary collapse

Methods inherited from Drawable

#add_child, #app, #contains?, #destroy_self, #each_peer, #focus_gained, #focus_lost, #focusable?, for_shoes_class, #hidden?, #initialize, #margin, #needs_layout!, #notify, #on_key, #on_mouse_move, #on_release, #paint, #positioned?, #properties_changed, #redraw!, #remove_child, #requested_height, #requested_width, #set_parent, #style

Constructor Details

This class inherits a constructor from Clogs::Drawable

Instance Method Details

#alignObject



127
128
129
130
131
132
133
# File 'lib/clogs/drawables/text.rb', line 127

def align
  case style(:align).to_s
  when "center" then :center
  when "right" then :right
  else :left
  end
end

#base_styleObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/clogs/drawables/text.rb', line 112

def base_style
  size = style(:size)
  resolved = Paragraph::SIZES[size.to_s.to_sym] || (size.is_a?(Numeric) ? size.to_i : default_size)
  Paragraph::TextStyle.new(
    family: style(:family) || Clogs.default_font_family,
    size: resolved,
    bold: style(:font_weight).to_s == "bold",
    italic: %w[italic oblique].include?(style(:emphasis).to_s),
    underline: false,
    color: Style.color(style(:stroke), [0, 0, 0, 255]),
    bg: Style.color(style(:fill), nil),
    owner: self
  )
end

#clickable?Boolean

Returns:

  • (Boolean)


169
170
171
# File 'lib/clogs/drawables/text.rb', line 169

def clickable?
  true
end

#cursor_index_at(x, y) ⇒ Object



193
194
195
# File 'lib/clogs/drawables/text.rb', line 193

def cursor_index_at(x, y)
  @paragraph&.index_at(x - @abs_x, y - @abs_y) || 0
end

#default_sizeObject



108
109
110
# File 'lib/clogs/drawables/text.rb', line 108

def default_size
  Paragraph::SIZES[:para]
end

#draw(painter, x, y) ⇒ Object



143
144
145
146
147
148
# File 'lib/clogs/drawables/text.rb', line 143

def draw(painter, x, y)
  return unless @paragraph

  @paragraph.draw(painter, x, y)
  draw_text_cursor(painter, x, y)
end

#draw_text_cursor(painter, x, y) ⇒ Object

Shoes' para.cursor = n puts a caret at character n. libui's text layouts do not expose caret geometry, but Clogs lays out word by word, so the position is a lookup plus one substring measurement.



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/clogs/drawables/text.rb', line 153

def draw_text_cursor(painter, x, y)
  position = style(:text_cursor)
  return if position.nil? || ENV["CLOGS_NO_CARET"]

  item = @paragraph.placed.find do |placed|
    position >= placed.char_offset && position <= placed.char_offset + placed.text.length
  end
  item ||= @paragraph.placed.last
  return unless item

  prefix = item.text[0...(position - item.char_offset)].to_s
  cx = x + item.x + Paragraph.measure(prefix, item.style)[0]
  cy = y + item.y
  painter.line(cx, cy, cx, cy + item.height, [0, 0, 0, 255], thickness: 1)
end


184
185
186
187
188
189
190
191
# File 'lib/clogs/drawables/text.rb', line 184

def link_at(lx, ly)
  owners = @paragraph.placed.map(&:owner).uniq.select { |o| o.is_a?(Link) }
  owners.find do |owner|
    @paragraph.boxes_for(owner).any? do |bx, by, bw, bh|
      lx >= bx && lx < bx + bw && ly >= by && ly < by + bh
    end
  end
end

#measure(available_width) ⇒ Object



135
136
137
138
139
140
141
# File 'lib/clogs/drawables/text.rb', line 135

def measure(available_width)
  ml, _mt, mr, = margin
  avail = requested_width(available_width) || (available_width - ml - mr)
  @paragraph = Paragraph.new(Clogs.expand_text_items(style(:text_items), base_style), avail, align: align)
  @width = requested_width(available_width) || [@paragraph.width.ceil, avail].min
  @height = requested_height(available_width) || @paragraph.height.ceil
end

#on_click(x, y, button) ⇒ Object

Find the link (if any) under this point and fire it.



174
175
176
177
178
179
180
181
182
# File 'lib/clogs/drawables/text.rb', line 174

def on_click(x, y, button)
  return unless @paragraph

  lx = x - @abs_x
  ly = y - @abs_y
  link = link_at(lx, ly)
  link&.click!(x, y)
  _ = button
end