made it work, more or less, with ruby 1.9
[nyuron.git] / modules / cli.rb
blobbb72ae466d2af27524dfaa837ba43c38d1ff7328
1 require 'ncurses'
3 module CLI
4         extend CLI
6         ## keytable {{{
8         ## maps the key numbers you get from the Ncurses module to strings
9         def self.keytable(key)
10                 case key
11                 when 12, 410
12                         '<redraw>'
13                 when ?\n.ord, Ncurses::KEY_ENTER
14                         '<cr>'
15                 when ?\b.ord, Ncurses::KEY_BACKSPACE, 127
16                         '<bs>'
17                 when Ncurses::KEY_DC
18                         '<del>'
19                 when Ncurses::KEY_END
20                         '<end>'
21                 when Ncurses::KEY_HOME
22                         '<home>'
23                 when Ncurses::KEY_RIGHT
24                         '<right>'
25                 when Ncurses::KEY_LEFT
26                         '<left>'
27                 when Ncurses::KEY_UP
28                         '<up>'
29                 when Ncurses::KEY_DOWN
30                         '<down>'
31                 when ?\e.ord
32                         '<esc>'
33 ## keep spaces as they are, makes more sense
34 #               when ?\s
35 #                       '<space>'
36                 when Ncurses::KEY_BTAB
37                         '<s-tab>'
38                 when 9
39                         '<tab>'
40                 when 1..26 # CTRL + ...
41                         "<c-#{(key+96).chr}>"
42                 when 32..126
43                         key.chr
44                 when -1
45                         ''
46                 else
47                         logerr("key not found: #{key}")
48                         ''
49                 end
50         end
52         ## }}}
53         
54         ## Initialize nourses. This needs to be called once, even after using closei
55         def self.initialize
56                 @@window = Ncurses.initscr
57                 starti
58         end
60         ## (Re)Start the ncurses
61         def starti
62                 @@running = true
63                 @@screen = Ncurses.stdscr
64                 @@screen.keypad(true)
65                 Ncurses.start_color
66                 Ncurses.use_default_colors
67                 Ncurses.ESCDELAY = 50
69                 Ncurses.noecho
70                 Ncurses.curs_set 0
71                 Ncurses.halfdelay(200)
72                 @@colortable = []
73         end
75         ## Close ncurses
76         def closei
77                 @@running = false
78                 Ncurses.echo
79                 Ncurses.cbreak
80                 Ncurses.curs_set 1
81                 Ncurses.endwin
82         end
84         def cursor(bool)
85                 Ncurses.curs_set(bool ? 1 : 0)
86         end
88         def refresh
89                 Ncurses.refresh
90         end
92         def running?() @@running end
94         ## Clears the whole screen by writing lines * cols spaces at position (0, 0).
95         ## I doubt that this is the best way of doing so, but this is rarely used so i don't care.
96         def cleari
97                 Ncurses.mvaddstr(0, 0, ' ' * (lines * cols))
98         end
100         def geti
101                 CLI.keytable(Ncurses.getch)
102         end
104         def set_title(x)
105                 print "\e]2;#{x}\007"
106         end
108         def lines
109                 Ncurses.LINES
110         end
112         def cols
113                 Ncurses.COLS
114         end
116         def movi(y=0, x=0)
117                 y < 0 and y += lines
118                 Ncurses.move(y, x)
119         end
121         def puti *args
122                 case args.size
123                 when 1
124                         Ncurses.addstr(args[0].to_s)
125                 when 2
126                         if (y = args[0]) < 0 then y += Ncurses.LINES end
127                         Ncurses.mvaddstr(y, 0, args[1].to_s)
128                 when 3
129                         if (y = args[0]) < 0 then y += Ncurses.LINES end
130                         if (x = args[1]) < 0 then x += Ncurses.COLS end
131                         Ncurses.mvaddstr(y, x, args[2].to_s)
132                 end
133         end
135         def color(fg = -1, bg = -1)
136                 if Opt.color
137                         Ncurses.color_set(get_color(fg,bg), nil)
138                 end
139         end
141         def attr_set(fg, bg, attr=nil)
142                 if Opt.color
143                         if attr
144                                 Ncurses.attrset(attr | Ncurses::COLOR_PAIR(get_color(fg, bg)))
145                         else
146                                 Ncurses.color_set(get_color(fg, bg), nil)
147                         end
148                 elsif attr
149                         Ncurses.attrset(attr)
150                 end
151         end
153         def attr_at(x, y, len, fg, bg, attr=0)
154                 y += lines if y < 0
155                 Ncurses.mvchgat(y, x, len, attr, get_color(fg, bg), nil)
156         end
158         def color_at y, x=0, len=-1, fg=-1, bg=-1, attributes=0
159                 fg, bg = -1, -1 unless Opt.color
160                 if y < 0 then y += Ncurses.LINES end
161                 Ncurses.mvchgat(y, x, len, attributes, get_color(fg, bg), nil)
162         end
164         def color_bold_at y, x=0, len=-1, fg=-1, bg=-1
165                 fg, bg = -1, -1 unless Opt.color
166                 color_at(y, x, len, fg, bg, attributes = Ncurses::A_BOLD)
167         end
169         def color_reverse_bold_at y, x=0, len=-1, fg=-1, bg=-1
170                 if Opt.color
171                         color_at(y, x, len, fg, bg, Ncurses::A_REVERSE | Ncurses::A_BOLD)
172                 else
173                         Ncurses.mvchgat(y, x, len, Ncurses::A_REVERSE | Ncurses::A_BOLD, 0, nil)
174                 end
175         end
176         alias color_bold_reverse_at color_reverse_bold_at
178         def color_reverse_at y, x=0, len=-1, fg=-1, bg=-1
179                 if Opt.color
180                         color_at(y, x, len, fg, bg, Ncurses::A_REVERSE)
181                 else
182                         Ncurses.mvchgat(y, x, len, Ncurses::A_REVERSE, 0, nil)
183                 end
184         end
186         def get_color(fg, bg)
187                 n = bg+2 + 9*(fg+2)
188                 color = @@colortable[n]
189                 unless color
190                         # create a new pair
191                         size = @@colortable.reject{|x| x.nil? }.size + 1
192                         Ncurses::init_pair(size, fg, bg)
193                         color = @@colortable[n] = size
194                 end
195                 return color
196         end
198         def bold(b = true)
199                 if b
200                         Ncurses.attron(Ncurses::A_BOLD) 
201                 else
202                         Ncurses.attroff(Ncurses::A_BOLD) 
203                 end
204         end
206         def reverse(b = true)
207                 if b
208                         Ncurses.attron(Ncurses::A_REVERSE) 
209                 else
210                         Ncurses.attroff(Ncurses::A_REVERSE) 
211                 end
212         end