BOXES v0.5

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 many_boxes and 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"))

lesson5.svg

Isn't that nice? If you look at it from afar it looks sort of familiar. Doesn't it?


Further references:

results matching ""

    No results matching ""