module Scrollable

Objects which include this module are supposed to be multi-line text as they have to respond to :to_s. The new functionality will allow this text to become scrollable in a terminal-window. See the scroll-functions up(), down(), left() and right().

You can have a box around the scrollable “window” by setting the attribute 'box' to true and, -as I do not care to be asked for my opinion-, you should.

Attributes

box[W]
clipped_bottom[R]
clipped_left[R]
clipped_right[R]
clipped_top[R]
fixed_cols[RW]
fixed_rows[RW]
height[R]
width[R]
xoff[R]
yoff[R]

Public Instance Methods

down() click to toggle source

scrolls

# File lib/scrollable.rb, line 111
def down
  defaults() if !@have_defaults
  # increase number of visible lines by step_y
  scroll_y(@step_y)
end
first_column() click to toggle source
# File lib/scrollable.rb, line 146
def first_column()
  defaults() if !@have_defaults
  @xoff = 0
end
first_line() click to toggle source
# File lib/scrollable.rb, line 136
def first_line()
  defaults() if !@have_defaults
  @yoff = 0
end
height=(h) click to toggle source
# File lib/scrollable.rb, line 177
def height=(h)
  @height = h if h >= 1
end
home() click to toggle source

read the code

# File lib/scrollable.rb, line 125
def home() 
  first_line
  first_column
end
last_column() click to toggle source
# File lib/scrollable.rb, line 151
def last_column()
  defaults() if !@have_defaults
  @xoff = num_columns - 1
end
last_line() click to toggle source
# File lib/scrollable.rb, line 141
def last_line()
  defaults() if !@have_defaults
  @yoff = @lines.length 
end
left() click to toggle source

scrolls

# File lib/scrollable.rb, line 93
def left()
  defaults() if !@have_defaults
  scroll_x(@step_x * -1)
end
right() click to toggle source

dto. To the right. You guessed that.

# File lib/scrollable.rb, line 99
def right()
  defaults() if !@have_defaults
  scroll_x(@step_x)
end
scroll(xoffset, yoffset) click to toggle source

scrolls

# File lib/scrollable.rb, line 118
def scroll(xoffset, yoffset)
  defaults() if !@have_defaults
  scroll_y(yoffset)
  scroll_x(xoffset)
end
scroll_x(offset) click to toggle source

guess

# File lib/scrollable.rb, line 66
def scroll_x(offset)
  defaults(self) if !@have_defaults
  if(offset != 0)
    xt = @xoff + offset
    width_x = num_columns - xt
    if(width_x > 0)
      @xoff = xt
    end
  end
  show()
end
scroll_y(offset) click to toggle source

scroll up or down by offset lines.

# File lib/scrollable.rb, line 79
def scroll_y(offset)
  defaults() if !@have_defaults
  # any offset is okay
  if(offset != 0 )
    yt = @yoff + offset
    height_y = @lines.length + yt
    if(height_y > 0)
      @yoff = yt
    end
  end
  show()
end
show() click to toggle source

does it

# File lib/scrollable.rb, line 54
def show
  defaults() if !@have_defaults
  system('clear')
  new_view = limit_lines
  if @box  
    box(new_view)
  else
    puts new_view
  end
end
step_x=(step) click to toggle source

set the size of a horizontal scroll step

# File lib/scrollable.rb, line 165
def step_x=(step)
  if step > 0
    @step_x = step
  else
    raise ScrollException.new('ERROR: scroll-steps must be positive numbers')
  end
end
step_y=(step) click to toggle source

set the size of a vertical scroll step

# File lib/scrollable.rb, line 156
def step_y=(step)
  if step > 0
    @step_y = step
  else
    raise ScrollException.new('ERROR: scroll-steps must be positive numbers')
  end
end
to_end() click to toggle source

dto.

# File lib/scrollable.rb, line 131
def to_end()
  last_column
  last_line
end
up() click to toggle source

scrolls

# File lib/scrollable.rb, line 105
def up()
  defaults() if !@have_defaults
  scroll_y(@step_y * -1 )
end
width=(w) click to toggle source
# File lib/scrollable.rb, line 173
def width=(w)
  @width = w if w >= 1
end

Private Instance Methods

box(view) click to toggle source

draw lines of color, wherever the content is clipped.

# File lib/scrollable.rb, line 265
def box(view)
  nl = "\n"
  lines = view.split(nl)

  ctl = @@box[0]
  bl = @@box[5]
  cbl = @@box[2]

  bt = @@box[4]

  ctr = @@box[1]
  br = @@box[5]
  cbr = @@box[3]

  bb = @@box[4]

  if clipped_left
    ctl = bold(blue(ctl))
    bl = bold(blue(bl))
    cbl = bold(blue(cbl))
  end
  if clipped_right
    ctr = bold(blue(ctr))
    br = bold(blue(br))
    cbr = bold(blue(cbr))
  end

  if clipped_top
    ctr = bold(blue(ctr))
    bt = bold(blue(bt))
    ctl = bold(blue(ctl))
  end

  if clipped_bottom
    cbl = bold(blue(cbl))
    cbr = bold(blue(cbr))
    bb = bold(blue(bb))
  end
  size = `stty size`.split.map { |x| x.to_i }.reverse
  @width -= 1 until (@width + 5) <= size[0]
  #@height -= 1 until (@height + 2) <=  size[1]
  puts "%s%s%s" %[ctl, bt * (@width + 3), ctr ]
  height.times {|n| puts "%s %-#{@width+1}s %s" %[bl, lines[n], br] }
  puts "%s%s%s" %[cbl, bb * (@width + 3), cbr ]
end
defaults() click to toggle source

sets a few values, needed for the rest of the module to function.

# File lib/scrollable.rb, line 229
def defaults()
  @log = @@log
  if(self.respond_to?(:to_s) )
    # @view = self
    @view = self.gsub(/\e\[\d+m/, '')

    @lines = @view.split("\n")

    @xoff = 0
    @yoff = 0

    @step_x ||= @@def_step_x
    @step_y ||= @@def_step_y

    @width ||= 60
    @height ||= 30

    @fixed_rows ||= 0
    @fixed_cols ||= 0

    @box ||= false

    @have_defaults = true 
  elsif !view
    msg = 'Need to know, what to scroll! (argument "view" missing)'
    @log.error(yellow(msg))
    raise ScrollException.new(msg)
  else
    msg = 'The "view" to scroll must have a method "to_s()"'
    @log.error(yellow(msg))
    raise ScrollException.new(msg)
  end
end
limit_lines() click to toggle source

Clip off all that cannot fit into the defined width and height. Removes probably more than needed, but in its current state, I tend to understand this method. In addition, it somehow appears to work for me…

# File lib/scrollable.rb, line 190
def limit_lines()
  # limit lines laterally
  if(@xoff < 0)
    @xoff = 0
  end
  new_view = @lines.collect do |l| 
    short = l[0...@fixed_cols].to_s + l[(@xoff + @fixed_cols)..(@width + @xoff)].to_s
  end


  # limit number of lines
  if(@yoff >= 0)
    if(@yoff > (@lines.length - @height + @fixed_rows))
      @yoff = @lines.length - @height + @fixed_rows
    end
  end

  @yoff = 0 if @yoff < 0
  new_view = new_view[0...@fixed_rows] + new_view[(@yoff + @fixed_rows)...(@height + @yoff - @fixed_rows) ]

  # describe the situation in case that someone must know..,
  if @box
    @clipped_left = @xoff > 0
    @clipped_top = @yoff > 0
    @clipped_right = num_columns - @xoff > @width
    @clipped_bottom = @lines.length - @yoff > @height
  end
  #... not, if not

  return new_view.join("\n")
end
num_columns() click to toggle source

calculates the number of columns (characters), needed.

# File lib/scrollable.rb, line 223
def num_columns
  defaults if !@have_defaults
  @lines.max {|a, b| a.length <=> b.length}.length
end