Class: CDK::ITEMLIST

Inherits:
CDKOBJS show all
Defined in:
lib/cdk/components/itemlist.rb

Instance Attribute Summary

Attributes included from HasTitle

#title_attrib

Attributes included from HasScreen

#is_visible, #screen, #screen_index

Attributes included from ExitConditions

#exit_type

Attributes included from Bindings

#binding_list

Attributes included from Focusable

#accepts_focus, #has_focus

Attributes included from Borders

#BXAttr, #HZChar, #LLChar, #LRChar, #ULChar, #URChar, #VTChar, #border_size, #box

Instance Method Summary collapse

Methods inherited from CDKOBJS

#setBackgroundColor, #timeout, #validCDKObject, #validObjType

Methods included from WindowHooks

#refreshData, #saveData

Methods included from WindowInput

#getc, #getch, #setPostProcess, #setPreProcess

Methods included from HasTitle

#cleanTitle, #drawTitle, #init_title, #setTitle

Methods included from HasScreen

#SCREEN_XPOS, #SCREEN_YPOS, #init_screen, #wrefresh

Methods included from ExitConditions

#init_exit_conditions, #resetExitType, #setExitType

Methods included from Bindings

#bind, #bindableObject, #checkBind, #cleanBindings, #init_bindings, #isBind, #unbind

Methods included from Focusable

#init_focus

Methods included from Borders

#getBox, #init_borders, #setBXattr, #setBox, #setHZchar, #setLLchar, #setLRchar, #setULchar, #setURchar, #setVTchar

Methods included from Movement

#move_specific

Methods included from Converters

#char2Chtype, #charOf, #chtype2Char, #chtype2String, #decode_attribute, #encode_attribute

Methods included from Justifications

#justify_string

Methods included from Alignments

#alignxy

Constructor Details

#initialize(cdkscreen, xplace, yplace, title, label, item, count, default_item, box, shadow) ⇒ ITEMLIST

Returns a new instance of ITEMLIST.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/cdk/components/itemlist.rb', line 5

def initialize(cdkscreen, xplace, yplace, title, label, item, count,
    default_item, box, shadow)
  super()
  parent_width = cdkscreen.window.getmaxx
  parent_height = cdkscreen.window.getmaxy
  field_width = 0

  if !self.createList(item, count)
    self.destroy
    return nil
  end

  self.setBox(box)
  box_height = (@border_size * 2) + 1

  # Set some basic values of the item list
  @label = ''
  @label_len = 0
  @label_win = nil

  # Translate the label string to a chtype array
  if !(label.nil?) && label.size > 0
    label_len = []
    @label = char2Chtype(label, label_len, [])
    @label_len = label_len[0]
  end

  # Set the box width. Allow an extra char in field width for cursor
  field_width = self.maximumFieldWidth + 1
  box_width = field_width + @label_len + 2 * @border_size
  box_width = self.setTitle(title, box_width)
  box_height += @title_lines

  # Make sure we didn't extend beyond the dimensions of the window
  @box_width = [box_width, parent_width].min
  @box_height = [box_height, parent_height].min
  self.updateFieldWidth

  # Rejustify the x and y positions if we need to.
  xtmp = [xplace]
  ytmp = [yplace]
  alignxy(cdkscreen.window, xtmp, ytmp, box_width, box_height)
  xpos = xtmp[0]
  ypos = ytmp[0]

  # Make the window.
  @win = Ncurses::WINDOW.new(box_height, box_width, ypos, xpos)
  if @win.nil?
    self.destroy
    return nil
  end

  # Make the label window if there was a label.
  if @label.size > 0
    @label_win = @win.subwin(1, @label_len,
        ypos + @border_size + @title_lines,
        xpos + @border_size)

    if @label_win.nil?
      self.destroy
      return nil
    end
  end

  @win.keypad(true)

  # Make the field window.
  if !self.createFieldWin(
      ypos + @border_size + @title_lines,
      xpos + @label_len + @border_size)
    self.destroy
    return nil
  end

  # Set up the rest of the structure
  @screen = cdkscreen
  @parent = cdkscreen.window
  @shadow_win = nil
  @accepts_focus = true
  @shadow = shadow

  # Set the default item.
  if default_item >= 0 && default_item < @list_size
    @current_item = default_item
    @default_item = default_item
  else
    @current_item = 0
    @default_item = 0
  end

  # Do we want a shadow?
  if shadow
    @shadow_win = Ncurses::WINDOW.new(box_height, box_width,
        ypos + 1, xpos + 1)
    if @shadow_win.nil?
      self.destroy
      return nil
    end
  end

  # Register this baby.
  cdkscreen.register(:ITEMLIST, self)
end

Instance Method Details

#activate(actions) ⇒ Object

This allows the user to play with the widget.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/cdk/components/itemlist.rb', line 110

def activate(actions)
  ret = -1

  # Draw the widget.
  self.draw(@box)
  self.drawField(true)

  if actions.nil? || actions.size == 0
    input = 0
    
    while true
      input = self.getch([])

      # Inject the character into the widget.
      ret = self.inject(input)
      if @exit_type != :EARLY_EXIT
        return ret
      end
    end
  else
    # Inject each character one at a time.
    actions.each do |action|
      ret = self.inject(action)
      if @exit_type != :EARLY_EXIT
        return ret
      end
    end
  end

  # Set the exit type and exit.
  self.setExitType(0)
  return ret
end

#createFieldWin(ypos, xpos) ⇒ Object

Make the field window.



457
458
459
460
461
462
463
464
465
# File 'lib/cdk/components/itemlist.rb', line 457

def createFieldWin(ypos, xpos)
  @field_win = @win.subwin(1, @field_width, ypos, xpos)
  unless @field_win.nil?
    @field_win.keypad(true)
    @input_window = @field_win
    return true
  end
  return false
end

#createList(item, count) ⇒ Object



391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
# File 'lib/cdk/components/itemlist.rb', line 391

def createList(item, count)
  status = false
  new_items = []
  new_pos = []
  new_len = []
  if count >= 0
    field_width = 0

    # Go through the list and determine the widest item.
    status = true
    (0...count).each do |x|
      # Copy the item to the list.
      lentmp = []
      postmp = []
      new_items << char2Chtype(item[x], lentmp, postmp)
      new_len << lentmp[0]
      new_pos << postmp[0]
      if new_items[0] == 0
        status = false
        break
      end
      field_width = [field_width, new_len[x]].max
    end

    # Now we need to justify the strings.
    (0...count).each do |x|
      new_pos[x] = justify_string(field_width + 1,
          new_len[x], new_pos[x])
    end

    if status
      self.destroyInfo

      # Copy in the new information
      @list_size = count
      @item = new_items
      @item_pos = new_pos
      @item_len = new_len
    end
  else
    self.destroyInfo
    status = true
  end

  return status
end

#destroyObject

This function destroys the widget and all the memory it used.



304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/cdk/components/itemlist.rb', line 304

def destroy
  self.cleanTitle
  self.destroyInfo

  # Delete the windows
  CDK.deleteCursesWindow(@field_win)
  CDK.deleteCursesWindow(@label_win)
  CDK.deleteCursesWindow(@shadow_win)
  CDK.deleteCursesWindow(@win)

  # Clean the key bindings.
  self.cleanBindings(:ITEMLIST)

  CDK::SCREEN.unregister(:ITEMLIST, self)
end

#destroyInfoObject



298
299
300
301
# File 'lib/cdk/components/itemlist.rb', line 298

def destroyInfo
  @list_size = 0
  @item = ''
end

#draw(box) ⇒ Object

This draws the widget on the screen.



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/cdk/components/itemlist.rb', line 228

def draw(box)
  # Did we ask for a shadow?
  unless @shadow_win.nil?
    Draw.drawShadow(@shadow_win)
  end

  self.drawTitle(@win)

  # Draw in the label to the widget.
  unless @label_win.nil?
    Draw.writeChtype(@label_win, 0, 0, @label, CDK::HORIZONTAL,
        0, @label.size)
  end

  # Box the widget if asked.
  if box
    Draw.drawObjBox(@win, self)
  end

  wrefresh

  # Draw in the field.
  self.drawField(false)
end

#drawField(highlight) ⇒ Object

This function draws the contents of the field.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/cdk/components/itemlist.rb', line 263

def drawField(highlight)
  # Declare local vars.
  current_item = @current_item

  # Determine how much we have to draw.
  len = [@item_len[current_item], @field_width].min

  # Erase the field window.
  @field_win.werase

  # Draw in the current item in the field.
  (0...len).each do |x|
    c = @item[current_item][x]

    if highlight
      c = c.ord | Ncurses::A_REVERSE
    end

    @field_win.mvwaddch(0, x + @item_pos[current_item], c)
  end

  # Redraw the field window.
  wrefresh(@field_win)
end

#eraseObject

This function removes the widget from the screen.



289
290
291
292
293
294
295
296
# File 'lib/cdk/components/itemlist.rb', line 289

def erase
  if self.validCDKObject
    CDK.eraseCursesWindow(@field_win)
    CDK.eraseCursesWindow(@label_win)
    CDK.eraseCursesWindow(@win)
    CDK.eraseCursesWindow(@shadow_win)
  end
end

#focusObject



383
384
385
# File 'lib/cdk/components/itemlist.rb', line 383

def focus
  self.drawField(true)
end

#getCurrentItemObject



363
364
365
# File 'lib/cdk/components/itemlist.rb', line 363

def getCurrentItem
  return @current_item
end

#getDefaultItemObject



379
380
381
# File 'lib/cdk/components/itemlist.rb', line 379

def getDefaultItem
  return @default_item
end

#getValues(size) ⇒ Object



350
351
352
353
# File 'lib/cdk/components/itemlist.rb', line 350

def getValues(size)
  size << @list_size
  return @item
end

#inject(input) ⇒ Object

This injects a single character into the widget.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/cdk/components/itemlist.rb', line 145

def inject(input)
  pp_return = 1
  ret = -1
  @complete = false

  # Set the exit type.
  self.setExitType(0)

  # Draw the widget field
  self.drawField(true)

  # Check if there is a pre-process function to be called.
  unless @pre_process_func.nil?
    pp_return = @pre_process_func.call(:ITEMLIST, self,
        @pre_process_data, input)
  end

  # Should we continue?
  if pp_return != 0
    # Check a predefined binding.
    if self.checkBind(:ITEMLIST, input)
      @complete = true
    else
      case input
      when Ncurses::KEY_UP, Ncurses::KEY_RIGHT, ' '.ord, '+'.ord, 'n'.ord
        if @current_item < @list_size - 1
          @current_item += 1
        else
          @current_item = 0
        end
      when Ncurses::KEY_DOWN, Ncurses::KEY_LEFT, '-'.ord, 'p'.ord
        if @current_item > 0
          @current_item -= 1
        else
          @current_item = @list_size - 1
        end
      when 'd'.ord, 'D'.ord
        @current_item = @default_item
      when '0'.ord
        @current_item = 0
      when '$'.ord
        @current_item = @list_size - 1
      when CDK::KEY_ESC
        self.setExitType(input)
        @complete = true
      when Ncurses::ERR
        self.setExitType(input)
        @complete = true
      when CDK::KEY_TAB, CDK::KEY_RETURN, Ncurses::KEY_ENTER
        self.setExitType(input)
        ret = @current_item
        @complete = true
      when CDK::REFRESH
        @screen.erase
        @screen.refresh
      else
        CDK.Beep
      end
    end

    # Should we call a post-process?
    if !@complete && !(@post_process_func.nil?)
      @post_process_func.call(:ITEMLIST, self, @post_process_data, input)
    end
  end

  if !@complete
    self.drawField(true)
    self.setExitType(0)
  end

  @result_data = ret
  return ret
end

#maximumFieldWidthObject

Go through the list and determine the widest item.



439
440
441
442
443
444
445
446
447
448
# File 'lib/cdk/components/itemlist.rb', line 439

def maximumFieldWidth
  max_width = -2**30

  (0...@list_size).each do |x|
    max_width = [max_width, @item_len[x]].max
  end
  max_width = [max_width, 0].max

  return max_width
end

#move(xplace, yplace, relative, refresh_flag) ⇒ Object

This moves the itemlist field to the given location.



221
222
223
224
225
# File 'lib/cdk/components/itemlist.rb', line 221

def move(xplace, yplace, relative, refresh_flag)
  windows = [@win, @field_win, @label_win, @shadow_win]
  self.move_specific(xplace, yplace, relative, refresh_flag,
      windows, [])
end

#object_typeObject



471
472
473
# File 'lib/cdk/components/itemlist.rb', line 471

def object_type
  :ITEMLIST
end

#positionObject



467
468
469
# File 'lib/cdk/components/itemlist.rb', line 467

def position
  super(@win)
end

#set(list, count, current, box) ⇒ Object

This sets multiple attributes of the widget.



321
322
323
324
# File 'lib/cdk/components/itemlist.rb', line 321

def set(list, count, current, box)
  self.setValues(list, count, current)
  self.setBox(box)
end

#setBKattr(attrib) ⇒ Object

This sets the background attribute of the widget



254
255
256
257
258
259
260
# File 'lib/cdk/components/itemlist.rb', line 254

def setBKattr(attrib)
  @win.wbkgd(attrib)
  @field_win.wbkgd(attrib)
  unless @label_win.nil?
    @label_win.wbkgd(attrib)
  end
end

#setCurrentItem(current_item) ⇒ Object

This sets the default/current item of the itemlist



356
357
358
359
360
361
# File 'lib/cdk/components/itemlist.rb', line 356

def setCurrentItem(current_item)
  # Set the default item.
  if current_item >= 0 && current_item < @list_size
    @current_item = current_item
  end
end

#setDefaultItem(default_item) ⇒ Object

This sets the default item in the list.



368
369
370
371
372
373
374
375
376
377
# File 'lib/cdk/components/itemlist.rb', line 368

def setDefaultItem(default_item)
  # Make sure the item is in the correct range.
  if default_item < 0
    @default_item = 0
  elsif default_item >= @list_size
    @default_item = @list_size - 1
  else
    @default_item = default_item
  end
end

#setValues(item, count, default_item) ⇒ Object

This function sets the contents of the list



327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/cdk/components/itemlist.rb', line 327

def setValues(item, count, default_item)
  if self.createList(item, count)
    old_width = @field_width

    # Set the default item.
    if default_item >= 0 && default_item < @list_size
      @current_item = default_item
      @default_item = default_item
    end

    # This will not resize the outer windows but can still make a usable
    # field width if the title made the outer window wide enough
    self.updateFieldWidth
    if @field_width > old_width
      self.createFieldWin(@field_win.getbegy, @field_win.getbegx)
    end

    # Draw the field.
    self.erase
    self.draw(@box)
  end
end

#unfocusObject



387
388
389
# File 'lib/cdk/components/itemlist.rb', line 387

def unfocus
  self.drawField(false)
end

#updateFieldWidthObject



450
451
452
453
454
# File 'lib/cdk/components/itemlist.rb', line 450

def updateFieldWidth
  want = self.maximumFieldWidth + 1
  have = @box_width - @label_len - 2 * @border_size
  @field_width = [want, have].min
end