Module: RubyText
- Defined in:
- lib/rubytext.rb,
lib/menu.rb,
lib/window.rb,
lib/widgets.rb,
lib/rubytext.rb,
lib/settings.rb,
lib/rubytext_version.rb
Overview
Skeleton… Can’t put classes at top because of #initalize
Defined Under Namespace
Modules: Keys Classes: Color, Effects, Window
Constant Summary collapse
- ValidArgs =
Hmm, all these are module-level…?
[:raw, :_raw, :echo, :_echo, :cbreak, :_cbreak, :keypad, :_keypad, :cursor, :_cursor]
- VERSION =
"0.1.5"- Path =
File.(File.join(File.dirname(__FILE__)))
Class Method Summary collapse
- .flags ⇒ Object
- .hide_cursor ⇒ Object
-
.inverse_flag(flag) ⇒ Object
FIXME Refactor the Hal out of this.
-
.method_missing(name, *args) ⇒ Object
For passing through arbitrary method calls to the lower level…
- .reset ⇒ Object
- .rest_flags ⇒ Object
- .save_flags ⇒ Object
- .selector(win: STDSCR, r: 0, c: 0, rows: 10, cols: 20, items:, fg: White, bg: Blue, win2:, callback:, enter: nil, quit: "q") ⇒ Object
-
.set(*args) ⇒ Object
Allow a block?.
- .show_cursor ⇒ Object
- .show_cursor! ⇒ Object
-
.spinner(label: "", win: STDSCR, &block) ⇒ Object
TODO delay, etc.
- .splash(msg) ⇒ Object
-
.start(*args, log: "/tmp/rubytext.log", fg: White, bg: Blue, scroll: false) ⇒ Object
FIXME refactor save/restore, etc.
- .started ⇒ Object
- .stop ⇒ Object
- .ticker(row: STDSCR.rows-1, col: 0, width: STDSCR.cols, fg: White, bg: Blue, text:, delay: 0.1) ⇒ Object
-
.window(high, wide, r: nil, c: nil, border: true, fg: White, bg: Blue, scroll: false) ⇒ Object
TODO add title:?.
Class Method Details
.flags ⇒ Object
36 37 38 39 |
# File 'lib/settings.rb', line 36 def self.flags @flags.uniq! @flags end |
.hide_cursor ⇒ Object
127 128 129 |
# File 'lib/settings.rb', line 127 def self.hide_cursor Curses.curs_set(0) end |
.inverse_flag(flag) ⇒ Object
FIXME Refactor the Hal out of this.
43 44 45 46 47 48 49 50 |
# File 'lib/settings.rb', line 43 def self.inverse_flag(flag) sflag = flag.to_s if sflag[0] == "_" sflag[1..-1].to_sym else ("_" + sflag).to_sym end end |
.method_missing(name, *args) ⇒ Object
For passing through arbitrary method calls to the lower level…
118 119 120 121 122 123 124 125 |
# File 'lib/settings.rb', line 118 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 |
.reset ⇒ Object
92 93 94 |
# File 'lib/settings.rb', line 92 def self.reset rest_flags end |
.rest_flags ⇒ Object
102 103 104 105 106 107 108 |
# File 'lib/settings.rb', line 102 def self.rest_flags @flags = @fstack.pop @flags.uniq! self.set(*@flags) rescue @flags = @defaults end |
.save_flags ⇒ Object
96 97 98 99 100 |
# File 'lib/settings.rb', line 96 def self.save_flags @fstack ||= [] @flags.uniq! @fstack.push @flags end |
.selector(win: STDSCR, r: 0, c: 0, rows: 10, cols: 20, items:, fg: White, bg: Blue, win2:, callback:, enter: nil, quit: "q") ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/menu.rb', line 58 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 Curses::KEY_UP if sel > 0 sel -= 1 handler.call(sel, items[sel], win2) end when Curses::KEY_DOWN if sel < max sel += 1 handler.call(sel, items[sel], win2) end when 10 # Enter if enter del = enter.call(sel, items[sel], win2) if del items -= [items[sel]] raise end end when 9 # tab Curses.flash when quit # parameter exit else Curses.beep # all else is trash end end rescue retry end |
.set(*args) ⇒ Object
Allow a block?
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/settings.rb', line 52 def self.set(*args) # Allow a block? standard = [:cbreak, :raw, :echo] @defaults = [:cbreak, :_echo, :keypad] @flags = @defaults.dup save_flags args.each do |arg| @flags += [arg] inv = inverse_flag(arg) @flags -= [inv] @flags.uniq! flag = arg.to_s if standard.include?(flag.to_sym) || standard.include?(flag.sub(/no/, "_").to_sym) Curses.send(flag) elsif flag[0] == "_" && standard.include?(flag[1..-1].to_sym) flag.sub!(/^_/, "no") Curses.send(flag) else case flag.to_sym when :cursor Curses.curs_set(1) when :_cursor, :nocursor Curses.curs_set(0) when :keypad STDSCR.cwin.keypad(true) when :_keypad STDSCR.cwin.keypad(false) else # self.stop rest_flags # prevent propagating error in test raise RTError("flag = #{flag.inspect}") end end end if block_given? yield rest_flags end end |
.show_cursor ⇒ Object
131 132 133 |
# File 'lib/settings.rb', line 131 def self.show_cursor Curses.curs_set(1) end |
.show_cursor! ⇒ Object
135 136 137 |
# File 'lib/settings.rb', line 135 def self.show_cursor! Curses.curs_set(2) # Doesn't work? Device-dependent? end |
.spinner(label: "", win: STDSCR, &block) ⇒ Object
TODO delay, etc.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# 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) ⇒ Object
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/widgets.rb', line 38 def self.splash(msg) lines = msg.split("\n") high = lines.size + 2 wide = lines.map {|x| x.length }.max + 2 STDSCR.saveback(high, wide, 10, 20) win = RubyText.window(high, wide, r: 10, c: 20, fg: White, bg: Red) win.puts msg getch STDSCR.restback(high, wide, 10, 20) end |
.start(*args, log: "/tmp/rubytext.log", fg: White, bg: Blue, scroll: false) ⇒ Object
FIXME refactor save/restore, etc. - rep as binary vector?
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/settings.rb', line 15 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 ValidArgs.include?(arg) } raise "#{fg} is not a color" unless ::Colors.include? fg raise "#{bg} is not a color" unless ::Colors.include? bg 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) self.set(:_echo, :cbreak, :keypad) # defaults self.set(*args) # override defaults @started = true rescue => err debug(err.inspect) debug(err.backtrace) raise RTError("#{err}") end |
.started ⇒ Object
7 8 9 |
# File 'lib/settings.rb', line 7 def self.started @started end |
.stop ⇒ Object
110 111 112 113 |
# File 'lib/settings.rb', line 110 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) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 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) ⇒ Object
TODO add title:?
4 5 6 7 8 9 |
# File 'lib/window.rb', line 4 def self.window(high, wide, r: nil, c: nil, border: true, fg: White, bg: Blue, scroll: false) r ||= (STDSCR.rows - high)/2 c ||= (STDSCR.cols - wide)/2 RubyText::Window.new(high, wide, r, c, border, fg, bg, scroll) end |