Class: RNDK::Scroll

Inherits:
Scroller show all
Defined in:
lib/rndk/scroll.rb

Overview

A scrolling items of text.

Keybindings

Left Arrow:: Shift the items left one column. Right Arrow:: Shift the items right one column. Up Arrow:: Select the previous item in the items. Down Arrow:: Select the next item in the items. Prev Page:: Scroll one page backward. Ctrl-B:: Scroll one page backward. Next Page:: Scroll one page forward. Ctrl-F:: Scroll one page forward. 1:: Move to the first element in the items. <:: Move to the first element in the items. g:: Move to the first element in the items. Home:: Move to the first element in the items.

:: Move to the last element in the items. G:: Move to the last element in the items. End:: Move to the last element in the items. $:: Shift the items to the far right. |:: Shift the items to the far left. Return:: Exit the widget and return the index of the selected item. Also set the widget exit_type to :NORMAL. Tab:: Exit the widget and return the index of the selected item. Also set the widget exit_type to :NORMAL. Escape:: Exit the widget and return -1. Also set the widget exit_type :ESCAPE_HIT. Ctrl-L:: Refreshes the screen.

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

Instance Method Summary collapse

Methods inherited from Scroller

#get_current_item, #max_view_size, #scroll_begin, #scroll_down, #scroll_end, #scroll_left, #scroll_page_down, #scroll_page_up, #scroll_right, #scroll_up, #set_current_item, #set_position, #set_view_size

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 = {}) ⇒ Scroll

Creates a Scroll Widget.

  • 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.
  • scroll_bar is where the scrollbar will be placed. It can be only RNDK::LEFT, RNDK::RIGHT or RNDK::NONE, for no scrollbar.
  • 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.
  • items is an Array of Strings to be shown on the Widget.
  • numbers is a flag to turn on/off line numbering at the front of the items items.
  • highlight is the attribute/color of the currently selected item at the items.
  • box if the Widget is drawn with a box outside it.
  • shadow turns on/off the shadow around the Widget.


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
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
218
219
# File 'lib/rndk/scroll.rb', line 62

def initialize(screen, config={})
  super()
  @widget_type = :scroll
  @supported_signals += [:before_input,
                         :after_input,
                         :after_scrolling]
  x          = 0
  y          = 0
  scroll_bar = RNDK::RIGHT
  width      = 0
  height     = 0
  title      = "scroll"
  items      = []
  numbers    = false
  highlight  = RNDK::Color[:reverse]
  box        = true
  shadow     = false

  config.each do |key, val|
    x         = val if key == :x
    y         = val if key == :y
    scroll_bar    = val if key == :scroll_bar
    width     = val if key == :width
    height    = val if key == :height
    title     = val if key == :title
    items     = val if key == :items
    numbers   = val if key == :numbers
    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

  xpos = x
  ypos = y

  scroll_adjust = 0

  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)

  box_width = self.set_title(title, box_width)

  # Set the box height.
  if @title_lines > box_height
    box_height = @title_lines + [items.size, 8].min + 2 * @border_size
  end

  # Adjust the box width if there is a scroll bar
  if scroll_bar == RNDK::LEFT || scroll_bar == RNDK::RIGHT
    @scrollbar = true
    box_width += 1
  else
    @scrollbar = false
  end

  # Make sure we didn't extend beyond the dimensions of the window.
  @box_width = if box_width > parent_width
               then parent_width - scroll_adjust
               else box_width
               end
  @box_height = if box_height > parent_height
                then parent_height
                else box_height
                end

  self.set_view_size(items.size)

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

  # Make the scrolling window
  @win = Ncurses.newwin(@box_height, @box_width, ypos, xpos)

  # Is the scrolling window null?
  if @win.nil?
    return nil
  end

  # Turn the keypad on for the window
  Ncurses.keypad(@win, true)

  # Create the scrollbar window.
  if scroll_bar == RNDK::RIGHT
    @scrollbar_win = Ncurses.subwin(@win,
                                    self.max_view_size,
                                    1,
                                    self.Screen_YPOS(ypos),
                                    xpos + box_width - @border_size - 1)
  elsif scroll_bar == RNDK::LEFT
    @scrollbar_win = Ncurses.subwin(@win,
                                    self.max_view_size,
                                    1,
                                    self.Screen_YPOS(ypos),
                                    self.Screen_XPOS(xpos))
  else
    @scrollbar_win = nil
  end

  # create the items window
  @items_win = Ncurses.subwin(@win,
                             self.max_view_size,
                             box_width - (2 * @border_size) - scroll_adjust,
                             self.Screen_YPOS(ypos),
                             self.Screen_XPOS(xpos) + (if scroll_bar == RNDK::LEFT then 1 else 0 end))

  # Set the rest of the variables
  @screen = screen
  @parent = screen.window
  @shadow_win = nil
  @scrollbar_placement = scroll_bar
  @max_left_char = 0
  @left_char = 0
  @highlight = highlight
  # initExitType (scrollp);
  @accepts_focus = true
  @input_window = @win
  @shadow = shadow

  self.set_position(0);

  # Create the scrolling items item items and needed variables.
  return nil unless self.create_item_list(numbers, items)

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

  # Standard keybindings (plus the Arrow Keys)
  self.bind_key('g') { self.scroll_begin }
  self.bind_key('1') { self.scroll_begin }
  self.bind_key('G') { self.scroll_end   }
  self.bind_key('<') { self.scroll_begin }
  self.bind_key('>') { self.scroll_end   }

  screen.register(:scroll, self);
  self
end

Instance Attribute Details

#current_itemObject (readonly)

Returns the value of attribute current_item.



37
38
39
# File 'lib/rndk/scroll.rb', line 37

def current_item
  @current_item
end

#highlightObject (readonly)

Returns the value of attribute highlight.



37
38
39
# File 'lib/rndk/scroll.rb', line 37

def highlight
  @highlight
end

#itemObject (readonly)

Returns the value of attribute item.



37
38
39
# File 'lib/rndk/scroll.rb', line 37

def item
  @item
end

Instance Method Details

#activate(actions = []) ⇒ Object

Activates the 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.



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/rndk/scroll.rb', line 231

def activate(actions=[])
  self.draw

  if actions.nil? || actions.size == 0
    loop do
      self.fix_cursor_position
      input = self.getch

      # Inject the character into the widget.
      ret = self.inject input

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

      return ret if @exit_type != :EARLY_EXIT
    end
  end

  # Set the exit type for the widget and return
  self.set_exit_type(0)
  return nil
end

#destroyObject

This function destroys



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/rndk/scroll.rb', line 386

def destroy
  self.clean_title

  # Clean up the windows.
  RNDK.window_delete(@scrollbar_win)
  RNDK.window_delete(@shadow_win)
  RNDK.window_delete(@items_win)
  RNDK.window_delete(@win)

  # Clean the key bindings.
  self.clean_bindings

  # Unregister this widget
  @screen.unregister self
end

#drawObject

This function draws the scrolling items widget.



365
366
367
368
369
370
371
372
373
# File 'lib/rndk/scroll.rb', line 365

def draw
  # Draw in the shadow if we need to.
  Draw.drawShadow(@shadow_win) unless @shadow_win.nil?

  self.draw_title @win

  # Draw in the scrolling items items.
  self.draw_items @box
end

#eraseObject

This function erases the scrolling items from the screen.



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

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

#focusObject

do this to update the view size, etc

self.set_position(@current_item)

end end



516
517
518
519
# File 'lib/rndk/scroll.rb', line 516

def focus
  self.draw_current
  Ncurses.wrefresh @items_win
end

#get_highlight(highlight) ⇒ Object



445
446
447
# File 'lib/rndk/scroll.rb', line 445

def get_highlight(highlight)
  return @highlight
end

#get_items(items) ⇒ Object



432
433
434
435
436
437
438
# File 'lib/rndk/scroll.rb', line 432

def get_items(items)
  (0...@item.size).each do |x|
    items << RNDK.chtype2Char(@item[x])
  end

  @item.size
end

#inject(input) ⇒ Object

See Also:



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/rndk/scroll.rb', line 259

def inject input
  ret = nil
  complete = false

  self.set_exit_type 0

  # Draw the scrolling items
  self.draw_items @box

  # Calls a pre-process block if exists.
  # They can interrup input.
  continue = run_signal_binding(:before_input, input)

  if continue

    # Check for a predefined key binding.
    if self.is_bound? input
      self.run_key_binding input

    else
      case input

      when Ncurses::KEY_UP
        self.scroll_up
        run_signal_binding(:after_scrolling, @current_item)

      when Ncurses::KEY_DOWN
        self.scroll_down
        run_signal_binding(:after_scrolling, @current_item)

      when Ncurses::KEY_LEFT
        self.scroll_left
        run_signal_binding(:after_scrolling, @current_item)

      when Ncurses::KEY_RIGHT
        self.scroll_right
        run_signal_binding(:after_scrolling, @current_item)

      when Ncurses::KEY_PPAGE
        self.scroll_page_up
        run_signal_binding(:after_scrolling, @current_item)

      when Ncurses::KEY_NPAGE
        self.scroll_page_down
        run_signal_binding(:after_scrolling, @current_item)

      when Ncurses::KEY_HOME
        self.scroll_begin
        run_signal_binding(:after_scrolling, @current_item)

      when Ncurses::KEY_END
        self.scroll_end
        run_signal_binding(:after_scrolling, @current_item)

      when RNDK::BACKCHAR
        self.scroll_page_up
        run_signal_binding(:after_scrolling, @current_item)

      when RNDK::FORCHAR
        self.scroll_page_down
        run_signal_binding(:after_scrolling, @current_item)

      when '$' then @left_char = @max_left_char
      when '|' then @left_char = 0

      when RNDK::KEY_ESC
        self.set_exit_type(input)
        complete = true

      when Ncurses::ERR
        self.set_exit_type(input)
        complete = true

      when RNDK::REFRESH
        @screen.erase
        @screen.refresh

      when RNDK::KEY_TAB, Ncurses::KEY_ENTER, RNDK::KEY_RETURN
        self.set_exit_type(input)
        ret = @current_item
        complete = true
      end
    end

    run_signal_binding(:after_input, input) if not complete
  end

  if not complete
    self.draw_items @box
    self.set_exit_type(0)
  end

  self.fix_cursor_position
  @result_data = ret

  ret
end

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

This moves the scroll field to the given location.



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

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

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

#positionObject

See Also:



222
223
224
# File 'lib/rndk/scroll.rb', line 222

def position
  super @win
end

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

This sets certain attributes of the scrolling items.



409
410
411
412
413
# File 'lib/rndk/scroll.rb', line 409

def set(items, numbers, highlight, box)
  self.set_items(items, numbers)
  self.set_highlight(highlight)
  self.set_box(box)
end

#set_bg_color(attrib) ⇒ Object

This sets the background attribute of the widget.



376
377
378
379
380
381
382
383
# File 'lib/rndk/scroll.rb', line 376

def set_bg_color(attrib)
  Ncurses.wbkgd(@win, attrib)
  Ncurses.wbkgd(@items_win, attrib)

  unless @scrollbar_win.nil?
    Ncurses.wbkgd(@scrollbar_win, attrib)
  end
end

#set_highlight(highlight) ⇒ Object

This sets the highlight of the scrolling items.



441
442
443
# File 'lib/rndk/scroll.rb', line 441

def set_highlight(highlight)
  @highlight = highlight
end

#set_items(items, numbers) ⇒ Object

Sets the scrolling items items. See Scroll#initialize.



417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/rndk/scroll.rb', line 417

def set_items(items, numbers)
  return unless self.create_item_list(numbers, items)

  # Clean up the display.
  (0...@view_size).each do |x|
    Draw.writeBlanks(@win, 1, x, RNDK::HORIZONTAL, 0, @box_width - 2);
  end

  self.set_view_size(items.size)
  self.set_position(0)
  self.erase

  @left_char = 0
end

#unfocusObject



521
522
523
524
# File 'lib/rndk/scroll.rb', line 521

def unfocus
  self.draw_current
  Ncurses.wrefresh @items_win
end