Class: Canis::Widget

Inherits:
Object show all
Includes:
ConfigSetup, EventHandler, Io, Utils
Defined in:
lib/canis/core/widgets/rwidget.rb

Overview

{{{

Since:

  • 1.2.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Io

#__create_footer_window, #clear_this, #get_file, #print_this, #rb_getchar, #rb_gets, #rb_getstr, #warn

Methods included from Utils

#ORIG_process_key, #ORIGbind_key, #ORIGkeycode_tos, #_process_key, #bind_composite_mapping, #bind_key, #bind_keys, #check_composite_mapping, #create_logger, #define_key, #define_prefix_command, #execute_mapping, #get_attrib, #get_color, #key, #key_tos, #print_key_bindings, #repeatm, #run_command, #shell_out, #shell_output, #suspend, #view, #xxxbind_composite_mapping

Methods included from ConfigSetup

#config_setup, #variable_set

Methods included from EventHandler

#bind, #event?, #event_list, #fire_handler, #fire_property_change, #register_events

Constructor Details

#initialize(aform, aconfig = {}, &block) ⇒ Widget

Returns a new instance of Widget.

Since:

  • 1.2.0



1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
# File 'lib/canis/core/widgets/rwidget.rb', line 1130

def initialize aform, aconfig={}, &block
  # I am trying to avoid passing the nil when you don't want to give a form.
  # I hope this does not create new issues 2011-11-20 
  if aform.is_a? Hash
    # presumable there's nothing coming in in hash, or else we will have to merge
    aconfig = aform
    @form = nil
  else
    #raise "got a #{aform.class} "
    @form = aform
  end
  @row_offset ||= 0
  @col_offset ||= 0
  #@ext_row_offset = @ext_col_offset = 0 # 2010-02-07 20:18  # removed on 2011-09-29 
  @state = :NORMAL

  @handler = nil # we can avoid firing if nil
  #@event_args = {} # 2014-04-22 - 18:47 declared in bind_key
  # 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])

  config_setup aconfig # @config.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
  # 2010-09-20 13:12 moved down, so it does not create problems with other who want to set their
  # own default
  #@bgcolor ||=  "black" # 0
  #@color ||= "white" # $datacolor
  set_form(@form) if @form
end

Instance Attribute Details

#_object_createdObject

2010-09-16 12:12 to prevent needless property change firing when object being set

Since:

  • 1.2.0



1114
1115
1116
# File 'lib/canis/core/widgets/rwidget.rb', line 1114

def _object_created
  @_object_created
end

#col_offsetObject (readonly)

where should the cursor be placed to start with

Since:

  • 1.2.0



1108
1109
1110
# File 'lib/canis/core/widgets/rwidget.rb', line 1108

def col_offset
  @col_offset
end

#configObject (readonly)

can be used for popping user objects too

Since:

  • 1.2.0



1105
1106
1107
# File 'lib/canis/core/widgets/rwidget.rb', line 1105

def config
  @config
end

#curposObject

cursor position inside object - column, not row.

Since:

  • 1.2.0



1104
1105
1106
# File 'lib/canis/core/widgets/rwidget.rb', line 1104

def curpos
  @curpos
end

#focussedObject

sometimes inside a container there’s no way of knowing if an individual comp is in focus other than to explicitly set it and inquire . 2010-09-02 14:47 @since 1.1.5 NOTE state takes care of this and is set by form. boolean

Since:

  • 1.2.0



1121
1122
1123
# File 'lib/canis/core/widgets/rwidget.rb', line 1121

def focussed
  @focussed
end

#formObject

made accessor 2008-11-27 22:32 so menu can set

Since:

  • 1.2.0



1106
1107
1108
# File 'lib/canis/core/widgets/rwidget.rb', line 1106

def form
  @form
end

#handlerObject (readonly)

event handler

Since:

  • 1.2.0



1128
1129
1130
# File 'lib/canis/core/widgets/rwidget.rb', line 1128

def handler
  @handler
end

#idObject

, :zorder

Since:

  • 1.2.0



1103
1104
1105
# File 'lib/canis/core/widgets/rwidget.rb', line 1103

def id
  @id
end

#key_labelObject (readonly)

descriptions for each key set in _key_map

Since:

  • 1.2.0



1127
1128
1129
# File 'lib/canis/core/widgets/rwidget.rb', line 1127

def key_label
  @key_label
end

#parent_componentObject

added 2010-01-12 23:28 BUFFERED - to bubble up

Since:

  • 1.2.0



1116
1117
1118
# File 'lib/canis/core/widgets/rwidget.rb', line 1116

def parent_component
  @parent_component
end

#row_offsetObject (readonly)

where should the cursor be placed to start with

Since:

  • 1.2.0



1108
1109
1110
# File 'lib/canis/core/widgets/rwidget.rb', line 1108

def row_offset
  @row_offset
end

#stateObject

normal, selected, highlighted

Since:

  • 1.2.0



1107
1108
1109
# File 'lib/canis/core/widgets/rwidget.rb', line 1107

def state
  @state
end

Instance Method Details

#action_managerObject

return an object of actionmanager class, creating if required Widgets and apps may add_action and show_menu using the same

Since:

  • 1.2.0



1510
1511
1512
1513
# File 'lib/canis/core/widgets/rwidget.rb', line 1510

def action_manager
  require 'canis/core/include/actionmanager'
  @action_manager ||= ActionManager.new
end

#bgcolor(*val) ⇒ Object

returns widgets bgcolor, or form’s color. This ensures that all widgets use form’s color

unless user has overriden the color.

This is to be used whenever a widget is rendering to check the color at this moment.

Since:

  • 1.2.0



1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
# File 'lib/canis/core/widgets/rwidget.rb', line 1213

def bgcolor( *val )
  if val.empty?
    return @bgcolor if @bgcolor
    return @form.bgcolor if @form
    return $def_bg_color
  else
    @color_pair = nil
    return property_set :bgcolor, val
  end
end

#color(*val) ⇒ Object

returns widgets color, or if not set then app default Ideally would have returned form’s color, but it seems that form does not have color any longer.

Since:

  • 1.2.0



1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
# File 'lib/canis/core/widgets/rwidget.rb', line 1200

def color( *val )
  if val.empty?
    return @color if @color
    return @form.color if @form
    return $def_fg_color
  else
    @color_pair = nil
    return property_set :color, val
  end
end

#color_pair(*val) ⇒ Object

2011-11-12 trying to make color setting a bit sane You may set as a color_pair using get_color which gives a fixnum or you may give 2 color symbols so i can update color, bgcolor and colorpair in one shot if one of them is nil, i just use the existing value

Since:

  • 1.2.0



1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
# File 'lib/canis/core/widgets/rwidget.rb', line 1474

def color_pair(*val)
  if val.empty?
    #return @color_pair 
    return @color_pair || get_color($datacolor, color(), bgcolor())
  end

  oldvalue = @color_pair
  case val.size
  when 1
    raise ArgumentError, "Expecting fixnum for color_pair." unless val[0].is_a? Fixnum
    @color_pair = val[0]
    @color, @bgcolor = ColorMap.get_colors_for_pair @color_pair
  when 2
    @color = val.first if val.first
    @bgcolor = val.last if val.last
    @color_pair = get_color $datacolor, @color, @bgcolor
  end
  if oldvalue != @color_pair
    fire_property_change(:color_pair, oldvalue, @color_pair)
    @property_changed = true
    repaint_all true
  end
  self
end

#command(*args, &block) ⇒ Object

a general method for all widgets to override with their favorite or most meaninful event Ideally this is where the block in the constructor should land up.

Since:

  • 1.5.0 2011-11-21



1501
1502
1503
1504
1505
1506
1507
# File 'lib/canis/core/widgets/rwidget.rb', line 1501

def command *args, &block
  if event? :PRESS
    bind :PRESS, *args, &block
  else
    bind :CHANGED, *args, &block
  end
end

#destroyObject

Since:

  • 1.2.0



1291
1292
1293
1294
1295
1296
# File 'lib/canis/core/widgets/rwidget.rb', line 1291

def destroy
  $log.debug "DESTROY : widget #{@name} "
  panel = @window.panel
  Ncurses::Panel.del_panel(panel.pointer) if !panel.nil?   
  @window.delwin if !@window.nil?
end

#focusObject

moves focus to this field we must look into running on_leave of previous field

Since:

  • 1.2.0



1354
1355
1356
1357
1358
1359
# File 'lib/canis/core/widgets/rwidget.rb', line 1354

def focus
  return if !@focusable
  if @form.validate_field != -1
    @form.select_field @id
  end
end

#focusable(*val) ⇒ Object

set or unset focusable (boolean). Whether a widget can get keyboard focus.

Since:

  • 1.2.0



1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
# File 'lib/canis/core/widgets/rwidget.rb', line 1361

def focusable(*val)
  return @focusable if val.empty?
  oldv = @focusable
  @focusable = val[0]

  return self if oldv.nil? || @_object_created.nil?
  # once the form has been painted then any changes will trigger update of focusables.
  @form.update_focusables if @form
  # actually i should only set the forms focusable_modified flag rather than call this. FIXME
  self
end

#focusable?Boolean

is this widget accessible from keyboard or not.

Returns:

  • (Boolean)

Since:

  • 1.2.0



1374
1375
1376
# File 'lib/canis/core/widgets/rwidget.rb', line 1374

def focusable?
  @focusable
end

#getvalueObject

return the value of the widget.

In cases where selection is possible, should return selected value/s

Since:

  • 1.2.0



1264
1265
1266
1267
# File 'lib/canis/core/widgets/rwidget.rb', line 1264

def getvalue
  #@text_variable && @text_variable.value || @text
  @text
end

#getvalue_for_paintObject

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

Since:

  • 1.2.0



1270
1271
1272
# File 'lib/canis/core/widgets/rwidget.rb', line 1270

def getvalue_for_paint
  getvalue
end

#handle_key(ch) ⇒ Object

to be added at end of handle_key of widgets so instlalled actions can be checked

Since:

  • 1.2.0



1393
1394
1395
1396
1397
# File 'lib/canis/core/widgets/rwidget.rb', line 1393

def handle_key(ch)
  ret = process_key ch, self
  return :UNHANDLED if ret == :UNHANDLED
  0
end

#hideObject

Since:

  • 1.2.0



1337
1338
1339
# File 'lib/canis/core/widgets/rwidget.rb', line 1337

def hide
  @visible = false
end

#init_varsObject

Since:

  • 1.2.0



1168
1169
1170
1171
# File 'lib/canis/core/widgets/rwidget.rb', line 1168

def init_vars
  # just in case anyone does a super. Not putting anything here
  # since i don't want anyone accidentally overriding
end

#modified?Boolean

modified

typically read will be overridden to check if value changed from what it was on enter. getter and setter for modified (added 2009-01-18 12:31 )

Returns:

  • (Boolean)

Since:

  • 1.2.0



1229
1230
1231
# File 'lib/canis/core/widgets/rwidget.rb', line 1229

def modified?
  @modified
end

#move(row, col) ⇒ Object

is this required can we remove

Since:

  • 1.2.0



1347
1348
1349
1350
# File 'lib/canis/core/widgets/rwidget.rb', line 1347

def move row, col
  @row = row
  @col = col
end

#on_enterObject

got left out by mistake 2008-11-26 20:20

Since:

  • 1.2.0



1239
1240
1241
1242
1243
1244
1245
# File 'lib/canis/core/widgets/rwidget.rb', line 1239

def on_enter
  @state = :HIGHLIGHTED    # duplicating since often these are inside containers
  @focussed = true
  if @handler && @handler.has_key?(:ENTER)
    fire_handler :ENTER, self
  end
end

#on_leaveObject

Called when user exits a widget

Since:

  • 1.2.0



1247
1248
1249
1250
1251
1252
1253
# File 'lib/canis/core/widgets/rwidget.rb', line 1247

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

#override_graphic(gr) ⇒ Object

When an enclosing component creates a pad (buffer) and the child component + should write onto the same pad, then the enclosing component should override + the default graphic of child. This applies mainly to editor components in + listboxes and tables. added 2010-01-05 15:25

Parameters:

  • graphic

    graphic object to use for writing contents

See Also:

  • in rlistbox.

Since:

  • 1.2.0



1419
1420
1421
# File 'lib/canis/core/widgets/rwidget.rb', line 1419

def override_graphic gr
  @graphic = gr
end

#process_key(keycode, object) ⇒ Object

e.g. process_key ch, self returns UNHANDLED if no block for it after form handles basic keys, it gives unhandled key to current field, if current field returns unhandled, then it checks this map.

Since:

  • 1.2.0



1388
1389
1390
# File 'lib/canis/core/widgets/rwidget.rb', line 1388

def process_key keycode, object
  return _process_key keycode, object, @graphic
end

#property_set(sym, val) ⇒ Object

this is supposed to be a duplicate of what dsl_property generates for cases when

we need to customise the get portion but not copy the set part. just call this.

Since:

  • 1.2.0



1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
# File 'lib/canis/core/widgets/rwidget.rb', line 1174

def property_set sym, val
  oldvalue = instance_variable_get "@#{sym}"
  tmp = val.size == 1 ? val[0] : val
  newvalue = tmp
  if oldvalue.nil? || @_object_created.nil?
    #@#{sym} = tmp
    instance_variable_set "@#{sym}", tmp
  end
  return(self) if oldvalue.nil? || @_object_created.nil?

  if oldvalue != newvalue
    # trying to reduce calls to fire, when object is being created
    begin
      @property_changed = true
      fire_property_change("#{sym}", oldvalue, newvalue) if !oldvalue.nil?
      #@#{sym} = tmp
      instance_variable_set "@#{sym}", tmp
      #@config["#{sym}"]=@#{sym}
    rescue PropertyVetoException
      $log.warn "PropertyVetoException for #{sym}:" + oldvalue.to_s + "->  "+ newvalue.to_s
    end
  end # if old
  self
end

#removeObject

Since:

  • 1.2.0



1343
1344
1345
# File 'lib/canis/core/widgets/rwidget.rb', line 1343

def remove
  @form.remove_widget(self)
end

#repaintObject

default repaint method. Called by form for all widgets.

widget does not have display_length.

Since:

  • 1.2.0



1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
# File 'lib/canis/core/widgets/rwidget.rb', line 1276

def repaint
    r,c = rowcol
    #@bgcolor ||= $def_bg_color # moved down 2011-11-5 
    #@color   ||= $def_fg_color
    _bgcolor = bgcolor()
    _color = color()
    $log.debug("widget repaint : r:#{r} c:#{c} col:#{_color}" )
    value = getvalue_for_paint
    len = @width || value.length
    acolor = @color_pair || get_color($datacolor, _color, _bgcolor)
    @graphic.printstring r, c, "%-*s" % [len, value], acolor, attr()
    # next line should be in same color but only have @att so we can change att is nec
    #@form.window.mvchgat(y=r, x=c, max=len, Ncurses::A_NORMAL, @bgcolor, nil)
end

#repaint_all(tf = true) ⇒ Object

Since:

  • 1.2.0



1406
1407
1408
1409
# File 'lib/canis/core/widgets/rwidget.rb', line 1406

def repaint_all(tf=true)
  @repaint_all = tf
  @repaint_required = tf
end

#repaint_required(tf = true) ⇒ Object

to give simple access to other components, (eg, parent) to tell a comp to either paint its data, or to paint all - borders, headers, footers due to a big change (ht/width)

Since:

  • 1.2.0



1403
1404
1405
# File 'lib/canis/core/widgets/rwidget.rb', line 1403

def repaint_required(tf=true)
  @repaint_required = tf
end

#rowcolObject

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.

Returns:

  • row and col of a widget where painting data actually starts

Since:

  • 1.2.0



1258
1259
1260
1261
# File 'lib/canis/core/widgets/rwidget.rb', line 1258

def rowcol
# $log.debug "widgte rowcol : #{@row+@row_offset}, #{@col+@col_offset}"
  return @row+@row_offset, @col+@col_offset
end

#set_form(form) ⇒ Object

in those cases where we create widget without a form, and later give it to some other program which sets the form. Dirty, we should perhaps create widgets without forms, and add explicitly.

Since:

  • 1.2.0



1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
# File 'lib/canis/core/widgets/rwidget.rb', line 1300

def set_form form
  raise "Form is nil in set_form" if form.nil?
  @form = form
  @id = form.add_widget(self) if !form.nil? and form.respond_to? :add_widget
  # 2009-10-29 15:04 use form.window, unless buffer created
  # should not use form.window so explicitly everywhere.
  # added 2009-12-27 20:05 BUFFERED in case child object needs a form.
  # We don;t wish to overwrite the graphic object
  if @graphic.nil?
    #$log.debug " setting graphic to form window for #{self.class}, #{form} "
    @graphic = form.window unless form.nil? # use screen for writing, not buffer
  end
  # execute those actions delayed due to absence of form -- used internally 
  # mostly by buttons and labels to bind hotkey to form
  fire_handler(:FORM_ATTACHED, self) if event? :FORM_ATTACHED
end

#set_form_col(col1 = @curpos) ⇒ Object

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

Since:

  • 1.2.0



1330
1331
1332
1333
1334
1335
1336
# File 'lib/canis/core/widgets/rwidget.rb', line 1330

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

#set_form_rowObject

puts cursor on correct row.

Since:

  • 1.2.0



1318
1319
1320
1321
1322
1323
1324
1325
# File 'lib/canis/core/widgets/rwidget.rb', line 1318

def set_form_row
#  @form.row = @row + 1 + @winrow
  #@form.row = @row + 1 
  r, c = rowcol
  #$log.warn " empty set_form_row in widget #{self} r = #{r} , c = #{c}  "
  #raise "trying to set 0, maybe called repaint before container has set value" if row <= 0
  setrowcol row, nil
end

#set_modified(tf = true) ⇒ Object Also known as: modified

Since:

  • 1.2.0



1232
1233
1234
1235
# File 'lib/canis/core/widgets/rwidget.rb', line 1232

def set_modified tf=true
  @modified = tf
  @form.modified = true if tf
end

#setformrowcol(r, c) ⇒ Object

passing a cursor up and adding col and row offsets Added 2010-01-13 13:27 I am checking this out. I would rather pass the value down and store it than do this recursive call + for each cursor display

See Also:

Since:

  • 1.2.0



1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
# File 'lib/canis/core/widgets/rwidget.rb', line 1428

def setformrowcol r, c
      @form.row = r unless r.nil?
      @form.col = c unless c.nil?
      # this is stupid, going through this route i was losing windows top and left
      # And this could get repeated if there are mult objects. 
   if !@parent_component.nil? and @parent_component != self
      r+= @parent_component.form.window.top unless  r.nil?
      c+= @parent_component.form.window.left unless c.nil?
      $log.debug " (#{@name}) calling parents setformrowcol #{r}, #{c} pa: #{@parent_component.name} self: #{name}, #{self.class}, poff #{@parent_component.row_offset}, #{@parent_component.col_offset}, top:#{@form.window.left} left:#{@form.window.left} "
      @parent_component.setformrowcol r, c
   else
      # no more parents, now set form
      $log.debug " name NO MORE parents setting #{r}, #{c}    in #{@form} "
      @form.setrowcol r, c
   end
end

#setrowcol(r, c) ⇒ Object

widget: i am putting one extra level of indirection so i can switch here between form#setrowcol and setformrowcol, since i am not convinced either are giving the accurate result. i am not sure what the issue is.

Since:

  • 1.2.0



1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
# File 'lib/canis/core/widgets/rwidget.rb', line 1447

def setrowcol r, c
    # 2010-02-07 21:32 is this where i should add ext_offsets
   #$log.debug " #{@name}  w.setrowcol #{r} + #{@ext_row_offset}, #{c} + #{@ext_col_offset}  "
   # commented off 2010-02-15 18:22 
   #r += @ext_row_offset unless r.nil?
   #c += @ext_col_offset unless c.nil?
   if @form
     @form.setrowcol r, c
   #elsif @parent_component
   else
     raise "Parent component not defined for #{self}, #{self.class} " unless @parent_component
     @parent_component.setrowcol r, c
   end
   #setformrowcol r,c 
end

#showObject

Since:

  • 1.2.0



1340
1341
1342
# File 'lib/canis/core/widgets/rwidget.rb', line 1340

def show
  @visible = true
end

#unbind_key(keycode) ⇒ Object

remove a binding that you don’t want

Since:

  • 1.2.0



1379
1380
1381
1382
# File 'lib/canis/core/widgets/rwidget.rb', line 1379

def unbind_key keycode
  @_key_args.delete keycode unless @_key_args.nil?
  @_key_map.delete keycode unless @_key_map.nil?
end