2.3 Proportion

In all the examples so far, the submorphs each have a fixed size. They can also be given proportional sizes so their actual size will be based on a percentage of the available space. The available space is the space after removing the padding, the gaps between submorphs, and the sizes of submorphs that have a fixed size.

Each submorph can be given a different proportional size value. The amount of the available space given to each is its percentage of the total values. For example, suppose a row LayoutMorph contains three submorphs that use a proportional width, and they are assigned the values 2, 3, and 5. The total is 10, so the first will take 2/10 (20%), the second will take 3/10 (30%), and the third will take 5/10 (50%) of the available space.

Let’s modify the previous example to cause the second submorph to take all the available space.

Each morph can have a LayoutSpec that specifies how it should be laid out within its owner, this ignored if the owner is not a LayoutMorph instance.

Instances of LayoutSpec have the following instance variables: morph, fixedWidth, fixedHeight, offAxisEdgeWeight, proportionalWidth, and proportionalHeight. There are methods to set each of these instance variables.

box2 layoutSpec proportionalWidth: 1
ch03-layoutmorph-example7

Figure 2.8: Using proportionalWidth

We could have added box2 to layout using the message #add:proportionWidth: which adds a submorph AND sets the proportionalWidth property of its LayoutSpec. However, an issue with this approach is that it creates a new instance of LayoutSpec where the values of proportionalWidth and proportionalHeight are both 1. To only modify one of those properties, it’s best to set it directly on the LayoutSpec instance of the morph.

Let’s modify our example Example 2.1 so the boxes are spread across the width of the LayoutMorph instance with an even amount of space between them.

box1 := ColoredBoxMorph new color: Color red; morphExtent: 50 @ 75.
box2 := ColoredBoxMorph new color: Color green; morphExtent: 75 @ 50.
box3 := ColoredBoxMorph new color: Color blue; morphExtent: 100 @ 100.
spacer1 := ColoredBoxMorph new color: Color transparent.
spacer1 layoutSpec proportionalWidth: 1.
spacer2 := ColoredBoxMorph new color: Color transparent.
spacer2 layoutSpec proportionalWidth: 1.
layout := LayoutMorph newRow
   morphExtent: 350 @ 150;
   separation: 10;
   addMorph: box1;
   addMorph: spacer1;
   addMorph: box2;
   addMorph: spacer2;
   addMorph: box3.
layout openInWorld.

Example 2.2: Layout with spacer

ch03-layoutmorph-example8

Figure 2.9: Evenly spaced

spacer1 and spacer2 each uses 1 of the free space left by the other morphs in the owner. The total free space is counted as 2 (1+1), therefore eacher spacer will occupy 1/2 of the free space.

 CuisLogo Edit the example Example 2.2 so that the first spacer use one quarter of the free space and the second one three quarters.

Exercise 2.2: Spacers in quarters