Code Coverage
 
Lines
Covered
98.67% covered (success)
98.67%
148 / 150
# require 'pry'
1
module TheFox
1
module TermKit
##
# View sub-class.
#
# Provides functionalities to show data in a scrollable table.
1
class TableView < View
1
attr_reader :header
1
attr_reader :header_height
# attr_reader :table
1
attr_reader :data
1
attr_reader :cells
1
attr_reader :cells_height_total
1
attr_accessor :highlighted_cell
1
attr_reader :cursor_position
1
attr_reader :cursor_position_old
1
attr_reader :cursor_direction
1
attr_reader :page_begin
1
attr_reader :page_end
1
attr_reader :page_height
1
attr_reader :page_direction
1
def initialize(name = nil)
# puts "TableView initialize '#{name.inspect}'"
30
super(name)
30
@header = nil
30
@header_height = 0
30
@data = []
30
@cells = []
30
@cells_height_total = 0
30
@highlighted_cell = nil
30
@cursor_position = 0
30
@cursor_position_old = 0
30
@cursor_direction = 0
30
@page_begin = 0
30
@page_end = 0
30
@page_height = 0
30
@page_direction = 0
30
@page_range = nil
30
@needs_refresh = true
30
@table = View.new("#{@name}_table")
30
@table.is_visible = true
30
add_subview(@table)
end
1
def size=(size)
27
super(size)
27
@needs_refresh = true
27
calc_page_height
27
calc_cursor
27
calc_page
end
1
def header=(header)
19
unless header.is_a?(View)
1
raise ArgumentError, "Argument is not a View -- #{header.class} given"
end
18
unless @header.nil?
5
remove_subview(@header)
end
18
@header = header
18
unless header.nil?
18
@header_height = @header.height
18
add_subview(@header)
end
18
@table.position = Point.new(0, @header_height)
18
@needs_refresh = true
18
calc_page_height
end
1
def remove_header
5
@header = nil
5
@header_height = 0
5
@table.position = Point.new(0, @header_height)
5
@needs_refresh = true
5
calc_page_height
end
1
def data=(data)
36
if !data.is_a?(Array)
1
raise ArgumentError, "Argument is not a Array -- #{data.class} given"
end
35
@data = data
35
@cells = []
35
cell_n = 0
35
y_pos = 0
35
@data.each do |row|
145
cell = nil
145
row_name = "row_#{cell_n}"
145
case row
when String
143
text_view = TextView.new(row, "text_#{row_name}")
143
text_view.is_visible = true
# text_view.text = row
143
cell = CellTableView.new(text_view, "cell_#{row_name}")
when CellTableView
1
cell = row
else
1
raise NotImplementedError, "Class '#{row.class}' not implemented yet"
end
144
@cells.push(cell)
#cell.is_visible = false
144
cell.is_visible = true
#cell.position = Point.new(0, y_pos)
#@table.add_subview(cell)
144
y_pos += cell.height
144
cell_n += 1
end
34
@cells_height_total = y_pos
34
@needs_refresh = true
34
calc_page_height
34
calc_cursor
34
calc_page
end
1
def cursor_position=(cursor_position)
56
@cursor_position_old = @cursor_position
56
@cursor_position = cursor_position
56
@needs_refresh = true
56
calc_cursor
56
calc_page
end
1
def cursor_up
0
self.cursor_position = @cursor_position - 1
end
1
def cursor_down
0
self.cursor_position = @cursor_position + 1
end
1
def is_cursor_at_bottom?
6
@cursor_position == @cells_height_total - 1
end
1
def render(area = nil)
24
puts "#{@name} -- render r?=#{@needs_refresh ? 'Y' : 'N'}"
24
if @needs_refresh
24
refresh
end
24
super(area)
end
1
def refresh
24
new_page_range = Range.new(@page_begin, @page_end)
24
affected_cells = @cells[new_page_range]
24
y_pos = 0
24
cell_n = 0
24
affected_cells.each do |cell|
69
highlighted = @cursor_position == (cell_n + @page_begin)
# puts "#{@name} -- [+] #{cell} n=#{cell_n} y=#{y_pos} h=#{highlighted ? 'Y' : 'N'}/#{cell.highlighted ? 'Y' : 'N'}"
69
cell.highlighted = highlighted
69
if highlighted
24
@highlighted_cell = cell
end
# cell.size = Size.new(@size.width, nil)
# puts "#{@name} -- [+] #{cell} y=#{y_pos} position"
69
cell.position = Point.new(0, y_pos)
69
unless @table.is_subview?(cell)
# puts "#{@name} -- [+] #{cell} y=#{y_pos} add_subview"
38
@table.add_subview(cell)
end
# puts "#{@name} -- [+] #{cell} y=#{y_pos} END"
69
y_pos += cell.height
69
cell_n += 1
end
# Hide out-of-scope cell(s) here. In the best case it's only ONE cell that will
# be hidden. If you scroll down the top cell will be hidden, if you scroll up
# only the bottom cell will be hidden.
75
(@cells - affected_cells).select{ |cell| cell.is_visible? }.each do |cell|
# puts "#{@name} -- [-] #{cell} y=#{cell.position.y} r?=#{cell.needs_rendering? ? 'Y' : 'N'}"
51
@table.remove_subview(cell)
end
24
@page_range = new_page_range
24
@needs_refresh = false
end
1
private
1
def calc_page_height
# puts "calc_page_height"
84
if @size.nil? || @size.height.nil?
# puts "calc_page_height size is nil"
11
@page_height = @cells_height_total
# puts "#{@name} -- calc_page_height A #{@page_height}"
else
73
@page_height = @size.height - @header_height
# puts "#{@name} -- calc_page_height B #{@page_height} = #{@size.height} - #{@header_height}"
end
end
1
def calc_cursor
# puts "calc_cursor @cursor_position '#{@cursor_position}' '#{@cells_height_total}'"
117
if @cursor_position > @cells_height_total - 1
31
@cursor_position = @cells_height_total - 1
# puts "#{@name} -- calc_cursor A #{@cursor_position}"
end
117
if @cursor_position < 0
24
@cursor_position = 0
# puts "#{@name} -- calc_cursor B #{@cursor_position}"
end
# -1 up
# 0 unchanged
# +1 down
117
if @cursor_position == @cursor_position_old
58
@cursor_direction = 0
59
elsif @cursor_position > @cursor_position_old
44
@cursor_direction = 1
else
15
@cursor_direction = -1
end
# puts "cursor n='#{@cursor_position}' o='#{@cursor_position_old}' d='#{cursor_direction}'"
end
1
def calc_page
# -1 up
# 0 unchanged
# +1 down
117
if @cursor_position > @page_end
19
@page_direction = 1
elsif @cursor_position < @page_begin
5
@page_direction = -1
else
93
@page_direction = 0
end
117
if @page_direction == 1
19
@page_begin = @cursor_position - @page_height + 1
# puts "#{@name} -- calc_page page_begin A #{page_begin} = #{@cursor_position} - #{@page_height} + 1"
elsif @page_direction == -1
5
@page_begin = @cursor_position
# puts "#{@name} -- calc_page page_begin B #{page_begin}"
end
117
page_begin_max = @cells_height_total - @page_height
117
if page_begin_max < 0
28
page_begin_max = 0
end
117
if @page_begin > page_begin_max
3
@page_begin = page_begin_max
# puts "#{@name} -- calc_page page_begin C #{page_begin}"
end
117
@page_end = @page_begin + @page_height - 1
# puts "#{@name} -- calc_page b=#{@page_begin} e=#{@page_end} h=#{@page_height} d=#{@page_direction}"
end
end
end
end