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