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
@@ -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