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.75"- 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.
- .menu(r: 0, c: 0, items:, curr: 0, 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
- .restback(high, wide, r, c) ⇒ Object
- .save_flags ⇒ Object
- .saveback(high, wide, r, c) ⇒ Object
- .selector(r: 0, c: 0, rows: 10, cols: 20, items:, fg: White, bg: Blue, win:, 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
Hmm, all these are module-level.
- .stop ⇒ Object
- .ticker(row: STDSCR.rows-1, col: 0, width: STDSCR.cols, fg: White, bg: Blue, text:, delay: 0.1) ⇒ Object
- .window(high, wide, r0, c0, border: true, fg: White, bg: Blue, scroll: false) ⇒ Object
Class Method Details
.flags ⇒ Object
19 20 21 22 |
# File 'lib/settings.rb', line 19 def self.flags @flags.uniq! @flags end |
.hide_cursor ⇒ Object
108 109 110 |
# File 'lib/settings.rb', line 108 def self.hide_cursor X.curs_set(0) end |
.inverse_flag(flag) ⇒ Object
FIXME Refactor the Hal out of this.
26 27 28 29 30 31 32 33 |
# File 'lib/settings.rb', line 26 def self.inverse_flag(flag) sflag = flag.to_s if sflag[0] == "_" sflag[1..-1].to_sym else ("_" + sflag).to_sym end end |
.menu(r: 0, c: 0, items:, curr: 0, fg: White, bg: Blue) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/menu.rb', line 23 def self.(r: 0, c: 0, items:, curr: 0, fg: White, bg: Blue) high = items.size + 2 wide = items.map(&:length).max + 4 saveback(high, wide, r, c) win = RubyText.window(high, wide, r, c, fg: fg, bg: bg) # RubyText.set(:raw) X.stdscr.keypad(true) RubyText.hide_cursor sel = curr max = items.size - 1 norm = RubyText::Effects.new(:normal) rev = RubyText::Effects.new(:reverse) loop do items.each.with_index do |item, row| win.go row, 0 style = (sel == row) ? rev : norm win.print style, " #{item} " 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 restback(high, wide, r, c) return [nil, nil] when 10 restback(high, wide, r, c) return [sel, items[sel]] end end end |
.method_missing(name, *args) ⇒ Object
For passing through arbitrary method calls to the lower level…
95 96 97 98 99 100 101 102 |
# File 'lib/settings.rb', line 95 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
71 72 73 |
# File 'lib/settings.rb', line 71 def self.reset rest_flags end |
.rest_flags ⇒ Object
81 82 83 84 85 86 |
# File 'lib/settings.rb', line 81 def self.rest_flags @flags = @fstack.pop @flags.uniq! rescue @flags = @defaults end |
.restback(high, wide, r, c) ⇒ Object
13 14 15 16 17 18 19 20 21 |
# File 'lib/menu.rb', line 13 def self.restback(high, wide, r, c) 0.upto(high-1) do |h| 0.upto(wide-1) do |w| STDSCR[h+r, w+c] = @save.shift end end STDSCR.go *@pos STDSCR.refresh end |
.save_flags ⇒ Object
75 76 77 78 79 |
# File 'lib/settings.rb', line 75 def self.save_flags @fstack ||= [] @flags.uniq! @fstack.push @flags end |
.saveback(high, wide, r, c) ⇒ Object
3 4 5 6 7 8 9 10 11 |
# File 'lib/menu.rb', line 3 def self.saveback(high, wide, r, c) @pos = STDSCR.rc @save = [] 0.upto(high-1) do |h| 0.upto(wide-1) do |w| @save << STDSCR[h+r, w+c] end end end |
.selector(r: 0, c: 0, rows: 10, cols: 20, items:, fg: White, bg: Blue, win:, 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 107 108 |
# File 'lib/menu.rb', line 58 def self.selector(r: 0, c: 0, rows: 10, cols: 20, items:, fg: White, bg: Blue, win:, callback:, enter: nil, quit: "q") high = rows wide = cols saveback(high, wide, r, c) = RubyText.window(high, wide, r, c, fg: fg, bg: bg) win2 = win handler = callback # RubyText.set(:raw) X.stdscr.keypad(true) RubyText.hide_cursor norm = RubyText::Effects.new(:normal) rev = RubyText::Effects.new(:reverse) sel = 0 max = items.size - 1 send(handler, sel, items[sel], win2) loop do .home items.each.with_index do |item, row| .left style = (sel == row) ? rev : norm .puts style, " #{item} " end ch = getch case ch when X::KEY_UP if sel > 0 sel -= 1 send(handler, sel, items[sel], win2) end when X::KEY_DOWN if sel < max sel += 1 send(handler, sel, items[sel], win2) end when 10 # Enter if enter del = send(enter, 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?
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/settings.rb', line 35 def self.set(*args) # Allow a block? standard = [:cbreak, :raw, :echo, :keypad] @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) 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
112 113 114 |
# File 'lib/settings.rb', line 112 def self.show_cursor X.curs_set(1) end |
.show_cursor! ⇒ Object
116 117 118 |
# File 'lib/settings.rb', line 116 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
Hmm, all these are module-level.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/settings.rb', line 4 def self.start(*args, log: "/tmp/rubytext.log", fg: White, bg: Blue, scroll: false) $debug ||= File.new(log, "w") if log # FIXME remove global 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) # defaults (:keypad?) self.set(*args) # override defaults rescue => err debug(err.inspect) debug(err.backtrace) raise RTError("#{err}") end |
.stop ⇒ Object
88 89 90 |
# File 'lib/settings.rb', line 88 def self.stop 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, row, 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, r0, c0, border: true, fg: White, bg: Blue, scroll: false) ⇒ Object
104 105 106 |
# File 'lib/settings.rb', line 104 def self.window(high, wide, r0, c0, border: true, fg: White, bg: Blue, scroll: false) RubyText::Window.new(high, wide, r0, c0, border, fg, bg, scroll) end |