cdk 0.9.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 +7 -0
- data/lib/cdk.rb +916 -0
- data/lib/cdk/alphalist.rb +562 -0
- data/lib/cdk/buttonbox.rb +354 -0
- data/lib/cdk/calendar.rb +770 -0
- data/lib/cdk/cdk_objs.rb +463 -0
- data/lib/cdk/dialog.rb +727 -0
- data/lib/cdk/display.rb +63 -0
- data/lib/cdk/draw.rb +233 -0
- data/lib/cdk/dscale.rb +13 -0
- data/lib/cdk/entry.rb +556 -0
- data/lib/cdk/fscale.rb +44 -0
- data/lib/cdk/fselect.rb +940 -0
- data/lib/cdk/fslider.rb +61 -0
- data/lib/cdk/histogram.rb +410 -0
- data/lib/cdk/itemlist.rb +475 -0
- data/lib/cdk/label.rb +207 -0
- data/lib/cdk/marquee.rb +241 -0
- data/lib/cdk/matrix.rb +1176 -0
- data/lib/cdk/mentry.rb +614 -0
- data/lib/cdk/menu.rb +448 -0
- data/lib/cdk/radio.rb +533 -0
- data/lib/cdk/scale.rb +525 -0
- data/lib/cdk/screen.rb +280 -0
- data/lib/cdk/scroll.rb +994 -0
- data/lib/cdk/scroller.rb +183 -0
- data/lib/cdk/selection.rb +619 -0
- data/lib/cdk/slider.rb +541 -0
- data/lib/cdk/swindow.rb +762 -0
- data/lib/cdk/template.rb +562 -0
- data/lib/cdk/traverse.rb +289 -0
- data/lib/cdk/uscale.rb +14 -0
- data/lib/cdk/uslider.rb +14 -0
- data/lib/cdk/viewer.rb +812 -0
- metadata +91 -0
data/lib/cdk/itemlist.rb
ADDED
@@ -0,0 +1,475 @@
|
|
1
|
+
require_relative 'cdk_objs'
|
2
|
+
|
3
|
+
module CDK
|
4
|
+
class ITEMLIST < CDK::CDKOBJS
|
5
|
+
def initialize(cdkscreen, xplace, yplace, title, label, item, count,
|
6
|
+
default_item, box, shadow)
|
7
|
+
super()
|
8
|
+
parent_width = cdkscreen.window.getmaxx
|
9
|
+
parent_height = cdkscreen.window.getmaxy
|
10
|
+
field_width = 0
|
11
|
+
|
12
|
+
if !self.createList(item, count)
|
13
|
+
self.destroy
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
self.setBox(box)
|
18
|
+
box_height = (@border_size * 2) + 1
|
19
|
+
|
20
|
+
# Set some basic values of the item list
|
21
|
+
@label = ''
|
22
|
+
@label_len = 0
|
23
|
+
@label_win = nil
|
24
|
+
|
25
|
+
# Translate the label string to a chtype array
|
26
|
+
if !(label.nil?) && label.size > 0
|
27
|
+
label_len = []
|
28
|
+
@label = CDK.char2Chtype(label, label_len, [])
|
29
|
+
@label_len = label_len[0]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Set the box width. Allow an extra char in field width for cursor
|
33
|
+
field_width = self.maximumFieldWidth + 1
|
34
|
+
box_width = field_width + @label_len + 2 * @border_size
|
35
|
+
box_width = self.setTitle(title, box_width)
|
36
|
+
box_height += @title_lines
|
37
|
+
|
38
|
+
# Make sure we didn't extend beyond the dimensions of the window
|
39
|
+
@box_width = [box_width, parent_width].min
|
40
|
+
@box_height = [box_height, parent_height].min
|
41
|
+
self.updateFieldWidth
|
42
|
+
|
43
|
+
# Rejustify the x and y positions if we need to.
|
44
|
+
xtmp = [xplace]
|
45
|
+
ytmp = [yplace]
|
46
|
+
CDK.alignxy(cdkscreen.window, xtmp, ytmp, box_width, box_height)
|
47
|
+
xpos = xtmp[0]
|
48
|
+
ypos = ytmp[0]
|
49
|
+
|
50
|
+
# Make the window.
|
51
|
+
@win = Ncurses::WINDOW.new(box_height, box_width, ypos, xpos)
|
52
|
+
if @win.nil?
|
53
|
+
self.destroy
|
54
|
+
return nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# Make the label window if there was a label.
|
58
|
+
if @label.size > 0
|
59
|
+
@label_win = @win.subwin(1, @label_len,
|
60
|
+
ypos + @border_size + @title_lines,
|
61
|
+
xpos + @border_size)
|
62
|
+
|
63
|
+
if @label_win.nil?
|
64
|
+
self.destroy
|
65
|
+
return nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@win.keypad(true)
|
70
|
+
|
71
|
+
# Make the field window.
|
72
|
+
if !self.createFieldWin(
|
73
|
+
ypos + @border_size + @title_lines,
|
74
|
+
xpos + @label_len + @border_size)
|
75
|
+
self.destroy
|
76
|
+
return nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# Set up the rest of the structure
|
80
|
+
@screen = cdkscreen
|
81
|
+
@parent = cdkscreen.window
|
82
|
+
@shadow_win = nil
|
83
|
+
@accepts_focus = true
|
84
|
+
@shadow = shadow
|
85
|
+
|
86
|
+
# Set the default item.
|
87
|
+
if default_item >= 0 && default_item < @list_size
|
88
|
+
@current_item = default_item
|
89
|
+
@default_item = default_item
|
90
|
+
else
|
91
|
+
@current_item = 0
|
92
|
+
@default_item = 0
|
93
|
+
end
|
94
|
+
|
95
|
+
# Do we want a shadow?
|
96
|
+
if shadow
|
97
|
+
@shadow_win = Ncurses::WINDOW.new(box_height, box_width,
|
98
|
+
ypos + 1, xpos + 1)
|
99
|
+
if @shadow_win.nil?
|
100
|
+
self.destroy
|
101
|
+
return nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Register this baby.
|
106
|
+
cdkscreen.register(:ITEMLIST, self)
|
107
|
+
end
|
108
|
+
|
109
|
+
# This allows the user to play with the widget.
|
110
|
+
def activate(actions)
|
111
|
+
ret = -1
|
112
|
+
|
113
|
+
# Draw the widget.
|
114
|
+
self.draw(@box)
|
115
|
+
self.drawField(true)
|
116
|
+
|
117
|
+
if actions.nil? || actions.size == 0
|
118
|
+
input = 0
|
119
|
+
|
120
|
+
while true
|
121
|
+
input = self.getch([])
|
122
|
+
|
123
|
+
# Inject the character into the widget.
|
124
|
+
ret = self.inject(input)
|
125
|
+
if @exit_type != :EARLY_EXIT
|
126
|
+
return ret
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
# Inject each character one at a time.
|
131
|
+
actions.each do |action|
|
132
|
+
ret = self.inject(action)
|
133
|
+
if @exit_type != :EARLY_EXIT
|
134
|
+
return ret
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Set the exit type and exit.
|
140
|
+
self.setExitType(0)
|
141
|
+
return ret
|
142
|
+
end
|
143
|
+
|
144
|
+
# This injects a single character into the widget.
|
145
|
+
def inject(input)
|
146
|
+
pp_return = 1
|
147
|
+
ret = -1
|
148
|
+
complete = false
|
149
|
+
|
150
|
+
# Set the exit type.
|
151
|
+
self.setExitType(0)
|
152
|
+
|
153
|
+
# Draw the widget field
|
154
|
+
self.drawField(true)
|
155
|
+
|
156
|
+
# Check if there is a pre-process function to be called.
|
157
|
+
unless @pre_process_func.nil?
|
158
|
+
pp_return = @pre_process_func.call(:ITEMLIST, self,
|
159
|
+
@pre_process_data, input)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Should we continue?
|
163
|
+
if pp_return != 0
|
164
|
+
# Check a predefined binding.
|
165
|
+
if self.checkBind(:ITEMLIST, input)
|
166
|
+
complete = true
|
167
|
+
else
|
168
|
+
case input
|
169
|
+
when Ncurses::KEY_UP, Ncurses::KEY_RIGHT, ' '.ord, '+'.ord, 'n'.ord
|
170
|
+
if @current_item < @list_size - 1
|
171
|
+
@current_item += 1
|
172
|
+
else
|
173
|
+
@current_item = 0
|
174
|
+
end
|
175
|
+
when Ncurses::KEY_DOWN, Ncurses::KEY_LEFT, '-'.ord, 'p'.ord
|
176
|
+
if @current_item > 0
|
177
|
+
@current_item -= 1
|
178
|
+
else
|
179
|
+
@current_item = @list_size - 1
|
180
|
+
end
|
181
|
+
when 'd'.ord, 'D'.ord
|
182
|
+
@current_item = @default_item
|
183
|
+
when '0'.ord
|
184
|
+
@current_item = 0
|
185
|
+
when '$'.ord
|
186
|
+
@current_item = @list_size - 1
|
187
|
+
when CDK::KEY_ESC
|
188
|
+
self.setExitType(input)
|
189
|
+
complete = true
|
190
|
+
when Ncurses::ERR
|
191
|
+
self.setExitType(input)
|
192
|
+
complete = true
|
193
|
+
when CDK::KEY_TAB, CDK::KEY_RETURN, Ncurses::KEY_ENTER
|
194
|
+
self.setExitType(input)
|
195
|
+
ret = @current_item
|
196
|
+
complete = true
|
197
|
+
when CDK::REFRESH
|
198
|
+
@screen.erase
|
199
|
+
@screen.refresh
|
200
|
+
else
|
201
|
+
CDK.Beep
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Should we call a post-process?
|
206
|
+
if !complete && !(@post_process_func.nil?)
|
207
|
+
@post_process_func.call(:ITEMLIST, self, @post_process_data, input)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
if !complete
|
212
|
+
self.drawField(true)
|
213
|
+
self.setExitType(0)
|
214
|
+
end
|
215
|
+
|
216
|
+
@result_data = ret
|
217
|
+
return ret
|
218
|
+
end
|
219
|
+
|
220
|
+
# This moves the itemlist field to the given location.
|
221
|
+
def move(xplace, yplace, relative, refresh_flag)
|
222
|
+
windows = [@win, @field_win, @label_win, @shadow_win]
|
223
|
+
self.move_specific(xplace, yplace, relative, refresh_flag,
|
224
|
+
windows, [])
|
225
|
+
end
|
226
|
+
|
227
|
+
# This draws the widget on the screen.
|
228
|
+
def draw(box)
|
229
|
+
# Did we ask for a shadow?
|
230
|
+
unless @shadow_win.nil?
|
231
|
+
Draw.drawShadow(@shadow_win)
|
232
|
+
end
|
233
|
+
|
234
|
+
self.drawTitle(@win)
|
235
|
+
|
236
|
+
# Draw in the label to the widget.
|
237
|
+
unless @label_win.nil?
|
238
|
+
Draw.writeChtype(@label_win, 0, 0, @label, CDK::HORIZONTAL,
|
239
|
+
0, @label.size)
|
240
|
+
end
|
241
|
+
|
242
|
+
# Box the widget if asked.
|
243
|
+
if box
|
244
|
+
Draw.drawObjBox(@win, self)
|
245
|
+
end
|
246
|
+
|
247
|
+
@win.wrefresh
|
248
|
+
|
249
|
+
# Draw in the field.
|
250
|
+
self.drawField(false)
|
251
|
+
end
|
252
|
+
|
253
|
+
# This sets the background attribute of the widget
|
254
|
+
def setBKattr(attrib)
|
255
|
+
@win.wbkgd(attrib)
|
256
|
+
@field_win.wbkgd(attrib)
|
257
|
+
unless @label_win.nil?
|
258
|
+
@label_win.wbkgd(attrib)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
# This function draws the contents of the field.
|
263
|
+
def drawField(highlight)
|
264
|
+
# Declare local vars.
|
265
|
+
current_item = @current_item
|
266
|
+
|
267
|
+
# Determine how much we have to draw.
|
268
|
+
len = [@item_len[current_item], @field_width].min
|
269
|
+
|
270
|
+
# Erase the field window.
|
271
|
+
@field_win.werase
|
272
|
+
|
273
|
+
# Draw in the current item in the field.
|
274
|
+
(0...len).each do |x|
|
275
|
+
c = @item[current_item][x]
|
276
|
+
|
277
|
+
if highlight
|
278
|
+
c = c.ord | Ncurses::A_REVERSE
|
279
|
+
end
|
280
|
+
|
281
|
+
@field_win.mvwaddch(0, x + @item_pos[current_item], c)
|
282
|
+
end
|
283
|
+
|
284
|
+
# Redraw the field window.
|
285
|
+
@field_win.wrefresh
|
286
|
+
end
|
287
|
+
|
288
|
+
# This function removes the widget from the screen.
|
289
|
+
def erase
|
290
|
+
if self.validCDKObject
|
291
|
+
CDK.eraseCursesWindow(@field_win)
|
292
|
+
CDK.eraseCursesWindow(@label_win)
|
293
|
+
CDK.eraseCursesWindow(@win)
|
294
|
+
CDK.eraseCursesWindow(@shadow_win)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def destroyInfo
|
299
|
+
@list_size = 0
|
300
|
+
@item = ''
|
301
|
+
end
|
302
|
+
|
303
|
+
# This function destroys the widget and all the memory it used.
|
304
|
+
def destroy
|
305
|
+
self.cleanTitle
|
306
|
+
self.destroyInfo
|
307
|
+
|
308
|
+
# Delete the windows
|
309
|
+
CDK.deleteCursesWindow(@field_win)
|
310
|
+
CDK.deleteCursesWindow(@label_win)
|
311
|
+
CDK.deleteCursesWindow(@shadow_win)
|
312
|
+
CDK.deleteCursesWindow(@win)
|
313
|
+
|
314
|
+
# Clean the key bindings.
|
315
|
+
self.cleanBindings(:ITEMLIST)
|
316
|
+
|
317
|
+
CDK::SCREEN.unregister(:ITEMLIST, self)
|
318
|
+
end
|
319
|
+
|
320
|
+
# This sets multiple attributes of the widget.
|
321
|
+
def set(list, count, current, box)
|
322
|
+
self.setValues(list, count, current)
|
323
|
+
self.setBox(box)
|
324
|
+
end
|
325
|
+
|
326
|
+
# This function sets the contents of the list
|
327
|
+
def setValues(item, count, default_item)
|
328
|
+
if self.createList(item, count)
|
329
|
+
old_width = @field_width
|
330
|
+
|
331
|
+
# Set the default item.
|
332
|
+
if default_item >= 0 && default_item < @list_size
|
333
|
+
@current_item = default_item
|
334
|
+
@default_item = default_item
|
335
|
+
end
|
336
|
+
|
337
|
+
# This will not resize the outer windows but can still make a usable
|
338
|
+
# field width if the title made the outer window wide enough
|
339
|
+
self.updateFieldWidth
|
340
|
+
if @field_width > old_width
|
341
|
+
self.createFieldWin(@field_win.getbegy, @field_win.getbegx)
|
342
|
+
end
|
343
|
+
|
344
|
+
# Draw the field.
|
345
|
+
self.erase
|
346
|
+
self.draw(@box)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def getValues(size)
|
351
|
+
size << @list_size
|
352
|
+
return @item
|
353
|
+
end
|
354
|
+
|
355
|
+
# This sets the default/current item of the itemlist
|
356
|
+
def setCurrentItem(current_item)
|
357
|
+
# Set the default item.
|
358
|
+
if current_item >= 0 && current_item < @list_size
|
359
|
+
@current_item = current_item
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
def getCurrentItem
|
364
|
+
return @current_item
|
365
|
+
end
|
366
|
+
|
367
|
+
# This sets the default item in the list.
|
368
|
+
def setDefaultItem(default_item)
|
369
|
+
# Make sure the item is in the correct range.
|
370
|
+
if default_item < 0
|
371
|
+
@default_item = 0
|
372
|
+
elsif default_item >= @list_size
|
373
|
+
@default_item = @list_size - 1
|
374
|
+
else
|
375
|
+
@default_item = default_item
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def getDefaultItem
|
380
|
+
return @default_item
|
381
|
+
end
|
382
|
+
|
383
|
+
def focus
|
384
|
+
self.drawField(true)
|
385
|
+
end
|
386
|
+
|
387
|
+
def unfocus
|
388
|
+
self.drawField(false)
|
389
|
+
end
|
390
|
+
|
391
|
+
def createList(item, count)
|
392
|
+
status = false
|
393
|
+
new_items = []
|
394
|
+
new_pos = []
|
395
|
+
new_len = []
|
396
|
+
if count >= 0
|
397
|
+
field_width = 0
|
398
|
+
|
399
|
+
# Go through the list and determine the widest item.
|
400
|
+
status = true
|
401
|
+
(0...count).each do |x|
|
402
|
+
# Copy the item to the list.
|
403
|
+
lentmp = []
|
404
|
+
postmp = []
|
405
|
+
new_items << CDK.char2Chtype(item[x], lentmp, postmp)
|
406
|
+
new_len << lentmp[0]
|
407
|
+
new_pos << postmp[0]
|
408
|
+
if new_items[0] == 0
|
409
|
+
status = false
|
410
|
+
break
|
411
|
+
end
|
412
|
+
field_width = [field_width, new_len[x]].max
|
413
|
+
end
|
414
|
+
|
415
|
+
# Now we need to justify the strings.
|
416
|
+
(0...count).each do |x|
|
417
|
+
new_pos[x] = CDK.justifyString(field_width + 1,
|
418
|
+
new_len[x], new_pos[x])
|
419
|
+
end
|
420
|
+
|
421
|
+
if status
|
422
|
+
self.destroyInfo
|
423
|
+
|
424
|
+
# Copy in the new information
|
425
|
+
@list_size = count
|
426
|
+
@item = new_items
|
427
|
+
@item_pos = new_pos
|
428
|
+
@item_len = new_len
|
429
|
+
end
|
430
|
+
else
|
431
|
+
self.destroyInfo
|
432
|
+
status = true
|
433
|
+
end
|
434
|
+
|
435
|
+
return status
|
436
|
+
end
|
437
|
+
|
438
|
+
# Go through the list and determine the widest item.
|
439
|
+
def maximumFieldWidth
|
440
|
+
max_width = -2**30
|
441
|
+
|
442
|
+
(0...@list_size).each do |x|
|
443
|
+
max_width = [max_width, @item_len[x]].max
|
444
|
+
end
|
445
|
+
max_width = [max_width, 0].max
|
446
|
+
|
447
|
+
return max_width
|
448
|
+
end
|
449
|
+
|
450
|
+
def updateFieldWidth
|
451
|
+
want = self.maximumFieldWidth + 1
|
452
|
+
have = @box_width - @label_len - 2 * @border_size
|
453
|
+
@field_width = [want, have].min
|
454
|
+
end
|
455
|
+
|
456
|
+
# Make the field window.
|
457
|
+
def createFieldWin(ypos, xpos)
|
458
|
+
@field_win = @win.subwin(1, @field_width, ypos, xpos)
|
459
|
+
unless @field_win.nil?
|
460
|
+
@field_win.keypad(true)
|
461
|
+
@input_window = @field_win
|
462
|
+
return true
|
463
|
+
end
|
464
|
+
return false
|
465
|
+
end
|
466
|
+
|
467
|
+
def position
|
468
|
+
super(@win)
|
469
|
+
end
|
470
|
+
|
471
|
+
def object_type
|
472
|
+
:ITEMLIST
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|