class Umbra::Widget

Parent class of all widgets/controls that are displayed on the screen/window and are managed by Form. Many attributes use `attr_property` instead of `attr_accessor`. This is used for elements that must repaint the widget whenever updated. They also fire a property change event. These properties may not show up in the generated RDoc. This class will not be instantiated by programs, only its subclasses will be. Widget registers `:ENTER` `:LEAVE` `:CHANGED` and `:PROPERTY_CHANGE` events. Widget defines three states: `:NORMAL` `:HIGHLIGHTED` and `:SELECTED`.

`HIGHLIGHTED` refers to the single widget that is focussed. 
`SELECTED` is only for Togglebuttons that may be in `SELECTED` state.
`NORMAL` state is for all others (the default state).

Attributes

col[RW]
col_offset[R]
curpos[RW]
focusable[R]
graphic[RW]
handler[R]

@return [Hash] event handler hash containing key and block association

key_label[R]

@return [String] descriptions for each key set in _key_map, NOT YET displayed TODO

modified[RW]
name[RW]
repaint_required[RW]

@param repaint_required [true, false] is a repaint required or not, boolean

row[W]
row_offset[R]
state[RW]

Public Class Methods

new(aconfig={}) { |self| ... } click to toggle source

@param aconfig [Hash] initialization parameters such as row, col, height, width, color_pair, text. @yield [Widget] self

# File lib/umbra/widget.rb, line 114
def initialize aconfig={}, &block
  @row_offset ||= 0
  @col_offset ||= 0
  @state = :NORMAL

  @handler = nil # we can avoid firing if nil
  # These are standard events for most widgets which will be fired by
  # Form. In the case of CHANGED, form fires if it's editable property is set, so
  # it does not apply to all widgets.
  register_events( [:ENTER, :LEAVE, :CHANGED, :PROPERTY_CHANGE])
  @repaint_required = true

  aconfig.each_pair { |k,v| variable_set(k,v) }
  #instance_eval &block if block_given?
  if block_given?
    if block.arity > 0
      yield self
    else
      self.instance_eval(&block)
    end
  end
end

Public Instance Methods

command(*args, &block) click to toggle source

A general method for all widgets to override with their favorite or most meaninful event This is a convenience method. Widgets that have a `PRESS` event will bind the given block to PRESS, all others to the `CHANGED` event.

# File lib/umbra/widget.rb, line 259
def command *args, &block
  if event? :PRESS
    bind_event :PRESS, *args, &block
  else
    bind_event :CHANGED, *args, &block
  end
end
focusable=(bool) click to toggle source

set focusable property to true or false Also updates the focusables array.

# File lib/umbra/widget.rb, line 273
def focusable=(bool)
  #$log.debug "  inside focusable= with #{bool} "
  @focusable = bool
  @_form.update_focusables if @_form
end
getvalue() click to toggle source

@return [String] the value of the widget.

# File lib/umbra/widget.rb, line 186
def getvalue
  @text
end
getvalue_for_paint() click to toggle source

Am making a separate method since often value for print differs from actual value

@return [String] the value of the widget for painting.
# File lib/umbra/widget.rb, line 193
def getvalue_for_paint
  getvalue
end
handle_key(ch) click to toggle source

Handle keys entered by user when this widget is focussed. Executes blocks bound to given key or else returns control to Form. To be called at end of `handle_key` of widgets so installed actions can be executed. @param ch [Integer] keystroke entered @return [0, :UNHANDLED] return value of block executed for given keystroke

# File lib/umbra/widget.rb, line 234
def handle_key(ch)
  ret = process_key ch, self
  return :UNHANDLED if ret == :UNHANDLED
  0
end
height() click to toggle source

Get height of widget. Used only for Multline widgets @return [Integer, nil] height of widget if applicable

# File lib/umbra/widget.rb, line 291
def height
  return nil unless @height
  if @height < 0
    return ((FFI::NCurses.LINES + @height) - self.row) + 1
    #return (FFI::NCurses.LINES + @height)
  end
  @height
end
modified?() click to toggle source

Widget modified or not. typically will be overridden to check if value changed from what it was on enter. @return [true, false] modified since on_enter or not

# File lib/umbra/widget.rb, line 150
def modified?
  @modified
end
on_enter() click to toggle source

triggered whenever a widget is entered.

Will invoke `:ENTER` handler/event
# File lib/umbra/widget.rb, line 156
def on_enter
  ## Form has already set this, and set modified to false
  @state = :HIGHLIGHTED    # duplicating since often these are inside containers
  #@focussed = true
  if @handler && @handler.has_key?(:ENTER)
    fire_handler :ENTER, self
  end
end
on_leave() click to toggle source

Called when user exits a widget Will invoke `:LEAVE` handler/event

# File lib/umbra/widget.rb, line 167
def on_leave
  @state = :NORMAL    # duplicating since often these are inside containers
  #@focussed = false
  if @handler && @handler.has_key?(:LEAVE)
    fire_handler :LEAVE, self
  end
end
repaint() click to toggle source

Default repaint method. Called by form for all widgets. widget does not have display_length. This should be overriden by concrete subclasses.

# File lib/umbra/widget.rb, line 200
def repaint
  r,c = rowcol
  $log.debug("widget repaint : r:#{r} c:#{c} col:#{@color_pair}" )
  value = getvalue_for_paint
  len = self.width || value.length
  acolor = @color_pair 
  @graphic.printstring r, c, "%-*s" % [len, value], acolor, attr()
end
row() click to toggle source

get row of widget @return [Integer, nil] row of widget

# File lib/umbra/widget.rb, line 302
def row
  return nil unless @row
  if @row < 0
    return FFI::NCurses.LINES + @row
  end
  @row
end
rowcol() click to toggle source

Returns row and col is where a widget starts. offsets usually take into account borders. the offsets typically are where the cursor should be positioned inside, upon on_enter. @return [Integer] row of widget where painting data actually starts @return [Integer] col of widget where painting data actually starts

# File lib/umbra/widget.rb, line 181
def rowcol
  return self.row+@row_offset, self.col+@col_offset
end
set_form_col(col1=@curpos) click to toggle source

set cursor on correct column, widget Ideally, this should be overriden, as it is not likely to be correct. NOTE: this is okay for some widgets but NOT for containers that will call their own components SFR and SFC Currently, Field has overriden this. setrowcol does not exist any longer.

# File lib/umbra/widget.rb, line 221
def set_form_col col1=@curpos
  @curpos = col1 || 0 # 2010-01-14 21:02
  #@form.col = @col + @col_offset + @curpos
  c = @col + @col_offset + @curpos
  #$log.warn " #{@name} empty set_form_col #{c}, curpos #{@curpos}  , #{@col} + #{@col_offset} #{@form} "
  setrowcol nil, c
end
touch() click to toggle source

Shortcut for users to indicate that a widget should be redrawn since some property has been changed. Now that I have created attr_property this may not be needed

# File lib/umbra/widget.rb, line 251
def touch
  @repaint_required = true
end
width() click to toggle source

Get width of widget, treating negatives as relative width. @return [Integer, nil] returns width of widget

# File lib/umbra/widget.rb, line 281
def width
  return nil unless @width    ## this is required otherwise checking for nil will fail
  if @width < 0
    return ( FFI::NCurses.COLS + @width ) - self.col + 1
  end
  @width
end