In all the examples so far, the submorphs 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 proportion of available space given to each is based on its value as a percentage of the total. 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 make the second submorph take all the available space.
Each morph can have a LayoutSpec that specifies how it should be laid out within its owner; this is ignored if the owner is not an instance of LayoutMorph. LayoutSpec is abstract with two subclasses:
Instances of LayoutSpec have morph as an instance variable. There are methods to set each of these instance variables.
box2 layoutSpec proportionalWidth: 1
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 LayoutSizeSpec. However, an issue with this approach is that it creates a new instance of LayoutSizeSpec and sets both proportionalWidth and proportionalHeight to 1. To modify only one of those properties, it is best to set it directly on the LayoutSizedSpec 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 even spacing 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
Figure 2.9: Evenly spaced
spacer1 and spacer2 each use 1 unit of the free space left by the other morphs in the owner. The total free space is 2 (1+1), therefore each spacer will occupy 1/2 of the free space.
Edit the example Example 2.2 so that the first spacer uses one quarter of the free space and the second one three quarters.
Exercise 2.2: Spacers in quarters