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; /** * Project: envoy-client
* File: SceneContext.java
* Created: 06.06.2020
* * @author Kai S. K. Engelbart * @since Envoy Client v0.1-beta */ public final class SceneContext { 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 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(); stage.setScene(sceneStack.peek()); applyCSS(); stage.show(); } private void applyCSS() { if (!sceneStack.isEmpty()) { final var styleSheets = stage.getScene().getStylesheets(); final var themeCSS = "/css/" + (settings.isUsingDefaultTheme() ? settings.getCurrentThemeName() : "custom") + ".css"; styleSheets.clear(); styleSheets.addAll(getClass().getResource("/css/base.css").toExternalForm(), getClass().getResource(themeCSS).toExternalForm()); } } /** * @param the type of the controller * @return the controller used by the current scene * @since Envoy Client v0.1-beta */ public T getController() { return loader.getController(); } }