Class: AbstractLayout

Inherits:
Object show all
Defined in:
lib/canis/core/include/layouts/abstractlayout.rb

Direct Known Subclasses

FlowLayout, SplitLayout, StackLayout

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(form, config = {}, &block) ⇒ AbstractLayout

Returns a new instance of AbstractLayout.

Parameters:

  • optional (Form)

    give a form

  • optional (Hash)

    give settings/attributes which will be set into variables



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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

Instance Attribute Details

#bottom_marginObject

top and left are actually row and col in widgets



16
17
18
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 16

def bottom_margin
  @bottom_margin
end

#componentsObject

Returns the value of attribute components.



23
24
25
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 23

def components
  @components
end

#formObject

Returns the value of attribute form.



13
14
15
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 13

def form
  @form
end

#gapObject

gp between objects



22
23
24
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 22

def gap
  @gap
end

#heightObject

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.



20
21
22
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 20

def height
  @height
end

#height_pcObject

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.



20
21
22
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 20

def height_pc
  @height_pc
end

#ignore_listObject

Returns the value of attribute ignore_list.



24
25
26
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 24

def ignore_list
  @ignore_list
end

#left_marginObject

top and left are actually row and col in widgets



16
17
18
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 16

def left_margin
  @left_margin
end

#right_marginObject

top and left are actually row and col in widgets



16
17
18
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 16

def right_margin
  @right_margin
end

#top_marginObject

top and left are actually row and col in widgets



16
17
18
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 16

def top_margin
  @top_margin
end

#widthObject

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.



20
21
22
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 20

def width
  @width
end

#width_pcObject

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.



20
21
22
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 20

def width_pc
  @width_pc
end

Instance Method Details

#_init_layoutObject

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



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# 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 = {}) ⇒ Object

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



59
60
61
62
63
64
65
66
# 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) ⇒ Object

Add a component, giving a weightage for height if wt is >= 1 then it is absolute height, else if between 0 and 1 , it is a percentage.

Parameters:

  • give (Fixnum, Float)

    absolute weight, or fraction of layouts height



93
94
95
96
97
# 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) ⇒ Object

return the config value for a key for an item. The keys are decided by the layout manager itself, such as :weight.

Parameters:

  • item (Widget)

    for which some attribute is required

  • the (Symbol, String)

    key



76
77
78
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 76

def cget item, key
  return @item_config[item][key]
end

#clearObject

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.



108
109
110
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 108

def clear
  @components.clear
end

#configure_item(item, config = {}) ⇒ Object



68
69
70
71
# 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) ⇒ Object

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.



83
84
85
86
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 83

def cset item, key, val
  @item_config[item][key] = val
  self
end

#do_layoutObject

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.



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# 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? Fixnum
        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) ⇒ Object Also known as: <<

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



51
52
53
54
55
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 51

def push *items
  @components ||= []
  @components.push items
  self
end

#remove(item) ⇒ Object

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



101
102
103
# File 'lib/canis/core/include/layouts/abstractlayout.rb', line 101

def remove item
  @components.remove item
end