class RNDK::Widget

Wrapper on common functionality between all RNDK Widgets.

Attributes

BXAttr[RW]
HZChar[RW]
LLChar[RW]
LRChar[RW]
ULChar[RW]
URChar[RW]
VTChar[RW]
accepts_focus[R]
binding_list[R]
border_size[R]
box[RW]
exit_type[R]
has_focus[RW]
is_visible[RW]
screen[RW]
screen_index[RW]
supported_signals[R]

All the signals the current widget supports. Use them on Widget#bind_signal

widget_type[R]

Which widget this is. It’s the name of the widget lowercased. Example: ‘:label`, `:calendar`, `:alphalist`

Public Class Methods

new() click to toggle source
# File lib/rndk/core/widget.rb, line 24
def initialize
  @has_focus  = true
  @is_visible = true

  RNDK::ALL_WIDGETS << self

  # set default line-drawing characters
  @ULChar = Ncurses::ACS_ULCORNER
  @URChar = Ncurses::ACS_URCORNER
  @LLChar = Ncurses::ACS_LLCORNER
  @LRChar = Ncurses::ACS_LRCORNER
  @HZChar = Ncurses::ACS_HLINE
  @VTChar = Ncurses::ACS_VLINE
  @BXAttr = RNDK::Color[:normal]

  # set default exit-types
  @exit_type  = :NEVER_ACTIVATED
  @early_exit = :NEVER_ACTIVATED

  @accepts_focus = false

  # Bound functions
  @binding_list = {}

  # Actions to be executed at certain signals
  @actions = {}

  @supported_signals = []
  @supported_signals << :destroy
end

Public Instance Methods

Screen_XPOS(n) click to toggle source
# File lib/rndk/core/widget.rb, line 92
def Screen_XPOS(n)
  n + @border_size
end
Screen_YPOS(n) click to toggle source
# File lib/rndk/core/widget.rb, line 96
def Screen_YPOS(n)
  n + @border_size + @title_lines
end
after_processing(data=nil, &block) click to toggle source

Makes ‘block` execute right after processing input on the Widget.

‘block` is called with the following arguments:

  • The Widget type (‘:scroll`, `:calendar`, etc)

  • The Widget itself (‘self`)

  • That ‘data` you send as an argument to `after_processing`.

  • The input character the Widget just received.

Make good use of them when making your callback.

# File lib/rndk/core/widget.rb, line 82
def after_processing(data=nil, &block)
  @post_process_data = data
  @post_process_func = block
end
before_processing(data=nil, &block) click to toggle source

Makes ‘block` execute right before processing input on the Widget.

‘block` is called with the following arguments:

  • The Widget type (‘:scroll`, `:calendar`, etc)

  • The Widget itself (‘self`)

  • That ‘data` you send as an argument to `before_processing`.

  • The input character the Widget just received.

Make good use of them when making your callback.

# File lib/rndk/core/widget.rb, line 66
def before_processing(data=nil, &block)
  @pre_process_data = data
  @pre_process_func = block
end
bind_key(key, data=nil, &action) click to toggle source

Binds a ‘function` to a `key`.

# File lib/rndk/core/widget_bind.rb, line 28
def bind_key(key, data=nil, &action)
  obj = self.bindable_widget @widget_type

  if (key.ord >= Ncurses::KEY_MAX) or (key.ord.zero?) or (obj.nil?)
    return
  end

  obj.binding_list[key.ord] = [action, data]
end
bind_signal(signal, &action) click to toggle source

Binds an ‘action` to be executed when `signal` is activated.

# File lib/rndk/core/widget_bind.rb, line 81
def bind_signal(signal, &action)
  return unless @supported_signals.include? signal

  @actions[signal] = [] if @actions[signal].nil?

  @actions[signal] << action
end
bindable_widget(rndktype) click to toggle source

Returns the internal Widget that accepts key bindings.

Some widgets are made of others. So when we bind keys to those complex widgets, we can specify which internal Widget accepts keybindings.

For example, on an Alphalist (which is composed of Scroll and Entry), we bind keys to the Entry, not Scroll.

# File lib/rndk/core/widget_bind.rb, line 14
def bindable_widget rndktype
  return nil if rndktype != @widget_type


  if [:Fselect, :alphalist].include? @widget_type
    return @entry_field

  else
    return self
  end
end
clean_bindings() click to toggle source
# File lib/rndk/core/widget_bind.rb, line 44
def clean_bindings
  obj = self.bindable_widget @widget_type

  if (not obj.nil?) and (not obj.binding_list.nil?)
    obj.binding_list.clear
  end
end
clean_title() click to toggle source

Remove storage for the widget’s title.

# File lib/rndk/core/widget.rb, line 291
def clean_title
  @title_lines = ''
end
destroy() click to toggle source

Destroys all windows inside the Widget and removes it from the Screen.

# File lib/rndk/core/widget.rb, line 232
def destroy
end
draw(a) click to toggle source
# File lib/rndk/core/widget.rb, line 100
def draw(a)
end
draw_title(win) click to toggle source

Draw the widget’s title

# File lib/rndk/core/widget.rb, line 174
def draw_title(win)
  (0...@title_lines).each do |x|
    Draw.writeChtype(@win, @title_pos[x] + @border_size,
        x + @border_size, @title[x], RNDK::HORIZONTAL, 0,
        @title_len[x])
  end
end
erase() click to toggle source

Erases the Widget from the Screen. @note It does not destroy the Widget.

# File lib/rndk/core/widget.rb, line 105
def erase
end
focus() click to toggle source
# File lib/rndk/core/widget.rb, line 205
def focus
end
get_box() click to toggle source

Tells if the widget has borders.

# File lib/rndk/core/widget.rb, line 201
def get_box
  return @box
end
getch(function_key=[]) click to toggle source

FIXME TODO What does ‘function_key` does?

# File lib/rndk/core/widget.rb, line 315
def getch(function_key=[])
  key = self.getc
  function_key << (key >= Ncurses::KEY_MIN && key <= Ncurses::KEY_MAX)

  key
end
inject(input) click to toggle source

Makes the Widget 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.

# File lib/rndk/core/widget.rb, line 190
def inject input
end
is_bound?(key) click to toggle source

Tells if the key binding for the key exists.

# File lib/rndk/core/widget_bind.rb, line 72
def is_bound? key
  obj = self.bindable_widget @widget_type
  return false if obj.nil?

  obj.binding_list.include? key
end
move(x, y, relative, refresh_flag) click to toggle source

Moves the Widget to the given position.

  • ‘x` and `y` are the new position of the Widget.

  • ‘x` may be an integer or one of the pre-defined values `RNDK::TOP`, `RNDK::BOTTOM`, and `RNDK::CENTER`.

  • ‘y` may be an integer or one of the pre-defined values `RNDK::LEFT`, `RNDK::RIGHT`, and `RNDK::CENTER`.

  • ‘relative` states whether the `x`/`y` pair is a relative move over it’s current position or an absolute move over the Screen’s top.

For example, if ‘x = 1` and `y = 2` and `relative = true`, the Widget would move one row down and two columns right.

If the value of relative was ‘false` then the widget would move to the position `(1,2)`.

Do not use the values ‘TOP`, `BOTTOM`, `LEFT`, `RIGHT`, or `CENTER` when `relative = true` - weird things may happen.

  • ‘refresh_flag` is a boolean value which states whether the Widget will get refreshed after the move.

# File lib/rndk/core/widget.rb, line 134
def move(x, y, relative, refresh_flag)
  self.move_specific(x, y, relative, refresh_flag, [@win, @shadow_win], [])
end
position(win) click to toggle source

Allows the user to move the Widget around the screen via the cursor/keypad keys.

‘win` is the main window of the Widget - from which subwins derive.

The following key bindings can be used to move the Widget around the screen:

Up Arrow

Moves the widget up one row.

Down Arrow

Moves the widget down one row.

Left Arrow

Moves the widget left one column

Right Arrow

Moves the widget right one column

1

Moves the widget down one row and left one column.

2

Moves the widget down one row.

3

Moves the widget down one row and right one column.

4

Moves the widget left one column.

5

Centers the widget both vertically and horizontally.

6

Moves the widget right one column

7

Moves the widget up one row and left one column.

8

Moves the widget up one row.

9

Moves the widget up one row and right one column.

t

Moves the widget to the top of the screen.

b

Moves the widget to the bottom of the screen.

l

Moves the widget to the left of the screen.

r

Moves the widget to the right of the screen.

c

Centers the widget between the left and right of the window.

C

Centers the widget between the top and bottom of the window.

Escape

Returns the widget to its original position.

Return

Exits the function and leaves the Widget where it was.

# File lib/rndk/core/widget.rb, line 353
def position win
  parent = @screen.window
  orig_x = Ncurses.getbegx win
  orig_y = Ncurses.getbegy win
  beg_x = Ncurses.getbegx parent
  beg_y = Ncurses.getbegy parent
  end_x = beg_x + Ncurses.getmaxx(@screen.window)
  end_y = beg_y + Ncurses.getmaxy(@screen.window)

  loop do
    key = self.getch

    # Let them move the widget around until they hit return.
    break if [RNDK::KEY_RETURN, Ncurses::KEY_ENTER].include? key

    case key
    when Ncurses::KEY_UP, '8'.ord
      if Ncurses.getbegy(win) > beg_y
        self.move(0, -1, true, true)
      else
        RNDK.beep
      end
    when Ncurses::KEY_DOWN, '2'.ord
      if (Ncurses.getbegy(win) + Ncurses.getmaxy(win)) < end_y
        self.move(0, 1, true, true)
      else
        RNDK.beep
      end
    when Ncurses::KEY_LEFT, '4'.ord
      if Ncurses.getbegx(win) > beg_x
        self.move(-1, 0, true, true)
      else
        RNDK.beep
      end
    when Ncurses::KEY_RIGHT, '6'.ord
      if (Ncurses.getbegx(win) + Ncurses.getmaxx(win)) < end_x
        self.move(1, 0, true, true)
      else
        RNDK.beep
      end
    when '7'.ord
      if Ncurses.getbegy(win) > beg_y && Ncurses.getbegx(win) > beg_x
        self.move(-1, -1, true, true)
      else
        RNDK.beep
      end
    when '9'.ord
      if (Ncurses.getbegx(win) + Ncurses.getmaxx(win)) < end_x && Ncurses.getbegy(win) > beg_y
        self.move(1, -1, true, true)
      else
        RNDK.beep
      end
    when '1'.ord
      if Ncurses.getbegx(win) > beg_x && (Ncurses.getbegy(win) + Ncurses.getmaxy(win)) < end_y
        self.move(-1, 1, true, true)
      else
        RNDK.beep
      end
    when '3'.ord
      if (Ncurses.getbegx(win) + Ncurses.getmaxx(win)) < end_x &&
          (Ncurses.getbegy(win) + Ncurses.getmaxy(win)) < end_y
        self.move(1, 1, true, true)
      else
        RNDK.beep
      end

    when '5'.ord
      self.move(RNDK::CENTER, RNDK::CENTER, false, true)

    when 't'.ord
      self.move(Ncurses.getbegx(win), RNDK::TOP, false, true)

    when 'b'.ord
      self.move(Ncurses.getbegx(win), RNDK::BOTTOM, false, true)

    when 'l'.ord
      self.move(RNDK::LEFT, Ncurses.getbegy(win), false, true)

    when 'r'.ord
      self.move(RNDK::RIGHT, Ncurses.getbegy(win), false, true)

    when 'c'.ord
      self.move(RNDK::CENTER, Ncurses.getbegy(win), false, true)

    when 'C'.ord
      self.move(Ncurses.getbegx(win), RNDK::CENTER, false, true)

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

    when RNDK::KEY_ESC
      self.move(orig_x, orig_y, false, true)
    else
      RNDK.beep
    end
  end
end
refresh_data() click to toggle source

Somehow refreshes all data within this Widget.

@note This method isn’t called whatsoever!

It only exists at Traverse module.

TODO Find out how can I insert this on Widgets.

# File lib/rndk/core/widget.rb, line 227
def refresh_data
end
run_key_binding(key) click to toggle source

Runs any binding that’s set for ‘key`.

@return The binding’s return value or ‘false`, if no

keybinding for `key` exists.
# File lib/rndk/core/widget_bind.rb, line 57
def run_key_binding key
  obj = self.bindable_widget @widget_type

  return false if obj.nil? or (not obj.binding_list.include? key)

  function = obj.binding_list[key][0]
  data     = obj.binding_list[key][1]

  # What the heck is this?
  return data if function == :getc

  function.call data
end
run_signal_binding(signal, data=nil) click to toggle source

Runs all actions based on ‘signal`, passing `data` as an argument.

@note It interrupts executing when any action returns

`false`.

@return ‘true` if all actions were executed or no actions

exist, `false` if they were interrupted.
# File lib/rndk/core/widget_bind.rb, line 96
def run_signal_binding(signal, data=nil)
  return true if @actions[signal].nil?

  @actions[signal].each do |action|
    return false if action.call(data) == false
  end

  true
end
save_data() click to toggle source

Somehow saves all data within this Widget.

@note This method isn’t called whatsoever!

It only exists at Traverse module.

TODO Find out how can I insert this on Widgets.

# File lib/rndk/core/widget.rb, line 217
def save_data
end
setBXattr(ch) click to toggle source

Set the widget’s box-attributes.

# File lib/rndk/core/widget.rb, line 266
def setBXattr(ch)
  @BXAttr = ch
end
setHZchar(ch) click to toggle source

Set the widget’s horizontal line-drawing character

# File lib/rndk/core/widget.rb, line 256
def setHZchar(ch)
  @HZChar = ch
end
setLLchar(ch) click to toggle source

Set the widget’s lower-left-corner line-drawing character.

# File lib/rndk/core/widget.rb, line 246
def setLLchar(ch)
  @LLChar = ch
end
setLRchar(ch) click to toggle source

Set the widget’s upper-right-corner line-drawing character.

# File lib/rndk/core/widget.rb, line 251
def setLRchar(ch)
  @LRChar = ch
end
setULchar(ch) click to toggle source

Set the widget’s upper-left-corner line-drawing character.

# File lib/rndk/core/widget.rb, line 236
def setULchar(ch)
  @ULChar = ch
end
setURchar(ch) click to toggle source

Set the widget’s upper-right-corner line-drawing character.

# File lib/rndk/core/widget.rb, line 241
def setURchar(ch)
  @URChar = ch
end
setVTchar(ch) click to toggle source

Set the widget’s vertical line-drawing character

# File lib/rndk/core/widget.rb, line 261
def setVTchar(ch)
  @VTChar = ch
end
set_bg_color(color) click to toggle source

This sets the background color of the widget.

FIXME BUG

# File lib/rndk/core/widget.rb, line 273
def set_bg_color color
  return if color.nil? || color == ''

  junk1 = []
  junk2 = []

  # Convert the value of the environment variable to a chtype
  holder = RNDK.char2Chtype(color, junk1, junk2)

  # Set the widget's background color

  ## FIXME BUG WTF
  ## What does this function do?
  ## Couldn't find anything on it
  self.SetBackAttrObj(holder[0])
end
set_box(box) click to toggle source

Makes the widget have a border if ‘box` is true, otherwise, cancel it.

# File lib/rndk/core/widget.rb, line 195
def set_box box
  @box = box
  @border_size = if @box then 1 else 0 end
end
set_exit_type(char) click to toggle source

Set the Widget#exit_type based on the input ‘char`.

According to default keybindings, if ‘char` is:

RETURN or TAB

Sets ‘:NORMAL`.

ESCAPE

Sets ‘:ESCAPE_HIT`.

Otherwise

Unless treated specifically by the Widget, sets ‘:EARLY_EXIT`.

# File lib/rndk/core/widget.rb, line 304
def set_exit_type char
  case char
  when Ncurses::ERR  then @exit_type = :ERROR
  when RNDK::KEY_ESC then @exit_type = :ESCAPE_HIT
  when 0             then @exit_type = :EARLY_EXIT
  when RNDK::KEY_TAB, Ncurses::KEY_ENTER, RNDK::KEY_RETURN
    @exit_type = :NORMAL
  end
end
set_title(title, box_width) click to toggle source

Set the widget’s title.

# File lib/rndk/core/widget.rb, line 139
def set_title(title, box_width)
  return if title.nil?

  temp = title.split "\n"
  @title_lines = temp.size

  if box_width >= 0
    max_width = 0
    temp.each do |line|
      len = []
      align = []
      holder = RNDK.char2Chtype(line, len, align)
      max_width = [len[0], max_width].max
    end
    box_width = [box_width, max_width + 2 * @border_size].max
  else
    box_width = -(box_width - 1)
  end

  # For each line in the title convert from string to chtype array
  title_width = box_width - (2 * @border_size)
  @title = []
  @title_pos = []
  @title_len = []
  (0...@title_lines).each do |x|
    len_x = []
    pos_x = []
    @title << RNDK.char2Chtype(temp[x], len_x, pos_x)
    @title_len.concat(len_x)
    @title_pos << RNDK.justifyString(title_width, len_x[0], pos_x[0])
  end
  box_width
end
unbind_key(key) click to toggle source
# File lib/rndk/core/widget_bind.rb, line 38
def unbind_key key
  obj = self.bindable_widget @widget_type

  obj.binding_list.delete(key) unless obj.nil?
end
unfocus() click to toggle source
# File lib/rndk/core/widget.rb, line 208
def unfocus
end
valid?() click to toggle source

Tells if a widget is valid.

# File lib/rndk/core/widget.rb, line 453
def valid?
  RNDK::ALL_WIDGETS.include?(self) and self.valid_type?
end
valid_type?() click to toggle source

Tells if current widget’s type is the type of an existing Widget.

# File lib/rndk/core/widget.rb, line 459
def valid_type?
  [:graph,
   :histogram,
   :label,
   :marquee,
   :viewer,
   :alphalist,
   :button,
   :buttonbox,
   :calendar,
   :dialog,
   :dscale,
   :entry,
   :fscale,
   :fselect,
   :fslider,
   :itemlist,
   :matrix,
   :mentry,
   :radio,
   :scale,
   :scroll,
   :selection,
   :slider,
   :swindow,
   :template,
   :uscale,
   :uslider].include? @widget_type
end

Protected Instance Methods

getc() click to toggle source

Gets a raw character from internal Ncurses window and returns the result, capped to sane values.

# File lib/rndk/core/widget.rb, line 536
def getc
  rndktype = self.widget_type
  test   = self.bindable_widget rndktype
  result = Ncurses.wgetch @input_window

  if (result >= 0) and
      (not test.nil?) and
      (test.binding_list.include? result) and
      (test.binding_list[result][0] == :getc)

    result = test.binding_list[result][1]

  elsif (test.nil?) or
      (not test.binding_list.include? result) or
      (test.binding_list[result][0].nil?)

    case result
    when "\r".ord, "\n".ord then result = Ncurses::KEY_ENTER
    when "\t".ord           then result = RNDK::KEY_TAB
    when RNDK::DELETE       then result = Ncurses::KEY_DC
    when "\b".ord           then result = Ncurses::KEY_BACKSPACE
    when RNDK::BEGOFLINE    then result = Ncurses::KEY_HOME
    when RNDK::ENDOFLINE    then result = Ncurses::KEY_END
    when RNDK::FORCHAR      then result = Ncurses::KEY_RIGHT
    when RNDK::BACKCHAR     then result = Ncurses::KEY_LEFT
    when RNDK::NEXT         then result = RNDK::KEY_TAB
    when RNDK::PREV         then result = Ncurses::KEY_BTAB
    end
  end

  return result
end
move_specific(x, y, relative, refresh_flag, windows, subwidgets) click to toggle source

Actually moves the widget.

# File lib/rndk/core/widget.rb, line 492
def move_specific(x, y, relative, refresh_flag, windows, subwidgets)
  current_x = Ncurses.getbegx @win
  current_y = Ncurses.getbegy @win
  xpos = x
  ypos = y

  # If this is a relative move, then we will adjust where we want
  # to move to.
  if relative
    xpos = Ncurses.getbegx(@win) + x
    ypos = Ncurses.getbegy(@win) + y
  end

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

  # Get the difference
  xdiff = current_x - xpos
  ydiff = current_y - ypos

  # Move the window to the new location.
  windows.each do |window|
    RNDK.window_move(window, -xdiff, -ydiff)
  end

  subwidgets.each do |subwidget|
    subwidget.move(x, y, relative, false)
  end

  # Touch the windows so they 'move'
  RNDK.window_refresh @screen.window

  # Redraw the window, if they asked for it
  if refresh_flag
    self.draw
  end
end