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/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
|