lib/ruco/window.rb in ruco-0.0.40 vs lib/ruco/window.rb in ruco-0.0.41
- old
+ new
@@ -1,35 +1,56 @@
module Ruco
class Window
OFFSET = 5
- attr_accessor :position, :lines, :columns, :top, :left
- attr_reader :cursor
+ attr_accessor :lines, :columns, :left
+ attr_reader :cursor, :top
- def initialize(lines, columns)
+ def initialize(lines, columns, options={})
+ @options = options
+
+ @options[:line_scroll_threshold] ||= 1
+ @options[:line_scroll_offset] ||= 1
+ @options[:column_scroll_threshold] ||= 1
+ @options[:column_scroll_offset] ||= 5
+
@lines = lines
@columns = columns
@top = 0
@left = 0
@cursor = Position.new(0,0)
end
- def crop(content)
- lines = content[visible_lines] || []
- lines[@lines-1] ||= nil
- lines.map do |line|
+ def position=(x)
+ set_position(x)
+ end
+
+ def set_position(position, options={})
+ scroll_line_into_view position.line, (options[:max_lines] || 9999)
+ scroll_column_into_view position.column
+ @cursor = Position.new(position.line - @top, position.column - @left)
+ end
+
+ def crop(lines)
+ lines_to_display = lines[visible_lines] || []
+ lines_to_display[@lines-1] ||= nil
+ lines_to_display.map do |line|
line ||= ''
line[visible_columns] || ''
end
end
- def position=(pos)
- self.top = pos.line - line_offset unless visible_lines.include?(pos.line)
- self.left = pos.column - column_offset unless visible_columns.include?(pos.column)
- @cursor = Position.new(pos.line - @top, pos.column - @left)
+ def scroll_line_into_view(line, total_lines)
+ result = adjustment(line, visible_lines, @options[:line_scroll_threshold], @options[:line_scroll_offset])
+ set_top result, total_lines if result
end
+ def scroll_column_into_view(column)
+ result = adjustment(column, visible_columns, @options[:column_scroll_threshold], @options[:column_scroll_offset])
+ self.left = result if result
+ end
+
def color_mask(selection)
mask = Array.new(lines)
return mask unless selection
mask.map_with_index do |_,line|
@@ -44,33 +65,35 @@
[last[1]-left, Curses::A_NORMAL]
]
end
end
- def top=(x)
- @top = [x,0].max
- end
-
def left=(x)
@left = [x,0].max
end
+ def set_top(line, total_lines)
+ max_top = total_lines - lines + 1 + @options[:line_scroll_offset]
+ @top = [[line, max_top].min, 0].max
+ end
+
private
+ def adjustment(current, allowed, threshold, offset)
+ if current < (allowed.first + threshold)
+ current - offset
+ elsif current > (allowed.last - threshold)
+ size = allowed.last - allowed.first + 1
+ current - size + 1 + offset
+ end
+ end
+
def visible_area(line)
line += @top
start_of_line = [line, @left]
last_visible_column = @left + @columns
end_of_line = [line, last_visible_column]
start_of_line..end_of_line
- end
-
- def line_offset
- @lines / 2
- end
-
- def column_offset
- @columns / 2
end
def visible_lines
@top..(@top+@lines-1)
end
\ No newline at end of file