Class: RubyRich::Viewport

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_rich/viewport.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content = "", scrollbar: true, auto_scroll: false, scrollbar_style: :blue) ⇒ Viewport

Returns a new instance of Viewport.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/ruby_rich/viewport.rb', line 8

def initialize(content = "", scrollbar: true, auto_scroll: false, scrollbar_style: :blue)
  @content = content
  @scrollbar = scrollbar
  @auto_scroll = auto_scroll
  @scrollbar_style = scrollbar_style
  @width = 0
  @height = 0
  @scroll_top = 0
  @dragging_scrollbar = false
  @drag_start_y = nil
  @drag_start_scroll_top = nil
  @selecting = false
  @selection_start = nil
  @selection_end = nil
  @selected_text = ""
  @focused = true
end

Instance Attribute Details

#contentObject

Returns the value of attribute content.



6
7
8
# File 'lib/ruby_rich/viewport.rb', line 6

def content
  @content
end

#heightObject

Returns the value of attribute height.



5
6
7
# File 'lib/ruby_rich/viewport.rb', line 5

def height
  @height
end

#scroll_topObject

Returns the value of attribute scroll_top.



5
6
7
# File 'lib/ruby_rich/viewport.rb', line 5

def scroll_top
  @scroll_top
end

#selected_textObject (readonly)

Returns the value of attribute selected_text.



6
7
8
# File 'lib/ruby_rich/viewport.rb', line 6

def selected_text
  @selected_text
end

#widthObject

Returns the value of attribute width.



5
6
7
# File 'lib/ruby_rich/viewport.rb', line 5

def width
  @width
end

Instance Method Details

#at_bottom?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'lib/ruby_rich/viewport.rb', line 132

def at_bottom?
  @scroll_top >= max_scroll_top
end

#attach(layout, priority: 100) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ruby_rich/viewport.rb', line 43

def attach(layout, priority: 100)
  [:page_up, :page_down, :home, :end, :up, :down].each do |event_name|
    layout.key(event_name, priority) do |event_data, _live|
      handle_event(event_data, layout)
      false
    end
  end

  [:mouse_wheel, :mouse_down, :mouse_drag, :mouse_up].each do |event_name|
    layout.key(event_name, priority) do |event_data, _live|
      handle_event(event_data, layout)
    end
  end

  self
end

#blurObject



31
32
33
34
# File 'lib/ruby_rich/viewport.rb', line 31

def blur
  @focused = false
  self
end

#focusObject



26
27
28
29
# File 'lib/ruby_rich/viewport.rb', line 26

def focus
  @focused = true
  self
end

#handle_event(event_data, layout = nil) ⇒ Object



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
# File 'lib/ruby_rich/viewport.rb', line 60

def handle_event(event_data, layout = nil)
  return false if keyboard_event?(event_data) && !@focused
  return false if mouse_event?(event_data) && !@focused

  case event_data[:name]
  when :page_up
    scroll_by(-page_size)
    false
  when :page_down
    scroll_by(page_size)
    false
  when :home
    scroll_to(0)
    false
  when :end
    scroll_to_bottom
    false
  when :up
    scroll_by(-1)
    false
  when :down
    scroll_by(1)
    false
  when :mouse_wheel
    scroll_by(event_data[:direction] == :down ? 3 : -3)
    true
  when :mouse_down
    return copy_selection if event_data[:button] == :right

    start_scrollbar_drag(event_data, layout) || start_selection(event_data, layout)
  when :mouse_drag
    drag_scrollbar(event_data, layout) || drag_selection(event_data, layout)
  when :mouse_up
    stop_scrollbar_drag || stop_selection
  else
    false
  end
end

#max_scroll_topObject



136
137
138
# File 'lib/ruby_rich/viewport.rb', line 136

def max_scroll_top
  [rendered_lines.length - @height, 0].max
end

#renderObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ruby_rich/viewport.rb', line 99

def render
  clamp_scroll
  return [] if @height.to_i <= 0 || @width.to_i <= 0

  visible_width = content_width
  visible = rendered_lines[@scroll_top, @height] || []
  lines = Array.new(@height) { "" }

  @height.times do |index|
    absolute_line = @scroll_top + index
    lines[index] = apply_selection(fit_line(visible[index].to_s, visible_width), absolute_line)
  end

  return lines unless show_scrollbar?

  scrollbar = render_scrollbar
  lines.each_with_index.map { |line, index| line + scrollbar[index] }
end

#scroll_by(delta) ⇒ Object



118
119
120
# File 'lib/ruby_rich/viewport.rb', line 118

def scroll_by(delta)
  scroll_to(@scroll_top + delta)
end

#scroll_to(line) ⇒ Object



122
123
124
125
# File 'lib/ruby_rich/viewport.rb', line 122

def scroll_to(line)
  @scroll_top = line.to_i
  clamp_scroll
end

#scroll_to_bottomObject



127
128
129
130
# File 'lib/ruby_rich/viewport.rb', line 127

def scroll_to_bottom
  @scroll_top = max_scroll_top
  clamp_scroll
end