def repack
      @widths = Array.new(@rows.empty? ? 0 : @rows[0].size, 0)
      @heights = Array.new(@rows.size, 0)

      filled_columns = []
      filled_rows = []

      # Calculate the maximum widths of each column and the maximum height of each row.
      @rows.each_with_index do |row, row_num|
        row.each_with_index do |element, column_num|
          fills = (element.align_h == :fill)
          @widths[column_num] = [fills ? element.min_width : element.outer_width, @widths[column_num]].max
          filled_columns.push fills

          fills = (element.align_v == :fill)
          @heights[row_num] = [fills ? element.min_width : element.outer_height, @heights[row_num]].max
          filled_rows.push fills
        end
      end

      # Expand the size of each filled column to make the minimum size required.
      unless @widths.empty?
        num_filled_columns = filled_columns.select {|value| value }.count
        total_width = @widths.inject(0, :+) + (padding_left + padding_right) + ((@num_columns - 1) * spacing_h)
        extra_width = min_width - total_width
        if extra_width > 0
          if num_filled_columns > 0
            @widths[filled_columns.index true] += extra_width
          else
            @widths[-1] += extra_width
          end
        end
      end

      # Expand the size of each filled row to make the minimum size required.
      unless @heights.empty?
        num_filled_rows = filled_rows.select {|value| value }.count
        total_height = @heights.inject(0, :+) + (padding_left + padding_right) + ((@num_rows - 1) * spacing_v)
        extra_height = min_height - total_height
        if extra_height > 0
          if num_filled_rows > 0
            @heights[filled_rows.index true] += extra_height
          else
            @heights[-1] += extra_height
          end
        end
      end

      # Actually place all the elements into the grid positions, modified by valign and align.
      current_y = y + padding_top
      @rows.each_with_index do |row, row_num|
        current_x = x + padding_left

        row.each_with_index do |element, column_num|
          element.x = current_x + element.border_thickness

          case element.align_h # Take horizontal alignment into consideration.
            when :fill
              if element.width < @widths[column_num]
                element.width = @widths[column_num]
                element.send :repack if element.is_a? Grid
              end
            when :center
              element.x += (@widths[column_num] - element.width) / 2
            when :right
              element.x += @widths[column_num] - element.width
          end

          current_x += @widths[column_num]
          current_x += spacing_h unless column_num == @num_columns - 1

          element.y = current_y + element.border_thickness

          case element.align_v # Take horizontal alignment into consideration.
            when :fill
              if element.height < @heights[row_num]
                element.height = @heights[row_num]
                element.send :repack if element.is_a? Grid
              end
            when :center
              element.y += (@heights[row_num] - element.height) / 2
            when :bottom
              element.y += @heights[row_num] - element.height
            else
          end
        end

        self.width = current_x - x + padding_left if row_num == 0

        current_y += @heights[row_num] unless row.empty?
        current_y += spacing_h unless row_num == num_rows - 1
      end

      self.height = current_y - y + padding_top

      nil
    end
def repack
      @widths = Array.new(@rows.empty? ? 0 : @rows[0].size, 0)
      @heights = Array.new(@rows.size, 0)

      filled_columns = []
      filled_rows = []

      # Calculate the maximum widths of each column and the maximum height of each row.
      @rows.each_with_index do |row, row_num|
        row.each_with_index do |element, column_num|
          fills = (element.align_h == :fill)
          @widths[column_num] = [fills ? element.min_width : element.outer_width, @widths[column_num]].max
          filled_columns.push fills

          fills = (element.align_v == :fill)
          @heights[row_num] = [fills ? element.min_width : element.outer_height, @heights[row_num]].max
          filled_rows.push fills
        end
      end

      # Expand the size of each filled column to make the minimum size required.
      unless @widths.empty?
        num_filled_columns = filled_columns.select {|value| value }.count
        total_width = @widths.inject(0, :+) + (padding_left + padding_right) + ((@num_columns - 1) * spacing_h)
        extra_width = min_width - total_width
        if extra_width > 0
          if num_filled_columns > 0
            @widths[filled_columns.index true] += extra_width
          else
            @widths[-1] += extra_width
          end
        end
      end

      # Expand the size of each filled row to make the minimum size required.
      unless @heights.empty?
        num_filled_rows = filled_rows.select {|value| value }.count
        total_height = @heights.inject(0, :+) + (padding_left + padding_right) + ((@num_rows - 1) * spacing_v)
        extra_height = min_height - total_height
        if extra_height > 0
          if num_filled_rows > 0
            @heights[filled_rows.index true] += extra_height
          else
            @heights[-1] += extra_height
          end
        end
      end

      # Actually place all the elements into the grid positions, modified by valign and align.
      current_y = y + padding_top
      @rows.each_with_index do |row, row_num|
        current_x = x + padding_left

        row.each_with_index do |element, column_num|
          element.x = current_x + element.border_thickness

          case element.align_h # Take horizontal alignment into consideration.
            when :fill
              if element.width < @widths[column_num]
                element.width = @widths[column_num]
                element.send :repack if element.is_a? Grid
              end
            when :center
              element.x += (@widths[column_num] - element.width) / 2
            when :right
              element.x += @widths[column_num] - element.width
          end

          current_x += @widths[column_num]
          current_x += spacing_h unless column_num == @num_columns - 1

          element.y = current_y + element.border_thickness

          case element.align_v # Take horizontal alignment into consideration.
            when :fill
              if element.height < @heights[row_num]
                element.height = @heights[row_num]
                element.send :repack if element.is_a? Grid
              end
            when :center
              element.y += (@heights[row_num] - element.height) / 2
            when :bottom
              element.y += @heights[row_num] - element.height
            else
          end
        end

        self.width = current_x - x + padding_left if row_num == 0

        current_y += @heights[row_num] unless row.empty?
        current_y += spacing_h unless row_num == num_rows - 1
      end

      self.height = current_y - y + padding_top

      nil
    end
Repack all the elements into their positions.