ncurses-ruby 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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
+