Improve Scene Switching #109
@@ -6,7 +6,7 @@ import envoy.data.User.UserStatus;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import envoy.client.data.Context;
 | 
					import envoy.client.data.Context;
 | 
				
			||||||
import envoy.client.helper.ShutdownHelper;
 | 
					import envoy.client.helper.ShutdownHelper;
 | 
				
			||||||
import envoy.client.ui.SceneContext.SceneInfo;
 | 
					import envoy.client.ui.SceneInfo;
 | 
				
			||||||
import envoy.client.util.UserUtil;
 | 
					import envoy.client.util.UserUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import java.util.*;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import javafx.scene.input.KeyCombination;
 | 
					import javafx.scene.input.KeyCombination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.ui.SceneContext.SceneInfo;
 | 
					import envoy.client.ui.SceneInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Contains all keyboard shortcuts used throughout the application.
 | 
					 * Contains all keyboard shortcuts used throughout the application.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,6 @@ import java.io.IOException;
 | 
				
			|||||||
import java.util.Stack;
 | 
					import java.util.Stack;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javafx.application.Platform;
 | 
					 | 
				
			||||||
import javafx.fxml.FXMLLoader;
 | 
					import javafx.fxml.FXMLLoader;
 | 
				
			||||||
import javafx.scene.*;
 | 
					import javafx.scene.*;
 | 
				
			||||||
import javafx.stage.Stage;
 | 
					import javafx.stage.Stage;
 | 
				
			||||||
@@ -28,51 +27,11 @@ import envoy.client.event.*;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public final class SceneContext implements EventListener {
 | 
					public final class SceneContext implements EventListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Contains information about different scenes and their FXML resource files.
 | 
					 | 
				
			||||||
	 *
 | 
					 | 
				
			||||||
	 * @author Kai S. K. Engelbart
 | 
					 | 
				
			||||||
	 * @since Envoy Client v0.1-beta
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public enum SceneInfo {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/**
 | 
					 | 
				
			||||||
		 * The main scene in which the chat screen is displayed.
 | 
					 | 
				
			||||||
		 *
 | 
					 | 
				
			||||||
		 * @since Envoy Client v0.1-beta
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		CHAT_SCENE("/fxml/ChatScene.fxml"),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/**
 | 
					 | 
				
			||||||
		 * The scene in which the settings screen is displayed.
 | 
					 | 
				
			||||||
		 *
 | 
					 | 
				
			||||||
		 * @since Envoy Client v0.1-beta
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		SETTINGS_SCENE("/fxml/SettingsScene.fxml"),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/**
 | 
					 | 
				
			||||||
		 * The scene in which the login screen is displayed.
 | 
					 | 
				
			||||||
		 *
 | 
					 | 
				
			||||||
		 * @since Envoy Client v0.1-beta
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		LOGIN_SCENE("/fxml/LoginScene.fxml");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/**
 | 
					 | 
				
			||||||
		 * The path to the FXML resource.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		public final String path;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		SceneInfo(String path) {
 | 
					 | 
				
			||||||
			this.path = path;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private final Stage			stage;
 | 
						private final Stage			stage;
 | 
				
			||||||
	private final FXMLLoader	loader			= new FXMLLoader();
 | 
						private final Stack<Parent>	roots		= new Stack<>();
 | 
				
			||||||
	private final Stack<Scene>	sceneStack		= new Stack<>();
 | 
						private final Stack<Object>	controllers	= new Stack<>();
 | 
				
			||||||
	private final Stack<Object>	controllerStack	= new Stack<>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final Settings settings = Settings.getInstance();
 | 
						private Scene scene;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Initializes the scene context.
 | 
						 * Initializes the scene context.
 | 
				
			||||||
@@ -88,44 +47,44 @@ public final class SceneContext implements EventListener {
 | 
				
			|||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Loads a new scene specified by a scene info.
 | 
						 * Loads a new scene specified by a scene info.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * @param sceneInfo specifies the scene to load
 | 
						 * @param info specifies the scene to load
 | 
				
			||||||
	 * @throws RuntimeException if the loading process fails
 | 
						 * @throws RuntimeException if the loading process fails
 | 
				
			||||||
	 * @since Envoy Client v0.1-beta
 | 
						 * @since Envoy Client v0.1-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void load(SceneInfo sceneInfo) {
 | 
						public void load(SceneInfo info) {
 | 
				
			||||||
		EnvoyLog.getLogger(SceneContext.class).log(Level.FINER, "Loading scene " + sceneInfo);
 | 
							EnvoyLog.getLogger(SceneContext.class).log(Level.FINER, "Loading scene " + info);
 | 
				
			||||||
		loader.setRoot(null);
 | 
					 | 
				
			||||||
		loader.setController(null);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			final var	rootNode	=
 | 
					 | 
				
			||||||
				(Parent) loader.load(getClass().getResourceAsStream(sceneInfo.path));
 | 
					 | 
				
			||||||
			final var	scene		= new Scene(rootNode);
 | 
					 | 
				
			||||||
			final var	controller	= loader.getController();
 | 
					 | 
				
			||||||
			controllerStack.push(controller);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sceneStack.push(scene);
 | 
								// Load root node and controller
 | 
				
			||||||
 | 
								var		loader		= new FXMLLoader();
 | 
				
			||||||
 | 
								Parent	root		= loader.load(getClass().getResourceAsStream(info.path));
 | 
				
			||||||
 | 
								Object	controller	= loader.getController();
 | 
				
			||||||
 | 
								roots.push(root);
 | 
				
			||||||
 | 
								controllers.push(controller);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (scene == null) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// One-time scene initialization
 | 
				
			||||||
 | 
									scene = new Scene(root, stage.getWidth(), stage.getHeight());
 | 
				
			||||||
 | 
									applyCSS();
 | 
				
			||||||
				stage.setScene(scene);
 | 
									stage.setScene(scene);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									scene.setRoot(root);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Remove previous keyboard shortcuts
 | 
				
			||||||
 | 
								scene.getAccelerators().clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Supply the global custom keyboard shortcuts for that scene
 | 
								// Supply the global custom keyboard shortcuts for that scene
 | 
				
			||||||
			scene.getAccelerators()
 | 
								scene.getAccelerators()
 | 
				
			||||||
				.putAll(GlobalKeyShortcuts.getInstance().getKeyboardShortcuts(sceneInfo));
 | 
									.putAll(GlobalKeyShortcuts.getInstance().getKeyboardShortcuts(info));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Supply the scene specific keyboard shortcuts
 | 
								// Supply the scene specific keyboard shortcuts
 | 
				
			||||||
			if (controller instanceof KeyboardMapping)
 | 
								if (controller instanceof KeyboardMapping)
 | 
				
			||||||
				scene.getAccelerators()
 | 
									scene.getAccelerators()
 | 
				
			||||||
					.putAll(((KeyboardMapping) controller).getKeyboardShortcuts());
 | 
										.putAll(((KeyboardMapping) controller).getKeyboardShortcuts());
 | 
				
			||||||
 | 
							} catch (IOException e) {
 | 
				
			||||||
			// The LoginScene is the only scene not intended to be resized
 | 
					 | 
				
			||||||
			// As strange as it seems, this is needed as otherwise the LoginScene won't be
 | 
					 | 
				
			||||||
			// displayed on some OS (...Debian...)
 | 
					 | 
				
			||||||
			stage.sizeToScene();
 | 
					 | 
				
			||||||
			Platform.runLater(() -> stage.setResizable(sceneInfo != SceneInfo.LOGIN_SCENE));
 | 
					 | 
				
			||||||
			applyCSS();
 | 
					 | 
				
			||||||
			stage.show();
 | 
					 | 
				
			||||||
		} catch (final IOException e) {
 | 
					 | 
				
			||||||
			EnvoyLog.getLogger(SceneContext.class).log(Level.SEVERE,
 | 
					 | 
				
			||||||
| 
						
							
	
	
	
	
	
	
	
	 
					
					kske marked this conversation as resolved
					
				 
				 | 
					|||||||
				String.format("Could not load scene for %s: ", sceneInfo), e);
 | 
					 | 
				
			||||||
			throw new RuntimeException(e);
 | 
								throw new RuntimeException(e);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -137,29 +96,30 @@ public final class SceneContext implements EventListener {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void pop() {
 | 
						public void pop() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Pop scene and controller
 | 
							// Pop current root node and controller
 | 
				
			||||||
		sceneStack.pop();
 | 
							roots.pop();
 | 
				
			||||||
		controllerStack.pop();
 | 
							controllers.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Apply new scene if present
 | 
							// Apply new scene if present
 | 
				
			||||||
		if (!sceneStack.isEmpty()) {
 | 
							if (!roots.isEmpty()) {
 | 
				
			||||||
			final var newScene = sceneStack.peek();
 | 
								scene.setRoot(roots.peek());
 | 
				
			||||||
			stage.setScene(newScene);
 | 
					
 | 
				
			||||||
			applyCSS();
 | 
								// Invoke restore if controller is restorable
 | 
				
			||||||
			stage.sizeToScene();
 | 
								var controller = controllers.peek();
 | 
				
			||||||
			// If the controller implements the Restorable interface,
 | 
					 | 
				
			||||||
			// the actions to perform on restoration will be executed here
 | 
					 | 
				
			||||||
			final var controller = controllerStack.peek();
 | 
					 | 
				
			||||||
			if (controller instanceof Restorable)
 | 
								if (controller instanceof Restorable)
 | 
				
			||||||
				((Restorable) controller).onRestore();
 | 
									((Restorable) controller).onRestore();
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Remove the current scene entirely
 | 
				
			||||||
 | 
								scene = null;
 | 
				
			||||||
 | 
								stage.setScene(null);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		stage.show();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void applyCSS() {
 | 
						private void applyCSS() {
 | 
				
			||||||
		if (!sceneStack.isEmpty()) {
 | 
							if (scene != null) {
 | 
				
			||||||
			final var	styleSheets	= stage.getScene().getStylesheets();
 | 
								var	styleSheets	= scene.getStylesheets();
 | 
				
			||||||
			final var	themeCSS	= "/css/" + settings.getCurrentTheme() + ".css";
 | 
								var	themeCSS	= "/css/" + Settings.getInstance().getCurrentTheme() + ".css";
 | 
				
			||||||
			styleSheets.clear();
 | 
								styleSheets.clear();
 | 
				
			||||||
			styleSheets.addAll(getClass().getResource("/css/base.css").toExternalForm(),
 | 
								styleSheets.addAll(getClass().getResource("/css/base.css").toExternalForm(),
 | 
				
			||||||
				getClass().getResource(themeCSS).toExternalForm());
 | 
									getClass().getResource(themeCSS).toExternalForm());
 | 
				
			||||||
@@ -168,8 +128,8 @@ public final class SceneContext implements EventListener {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	@Event(eventType = Logout.class, priority = 150)
 | 
						@Event(eventType = Logout.class, priority = 150)
 | 
				
			||||||
	private void onLogout() {
 | 
						private void onLogout() {
 | 
				
			||||||
		sceneStack.clear();
 | 
							roots.clear();
 | 
				
			||||||
		controllerStack.clear();
 | 
							controllers.clear();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Event(priority = 150, eventType = ThemeChangeEvent.class)
 | 
						@Event(priority = 150, eventType = ThemeChangeEvent.class)
 | 
				
			||||||
@@ -182,7 +142,7 @@ public final class SceneContext implements EventListener {
 | 
				
			|||||||
	 * @return the controller used by the current scene
 | 
						 * @return the controller used by the current scene
 | 
				
			||||||
	 * @since Envoy Client v0.1-beta
 | 
						 * @since Envoy Client v0.1-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public <T> T getController() { return (T) controllerStack.peek(); }
 | 
						public <T> T getController() { return (T) controllers.peek(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the stage in which the scenes are displayed
 | 
						 * @return the stage in which the scenes are displayed
 | 
				
			||||||
@@ -194,5 +154,5 @@ public final class SceneContext implements EventListener {
 | 
				
			|||||||
	 * @return whether the scene stack is empty
 | 
						 * @return whether the scene stack is empty
 | 
				
			||||||
	 * @since Envoy Client v0.2-beta
 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public boolean isEmpty() { return sceneStack.isEmpty(); }
 | 
						public boolean isEmpty() { return roots.isEmpty(); }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								client/src/main/java/envoy/client/ui/SceneInfo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								client/src/main/java/envoy/client/ui/SceneInfo.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					package envoy.client.ui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Contains information about different scenes and their FXML resource files.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 | 
					 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public enum SceneInfo {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * The main scene in which the chat screen is displayed.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						CHAT_SCENE("/fxml/ChatScene.fxml"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * The scene in which the settings screen is displayed.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						SETTINGS_SCENE("/fxml/SettingsScene.fxml"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * The scene in which the login screen is displayed.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						LOGIN_SCENE("/fxml/LoginScene.fxml");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * The path to the FXML resource.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public final String path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SceneInfo(String path) {
 | 
				
			||||||
 | 
							this.path = path;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -20,7 +20,6 @@ import envoy.client.data.*;
 | 
				
			|||||||
import envoy.client.data.shortcuts.EnvoyShortcutConfig;
 | 
					import envoy.client.data.shortcuts.EnvoyShortcutConfig;
 | 
				
			||||||
import envoy.client.helper.ShutdownHelper;
 | 
					import envoy.client.helper.ShutdownHelper;
 | 
				
			||||||
import envoy.client.net.Client;
 | 
					import envoy.client.net.Client;
 | 
				
			||||||
import envoy.client.ui.SceneContext.SceneInfo;
 | 
					 | 
				
			||||||
import envoy.client.ui.controller.LoginScene;
 | 
					import envoy.client.ui.controller.LoginScene;
 | 
				
			||||||
import envoy.client.util.IconUtil;
 | 
					import envoy.client.util.IconUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -94,7 +93,7 @@ public final class Startup extends Application {
 | 
				
			|||||||
		final var sceneContext = new SceneContext(stage);
 | 
							final var sceneContext = new SceneContext(stage);
 | 
				
			||||||
		context.setSceneContext(sceneContext);
 | 
							context.setSceneContext(sceneContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Authenticate with token if present
 | 
							// Authenticate with token if present or load login scene
 | 
				
			||||||
		if (localDB.getAuthToken() != null) {
 | 
							if (localDB.getAuthToken() != null) {
 | 
				
			||||||
			logger.info("Attempting authentication with token...");
 | 
								logger.info("Attempting authentication with token...");
 | 
				
			||||||
			localDB.loadUserData();
 | 
								localDB.loadUserData();
 | 
				
			||||||
@@ -103,8 +102,9 @@ public final class Startup extends Application {
 | 
				
			|||||||
					VERSION, localDB.getLastSync())))
 | 
										VERSION, localDB.getLastSync())))
 | 
				
			||||||
				sceneContext.load(SceneInfo.LOGIN_SCENE);
 | 
									sceneContext.load(SceneInfo.LOGIN_SCENE);
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			// Load login scene
 | 
					 | 
				
			||||||
			sceneContext.load(SceneInfo.LOGIN_SCENE);
 | 
								sceneContext.load(SceneInfo.LOGIN_SCENE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							stage.show();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -226,7 +226,7 @@ public final class Startup extends Application {
 | 
				
			|||||||
		// Load ChatScene
 | 
							// Load ChatScene
 | 
				
			||||||
		stage.setMinHeight(400);
 | 
							stage.setMinHeight(400);
 | 
				
			||||||
		stage.setMinWidth(843);
 | 
							stage.setMinWidth(843);
 | 
				
			||||||
		context.getSceneContext().load(SceneContext.SceneInfo.CHAT_SCENE);
 | 
							context.getSceneContext().load(SceneInfo.CHAT_SCENE);
 | 
				
			||||||
		stage.centerOnScreen();
 | 
							stage.centerOnScreen();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Exit or minimize the stage when a close request occurs
 | 
							// Exit or minimize the stage when a close request occurs
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ import envoy.util.EnvoyLog;
 | 
				
			|||||||
import envoy.client.data.Context;
 | 
					import envoy.client.data.Context;
 | 
				
			||||||
import envoy.client.data.commands.*;
 | 
					import envoy.client.data.commands.*;
 | 
				
			||||||
import envoy.client.helper.ShutdownHelper;
 | 
					import envoy.client.helper.ShutdownHelper;
 | 
				
			||||||
import envoy.client.ui.SceneContext.SceneInfo;
 | 
					import envoy.client.ui.SceneInfo;
 | 
				
			||||||
import envoy.client.ui.controller.ChatScene;
 | 
					import envoy.client.ui.controller.ChatScene;
 | 
				
			||||||
import envoy.client.util.*;
 | 
					import envoy.client.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,7 +32,7 @@ public final class ChatSceneCommands {
 | 
				
			|||||||
	private final SystemCommandBuilder	builder					=
 | 
						private final SystemCommandBuilder	builder					=
 | 
				
			||||||
		new SystemCommandBuilder(messageTextAreaCommands);
 | 
							new SystemCommandBuilder(messageTextAreaCommands);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final String messageDependantCommandDescription =
 | 
						private static final String messageDependentCommandDescription =
 | 
				
			||||||
		" the given message. Use s/S to use the selected message. Otherwise expects a number relative to the uppermost completely visible message.";
 | 
							" the given message. Use s/S to use the selected message. Otherwise expects a number relative to the uppermost completely visible message.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -141,7 +141,7 @@ public final class ChatSceneCommands {
 | 
				
			|||||||
			else
 | 
								else
 | 
				
			||||||
				useRelativeMessage(command, action, additionalCheck, positionalArgument, false);
 | 
									useRelativeMessage(command, action, additionalCheck, positionalArgument, false);
 | 
				
			||||||
		}).setDefaults("s").setNumberOfArguments(1)
 | 
							}).setDefaults("s").setNumberOfArguments(1)
 | 
				
			||||||
			.setDescription(description.concat(messageDependantCommandDescription)).build(command);
 | 
								.setDescription(description.concat(messageDependentCommandDescription)).build(command);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void selectionNeighbor(Consumer<Message> action, Predicate<Message> additionalCheck,
 | 
						private void selectionNeighbor(Consumer<Message> action, Predicate<Message> additionalCheck,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
package envoy.client.ui.controller;
 | 
					package envoy.client.ui.controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static envoy.client.ui.SceneInfo.SETTINGS_SCENE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.awt.Toolkit;
 | 
					import java.awt.Toolkit;
 | 
				
			||||||
import java.awt.datatransfer.StringSelection;
 | 
					import java.awt.datatransfer.StringSelection;
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
@@ -32,7 +34,7 @@ import envoy.data.*;
 | 
				
			|||||||
import envoy.data.Attachment.AttachmentType;
 | 
					import envoy.data.Attachment.AttachmentType;
 | 
				
			||||||
import envoy.data.Message.MessageStatus;
 | 
					import envoy.data.Message.MessageStatus;
 | 
				
			||||||
import envoy.event.*;
 | 
					import envoy.event.*;
 | 
				
			||||||
import envoy.event.contact.*;
 | 
					import envoy.event.contact.UserOperation;
 | 
				
			||||||
import envoy.exception.EnvoyException;
 | 
					import envoy.exception.EnvoyException;
 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.EnvoyLog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -445,7 +447,7 @@ public final class ChatScene implements EventListener, Restorable, KeyboardMappi
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private void settingsButtonClicked() {
 | 
						private void settingsButtonClicked() {
 | 
				
			||||||
		sceneContext.load(SceneContext.SceneInfo.SETTINGS_SCENE);
 | 
							sceneContext.load(SETTINGS_SCENE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ import envoy.util.EnvoyLog;
 | 
				
			|||||||
import envoy.client.data.Context;
 | 
					import envoy.client.data.Context;
 | 
				
			||||||
import envoy.client.event.*;
 | 
					import envoy.client.event.*;
 | 
				
			||||||
import envoy.client.helper.*;
 | 
					import envoy.client.helper.*;
 | 
				
			||||||
import envoy.client.ui.SceneContext.SceneInfo;
 | 
					import envoy.client.ui.SceneInfo;
 | 
				
			||||||
import envoy.client.ui.controller.ChatScene;
 | 
					import envoy.client.ui.controller.ChatScene;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,8 +24,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<GridPane maxHeight="-Infinity" maxWidth="-Infinity"
 | 
					<GridPane maxHeight="-Infinity" maxWidth="-Infinity"
 | 
				
			||||||
	minHeight="400.0" minWidth="500.0"
 | 
						minHeight="400.0" minWidth="500.0"
 | 
				
			||||||
	prefHeight="${screen.visualBounds.height}"
 | 
					 | 
				
			||||||
	prefWidth="${screen.visualBounds.width}"
 | 
						prefWidth="${screen.visualBounds.width}"
 | 
				
			||||||
 | 
						prefHeight="${screen.visualBounds.height}"
 | 
				
			||||||
	xmlns="http://javafx.com/javafx/11.0.1"
 | 
						xmlns="http://javafx.com/javafx/11.0.1"
 | 
				
			||||||
	xmlns:fx="http://javafx.com/fxml/1"
 | 
						xmlns:fx="http://javafx.com/fxml/1"
 | 
				
			||||||
	fx:controller="envoy.client.ui.controller.ChatScene">
 | 
						fx:controller="envoy.client.ui.controller.ChatScene">
 | 
				
			||||||
@@ -57,8 +57,7 @@
 | 
				
			|||||||
					<content>
 | 
										<content>
 | 
				
			||||||
						<AnchorPane minHeight="0.0" minWidth="0.0">
 | 
											<AnchorPane minHeight="0.0" minWidth="0.0">
 | 
				
			||||||
							<children>
 | 
												<children>
 | 
				
			||||||
								<VBox prefHeight="3000.0"
 | 
													<VBox prefHeight="3000.0" prefWidth="316.0">
 | 
				
			||||||
									prefWidth="316.0">
 | 
					 | 
				
			||||||
									<children>
 | 
														<children>
 | 
				
			||||||
										<VBox id="search-panel" maxHeight="-Infinity"
 | 
															<VBox id="search-panel" maxHeight="-Infinity"
 | 
				
			||||||
											minHeight="-Infinity" prefHeight="80.0" prefWidth="316.0">
 | 
																minHeight="-Infinity" prefHeight="80.0" prefWidth="316.0">
 | 
				
			||||||
@@ -156,8 +155,7 @@
 | 
				
			|||||||
						<Insets left="15.0" top="5.0" right="10.0" />
 | 
											<Insets left="15.0" top="5.0" right="10.0" />
 | 
				
			||||||
					</HBox.margin>
 | 
										</HBox.margin>
 | 
				
			||||||
				</ImageView>
 | 
									</ImageView>
 | 
				
			||||||
				<Region id="transparent-background"
 | 
									<Region id="transparent-background" HBox.hgrow="ALWAYS" />
 | 
				
			||||||
					HBox.hgrow="ALWAYS" />
 | 
					 | 
				
			||||||
				<Button fx:id="settingsButton" mnemonicParsing="false"
 | 
									<Button fx:id="settingsButton" mnemonicParsing="false"
 | 
				
			||||||
					onAction="#settingsButtonClicked" prefHeight="30.0"
 | 
										onAction="#settingsButtonClicked" prefHeight="30.0"
 | 
				
			||||||
					prefWidth="30.0" alignment="CENTER_RIGHT">
 | 
										prefWidth="30.0" alignment="CENTER_RIGHT">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,11 +7,16 @@
 | 
				
			|||||||
<?import javafx.scene.layout.HBox?>
 | 
					<?import javafx.scene.layout.HBox?>
 | 
				
			||||||
<?import javafx.scene.layout.VBox?>
 | 
					<?import javafx.scene.layout.VBox?>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<VBox alignment="TOP_RIGHT" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="envoy.client.ui.controller.SettingsScene">
 | 
					<VBox alignment="TOP_RIGHT" maxHeight="-Infinity" minHeight="400.0"
 | 
				
			||||||
 | 
						minWidth="500.0" xmlns="http://javafx.com/javafx/11.0.1"
 | 
				
			||||||
 | 
						xmlns:fx="http://javafx.com/fxml/1"
 | 
				
			||||||
 | 
						fx:controller="envoy.client.ui.controller.SettingsScene">
 | 
				
			||||||
	<children>
 | 
						<children>
 | 
				
			||||||
		<HBox prefHeight="389.0" prefWidth="600.0">
 | 
							<HBox prefHeight="389.0" prefWidth="600.0">
 | 
				
			||||||
			<children>
 | 
								<children>
 | 
				
			||||||
				<ListView id="message-list" fx:id="settingsList" onMouseClicked="#settingsListClicked" prefHeight="200.0" prefWidth="200.0">
 | 
									<ListView id="message-list" fx:id="settingsList"
 | 
				
			||||||
 | 
										onMouseClicked="#settingsListClicked" prefHeight="200.0"
 | 
				
			||||||
 | 
										prefWidth="200.0">
 | 
				
			||||||
					<opaqueInsets>
 | 
										<opaqueInsets>
 | 
				
			||||||
						<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
											<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
					</opaqueInsets>
 | 
										</opaqueInsets>
 | 
				
			||||||
@@ -22,7 +27,8 @@
 | 
				
			|||||||
						<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
											<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
					</padding>
 | 
										</padding>
 | 
				
			||||||
				</ListView>
 | 
									</ListView>
 | 
				
			||||||
				<TitledPane fx:id="titledPane" collapsible="false" prefHeight="400.0" prefWidth="400.0">
 | 
									<TitledPane fx:id="titledPane" collapsible="false"
 | 
				
			||||||
 | 
										prefHeight="400.0" prefWidth="400.0">
 | 
				
			||||||
					<HBox.margin>
 | 
										<HBox.margin>
 | 
				
			||||||
						<Insets bottom="10.0" left="5.0" right="10.0" top="10.0" />
 | 
											<Insets bottom="10.0" left="5.0" right="10.0" top="10.0" />
 | 
				
			||||||
					</HBox.margin>
 | 
										</HBox.margin>
 | 
				
			||||||
@@ -32,7 +38,8 @@
 | 
				
			|||||||
				</TitledPane>
 | 
									</TitledPane>
 | 
				
			||||||
			</children>
 | 
								</children>
 | 
				
			||||||
		</HBox>
 | 
							</HBox>
 | 
				
			||||||
		<Button defaultButton="true" mnemonicParsing="true" onMouseClicked="#backButtonClicked" text="_Back">
 | 
							<Button defaultButton="true" mnemonicParsing="true"
 | 
				
			||||||
 | 
								onMouseClicked="#backButtonClicked" text="_Back">
 | 
				
			||||||
			<opaqueInsets>
 | 
								<opaqueInsets>
 | 
				
			||||||
				<Insets />
 | 
									<Insets />
 | 
				
			||||||
			</opaqueInsets>
 | 
								</opaqueInsets>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user
	
Wait, you don't want to log the failed loading?