Pārlūkot izejas kodu

Refactored stage creation

Sebastian Stenzel 5 gadi atpakaļ
vecāks
revīzija
117fe78a4a

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java

@@ -21,6 +21,7 @@ import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.common.NewPasswordController;
 import org.cryptomator.ui.common.PasswordStrengthUtil;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.mainwindow.MainWindow;
 import org.cryptomator.ui.recoverykey.RecoveryKeyDisplayController;
 
@@ -51,13 +52,12 @@ public abstract class AddVaultModule {
 	@Provides
 	@AddVaultWizardWindow
 	@AddVaultWizardScoped
-	static Stage provideStage(@MainWindow Stage owner, ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, @MainWindow Stage owner, ResourceBundle resourceBundle) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("addvaultwizard.title"));
 		stage.setResizable(false);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/changepassword/ChangePasswordModule.java

@@ -18,6 +18,7 @@ import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.common.NewPasswordController;
 import org.cryptomator.ui.common.PasswordStrengthUtil;
+import org.cryptomator.ui.common.StageFactory;
 
 import javax.inject.Named;
 import javax.inject.Provider;
@@ -46,13 +47,12 @@ abstract class ChangePasswordModule {
 	@Provides
 	@ChangePasswordWindow
 	@ChangePasswordScoped
-	static Stage provideStage(@Named("changePasswordOwner") Stage owner, ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, @Named("changePasswordOwner") Stage owner, ResourceBundle resourceBundle) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("changepassword.title"));
 		stage.setResizable(false);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 26 - 0
main/ui/src/main/java/org/cryptomator/ui/common/StageFactory.java

@@ -0,0 +1,26 @@
+package org.cryptomator.ui.common;
+
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+import java.util.function.Consumer;
+
+public class StageFactory {
+
+	private final Consumer<Stage> initializer;
+
+	public StageFactory(Consumer<Stage> initializer) {
+		this.initializer = initializer;
+	}
+	
+	public Stage create() {
+		return create(StageStyle.DECORATED);
+	}
+	
+	public Stage create(StageStyle stageStyle) {
+		Stage stage = new Stage(stageStyle);
+		initializer.accept(stage);
+		return stage;
+	}
+
+}

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/forgetPassword/ForgetPasswordModule.java

@@ -17,6 +17,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 
 import javax.inject.Named;
 import javax.inject.Provider;
@@ -37,13 +38,12 @@ abstract class ForgetPasswordModule {
 	@Provides
 	@ForgetPasswordWindow
 	@ForgetPasswordScoped
-	static Stage provideStage(ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons, @Named("forgetPasswordOwner") Stage owner) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle, @Named("forgetPasswordOwner") Stage owner) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("forgetPassword.title"));
 		stage.setResizable(false);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 7 - 16
main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java

@@ -43,11 +43,10 @@ public class FxApplication extends Application {
 	private final Optional<MacFunctions> macFunctions;
 	private final VaultService vaultService;
 	private final LicenseHolder licenseHolder;
-	private final ObservableSet<Stage> visibleStages = FXCollections.observableSet();
-	private final BooleanBinding hasVisibleStages = Bindings.isNotEmpty(visibleStages);
+	private final BooleanBinding hasVisibleStages;
 
 	@Inject
-	FxApplication(Settings settings, Lazy<MainWindowComponent> mainWindow, Lazy<PreferencesComponent> preferencesWindow, UnlockComponent.Builder unlockWindowBuilder, QuitComponent.Builder quitWindowBuilder, Optional<MacFunctions> macFunctions, VaultService vaultService, LicenseHolder licenseHolder) {
+	FxApplication(Settings settings, Lazy<MainWindowComponent> mainWindow, Lazy<PreferencesComponent> preferencesWindow, UnlockComponent.Builder unlockWindowBuilder, QuitComponent.Builder quitWindowBuilder, Optional<MacFunctions> macFunctions, VaultService vaultService, LicenseHolder licenseHolder, ObservableSet<Stage> visibleStages) {
 		this.settings = settings;
 		this.mainWindow = mainWindow;
 		this.preferencesWindow = preferencesWindow;
@@ -56,6 +55,7 @@ public class FxApplication extends Application {
 		this.macFunctions = macFunctions;
 		this.vaultService = vaultService;
 		this.licenseHolder = licenseHolder;
+		this.hasVisibleStages = Bindings.isNotEmpty(visibleStages);
 	}
 
 	public void start() {
@@ -73,11 +73,6 @@ public class FxApplication extends Application {
 		throw new UnsupportedOperationException("Use start() instead.");
 	}
 
-	private void addVisibleStage(Stage stage) {
-		visibleStages.add(stage);
-		stage.setOnHidden(evt -> visibleStages.remove(stage));
-	}
-
 	private void hasVisibleStagesChanged(@SuppressWarnings("unused") ObservableValue<? extends Boolean> observableValue, @SuppressWarnings("unused") boolean oldValue, boolean newValue) {
 		if (newValue) {
 			macFunctions.map(MacFunctions::uiState).ifPresent(MacApplicationUiState::transformToForegroundApplication);
@@ -88,32 +83,28 @@ public class FxApplication extends Application {
 
 	public void showPreferencesWindow(SelectedPreferencesTab selectedTab) {
 		Platform.runLater(() -> {
-			Stage stage = preferencesWindow.get().showPreferencesWindow(selectedTab);
-			addVisibleStage(stage);
+			preferencesWindow.get().showPreferencesWindow(selectedTab);
 			LOG.debug("Showing Preferences");
 		});
 	}
 
 	public void showMainWindow() {
 		Platform.runLater(() -> {
-			Stage stage = mainWindow.get().showMainWindow();
-			addVisibleStage(stage);
+			mainWindow.get().showMainWindow();
 			LOG.debug("Showing MainWindow");
 		});
 	}
 
 	public void showUnlockWindow(Vault vault) {
 		Platform.runLater(() -> {
-			Stage stage = unlockWindowBuilder.vault(vault).build().showUnlockWindow();
-			addVisibleStage(stage);
+			unlockWindowBuilder.vault(vault).build().showUnlockWindow();
 			LOG.debug("Showing UnlockWindow for {}", vault.getDisplayableName());
 		});
 	}
 
 	public void showQuitWindow(QuitResponse response) {
 		Platform.runLater(() -> {
-			Stage stage = quitWindowBuilder.quitResponse(response).build().showQuitWindow();
-			addVisibleStage(stage);
+			quitWindowBuilder.quitResponse(response).build().showQuitWindow();
 			LOG.debug("Showing QuitWindow");
 		});
 	}

+ 25 - 1
main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java

@@ -11,10 +11,14 @@ import dagger.Provides;
 import javafx.application.Application;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableSet;
 import javafx.scene.image.Image;
+import javafx.stage.Stage;
 import org.apache.commons.lang3.SystemUtils;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.ui.common.ErrorComponent;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.mainwindow.MainWindowComponent;
 import org.cryptomator.ui.preferences.PreferencesComponent;
 import org.cryptomator.ui.quit.QuitComponent;
@@ -36,6 +40,12 @@ abstract class FxApplicationModule {
 		return new SimpleObjectProperty<>();
 	}
 
+	@Provides
+	@FxApplicationScoped
+	static ObservableSet<Stage> provideVisibleStages() {
+		return FXCollections.observableSet();
+	}
+
 	@Provides
 	@Named("windowIcons")
 	@FxApplicationScoped
@@ -43,7 +53,6 @@ abstract class FxApplicationModule {
 		if (SystemUtils.IS_OS_MAC) {
 			return Collections.emptyList();
 		}
-
 		try {
 			return List.of( //
 					createImageFromResource("/window_icon_32.png"), //
@@ -53,6 +62,21 @@ abstract class FxApplicationModule {
 			throw new UncheckedIOException("Failed to load embedded resource.", e);
 		}
 	}
+	
+	@Provides
+	@FxApplicationScoped
+	static StageFactory provideStageFactory(@Named("windowIcons") List<Image> windowIcons, ObservableSet<Stage> visibleStages) {
+		return new StageFactory(stage -> {
+			stage.getIcons().addAll(windowIcons);
+			stage.showingProperty().addListener((observableValue, wasShowing, isShowing) -> {
+				if (isShowing) {
+					visibleStages.add(stage);
+				} else {
+					visibleStages.remove(stage);
+				}
+			});
+		});
+	}
 
 	private static Image createImageFromResource(String resourceName) throws IOException {
 		try (InputStream in = FxApplicationModule.class.getResourceAsStream(resourceName)) {

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java

@@ -14,6 +14,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.migration.MigrationComponent;
 import org.cryptomator.ui.removevault.RemoveVaultComponent;
 import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
@@ -38,15 +39,14 @@ abstract class MainWindowModule {
 	@Provides
 	@MainWindow
 	@MainWindowScoped
-	static Stage provideStage(@Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage(StageStyle.UNDECORATED);
+	static Stage provideStage(StageFactory factory) {
+		Stage stage = factory.create(StageStyle.UNDECORATED);
 		// TODO: min/max values chosen arbitrarily. We might wanna take a look at the user's resolution...
 		stage.setMinWidth(650);
 		stage.setMinHeight(440);
 		stage.setMaxWidth(1000);
 		stage.setMaxHeight(700);
 		stage.setTitle("Cryptomator");
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/migration/MigrationModule.java

@@ -17,6 +17,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.mainwindow.MainWindow;
 
 import javax.inject.Named;
@@ -38,13 +39,12 @@ abstract class MigrationModule {
 	@Provides
 	@MigrationWindow
 	@MigrationScoped
-	static Stage provideStage(@MainWindow Stage owner, ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, @MainWindow Stage owner, ResourceBundle resourceBundle) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("migration.title"));
 		stage.setResizable(false);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 	

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java

@@ -15,6 +15,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 
 import javax.inject.Named;
 import javax.inject.Provider;
@@ -41,11 +42,10 @@ abstract class PreferencesModule {
 	@Provides
 	@PreferencesWindow
 	@PreferencesScoped
-	static Stage provideStage(ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("preferences.title"));
 		stage.setResizable(false);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/quit/QuitModule.java

@@ -17,6 +17,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 
 import javax.inject.Named;
 import javax.inject.Provider;
@@ -37,12 +38,11 @@ abstract class QuitModule {
 	@Provides
 	@QuitWindow
 	@QuitScoped
-	static Stage provideStage(@Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory) {
+		Stage stage = factory.create();
 		stage.setMinWidth(300);
 		stage.setMinHeight(100);
 		stage.initModality(Modality.APPLICATION_MODAL);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java

@@ -21,6 +21,7 @@ import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.common.NewPasswordController;
 import org.cryptomator.ui.common.PasswordStrengthUtil;
+import org.cryptomator.ui.common.StageFactory;
 
 import javax.inject.Named;
 import javax.inject.Provider;
@@ -41,13 +42,12 @@ abstract class RecoveryKeyModule {
 	@Provides
 	@RecoveryKeyWindow
 	@RecoveryKeyScoped
-	static Stage provideStage(ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons, @Named("keyRecoveryOwner") Stage owner) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle, @Named("keyRecoveryOwner") Stage owner) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("recoveryKey.title"));
 		stage.setResizable(false);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 	

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/removevault/RemoveVaultModule.java

@@ -17,6 +17,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.mainwindow.MainWindow;
 
 import javax.inject.Named;
@@ -38,13 +39,12 @@ abstract class RemoveVaultModule {
 	@Provides
 	@RemoveVaultWindow
 	@RemoveVaultScoped
-	static Stage provideStage(@MainWindow Stage owner,  ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, @MainWindow Stage owner, ResourceBundle resourceBundle) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("removeVault.title"));
 		stage.setResizable(false);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockModule.java

@@ -15,6 +15,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
 
 import javax.inject.Named;
@@ -36,12 +37,11 @@ abstract class UnlockModule {
 	@Provides
 	@UnlockWindow
 	@UnlockScoped
-	static Stage provideStage(@UnlockWindow Vault vault, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, @UnlockWindow Vault vault) {
+		Stage stage = factory.create();
 		stage.setTitle(vault.getDisplayableName());
 		stage.setResizable(false);
 		stage.initModality(Modality.APPLICATION_MODAL);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/vaultoptions/VaultOptionsModule.java

@@ -16,6 +16,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.mainwindow.MainWindow;
 import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
 
@@ -38,15 +39,14 @@ abstract class VaultOptionsModule {
 	@Provides
 	@VaultOptionsWindow
 	@VaultOptionsScoped
-	static Stage provideStage(@MainWindow Stage owner, @VaultOptionsWindow Vault vault, ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, @MainWindow Stage owner, @VaultOptionsWindow Vault vault) {
+		Stage stage = factory.create();
 		stage.setTitle(vault.getDisplayableName());
 		stage.setResizable(true);
 		stage.setMinWidth(400);
 		stage.setMinHeight(300);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}
 

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertModule.java

@@ -14,6 +14,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.mainwindow.MainWindow;
 
 import javax.inject.Named;
@@ -35,13 +36,12 @@ abstract class WrongFileAlertModule {
 	@Provides
 	@WrongFileAlertWindow
 	@WrongFileAlertScoped
-	static Stage provideStage(@MainWindow Stage mainWindow, ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons) {
-		Stage stage = new Stage();
+	static Stage provideStage(StageFactory factory, @MainWindow Stage mainWindow, ResourceBundle resourceBundle) {
+		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("wrongFileAlert.title"));
 		stage.setResizable(false);
 		stage.initOwner(mainWindow);
 		stage.initModality(Modality.WINDOW_MODAL);
-		stage.getIcons().addAll(windowIcons);
 		return stage;
 	}