Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ask to save the current layout when closing shuffleboard #307

Merged
merged 4 commits into from
Nov 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,11 @@
/* Bring the content to all edges */
-fx-padding: 0; /* 10 0 0 10 */
}

.dialog-pane .header-panel {
-fx-background-color: -swatch-500;
}

.dialog-pane .header-panel .label {
-fx-text-fill: white;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package edu.wpi.first.shuffleboard.app;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.io.Files;

import edu.wpi.first.shuffleboard.api.DashboardMode;
import edu.wpi.first.shuffleboard.api.components.SourceTreeTable;
import edu.wpi.first.shuffleboard.api.components.WidgetPropertySheet;
import edu.wpi.first.shuffleboard.api.dnd.DataFormats;
import edu.wpi.first.shuffleboard.api.plugin.Plugin;
import edu.wpi.first.shuffleboard.api.prefs.FlushableProperty;
import edu.wpi.first.shuffleboard.api.sources.DataSource;
import edu.wpi.first.shuffleboard.api.sources.SourceEntry;
import edu.wpi.first.shuffleboard.api.sources.recording.Recorder;
Expand All @@ -19,13 +17,15 @@
import edu.wpi.first.shuffleboard.app.components.DashboardTab;
import edu.wpi.first.shuffleboard.app.components.DashboardTabPane;
import edu.wpi.first.shuffleboard.app.components.WidgetGallery;
import edu.wpi.first.shuffleboard.api.components.WidgetPropertySheet;
import edu.wpi.first.shuffleboard.app.json.JsonBuilder;
import edu.wpi.first.shuffleboard.app.plugin.PluginLoader;
import edu.wpi.first.shuffleboard.app.prefs.AppPreferences;
import edu.wpi.first.shuffleboard.api.prefs.FlushableProperty;
import edu.wpi.first.shuffleboard.app.sources.recording.Playback;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.io.Files;

import org.fxmisc.easybind.EasyBind;

import java.io.File;
Expand Down Expand Up @@ -68,6 +68,8 @@
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;
import javafx.stage.WindowEvent;

import static edu.wpi.first.shuffleboard.api.components.SourceTreeTable.alphabetical;
import static edu.wpi.first.shuffleboard.api.components.SourceTreeTable.branchesFirst;
Expand Down Expand Up @@ -292,10 +294,17 @@ public void setDashboard(DashboardTabPane dashboard) {
centerSplitPane.getItems().add(dashboard);
}

/**
* Closes from interacting with the "Close" menu item.
*/
@FXML
public void close() {
log.info("Exiting app");
System.exit(0);

// Attempt to close the main window. This lets window closing handlers run. Calling System.exit() or Platform.exit()
// will more-or-less immediately terminate the application without calling these handlers.
Window window = root.getScene().getWindow();
window.fireEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSE_REQUEST));
}

/**
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/java/edu/wpi/first/shuffleboard/app/Shuffleboard.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.layout.Pane;
import javafx.stage.Screen;
import javafx.stage.Stage;
Expand Down Expand Up @@ -90,6 +92,30 @@ public void start(Stage primaryStage) throws IOException {
primaryStage.setMinHeight(480);
primaryStage.setWidth(Screen.getPrimary().getVisualBounds().getWidth());
primaryStage.setHeight(Screen.getPrimary().getVisualBounds().getHeight());
primaryStage.setOnCloseRequest(closeEvent -> {
if (!AppPreferences.getInstance().isConfirmExit()) {
// Don't show the confirmation dialog, just exit
return;
}
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("Save layout");
alert.getDialogPane().getScene().getStylesheets().setAll(mainPane.getStylesheets());
alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO, ButtonType.CANCEL);
alert.getDialogPane().setHeaderText("Save the current layout before closing?");
alert.showAndWait().ifPresent(bt -> {
if (bt == ButtonType.YES) {
try {
mainWindowController.save();
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not save the layout", ex);
}
} else if (bt == ButtonType.CANCEL) {
// cancel the close request by consuming the event
closeEvent.consume();
}
// Don't need to check for NO because it just lets the window close normally
});
});
primaryStage.show();
Time.setStartTime(Time.now());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
import javafx.beans.property.SimpleObjectProperty;

/**
* Contains the user preferences for the app. These preferences are user-specific and are saved
* to the users home directory and are not contained in save files.
* Contains the user preferences for the app. These preferences are user-specific and are not contained in save files.
*/
public final class AppPreferences {

Expand All @@ -28,6 +27,8 @@ public final class AppPreferences {
private final Property<File> saveFile = new SimpleObjectProperty<>(this, "saveFile", null);
private final BooleanProperty autoLoadLastSaveFile =
new SimpleBooleanProperty(this, "automaticallyLoadLastSaveFile", true);
private final BooleanProperty confirmExit =
new SimpleBooleanProperty(this, "showConfirmationDialogWhenExiting", true);

@VisibleForTesting
static AppPreferences instance = new AppPreferences();
Expand All @@ -41,11 +42,13 @@ public AppPreferences() {
PreferencesUtils.read(defaultTileSize, preferences);
PreferencesUtils.read(saveFile, preferences, File::new);
PreferencesUtils.read(autoLoadLastSaveFile, preferences);
PreferencesUtils.read(confirmExit, preferences);

theme.addListener(__ -> PreferencesUtils.save(theme, preferences, Theme::getName));
defaultTileSize.addListener(__ -> PreferencesUtils.save(defaultTileSize, preferences));
saveFile.addListener(__ -> PreferencesUtils.save(saveFile, preferences, File::getAbsolutePath));
autoLoadLastSaveFile.addListener(__ -> PreferencesUtils.save(autoLoadLastSaveFile, preferences));
confirmExit.addListener(__ -> PreferencesUtils.save(confirmExit, preferences));
}

public static AppPreferences getInstance() {
Expand All @@ -59,7 +62,8 @@ public ImmutableList<Property<?>> getProperties() {
return ImmutableList.of(
theme,
defaultTileSize,
autoLoadLastSaveFile
autoLoadLastSaveFile,
confirmExit
);
}

Expand Down Expand Up @@ -110,4 +114,16 @@ public BooleanProperty autoLoadLastSaveFileProperty() {
public void setAutoLoadLastSaveFile(boolean autoLoadLastSaveFile) {
this.autoLoadLastSaveFile.set(autoLoadLastSaveFile);
}

public boolean isConfirmExit() {
return confirmExit.get();
}

public BooleanProperty confirmExitProperty() {
return confirmExit;
}

public void setConfirmExit(boolean confirmExit) {
this.confirmExit.set(confirmExit);
}
}