-
Notifications
You must be signed in to change notification settings - Fork 35
Navigating Between Views
Navigating between views using InventoryFramework is pretty simple and straightforward, but there's some "little things" that you must understand about Data Transitivity and Shared Contexts before really diving into it.
- Basic Usage
openForPlayervs.openForEveryone-
Creating Flows with
back()andonResume - Understaing Data Transitivity
Let's get started with the most basic usage of navigation between views, we have the following views:
// A.java
@Override
public void onInit(ViewConfigBuilder config) {
config.title("A");
}
@Override
public void onFirstRender(RenderContext render) {
// Moves player to "B" view on click
render.firstSlot(new ItemStack(Material.DIAMOND))
.onClick(click -> click.openForPlayer(B.class));
}// B.java
@Override
public void onInit(ViewConfigBuilder config) {
config.title("B");
}
@Override
public void onFirstRender(RenderContext render) {
// Moves player to back to "A" view on click
render.firstSlot(new ItemStack(Material.REDSTONE))
.onClick(click -> click.openForPlayer(A.class));
}Take a look inside the onClick method of each item, we have a openForPlayer method. That method is responsible for opening a view to the player that clicked on the item. Its signature is similar to ViewFrame's open but without the view class parameter. Pretty simple.
You've probably noticed that there is a another function called openForEveryone, it's also used to navigate between views, but... For shared contexts. Learn more about Shared Contexts.
In short, the difference is that: openForPlayer considers the subject of the context launched at that moment, that is, if you are opening within an onClick the context is SlotClickContext whose current player is the one who clicked on the item, then the next view will be displayed for that player.
Now, with shared context and using openForEveryone, the next screen will be opened to all players present in that context.
Inventory Framework has a feature that make possible to return to the previous view using a method called back(), it's works exactly like a browser history and it's especially useful when...
- You don't know which view the player is coming from;
- Cannot access the view (e.g.
SomeView.classis not available) so is not possible to useopenForPlayer(...)) - Your view can be opened from different views, not just one, so there is no way to directly reference a single view to return.
So let's take a look, we will use a code similiar from Basic Usage topic but replacing openForPlayer in "B" view by back() and REDSTONE item by a GLOWSTONE_DUST.
// B.java
@Override
public void onInit(ViewConfigBuilder config) {
config.title("B");
}
@Override
public void onFirstRender(RenderContext render) {
// Moves player to back to the previous view on click
render.firstSlot(new ItemStack(Material.GLOWSTONE_DUST))
.onClick(click -> click.back());
}onResume is a method that is called when a player comes back from a view that used back() to navigate, so:
- Player go to "B" from "A" using
openForPlayer(B.class) - Player goes back to "A" using
back() -
onResumeis called on "A".
Resume have two parameters: origin that called back() and target that's the view who player is going back to. In our case origin context will have "B" as root and target will have "A" as root.
You can do cool things with that like changing the title of current view from "A" to "Welcome Back"!!
// A.java
@Override
public void onResume(Context origin, Context target) {
// Use `target` here since its the current context
target.updateTitleForPlayer("Welcome back!");
}Different from ViewFrame's open, context's back() actually opens the view to the player but it doesn't perform rendering, instead, once player uses openForPlayer or openForEveryone a snapshot of his context is stored internally and when back() is called it's resumed exactly the same way it was before so:
-
onOpennoronFirstRenderis called; - All states will have the same value they had before
open.
Let's see it in practice, we'll create a counter state that holds a initial int value of 0, before player get's navigated to "B" view, we'll change the value of this counter to 1.
private final MutableIntState counterState = mutableState(0);
// B.java
@Override
public void onInit(ViewConfigBuilder config) {
config.title("B");
}
@Override
public void onOpen(OpenContext open) {
int currentCount = counterState.get(open);
// This code changes the current title to
open.modifyConfig().title("B (count = " + currentCount + ")")
}
@Override
public void onFirstRender(RenderContext render) {
// Moves player to back to the previous view on click
render.firstSlot(new ItemStack(Material.GLOWSTONE_DUST))
.onClick(click -> click.back());
}We have a Counter code sample that uses a State Management to create a counter, take a look at it!
Data transitivity during navigation between screens can simplify data resolution so that it is not necessary to re-declare each piece of data at each navigation.
In the "Opening and Closing" in Basic Usage or "Initial State" in Advanced State Management teaches you how to apply initial data when a view is opened, this data disappears when the view closes, however, you can keep it in case of transition from one screen to another.
Welcome to the Inventory Framework documentation.
- Pagination — Display large collections of items across multiple pages.
- Layouts (a.k.a. Masks or Patterns) — Define visual patterns for item placement.
- Scheduled Updates
- Anvil Input — Capture text input from players using an anvil GUI.
- Dynamic Title Update — Update the inventory’s title in real time.
You can find practical examples in the examples directory.