Class: RNDK::Alphalist

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

Overview

TODO:

Kinda buggy, fix first words, mate

Allows user to select from a items of alphabetically sorted words.

Use the arrow keys to navigate on the items or type in the beginning of the word and it'll automagically adjust itself in the correct place.

Keybindings

Since Alphaitems is built from both the Scroll and Entry Widgets, the key bindings are the same for the respective fields.

Extra key bindings are itemsed below:

Up Arrow:: Scrolls the scrolling items up one line. Down Arrow:: Scrolls the scrolling items down one line. Page Up:: Scrolls the scrolling items up one page. CTRL-B:: Scrolls the scrolling items up one page. Page Down:: Scrolls the scrolling items down one page. CTRL-F:: Scrolls the scrolling items down one page. Tab:: Tries to complete the word in the entry field. If the word segment is not unique then the widget will beep and present a items of close matches. Return:: Returns the word in the entry field. It also sets the widget data exitType to :NORMAL. Escape:: Exits the widget and returns nil. It also sets the widget data exitType to :ESCAPE_HIT.

Developer notes

This widget, like the file selector widget, is a compound widget of both the entry field widget and the scrolling items widget - sorted.

Instance Attribute Summary collapse

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

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Widget

#Screen_XPOS, #Screen_YPOS, #after_processing, #before_processing, #bind_key, #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 = {}) ⇒ Alphalist

Creates an Alphalist Widget.

Settings

  • x is the x position - can be an integer or RNDK::LEFT, RNDK::RIGHT, RNDK::CENTER.
  • y is the y position - can be an integer or RNDK::TOP, RNDK::BOTTOM, RNDK::CENTER.
  • width/height are integers - if either are 0, Widget will be created with full width/height of the screen. If it's a negative value, will create with full width/height minus the value.
  • title can be more than one line - just split them with \ns.
  • label is the String that will appear on the label of the Entry field.
  • items is an Array of Strings with the content to display.
  • filler_char is the character to display on the empty spaces in the Entry field.
  • highlight is the attribute/color of the current item.
  • box if the Widget is drawn with a box outside it.
  • shadow turns on/off the shadow around the Widget.


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
133
134
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
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
# File 'lib/rndk/alphalist.rb', line 68

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

  # This is UGLY AS HELL
  # But I don't have time to clean this up right now
  # (lots of widgets, you know)  :(
  x           = 0
  y           = 0
  width       = 0
  height      = 0
  title       = "alphaitems"
  label       = "label"
  items        = []
  filler_char = '.'
  highlight   = RNDK::Color[:reverse]
  box         = true
  shadow      = false

  config.each do |key, val|
    x           = val if key == :x
    y           = val if key == :y
    width       = val if key == :width
    height      = val if key == :height
    title       = val if key == :title
    label       = val if key == :label
    items        = val if key == :items
    filler_char = val if key == :filler_char
    highlight   = val if key == :highlight
    box         = val if key == :box
    shadow      = val if key == :shadow
  end

  parent_width  = Ncurses.getmaxx screen.window
  parent_height = Ncurses.getmaxy screen.window

  box_width  = width
  box_height = height

  label_len = 0

  if not self.create_items items
    self.destroy
    return nil
  end

  self.set_box box

  # If the height is a negative value, the height will be ROWS-height,
  # otherwise the height will be the given height.
  box_height = RNDK.set_widget_dimension(parent_height, height, 0)

  # If the width is a negative value, the width will be COLS-width,
  # otherwise the width will be the given width.
  box_width = RNDK.set_widget_dimension(parent_width, width, 0)

  # Translate the label string to a chtype array
  if label.size > 0
    lentmp = []
    chtype_label = RNDK.char2Chtype(label, lentmp, [])
    label_len = lentmp[0]
  end

  # 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 file selector window.
  @win = Ncurses.newwin(box_height, box_width, ypos, xpos)

  if @win.nil?
    self.destroy
    return nil
  end
  Ncurses.keypad(@win, true)

  @screen = screen
  @parent = screen.window
  @highlight   = highlight
  @filler_char = filler_char

  @box_width  = box_width
  @box_height = box_height

  @shadow = shadow
  @shadow_win = nil

  # Do we want a shadow?
  if shadow
    @shadow_win = Ncurses.newwin(box_height, box_width, ypos+1, xpos+1)
  end

  # Create the entry field.
  temp_width =  if Alphalist.isFullWidth(width)
                then RNDK::FULL
                else box_width - 2 - label_len
                end

  @entry_field = RNDK::Entry.new(screen, {
                                   :x => Ncurses.getbegx(@win),
                                   :y => Ncurses.getbegy(@win),
                                   :title => title,
                                   :label => label,
                                   :filler => filler_char,
                                   :field_width => temp_width,
                                   :box => box
                                 })
  if @entry_field.nil?
    self.destroy
    return nil
  end
  @entry_field.setLLchar Ncurses::ACS_LTEE
  @entry_field.setLRchar Ncurses::ACS_RTEE

  # Set the key bindings for the entry field.
  @entry_field.bind_key(Ncurses::KEY_UP)    { self.autocomplete }
  @entry_field.bind_key(RNDK::KEY_TAB)      { self.autocomplete }
  @entry_field.bind_key(Ncurses::KEY_DOWN)  { self.adjust_items }
  @entry_field.bind_key(Ncurses::KEY_NPAGE) { self.adjust_items }
  @entry_field.bind_key(Ncurses::KEY_PPAGE) { self.adjust_items }

  @entry_field.bind_signal(:before_input) { |char| self.pre_process_entry_field(char) }

  # Create the scrolling items.  It overlaps the entry field by one line if
  # we are using box-borders.
  temp_height = Ncurses.getmaxy(@entry_field.win) - @border_size
  temp_width = if Alphalist.isFullWidth(width)
               then RNDK::FULL
               else box_width - 1
               end

  @scroll_field = RNDK::Scroll.new(screen, {
                                     :x => Ncurses.getbegx(@win),
                                     :y => Ncurses.getbegy(@entry_field.win) + temp_height,
                                     :width => temp_width,
                                     :height => box_height - temp_height,
                                     :title => '',
                                     :items => items,
                                     :box => box
                                   })

  @scroll_field.setULchar Ncurses::ACS_LTEE
  @scroll_field.setURchar Ncurses::ACS_RTEE

  screen.register(:alphaitems, self)
end

Instance Attribute Details

#entry_fieldObject (readonly)

Returns the value of attribute entry_field.



41
42
43
# File 'lib/rndk/alphalist.rb', line 41

def entry_field
  @entry_field
end

#itemsObject (readonly)

Returns the value of attribute items.



41
42
43
# File 'lib/rndk/alphalist.rb', line 41

def items
  @items
end

#scroll_fieldObject (readonly)

Returns the value of attribute scroll_field.



41
42
43
# File 'lib/rndk/alphalist.rb', line 41

def scroll_field
  @scroll_field
end

Class Method Details

.isFullWidth(width) ⇒ Object



494
495
496
# File 'lib/rndk/alphalist.rb', line 494

def self.isFullWidth(width)
  width == RNDK::FULL || (Ncurses.COLS != 0 && width >= Ncurses.COLS)
end

Instance Method Details

#activate(actions = []) ⇒ Object

Activates the Alphalist Widget, letting the user interact with it.

actions is an Array of characters. If it's non-null, will #inject each char on it into the Widget.

See Alphalist for keybindings.

Returns:

  • The text currently inside the entry field (and exit_type will be :NORMAL) or nil (and exit_type will be :ESCAPE_HIT).



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/rndk/alphalist.rb', line 285

def activate(actions=[])
  ret = 0

  # Draw the widget.
  self.draw

  # Activate the widget.
  ret = @entry_field.activate actions

  # Copy the exit type from the entry field.
  @exit_type = @entry_field.exit_type

  # Determine the exit status.
  if @exit_type != :EARLY_EXIT
    return ret
  end
  return 0
end

#bind_signal(signal, &action) ⇒ Object

See Also:



456
457
458
# File 'lib/rndk/alphalist.rb', line 456

def bind_signal(signal, &action)
  @entry_field.bind_signal(signal, action)
end

#create_items(items) ⇒ Object



460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
# File 'lib/rndk/alphalist.rb', line 460

def create_items items
  if items.size >= 0
    newitems = []

    # Copy in the new information.
    status = true
    (0...items.size).each do |x|
      newitems << items[x]
      if newitems[x] == 0
        status = false
        break
      end
    end
    if status
      self.destroyInfo
      @items_size = items.size
      @items = newitems
      @items.sort!
    end
  else
    self.destroyInfo
    status = true
  end
  status
end

#destroyObject

This destroys the alpha items



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/rndk/alphalist.rb', line 438

def destroy
  self.destroyInfo

  # Clean the key bindings.
  self.clean_bindings

  @entry_field.destroy
  @scroll_field.destroy

  # Free up the window pointers.
  RNDK.window_delete(@shadow_win)
  RNDK.window_delete(@win)

  # Unregister the widget.
  @screen.unregister self
end

#destroyInfoObject



432
433
434
435
# File 'lib/rndk/alphalist.rb', line 432

def destroyInfo
  @items = ''
  @items_size = 0
end

#drawObject

Draws the Widget on the Screen.

If box is true, it is drawn with a box.



265
266
267
268
269
270
271
272
273
# File 'lib/rndk/alphalist.rb', line 265

def draw
  Draw.drawShadow @shadow_win unless @shadow_win.nil?

  # Draw in the entry field.
  @entry_field.draw @entry_field.box

  # Draw in the scroll field.
  self.draw_scroller
end

#draw_scrollerObject



250
251
252
253
254
# File 'lib/rndk/alphalist.rb', line 250

def draw_scroller
  self.saveFocus
  @scroll_field.draw
  self.restoreFocus
end

#eraseObject

See Also:



220
221
222
223
224
225
226
227
228
# File 'lib/rndk/alphalist.rb', line 220

def erase
  if self.valid?
    @scroll_field.erase
    @entry_field.erase

    RNDK.window_erase(@shadow_win)
    RNDK.window_erase(@win)
  end
end

#focusObject



486
487
488
# File 'lib/rndk/alphalist.rb', line 486

def focus
  self.entry_field.focus
end

#get_current_itemObject

Get/set the current position in the scroll widget.



364
365
366
# File 'lib/rndk/alphalist.rb', line 364

def get_current_item
  return @scroll_field.get_current_item
end

#get_filler_charObject



381
382
383
# File 'lib/rndk/alphalist.rb', line 381

def get_filler_char
  return @filler_char
end

#getContents(size) ⇒ Object

This returns the contents of the widget.



358
359
360
361
# File 'lib/rndk/alphalist.rb', line 358

def getContents size
  size << @items_size
  return @items
end

#getHighlightObject



390
391
392
# File 'lib/rndk/alphalist.rb', line 390

def getHighlight
  @highlight
end

#inject(input) ⇒ Object

Makes the Alphalist react to char just as if the user had pressed it.

Nice to simulate batch actions on a Widget.

Besides normal keybindings (arrow keys and such), see Widget#set_exit_type to see how the Widget exits.



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/rndk/alphalist.rb', line 312

def inject input
  ret = false

  self.draw

  # Inject a character into the widget.
  ret = @entry_field.inject input

  # Copy the eixt type from the entry field.
  @exit_type = @entry_field.exit_type

  # Determine the exit status.
  ret = false if @exit_type == :EARLY_EXIT

  @result_data = ret
  ret
end

#injectMyScroller(key) ⇒ Object



256
257
258
259
260
# File 'lib/rndk/alphalist.rb', line 256

def injectMyScroller(key)
  self.saveFocus
  @scroll_field.inject(key)
  self.restoreFocus
end

#move(x, y, relative, refresh_flag) ⇒ Object

See Also:



231
232
233
234
235
# File 'lib/rndk/alphalist.rb', line 231

def move(x, y, relative, refresh_flag)
  windows = [@win, @shadow_win]
  subwidgets = [@entry_field, @scroll_field]
  self.move_specific(x, y, relative, refresh_flag, windows, subwidgets)
end

#positionObject



498
499
500
# File 'lib/rndk/alphalist.rb', line 498

def position
  super(@win)
end

#restoreFocusObject



246
247
248
# File 'lib/rndk/alphalist.rb', line 246

def restoreFocus
  @scroll_field.has_focus = @save
end

#saveFocusObject

The alphaitems's focus resides in the entry widget. But the scroll widget will not draw items highlighted unless it has focus. Temporarily adjust the focus of the scroll widget when drawing on it to get the right highlighting.



241
242
243
244
# File 'lib/rndk/alphalist.rb', line 241

def saveFocus
  @save = @scroll_field.has_focus
  @scroll_field.has_focus = @entry_field.has_focus
end

#set(items, filler_char, highlight, box) ⇒ Object

Sets multiple attributes of the Widget.

See Alphalist#initialize.



333
334
335
336
337
338
# File 'lib/rndk/alphalist.rb', line 333

def set(items, filler_char, highlight, box)
  self.set_contents   items
  self.set_filler_char filler_char
  self.set_highlight highlight
  self.set_box box
end

#set_bg_color(attrib) ⇒ Object

This sets the background attribute of the widget.



427
428
429
430
# File 'lib/rndk/alphalist.rb', line 427

def set_bg_color(attrib)
  @entry_field.set_bg_color(attrib)
  @scroll_field.set_bg_color(attrib)
end

#set_contents(items) ⇒ Object

This function sets the information inside the alphaitems.



341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/rndk/alphalist.rb', line 341

def set_contents items
  return if not self.create_items items

  # Set the information in the scrolling items.
  @scroll_field.set(@items, @items_size, false,
      @scroll_field.highlight, @scroll_field.box)

  # Clean out the entry field.
  self.set_current_item(0)
  @entry_field.clean

  # Redraw the widget.
  self.erase
  self.draw
end

#set_current_item(item) ⇒ Object



368
369
370
371
372
373
# File 'lib/rndk/alphalist.rb', line 368

def set_current_item item
  if @items_size != 0
    @scroll_field.set_current_item item
    @entry_field.setValue @items[@scroll_field.get_current_item]
  end
end

#set_filler_char(char) ⇒ Object

This sets the filler character of the entry field of the alphaitems.



376
377
378
379
# File 'lib/rndk/alphalist.rb', line 376

def set_filler_char char
  @filler_char = char
  @entry_field.set_filler_char char
end

#set_highlight(highlight) ⇒ Object

This sets the highlgith bar attributes



386
387
388
# File 'lib/rndk/alphalist.rb', line 386

def set_highlight(highlight)
  @highlight = highlight
end

#setMyBXattr(character) ⇒ Object



421
422
423
424
# File 'lib/rndk/alphalist.rb', line 421

def setMyBXattr(character)
  @entry_field.setBXattr(character)
  @scroll_field.setBXattr(character)
end

#setMyHZchar(character) ⇒ Object



416
417
418
419
# File 'lib/rndk/alphalist.rb', line 416

def setMyHZchar(character)
  @entry_field.setHZchar(character)
  @scroll_field.setHZchar(character)
end

#setMyLLchar(character) ⇒ Object



403
404
405
# File 'lib/rndk/alphalist.rb', line 403

def setMyLLchar(character)
  @scroll_field.setLLchar(character)
end

#setMyLRchar(character) ⇒ Object



407
408
409
# File 'lib/rndk/alphalist.rb', line 407

def setMyLRchar(character)
  @scroll_field.setLRchar(character)
end

#setMyULchar(character) ⇒ Object

These functions set the drawing characters of the widget.



395
396
397
# File 'lib/rndk/alphalist.rb', line 395

def setMyULchar(character)
  @entry_field.setULchar(character)
end

#setMyURchar(character) ⇒ Object



399
400
401
# File 'lib/rndk/alphalist.rb', line 399

def setMyURchar(character)
  @entry_field.setURchar(character)
end

#setMyVTchar(character) ⇒ Object



411
412
413
414
# File 'lib/rndk/alphalist.rb', line 411

def setMyVTchar(character)
  @entry_field.setVTchar(character)
  @scroll_field.setVTchar(character)
end

#unfocusObject



490
491
492
# File 'lib/rndk/alphalist.rb', line 490

def unfocus
  self.entry_field.unfocus
end