diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java index 0d4afa902a3c42ae0edf0a85488b120b48402398..bedbaf92da351ab21f79d3ce6534fa9f4840b6b5 100644 --- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java +++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java @@ -6,8 +6,18 @@ package edu.ntnu.idatt2001.group_30.paths.model.actions; * @author Trym Hamer Gudvangen */ public enum ActionType { - GOLD_ACTION, - HEALTH_ACTION, - INVENTORY_ACTION, - SCORE_ACTION, + GOLD_ACTION("Gold Action"), + HEALTH_ACTION("Health Action"), + INVENTORY_ACTION("Inventory Action"), + SCORE_ACTION("Score Action"); + + private final String displayName; + + ActionType(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } } diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java index 4a15f80fcaa7561d9c2663df520ddc2fbbaddd71..8e955bfa5744ecce57373540daaa58702e3a2adf 100644 --- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java +++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java @@ -159,7 +159,7 @@ public class GoalsPopUp extends AbstractPopUp{ .withTitle("Add goals to your player") .withoutCloseButton() .withContent(scrollPane) - .withDialogSize(400, 500); + .withDialogSize(400, 750); popUp.showAndWait(); diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/LinkPopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/LinkPopUp.java index 8df7aea784e202dd4909e7fe53eddcb04ba0d44e..4824b4c46ec56c178f7444d9c45675ebf263e375 100644 --- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/LinkPopUp.java +++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/LinkPopUp.java @@ -3,10 +3,16 @@ 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 edu.ntnu.idatt2001.group_30.paths.model.actions.ActionFactory; +import edu.ntnu.idatt2001.group_30.paths.model.actions.ActionType; +import edu.ntnu.idatt2001.group_30.paths.model.utils.TextValidation; +import edu.ntnu.idatt2001.group_30.paths.view.components.table.ActionTable; +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; import java.util.HashMap; @@ -14,20 +20,23 @@ import java.util.HashMap; public class LinkPopUp extends AbstractPopUp{ private TextField textField; + private TextField actionTextField; private Button saveButton; private Button addActionButton; + private Button removeActionButton; private ComboBox<String> reference; - private ComboBox<Action<?>> actionComboBox; + private ComboBox<ActionType> actionComboBox; + private ActionTable<Action<?>> actionTable; private VBox content; private final ObservableList<Passage> passages; - private final ObservableList<Link> links; + private ObservableList<Action<?>> actions; private HashMap<String, Passage> passageHashMap; private Link link; private PopUp<VBox, ?> popUp; - public LinkPopUp(ObservableList<Passage> passages, ObservableList<Link> links) { + public LinkPopUp(ObservableList<Passage> passages) { + this.actions = FXCollections.observableArrayList(); this.passages = passages; - this.links = links; this.passageHashMap = new HashMap<>(); passages.forEach(passage -> passageHashMap.put(passage.getTitle(), passage)); @@ -35,6 +44,18 @@ public class LinkPopUp extends AbstractPopUp{ createPopUp(); } + public LinkPopUp(ObservableList<Passage> passages, Link link) { + this.link = link; + this.actions = FXCollections.observableArrayList(link.getActions()); + this.passages = passages; + this.passageHashMap = new HashMap<>(); + passages.forEach(passage -> passageHashMap.put(passage.getTitle(), passage)); + + initialize(); + loadLink(); + createPopUp(); + } + @Override protected void setupUiComponents() { @@ -46,17 +67,40 @@ public class LinkPopUp extends AbstractPopUp{ saveButton = new Button("Save"); - actionComboBox = new ComboBox<>(null); + ObservableList<ActionType> actionTypes = FXCollections.observableArrayList(ActionType.values()); + + actionComboBox = new ComboBox<>(actionTypes); + actionComboBox.setPromptText("Select an action"); + + actionTextField = new TextField(); + + + removeActionButton = new Button("Remove Action"); + removeActionButton.setDisable(true); + + addActionButton = new Button("Add Action"); + HBox actionHbox = new HBox(actionComboBox, actionTextField, addActionButton); + actionHbox.setAlignment(Pos.CENTER); + + actionTable = new ActionTable<>(new TableDisplay.Builder<Action<?>>() + .addColumnWithComplexValue("Type", action -> action.getClass().getSimpleName()) + .addColumnWithComplexValue("Value", action -> action.getActionValue().toString())); + + actionTable.setItems(actions); + + actionTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + content = new VBox( new Label("Link Text:"), textField, new Label("Link Reference:"), reference, new Label("Actions:"), - actionComboBox, - addActionButton, + actionHbox, + actionTable, + removeActionButton, saveButton ); @@ -68,9 +112,17 @@ public class LinkPopUp extends AbstractPopUp{ @Override protected void setupBehavior() { + + removeActionButton.setOnAction(event -> actions.remove(actionTable.getSelectionModel().getSelectedItem())); + + actionTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> { + removeActionButton.setDisable(newSelection == null); + }); + + addActionButton.setOnAction(e -> { if (actionComboBox.getValue() != null) { - //TODO: add the action to the link + actions.add(ActionFactory.getAction(actionComboBox.getValue(), actionTextField.getText())); actionComboBox.setValue(null); } }); @@ -80,9 +132,28 @@ public class LinkPopUp extends AbstractPopUp{ AlertDialog.showWarning("The text or reference cannot be blank."); } else { link = new Link(textField.getText(), passageHashMap.get(reference.getValue()).getTitle()); + actions.forEach(action -> link.addAction(action)); popUp.close(); } }); + + actionComboBox.setCellFactory(listView -> new ListCell<>() { + @Override + protected void updateItem(ActionType actionType, boolean empty) { + super.updateItem(actionType, empty); + if (empty || actionType == null) { + setText(null); + } else { + setText(actionType.getDisplayName()); + switch(actionType) { + case SCORE_ACTION, GOLD_ACTION, HEALTH_ACTION -> actionTextField.setTextFormatter(TextValidation.createIntegerTextFormatter()); + case INVENTORY_ACTION -> actionTextField.setTextFormatter(null); + } + } + } + }); + + actionComboBox.setButtonCell(actionComboBox.getCellFactory().call(null)); } @Override @@ -97,6 +168,11 @@ public class LinkPopUp extends AbstractPopUp{ popUp.showAndWait(); } + private void loadLink() { + textField.setText(this.link.getText()); + reference.setValue(this.link.getReference()); + } + /** * This method retrieves the link created in the pop-up. * @return Link created in pop-up, given as a Link object. diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PassagePopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PassagePopUp.java index f7036e02ab804f0584341b7359fe19f62599586e..900784b3cfb16f1e7458c10c22f97156256cf600 100644 --- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PassagePopUp.java +++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PassagePopUp.java @@ -23,6 +23,7 @@ public class PassagePopUp extends AbstractPopUp{ private Button saveButton; private Button removeLinkButton; private Button addLinkButton; + private Button editLinkButton; private VBox content; private LinkTable<Link> linkTable; private final ObservableList<Passage> passages; @@ -58,6 +59,7 @@ public class PassagePopUp extends AbstractPopUp{ contentArea = new TextArea(); contentArea.setPromptText("Enter the content of the passage"); + contentArea.setMinHeight(150); saveButton = new Button("Save"); @@ -68,13 +70,16 @@ public class PassagePopUp extends AbstractPopUp{ linkTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); linkTable.setItems(links); + editLinkButton = new Button("Edit Link"); + editLinkButton.setDisable(true); + removeLinkButton = new Button("Remove Link"); removeLinkButton.setDisable(true); addLinkButton = new Button("Add Link"); if(passages.isEmpty()) addLinkButton.setDisable(true); - HBox linkTableButtonHBox = new HBox(addLinkButton, removeLinkButton); + HBox linkTableButtonHBox = new HBox(editLinkButton, addLinkButton, removeLinkButton); linkTableButtonHBox.setAlignment(Pos.CENTER); content = new VBox( @@ -94,14 +99,24 @@ public class PassagePopUp extends AbstractPopUp{ @Override protected void setupBehavior() { + editLinkButton.setOnAction(e -> { + Link newLink = new LinkPopUp(this.passages, linkTable.getSelectionModel().getSelectedItem()).getLink(); + if(newLink != null) { + this.links.remove(linkTable.getSelectionModel().getSelectedItem()); + this.links.add(newLink); + } + }); + removeLinkButton.setOnAction(e -> links.remove(linkTable.getSelectionModel().getSelectedItem())); - linkTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> - removeLinkButton.setDisable(newSelection == null)); + linkTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> { + removeLinkButton.setDisable(newSelection == null); + editLinkButton.setDisable(newSelection == null); + }); addLinkButton.setOnAction(e -> { - Link newLink = new LinkPopUp(this.passages, links).getLink(); + Link newLink = new LinkPopUp(this.passages).getLink(); if(newLink != null) { this.links.add(newLink); } @@ -111,13 +126,13 @@ public class PassagePopUp extends AbstractPopUp{ saveButton.setOnAction(e -> { if (titleField.getText().isBlank() || contentArea.getText().isBlank()) { AlertDialog.showWarning("The title or content cannot be blank."); + } else if (this.passages.stream().anyMatch(passage1 -> passage1.getTitle().equals(titleField.getText()) + && passage != passage1)) { + AlertDialog.showWarning("A passage with the title " + titleField.getText() + " already exists."); } else { this.passage = new Passage(titleField.getText(), contentArea.getText()); this.links.forEach(link -> this.passage.addLink(link)); - //TODO: save the new passage - //TODO: add links from the table to the new passage - popUp.close(); } }); @@ -130,7 +145,7 @@ public class PassagePopUp extends AbstractPopUp{ .withTitle("Create a Passage") .withoutCloseButton() .withContent(content) - .withDialogSize(400, 500); + .withDialogSize(400, 750); popUp.showAndWait(); } diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/ActionTable.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/ActionTable.java new file mode 100644 index 0000000000000000000000000000000000000000..60cedae7938aab8e730e77aa81e5d55f000f0d3e --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/ActionTable.java @@ -0,0 +1,19 @@ +package edu.ntnu.idatt2001.group_30.paths.view.components.table; + +/** + * This class contains the table display implementation for the action object. + * @param <Action> Type of table, which is for Action. + * + * @author Trym Hamer Gudvangen + */ +public class ActionTable<Action> extends TableDisplay<Action>{ + + /** + * This is a constructor which is used to construct a table for different actions. + * + * @param tableBuilder The builder used to construct a table, represented using an tableBuilder object. + */ + public ActionTable(Builder<Action> tableBuilder) { + super(tableBuilder); + } +} diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java index be5916a7410212bd28a4740820b490e3e6b4d080..c9646a11b7d1f7fff6ec658b8d90751dc145d50a 100644 --- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java +++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java @@ -1,5 +1,11 @@ package edu.ntnu.idatt2001.group_30.paths.view.components.table; +/** + * This class contains the specific table display implementation for the Goal classes. + * @param <Goal> Type of table, which is Goal. + * + * @author Trym Hamer Gudvangen + */ public class GoalTable<Goal> extends TableDisplay<Goal> { /** diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewStoryView.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewStoryView.java index ce960239bc933969d480723f520843e153680022..98c03f54ec746d553e51b7bb8aa974284890b18a 100644 --- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewStoryView.java +++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewStoryView.java @@ -98,14 +98,10 @@ public class NewStoryView extends View<BorderPane> { if (selectedPassage != null) { Passage updatedPassage = new PassagePopUp(passages, selectedPassage).getPassage(); if(updatedPassage != null && !selectedPassage.equals(updatedPassage)) { - passages.forEach(passage -> { - System.out.println(passage.getTitle()); - System.out.println(passage.getLinks()); - passage.getLinks().replaceAll(link -> - link.getReference().equals(selectedPassage.getTitle()) ? - new Link(link.getText(), updatedPassage.getTitle()) : link - ); - }); + passages.forEach(passage -> passage.getLinks().replaceAll(link -> + link.getReference().equals(selectedPassage.getTitle()) ? + new Link(link.getText(), updatedPassage.getTitle()) : link + )); passages.remove(selectedPassage); passages.add(updatedPassage); }