Galleries
A gallery is a place in the user interface where other entities can show their content. One entity owns the gallery, and then other entities give content to the gallery for display.
Here are some examples of how it could be used:
- An inventory management panel could have a gallery where each item in the inventory displays itself.
- A gallery could be used to show the live ranking of the players. Each player could show how many points they have in the gallery. The gallery would be sorted by points, so the player with the most points would be at the top.
- You could display a grid of a player's abilities using a gallery. Each ability would be responsible for displaying its status in the gallery, for example its icon, cooldown progress, whether it is currently active, etc.
While it would be possible for the main entity to, for example, iterate over all inventory entities and display them directly, this would require more boilerplate to pass data from one context to another, and also for detecting when items are added, removed or changed. Galleries allow you to keep your logic local, making this common pattern much easier to implement.
Galleries allow you to separate the decision of "what" should be displayed from "where" to display it, decoupling the logic of your game from the structure of your user interface, which can simplify your code.
A gallery is a lot like a collector but for user interface content.
Minimal example
This is how you could implement a live ranking gallery that shows each player's score:
pub gallery World.PlayersGallery
pub game fn World.Main() {
// Display the PlayersGallery in a Panel
Content {
Panel {
PlayersGallery
}
}
// Each player gives their own content to the gallery
SpawnEachPlayer owner {
give PlayersGallery {
%(PlayerName + " is here!")
}
}
}
Declaration
A gallery is declared using the gallery keyword:
pub gallery owner.AbilityGallery
The object parameter specifies which entity the gallery belongs to.
In this example, we have chosen the owner as the object parameter
because each player has their own set of abilities, so it makes sense for the gallery to be owned by the player entity.
Use World as the object parameter if you want the gallery to be global:
pub gallery World.RankingGallery
Giving content to a gallery
Use the give keyword to give gallery:
Subspawn ability {
give owner.AbilityGallery {
RaisedButton(KeyQ) { "Fireball" }
}
}
Only until despawned
When an entity despawns, any content it was giving to galleries is automatically removed. This is a powerful feature that ensures your galleries only contain relevant and up-to-date content without needing to manually manage it. For example, your inventory gallery will automatically update as items are added or removed from the player's inventory, without needing to write extra code to handle those cases.
Omitting the object parameter
If omitted, the object parameter will be found from context, if possible:
Spawn ability {
give AbilityGallery { // `owner` object parameter omitted, will be found from context
RaisedButton(KeyQ) { "Fireball" }
}
}
Displaying the gallery
To display the gallery, simply call it directly:
Content {
Panel {
AbilityGallery
}
}
The items in the gallery will follow the layout of the parent element.
So to display items horizontally for example, put them in an HStack:
Content {
Panel {
HStack {
AbilityGallery
}
}
}
You should only ever display the gallery in at most one place in the UI, otherwise the content will be duplicated and it may cause unexpected behavior.
Empty states
To fallback on displaying something else when the gallery is empty, provide a subblock when calling the gallery:
Content {
Panel {
AbilityGallery {
"You have no abilities yet!"
}
}
}
Removing content from a gallery
To manually remove content from a gallery, use an Id with the give keyword,
and then call delete give with the same Id:
give<fireballBtn> owner.AbilityGallery {
RaisedButton(KeyQ) { "Fireball" }
}
delete give<fireballBtn>
When an entity despawns, any content it was giving to galleries is automatically removed, so in many cases you won't need to remove content manually.
Replacing content in a gallery
When you give new content with the same Id, it will replace the old content:
give<fireballBtn> owner.AbilityGallery {
RaisedButton(KeyQ) { "Fireball" }
}
await Tick(5s)
give<fireballBtn> owner.AbilityGallery {
RaisedButton(KeyQ) { "Super Fireball" }
}
Implicit IDs
If you don't specify an Id for the give, the compiler will automatically assign an Id based in its line number.
This means you can omit the Id in many situations, like when inside a with block:
// the with block executes once, and then re-executes whenever FireballPower changes
with FireballPower {
// `give` has no ID here, which means it is given an implicit ID based on its line number.
// This means this block will always replace the `give` from the previous iteration:
give owner.AbilityGallery {
RaisedButton(KeyQ) {
%(FireballPower > 9000 ? "Super Fireball" : Fireball")
}
}
}
This is a common pattern throughout Easel, see Implicit IDs for more details and examples.
Order
Use the order parameter to control the order of content in the gallery.
By default, the order is 0, and items with lower order are displayed before items with higher order.
Items with the same order will be sorted by the time they were given (older items first).
SpawnEachPlayer owner {
with Score { // Use `with` block so when Score changes, we update the content
give RankingGallery(order=-Score) { // negative score so that higher scores are displayed first
%(PlayerName + ": " + Score)
}
}
}
Audience
The audience (and owner) parameters can be used to limit which players can see the content.
By default, audience is set to Audience:All, meaning everyone can see the content,
but you can change it to only show the content to only a specific player or team, for example.
give TauntGallery(audience=Audience:Enemy) {
"Watch out!"
}
The audience and owner parameters work the same as with other functions throughout Easel.
See Audiences for more details and examples on how to use the audience parameter.