Module: RubyText
- Defined in:
- lib/rubytext.rb,
lib/menu.rb,
lib/version.rb,
lib/widgets.rb,
lib/rubytext.rb,
lib/settings.rb
Overview
Skeleton… Can’t put classes at top because of #initalize
Defined Under Namespace
Modules: Keys Classes: Color, Effects, Window
Constant Summary collapse
- VERSION =
"0.0.87"- Path =
File.(File.join(File.dirname(__FILE__)))
- ValidArgs =
Hmm, all these are module-level.
[:raw, :_raw, :echo, :_echo, :cbreak, :_cbreak, :keypad, :_keypad]
Class Method Summary collapse
- .flags ⇒ Object
- .hide_cursor ⇒ Object
-
.inverse_flag(flag) ⇒ Object
FIXME Refactor the Hal out of this.
- .menu(win: STDSCR, r: 0, c: 0, items:, curr: 0, title: nil, fg: White, bg: Blue) ⇒ Object
-
.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
- .start(*args, log: "/tmp/rubytext.log", fg: White, bg: Blue, scroll: false) ⇒ Object
- .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
Why did I put this here?.
Class Method Details
.flags ⇒ Object
33 34 35 36 |
# File 'lib/settings.rb', line 33 def self.flags @flags.uniq! @flags end |
.hide_cursor ⇒ Object
133 134 135 |
# File 'lib/settings.rb', line 133 def self.hide_cursor X.curs_set(0) end |
.inverse_flag(flag) ⇒ Object
FIXME Refactor the Hal out of this.
40 41 42 43 44 45 46 47 |
# File 'lib/settings.rb', line 40 def self.inverse_flag(flag) sflag = flag.to_s if sflag[0] == "_" sflag[1..-1].to_sym else ("_" + sflag).to_sym end end |
.menu(win: STDSCR, r: 0, c: 0, items:, curr: 0, title: nil, fg: White, bg: Blue) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/menu.rb', line 3 def self.(win: STDSCR, r: 0, c: 0, items:, curr: 0, title: nil, fg: White, bg: Blue) RubyText.hide_cursor high = items.size + 2 wide = items.map(&:length).max + 4 tlen = title.length + 6 wide = [wide, tlen].max win.saveback(high, wide, r, c) mr, mc = r+win.r0+1, c+win.c0+1 mwin = RubyText.window(high, wide, r: mr, c: mc, fg: fg, bg: bg) win.go(mr-2, mc-win.c0) { win.print fx("[ #{title} ]", :bold, fg, bg: bg) } unless title.nil? X.stdscr.keypad(true) sel = curr max = items.size - 1 norm = RubyText::Effects.new(:normal) rev = RubyText::Effects.new(:reverse) 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 label = (" "*3 + item + " "*8)[0..wide-1] mwin.print fx(label, style) end ch = getch case ch when X::KEY_UP sel -= 1 if sel > 0 when X::KEY_DOWN sel += 1 if sel < max when 27 win.restback(high, wide, r, c) RubyText.show_cursor return [nil, nil] when 10 win.restback(high, wide, r, c) RubyText.show_cursor return [sel, items[sel]] end RubyText.show_cursor end end |
.method_missing(name, *args) ⇒ Object
For passing through arbitrary method calls to the lower level…
115 116 117 118 119 120 121 122 |
# File 'lib/settings.rb', line 115 def self.method_missing(name, *args) debug "method_missing: #{name} #{args.inspect}" if name[0] == '_' X.send(name[1..-1], *args) else raise "#{name} #{args.inspect}" # NoMethodError end end |
.reset ⇒ Object
89 90 91 |
# File 'lib/settings.rb', line 89 def self.reset rest_flags end |
.rest_flags ⇒ Object
99 100 101 102 103 104 105 |
# File 'lib/settings.rb', line 99 def self.rest_flags @flags = @fstack.pop @flags.uniq! self.set(*@flags) rescue @flags = @defaults end |
.save_flags ⇒ Object
93 94 95 96 97 |
# File 'lib/settings.rb', line 93 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
48 49 50 51 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 91 92 93 94 95 |
# File 'lib/menu.rb', line 48 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.indow(high, wide, r: r, c: c, fg: fg, bg: bg) handler = callback X.stdscr.keypad(true) RubyText.hide_cursor norm = RubyText::Effects.new(:normal) rev = RubyText::Effects.new(:reverse) 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 X::KEY_UP if sel > 0 sel -= 1 handler.call(sel, items[sel], win2) end when X::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 quit # parameter exit end end rescue retry end |
.set(*args) ⇒ Object
Allow a block?
49 50 51 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 |
# File 'lib/settings.rb', line 49 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) X.send(flag) elsif flag[0] == "_" && standard.include?(flag[1..-1].to_sym) flag.sub!(/^_/, "no") X.send(flag) else case flag.to_sym when :cursor X.curs_set(1) when :_cursor, :nocursor X.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
137 138 139 |
# File 'lib/settings.rb', line 137 def self.show_cursor X.curs_set(1) end |
.show_cursor! ⇒ Object
141 142 143 |
# File 'lib/settings.rb', line 141 def self.show_cursor! X.curs_set(2) # Doesn't work? Device-dependent? end |
.start(*args, log: "/tmp/rubytext.log", fg: White, bg: Blue, scroll: false) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/settings.rb', line 12 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
6 7 8 |
# File 'lib/settings.rb', line 6 def self.started @started end |
.stop ⇒ Object
107 108 109 110 |
# File 'lib/settings.rb', line 107 def self.stop @started = false X.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
Why did I put this here?
126 127 128 129 130 131 |
# File 'lib/settings.rb', line 126 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 |