diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java index a6bc85d369e4a2583c38d4202cd6003b8e6623af..30e59521da7e0bd0bd2a9bd483468edbd6d80aaa 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java @@ -10,101 +10,34 @@ import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Button; import javafx.scene.control.ListView; import javafx.scene.input.MouseEvent; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.recipes.*; + import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.ResourceBundle; -/** - * The AllRecipesController manages the view named AllRecipes.fxml that displays a scrollable list of all the - * recipes that are stored in the recipe register at 'src/main/resources/recipes/Recipes.register'. The controller - * holds an instance of the IngredientsAtHand class and the RecipeRegister class and combines the two to - * fill the list with recipes sorted by the number of ingredients that are not currently in the 'fridge' of the - * user. Each recipe is also lister with a percentage value that shows how many percent of the recipe's - * ingredients are actually in the fridge. This information is included so that recipes with a lower number of - * ingredients are not given an unfair advantage over others where the user may have a significant number of - * the ingredients available. Each listed recipe may be clicked on by the user to open it in a new view in full - * detail. - * - * @author hannesofie - */ public class AllRecipesController implements Initializable { IngredientsAtHand ingredientsAtHand; RecipeRegister recipeRegister; @FXML - private ListView<String> allList; - - private String selectedRecipeName; - - - /** - * The initialize method of the controller takes in a URL (location) and ResourceBundle(resources) to - * initialize the controller once its root element has been processed. The method then reads and creates - * an object of the IngredientsAtHand class and one of the RecipesRegister class. - * If the recipe register exists, the list is filled with Strings for each recipe at the format: - * <Recipe name> - X missing ingredients (XX%) - * Finally, a MouseClick event and handler is attached to the list that gets the recipe name of the clicked - * list item and runs the method showRecipe() with that name as input to show the recipe in detail in the - * view Recipe.fxml. - * - * @param url The location to resolve the relative paths to the root object. - * @param resourceBundle Resources used to localize the root object. - */ - @Override - public void initialize(URL url, ResourceBundle resourceBundle) { + private Button goBackBtn; - ingredientsAtHand = FileHandler.readIngredientsAtHand("Fridge"); - recipeRegister = FileHandler.readRecipeRegister("Recipes"); - - ObservableList<String> recipes; - - if(recipeRegister == null) { - recipes = FXCollections.observableArrayList(new ArrayList<>()); - } else { - int numberOfRecipes = recipeRegister.getRecipes().size(); - - ArrayList<Recipe> sortedRecipes = recipeRegister.pickBestFits(numberOfRecipes, ingredientsAtHand); - - recipes = FXCollections.observableArrayList(sortedRecipes.stream().map(recipe -> String.format("# %s - %d missing ingredients (%2.0f %%)", recipe.getName(), recipe.getMissingIngredients(), percent(recipe.getIngredientList().size() - recipe.getMissingIngredients(), recipe.getIngredientList().size()))).toList()); - } + @FXML + private ListView<String> allList; - allList.setItems(recipes); - allList.setOnMouseClicked(new EventHandler<>() { + private ObservableList<String> recipes; - /** - * The handler method takes a MouseEvent(Mouse Click) and uses the list item that was subjected to the - * mouse click and extracts the recipe name. That name as a String is then passed to the method - * 'showRecipe' that loads the view Recipe.fxml to display this particular recipe in full detail. - * - * @param mouseEvent A mouse event, in this case a MouseClicked event. - */ - @Override - public void handle(MouseEvent mouseEvent) { - selectedRecipeName = allList.getSelectionModel() - .getSelectedItem().split("[-#]")[1].strip(); - try { - showRecipe(selectedRecipeName); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }); - } + private String selectedRecipeName; - /** - * The goBack method is fired whenever the user presses the button 'Back To Suggestions'. It loads the location - * of the SuggestRecipes.fxml view and sets the new stage. - * @param event Action event that triggers this method, in this case a button click. - * @throws IOException If the method fails to load the location at the given file path. - */ @FXML private void goBack(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(); @@ -117,12 +50,6 @@ public class AllRecipesController implements Initializable { stage.show(); } - /** - * The showRecipe method takes in a recipe name as a String and navigates to the view Recipe.fxml after having - * the RecipeController set the data of the view according to this particular recipe. - * @param recipeName A case-sensitive string representation of the recipe to open in detail. - * @throws IOException If the method fails to load the location of the Recipe.fxml view. - */ private void showRecipe(String recipeName) throws IOException { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/Recipe.fxml")); @@ -130,33 +57,59 @@ public class AllRecipesController implements Initializable { Recipe recipeOfInterest = recipeRegister.getRecipe(recipeName); Parent root = loader.load(); + RecipeController recipeController = loader.getController(); - if(recipeOfInterest != null) { - recipeController.setData(recipeOfInterest); - Stage stage = (Stage)allList.getParent().getScene().getWindow(); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); - } else { - System.out.println("The selected recipe is null."); - } + recipeController.setData(recipeOfInterest); + + Stage stage = (Stage)allList.getParent().getScene().getWindow(); + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); } - /** - * The percent method takes in two integers(a, b) and performs float-division(a/b) on then and multiplies the - * answer by 100 to get the percentage 'a' makes of the total 'b'. If either 'a' or 'b' is zero, zero is returned. - * In the current context; 'a' is an int representing a number of ingredients at hand and part of a recipe and 'b' - * is an int representing the total number of ingredients in the same recipe. - * @param a An int to divide by b and multiply by 100. - * @param b An int by which to divide 'a'. - * @return A float value presenting the percentage value of 'a' out of 'b'. - */ - private float percent(int a, int b) { - if (b != 0 && a != 0) { - return (a * 100f / b); +private float percent(int a, int b) { + if(b != 0 && a != 0) { + return (float) a / b; } else { return 0; } + + +} + + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + + ingredientsAtHand = FileHandler.readIngredientsAtHand("Fridge"); + recipeRegister = FileHandler.readRecipeRegister("Recipes"); + + int numberOfRecipes = recipeRegister.getRecipes().size(); + + ArrayList<Recipe> sortedRecipes = recipeRegister.pickBestFits(numberOfRecipes, ingredientsAtHand); + + recipes = FXCollections.observableArrayList(sortedRecipes.stream().map(recipe -> { + return String.format("# %s - %d missing ingredients (%.2f %% covered)", recipe.getName(), recipe.getMissingIngredients(), percent(recipe.getIngredientList().size() - recipe.getMissingIngredients(),recipe.getIngredientList().size())); + }).toList()); + + allList.setItems(recipes); + + allList.setOnMouseClicked(new EventHandler<MouseEvent>() { + + @Override + public void handle(MouseEvent mouseEvent) { + selectedRecipeName = allList.getSelectionModel() + .getSelectedItem().split("-|#")[1].strip(); + + try { + showRecipe(selectedRecipeName); + + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + }); + } } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/IngredientTileController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/IngredientTileController.java index 05937bc1e949e87ddd9f7221cae9e3de15c679a4..d7cb7ac75c2e654d9acfab29eb729e4d4eab3216 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/IngredientTileController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/IngredientTileController.java @@ -31,5 +31,6 @@ public class IngredientTileController { .append(ingredient.getAmount()).append(" ") .append(ingredient.getUnit().label); text.setText(String.valueOf(sb)); + text.setStyle("-fx-font-size: 18"); } } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/RecipeTileController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/RecipeTileController.java index 81e5e3b0584efc8c6b5c984e98dea75b42bbacae..b0d579b3d496d5fa0550925cd5043da9c3d3abe1 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/RecipeTileController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/RecipeTileController.java @@ -27,7 +27,7 @@ import java.util.ResourceBundle; public class RecipeTileController implements Initializable { @FXML - private Button nameTag; + private Label nameTag; @FXML private Label missingTag; diff --git a/src/main/resources/recipes/Fridge.register b/src/main/resources/recipes/Fridge.register index c39c5a876cd3ef509f5cfd5bb5be3f7e5e5e05d8..a2241d993010922e34ad456521e9b392f2312319 100644 --- a/src/main/resources/recipes/Fridge.register +++ b/src/main/resources/recipes/Fridge.register @@ -1,9 +1,19 @@ +CARROT +MILK +AVOCADO +CANNED_TOMATO +CELERY +BROTH +BAY_LEAF +DRY_OREGANO +WHITE_BEANS +DRY_THYME +FRESH_YEAST +GARLIC_CLOVE +RED_ONION +PIE_DOUGH +BROCCOLI +LAM +CHILLI_POWDER +SAUSAGE YELLOW_CHEESE -MINCED_MEAT -ONION -HAM -WHEAT_FLOUR -ORANGE -OIL -POTATO -OLIVE_OIL diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 1dc2e5ed8ba85a1bbf804bd1938ec4fdc4be5dd7..57dceb0f65b105249c914f60787a37473b58a348 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -10,15 +10,13 @@ } .button-style { - //-fx-background-color: linear-gradient(#8ca45b, #1e5b5b); -fx-background-color: white; -fx-text-fill: black; -fx-background-radius: 30; -fx-background-insets: 0; -fx-font-family: "JetBrains Mono"; - -fx-font-size: 16; - //-fx-text-fill: white; + } .welcome-button { @@ -36,7 +34,7 @@ } #on-white { - -fx-background-color: #79b2b2; + -fx-background-color: #83b6b6; -fx-text-fill: black; } @@ -80,9 +78,10 @@ } .list-cell{ - -fx-font-size:18.0; + -fx-font-size:20.0; } + .list-cell:even { -fx-background-color: rgba(255, 255, 255, 0.7); } @@ -101,12 +100,17 @@ -fx-alignment: center; } -.ingredient:hover { - -fx-scale-x: 1.05; - -fx-scale-y: 1.05; - -fx-scale-z: 1.05; +/*#ingredient-label { + -fx-font-family: "JetBrains Mono Medium"; } +#ingredient:hover { + -fx-text-fill: red; + -fx-scale-x: 1.03; + -fx-scale-y: 1.03; + -fx-scale-z: 1.03; +}*/ + .recipe-instructions { -fx-font-size: 16; -fx-font-style: italic; @@ -122,9 +126,19 @@ .scroll-pane > .viewport { -fx-background-color: transparent; } + .scroll-pane { - -fx-background-color: rgba(255, 255, 255, 0.5); + -fx-background-color: rgba(255, 255, 255, 0.35); -fx-border-width: 5; -fx-border-radius: 5; -fx-border-color: rgba(255, 255, 255, 0.75); } + +#help { + -fx-font-size: 30; + -fx-font-weight: bold; + -fx-background-color: #e09188; + -fx-border-width: 5; + -fx-border-radius: 30; + -fx-border-color: white; +} \ No newline at end of file diff --git a/src/main/resources/view/AddIngredient.fxml b/src/main/resources/view/AddIngredient.fxml index eb4ecda794c1ea8b84655e96dc1871b33bf1e8e6..3384b11dd2e656b33c21031ce603264f17525783 100644 --- a/src/main/resources/view/AddIngredient.fxml +++ b/src/main/resources/view/AddIngredient.fxml @@ -5,7 +5,7 @@ <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> -<DialogPane id="dialog-pane" expanded="true" prefHeight="524.0" prefWidth="614.0" stylesheets="@../style.css" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.AddIngredientController"> +<DialogPane id="dialog-pane" expanded="true" prefHeight="555.0" prefWidth="614.0" stylesheets="@../style.css" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.AddIngredientController"> <content> <AnchorPane prefHeight="400.0" prefWidth="600.0"> <padding> @@ -56,9 +56,9 @@ </Pane> <Pane prefHeight="100.0" prefWidth="614.0"> <children> - <Label fx:id="status" layoutX="28.0" layoutY="6.0" prefHeight="44.0" prefWidth="558.0" textAlignment="CENTER" wrapText="true"> + <Label fx:id="status" layoutX="28.0" layoutY="-4.0" prefHeight="44.0" prefWidth="558.0" textAlignment="CENTER" wrapText="true"> <font> - <Font size="14.0" /> + <Font size="20.0" /> </font></Label> </children> </Pane> @@ -66,17 +66,30 @@ </VBox> </children></AnchorPane> </content> - <header> - <Label fx:id="addIngredientPane" alignment="CENTER" contentDisplay="CENTER" styleClass="font" stylesheets="@../style.css" text="Add an ingredient to the fridge"> - <font> - <Font size="24.0" /> - </font> - <padding> - <Insets bottom="25.0" top="20.0" /> - </padding> - </Label> - </header> <buttonTypes> <ButtonType fx:constant="CLOSE" /> </buttonTypes> + <header> + <HBox prefHeight="100.0" prefWidth="200.0"> + <children> + <Pane prefHeight="100.0" prefWidth="543.0"> + <children> + <Label layoutX="19.0" layoutY="30.0" prefWidth="516.0" styleClass="head-line" stylesheets="@../style.css" text="Add ingredients to Fridge"> + <font> + <Font size="30.0" /> + </font> + </Label> + </children> + </Pane> + <Pane prefHeight="100.0" prefWidth="102.0"> + <children> + <Button id="help" fx:id="helpBtn" layoutX="9.0" layoutY="14.0" mnemonicParsing="false" onAction="#help" styleClass="button-style" stylesheets="@../style.css" text="?"> + <font> + <Font name="System Bold" size="36.0" /> + </font></Button> + </children> + </Pane> + </children> + </HBox> + </header> </DialogPane> diff --git a/src/main/resources/view/IngredientTile.fxml b/src/main/resources/view/IngredientTile.fxml index 4940a578a471985fa4edd8451b1a121901aa6689..bd749e3a189d66636ae1054b0ca94b55744a10fc 100644 --- a/src/main/resources/view/IngredientTile.fxml +++ b/src/main/resources/view/IngredientTile.fxml @@ -5,11 +5,11 @@ <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> -<Pane fx:id="ingredientPane" styleClass="ingredient" stylesheets="@../style.css" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.IngredientTileController"> +<Pane id="ingredient" fx:id="ingredientPane" mouseTransparent="true" stylesheets="@../style.css" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.IngredientTileController"> <children> - <Label fx:id="text" prefHeight="40.0" prefWidth="250.0" styleClass="font" stylesheets="@../style.css" text="Ingredient"> + <Label id="ingredient-label" fx:id="text" prefHeight="40.0" prefWidth="250.0" styleClass="font" stylesheets="@../style.css" text="Ingredient"> <font> - <Font name="Ani" size="14.0" /> + <Font name="Ani" size="18.0" /> </font> <padding> <Insets left="15.0" /> diff --git a/src/main/resources/view/RecipeTile.fxml b/src/main/resources/view/RecipeTile.fxml index b4f2c0704ecb6174aee5efd6cdba1f2f6c951f11..9f4c03272d4fd07b457be86fc285421dee2fa45e 100644 --- a/src/main/resources/view/RecipeTile.fxml +++ b/src/main/resources/view/RecipeTile.fxml @@ -7,34 +7,49 @@ <VBox fx:id="recipeTile" prefHeight="220.0" prefWidth="280.0" styleClass="recipe-tile" stylesheets="@../style.css" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.RecipeTileController"> <children> - <Pane fx:id="namePane" prefHeight="178.0" prefWidth="268.0"> + <Pane fx:id="namePane" prefHeight="218.0" prefWidth="268.0"> <children> - <Button fx:id="nameTag" mnemonicParsing="false" onAction="#tileClick" prefHeight="149.0" prefWidth="268.0" styleClass="tile-button" stylesheets="@../style.css" text="nameOfRecipe"> + <Button fx:id="tileBtn" alignment="TOP_LEFT" layoutX="-6.0" mnemonicParsing="false" onAction="#tileClick" prefHeight="213.0" prefWidth="280.0" styleClass="tile-button" stylesheets="@../style.css" textAlignment="CENTER"> <font> - <Font size="24.0" /> + <Font name="System Bold" size="24.0" /> </font> + <graphic> + <VBox prefHeight="199.0" prefWidth="95.0"> + <children> + <Pane prefHeight="132.0" prefWidth="248.0" styleClass="font" stylesheets="@../style.css"> + <children> + <Label fx:id="nameTag" alignment="CENTER" contentDisplay="CENTER" prefHeight="135.0" prefWidth="250.0" text="nameOfRecipe" textAlignment="CENTER" wrapText="true"> + <font> + <Font name="System Bold" size="24.0" /> + </font> + </Label> + </children> + </Pane> + <HBox accessibleRole="BUTTON" prefHeight="66.0" prefWidth="268.0"> + <children> + <Label alignment="CENTER" prefHeight="66.0" prefWidth="243.0" text="Missing ingredients:" textAlignment="CENTER" wrapText="true"> + <font> + <Font size="24.0" /> + </font> + <opaqueInsets> + <Insets left="20.0" right="20.0" /> + </opaqueInsets> + </Label> + <Label id="noMissingIngredients" fx:id="missingTag" alignment="CENTER" contentDisplay="CENTER" prefHeight="69.0" prefWidth="127.0" text="# missing"> + <font> + <Font size="24.0" /> + </font> + </Label> + </children> + <opaqueInsets> + <Insets left="20.0" right="20.0" /> + </opaqueInsets> + </HBox> + </children> + </VBox> + </graphic> </Button> </children> </Pane> - <HBox prefHeight="88.0" prefWidth="500.0"> - <children> - <Label alignment="CENTER" prefHeight="63.0" prefWidth="292.0" text="Ingredients missing:"> - <font> - <Font size="18.0" /> - </font> - <opaqueInsets> - <Insets left="20.0" right="20.0" /> - </opaqueInsets> - </Label> - <Label id="noMissingIngredients" fx:id="missingTag" alignment="CENTER" contentDisplay="CENTER" prefHeight="69.0" prefWidth="127.0" text="# missing"> - <font> - <Font size="24.0" /> - </font> - </Label> - </children> - <opaqueInsets> - <Insets left="20.0" right="20.0" /> - </opaqueInsets> - </HBox> </children> </VBox> diff --git a/src/main/resources/view/SuggestRecipes.fxml b/src/main/resources/view/SuggestRecipes.fxml index 7be5df95fcb2bccf4167941ca8fcc4a342ac21c0..adb817c107e493515275b00d9009ff6953b01fa8 100644 --- a/src/main/resources/view/SuggestRecipes.fxml +++ b/src/main/resources/view/SuggestRecipes.fxml @@ -30,7 +30,7 @@ </Label> </children> </Pane> - <ListView id="list-cell" fx:id="fridgeList" prefHeight="470.0" prefWidth="378.0" stylesheets="@../style.css"> + <ListView fx:id="fridgeList" prefHeight="470.0" prefWidth="378.0" styleClass="list-cell" stylesheets="@../style.css"> <VBox.margin> <Insets right="20.0" /> </VBox.margin></ListView> @@ -60,7 +60,7 @@ <children> <Label fx:id="missingList" stylesheets="@../style.css"> <font> - <Font name="System Bold" size="14.0" /> + <Font name="System Bold" size="20.0" /> </font> <padding> <Insets left="20.0" right="20.0" /> @@ -106,7 +106,7 @@ </BorderPane> </top> <center> - <GridPane fx:id="recipeGrid" hgap="20.0" prefWidth="603.0" vgap="20.0" BorderPane.alignment="CENTER"> + <GridPane fx:id="recipeGrid" hgap="20.0" prefHeight="443.0" prefWidth="609.0" vgap="20.0" BorderPane.alignment="CENTER"> <columnConstraints> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />