Class: Umbra::Window
- Inherits:
-
Object
- Object
- Umbra::Window
- Defined in:
- lib/umbra/window.rb
Overview
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.
Instance Attribute Summary collapse
-
#height ⇒ Object
readonly
Returns the value of attribute height.
-
#left ⇒ Object
readonly
Returns the value of attribute left.
-
#panel ⇒ Object
readonly
panel associated with window.
-
#pointer ⇒ Object
readonly
pointer to FFI routines, use when calling FFI directly.
-
#top ⇒ Object
readonly
Returns the value of attribute top.
-
#width ⇒ Object
readonly
Returns the value of attribute width.
Class Method Summary collapse
-
.create(h = 0, w = 0, top = 0, left = 0) ⇒ Object
create a window and return window, or yield window to block.
Instance Method Summary collapse
-
#box ⇒ Object
make a box around the window.
-
#destroy ⇒ Object
destroy the window and the panel.
-
#getch ⇒ Integer
(also: #getkey)
Get a key from the standard input.
-
#getchar ⇒ Object
Convenience method for a waiting getch.
-
#initialize(h = 0, w = 0, top = 0, left = 0) ⇒ Window
constructor
creates a window with given height, width, top and left.
-
#method_missing(name, *args) ⇒ Object
route other methods to ffi.
-
#OLDgetch ⇒ Object
this works fine for basic, control and function keys.
- #printstr(str, x = 0, y = 0) ⇒ Object deprecated Deprecated.
-
#printstring(r, c, string, color = 0, att = FFI::NCurses::A_NORMAL) ⇒ Object
2018-03-08 - taken from canis reduced print given string at row, col with given color and attributes.
-
#repaint ⇒ Object
repaints windows objects like title and box.
-
#title(str, color = 0, att = BOLD) ⇒ Object
Print a centered title on top of window.
-
#wrefresh ⇒ Object
refresh the window (wrapper) To be called after printing on a window.
Constructor Details
#initialize(h = 0, w = 0, top = 0, left = 0) ⇒ Window
creates a window with given height, width, top and left. If no args given, creates a root window (i.e. full size).
129 130 131 132 133 134 135 136 137 138 139 |
# 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 |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
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.
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# 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 |
Instance Attribute Details
#height ⇒ Object (readonly)
Returns the value of attribute height.
121 122 123 |
# File 'lib/umbra/window.rb', line 121 def height @height end |
#left ⇒ Object (readonly)
Returns the value of attribute left.
121 122 123 |
# File 'lib/umbra/window.rb', line 121 def left @left end |
#panel ⇒ Object (readonly)
panel associated with window
120 121 122 |
# File 'lib/umbra/window.rb', line 120 def panel @panel end |
#pointer ⇒ Object (readonly)
pointer to FFI routines, use when calling FFI directly.
119 120 121 |
# File 'lib/umbra/window.rb', line 119 def pointer @pointer end |
#top ⇒ Object (readonly)
Returns the value of attribute top.
121 122 123 |
# File 'lib/umbra/window.rb', line 121 def top @top end |
#width ⇒ Object (readonly)
Returns the value of attribute width.
121 122 123 |
# File 'lib/umbra/window.rb', line 121 def width @width end |
Class Method Details
.create(h = 0, w = 0, top = 0, left = 0) ⇒ Object
create a window and return window, or yield window to block
142 143 144 145 146 147 148 149 150 151 152 |
# 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 |
Instance Method Details
#box ⇒ Object
make a box around the window. Just a wrapper
287 288 289 290 |
# File 'lib/umbra/window.rb', line 287 def box @box = true FFI::NCurses.box(@pointer, 0, 0) end |
#destroy ⇒ Object
destroy the window and the panel. This is important. It should be placed in the ensure block of caller application, so it happens.
262 263 264 265 266 |
# 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 ⇒ Integer Also known as: getkey
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
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# 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 |
#getchar ⇒ Object
Convenience method for a waiting getch
240 241 242 243 |
# File 'lib/umbra/window.rb', line 240 def getchar $ncurses_timeout = -1 return self.getch end |
#OLDgetch ⇒ Object
this works fine for basic, control and function keys
246 247 248 249 250 251 252 |
# 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 |
#printstr(str, x = 0, y = 0) ⇒ Object
print string at x, y coordinates. replace this with the original one below
156 157 158 159 160 |
# 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) ⇒ Object
2018-03-08 - taken from canis reduced print given string at row, col with given color and attributes
168 169 170 171 172 173 174 175 176 177 178 179 180 |
# 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 ⇒ Object
repaints windows objects like title and box. To be called from form on pressing redraw, and SIGWINCH
307 308 309 310 311 312 313 314 315 316 |
# 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) ⇒ Object
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
297 298 299 300 301 302 303 |
# 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 ⇒ Object
refresh the window (wrapper) To be called after printing on a window.
257 258 259 |
# File 'lib/umbra/window.rb', line 257 def wrefresh FFI::NCurses.wrefresh(@pointer) end |