Grid
Layout renderables (hLine
, vLine
), nesting, stacking... all very nice. But boy is it a lot of work sometimes to combine it all into a single layout!
Well that's were grid
comes in (and Compositor
too, see the next page). The idea is simple: take a bunch of renderables and make a grid out of them:
import Term: Panel
import Term.Grid: grid
panels = repeat([Panel(height=6, width=12)], 8)
grid(panels)
╭──────────╮╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯╰──────────╯
Simple, but effective. grid
gives you a lot of options to control the layout:
grid(panels; pad=2) # specify padding
╭──────────╮ ╭──────────╮ ╭──────────╮ ╭──────────╮
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
╰──────────╯ ╰──────────╯ ╰──────────╯ ╰──────────╯
╭──────────╮ ╭──────────╮ ╭──────────╮ ╭──────────╮
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
╰──────────╯ ╰──────────╯ ╰──────────╯ ╰──────────╯
grid(panels; pad=(8, 1)) # hpad & vpad
╭──────────╮ ╭──────────╮ ╭──────────╮ ╭──────────╮
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
╰──────────╯ ╰──────────╯ ╰──────────╯ ╰──────────╯
╭──────────╮ ╭──────────╮ ╭──────────╮ ╭──────────╮
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
╰──────────╯ ╰──────────╯ ╰──────────╯ ╰──────────╯
You can also specify the aspect ratio of the grid:
grid(panels; aspect=1)
╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╲ ╲ ╲ ╲ ╲ ╲
│ ││ │ ╲ ╲ ╲ ╲ ╲ ╲
│ ││ │╲ ╲ ╲ ╲ ╲ ╲
│ ││ │ ╲ ╲ ╲ ╲ ╲ ╲
│ ││ │╲ ╲ ╲ ╲ ╲ ╲
╰──────────╯╰──────────╯ ╲ ╲ ╲ ╲ ╲ ╲
Note that with an aspect ratio of 1
the best way is to create 3
columns and 3
rows, but we only have 8
renderables! No problem, grid
introduces a placeholder for the missing renderables. This is not shown by default, but you can see it with: But you can hide it too:
grid(panels; aspect=1, show_placeholder=true)
╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╲ ╲ ╲ ╲ ╲ ╲
│ ││ │ ╲ ╲ ╲ ╲ ╲ ╲
│ ││ │╲ ╲ ╲ ╲ ╲ ╲
│ ││ │ ╲ ╲ ╲ ╲ ╲ ╲
│ ││ │╲ ╲ ╲ ╲ ╲ ╲
╰──────────╯╰──────────╯ ╲ ╲ ╲ ╲ ╲ ╲
You can use layout
to more directly specify the number of rows and columns in the grid:
grid(panels; layout=(3, 4), show_placeholder=true)
╭──────────╮╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
│ ││ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯╰──────────╯
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲
Leaving a nothing
argument will auto-magically compute the remaining rows
or cols
of the layout: You can use layout
to more directly specify the number of rows and columns in the grid:
grid(panels; layout=(3, nothing), show_placeholder=true)
╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╭──────────╮
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
╰──────────╯╰──────────╯╰──────────╯
╭──────────╮╭──────────╮╲ ╲ ╲ ╲ ╲ ╲
│ ││ │ ╲ ╲ ╲ ╲ ╲ ╲
│ ││ │╲ ╲ ╲ ╲ ╲ ╲
│ ││ │ ╲ ╲ ╲ ╲ ╲ ╲
│ ││ │╲ ╲ ╲ ╲ ╲ ╲
╰──────────╯╰──────────╯ ╲ ╲ ╲ ╲ ╲ ╲
One can use complex expressions for layouts, using an underscore _
to specify empty elements in the layout:
grid(panels[1:6]; layout=:((a * _ * b) / (_ * _ * c * d) / (_ * e * f)))
╭──────────╮╲ ╲ ╲ ╲ ╲ ╲ ╭──────────╮
│ │ ╲ ╲ ╲ ╲ ╲ ╲│ │
│ │╲ ╲ ╲ ╲ ╲ ╲ │ │
│ │ ╲ ╲ ╲ ╲ ╲ ╲│ │
│ │╲ ╲ ╲ ╲ ╲ ╲ │ │
╰──────────╯ ╲ ╲ ╲ ╲ ╲ ╲╰──────────╯
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╭──────────╮╭──────────╮
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲│ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ │ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲│ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ │ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲╰──────────╯╰──────────╯
╲ ╲ ╲ ╲ ╲ ╲ ╭──────────╮╭──────────╮
╲ ╲ ╲ ╲ ╲ ╲│ ││ │
╲ ╲ ╲ ╲ ╲ ╲ │ ││ │
╲ ╲ ╲ ╲ ╲ ╲│ ││ │
╲ ╲ ╲ ╲ ╲ ╲ │ ││ │
╲ ╲ ╲ ╲ ╲ ╲╰──────────╯╰──────────╯
Repeating elements is supported:
grid(panels[1:2]; layout=:((α * _ * α) / (_ * _ * β * β)))
╭──────────╮╲ ╲ ╲ ╲ ╲ ╲ ╭──────────╮
│ │ ╲ ╲ ╲ ╲ ╲ ╲│ │
│ │╲ ╲ ╲ ╲ ╲ ╲ │ │
│ │ ╲ ╲ ╲ ╲ ╲ ╲│ │
│ │╲ ╲ ╲ ╲ ╲ ╲ │ │
╰──────────╯ ╲ ╲ ╲ ╲ ╲ ╲╰──────────╯
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╭──────────╮╭──────────╮
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲│ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ │ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲│ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ │ ││ │
╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲ ╲╰──────────╯╰──────────╯
Note that grid uses vstack
and hstack
to combine the renderables into the layout you requested. As such, it returns a single renderable, you don't have access to the individual renderables that went into making the grid any longer. This also means that the grid can be stack with other content to create a larger layout.