class AbstractLayout

—————————————————————————– #

       File: abstractlayout.rb
Description: An abstract class for other concrete layouts to subclass
     Author: j kepler  http://github.com/mare-imbrium/canis/
       Date: 2014-05-09 - 17:15
    License: MIT
Last update: 2017-03-09 23:13

—————————————————————————– #

abstractlayout.rb  Copyright (C) 2012-2014 j kepler

Attributes

bottom_margin[RW]

top and left are actually row and col in widgets

components[RW]
form[RW]
gap[RW]

gp between objects

height[RW]

if width percent is given, then it calculates and overwrites width. Same for height_pc The _pc values should be between 0 and 1, e.g 0.8 for 80 percent height and width can be negaive. -1 will stretch the stack to one less than end. 0 will stretch till end.

height_pc[RW]

if width percent is given, then it calculates and overwrites width. Same for height_pc The _pc values should be between 0 and 1, e.g 0.8 for 80 percent height and width can be negaive. -1 will stretch the stack to one less than end. 0 will stretch till end.

ignore_list[RW]
left_margin[RW]

top and left are actually row and col in widgets

right_margin[RW]

top and left are actually row and col in widgets

top_margin[RW]

top and left are actually row and col in widgets

width[RW]

if width percent is given, then it calculates and overwrites width. Same for height_pc The _pc values should be between 0 and 1, e.g 0.8 for 80 percent height and width can be negaive. -1 will stretch the stack to one less than end. 0 will stretch till end.

width_pc[RW]

if width percent is given, then it calculates and overwrites width. Same for height_pc The _pc values should be between 0 and 1, e.g 0.8 for 80 percent height and width can be negaive. -1 will stretch the stack to one less than end. 0 will stretch till end.

Public Class Methods

new(form, config={}) click to toggle source

@param [Form] optional give a form

@param [Hash] optional give settings/attributes which will be set into variables

# File lib/canis/core/include/layouts/abstractlayout.rb, line 28
def initialize form, config={}, &block
  @width = @height = 0
  @top_margin = @left_margin = @right_margin = @bottom_margin = 0
  # weightages of each object
  #@wts = {}
  # item_config is a hash which contains a hash of attibs for each item.
  @item_config = Hash.new do |hash, key| hash[key]={}; end

  if form.is_a? Hash
    @config = form
  elsif form.is_a? Form
    @form = form
  end
  @gap = 0
  @ignore_list = ["canis::statusline", "canis::applicationheader"]
  @config.each_pair { |k,v| instance_variable_set("@#{k}",v) }
  #@ignore_list = [Canis::StatusLine, Canis::ApplicationHeader]
  instance_eval &block if block_given?
end

Public Instance Methods

<<(*items)
Alias for: push
_init_layout() click to toggle source

does some initial common calculations that hopefully should be common across layouters so that do_layout can be ovveridden while calling this.

# File lib/canis/core/include/layouts/abstractlayout.rb, line 114
def _init_layout
  # when user gives a negative value, we recalc and overwrite so the need to save, for a redraw.
  @saved_width ||= @width
  @saved_height ||= @height

  lines = Ncurses.LINES - 1
  columns = Ncurses.COLS - 1
  if @height_pc
    @height = ((lines - @top_margin - @bottom_margin) * @height_pc).floor
  elsif @saved_height <= 0
    @height = lines - @saved_height - @top_margin - @bottom_margin
  end
  $log.debug "  layout height = #{@height} "
  if @width_pc
    @width = ((columns - @left_margin - @right_margin) * width_pc).floor
  elsif @saved_width <= 0
    # if width was -1 we have overwritten it so now we cannot recalc it. it remains the same
    @width = columns - @saved_width - @left_margin - @right_margin
  end
  $log.debug "  layout wid = #{@width} "
  # if user has not specified, then get all the objects
  @components ||= @form.widgets.select do |w| w.visible != false && !@ignore_list.include?(w.class.to_s.downcase); end
  $log.debug "  components #{@components.count} "
end
add(item, config={}) click to toggle source

add a widget giving a hash of attributes to be used later.

# File lib/canis/core/include/layouts/abstractlayout.rb, line 59
def add item, config={}
  @components ||= []
  @components << item
  if config
    @item_config[item] = config
  end
  self
end
add_with_weight(item, weight) click to toggle source

Add a component, giving a weightage for height @param [Integer, Float] give absolute weight, or fraction of layouts height if wt is >= 1 then it is absolute height, else if between 0 and 1 , it is a percentage.

# File lib/canis/core/include/layouts/abstractlayout.rb, line 93
def add_with_weight item, weight
  @components ||= []
  @components << item
  cfg[item][:weight] = weight
end
cget(item, key) click to toggle source

return the config value for a key for an item. The keys are decided by the layout manager itself, such as :weight. @param [Widget] item for which some attribute is required @param [Symbol, String] the key

# File lib/canis/core/include/layouts/abstractlayout.rb, line 76
def cget item, key
  return @item_config[item][key]
end
clear() click to toggle source

clear the list of items the layout has. Usually, the layout fills this list only once. However, if the list of items has changed then this can be used to clear the list, so it is fetched again.

# File lib/canis/core/include/layouts/abstractlayout.rb, line 108
def clear
  @components.clear
end
configure_item(item, config={}) click to toggle source
# File lib/canis/core/include/layouts/abstractlayout.rb, line 68
def configure_item item, config={}
  @item_config[item].merge( config )
  self
end
cset(item, key, val) click to toggle source

set a value for an item and key This is similar to configure_item which takes multiple pairs ( a hash). I am seeing which will be more useful.

# File lib/canis/core/include/layouts/abstractlayout.rb, line 83
def cset item, key, val
  @item_config[item][key] = val
  self
end
do_layout() click to toggle source

This program lays out the widgets deciding their row and columm and height and weight. This program is called once at start of application, and again whenever a RESIZE event happens.

# File lib/canis/core/include/layouts/abstractlayout.rb, line 141
def do_layout
  $log.debug "  inside do_layout"
  _init_layout
  raise "please implement this in your subclass "
  c = @left_margin
  # determine fixed widths and how much is left to share with others,
  # and how many variable width components there are.
  ht = 0   # accumulate fixed height
  fixed_ctr = 0 # how many items have a fixed wt
  var_ctr = 0
  var_wt = 0.0
  @components.each do |e|
    $log.debug "  looping 1 #{e.name} "
    _tmpwt = @wts[e] || 0
    # what of field and button placed side by side
    if e.is_a? Field or e.is_a? Button or e.is_a? Label
      @wts[e] ||= 1
      ht += @wts[e] || 1
      fixed_ctr += 1
    elsif _tmpwt >= 1
        ht += @wts[e] || 0
        fixed_ctr += 1
    elsif _tmpwt > 0 and _tmpwt <= 1
      # FIXME how to specify 100 % ???
      var_ctr += 1
      var_wt += @wts[e]
    end
  end
  unaccounted = @components.count - (fixed_ctr + var_ctr)
  $log.debug "  unacc #{unaccounted} , fixed #{fixed_ctr} , var : #{var_ctr} , ht #{ht} height #{@height}  "
  balance_ht = @height - ht # use this for those who have specified a %
  balance_ht1 = balance_ht * (1 - var_wt )
  average_ht = (balance_ht1 / unaccounted).floor # give this to those who have not specified ht
  average_ht = (balance_ht1 / unaccounted) # give this to those who have not specified ht
  $log.debug "  #{balance_ht} , #{balance_ht1} , #{average_ht} "
  # not accounted for gap in heights
  rem = 0 # remainder to be carried over
  @components.each do |e|
    $log.debug "  looping 2 #{e.name} #{e.class.to_s.downcase} "
    next if @ignore_list.include? e.class.to_s.downcase
    $log.debug "  looping 3 #{e.name} "
    e.row = r
    e.col = c
    wt = @wts[e]
    if wt
      if wt.is_a? Integer
        e.height = wt
      elsif wt.is_a? Float
        e.height = (wt * balance_ht).floor
      end
    else
      # no wt specified, give average of balance wt
      e.height = average_ht
      hround = e.height.floor

      rem += e.height - hround
      e.height = hround
      # see comment in prev block regarding remaininder
      if rem >= 1
        e.height += 1
        rem = 0
      end
    end
    $log.debug "  layout #{e.name} , h: #{e.height} r: #{e.row} , c = #{e.col} "

    e.width = @width
    r += e.height.floor
    r += @gap
  end
  $log.debug "  layout finished "
end
push(*items) click to toggle source

add one more items for this layout to lay out If no items are given, this program will take all visible widgets from the form and stack them, ignoring statusline and applicationheader

# File lib/canis/core/include/layouts/abstractlayout.rb, line 51
def push *items
  @components ||= []
  @components.push items
  self
end
Also aliased as: <<
remove(item) click to toggle source

remove given item from components list This could happen if the item has been removed from the form

# File lib/canis/core/include/layouts/abstractlayout.rb, line 101
def remove item
  @components.remove item
end