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
pointer to FFI routines, use when calling FFI directly.
Public Class Methods
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
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
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
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 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
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
Convenience method for a waiting getch
# File lib/umbra/window.rb, line 240 def getchar $ncurses_timeout = -1 return self.getch end
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
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
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
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
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
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