class Umbra::Window

Window class Creates and manages the underlying window in which we write or place a form and fields. The two important methods here are the constructor, and +destroy()+. pointer is important for making further direct calls to FFI::NCurses.

Attributes

height[R]
left[R]
panel[R]
pointer[R]

pointer to FFI routines, use when calling FFI directly.

top[R]
width[R]

Public Class Methods

create(h=0, w=0, top=0, left=0) { |win| ... } click to toggle source

create a window and return window, or yield window to block

# File lib/umbra/window.rb, line 142
def self.create h=0, w=0, top=0, left=0
  win = Window.new h, w, top, left
  return win unless block_given?

  begin
    yield win
  ensure
    win.destroy
  end

end
new(h=0, w=0, top=0, left=0) click to toggle source

creates a window with given height, width, top and left. If no args given, creates a root window (i.e. full size). @param height [Integer] @param width [Integer] @param top [Integer] @param left [Integer]

# File lib/umbra/window.rb, line 129
def initialize h=0, w=0, top=0, left=0
  @height, @width, @top, @left = h, w, top, left

  @height = FFI::NCurses.LINES if @height == 0   # 2011-11-14 added since tired of checking for zero
  @width = FFI::NCurses.COLS   if @width == 0
  @pointer = FFI::NCurses.newwin(@height, @width, @top, @left) # added FFI 2011-09-6

  @panel = FFI::NCurses.new_panel(@pointer)
  FFI::NCurses.keypad(@pointer, true)
  return @pointer
end

Public Instance Methods

OLDgetch() click to toggle source

this works fine for basic, control and function keys

# File lib/umbra/window.rb, line 246
def OLDgetch
  c = FFI::NCurses.wgetch(@pointer)
rescue SystemExit, Interrupt 
  3      # is C-c
rescue StandardError
  -1     # is C-c
end
box() click to toggle source

make a box around the window. Just a wrapper

# File lib/umbra/window.rb, line 287
def box
  @box = true
  FFI::NCurses.box(@pointer, 0, 0)
end
destroy() click to toggle source

destroy the window and the panel. This is important. It should be placed in the ensure block of caller application, so it happens.

# File lib/umbra/window.rb, line 262
def destroy
  FFI::NCurses.del_panel(@panel) if @panel
  FFI::NCurses.delwin(@pointer)   if @pointer
  @panel = @pointer = nil # prevent call twice
end
getch() click to toggle source

Get a key from the standard input.

This will get control keys and function keys but not Alt keys. This is usually called in a loop by the main program. It returns the ascii code (integer). 1 is Ctrl-a .… 27 is Esc FFI already has constants declared for function keys and control keys for checkin against. Can return a 3 or -1 if user pressed Control-C.

NOTE: For ALT keys we need to check for 27/Esc and if so, then do another read with a timeout. If we get a key, then resolve. Otherwise, it is just ESC NOTE: this was working fine with nodelay. However, that would not allow an app to continuously

update the screen, as the getch was blocked. wtimeout allows screen to update without a key
being pressed. 2018-04-07

@return [Integer] ascii code of key. For undefined keys, returns a String representation.

# File lib/umbra/window.rb, line 197
def getch
  FFI::NCurses.wtimeout(@pointer, $ncurses_timeout || 1000)
  c = FFI::NCurses.wgetch(@pointer)
  if c == 27    ## {{{

    # don't wait for another key
    FFI::NCurses.nodelay(@pointer, true)
    k = FFI::NCurses.wgetch(@pointer)
    if k == -1
      # wait for key
      #FFI::NCurses.nodelay(@pointer, false)
      return 27
    else
      buf = ""
      loop do
        n = FFI::NCurses.wgetch(@pointer)
        break if n == -1
        buf += n.chr
      end
      # wait for next key
      #FFI::NCurses.nodelay(@pointer, false)

      # this works for all alt-keys but it messes with shift-function keys
      # shift-function keys start with M-[ (91) and then have more keys
      if buf == ""
        return k + 128
      end
      #$log.debug "  getch buf is #{k.chr}#{buf} "
      # returning a string key here which is for Shift-Function keys or other undefined keys.
      key = 27.chr + k.chr + buf
      return key

    end
  end   ## }}}
  #FFI::NCurses.nodelay(@pointer, false) # this works but trying out for continueous updates
  c
rescue SystemExit, Interrupt 
  3      # is C-c
rescue StandardError
  -1     # is C-c
end
Also aliased as: getkey
getchar() click to toggle source

Convenience method for a waiting getch

# File lib/umbra/window.rb, line 240
def getchar
  $ncurses_timeout = -1
  return self.getch
end
getkey()
Alias for: getch
method_missing(name, *args) click to toggle source

route other methods to ffi. {{{ This should preferable NOT be used. Better to use the direct call itself. It attempts to route other calls to FFI::NCurses by trying to add w to the name and passing the pointer. I would like to remove this at some time.

# File lib/umbra/window.rb, line 271
def method_missing(name, *args)
  name = name.to_s
  if (name[0,2] == "mv")
    test_name = name.dup
    test_name[2,0] = "w" # insert "w" after"mv"
    if (FFI::NCurses.respond_to?(test_name))
      return FFI::NCurses.send(test_name, @pointer, *args)
    end
  end
  test_name = "w" + name
  if (FFI::NCurses.respond_to?(test_name))
    return FFI::NCurses.send(test_name, @pointer, *args)
  end
  FFI::NCurses.send(name, @pointer, *args)
end
printstr(str, x=0,y=0) click to toggle source

print string at x, y coordinates. replace this with the original one below @deprecated

# File lib/umbra/window.rb, line 156
def printstr(str, x=0,y=0)
  win = @pointer
  FFI::NCurses.wmove(win, x, y)
  FFI::NCurses.waddstr win, str
end
printstring(r,c,string, color=0, att = FFI::NCurses::A_NORMAL) click to toggle source

2018-03-08 - taken from canis reduced print given string at row, col with given color and attributes @param row [Integer] row to print on @param col [Integer] column to print on @param color [Integer] color_pair created earlier @param attr [Integer] any of the four FFI attributes, e.g. A_BOLD, A_REVERSE

# File lib/umbra/window.rb, line 168
def printstring(r,c,string, color=0, att = FFI::NCurses::A_NORMAL)

  #$log.debug "printstring recvd nil row #{r} or col #{c}, color:#{color},att:#{att}."  if $log
  raise "printstring recvd nil row #{r} or col #{c}, color:#{color},att:#{att} " if r.nil? || c.nil?
  att ||= FFI::NCurses::A_NORMAL
  color ||= 0
  raise "color is nil " unless color
  raise "att is nil " unless att

  FFI::NCurses.wattron(@pointer, FFI::NCurses.COLOR_PAIR(color) | att)
  FFI::NCurses.mvwprintw(@pointer, r, c, "%s", :string, string);
  FFI::NCurses.wattroff(@pointer, FFI::NCurses.COLOR_PAIR(color) | att)
end
repaint() click to toggle source

repaints windows objects like title and box. To be called from form on pressing redraw, and SIGWINCH

# File lib/umbra/window.rb, line 307
def repaint
  curses.wclear(@pointer)
  if @box
    self.box
  end
  if @title_data
    str, color, att = @title_data
    self.title str, color, att
  end
end
title(str, color=0, att=BOLD) click to toggle source

Print a centered title on top of window. NOTE : the string is not stored, so it can be overwritten. This should be called after box, or else box will erase the title @param str [String] title to print @param color [Integer] color_pair @param att [Integer] attribute constant

# File lib/umbra/window.rb, line 297
def title str, color=0, att=BOLD
  ## save so we can repaint if required
  @title_data = [str, color, att]
  strl = str.length
  col = (@width - strl)/2
  printstring(0,col, str, color, att)
end
wrefresh() click to toggle source

refresh the window (wrapper) To be called after printing on a window.

# File lib/umbra/window.rb, line 257
def wrefresh
  FFI::NCurses.wrefresh(@pointer)
end