Skip to content

Commit

Permalink
Add simplified version of New Project dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
emd4600 committed Oct 16, 2024
1 parent c104605 commit e3ff96e
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 61 deletions.
52 changes: 42 additions & 10 deletions src/sporemodder/ProjectManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,8 @@
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.*;
import java.util.stream.Collectors;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
Expand Down Expand Up @@ -2302,4 +2294,44 @@ public boolean showSaveDialog() {
return closeEditedFileDecision == CloseEditedFileDecision.SAVE;
}
}

private void createNewProjectCommon(ModBundle modBundle, String projectName, List<ProjectPreset> presets) throws ParserConfigurationException, TransformerException, IOException {
// Set default presets if not specified
if (presets == null) {
presets = this.presets.stream().filter(ProjectPreset::isRecommendable).collect(Collectors.toList());
}

// Create package project
Project project = new Project(projectName, modBundle);
modBundle.addProject(project);

// Add project references
project.getReferences().addAll(presets.stream().map(preset -> getProject(preset.getName())).collect(Collectors.toList()));

// Initialize package project folder
initializeProject(project);

// Save ModInfo
if (!modBundle.hasCustomModInfo()) {
modBundle.saveModInfo();
}
}

public void createNewMod(String modName, String uniqueTag, String description, String projectName, List<ProjectPreset> presets) throws IOException, ParserConfigurationException, TransformerException, InterruptedException {
ModBundle modBundle = new ModBundle(modName);
modBundle.setDescription(description);
modBundle.setUniqueTag(uniqueTag);
initializeModBundle(modBundle);
createNewProjectCommon(modBundle, projectName, presets);

// Initialize git repository, but don't try if git is not installed
if (GitHubManager.get().hasGitInstalled()) {
initializeModBundleGit(modBundle);
}
}

public void createNewProjectInMod(ModBundle modBundle, String projectName, List<ProjectPreset> presets) throws ParserConfigurationException, IOException, TransformerException {
assert modBundle != null;
createNewProjectCommon(modBundle, projectName, presets);
}
}
2 changes: 2 additions & 0 deletions src/sporemodder/util/ModBundle.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public enum ExperimentalStatus {
public static final String UNIQUETAG_ALLOWED_REGEX = "[" + UNIQUETAG_REGEX + "]";
public static final String UNIQUETAG_FORBIDDEN_REGEX = "[^" + UNIQUETAG_REGEX + "]";

public static final String NAME_ILLEGAL_CHARACTERS = "/\\[]{}";

private final String name;
private final List<Project> projects = new ArrayList<>();
/** The base folder with all the data and source code of the mod. */
Expand Down
7 changes: 2 additions & 5 deletions src/sporemodder/view/IntroUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@
import sporemodder.ProjectManager;
import sporemodder.UIManager;
import sporemodder.util.Project;
import sporemodder.view.dialogs.CreateProjectUI;
import sporemodder.view.dialogs.OpenProjectUI;
import sporemodder.view.dialogs.UnpackPackageUI;
import sporemodder.view.dialogs.UnpackPresetsUI;
import sporemodder.view.dialogs.*;

public class IntroUI implements Controller {

Expand Down Expand Up @@ -78,7 +75,7 @@ private void setHyperlinkURL(Hyperlink hyperlink, String url) {
@FXML private void initialize() {

btnNew.setOnAction(event -> {
CreateProjectUI.show();
CreateProjectSimpleUI.show();
});
btnNew.setTooltip(new Tooltip("Creates a new empty project to start modding."));

Expand Down
19 changes: 19 additions & 0 deletions src/sporemodder/view/dialogs/CreateProjectSimpleUI.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>


<VBox fx:id="mainNode" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="450.0" spacing="10.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sporemodder.view.dialogs.CreateProjectSimpleUI">
<children>
<HBox alignment="CENTER_LEFT" spacing="5.0">
<children>
<Label text="Mod Name:" />
<TextField fx:id="modNameTextField" HBox.hgrow="ALWAYS" />
</children>
</HBox>
<Label fx:id="warningLabel" text="Label" visible="false" />
</children>
</VBox>
101 changes: 101 additions & 0 deletions src/sporemodder/view/dialogs/CreateProjectSimpleUI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package sporemodder.view.dialogs;

import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.*;
import sporemodder.ProjectManager;
import sporemodder.UIManager;
import sporemodder.util.ModBundle;
import sporemodder.view.Controller;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.IOException;

public class CreateProjectSimpleUI implements Controller {

private Dialog<ButtonType> dialog;
@FXML
private Node mainNode;
@FXML
private TextField modNameTextField;
@FXML
private Label warningLabel;

@FXML
private void initialize() {
warningLabel.setGraphic(UIManager.get().getAlertIcon(Alert.AlertType.WARNING, 16, 16));

// Set a project text
modNameTextField.setText("Project " + (ProjectManager.get().getProjects().size() + 1));

modNameTextField.requestFocus();
modNameTextField.selectAll();
modNameTextField.requestFocus();

// Ban illegal characters
modNameTextField.setTextFormatter(new TextFormatter<>(change -> {
String text = change.getControlNewText();
if (ModBundle.NAME_ILLEGAL_CHARACTERS.chars().anyMatch(c -> text.indexOf(c) != -1)) {
return null;
} else {
return change;
}
}));
}

private void validateModFields() {
boolean showWarning = true;
// Show warning if name collides
String modName = modNameTextField.getText();
if (ProjectManager.get().hasModBundle(modName) ||
ProjectManager.get().hasProject(modName)) {
warningLabel.setText("A project with this name already exists");
} else if (modName.isBlank()) {
warningLabel.setText("Mod name cannot be blank");
} else {
showWarning = false;
}

warningLabel.setVisible(showWarning);
dialog.getDialogPane().lookupButton(ButtonType.OK).setDisable(showWarning);
}

public void createMod() throws IOException, InterruptedException, ParserConfigurationException, TransformerException {
ProjectManager.get().createNewMod(
modNameTextField.getText(),
ModBundle.generateUniqueTagFromName(modNameTextField.getText()),
"",
modNameTextField.getText(),
null
);
}

public static void show() {
CreateProjectSimpleUI node = UIManager.get().loadUI("dialogs/CreateProjectSimpleUI");
node.dialog = new Dialog<>();
node.dialog.getDialogPane().setContent(node.getMainNode());

node.dialog.setTitle("Create new mod project");
node.dialog.getDialogPane().getButtonTypes().setAll(ButtonType.CANCEL, ButtonType.OK, ButtonType.NEXT);

((Button)node.dialog.getDialogPane().lookupButton(ButtonType.NEXT)).setText("Advanced Options");

node.validateModFields();

UIManager.get().showDialog(node.dialog).ifPresent(result -> {
if (result == ButtonType.NEXT) {
CreateProjectUI.show();
} else if (result == ButtonType.OK && UIManager.get().tryAction(node::createMod,
"Cannot initialize project. Try manually deleting the project folder in SporeModder FX\\Projects\\"))
{
ProjectManager.get().setActive(ProjectManager.get().getProject(node.modNameTextField.getText()));
}
});
}

@Override
public Node getMainNode() {
return mainNode;
}
}
62 changes: 22 additions & 40 deletions src/sporemodder/view/dialogs/CreateProjectUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,13 @@

public class CreateProjectUI implements Controller {

private static final String ILLEGAL_CHARACTERS = "/\\[]{}";

private static final String WARNING_UNIQUE_TAG_EMPTY = "Unique tag cannot be empty";
private static final String WARNING_MOD_NAME_EMPTY = "Mod name cannot be empty";
private static final String WARNING_PROJECT_NAME_EMPTY = "Package project name cannot be empty";
private static final String WARNING_MOD_NAME_REPEATED = "A mod with this name already exists";
private static final String WARNING_PROJECT_NAME_REPEATED = "A package project with this name already exists";
private static final String WARNING_MOD_NAME_INVALID = "Mod name cannot contain any character from " + ILLEGAL_CHARACTERS;
private static final String WARNING_PROJECT_NAME_INVALID = "Package project name cannot contain any character from " + ILLEGAL_CHARACTERS;
private static final String WARNING_MOD_NAME_INVALID = "Mod name cannot contain any character from " + ModBundle.NAME_ILLEGAL_CHARACTERS;
private static final String WARNING_PROJECT_NAME_INVALID = "Package project name cannot contain any character from " + ModBundle.NAME_ILLEGAL_CHARACTERS;

private Dialog<ButtonType> dialog;

Expand Down Expand Up @@ -103,42 +101,26 @@ public Pane getMainNode() {
}

public void createMod() throws IOException, InterruptedException, ParserConfigurationException, TransformerException {
ProjectManager projectManager = ProjectManager.get();

// Create base mod
ModBundle modBundle;
if (newModButton.isSelected()) {
modBundle = new ModBundle(modNameField.getText());
modBundle.setDescription(descriptionTextField.getText());
modBundle.setUniqueTag(uniqueTagTextField.getText());
projectManager.initializeModBundle(modBundle);
} else {
modBundle = projectManager.getModBundle(existingModChoiceBox.getValue());
assert modBundle != null;
}

// Create package project
Project project = new Project(projectNameField.getText(), modBundle);
modBundle.addProject(project);

// Add project references
project.getReferences().addAll(presetBoxes.stream()
List<ProjectPreset> presets = presetBoxes.stream()
.filter(CheckBox::isSelected)
.map(box -> projectManager.getProject(((ProjectPreset)box.getUserData()).getName()))
.map(box -> ((ProjectPreset)box.getUserData()))
.filter(Objects::nonNull)
.collect(Collectors.toList()));

// Initialize package project folder
projectManager.initializeProject(project);

// Save ModInfo
if (!modBundle.hasCustomModInfo()) {
modBundle.saveModInfo();
}
.collect(Collectors.toList());

// Initialize git repository, but don't try if git is not installed
if (newModButton.isSelected() && GitHubManager.get().hasGitInstalled()) {
projectManager.initializeModBundleGit(modBundle);
if (newModButton.isSelected()) {
ProjectManager.get().createNewMod(
modNameField.getText(),
uniqueTagTextField.getText(),
descriptionTextField.getText(),
projectNameField.getText(),
presets
);
} else {
ProjectManager.get().createNewProjectInMod(
ProjectManager.get().getModBundle(existingModChoiceBox.getValue()),
projectNameField.getText(),
presets
);
}
}

Expand All @@ -162,7 +144,7 @@ public static void show() {
}

private static boolean hasIllegalChar(String text) {
return ILLEGAL_CHARACTERS.chars().anyMatch(c -> text.indexOf(c) != -1);
return ModBundle.NAME_ILLEGAL_CHARACTERS.chars().anyMatch(c -> text.indexOf(c) != -1);
}

private boolean isValid() {
Expand Down Expand Up @@ -224,15 +206,15 @@ private void initialize() {
// Ban illegal characters
modNameField.setTextFormatter(new TextFormatter<>(change -> {
String text = change.getControlNewText();
if (ILLEGAL_CHARACTERS.chars().anyMatch(c -> text.indexOf(c) != -1)) {
if (ModBundle.NAME_ILLEGAL_CHARACTERS.chars().anyMatch(c -> text.indexOf(c) != -1)) {
return null;
} else {
return change;
}
}));
projectNameField.setTextFormatter(new TextFormatter<>(change -> {
String text = change.getControlNewText();
if (ILLEGAL_CHARACTERS.chars().anyMatch(c -> text.indexOf(c) != -1)) {
if (ModBundle.NAME_ILLEGAL_CHARACTERS.chars().anyMatch(c -> text.indexOf(c) != -1)) {
return null;
} else {
return change;
Expand Down
8 changes: 2 additions & 6 deletions src/sporemodder/view/ribbons/ProgramMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,7 @@
import sporemodder.UIManager;
import sporemodder.util.Project;
import sporemodder.view.UIUpdateListener;
import sporemodder.view.dialogs.CreateProjectUI;
import sporemodder.view.dialogs.OpenProjectUI;
import sporemodder.view.dialogs.ProgramSettingsUI;
import sporemodder.view.dialogs.UnpackPackageUI;
import sporemodder.view.dialogs.UnpackPresetsUI;
import sporemodder.view.dialogs.*;

/**
* The main program menu, which is the first tab of the ribbon. This program menu shows a dropdown panel with a vertical division:
Expand Down Expand Up @@ -208,7 +204,7 @@ public void initialize(Ribbon ribbon) {

newProjectButton = createButton("New project", null);
newProjectButton.setOnAction((event) -> {
CreateProjectUI.show();
CreateProjectSimpleUI.show();
});
newProjectButton.setTooltip(new Tooltip("Creates a new empty project to start modding."));

Expand Down

0 comments on commit e3ff96e

Please sign in to comment.