Method: TerminalLayout::RenderObject#layout

Defined in:
lib/terminal_layout.rb

#layoutObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/terminal_layout.rb', line 120

def layout
  self.children = []
  @current_x = 0
  @current_y = 0
  if @box.display == :block && @box.content.length > 0
    ending_x = ending_x_for_current_y
    available_width = ending_x - @current_x
    new_parent = Box.new(content: nil, style: @box.style.dup.merge(width: available_width))
    inline_box = Box.new(content: @box.content, style: {display: :inline})
    new_parent.children = [inline_box].concat @box.children
    children2crawl = [new_parent]
  else
    children2crawl = @box.children
  end

  children2crawl.each do |cbox|
    if cbox.display == :float
      next if cbox.width.to_i == 0

      render_object = layout_float cbox
      cbox.height = render_object.height

      next if cbox.height.to_i == 0

      self.children << render_object
    elsif cbox.display == :block
      if children.last && children.last.display == :inline && @current_x != 0
        @current_x = 0
        @current_y += 1
      end

      @current_x = starting_x_for_current_y
      available_width = ending_x_for_current_y - @current_x

      if cbox.width && cbox.width > available_width
        @current_y += 1
        @current_x = starting_x_for_current_y
        available_width = ending_x_for_current_y - @current_x
      end

      render_object = render_object_for(cbox, content:nil, style: {
        x: @current_x,
        y: @current_y,
        width: (cbox.width || available_width)
      })
      render_object.layout

      if cbox.height
        render_object.height = cbox.height
      end

      next if [nil, 0].include?(render_object.width) || [nil, 0].include?(render_object.height)

      @current_x = 0
      @current_y += [render_object.height, 1].max

      self.children << render_object
    elsif cbox.display == :inline
      @current_x = starting_x_for_current_y if @current_x == 0
      available_width = ending_x_for_current_y - @current_x

      content_i = 0
      content = ""

      loop do
        partial_content = cbox.content[content_i...(content_i + available_width)]
        chars_needed = partial_content.length
        self.children << render_object_for(
          cbox,
          content:partial_content,
          style: {
            display: :inline,
            x: @current_x,
            y: @current_y,
            width:chars_needed,
            height:1
          }
        )

        content_i += chars_needed

        if chars_needed >= available_width
          @current_y += 1
          @current_x = starting_x_for_current_y
          available_width = ending_x_for_current_y - @current_x
        elsif chars_needed == 0
          break
        else
          @current_x += chars_needed
        end

        break if content_i >= cbox.content.length
      end
    end
  end

  if !height
    if children.length >= 2
      last_child = children.max{ |child| child.y }
      self.height = last_child.y + last_child.height
    elsif children.length == 1
      self.height = self.children.first.height
    else
      self.height = @box.height || 0
    end
  end

  self.children.each do |child|
    child.box.computed[:x] += x
    child.box.computed[:y] += y
  end

  self.children
end