module RubyText
The top-level module
Skeleton… Can't put classes at top because of initalize
Constants
- ESCDELAY
- Path
- VERSION
Public Class Methods
beep()
click to toggle source
# File lib/settings.rb, line 77 def self.beep Curses.beep end
flash()
click to toggle source
# File lib/settings.rb, line 81 def self.flash Curses.flash end
hide_cursor()
click to toggle source
# File lib/settings.rb, line 137 def self.hide_cursor # remove later? Curses.curs_set(0) end
method_missing(name, *args)
click to toggle source
For passing through arbitrary method calls to the lower level…
# File lib/settings.rb, line 128 def self.method_missing(name, *args) debug "method_missing: #{name} #{args.inspect}" if name[0] == '_' Curses.send(name[1..-1], *args) else raise "#{name} #{args.inspect}" # NoMethodError end end
selector(win: STDSCR, r: 0, c: 0, rows: 10, cols: 20, items:, fg: White, bg: Blue, win2:, callback:, enter: nil, quit: "q")
click to toggle source
Two-paned widget with menu on left, informtional area on right
# File lib/menu.rb, line 275 def self.selector(win: STDSCR, r: 0, c: 0, rows: 10, cols: 20, items:, fg: White, bg: Blue, win2:, callback:, enter: nil, quit: "q") high = rows wide = cols mwin = RubyText.window(high, wide, r: r, c: c, fg: fg, bg: bg) handler = callback Curses.stdscr.keypad(true) RubyText.hide_cursor sel = 0 max = items.size - 1 handler.call(sel, items[sel], win2) loop do mwin.home items.each.with_index do |item, row| mwin.crlf style = (sel == row) ? :reverse : :normal mwin.print fx(" #{item}", style) end ch = getch case ch when Up if sel > 0 sel -= 1 handler.call(sel, items[sel], win2) end when Down if sel < max sel += 1 handler.call(sel, items[sel], win2) end when Enter if enter del = enter.call(sel, items[sel], win2) if del items -= [items[sel]] raise end end when Tab Curses.flash when quit # parameter exit else Curses.beep # all else is trash end end rescue retry end
show_cursor()
click to toggle source
# File lib/settings.rb, line 141 def self.show_cursor # remove later? Curses.curs_set(1) end
show_cursor!()
click to toggle source
# File lib/settings.rb, line 145 def self.show_cursor! Curses.curs_set(2) # Doesn't work? Device-dependent? end
spinner(label: "", win: STDSCR, &block)
click to toggle source
# File lib/widgets.rb, line 16 def self.spinner(label: "", win: STDSCR, &block) # TODO delay, etc. chars = "-\\|/" RubyText.hide_cursor t0 = Time.now.to_i thread = Thread.new do i=0 loop do t1 = Time.now.to_i elapsed = "0:%02d" % (t1-t0) # FIXME breaks at 60 sec i = (i+1) % 4 win.print " #{label} #{chars[i]} #{elapsed}" win.left! sleep 0.04 end end ret = block.call win.puts Thread.kill(thread) RubyText.show_cursor ret end
splash(msg)
click to toggle source
# File lib/widgets.rb, line 38 def self.splash(msg) lines = msg.split("\n") high = lines.size + 4 wide = lines.map {|x| x.length }.max + 4 r0 = (STDSCR.rows - high)/2 c0 = (STDSCR.cols - wide)/2 STDSCR.saveback(high, wide, r0, c0) win = RubyText.window(high, wide, r: r0, c: c0, fg: White, bg: Red, title: "[Press any key]") win.print "\n " win.puts msg getch STDSCR.restback(high, wide, r0, c0) end
start(*args, log: "/tmp/rubytext.log", fg: White, bg: Blue, scroll: false)
click to toggle source
FIXME refactor save/restore, etc. - rep as binary vector?
# File lib/settings.rb, line 89 def self.start(*args, log: "/tmp/rubytext.log", fg: White, bg: Blue, scroll: false) $debug ||= File.new(log, "w") if log # FIXME remove global args.each {|arg| raise "#{arg} is not valid" unless Settings::ValidArgs.include?(arg) } raise RTError("#{fg} is not a color") unless ::Colors.include? fg raise RTError("#{bg} is not a color") unless ::Colors.include? bg @settings = Settings.new @settings.set(*args) # override defaults main = RubyText::Window.main(fg: fg, bg: bg, scroll: scroll) Object.const_set(:STDSCR, main) unless defined? STDSCR $stdscr = STDSCR # FIXME global needed? Object.include(WindowIO) Curses.ESCDELAY = 10 @started = true # rescue => err # puts(err.inspect) # puts(err.backtrace) # raise RTError("#{err}") end
started()
click to toggle source
# File lib/settings.rb, line 69 def self.started # remove later @started end
started?()
click to toggle source
# File lib/settings.rb, line 73 def self.started? @started end
stop()
click to toggle source
# File lib/settings.rb, line 112 def self.stop @started = false Curses.close_screen end
ticker(row: STDSCR.rows-1, col: 0, width: STDSCR.cols, fg: White, bg: Blue, text:, delay: 0.1)
click to toggle source
# File lib/widgets.rb, line 2 def self.ticker(row: STDSCR.rows-1, col: 0, width: STDSCR.cols, fg: White, bg: Blue, text:, delay: 0.1) text = text.gsub("\n", " ") + " " win = RubyText.window(1, width, r: row, c: col, border: false, fg: fg, bg: bg) leader = " "*width + text leader = text.chars.cycle.each_cons(width) width.times { win.rcprint 0, 0, leader.next.join } repeat = text.chars.cycle.each_cons(width) loop do # Warning: loops forever win.rcprint 0, 0, repeat.next.join sleep delay end end
window(high, wide, r: nil, c: nil, border: true, fg: White, bg: Blue, scroll: false, title: nil)
click to toggle source
# File lib/window.rb, line 3 def self.window(high, wide, r: nil, c: nil, border: true, fg: White, bg: Blue, scroll: false, title: nil) r ||= (STDSCR.rows - high)/2 c ||= (STDSCR.cols - wide)/2 win = RubyText::Window.new(high, wide, r, c, border, fg, bg, scroll) win.add_title(title) if title 0.upto(high) {|row| 0.upto(wide) {|col| win[row, col] = " " } } win end
Public Instance Methods
checklist(r: :center, c: :center, items:, curr: 0, selected: [], title: nil, sel_fg: Yellow, fg: White, bg: Blue)
click to toggle source
“Menu” for checklists
# File lib/menu.rb, line 327 def checklist(r: :center, c: :center, items:, curr: 0, selected: [], title: nil, sel_fg: Yellow, fg: White, bg: Blue) RubyText.hide_cursor high = items.size + 2 wide = items.map(&:length).max + 8 tlen = title.length + 8 rescue 0 wide = [wide, tlen].max row, col = self.coords(r, c) row = row - high/2 if r == :center col = col - wide/2 if c == :center r, c = row, col self.saveback(high, wide, r, c) mr, mc = r+self.r0, c+self.c0 mwin = RubyText.window(high, wide, r: mr, c: mc, fg: fg, bg: bg, title: title) Curses.stdscr.keypad(true) sel = curr max = items.size - 1 loop do RubyText.hide_cursor # FIXME should be unnecessary items.each.with_index do |item, row| mwin.go row, 0 style = (sel == row) ? :reverse : :normal color = selected.find {|x| x[0] == row } ? sel_fg : fg label = "[ ]" + item mwin.print fx(label, color, style) end ch = getch case ch when Up sel -= 1 if sel > 0 when Down sel += 1 if sel < max when Esc self.restback(high, wide, r, c) RubyText.show_cursor return [] when Enter self.restback(high, wide, r, c) RubyText.show_cursor return selected.map {|i| items[i] } when " " selected << [sel, items[sel]] sel += 1 if sel < max else Curses.beep end RubyText.show_cursor end end
reset()
click to toggle source
# File lib/settings.rb, line 121 def reset @settings.reset end
set(*args)
click to toggle source
# File lib/settings.rb, line 117 def set(*args) @settings.set(*args) end