Page
On this page you find the documentation for the Page
class.
Introduction
Your app consists of different pages. One page at a time will be shown to the user, so each page has its own graphical user interface (GUI). The user can interact with the GUI in a page (for example by clicking on a button in it). After the user has interacted with the GUI on the page, the app will take the user to the next page and show the GUI of that one instead, and so on.
To add a page to your app, create your own class that extends the Page
class, and override some methods there to give your own Page
class the specific behavior you want it to have. You can name your own Page
classes whatever you want, but they need to have unique names within your app.
Example showing the basic structure of a simple app.
class MyApp extends App{
createStartPage(){
return StartPage
}
}
class StartPage extends Page{
// Override methods here to give the StartPage
// the specific behavior you want it to have.
}
class MenuPage extends Page{
// Override methods here to give the MenuPage
// the specific behavior you want it to have.
}
class GameOverPage extends Page{
// Override methods here to give the GameOverPage
// the specific behavior you want it to have.
}
The p
variable
In BagaWork, you can use the special variable named p
, short for page, to access the constants/variables/methods you have in your Page
class. So, unlike the a
variable, the p
variable refers to different things in your different pages:
- In the
HelloPage
, you can usep
to access the constants/variables/methods you have in theHelloPage
- In the
AboutPage
, you can usep
to access the constants/variables/methods you have in theAboutPage
- Etc.
Example of a page with:
- A page constant
- A page variable
- A page method
class StartPage extends Page{
THE_CONSTANT_NAME = "The constant value"
theVariableName = "The variable value"
theMethodName(){
// Can use p.THE_CONSTANT_NAME to access the constant value.
// Can use p.theVariableName to access the variable value.
// Can use p.theMethodName to access the method.
}
}
In your Page
classes, you can also use the special BagaWork variable a
to access the things you have in your App
class. For more information, see the documentation for the App class.
createBeforeDirections()
- Redirecting the user to another page
The method createBeforeDirections()
will be called directly when the user comes to the page. In it, you can return an array of Direction objects. If there exists a Direction
object that has if
set to true
, the user will immediately be taken to that page, and will never see the GUI of this page (no other methods on this page will be called, not even onBefore()
).
class StartPage extends Page{
createBeforeDirections(){
const oneOrTwo = m.randomInt(1, 2)
return [
Direction.when(oneOrTwo == 1).page(LuckyPage).text(`Was lucky`),
Direction.when(oneOrTwo == 2).page(UnluckyPage).text(`Was unlucky`),
]
}
createGui(){
return Text.text(`This GUI will only be used in the preview, the user will never see it in the app.`)
}
}
class LuckyPage extends Page{
createGui(){
return Rows.children(
Text.text(`You are lucky!`),
Button.text(`Try again`).page(StartPage)
)
}
}
class UnluckyPage extends Page{
createGui(){
return Rows.children(
Text.text(`You are unlucky!`),
Button.text(`Try again`).page(StartPage)
)
}
}
You only need to implement createBeforeDirections()
if you need it.
onBefore()
- Initializing the state of the page
The method onBefore()
will be called each time the user comes to the page (before the page is shown on the screen).
class StartPage extends Page{
// This variable should keep track of how many
// times the user has been on this page.
numberOfVisits = 0
onBefore(){
// So each time the user comes to this page,
// we increment it by 1.
p.numberOfVisits += 1
}
createGui(){
return Rows.children(
Text.text(`You have been on the StartPage ${p.numberOfVisits} times.`),
Button.text(`Go to OtherPage`).page(OtherPage)
)
}
}
You only need to implement onBefore()
if you need it. Many simple pages can leave this method empty, or simply not have it at all.
createGui()
- Creating the GUI
After onBefore()
has been called, createGui()
will be called. In this method you should create the GUI structure the page should have, and send back the GUI structure's root component. The app will then show the page's GUI on the user's screen.
Example showing how to use Page.createGui()
.
class AskQuestionPage extends Page{
createGui(){
return Rows.children(
Text.text(`Do you know the answer to this question?`),
Columns.children(
Button.text(`Yes`).page(YesPage),
Button.text(`No` ).page(NoPage),
),
)
}
}
The root component in your GUI (the Rows
component in the example above) will always be as wide and high as the screen itself.
The GUI is built with the GUI Components from the BagaWork framework. In the sidebar on this page you have a list of them (Views and Layouts).
onAfter()
- Handling user input
When the user has interacted with your GUI (for example by clicking on a button in it) and should be taken to another page, onAfter()
will be called, in which you can handle the user's input.
Example showing how to use Page.onAfter()
.
class AskQuestionPage extends Page{
startTimeInMs = Date.now()
answer = ``
createGui(){
return Rows.children(
Text.text(`Do you know the answer to this question?`),
Columns.children(
Button.text(`Yes`).handler(p.onYesAnswer),
Button.text(`No` ).handler(p.onNoAnswer),
),
)
}
onYesAnswer(){
p.answer = `yes`
}
onNoAnswer(){
p.answer = `no`
}
onAfter(){
const endTimeInMs = Date.now()
const timeToAnswerInMs = endTimeInMs - p.startTimeInMs
if(10000 < timeToAnswerInMs){
// Took more than 10 seconds to answer (too long), handle that here.
}else if(p.answer == `yes`){
// The user clicked on the yes-button within 10 seconds, handle that here.
}else{
// The user clicked on the no-button within 10 seconds, handle that here.
}
}
}
You only need to handle user input in onAfter()
if your app's logic require's that. Many simple apps can simply leave this method empty, or not have it at all.
createAfterDirections()
- Redirecting the user to another page
The method createAfterDirections()
will be called after the user has interacted with the GUI. In it, you can return back an array with Direction objects, indicating which page the user should come to.
class StartPage extends Page{
createGui(){
return Rows.children(
Text.text(`Ready to try your luck?`),
Button.text(`Yes!`),
)
}
createAfterDirections(){
const oneOrTwo = m.randomInt(1, 2)
return [
Direction.when(oneOrTwo == 1).page(LuckyPage).text(`Was lucky`),
Direction.when(oneOrTwo == 2).page(UnluckyPage).text(`Was unlucky`),
]
}
}
class LuckyPage extends Page{
createGui(){
return Rows.children(
Text.text(`You are lucky!`),
Button.text(`Try again`).page(StartPage)
)
}
}
class UnluckyPage extends Page{
createGui(){
return Rows.children(
Text.text(`You are unlucky!`),
Button.text(`Try again`).page(StartPage)
)
}
}
You only need to implement createAfterDirections()
if you need it.
Referring to a page
Sometimes you need to refer to a page you have created. For example, when the user clicks on a Button, you might want to take the user to the page you have created named AboutPage
. To tell the Button
that the user should come to that page when the Button
is clicked, you call the configuration method page()
on the Button
, and you pass it the page the user should come to. To obtain that page, simply write the name you have given your page, e.g.:
Button.page(AboutPage)
class StartPage extends Page{
createGui(){
return Rows.children(
Text.text(`This is the StartPage`),
Button.text(`Go to AboutPage`).page(AboutPage)
)
}
}
Page arguments
When you specify a page the user should come to, you can also pass along arguments (values) to that page by using page argument methods. Page argument methods work the same way as configuration methods on GUI components, but with page argument methods, you decide the names. For example, if you want to pass along an argument named age
with the value 10
, you would write:
ThePageName.age(10)
You can name the argument whatever you want, and you can pass along how many page arguments you want.
The arguments will then be assigned to the page the user comes to, so you can access them through the p
variable, e.g. use p.age
to obtain the value.
class StartPage extends Page{
createGui(){
return Rows.children(
Text.text(`This is the StartPage`),
Button.text(`Info about Alice`).page(AboutPage.name(`Alice`).age(10)),
Button.text(`Info about Bob`).page(AboutPage.age(15).name(`Bob`)),
)
}
}
class AboutPage extends Page{
// These will get their values from page arguments.
name = `DEFAULT_NAME`
age = -1
createGui(){
return Rows.children(
Text.text(`${p.name} is ${p.age} years old.`),
Button.text(`Go to StartPage`).page(StartPage)
)
}
}