This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/src/main/java/envoy/client/ui/SceneContext.java

108 lines
2.8 KiB
Java
Raw Normal View History

package envoy.client.ui;
import java.io.IOException;
import java.util.Stack;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import envoy.client.data.Settings;
import envoy.client.event.ThemeChangeEvent;
import envoy.event.EventBus;
/**
* Manages a stack of scenes. The most recently added scene is displayed inside
* a stage. When a scene is removed from the stack, its predecessor is
* displayed.
* <p>
* When a scene is loaded, the style sheet for the current theme is applied to
* it.
* <p>
* Project: <strong>envoy-client</strong><br>
* File: <strong>SceneContext.java</strong><br>
* Created: <strong>06.06.2020</strong><br>
*
* @author Kai S. K. Engelbart
* @since Envoy Client v0.1-beta
*/
public final class SceneContext {
public static enum SceneInfo {
CHAT_SCENE("/fxml/ChatScene.fxml"), SETTINGS_SCENE("/fxml/SettingsScene.fxml"), CONTACT_SEARCH_SCENE("/fxml/ContactSearchScene.fxml");
public final String path;
SceneInfo(String path) { this.path = path; }
}
private final Stage stage;
private final FXMLLoader loader = new FXMLLoader();
private final Stack<Scene> sceneStack = new Stack<>();
private static final Settings settings = Settings.getInstance();
/**
* Initializes the scene context.
*
* @param stage the stage in which scenes will be displayed
* @since Envoy Client v0.1-beta
*/
public SceneContext(Stage stage) {
this.stage = stage;
EventBus.getInstance().register(ThemeChangeEvent.class, theme -> applyCSS());
}
/**
* Loads a new scene specified by a scene info.
*
* @param sceneInfo specifies the scene to load
* @throws IOException if the loading process fails
* @since Envoy Client v0.1-beta
*/
public void load(SceneInfo sceneInfo) throws IOException {
loader.setRoot(null);
loader.setController(null);
final var rootNode = (Parent) loader.load(getClass().getResourceAsStream(sceneInfo.path));
final var scene = new Scene(rootNode);
sceneStack.push(scene);
stage.setScene(scene);
applyCSS();
stage.show();
}
/**
* Removes the current scene and displays the previous one.
*
* @since Envoy Client v0.1-beta
*/
public void pop() {
sceneStack.pop();
if (!sceneStack.isEmpty()) {
stage.setScene(sceneStack.peek());
applyCSS();
}
stage.show();
}
private void applyCSS() {
if (!sceneStack.isEmpty()) {
final var styleSheets = stage.getScene().getStylesheets();
2020-06-08 10:02:39 +02:00
final var themeCSS = "/css/" + settings.getCurrentTheme() + ".css";
styleSheets.clear();
styleSheets.addAll(getClass().getResource("/css/base.css").toExternalForm(), getClass().getResource(themeCSS).toExternalForm());
}
}
/**
* @param <T> the type of the controller
* @return the controller used by the current scene
* @since Envoy Client v0.1-beta
*/
public <T> T getController() { return loader.getController(); }
}