6. Sizing GUI Components
This tutorial will teach you how you can change size of GUI components.
Positioning children
First, some quick repetition.
The child components in Rows
are:
- As wide as the
Rows
component - Just heigh enough to surround their content
- Positioned at the top of
Rows
(by default)
To position the child components elsewhere in Rows
, you can insert extra Space
components in Rows
to push apart the children. The Space
children will share the remaining space available in Rows
evenly among themselves.
It works the same for the Columns
component, but the children are instead positioned as columns, and not as rows.
Try resizing the app below, and notice how the Space
children gets smaller/bigger, while the three other children stay at the same size.
class StartPage extends Page{
createGui(){
return Rows.children(
Text.text(`First`).backgroundColor(`red`),
Space.backgroundColor(`pink`),
Text.text(`Second`).backgroundColor(`yellow`),
Space.backgroundColor(`purple`),
Button.text(`To columns`).page(ColumnsPage),
)
}
}
class ColumnsPage extends Page{
createGui(){
return Columns.children(
Text.text(`First`).backgroundColor(`red`),
Space.backgroundColor(`pink`),
Text.text(`Second`).backgroundColor(`yellow`),
Space.backgroundColor(`purple`),
Button.text(`To Rows`).page(StartPage),
)
}
}
Sizing children
It's not only Space
children that can grab some of the remaining available space; any child in Rows
and Columns
can grab some of the remaining available space. But it's only the Space
children that grabs it by default, and by default they all grab equally much of it. But all this can be changed with the configuration method .grow()
on the children. Let's go through how this works in detail.
First, let us ignore the Space
children, and instead focus on all other children, such as Text
and Button
components.
By default, all children in Rows
will be just tall enough to surround their content. If you want them to grow tallwr by grabbing some of the remaining available space, you can call the method .grow()
on the child, and pass it a number indicating how tall the child should be in relation to other children that have also called .grow()
.
A few examples.
class FirstPage extends Page{
createGui(){
return Rows.children(
Text.text(`FirstPage`),
Text.backgroundColor(`red`).text(`None of the children here call .grow(), so all children are just tall enough to surround their content.`),
Button.text(`Go to second page`).page(SecondPage),
)
}
}
class SecondPage extends Page{
createGui(){
return Rows.children(
Text.text(`SecondPage`),
Text.grow(1).backgroundColor(`red`).text(`This text component has called grow(1). Since this is the only child that has called grow(), it will get all of the remaining available space.`),
Button.text(`Go to third page`).page(ThirdPage),
)
}
}
class ThirdPage extends Page{
createGui(){
return Rows.children(
Text.text(`ThirdPage`),
Text.grow(100).backgroundColor(`red`).text(`This text component has called grow(100). Since this is the only child that has called grow(), it will get all of the remaining available space.`),
Button.text(`Go to fourth page`).page(FourthPage),
)
}
}
class FourthPage extends Page{
createGui(){
return Rows.children(
Text.text(`FourthPage`),
Text.grow(2).backgroundColor(`red`).text(`This text component has called grow(2). Since the button below has called grow(1), this component will be twice as tall as the button below.`),
Button.grow(1).text(`Go to first page`).page(FirstPage),
)
}
}
The special thing with the Space
component is that it has the grow set to 1
by default (it has been made like this because that's often how one wants to use it), while all other components has the grow set to 0
by default (which means they will be just big enough to surround their content).
So when you use the Space
component like this:
Space
It has the same functionality as being used like this:
Space.grow(1)
class StartPage extends Page{
createGui(){
return Rows.children(
Space.backgroundColor(`yellow`),
Text.grow(1).backgroundColor(`red`).text(`I grow to one third of the space.`),
Space.backgroundColor(`pink`),
)
}
}
You can still call .grow()
on Space
if you want it to claim another amount of shares of the remaning available space.
class StartPage extends Page{
createGui(){
return Rows.children(
Space.backgroundColor(`yellow`),
Text.grow(1).backgroundColor(`red`).text(`I grow to one fifth of the space.`),
Space.grow(3).backgroundColor(`pink`),
)
}
}
Exercises
Complete the exercises below to see if you have fully mastered what has been taught in this tutorial.
The code in this BagaWork project currently displays a page looking like this:
Your task is to change the code, so The main content
component covers as much space as possible, so the page instead looks like this:
Hint
A carefully chosen .grow(1)
should do the trick. But on which component?
The code in this BagaWork project contains no pages. Your task is to add a new page to the project named StartPage
, and make it look as the page shown below.
Hint
Hmm... Is that GUI conisting of two Rows
that contain two Columns
each? Or two Columns
that contain two Rows
each? Hmm... Seems impossible to tell... Wait, does that mean any of the two approaches will work?
And remember, .grow()
can be called on any child component in Rows
and Columns
. So if Columns
is being used as a child in Rows
, you can call .grow()
on that Columns
component!
Continue on your project from Exercise 2
, but make the GUI look like this:
Hint
You need more .grow(1)
. Add as many as you can. And then add some more. Ehh... No, scratch that last sentence 😅
That's it!
Good work, now you know how to change the size of GUI components! 🥳 Using Rows
and Columns
with .grow()
on the children is enough to create almost any layout you want.
The last thing to learn in the Fundamental section is the tutorial Fundamentals 7. The App Class. Then you will actually know everything needed to be able to start creating small apps 🙂