class Umbra::Pad

Public Class Methods

new(config={}) click to toggle source

You may pass height, width, row and col for creating a window otherwise a fullscreen window will be created. If you pass a window from caller then that window will be used. Some keys are trapped, jkhl space, pgup, pgdown, end, home, t b NOTE: this is very minimal, and uses no widgets, so I am unable to yield an object

for further configuration. If we used a textbox, I could have yielded that. 
TODO handle passed block
# File lib/umbra/pad.rb, line 33
def initialize config={}, &block

  $log.debug "  inside pad contructor" if $log
  @config = config
  @rows = FFI::NCurses.LINES-1
  @cols = FFI::NCurses.COLS-1
  @prow = @pcol = 0                        # how many cols we are panning
  @startrow = 0
  @startcol = 0
  
  h = config.fetch(:height, 0)
  w = config.fetch(:width, 0)
  t = config.fetch(:row, 0)
  l = config.fetch(:col, 0)
  @color_pair = config.fetch(:color_pair, 14)
  @attr = config.fetch(:attr, FFI::NCurses::A_BOLD)
  @rows = h unless h == 0
  @cols = w unless w == 0
  @startrow = t unless t == 0
  @startcol = l unless l == 0
  @suppress_border = config[:suppress_border]
  top = t
  left = l
  @height = h
  @width = w
  #@pointer, @panel = create_window(h, w, t, l)
  @pointer, @panel = create_centered_window(h, w, @color_pair, @attr)

  @startrow, @startcol = FFI::NCurses.getbegyx(@pointer)
  unless @suppress_border
    @startrow += 1
    @startcol += 1
    @rows -=3  # 3 is since print_border_only reduces one from width, to check whether this is correct
    @cols -=3
  end
  $log.debug "top and left are: #{top}  #{left} " if $log
  #@window.box # 2018-03-28 -
  FFI::NCurses.box @pointer, 0, 0
  title(config[:title])
  FFI::NCurses.wbkgd(@pointer, FFI::NCurses.COLOR_PAIR(@color_pair) | @attr);
  FFI::NCurses.curs_set 0                  # cursor invisible
  if config[:filename]
    self.filename=(config[:filename])
  elsif config[:list]
    self.list=(config[:list])
  end
end

Public Instance Methods

create_centered_window(height, width, color_pair=14, attr=FFI::NCurses::A_BOLD) click to toggle source
# File lib/umbra/pad.rb, line 90
def create_centered_window height, width, color_pair=14, attr=FFI::NCurses::A_BOLD
  row = ((FFI::NCurses.LINES-height)/2).floor
  col = ((FFI::NCurses.COLS-width)/2).floor
  pointer = FFI::NCurses.newwin(height, width, row, col)
  FFI::NCurses.wbkgd(pointer, FFI::NCurses.COLOR_PAIR(color_pair) | attr);
  panel = FFI::NCurses.new_panel(pointer)
  FFI::NCurses.keypad(pointer, true)
  return pointer, panel
end
create_window(h, w, t, l) click to toggle source

minimum window creator method, not using a class. However, some methods do require windows width and ht etc

# File lib/umbra/pad.rb, line 84
def create_window h, w, t, l
  pointer = FFI::NCurses.newwin(h, w, t, l)
  panel = FFI::NCurses.new_panel(pointer)
  FFI::NCurses.keypad(pointer, true)
  return pointer, panel
end
destroy_pad() click to toggle source
# File lib/umbra/pad.rb, line 104
def destroy_pad
  if @pad
    FFI::NCurses.delwin(@pad) 
    @pad = nil
  end
end
destroy_window(pointer, panel) click to toggle source
# File lib/umbra/pad.rb, line 99
def destroy_window pointer, panel
  FFI::NCurses.del_panel(panel)  if panel
  FFI::NCurses.delwin(pointer)   if pointer
  panel = pointer = nil         # prevent call twice
end
filename=(filename) click to toggle source

source of data is a filename

# File lib/umbra/pad.rb, line 155
def filename=(filename)
  content = File.open(filename,"r").read.split("\n")
  display_content content
end
list=(content) click to toggle source

receive array as content source

# File lib/umbra/pad.rb, line 151
def list=(content)
  display_content content
end
render(content, pad, color_pair, attr) click to toggle source

renders the content in a loop.

NOTE: separated in the hope that caller can override.
# File lib/umbra/pad.rb, line 136
def render content, pad, color_pair, attr
  cp = color_pair
  FFI::NCurses.wbkgd(pad, FFI::NCurses.COLOR_PAIR(color_pair) | attr);
  FFI::NCurses.wattron(pad, FFI::NCurses.COLOR_PAIR(cp) | attr)
  # WRITE
  #filler = " "*@content_cols
  content.each_index { |ix|
    #FFI::NCurses.mvwaddstr(pad,ix, 0, filler)
    FFI::NCurses.mvwaddstr(pad,ix, 0, content[ix])
  }
  FFI::NCurses.wattroff(pad, FFI::NCurses.COLOR_PAIR(cp) | attr)
end
run() click to toggle source

returns button index Call this after instantiating the window

# File lib/umbra/pad.rb, line 176
def run
  return handle_keys
end
title(stitle) click to toggle source

print a title over the box on zeroth row

# File lib/umbra/pad.rb, line 111
def title stitle
  return unless stitle
  stitle = "| #{stitle} |"
  col = (@width-stitle.size)/2
  FFI::NCurses.mvwaddstr(@pointer, 0, col, stitle) 
end

Private Instance Methods

content_cols(content) click to toggle source
# File lib/umbra/pad.rb, line 185
def content_cols content
  # next line bombs if content contains integer or nil.
  #longest = content.max_by(&:length)
  #longest.length
  max = 1
  content.each do |line|
    next unless line
    l = 1
    case line
    when String
      l = line.length
    else
      l = line.to_s.length
    end
    max = l if l > max
  end
  return max
end
content_dimensions(content) click to toggle source
# File lib/umbra/pad.rb, line 159
        def content_dimensions content
  content_rows = content.count
  content_cols = content_cols(content)
  return content_rows, content_cols
end
create_pad(content) click to toggle source
# File lib/umbra/pad.rb, line 123
        def create_pad content
  # destroy pad if exists
  destroy_pad
  @content_rows, @content_cols = content_dimensions(content)
  pad = FFI::NCurses.newpad(@content_rows, @content_cols)
  FFI::NCurses.keypad(pad, true);         # function and arrow keys

  FFI::NCurses.update_panels
  render(content, pad, @color_pair, @attr)
  return pad
end
display_content(content) click to toggle source
# File lib/umbra/pad.rb, line 117
        def display_content content
    @pad = create_pad content 
    FFI::NCurses.wrefresh(@pointer)
    padrefresh
end
handle_keys() click to toggle source

returns button index

# File lib/umbra/pad.rb, line 213
def handle_keys
  @height = FFI::NCurses.LINES-1 if @height == 0
  ht = @rows 
  scroll_lines = @height/2
  buttonindex = catch(:close) do 
    maxrow = @content_rows - @rows
    maxcol = @content_cols - @cols 
    while ((ch = FFI::NCurses.wgetch(@pointer)) != FFI::NCurses::KEY_F10)
      break if ch == ?\C-q.getbyte(0) 
      begin
        case ch
        when key(?g), 279 # home as per iterm2
          @prow = 0
          @pcol = 0
        when key(?b), key(?G), 277 # end as per iterm2
          @prow = maxrow-1
          @pcol = 0
        when key(?j), FFI::NCurses::KEY_DOWN
          @prow += 1
        when key(?k), FFI::NCurses::KEY_UP
          @prow -= 1
        when 32, 338   # Page Down abd Page Up as per iTerm2
          @prow += 10
        when key(?\C-d)
          @prow += scroll_lines
        when key(?\C-b)
          @prow -= scroll_lines
        when key(?\C-f)
          @prow += ht
        when key(?\C-u)
          @prow -= ht
        when 339
          @prow -= 10
        when key(?l), FFI::NCurses::KEY_RIGHT
          @pcol += 1
        when key(?$)
          @pcol = maxcol - 1
        when key(?h), FFI::NCurses::KEY_LEFT
          @pcol -= 1
        when key(?0)
          @pcol = 0
        when key(?q)
          throw :close
        else 
          #alert " #{ch} not mapped "
        end
        @prow = 0 if @prow < 0
        @pcol = 0 if @pcol < 0
        if @prow > maxrow-1
          @prow = maxrow-1
        end
        if @pcol > maxcol-1
          @pcol = maxcol-1
        end
        padrefresh
        #FFI::NCurses::Panel.update_panels # 2018-03-28 - this bombs elsewhere
      rescue => err
        if $log
          $log.debug err.to_s                 
          $log.debug err.backtrace.join("\n")
        end
        FFI::NCurses.endwin
        puts "INSIDE pad.rb"
        puts err
        puts err.backtrace.join("\n")
      ensure
      end

    end # while loop
  end # close
rescue => err
  if $log
    $log.debug err.to_s
    $log.debug err.backtrace.join("\n")
  end
  FFI::NCurses.endwin
  puts err
  puts err.backtrace.join("\n")
ensure
  #@window.destroy #unless @config[:window]
  destroy_window @pointer, @panel
  #FFI::NCurses.delwin(@pad)       if @pad
  destroy_pad
  FFI::NCurses.curs_set 1                  # cursor visible again
  return buttonindex 
end
key(x) click to toggle source

convenience method

# File lib/umbra/pad.rb, line 182
def key x
  x.getbyte(0)
end
padrefresh() click to toggle source

write pad onto window

# File lib/umbra/pad.rb, line 168
def padrefresh
  raise "padrefresh: Pad not created" unless @pad
  FFI::NCurses.prefresh(@pad,@prow,@pcol, @startrow,@startcol, @rows + @startrow,@cols+@startcol);
end