rndk 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.
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,619 @@
1
+ require 'rndk'
2
+
3
+ module RNDK
4
+ class MENTRY < RNDK::Widget
5
+ attr_accessor :info, :current_col, :current_row, :top_row
6
+ attr_reader :disp_type, :field_width, :rows, :field_win
7
+
8
+ def initialize(rndkscreen, xplace, yplace, title, label, field_attr,
9
+ filler, disp_type, f_width, f_rows, logical_rows, min, box, shadow)
10
+ super()
11
+ parent_width = Ncurses.getmaxx(rndkscreen.window)
12
+ parent_height = Ncurses.getmaxy(rndkscreen.window)
13
+ field_width = f_width
14
+ field_rows = f_rows
15
+
16
+ self.setBox(box)
17
+
18
+ # If the field_width is a negative value, the field_width will be
19
+ # COLS-field_width, otherwise the field_width will be the given width.
20
+ field_width = RNDK.setWidgetDimension(parent_width, field_width, 0)
21
+
22
+ # If the field_rows is a negative value, the field_rows will be
23
+ # ROWS-field_rows, otherwise the field_rows will be the given rows.
24
+ field_rows = RNDK.setWidgetDimension(parent_width, field_rows, 0)
25
+ box_height = field_rows + 2
26
+
27
+ # Set some basic values of the mentry field
28
+ @label = ''
29
+ @label_len = 0
30
+ @label_win = nil
31
+
32
+ # We need to translate the string label to a chtype array
33
+ if label.size > 0
34
+ label_len = []
35
+ @label = RNDK.char2Chtype(label, label_len, [])
36
+ @label_len = label_len[0]
37
+ end
38
+ box_width = @label_len + field_width + 2
39
+
40
+ old_width = box_width
41
+ box_width = self.setTitle(title, box_width)
42
+ horizontal_adjust = (box_width - old_width) / 2
43
+
44
+ box_height += @title_lines
45
+
46
+ # Make sure we didn't extend beyond the parent window.
47
+ box_width = [box_width, parent_width].min
48
+ box_height = [box_height, parent_height].min
49
+ field_width = [box_width - @label_len - 2, field_width].min
50
+ field_rows = [box_height - @title_lines - 2, field_rows].min
51
+
52
+ # Rejustify the x and y positions if we need to.
53
+ xtmp = [xplace]
54
+ ytmp = [yplace]
55
+ RNDK.alignxy(rndkscreen.window, xtmp, ytmp, box_width, box_height)
56
+ xpos = xtmp[0]
57
+ ypos = ytmp[0]
58
+
59
+ # Make the label window.
60
+ @win = Ncurses.newwin(box_height, box_width, ypos, xpos)
61
+
62
+ # Is the window nil?
63
+ if @win.nil?
64
+ self.destroy
65
+ return nil
66
+ end
67
+
68
+ # Create the label window.
69
+ if @label.size > 0
70
+ @label_win = Ncurses.subwin(@win,
71
+ field_rows,
72
+ @label_len + 2,
73
+ ypos + @title_lines + 1,
74
+ xpos + horizontal_adjust + 1)
75
+ end
76
+
77
+ # make the field window.
78
+ @field_win = Ncurses.subwin(@win,
79
+ field_rows,
80
+ field_width,
81
+ ypos + @title_lines + 1,
82
+ xpos + @label_len + horizontal_adjust + 1)
83
+
84
+ # Turn on the keypad.
85
+ Ncurses.keypad(@field_win, true)
86
+ Ncurses.keypad(@win, true)
87
+
88
+ # Set up the rest of the structure.
89
+ @parent = rndkscreen.window
90
+ @total_width = (field_width * logical_rows) + 1
91
+
92
+ # Create the info string
93
+ @info = ''
94
+
95
+ # Set up the rest of the widget information.
96
+ @screen = rndkscreen
97
+ @shadow_win = nil
98
+ @field_attr = field_attr
99
+ @field_width = field_width
100
+ @rows = field_rows
101
+ @box_height = box_height
102
+ @box_width = box_width
103
+ @filler = filler.ord
104
+ @hidden = filler.ord
105
+ @input_window = @win
106
+ @accepts_focus = true
107
+ @current_row = 0
108
+ @current_col = 0
109
+ @top_row = 0
110
+ @shadow = shadow
111
+ @disp_type = disp_type
112
+ @min = min
113
+ @logical_rows = logical_rows
114
+
115
+ # This is a generic character parser for the mentry field. It is used as
116
+ # a callback function, so any personal modifications can be made by
117
+ # creating a new function and calling that one the mentry activation.
118
+ mentry_callback = lambda do |mentry, character|
119
+ cursor_pos = mentry.getCursorPos
120
+ newchar = Display.filterByDisplayType(mentry.disp_type, character)
121
+
122
+ if newchar == Ncurses::ERR
123
+ RNDK.beep
124
+ else
125
+ mentry.info = mentry.info[0...cursor_pos] + newchar.chr +
126
+ mentry.info[cursor_pos..-1]
127
+ mentry.current_col += 1
128
+
129
+ mentry.drawField
130
+
131
+ # Have we gone out of bounds
132
+ if mentry.current_col >= mentry.field_width
133
+ # Update the row and col values.
134
+ mentry.current_col = 0
135
+ mentry.current_row += 1
136
+
137
+ # If we have gone outside of the visual boundaries, we
138
+ # need to scroll the window.
139
+ if mentry.current_row == mentry.rows
140
+ # We have to redraw the screen
141
+ mentry.current_row -= 1
142
+ mentry.top_row += 1
143
+ mentry.drawField
144
+ end
145
+ Ncurses.wmove(mentry.field_win, mentry.current_row, mentry.current_col)
146
+ Ncurses.wrefresh(mentry.field_win)
147
+ end
148
+ end
149
+ end
150
+ @callbackfn = mentry_callback
151
+
152
+ # Do we need to create a shadow.
153
+ if shadow
154
+ @shadow_win = Ncurses.newwin(box_height,
155
+ box_width,
156
+ ypos + 1,
157
+ xpos + 1)
158
+ end
159
+
160
+ # Register
161
+ rndkscreen.register(:MENTRY, self)
162
+ end
163
+
164
+ # This actually activates the mentry widget...
165
+ def activate(actions)
166
+ input = 0
167
+
168
+ # Draw the mentry widget.
169
+ self.draw(@box)
170
+
171
+ if actions.size == 0
172
+ while true
173
+ input = self.getch([])
174
+
175
+ # Inject this character into the widget.
176
+ ret = self.inject(input)
177
+ if @exit_type != :EARLY_EXIT
178
+ return ret
179
+ end
180
+ end
181
+ else
182
+ actions.each do |action|
183
+ ret = self.inject(action)
184
+ if @exit_type != :EARLY_EXIT
185
+ return ret
186
+ end
187
+ end
188
+ end
189
+
190
+ # Set the exit type and exit.
191
+ self.setExitType(0)
192
+ return 0
193
+ end
194
+
195
+ def setTopRow(row)
196
+ if @top_row != row
197
+ @top_row = row
198
+ return true
199
+ end
200
+ return false
201
+ end
202
+
203
+ def setCurPos(row, col)
204
+ if @current_row != row || @current_col != col
205
+ @current_row = row
206
+ @current_col = col
207
+ return true
208
+ end
209
+ return false
210
+ end
211
+
212
+ def KEY_LEFT(moved, redraw)
213
+ result = true
214
+ if @current_col != 0
215
+ moved[0] = self.setCurPos(@current_row, @current_col - 1)
216
+ elsif @current_row == 0
217
+ if @top_row != 0
218
+ moved[0] = self.setCurPos(@current_row, @field_width - 1)
219
+ redraw[0] = self.setTopRow(@top_row - 1)
220
+ end
221
+ else
222
+ moved[0] = self.setCurPos(@current_row - 1, @field_width - 1)
223
+ end
224
+
225
+ if !moved[0] && !redraw[0]
226
+ RNDK.beep
227
+ result = false
228
+ end
229
+ return result
230
+ end
231
+
232
+ def getCursorPos
233
+ return (@current_row + @top_row) * @field_width + @current_col
234
+ end
235
+
236
+ # This injects a character into the widget.
237
+ def inject(input)
238
+ cursor_pos = self.getCursorPos
239
+ pp_return = 1
240
+ ret = -1
241
+ complete = false
242
+
243
+ # Set the exit type.
244
+ self.setExitType(0)
245
+
246
+ # Refresh the field.
247
+ self.drawField
248
+
249
+ # Check if there is a pre-process function to be called.
250
+ unless @pre_process_func.nil?
251
+ # Call the pre-process function
252
+ pp_return = @pre_process_func.call(:MENTRY, self,
253
+ @pre_process_data, input)
254
+ end
255
+
256
+ # Should we continue?
257
+ if pp_return != 0
258
+ # Check for a key binding...
259
+ if self.checkBind(:MENTRY, input)
260
+ complete = true
261
+ else
262
+ moved = false
263
+ redraw = false
264
+
265
+ case input
266
+ when Ncurses::KEY_HOME
267
+ moved = self.setCurPos(0, 0)
268
+ redraw = self.setTopRow(0)
269
+ when Ncurses::KEY_END
270
+ field_characters = @rows * @field_width
271
+ if @info.size < field_characters
272
+ redraw = self.setTopRow(0)
273
+ moved = self.setCurPos(
274
+ @info.size / @field_width, @info.size % @field_width)
275
+ else
276
+ redraw = self.setTopRow(@info.size / @field_width, @rows + 1)
277
+ moved = self.setCurPos(@rows - 1, @info.size % @field_width)
278
+ end
279
+ when Ncurses::KEY_LEFT
280
+ mtmp = [moved]
281
+ rtmp = [redraw]
282
+ self.KEY_LEFT(mtmp, rtmp)
283
+ moved = mtmp[0]
284
+ redraw = rtmp[0]
285
+ when Ncurses::KEY_RIGHT
286
+ if @current_col < @field_width - 1
287
+ if self.getCursorPos + 1 <= @info.size
288
+ moved = self.setCurPos(@current_row, @current_col + 1)
289
+ end
290
+ elsif @current_row == @rows - 1
291
+ if @top_row + @current_row + 1 < @logical_rows
292
+ moved = self.setCurPos(@current_row, 0)
293
+ redraw = self.setTopRow(@top_row + 1)
294
+ end
295
+ else
296
+ moved = self.setCurPos(@current_row + 1, 0)
297
+ end
298
+ if !moved && !redraw
299
+ RNDK.beep
300
+ end
301
+ when Ncurses::KEY_DOWN
302
+ if @current_row != @rows - 1
303
+ if self.getCursorPos + @field_width + 1 <= @info.size
304
+ moved = self.setCurPos(@current_row + 1, @current_col)
305
+ end
306
+ elsif @top_row < @logical_rows - @rows
307
+ if (@top_row + @current_row + 1) * @field_width <= @info.size
308
+ redraw = self.setTopRow(@top_row + 1)
309
+ end
310
+ end
311
+ if !moved && !redraw
312
+ RNDK.beep
313
+ end
314
+ when Ncurses::KEY_UP
315
+ if @current_row != 0
316
+ moved = self.setCurPos(@current_row - 1, @current_col)
317
+ elsif @top_row != 0
318
+ redraw = self.setTopRow(@top_row - 1)
319
+ end
320
+ if !moved && !redraw
321
+ RNDK.beep
322
+ end
323
+ when Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC
324
+ if @disp_type == :VIEWONLY
325
+ RNDK.beep
326
+ elsif @info.length == 0
327
+ RNDK.beep
328
+ elsif input == Ncurses::KEY_DC
329
+ cursor_pos = self.getCursorPos
330
+ if cursor_pos < @info.size
331
+ @info = @info[0...cursor_pos] + @info[cursor_pos + 1..-1]
332
+ self.drawField
333
+ else
334
+ RNDK.beep
335
+ end
336
+ else
337
+ mtmp = [moved]
338
+ rtmp = [redraw]
339
+ hKL = self.KEY_LEFT(mtmp, rtmp)
340
+ moved = mtmp[0]
341
+ rtmp = [redraw]
342
+ if hKL
343
+ cursor_pos = self.getCursorPos
344
+ if cursor_pos < @info.size
345
+ @info = @info[0...cursor_pos] + @info[cursor_pos + 1..-1]
346
+ self.drawField
347
+ else
348
+ RNDK.beep
349
+ end
350
+ end
351
+ end
352
+ when RNDK::TRANSPOSE
353
+ if cursor_pos >= @info.size - 1
354
+ RNDK.beep
355
+ else
356
+ holder = @info[cursor_pos]
357
+ @info[cursor_pos] = @info[cursor_pos + 1]
358
+ @info[cursor_pos + 1] = holder
359
+ self.drawField
360
+ end
361
+ when RNDK::ERASE
362
+ if @info.size != 0
363
+ self.clean
364
+ self.drawField
365
+ end
366
+ when RNDK::CUT
367
+ if @info.size == 0
368
+ RNDK.beep
369
+ else
370
+ @@g_paste_buffer = @info.clone
371
+ self.clean
372
+ self.drawField
373
+ end
374
+ when RNDK::COPY
375
+ if @info.size == 0
376
+ RNDK.beep
377
+ else
378
+ @@g_paste_buffer = @info.clone
379
+ end
380
+ when RNDK::PASTE
381
+ if @@g_paste_buffer.size == 0
382
+ RNDK.beep
383
+ else
384
+ self.setValue(@@g_paste_buffer)
385
+ self.draw(@box)
386
+ end
387
+ when RNDK::KEY_TAB, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
388
+ if @info.size < @min + 1
389
+ RNDK.beep
390
+ else
391
+ self.setExitType(input)
392
+ ret = @info
393
+ complete = true
394
+ end
395
+ when Ncurses::ERR
396
+ self.setExitType(input)
397
+ complete = true
398
+ when RNDK::KEY_ESC
399
+ self.setExitType(input)
400
+ complete = true
401
+ when RNDK::REFRESH
402
+ @screen.erase
403
+ @screen.refresh
404
+ else
405
+ if @disp_type == :VIEWONLY || @info.size >= @total_width
406
+ RNDK.beep
407
+ else
408
+ @callbackfn.call(self, input)
409
+ end
410
+ end
411
+
412
+ if redraw
413
+ self.drawField
414
+ elsif moved
415
+ Ncurses.wmove(@field_win, @current_row, @current_col)
416
+ Ncurses.wrefresh(@field_win)
417
+ end
418
+ end
419
+
420
+ # Should we do a post-process?
421
+ if !complete && !(@post_process_func.nil?)
422
+ @post_process_func.call(:MENTRY, self, @post_process_data, input)
423
+ end
424
+ end
425
+
426
+ if !complete
427
+ self.setExitType(0)
428
+ end
429
+
430
+ @result_data = ret
431
+ return ret
432
+ end
433
+
434
+ # This moves the mentry field to the given location.
435
+ def move(xplace, yplace, relative, refresh_flag)
436
+ windows = [@win, @field_win, @label_win, @shadow_win]
437
+
438
+ self.move_specific(xplace, yplace, relative, refresh_flag, windows, [])
439
+ end
440
+
441
+ # This function redraws the multiple line entry field.
442
+ def drawField
443
+ currchar = @field_width * @top_row
444
+
445
+ self.drawTitle @win
446
+ Ncurses.wrefresh @win
447
+
448
+ lastpos = @info.size
449
+
450
+ # Start redrawing the fields.
451
+ (0...@rows).each do |x|
452
+ (0...@field_width).each do |y|
453
+ if currchar < lastpos
454
+ if Display.isHiddenDisplayType(@disp_type)
455
+ Ncurses.mvwaddch(@field_win, x, y, @filler)
456
+ else
457
+ Ncurses.mvwaddch(@field_win, x, y, @info[currchar].ord | @field_attr)
458
+ currchar += 1
459
+ end
460
+ else
461
+ Ncurses.mvwaddch(@field_win, x, y, @filler)
462
+ end
463
+ end
464
+ end
465
+
466
+ # Refresh the screen.
467
+ Ncurses.wmove(@field_win, @current_row, @current_col)
468
+ Ncurses.wrefresh(@field_win)
469
+ end
470
+
471
+ # This function draws the multiple line entry field.
472
+ def draw(box)
473
+ # Box the widget if asked.
474
+ if box
475
+ Draw.drawObjBox(@win, self)
476
+ Ncurses.wrefresh @win
477
+ end
478
+
479
+ # Do we need to draw in the shadow?
480
+ unless @shadow_win.nil?
481
+ Draw.drawShadow(@shadow_win)
482
+ end
483
+
484
+ # Draw in the label to the widget.
485
+ unless @label_win.nil?
486
+ Draw.writeChtype(@label_win, 0, 0, @label, RNDK::HORIZONTAL, 0, @label_len)
487
+ Ncurses.wrefresh @label_win
488
+ end
489
+
490
+ # Draw the mentry field
491
+ self.drawField
492
+ end
493
+
494
+ # This sets the background attribute of the widget.
495
+ def setBKattr(attrib)
496
+ Ncurses.wbkgd(@win, attrib)
497
+ Ncurses.wbkgd(@field_win, attrib)
498
+ Ncurses.wbkgd(@label_win, attrib) unless @label_win.nil?
499
+ end
500
+
501
+ # This function erases the multiple line entry field from the screen.
502
+ def erase
503
+ if self.validRNDKObject
504
+ RNDK.eraseCursesWindow(@field_win)
505
+ RNDK.eraseCursesWindow(@label_win)
506
+ RNDK.eraseCursesWindow(@win)
507
+ RNDK.eraseCursesWindow(@shadow_win)
508
+ end
509
+ end
510
+
511
+ # This function destroys a multiple line entry field widget.
512
+ def destroy
513
+ self.cleanTitle
514
+
515
+ # Clean up the windows.
516
+ RNDK.deleteCursesWindow(@field_win)
517
+ RNDK.deleteCursesWindow(@label_win)
518
+ RNDK.deleteCursesWindow(@shadow_win)
519
+ RNDK.deleteCursesWindow(@win)
520
+
521
+ # Clean the key bindings.
522
+ self.cleanBindings(:MENTRY)
523
+
524
+ # Unregister this object.
525
+ RNDK::Screen.unregister(:MENTRY, self)
526
+ end
527
+
528
+ # This sets multiple attributes of the widget.
529
+ def set(value, min, box)
530
+ self.setValue(value)
531
+ self.setMin(min)
532
+ self.setBox(box)
533
+ end
534
+
535
+ # This removes the old information in the entry field and keeps the
536
+ # new information given.
537
+ def setValue(new_value)
538
+ field_characters = @rows * @field_width
539
+
540
+ @info = new_value
541
+
542
+ # Set the cursor/row info
543
+ if new_value.size < field_characters
544
+ @top_row = 0
545
+ @current_row = new_value.size / @field_width
546
+ @current_col = new_value.size % @field_width
547
+ else
548
+ row_used = new_value.size / @field_width
549
+ @top_row = row_used - @rows + 1
550
+ @current_row = @rows - 1
551
+ @current_col = new_value.size % @field_width
552
+ end
553
+
554
+ # Redraw the widget.
555
+ self.drawField
556
+ end
557
+
558
+ def getValue
559
+ return @info
560
+ end
561
+
562
+ # This sets the filler character to use when drawing the widget.
563
+ def setFillerChar(filler)
564
+ @filler = filler.ord
565
+ end
566
+
567
+ def getFillerChar
568
+ return @filler
569
+ end
570
+
571
+ # This sets the character to use when a hidden character type is used
572
+ def setHiddenChar(character)
573
+ @hidden = character
574
+ end
575
+
576
+ def getHiddenChar
577
+ return @hidden
578
+ end
579
+
580
+ # This sets a minimum length of the widget.
581
+ def setMin(min)
582
+ @min = min
583
+ end
584
+
585
+ def getMin
586
+ return @min
587
+ end
588
+
589
+ # This erases the information in the multiple line entry widget
590
+ def clean
591
+ @info = ''
592
+ @current_row = 0
593
+ @current_col = 0
594
+ @top_row = 0
595
+ end
596
+
597
+ # This sets the callback function.
598
+ def setCB(callback)
599
+ @callbackfn = callback
600
+ end
601
+
602
+ def focus
603
+ Ncurses.wmove(@field_win, 0, @current_col)
604
+ Ncurses.wrefresh @field_win
605
+ end
606
+
607
+ def unfocus
608
+ Ncurses.wrefresh @field_win
609
+ end
610
+
611
+ def position
612
+ super(@win)
613
+ end
614
+
615
+ def object_type
616
+ :MENTRY
617
+ end
618
+ end
619
+ end