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.
- checksums.yaml +4 -4
- data/README.md +13 -4
- data/TODO +21 -1
- data/demos/appointment.rb +279 -299
- data/demos/clock.rb +13 -8
- data/demos/rss-reader.rb +84 -0
- data/examples/01-hello-world.rb +13 -11
- data/examples/02-colors.rb +14 -21
- data/examples/03-markup.rb +7 -7
- data/examples/04-quick-widgets.rb +2 -2
- data/examples/05-position-widget.rb +50 -31
- data/examples/06-callbacks.rb +77 -0
- data/examples/07-traverse.rb +90 -0
- data/examples/10-all-widgets.rb +165 -0
- data/examples/calendar.rb +20 -32
- data/examples/entry.rb +15 -20
- data/examples/label.rb +11 -11
- data/examples/scroll.rb +16 -60
- data/examples/slider.rb +18 -19
- data/examples/viewer.rb +65 -0
- data/lib/rndk.rb +28 -7
- data/lib/rndk/alphalist.rb +309 -313
- data/lib/rndk/button.rb +239 -157
- data/lib/rndk/buttonbox.rb +136 -103
- data/lib/rndk/calendar.rb +246 -203
- data/lib/rndk/core/color.rb +63 -13
- data/lib/rndk/core/display.rb +1 -1
- data/lib/rndk/core/draw.rb +11 -11
- data/lib/rndk/core/markup.rb +21 -21
- data/lib/rndk/core/quick_widgets.rb +75 -96
- data/lib/rndk/core/screen.rb +145 -102
- data/lib/rndk/core/traverse.rb +150 -136
- data/lib/rndk/core/utils.rb +5 -6
- data/lib/rndk/core/widget.rb +207 -191
- data/lib/rndk/core/widget_bind.rb +108 -0
- data/lib/rndk/dialog.rb +88 -56
- data/lib/rndk/entry.rb +79 -64
- data/lib/rndk/fscale.rb +38 -20
- data/lib/rndk/fslider.rb +38 -23
- data/lib/rndk/graph.rb +92 -53
- data/lib/rndk/itemlist.rb +80 -62
- data/lib/rndk/label.rb +111 -77
- data/lib/rndk/radio.rb +138 -128
- data/lib/rndk/scale.rb +123 -122
- data/lib/rndk/scroll.rb +444 -391
- data/lib/rndk/scroller.rb +21 -21
- data/lib/rndk/slider.rb +149 -140
- data/lib/rndk/template.rb +74 -61
- data/lib/rndk/version.rb +1 -1
- data/lib/rndk/viewer.rb +499 -298
- metadata +8 -14
- data/demos/fileview.rb +0 -141
- data/lib/rndk/dscale.rb +0 -13
- data/lib/rndk/fselect.rb +0 -938
- data/lib/rndk/histogram.rb +0 -412
- data/lib/rndk/marquee.rb +0 -244
- data/lib/rndk/matrix.rb +0 -1189
- data/lib/rndk/mentry.rb +0 -619
- data/lib/rndk/menu.rb +0 -478
- data/lib/rndk/selection.rb +0 -630
- data/lib/rndk/swindow.rb +0 -766
- data/lib/rndk/uscale.rb +0 -14
- data/lib/rndk/uslider.rb +0 -14
data/lib/rndk/core/screen.rb
CHANGED
@@ -10,18 +10,44 @@ module RNDK
|
|
10
10
|
# The only methods you should worry about are:
|
11
11
|
#
|
12
12
|
# * Screen#initialize
|
13
|
-
# * Screen#
|
13
|
+
# * Screen#finish
|
14
14
|
# * Screen#draw or #refresh
|
15
15
|
# * Screen#erase
|
16
16
|
#
|
17
17
|
# ## Developer Notes
|
18
18
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
19
|
+
# When a Widget is created, it calls Screen#register with it's
|
20
|
+
# type and self pointer.
|
21
|
+
#
|
22
|
+
# That adds the widget pointer to an Array `@widget` that
|
23
|
+
# contains all the widgets inside this screen.
|
24
|
+
#
|
25
|
+
# During it's lifetime, most widgets would call only Screen#erase
|
26
|
+
# and Screen#refresh.
|
27
|
+
#
|
28
|
+
# When Widget#destroy is called, we call Screen#unregister to
|
29
|
+
# remove it from the `@widget` array.
|
30
|
+
#
|
31
|
+
# Now, what happens when the Ruby garbage collector kills the
|
32
|
+
# widget?
|
22
33
|
#
|
23
34
|
class Screen
|
24
|
-
|
35
|
+
# Index of the current focused widget
|
36
|
+
attr_accessor :widget_focus
|
37
|
+
|
38
|
+
# How many widgets we currently have
|
39
|
+
attr_accessor :widget_count
|
40
|
+
|
41
|
+
# Maximum widget capacity of the screen (always expands)
|
42
|
+
attr_accessor :widget_limit
|
43
|
+
|
44
|
+
# Array with all the widgets currently on the screen
|
45
|
+
attr_accessor :widget
|
46
|
+
|
47
|
+
# Raw Ncurses window that represents this Screen
|
48
|
+
attr_accessor :window
|
49
|
+
|
50
|
+
# Nothing... for now
|
25
51
|
attr_accessor :exit_status
|
26
52
|
|
27
53
|
NOEXIT = 0
|
@@ -47,7 +73,7 @@ module RNDK
|
|
47
73
|
|
48
74
|
# If the user didn't start Ncurses for us,
|
49
75
|
# we'll do it anyway.
|
50
|
-
if RNDK::ALL_SCREENS.
|
76
|
+
if RNDK::ALL_SCREENS.empty? or ncurses_window.nil?
|
51
77
|
|
52
78
|
## Why is this here?
|
53
79
|
# Set up basic curses settings.
|
@@ -58,18 +84,30 @@ module RNDK
|
|
58
84
|
ncurses_window = Ncurses.initscr
|
59
85
|
Ncurses.noecho
|
60
86
|
Ncurses.cbreak
|
87
|
+
Ncurses.keypad(ncurses_window, true)
|
61
88
|
end
|
62
89
|
|
63
90
|
RNDK::ALL_SCREENS << self
|
64
|
-
@
|
65
|
-
@
|
66
|
-
@
|
91
|
+
@widget_count = 0
|
92
|
+
@widget_limit = 2
|
93
|
+
@widget = Array.new(@widget_limit, nil)
|
67
94
|
@window = ncurses_window
|
68
|
-
@
|
95
|
+
@widget_focus = 0
|
69
96
|
end
|
70
97
|
|
71
|
-
# Shuts down RNDK and Ncurses
|
72
|
-
|
98
|
+
# Shuts down RNDK and Ncurses, plus destroying all the
|
99
|
+
# widgets ever created.
|
100
|
+
def self.finish
|
101
|
+
|
102
|
+
## If I do this it gives me a segmentation fault.
|
103
|
+
## I guess that would happen because of the
|
104
|
+
## ruby garbage collector.
|
105
|
+
##
|
106
|
+
## What should I do instead?
|
107
|
+
#
|
108
|
+
# RNDK::ALL_WIDGETS.each { |obj| obj.destroy }
|
109
|
+
# RNDK::ALL_SCREENS.each { |scr| scr.destroy }
|
110
|
+
|
73
111
|
Ncurses.echo
|
74
112
|
Ncurses.nocbreak
|
75
113
|
Ncurses.endwin
|
@@ -79,87 +117,62 @@ module RNDK
|
|
79
117
|
#
|
80
118
|
# @note This is called automatically when a widget is created.
|
81
119
|
#
|
82
|
-
# `rndktype` states what RNDK Widget type this
|
83
|
-
# `
|
120
|
+
# * `rndktype` states what RNDK Widget type this widget is.
|
121
|
+
# * `widget` is a pointer to the Widget itself.
|
84
122
|
#
|
85
|
-
def register(rndktype,
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
@
|
123
|
+
def register(rndktype, widget)
|
124
|
+
|
125
|
+
# Expanding the limit by 2
|
126
|
+
if (@widget_count + 1) >= @widget_limit
|
127
|
+
@widget_limit += 2
|
128
|
+
@widget_limit *= 2
|
129
|
+
@widget.concat Array.new(@widget_limit - @widget.size, nil)
|
90
130
|
end
|
91
131
|
|
92
|
-
if
|
93
|
-
self.
|
94
|
-
@
|
132
|
+
if widget.valid_type?
|
133
|
+
self.set_screen_index(@widget_count, widget)
|
134
|
+
@widget_count += 1
|
95
135
|
end
|
96
136
|
end
|
97
137
|
|
98
|
-
# Removes a Widget from
|
138
|
+
# Removes a Widget from this Screen.
|
99
139
|
#
|
100
140
|
# @note This is called automatically when a widget is destroyed.
|
101
141
|
#
|
102
|
-
# This does NOT destroy the
|
142
|
+
# This does NOT destroy the widget, it removes the Widget
|
103
143
|
# from any further refreshes by Screen#refresh.
|
104
144
|
#
|
105
|
-
# `rndktype` states what RNDK Widget type this
|
106
|
-
# `
|
145
|
+
# `rndktype` states what RNDK Widget type this widget is.
|
146
|
+
# `widget` is a pointer to the Widget itself.
|
107
147
|
#
|
108
|
-
def
|
109
|
-
return
|
110
|
-
|
111
|
-
screen = object.screen
|
112
|
-
return if screen.nil?
|
148
|
+
def unregister widget
|
149
|
+
return unless (widget.valid_type? and (widget.screen_index >= 0))
|
113
150
|
|
114
|
-
index =
|
115
|
-
|
151
|
+
index = widget.screen_index
|
152
|
+
widget.screen_index = -1
|
116
153
|
|
117
|
-
# Resequence the
|
118
|
-
(index...
|
119
|
-
|
154
|
+
# Resequence the widgets
|
155
|
+
(index...self.widget_count - 1).each do |x|
|
156
|
+
self.set_screen_index(x, self.widget[x+1])
|
120
157
|
end
|
121
158
|
|
122
|
-
if
|
123
|
-
# if no more
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
else
|
128
|
-
screen.object[screen.object_count] = nil
|
129
|
-
screen.object_count -= 1
|
130
|
-
|
131
|
-
# Update the object-focus
|
132
|
-
if screen.object_focus == index
|
133
|
-
screen.object_focus -= 1
|
134
|
-
Traverse.setRNDKFocusNext(screen)
|
135
|
-
|
136
|
-
elsif screen.object_focus > index
|
137
|
-
screen.object_focus -= 1
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
159
|
+
if self.widget_count <= 1
|
160
|
+
# if no more widgets, remove the array
|
161
|
+
self.widget = []
|
162
|
+
self.widget_count = 0
|
163
|
+
self.widget_limit = 0
|
141
164
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@object[number] = obj
|
146
|
-
end
|
165
|
+
else
|
166
|
+
self.widget[self.widget_count] = nil
|
167
|
+
self.widget_count -= 1
|
147
168
|
|
148
|
-
|
149
|
-
|
150
|
-
|
169
|
+
# Update the widget-focus
|
170
|
+
if self.widget_focus == index
|
171
|
+
self.widget_focus -= 1
|
172
|
+
Traverse.set_next_focus(screen)
|
151
173
|
|
152
|
-
|
153
|
-
|
154
|
-
o1 = @object[n1]
|
155
|
-
o2 = @object[n2]
|
156
|
-
self.setScreenIndex(n1, o2)
|
157
|
-
self.setScreenIndex(n2, o1)
|
158
|
-
|
159
|
-
if @object_focus == n1
|
160
|
-
@object_focus = n2
|
161
|
-
elsif @object_focus == n2
|
162
|
-
@object_focus = n1
|
174
|
+
elsif self.widget_focus > index
|
175
|
+
self.widget_focus -= 1
|
163
176
|
end
|
164
177
|
end
|
165
178
|
end
|
@@ -167,21 +180,21 @@ module RNDK
|
|
167
180
|
# Raises the Widget to the top of the screen.
|
168
181
|
# It will now overlap any other obstructing Widgets.
|
169
182
|
#
|
170
|
-
# `rndktype` states what RNDK Widget type this
|
171
|
-
# `
|
183
|
+
# `rndktype` states what RNDK Widget type this widget is.
|
184
|
+
# `widget` is a pointer to the Widget itself.
|
172
185
|
#
|
173
|
-
def self.raise_widget
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
186
|
+
def self.raise_widget widget
|
187
|
+
return unless widget.valid_type?
|
188
|
+
|
189
|
+
screen = widget.screen
|
190
|
+
screen.swap_indexes(widget.screen_index, screen.widget_count - 1)
|
178
191
|
end
|
179
192
|
|
180
193
|
# Has the opposite effect of #raise_widget.
|
181
|
-
def self.lower_widget
|
182
|
-
|
183
|
-
|
184
|
-
|
194
|
+
def self.lower_widget widget
|
195
|
+
return unless widget.valid_type?
|
196
|
+
|
197
|
+
widget.screen.swap_indexes(widget.screen_index, 0)
|
185
198
|
end
|
186
199
|
|
187
200
|
# Redraws all Widgets inside this Screen.
|
@@ -196,12 +209,12 @@ module RNDK
|
|
196
209
|
|
197
210
|
RNDK.window_refresh(@window)
|
198
211
|
|
199
|
-
# We erase all the invisible
|
200
|
-
# that the
|
212
|
+
# We erase all the invisible widgets, then only draw it all back, so
|
213
|
+
# that the widgets can overlap, and the visible ones will always be
|
201
214
|
# drawn after all the invisible ones are erased
|
202
|
-
(0...@
|
203
|
-
obj = @
|
204
|
-
if obj.
|
215
|
+
(0...@widget_count).each do |x|
|
216
|
+
obj = @widget[x]
|
217
|
+
if obj.valid_type?
|
205
218
|
if obj.is_visible
|
206
219
|
if visible < 0
|
207
220
|
visible = x
|
@@ -215,14 +228,14 @@ module RNDK
|
|
215
228
|
end
|
216
229
|
end
|
217
230
|
|
218
|
-
(0...@
|
219
|
-
obj = @
|
231
|
+
(0...@widget_count).each do |x|
|
232
|
+
obj = @widget[x]
|
220
233
|
|
221
|
-
if obj.
|
234
|
+
if obj.valid_type?
|
222
235
|
obj.has_focus = (x == focused)
|
223
236
|
|
224
237
|
if obj.is_visible
|
225
|
-
obj.draw
|
238
|
+
obj.draw
|
226
239
|
end
|
227
240
|
end
|
228
241
|
end
|
@@ -234,28 +247,29 @@ module RNDK
|
|
234
247
|
# characters on the terminal screen.
|
235
248
|
# This does NOT destroy any widgets.
|
236
249
|
def erase
|
237
|
-
(0...@
|
238
|
-
obj = @
|
239
|
-
obj.erase if obj.
|
250
|
+
(0...@widget_count).each do |x|
|
251
|
+
obj = @widget[x]
|
252
|
+
obj.erase if obj.valid_type?
|
240
253
|
end
|
241
254
|
Ncurses.wrefresh(@window)
|
242
255
|
end
|
243
256
|
|
244
257
|
# Destroys all the Widgets inside this Screen.
|
245
258
|
def destroy_widgets
|
246
|
-
(0...@
|
247
|
-
obj = @
|
248
|
-
before = @
|
259
|
+
(0...@widget_count).each do |x|
|
260
|
+
obj = @widget[x]
|
261
|
+
before = @widget_count
|
249
262
|
|
250
|
-
if obj.
|
263
|
+
if obj.valid_type?
|
251
264
|
obj.erase
|
252
265
|
obj.destroy
|
253
|
-
x -= (@
|
266
|
+
x -= (@widget_count - before)
|
254
267
|
end
|
255
268
|
end
|
256
269
|
end
|
257
270
|
|
258
271
|
# Destroys this Screen.
|
272
|
+
#
|
259
273
|
# @note It does nothing to the widgets inside it.
|
260
274
|
# You must either destroy them separatedly
|
261
275
|
# or call #destroy_widgets before.
|
@@ -263,6 +277,35 @@ module RNDK
|
|
263
277
|
RNDK::ALL_SCREENS.delete self
|
264
278
|
end
|
265
279
|
|
280
|
+
protected
|
281
|
+
|
282
|
+
def set_screen_index(number, obj)
|
283
|
+
obj.screen_index = number
|
284
|
+
obj.screen = self
|
285
|
+
@widget[number] = obj
|
286
|
+
end
|
287
|
+
|
288
|
+
def valid_index? n
|
289
|
+
(n >= 0) and (n < @widget_count)
|
290
|
+
end
|
291
|
+
|
292
|
+
# Swap positions of widgets with indexes `n1` and `n2`.
|
293
|
+
def swap_indexes(n1, n2)
|
294
|
+
return unless (n1 != n2) and (self.valid_index? n1) and (self.valid_index? n2)
|
295
|
+
|
296
|
+
o1 = @widget[n1]
|
297
|
+
o2 = @widget[n2]
|
298
|
+
self.set_screen_index(n1, o2)
|
299
|
+
self.set_screen_index(n2, o1)
|
300
|
+
|
301
|
+
if @widget_focus == n1
|
302
|
+
@widget_focus = n2
|
303
|
+
|
304
|
+
elsif @widget_focus == n2
|
305
|
+
@widget_focus = n1
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
266
309
|
end
|
267
310
|
end
|
268
311
|
|
data/lib/rndk/core/traverse.rb
CHANGED
@@ -1,43 +1,128 @@
|
|
1
1
|
module RNDK
|
2
|
+
|
3
|
+
#
|
4
|
+
#
|
2
5
|
module Traverse
|
3
|
-
|
4
|
-
|
6
|
+
|
7
|
+
# Traverse the screen just one time.
|
8
|
+
def Traverse.once(screen,
|
9
|
+
curobj,
|
10
|
+
key_code,
|
11
|
+
function_key,
|
12
|
+
func_menu_key)
|
13
|
+
|
14
|
+
case key_code
|
15
|
+
when Ncurses::KEY_BTAB
|
16
|
+
switch_focus(set_previous_focus(screen), curobj)
|
17
|
+
|
18
|
+
when RNDK::KEY_TAB
|
19
|
+
switch_focus(set_next_focus(screen), curobj)
|
20
|
+
|
21
|
+
when RNDK.KEY_F(10)
|
22
|
+
# save data and exit
|
23
|
+
exit_ok(screen)
|
24
|
+
|
25
|
+
when RNDK.CTRL('X')
|
26
|
+
exit_cancel screen
|
27
|
+
|
28
|
+
when RNDK.CTRL('R')
|
29
|
+
# reset data to defaults
|
30
|
+
reset(screen)
|
31
|
+
set_focus(curobj)
|
32
|
+
|
33
|
+
when RNDK::REFRESH
|
34
|
+
# redraw screen
|
35
|
+
screen.refresh
|
36
|
+
set_focus(curobj)
|
37
|
+
|
38
|
+
else
|
39
|
+
# not everyone wants menus, so we make them optional here
|
40
|
+
if !(func_menu_key.nil?) &&
|
41
|
+
(func_menu_key.call(key_code, function_key))
|
42
|
+
# find and enable drop down menu
|
43
|
+
screen.widget.each do |widget|
|
44
|
+
if !(widget.nil?) && widget.widget_type == :MENU
|
45
|
+
Traverse.handleMenu(screen, widget, curobj)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
else
|
50
|
+
curobj.inject(key_code)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Traverse continuously the widgets on a screen.
|
56
|
+
def Traverse.over screen
|
57
|
+
result = 0
|
58
|
+
curobj = set_first_focus(screen)
|
59
|
+
|
60
|
+
unless curobj.nil?
|
61
|
+
refresh_data(screen)
|
62
|
+
|
63
|
+
screen.exit_status = RNDK::Screen::NOEXIT
|
64
|
+
|
65
|
+
while !((curobj = get_current_focus(screen)).nil?) &&
|
66
|
+
screen.exit_status == RNDK::Screen::NOEXIT
|
67
|
+
function = []
|
68
|
+
key = curobj.getch(function)
|
69
|
+
|
70
|
+
# TODO look at more direct way to do this
|
71
|
+
check_menu_key = lambda do |key_code, function_key|
|
72
|
+
Traverse.checkMenuKey(key_code, function_key)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
Traverse.once(screen, curobj, key,
|
77
|
+
function[0], check_menu_key)
|
78
|
+
end
|
79
|
+
|
80
|
+
if screen.exit_status == RNDK::Screen::EXITOK
|
81
|
+
save_data(screen)
|
82
|
+
result = 1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
return result
|
86
|
+
end
|
87
|
+
|
88
|
+
def Traverse.reset screen
|
89
|
+
refresh_data(screen)
|
5
90
|
end
|
6
91
|
|
7
|
-
def Traverse.
|
92
|
+
def Traverse.exit_ok screen
|
8
93
|
screen.exit_status = RNDK::Screen::EXITOK
|
9
94
|
end
|
10
95
|
|
11
|
-
def Traverse.
|
96
|
+
def Traverse.exit_cancel screen
|
12
97
|
screen.exit_status = RNDK::Screen::EXITCANCEL
|
13
98
|
end
|
14
99
|
|
15
|
-
def Traverse.
|
16
|
-
|
100
|
+
def Traverse.exit_ok_of(obj)
|
101
|
+
exit_ok obj.screen
|
17
102
|
end
|
18
103
|
|
19
|
-
def Traverse.
|
20
|
-
|
104
|
+
def Traverse.exit_cancel_of(obj)
|
105
|
+
exit_cancel obj.screen
|
21
106
|
end
|
22
107
|
|
23
|
-
def Traverse.
|
24
|
-
|
108
|
+
def Traverse.reset_of(obj)
|
109
|
+
reset(obj.screen)
|
25
110
|
end
|
26
111
|
|
27
|
-
# Returns the
|
28
|
-
def Traverse.
|
112
|
+
# Returns the widget on which the focus lies.
|
113
|
+
def Traverse.get_current_focus(screen)
|
29
114
|
result = nil
|
30
|
-
n = screen.
|
115
|
+
n = screen.widget_focus
|
31
116
|
|
32
|
-
if n >= 0 && n < screen.
|
33
|
-
result = screen.
|
117
|
+
if n >= 0 && n < screen.widget_count
|
118
|
+
result = screen.widget[n]
|
34
119
|
end
|
35
120
|
|
36
121
|
return result
|
37
122
|
end
|
38
123
|
|
39
|
-
# Set focus to the next
|
40
|
-
def Traverse.
|
124
|
+
# Set focus to the next widget, returning it.
|
125
|
+
def Traverse.set_next_focus(screen)
|
41
126
|
result = nil
|
42
127
|
curobj = nil
|
43
128
|
n = getFocusIndex(screen)
|
@@ -45,10 +130,10 @@ module RNDK
|
|
45
130
|
|
46
131
|
while true
|
47
132
|
n+= 1
|
48
|
-
if n >= screen.
|
133
|
+
if n >= screen.widget_count
|
49
134
|
n = 0
|
50
135
|
end
|
51
|
-
curobj = screen.
|
136
|
+
curobj = screen.widget[n]
|
52
137
|
if !(curobj.nil?) && curobj.accepts_focus
|
53
138
|
result = curobj
|
54
139
|
break
|
@@ -59,12 +144,12 @@ module RNDK
|
|
59
144
|
end
|
60
145
|
end
|
61
146
|
|
62
|
-
|
147
|
+
set_focusIndex(screen, if !(result.nil?) then n else -1 end)
|
63
148
|
return result
|
64
149
|
end
|
65
150
|
|
66
|
-
# Set focus to the previous
|
67
|
-
def Traverse.
|
151
|
+
# Set focus to the previous widget, returning it.
|
152
|
+
def Traverse.set_previous_focus(screen)
|
68
153
|
result = nil
|
69
154
|
curobj = nil
|
70
155
|
n = getFocusIndex(screen)
|
@@ -73,9 +158,9 @@ module RNDK
|
|
73
158
|
while true
|
74
159
|
n -= 1
|
75
160
|
if n < 0
|
76
|
-
n = screen.
|
161
|
+
n = screen.widget_count - 1
|
77
162
|
end
|
78
|
-
curobj = screen.
|
163
|
+
curobj = screen.widget[n]
|
79
164
|
if !(curobj.nil?) && curobj.accepts_focus
|
80
165
|
result = curobj
|
81
166
|
break
|
@@ -84,13 +169,13 @@ module RNDK
|
|
84
169
|
end
|
85
170
|
end
|
86
171
|
|
87
|
-
|
172
|
+
set_focusIndex(screen, if !(result.nil?) then n else -1 end)
|
88
173
|
return result
|
89
174
|
end
|
90
175
|
|
91
|
-
# Set focus to a specific
|
92
|
-
# If the
|
93
|
-
def Traverse.
|
176
|
+
# Set focus to a specific widget, returning it.
|
177
|
+
# If the widget cannot be found, return nil.
|
178
|
+
def Traverse.set_current_focus(screen, newobj)
|
94
179
|
result = nil
|
95
180
|
curobj = nil
|
96
181
|
n = getFocusIndex(screen)
|
@@ -98,11 +183,11 @@ module RNDK
|
|
98
183
|
|
99
184
|
while true
|
100
185
|
n += 1
|
101
|
-
if n >= screen.
|
186
|
+
if n >= screen.widget_count
|
102
187
|
n = 0
|
103
188
|
end
|
104
189
|
|
105
|
-
curobj = screen.
|
190
|
+
curobj = screen.widget[n]
|
106
191
|
if curobj == newobj
|
107
192
|
result = curobj
|
108
193
|
break
|
@@ -111,95 +196,26 @@ module RNDK
|
|
111
196
|
end
|
112
197
|
end
|
113
198
|
|
114
|
-
|
199
|
+
set_focusIndex(screen, if !(result.nil?) then n else -1 end)
|
115
200
|
return result
|
116
201
|
end
|
117
202
|
|
118
|
-
# Set focus to the first
|
119
|
-
def Traverse.
|
120
|
-
|
121
|
-
return
|
203
|
+
# Set focus to the first widget in the screen.
|
204
|
+
def Traverse.set_first_focus(screen)
|
205
|
+
set_focusIndex(screen, screen.widget_count - 1)
|
206
|
+
return switch_focus(set_next_focus(screen), nil)
|
122
207
|
end
|
123
208
|
|
124
|
-
# Set focus to the last
|
125
|
-
def Traverse.
|
126
|
-
|
127
|
-
return
|
128
|
-
end
|
129
|
-
|
130
|
-
def Traverse.traverseRNDKOnce(screen, curobj, key_code,
|
131
|
-
function_key, func_menu_key)
|
132
|
-
case key_code
|
133
|
-
when Ncurses::KEY_BTAB
|
134
|
-
switchFocus(setRNDKFocusPrevious(screen), curobj)
|
135
|
-
when RNDK::KEY_TAB
|
136
|
-
switchFocus(setRNDKFocusNext(screen), curobj)
|
137
|
-
when RNDK.KEY_F(10)
|
138
|
-
# save data and exit
|
139
|
-
exitOKRNDKScreen(screen)
|
140
|
-
when RNDK.CTRL('X')
|
141
|
-
exitCancelRNDKScreen(screen)
|
142
|
-
when RNDK.CTRL('R')
|
143
|
-
# reset data to defaults
|
144
|
-
resetRNDKScreen(screen)
|
145
|
-
setFocus(curobj)
|
146
|
-
when RNDK::REFRESH
|
147
|
-
# redraw screen
|
148
|
-
screen.refresh
|
149
|
-
setFocus(curobj)
|
150
|
-
else
|
151
|
-
# not everyone wants menus, so we make them optional here
|
152
|
-
if !(func_menu_key.nil?) &&
|
153
|
-
(func_menu_key.call(key_code, function_key))
|
154
|
-
# find and enable drop down menu
|
155
|
-
screen.object.each do |object|
|
156
|
-
if !(object.nil?) && object.object_type == :MENU
|
157
|
-
Traverse.handleMenu(screen, object, curobj)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
else
|
161
|
-
curobj.inject(key_code)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
# Traverse the widgets on a screen.
|
167
|
-
def Traverse.traverseRNDKScreen(screen)
|
168
|
-
result = 0
|
169
|
-
curobj = setRNDKFocusFirst(screen)
|
170
|
-
|
171
|
-
unless curobj.nil?
|
172
|
-
refreshDataRNDKScreen(screen)
|
173
|
-
|
174
|
-
screen.exit_status = RNDK::Screen::NOEXIT
|
175
|
-
|
176
|
-
while !((curobj = getRNDKFocusCurrent(screen)).nil?) &&
|
177
|
-
screen.exit_status == RNDK::Screen::NOEXIT
|
178
|
-
function = []
|
179
|
-
key = curobj.getch(function)
|
180
|
-
|
181
|
-
# TODO look at more direct way to do this
|
182
|
-
check_menu_key = lambda do |key_code, function_key|
|
183
|
-
Traverse.checkMenuKey(key_code, function_key)
|
184
|
-
end
|
185
|
-
|
186
|
-
|
187
|
-
Traverse.traverseRNDKOnce(screen, curobj, key,
|
188
|
-
function[0], check_menu_key)
|
189
|
-
end
|
190
|
-
|
191
|
-
if screen.exit_status == RNDK::Screen::EXITOK
|
192
|
-
saveDataRNDKScreen(screen)
|
193
|
-
result = 1
|
194
|
-
end
|
195
|
-
end
|
196
|
-
return result
|
209
|
+
# Set focus to the last widget in the screen.
|
210
|
+
def Traverse.set_last_focus(screen)
|
211
|
+
set_focusIndex(screen, 0)
|
212
|
+
return switch_focus(set_previous_focus(screen), nil)
|
197
213
|
end
|
198
214
|
|
199
215
|
private
|
200
216
|
|
201
217
|
def Traverse.limitFocusIndex(screen, value)
|
202
|
-
if value >= screen.
|
218
|
+
if value >= screen.widget_count || value < 0
|
203
219
|
0
|
204
220
|
else
|
205
221
|
value
|
@@ -207,33 +223,33 @@ module RNDK
|
|
207
223
|
end
|
208
224
|
|
209
225
|
def Traverse.getFocusIndex(screen)
|
210
|
-
return limitFocusIndex(screen, screen.
|
226
|
+
return limitFocusIndex(screen, screen.widget_focus)
|
211
227
|
end
|
212
228
|
|
213
|
-
def Traverse.
|
214
|
-
screen.
|
229
|
+
def Traverse.set_focusIndex(screen, value)
|
230
|
+
screen.widget_focus = limitFocusIndex(screen, value)
|
215
231
|
end
|
216
232
|
|
217
|
-
def Traverse.
|
218
|
-
|
233
|
+
def Traverse.unset_focus(obj)
|
234
|
+
RNDK::blink_cursor false
|
219
235
|
unless obj.nil?
|
220
236
|
obj.has_focus = false
|
221
237
|
obj.unfocus
|
222
238
|
end
|
223
239
|
end
|
224
240
|
|
225
|
-
def Traverse.
|
241
|
+
def Traverse.set_focus(obj)
|
226
242
|
unless obj.nil?
|
227
243
|
obj.has_focus = true
|
228
244
|
obj.focus
|
229
245
|
end
|
230
|
-
|
246
|
+
RNDK::blink_cursor true
|
231
247
|
end
|
232
248
|
|
233
|
-
def Traverse.
|
249
|
+
def Traverse.switch_focus(newobj, oldobj)
|
234
250
|
if oldobj != newobj
|
235
|
-
Traverse.
|
236
|
-
Traverse.
|
251
|
+
Traverse.unset_focus(oldobj)
|
252
|
+
Traverse.set_focus(newobj)
|
237
253
|
end
|
238
254
|
return newobj
|
239
255
|
end
|
@@ -245,9 +261,9 @@ module RNDK
|
|
245
261
|
def Traverse.handleMenu(screen, menu, oldobj)
|
246
262
|
done = false
|
247
263
|
|
248
|
-
|
264
|
+
switch_focus(menu, oldobj)
|
249
265
|
while !done
|
250
|
-
key = menu.getch
|
266
|
+
key = menu.getch
|
251
267
|
|
252
268
|
case key
|
253
269
|
when RNDK::KEY_TAB
|
@@ -261,29 +277,27 @@ module RNDK
|
|
261
277
|
end
|
262
278
|
end
|
263
279
|
|
264
|
-
if (newobj = Traverse.
|
265
|
-
newobj = Traverse.
|
280
|
+
if (newobj = Traverse.get_current_focus(screen)).nil?
|
281
|
+
newobj = Traverse.set_next_focus(screen)
|
266
282
|
end
|
267
283
|
|
268
|
-
return
|
284
|
+
return switch_focus(newobj, menu)
|
269
285
|
end
|
270
286
|
|
271
|
-
#
|
272
|
-
def Traverse.
|
273
|
-
screen.
|
274
|
-
unless
|
275
|
-
object.saveData
|
276
|
-
end
|
287
|
+
# Calls Widget#save_data on all widgets of `screen`.
|
288
|
+
def Traverse.save_data screen
|
289
|
+
screen.widget.each do |widget|
|
290
|
+
widget.save_data unless widget.nil?
|
277
291
|
end
|
278
292
|
end
|
279
293
|
|
280
|
-
#
|
281
|
-
def Traverse.
|
282
|
-
screen.
|
283
|
-
unless
|
284
|
-
object.refreshData
|
285
|
-
end
|
294
|
+
# Calls Widget#refresh_data on all widgets of `screen`.
|
295
|
+
def Traverse.refresh_data screen
|
296
|
+
screen.widget.each do |widget|
|
297
|
+
widget.refresh_data unless widget.nil?
|
286
298
|
end
|
287
299
|
end
|
300
|
+
|
288
301
|
end
|
289
302
|
end
|
303
|
+
|