rndk 0.0.1
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 +7 -0
- data/.gitignore +23 -0
- data/COPYING +137 -0
- data/Gemfile +4 -0
- data/README.md +100 -0
- data/Rakefile +3 -0
- data/TODO +68 -0
- data/demos/appointment.rb +346 -0
- data/demos/clock.rb +56 -0
- data/examples/01-hello-world.rb +56 -0
- data/examples/05-position-widget.rb +108 -0
- data/lib/rndk.rb +912 -0
- data/lib/rndk/alphalist.rb +572 -0
- data/lib/rndk/button.rb +370 -0
- data/lib/rndk/buttonbox.rb +359 -0
- data/lib/rndk/calendar.rb +766 -0
- data/lib/rndk/core/display.rb +63 -0
- data/lib/rndk/core/draw.rb +238 -0
- data/lib/rndk/core/quick_widgets.rb +106 -0
- data/lib/rndk/core/screen.rb +269 -0
- data/lib/rndk/core/traverse.rb +289 -0
- data/lib/rndk/core/widget.rb +506 -0
- data/lib/rndk/dialog.rb +367 -0
- data/lib/rndk/dscale.rb +13 -0
- data/lib/rndk/entry.rb +575 -0
- data/lib/rndk/fscale.rb +61 -0
- data/lib/rndk/fselect.rb +940 -0
- data/lib/rndk/fslider.rb +80 -0
- data/lib/rndk/graph.rb +401 -0
- data/lib/rndk/histogram.rb +412 -0
- data/lib/rndk/itemlist.rb +474 -0
- data/lib/rndk/label.rb +218 -0
- data/lib/rndk/marquee.rb +244 -0
- data/lib/rndk/matrix.rb +1189 -0
- data/lib/rndk/mentry.rb +619 -0
- data/lib/rndk/menu.rb +478 -0
- data/lib/rndk/radio.rb +538 -0
- data/lib/rndk/scale.rb +538 -0
- data/lib/rndk/scroll.rb +633 -0
- data/lib/rndk/scroller.rb +183 -0
- data/lib/rndk/selection.rb +630 -0
- data/lib/rndk/slider.rb +545 -0
- data/lib/rndk/swindow.rb +766 -0
- data/lib/rndk/template.rb +560 -0
- data/lib/rndk/uscale.rb +14 -0
- data/lib/rndk/uslider.rb +14 -0
- data/lib/rndk/version.rb +6 -0
- data/lib/rndk/viewer.rb +825 -0
- data/rndk.gemspec +35 -0
- metadata +141 -0
data/lib/rndk/scroll.rb
ADDED
@@ -0,0 +1,633 @@
|
|
1
|
+
require 'rndk/scroller'
|
2
|
+
|
3
|
+
module RNDK
|
4
|
+
class SCROLL < RNDK::SCROLLER
|
5
|
+
attr_reader :item, :list_size, :current_item, :highlight
|
6
|
+
|
7
|
+
def initialize (rndkscreen, xplace, yplace, splace, height, width, title,
|
8
|
+
list, list_size, numbers, highlight, box, shadow)
|
9
|
+
super()
|
10
|
+
parent_width = Ncurses.getmaxx(rndkscreen.window)
|
11
|
+
parent_height = Ncurses.getmaxy(rndkscreen.window)
|
12
|
+
box_width = width
|
13
|
+
box_height = height
|
14
|
+
xpos = xplace
|
15
|
+
ypos = yplace
|
16
|
+
scroll_adjust = 0
|
17
|
+
bindings = {
|
18
|
+
RNDK::BACKCHAR => Ncurses::KEY_PPAGE,
|
19
|
+
RNDK::FORCHAR => Ncurses::KEY_NPAGE,
|
20
|
+
'g' => Ncurses::KEY_HOME,
|
21
|
+
'1' => Ncurses::KEY_HOME,
|
22
|
+
'G' => Ncurses::KEY_END,
|
23
|
+
'<' => Ncurses::KEY_HOME,
|
24
|
+
'>' => Ncurses::KEY_END
|
25
|
+
}
|
26
|
+
|
27
|
+
self.setBox(box)
|
28
|
+
|
29
|
+
# If the height is a negative value, the height will be ROWS-height,
|
30
|
+
# otherwise the height will be the given height
|
31
|
+
box_height = RNDK.setWidgetDimension(parent_height, height, 0)
|
32
|
+
|
33
|
+
# If the width is a negative value, the width will be COLS-width,
|
34
|
+
# otherwise the width will be the given width
|
35
|
+
box_width = RNDK.setWidgetDimension(parent_width, width, 0)
|
36
|
+
|
37
|
+
box_width = self.setTitle(title, box_width)
|
38
|
+
|
39
|
+
# Set the box height.
|
40
|
+
if @title_lines > box_height
|
41
|
+
box_height = @title_lines + [list_size, 8].min + 2 * @border_size
|
42
|
+
end
|
43
|
+
|
44
|
+
# Adjust the box width if there is a scroll bar
|
45
|
+
if splace == RNDK::LEFT || splace == RNDK::RIGHT
|
46
|
+
@scrollbar = true
|
47
|
+
box_width += 1
|
48
|
+
else
|
49
|
+
@scrollbar = false
|
50
|
+
end
|
51
|
+
|
52
|
+
# Make sure we didn't extend beyond the dimensions of the window.
|
53
|
+
@box_width = if box_width > parent_width
|
54
|
+
then parent_width - scroll_adjust
|
55
|
+
else box_width
|
56
|
+
end
|
57
|
+
@box_height = if box_height > parent_height
|
58
|
+
then parent_height
|
59
|
+
else box_height
|
60
|
+
end
|
61
|
+
|
62
|
+
self.setViewSize(list_size)
|
63
|
+
|
64
|
+
# Rejustify the x and y positions if we need to.
|
65
|
+
xtmp = [xpos]
|
66
|
+
ytmp = [ypos]
|
67
|
+
RNDK.alignxy(rndkscreen.window, xtmp, ytmp, @box_width, @box_height)
|
68
|
+
xpos = xtmp[0]
|
69
|
+
ypos = ytmp[0]
|
70
|
+
|
71
|
+
# Make the scrolling window
|
72
|
+
@win = Ncurses.newwin(@box_height, @box_width, ypos, xpos)
|
73
|
+
|
74
|
+
# Is the scrolling window null?
|
75
|
+
if @win.nil?
|
76
|
+
return nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# Turn the keypad on for the window
|
80
|
+
Ncurses.keypad(@win, true)
|
81
|
+
|
82
|
+
# Create the scrollbar window.
|
83
|
+
if splace == RNDK::RIGHT
|
84
|
+
@scrollbar_win = Ncurses.subwin(@win, self.maxViewSize, 1,
|
85
|
+
self.Screen_YPOS(ypos), xpos + box_width - @border_size - 1)
|
86
|
+
elsif splace == RNDK::LEFT
|
87
|
+
@scrollbar_win = Ncurses.subwin(@win, self.maxViewSize, 1,
|
88
|
+
self.Screen_YPOS(ypos), self.Screen_XPOS(xpos))
|
89
|
+
else
|
90
|
+
@scrollbar_win = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
# create the list window
|
94
|
+
@list_win = Ncurses.subwin(@win, self.maxViewSize,
|
95
|
+
box_width - (2 * @border_size) - scroll_adjust,
|
96
|
+
self.Screen_YPOS(ypos),
|
97
|
+
self.Screen_XPOS(xpos) + (if splace == RNDK::LEFT then 1 else 0 end))
|
98
|
+
|
99
|
+
# Set the rest of the variables
|
100
|
+
@screen = rndkscreen
|
101
|
+
@parent = rndkscreen.window
|
102
|
+
@shadow_win = nil
|
103
|
+
@scrollbar_placement = splace
|
104
|
+
@max_left_char = 0
|
105
|
+
@left_char = 0
|
106
|
+
@highlight = highlight
|
107
|
+
# initExitType (scrollp);
|
108
|
+
@accepts_focus = true
|
109
|
+
@input_window = @win
|
110
|
+
@shadow = shadow
|
111
|
+
|
112
|
+
self.setPosition(0);
|
113
|
+
|
114
|
+
# Create the scrolling list item list and needed variables.
|
115
|
+
if self.createItemList(numbers, list, list_size) <= 0
|
116
|
+
return nil
|
117
|
+
end
|
118
|
+
|
119
|
+
# Do we need to create a shadow?
|
120
|
+
if shadow
|
121
|
+
@shadow_win = Ncurses.newwin(@box_height, box_width,
|
122
|
+
ypos + 1, xpos + 1)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Set up the key bindings.
|
126
|
+
bindings.each do |from, to|
|
127
|
+
#self.bind(:SCROLL, from, getc_lambda, to)
|
128
|
+
self.bind(:SCROLL, from, :getc, to)
|
129
|
+
end
|
130
|
+
|
131
|
+
rndkscreen.register(:SCROLL, self);
|
132
|
+
|
133
|
+
return self
|
134
|
+
end
|
135
|
+
|
136
|
+
def object_type
|
137
|
+
:SCROLL
|
138
|
+
end
|
139
|
+
|
140
|
+
def position
|
141
|
+
super(@win)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Put the cursor on the currently-selected item's row.
|
145
|
+
def fixCursorPosition
|
146
|
+
scrollbar_adj = if @scrollbar_placement == LEFT then 1 else 0 end
|
147
|
+
ypos = self.Screen_YPOS(@current_item - @current_top)
|
148
|
+
xpos = self.Screen_XPOS(0) + scrollbar_adj
|
149
|
+
|
150
|
+
Ncurses.wmove(@input_window, ypos, xpos)
|
151
|
+
Ncurses.wrefresh(@input_window)
|
152
|
+
end
|
153
|
+
|
154
|
+
# This actually does all the 'real' work of managing the scrolling list.
|
155
|
+
def activate(actions)
|
156
|
+
# Draw the scrolling list
|
157
|
+
self.draw(@box)
|
158
|
+
|
159
|
+
if actions.nil? || actions.size == 0
|
160
|
+
while true
|
161
|
+
self.fixCursorPosition
|
162
|
+
input = self.getch([])
|
163
|
+
|
164
|
+
# Inject the character into the widget.
|
165
|
+
ret = self.inject(input)
|
166
|
+
if @exit_type != :EARLY_EXIT
|
167
|
+
return ret
|
168
|
+
end
|
169
|
+
end
|
170
|
+
else
|
171
|
+
# Inject each character one at a time.
|
172
|
+
actions.each do |action|
|
173
|
+
ret = self.inject(action)
|
174
|
+
if @exit_type != :EARLY_EXIT
|
175
|
+
return ret
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Set the exit type for the widget and return
|
181
|
+
self.setExitType(0)
|
182
|
+
return -1
|
183
|
+
end
|
184
|
+
|
185
|
+
# This injects a single character into the widget.
|
186
|
+
def inject(input)
|
187
|
+
pp_return = 1
|
188
|
+
ret = -1
|
189
|
+
complete = false
|
190
|
+
|
191
|
+
# Set the exit type for the widget.
|
192
|
+
self.setExitType(0)
|
193
|
+
|
194
|
+
# Draw the scrolling list
|
195
|
+
self.drawList(@box)
|
196
|
+
|
197
|
+
#Check if there is a pre-process function to be called.
|
198
|
+
unless @pre_process_func.nil?
|
199
|
+
pp_return = @pre_process_func.call(:SCROLL, self,
|
200
|
+
@pre_process_data, input)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Should we continue?
|
204
|
+
if pp_return != 0
|
205
|
+
# Check for a predefined key binding.
|
206
|
+
if self.checkBind(:SCROLL, input) != false
|
207
|
+
#self.checkEarlyExit
|
208
|
+
complete = true
|
209
|
+
else
|
210
|
+
case input
|
211
|
+
when Ncurses::KEY_UP
|
212
|
+
self.KEY_UP
|
213
|
+
when Ncurses::KEY_DOWN
|
214
|
+
self.KEY_DOWN
|
215
|
+
when Ncurses::KEY_RIGHT
|
216
|
+
self.KEY_RIGHT
|
217
|
+
when Ncurses::KEY_LEFT
|
218
|
+
self.KEY_LEFT
|
219
|
+
when Ncurses::KEY_PPAGE
|
220
|
+
self.KEY_PPAGE
|
221
|
+
when Ncurses::KEY_NPAGE
|
222
|
+
self.KEY_NPAGE
|
223
|
+
when Ncurses::KEY_HOME
|
224
|
+
self.KEY_HOME
|
225
|
+
when Ncurses::KEY_END
|
226
|
+
self.KEY_END
|
227
|
+
when '$'
|
228
|
+
@left_char = @max_left_char
|
229
|
+
when '|'
|
230
|
+
@left_char = 0
|
231
|
+
when RNDK::KEY_ESC
|
232
|
+
self.setExitType(input)
|
233
|
+
complete = true
|
234
|
+
when Ncurses::ERR
|
235
|
+
self.setExitType(input)
|
236
|
+
complete = true
|
237
|
+
when RNDK::REFRESH
|
238
|
+
@screen.erase
|
239
|
+
@screen.refresh
|
240
|
+
when RNDK::KEY_TAB, Ncurses::KEY_ENTER, RNDK::KEY_RETURN
|
241
|
+
self.setExitType(input)
|
242
|
+
ret = @current_item
|
243
|
+
complete = true
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
if !complete && !(@post_process_func.nil?)
|
248
|
+
@post_process_func.call(:SCROLL, self, @post_process_data, input)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
if !complete
|
253
|
+
self.drawList(@box)
|
254
|
+
self.setExitType(0)
|
255
|
+
end
|
256
|
+
|
257
|
+
self.fixCursorPosition
|
258
|
+
@result_data = ret
|
259
|
+
|
260
|
+
#return ret != -1
|
261
|
+
return ret
|
262
|
+
end
|
263
|
+
|
264
|
+
def getCurrentTop
|
265
|
+
return @current_top
|
266
|
+
end
|
267
|
+
|
268
|
+
def setCurrentTop(item)
|
269
|
+
if item < 0
|
270
|
+
item = 0
|
271
|
+
elsif item > @max_top_item
|
272
|
+
item = @max_top_item
|
273
|
+
end
|
274
|
+
@current_top = item
|
275
|
+
|
276
|
+
self.setPosition(item);
|
277
|
+
end
|
278
|
+
|
279
|
+
# This moves the scroll field to the given location.
|
280
|
+
def move(xplace, yplace, relative, refresh_flag)
|
281
|
+
windows = [@win, @list_win, @shadow_win, @scrollbar_win]
|
282
|
+
self.move_specific(xplace, yplace, relative, refresh_flag,
|
283
|
+
windows, [])
|
284
|
+
end
|
285
|
+
|
286
|
+
# This function draws the scrolling list widget.
|
287
|
+
def draw(box)
|
288
|
+
# Draw in the shadow if we need to.
|
289
|
+
unless @shadow_win.nil?
|
290
|
+
Draw.drawShadow(@shadow_win)
|
291
|
+
end
|
292
|
+
|
293
|
+
self.drawTitle(@win)
|
294
|
+
|
295
|
+
# Draw in the scrolling list items.
|
296
|
+
self.drawList(box)
|
297
|
+
end
|
298
|
+
|
299
|
+
def drawCurrent
|
300
|
+
# Rehighlight the current menu item.
|
301
|
+
screen_pos = @item_pos[@current_item] - @left_char
|
302
|
+
highlight = if self.has_focus
|
303
|
+
then @highlight
|
304
|
+
else Ncurses::A_NORMAL
|
305
|
+
end
|
306
|
+
|
307
|
+
Draw.writeChtypeAttrib(@list_win,
|
308
|
+
if screen_pos >= 0 then screen_pos else 0 end,
|
309
|
+
@current_high, @item[@current_item], highlight, RNDK::HORIZONTAL,
|
310
|
+
if screen_pos >= 0 then 0 else 1 - screen_pos end,
|
311
|
+
@item_len[@current_item])
|
312
|
+
end
|
313
|
+
|
314
|
+
def drawList(box)
|
315
|
+
# If the list is empty, don't draw anything.
|
316
|
+
if @list_size > 0
|
317
|
+
# Redraw the list
|
318
|
+
(0...@view_size).each do |j|
|
319
|
+
k = j + @current_top
|
320
|
+
|
321
|
+
Draw.writeBlanks(@list_win, 0, j, RNDK::HORIZONTAL, 0,
|
322
|
+
@box_width - (2 * @border_size))
|
323
|
+
|
324
|
+
# Draw the elements in the scrolling list.
|
325
|
+
if k < @list_size
|
326
|
+
screen_pos = @item_pos[k] - @left_char
|
327
|
+
ypos = j
|
328
|
+
|
329
|
+
# Write in the correct line.
|
330
|
+
Draw.writeChtype(@list_win,
|
331
|
+
if screen_pos >= 0 then screen_pos else 1 end,
|
332
|
+
ypos, @item[k], RNDK::HORIZONTAL,
|
333
|
+
if screen_pos >= 0 then 0 else 1 - screen_pos end,
|
334
|
+
@item_len[k])
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
self.drawCurrent
|
339
|
+
|
340
|
+
# Determine where the toggle is supposed to be.
|
341
|
+
unless @scrollbar_win.nil?
|
342
|
+
@toggle_pos = (@current_item * @step).floor
|
343
|
+
|
344
|
+
# Make sure the toggle button doesn't go out of bounds.
|
345
|
+
if @toggle_pos >= Ncurses.getmaxy(@scrollbar_win)
|
346
|
+
@toggle_pos = Ncurses.getmaxy(@scrollbar_win) - 1
|
347
|
+
end
|
348
|
+
|
349
|
+
# Draw the scrollbar
|
350
|
+
Ncurses.mvwvline(@scrollbar_win,
|
351
|
+
0,
|
352
|
+
0,
|
353
|
+
Ncurses::ACS_CKBOARD,
|
354
|
+
Ncurses.getmaxy(@scrollbar_win))
|
355
|
+
|
356
|
+
Ncurses.mvwvline(@scrollbar_win,
|
357
|
+
@toggle_pos,
|
358
|
+
0,
|
359
|
+
' '.ord | Ncurses::A_REVERSE,
|
360
|
+
@toggle_size)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
# Box it if needed.
|
365
|
+
if box
|
366
|
+
Draw.drawObjBox(@win, self)
|
367
|
+
end
|
368
|
+
|
369
|
+
# Refresh the window
|
370
|
+
Ncurses.wrefresh @win
|
371
|
+
end
|
372
|
+
|
373
|
+
# This sets the background attribute of the widget.
|
374
|
+
def setBKattr(attrib)
|
375
|
+
Ncurses.wbkgd(@win, attrib)
|
376
|
+
Ncurses.wbkgd(@list_win, attrib)
|
377
|
+
unless @scrollbar_win.nil?
|
378
|
+
Ncurses.wbkgd(@scrollbar_win, attrib)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
# This function destroys
|
383
|
+
def destroy
|
384
|
+
self.cleanTitle
|
385
|
+
|
386
|
+
# Clean up the windows.
|
387
|
+
RNDK.deleteCursesWindow(@scrollbar_win)
|
388
|
+
RNDK.deleteCursesWindow(@shadow_win)
|
389
|
+
RNDK.deleteCursesWindow(@list_win)
|
390
|
+
RNDK.deleteCursesWindow(@win)
|
391
|
+
|
392
|
+
# Clean the key bindings.
|
393
|
+
self.cleanBindings(:SCROLL)
|
394
|
+
|
395
|
+
# Unregister this object
|
396
|
+
RNDK::Screen.unregister(:SCROLL, self)
|
397
|
+
end
|
398
|
+
|
399
|
+
# This function erases the scrolling list from the screen.
|
400
|
+
def erase
|
401
|
+
RNDK.eraseCursesWindow(@win)
|
402
|
+
RNDK.eraseCursesWindow(@shadow_win)
|
403
|
+
end
|
404
|
+
|
405
|
+
def allocListArrays(old_size, new_size)
|
406
|
+
result = true
|
407
|
+
new_list = Array.new(new_size)
|
408
|
+
new_len = Array.new(new_size)
|
409
|
+
new_pos = Array.new(new_size)
|
410
|
+
|
411
|
+
(0...old_size).each do |n|
|
412
|
+
new_list[n] = @item[n]
|
413
|
+
new_len[n] = @item_len[n]
|
414
|
+
new_pos[n] = @item_pos[n]
|
415
|
+
end
|
416
|
+
|
417
|
+
@item = new_list
|
418
|
+
@item_len = new_len
|
419
|
+
@item_pos = new_pos
|
420
|
+
|
421
|
+
return result
|
422
|
+
end
|
423
|
+
|
424
|
+
def allocListItem(which, work, used, number, value)
|
425
|
+
if number > 0
|
426
|
+
value = "%4d. %s" % [number, value]
|
427
|
+
end
|
428
|
+
|
429
|
+
item_len = []
|
430
|
+
item_pos = []
|
431
|
+
@item[which] = RNDK.char2Chtype(value, item_len, item_pos)
|
432
|
+
@item_len[which] = item_len[0]
|
433
|
+
@item_pos[which] = item_pos[0]
|
434
|
+
|
435
|
+
@item_pos[which] = RNDK.justifyString(@box_width,
|
436
|
+
@item_len[which], @item_pos[which])
|
437
|
+
return true
|
438
|
+
end
|
439
|
+
|
440
|
+
# This function creates the scrolling list information and sets up the
|
441
|
+
# needed variables for the scrolling list to work correctly.
|
442
|
+
def createItemList(numbers, list, list_size)
|
443
|
+
status = 0
|
444
|
+
if list_size > 0
|
445
|
+
widest_item = 0
|
446
|
+
x = 0
|
447
|
+
have = 0
|
448
|
+
temp = ''
|
449
|
+
if allocListArrays(0, list_size)
|
450
|
+
# Create the items in the scrolling list.
|
451
|
+
status = 1
|
452
|
+
(0...list_size).each do |x|
|
453
|
+
number = if numbers then x + 1 else 0 end
|
454
|
+
if !self.allocListItem(x, temp, have, number, list[x])
|
455
|
+
status = 0
|
456
|
+
break
|
457
|
+
end
|
458
|
+
|
459
|
+
widest_item = [@item_len[x], widest_item].max
|
460
|
+
end
|
461
|
+
|
462
|
+
if status
|
463
|
+
self.updateViewWidth(widest_item);
|
464
|
+
|
465
|
+
# Keep the boolean flag 'numbers'
|
466
|
+
@numbers = numbers
|
467
|
+
end
|
468
|
+
end
|
469
|
+
else
|
470
|
+
status = 1 # null list is ok - for a while
|
471
|
+
end
|
472
|
+
|
473
|
+
return status
|
474
|
+
end
|
475
|
+
|
476
|
+
# This sets certain attributes of the scrolling list.
|
477
|
+
def set(list, list_size, numbers, highlight, box)
|
478
|
+
self.setItems(list, list_size, numbers)
|
479
|
+
self.setHighlight(highlight)
|
480
|
+
self.setBox(box)
|
481
|
+
end
|
482
|
+
|
483
|
+
# This sets the scrolling list items
|
484
|
+
def setItems(list, list_size, numbers)
|
485
|
+
if self.createItemList(numbers, list, list_size) <= 0
|
486
|
+
return
|
487
|
+
end
|
488
|
+
|
489
|
+
# Clean up the display.
|
490
|
+
(0...@view_size).each do |x|
|
491
|
+
Draw.writeBlanks(@win, 1, x, RNDK::HORIZONTAL, 0, @box_width - 2);
|
492
|
+
end
|
493
|
+
|
494
|
+
self.setViewSize(list_size)
|
495
|
+
self.setPosition(0)
|
496
|
+
@left_char = 0
|
497
|
+
end
|
498
|
+
|
499
|
+
def getItems(list)
|
500
|
+
(0...@list_size).each do |x|
|
501
|
+
list << RNDK.chtype2Char(@item[x])
|
502
|
+
end
|
503
|
+
|
504
|
+
return @list_size
|
505
|
+
end
|
506
|
+
|
507
|
+
# This sets the highlight of the scrolling list.
|
508
|
+
def setHighlight(highlight)
|
509
|
+
@highlight = highlight
|
510
|
+
end
|
511
|
+
|
512
|
+
def getHighlight(highlight)
|
513
|
+
return @highlight
|
514
|
+
end
|
515
|
+
|
516
|
+
# Resequence the numbers after an insertion/deletion.
|
517
|
+
def resequence
|
518
|
+
if @numbers
|
519
|
+
(0...@list_size).each do |j|
|
520
|
+
target = @item[j]
|
521
|
+
|
522
|
+
source = "%4d. %s" % [j + 1, ""]
|
523
|
+
|
524
|
+
k = 0
|
525
|
+
while k < source.size
|
526
|
+
# handle deletions that change the length of number
|
527
|
+
if source[k] == "." && target[k] != "."
|
528
|
+
source = source[0...k] + source[k+1..-1]
|
529
|
+
end
|
530
|
+
|
531
|
+
target[k] &= Ncurses::A_ATTRIBUTES
|
532
|
+
target[k] |= source[k].ord
|
533
|
+
k += 1
|
534
|
+
end
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
def insertListItem(item)
|
540
|
+
@item = @item[0..item] + @item[item..-1]
|
541
|
+
@item_len = @item_len[0..item] + @item_len[item..-1]
|
542
|
+
@item_pos = @item_pos[0..item] + @item_pos[item..-1]
|
543
|
+
return true
|
544
|
+
end
|
545
|
+
|
546
|
+
# This adds a single item to a scrolling list, at the end of the list.
|
547
|
+
def addItem(item)
|
548
|
+
item_number = @list_size
|
549
|
+
widest_item = self.WidestItem
|
550
|
+
temp = ''
|
551
|
+
have = 0
|
552
|
+
|
553
|
+
if self.allocListArrays(@list_size, @list_size + 1) &&
|
554
|
+
self.allocListItem(item_number, temp, have,
|
555
|
+
if @numbers then item_number + 1 else 0 end,
|
556
|
+
item)
|
557
|
+
# Determine the size of the widest item.
|
558
|
+
widest_item = [@item_len[item_number], widest_item].max
|
559
|
+
|
560
|
+
self.updateViewWidth(widest_item)
|
561
|
+
self.setViewSize(@list_size + 1)
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
# This adds a single item to a scrolling list before the current item
|
566
|
+
def insertItem(item)
|
567
|
+
widest_item = self.WidestItem
|
568
|
+
temp = ''
|
569
|
+
have = 0
|
570
|
+
|
571
|
+
if self.allocListArrays(@list_size, @list_size + 1) &&
|
572
|
+
self.insertListItem(@current_item) &&
|
573
|
+
self.allocListItem(@current_item, temp, have,
|
574
|
+
if @numbers then @current_item + 1 else 0 end,
|
575
|
+
item)
|
576
|
+
# Determine the size of the widest item.
|
577
|
+
widest_item = [@item_len[@current_item], widest_item].max
|
578
|
+
|
579
|
+
self.updateViewWidth(widest_item)
|
580
|
+
self.setViewSize(@list_size + 1)
|
581
|
+
self.resequence
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
# This removes a single item from a scrolling list.
|
586
|
+
def deleteItem(position)
|
587
|
+
if position >= 0 && position < @list_size
|
588
|
+
# Adjust the list
|
589
|
+
@item = @item[0...position] + @item[position+1..-1]
|
590
|
+
@item_len = @item_len[0...position] + @item_len[position+1..-1]
|
591
|
+
@item_pos = @item_pos[0...position] + @item_pos[position+1..-1]
|
592
|
+
|
593
|
+
self.setViewSize(@list_size - 1)
|
594
|
+
|
595
|
+
if @list_size > 0
|
596
|
+
self.resequence
|
597
|
+
end
|
598
|
+
|
599
|
+
if @list_size < self.maxViewSize
|
600
|
+
@win.werase # force the next redraw to be complete
|
601
|
+
end
|
602
|
+
|
603
|
+
# do this to update the view size, etc
|
604
|
+
self.setPosition(@current_item)
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
def focus
|
609
|
+
self.drawCurrent
|
610
|
+
Ncurses.wrefresh @list_win
|
611
|
+
end
|
612
|
+
|
613
|
+
def unfocus
|
614
|
+
self.drawCurrent
|
615
|
+
Ncurses.wrefresh @list_win
|
616
|
+
end
|
617
|
+
|
618
|
+
def AvailableWidth
|
619
|
+
@box_width - (2 * @border_size)
|
620
|
+
end
|
621
|
+
|
622
|
+
def updateViewWidth(widest)
|
623
|
+
@max_left_char = if @box_width > widest
|
624
|
+
then 0
|
625
|
+
else widest - self.AvailableWidth
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
def WidestItem
|
630
|
+
@max_left_char + self.AvailableWidth
|
631
|
+
end
|
632
|
+
end
|
633
|
+
end
|