rndk 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/COPYING +137 -0
  4. data/Gemfile +4 -0
  5. data/README.md +100 -0
  6. data/Rakefile +3 -0
  7. data/TODO +68 -0
  8. data/demos/appointment.rb +346 -0
  9. data/demos/clock.rb +56 -0
  10. data/examples/01-hello-world.rb +56 -0
  11. data/examples/05-position-widget.rb +108 -0
  12. data/lib/rndk.rb +912 -0
  13. data/lib/rndk/alphalist.rb +572 -0
  14. data/lib/rndk/button.rb +370 -0
  15. data/lib/rndk/buttonbox.rb +359 -0
  16. data/lib/rndk/calendar.rb +766 -0
  17. data/lib/rndk/core/display.rb +63 -0
  18. data/lib/rndk/core/draw.rb +238 -0
  19. data/lib/rndk/core/quick_widgets.rb +106 -0
  20. data/lib/rndk/core/screen.rb +269 -0
  21. data/lib/rndk/core/traverse.rb +289 -0
  22. data/lib/rndk/core/widget.rb +506 -0
  23. data/lib/rndk/dialog.rb +367 -0
  24. data/lib/rndk/dscale.rb +13 -0
  25. data/lib/rndk/entry.rb +575 -0
  26. data/lib/rndk/fscale.rb +61 -0
  27. data/lib/rndk/fselect.rb +940 -0
  28. data/lib/rndk/fslider.rb +80 -0
  29. data/lib/rndk/graph.rb +401 -0
  30. data/lib/rndk/histogram.rb +412 -0
  31. data/lib/rndk/itemlist.rb +474 -0
  32. data/lib/rndk/label.rb +218 -0
  33. data/lib/rndk/marquee.rb +244 -0
  34. data/lib/rndk/matrix.rb +1189 -0
  35. data/lib/rndk/mentry.rb +619 -0
  36. data/lib/rndk/menu.rb +478 -0
  37. data/lib/rndk/radio.rb +538 -0
  38. data/lib/rndk/scale.rb +538 -0
  39. data/lib/rndk/scroll.rb +633 -0
  40. data/lib/rndk/scroller.rb +183 -0
  41. data/lib/rndk/selection.rb +630 -0
  42. data/lib/rndk/slider.rb +545 -0
  43. data/lib/rndk/swindow.rb +766 -0
  44. data/lib/rndk/template.rb +560 -0
  45. data/lib/rndk/uscale.rb +14 -0
  46. data/lib/rndk/uslider.rb +14 -0
  47. data/lib/rndk/version.rb +6 -0
  48. data/lib/rndk/viewer.rb +825 -0
  49. data/rndk.gemspec +35 -0
  50. metadata +141 -0
@@ -0,0 +1,14 @@
1
+ require 'rndk/scale'
2
+
3
+ module RNDK
4
+ class USCALE < RNDK::SCALE
5
+ # The original UScale handled unsigned values.
6
+ # Since Ruby's typing is different this is really just SCALE
7
+ # but is nice it's nice to have this for compatibility/completeness
8
+ # sake.
9
+
10
+ def object_type
11
+ :USCALE
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'rndk/slider'
2
+
3
+ module RNDK
4
+ class USLIDER < RNDK::SLIDER
5
+ # The original USlider handled unsigned values.
6
+ # Since Ruby's typing is different this is really just SLIDER
7
+ # but is nice it's nice to have this for compatibility/completeness
8
+ # sake.
9
+
10
+ def object_type
11
+ :USLIDER
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ module RNDK
2
+ VERSION="0.0.1"
3
+ VERSION_MAJOR = VERSION.split('.')[0]
4
+ VERSION_MINOR = VERSION.split('.')[1]
5
+ VERSION_PATCH = VERSION.split('.')[2]
6
+ end
@@ -0,0 +1,825 @@
1
+ require 'rndk'
2
+
3
+ module RNDK
4
+ class VIEWER < RNDK::Widget
5
+ DOWN = 0
6
+ UP = 1
7
+
8
+ def initialize(rndkscreen, xplace, yplace, height, width,
9
+ buttons, button_count, button_highlight, box, shadow)
10
+ super()
11
+ parent_width = Ncurses.getmaxx(rndkscreen.window)
12
+ parent_height = Ncurses.getmaxy(rndkscreen.window)
13
+ box_width = width
14
+ box_height = height
15
+ button_width = 0
16
+ button_adj = 0
17
+ button_pos = 1
18
+ bindings = {
19
+ RNDK::BACKCHAR => Ncurses::KEY_PPAGE,
20
+ 'b' => Ncurses::KEY_PPAGE,
21
+ 'B' => Ncurses::KEY_PPAGE,
22
+ RNDK::FORCHAR => Ncurses::KEY_NPAGE,
23
+ ' ' => Ncurses::KEY_NPAGE,
24
+ 'f' => Ncurses::KEY_NPAGE,
25
+ 'F' => Ncurses::KEY_NPAGE,
26
+ '|' => Ncurses::KEY_HOME,
27
+ '$' => Ncurses::KEY_END,
28
+ }
29
+
30
+ self.setBox(box)
31
+
32
+ box_height = RNDK.setWidgetDimension(parent_height, height, 0)
33
+ box_width = RNDK.setWidgetDimension(parent_width, width, 0)
34
+
35
+ # Rejustify the x and y positions if we need to.
36
+ xtmp = [xplace]
37
+ ytmp = [yplace]
38
+ RNDK.alignxy(rndkscreen.window, xtmp, ytmp, box_width, box_height)
39
+ xpos = xtmp[0]
40
+ ypos = ytmp[0]
41
+
42
+ # Make the viewer window.
43
+ @win= Ncurses.newwin(box_height, box_width, ypos, xpos)
44
+ if @win.nil?
45
+ self.destroy
46
+ return nil
47
+ end
48
+
49
+ # Turn the keypad on for the viewer.
50
+ Ncurses.keypad(@win, true)
51
+
52
+ # Create the buttons.
53
+ @button_count = button_count
54
+ @button = []
55
+ @button_len = []
56
+ @button_pos = []
57
+ if button_count > 0
58
+ (0...button_count).each do |x|
59
+ button_len = []
60
+ @button << RNDK.char2Chtype(buttons[x], button_len, [])
61
+ @button_len << button_len[0]
62
+ button_width += @button_len[x] + 1
63
+ end
64
+ button_adj = (box_width - button_width) / (button_count + 1)
65
+ button_pos = 1 + button_adj
66
+ (0...button_count).each do |x|
67
+ @button_pos << button_pos
68
+ button_pos += button_adj + @button_len[x]
69
+ end
70
+ end
71
+
72
+ # Set the rest of the variables.
73
+ @screen = rndkscreen
74
+ @parent = rndkscreen.window
75
+ @shadow_win = nil
76
+ @button_highlight = button_highlight
77
+ @box_height = box_height
78
+ @box_width = box_width - 2
79
+ @view_size = height - 2
80
+ @input_window = @win
81
+ @shadow = shadow
82
+ @current_button = 0
83
+ @current_top = 0
84
+ @length = 0
85
+ @left_char = 0
86
+ @max_left_char = 0
87
+ @max_top_line = 0
88
+ @characters = 0
89
+ @list_size = -1
90
+ @show_line_info = 1
91
+ @exit_type = :EARLY_EXIT
92
+
93
+ # Do we need to create a shadow?
94
+ if shadow
95
+ @shadow_win = Ncurses.newwin(box_height,
96
+ box_width + 1,
97
+ ypos + 1,
98
+ xpos + 1)
99
+ if @shadow_win.nil?
100
+ self.destroy
101
+ return nil
102
+ end
103
+ end
104
+
105
+ # Setup the key bindings.
106
+ bindings.each do |from, to|
107
+ self.bind(:VIEWER, from, :getc, to)
108
+ end
109
+
110
+ rndkscreen.register(:VIEWER, self)
111
+ end
112
+
113
+ # This function sets various attributes of the widget.
114
+ def set(title, list, list_size, button_highlight,
115
+ attr_interp, show_line_info, box)
116
+ self.setTitle(title)
117
+ self.setHighlight(button_highlight)
118
+ self.setInfoLine(show_line_info)
119
+ self.setBox(box)
120
+ return self.setInfo(list, list_size, attr_interp)
121
+ end
122
+
123
+ # This sets the title of the viewer. (A nil title is allowed.
124
+ # It just means that the viewer will not have a title when drawn.)
125
+ def setTitle(title)
126
+ super(title, -(@box_width + 1))
127
+ @title_adj = @title_lines
128
+
129
+ # Need to set @view_size
130
+ @view_size = @box_height - (@title_lines + 1) - 2
131
+ end
132
+
133
+ def getTitle
134
+ return @title
135
+ end
136
+
137
+ def setupLine(interpret, list, x)
138
+ # Did they ask for attribute interpretation?
139
+ if interpret
140
+ list_len = []
141
+ list_pos = []
142
+ @list[x] = RNDK.char2Chtype(list, list_len, list_pos)
143
+ @list_len[x] = list_len[0]
144
+ @list_pos[x] = RNDK.justifyString(@box_width, @list_len[x], list_pos[0])
145
+ else
146
+ # We must convert tabs and other nonprinting characters. The curses
147
+ # library normally does this, but we are bypassing it by writing
148
+ # chtypes directly.
149
+ t = ''
150
+ len = 0
151
+ (0...list.size).each do |y|
152
+ if list[y] == "\t".ord
153
+ begin
154
+ t << ' '
155
+ len += 1
156
+ end while (len & 7) != 0
157
+ elsif RNDK.CharOf(list[y].ord).match(/^[[:print:]]$/)
158
+ t << RNDK.CharOf(list[y].ord)
159
+ len += 1
160
+ else
161
+ t << Ncurses.unctrl(list[y].ord)
162
+ len += 1
163
+ end
164
+ end
165
+ @list[x] = t
166
+ @list_len[x] = t.size
167
+ @list_pos[x] = 0
168
+ end
169
+ @widest_line = [@widest_line, @list_len[x]].max
170
+ end
171
+
172
+ def freeLine(x)
173
+ if x < @list_size
174
+ @list[x] = ''
175
+ end
176
+ end
177
+
178
+ # This function sets the contents of the viewer.
179
+ def setInfo(list, list_size, interpret)
180
+ current_line = 0
181
+ viewer_size = list_size
182
+
183
+ if list_size < 0
184
+ list_size = list.size
185
+ end
186
+
187
+ # Compute the size of the resulting display
188
+ viewer_size = list_size
189
+ if list.size > 0 && interpret
190
+ (0...list_size).each do |x|
191
+ filename = ''
192
+ if RNDK.checkForLink(list[x], filename) == 1
193
+ file_contents = []
194
+ file_len = RNDK.readFile(filename, file_contents)
195
+
196
+ if file_len >= 0
197
+ viewer_size += (file_len - 1)
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ # Clean out the old viewer info. (if there is any)
204
+ @in_progress = true
205
+ self.clean
206
+ self.createList(viewer_size)
207
+
208
+ # Keep some semi-permanent info
209
+ @interpret = interpret
210
+
211
+ # Copy the information given.
212
+ current_line = 0
213
+ x = 0
214
+ while x < list_size && current_line < viewer_size
215
+ if list[x].size == 0
216
+ @list[current_line] = ''
217
+ @list_len[current_line] = 0
218
+ @list_pos[current_line] = 0
219
+ current_line += 1
220
+ else
221
+ # Check if we have a file link in this line.
222
+ filename = []
223
+ if RNDK.checkForLink(list[x], filename) == 1
224
+ # We have a link, open the file.
225
+ file_contents = []
226
+ file_len = 0
227
+
228
+ # Open the file and put it into the viewer
229
+ file_len = RNDK.readFile(filename, file_contents)
230
+ if file_len == -1
231
+ fopen_fmt = if Ncurses.has_colors?
232
+ then '<C></16>Link Failed: Could not open the file %s'
233
+ else '<C></K>Link Failed: Could not open the file %s'
234
+ end
235
+ temp = fopen_fmt % filename
236
+ self.setupLine(true, temp, current_line)
237
+ current_line += 1
238
+ else
239
+ # For each line read, copy it into the viewer.
240
+ file_len = [file_len, viewer_size - current_line].min
241
+ (0...file_len).each do |file_line|
242
+ if current_line >= viewer_size
243
+ break
244
+ end
245
+ self.setupLine(false, file_contents[file_line], current_line)
246
+ @characters += @list_len[current_line]
247
+ current_line += 1
248
+ end
249
+ end
250
+ elsif current_line < viewer_size
251
+ self.setupLine(@interpret, list[x], current_line)
252
+ @characters += @list_len[current_line]
253
+ current_line += 1
254
+ end
255
+ end
256
+ x+= 1
257
+ end
258
+
259
+ # Determine how many characters we can shift to the right before
260
+ # all the items have been viewer off the screen.
261
+ if @widest_line > @box_width
262
+ @max_left_char = (@widest_line - @box_width) + 1
263
+ else
264
+ @max_left_char = 0
265
+ end
266
+
267
+ # Set up the needed vars for the viewer list.
268
+ @in_progress = false
269
+ @list_size = viewer_size
270
+ if @list_size <= @view_size
271
+ @max_top_line = 0
272
+ else
273
+ @max_top_line = @list_size - 1
274
+ end
275
+ return @list_size
276
+ end
277
+
278
+ def getInfo(size)
279
+ size << @list_size
280
+ return @list
281
+ end
282
+
283
+ # This function sets the highlight type of the buttons.
284
+ def setHighlight(button_highlight)
285
+ @button_highlight = button_highlight
286
+ end
287
+
288
+ def getHighlight
289
+ return @button_highlight
290
+ end
291
+
292
+ # This sets whether or not you wnat to set the viewer info line.
293
+ def setInfoLine(show_line_info)
294
+ @show_line_info = show_line_info
295
+ end
296
+
297
+ def getInfoLine
298
+ return @show_line_info
299
+ end
300
+
301
+ # This removes all the lines inside the scrolling window.
302
+ def clean
303
+ # Clean up the memory used...
304
+ (0...@list_size).each do |x|
305
+ self.freeLine(x)
306
+ end
307
+
308
+ # Reset some variables.
309
+ @list_size = 0
310
+ @max_left_char = 0
311
+ @widest_line = 0
312
+ @current_top = 0
313
+ @max_top_line = 0
314
+
315
+ # Redraw the window.
316
+ self.draw @box
317
+ end
318
+
319
+ def PatternNotFound(pattern)
320
+ temp_info = [
321
+ "</U/5>Pattern '%s' not found.<!U!5>" % pattern,
322
+ ]
323
+ self.popUpLabel(temp_info)
324
+ end
325
+
326
+ # This function actually controls the viewer...
327
+ def activate(actions)
328
+ refresh = false
329
+ # Create the information about the file stats.
330
+ file_info = [
331
+ '</5> </U>File Statistics<!U> <!5>',
332
+ '</5> <!5>',
333
+ '</5/R>Character Count:<!R> %-4d <!5>' % @characters,
334
+ '</5/R>Line Count :<!R> %-4d <!5>' % @list_size,
335
+ '</5> <!5>',
336
+ '<C></5>Press Any Key To Continue.<!5>'
337
+ ]
338
+
339
+ temp_info = ['<C></5>Press Any Key To Continue.<!5>']
340
+
341
+ # Set the current button.
342
+ @current_button = 0
343
+
344
+ # Draw the widget list.
345
+ self.draw(@box)
346
+
347
+ # Do this until KEY_ENTER is hit.
348
+ while true
349
+ # Reset the refresh flag.
350
+ refresh = false
351
+
352
+ input = self.getch([])
353
+ if !self.checkBind(:VIEWER, input)
354
+ case input
355
+ when RNDK::KEY_TAB
356
+ if @button_count > 1
357
+ if @current_button == @button_count - 1
358
+ @current_button = 0
359
+ else
360
+ @current_button += 1
361
+ end
362
+
363
+ # Redraw the buttons.
364
+ self.drawButtons
365
+ end
366
+ when RNDK::PREV
367
+ if @button_count > 1
368
+ if @current_button == 0
369
+ @current_button = @button_count - 1
370
+ else
371
+ @current_button -= 1
372
+ end
373
+
374
+ # Redraw the buttons.
375
+ self.drawButtons
376
+ end
377
+ when Ncurses::KEY_UP
378
+ if @current_top > 0
379
+ @current_top -= 1
380
+ refresh = true
381
+ else
382
+ RNDK.beep
383
+ end
384
+ when Ncurses::KEY_DOWN
385
+ if @current_top < @max_top_line
386
+ @current_top += 1
387
+ refresh = true
388
+ else
389
+ RNDK.beep
390
+ end
391
+ when Ncurses::KEY_RIGHT
392
+ if @left_char < @max_left_char
393
+ @left_char += 1
394
+ refresh = true
395
+ else
396
+ RNDK.beep
397
+ end
398
+ when Ncurses::KEY_LEFT
399
+ if @left_char > 0
400
+ @left_char -= 1
401
+ refresh = true
402
+ else
403
+ RNDK.beep
404
+ end
405
+ when Ncurses::KEY_PPAGE
406
+ if @current_top > 0
407
+ if @current_top - (@view_size - 1) > 0
408
+ @current_top = @current_top - (@view_size - 1)
409
+ else
410
+ @current_top = 0
411
+ end
412
+ refresh = true
413
+ else
414
+ RNDK.beep
415
+ end
416
+ when Ncurses::KEY_NPAGE
417
+ if @current_top < @max_top_line
418
+ if @current_top + @view_size < @max_top_line
419
+ @current_top = @current_top + (@view_size - 1)
420
+ else
421
+ @current_top = @max_top_line
422
+ end
423
+ refresh = true
424
+ else
425
+ RNDK.beep
426
+ end
427
+ when Ncurses::KEY_HOME
428
+ @left_char = 0
429
+ refresh = true
430
+ when Ncurses::KEY_END
431
+ @left_char = @max_left_char
432
+ refresh = true
433
+ when 'g'.ord, '1'.ord, '<'.ord
434
+ @current_top = 0
435
+ refresh = true
436
+ when 'G'.ord, '>'.ord
437
+ @current_top = @max_top_line
438
+ refresh = true
439
+ when 'L'.ord
440
+ x = (@list_size + @current_top) / 2
441
+ if x < @max_top_line
442
+ @current_top = x
443
+ refresh = true
444
+ else
445
+ RNDK.beep
446
+ end
447
+ when 'l'.ord
448
+ x = @current_top / 2
449
+ if x >= 0
450
+ @current_top = x
451
+ refresh = true
452
+ else
453
+ RNDK.beep
454
+ end
455
+ when '?'.ord
456
+ @search_direction = RNDK::VIEWER::UP
457
+ self.getAndStorePattern(@screen)
458
+ if !self.searchForWord(@search_pattern, @search_direction)
459
+ self.PatternNotFound(@search_pattern)
460
+ end
461
+ refresh = true
462
+ when '/'.ord
463
+ @search_direction = RNDK::VIEWER:DOWN
464
+ self.getAndStorePattern(@screen)
465
+ if !self.searchForWord(@search_pattern, @search_direction)
466
+ self.PatternNotFound(@search_pattern)
467
+ end
468
+ refresh = true
469
+ when 'N'.ord, 'n'.ord
470
+ if @search_pattern == ''
471
+ temp_info[0] = '</5>There is no pattern in the buffer.<!5>'
472
+ self.popUpLabel(temp_info)
473
+ elsif !self.searchForWord(@search_pattern,
474
+ if input == 'n'.ord
475
+ then @search_direction
476
+ else 1 - @search_direction
477
+ end)
478
+ self.PatternNotFound(@search_pattern)
479
+ end
480
+ refresh = true
481
+ when ':'.ord
482
+ @current_top = self.jumpToLine
483
+ refresh = true
484
+ when 'i'.ord, 's'.ord, 'S'.ord
485
+ self.popUpLabel(file_info)
486
+ refresh = true
487
+ when RNDK::KEY_ESC
488
+ self.setExitType(input)
489
+ return -1
490
+ when Ncurses::ERR
491
+ self.setExitType(input)
492
+ return -1
493
+ when Ncurses::KEY_ENTER, RNDK::KEY_RETURN
494
+ self.setExitType(input)
495
+ return @current_button
496
+ when RNDK::REFRESH
497
+ @screen.erase
498
+ @screen.refresh
499
+ else
500
+ RNDK.beep
501
+ end
502
+ end
503
+
504
+ # Do we need to redraw the screen?
505
+ if refresh
506
+ self.drawInfo
507
+ end
508
+ end
509
+ end
510
+
511
+ # This searches the document looking for the given word.
512
+ def getAndStorePattern(screen)
513
+ temp = ''
514
+
515
+ # Check the direction.
516
+ if @search_direction == RNDK::VIEWER::UP
517
+ temp = '</5>Search Up : <!5>'
518
+ else
519
+ temp = '</5>Search Down: <!5>'
520
+ end
521
+
522
+ # Pop up the entry field.
523
+ get_pattern = RNDK::ENTRY.new(screen, RNDK::CENTER, RNDK::CENTER,
524
+ '', label, Ncurses.COLOR_PAIR(5) | Ncurses::A_BOLD,
525
+ '.' | Ncurses.COLOR_PAIR(5) | Ncurses::A_BOLD,
526
+ :MIXED, 10, 0, 256, true, false)
527
+
528
+ # Is there an old search pattern?
529
+ if @search_pattern.size != 0
530
+ get_pattern.set(@search_pattern, get_pattern.min, get_pattern.max,
531
+ get_pattern.box)
532
+ end
533
+
534
+ # Activate this baby.
535
+ list = get_pattern.activate([])
536
+
537
+ # Save teh list.
538
+ if list.size != 0
539
+ @search_pattern = list
540
+ end
541
+
542
+ # Clean up.
543
+ get_pattern.destroy
544
+ end
545
+
546
+ # This searches for a line containing the word and realigns the value on
547
+ # the screen.
548
+ def searchForWord(pattern, direction)
549
+ found = false
550
+
551
+ # If the pattern is empty then return.
552
+ if pattern.size != 0
553
+ if direction == RNDK::VIEWER::DOWN
554
+ # Start looking from 'here' down.
555
+ x = @current_top + 1
556
+ while !found && x < @list_size
557
+ pos = 0
558
+ y = 0
559
+ while y < @list[x].size
560
+ plain_char = RNDK.CharOf(@list[x][y])
561
+
562
+ pos += 1
563
+ if @RNDK.CharOf(pattern[pos-1]) != plain_char
564
+ y -= (pos - 1)
565
+ pos = 0
566
+ elsif pos == pattern.size
567
+ @current_top = [x, @max_top_line].min
568
+ @left_char = if y < @box_width then 0 else @max_left_char end
569
+ found = true
570
+ break
571
+ end
572
+ y += 1
573
+ end
574
+ x += 1
575
+ end
576
+ else
577
+ # Start looking from 'here' up.
578
+ x = @current_top - 1
579
+ while ! found && x >= 0
580
+ y = 0
581
+ pos = 0
582
+ while y < @list[x].size
583
+ plain_char = RNDK.CharOf(@list[x][y])
584
+
585
+ pos += 1
586
+ if RNDK.CharOf(pattern[pos-1]) != plain_char
587
+ y -= (pos - 1)
588
+ pos = 0
589
+ elsif pos == pattern.size
590
+ @current_top = x
591
+ @left_char = if y < @box_width then 0 else @max_left_char end
592
+ found = true
593
+ break
594
+ end
595
+ end
596
+ end
597
+ end
598
+ end
599
+ return found
600
+ end
601
+
602
+ # This allows us to 'jump' to a given line in the file.
603
+ def jumpToLine
604
+ newline = RNDK::SCALE.new(@screen, RNDK::CENTER, RNDK::CENTER,
605
+ '<C>Jump To Line', '</5>Line :', Ncurses::A_BOLD,
606
+ @list_size.size + 1, @current_top + 1, 0, @max_top_line + 1,
607
+ 1, 10, true, true)
608
+ line = newline.activate([])
609
+ newline.destroy
610
+ return line - 1
611
+ end
612
+
613
+ # This pops a little message up on the screen.
614
+ def popUpLabel(mesg)
615
+ # Set up variables.
616
+ label = RNDK::LABEL.new(@screen, RNDK::CENTER, RNDK::CENTER,
617
+ mesg, mesg.size, true, false)
618
+
619
+ # Draw the label and wait.
620
+ label.draw(true)
621
+ label.getch([])
622
+
623
+ # Clean up.
624
+ label.destroy
625
+ end
626
+
627
+ # This moves the viewer field to the given location.
628
+ # Inherited
629
+ # def move(xplace, yplace, relative, refresh_flag)
630
+ # end
631
+
632
+ # This function draws the viewer widget.
633
+ def draw(box)
634
+ # Do we need to draw in the shadow?
635
+ unless @shadow_win.nil?
636
+ Draw.drawShadow @shadow_win
637
+ end
638
+
639
+ # Box it if it was asked for.
640
+ if box
641
+ Draw.drawObjBox(@win, self)
642
+ Ncurses.wrefresh @win
643
+ end
644
+
645
+ # Draw the info in the viewer.
646
+ self.drawInfo
647
+ end
648
+
649
+ # This redraws the viewer buttons.
650
+ def drawButtons
651
+ # No buttons, no drawing
652
+ if @button_count == 0
653
+ return
654
+ end
655
+
656
+ # Redraw the buttons.
657
+ (0...@button_count).each do |x|
658
+ Draw.writeChtype(@win,
659
+ @button_pos[x],
660
+ @box_height - 2,
661
+ @button[x],
662
+ RNDK::HORIZONTAL,
663
+ 0,
664
+ @button_len[x])
665
+ end
666
+
667
+ # Highlight the current button.
668
+ (0...@button_len[@current_button]).each do |x|
669
+ # Strip the character of any extra attributes.
670
+ character = RNDK.CharOf(@button[@current_button][x])
671
+
672
+ # Add the character into the window.
673
+ Ncurses.mvwaddch(@win,
674
+ @box_height - 2,
675
+ @button_pos[@current_button] + x,
676
+ character.ord | @button_highlight)
677
+ end
678
+
679
+ # Refresh the window.
680
+ Ncurses.wrefresh @win
681
+ end
682
+
683
+ # This sets the background attribute of the widget.
684
+ def setBKattr(attrib)
685
+ Ncurses.wbkgd(@win, attrib)
686
+ end
687
+
688
+ def destroyInfo
689
+ @list = []
690
+ @list_pos = []
691
+ @list_len = []
692
+ end
693
+
694
+ # This function destroys the viewer widget.
695
+ def destroy
696
+ self.destroyInfo
697
+
698
+ self.cleanTitle
699
+
700
+ # Clean up the windows.
701
+ RNDK.deleteCursesWindow(@shadow_win)
702
+ RNDK.deleteCursesWindow(@win)
703
+
704
+ # Clean the key bindings.
705
+ self.cleanBindings(:VIEWER)
706
+
707
+ # Unregister this object.
708
+ RNDK::Screen.unregister(:VIEWER, self)
709
+ end
710
+
711
+ # This function erases the viewer widget from the screen.
712
+ def erase
713
+ if self.validRNDKObject
714
+ RNDK.eraseCursesWindow(@win)
715
+ RNDK.eraseCursesWindow(@shadow_win)
716
+ end
717
+ end
718
+
719
+ # This draws the viewer info lines.
720
+ def drawInfo
721
+ temp = ''
722
+ line_adjust = false
723
+
724
+ # Clear the window.
725
+ Ncurses.werase(@win)
726
+
727
+ self.drawTitle(@win)
728
+
729
+ # Draw in the current line at the top.
730
+ if @show_line_info == true
731
+ # Set up the info line and draw it.
732
+ if @in_progress
733
+ temp = 'processing...'
734
+ elsif @list_size != 0
735
+ temp = '%d/%d %2.0f%%' % [@current_top + 1, @list_size,
736
+ ((1.0 * @current_top + 1) / (@list_size)) * 100]
737
+ else
738
+ temp = '%d/%d %2.0f%%' % [0, 0, 0.0]
739
+ end
740
+
741
+ # The list_adjust variable tells us if we have to shift down one line
742
+ # because the person asked for the line X of Y line at the top of the
743
+ # screen. We only want to set this to true if they asked for the info
744
+ # line and there is no title or if the two items overlap.
745
+ if @title_lines == '' || @title_pos[0] < temp.size + 2
746
+ list_adjust = true
747
+ end
748
+ Draw.writeChar(@win,
749
+ 1,
750
+ if list_adjust then @title_lines else 0 end + 1,
751
+ temp,
752
+ RNDK::HORIZONTAL,
753
+ 0,
754
+ temp.size)
755
+ end
756
+
757
+ # Determine the last line to draw.
758
+ last_line = [@list_size, @view_size].min
759
+ last_line -= if list_adjust then 1 else 0 end
760
+
761
+ # Redraw the list.
762
+ (0...last_line).each do |x|
763
+ if @current_top + x < @list_size
764
+ screen_pos = @list_pos[@current_top + x] + 1 - @left_char
765
+
766
+ Draw.writeChtype(@win,
767
+ if screen_pos >= 0 then screen_pos else 1 end,
768
+ x + @title_lines + if list_adjust then 1 else 0 end + 1,
769
+ @list[x + @current_top],
770
+ RNDK::HORIZONTAL,
771
+ if screen_pos >= 0
772
+ then 0
773
+ else @left_char - @list_pos[@current_top + x]
774
+ end,
775
+ @list_len[x + @current_top])
776
+ end
777
+ end
778
+
779
+ # Box it if we have to.
780
+ if @box
781
+ Draw.drawObjBox(@win, self)
782
+ Ncurses.wrefresh @win
783
+ end
784
+
785
+ # Draw the separation line.
786
+ if @button_count > 0
787
+ boxattr = @BXAttr
788
+
789
+ (1..@box_width).each do |x|
790
+ Ncurses.mvwaddch(@win, @box_height - 3, x, @HZChar | boxattr)
791
+ end
792
+
793
+ Ncurses.mvwaddch(@win, @box_height - 3, 0, Ncurses::ACS_LTEE | boxattr)
794
+ Ncurses.mvwaddch(@win, @box_height - 3, Ncurses.getmaxx(@win) - 1, Ncurses::ACS_RTEE | boxattr)
795
+ end
796
+
797
+ # Draw the buttons. This will call refresh on the viewer win.
798
+ self.drawButtons
799
+ end
800
+
801
+ # The list_size may be negative, to assign no definite limit.
802
+ def createList(list_size)
803
+ status = false
804
+
805
+ self.destroyInfo
806
+
807
+ if list_size >= 0
808
+ status = true
809
+
810
+ @list = []
811
+ @list_pos = []
812
+ @list_len = []
813
+ end
814
+ return status
815
+ end
816
+
817
+ def position
818
+ super(@win)
819
+ end
820
+
821
+ def object_type
822
+ :VIEWER
823
+ end
824
+ end
825
+ end