Skip to content
Snippets Groups Projects
Commit e6a7b42e authored by Trym Hamer Gudvangen's avatar Trym Hamer Gudvangen
Browse files

feat: add link pop up for a passage

parent 0e4b63ca
No related branches found
No related tags found
2 merge requests!34Feat/create story gui,!7Feat/part three
Showing
with 201 additions and 42 deletions
......@@ -5,6 +5,8 @@ import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
import edu.ntnu.idatt2001.group_30.paths.model.filehandling.StoryFileReader;
import edu.ntnu.idatt2001.group_30.paths.view.views.NewStoryView;
import edu.ntnu.idatt2001.group_30.paths.view.views.PlaythroughView;
import java.io.File;
import java.io.IOException;
......@@ -23,4 +25,5 @@ public class NewGameController extends Controller {
throw new RuntimeException(ex);
}
}
}
......@@ -7,6 +7,7 @@ import edu.ntnu.idatt2001.group_30.paths.view.views.NewStoryView;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
......@@ -37,6 +38,10 @@ public class NewStoryController extends Controller{
if (selectedFile != null) {
StoryFileWriter storyFileWriter = new StoryFileWriter();
storyFileWriter.create(story, selectedFile);
} else {
throw new FileNotFoundException("File was not saved to file system");
}
INSTANCE.setStoryFile(selectedFile);
}
}
......@@ -20,7 +20,7 @@ import javafx.scene.image.ImageView;
*
* @author Nicolai H. Brand.
*/
public class PlaytroughController extends Controller {
public class PlaythroughController extends Controller {
private Playthrough playthrough;
......@@ -30,7 +30,7 @@ public class PlaytroughController extends Controller {
private final StringProperty passageContent = new SimpleStringProperty();
private final ObservableList<Link> links = FXCollections.observableList(new ArrayList<>());
private final ObservableList<String> inventory = FXCollections.observableList(new ArrayList<>());
private final ObservableMap<Goal, Boolean> goals = FXCollections.observableMap(new HashMap<>());
private final ObservableMap<Goal<?>, Boolean> goals = FXCollections.observableMap(new HashMap<>());
private final StringProperty health = new SimpleStringProperty();
private final StringProperty score = new SimpleStringProperty();
private final StringProperty gold = new SimpleStringProperty();
......@@ -40,7 +40,7 @@ public class PlaytroughController extends Controller {
* Creates a new instance of the controller.
* It initializes the controller and starts a new game.
*/
public PlaytroughController() {
public PlaythroughController() {
super(HomeView.class, HelpView.class);
startNewPlaythrough();
}
......@@ -178,7 +178,7 @@ public class PlaytroughController extends Controller {
* Returns the goals of the game as an observable map.
* @return the goals of the game.
*/
public ObservableMap<Goal, Boolean> getGoals() {
public ObservableMap<Goal<?>, Boolean> getGoals() {
return goals;
}
......
package edu.ntnu.idatt2001.group_30.paths.view.components.pop_up;
import edu.ntnu.idatt2001.group_30.paths.model.Link;
import edu.ntnu.idatt2001.group_30.paths.model.Passage;
import edu.ntnu.idatt2001.group_30.paths.model.actions.Action;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
public class LinkPopUp {
private TextField textField;
private TextField referenceField;
private Button saveButton;
private ObservableList<Passage> passages;
private ObservableList<Link> links;
private Link link;
public LinkPopUp(ObservableList<Passage> passages, ObservableList<Link> links) {
this.passages = passages;
this.links = links;
textField = new TextField();
textField.setPromptText("Enter the text of the link");
referenceField = new TextField();
referenceField.setPromptText("Enter the reference of the link");
saveButton = new Button("Save");
ComboBox<Action<?>> actionComboBox = new ComboBox<>(null);
Button addActionButton = new Button("Add Action");
addActionButton.setOnAction(e -> {
if (actionComboBox.getValue() != null) {
//TODO: add the action to the link
actionComboBox.setValue(null);
}
});
VBox content = new VBox(
new Label("Link Text:"),
textField,
new Label("Link Reference:"),
referenceField,
new Label("Actions:"),
actionComboBox,
addActionButton,
saveButton
);
content.setAlignment(Pos.CENTER);
content.setSpacing(20);
PopUp<VBox, ?> popUp = PopUp
.<VBox>create()
.withTitle("Create a Link")
.withoutCloseButton()
.withContent(content)
.withDialogSize(400, 500);
saveButton.setOnAction(e -> {
if (textField.getText().isBlank() || referenceField.getText().isBlank()) {
AlertDialog.showWarning("The text or reference cannot be blank.");
} else {
link = new Link(textField.getText(), referenceField.getText());
popUp.close();
}
});
popUp.showAndWait();
}
public Link getLink() {
return link;
}
}
package edu.ntnu.idatt2001.group_30.paths.view.components.pop_up;
import edu.ntnu.idatt2001.group_30.paths.model.Passage;
import edu.ntnu.idatt2001.group_30.paths.model.Link;
import edu.ntnu.idatt2001.group_30.paths.model.actions.Action;
import edu.ntnu.idatt2001.group_30.paths.view.components.table.LinkTable;
import edu.ntnu.idatt2001.group_30.paths.view.components.table.PassageTable;
import edu.ntnu.idatt2001.group_30.paths.view.components.table.TableDisplay;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class PassagePopUp {
import java.util.stream.Collectors;
private TextField titleField;
private TextArea contentArea;
private Button saveButton;
/**
* This class contains a pop-up for creating a new passage.
*
* @author Trym Hamer Gudvangen
*/
public class PassagePopUp {
private final TextField titleField;
private final TextArea contentArea;
private final Button saveButton;
private final Button removeLinkButton;
private final LinkTable<Link> linkTable;
private final ObservableList<Passage> passages;
private final ObservableList<Link> links;
private Passage passage;
public PassagePopUp(ObservableList<Passage> passages) {
this.passages = passages;
this.links = FXCollections.observableArrayList();
public PassagePopUp() {
titleField = new TextField();
titleField.setPromptText("Enter the title of the passage");
......@@ -22,11 +43,34 @@ public class PassagePopUp {
saveButton = new Button("Save");
linkTable = new LinkTable<>(new TableDisplay.Builder<Link>()
.addColumn("Link Title", "text")
.addColumn("Reference", "reference"));
linkTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
linkTable.setItems(links);
removeLinkButton = new Button("Remove Link");
removeLinkButton.setDisable(true);
removeLinkButton.setOnAction(e -> links.remove(linkTable.getSelectionModel().getSelectedItem()));
linkTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) ->
removeLinkButton.setDisable(newSelection == null));
Button addLinkButton = new Button("Add Link");
HBox linkTableButtonHBox = new HBox(addLinkButton, removeLinkButton);
linkTableButtonHBox.setAlignment(Pos.CENTER);
addLinkButton.setOnAction(e -> this.links.add(new LinkPopUp(passages, links).getLink()));
VBox content = new VBox(
new Label("Passage Title:"),
titleField,
new Label("Passage Content:"),
contentArea,
new Label("Links:"),
linkTable,
linkTableButtonHBox,
saveButton
);
......@@ -39,18 +83,29 @@ public class PassagePopUp {
.withoutCloseButton()
.withContent(content)
.withDialogSize(400, 500);
;
saveButton.setOnAction(e -> {
if (titleField.getText().isBlank() || contentArea.getText().isBlank()) {
AlertDialog.showWarning("The title or content cannot be blank.");
} else {
Passage newPassage = new Passage(titleField.getText(), contentArea.getText());
this.passage = new Passage(titleField.getText(), contentArea.getText());
//TODO: save the new passage
//TODO: add links from the table to the new passage
popUp.close();
}
});
popUp.showAndWait();
}
/**
* This method retrieves the passages created from the pop-up.
* @return Passags created, given as a List of Passage objects.
*/
public Passage getPassage() {
return passage;
}
}
......@@ -48,14 +48,22 @@ public class LoadGameView extends View<BorderPane> {
VBox mainContainer = createMainContainerVBox(titlePane);
if(INSTANCE.getStory() != null) {
try {
addStoryPane();
} catch (IOException e) {
AlertDialog.showError(e.getMessage());
}
}
setupParentPane(mainContainer);
}
private VBox createMainContainerVBox(BorderPane titlePane) {
VBox mainContainer = new VBox();
mainContainer.getChildren().addAll(titlePane);
mainContainer.setAlignment(Pos.CENTER);
mainContainer.setSpacing(40);
mainContainer.setAlignment(Pos.TOP_CENTER);
mainContainer.setSpacing(100);
Button backButton = new Button("Back");
backButton.setOnAction(e -> StageManager.getInstance().goBack());
......@@ -90,6 +98,7 @@ public class LoadGameView extends View<BorderPane> {
title.setStyle("-fx-font-size: 20px; -fx-font-weight: bold");
titlePane.setTop(title);
BorderPane.setAlignment(title, Pos.TOP_CENTER);
titlePane.getTop().setTranslateY(-70);
loadButton = new Button("Load");
newButton = new Button("New");
......@@ -156,9 +165,7 @@ public class LoadGameView extends View<BorderPane> {
VBox storyContainer = new VBox(storyVBox, buttonIcons);
storyContainer.setAlignment(Pos.CENTER);
pencilButton.setOnAction(event -> {
StageManager.getInstance().setCurrentView(new NewStoryView());
});
pencilButton.setOnAction(newGameController.goTo(NewStoryView.class));
xButton.setOnAction(event -> {
titlePane.getChildren().remove(storyContainer);
......
......@@ -28,19 +28,18 @@ import javafx.scene.text.Text;
import java.net.URL;
import java.util.stream.Collectors;
//TODO: Add message that first passage will be opening passage
public class NewStoryView extends View<BorderPane> {
private final NewStoryController newStoryController;
private String title = "";
private Story story;
private final ObservableList<Passage> passages;
private final Button removePassageButton;
public NewStoryView() {
super(BorderPane.class);
newStoryController = new NewStoryController();
if (INSTANCE.getStory() != null) {
......@@ -72,14 +71,24 @@ public class NewStoryView extends View<BorderPane> {
PassageTable<Passage> passageTable = new PassageTable<>(new TableDisplay.Builder<Passage>()
.addColumn("Name of Passage", "title")
.addColumn("Passage Content", "content")
.addColumnWithComplexValue("Links", passage -> passage.getLinks().stream()
.map(Link::getText)
.collect(Collectors.joining(", "))));
.addColumnWithComplexValue("Links", passage -> passage == null ?
null :
passage.getLinks().stream()
.map(Link::getText)
.collect(Collectors.joining(", "))
));
passageTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
passageTable.setItems(passages);
passageTable.setMaxWidth(1000);
removePassageButton = new Button("Remove Passage");
removePassageButton.setDisable(true);
removePassageButton.setOnAction(e -> passages.remove(passageTable.getSelectionModel().getSelectedItem()));
passageTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) ->
removePassageButton.setDisable(newSelection == null));
Button addPassageButton = new Button();
URL imageUrl = getClass().getResource("/images/plus.png");
if (imageUrl != null) {
......@@ -91,24 +100,28 @@ public class NewStoryView extends View<BorderPane> {
System.err.println("Something is wrong with the trash image resource link");
}
addPassageButton.setOnAction(event -> new PassagePopUp());
addPassageButton.setOnAction(event -> {
if(passages.isEmpty()) {
AlertDialog.showInformation("Every story needs an opening passage.", "The opening passage" +
" will by default be the first passage added.");
}
PassagePopUp passagePopUp = new PassagePopUp(INSTANCE.getStory() == null ?
FXCollections.observableArrayList() : FXCollections.observableArrayList(INSTANCE.getStory().getPassages()));
if(passagePopUp.getPassage() != null) this.passages.addAll(passagePopUp.getPassage());
});
Button saveButton = new Button("Save");
saveButton.setOnAction(event -> {
try {
//TODO: if everything goes right, give a little feedback and
// then take back to load with story selected
// Add passage with links
newStoryController.addStory(title, passages);
} catch (Exception ex) {
StageManager.getInstance().setCurrentView(new LoadGameView());
}
catch (Exception ex) {
AlertDialog.showWarning(ex.getMessage());
}
StageManager.getInstance().setCurrentView(new LoadGameView());
});
VBox display = new VBox(titleText, titleBox, passageTable, addPassageButton, saveButton);
VBox display = new VBox(titleText, titleBox, passageTable, addPassageButton, removePassageButton, saveButton);
display.setAlignment(Pos.CENTER);
display.setSpacing(10);
display.setPrefWidth(500);
......@@ -118,10 +131,6 @@ public class NewStoryView extends View<BorderPane> {
getParentPane().setCenter(display);
getParentPane().setBottom(backButton);
}
}
package edu.ntnu.idatt2001.group_30.paths.view.views;
import edu.ntnu.idatt2001.group_30.paths.controller.PlaytroughController;
import edu.ntnu.idatt2001.group_30.paths.controller.PlaythroughController;
import edu.ntnu.idatt2001.group_30.paths.model.Link;
import edu.ntnu.idatt2001.group_30.paths.model.PlaythroughState;
import edu.ntnu.idatt2001.group_30.paths.model.goals.Goal;
......@@ -35,7 +35,7 @@ import javafx.scene.text.Text;
*/
public class PlaythroughView extends View<VBox> {
private final PlaytroughController controller;
private final PlaythroughController controller;
/**
* Creates a new instance of the view.
......@@ -44,7 +44,7 @@ public class PlaythroughView extends View<VBox> {
*/
public PlaythroughView() {
super(VBox.class);
controller = new PlaytroughController();
controller = new PlaythroughController();
/*
* The view is divided into three parts:
......@@ -54,7 +54,7 @@ public class PlaythroughView extends View<VBox> {
* | | player & game |
* | | info |
* | | --------------- |
* | play-trough window | goals |
* | play-through window | goals |
* | | --------------- |
* | | inventory |
* | | |
......@@ -317,9 +317,9 @@ public class PlaythroughView extends View<VBox> {
content.setSpacing(20);
content.setPadding(new Insets(0, 0, 0, 20));
ObservableMap<Goal, Boolean> goals = controller.getGoals();
ObservableMap<Goal<?>, Boolean> goals = controller.getGoals();
goals.addListener(
(MapChangeListener<Goal, Boolean>) change -> {
(MapChangeListener<Goal<?>, Boolean>) change -> {
showGoals(goals, content);
}
);
......@@ -388,7 +388,7 @@ public class PlaythroughView extends View<VBox> {
* @param goals The goals to show.
* @param content The pane to show the goals in.
*/
private void showGoals(ObservableMap<Goal, Boolean> goals, Pane content) {
private void showGoals(ObservableMap<Goal<?>, Boolean> goals, Pane content) {
content.getChildren().clear();
goals.forEach((goal, completed) -> {
HBox goalBox = new HBox();
......
......@@ -6,6 +6,7 @@ module edu.ntnu.idatt2001.group_30.paths {
exports edu.ntnu.idatt2001.group_30.paths.view;
exports edu.ntnu.idatt2001.group_30.paths.model;
exports edu.ntnu.idatt2001.group_30.paths.model.goals;
exports edu.ntnu.idatt2001.group_30.paths.model.actions;
exports edu.ntnu.idatt2001.group_30.paths.view.components;
exports edu.ntnu.idatt2001.group_30.paths.view.components.common;
exports edu.ntnu.idatt2001.group_30.paths.view.components.pane;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment