rndk 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -4
  3. data/TODO +21 -1
  4. data/demos/appointment.rb +279 -299
  5. data/demos/clock.rb +13 -8
  6. data/demos/rss-reader.rb +84 -0
  7. data/examples/01-hello-world.rb +13 -11
  8. data/examples/02-colors.rb +14 -21
  9. data/examples/03-markup.rb +7 -7
  10. data/examples/04-quick-widgets.rb +2 -2
  11. data/examples/05-position-widget.rb +50 -31
  12. data/examples/06-callbacks.rb +77 -0
  13. data/examples/07-traverse.rb +90 -0
  14. data/examples/10-all-widgets.rb +165 -0
  15. data/examples/calendar.rb +20 -32
  16. data/examples/entry.rb +15 -20
  17. data/examples/label.rb +11 -11
  18. data/examples/scroll.rb +16 -60
  19. data/examples/slider.rb +18 -19
  20. data/examples/viewer.rb +65 -0
  21. data/lib/rndk.rb +28 -7
  22. data/lib/rndk/alphalist.rb +309 -313
  23. data/lib/rndk/button.rb +239 -157
  24. data/lib/rndk/buttonbox.rb +136 -103
  25. data/lib/rndk/calendar.rb +246 -203
  26. data/lib/rndk/core/color.rb +63 -13
  27. data/lib/rndk/core/display.rb +1 -1
  28. data/lib/rndk/core/draw.rb +11 -11
  29. data/lib/rndk/core/markup.rb +21 -21
  30. data/lib/rndk/core/quick_widgets.rb +75 -96
  31. data/lib/rndk/core/screen.rb +145 -102
  32. data/lib/rndk/core/traverse.rb +150 -136
  33. data/lib/rndk/core/utils.rb +5 -6
  34. data/lib/rndk/core/widget.rb +207 -191
  35. data/lib/rndk/core/widget_bind.rb +108 -0
  36. data/lib/rndk/dialog.rb +88 -56
  37. data/lib/rndk/entry.rb +79 -64
  38. data/lib/rndk/fscale.rb +38 -20
  39. data/lib/rndk/fslider.rb +38 -23
  40. data/lib/rndk/graph.rb +92 -53
  41. data/lib/rndk/itemlist.rb +80 -62
  42. data/lib/rndk/label.rb +111 -77
  43. data/lib/rndk/radio.rb +138 -128
  44. data/lib/rndk/scale.rb +123 -122
  45. data/lib/rndk/scroll.rb +444 -391
  46. data/lib/rndk/scroller.rb +21 -21
  47. data/lib/rndk/slider.rb +149 -140
  48. data/lib/rndk/template.rb +74 -61
  49. data/lib/rndk/version.rb +1 -1
  50. data/lib/rndk/viewer.rb +499 -298
  51. metadata +8 -14
  52. data/demos/fileview.rb +0 -141
  53. data/lib/rndk/dscale.rb +0 -13
  54. data/lib/rndk/fselect.rb +0 -938
  55. data/lib/rndk/histogram.rb +0 -412
  56. data/lib/rndk/marquee.rb +0 -244
  57. data/lib/rndk/matrix.rb +0 -1189
  58. data/lib/rndk/mentry.rb +0 -619
  59. data/lib/rndk/menu.rb +0 -478
  60. data/lib/rndk/selection.rb +0 -630
  61. data/lib/rndk/swindow.rb +0 -766
  62. data/lib/rndk/uscale.rb +0 -14
  63. data/lib/rndk/uslider.rb +0 -14
@@ -1,31 +1,85 @@
1
1
  require 'rndk'
2
2
 
3
3
  module RNDK
4
- class BUTTON < Widget
5
- def initialize(rndkscreen, xplace, yplace, text, callback, box, shadow)
4
+
5
+ class Button < Widget
6
+
7
+ # A button with a label attached to a callback.
8
+ #
9
+ # ## Settings
10
+ #
11
+ # * `x` is the x position - can be an integer or `RNDK::LEFT`,
12
+ # `RNDK::RIGHT`, `RNDK::CENTER`.
13
+ # * `y` is the y position - can be an integer or `RNDK::TOP`,
14
+ # `RNDK::BOTTOM`, `RNDK::CENTER`.
15
+ # * `label` is the String that will appear on the button.
16
+ # * `action` is a Proc that will execute when the button is
17
+ # pressed.
18
+ # * `box` if the Widget is drawn with a box outside it.
19
+ # * `shadow` turns on/off the shadow around the Widget.
20
+ #
21
+ # ## Usage
22
+ # ```
23
+ # b = RNDK::Button.new(screen, {
24
+ # :x => 50,
25
+ # :y => 8,
26
+ # :label => "</77>button",
27
+ # })
28
+ #
29
+ # b.bind_signal(:pressed) do
30
+ # screen.popup_label "Button pressed"
31
+ # end
32
+ # ```
33
+ #
34
+ # @note When binding signals, remember that if you return
35
+ # `false` it stops executing other signals.
36
+ # So that's a nice idea for a `:before_pressing`
37
+ # signal that asks the user if he's certain of pressing.
38
+ def initialize(screen, config={})
6
39
  super()
7
- parent_width = Ncurses.getmaxx(rndkscreen.window)
8
- parent_height = Ncurses.getmaxy(rndkscreen.window)
40
+ @widget_type = :button
41
+ @supported_signals += [:before_pressing, :pressed]
42
+
43
+ x = 0
44
+ y = 0
45
+ label = "button"
46
+ action = nil
47
+ box = true
48
+ shadow = false
49
+
50
+ config.each do |key, val|
51
+ x = val if key == :x
52
+ y = val if key == :y
53
+ label = val if key == :label
54
+ action = val if key == :action
55
+ box = val if key == :box
56
+ shadow = val if key == :shadow
57
+ end
58
+
59
+ parent_width = Ncurses.getmaxx screen.window
60
+ parent_height = Ncurses.getmaxy screen.window
9
61
  box_width = 0
10
- xpos = xplace
11
- ypos = yplace
62
+ x = x
63
+ y = y
12
64
 
13
- self.set_box(box)
65
+ self.set_box box
14
66
  box_height = 1 + 2 * @border_size
15
67
 
16
68
  # Translate the string to a chtype array.
17
69
  info_len = []
18
70
  info_pos = []
19
- @info = RNDK.char2Chtype(text, info_len, info_pos)
71
+ @info = RNDK.char2Chtype(label, info_len, info_pos)
20
72
  @info_len = info_len[0]
21
73
  @info_pos = info_pos[0]
22
74
  box_width = [box_width, @info_len].max + 2 * @border_size
23
75
 
24
76
  # Create the string alignments.
25
77
  @info_pos = RNDK.justifyString(box_width - 2 * @border_size,
26
- @info_len, @info_pos)
78
+ @info_len,
79
+ @info_pos)
27
80
 
28
- # Make sure we didn't extend beyond the dimensions of the window.
81
+ # Make sure we didn't extend beyond the dimensions of the
82
+ # window.
29
83
  box_width = if box_width > parent_width
30
84
  then parent_width
31
85
  else box_width
@@ -36,23 +90,22 @@ module RNDK
36
90
  end
37
91
 
38
92
  # Rejustify the x and y positions if we need to.
39
- xtmp = [xpos]
40
- ytmp = [ypos]
41
- RNDK.alignxy(rndkscreen.window, xtmp, ytmp, box_width, box_height)
42
- xpos = xtmp[0]
43
- ypos = ytmp[0]
93
+ xtmp = [x]
94
+ ytmp = [y]
95
+ RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
96
+ x = xtmp[0]
97
+ y = ytmp[0]
44
98
 
45
99
  # Create the button.
46
- @screen = rndkscreen
100
+ @screen = screen
47
101
  # ObjOf (button)->fn = &my_funcs;
48
- @parent = rndkscreen.window
49
- @win = Ncurses.newwin(box_height, box_width, ypos, xpos)
102
+ @parent = screen.window
103
+ @win = Ncurses.newwin(box_height, box_width, y, x)
50
104
  @shadow_win = nil
51
- @xpos = xpos
52
- @ypos = ypos
105
+ @x = x
106
+ @y = y
53
107
  @box_width = box_width
54
108
  @box_height = box_height
55
- @callback = callback
56
109
  @input_window = @win
57
110
  @accepts_focus = true
58
111
  @shadow = shadow
@@ -64,76 +117,73 @@ module RNDK
64
117
 
65
118
  Ncurses.keypad(@win, true)
66
119
 
67
- # If a shadow was requested, then create the shadow window.
68
- if shadow
69
- @shadow_win = Ncurses.newwin(box_height, box_width,
70
- ypos + 1, xpos + 1)
71
- end
120
+ set_shadow @shadow
72
121
 
73
122
  # Register this baby.
74
- rndkscreen.register(:BUTTON, self)
123
+ screen.register(@widget_type, self)
75
124
  end
76
125
 
77
- # This was added for the builder.
78
- def activate(actions)
79
- self.draw(@box)
80
- ret = -1
81
-
82
- if actions.nil? || actions.size == 0
83
- while true
84
- input = self.getch([])
85
-
86
- # Inject the character into the widget.
87
- ret = self.inject(input)
88
- if @exit_type != :EARLY_EXIT
89
- return ret
90
- end
91
- end
92
- else
93
- # Inject each character one at a time.
94
- actions.each do |x|
95
- ret = self.inject(action)
96
- if @exit_type == :EARLY_EXIT
97
- return ret
98
- end
99
- end
126
+ # Sets multiple attributes of the Widget.
127
+ #
128
+ # See Button#initialize.
129
+ #
130
+ # @note Don't try to change `x`/`y` positions here,
131
+ # use Button#move
132
+ # @note Don't try to change `action` here,
133
+ # use TODO
134
+ def set(config)
135
+ label = @label
136
+ box = @box
137
+ shadow = @shadow
138
+
139
+ config.each do |key, val|
140
+ label = val if key == :label
141
+ box = val if key == :box
142
+ shadow = val if key == :shadow
100
143
  end
101
144
 
102
- # Set the exit type and exit
103
- self.set_exit_type(0)
104
- return -1
105
- end
106
-
107
- # This sets multiple attributes of the widget.
108
- def set(mesg, box)
109
- self.set_message(mesg)
110
- self.set_box(box)
145
+ self.set_label(label) if label != @label
146
+ self.set_box(box) if box != @box
147
+ self.set_shadow(shadow) if shadow != @shadow
111
148
  end
112
149
 
113
- # This sets the information within the button.
114
- def set_message(info)
115
- info_len = []
116
- info_pos = []
117
- @info = RNDK.char2Chtype(info, info_len, info_pos)
118
- @info_len = info_len[0]
119
- @info_pos = RNDK.justifyString(@box_width - 2 * @border_size,
120
- info_pos[0])
150
+ # Sets the text within the button.
151
+ def set_label label
152
+ label_len = []
153
+ label_pos = []
154
+ @label = RNDK.char2Chtype(label, label_len, label_pos)
155
+ @label_len = label_len[0]
156
+ @label_pos = RNDK.justifyString(@box_width - 2 * @border_size,
157
+ label_pos[0])
121
158
 
122
159
  # Redraw the button widget.
123
160
  self.erase
124
161
  self.draw(box)
125
162
  end
126
163
 
127
- def get_message
164
+ def get_label
128
165
  return @info
129
166
  end
130
167
 
168
+ # Turns on/off the shadow around the window
169
+ def set_shadow option
170
+ if option and @shadow_win.nil?
171
+ @shadow_win = Ncurses.newwin(box_height,
172
+ box_width,
173
+ y + 1,
174
+ x + 1)
175
+
176
+ elsif (not option) and (not @shadow_win.nil?)
177
+ RNDK::window_delete @shadow_win
178
+ end
179
+ end
180
+
131
181
  # This sets the background attribute of the widget.
132
- def set_bg_attrib(attrib)
182
+ def set_bg_color(attrib)
133
183
  Ncurses.wbkgd(@win, attrib)
134
184
  end
135
185
 
136
- def drawText
186
+ def draw_label
137
187
  box_width = @box_width
138
188
 
139
189
  # Draw in the message.
@@ -147,7 +197,7 @@ module RNDK
147
197
  end
148
198
 
149
199
  if @has_focus
150
- c = Ncurses::A_REVERSE | c
200
+ c = RNDK::Color[:reverse] | c
151
201
  end
152
202
 
153
203
  Ncurses.mvwaddch(@win, @border_size, i + @border_size, c)
@@ -155,52 +205,51 @@ module RNDK
155
205
  end
156
206
 
157
207
  # This draws the button widget
158
- def draw(box)
208
+ def draw
159
209
  # Is there a shadow?
160
210
  unless @shadow_win.nil?
161
211
  Draw.drawShadow(@shadow_win)
162
212
  end
163
213
 
164
214
  # Box the widget if asked.
165
- if @box
166
- Draw.drawObjBox(@win, self)
167
- end
168
- self.drawText
215
+ Draw.drawObjBox(@win, self) if @box
216
+
217
+ self.draw_label
169
218
  Ncurses.wrefresh @win
170
219
  end
171
220
 
172
221
  # This erases the button widget.
173
222
  def erase
174
- if self.valid_widget?
223
+ if self.valid?
175
224
  RNDK.window_erase(@win)
176
225
  RNDK.window_erase(@shadow_win)
177
226
  end
178
227
  end
179
228
 
180
229
  # @see Widget#move
181
- def move(xplace, yplace, relative, refresh_flag)
230
+ def move(x, y, relative, refresh_flag)
182
231
  current_x = Ncurses.getbegx(@win)
183
232
  current_y = Ncurses.getbegy(@win)
184
- xpos = xplace
185
- ypos = yplace
233
+ x = x
234
+ y = y
186
235
 
187
236
  # If this is a relative move, then we will adjust where we want
188
237
  # to move to.
189
238
  if relative
190
- xpos = Ncurses.getbegx(@win) + xplace
191
- ypos = Ncurses.getbegy(@win) + yplace
239
+ x = Ncurses.getbegx(@win) + x
240
+ y = Ncurses.getbegy(@win) + y
192
241
  end
193
242
 
194
243
  # Adjust the window if we need to.
195
- xtmp = [xpos]
196
- ytmp = [ypos]
244
+ xtmp = [x]
245
+ ytmp = [y]
197
246
  RNDK.alignxy(@screen.window, xtmp, ytmp, @box_width, @box_height)
198
- xpos = xtmp[0]
199
- ypos = ytmp[0]
247
+ x = xtmp[0]
248
+ y = ytmp[0]
200
249
 
201
250
  # Get the difference
202
- xdiff = current_x - xpos
203
- ydiff = current_y - ypos
251
+ xdiff = current_x - x
252
+ ydiff = current_y - y
204
253
 
205
254
  # Move the window to the new location.
206
255
  RNDK.window_move(@win, -xdiff, -ydiff)
@@ -211,12 +260,110 @@ module RNDK
211
260
 
212
261
  # Redraw the window, if they asked for it.
213
262
  if refresh_flag
214
- self.draw(@box)
263
+ self.draw
215
264
  end
216
265
  end
217
266
 
218
- # This allows the user to use the cursor keys to adjust the
219
- # position of the widget.
267
+ # This destroys the button widget pointer.
268
+ def destroy
269
+ RNDK.window_delete @shadow_win
270
+ RNDK.window_delete @win
271
+
272
+ self.clean_bindings
273
+
274
+ @screen.unregister self
275
+ end
276
+
277
+ # Activates the Widget, letting the user interact with it.
278
+ #
279
+ # `actions` is an Array of characters. If it's non-null,
280
+ # will #inject each char on it into the Widget.
281
+ #
282
+ # @return `true` if pressed, `false` elsewhere.
283
+ def activate(actions=[])
284
+ self.draw
285
+ ret = false
286
+
287
+ if actions.nil? || actions.size == 0
288
+ while true
289
+ input = self.getch
290
+
291
+ # Inject the character into the widget.
292
+ ret = self.inject input
293
+
294
+ return ret if @exit_type != :EARLY_EXIT
295
+ end
296
+ else
297
+ # Inject each character one at a time.
298
+ actions.each do |x|
299
+ ret = self.inject action
300
+
301
+ return ret if @exit_type == :EARLY_EXIT
302
+ end
303
+ end
304
+
305
+ # Set the exit type and exit
306
+ self.set_exit_type(0)
307
+ return false
308
+ end
309
+
310
+ # This injects a single character into the widget.
311
+ def inject input
312
+ ret = false
313
+ complete = false
314
+
315
+ self.set_exit_type(0)
316
+
317
+ # Check a predefined binding.
318
+ if self.is_bound? input
319
+ self.run_key_binding input
320
+ #complete = true
321
+
322
+ else
323
+ case input
324
+ when RNDK::KEY_ESC, Ncurses::ERR
325
+ self.set_exit_type(input)
326
+ complete = true
327
+
328
+ when ' '.ord, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
329
+ keep_going = self.run_signal_binding(:before_pressing)
330
+
331
+ # RUBY DOESN'T HAVE BREAK INSIDE CASE..WHEN BLOCKS
332
+ # AGHGW
333
+
334
+ if keep_going
335
+ self.run_signal_binding(:pressed)
336
+ self.set_exit_type(Ncurses::KEY_ENTER)
337
+ ret = true
338
+ complete = true
339
+ end
340
+
341
+ when RNDK::REFRESH
342
+ @screen.erase
343
+ @screen.refresh
344
+
345
+ else
346
+ RNDK.beep
347
+ end
348
+ end
349
+
350
+ self.set_exit_type(0) unless complete
351
+
352
+ @result_data = ret
353
+ ret
354
+ end
355
+
356
+ def focus
357
+ self.draw_label
358
+ Ncurses.wrefresh @win
359
+ end
360
+
361
+ def unfocus
362
+ self.draw_label
363
+ Ncurses.wrefresh @win
364
+ end
365
+
366
+ # @see Widget#position
220
367
  def position
221
368
  # Declare some variables
222
369
  orig_x = Ncurses.getbegx(@win)
@@ -225,7 +372,7 @@ module RNDK
225
372
 
226
373
  # Let them move the widget around until they hit return
227
374
  while key != Ncurses::KEY_ENTER && key != RNDK::KEY_RETURN
228
- key = self.getch([])
375
+ key = self.getch
229
376
  if key == Ncurses::KEY_UP || key == '8'.ord
230
377
  if Ncurses.getbegy(@win) > 0
231
378
  self.move(0, -1, true, true)
@@ -302,71 +449,6 @@ module RNDK
302
449
  end
303
450
  end
304
451
 
305
- # This destroys the button object pointer.
306
- def destroy
307
- RNDK.window_delete(@shadow_win)
308
- RNDK.window_delete(@win)
309
-
310
- self.clean_bindings(:BUTTON)
311
-
312
- RNDK::Screen.unregister(:BUTTON, self)
313
- end
314
-
315
- # This injects a single character into the widget.
316
- def inject(input)
317
- ret = -1
318
- complete = false
319
-
320
- self.set_exit_type(0)
321
-
322
- # Check a predefined binding.
323
- if self.checkBind(:BUTTON, input)
324
- complete = true
325
- else
326
- case input
327
- when RNDK::KEY_ESC
328
- self.set_exit_type(input)
329
- complete = true
330
- when Ncurses::ERR
331
- self.set_exit_type(input)
332
- complete = true
333
- when ' '.ord, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
334
- unless @callback.nil?
335
- @callback.call(self)
336
- end
337
- self.set_exit_type(Ncurses::KEY_ENTER)
338
- ret = 0
339
- complete = true
340
- when RNDK::REFRESH
341
- @screen.erase
342
- @screen.refresh
343
- else
344
- RNDK.beep
345
- end
346
- end
347
-
348
- unless complete
349
- self.set_exit_type(0)
350
- end
351
-
352
- @result_data = ret
353
- return ret
354
- end
355
-
356
- def focus
357
- self.drawText
358
- Ncurses.wrefresh @win
359
- end
360
-
361
- def unfocus
362
- self.drawText
363
- Ncurses.wrefresh @win
364
- end
365
-
366
- def object_type
367
- :BUTTON
368
- end
369
-
370
452
  end
371
453
  end
372
454