slithernix-cdk 0.0.1

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