rndk 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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