rndk 0.2.0 → 1.0.0

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -4
  3. data/TODO +21 -1
  4. data/demos/appointment.rb +279 -299
  5. data/demos/clock.rb +13 -8
  6. data/demos/rss-reader.rb +84 -0
  7. data/examples/01-hello-world.rb +13 -11
  8. data/examples/02-colors.rb +14 -21
  9. data/examples/03-markup.rb +7 -7
  10. data/examples/04-quick-widgets.rb +2 -2
  11. data/examples/05-position-widget.rb +50 -31
  12. data/examples/06-callbacks.rb +77 -0
  13. data/examples/07-traverse.rb +90 -0
  14. data/examples/10-all-widgets.rb +165 -0
  15. data/examples/calendar.rb +20 -32
  16. data/examples/entry.rb +15 -20
  17. data/examples/label.rb +11 -11
  18. data/examples/scroll.rb +16 -60
  19. data/examples/slider.rb +18 -19
  20. data/examples/viewer.rb +65 -0
  21. data/lib/rndk.rb +28 -7
  22. data/lib/rndk/alphalist.rb +309 -313
  23. data/lib/rndk/button.rb +239 -157
  24. data/lib/rndk/buttonbox.rb +136 -103
  25. data/lib/rndk/calendar.rb +246 -203
  26. data/lib/rndk/core/color.rb +63 -13
  27. data/lib/rndk/core/display.rb +1 -1
  28. data/lib/rndk/core/draw.rb +11 -11
  29. data/lib/rndk/core/markup.rb +21 -21
  30. data/lib/rndk/core/quick_widgets.rb +75 -96
  31. data/lib/rndk/core/screen.rb +145 -102
  32. data/lib/rndk/core/traverse.rb +150 -136
  33. data/lib/rndk/core/utils.rb +5 -6
  34. data/lib/rndk/core/widget.rb +207 -191
  35. data/lib/rndk/core/widget_bind.rb +108 -0
  36. data/lib/rndk/dialog.rb +88 -56
  37. data/lib/rndk/entry.rb +79 -64
  38. data/lib/rndk/fscale.rb +38 -20
  39. data/lib/rndk/fslider.rb +38 -23
  40. data/lib/rndk/graph.rb +92 -53
  41. data/lib/rndk/itemlist.rb +80 -62
  42. data/lib/rndk/label.rb +111 -77
  43. data/lib/rndk/radio.rb +138 -128
  44. data/lib/rndk/scale.rb +123 -122
  45. data/lib/rndk/scroll.rb +444 -391
  46. data/lib/rndk/scroller.rb +21 -21
  47. data/lib/rndk/slider.rb +149 -140
  48. data/lib/rndk/template.rb +74 -61
  49. data/lib/rndk/version.rb +1 -1
  50. data/lib/rndk/viewer.rb +499 -298
  51. metadata +8 -14
  52. data/demos/fileview.rb +0 -141
  53. data/lib/rndk/dscale.rb +0 -13
  54. data/lib/rndk/fselect.rb +0 -938
  55. data/lib/rndk/histogram.rb +0 -412
  56. data/lib/rndk/marquee.rb +0 -244
  57. data/lib/rndk/matrix.rb +0 -1189
  58. data/lib/rndk/mentry.rb +0 -619
  59. data/lib/rndk/menu.rb +0 -478
  60. data/lib/rndk/selection.rb +0 -630
  61. data/lib/rndk/swindow.rb +0 -766
  62. data/lib/rndk/uscale.rb +0 -14
  63. data/lib/rndk/uslider.rb +0 -14
@@ -14,11 +14,11 @@ require 'rndk/scroll'
14
14
 
15
15
  begin
16
16
  # Set up RNDK and colors
17
- rndkscreen = RNDK::Screen.new
17
+ screen = RNDK::Screen.new
18
18
  RNDK::Color.init
19
19
 
20
20
  # Turning off the blinking cursor
21
- Ncurses.curs_set 0
21
+ RNDK::blink_cursor false
22
22
 
23
23
  # Use the current directory list to fill the radio list
24
24
  item = RNDK.get_directory_contents '.'
@@ -29,73 +29,29 @@ begin
29
29
  # See example 'markup.rb' for more details.
30
30
  title = <<END
31
31
  <C></77>Pick a file
32
- </77>Press 'a' to append an item
33
- </77>Press 'i' to insert an item
34
- </77>Press 'd' to delete current item
35
- </77>(don't worry, won't delete your files)
36
32
  </77>Press 'enter' or 'tab' to select item
37
33
  ------------------------------------------------
38
34
  END
39
35
 
40
36
  # Create the scrolling list.
41
- scroll_list = RNDK::Scroll.new(rndkscreen,
42
- RNDK::CENTER, # x
43
- RNDK::CENTER, # y
44
- RNDK::RIGHT, # scrollbar position
45
- 50, # width
46
- 24, # height
47
- title, # title
48
- item, # items on the list
49
- true, # show numbers
50
- RNDK::Color[:red], # highlight color
51
- true, # box
52
- false) # shadow
37
+ scroll_list = RNDK::Scroll.new(screen, {
38
+ :x => RNDK::CENTER,
39
+ :y => RNDK::CENTER,
40
+ :width => 50,
41
+ :height => 24,
42
+ :title => title,
43
+ :items => item,
44
+ :numbers => true,
45
+ :highlight => RNDK::Color[:red]
46
+ })
53
47
 
54
48
  if scroll_list.nil?
55
- RNDK::Screen.end_rndk
49
+ RNDK::Screen.finish
56
50
 
57
51
  puts "Cannot make scrolling list. Is the window too small?"
58
52
  exit 1
59
53
  end
60
54
 
61
- # These are the functions that will modify the
62
- # Scroll List at runtime.
63
- #
64
- # The arguments to the block are provided by
65
- # default, you can ignore them right now.
66
- #
67
- # The only thing you need to know is that `widget` is
68
- # the scroll - widget that we attach the callback to.
69
- $counter = 0
70
-
71
- add_item_callback = lambda do |type, widget, client_data, input|
72
- widget.addItem "add_#{$counter}"
73
- $counter += 1
74
- widget.screen.refresh
75
- return true
76
- end
77
-
78
- insert_item_callback = lambda do |type, widget, client_data, input|
79
- widget.insertItem "insert_#{$counter}"
80
- $counter += 1
81
- widget.screen.refresh
82
- return true
83
- end
84
-
85
- delete_item_callback = lambda do |type, widget, client_data, input|
86
- widget.deleteItem widget.getCurrentItem
87
- widget.screen.refresh
88
- return true
89
- end
90
-
91
- # And this is how we bind keys to actions.
92
- #
93
- # It only accepts lambdas.
94
-
95
- scroll_list.bind(:scroll, 'a', add_item_callback, nil)
96
- scroll_list.bind(:scroll, 'i', insert_item_callback, nil)
97
- scroll_list.bind(:scroll, 'd', delete_item_callback, nil)
98
-
99
55
  # Activate the scrolling list.
100
56
  selection = scroll_list.activate
101
57
 
@@ -116,13 +72,13 @@ END
116
72
  end
117
73
 
118
74
  # A quick widget - see example 'quick-widgets.rb'
119
- rndkscreen.popup_label msg
75
+ screen.popup_label msg
120
76
 
121
- RNDK::Screen.end_rndk
77
+ RNDK::Screen.finish
122
78
 
123
79
  # Just in case something bad happens.
124
80
  rescue Exception => e
125
- RNDK::Screen.end_rndk
81
+ RNDK::Screen.finish
126
82
 
127
83
  puts e
128
84
  puts e.inspect
@@ -10,27 +10,26 @@ begin
10
10
  label = '</B>Current Value:'
11
11
 
12
12
  # Set up RNDK
13
- rndkscreen = RNDK::Screen.new
13
+ screen = RNDK::Screen.new
14
14
  RNDK::Color.init
15
15
 
16
16
  # Create the widget
17
- widget = RNDK::Slider.new(rndkscreen,
18
- RNDK::CENTER,
19
- RNDK::CENTER,
20
- title,
21
- label,
22
- Ncurses::A_REVERSE | RNDK::Color[:white_blue] | ' '.ord,
23
- 50,
24
- 1,
25
- 1,
26
- 100,
27
- 1,
28
- 2,
29
- true,
30
- false)
17
+ widget = RNDK::Slider.new(screen, {
18
+ :x => RNDK::CENTER,
19
+ :y => RNDK::CENTER,
20
+ :title => title,
21
+ :label => label,
22
+ :filler => RNDK::Color[:reverse] | RNDK::Color[:white_blue] | ' '.ord,
23
+ :field_width => 50,
24
+ :start => 50,
25
+ :mininum => 1,
26
+ :maximum => 100,
27
+ :increment => 1,
28
+ :fast_increment => 2
29
+ })
31
30
 
32
31
  if widget.nil?
33
- RNDK::Screen.end_rndk
32
+ RNDK::Screen.finish
34
33
 
35
34
  puts "Cannot make the widget. Is the window too small?"
36
35
  exit 1
@@ -53,14 +52,14 @@ begin
53
52
 
54
53
  # A quick popup widget! Check out the
55
54
  # example file 'quick-widgets.rb'
56
- rndkscreen.popup_label mesg
55
+ screen.popup_label mesg
57
56
 
58
57
  # Clean up
59
- RNDK::Screen.end_rndk
58
+ RNDK::Screen.finish
60
59
 
61
60
  # Just in case something bad happens.
62
61
  rescue Exception => e
63
- RNDK::Screen.end_rndk
62
+ RNDK::Screen.finish
64
63
 
65
64
  puts e
66
65
  puts e.inspect
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Shows the content of this file with the Viewer widget.
4
+ # See file `lib/rndk/viewer.rb` for keybindings.
5
+ #
6
+ require 'rndk/viewer'
7
+
8
+ begin
9
+ screen = RNDK::Screen.new
10
+ RNDK::Color.init
11
+
12
+ # Oh yeah, gimme this file
13
+ lines = RNDK.read_file(__FILE__)
14
+ buttons = ["These", "Don't", "do", "a", "thing"]
15
+
16
+ viewer = RNDK::Viewer.new(screen, {
17
+ :x => RNDK::CENTER,
18
+ :y => RNDK::CENTER,
19
+ :title => "</77>Awesome Viewer",
20
+ :buttons => buttons,
21
+ :button_highlight => RNDK::Color[:white_red],
22
+ :shadow => true
23
+ })
24
+
25
+ # To set the lines of Viewer we must use Viewer#set.
26
+ # No way to do it on the constructor :(
27
+ viewer.set :items => lines
28
+
29
+ if viewer.nil?
30
+ RNDK::Screen.finish
31
+
32
+ puts "Cannot create the viewer. Is the window too small?"
33
+ exit 1
34
+ end
35
+
36
+ selected = viewer.activate
37
+
38
+ # Check how the person exited from the widget.
39
+ mesg = []
40
+
41
+ if viewer.exit_type == :ESCAPE_HIT
42
+ mesg = ["<C>Escape hit. No Button selected..",
43
+ "",
44
+ "<C>Press any key to continue."]
45
+
46
+ elsif viewer.exit_type == :NORMAL
47
+ mesg = ["<C>You selected button #{selected}",
48
+ "<C>Press any key to continue."]
49
+
50
+ end
51
+ # Quickly show message
52
+ screen.popup_label mesg
53
+
54
+ RNDK::Screen.finish
55
+
56
+ # Just in case something bad happens.
57
+ rescue Exception => e
58
+ RNDK::Screen.finish
59
+
60
+ puts e
61
+ puts e.inspect
62
+ puts e.backtrace
63
+ exit 1
64
+ end
65
+
@@ -19,8 +19,13 @@
19
19
  # page with `man lowercase_function_name`.
20
20
  #
21
21
  require 'ffi-ncurses'
22
- require 'scanf'
23
22
 
23
+ # Shortcut to avoid typing FFI::NCurses all the time.
24
+ # You can use it too!
25
+ # It MUST come before `require 'rndk/core/draw'`
26
+ Ncurses = FFI::NCurses
27
+
28
+ require 'scanf'
24
29
  require 'rndk/core/draw'
25
30
  require 'rndk/core/color'
26
31
  require 'rndk/core/display'
@@ -30,9 +35,6 @@ require 'rndk/core/screen'
30
35
  require 'rndk/core/markup'
31
36
  require 'rndk/core/utils'
32
37
 
33
- # Shortcut to avoid typing FFI::NCurses all the time.
34
- # You can use it too!
35
- Ncurses = FFI::NCurses
36
38
 
37
39
  module RNDK
38
40
 
@@ -58,7 +60,7 @@ module RNDK
58
60
 
59
61
  MAX_BINDINGS = 300
60
62
  MAX_ITEMS = 2000
61
- MAX_BUTTONS = 200
63
+ MAX_ButtonS = 200
62
64
 
63
65
  # Key value when pressing Ctrl+`char`.
64
66
  def RNDK.CTRL(char)
@@ -69,6 +71,7 @@ module RNDK
69
71
  # for Widget interaction.
70
72
  #
71
73
  # Example: `RNDK.CTRL('L')` is `Ctrl+L` or `C-l`
74
+
72
75
  REFRESH = RNDK.CTRL('L')
73
76
  PASTE = RNDK.CTRL('V')
74
77
  COPY = RNDK.CTRL('Y')
@@ -86,8 +89,11 @@ module RNDK
86
89
  KEY_RETURN = "\012".ord
87
90
  KEY_TAB = "\t".ord
88
91
 
92
+ # All the screens eventually created.
89
93
  ALL_SCREENS = []
90
- ALL_OBJECTS = []
94
+
95
+ # All the widgets eventually created.
96
+ ALL_WIDGETS = []
91
97
 
92
98
  # Beeps then flushes the stdout stream.
93
99
  #
@@ -116,7 +122,8 @@ module RNDK
116
122
  (character >= 0) and (character < Ncurses::KEY_MIN)
117
123
  end
118
124
 
119
- # Returns the function keys - F1, F2 ... F12 ...
125
+ # Returns internal Ncurses' function keys values
126
+ # (F1, F2 ... F12 ...)
120
127
  def RNDK.KEY_F(n)
121
128
  264 + n
122
129
  end
@@ -148,6 +155,7 @@ module RNDK
148
155
 
149
156
  RNDK.window_erase window
150
157
  Ncurses.delwin window
158
+ window = nil
151
159
  end
152
160
 
153
161
  # Safely moves a raw Ncurses window.
@@ -230,5 +238,18 @@ module RNDK
230
238
  end
231
239
  end
232
240
 
241
+ # Sets on/off the blinking cursor.
242
+ # @return The cursor's previous state.
243
+ def RNDK.blink_cursor option
244
+ ret = false
245
+ if option
246
+ ret = Ncurses.curs_set 1
247
+ else
248
+ ret = Ncurses.curs_set 0
249
+ end
250
+
251
+ if ret == 1 then true else false end
252
+ end
253
+
233
254
  end
234
255
 
@@ -2,28 +2,29 @@ require 'rndk'
2
2
 
3
3
  module RNDK
4
4
 
5
- # Allows user to select from a list of alphabetically sorted words.
5
+ # Allows user to select from a items of alphabetically sorted
6
+ # words.
6
7
  #
7
- # Use the arrow keys to navigate on the list or type in the
8
+ # Use the arrow keys to navigate on the items or type in the
8
9
  # beginning of the word and it'll automagically adjust
9
10
  # itself in the correct place.
10
11
  #
11
12
  # ## Keybindings
12
13
  #
13
- # Since Alphalist is built from both the Scroll and Entry Widgets,
14
+ # Since Alphaitems is built from both the Scroll and Entry Widgets,
14
15
  # the key bindings are the same for the respective fields.
15
16
  #
16
- # Extra key bindings are listed below:
17
+ # Extra key bindings are itemsed below:
17
18
  #
18
- # Up Arrow:: Scrolls the scrolling list up one line.
19
- # Down Arrow:: Scrolls the scrolling list down one line.
20
- # Page Up:: Scrolls the scrolling list up one page.
21
- # CTRL-B:: Scrolls the scrolling list up one page.
22
- # Page Down:: Scrolls the scrolling list down one page.
23
- # CTRL-F:: Scrolls the scrolling list down one page.
19
+ # Up Arrow:: Scrolls the scrolling items up one line.
20
+ # Down Arrow:: Scrolls the scrolling items down one line.
21
+ # Page Up:: Scrolls the scrolling items up one page.
22
+ # CTRL-B:: Scrolls the scrolling items up one page.
23
+ # Page Down:: Scrolls the scrolling items down one page.
24
+ # CTRL-F:: Scrolls the scrolling items down one page.
24
25
  # Tab:: Tries to complete the word in the entry field.
25
26
  # If the word segment is not unique then the widget
26
- # will beep and present a list of close matches.
27
+ # will beep and present a items of close matches.
27
28
  # Return:: Returns the word in the entry field.
28
29
  # It also sets the widget data exitType to `:NORMAL`.
29
30
  # Escape:: Exits the widget and returns `nil`.
@@ -32,28 +33,30 @@ module RNDK
32
33
  # ## Developer notes
33
34
  #
34
35
  # This widget, like the file selector widget, is a compound widget
35
- # of both the entry field widget and the scrolling list widget - sorted.
36
+ # of both the entry field widget and the scrolling items widget - sorted.
37
+ #
38
+ # @todo Kinda buggy, fix first words, mate
36
39
  #
37
40
  class Alphalist < Widget
38
- attr_reader :scroll_field, :entry_field, :list
41
+ attr_reader :scroll_field, :entry_field, :items
39
42
 
40
43
  # Creates an Alphalist Widget.
41
44
  #
42
- # * `xplace` is the x position - can be an integer or `RNDK::LEFT`,
45
+ # ## Settings
46
+ #
47
+ # * `x` is the x position - can be an integer or `RNDK::LEFT`,
43
48
  # `RNDK::RIGHT`, `RNDK::CENTER`.
44
- # * `yplace` is the y position - can be an integer or `RNDK::TOP`,
49
+ # * `y` is the y position - can be an integer or `RNDK::TOP`,
45
50
  # `RNDK::BOTTOM`, `RNDK::CENTER`.
46
51
  # * `width`/`height` are integers - if either are 0, Widget
47
52
  # will be created with full width/height of the screen.
48
53
  # If it's a negative value, will create with full width/height
49
54
  # minus the value.
50
- # * `message` is an Array of Strings with all the lines you'd want
51
- # to show. RNDK markup applies (see RNDK#Markup).
52
55
  # * `title` can be more than one line - just split them
53
56
  # with `\n`s.
54
57
  # * `label` is the String that will appear on the label
55
58
  # of the Entry field.
56
- # * `list` is an Array of Strings with the content to
59
+ # * `items` is an Array of Strings with the content to
57
60
  # display.
58
61
  # * `filler_char` is the character to display on the
59
62
  # empty spaces in the Entry field.
@@ -62,34 +65,49 @@ module RNDK
62
65
  # * `box` if the Widget is drawn with a box outside it.
63
66
  # * `shadow` turns on/off the shadow around the Widget.
64
67
  #
65
- def initialize(rndkscreen,
66
- xplace,
67
- yplace,
68
- width,
69
- height,
70
- title,
71
- label,
72
- list,
73
- filler_char,
74
- highlight,
75
- box,
76
- shadow)
68
+ def initialize(screen, config={})
77
69
  super()
70
+ @widget_type = :alphaitems
71
+ @supported_signals += [:before_input, :after_input]
72
+
73
+ # This is UGLY AS HELL
74
+ # But I don't have time to clean this up right now
75
+ # (lots of widgets, you know) :(
76
+ x = 0
77
+ y = 0
78
+ width = 0
79
+ height = 0
80
+ title = "alphaitems"
81
+ label = "label"
82
+ items = []
83
+ filler_char = '.'
84
+ highlight = RNDK::Color[:reverse]
85
+ box = true
86
+ shadow = false
87
+
88
+ config.each do |key, val|
89
+ x = val if key == :x
90
+ y = val if key == :y
91
+ width = val if key == :width
92
+ height = val if key == :height
93
+ title = val if key == :title
94
+ label = val if key == :label
95
+ items = val if key == :items
96
+ filler_char = val if key == :filler_char
97
+ highlight = val if key == :highlight
98
+ box = val if key == :box
99
+ shadow = val if key == :shadow
100
+ end
78
101
 
79
- parent_width = Ncurses.getmaxx rndkscreen.window
80
- parent_height = Ncurses.getmaxy rndkscreen.window
102
+ parent_width = Ncurses.getmaxx screen.window
103
+ parent_height = Ncurses.getmaxy screen.window
81
104
 
82
105
  box_width = width
83
106
  box_height = height
84
107
 
85
108
  label_len = 0
86
109
 
87
- bindings = {
88
- RNDK::BACKCHAR => Ncurses::KEY_PPAGE,
89
- RNDK::FORCHAR => Ncurses::KEY_NPAGE,
90
- }
91
-
92
- if not self.createList list
110
+ if not self.create_items items
93
111
  self.destroy
94
112
  return nil
95
113
  end
@@ -98,11 +116,11 @@ module RNDK
98
116
 
99
117
  # If the height is a negative value, the height will be ROWS-height,
100
118
  # otherwise the height will be the given height.
101
- box_height = RNDK.setWidgetDimension(parent_height, height, 0)
119
+ box_height = RNDK.set_widget_dimension(parent_height, height, 0)
102
120
 
103
121
  # If the width is a negative value, the width will be COLS-width,
104
122
  # otherwise the width will be the given width.
105
- box_width = RNDK.setWidgetDimension(parent_width, width, 0)
123
+ box_width = RNDK.set_widget_dimension(parent_width, width, 0)
106
124
 
107
125
  # Translate the label string to a chtype array
108
126
  if label.size > 0
@@ -112,9 +130,9 @@ module RNDK
112
130
  end
113
131
 
114
132
  # Rejustify the x and y positions if we need to.
115
- xtmp = [xplace]
116
- ytmp = [yplace]
117
- RNDK.alignxy(rndkscreen.window, xtmp, ytmp, box_width, box_height)
133
+ xtmp = [x]
134
+ ytmp = [y]
135
+ RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
118
136
  xpos = xtmp[0]
119
137
  ypos = ytmp[0]
120
138
 
@@ -127,8 +145,8 @@ module RNDK
127
145
  end
128
146
  Ncurses.keypad(@win, true)
129
147
 
130
- @screen = rndkscreen
131
- @parent = rndkscreen.window
148
+ @screen = screen
149
+ @parent = screen.window
132
150
  @highlight = highlight
133
151
  @filler_char = filler_char
134
152
 
@@ -149,19 +167,15 @@ module RNDK
149
167
  else box_width - 2 - label_len
150
168
  end
151
169
 
152
- @entry_field = RNDK::Entry.new(rndkscreen,
153
- Ncurses.getbegx(@win),
154
- Ncurses.getbegy(@win),
155
- title,
156
- label,
157
- Ncurses::A_NORMAL,
158
- filler_char,
159
- :MIXED,
160
- temp_width,
161
- 0,
162
- 512,
163
- box,
164
- false)
170
+ @entry_field = RNDK::Entry.new(screen, {
171
+ :x => Ncurses.getbegx(@win),
172
+ :y => Ncurses.getbegy(@win),
173
+ :title => title,
174
+ :label => label,
175
+ :filler => filler_char,
176
+ :field_width => temp_width,
177
+ :box => box
178
+ })
165
179
  if @entry_field.nil?
166
180
  self.destroy
167
181
  return nil
@@ -169,191 +183,16 @@ module RNDK
169
183
  @entry_field.setLLchar Ncurses::ACS_LTEE
170
184
  @entry_field.setLRchar Ncurses::ACS_RTEE
171
185
 
172
- # Callback functions
173
- adjust_alphalist_cb = lambda do |object_type, object, alphalist, key|
174
- scrollp = alphalist.scroll_field
175
- entry = alphalist.entry_field
176
-
177
- if scrollp.list_size > 0
178
- # Adjust the scrolling list.
179
- alphalist.injectMyScroller(key)
180
-
181
- # Set the value in the entry field.
182
- current = RNDK.chtype2Char scrollp.item[scrollp.current_item]
183
- entry.setValue current
184
- entry.draw entry.box
185
- return true
186
- end
187
-
188
- RNDK.beep
189
- false
190
- end
191
-
192
- complete_word_cb = lambda do |object_type, object, alphalist, key|
193
- entry = alphalist.entry_field
194
- scrollp = nil
195
- selected = -1
196
- ret = 0
197
- alt_words = []
198
-
199
- if entry.info.size == 0
200
- RNDK.beep
201
- return true
202
- end
203
-
204
- # Look for a unique word match.
205
- index = RNDK.searchList(alphalist.list, alphalist.list.size, entry.info)
206
-
207
- # if the index is less than zero, return we didn't find a match
208
- if index < 0
209
- RNDK.beep
210
- return true
211
- end
212
-
213
- # Did we find the last word in the list?
214
- if index == alphalist.list.size - 1
215
- entry.setValue alphalist.list[index]
216
- entry.draw entry.box
217
- return true
218
- end
219
-
220
- # Ok, we found a match, is the next item similar?
221
- len = [entry.info.size, alphalist.list[index + 1].size].min
222
- ret = alphalist.list[index + 1][0...len] <=> entry.info
223
- if ret == 0
224
- current_index = index
225
- match = 0
226
- selected = -1
227
-
228
- # Start looking for alternate words
229
- # FIXME(original): bsearch would be more suitable.
230
- while (current_index < alphalist.list.size) and
231
- ((alphalist.list[current_index][0...len] <=> entry.info) == 0)
232
- alt_words << alphalist.list[current_index]
233
- current_index += 1
234
- end
235
-
236
- # Determine the height of the scrolling list.
237
- height = if alt_words.size < 8 then alt_words.size + 3 else 11 end
238
-
239
- # Create a scrolling list of close matches.
240
- scrollp = RNDK::Scroll.new(entry.screen,
241
- RNDK::CENTER,
242
- RNDK::CENTER,
243
- RNDK::RIGHT,
244
- height,
245
- -30,
246
- "<C></B/5>Possible Matches.",
247
- alt_words,
248
- true,
249
- Ncurses::A_REVERSE,
250
- true,
251
- false)
252
-
253
- # Allow them to select a close match.
254
- match = scrollp.activate
255
- selected = scrollp.current_item
256
-
257
- # Check how they exited the list.
258
- if scrollp.exit_type == :ESCAPE_HIT
259
- # Destroy the scrolling list.
260
- scrollp.destroy
261
-
262
- RNDK.beep
263
-
264
- # Redraw the alphalist and return.
265
- alphalist.draw(alphalist.box)
266
- return true
267
- end
268
-
269
- # Destroy the scrolling list.
270
- scrollp.destroy
271
-
272
- # Set the entry field to the selected value.
273
- entry.set(alt_words[match], entry.min, entry.max, entry.box)
274
-
275
- # Move the highlight bar down to the selected value.
276
- (0...selected).each do |x|
277
- alphalist.injectMyScroller(Ncurses::KEY_DOWN)
278
- end
279
-
280
- # Redraw the alphalist.
281
- alphalist.draw alphalist.box
282
-
283
- else
284
- # Set the entry field with the found item.
285
- entry.set(alphalist.list[index], entry.min, entry.max, entry.box)
286
- entry.draw entry.box
287
- end
288
- true
289
- end
290
-
291
- pre_process_entry_field = lambda do |rndktype, object, alphalist, input|
292
- scrollp = alphalist.scroll_field
293
- entry = alphalist.entry_field
294
- info_len = entry.info.size
295
- result = 1
296
- empty = false
297
-
298
- if alphalist.isBind(:alphalist, input)
299
- result = 1 # Don't try to use this key in editing
300
-
301
- elsif (RNDK.is_char?(input) &&
302
- input.chr.match(/^[[:alnum:][:punct:]]$/)) ||
303
- [Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC].include?(input)
304
-
305
- index = 0
306
- curr_pos = entry.screen_col + entry.left_char
307
- pattern = entry.info.clone
308
-
309
- if [Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC].include? input
310
-
311
- curr_pos -= 1 if input == Ncurses::KEY_BACKSPACE
312
-
313
- pattern.slice!(curr_pos) if curr_pos >= 0
314
-
315
- else
316
- front = (pattern[0...curr_pos] or '')
317
- back = (pattern[curr_pos..-1] or '')
318
- pattern = front + input.chr + back
319
- end
320
-
321
- if pattern.size == 0
322
- empty = true
323
-
324
- elsif (index = RNDK.searchList(alphalist.list,
325
- alphalist.list.size,
326
- pattern)) >= 0
327
-
328
- # XXX: original uses n scroll downs/ups for <10 positions change
329
- scrollp.setPosition(index)
330
- alphalist.drawMyScroller
331
-
332
- else
333
- RNDK.beep
334
- result = 0
335
- end
336
- end
337
-
338
- if empty
339
- scrollp.setPosition(0)
340
- alphalist.drawMyScroller
341
- end
342
-
343
- result
344
- end
345
-
346
186
  # Set the key bindings for the entry field.
347
- @entry_field.bind(:entry, Ncurses::KEY_UP, adjust_alphalist_cb, self)
348
- @entry_field.bind(:entry, Ncurses::KEY_DOWN, adjust_alphalist_cb, self)
349
- @entry_field.bind(:entry, Ncurses::KEY_NPAGE, adjust_alphalist_cb, self)
350
- @entry_field.bind(:entry, Ncurses::KEY_PPAGE, adjust_alphalist_cb, self)
351
- @entry_field.bind(:entry, RNDK::KEY_TAB, complete_word_cb, self)
187
+ @entry_field.bind_key(Ncurses::KEY_UP) { self.autocomplete }
188
+ @entry_field.bind_key(RNDK::KEY_TAB) { self.autocomplete }
189
+ @entry_field.bind_key(Ncurses::KEY_DOWN) { self.adjust_items }
190
+ @entry_field.bind_key(Ncurses::KEY_NPAGE) { self.adjust_items }
191
+ @entry_field.bind_key(Ncurses::KEY_PPAGE) { self.adjust_items }
352
192
 
353
- # Set up the post-process function for the entry field.
354
- @entry_field.setPreProcess(pre_process_entry_field, self)
193
+ @entry_field.bind_signal(:before_input) { |char| self.pre_process_entry_field(char) }
355
194
 
356
- # Create the scrolling list. It overlaps the entry field by one line if
195
+ # Create the scrolling items. It overlaps the entry field by one line if
357
196
  # we are using box-borders.
358
197
  temp_height = Ncurses.getmaxy(@entry_field.win) - @border_size
359
198
  temp_width = if Alphalist.isFullWidth(width)
@@ -361,33 +200,25 @@ module RNDK
361
200
  else box_width - 1
362
201
  end
363
202
 
364
- @scroll_field = RNDK::Scroll.new(rndkscreen,
365
- Ncurses.getbegx(@win),
366
- Ncurses.getbegy(@entry_field.win) + temp_height,
367
- RNDK::RIGHT,
368
- box_height - temp_height,
369
- temp_width,
370
- '',
371
- list,
372
- false,
373
- Ncurses::A_REVERSE,
374
- box,
375
- false)
203
+ @scroll_field = RNDK::Scroll.new(screen, {
204
+ :x => Ncurses.getbegx(@win),
205
+ :y => Ncurses.getbegy(@entry_field.win) + temp_height,
206
+ :width => temp_width,
207
+ :height => box_height - temp_height,
208
+ :title => '',
209
+ :items => items,
210
+ :box => box
211
+ })
376
212
 
377
213
  @scroll_field.setULchar Ncurses::ACS_LTEE
378
214
  @scroll_field.setURchar Ncurses::ACS_RTEE
379
215
 
380
- # Setup the key bindings.
381
- bindings.each do |from, to|
382
- self.bind(:alphalist, from, :getc, to)
383
- end
384
-
385
- rndkscreen.register(:alphalist, self)
216
+ screen.register(:alphaitems, self)
386
217
  end
387
218
 
388
219
  # @see Widget#erase
389
220
  def erase
390
- if self.valid_widget?
221
+ if self.valid?
391
222
  @scroll_field.erase
392
223
  @entry_field.erase
393
224
 
@@ -397,13 +228,13 @@ module RNDK
397
228
  end
398
229
 
399
230
  # @see Widget#move
400
- def move(xplace, yplace, relative, refresh_flag)
231
+ def move(x, y, relative, refresh_flag)
401
232
  windows = [@win, @shadow_win]
402
233
  subwidgets = [@entry_field, @scroll_field]
403
- self.move_specific(xplace, yplace, relative, refresh_flag, windows, subwidgets)
234
+ self.move_specific(x, y, relative, refresh_flag, windows, subwidgets)
404
235
  end
405
236
 
406
- # The alphalist's focus resides in the entry widget. But the scroll widget
237
+ # The alphaitems's focus resides in the entry widget. But the scroll widget
407
238
  # will not draw items highlighted unless it has focus. Temporarily adjust
408
239
  # the focus of the scroll widget when drawing on it to get the right
409
240
  # highlighting.
@@ -416,9 +247,9 @@ module RNDK
416
247
  @scroll_field.has_focus = @save
417
248
  end
418
249
 
419
- def drawMyScroller
250
+ def draw_scroller
420
251
  self.saveFocus
421
- @scroll_field.draw(@scroll_field.box)
252
+ @scroll_field.draw
422
253
  self.restoreFocus
423
254
  end
424
255
 
@@ -431,14 +262,14 @@ module RNDK
431
262
  # Draws the Widget on the Screen.
432
263
  #
433
264
  # If `box` is true, it is drawn with a box.
434
- def draw box
265
+ def draw
435
266
  Draw.drawShadow @shadow_win unless @shadow_win.nil?
436
267
 
437
268
  # Draw in the entry field.
438
269
  @entry_field.draw @entry_field.box
439
270
 
440
271
  # Draw in the scroll field.
441
- self.drawMyScroller
272
+ self.draw_scroller
442
273
  end
443
274
 
444
275
  # Activates the Alphalist Widget, letting the user interact with it.
@@ -455,7 +286,7 @@ module RNDK
455
286
  ret = 0
456
287
 
457
288
  # Draw the widget.
458
- self.draw(@box)
289
+ self.draw
459
290
 
460
291
  # Activate the widget.
461
292
  ret = @entry_field.activate actions
@@ -478,19 +309,19 @@ module RNDK
478
309
  # Besides normal keybindings (arrow keys and such), see
479
310
  # Widget#set_exit_type to see how the Widget exits.
480
311
  #
481
- def inject char
482
- ret = -1
312
+ def inject input
313
+ ret = false
483
314
 
484
- self.draw @box
315
+ self.draw
485
316
 
486
317
  # Inject a character into the widget.
487
- ret = @entry_field.inject char
318
+ ret = @entry_field.inject input
488
319
 
489
320
  # Copy the eixt type from the entry field.
490
321
  @exit_type = @entry_field.exit_type
491
322
 
492
323
  # Determine the exit status.
493
- ret = -1 if @exit_type == :EARLY_EXIT
324
+ ret = false if @exit_type == :EARLY_EXIT
494
325
 
495
326
  @result_data = ret
496
327
  ret
@@ -499,19 +330,19 @@ module RNDK
499
330
  # Sets multiple attributes of the Widget.
500
331
  #
501
332
  # See Alphalist#initialize.
502
- def set(list, filler_char, highlight, box)
503
- self.set_contents list
333
+ def set(items, filler_char, highlight, box)
334
+ self.set_contents items
504
335
  self.set_filler_char filler_char
505
336
  self.set_highlight highlight
506
337
  self.set_box box
507
338
  end
508
339
 
509
- # This function sets the information inside the alphalist.
510
- def set_contents list
511
- return if not self.createList list
340
+ # This function sets the information inside the alphaitems.
341
+ def set_contents items
342
+ return if not self.create_items items
512
343
 
513
- # Set the information in the scrolling list.
514
- @scroll_field.set(@list, @list_size, false,
344
+ # Set the information in the scrolling items.
345
+ @scroll_field.set(@items, @items_size, false,
515
346
  @scroll_field.highlight, @scroll_field.box)
516
347
 
517
348
  # Clean out the entry field.
@@ -520,13 +351,13 @@ module RNDK
520
351
 
521
352
  # Redraw the widget.
522
353
  self.erase
523
- self.draw @box
354
+ self.draw
524
355
  end
525
356
 
526
357
  # This returns the contents of the widget.
527
358
  def getContents size
528
- size << @list_size
529
- return @list
359
+ size << @items_size
360
+ return @items
530
361
  end
531
362
 
532
363
  # Get/set the current position in the scroll widget.
@@ -535,13 +366,13 @@ module RNDK
535
366
  end
536
367
 
537
368
  def set_current_item item
538
- if @list_size != 0
369
+ if @items_size != 0
539
370
  @scroll_field.set_current_item item
540
- @entry_field.setValue @list[@scroll_field.get_current_item]
371
+ @entry_field.setValue @items[@scroll_field.get_current_item]
541
372
  end
542
373
  end
543
374
 
544
- # This sets the filler character of the entry field of the alphalist.
375
+ # This sets the filler character of the entry field of the alphaitems.
545
376
  def set_filler_char char
546
377
  @filler_char = char
547
378
  @entry_field.set_filler_char char
@@ -593,22 +424,22 @@ module RNDK
593
424
  end
594
425
 
595
426
  # This sets the background attribute of the widget.
596
- def set_bg_attrib(attrib)
597
- @entry_field.set_bg_attrib(attrib)
598
- @scroll_field.set_bg_attrib(attrib)
427
+ def set_bg_color(attrib)
428
+ @entry_field.set_bg_color(attrib)
429
+ @scroll_field.set_bg_color(attrib)
599
430
  end
600
431
 
601
432
  def destroyInfo
602
- @list = ''
603
- @list_size = 0
433
+ @items = ''
434
+ @items_size = 0
604
435
  end
605
436
 
606
- # This destroys the alpha list
437
+ # This destroys the alpha items
607
438
  def destroy
608
439
  self.destroyInfo
609
440
 
610
441
  # Clean the key bindings.
611
- self.clean_bindings(:alphalist)
442
+ self.clean_bindings
612
443
 
613
444
  @entry_field.destroy
614
445
  @scroll_field.destroy
@@ -617,38 +448,33 @@ module RNDK
617
448
  RNDK.window_delete(@shadow_win)
618
449
  RNDK.window_delete(@win)
619
450
 
620
- # Unregister the object.
621
- RNDK::Screen.unregister(:alphalist, self)
451
+ # Unregister the widget.
452
+ @screen.unregister self
622
453
  end
623
454
 
624
- # This function sets the pre-process function.
625
- def setPreProcess(callback, data)
626
- @entry_field.setPreProcess(callback, data)
455
+ # @see Widget#bind_signal
456
+ def bind_signal(signal, &action)
457
+ @entry_field.bind_signal(signal, action)
627
458
  end
628
459
 
629
- # This function sets the post-process function.
630
- def setPostProcess(callback, data)
631
- @entry_field.setPostProcess(callback, data)
632
- end
633
-
634
- def createList list
635
- if list.size >= 0
636
- newlist = []
460
+ def create_items items
461
+ if items.size >= 0
462
+ newitems = []
637
463
 
638
464
  # Copy in the new information.
639
465
  status = true
640
- (0...list.size).each do |x|
641
- newlist << list[x]
642
- if newlist[x] == 0
466
+ (0...items.size).each do |x|
467
+ newitems << items[x]
468
+ if newitems[x] == 0
643
469
  status = false
644
470
  break
645
471
  end
646
472
  end
647
473
  if status
648
474
  self.destroyInfo
649
- @list_size = list.size
650
- @list = newlist
651
- @list.sort!
475
+ @items_size = items.size
476
+ @items = newitems
477
+ @items.sort!
652
478
  end
653
479
  else
654
480
  self.destroyInfo
@@ -673,8 +499,178 @@ module RNDK
673
499
  super(@win)
674
500
  end
675
501
 
676
- def object_type
677
- :alphalist
502
+
503
+ protected
504
+
505
+ def autocomplete
506
+ scrollp = self.scroll_field
507
+ entry = self.entry_field
508
+
509
+ if scrollp.items_size > 0
510
+ # Adjust the scrolling items.
511
+ self.injectMyScroller Ncurses::KEY_UP
512
+
513
+ # Set the value in the entry field.
514
+ current = RNDK.chtype2Char scrollp.item[scrollp.current_item]
515
+ entry.setValue current
516
+ entry.draw entry.box
517
+ return true
518
+ end
519
+
520
+ RNDK.beep
521
+ false
522
+ end
523
+
524
+ def adjust_items
525
+ entry = self.entry_field
526
+ scrollp = nil
527
+ selected = -1
528
+ ret = 0
529
+ alt_words = []
530
+
531
+ if entry.info.size == 0
532
+ RNDK.beep
533
+ return true
534
+ end
535
+
536
+ # Look for a unique word match.
537
+ index = RNDK.search_list(self.items, self.items.size, entry.info)
538
+
539
+ # if the index is less than zero, return we didn't find a match
540
+ if index < 0
541
+ RNDK.beep
542
+ return true
543
+ end
544
+
545
+ # Did we find the last word in the items?
546
+ if index == self.items.size - 1
547
+ entry.setValue self.items[index]
548
+ entry.draw entry.box
549
+ return true
550
+ end
551
+
552
+ # Ok, we found a match, is the next item similar?
553
+ len = [entry.info.size, self.items[index + 1].size].min
554
+ ret = self.items[index + 1][0...len] <=> entry.info
555
+ if ret == 0
556
+ current_index = index
557
+ match = 0
558
+ selected = -1
559
+
560
+ # Start looking for alternate words
561
+ # FIXME(original): bsearch would be more suitable.
562
+ while (current_index < self.items.size) and
563
+ ((self.items[current_index][0...len] <=> entry.info) == 0)
564
+ alt_words << self.items[current_index]
565
+ current_index += 1
566
+ end
567
+
568
+ # Determine the height of the scrolling items.
569
+ height = if alt_words.size < 8 then alt_words.size + 3 else 11 end
570
+
571
+ # Create a scrolling items of close matches.
572
+ scrollp = RNDK::Scroll.new(entry.screen, {
573
+ :x => RNDK::CENTER,
574
+ :y => RNDK::CENTER,
575
+ :width => -30,
576
+ :height => height,
577
+ :title => "<C></B/5>Possible Matches.",
578
+ :items => alt_words,
579
+ :numbers => true
580
+ })
581
+
582
+ # Allow them to select a close match.
583
+ match = scrollp.activate
584
+ selected = scrollp.current_item
585
+
586
+ # Check how they exited the items.
587
+ if scrollp.exit_type == :ESCAPE_HIT
588
+ # Destroy the scrolling items.
589
+ scrollp.destroy
590
+
591
+ RNDK.beep
592
+
593
+ # Redraw the self and return.
594
+ self.draw(self.box)
595
+ return true
596
+ end
597
+
598
+ # Destroy the scrolling items.
599
+ scrollp.destroy
600
+
601
+ # Set the entry field to the selected value.
602
+ entry.set(alt_words[match], entry.min, entry.max, entry.box)
603
+
604
+ # Move the highlight bar down to the selected value.
605
+ (0...selected).each do |x|
606
+ self.injectMyScroller(Ncurses::KEY_DOWN)
607
+ end
608
+
609
+ # Redraw the self.
610
+ self.draw self.box
611
+
612
+ else
613
+ # Set the entry field with the found item.
614
+ entry.set(self.items[index], entry.min, entry.max, entry.box)
615
+ entry.draw entry.box
616
+ end
617
+ true
618
+ end
619
+
620
+ def pre_process_entry_field(input)
621
+ scrollp = self.scroll_field
622
+ entry = self.entry_field
623
+ info_len = entry.info.size
624
+ result = 1
625
+ empty = false
626
+
627
+ if self.is_bound? input
628
+ result = 1 # Don't try to use this key in editing
629
+
630
+ elsif (RNDK.is_char?(input) &&
631
+ input.chr.match(/^[[:alnum:][:punct:]]$/)) ||
632
+ [Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC].include?(input)
633
+
634
+ index = 0
635
+ curr_pos = entry.screen_col + entry.left_char
636
+ pattern = entry.info.clone
637
+
638
+ if [Ncurses::KEY_BACKSPACE, Ncurses::KEY_DC].include? input
639
+
640
+ curr_pos -= 1 if input == Ncurses::KEY_BACKSPACE
641
+
642
+ pattern.slice!(curr_pos) if curr_pos >= 0
643
+
644
+ else
645
+ front = (pattern[0...curr_pos] or '')
646
+ back = (pattern[curr_pos..-1] or '')
647
+ pattern = front + input.chr + back
648
+ end
649
+
650
+ if pattern.size == 0
651
+ empty = true
652
+
653
+ elsif (index = RNDK.search_list(self.items,
654
+ self.items.size,
655
+ pattern)) >= 0
656
+
657
+ # XXX: original uses n scroll downs/ups for <10 positions change
658
+ scrollp.set_position(index)
659
+ self.draw_scroller
660
+
661
+ else
662
+ RNDK.beep
663
+ result = 0
664
+ end
665
+ end
666
+
667
+ if empty
668
+ scrollp.set_position(0)
669
+ self.draw_scroller
670
+ end
671
+
672
+ result
678
673
  end
674
+
679
675
  end
680
676
  end