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
@return [Hash] event handler hash containing key and block association
@return [String] descriptions for each key set in _key_map, NOT YET displayed TODO
@param repaint_required
[true, false] is a repaint required or not, boolean
Public Class Methods
@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
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
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
@return [String] the value of the widget.
# File lib/umbra/widget.rb, line 186 def getvalue @text end
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 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
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
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
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
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
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
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 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
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
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