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