Class: RNDK::Itemlist

Inherits:
Widget
  • Object
show all
Defined in:
lib/rndk/itemlist.rb

Instance Attribute Summary

Attributes inherited from Widget

#BXAttr, #HZChar, #LLChar, #LRChar, #ULChar, #URChar, #VTChar, #accepts_focus, #binding_list, #border_size, #box, #exit_type, #has_focus, #is_visible, #screen, #screen_index, #supported_signals, #widget_type

Instance Method Summary collapse

Methods inherited from Widget

#Screen_XPOS, #Screen_YPOS, #after_processing, #before_processing, #bind_key, #bind_signal, #bindable_widget, #clean_bindings, #clean_title, #draw_title, #get_box, #getch, #is_bound?, #refresh_data, #run_key_binding, #run_signal_binding, #save_data, #setBXattr, #setHZchar, #setLLchar, #setLRchar, #setULchar, #setURchar, #setVTchar, #set_box, #set_exit_type, #set_title, #unbind_key, #valid?, #valid_type?

Constructor Details

#initialize(screen, config = {}) ⇒ Itemlist

Returns a new instance of Itemlist.



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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/rndk/itemlist.rb', line 7

def initialize(screen, config={})
  super()
  @widget_type = :itemlist
  @supported_signals += [:before_input, :after_input]

  x            = 0
  y            = 0
  title        = "itemlist"
  label        = "label"
  items        = []
  default_item = 0
  box          = true
  shadow       = false

  config.each do |key, val|
    x            = val if key == :x
    y            = val if key == :y
    title        = val if key == :title
    label        = val if key == :label
    items        = val if key == :items
    default_item = val if key == :default_item
    box          = val if key == :box
    shadow       = val if key == :shadow
  end

  count = items.size
  parent_width = Ncurses.getmaxx(screen.window)
  parent_height = Ncurses.getmaxy(screen.window)
  field_width = 0

  if !self.create_list items
    self.destroy
    return nil
  end

  self.set_box(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 = RNDK.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.set_title(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 = [x]
  ytmp = [y]
  RNDK.alignxy(screen.window, xtmp, ytmp, box_width, box_height)
  xpos = xtmp[0]
  ypos = ytmp[0]

  # Make the window.
  @win = Ncurses.newwin(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 = Ncurses.subwin(@win, 1, @label_len,
        ypos + @border_size + @title_lines,
        xpos + @border_size)

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

  Ncurses.keypad(@win, 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 = screen
  @parent = screen.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.newwin(box_height, box_width,
        ypos + 1, xpos + 1)
    if @shadow_win.nil?
      self.destroy
      return nil
    end
  end

  # Register this baby.
  screen.register(@widget_type, self)
end

Instance Method Details

#activate(actions = []) ⇒ Object

This allows the user to play with the widget.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rndk/itemlist.rb', line 135

def activate(actions=[])
  ret = false

  # Draw the widget.
  self.draw
  self.draw_field(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.set_exit_type(0)
  return ret
end

#create_list(item) ⇒ Object



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
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/rndk/itemlist.rb', line 406

def create_list item
  count = item.size

  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 << RNDK.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] = RNDK.justifyString(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

#createFieldWin(ypos, xpos) ⇒ Object

Make the field window.



474
475
476
477
478
479
480
481
482
483
# File 'lib/rndk/itemlist.rb', line 474

def createFieldWin(ypos, xpos)
  @field_win = Ncurses.subwin(@win, 1, @field_width, ypos, xpos)

  unless @field_win.nil?
    Ncurses.keypad(@field_win, true)
    @input_window = @field_win
    return true
  end
  return false
end

#destroyObject

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



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/rndk/itemlist.rb', line 319

def destroy
  self.clean_title
  self.destroyInfo

  # Delete the windows
  RNDK.window_delete(@field_win)
  RNDK.window_delete(@label_win)
  RNDK.window_delete(@shadow_win)
  RNDK.window_delete(@win)

  # Clean the key bindings.
  self.clean_bindings

  @screen.unregister self
end

#destroyInfoObject



313
314
315
316
# File 'lib/rndk/itemlist.rb', line 313

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

#drawObject

This draws the widget on the screen.



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/rndk/itemlist.rb', line 249

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

  self.draw_title(@win)

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

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

  Ncurses.wrefresh @win

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

#draw_field(highlight) ⇒ Object

This function draws the contents of the field.



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/rndk/itemlist.rb', line 278

def draw_field(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.
  Ncurses.werase(@field_win)

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

    if highlight
      c = c.ord | RNDK::Color[:reverse]
    end

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

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

#eraseObject

This function removes the widget from the screen.



304
305
306
307
308
309
310
311
# File 'lib/rndk/itemlist.rb', line 304

def erase
  if self.valid?
    RNDK.window_erase(@field_win)
    RNDK.window_erase(@label_win)
    RNDK.window_erase(@win)
    RNDK.window_erase(@shadow_win)
  end
end

#focusObject



398
399
400
# File 'lib/rndk/itemlist.rb', line 398

def focus
  self.draw_field(true)
end

#getCurrentItemObject



378
379
380
# File 'lib/rndk/itemlist.rb', line 378

def getCurrentItem
  return @current_item
end

#getDefaultItemObject



394
395
396
# File 'lib/rndk/itemlist.rb', line 394

def getDefaultItem
  return @default_item
end

#getValues(size) ⇒ Object



365
366
367
368
# File 'lib/rndk/itemlist.rb', line 365

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

#inject(input) ⇒ Object

This injects a single character into the widget.



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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/rndk/itemlist.rb', line 170

def inject input
  pp_return = true
  ret = false
  complete = false

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

  # Draw the widget field
  self.draw_field(true)

  # Check if there is a pre-process function to be called.
  keep_going = self.run_signal_binding(:before_input, input)

  if keep_going

    # Check a predefined binding.
    if self.is_bound? input
      self.run_key_binding 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 RNDK::KEY_ESC
        self.set_exit_type(input)
        complete = true
      when Ncurses::ERR
        self.set_exit_type(input)
        complete = true
      when RNDK::KEY_TAB, RNDK::KEY_RETURN, Ncurses::KEY_ENTER
        self.set_exit_type(input)
        ret = @current_item
        complete = true
      when RNDK::REFRESH
        @screen.erase
        @screen.refresh
      else
        RNDK.beep
      end
    end

    # Should we call a post-process?
    self.run_signal_binding(:after_input) if not complete
  end

  if !complete
    self.draw_field(true)
    self.set_exit_type(0)
  end

  @result_data = ret
  return ret
end

#maximumFieldWidthObject

Go through the list and determine the widest item.



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

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(x, y, relative, refresh_flag) ⇒ Object

This moves the itemlist field to the given location.



242
243
244
245
246
# File 'lib/rndk/itemlist.rb', line 242

def move(x, y, relative, refresh_flag)
  windows = [@win, @field_win, @label_win, @shadow_win]

  self.move_specific(x, y, relative, refresh_flag, windows, [])
end

#positionObject



485
486
487
# File 'lib/rndk/itemlist.rb', line 485

def position
  super(@win)
end

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

This sets multiple attributes of the widget.



336
337
338
339
# File 'lib/rndk/itemlist.rb', line 336

def set(list, count, current, box)
  self.set_values(list, count, current)
  self.set_box(box)
end

#set_bg_color(attrib) ⇒ Object

This sets the background attribute of the widget



271
272
273
274
275
# File 'lib/rndk/itemlist.rb', line 271

def set_bg_color(attrib)
  Ncurses.wbkgd(@win, attrib)
  Ncurses.wbkgd(@field_win, attrib)
  Ncurses.wbkgd(@label_win, attrib) unless @label_win.nil?
end

#set_values(item, default_item) ⇒ Object

This function sets the contents of the list



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/rndk/itemlist.rb', line 342

def set_values(item, default_item)
  if self.create_list item
    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
  end
end

#setCurrentItem(current_item) ⇒ Object

This sets the default/current item of the itemlist



371
372
373
374
375
376
# File 'lib/rndk/itemlist.rb', line 371

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.



383
384
385
386
387
388
389
390
391
392
# File 'lib/rndk/itemlist.rb', line 383

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

#unfocusObject



402
403
404
# File 'lib/rndk/itemlist.rb', line 402

def unfocus
  self.draw_field(false)
end

#updateFieldWidthObject



467
468
469
470
471
# File 'lib/rndk/itemlist.rb', line 467

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