In our previous lesson, we created code that can fill a series of pages using many small boxes.
But only when those boxes are all alike. Once the boxes had different widths, the right side of our layout got all ragged. You surely have seen things like it when using word processors or reading web pages, where the text is all aligned on the left and all ragged on the right. It's called a "left-aligned" or "ragged-right" layout.
The reason is that we exceed the page width by a random amount, and then, when moving that box to the next row, we are left a random amount short of the desired width.
Could we make it look aligned on BOTH sides? Of course. Let's try.
The code for the
Box class and creating
pages is just like
before, so it will not be shown here.
And of course, we need a new layout function. The plan is this:
- Organize boxes in rows, like before.
- When we are about to go too wide, see how much "slack" is left between the right side of our last box in the row and the edge of the page.
- Spread that slack by sliding all boxes slightly right so nobody notices.
22# We add a "separation" constant so you can see the boxes individually 23separation = .2 24 25 26def layout(_boxes): 27 # Because we modify the box list, we will work on a copy 28 boxes = _boxes[:] 29 # We start at page 0 30 page = 0 31 # The 1st box should be placed in the correct page 32 previous = boxes.pop(0) 33 previous.x = pages[page].x 34 previous.y = pages[page].y 35 row =  36 while boxes: 37 # We take the new 1st box 38 box = boxes.pop(0) 39 # And put it next to the other 40 box.x = previous.x + previous.w + separation 41 # At the same vertical location 42 box.y = previous.y 43 # But if it's too far to the right... 44 if (box.x + box.w) > (pages[page].x + pages[page].w): 45 # We adjust the row 46 slack = (pages[page].x + pages[page].w) - ( 47 row[-1].x + row[-1].w 48 ) 49 bump = slack / len(row) 50 # The 1st box gets 0 bumps, the 2nd gets 1 and so on 51 for i, b in enumerate(row): 52 b.x += bump * i 53 # We start a new row 54 row =  55 # We go all the way left and a little down 56 box.x = pages[page].x 57 box.y = previous.y + previous.h + separation 58 59 # But if we go too far down 60 if box.y + box.h > pages[page].y + pages[page].h: 61 # We go to the next page 62 page += 1 63 # And put the box at the top-left 64 box.x = pages[page].x 65 box.y = pages[page].y 66 67 # Put the box in the row 68 row.append(box) 69 previous = box 70 71 72layout(many_boxes)
The code for
draw_boxes() itself needs no changes, so it will not be shown.
101draw_boxes(many_boxes, "lesson5.svg", ("100cm", "50cm"))
Isn't that nice? If you look at it from afar it looks sort of familiar. Doesn't it?