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
data/lib/rndk/menu.rb ADDED
@@ -0,0 +1,478 @@
1
+ require 'rndk'
2
+
3
+ module RNDK
4
+ class MENU < RNDK::Widget
5
+ TITLELINES = 1
6
+ MAX_MENU_ITEMS = 30
7
+ MAX_SUB_ITEMS = 98
8
+
9
+ attr_reader :current_title, :current_subtitle
10
+ attr_reader :sublist
11
+
12
+ def initialize(rndkscreen,
13
+ menu_list,
14
+ menu_items,
15
+ subsize,
16
+ menu_location,
17
+ menu_pos,
18
+ title_attr,
19
+ subtitle_attr)
20
+ super()
21
+
22
+ right_count = menu_items - 1
23
+ rightloc = Ncurses.getmaxx rndkscreen.window
24
+ leftloc = 0
25
+ xpos = Ncurses.getbegx rndkscreen.window
26
+ ypos = Ncurses.getbegy rndkscreen.window
27
+ ymax = Ncurses.getmaxy rndkscreen.window
28
+
29
+ # Start making a copy of the information.
30
+ @screen = rndkscreen
31
+ @box = false
32
+ @accepts_focus = false
33
+ rightcount = menu_items - 1
34
+ @parent = rndkscreen.window
35
+ @menu_items = menu_items
36
+ @title_attr = title_attr
37
+ @subtitle_attr = subtitle_attr
38
+ @current_title = 0
39
+ @current_subtitle = 0
40
+ @last_selection = -1
41
+ @menu_pos = menu_pos
42
+
43
+ @pull_win = [nil] * menu_items
44
+ @title_win = [nil] * menu_items
45
+ @title = [''] * menu_items
46
+ @title_len = [0] * menu_items
47
+ @sublist = (1..menu_items).map {[nil] * subsize.max}.compact
48
+ @sublist_len = (1..menu_items).map {
49
+ [0] * subsize.max}.compact
50
+ @subsize = [0] * menu_items
51
+
52
+
53
+ # Create the pull down menus.
54
+ (0...menu_items).each do |x|
55
+ x1 = if menu_location[x] == RNDK::LEFT
56
+ then x
57
+ else
58
+ rightcount -= 1
59
+ rightcount + 1
60
+ end
61
+ x2 = 0
62
+ y1 = if menu_pos == RNDK::BOTTOM then ymax - 1 else 0 end
63
+ y2 = if menu_pos == RNDK::BOTTOM
64
+ then ymax - subsize[x] - 2
65
+ else RNDK::MENU::TITLELINES
66
+ end
67
+ high = subsize[x] + RNDK::MENU::TITLELINES
68
+
69
+ # Limit the menu height to fit on the screen.
70
+ if high + y2 > ymax
71
+ high = ymax - RNDK::MENU::TITLELINES
72
+ end
73
+
74
+ max = -1
75
+ (RNDK::MENU::TITLELINES...subsize[x]).to_a.each do |y|
76
+ y0 = y - RNDK::MENU::TITLELINES
77
+ sublist_len = []
78
+ @sublist[x1][y0] = RNDK.char2Chtype(menu_list[x][y],
79
+ sublist_len, [])
80
+ @sublist_len[x1][y0] = sublist_len[0]
81
+ max = [max, sublist_len[0]].max
82
+ end
83
+
84
+ if menu_location[x] == RNDK::LEFT
85
+ x2 = leftloc
86
+ else
87
+ x2 = (rightloc -= max + 2)
88
+ end
89
+
90
+ title_len = []
91
+ @title[x1] = RNDK.char2Chtype(menu_list[x][0], title_len, [])
92
+ @title_len[x1] = title_len[0]
93
+ @subsize[x1] = subsize[x] - RNDK::MENU::TITLELINES
94
+ @title_win[x1] = Ncurses.subwin(rndkscreen.window,
95
+ RNDK::MENU::TITLELINES,
96
+ @title_len[x1] + 2,
97
+ ypos + y1,
98
+ xpos + x2)
99
+
100
+ @pull_win[x1] = Ncurses.subwin(rndkscreen.window,
101
+ high,
102
+ max + 2,
103
+ ypos + y2,
104
+ xpos + x2)
105
+
106
+ if @title_win[x1].nil? || @pull_win[x1].nil?
107
+ self.destroy
108
+ return nil
109
+ end
110
+
111
+ leftloc += @title_len[x] + 1
112
+ Ncurses.keypad(@title_win[x1], true)
113
+ Ncurses.keypad(@pull_win[x1], true)
114
+ end
115
+ @input_window = @title_win[@current_title]
116
+
117
+ # Register this baby.
118
+ rndkscreen.register(:MENU, self)
119
+ end
120
+
121
+ # This activates the RNDK Menu
122
+ def activate(actions)
123
+ ret = 0
124
+
125
+ # Draw in the screen.
126
+ @screen.refresh
127
+
128
+ # Display the menu titles.
129
+ self.draw(@box)
130
+
131
+ # Highlight the current title and window.
132
+ self.drawSubwin
133
+
134
+ # If the input string is empty this is an interactive activate.
135
+ if actions.nil? || actions.size == 0
136
+ @input_window = @title_win[@current_title]
137
+
138
+ # Start taking input from the keyboard.
139
+ while true
140
+ input = self.getch([])
141
+
142
+ # Inject the character into the widget.
143
+ ret = self.inject(input)
144
+ if @exit_type != :EARLY_EXIT
145
+ return ret
146
+ end
147
+ end
148
+ else
149
+ actions.each do |action|
150
+ if @exit_type != :EARLY_EXIT
151
+ return ret
152
+ end
153
+ end
154
+ end
155
+
156
+ # Set the exit type and return.
157
+ self.setExitType(0)
158
+ return -1
159
+ end
160
+
161
+ def drawTitle(item)
162
+ Draw.writeChtype(@title_win[item],
163
+ 0,
164
+ 0,
165
+ @title[item],
166
+ RNDK::HORIZONTAL,
167
+ 0,
168
+ @title_len[item])
169
+ end
170
+
171
+ def drawItem(item, offset)
172
+ Draw.writeChtype(@pull_win[@current_title],
173
+ 1,
174
+ item + RNDK::MENU::TITLELINES - offset,
175
+ @sublist[@current_title][item],
176
+ RNDK::HORIZONTAL,
177
+ 0,
178
+ @sublist_len[@current_title][item])
179
+ end
180
+
181
+ # Highlight the current sub-menu item
182
+ def selectItem(item, offset)
183
+ Draw.writeChtypeAttrib(@pull_win[@current_title],
184
+ 1,
185
+ item + RNDK::MENU::TITLELINES - offset,
186
+ @sublist[@current_title][item],
187
+ @subtitle_attr,
188
+ RNDK::HORIZONTAL,
189
+ 0,
190
+ @sublist_len[@current_title][item])
191
+ end
192
+
193
+ def withinSubmenu(step)
194
+ next_item = RNDK::MENU.wrapped(@current_subtitle + step,
195
+ @subsize[@current_title])
196
+
197
+ if next_item != @current_subtitle
198
+ ymax = Ncurses.getmaxy(@screen.window)
199
+
200
+ if 1 + Ncurses.getbegy(@pull_win[@current_title]) + @subsize[@current_title] >= ymax
201
+ @current_subtitle = next_item
202
+ self.drawSubwin
203
+ else
204
+ # Erase the old subtitle.
205
+ self.drawItem(@current_subtitle, 0)
206
+
207
+ # Set the values
208
+ @current_subtitle = next_item
209
+
210
+ # Draw the new sub-title.
211
+ self.selectItem(@current_subtitle, 0)
212
+
213
+ Ncurses.wrefresh @pull_win[@current_title]
214
+ end
215
+
216
+ @input_window = @title_win[@current_title]
217
+ end
218
+ end
219
+
220
+ def acrossSubmenus(step)
221
+ next_item = RNDK::MENU.wrapped(@current_title + step, @menu_items)
222
+
223
+ if next_item != @current_title
224
+ # Erase the menu sub-window.
225
+ self.eraseSubwin
226
+ @screen.refresh
227
+
228
+ # Set the values.
229
+ @current_title = next_item
230
+ @current_subtitle = 0
231
+
232
+ # Draw the new menu sub-window.
233
+ self.drawSubwin
234
+ @input_window = @title_win[@current_title]
235
+ end
236
+ end
237
+
238
+ # Inject a character into the menu widget.
239
+ def inject(input)
240
+ pp_return = 1
241
+ ret = -1
242
+ complete = false
243
+
244
+ # Set the exit type.
245
+ self.setExitType(0)
246
+
247
+ # Check if there is a pre-process function to be called.
248
+ unless @pre_process_func.nil?
249
+ # Call the pre-process function.
250
+ pp_return = @pre_process_func.call(:MENU, self,
251
+ @pre_process_data, input)
252
+ end
253
+
254
+ # Should we continue?
255
+
256
+ if pp_return != 0
257
+ # Check for key bindings.
258
+ if self.checkBind(:MENU, input)
259
+ complete = true
260
+ else
261
+ case input
262
+ when Ncurses::KEY_LEFT
263
+ self.acrossSubmenus(-1)
264
+ when Ncurses::KEY_RIGHT, RNDK::KEY_TAB
265
+ self.acrossSubmenus(1)
266
+ when Ncurses::KEY_UP
267
+ self.withinSubmenu(-1)
268
+ when Ncurses::KEY_DOWN, ' '.ord
269
+ self.withinSubmenu(1)
270
+ when Ncurses::KEY_ENTER, RNDK::KEY_RETURN
271
+ self.cleanUpMenu
272
+ self.setExitType(input)
273
+ @last_selection = @current_title * 100 + @current_subtitle
274
+ ret = @last_selection
275
+ complete = true
276
+ when RNDK::KEY_ESC
277
+ self.cleanUpMenu
278
+ self.setExitType(input)
279
+ @last_selection = -1
280
+ ret = @last_selection
281
+ complete = true
282
+ when Ncurses::ERR
283
+ self.setExitType(input)
284
+ complete = true
285
+ when RNDK::REFRESH
286
+ self.erase
287
+ self.refresh
288
+ end
289
+ end
290
+
291
+ # Should we call a post-process?
292
+ if !complete && !(@post_process_func.nil?)
293
+ @post_process_func.call(:MENU, self, @post_process_data, input)
294
+ end
295
+ end
296
+
297
+ if !complete
298
+ self.setExitType(0)
299
+ end
300
+
301
+ @result_data = ret
302
+ return ret
303
+ end
304
+
305
+ # Draw a menu item subwindow
306
+ def drawSubwin
307
+ high = Ncurses.getmaxy(@pull_win[@current_title]) - 2
308
+ x0 = 0
309
+ x1 = @subsize[@current_title]
310
+
311
+ if x1 > high
312
+ x1 = high
313
+ end
314
+
315
+ if @current_subtitle >= x1
316
+ x0 = @current_subtitle - x1 + 1
317
+ x1 += x0
318
+ end
319
+
320
+ # Box the window
321
+ @pull_win[@current_title]
322
+ Ncurses.box(@pull_win[@current_title], Ncurses::ACS_VLINE, Ncurses::ACS_HLINE)
323
+ if @menu_pos == RNDK::BOTTOM
324
+ Ncurses.mvwaddch(@pull_win[@current_title],
325
+ @subsize[@current_title] + 1,
326
+ 0,
327
+ Ncurses::ACS_LTEE)
328
+ else
329
+ Ncurses.mvwaddch(@pull_win[@current_title],
330
+ 0,
331
+ 0,
332
+ Ncurses::ACS_LTEE)
333
+ end
334
+
335
+ # Draw the items.
336
+ (x0...x1).each do |x|
337
+ self.drawItem(x, x0)
338
+ end
339
+
340
+ self.selectItem(@current_subtitle, x0)
341
+ Ncurses.wrefresh @pull_win[@current_title]
342
+
343
+ # Highlight the title.
344
+ Draw.writeChtypeAttrib(@title_win[@current_title], 0, 0,
345
+ @title[@current_title], @title_attr, RNDK::HORIZONTAL,
346
+ 0, @title_len[@current_title])
347
+ Ncurses.wrefresh @title_win[@current_title]
348
+ end
349
+
350
+ # Erase a menu item subwindow
351
+ def eraseSubwin
352
+ RNDK.eraseCursesWindow(@pull_win[@current_title])
353
+
354
+ # Redraw the sub-menu title.
355
+ self.drawTitle(@current_title)
356
+ Ncurses.wrefresh @title_win[@current_title]
357
+ end
358
+
359
+ # Draw the menu.
360
+ def draw(box)
361
+ # Draw in the menu titles.
362
+ (0...@menu_items).each do |x|
363
+ self.drawTitle(x)
364
+ Ncurses.wrefresh @title_win[x]
365
+ end
366
+ end
367
+
368
+ # Move the menu to the given location.
369
+ def move(xplace, yplace, relative, refresh_flag)
370
+ windows = [@screen.window]
371
+ (0...@menu_items).each do |x|
372
+ windows << @title_win[x]
373
+ end
374
+ self.move_specific(xplace, yplace, relative, refresh_flag,
375
+ windows, [])
376
+ end
377
+
378
+ # Set the background attribute of the widget.
379
+ def setBKattr(attrib)
380
+ (0...@menu_items).each do |x|
381
+ @title_win[x].wbkgd(attrib)
382
+ @pull_win[x].wbkgd(attrib)
383
+ end
384
+ end
385
+
386
+ # Destroy a menu widget.
387
+ def destroy
388
+ # Clean up the windows
389
+ (0...@menu_items).each do |x|
390
+ RNDK.deleteCursesWindow(@title_win[x])
391
+ RNDK.deleteCursesWindow(@pull_win[x])
392
+ end
393
+
394
+ # Clean the key bindings.
395
+ self.cleanBindings(:MENU)
396
+
397
+ # Unregister the object
398
+ RNDK::Screen.unregister(:MENU, self)
399
+ end
400
+
401
+ # Erase the menu widget from the screen.
402
+ def erase
403
+ if self.validRNDKObject
404
+ (0...@menu_items).each do |x|
405
+ Ncurses.werase @title_win[x]
406
+ Ncurses.wrefresh @title_win[x]
407
+ Ncurses.werase @pull_win[x]
408
+ Ncurses.wrefresh @pull_win[x]
409
+ end
410
+ end
411
+ end
412
+
413
+ def set(menu_item, submenu_item, title_highlight, subtitle_highlight)
414
+ self.setCurrentItem(menu_item, submenu_item)
415
+ self.setTitleHighlight(title_highlight)
416
+ self.setSubTitleHighlight(subtitle_highlight)
417
+ end
418
+
419
+ # Set the current menu item to highlight.
420
+ def setCurrentItem(menuitem, submenuitem)
421
+ @current_title = RNDK::MENU.wrapped(menuitem, @menu_items)
422
+ @current_subtitle = RNDK::MENU.wrapped(
423
+ submenuitem, @subsize[@current_title])
424
+ end
425
+
426
+ def getCurrentItem(menu_item, submenu_item)
427
+ menu_item << @current_title
428
+ submenu_item << @current_subtitle
429
+ end
430
+
431
+ # Set the attribute of the menu titles.
432
+ def setTitleHighlight(highlight)
433
+ @title_attr = highlight
434
+ end
435
+
436
+ def getTitleHighlight
437
+ return @title_attr
438
+ end
439
+
440
+ # Set the attribute of the sub-title.
441
+ def setSubTitleHighlight(highlight)
442
+ @subtitle_attr = highlight
443
+ end
444
+
445
+ def getSubTitleHighlight
446
+ return @subtitle_attr
447
+ end
448
+
449
+ # Exit the menu.
450
+ def cleanUpMenu
451
+ # Erase the sub-menu.
452
+ self.eraseSubwin
453
+ Ncurses.wrefresh @pull_win[@current_title]
454
+
455
+ # Refresh the screen.
456
+ @screen.refresh
457
+ end
458
+
459
+ def focus
460
+ self.drawSubwin
461
+ @input_window = @title_win[@current_title]
462
+ end
463
+
464
+ # The "%" operator is simpler but does not handle negative values
465
+ def self.wrapped(within, limit)
466
+ if within < 0
467
+ within = limit - 1
468
+ elsif within >= limit
469
+ within = 0
470
+ end
471
+ return within
472
+ end
473
+
474
+ def object_type
475
+ :MENU
476
+ end
477
+ end
478
+ end