class Sibori

\ |

\      | <--- whipped cream
 \     |
  \    |
   \-~~|
    \  | <--- shibori kutigane (piping nozzle in Japanese)
     \Ml
      (\    __ __
      ( \--(  )  )
       (__(__)__)  <--- compressed whipped cream

Attributes

output[W]

Public Class Methods

new(width, height, cursor_pos) click to toggle source
# File lib/reline/sibori.rb, line 20
def initialize(width, height, cursor_pos)
  @width = width
  @height = height
  @cursor_pos = cursor_pos
  @screen = [String.new]
  @line_index = 0
  @byte_pointer_in_line = 0
  @cleared = false
  clone_screen
end

Public Instance Methods

clear_screen() click to toggle source
# File lib/reline/sibori.rb, line 107
def clear_screen
  #$stderr.puts "clear_screen"
  @screen = [String.new]
  @line_index = 0
  @byte_pointer_in_line = 0
  @cursor_pos.x = @cursor_pos.y = 0
  @cleared = true
  Reline::IOGate.clear_screen
end
clone_screen() click to toggle source
# File lib/reline/sibori.rb, line 31
def clone_screen
  @prev_screen = @screen.map { |line|
    line.dup
  }
  @prev_cursor_pos = @cursor_pos.dup
  @prev_line_index = @line_index
end
deprep() click to toggle source
# File lib/reline/sibori.rb, line 167
def deprep
  Reline::IOGate.deprep
end
erase_after_cursor() click to toggle source
# File lib/reline/sibori.rb, line 102
def erase_after_cursor
  #$stderr.puts "erase_after_cursor"
  @screen[@line_index] = @screen[@line_index].byteslice(0, @byte_pointer_in_line)
end
move_cursor_column(col) click to toggle source
# File lib/reline/sibori.rb, line 56
def move_cursor_column(col)
  #$stderr.puts "move_cursor_column(#{col})"
  @byte_pointer_in_line = width_to_bytesize(@screen[@line_index], col)
  @cursor_pos.x = col
end
move_cursor_down(val) click to toggle source
# File lib/reline/sibori.rb, line 71
def move_cursor_down(val)
  #$stderr.puts "move_cursor_down(#{val})"
  if @line_index < @height - 1
    #$stderr.puts "@line_index #{@line_index}  @screen.size #{@screen.size}  @height #{@height}"
    #$stderr.puts @screen.inspect
    @line_index += val
    @screen[@line_index] = String.new if @line_index == @screen.size
    @byte_pointer_in_line = width_to_bytesize(@screen[@line_index], @cursor_pos.x)
    @cursor_pos.y += val
  end
end
move_cursor_up(val) click to toggle source
# File lib/reline/sibori.rb, line 62
def move_cursor_up(val)
  #$stderr.puts "move_cursor_up(#{val})"
  if @line_index.positive?
    @line_index -= val
    @byte_pointer_in_line = width_to_bytesize(@screen[@line_index], @cursor_pos.x)
    @cursor_pos.y -= val
  end
end
prep() click to toggle source
# File lib/reline/sibori.rb, line 163
def prep
  Reline::IOGate.prep
end
print(str) click to toggle source
render() click to toggle source
# File lib/reline/sibori.rb, line 122
def render
  #$stderr.puts ?* * 100
  Reline::IOGate.move_cursor_up(@prev_line_index) if @prev_line_index.positive?
  #$stderr.puts "! move_cursor_up(#{@prev_line_index})" if @prev_line_index.positive?
  #$stderr.puts "@prev_line_index #{@prev_line_index}  @line_index #{@line_index}"
  if @screen.size > @prev_screen.size
  #$stderr.puts ?a * 100
    down = @screen.size - @prev_screen.size
    #$stderr.puts "#{@prev_cursor_pos.y} #{down} #{@height}"
    if @prev_cursor_pos.y + down > (@height - 1)
  #$stderr.puts ?b * 100
      scroll = (@prev_cursor_pos.y + down) - (@height - 1)
      Reline::IOGate.scroll_down(scroll)
      #$stderr.puts "! scroll_down(#{scroll})"
  #$stderr.puts "down #{down}"
      Reline::IOGate.move_cursor_up(@screen.size - 1 - scroll)
      #$stderr.puts "! move_cursor_up(#{@screen.size - 1})"
    else
  #$stderr.puts ?c * 100
    end
  end
  @screen.size.times do |n|
    Reline::IOGate.move_cursor_column(0)
    #$stderr.puts "! move_cursor_column(0)"
    @output.write @screen[n]
    #$stderr.puts "! print #{@screen[n].inspect}"
    Reline::IOGate.erase_after_cursor
    #$stderr.puts "! erase_after_cursor"
    Reline::IOGate.move_cursor_down(1) if n != (@screen.size - 1)
    #$stderr.puts "! move_cursor_down(1)" if n != (@screen.size - 1)
  end
  up = @screen.size - 1 - @line_index
  Reline::IOGate.move_cursor_up(up) if up.positive?
  #$stderr.puts "! move_cursor_up(#{up})" if up.positive?
  column = Reline::Unicode.calculate_width(@screen[@line_index].byteslice(0, @byte_pointer_in_line), true)
  Reline::IOGate.move_cursor_column(column)
  #$stderr.puts "! move_cursor_column(#{column}) #{@byte_pointer_in_line}"
  clone_screen
  #$stderr.puts ?- * 10
end
scroll_down(val) click to toggle source
# File lib/reline/sibori.rb, line 83
def scroll_down(val)
  #$stderr.puts "scroll_down(#{val})"
  if val >= @height
    clear_screen
    @line_index = @screen.size - 1
    return
  end
  @screen.size.times do |n|
    if n < @screen.size - val
      #$stderr.puts "A @screen[#{val} + #{n}] (#{@screen[val + n].inspect}) to @screen[#{n}]"
      @screen[n] = @screen[val + n]
    else
      #$stderr.puts "B String.new to @screen[#{n}]"
      @screen[n] = String.new
    end
  end
  @line_index += val
end

Private Instance Methods

width_to_bytesize(str, width) click to toggle source
# File lib/reline/sibori.rb, line 117
        def width_to_bytesize(str, width)
  lines, _ = Reline::Unicode.split_by_width(str, width)
  lines.first.bytesize
end