Refactored stage creation

This commit is contained in:
Sebastian Stenzel
2020-05-07 12:35:01 +02:00
parent 153d43573a
commit 117fe78a4a
15 changed files with 94 additions and 53 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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");
});
}

View File

@@ -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)) {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}