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