ncurses-ruby 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/examples/rain.rb ADDED
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: rain.rb,v 1.6 2005/08/22 21:41:49 t-peters Exp $
4
+
5
+ # This program is a translation of the popular rain.c demo program from the
6
+ # ncurses library distribution.
7
+ #
8
+ # Copyright (C) 2002 Tobias Peters <t-peters@users.berlios.de>
9
+ #
10
+ # I do not impose any additional restrictions over the copyright of the
11
+ # ncurses library distribution. It has the following Copyright notice
12
+
13
+ #/****************************************************************************
14
+ # * Copyright (c) 1998 Free Software Foundation, Inc. *
15
+ # * *
16
+ # * Permission is hereby granted, free of charge, to any person obtaining a *
17
+ # * copy of this software and associated documentation files (the *
18
+ # * "Software"), to deal in the Software without restriction, including *
19
+ # * without limitation the rights to use, copy, modify, merge, publish, *
20
+ # * distribute, distribute with modifications, sublicense, and/or sell *
21
+ # * copies of the Software, and to permit persons to whom the Software is *
22
+ # * furnished to do so, subject to the following conditions: *
23
+ # * *
24
+ # * The above copyright notice and this permission notice shall be included *
25
+ # * in all copies or substantial portions of the Software. *
26
+ # * *
27
+ # * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
28
+ # * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
29
+ # * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
30
+ # * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
31
+ # * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
32
+ # * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
33
+ # * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
34
+ # * *
35
+ # * Except as contained in this notice, the name(s) of the above copyright *
36
+ # * holders shall not be used in advertising or otherwise to promote the *
37
+ # * sale, use or other dealings in this Software without prior written *
38
+ # * authorization. *
39
+ # ****************************************************************************/
40
+
41
+
42
+
43
+ require "ncurses"
44
+
45
+
46
+ # A class responsible for raindrop drawing
47
+ class Raindrop
48
+ def initialize (window, color_pair = nil)
49
+ @window = window
50
+ @color_pair = color_pair
51
+ lines = []
52
+ columns = []
53
+ window.getmaxyx(lines,columns)
54
+ lines = (lines[0] <= 4) ? 1 : (lines[0] - 4)
55
+ columns = (columns[0] <= 4) ? 1 : (columns[0] - 4)
56
+ @current_phase = 0
57
+ @x = rand(columns)+2
58
+ @y = rand(lines)+2
59
+ end
60
+
61
+ # draw_next_phase draws the next phase of a raindrop. If this was the last
62
+ # phase, returns 0, otherwise returns the raindrop.
63
+ def draw_next_phase
64
+ if (@color_pair)
65
+ if Ncurses.respond_to?(:color_set)
66
+ @window.color_set(@color_pair, nil)
67
+ else
68
+ @window.attrset(Ncurses.COLOR_PAIR(@color_pair))
69
+ end
70
+ end
71
+ if (DRAWING_PROCS[@current_phase].call(@window,@y,@x))
72
+ @current_phase += 1
73
+ self
74
+ end
75
+ end
76
+
77
+ DRAWING_PROCS = [
78
+ Proc.new{|window,y,x|
79
+ window.mvaddstr(y,x, ".")
80
+ },
81
+ Proc.new{|window,y,x|
82
+ window.mvaddstr(y, x, "o")
83
+ },
84
+ Proc.new{|window,y,x|
85
+ window.mvaddstr(y, x, "O")
86
+ },
87
+ Proc.new{|window,y,x|
88
+ window.mvaddstr(y-1, x, "-")
89
+ window.mvaddstr(y, x-1, "|.|")
90
+ window.mvaddstr(y+1, x, "-")
91
+ },
92
+ Proc.new{|window,y,x|
93
+ window.mvaddstr(y-2, x, "-")
94
+ window.mvaddstr(y-1, x-1, "/ \\")
95
+ window.mvaddstr(y, x-2, "| O |")
96
+ window.mvaddstr(y+1, x-1, "\\ /")
97
+ window.mvaddstr(y+2, x, "-")
98
+ },
99
+ Proc.new{|window,y,x|
100
+ window.mvaddstr(y-2, x, " ")
101
+ window.mvaddstr(y-1, x-1, " ")
102
+ window.mvaddstr(y, x-2, " ")
103
+ window.mvaddstr(y+1, x-1, " ")
104
+ window.mvaddstr(y+2, x, " ")
105
+ nil # signal the last raindrop phase
106
+ }
107
+ ]
108
+ NUMBER_OF_PHASES = DRAWING_PROCS.size - 1
109
+ end
110
+
111
+
112
+ # This class creates raindrops and tells them to draw on the screen
113
+ class Rain
114
+ AVERAGE_RAINDROP_SPACE = 475.1 # 4 simultaneous raindrops in a 80x24 Window
115
+
116
+ def Rain.sigwinch_handler(sig = nil)
117
+ ObjectSpace.each_object(Rain){|rain|
118
+ rain.window_size_changed = true
119
+ }
120
+ end
121
+
122
+ attr_writer :window_size_changed
123
+
124
+ def initialize(window)
125
+ @window = window
126
+ @window_size_changed = true
127
+ @raindrops = []
128
+ @has_colors = Ncurses.has_colors?
129
+ if (@has_colors)
130
+ @current_color = 1
131
+ end
132
+ end
133
+
134
+ def fall_for_a_moment
135
+ adjust_to_new_window_size if (@window_size_changed)
136
+
137
+ current_number_of_new_raindrops.times{
138
+ if (@has_colors)
139
+ @raindrops.push(Raindrop.new(@window, @current_color))
140
+ @current_color = 3 - @current_color # alternate between 1 and 2
141
+ else
142
+ @raindrops.push(Raindrop.new(@window))
143
+ end
144
+ }
145
+
146
+ @raindrops = @raindrops.collect{|raindrop|
147
+ raindrop.draw_next_phase
148
+ }.compact # erase raindrops that have expired from the list
149
+ end
150
+
151
+ def adjust_to_new_window_size
152
+ @window_size_changed = false
153
+ window_size = @window.getmaxx * @window.getmaxy
154
+ average_number_of_raindrops = window_size / AVERAGE_RAINDROP_SPACE
155
+ @average_number_of_new_raindrops =
156
+ average_number_of_raindrops / Raindrop::NUMBER_OF_PHASES
157
+ end
158
+
159
+ def current_number_of_new_raindrops
160
+ num_floor = @average_number_of_new_raindrops.floor
161
+ num_ceil = @average_number_of_new_raindrops.ceil
162
+ chance = @average_number_of_new_raindrops - num_floor
163
+ if (rand > chance)
164
+ num_floor
165
+ else
166
+ num_ceil
167
+ end
168
+ end
169
+
170
+ def fall(pause = 0.1)
171
+ begin
172
+ fall_for_a_moment
173
+ @window.refresh
174
+ sleep(pause)
175
+ end while (true)
176
+ end
177
+ end
178
+
179
+ Ncurses.initscr
180
+ begin
181
+ if (Ncurses.has_colors?)
182
+ bg = Ncurses::COLOR_BLACK
183
+ Ncurses.start_color
184
+ if (Ncurses.respond_to?("use_default_colors"))
185
+ if (Ncurses.use_default_colors == Ncurses::OK)
186
+ bg = -1
187
+ end
188
+ end
189
+ Ncurses.init_pair(1, Ncurses::COLOR_BLUE, bg);
190
+ Ncurses.init_pair(2, Ncurses::COLOR_CYAN, bg);
191
+ end
192
+ Ncurses.nl()
193
+ Ncurses.noecho()
194
+ Ncurses.curs_set(0)
195
+ Ncurses.stdscr.nodelay(true)
196
+
197
+ rain = Rain.new(Ncurses.stdscr)
198
+
199
+ begin
200
+ case(Ncurses.getch())
201
+ when 'q'[0], 'Q'[0]
202
+ Ncurses.curs_set(1)
203
+ Ncurses.endwin()
204
+ exit
205
+ when 's'[0]
206
+ Ncurses.stdscr.nodelay(false)
207
+ when ' '[0]
208
+ Ncurses.stdscr.nodelay(true)
209
+ when Ncurses::KEY_RESIZE
210
+ Rain.sigwinch_handler
211
+ end
212
+ sleep(0.050)
213
+ rain.fall_for_a_moment
214
+ Ncurses.refresh
215
+ end while true
216
+ ensure
217
+ Ncurses.curs_set(1)
218
+ Ncurses.endwin()
219
+ end
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ # Emacs: This is -*- ruby -*- code!
3
+ #
4
+ # Unfinished read_line function
5
+ #
6
+ # Written 2003, 2004 by Tobias Peters
7
+ # No warranties
8
+ # Share and enjoy!
9
+
10
+ require "ncurses"
11
+
12
+ # read_line returns an array
13
+ # [string, last_cursor_position_in_string, keycode_of_terminating_enter_key].
14
+ # Complete the "when" clauses before including in your app!
15
+ def read_line(y, x,
16
+ window = Ncurses.stdscr,
17
+ max_len = (window.getmaxx - x - 1),
18
+ string = "",
19
+ cursor_pos = 0)
20
+ loop do
21
+ window.mvaddstr(y,x,string)
22
+ window.move(y,x+cursor_pos)
23
+ ch = window.getch
24
+ case ch
25
+ when Ncurses::KEY_LEFT
26
+ cursor_pos = [0, cursor_pos-1].max
27
+ when Ncurses::KEY_RIGHT
28
+ # similar, implement yourself !
29
+ when Ncurses::KEY_ENTER, ?\n, ?\r
30
+ return string, cursor_pos, ch # Which return key has been used?
31
+ when Ncurses::KEY_BACKSPACE
32
+ string = string[0...([0, cursor_pos-1].max)] + string[cursor_pos..-1]
33
+ cursor_pos = [0, cursor_pos-1].max
34
+ window.mvaddstr(y, x+string.length, " ")
35
+ # when etc...
36
+ when " "[0]..255 # remaining printables
37
+ if (cursor_pos < max_len)
38
+ string[cursor_pos,0] = ch.chr
39
+ cursor_pos += 1
40
+ else
41
+ Ncurses.beep
42
+ end
43
+ else
44
+ Ncurses.beep
45
+ end
46
+ end
47
+ end
48
+
49
+ if (__FILE__ == $0) then begin
50
+ # demo mode
51
+ Ncurses.initscr
52
+ Ncurses.cbreak
53
+ Ncurses.noecho
54
+
55
+ # recognize KEY_ENTER, KEY_BACKSPACE etc
56
+ Ncurses.keypad(Ncurses.stdscr, true)
57
+
58
+ y = 10
59
+ x = 2
60
+ prompt = "Hallo > "
61
+ Ncurses.mvaddstr(y,x, prompt)
62
+ s = read_line(y, x + prompt.length)
63
+
64
+ ensure
65
+ Ncurses.endwin
66
+ end end
67
+ p s
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: tclock.rb,v 1.6 2002/02/28 13:50:10 t-peters Exp $
4
+
5
+ # tclock - analog/digital clock for curses, translated to ruby
6
+ # Copyright (C) 2002 Tobias Peters <t-peters@users.berlios.de>
7
+ # This file was adapted from the C program tclock.c from the ncurses
8
+ # distribution, which bears the following copyright statement:
9
+
10
+ # tclock - analog/digital clock for curses.
11
+ # If it gives you joy, then
12
+ # (a) I'm glad
13
+ # (b) you need to get out more :-)
14
+ #
15
+ # This program is copyright Howard Jones, September 1994
16
+ # (ha.jones@ic.ac.uk). It may be freely distributed as
17
+ # long as this copyright message remains intact, and any
18
+ # modifications are clearly marked as such. [In fact, if
19
+ # you modify it, I wouldn't mind the modifications back,
20
+ # especially if they add any nice features. A good one
21
+ # would be a precalc table for the 60 hand positions, so
22
+ # that the floating point stuff can be ditched. As I said,
23
+ # it was a 20 hackup minute job.]
24
+ #
25
+ # COMING SOON: tfishtank. Be the envy of your mac-owning
26
+ # colleagues.
27
+
28
+ ###########################################################################
29
+ # The translation of this program to ruby is a modification and is hereby #
30
+ # clearly marked as such. #
31
+ ###########################################################################
32
+
33
+ require "ncurses"
34
+ PI = Math::PI
35
+
36
+ def sign(_x)
37
+ (_x<0?-1:1)
38
+ end
39
+
40
+ ASPECT = 2.2
41
+
42
+ def a2x(angle,radius)
43
+ (ASPECT * radius * Math::sin(angle)).round
44
+ end
45
+ def a2y(angle,radius)
46
+ (radius * Math::cos(angle)).round
47
+ end
48
+
49
+ # Plot a point
50
+ def plot(x, y, c)
51
+ Ncurses.mvaddch(y, x, c[0])
52
+ end
53
+
54
+ # Draw a diagonal(arbitrary) line using Bresenham's alogrithm.
55
+ def dline(pair, from_x, from_y, x2, y2, ch)
56
+ if (Ncurses.has_colors?)
57
+ Ncurses.attrset(Ncurses.COLOR_PAIR(pair))
58
+ end
59
+
60
+ dx = x2 - from_x;
61
+ dy = y2 - from_y;
62
+
63
+ ax = (dx * 2).abs
64
+ ay = (dy * 2).abs
65
+
66
+ sx = sign(dx);
67
+ sy = sign(dy);
68
+
69
+ x = from_x;
70
+ y = from_y;
71
+
72
+ if (ax > ay)
73
+ d = ay - (ax / 2);
74
+
75
+ while (1)
76
+ plot(x, y, ch);
77
+ if (x == x2)
78
+ return nil
79
+ end
80
+ if (d >= 0)
81
+ y += sy;
82
+ d -= ax;
83
+ end
84
+ x += sx;
85
+ d += ay;
86
+ end
87
+ else
88
+ d = ax - (ay / 2);
89
+
90
+ while (1)
91
+ plot(x, y, ch);
92
+ if (y == y2)
93
+ return nil;
94
+ end
95
+ if (d >= 0)
96
+ x += sx;
97
+ d -= ay;
98
+ end
99
+ y += sy;
100
+ d += ax;
101
+ end
102
+ end
103
+ end
104
+
105
+ begin
106
+ # int i, cx, cy;
107
+ # double mradius, hradius, mangle, hangle;
108
+ # double sangle, sradius, hours;
109
+ # int hdx, hdy;
110
+ # int mdx, mdy;
111
+ # int sdx, sdy;
112
+ # int ch;
113
+
114
+
115
+ lastbeep = -1;
116
+ my_bg = Ncurses::COLOR_BLACK;
117
+
118
+ Ncurses::initscr();
119
+ Ncurses::noecho();
120
+ Ncurses::cbreak();
121
+ Ncurses::nodelay(Ncurses::stdscr, TRUE);
122
+ Ncurses::curs_set(0);
123
+
124
+ if (Ncurses::has_colors?())
125
+ Ncurses::start_color();
126
+
127
+ Ncurses::init_pair(1, Ncurses::COLOR_RED, my_bg);
128
+ Ncurses::init_pair(2, Ncurses::COLOR_MAGENTA, my_bg);
129
+ Ncurses::init_pair(3, Ncurses::COLOR_GREEN, my_bg);
130
+ end
131
+ Ncurses::keypad(Ncurses::stdscr, TRUE);
132
+
133
+ while (:restart)
134
+ cx = (Ncurses.COLS - 1) / 2; #/* 39 */
135
+ cy = Ncurses.LINES / 2; #/* 12 */
136
+ ch = (cx > cy) ? cy : cx; #/* usually cy */
137
+ mradius = ((3 * cy) / 4).to_f; #/* 9 */
138
+ hradius = (cy / 2).to_f; #/* 6 */
139
+ sradius = ((2 * cy) / 3).to_f; #/* 8 */
140
+
141
+ for i in (0...12)
142
+ sangle = (i + 1) * (2.0 * PI) / 12.0;
143
+ sradius = ((5 * cy) / 6).to_f; #/* 10 */
144
+ sdx = a2x(sangle, sradius);
145
+ sdy = a2y(sangle, sradius);
146
+ szChar = sprintf("%d", i + 1);
147
+
148
+ Ncurses::mvaddstr(cy - sdy, cx + sdx, szChar);
149
+ end
150
+
151
+ Ncurses::mvaddstr(0, 0,
152
+ "ASCII Clock by Howard Jones (ha.jones@ic.ac.uk),1994");
153
+
154
+ sradius -=2
155
+ sradius = 1 if sradius < 1
156
+ window_size_changed = false
157
+ while (window_size_changed == false)
158
+ sleep(0.100);
159
+
160
+ hours = Time.now.hour + Time.now.min / 60.0;
161
+ if (hours > 12.0)
162
+ hours -= 12.0;
163
+ end
164
+
165
+ mangle = Time.now.min * (2 * PI) / 60.0;
166
+ mdx = a2x(mangle, mradius);
167
+ mdy = a2y(mangle, mradius);
168
+
169
+ hangle = ((hours) * (2.0 * PI) / 12.0);
170
+ hdx = a2x(hangle, hradius);
171
+ hdy = a2y(hangle, hradius);
172
+
173
+ sangle = ((Time.now.sec) * (2.0 * PI) / 60.0);
174
+ sdx = a2x(sangle, sradius);
175
+ sdy = a2y(sangle, sradius);
176
+
177
+ dline(3, cx, cy, cx + mdx, cy - mdy, '#');
178
+
179
+ Ncurses::attrset(Ncurses::A_REVERSE);
180
+ dline(2, cx, cy, cx + hdx, cy - hdy, '.');
181
+ Ncurses::attroff(Ncurses::A_REVERSE);
182
+
183
+ if (Ncurses::has_colors?())
184
+ Ncurses::attrset(Ncurses::COLOR_PAIR(1));
185
+ end
186
+ plot(cx + sdx, cy - sdy, 'O');
187
+
188
+ if (Ncurses::has_colors?())
189
+ Ncurses::attrset(Ncurses::COLOR_PAIR(0));
190
+ end
191
+ Ncurses::mvaddstr(Ncurses.LINES - 2, 0, Time.now.to_s);
192
+ Ncurses::refresh();
193
+ if ((Time.now.sec % 5) == 0 &&
194
+ Time.now.sec != lastbeep)
195
+ lastbeep = Time.now.sec;
196
+ Ncurses::beep();
197
+ end
198
+
199
+ if ((ch = Ncurses::getch()) != Ncurses::ERR)
200
+ if (ch == Ncurses::KEY_RESIZE)
201
+ Ncurses::erase();
202
+ window_size_changed = true;
203
+ else
204
+ break;
205
+ end
206
+ end
207
+
208
+ plot(cx + sdx, cy - sdy, ' ');
209
+ dline(0, cx, cy, cx + hdx, cy - hdy, ' ');
210
+ dline(0, cx, cy, cx + mdx, cy - mdy, ' ');
211
+
212
+ end
213
+
214
+ if ! window_size_changed
215
+ $stderr.puts "! window_size_changed"
216
+ break
217
+ end
218
+ end
219
+ ensure
220
+ Ncurses::curs_set(1);
221
+ Ncurses::endwin();
222
+ end
223
+
224
+
225
+
226
+
227
+