Class: Thaum::ScrollView

Inherits:
Object
  • Object
show all
Includes:
Sigil
Defined in:
lib/thaum/sigils/scroll_view.rb

Overview

A scrollable viewport over a list of pre-rendered text rows.

This is the row-list variant — apps supply an Array of String rows (one row per element) and ScrollView handles vertical + horizontal scrolling. Long rows are sliced by display columns, so wide chars (CJK, emoji) scroll cleanly.

Constant Summary collapse

WHEEL_STEP =
3

Instance Attribute Summary collapse

Attributes included from Sigil

#handler_parent, #rect, #thaum_app

Instance Method Summary collapse

Methods included from Sigil

#emit, #focusable?, #focused?, #on_blur, #on_focus, #on_mount, #on_paste, #on_tick, #on_unmount, #on_update, #request_render

Constructor Details

#initialize(rows: []) ⇒ ScrollView

Returns a new instance of ScrollView.



17
18
19
20
21
# File 'lib/thaum/sigils/scroll_view.rb', line 17

def initialize(rows: [])
  @rows     = rows
  @offset_y = 0
  @offset_x = 0
end

Instance Attribute Details

#offset_xObject (readonly)

Returns the value of attribute offset_x.



15
16
17
# File 'lib/thaum/sigils/scroll_view.rb', line 15

def offset_x
  @offset_x
end

#offset_yObject (readonly)

Returns the value of attribute offset_y.



15
16
17
# File 'lib/thaum/sigils/scroll_view.rb', line 15

def offset_y
  @offset_y
end

#rowsObject

Returns the value of attribute rows.



15
16
17
# File 'lib/thaum/sigils/scroll_view.rb', line 15

def rows
  @rows
end

Instance Method Details

#on_key(event) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/thaum/sigils/scroll_view.rb', line 30

def on_key(event)
  case event.key
  when :up        then @offset_y = [@offset_y - 1, 0].max
  when :down      then @offset_y = [@offset_y + 1, max_offset_y_estimate].min
  when :page_up   then @offset_y = [@offset_y - 10, 0].max
  when :page_down then @offset_y = [@offset_y + 10, max_offset_y_estimate].min
  when :home      then @offset_y = 0
  when :end       then @offset_y = max_offset_y_estimate
  when :left      then @offset_x = [@offset_x - 1, 0].max
  when :right     then @offset_x = [@offset_x + 1, max_x].min
  else                 emit event
  end
end

#on_mouse(event) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/thaum/sigils/scroll_view.rb', line 44

def on_mouse(event)
  case event.button
  when :wheel_up   then @offset_y = [@offset_y - WHEEL_STEP, 0].max
  when :wheel_down then @offset_y = [@offset_y + WHEEL_STEP, max_offset_y_estimate].min
  else                  emit event
  end
end

#render(canvas:, theme:) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/thaum/sigils/scroll_view.rb', line 52

def render(canvas:, theme:)
  canvas.fill(bg: theme.bg)

  # Per-canvas vertical clamp: don't scroll past the last page.
  max_offset = [rows.length - canvas.height, 0].max
  @offset_y = max_offset if @offset_y > max_offset

  canvas.height.times do |row_idx|
    file_row = @offset_y + row_idx
    text     = rows[file_row]
    break if text.nil?

    sliced = slice_by_columns(str: text, start_col: @offset_x, max_cols: canvas.width)
    canvas.row(row_idx).text(content: sliced, fg: theme.fg)
  end

  draw_indicators(canvas: canvas, theme: theme)
end