Note: This is a pre-release of Bagawork. Many things will likely change before the first stable release.

4. Positioning GUI Components

This tutorial will teach you how to create more fancy GUIs by using multiple GUI components in your pages' GUIs.

The root component

As you know, you should in the Page method createGui() use GUI components from Bagawork to create and send back the page's GUI. This method, as all methods, can only send back one value, and in this case that value should be a GUI component. That GUI component is know as the page's root component, and it will cover the entire screen. That it indeed does cover the entire screen is easy to verify by giving the component a background color.

Example

In the app below, the root component of the page has no background color (its background is transparent), and it's the application's default background color we se. So it's hard to tell what space the root component does occupy (but it does still occupy the entire screen).

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Text.text(`This Text component has no background, so it's hard too see what space it occupies.`)
	}
}
Example

In the app below, the root component of the page has an orange background color, so it's easy to see what space it occupies (the entire screen).

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Text.backgroundColor(`orange`).text(`This Text component has an orange background, so it's easy too see what space it occupies.`)
	}
}

Using multiple GUI components

But if createGui() can send back only one GUI component, how can I use multiple GUI components? Well, there exists some GUI components whose sole purpose it to contain and position other GUI components on the screen. These GUI components are called layouts, and the GUI components they contain are called children.

By using a layout, createGui() can send back only one GUI component (the layout), but that GUI component can in turn contain other GUI components. And when the layout component is shown on the screen, it will position and show the child components it contains on the screen too. This way we can build a GUI consisting of multiple GUI components!

Let's go through some of the layouts we can use.

The Rows component

The GUI component called Rows is a layout that positions its children as rows:

  • The first child is positioned at the top
  • The second child is positioned below the first child
  • The third child is positioned below the second child
  • And so on...

All children are as wide as the Rows component, and their height is by default just big enough to surround their content. The Rows component's children should be passed as individual arguments to the configuration method children() (separate the arguments (the children) by , (comma)).

Example

Example of how to use the Rows component to position three Text components as rows. All GUI components are given a background color, so one easily can see the space each component occupies.

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Rows.backgroundColor(`red`).children(
			Text.text(`I'm the first row`).backgroundColor(`pink`),
			Text.text(`I'm the second row`).backgroundColor(`aqua`),
			Text.text(`I'm the third row`).backgroundColor(`lime`)
		)
	}
}

Note in the example above that the root component (the Rows component in this case) occupies the entire screen, including the part occupied by the children, although it doesn't look like that. The children are drawn on top of the Rows component, so their' background is covering the background of the Rows component, so therefore we can't see the background of the Rows component where the children are positioned in this example.

Example

This is the same example as before, but only the Rows component and the third child are given a background to show that the Rows component's background also id drawn where the children are (underneath them).

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Rows.backgroundColor(`red`).children(
			Text.text(`I'm the first row`),
			Text.text(`I'm the second row`),
			Text.text(`I'm the third row`).backgroundColor(`lime`)
		)
	}
}

Positioning children

As you can see in the previous example, the children in Rows will be positioned at the top of the Rows component. You can use the GUI component Space as children in Rows to push apart the children. The Space component is a GUI component who's primary purpose is to simply occupy space, so the other children in Rows are positioned where they should be.

If the Rows component contains a single Space child, that Space child will occupy all the space remaining after the other children have occupied their spaces.

Example

Example of using Rows with a Space child.

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Rows.backgroundColor(`red`).children(
			Text.text(`I'm the first row`).backgroundColor(`pink`),
			Space,
			Text.text(`I'm the last row`).backgroundColor(`lime`)
		)
	}
}

If you use multiple Space children in Rows, then the remaining available space of the Rows component will be divided evenly among the Space children.

Example

Example of using Rows with two Space children.

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Rows.backgroundColor(`red`).children(
			Text.text(`I'm the first row`).backgroundColor(`pink`),
			Space,
			Text.text(`I'm the second row`).backgroundColor(`aqua`),
			Space,
			Text.text(`I'm the third row`).backgroundColor(`lime`)
		)
	}
}

The Space component doesn't show anything, so you can't see it on the screen. But if you give it a background color, you can easily see what space it occupies. While developing, it's a very good idea to give each component a unique color, so you can easily see what space it occupies.

Example

Example of using Rows with three Space children.

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Rows.backgroundColor(`red`).children(
			Text.text(`I'm the first row`).backgroundColor(`pink`),
			Space.backgroundColor(`silver`),
			Text.text(`I'm the second row`).backgroundColor(`aqua`),
			Space.backgroundColor(`yellow`),
			Space.backgroundColor(`brown`),
			Text.text(`I'm the third row`).backgroundColor(`lime`)
		)
	}
}

The Columns component

The GUI component called Columns is a layout that positions its children as columns:

  • The first child is positioned to the left
  • The second child is positioned to the right of the first child
  • The third child is positioned to the right of the second child
  • And so on...

All children are as tall as the Columns component, and their width is by default just big enough to surround their content. The Columns component's children should be passed as individual arguments to the configuration method children() (separate the children/arguments by , (comma)).

Example

Example of how to use the Columns components. All GUI components are given a background color, so one easily can see the space they occupy.

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Columns.backgroundColor(`red`).children(
			Text.text(`First`).backgroundColor(`pink`),
			Text.text(`Second`).backgroundColor(`aqua`),
			Text.text(`Third`).backgroundColor(`lime`)
		)
	}
}

Positioning children

Just as with the Rows component, you can insert extra Space children to push apart the other children.

Example
Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Columns.backgroundColor(`red`).children(
			Text.text(`Left`).backgroundColor(`pink`),
			Space,
			Text.text(`Right`).backgroundColor(`lime`)
		)
	}
}
Example
Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Columns.backgroundColor(`red`).children(
			Space,
			Text.text(`Centered`).backgroundColor(`pink`),
			Space
		)
	}
}

Combining Layouts

So far you might not be that impressed. Not many applications have a GUI consisting of only rows or of only columns like that. But fear not; here's the secret to success: one can use a layout component as a child in another layout component! This way, a wide vararity GUIs can be implemented.

Example

Example of how to combine the Rows component and the Columns component to create a layout with a bottom navigation view (learn how to make it functional later).

Open in Online Editor
class StartPage extends Page{
	createGui(){
		return Rows.backgroundColor(`red`).children(
			Space,
			Text.text(`I'm the main content`).backgroundColor(`pink`),
			Space,
			Columns.backgroundColor(`lime`).children(
				Space,
				Text.text(`Option 1`).backgroundColor(`gold`),
				Space,
				Text.text(`Option 2`).backgroundColor(`silver`),
				Space,
				Text.text(`Option 3`).backgroundColor(`brown`),
				Space
			)
		)
	}
}

Most real GUIs are built on rows and columns like this, so this is a very powerful technique.

Exercises

Complete the exercises below to see if you have fully mastered what has been taught in this tutorial.

Exercise 1

The code in this BagaWork project currently displays a page looking like this:

Your task is to change the code, so the page instead looks like this:

Hint

Just changing the root GUI component to another GUI component should do it. But which GUI component should you change it to?

Exercise 2

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... Doesn't the GUI look like two Rows? With the first row being some Space, and the second row being some Text?

Exercise 3

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... What does the root component look like? Does the GUI seem to consists of Rows, or Columns? After you have figured that out, you can hopefully figure out the rest too. Hopefully ^^

That's it!

Good work, now you have learned the basics about using layouts and building more fancy GUIs! 🥳 It takes some practice before you're good at seeing GUIs as rows and columns, but you actually don't need much more than this to create a wide variety of layouts. Just look at your web browser; all GUI components in it are arranged as rows and columns!

Excited about to learn some more? Then continue with Tutorial 5. Changing Page.