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/scale.rb
CHANGED
@@ -1,27 +1,51 @@
|
|
1
1
|
require 'rndk'
|
2
2
|
|
3
3
|
module RNDK
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
|
5
|
+
class Scale < Widget
|
6
|
+
|
7
|
+
def initialize(screen, config={})
|
7
8
|
super()
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
@widget_type = :scale
|
10
|
+
@supported_signals += [:before_input, :after_input]
|
11
|
+
|
12
|
+
x = 0
|
13
|
+
y = 0
|
14
|
+
title = "scale"
|
15
|
+
label = "label"
|
16
|
+
field_color = RNDK::Color[:normal]
|
17
|
+
field_width = 0
|
18
|
+
start = 0
|
19
|
+
low = 0
|
20
|
+
high = 100
|
21
|
+
inc = 1
|
22
|
+
fast_increment = 5
|
23
|
+
box = true
|
24
|
+
shadow = false
|
25
|
+
|
26
|
+
config.each do |key, val|
|
27
|
+
x = val if key == :x
|
28
|
+
y = val if key == :y
|
29
|
+
title = val if key == :title
|
30
|
+
label = val if key == :label
|
31
|
+
field_color = val if key == :field_color
|
32
|
+
field_width = val if key == :field_width
|
33
|
+
start = val if key == :start
|
34
|
+
low = val if key == :low
|
35
|
+
high = val if key == :high
|
36
|
+
inc = val if key == :inc
|
37
|
+
fast_increment = val if key == :fast_increment
|
38
|
+
box = val if key == :box
|
39
|
+
shadow = val if key == :shadow
|
40
|
+
end
|
41
|
+
|
42
|
+
parent_width = Ncurses.getmaxx screen.window
|
43
|
+
parent_height = Ncurses.getmaxy screen.window
|
22
44
|
|
45
|
+
self.set_box box
|
46
|
+
|
47
|
+
box_width = field_width + 2 * @border_size
|
23
48
|
box_height = @border_size * 2 + 1
|
24
|
-
box_width = field_width + 2 * @border_size
|
25
49
|
|
26
50
|
# Set some basic values of the widget's data field.
|
27
51
|
@label = []
|
@@ -31,7 +55,9 @@ module RNDK
|
|
31
55
|
# If the field_width is a negative value, the field_width will
|
32
56
|
# be COLS-field_width, otherwise the field_width will be the
|
33
57
|
# given width.
|
34
|
-
field_width = RNDK.
|
58
|
+
field_width = RNDK.set_widget_dimension(parent_width,
|
59
|
+
field_width,
|
60
|
+
0)
|
35
61
|
box_width = field_width + 2 * @border_size
|
36
62
|
|
37
63
|
# Translate the label string to a chtype array
|
@@ -55,9 +81,9 @@ module RNDK
|
|
55
81
|
box_width - @label_len - 2 * @border_size].min
|
56
82
|
|
57
83
|
# Rejustify the x and y positions if we need to.
|
58
|
-
xtmp = [
|
59
|
-
ytmp = [
|
60
|
-
RNDK.alignxy(
|
84
|
+
xtmp = [x]
|
85
|
+
ytmp = [y]
|
86
|
+
RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
|
61
87
|
xpos = xtmp[0]
|
62
88
|
ypos = ytmp[0]
|
63
89
|
|
@@ -98,19 +124,19 @@ module RNDK
|
|
98
124
|
Ncurses.keypad(@win, true)
|
99
125
|
|
100
126
|
# Create the widget's data field.
|
101
|
-
@screen =
|
102
|
-
@parent =
|
127
|
+
@screen = screen
|
128
|
+
@parent = screen.window
|
103
129
|
@shadow_win = nil
|
104
130
|
@box_width = box_width
|
105
131
|
@box_height = box_height
|
106
132
|
@field_width = field_width
|
107
|
-
@
|
133
|
+
@field_color = field_color
|
108
134
|
@current = low
|
109
135
|
@low = low
|
110
136
|
@high = high
|
111
137
|
@current = start
|
112
138
|
@inc = inc
|
113
|
-
@fastinc =
|
139
|
+
@fastinc = fast_increment
|
114
140
|
@accepts_focus = true
|
115
141
|
@input_window = @win
|
116
142
|
@shadow = shadow
|
@@ -129,59 +155,60 @@ module RNDK
|
|
129
155
|
end
|
130
156
|
|
131
157
|
# Setup the key bindings.
|
132
|
-
bindings.each do |from, to|
|
133
|
-
self.bind(self.object_type, from, :getc, to)
|
134
|
-
end
|
135
158
|
|
136
|
-
|
159
|
+
self.bind_key('u') { self.increment @inc }
|
160
|
+
self.bind_key('U') { self.increment @fastinc }
|
161
|
+
self.bind_key('g') { @current = @low }
|
162
|
+
self.bind_key('^') { @current = @low }
|
163
|
+
self.bind_key('G') { @current = @high }
|
164
|
+
self.bind_key('$') { @current = @high }
|
165
|
+
|
166
|
+
screen.register(self.widget_type, self)
|
137
167
|
end
|
138
168
|
|
139
169
|
# This allows the person to use the widget's data field.
|
140
|
-
def activate(actions)
|
141
|
-
ret =
|
142
|
-
|
143
|
-
self.draw
|
170
|
+
def activate(actions=[])
|
171
|
+
ret = false
|
172
|
+
|
173
|
+
self.draw
|
144
174
|
|
145
175
|
if actions.nil? || actions.size == 0
|
146
176
|
input = 0
|
147
177
|
while true
|
148
|
-
input = self.getch
|
178
|
+
input = self.getch
|
149
179
|
|
150
180
|
# Inject the character into the widget.
|
151
181
|
ret = self.inject(input)
|
152
|
-
|
153
|
-
|
154
|
-
end
|
182
|
+
|
183
|
+
return ret if @exit_type != :EARLY_EXIT
|
155
184
|
end
|
156
185
|
else
|
157
186
|
# Inject each character one at a time.
|
158
187
|
actions.each do |action|
|
159
188
|
ret = self.inject(action)
|
160
189
|
end
|
161
|
-
|
162
|
-
|
163
|
-
end
|
190
|
+
|
191
|
+
return ret if @exit_type != :EARLY_EXIT
|
164
192
|
end
|
165
193
|
|
166
194
|
# Set the exit type and return.
|
167
195
|
self.set_exit_type(0)
|
168
|
-
|
196
|
+
ret
|
169
197
|
end
|
170
198
|
|
171
199
|
# Check if the value lies outsid the low/high range. If so, force it in.
|
172
200
|
def limitCurrentValue
|
173
201
|
if @current < @low
|
174
202
|
@current = @low
|
175
|
-
RNDK.beep
|
176
203
|
elsif @current > @high
|
177
204
|
@current = @high
|
178
|
-
RNDK.beep
|
179
205
|
end
|
206
|
+
RNDK.beep
|
180
207
|
end
|
181
208
|
|
182
209
|
# Move the cursor to the given edit-position
|
183
210
|
def moveToEditPosition(new_position)
|
184
|
-
|
211
|
+
Ncurses.wmove(@field_win, 0, @field_width - new_position - 1)
|
185
212
|
end
|
186
213
|
|
187
214
|
# Check if the cursor is on a valid edit-position. This must be one of
|
@@ -254,10 +281,10 @@ module RNDK
|
|
254
281
|
temp[col] = input.chr
|
255
282
|
elsif input == Ncurses::KEY_BACKSPACE
|
256
283
|
# delete the char before the cursor
|
257
|
-
modify =
|
284
|
+
modify = Scale.removeChar(temp, col - 1)
|
258
285
|
elsif input == Ncurses::KEY_DC
|
259
286
|
# delete the char at the cursor
|
260
|
-
modify =
|
287
|
+
modify = Scale.removeChar(temp, col)
|
261
288
|
else
|
262
289
|
modify = false
|
263
290
|
end
|
@@ -272,64 +299,51 @@ module RNDK
|
|
272
299
|
return result
|
273
300
|
end
|
274
301
|
|
275
|
-
def
|
276
|
-
if
|
277
|
-
value - by
|
278
|
-
else
|
279
|
-
value
|
280
|
-
end
|
302
|
+
def decrement by
|
303
|
+
@current = @current - by if (@current - by) < @current
|
281
304
|
end
|
282
305
|
|
283
|
-
def
|
284
|
-
if
|
285
|
-
value + by
|
286
|
-
else
|
287
|
-
value
|
288
|
-
end
|
306
|
+
def increment by
|
307
|
+
@current = @current + by if (@current + by) > @current
|
289
308
|
end
|
290
309
|
|
291
310
|
# This function injects a single character into the widget.
|
292
|
-
def inject
|
293
|
-
pp_return =
|
294
|
-
ret =
|
311
|
+
def inject input
|
312
|
+
pp_return = true
|
313
|
+
ret = false
|
295
314
|
complete = false
|
296
315
|
|
297
316
|
# Set the exit type.
|
298
317
|
self.set_exit_type(0)
|
299
318
|
|
300
319
|
# Draw the field.
|
301
|
-
self.
|
320
|
+
self.draw_field
|
302
321
|
|
303
322
|
# Check if there is a pre-process function to be called.
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
@pre_process_data, input)
|
308
|
-
end
|
323
|
+
keep_going = self.run_signal_binding(:before_input, input)
|
324
|
+
|
325
|
+
if keep_going
|
309
326
|
|
310
|
-
# Should we continue?
|
311
|
-
if pp_return != 0
|
312
327
|
# Check for a key bindings.
|
313
|
-
if self.
|
314
|
-
|
328
|
+
if self.is_bound? input
|
329
|
+
self.run_key_binding input
|
330
|
+
#complete = true
|
331
|
+
|
315
332
|
else
|
316
333
|
case input
|
317
334
|
when Ncurses::KEY_LEFT
|
318
335
|
self.setEditPosition(@field_edit + 1)
|
319
336
|
when Ncurses::KEY_RIGHT
|
320
337
|
self.setEditPosition(@field_edit - 1)
|
321
|
-
|
322
|
-
|
323
|
-
when Ncurses::KEY_UP
|
324
|
-
|
325
|
-
when Ncurses::
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
@current = @low
|
331
|
-
when Ncurses::KEY_END
|
332
|
-
@current = @high
|
338
|
+
|
339
|
+
when Ncurses::KEY_DOWN then self.decrement @inc
|
340
|
+
when Ncurses::KEY_UP then self.increment @inc
|
341
|
+
when Ncurses::KEY_HOME then @current = @low
|
342
|
+
when Ncurses::KEY_END then @current = @high
|
343
|
+
when Ncurses::KEY_PPAGE, RNDK::BACKCHAR
|
344
|
+
self.increment @fastinc
|
345
|
+
when Ncurses::KEY_NPAGE, RNDK::FORCHAR
|
346
|
+
self.decrement @fastinc
|
333
347
|
when RNDK::KEY_TAB, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
|
334
348
|
self.set_exit_type(input)
|
335
349
|
ret = @current
|
@@ -368,16 +382,12 @@ module RNDK
|
|
368
382
|
end
|
369
383
|
self.limitCurrentValue
|
370
384
|
|
371
|
-
|
372
|
-
if !complete && !(@post_process_func).nil?
|
373
|
-
@post_process_func.call(self.object_type, self,
|
374
|
-
@post_process_data, input)
|
375
|
-
end
|
385
|
+
self.run_signal_binding(:after_input) if not complete
|
376
386
|
end
|
377
387
|
|
378
|
-
if
|
379
|
-
self.
|
380
|
-
self.set_exit_type
|
388
|
+
if not complete
|
389
|
+
self.draw_field
|
390
|
+
self.set_exit_type 0
|
381
391
|
end
|
382
392
|
|
383
393
|
@result_data = ret
|
@@ -385,25 +395,19 @@ module RNDK
|
|
385
395
|
end
|
386
396
|
|
387
397
|
# This moves the widget's data field to the given location.
|
388
|
-
def move(
|
398
|
+
def move(x, y, relative, refresh_flag)
|
389
399
|
windows = [@win, @label_win, @field_win, @shadow_win]
|
390
400
|
|
391
|
-
self.move_specific(
|
401
|
+
self.move_specific(x, y, relative, refresh_flag, windows, [])
|
392
402
|
end
|
393
403
|
|
394
404
|
# This function draws the widget.
|
395
|
-
def draw
|
396
|
-
|
397
|
-
unless @shadow_win.nil?
|
398
|
-
Draw.drawShadow(@shadow_win)
|
399
|
-
end
|
405
|
+
def draw
|
406
|
+
Draw.drawShadow(@shadow_win) unless @shadow_win.nil?
|
400
407
|
|
401
|
-
|
402
|
-
if box
|
403
|
-
Draw.drawObjBox(@win, self)
|
404
|
-
end
|
408
|
+
Draw.drawObjBox(@win, self) if @box
|
405
409
|
|
406
|
-
self.
|
410
|
+
self.draw_title @win
|
407
411
|
|
408
412
|
# Draw the label.
|
409
413
|
unless @label_win.nil?
|
@@ -413,16 +417,16 @@ module RNDK
|
|
413
417
|
@label, RNDK::HORIZONTAL,
|
414
418
|
0,
|
415
419
|
@label_len)
|
416
|
-
Ncurses.wrefresh
|
420
|
+
Ncurses.wrefresh @label_win
|
417
421
|
end
|
418
422
|
Ncurses.wrefresh @win
|
419
423
|
|
420
424
|
# Draw the field window.
|
421
|
-
self.
|
425
|
+
self.draw_field
|
422
426
|
end
|
423
427
|
|
424
428
|
# This draws the widget.
|
425
|
-
def
|
429
|
+
def draw_field
|
426
430
|
Ncurses.werase(@field_win)
|
427
431
|
|
428
432
|
# Draw the value in the field.
|
@@ -431,7 +435,7 @@ module RNDK
|
|
431
435
|
@field_width - temp.size - 1,
|
432
436
|
0,
|
433
437
|
temp,
|
434
|
-
@
|
438
|
+
@field_color,
|
435
439
|
RNDK::HORIZONTAL,
|
436
440
|
0,
|
437
441
|
temp.size)
|
@@ -441,7 +445,7 @@ module RNDK
|
|
441
445
|
end
|
442
446
|
|
443
447
|
# This sets the background attribute of teh widget.
|
444
|
-
def
|
448
|
+
def set_bg_color attrib
|
445
449
|
Ncurses.wbkgd(@win, attrib)
|
446
450
|
Ncurses.wbkgd(@field_win, attrib)
|
447
451
|
Ncurses.wbkgd(@label_win, attrib) unless @label_win.nil?
|
@@ -449,7 +453,7 @@ module RNDK
|
|
449
453
|
|
450
454
|
# This function destroys the widget.
|
451
455
|
def destroy
|
452
|
-
self.
|
456
|
+
self.clean_title
|
453
457
|
@label = []
|
454
458
|
|
455
459
|
# Clean up the windows.
|
@@ -459,15 +463,15 @@ module RNDK
|
|
459
463
|
RNDK.window_delete @win
|
460
464
|
|
461
465
|
# Clean the key bindings.
|
462
|
-
self.clean_bindings
|
466
|
+
self.clean_bindings
|
463
467
|
|
464
|
-
# Unregister this
|
465
|
-
|
468
|
+
# Unregister this widget
|
469
|
+
@screen.unregister(self.widget_type, self)
|
466
470
|
end
|
467
471
|
|
468
472
|
# This function erases the widget from the screen.
|
469
473
|
def erase
|
470
|
-
if self.
|
474
|
+
if self.valid?
|
471
475
|
RNDK.window_erase @label_win
|
472
476
|
RNDK.window_erase @field_win
|
473
477
|
RNDK.window_erase @win
|
@@ -478,12 +482,12 @@ module RNDK
|
|
478
482
|
# This function sets the low/high/current values of the widget.
|
479
483
|
def set(low, high, value, box)
|
480
484
|
self.setLowHigh(low, high)
|
481
|
-
self.setValue
|
482
|
-
self.set_box
|
485
|
+
self.setValue value
|
486
|
+
self.set_box box
|
483
487
|
end
|
484
488
|
|
485
489
|
# This sets the widget's value
|
486
|
-
def setValue
|
490
|
+
def setValue value
|
487
491
|
@current = value
|
488
492
|
self.limitCurrentValue
|
489
493
|
end
|
@@ -516,11 +520,11 @@ module RNDK
|
|
516
520
|
end
|
517
521
|
|
518
522
|
def focus
|
519
|
-
self.draw
|
523
|
+
self.draw
|
520
524
|
end
|
521
525
|
|
522
526
|
def unfocus
|
523
|
-
self.draw
|
527
|
+
self.draw
|
524
528
|
end
|
525
529
|
|
526
530
|
def position
|
@@ -531,8 +535,5 @@ module RNDK
|
|
531
535
|
'%d%c'
|
532
536
|
end
|
533
537
|
|
534
|
-
def object_type
|
535
|
-
:SCALE
|
536
|
-
end
|
537
538
|
end
|
538
539
|
end
|
data/lib/rndk/scroll.rb
CHANGED
@@ -2,27 +2,27 @@ require 'rndk/scroller'
|
|
2
2
|
|
3
3
|
module RNDK
|
4
4
|
|
5
|
-
# A scrolling
|
5
|
+
# A scrolling items of text.
|
6
6
|
#
|
7
7
|
# ## Keybindings
|
8
8
|
#
|
9
|
-
# Left Arrow:: Shift the
|
10
|
-
# Right Arrow:: Shift the
|
11
|
-
# Up Arrow:: Select the previous item in the
|
12
|
-
# Down Arrow:: Select the next item in the
|
9
|
+
# Left Arrow:: Shift the items left one column.
|
10
|
+
# Right Arrow:: Shift the items right one column.
|
11
|
+
# Up Arrow:: Select the previous item in the items.
|
12
|
+
# Down Arrow:: Select the next item in the items.
|
13
13
|
# Prev Page:: Scroll one page backward.
|
14
14
|
# Ctrl-B:: Scroll one page backward.
|
15
15
|
# Next Page:: Scroll one page forward.
|
16
16
|
# Ctrl-F:: Scroll one page forward.
|
17
|
-
# 1:: Move to the first element in the
|
18
|
-
# <:: Move to the first element in the
|
19
|
-
# g:: Move to the first element in the
|
20
|
-
# Home:: Move to the first element in the
|
21
|
-
# >:: Move to the last element in the
|
22
|
-
# G:: Move to the last element in the
|
23
|
-
# End:: Move to the last element in the
|
24
|
-
# $:: Shift the
|
25
|
-
# |:: Shift the
|
17
|
+
# 1:: Move to the first element in the items.
|
18
|
+
# <:: Move to the first element in the items.
|
19
|
+
# g:: Move to the first element in the items.
|
20
|
+
# Home:: Move to the first element in the items.
|
21
|
+
# >:: Move to the last element in the items.
|
22
|
+
# G:: Move to the last element in the items.
|
23
|
+
# End:: Move to the last element in the items.
|
24
|
+
# $:: Shift the items to the far right.
|
25
|
+
# |:: Shift the items to the far left.
|
26
26
|
# Return:: Exit the widget and return the index
|
27
27
|
# of the selected item. Also set the
|
28
28
|
# widget `exit_type` to `:NORMAL`.
|
@@ -33,16 +33,16 @@ module RNDK
|
|
33
33
|
# set the widget `exit_type` `:ESCAPE_HIT`.
|
34
34
|
# Ctrl-L:: Refreshes the screen.
|
35
35
|
#
|
36
|
-
class Scroll <
|
37
|
-
attr_reader :item, :
|
36
|
+
class Scroll < Scroller
|
37
|
+
attr_reader :item, :current_item, :highlight
|
38
38
|
|
39
39
|
# Creates a Scroll Widget.
|
40
40
|
#
|
41
|
-
# * `
|
41
|
+
# * `x` is the x position - can be an integer or
|
42
42
|
# `RNDK::LEFT`, `RNDK::RIGHT`, `RNDK::CENTER`.
|
43
|
-
# * `
|
43
|
+
# * `y` is the y position - can be an integer or
|
44
44
|
# `RNDK::TOP`, `RNDK::BOTTOM`, `RNDK::CENTER`.
|
45
|
-
# * `
|
45
|
+
# * `scroll_bar` is where the scrollbar will be placed.
|
46
46
|
# It can be only `RNDK::LEFT`, `RNDK::RIGHT` or
|
47
47
|
# `RNDK::NONE`, for no scrollbar.
|
48
48
|
# * `width`/`height` are integers - if either are 0, Widget
|
@@ -51,68 +51,76 @@ module RNDK
|
|
51
51
|
# minus the value.
|
52
52
|
# * `title` can be more than one line - just split them
|
53
53
|
# with `\n`s.
|
54
|
-
# * `
|
54
|
+
# * `items` is an Array of Strings to be shown on the Widget.
|
55
55
|
# * `numbers` is a flag to turn on/off line numbering at
|
56
|
-
# the front of the
|
56
|
+
# the front of the items items.
|
57
57
|
# * `highlight` is the attribute/color of the currently selected
|
58
|
-
# item at the
|
58
|
+
# item at the items.
|
59
59
|
# * `box` if the Widget is drawn with a box outside it.
|
60
60
|
# * `shadow` turns on/off the shadow around the Widget.
|
61
61
|
#
|
62
|
-
def initialize
|
63
|
-
xplace,
|
64
|
-
yplace,
|
65
|
-
splace,
|
66
|
-
width,
|
67
|
-
height,
|
68
|
-
title,
|
69
|
-
list,
|
70
|
-
numbers,
|
71
|
-
highlight,
|
72
|
-
box,
|
73
|
-
shadow)
|
62
|
+
def initialize(screen, config={})
|
74
63
|
super()
|
64
|
+
@widget_type = :scroll
|
65
|
+
@supported_signals += [:before_input,
|
66
|
+
:after_input,
|
67
|
+
:after_scrolling]
|
68
|
+
x = 0
|
69
|
+
y = 0
|
70
|
+
scroll_bar = RNDK::RIGHT
|
71
|
+
width = 0
|
72
|
+
height = 0
|
73
|
+
title = "scroll"
|
74
|
+
items = []
|
75
|
+
numbers = false
|
76
|
+
highlight = RNDK::Color[:reverse]
|
77
|
+
box = true
|
78
|
+
shadow = false
|
79
|
+
|
80
|
+
config.each do |key, val|
|
81
|
+
x = val if key == :x
|
82
|
+
y = val if key == :y
|
83
|
+
scroll_bar = val if key == :scroll_bar
|
84
|
+
width = val if key == :width
|
85
|
+
height = val if key == :height
|
86
|
+
title = val if key == :title
|
87
|
+
items = val if key == :items
|
88
|
+
numbers = val if key == :numbers
|
89
|
+
highlight = val if key == :highlight
|
90
|
+
box = val if key == :box
|
91
|
+
shadow = val if key == :shadow
|
92
|
+
end
|
75
93
|
|
76
|
-
parent_width = Ncurses.getmaxx
|
77
|
-
parent_height = Ncurses.getmaxy
|
94
|
+
parent_width = Ncurses.getmaxx screen.window
|
95
|
+
parent_height = Ncurses.getmaxy screen.window
|
78
96
|
|
79
97
|
box_width = width
|
80
98
|
box_height = height
|
81
99
|
|
82
|
-
xpos =
|
83
|
-
ypos =
|
100
|
+
xpos = x
|
101
|
+
ypos = y
|
84
102
|
|
85
103
|
scroll_adjust = 0
|
86
104
|
|
87
|
-
bindings = {
|
88
|
-
RNDK::BACKCHAR => Ncurses::KEY_PPAGE,
|
89
|
-
RNDK::FORCHAR => Ncurses::KEY_NPAGE,
|
90
|
-
'g' => Ncurses::KEY_HOME,
|
91
|
-
'1' => Ncurses::KEY_HOME,
|
92
|
-
'G' => Ncurses::KEY_END,
|
93
|
-
'<' => Ncurses::KEY_HOME,
|
94
|
-
'>' => Ncurses::KEY_END
|
95
|
-
}
|
96
|
-
|
97
105
|
self.set_box box
|
98
106
|
|
99
107
|
# If the height is a negative value, the height will be ROWS-height,
|
100
108
|
# otherwise the height will be the given height
|
101
|
-
box_height = RNDK.
|
109
|
+
box_height = RNDK.set_widget_dimension(parent_height, height, 0)
|
102
110
|
|
103
111
|
# If the width is a negative value, the width will be COLS-width,
|
104
112
|
# otherwise the width will be the given width
|
105
|
-
box_width = RNDK.
|
113
|
+
box_width = RNDK.set_widget_dimension(parent_width, width, 0)
|
106
114
|
|
107
115
|
box_width = self.set_title(title, box_width)
|
108
116
|
|
109
117
|
# Set the box height.
|
110
118
|
if @title_lines > box_height
|
111
|
-
box_height = @title_lines + [
|
119
|
+
box_height = @title_lines + [items.size, 8].min + 2 * @border_size
|
112
120
|
end
|
113
121
|
|
114
122
|
# Adjust the box width if there is a scroll bar
|
115
|
-
if
|
123
|
+
if scroll_bar == RNDK::LEFT || scroll_bar == RNDK::RIGHT
|
116
124
|
@scrollbar = true
|
117
125
|
box_width += 1
|
118
126
|
else
|
@@ -129,12 +137,12 @@ module RNDK
|
|
129
137
|
else box_height
|
130
138
|
end
|
131
139
|
|
132
|
-
self.
|
140
|
+
self.set_view_size(items.size)
|
133
141
|
|
134
142
|
# Rejustify the x and y positions if we need to.
|
135
143
|
xtmp = [xpos]
|
136
144
|
ytmp = [ypos]
|
137
|
-
RNDK.alignxy(
|
145
|
+
RNDK.alignxy(screen.window, xtmp, ytmp, @box_width, @box_height)
|
138
146
|
xpos = xtmp[0]
|
139
147
|
ypos = ytmp[0]
|
140
148
|
|
@@ -150,15 +158,15 @@ module RNDK
|
|
150
158
|
Ncurses.keypad(@win, true)
|
151
159
|
|
152
160
|
# Create the scrollbar window.
|
153
|
-
if
|
161
|
+
if scroll_bar == RNDK::RIGHT
|
154
162
|
@scrollbar_win = Ncurses.subwin(@win,
|
155
|
-
self.
|
163
|
+
self.max_view_size,
|
156
164
|
1,
|
157
165
|
self.Screen_YPOS(ypos),
|
158
166
|
xpos + box_width - @border_size - 1)
|
159
|
-
elsif
|
167
|
+
elsif scroll_bar == RNDK::LEFT
|
160
168
|
@scrollbar_win = Ncurses.subwin(@win,
|
161
|
-
self.
|
169
|
+
self.max_view_size,
|
162
170
|
1,
|
163
171
|
self.Screen_YPOS(ypos),
|
164
172
|
self.Screen_XPOS(xpos))
|
@@ -166,18 +174,18 @@ module RNDK
|
|
166
174
|
@scrollbar_win = nil
|
167
175
|
end
|
168
176
|
|
169
|
-
# create the
|
170
|
-
@
|
171
|
-
self.
|
177
|
+
# create the items window
|
178
|
+
@items_win = Ncurses.subwin(@win,
|
179
|
+
self.max_view_size,
|
172
180
|
box_width - (2 * @border_size) - scroll_adjust,
|
173
181
|
self.Screen_YPOS(ypos),
|
174
|
-
self.Screen_XPOS(xpos) + (if
|
182
|
+
self.Screen_XPOS(xpos) + (if scroll_bar == RNDK::LEFT then 1 else 0 end))
|
175
183
|
|
176
184
|
# Set the rest of the variables
|
177
|
-
@screen =
|
178
|
-
@parent =
|
185
|
+
@screen = screen
|
186
|
+
@parent = screen.window
|
179
187
|
@shadow_win = nil
|
180
|
-
@scrollbar_placement =
|
188
|
+
@scrollbar_placement = scroll_bar
|
181
189
|
@max_left_char = 0
|
182
190
|
@left_char = 0
|
183
191
|
@highlight = highlight
|
@@ -186,12 +194,10 @@ module RNDK
|
|
186
194
|
@input_window = @win
|
187
195
|
@shadow = shadow
|
188
196
|
|
189
|
-
self.
|
197
|
+
self.set_position(0);
|
190
198
|
|
191
|
-
# Create the scrolling
|
192
|
-
|
193
|
-
return nil
|
194
|
-
end
|
199
|
+
# Create the scrolling items item items and needed variables.
|
200
|
+
return nil unless self.create_item_list(numbers, items)
|
195
201
|
|
196
202
|
# Do we need to create a shadow?
|
197
203
|
if shadow
|
@@ -201,19 +207,15 @@ module RNDK
|
|
201
207
|
xpos + 1)
|
202
208
|
end
|
203
209
|
|
204
|
-
#
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
rndkscreen.register(:scroll, self);
|
211
|
-
|
212
|
-
return self
|
213
|
-
end
|
210
|
+
# Standard keybindings (plus the Arrow Keys)
|
211
|
+
self.bind_key('g') { self.scroll_begin }
|
212
|
+
self.bind_key('1') { self.scroll_begin }
|
213
|
+
self.bind_key('G') { self.scroll_end }
|
214
|
+
self.bind_key('<') { self.scroll_begin }
|
215
|
+
self.bind_key('>') { self.scroll_end }
|
214
216
|
|
215
|
-
|
216
|
-
|
217
|
+
screen.register(:scroll, self);
|
218
|
+
self
|
217
219
|
end
|
218
220
|
|
219
221
|
# @see Widget#position
|
@@ -221,29 +223,18 @@ module RNDK
|
|
221
223
|
super @win
|
222
224
|
end
|
223
225
|
|
224
|
-
# Put the cursor on the currently-selected item's row.
|
225
|
-
def fixCursorPosition
|
226
|
-
scrollbar_adj = if @scrollbar_placement == LEFT then 1 else 0 end
|
227
|
-
ypos = self.Screen_YPOS(@current_item - @current_top)
|
228
|
-
xpos = self.Screen_XPOS(0) + scrollbar_adj
|
229
|
-
|
230
|
-
Ncurses.wmove(@input_window, ypos, xpos)
|
231
|
-
Ncurses.wrefresh(@input_window)
|
232
|
-
end
|
233
|
-
|
234
226
|
# Activates the Widget, letting the user interact with it.
|
235
227
|
#
|
236
228
|
# `actions` is an Array of characters. If it's non-null,
|
237
229
|
# will #inject each char on it into the Widget.
|
238
230
|
#
|
239
231
|
def activate(actions=[])
|
240
|
-
|
241
|
-
self.draw(@box)
|
232
|
+
self.draw
|
242
233
|
|
243
234
|
if actions.nil? || actions.size == 0
|
244
235
|
loop do
|
245
|
-
self.
|
246
|
-
input = self.getch
|
236
|
+
self.fix_cursor_position
|
237
|
+
input = self.getch
|
247
238
|
|
248
239
|
# Inject the character into the widget.
|
249
240
|
ret = self.inject input
|
@@ -261,64 +252,87 @@ module RNDK
|
|
261
252
|
|
262
253
|
# Set the exit type for the widget and return
|
263
254
|
self.set_exit_type(0)
|
264
|
-
return
|
255
|
+
return nil
|
265
256
|
end
|
266
257
|
|
267
258
|
# @see Widget#inject
|
268
259
|
def inject input
|
269
|
-
|
270
|
-
ret = -1
|
260
|
+
ret = nil
|
271
261
|
complete = false
|
272
262
|
|
273
|
-
|
274
|
-
self.set_exit_type(0)
|
263
|
+
self.set_exit_type 0
|
275
264
|
|
276
|
-
# Draw the scrolling
|
277
|
-
self.
|
265
|
+
# Draw the scrolling items
|
266
|
+
self.draw_items @box
|
278
267
|
|
279
|
-
#
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
268
|
+
# Calls a pre-process block if exists.
|
269
|
+
# They can interrup input.
|
270
|
+
continue = run_signal_binding(:before_input, input)
|
271
|
+
|
272
|
+
if continue
|
284
273
|
|
285
|
-
# Should we continue?
|
286
|
-
if pp_return != 0
|
287
274
|
# Check for a predefined key binding.
|
288
|
-
if self.
|
289
|
-
|
290
|
-
|
275
|
+
if self.is_bound? input
|
276
|
+
self.run_key_binding input
|
277
|
+
|
291
278
|
else
|
292
279
|
case input
|
280
|
+
|
293
281
|
when Ncurses::KEY_UP
|
294
|
-
self.
|
282
|
+
self.scroll_up
|
283
|
+
run_signal_binding(:after_scrolling, @current_item)
|
284
|
+
|
295
285
|
when Ncurses::KEY_DOWN
|
296
|
-
self.
|
297
|
-
|
298
|
-
|
286
|
+
self.scroll_down
|
287
|
+
run_signal_binding(:after_scrolling, @current_item)
|
288
|
+
|
299
289
|
when Ncurses::KEY_LEFT
|
300
|
-
self.
|
290
|
+
self.scroll_left
|
291
|
+
run_signal_binding(:after_scrolling, @current_item)
|
292
|
+
|
293
|
+
when Ncurses::KEY_RIGHT
|
294
|
+
self.scroll_right
|
295
|
+
run_signal_binding(:after_scrolling, @current_item)
|
296
|
+
|
301
297
|
when Ncurses::KEY_PPAGE
|
302
|
-
self.
|
298
|
+
self.scroll_page_up
|
299
|
+
run_signal_binding(:after_scrolling, @current_item)
|
300
|
+
|
303
301
|
when Ncurses::KEY_NPAGE
|
304
|
-
self.
|
302
|
+
self.scroll_page_down
|
303
|
+
run_signal_binding(:after_scrolling, @current_item)
|
304
|
+
|
305
305
|
when Ncurses::KEY_HOME
|
306
|
-
self.
|
306
|
+
self.scroll_begin
|
307
|
+
run_signal_binding(:after_scrolling, @current_item)
|
308
|
+
|
307
309
|
when Ncurses::KEY_END
|
308
|
-
self.
|
309
|
-
|
310
|
-
|
311
|
-
when
|
312
|
-
|
310
|
+
self.scroll_end
|
311
|
+
run_signal_binding(:after_scrolling, @current_item)
|
312
|
+
|
313
|
+
when RNDK::BACKCHAR
|
314
|
+
self.scroll_page_up
|
315
|
+
run_signal_binding(:after_scrolling, @current_item)
|
316
|
+
|
317
|
+
when RNDK::FORCHAR
|
318
|
+
self.scroll_page_down
|
319
|
+
run_signal_binding(:after_scrolling, @current_item)
|
320
|
+
|
321
|
+
when '$' then @left_char = @max_left_char
|
322
|
+
when '|' then @left_char = 0
|
323
|
+
|
313
324
|
when RNDK::KEY_ESC
|
314
325
|
self.set_exit_type(input)
|
315
326
|
complete = true
|
327
|
+
|
316
328
|
when Ncurses::ERR
|
317
329
|
self.set_exit_type(input)
|
318
330
|
complete = true
|
331
|
+
|
319
332
|
when RNDK::REFRESH
|
320
333
|
@screen.erase
|
321
334
|
@screen.refresh
|
335
|
+
|
322
336
|
when RNDK::KEY_TAB, Ncurses::KEY_ENTER, RNDK::KEY_RETURN
|
323
337
|
self.set_exit_type(input)
|
324
338
|
ret = @current_item
|
@@ -326,136 +340,43 @@ module RNDK
|
|
326
340
|
end
|
327
341
|
end
|
328
342
|
|
329
|
-
if
|
330
|
-
@post_process_func.call(:scroll, self, @post_process_data, input)
|
331
|
-
end
|
343
|
+
run_signal_binding(:after_input, input) if not complete
|
332
344
|
end
|
333
345
|
|
334
|
-
if
|
335
|
-
self.
|
346
|
+
if not complete
|
347
|
+
self.draw_items @box
|
336
348
|
self.set_exit_type(0)
|
337
349
|
end
|
338
350
|
|
339
|
-
self.
|
351
|
+
self.fix_cursor_position
|
340
352
|
@result_data = ret
|
341
353
|
|
342
|
-
|
343
|
-
return ret
|
344
|
-
end
|
345
|
-
|
346
|
-
def getCurrentTop
|
347
|
-
return @current_top
|
348
|
-
end
|
349
|
-
|
350
|
-
def setCurrentTop(item)
|
351
|
-
if item < 0
|
352
|
-
item = 0
|
353
|
-
elsif item > @max_top_item
|
354
|
-
item = @max_top_item
|
355
|
-
end
|
356
|
-
@current_top = item
|
357
|
-
|
358
|
-
self.setPosition(item);
|
354
|
+
ret
|
359
355
|
end
|
360
356
|
|
361
357
|
# This moves the scroll field to the given location.
|
362
|
-
def move(
|
363
|
-
windows = [@win, @
|
358
|
+
def move(x, y, relative, refresh_flag)
|
359
|
+
windows = [@win, @items_win, @shadow_win, @scrollbar_win]
|
364
360
|
|
365
|
-
self.move_specific(
|
361
|
+
self.move_specific(x, y, relative, refresh_flag, windows, [])
|
366
362
|
end
|
367
363
|
|
368
|
-
# This function draws the scrolling
|
369
|
-
def draw
|
364
|
+
# This function draws the scrolling items widget.
|
365
|
+
def draw
|
370
366
|
# Draw in the shadow if we need to.
|
371
|
-
unless @shadow_win.nil?
|
372
|
-
Draw.drawShadow(@shadow_win)
|
373
|
-
end
|
374
|
-
|
375
|
-
self.drawTitle(@win)
|
376
|
-
|
377
|
-
# Draw in the scrolling list items.
|
378
|
-
self.drawList(box)
|
379
|
-
end
|
380
|
-
|
381
|
-
def drawCurrent
|
382
|
-
# Rehighlight the current menu item.
|
383
|
-
screen_pos = @item_pos[@current_item] - @left_char
|
384
|
-
highlight = if self.has_focus
|
385
|
-
then @highlight
|
386
|
-
else Ncurses::A_NORMAL
|
387
|
-
end
|
388
|
-
|
389
|
-
Draw.writeChtypeAttrib(@list_win,
|
390
|
-
if screen_pos >= 0 then screen_pos else 0 end,
|
391
|
-
@current_high, @item[@current_item], highlight, RNDK::HORIZONTAL,
|
392
|
-
if screen_pos >= 0 then 0 else 1 - screen_pos end,
|
393
|
-
@item_len[@current_item])
|
394
|
-
end
|
395
|
-
|
396
|
-
def drawList box
|
397
|
-
# If the list is empty, don't draw anything.
|
398
|
-
if @list_size > 0
|
399
|
-
# Redraw the list
|
400
|
-
(0...@view_size).each do |j|
|
401
|
-
k = j + @current_top
|
402
|
-
|
403
|
-
Draw.writeBlanks(@list_win, 0, j, RNDK::HORIZONTAL, 0,
|
404
|
-
@box_width - (2 * @border_size))
|
405
|
-
|
406
|
-
# Draw the elements in the scrolling list.
|
407
|
-
if k < @list_size
|
408
|
-
screen_pos = @item_pos[k] - @left_char
|
409
|
-
ypos = j
|
410
|
-
|
411
|
-
# Write in the correct line.
|
412
|
-
Draw.writeChtype(@list_win,
|
413
|
-
if screen_pos >= 0 then screen_pos else 1 end,
|
414
|
-
ypos, @item[k], RNDK::HORIZONTAL,
|
415
|
-
if screen_pos >= 0 then 0 else 1 - screen_pos end,
|
416
|
-
@item_len[k])
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
self.drawCurrent
|
367
|
+
Draw.drawShadow(@shadow_win) unless @shadow_win.nil?
|
421
368
|
|
422
|
-
|
423
|
-
unless @scrollbar_win.nil?
|
424
|
-
@toggle_pos = (@current_item * @step).floor
|
425
|
-
|
426
|
-
# Make sure the toggle button doesn't go out of bounds.
|
427
|
-
if @toggle_pos >= Ncurses.getmaxy(@scrollbar_win)
|
428
|
-
@toggle_pos = Ncurses.getmaxy(@scrollbar_win) - 1
|
429
|
-
end
|
430
|
-
|
431
|
-
# Draw the scrollbar
|
432
|
-
Ncurses.mvwvline(@scrollbar_win,
|
433
|
-
0,
|
434
|
-
0,
|
435
|
-
Ncurses::ACS_CKBOARD,
|
436
|
-
Ncurses.getmaxy(@scrollbar_win))
|
369
|
+
self.draw_title @win
|
437
370
|
|
438
|
-
|
439
|
-
|
440
|
-
0,
|
441
|
-
' '.ord | Ncurses::A_REVERSE,
|
442
|
-
@toggle_size)
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
# Box it if needed.
|
447
|
-
if box
|
448
|
-
Draw.drawObjBox(@win, self)
|
449
|
-
end
|
450
|
-
|
451
|
-
# Refresh the window
|
452
|
-
Ncurses.wrefresh @win
|
371
|
+
# Draw in the scrolling items items.
|
372
|
+
self.draw_items @box
|
453
373
|
end
|
454
374
|
|
455
375
|
# This sets the background attribute of the widget.
|
456
|
-
def
|
376
|
+
def set_bg_color(attrib)
|
457
377
|
Ncurses.wbkgd(@win, attrib)
|
458
|
-
Ncurses.wbkgd(@
|
378
|
+
Ncurses.wbkgd(@items_win, attrib)
|
379
|
+
|
459
380
|
unless @scrollbar_win.nil?
|
460
381
|
Ncurses.wbkgd(@scrollbar_win, attrib)
|
461
382
|
end
|
@@ -463,78 +384,182 @@ module RNDK
|
|
463
384
|
|
464
385
|
# This function destroys
|
465
386
|
def destroy
|
466
|
-
self.
|
387
|
+
self.clean_title
|
467
388
|
|
468
389
|
# Clean up the windows.
|
469
390
|
RNDK.window_delete(@scrollbar_win)
|
470
391
|
RNDK.window_delete(@shadow_win)
|
471
|
-
RNDK.window_delete(@
|
392
|
+
RNDK.window_delete(@items_win)
|
472
393
|
RNDK.window_delete(@win)
|
473
394
|
|
474
395
|
# Clean the key bindings.
|
475
|
-
self.clean_bindings
|
396
|
+
self.clean_bindings
|
476
397
|
|
477
|
-
# Unregister this
|
478
|
-
|
398
|
+
# Unregister this widget
|
399
|
+
@screen.unregister self
|
479
400
|
end
|
480
401
|
|
481
|
-
# This function erases the scrolling
|
402
|
+
# This function erases the scrolling items from the screen.
|
482
403
|
def erase
|
483
404
|
RNDK.window_erase(@win)
|
484
405
|
RNDK.window_erase(@shadow_win)
|
485
406
|
end
|
486
407
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
408
|
+
# This sets certain attributes of the scrolling items.
|
409
|
+
def set(items, numbers, highlight, box)
|
410
|
+
self.set_items(items, numbers)
|
411
|
+
self.set_highlight(highlight)
|
412
|
+
self.set_box(box)
|
413
|
+
end
|
492
414
|
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
415
|
+
# Sets the scrolling items items.
|
416
|
+
# See Scroll#initialize.
|
417
|
+
def set_items(items, numbers)
|
418
|
+
return unless self.create_item_list(numbers, items)
|
419
|
+
|
420
|
+
# Clean up the display.
|
421
|
+
(0...@view_size).each do |x|
|
422
|
+
Draw.writeBlanks(@win, 1, x, RNDK::HORIZONTAL, 0, @box_width - 2);
|
497
423
|
end
|
498
424
|
|
499
|
-
|
500
|
-
|
501
|
-
|
425
|
+
self.set_view_size(items.size)
|
426
|
+
self.set_position(0)
|
427
|
+
self.erase
|
502
428
|
|
503
|
-
|
429
|
+
@left_char = 0
|
504
430
|
end
|
505
431
|
|
506
|
-
def
|
507
|
-
|
508
|
-
|
432
|
+
def get_items(items)
|
433
|
+
(0...@item.size).each do |x|
|
434
|
+
items << RNDK.chtype2Char(@item[x])
|
509
435
|
end
|
510
436
|
|
511
|
-
|
512
|
-
|
513
|
-
@item[which] = RNDK.char2Chtype(value, item_len, item_pos)
|
514
|
-
@item_len[which] = item_len[0]
|
515
|
-
@item_pos[which] = item_pos[0]
|
437
|
+
@item.size
|
438
|
+
end
|
516
439
|
|
517
|
-
|
518
|
-
|
519
|
-
|
440
|
+
# This sets the highlight of the scrolling items.
|
441
|
+
def set_highlight(highlight)
|
442
|
+
@highlight = highlight
|
520
443
|
end
|
521
444
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
445
|
+
def get_highlight(highlight)
|
446
|
+
return @highlight
|
447
|
+
end
|
448
|
+
|
449
|
+
# # Adds a single item to a scrolling items, at the end of
|
450
|
+
# # the items.
|
451
|
+
# def add_item(item)
|
452
|
+
# item_number = @item.size
|
453
|
+
# widest_item = self.widest_item
|
454
|
+
# temp = ''
|
455
|
+
# have = 0
|
456
|
+
|
457
|
+
# if (self.alloc_items_arrays(@item.size, @item.size + 1)) and
|
458
|
+
# (self.alloc_items_item(item_number,
|
459
|
+
# temp,
|
460
|
+
# have,
|
461
|
+
# if @numbers then item_number + 1 else 0 end,
|
462
|
+
# item))
|
463
|
+
# # Determine the size of the widest item.
|
464
|
+
# widest_item = [@item_len[item_number], widest_item].max
|
465
|
+
|
466
|
+
# self.update_view_width(widest_item)
|
467
|
+
# self.set_view_size(@item.size + 1)
|
468
|
+
# end
|
469
|
+
# end
|
470
|
+
|
471
|
+
# # Adds a single item to a scrolling items before the current
|
472
|
+
# # item.
|
473
|
+
# def insert_item(item)
|
474
|
+
# widest_item = self.widest_item
|
475
|
+
# temp = ''
|
476
|
+
# have = 0
|
477
|
+
|
478
|
+
# if (self.alloc_items_arrays(@item.size, @item.size + 1)) and
|
479
|
+
# (self.insert_items_item(@current_item)) and
|
480
|
+
# (self.alloc_items_item(@current_item,
|
481
|
+
# temp,
|
482
|
+
# have,
|
483
|
+
# if @numbers then @current_item + 1 else 0 end,
|
484
|
+
# item))
|
485
|
+
|
486
|
+
# # Determine the size of the widest item.
|
487
|
+
# widest_item = [@item_len[@current_item], widest_item].max
|
488
|
+
|
489
|
+
# self.update_view_width(widest_item)
|
490
|
+
# self.set_view_size(@item.size + 1)
|
491
|
+
# self.resequence
|
492
|
+
# end
|
493
|
+
# end
|
494
|
+
|
495
|
+
# # This removes a single item from a scrolling items.
|
496
|
+
# def delete_item(position)
|
497
|
+
# if position >= 0 && position < @item.size
|
498
|
+
# # Adjust the items
|
499
|
+
# @item = @item[0...position] + @item[position+1..-1]
|
500
|
+
# @item_len = @item_len[0...position] + @item_len[position+1..-1]
|
501
|
+
# @item_pos = @item_pos[0...position] + @item_pos[position+1..-1]
|
502
|
+
|
503
|
+
# self.set_view_size(@item.size - 1)
|
504
|
+
|
505
|
+
# self.resequence if @item.size > 0
|
506
|
+
|
507
|
+
# if @item.size < self.max_view_size
|
508
|
+
# Ncurses.werase @win # force the next redraw to be complete
|
509
|
+
# end
|
510
|
+
|
511
|
+
# # do this to update the view size, etc
|
512
|
+
# self.set_position(@current_item)
|
513
|
+
# end
|
514
|
+
# end
|
515
|
+
|
516
|
+
def focus
|
517
|
+
self.draw_current
|
518
|
+
Ncurses.wrefresh @items_win
|
519
|
+
end
|
520
|
+
|
521
|
+
def unfocus
|
522
|
+
self.draw_current
|
523
|
+
Ncurses.wrefresh @items_win
|
524
|
+
end
|
525
|
+
|
526
|
+
# _ _ _
|
527
|
+
# | | | | | |
|
528
|
+
# _ __ _ __ ___ | |_ ___ ___| |_ ___ __| |
|
529
|
+
# | '_ \| '__/ _ \| __/ _ \/ __| __/ _ \/ _` |
|
530
|
+
# | |_) | | | (_) | || __| (__| || __| (_| |
|
531
|
+
# | .__/|_| \___/ \__\___|\___|\__\___|\__,_|
|
532
|
+
# | |
|
533
|
+
# |_|
|
534
|
+
protected
|
535
|
+
|
536
|
+
# Creates the scrolling items information and sets up the
|
537
|
+
# needed variables for the scrolling items to work correctly.
|
538
|
+
def create_item_list(numbers, items)
|
539
|
+
status = false
|
540
|
+
|
541
|
+
# If any element is not a String, try to convert
|
542
|
+
# it anyway.
|
543
|
+
items.each_with_index do |item, i|
|
544
|
+
if item.class != String
|
545
|
+
items[i] = item.to_s
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
if items.size > 0
|
527
550
|
widest_item = 0
|
528
551
|
x = 0
|
529
552
|
have = 0
|
530
553
|
temp = ''
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
554
|
+
|
555
|
+
if alloc_items_arrays(0, items.size)
|
556
|
+
# Create the items in the scrolling items.
|
557
|
+
status = true
|
558
|
+
(0...items.size).each do |x|
|
535
559
|
number = if numbers then x + 1 else 0 end
|
536
|
-
|
537
|
-
|
560
|
+
|
561
|
+
unless self.alloc_items_item(x, temp, have, number, items[x])
|
562
|
+
status = false
|
538
563
|
break
|
539
564
|
end
|
540
565
|
|
@@ -542,175 +567,203 @@ module RNDK
|
|
542
567
|
end
|
543
568
|
|
544
569
|
if status
|
545
|
-
self.
|
570
|
+
self.update_view_width widest_item
|
546
571
|
|
547
572
|
# Keep the boolean flag 'numbers'
|
548
573
|
@numbers = numbers
|
549
574
|
end
|
550
575
|
end
|
576
|
+
|
551
577
|
else
|
552
|
-
status =
|
578
|
+
status = true # null items is ok - for a while
|
553
579
|
end
|
554
|
-
|
555
|
-
return status
|
580
|
+
status
|
556
581
|
end
|
557
582
|
|
558
|
-
|
559
|
-
def set(list, list_size, numbers, highlight, box)
|
560
|
-
self.setItems(list, list_size, numbers)
|
561
|
-
self.set_highlight(highlight)
|
562
|
-
self.set_box(box)
|
563
|
-
end
|
583
|
+
def alloc_items_arrays(old_size, new_size)
|
564
584
|
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
return
|
569
|
-
end
|
585
|
+
new_items = Array.new new_size
|
586
|
+
new_len = Array.new new_size
|
587
|
+
new_pos = Array.new new_size
|
570
588
|
|
571
|
-
|
572
|
-
|
573
|
-
|
589
|
+
(0...old_size).each do |n|
|
590
|
+
new_items[n] = @item[n]
|
591
|
+
new_len[n] = @item_len[n]
|
592
|
+
new_pos[n] = @item_pos[n]
|
574
593
|
end
|
575
594
|
|
576
|
-
|
577
|
-
|
578
|
-
@
|
595
|
+
@item = new_items
|
596
|
+
@item_len = new_len
|
597
|
+
@item_pos = new_pos
|
598
|
+
|
599
|
+
true
|
579
600
|
end
|
580
601
|
|
581
|
-
|
582
|
-
|
583
|
-
list << RNDK.chtype2Char(@item[x])
|
584
|
-
end
|
602
|
+
# Creates a single item on the scroll items.
|
603
|
+
def alloc_items_item(which, work, used, number, value)
|
585
604
|
|
586
|
-
|
587
|
-
|
605
|
+
if number > 0
|
606
|
+
value = "%4d. %s" % [number, value]
|
607
|
+
end
|
588
608
|
|
589
|
-
|
590
|
-
|
591
|
-
@
|
592
|
-
|
609
|
+
item_len = []
|
610
|
+
item_pos = []
|
611
|
+
@item[which] = RNDK.char2Chtype(value, item_len, item_pos)
|
612
|
+
@item_len[which] = item_len[0]
|
613
|
+
@item_pos[which] = item_pos[0]
|
593
614
|
|
594
|
-
|
595
|
-
|
615
|
+
@item_pos[which] = RNDK.justifyString(@box_width,
|
616
|
+
@item_len[which],
|
617
|
+
@item_pos[which])
|
618
|
+
true
|
596
619
|
end
|
597
620
|
|
598
621
|
# Resequence the numbers after an insertion/deletion.
|
599
622
|
def resequence
|
600
|
-
|
601
|
-
(0...@list_size).each do |j|
|
602
|
-
target = @item[j]
|
623
|
+
return unless @numbers
|
603
624
|
|
604
|
-
|
625
|
+
(0...@item.size).each do |j|
|
626
|
+
target = @item[j]
|
605
627
|
|
606
|
-
|
607
|
-
while k < source.size
|
608
|
-
# handle deletions that change the length of number
|
609
|
-
if source[k] == "." && target[k] != "."
|
610
|
-
source = source[0...k] + source[k+1..-1]
|
611
|
-
end
|
628
|
+
source = "%4d. %s" % [j + 1, ""]
|
612
629
|
|
613
|
-
|
614
|
-
|
615
|
-
|
630
|
+
k = 0
|
631
|
+
while k < source.size
|
632
|
+
# handle deletions that change the length of number
|
633
|
+
if (source[k] == ".") and (target[k] != ".")
|
634
|
+
source = source[0...k] + source[k+1..-1]
|
616
635
|
end
|
636
|
+
|
637
|
+
target[k] &= RNDK::Color[:extract]
|
638
|
+
target[k] |= source[k].ord
|
639
|
+
k += 1
|
617
640
|
end
|
618
641
|
end
|
619
642
|
end
|
620
643
|
|
621
|
-
def
|
644
|
+
def insert_items_item(item)
|
622
645
|
@item = @item[0..item] + @item[item..-1]
|
623
646
|
@item_len = @item_len[0..item] + @item_len[item..-1]
|
624
647
|
@item_pos = @item_pos[0..item] + @item_pos[item..-1]
|
625
|
-
|
648
|
+
|
649
|
+
true
|
626
650
|
end
|
627
651
|
|
628
|
-
|
629
|
-
|
630
|
-
item_number = @list_size
|
631
|
-
widest_item = self.WidestItem
|
632
|
-
temp = ''
|
633
|
-
have = 0
|
634
|
-
|
635
|
-
if self.allocListArrays(@list_size, @list_size + 1) &&
|
636
|
-
self.allocListItem(item_number, temp, have,
|
637
|
-
if @numbers then item_number + 1 else 0 end,
|
638
|
-
item)
|
639
|
-
# Determine the size of the widest item.
|
640
|
-
widest_item = [@item_len[item_number], widest_item].max
|
641
|
-
|
642
|
-
self.updateViewWidth(widest_item)
|
643
|
-
self.setViewSize(@list_size + 1)
|
644
|
-
end
|
652
|
+
def available_width
|
653
|
+
@box_width - (2 * @border_size)
|
645
654
|
end
|
646
655
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
if self.allocListArrays(@list_size, @list_size + 1) &&
|
654
|
-
self.insertListItem(@current_item) &&
|
655
|
-
self.allocListItem(@current_item, temp, have,
|
656
|
-
if @numbers then @current_item + 1 else 0 end,
|
657
|
-
item)
|
658
|
-
# Determine the size of the widest item.
|
659
|
-
widest_item = [@item_len[@current_item], widest_item].max
|
660
|
-
|
661
|
-
self.updateViewWidth(widest_item)
|
662
|
-
self.setViewSize(@list_size + 1)
|
663
|
-
self.resequence
|
664
|
-
end
|
656
|
+
def update_view_width(widest)
|
657
|
+
@max_left_char = if @box_width > widest
|
658
|
+
then 0
|
659
|
+
else widest - self.available_width
|
660
|
+
end
|
665
661
|
end
|
666
662
|
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
663
|
+
def widest_item
|
664
|
+
@max_left_char + self.available_width
|
665
|
+
end
|
666
|
+
|
667
|
+
# Draws the scrolling items.
|
668
|
+
def draw_items box
|
669
|
+
|
670
|
+
# If the items is empty, don't draw anything.
|
671
|
+
if @item.size > 0
|
672
|
+
|
673
|
+
# Redraw the items
|
674
|
+
(0...@view_size).each do |j|
|
675
|
+
k = j + @current_top
|
676
|
+
|
677
|
+
Draw.writeBlanks(@items_win,
|
678
|
+
0,
|
679
|
+
j,
|
680
|
+
RNDK::HORIZONTAL, 0,
|
681
|
+
@box_width - (2 * @border_size))
|
674
682
|
|
675
|
-
|
683
|
+
# Draw the elements in the scrolling items.
|
684
|
+
if k < @item.size
|
676
685
|
|
677
|
-
|
686
|
+
screen_pos = @item_pos[k] - @left_char
|
687
|
+
ypos = j
|
678
688
|
|
679
|
-
|
680
|
-
|
689
|
+
# Write in the correct line.
|
690
|
+
Draw.writeChtype(@items_win,
|
691
|
+
if screen_pos >= 0 then screen_pos else 1 end,
|
692
|
+
ypos, @item[k], RNDK::HORIZONTAL,
|
693
|
+
if screen_pos >= 0 then 0 else 1 - screen_pos end,
|
694
|
+
@item_len[k])
|
695
|
+
end
|
681
696
|
end
|
682
697
|
|
683
|
-
|
684
|
-
|
698
|
+
self.draw_current
|
699
|
+
|
700
|
+
# Determine where the toggle is supposed to be.
|
701
|
+
unless @scrollbar_win.nil?
|
702
|
+
@toggle_pos = (@current_item * @step).floor
|
703
|
+
|
704
|
+
# Make sure the toggle button doesn't go out of bounds.
|
705
|
+
if @toggle_pos >= Ncurses.getmaxy(@scrollbar_win)
|
706
|
+
@toggle_pos = Ncurses.getmaxy(@scrollbar_win) - 1
|
707
|
+
end
|
708
|
+
|
709
|
+
# Draw the scrollbar
|
710
|
+
Ncurses.mvwvline(@scrollbar_win,
|
711
|
+
0,
|
712
|
+
0,
|
713
|
+
Ncurses::ACS_CKBOARD,
|
714
|
+
Ncurses.getmaxy(@scrollbar_win))
|
715
|
+
|
716
|
+
Ncurses.mvwvline(@scrollbar_win,
|
717
|
+
@toggle_pos,
|
718
|
+
0,
|
719
|
+
' '.ord | RNDK::Color[:reverse],
|
720
|
+
@toggle_size)
|
721
|
+
end
|
685
722
|
end
|
686
|
-
end
|
687
723
|
|
688
|
-
|
689
|
-
|
690
|
-
Ncurses.wrefresh @list_win
|
724
|
+
Draw.drawObjBox(@win, self) if box
|
725
|
+
Ncurses.wrefresh @win
|
691
726
|
end
|
692
727
|
|
693
|
-
def
|
694
|
-
|
695
|
-
Ncurses.wrefresh @list_win
|
728
|
+
def get_current_top
|
729
|
+
@current_top
|
696
730
|
end
|
697
731
|
|
698
|
-
def
|
699
|
-
|
700
|
-
|
732
|
+
def set_current_top(item)
|
733
|
+
if item < 0
|
734
|
+
item = 0
|
735
|
+
elsif item > @max_top_item
|
736
|
+
item = @max_top_item
|
737
|
+
end
|
738
|
+
@current_top = item
|
701
739
|
|
702
|
-
|
703
|
-
@max_left_char = if @box_width > widest
|
704
|
-
then 0
|
705
|
-
else widest - self.AvailableWidth
|
706
|
-
end
|
740
|
+
self.set_position(item);
|
707
741
|
end
|
708
742
|
|
709
|
-
def
|
710
|
-
|
743
|
+
def draw_current
|
744
|
+
# Rehighlight the current menu item.
|
745
|
+
screen_pos = @item_pos[@current_item] - @left_char
|
746
|
+
highlight = if self.has_focus
|
747
|
+
then @highlight
|
748
|
+
else RNDK::Color[:normal]
|
749
|
+
end
|
750
|
+
|
751
|
+
Draw.writeChtypeAttrib(@items_win,
|
752
|
+
if screen_pos >= 0 then screen_pos else 0 end,
|
753
|
+
@current_high, @item[@current_item], highlight, RNDK::HORIZONTAL,
|
754
|
+
if screen_pos >= 0 then 0 else 1 - screen_pos end,
|
755
|
+
@item_len[@current_item])
|
711
756
|
end
|
712
757
|
|
713
|
-
|
758
|
+
# Put the cursor on the currently-selected item's row.
|
759
|
+
def fix_cursor_position
|
760
|
+
scrollbar_adj = if @scrollbar_placement == LEFT then 1 else 0 end
|
761
|
+
ypos = self.Screen_YPOS(@current_item - @current_top)
|
762
|
+
xpos = self.Screen_XPOS(0) + scrollbar_adj
|
763
|
+
|
764
|
+
Ncurses.wmove(@input_window, ypos, xpos)
|
765
|
+
Ncurses.wrefresh(@input_window)
|
766
|
+
end
|
714
767
|
|
715
768
|
end
|
716
769
|
end
|