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,27 +1,51 @@
1
1
  require 'rndk'
2
2
 
3
3
  module RNDK
4
- class SCALE < Widget
5
- def initialize(rndkscreen, xplace, yplace, title, label, field_attr,
6
- field_width, start, low, high, inc, fast_inc, box, shadow)
4
+
5
+ class Scale < Widget
6
+
7
+ def initialize(screen, config={})
7
8
  super()
8
- parent_width = Ncurses.getmaxx(rndkscreen.window)
9
- parent_height = Ncurses.getmaxy(rndkscreen.window)
10
- bindings = {
11
- 'u' => Ncurses::KEY_UP,
12
- 'U' => Ncurses::KEY_PPAGE,
13
- RNDK::BACKCHAR => Ncurses::KEY_PPAGE,
14
- RNDK::FORCHAR => Ncurses::KEY_NPAGE,
15
- 'g' => Ncurses::KEY_HOME,
16
- '^' => Ncurses::KEY_HOME,
17
- 'G' => Ncurses::KEY_END,
18
- '$' => Ncurses::KEY_END,
19
- }
20
-
21
- self.set_box(box)
9
+ @widget_type = :scale
10
+ @supported_signals += [:before_input, :after_input]
11
+
12
+ x = 0
13
+ y = 0
14
+ title = "scale"
15
+ label = "label"
16
+ field_color = RNDK::Color[:normal]
17
+ field_width = 0
18
+ start = 0
19
+ low = 0
20
+ high = 100
21
+ inc = 1
22
+ fast_increment = 5
23
+ box = true
24
+ shadow = false
25
+
26
+ config.each do |key, val|
27
+ x = val if key == :x
28
+ y = val if key == :y
29
+ title = val if key == :title
30
+ label = val if key == :label
31
+ field_color = val if key == :field_color
32
+ field_width = val if key == :field_width
33
+ start = val if key == :start
34
+ low = val if key == :low
35
+ high = val if key == :high
36
+ inc = val if key == :inc
37
+ fast_increment = val if key == :fast_increment
38
+ box = val if key == :box
39
+ shadow = val if key == :shadow
40
+ end
41
+
42
+ parent_width = Ncurses.getmaxx screen.window
43
+ parent_height = Ncurses.getmaxy screen.window
22
44
 
45
+ self.set_box box
46
+
47
+ box_width = field_width + 2 * @border_size
23
48
  box_height = @border_size * 2 + 1
24
- box_width = field_width + 2 * @border_size
25
49
 
26
50
  # Set some basic values of the widget's data field.
27
51
  @label = []
@@ -31,7 +55,9 @@ module RNDK
31
55
  # If the field_width is a negative value, the field_width will
32
56
  # be COLS-field_width, otherwise the field_width will be the
33
57
  # given width.
34
- field_width = RNDK.setWidgetDimension(parent_width, field_width, 0)
58
+ field_width = RNDK.set_widget_dimension(parent_width,
59
+ field_width,
60
+ 0)
35
61
  box_width = field_width + 2 * @border_size
36
62
 
37
63
  # Translate the label string to a chtype array
@@ -55,9 +81,9 @@ module RNDK
55
81
  box_width - @label_len - 2 * @border_size].min
56
82
 
57
83
  # Rejustify the x and y positions if we need to.
58
- xtmp = [xplace]
59
- ytmp = [yplace]
60
- RNDK.alignxy(rndkscreen.window, xtmp, ytmp, box_width, box_height)
84
+ xtmp = [x]
85
+ ytmp = [y]
86
+ RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
61
87
  xpos = xtmp[0]
62
88
  ypos = ytmp[0]
63
89
 
@@ -98,19 +124,19 @@ module RNDK
98
124
  Ncurses.keypad(@win, true)
99
125
 
100
126
  # Create the widget's data field.
101
- @screen = rndkscreen
102
- @parent = rndkscreen.window
127
+ @screen = screen
128
+ @parent = screen.window
103
129
  @shadow_win = nil
104
130
  @box_width = box_width
105
131
  @box_height = box_height
106
132
  @field_width = field_width
107
- @field_attr = field_attr
133
+ @field_color = field_color
108
134
  @current = low
109
135
  @low = low
110
136
  @high = high
111
137
  @current = start
112
138
  @inc = inc
113
- @fastinc = fast_inc
139
+ @fastinc = fast_increment
114
140
  @accepts_focus = true
115
141
  @input_window = @win
116
142
  @shadow = shadow
@@ -129,59 +155,60 @@ module RNDK
129
155
  end
130
156
 
131
157
  # Setup the key bindings.
132
- bindings.each do |from, to|
133
- self.bind(self.object_type, from, :getc, to)
134
- end
135
158
 
136
- rndkscreen.register(self.object_type, self)
159
+ self.bind_key('u') { self.increment @inc }
160
+ self.bind_key('U') { self.increment @fastinc }
161
+ self.bind_key('g') { @current = @low }
162
+ self.bind_key('^') { @current = @low }
163
+ self.bind_key('G') { @current = @high }
164
+ self.bind_key('$') { @current = @high }
165
+
166
+ screen.register(self.widget_type, self)
137
167
  end
138
168
 
139
169
  # This allows the person to use the widget's data field.
140
- def activate(actions)
141
- ret = -1
142
- # Draw the widget.
143
- self.draw(@box)
170
+ def activate(actions=[])
171
+ ret = false
172
+
173
+ self.draw
144
174
 
145
175
  if actions.nil? || actions.size == 0
146
176
  input = 0
147
177
  while true
148
- input = self.getch([])
178
+ input = self.getch
149
179
 
150
180
  # Inject the character into the widget.
151
181
  ret = self.inject(input)
152
- if @exit_type != :EARLY_EXIT
153
- return ret
154
- end
182
+
183
+ return ret if @exit_type != :EARLY_EXIT
155
184
  end
156
185
  else
157
186
  # Inject each character one at a time.
158
187
  actions.each do |action|
159
188
  ret = self.inject(action)
160
189
  end
161
- if @exit_type != :EARLY_EXIT
162
- return ret
163
- end
190
+
191
+ return ret if @exit_type != :EARLY_EXIT
164
192
  end
165
193
 
166
194
  # Set the exit type and return.
167
195
  self.set_exit_type(0)
168
- return ret
196
+ ret
169
197
  end
170
198
 
171
199
  # Check if the value lies outsid the low/high range. If so, force it in.
172
200
  def limitCurrentValue
173
201
  if @current < @low
174
202
  @current = @low
175
- RNDK.beep
176
203
  elsif @current > @high
177
204
  @current = @high
178
- RNDK.beep
179
205
  end
206
+ RNDK.beep
180
207
  end
181
208
 
182
209
  # Move the cursor to the given edit-position
183
210
  def moveToEditPosition(new_position)
184
- return Ncurses.wmove(@field_win, 0, @field_width - new_position - 1)
211
+ Ncurses.wmove(@field_win, 0, @field_width - new_position - 1)
185
212
  end
186
213
 
187
214
  # Check if the cursor is on a valid edit-position. This must be one of
@@ -254,10 +281,10 @@ module RNDK
254
281
  temp[col] = input.chr
255
282
  elsif input == Ncurses::KEY_BACKSPACE
256
283
  # delete the char before the cursor
257
- modify = RNDK::SCALE.removeChar(temp, col - 1)
284
+ modify = Scale.removeChar(temp, col - 1)
258
285
  elsif input == Ncurses::KEY_DC
259
286
  # delete the char at the cursor
260
- modify = RNDK::SCALE.removeChar(temp, col)
287
+ modify = Scale.removeChar(temp, col)
261
288
  else
262
289
  modify = false
263
290
  end
@@ -272,64 +299,51 @@ module RNDK
272
299
  return result
273
300
  end
274
301
 
275
- def self.Decrement(value, by)
276
- if value - by < value
277
- value - by
278
- else
279
- value
280
- end
302
+ def decrement by
303
+ @current = @current - by if (@current - by) < @current
281
304
  end
282
305
 
283
- def self.Increment(value, by)
284
- if value + by > value
285
- value + by
286
- else
287
- value
288
- end
306
+ def increment by
307
+ @current = @current + by if (@current + by) > @current
289
308
  end
290
309
 
291
310
  # This function injects a single character into the widget.
292
- def inject(input)
293
- pp_return = 1
294
- ret = -1
311
+ def inject input
312
+ pp_return = true
313
+ ret = false
295
314
  complete = false
296
315
 
297
316
  # Set the exit type.
298
317
  self.set_exit_type(0)
299
318
 
300
319
  # Draw the field.
301
- self.drawField
320
+ self.draw_field
302
321
 
303
322
  # Check if there is a pre-process function to be called.
304
- unless @pre_process_func.nil?
305
- # Call the pre-process function.
306
- pp_return = @pre_process_func.call(self.object_type, self,
307
- @pre_process_data, input)
308
- end
323
+ keep_going = self.run_signal_binding(:before_input, input)
324
+
325
+ if keep_going
309
326
 
310
- # Should we continue?
311
- if pp_return != 0
312
327
  # Check for a key bindings.
313
- if self.checkBind(self.object_type, input)
314
- complete = true
328
+ if self.is_bound? input
329
+ self.run_key_binding input
330
+ #complete = true
331
+
315
332
  else
316
333
  case input
317
334
  when Ncurses::KEY_LEFT
318
335
  self.setEditPosition(@field_edit + 1)
319
336
  when Ncurses::KEY_RIGHT
320
337
  self.setEditPosition(@field_edit - 1)
321
- when Ncurses::KEY_DOWN
322
- @current = RNDK::SCALE.Decrement(@current, @inc)
323
- when Ncurses::KEY_UP
324
- @current = RNDK::SCALE.Increment(@current, @inc)
325
- when Ncurses::KEY_PPAGE
326
- @current = RNDK::SCALE.Increment(@current, @fastinc)
327
- when Ncurses::KEY_NPAGE
328
- @current = RNDK::SCALE.Decrement(@current, @fastinc)
329
- when Ncurses::KEY_HOME
330
- @current = @low
331
- when Ncurses::KEY_END
332
- @current = @high
338
+
339
+ when Ncurses::KEY_DOWN then self.decrement @inc
340
+ when Ncurses::KEY_UP then self.increment @inc
341
+ when Ncurses::KEY_HOME then @current = @low
342
+ when Ncurses::KEY_END then @current = @high
343
+ when Ncurses::KEY_PPAGE, RNDK::BACKCHAR
344
+ self.increment @fastinc
345
+ when Ncurses::KEY_NPAGE, RNDK::FORCHAR
346
+ self.decrement @fastinc
333
347
  when RNDK::KEY_TAB, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
334
348
  self.set_exit_type(input)
335
349
  ret = @current
@@ -368,16 +382,12 @@ module RNDK
368
382
  end
369
383
  self.limitCurrentValue
370
384
 
371
- # Should we call a post-process?
372
- if !complete && !(@post_process_func).nil?
373
- @post_process_func.call(self.object_type, self,
374
- @post_process_data, input)
375
- end
385
+ self.run_signal_binding(:after_input) if not complete
376
386
  end
377
387
 
378
- if !complete
379
- self.drawField
380
- self.set_exit_type(0)
388
+ if not complete
389
+ self.draw_field
390
+ self.set_exit_type 0
381
391
  end
382
392
 
383
393
  @result_data = ret
@@ -385,25 +395,19 @@ module RNDK
385
395
  end
386
396
 
387
397
  # This moves the widget's data field to the given location.
388
- def move(xplace, yplace, relative, refresh_flag)
398
+ def move(x, y, relative, refresh_flag)
389
399
  windows = [@win, @label_win, @field_win, @shadow_win]
390
400
 
391
- self.move_specific(xplace, yplace, relative, refresh_flag, windows, [])
401
+ self.move_specific(x, y, relative, refresh_flag, windows, [])
392
402
  end
393
403
 
394
404
  # This function draws the widget.
395
- def draw(box)
396
- # Draw the shadow.
397
- unless @shadow_win.nil?
398
- Draw.drawShadow(@shadow_win)
399
- end
405
+ def draw
406
+ Draw.drawShadow(@shadow_win) unless @shadow_win.nil?
400
407
 
401
- # Box the widget if asked.
402
- if box
403
- Draw.drawObjBox(@win, self)
404
- end
408
+ Draw.drawObjBox(@win, self) if @box
405
409
 
406
- self.drawTitle(@win)
410
+ self.draw_title @win
407
411
 
408
412
  # Draw the label.
409
413
  unless @label_win.nil?
@@ -413,16 +417,16 @@ module RNDK
413
417
  @label, RNDK::HORIZONTAL,
414
418
  0,
415
419
  @label_len)
416
- Ncurses.wrefresh(@label_win)
420
+ Ncurses.wrefresh @label_win
417
421
  end
418
422
  Ncurses.wrefresh @win
419
423
 
420
424
  # Draw the field window.
421
- self.drawField
425
+ self.draw_field
422
426
  end
423
427
 
424
428
  # This draws the widget.
425
- def drawField
429
+ def draw_field
426
430
  Ncurses.werase(@field_win)
427
431
 
428
432
  # Draw the value in the field.
@@ -431,7 +435,7 @@ module RNDK
431
435
  @field_width - temp.size - 1,
432
436
  0,
433
437
  temp,
434
- @field_attr,
438
+ @field_color,
435
439
  RNDK::HORIZONTAL,
436
440
  0,
437
441
  temp.size)
@@ -441,7 +445,7 @@ module RNDK
441
445
  end
442
446
 
443
447
  # This sets the background attribute of teh widget.
444
- def set_bg_attrib attrib
448
+ def set_bg_color attrib
445
449
  Ncurses.wbkgd(@win, attrib)
446
450
  Ncurses.wbkgd(@field_win, attrib)
447
451
  Ncurses.wbkgd(@label_win, attrib) unless @label_win.nil?
@@ -449,7 +453,7 @@ module RNDK
449
453
 
450
454
  # This function destroys the widget.
451
455
  def destroy
452
- self.cleanTitle
456
+ self.clean_title
453
457
  @label = []
454
458
 
455
459
  # Clean up the windows.
@@ -459,15 +463,15 @@ module RNDK
459
463
  RNDK.window_delete @win
460
464
 
461
465
  # Clean the key bindings.
462
- self.clean_bindings(self.object_type)
466
+ self.clean_bindings
463
467
 
464
- # Unregister this object
465
- RNDK::Screen.unregister(self.object_type, self)
468
+ # Unregister this widget
469
+ @screen.unregister(self.widget_type, self)
466
470
  end
467
471
 
468
472
  # This function erases the widget from the screen.
469
473
  def erase
470
- if self.valid_widget?
474
+ if self.valid?
471
475
  RNDK.window_erase @label_win
472
476
  RNDK.window_erase @field_win
473
477
  RNDK.window_erase @win
@@ -478,12 +482,12 @@ module RNDK
478
482
  # This function sets the low/high/current values of the widget.
479
483
  def set(low, high, value, box)
480
484
  self.setLowHigh(low, high)
481
- self.setValue(value)
482
- self.set_box(box)
485
+ self.setValue value
486
+ self.set_box box
483
487
  end
484
488
 
485
489
  # This sets the widget's value
486
- def setValue(value)
490
+ def setValue value
487
491
  @current = value
488
492
  self.limitCurrentValue
489
493
  end
@@ -516,11 +520,11 @@ module RNDK
516
520
  end
517
521
 
518
522
  def focus
519
- self.draw(@box)
523
+ self.draw
520
524
  end
521
525
 
522
526
  def unfocus
523
- self.draw(@box)
527
+ self.draw
524
528
  end
525
529
 
526
530
  def position
@@ -531,8 +535,5 @@ module RNDK
531
535
  '%d%c'
532
536
  end
533
537
 
534
- def object_type
535
- :SCALE
536
- end
537
538
  end
538
539
  end
@@ -2,27 +2,27 @@ require 'rndk/scroller'
2
2
 
3
3
  module RNDK
4
4
 
5
- # A scrolling list of text.
5
+ # A scrolling items of text.
6
6
  #
7
7
  # ## Keybindings
8
8
  #
9
- # Left Arrow:: Shift the list left one column.
10
- # Right Arrow:: Shift the list right one column.
11
- # Up Arrow:: Select the previous item in the list.
12
- # Down Arrow:: Select the next item in the list.
9
+ # Left Arrow:: Shift the items left one column.
10
+ # Right Arrow:: Shift the items right one column.
11
+ # Up Arrow:: Select the previous item in the items.
12
+ # Down Arrow:: Select the next item in the items.
13
13
  # Prev Page:: Scroll one page backward.
14
14
  # Ctrl-B:: Scroll one page backward.
15
15
  # Next Page:: Scroll one page forward.
16
16
  # Ctrl-F:: Scroll one page forward.
17
- # 1:: Move to the first element in the list.
18
- # <:: Move to the first element in the list.
19
- # g:: Move to the first element in the list.
20
- # Home:: Move to the first element in the list.
21
- # >:: Move to the last element in the list.
22
- # G:: Move to the last element in the list.
23
- # End:: Move to the last element in the list.
24
- # $:: Shift the list to the far right.
25
- # |:: Shift the list to the far left.
17
+ # 1:: Move to the first element in the items.
18
+ # <:: Move to the first element in the items.
19
+ # g:: Move to the first element in the items.
20
+ # Home:: Move to the first element in the items.
21
+ # >:: Move to the last element in the items.
22
+ # G:: Move to the last element in the items.
23
+ # End:: Move to the last element in the items.
24
+ # $:: Shift the items to the far right.
25
+ # |:: Shift the items to the far left.
26
26
  # Return:: Exit the widget and return the index
27
27
  # of the selected item. Also set the
28
28
  # widget `exit_type` to `:NORMAL`.
@@ -33,16 +33,16 @@ module RNDK
33
33
  # set the widget `exit_type` `:ESCAPE_HIT`.
34
34
  # Ctrl-L:: Refreshes the screen.
35
35
  #
36
- class Scroll < SCROLLER
37
- attr_reader :item, :list_size, :current_item, :highlight
36
+ class Scroll < Scroller
37
+ attr_reader :item, :current_item, :highlight
38
38
 
39
39
  # Creates a Scroll Widget.
40
40
  #
41
- # * `xplace` is the x position - can be an integer or
41
+ # * `x` is the x position - can be an integer or
42
42
  # `RNDK::LEFT`, `RNDK::RIGHT`, `RNDK::CENTER`.
43
- # * `yplace` is the y position - can be an integer or
43
+ # * `y` is the y position - can be an integer or
44
44
  # `RNDK::TOP`, `RNDK::BOTTOM`, `RNDK::CENTER`.
45
- # * `splace` is where the scrollbar will be placed.
45
+ # * `scroll_bar` is where the scrollbar will be placed.
46
46
  # It can be only `RNDK::LEFT`, `RNDK::RIGHT` or
47
47
  # `RNDK::NONE`, for no scrollbar.
48
48
  # * `width`/`height` are integers - if either are 0, Widget
@@ -51,68 +51,76 @@ module RNDK
51
51
  # minus the value.
52
52
  # * `title` can be more than one line - just split them
53
53
  # with `\n`s.
54
- # * `list` is an Array of Strings to be shown on the Widget.
54
+ # * `items` is an Array of Strings to be shown on the Widget.
55
55
  # * `numbers` is a flag to turn on/off line numbering at
56
- # the front of the list items.
56
+ # the front of the items items.
57
57
  # * `highlight` is the attribute/color of the currently selected
58
- # item at the list.
58
+ # item at the items.
59
59
  # * `box` if the Widget is drawn with a box outside it.
60
60
  # * `shadow` turns on/off the shadow around the Widget.
61
61
  #
62
- def initialize (rndkscreen,
63
- xplace,
64
- yplace,
65
- splace,
66
- width,
67
- height,
68
- title,
69
- list,
70
- numbers,
71
- highlight,
72
- box,
73
- shadow)
62
+ def initialize(screen, config={})
74
63
  super()
64
+ @widget_type = :scroll
65
+ @supported_signals += [:before_input,
66
+ :after_input,
67
+ :after_scrolling]
68
+ x = 0
69
+ y = 0
70
+ scroll_bar = RNDK::RIGHT
71
+ width = 0
72
+ height = 0
73
+ title = "scroll"
74
+ items = []
75
+ numbers = false
76
+ highlight = RNDK::Color[:reverse]
77
+ box = true
78
+ shadow = false
79
+
80
+ config.each do |key, val|
81
+ x = val if key == :x
82
+ y = val if key == :y
83
+ scroll_bar = val if key == :scroll_bar
84
+ width = val if key == :width
85
+ height = val if key == :height
86
+ title = val if key == :title
87
+ items = val if key == :items
88
+ numbers = val if key == :numbers
89
+ highlight = val if key == :highlight
90
+ box = val if key == :box
91
+ shadow = val if key == :shadow
92
+ end
75
93
 
76
- parent_width = Ncurses.getmaxx rndkscreen.window
77
- parent_height = Ncurses.getmaxy rndkscreen.window
94
+ parent_width = Ncurses.getmaxx screen.window
95
+ parent_height = Ncurses.getmaxy screen.window
78
96
 
79
97
  box_width = width
80
98
  box_height = height
81
99
 
82
- xpos = xplace
83
- ypos = yplace
100
+ xpos = x
101
+ ypos = y
84
102
 
85
103
  scroll_adjust = 0
86
104
 
87
- bindings = {
88
- RNDK::BACKCHAR => Ncurses::KEY_PPAGE,
89
- RNDK::FORCHAR => Ncurses::KEY_NPAGE,
90
- 'g' => Ncurses::KEY_HOME,
91
- '1' => Ncurses::KEY_HOME,
92
- 'G' => Ncurses::KEY_END,
93
- '<' => Ncurses::KEY_HOME,
94
- '>' => Ncurses::KEY_END
95
- }
96
-
97
105
  self.set_box box
98
106
 
99
107
  # If the height is a negative value, the height will be ROWS-height,
100
108
  # otherwise the height will be the given height
101
- box_height = RNDK.setWidgetDimension(parent_height, height, 0)
109
+ box_height = RNDK.set_widget_dimension(parent_height, height, 0)
102
110
 
103
111
  # If the width is a negative value, the width will be COLS-width,
104
112
  # otherwise the width will be the given width
105
- box_width = RNDK.setWidgetDimension(parent_width, width, 0)
113
+ box_width = RNDK.set_widget_dimension(parent_width, width, 0)
106
114
 
107
115
  box_width = self.set_title(title, box_width)
108
116
 
109
117
  # Set the box height.
110
118
  if @title_lines > box_height
111
- box_height = @title_lines + [list.size, 8].min + 2 * @border_size
119
+ box_height = @title_lines + [items.size, 8].min + 2 * @border_size
112
120
  end
113
121
 
114
122
  # Adjust the box width if there is a scroll bar
115
- if splace == RNDK::LEFT || splace == RNDK::RIGHT
123
+ if scroll_bar == RNDK::LEFT || scroll_bar == RNDK::RIGHT
116
124
  @scrollbar = true
117
125
  box_width += 1
118
126
  else
@@ -129,12 +137,12 @@ module RNDK
129
137
  else box_height
130
138
  end
131
139
 
132
- self.setViewSize(list.size)
140
+ self.set_view_size(items.size)
133
141
 
134
142
  # Rejustify the x and y positions if we need to.
135
143
  xtmp = [xpos]
136
144
  ytmp = [ypos]
137
- RNDK.alignxy(rndkscreen.window, xtmp, ytmp, @box_width, @box_height)
145
+ RNDK.alignxy(screen.window, xtmp, ytmp, @box_width, @box_height)
138
146
  xpos = xtmp[0]
139
147
  ypos = ytmp[0]
140
148
 
@@ -150,15 +158,15 @@ module RNDK
150
158
  Ncurses.keypad(@win, true)
151
159
 
152
160
  # Create the scrollbar window.
153
- if splace == RNDK::RIGHT
161
+ if scroll_bar == RNDK::RIGHT
154
162
  @scrollbar_win = Ncurses.subwin(@win,
155
- self.maxViewSize,
163
+ self.max_view_size,
156
164
  1,
157
165
  self.Screen_YPOS(ypos),
158
166
  xpos + box_width - @border_size - 1)
159
- elsif splace == RNDK::LEFT
167
+ elsif scroll_bar == RNDK::LEFT
160
168
  @scrollbar_win = Ncurses.subwin(@win,
161
- self.maxViewSize,
169
+ self.max_view_size,
162
170
  1,
163
171
  self.Screen_YPOS(ypos),
164
172
  self.Screen_XPOS(xpos))
@@ -166,18 +174,18 @@ module RNDK
166
174
  @scrollbar_win = nil
167
175
  end
168
176
 
169
- # create the list window
170
- @list_win = Ncurses.subwin(@win,
171
- self.maxViewSize,
177
+ # create the items window
178
+ @items_win = Ncurses.subwin(@win,
179
+ self.max_view_size,
172
180
  box_width - (2 * @border_size) - scroll_adjust,
173
181
  self.Screen_YPOS(ypos),
174
- self.Screen_XPOS(xpos) + (if splace == RNDK::LEFT then 1 else 0 end))
182
+ self.Screen_XPOS(xpos) + (if scroll_bar == RNDK::LEFT then 1 else 0 end))
175
183
 
176
184
  # Set the rest of the variables
177
- @screen = rndkscreen
178
- @parent = rndkscreen.window
185
+ @screen = screen
186
+ @parent = screen.window
179
187
  @shadow_win = nil
180
- @scrollbar_placement = splace
188
+ @scrollbar_placement = scroll_bar
181
189
  @max_left_char = 0
182
190
  @left_char = 0
183
191
  @highlight = highlight
@@ -186,12 +194,10 @@ module RNDK
186
194
  @input_window = @win
187
195
  @shadow = shadow
188
196
 
189
- self.setPosition(0);
197
+ self.set_position(0);
190
198
 
191
- # Create the scrolling list item list and needed variables.
192
- if self.createItemList(numbers, list, list.size) <= 0
193
- return nil
194
- end
199
+ # Create the scrolling items item items and needed variables.
200
+ return nil unless self.create_item_list(numbers, items)
195
201
 
196
202
  # Do we need to create a shadow?
197
203
  if shadow
@@ -201,19 +207,15 @@ module RNDK
201
207
  xpos + 1)
202
208
  end
203
209
 
204
- # Set up the key bindings.
205
- bindings.each do |from, to|
206
- #self.bind(:scroll, from, getc_lambda, to)
207
- self.bind(:scroll, from, :getc, to)
208
- end
209
-
210
- rndkscreen.register(:scroll, self);
211
-
212
- return self
213
- end
210
+ # Standard keybindings (plus the Arrow Keys)
211
+ self.bind_key('g') { self.scroll_begin }
212
+ self.bind_key('1') { self.scroll_begin }
213
+ self.bind_key('G') { self.scroll_end }
214
+ self.bind_key('<') { self.scroll_begin }
215
+ self.bind_key('>') { self.scroll_end }
214
216
 
215
- def object_type
216
- :scroll
217
+ screen.register(:scroll, self);
218
+ self
217
219
  end
218
220
 
219
221
  # @see Widget#position
@@ -221,29 +223,18 @@ module RNDK
221
223
  super @win
222
224
  end
223
225
 
224
- # Put the cursor on the currently-selected item's row.
225
- def fixCursorPosition
226
- scrollbar_adj = if @scrollbar_placement == LEFT then 1 else 0 end
227
- ypos = self.Screen_YPOS(@current_item - @current_top)
228
- xpos = self.Screen_XPOS(0) + scrollbar_adj
229
-
230
- Ncurses.wmove(@input_window, ypos, xpos)
231
- Ncurses.wrefresh(@input_window)
232
- end
233
-
234
226
  # Activates the Widget, letting the user interact with it.
235
227
  #
236
228
  # `actions` is an Array of characters. If it's non-null,
237
229
  # will #inject each char on it into the Widget.
238
230
  #
239
231
  def activate(actions=[])
240
- # Draw the scrolling list
241
- self.draw(@box)
232
+ self.draw
242
233
 
243
234
  if actions.nil? || actions.size == 0
244
235
  loop do
245
- self.fixCursorPosition
246
- input = self.getch([])
236
+ self.fix_cursor_position
237
+ input = self.getch
247
238
 
248
239
  # Inject the character into the widget.
249
240
  ret = self.inject input
@@ -261,64 +252,87 @@ module RNDK
261
252
 
262
253
  # Set the exit type for the widget and return
263
254
  self.set_exit_type(0)
264
- return -1
255
+ return nil
265
256
  end
266
257
 
267
258
  # @see Widget#inject
268
259
  def inject input
269
- pp_return = 1
270
- ret = -1
260
+ ret = nil
271
261
  complete = false
272
262
 
273
- # Set the exit type for the widget.
274
- self.set_exit_type(0)
263
+ self.set_exit_type 0
275
264
 
276
- # Draw the scrolling list
277
- self.drawList(@box)
265
+ # Draw the scrolling items
266
+ self.draw_items @box
278
267
 
279
- #Check if there is a pre-process function to be called.
280
- unless @pre_process_func.nil?
281
- pp_return = @pre_process_func.call(:scroll, self,
282
- @pre_process_data, input)
283
- end
268
+ # Calls a pre-process block if exists.
269
+ # They can interrup input.
270
+ continue = run_signal_binding(:before_input, input)
271
+
272
+ if continue
284
273
 
285
- # Should we continue?
286
- if pp_return != 0
287
274
  # Check for a predefined key binding.
288
- if self.checkBind(:scroll, input) != false
289
- #self.checkEarlyExit
290
- complete = true
275
+ if self.is_bound? input
276
+ self.run_key_binding input
277
+
291
278
  else
292
279
  case input
280
+
293
281
  when Ncurses::KEY_UP
294
- self.KEY_UP
282
+ self.scroll_up
283
+ run_signal_binding(:after_scrolling, @current_item)
284
+
295
285
  when Ncurses::KEY_DOWN
296
- self.KEY_DOWN
297
- when Ncurses::KEY_RIGHT
298
- self.KEY_RIGHT
286
+ self.scroll_down
287
+ run_signal_binding(:after_scrolling, @current_item)
288
+
299
289
  when Ncurses::KEY_LEFT
300
- self.KEY_LEFT
290
+ self.scroll_left
291
+ run_signal_binding(:after_scrolling, @current_item)
292
+
293
+ when Ncurses::KEY_RIGHT
294
+ self.scroll_right
295
+ run_signal_binding(:after_scrolling, @current_item)
296
+
301
297
  when Ncurses::KEY_PPAGE
302
- self.KEY_PPAGE
298
+ self.scroll_page_up
299
+ run_signal_binding(:after_scrolling, @current_item)
300
+
303
301
  when Ncurses::KEY_NPAGE
304
- self.KEY_NPAGE
302
+ self.scroll_page_down
303
+ run_signal_binding(:after_scrolling, @current_item)
304
+
305
305
  when Ncurses::KEY_HOME
306
- self.KEY_HOME
306
+ self.scroll_begin
307
+ run_signal_binding(:after_scrolling, @current_item)
308
+
307
309
  when Ncurses::KEY_END
308
- self.KEY_END
309
- when '$'
310
- @left_char = @max_left_char
311
- when '|'
312
- @left_char = 0
310
+ self.scroll_end
311
+ run_signal_binding(:after_scrolling, @current_item)
312
+
313
+ when RNDK::BACKCHAR
314
+ self.scroll_page_up
315
+ run_signal_binding(:after_scrolling, @current_item)
316
+
317
+ when RNDK::FORCHAR
318
+ self.scroll_page_down
319
+ run_signal_binding(:after_scrolling, @current_item)
320
+
321
+ when '$' then @left_char = @max_left_char
322
+ when '|' then @left_char = 0
323
+
313
324
  when RNDK::KEY_ESC
314
325
  self.set_exit_type(input)
315
326
  complete = true
327
+
316
328
  when Ncurses::ERR
317
329
  self.set_exit_type(input)
318
330
  complete = true
331
+
319
332
  when RNDK::REFRESH
320
333
  @screen.erase
321
334
  @screen.refresh
335
+
322
336
  when RNDK::KEY_TAB, Ncurses::KEY_ENTER, RNDK::KEY_RETURN
323
337
  self.set_exit_type(input)
324
338
  ret = @current_item
@@ -326,136 +340,43 @@ module RNDK
326
340
  end
327
341
  end
328
342
 
329
- if !complete && !(@post_process_func.nil?)
330
- @post_process_func.call(:scroll, self, @post_process_data, input)
331
- end
343
+ run_signal_binding(:after_input, input) if not complete
332
344
  end
333
345
 
334
- if !complete
335
- self.drawList(@box)
346
+ if not complete
347
+ self.draw_items @box
336
348
  self.set_exit_type(0)
337
349
  end
338
350
 
339
- self.fixCursorPosition
351
+ self.fix_cursor_position
340
352
  @result_data = ret
341
353
 
342
- #return ret != -1
343
- return ret
344
- end
345
-
346
- def getCurrentTop
347
- return @current_top
348
- end
349
-
350
- def setCurrentTop(item)
351
- if item < 0
352
- item = 0
353
- elsif item > @max_top_item
354
- item = @max_top_item
355
- end
356
- @current_top = item
357
-
358
- self.setPosition(item);
354
+ ret
359
355
  end
360
356
 
361
357
  # This moves the scroll field to the given location.
362
- def move(xplace, yplace, relative, refresh_flag)
363
- windows = [@win, @list_win, @shadow_win, @scrollbar_win]
358
+ def move(x, y, relative, refresh_flag)
359
+ windows = [@win, @items_win, @shadow_win, @scrollbar_win]
364
360
 
365
- self.move_specific(xplace, yplace, relative, refresh_flag, windows, [])
361
+ self.move_specific(x, y, relative, refresh_flag, windows, [])
366
362
  end
367
363
 
368
- # This function draws the scrolling list widget.
369
- def draw(box)
364
+ # This function draws the scrolling items widget.
365
+ def draw
370
366
  # Draw in the shadow if we need to.
371
- unless @shadow_win.nil?
372
- Draw.drawShadow(@shadow_win)
373
- end
374
-
375
- self.drawTitle(@win)
376
-
377
- # Draw in the scrolling list items.
378
- self.drawList(box)
379
- end
380
-
381
- def drawCurrent
382
- # Rehighlight the current menu item.
383
- screen_pos = @item_pos[@current_item] - @left_char
384
- highlight = if self.has_focus
385
- then @highlight
386
- else Ncurses::A_NORMAL
387
- end
388
-
389
- Draw.writeChtypeAttrib(@list_win,
390
- if screen_pos >= 0 then screen_pos else 0 end,
391
- @current_high, @item[@current_item], highlight, RNDK::HORIZONTAL,
392
- if screen_pos >= 0 then 0 else 1 - screen_pos end,
393
- @item_len[@current_item])
394
- end
395
-
396
- def drawList box
397
- # If the list is empty, don't draw anything.
398
- if @list_size > 0
399
- # Redraw the list
400
- (0...@view_size).each do |j|
401
- k = j + @current_top
402
-
403
- Draw.writeBlanks(@list_win, 0, j, RNDK::HORIZONTAL, 0,
404
- @box_width - (2 * @border_size))
405
-
406
- # Draw the elements in the scrolling list.
407
- if k < @list_size
408
- screen_pos = @item_pos[k] - @left_char
409
- ypos = j
410
-
411
- # Write in the correct line.
412
- Draw.writeChtype(@list_win,
413
- if screen_pos >= 0 then screen_pos else 1 end,
414
- ypos, @item[k], RNDK::HORIZONTAL,
415
- if screen_pos >= 0 then 0 else 1 - screen_pos end,
416
- @item_len[k])
417
- end
418
- end
419
-
420
- self.drawCurrent
367
+ Draw.drawShadow(@shadow_win) unless @shadow_win.nil?
421
368
 
422
- # Determine where the toggle is supposed to be.
423
- unless @scrollbar_win.nil?
424
- @toggle_pos = (@current_item * @step).floor
425
-
426
- # Make sure the toggle button doesn't go out of bounds.
427
- if @toggle_pos >= Ncurses.getmaxy(@scrollbar_win)
428
- @toggle_pos = Ncurses.getmaxy(@scrollbar_win) - 1
429
- end
430
-
431
- # Draw the scrollbar
432
- Ncurses.mvwvline(@scrollbar_win,
433
- 0,
434
- 0,
435
- Ncurses::ACS_CKBOARD,
436
- Ncurses.getmaxy(@scrollbar_win))
369
+ self.draw_title @win
437
370
 
438
- Ncurses.mvwvline(@scrollbar_win,
439
- @toggle_pos,
440
- 0,
441
- ' '.ord | Ncurses::A_REVERSE,
442
- @toggle_size)
443
- end
444
- end
445
-
446
- # Box it if needed.
447
- if box
448
- Draw.drawObjBox(@win, self)
449
- end
450
-
451
- # Refresh the window
452
- Ncurses.wrefresh @win
371
+ # Draw in the scrolling items items.
372
+ self.draw_items @box
453
373
  end
454
374
 
455
375
  # This sets the background attribute of the widget.
456
- def set_bg_attrib(attrib)
376
+ def set_bg_color(attrib)
457
377
  Ncurses.wbkgd(@win, attrib)
458
- Ncurses.wbkgd(@list_win, attrib)
378
+ Ncurses.wbkgd(@items_win, attrib)
379
+
459
380
  unless @scrollbar_win.nil?
460
381
  Ncurses.wbkgd(@scrollbar_win, attrib)
461
382
  end
@@ -463,78 +384,182 @@ module RNDK
463
384
 
464
385
  # This function destroys
465
386
  def destroy
466
- self.cleanTitle
387
+ self.clean_title
467
388
 
468
389
  # Clean up the windows.
469
390
  RNDK.window_delete(@scrollbar_win)
470
391
  RNDK.window_delete(@shadow_win)
471
- RNDK.window_delete(@list_win)
392
+ RNDK.window_delete(@items_win)
472
393
  RNDK.window_delete(@win)
473
394
 
474
395
  # Clean the key bindings.
475
- self.clean_bindings(:scroll)
396
+ self.clean_bindings
476
397
 
477
- # Unregister this object
478
- RNDK::Screen.unregister(:scroll, self)
398
+ # Unregister this widget
399
+ @screen.unregister self
479
400
  end
480
401
 
481
- # This function erases the scrolling list from the screen.
402
+ # This function erases the scrolling items from the screen.
482
403
  def erase
483
404
  RNDK.window_erase(@win)
484
405
  RNDK.window_erase(@shadow_win)
485
406
  end
486
407
 
487
- def allocListArrays(old_size, new_size)
488
- result = true
489
- new_list = Array.new(new_size)
490
- new_len = Array.new(new_size)
491
- new_pos = Array.new(new_size)
408
+ # This sets certain attributes of the scrolling items.
409
+ def set(items, numbers, highlight, box)
410
+ self.set_items(items, numbers)
411
+ self.set_highlight(highlight)
412
+ self.set_box(box)
413
+ end
492
414
 
493
- (0...old_size).each do |n|
494
- new_list[n] = @item[n]
495
- new_len[n] = @item_len[n]
496
- new_pos[n] = @item_pos[n]
415
+ # Sets the scrolling items items.
416
+ # See Scroll#initialize.
417
+ def set_items(items, numbers)
418
+ return unless self.create_item_list(numbers, items)
419
+
420
+ # Clean up the display.
421
+ (0...@view_size).each do |x|
422
+ Draw.writeBlanks(@win, 1, x, RNDK::HORIZONTAL, 0, @box_width - 2);
497
423
  end
498
424
 
499
- @item = new_list
500
- @item_len = new_len
501
- @item_pos = new_pos
425
+ self.set_view_size(items.size)
426
+ self.set_position(0)
427
+ self.erase
502
428
 
503
- return result
429
+ @left_char = 0
504
430
  end
505
431
 
506
- def allocListItem(which, work, used, number, value)
507
- if number > 0
508
- value = "%4d. %s" % [number, value]
432
+ def get_items(items)
433
+ (0...@item.size).each do |x|
434
+ items << RNDK.chtype2Char(@item[x])
509
435
  end
510
436
 
511
- item_len = []
512
- item_pos = []
513
- @item[which] = RNDK.char2Chtype(value, item_len, item_pos)
514
- @item_len[which] = item_len[0]
515
- @item_pos[which] = item_pos[0]
437
+ @item.size
438
+ end
516
439
 
517
- @item_pos[which] = RNDK.justifyString(@box_width,
518
- @item_len[which], @item_pos[which])
519
- return true
440
+ # This sets the highlight of the scrolling items.
441
+ def set_highlight(highlight)
442
+ @highlight = highlight
520
443
  end
521
444
 
522
- # This function creates the scrolling list information and sets up the
523
- # needed variables for the scrolling list to work correctly.
524
- def createItemList(numbers, list, list_size)
525
- status = 0
526
- if list_size > 0
445
+ def get_highlight(highlight)
446
+ return @highlight
447
+ end
448
+
449
+ # # Adds a single item to a scrolling items, at the end of
450
+ # # the items.
451
+ # def add_item(item)
452
+ # item_number = @item.size
453
+ # widest_item = self.widest_item
454
+ # temp = ''
455
+ # have = 0
456
+
457
+ # if (self.alloc_items_arrays(@item.size, @item.size + 1)) and
458
+ # (self.alloc_items_item(item_number,
459
+ # temp,
460
+ # have,
461
+ # if @numbers then item_number + 1 else 0 end,
462
+ # item))
463
+ # # Determine the size of the widest item.
464
+ # widest_item = [@item_len[item_number], widest_item].max
465
+
466
+ # self.update_view_width(widest_item)
467
+ # self.set_view_size(@item.size + 1)
468
+ # end
469
+ # end
470
+
471
+ # # Adds a single item to a scrolling items before the current
472
+ # # item.
473
+ # def insert_item(item)
474
+ # widest_item = self.widest_item
475
+ # temp = ''
476
+ # have = 0
477
+
478
+ # if (self.alloc_items_arrays(@item.size, @item.size + 1)) and
479
+ # (self.insert_items_item(@current_item)) and
480
+ # (self.alloc_items_item(@current_item,
481
+ # temp,
482
+ # have,
483
+ # if @numbers then @current_item + 1 else 0 end,
484
+ # item))
485
+
486
+ # # Determine the size of the widest item.
487
+ # widest_item = [@item_len[@current_item], widest_item].max
488
+
489
+ # self.update_view_width(widest_item)
490
+ # self.set_view_size(@item.size + 1)
491
+ # self.resequence
492
+ # end
493
+ # end
494
+
495
+ # # This removes a single item from a scrolling items.
496
+ # def delete_item(position)
497
+ # if position >= 0 && position < @item.size
498
+ # # Adjust the items
499
+ # @item = @item[0...position] + @item[position+1..-1]
500
+ # @item_len = @item_len[0...position] + @item_len[position+1..-1]
501
+ # @item_pos = @item_pos[0...position] + @item_pos[position+1..-1]
502
+
503
+ # self.set_view_size(@item.size - 1)
504
+
505
+ # self.resequence if @item.size > 0
506
+
507
+ # if @item.size < self.max_view_size
508
+ # Ncurses.werase @win # force the next redraw to be complete
509
+ # end
510
+
511
+ # # do this to update the view size, etc
512
+ # self.set_position(@current_item)
513
+ # end
514
+ # end
515
+
516
+ def focus
517
+ self.draw_current
518
+ Ncurses.wrefresh @items_win
519
+ end
520
+
521
+ def unfocus
522
+ self.draw_current
523
+ Ncurses.wrefresh @items_win
524
+ end
525
+
526
+ # _ _ _
527
+ # | | | | | |
528
+ # _ __ _ __ ___ | |_ ___ ___| |_ ___ __| |
529
+ # | '_ \| '__/ _ \| __/ _ \/ __| __/ _ \/ _` |
530
+ # | |_) | | | (_) | || __| (__| || __| (_| |
531
+ # | .__/|_| \___/ \__\___|\___|\__\___|\__,_|
532
+ # | |
533
+ # |_|
534
+ protected
535
+
536
+ # Creates the scrolling items information and sets up the
537
+ # needed variables for the scrolling items to work correctly.
538
+ def create_item_list(numbers, items)
539
+ status = false
540
+
541
+ # If any element is not a String, try to convert
542
+ # it anyway.
543
+ items.each_with_index do |item, i|
544
+ if item.class != String
545
+ items[i] = item.to_s
546
+ end
547
+ end
548
+
549
+ if items.size > 0
527
550
  widest_item = 0
528
551
  x = 0
529
552
  have = 0
530
553
  temp = ''
531
- if allocListArrays(0, list_size)
532
- # Create the items in the scrolling list.
533
- status = 1
534
- (0...list_size).each do |x|
554
+
555
+ if alloc_items_arrays(0, items.size)
556
+ # Create the items in the scrolling items.
557
+ status = true
558
+ (0...items.size).each do |x|
535
559
  number = if numbers then x + 1 else 0 end
536
- if !self.allocListItem(x, temp, have, number, list[x])
537
- status = 0
560
+
561
+ unless self.alloc_items_item(x, temp, have, number, items[x])
562
+ status = false
538
563
  break
539
564
  end
540
565
 
@@ -542,175 +567,203 @@ module RNDK
542
567
  end
543
568
 
544
569
  if status
545
- self.updateViewWidth(widest_item);
570
+ self.update_view_width widest_item
546
571
 
547
572
  # Keep the boolean flag 'numbers'
548
573
  @numbers = numbers
549
574
  end
550
575
  end
576
+
551
577
  else
552
- status = 1 # null list is ok - for a while
578
+ status = true # null items is ok - for a while
553
579
  end
554
-
555
- return status
580
+ status
556
581
  end
557
582
 
558
- # This sets certain attributes of the scrolling list.
559
- def set(list, list_size, numbers, highlight, box)
560
- self.setItems(list, list_size, numbers)
561
- self.set_highlight(highlight)
562
- self.set_box(box)
563
- end
583
+ def alloc_items_arrays(old_size, new_size)
564
584
 
565
- # This sets the scrolling list items
566
- def setItems(list, list_size, numbers)
567
- if self.createItemList(numbers, list, list_size) <= 0
568
- return
569
- end
585
+ new_items = Array.new new_size
586
+ new_len = Array.new new_size
587
+ new_pos = Array.new new_size
570
588
 
571
- # Clean up the display.
572
- (0...@view_size).each do |x|
573
- Draw.writeBlanks(@win, 1, x, RNDK::HORIZONTAL, 0, @box_width - 2);
589
+ (0...old_size).each do |n|
590
+ new_items[n] = @item[n]
591
+ new_len[n] = @item_len[n]
592
+ new_pos[n] = @item_pos[n]
574
593
  end
575
594
 
576
- self.setViewSize(list_size)
577
- self.setPosition(0)
578
- @left_char = 0
595
+ @item = new_items
596
+ @item_len = new_len
597
+ @item_pos = new_pos
598
+
599
+ true
579
600
  end
580
601
 
581
- def getItems(list)
582
- (0...@list_size).each do |x|
583
- list << RNDK.chtype2Char(@item[x])
584
- end
602
+ # Creates a single item on the scroll items.
603
+ def alloc_items_item(which, work, used, number, value)
585
604
 
586
- return @list_size
587
- end
605
+ if number > 0
606
+ value = "%4d. %s" % [number, value]
607
+ end
588
608
 
589
- # This sets the highlight of the scrolling list.
590
- def set_highlight(highlight)
591
- @highlight = highlight
592
- end
609
+ item_len = []
610
+ item_pos = []
611
+ @item[which] = RNDK.char2Chtype(value, item_len, item_pos)
612
+ @item_len[which] = item_len[0]
613
+ @item_pos[which] = item_pos[0]
593
614
 
594
- def getHighlight(highlight)
595
- return @highlight
615
+ @item_pos[which] = RNDK.justifyString(@box_width,
616
+ @item_len[which],
617
+ @item_pos[which])
618
+ true
596
619
  end
597
620
 
598
621
  # Resequence the numbers after an insertion/deletion.
599
622
  def resequence
600
- if @numbers
601
- (0...@list_size).each do |j|
602
- target = @item[j]
623
+ return unless @numbers
603
624
 
604
- source = "%4d. %s" % [j + 1, ""]
625
+ (0...@item.size).each do |j|
626
+ target = @item[j]
605
627
 
606
- k = 0
607
- while k < source.size
608
- # handle deletions that change the length of number
609
- if source[k] == "." && target[k] != "."
610
- source = source[0...k] + source[k+1..-1]
611
- end
628
+ source = "%4d. %s" % [j + 1, ""]
612
629
 
613
- target[k] &= Ncurses::A_ATTRIBUTES
614
- target[k] |= source[k].ord
615
- k += 1
630
+ k = 0
631
+ while k < source.size
632
+ # handle deletions that change the length of number
633
+ if (source[k] == ".") and (target[k] != ".")
634
+ source = source[0...k] + source[k+1..-1]
616
635
  end
636
+
637
+ target[k] &= RNDK::Color[:extract]
638
+ target[k] |= source[k].ord
639
+ k += 1
617
640
  end
618
641
  end
619
642
  end
620
643
 
621
- def insertListItem(item)
644
+ def insert_items_item(item)
622
645
  @item = @item[0..item] + @item[item..-1]
623
646
  @item_len = @item_len[0..item] + @item_len[item..-1]
624
647
  @item_pos = @item_pos[0..item] + @item_pos[item..-1]
625
- return true
648
+
649
+ true
626
650
  end
627
651
 
628
- # This adds a single item to a scrolling list, at the end of the list.
629
- def addItem(item)
630
- item_number = @list_size
631
- widest_item = self.WidestItem
632
- temp = ''
633
- have = 0
634
-
635
- if self.allocListArrays(@list_size, @list_size + 1) &&
636
- self.allocListItem(item_number, temp, have,
637
- if @numbers then item_number + 1 else 0 end,
638
- item)
639
- # Determine the size of the widest item.
640
- widest_item = [@item_len[item_number], widest_item].max
641
-
642
- self.updateViewWidth(widest_item)
643
- self.setViewSize(@list_size + 1)
644
- end
652
+ def available_width
653
+ @box_width - (2 * @border_size)
645
654
  end
646
655
 
647
- # This adds a single item to a scrolling list before the current item
648
- def insertItem(item)
649
- widest_item = self.WidestItem
650
- temp = ''
651
- have = 0
652
-
653
- if self.allocListArrays(@list_size, @list_size + 1) &&
654
- self.insertListItem(@current_item) &&
655
- self.allocListItem(@current_item, temp, have,
656
- if @numbers then @current_item + 1 else 0 end,
657
- item)
658
- # Determine the size of the widest item.
659
- widest_item = [@item_len[@current_item], widest_item].max
660
-
661
- self.updateViewWidth(widest_item)
662
- self.setViewSize(@list_size + 1)
663
- self.resequence
664
- end
656
+ def update_view_width(widest)
657
+ @max_left_char = if @box_width > widest
658
+ then 0
659
+ else widest - self.available_width
660
+ end
665
661
  end
666
662
 
667
- # This removes a single item from a scrolling list.
668
- def deleteItem(position)
669
- if position >= 0 && position < @list_size
670
- # Adjust the list
671
- @item = @item[0...position] + @item[position+1..-1]
672
- @item_len = @item_len[0...position] + @item_len[position+1..-1]
673
- @item_pos = @item_pos[0...position] + @item_pos[position+1..-1]
663
+ def widest_item
664
+ @max_left_char + self.available_width
665
+ end
666
+
667
+ # Draws the scrolling items.
668
+ def draw_items box
669
+
670
+ # If the items is empty, don't draw anything.
671
+ if @item.size > 0
672
+
673
+ # Redraw the items
674
+ (0...@view_size).each do |j|
675
+ k = j + @current_top
676
+
677
+ Draw.writeBlanks(@items_win,
678
+ 0,
679
+ j,
680
+ RNDK::HORIZONTAL, 0,
681
+ @box_width - (2 * @border_size))
674
682
 
675
- self.setViewSize(@list_size - 1)
683
+ # Draw the elements in the scrolling items.
684
+ if k < @item.size
676
685
 
677
- self.resequence if @list_size > 0
686
+ screen_pos = @item_pos[k] - @left_char
687
+ ypos = j
678
688
 
679
- if @list_size < self.maxViewSize
680
- Ncurses.werase @win # force the next redraw to be complete
689
+ # Write in the correct line.
690
+ Draw.writeChtype(@items_win,
691
+ if screen_pos >= 0 then screen_pos else 1 end,
692
+ ypos, @item[k], RNDK::HORIZONTAL,
693
+ if screen_pos >= 0 then 0 else 1 - screen_pos end,
694
+ @item_len[k])
695
+ end
681
696
  end
682
697
 
683
- # do this to update the view size, etc
684
- self.setPosition(@current_item)
698
+ self.draw_current
699
+
700
+ # Determine where the toggle is supposed to be.
701
+ unless @scrollbar_win.nil?
702
+ @toggle_pos = (@current_item * @step).floor
703
+
704
+ # Make sure the toggle button doesn't go out of bounds.
705
+ if @toggle_pos >= Ncurses.getmaxy(@scrollbar_win)
706
+ @toggle_pos = Ncurses.getmaxy(@scrollbar_win) - 1
707
+ end
708
+
709
+ # Draw the scrollbar
710
+ Ncurses.mvwvline(@scrollbar_win,
711
+ 0,
712
+ 0,
713
+ Ncurses::ACS_CKBOARD,
714
+ Ncurses.getmaxy(@scrollbar_win))
715
+
716
+ Ncurses.mvwvline(@scrollbar_win,
717
+ @toggle_pos,
718
+ 0,
719
+ ' '.ord | RNDK::Color[:reverse],
720
+ @toggle_size)
721
+ end
685
722
  end
686
- end
687
723
 
688
- def focus
689
- self.drawCurrent
690
- Ncurses.wrefresh @list_win
724
+ Draw.drawObjBox(@win, self) if box
725
+ Ncurses.wrefresh @win
691
726
  end
692
727
 
693
- def unfocus
694
- self.drawCurrent
695
- Ncurses.wrefresh @list_win
728
+ def get_current_top
729
+ @current_top
696
730
  end
697
731
 
698
- def AvailableWidth
699
- @box_width - (2 * @border_size)
700
- end
732
+ def set_current_top(item)
733
+ if item < 0
734
+ item = 0
735
+ elsif item > @max_top_item
736
+ item = @max_top_item
737
+ end
738
+ @current_top = item
701
739
 
702
- def updateViewWidth(widest)
703
- @max_left_char = if @box_width > widest
704
- then 0
705
- else widest - self.AvailableWidth
706
- end
740
+ self.set_position(item);
707
741
  end
708
742
 
709
- def WidestItem
710
- @max_left_char + self.AvailableWidth
743
+ def draw_current
744
+ # Rehighlight the current menu item.
745
+ screen_pos = @item_pos[@current_item] - @left_char
746
+ highlight = if self.has_focus
747
+ then @highlight
748
+ else RNDK::Color[:normal]
749
+ end
750
+
751
+ Draw.writeChtypeAttrib(@items_win,
752
+ if screen_pos >= 0 then screen_pos else 0 end,
753
+ @current_high, @item[@current_item], highlight, RNDK::HORIZONTAL,
754
+ if screen_pos >= 0 then 0 else 1 - screen_pos end,
755
+ @item_len[@current_item])
711
756
  end
712
757
 
713
- private
758
+ # Put the cursor on the currently-selected item's row.
759
+ def fix_cursor_position
760
+ scrollbar_adj = if @scrollbar_placement == LEFT then 1 else 0 end
761
+ ypos = self.Screen_YPOS(@current_item - @current_top)
762
+ xpos = self.Screen_XPOS(0) + scrollbar_adj
763
+
764
+ Ncurses.wmove(@input_window, ypos, xpos)
765
+ Ncurses.wrefresh(@input_window)
766
+ end
714
767
 
715
768
  end
716
769
  end