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



1128
1129
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
# File 'lib/canis/core/widgets/rwidget.rb', line 1128

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



1112
1113
1114
# File 'lib/canis/core/widgets/rwidget.rb', line 1112

def _object_created
  @_object_created
end

#col_offsetObject (readonly)

where should the cursor be placed to start with

Since:

  • 1.2.0



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

def col_offset
  @col_offset
end

#configObject (readonly)

can be used for popping user objects too

Since:

  • 1.2.0



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

def config
  @config
end

#curposObject

cursor position inside object - column, not row.

Since:

  • 1.2.0



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

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



1119
1120
1121
# File 'lib/canis/core/widgets/rwidget.rb', line 1119

def focussed
  @focussed
end

#formObject

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

Since:

  • 1.2.0



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

def form
  @form
end

#handlerObject (readonly)

event handler

Since:

  • 1.2.0



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

def handler
  @handler
end

#idObject

, :zorder

Since:

  • 1.2.0



1101
1102
1103
# File 'lib/canis/core/widgets/rwidget.rb', line 1101

def id
  @id
end

#key_labelObject (readonly)

descriptions for each key set in _key_map

Since:

  • 1.2.0



1125
1126
1127
# File 'lib/canis/core/widgets/rwidget.rb', line 1125

def key_label
  @key_label
end

#parent_componentObject

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

Since:

  • 1.2.0



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

def parent_component
  @parent_component
end

#row_offsetObject (readonly)

where should the cursor be placed to start with

Since:

  • 1.2.0



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

def row_offset
  @row_offset
end

#stateObject

normal, selected, highlighted

Since:

  • 1.2.0



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

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



1508
1509
1510
1511
# File 'lib/canis/core/widgets/rwidget.rb', line 1508

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



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

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



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

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



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

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? Integer
    @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



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

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

#destroyObject

Since:

  • 1.2.0



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

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



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

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



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

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



1372
1373
1374
# File 'lib/canis/core/widgets/rwidget.rb', line 1372

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



1262
1263
1264
1265
# File 'lib/canis/core/widgets/rwidget.rb', line 1262

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



1268
1269
1270
# File 'lib/canis/core/widgets/rwidget.rb', line 1268

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



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

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

#hideObject

Since:

  • 1.2.0



1335
1336
1337
# File 'lib/canis/core/widgets/rwidget.rb', line 1335

def hide
  @visible = false
end

#init_varsObject

Since:

  • 1.2.0



1166
1167
1168
1169
# File 'lib/canis/core/widgets/rwidget.rb', line 1166

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



1227
1228
1229
# File 'lib/canis/core/widgets/rwidget.rb', line 1227

def modified?
  @modified
end

#move(row, col) ⇒ Object

is this required can we remove

Since:

  • 1.2.0



1345
1346
1347
1348
# File 'lib/canis/core/widgets/rwidget.rb', line 1345

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



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

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



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

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



1417
1418
1419
# File 'lib/canis/core/widgets/rwidget.rb', line 1417

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



1386
1387
1388
# File 'lib/canis/core/widgets/rwidget.rb', line 1386

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



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

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



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

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



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

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



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

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



1401
1402
1403
# File 'lib/canis/core/widgets/rwidget.rb', line 1401

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



1256
1257
1258
1259
# File 'lib/canis/core/widgets/rwidget.rb', line 1256

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



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

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



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

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



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

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



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

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



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

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



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

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



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

def show
  @visible = true
end

#unbind_key(keycode) ⇒ Object

remove a binding that you don’t want

Since:

  • 1.2.0



1377
1378
1379
1380
# File 'lib/canis/core/widgets/rwidget.rb', line 1377

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