Class: RubyRich::Viewport

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

Constant Summary collapse

DRAG_MODES =

drag_mode controls what left-click drag does in the content area:

:viewport  – drag scrolls the viewport (default, backward-compatible)
:selection – drag selects text
[:viewport, :selection].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Viewport.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ruby_rich/viewport.rb', line 15

def initialize(content = "",
               scrollbar: true, auto_scroll: false,
               scrollbar_style: :blue, auto_copy: true,
               drag_mode: :viewport)
  @content = content
  @scrollbar = scrollbar
  @auto_scroll = auto_scroll
  @scrollbar_style = scrollbar_style
  @width = 0
  @height = 0
  @scroll_top = 0
  @dragging_scrollbar = false
  @dragging_viewport = false
  @drag_start_y = nil
  @drag_start_scroll_top = nil
  @selecting = false
  @selection_start = nil
  @selection_end = nil
  @selected_text = ""
  @focused = true
  @auto_copy = auto_copy
  @drag_mode = DRAG_MODES.include?(drag_mode) ? drag_mode : :viewport
  @rendered_lines_cache_key = nil
  @rendered_lines_cache = nil
end

Instance Attribute Details

#contentObject

Returns the value of attribute content.



8
9
10
# File 'lib/ruby_rich/viewport.rb', line 8

def content
  @content
end

#heightObject

Returns the value of attribute height.



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

def height
  @height
end

#scroll_topObject

Returns the value of attribute scroll_top.



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

def scroll_top
  @scroll_top
end

#selected_textObject (readonly)

Returns the value of attribute selected_text.



8
9
10
# File 'lib/ruby_rich/viewport.rb', line 8

def selected_text
  @selected_text
end

#widthObject

Returns the value of attribute width.



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

def width
  @width
end

Instance Method Details

#at_bottom?Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/ruby_rich/viewport.rb', line 151

def at_bottom?
  @scroll_top >= max_scroll_top
end

#attach(layout, priority: 100) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ruby_rich/viewport.rb', line 59

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



46
47
48
49
# File 'lib/ruby_rich/viewport.rb', line 46

def blur
  @focused = false
  self
end

#focusObject



41
42
43
44
# File 'lib/ruby_rich/viewport.rb', line 41

def focus
  @focused = true
  self
end

#handle_event(event_data, layout = nil) ⇒ Object



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

def handle_event(event_data, layout = nil)
  return false if keyboard_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
    if @drag_mode == :selection
      start_scrollbar_drag(event_data, layout) || start_selection(event_data, layout)
    else
      start_scrollbar_drag(event_data, layout) || start_viewport_drag(event_data, layout)
    end
  when :mouse_drag
    drag_scrollbar(event_data, layout) ||
      (@drag_mode == :selection ? drag_selection(event_data, layout) : (drag_viewport(event_data, layout) || drag_selection(event_data, layout)))
  when :mouse_up
    stop_scrollbar_drag || stop_viewport_drag || stop_selection
  else
    false
  end
end

#max_scroll_topObject



155
156
157
# File 'lib/ruby_rich/viewport.rb', line 155

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

#renderObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/ruby_rich/viewport.rb', line 118

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



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

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

#scroll_to(line) ⇒ Object



141
142
143
144
# File 'lib/ruby_rich/viewport.rb', line 141

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

#scroll_to_bottomObject



146
147
148
149
# File 'lib/ruby_rich/viewport.rb', line 146

def scroll_to_bottom
  @scroll_top = max_scroll_top
  clamp_scroll
end