rndk 0.2.0 → 1.0.0

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.
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
@@ -21,7 +21,7 @@ module RNDK
21
21
  end
22
22
 
23
23
  # This looks for a subset of a word in the given list
24
- def RNDK.searchList(list, list_size, pattern)
24
+ def RNDK.search_list(list, list_size, pattern)
25
25
  index = -1
26
26
 
27
27
  if pattern.size > 0
@@ -92,7 +92,7 @@ module RNDK
92
92
  # If the dimension is a negative value, the dimension will be the full
93
93
  # height/width of the parent window - the value of the dimension. Otherwise,
94
94
  # the dimension will be the given value.
95
- def RNDK.setWidgetDimension (parent_dim, proposed_dim, adjustment)
95
+ def RNDK.set_widget_dimension (parent_dim, proposed_dim, adjustment)
96
96
  # If the user passed in FULL, return the parents size
97
97
  if proposed_dim == FULL or proposed_dim == 0
98
98
  parent_dim
@@ -119,7 +119,7 @@ module RNDK
119
119
  # Reads a file and concatenate it's lines into `array`.
120
120
  #
121
121
  # @note The lines don't end with '\n'.
122
- def RNDK.read_file(filename, array)
122
+ def RNDK.read_file filename
123
123
  begin
124
124
  fd = File.new(filename, "r")
125
125
  rescue
@@ -133,10 +133,9 @@ module RNDK
133
133
  line
134
134
  end
135
135
  end
136
-
137
- array.concat lines
138
136
  fd.close
139
- array.size
137
+
138
+ lines
140
139
  end
141
140
 
142
141
  end
@@ -1,21 +1,31 @@
1
1
  require 'rndk'
2
+ require 'rndk/core/widget_bind'
2
3
 
3
4
  module RNDK
4
5
 
5
6
  # Wrapper on common functionality between all RNDK Widgets.
6
7
  #
7
8
  class Widget
9
+ # Which widget this is.
10
+ # It's the name of the widget lowercased.
11
+ # Example: `:label`, `:calendar`, `:alphalist`
12
+ attr_reader :widget_type
13
+
8
14
  attr_accessor :screen_index, :screen, :has_focus, :is_visible, :box
9
15
  attr_accessor :ULChar, :URChar, :LLChar, :LRChar, :HZChar, :VTChar, :BXAttr
10
16
  attr_reader :binding_list, :accepts_focus, :exit_type, :border_size
11
17
 
18
+ # All the signals the current widget supports.
19
+ # Use them on Widget#bind_signal
20
+ attr_reader :supported_signals
21
+
12
22
  @@g_paste_buffer = ''
13
23
 
14
24
  def initialize
15
25
  @has_focus = true
16
26
  @is_visible = true
17
27
 
18
- RNDK::ALL_OBJECTS << self
28
+ RNDK::ALL_WIDGETS << self
19
29
 
20
30
  # set default line-drawing characters
21
31
  @ULChar = Ncurses::ACS_ULCORNER
@@ -24,7 +34,7 @@ module RNDK
24
34
  @LRChar = Ncurses::ACS_LRCORNER
25
35
  @HZChar = Ncurses::ACS_HLINE
26
36
  @VTChar = Ncurses::ACS_VLINE
27
- @BXAttr = Ncurses::A_NORMAL
37
+ @BXAttr = RNDK::Color[:normal]
28
38
 
29
39
  # set default exit-types
30
40
  @exit_type = :NEVER_ACTIVATED
@@ -34,16 +44,49 @@ module RNDK
34
44
 
35
45
  # Bound functions
36
46
  @binding_list = {}
47
+
48
+ # Actions to be executed at certain signals
49
+ @actions = {}
50
+
51
+ @supported_signals = []
52
+ @supported_signals << :destroy
37
53
  end
38
54
 
39
- def object_type
40
- # no type by default
41
- :NULL
55
+ # Makes `block` execute right before processing input
56
+ # on the Widget.
57
+ #
58
+ # `block` is called with the following arguments:
59
+ #
60
+ # * The Widget type (`:scroll`, `:calendar`, etc)
61
+ # * The Widget itself (`self`)
62
+ # * That `data` you send as an argument to `before_processing`.
63
+ # * The input character the Widget just received.
64
+ #
65
+ # Make good use of them when making your callback.
66
+ def before_processing(data=nil, &block)
67
+ @pre_process_data = data
68
+ @pre_process_func = block
42
69
  end
43
70
 
44
- def validObjType(type)
45
- # dummy version for now
46
- true
71
+ # Makes `block` execute right after processing input
72
+ # on the Widget.
73
+ #
74
+ # `block` is called with the following arguments:
75
+ #
76
+ # * The Widget type (`:scroll`, `:calendar`, etc)
77
+ # * The Widget itself (`self`)
78
+ # * That `data` you send as an argument to `after_processing`.
79
+ # * The input character the Widget just received.
80
+ #
81
+ # Make good use of them when making your callback.
82
+ def after_processing(data=nil, &block)
83
+ @post_process_data = data
84
+ @post_process_func = block
85
+ end
86
+
87
+ def widget_type
88
+ # no type by default
89
+ :NULL
47
90
  end
48
91
 
49
92
  def Screen_XPOS(n)
@@ -64,19 +107,19 @@ module RNDK
64
107
 
65
108
  # Moves the Widget to the given position.
66
109
  #
67
- # * `xplace` and `yplace` are the new position of the Widget.
110
+ # * `x` and `y` are the new position of the Widget.
68
111
  #
69
- # * `xplace` may be an integer or one of the pre-defined
112
+ # * `x` may be an integer or one of the pre-defined
70
113
  # values `RNDK::TOP`, `RNDK::BOTTOM`, and `RNDK::CENTER`.
71
114
  #
72
- # * `yplace` may be an integer or one of the pre-defined
115
+ # * `y` may be an integer or one of the pre-defined
73
116
  # values `RNDK::LEFT`, `RNDK::RIGHT`, and `RNDK::CENTER`.
74
117
  #
75
- # * `relative` states whether the `xplace`/`yplace` pair is a
118
+ # * `relative` states whether the `x`/`y` pair is a
76
119
  # relative move over it's current position or an absolute move
77
120
  # over the Screen's top.
78
121
  #
79
- # For example, if `xplace = 1` and `yplace = 2` and `relative = true`,
122
+ # For example, if `x = 1` and `y = 2` and `relative = true`,
80
123
  # the Widget would move one row down and two columns right.
81
124
  #
82
125
  # If the value of relative was `false` then the widget would move to
@@ -88,49 +131,51 @@ module RNDK
88
131
  # * `refresh_flag` is a boolean value which states whether the
89
132
  # Widget will get refreshed after the move.
90
133
  #
91
- def move(xplace, yplace, relative, refresh_flag)
92
- self.move_specific(xplace, yplace, relative, refresh_flag, [@win, @shadow_win], [])
134
+ def move(x, y, relative, refresh_flag)
135
+ self.move_specific(x, y, relative, refresh_flag, [@win, @shadow_win], [])
93
136
  end
94
137
 
95
- def move_specific(xplace, yplace, relative, refresh_flag, windows, subwidgets)
96
- current_x = Ncurses.getbegx @win
97
- current_y = Ncurses.getbegy @win
98
- xpos = xplace
99
- ypos = yplace
100
-
101
- # If this is a relative move, then we will adjust where we want
102
- # to move to.
103
- if relative
104
- xpos = Ncurses.getbegx(@win) + xplace
105
- ypos = Ncurses.getbegy(@win) + yplace
106
- end
107
-
108
- # Adjust the window if we need to
109
- xtmp = [xpos]
110
- ytmp = [ypos]
111
- RNDK.alignxy(@screen.window, xtmp, ytmp, @box_width, @box_height)
112
- xpos = xtmp[0]
113
- ypos = ytmp[0]
138
+ # Set the widget's title.
139
+ def set_title(title, box_width)
140
+ return if title.nil?
114
141
 
115
- # Get the difference
116
- xdiff = current_x - xpos
117
- ydiff = current_y - ypos
142
+ temp = title.split "\n"
143
+ @title_lines = temp.size
118
144
 
119
- # Move the window to the new location.
120
- windows.each do |window|
121
- RNDK.window_move(window, -xdiff, -ydiff)
145
+ if box_width >= 0
146
+ max_width = 0
147
+ temp.each do |line|
148
+ len = []
149
+ align = []
150
+ holder = RNDK.char2Chtype(line, len, align)
151
+ max_width = [len[0], max_width].max
152
+ end
153
+ box_width = [box_width, max_width + 2 * @border_size].max
154
+ else
155
+ box_width = -(box_width - 1)
122
156
  end
123
157
 
124
- subwidgets.each do |subwidget|
125
- subwidget.move(xplace, yplace, relative, false)
158
+ # For each line in the title convert from string to chtype array
159
+ title_width = box_width - (2 * @border_size)
160
+ @title = []
161
+ @title_pos = []
162
+ @title_len = []
163
+ (0...@title_lines).each do |x|
164
+ len_x = []
165
+ pos_x = []
166
+ @title << RNDK.char2Chtype(temp[x], len_x, pos_x)
167
+ @title_len.concat(len_x)
168
+ @title_pos << RNDK.justifyString(title_width, len_x[0], pos_x[0])
126
169
  end
170
+ box_width
171
+ end
127
172
 
128
- # Touch the windows so they 'move'
129
- RNDK.window_refresh @screen.window
130
-
131
- # Redraw the window, if they asked for it
132
- if refresh_flag
133
- self.draw(@box)
173
+ # Draw the widget's title
174
+ def draw_title(win)
175
+ (0...@title_lines).each do |x|
176
+ Draw.writeChtype(@win, @title_pos[x] + @border_size,
177
+ x + @border_size, @title[x], RNDK::HORIZONTAL, 0,
178
+ @title_len[x])
134
179
  end
135
180
  end
136
181
 
@@ -142,15 +187,18 @@ module RNDK
142
187
  # Besides normal keybindings (arrow keys and such), see
143
188
  # Widget#set_exit_type to see how the Widget exits.
144
189
  #
145
- def inject char
190
+ def inject input
146
191
  end
147
192
 
148
- def set_box(box)
193
+ # Makes the widget have a border if `box` is true,
194
+ # otherwise, cancel it.
195
+ def set_box box
149
196
  @box = box
150
197
  @border_size = if @box then 1 else 0 end
151
198
  end
152
199
 
153
- def getBox
200
+ # Tells if the widget has borders.
201
+ def get_box
154
202
  return @box
155
203
  end
156
204
 
@@ -160,10 +208,23 @@ module RNDK
160
208
  def unfocus
161
209
  end
162
210
 
163
- def saveData
211
+ # Somehow saves all data within this Widget.
212
+ #
213
+ # @note This method isn't called whatsoever!
214
+ # It only exists at Traverse module.
215
+ #
216
+ # TODO Find out how can I insert this on Widgets.
217
+ def save_data
164
218
  end
165
219
 
166
- def refreshData
220
+
221
+ # Somehow refreshes all data within this Widget.
222
+ #
223
+ # @note This method isn't called whatsoever!
224
+ # It only exists at Traverse module.
225
+ #
226
+ # TODO Find out how can I insert this on Widgets.
227
+ def refresh_data
167
228
  end
168
229
 
169
230
  # Destroys all windows inside the Widget and
@@ -171,42 +232,44 @@ module RNDK
171
232
  def destroy
172
233
  end
173
234
 
174
- # Set the object's upper-left-corner line-drawing character.
235
+ # Set the widget's upper-left-corner line-drawing character.
175
236
  def setULchar(ch)
176
237
  @ULChar = ch
177
238
  end
178
239
 
179
- # Set the object's upper-right-corner line-drawing character.
240
+ # Set the widget's upper-right-corner line-drawing character.
180
241
  def setURchar(ch)
181
242
  @URChar = ch
182
243
  end
183
244
 
184
- # Set the object's lower-left-corner line-drawing character.
245
+ # Set the widget's lower-left-corner line-drawing character.
185
246
  def setLLchar(ch)
186
247
  @LLChar = ch
187
248
  end
188
249
 
189
- # Set the object's upper-right-corner line-drawing character.
250
+ # Set the widget's upper-right-corner line-drawing character.
190
251
  def setLRchar(ch)
191
252
  @LRChar = ch
192
253
  end
193
254
 
194
- # Set the object's horizontal line-drawing character
255
+ # Set the widget's horizontal line-drawing character
195
256
  def setHZchar(ch)
196
257
  @HZChar = ch
197
258
  end
198
259
 
199
- # Set the object's vertical line-drawing character
260
+ # Set the widget's vertical line-drawing character
200
261
  def setVTchar(ch)
201
262
  @VTChar = ch
202
263
  end
203
264
 
204
- # Set the object's box-attributes.
265
+ # Set the widget's box-attributes.
205
266
  def setBXattr(ch)
206
267
  @BXAttr = ch
207
268
  end
208
269
 
209
270
  # This sets the background color of the widget.
271
+ #
272
+ # FIXME BUG
210
273
  def set_bg_color color
211
274
  return if color.nil? || color == ''
212
275
 
@@ -224,67 +287,11 @@ module RNDK
224
287
  self.SetBackAttrObj(holder[0])
225
288
  end
226
289
 
227
- # Set the widget's title.
228
- def set_title (title, box_width)
229
- return if title.nil?
230
-
231
- temp = title.split "\n"
232
- @title_lines = temp.size
233
-
234
- if box_width >= 0
235
- max_width = 0
236
- temp.each do |line|
237
- len = []
238
- align = []
239
- holder = RNDK.char2Chtype(line, len, align)
240
- max_width = [len[0], max_width].max
241
- end
242
- box_width = [box_width, max_width + 2 * @border_size].max
243
- else
244
- box_width = -(box_width - 1)
245
- end
246
-
247
- # For each line in the title convert from string to chtype array
248
- title_width = box_width - (2 * @border_size)
249
- @title = []
250
- @title_pos = []
251
- @title_len = []
252
- (0...@title_lines).each do |x|
253
- len_x = []
254
- pos_x = []
255
- @title << RNDK.char2Chtype(temp[x], len_x, pos_x)
256
- @title_len.concat(len_x)
257
- @title_pos << RNDK.justifyString(title_width, len_x[0], pos_x[0])
258
- end
259
- box_width
260
- end
261
-
262
- # Draw the widget's title
263
- def drawTitle(win)
264
- (0...@title_lines).each do |x|
265
- Draw.writeChtype(@win, @title_pos[x] + @border_size,
266
- x + @border_size, @title[x], RNDK::HORIZONTAL, 0,
267
- @title_len[x])
268
- end
269
- end
270
-
271
290
  # Remove storage for the widget's title.
272
- def cleanTitle
291
+ def clean_title
273
292
  @title_lines = ''
274
293
  end
275
294
 
276
- # Set data for preprocessing
277
- def setPreProcess (fn, data)
278
- @pre_process_func = fn
279
- @pre_process_data = data
280
- end
281
-
282
- # Set data for postprocessing
283
- def setPostProcess (fn, data)
284
- @post_process_func = fn
285
- @post_process_data = data
286
- end
287
-
288
295
  # Set the Widget#exit_type based on the input `char`.
289
296
  #
290
297
  # According to default keybindings, if `char` is:
@@ -304,14 +311,6 @@ module RNDK
304
311
  end
305
312
  end
306
313
 
307
- def valid_widget?
308
- result = false
309
- if RNDK::ALL_OBJECTS.include?(self)
310
- result = self.validObjType(self.object_type)
311
- end
312
- result
313
- end
314
-
315
314
  # FIXME TODO What does `function_key` does?
316
315
  def getch(function_key=[])
317
316
  key = self.getc
@@ -320,69 +319,6 @@ module RNDK
320
319
  key
321
320
  end
322
321
 
323
- def bindableObject(rndktype)
324
- if rndktype != self.object_type
325
- return nil
326
- elsif [:FSELECT, :alphalist].include?(self.object_type)
327
- return @entry_field
328
- else
329
- return self
330
- end
331
- end
332
-
333
- def bind(type, key, function, data)
334
- obj = self.bindableObject(type)
335
- if key.ord < Ncurses::KEY_MAX && !(obj.nil?)
336
- if key.ord != 0
337
- obj.binding_list[key.ord] = [function, data]
338
- end
339
- end
340
- end
341
-
342
- def unbind(type, key)
343
- obj = self.bindableObject(type)
344
- unless obj.nil?
345
- obj.binding_list.delete(key)
346
- end
347
- end
348
-
349
- def clean_bindings(type)
350
- obj = self.bindableObject(type)
351
- if !(obj.nil?) && !(obj.binding_list.nil?)
352
- obj.binding_list.clear
353
- end
354
- end
355
-
356
- # Checks to see if the binding for the key exists:
357
- # If it does then it runs the command and returns its value, normally true
358
- # If it doesn't it returns a false. This way we can 'overwrite' coded
359
- # bindings.
360
- def checkBind(type, key)
361
- obj = self.bindableObject(type)
362
- if !(obj.nil?) && obj.binding_list.include?(key)
363
- function = obj.binding_list[key][0]
364
- data = obj.binding_list[key][1]
365
-
366
- if function == :getc
367
- return data
368
- else
369
- return function.call(type, obj, data, key)
370
- end
371
- end
372
- return false
373
- end
374
-
375
- # Checks to see if the binding for the key exists.
376
- def isBind(type, key)
377
- result = false
378
- obj = self.bindableObject(type)
379
- unless obj.nil?
380
- result = obj.binding_list.include?(key)
381
- end
382
-
383
- return result
384
- end
385
-
386
322
  # Allows the user to move the Widget around
387
323
  # the screen via the cursor/keypad keys.
388
324
  #
@@ -424,7 +360,7 @@ module RNDK
424
360
  end_y = beg_y + Ncurses.getmaxy(@screen.window)
425
361
 
426
362
  loop do
427
- key = self.getch([])
363
+ key = self.getch
428
364
 
429
365
  # Let them move the widget around until they hit return.
430
366
  break if [RNDK::KEY_RETURN, Ncurses::KEY_ENTER].include? key
@@ -513,13 +449,93 @@ module RNDK
513
449
  end
514
450
  end
515
451
 
452
+ # Tells if a widget is valid.
453
+ def valid?
454
+ RNDK::ALL_WIDGETS.include?(self) and self.valid_type?
455
+ end
456
+
457
+ # Tells if current widget's type is the
458
+ # type of an existing Widget.
459
+ def valid_type?
460
+ [:graph,
461
+ :histogram,
462
+ :label,
463
+ :marquee,
464
+ :viewer,
465
+ :alphalist,
466
+ :button,
467
+ :buttonbox,
468
+ :calendar,
469
+ :dialog,
470
+ :dscale,
471
+ :entry,
472
+ :fscale,
473
+ :fselect,
474
+ :fslider,
475
+ :itemlist,
476
+ :matrix,
477
+ :mentry,
478
+ :radio,
479
+ :scale,
480
+ :scroll,
481
+ :selection,
482
+ :slider,
483
+ :swindow,
484
+ :template,
485
+ :uscale,
486
+ :uslider].include? @widget_type
487
+ end
488
+
516
489
  protected
517
490
 
491
+ # Actually moves the widget.
492
+ def move_specific(x, y, relative, refresh_flag, windows, subwidgets)
493
+ current_x = Ncurses.getbegx @win
494
+ current_y = Ncurses.getbegy @win
495
+ xpos = x
496
+ ypos = y
497
+
498
+ # If this is a relative move, then we will adjust where we want
499
+ # to move to.
500
+ if relative
501
+ xpos = Ncurses.getbegx(@win) + x
502
+ ypos = Ncurses.getbegy(@win) + y
503
+ end
504
+
505
+ # Adjust the window if we need to
506
+ xtmp = [xpos]
507
+ ytmp = [ypos]
508
+ RNDK.alignxy(@screen.window, xtmp, ytmp, @box_width, @box_height)
509
+ xpos = xtmp[0]
510
+ ypos = ytmp[0]
511
+
512
+ # Get the difference
513
+ xdiff = current_x - xpos
514
+ ydiff = current_y - ypos
515
+
516
+ # Move the window to the new location.
517
+ windows.each do |window|
518
+ RNDK.window_move(window, -xdiff, -ydiff)
519
+ end
520
+
521
+ subwidgets.each do |subwidget|
522
+ subwidget.move(x, y, relative, false)
523
+ end
524
+
525
+ # Touch the windows so they 'move'
526
+ RNDK.window_refresh @screen.window
527
+
528
+ # Redraw the window, if they asked for it
529
+ if refresh_flag
530
+ self.draw
531
+ end
532
+ end
533
+
518
534
  # Gets a raw character from internal Ncurses window
519
535
  # and returns the result, capped to sane values.
520
536
  def getc
521
- rndktype = self.object_type
522
- test = self.bindableObject rndktype
537
+ rndktype = self.widget_type
538
+ test = self.bindable_widget rndktype
523
539
  result = Ncurses.wgetch @input_window
524
540
 
525
541
  if (result >= 0) and