class TTY::Table::ColumnConstraint

A class responsible for enforcing column constraints.

Used internally by {Renderer::Basic} to enforce correct column widths.

@api private

Constants

BORDER_WIDTH
MIN_WIDTH

Attributes

renderer[R]
table[R]

Public Class Methods

new(table, renderer) click to toggle source

Initialize a Columns

@param [TTY::Table] table

@param [TTY::Table::Renderer] renderer

@api public

# File lib/tty/table/column_constraint.rb, line 30
def initialize(table, renderer)
  @table    = table
  @renderer = renderer
end

Public Instance Methods

border_size() click to toggle source

Total border size

@return [Integer]

@api public

# File lib/tty/table/column_constraint.rb, line 49
def border_size
  BORDER_WIDTH * (table.columns_size - 1) + outside_border_size
end
enforce() click to toggle source

Return the constrained column widths.

Account for table field widths and any user defined constraints on the table width.

@api public

# File lib/tty/table/column_constraint.rb, line 87
def enforce
  assert_minimum_width
  padding = renderer.padding

  if natural_width <= renderer.width
    if renderer.resize
      expand_column_widths
    else
      renderer.column_widths.map do |width|
        padding.left + width + padding.right
      end
    end
  else
    if renderer.resize
      shrink
    else
      rotate
    end
  end
end
minimum_width() click to toggle source

Estimate minimum table width to be able to display content

@return [Integer]

@api public

# File lib/tty/table/column_constraint.rb, line 68
def minimum_width
  table.columns_size * MIN_WIDTH + border_size
end
natural_width() click to toggle source

Return column's natural unconstrained widths

@return [Integer]

@api public

# File lib/tty/table/column_constraint.rb, line 77
def natural_width
  renderer.column_widths.inject(0, &:+) + border_size + padding_size
end
outside_border_size() click to toggle source

Estimate outside border size

@return [Integer]

@api public

# File lib/tty/table/column_constraint.rb, line 40
def outside_border_size
  renderer.border_class == TTY::Table::Border::Null ? 0 : 2
end
padding_size() click to toggle source

Measure total padding size for a table

@return [Integer]

@api public

# File lib/tty/table/column_constraint.rb, line 58
def padding_size
  padding = renderer.padding
  (padding.left + padding.right) * table.columns_count
end

Private Instance Methods

assert_minimum_width() click to toggle source

Assert minimum width for the table content

@raise [TTY::ResizeError]

@api private

# File lib/tty/table/column_constraint.rb, line 157
def assert_minimum_width
  width = renderer.width
  return unless width <= minimum_width
  raise ResizeError, "Table's width is too small to contain the content " \
                     "(min width #{minimum_width}, currently set #{width})"
end
distribute_extra_width(widths) click to toggle source

Distribute remaining width to meet the total width requirement.

@param [Array] widths

@api private

# File lib/tty/table/column_constraint.rb, line 169
def distribute_extra_width(widths)
  column_size     = table.columns_size
  # TODO - add padding size to fully check extra width
  extra_width     = renderer.width - (widths.reduce(:+) + border_size)
  per_field_width = extra_width / column_size
  remaining_width = extra_width % column_size
  extra = [1] * remaining_width + [0] * (column_size - remaining_width)

  widths.map.with_index do |width, index|
    width + per_field_width + extra[index]
  end
end
expand_column_widths() click to toggle source

Expand column widths to match the requested width

@api private

# File lib/tty/table/column_constraint.rb, line 124
def expand_column_widths
  columns_count = table.columns_count
  max_width     = renderer.width
  extra_column_width = ((max_width - natural_width) / columns_count.to_f).floor

  widths = (0...columns_count).reduce([]) do |lengths, col|
    lengths << renderer.column_widths[col] + extra_column_width
  end
  distribute_extra_width(widths)
end
rotate() click to toggle source

Rotate table to vertical orientation and print information to stdout

@api private

# File lib/tty/table/column_constraint.rb, line 113
def rotate
  Kernel.warn "The table size exceeds the currently set width." \
              "Defaulting to vertical orientation."
  table.orientation = :vertical
  table.rotate
  Columns.widths_from(table)
end
shrink() click to toggle source

Shrink column widths to match the requested width

@api private

# File lib/tty/table/column_constraint.rb, line 138
def shrink
  column_size = table.columns_size
  ratio       = ((natural_width - renderer.width) / column_size.to_f).ceil

  widths = (0...column_size).reduce([]) do |lengths, col|
    width = (renderer.column_widths[col] - ratio)
    # basically ruby 2.4 Numeric#clamp
    width = width < minimum_width ? minimum_width : width
    width = width > renderer.width ? renderer.width : width
    lengths << width
  end
  distribute_extra_width(widths)
end