From ee4fbeb75407a42fca89eef1f4d782ed36271aa4 Mon Sep 17 00:00:00 2001 From: Lukas Karsch <lk224@hdm-stuttgart.de> Date: Mon, 26 Jun 2023 12:00:23 +0200 Subject: [PATCH] turned nutrition tables into a .fxml component, editing recipes works correctly --- .../mi/hdm/controllers/BaseController.java | 14 ++ .../hdm/controllers/MealPlanController.java | 103 +++------- .../controllers/RecipeCreatorController.java | 6 +- .../controllers/RecipeEditorController.java | 60 +++--- .../hdm/controllers/RecipeViewController.java | 2 - .../mi/hdm/controllers/ViewComponent.java | 18 +- src/main/java/mi/hdm/mealPlan/MealPlan.java | 7 +- .../java/mi/hdm/recipes/RecipeManager.java | 4 +- .../java/mi/hdm/recipes/RecipeSearch.java | 2 +- .../mi/hdm/shoppingList/ShoppingList.java | 2 +- src/main/resources/fxml/Meal_Plan.fxml | 181 +++--------------- src/main/resources/fxml/recipe-editor.fxml | 109 ++++++----- src/main/resources/fxml/recipe-view.fxml | 15 +- 13 files changed, 194 insertions(+), 329 deletions(-) diff --git a/src/main/java/mi/hdm/controllers/BaseController.java b/src/main/java/mi/hdm/controllers/BaseController.java index f4b23f8..bf07d09 100644 --- a/src/main/java/mi/hdm/controllers/BaseController.java +++ b/src/main/java/mi/hdm/controllers/BaseController.java @@ -2,9 +2,12 @@ package mi.hdm.controllers; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Pane; import javafx.stage.Stage; import mi.hdm.GUIDriver; +import mi.hdm.recipes.NutritionTable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -57,4 +60,15 @@ public abstract class BaseController { e.printStackTrace(); } } + + protected void putNutritionTable(Pane target, NutritionTable nutritionTable, String text) { + target.getChildren().clear(); + try { + target.getChildren().add(ViewComponent.NUTRITION_TABLE.getParentElement(nutritionTable, text)); + } catch (IOException e) { + log.error("Could not load nutrition table. Displaying placeholder"); + e.printStackTrace(); + target.getChildren().add(new Label("Placeholder - nutrition table couldn't be loaded!")); + } + } } diff --git a/src/main/java/mi/hdm/controllers/MealPlanController.java b/src/main/java/mi/hdm/controllers/MealPlanController.java index 30f6335..eb30903 100644 --- a/src/main/java/mi/hdm/controllers/MealPlanController.java +++ b/src/main/java/mi/hdm/controllers/MealPlanController.java @@ -8,22 +8,21 @@ import javafx.scene.control.*; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.*; -import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; -import javafx.scene.text.Text; import mi.hdm.components.IngredientSearchResultLabel; import mi.hdm.mealPlan.MealPlan; -import mi.hdm.recipes.*; +import mi.hdm.recipes.IngredientManager; +import mi.hdm.recipes.Recipe; +import mi.hdm.recipes.RecipeManager; +import mi.hdm.recipes.RecipeSearch; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; -import java.util.Map; public class MealPlanController extends BaseController { private final MealPlan mealPlan; @@ -44,29 +43,7 @@ public class MealPlanController extends BaseController { @FXML private VBox searchVBox; @FXML - private ProgressBar caloriesProgressBar; - @FXML - private ProgressBar carbsProgressBar; - @FXML - private ProgressBar fatProgressbar; - @FXML - private ProgressBar proteinProgressBar; - @FXML - private ProgressBar fibersProgressBar; - @FXML - private ProgressBar saltProgressBar; - @FXML - private Text caloriesPercentage; - @FXML - private Text carbsPercentage; - @FXML - private Text fatPercentage; - @FXML - private Text proteinPercentage; - @FXML - private Text fiberPercentage; - @FXML - private Text saltPercentage; + private VBox nutritionTableContainer; public MealPlanController(MealPlan mealPlan, RecipeManager recipeManager, IngredientManager ingredientManager) { this.mealPlan = mealPlan; @@ -100,7 +77,7 @@ public class MealPlanController extends BaseController { for (int j = 0; j < 7; j++) { final int J = j; mealPlan.getRecipeCodeForDay(LocalDate.now().plusDays(J)).ifPresentOrElse(code -> { - Recipe r = recipeManager.getRecipeByCode(code); + Recipe r = recipeManager.getRecipe(code).get(); VBox displayRecipeVBox = new VBox(); ImageView recipeImage = new ImageView(new Image(r.getImageURL().toString())); @@ -156,21 +133,21 @@ public class MealPlanController extends BaseController { searchVBox = new VBox(); searchVBox.setMaxSize(800, 800); searchVBox.setAlignment(Pos.CENTER); - TextField searchTextField = new TextField(); - searchTextField.setPromptText("Search for recipe"); - searchTextField.textProperty().addListener(e -> { - String input = searchTextField.getText(); - log.debug("Input in search field changed, searching through recipes with query '{}'.", input); - searchResults = recipeSearch.searchByQuery(recipeManager.getRecipes(), input); - drawRecipeSearchResults(date); - } - ); - searchScrollPane = new ScrollPane(); - searchTextField.setStyle("-fx-border-color: d91c1c; -fx-border-width: 4; -fx-border-radius: 10"); - searchScrollPane.setStyle("-fx-border-color: d91c1c; -fx-border-width: 4; -fx-border-radius: 10"); - searchVBox.getChildren().addAll(searchTextField, searchScrollPane); - stackPane.getChildren().add(searchVBox); - } + TextField searchTextField = new TextField(); + searchTextField.setPromptText("Search for recipe"); + searchTextField.textProperty().addListener(e -> { + String input = searchTextField.getText(); + log.debug("Input in search field changed, searching through recipes with query '{}'.", input); + searchResults = recipeSearch.searchByQuery(recipeManager.getRecipes(), input); + drawRecipeSearchResults(date); + } + ); + searchScrollPane = new ScrollPane(); + searchTextField.setStyle("-fx-border-color: #d91c1c; -fx-border-width: 4; -fx-border-radius: 10"); + searchScrollPane.setStyle("-fx-border-color: #d91c1c; -fx-border-width: 4; -fx-border-radius: 10"); + searchVBox.getChildren().addAll(searchTextField, searchScrollPane); + stackPane.getChildren().add(searchVBox); + } private void drawRecipeSearchResults(LocalDate date) { log.debug("Drawing search results"); @@ -195,41 +172,7 @@ public class MealPlanController extends BaseController { @FXML public void clearMealPlan() { mealPlan.clear(); - displayMealPlan(); - } - - private void drawNutritionTable() { - log.debug("Drawing nutrition table for meal plan."); - final Map<Nutrition, BigDecimal> weeklyNutrition = mealPlan.getNutritionTable().getTable(); - //calculate percentage of weekly recommended dosage - double cals = weeklyNutrition.get(Nutrition.CALORIES).doubleValue() / (NutritionTable.CALORIES_DAILY * 7); - double carbs = weeklyNutrition.get(Nutrition.CARBS).doubleValue() / (NutritionTable.CARBS_DAILY * 7); - double fat = weeklyNutrition.get(Nutrition.FAT).doubleValue() / (NutritionTable.FAT_DAILY * 7); - double protein = weeklyNutrition.get(Nutrition.PROTEINS).doubleValue() / (NutritionTable.DAILY_PROTEIN * 7); - double fiber = weeklyNutrition.get(Nutrition.FIBERS).doubleValue() / (NutritionTable.DAILY_FIBER * 7); - double salt = weeklyNutrition.get(Nutrition.SALT).doubleValue() / (NutritionTable.DAILY_SALT * 7); - //update gui - setPercentage(caloriesProgressBar, caloriesPercentage, cals); - setPercentage(carbsProgressBar, carbsPercentage, carbs); - setPercentage(fatProgressbar, fatPercentage, fat); - setPercentage(proteinProgressBar, proteinPercentage, protein); - setPercentage(fibersProgressBar, fiberPercentage, fiber); - setPercentage(saltProgressBar, saltPercentage, salt); - } - - private void setPercentage(ProgressBar progressBar, Text textObject, double value) { - log.debug("Setting percentage for {}", textObject.getId()); - progressBar.setProgress(value); - textObject.setText(Math.round(value * 100) + "%"); - //set text color for percentages - if (value > 0.9) { - if (value > 1) { - textObject.setFill(Color.valueOf("#D91C1C")); //red - } - textObject.setFill(Color.valueOf("#ff8a0d")); //orange - } else { - textObject.setFill(Color.valueOf("#000000")); //default: black - } + render(); } /** @@ -237,6 +180,6 @@ public class MealPlanController extends BaseController { */ private void render() { displayMealPlan(); - drawNutritionTable(); + putNutritionTable(nutritionTableContainer, mealPlan.getNutritionTable(), "Check out the nutrition score for this week!"); } } diff --git a/src/main/java/mi/hdm/controllers/RecipeCreatorController.java b/src/main/java/mi/hdm/controllers/RecipeCreatorController.java index b09deb2..c808cb6 100644 --- a/src/main/java/mi/hdm/controllers/RecipeCreatorController.java +++ b/src/main/java/mi/hdm/controllers/RecipeCreatorController.java @@ -171,8 +171,8 @@ public class RecipeCreatorController extends BaseController { try { recipe = new Recipe(name, ingredients, description, preparation, categories, preparationTimeMins); recipeManager.addRecipe(recipe); - if (Files.exists(Paths.get(new URI(imagePathTextField.getText())))) { - recipe.setImage(new URL(imagePathTextField.getText())); + if (!imagePathString.isBlank() && Files.exists(Paths.get(new URI(imagePathString)))) { + recipe.setImage(new URL(imagePathString)); } log.info("Recipe '{}' was created.", name); changeScene(View.RECIPE_VIEW, recipe); @@ -188,7 +188,7 @@ public class RecipeCreatorController extends BaseController { a.setHeaderText("Image was not set"); a.setContentText("Invalid argument provided: The filepath to your image was not correct and the default image was loaded."); a.show(); - Recipe r = recipeManager.getRecipeByName(name).get(); //TODO: this is terrible! + Recipe r = recipeManager.getRecipeByName(name).get(); //TODO: fix me - this is terrible log.warn("Invalid image path '{}', loaded default image.", imagePathString); log.info("Recipe '{}' was created with default image.", name); changeScene(View.RECIPE_VIEW, r); diff --git a/src/main/java/mi/hdm/controllers/RecipeEditorController.java b/src/main/java/mi/hdm/controllers/RecipeEditorController.java index 0568280..4b624e0 100644 --- a/src/main/java/mi/hdm/controllers/RecipeEditorController.java +++ b/src/main/java/mi/hdm/controllers/RecipeEditorController.java @@ -2,7 +2,6 @@ package mi.hdm.controllers; import javafx.fxml.FXML; import javafx.scene.control.*; -import javafx.scene.image.ImageView; import javafx.scene.layout.FlowPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; @@ -10,8 +9,8 @@ import mi.hdm.components.CategoryCheckBox; import mi.hdm.components.CategoryPreviewLabel; import mi.hdm.components.IngredientSearchResultLabel; import mi.hdm.components.SelectedIngredientLabel; +import mi.hdm.exceptions.InvalidIngredientException; import mi.hdm.exceptions.InvalidRecipeException; -import mi.hdm.helpers.Validation; import mi.hdm.recipes.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -83,13 +82,9 @@ public class RecipeEditorController extends BaseController { searchResults = new ArrayList<>(); selectedIngredients = new ArrayList<>(); - ingredientManager.getIngredientsFromKeys(recipe.getIngredients()).forEach((i, amount) -> { - if (i instanceof Ingredient) { - selectedIngredients.add(i); - } else { - log.error("No ingredient with code {}", i.getUniqueCode()); - } - }); + recipe.getIngredients().forEach((code, amount) -> + selectedIngredients.add(componentFromCode(code)) + ); recipeSearch = new RecipeSearch(recipeManager, ingredientManager); selectedIngredientsVbox = new VBox(); selectedIngredientLabels = new ArrayList<>(); @@ -101,25 +96,26 @@ public class RecipeEditorController extends BaseController { displayRecipe(); ingredientSearch.textProperty().addListener(((e) -> searchIngredients())); //adds onChange listener to the search field selectedIngredientsScrollPane.setContent(selectedIngredientsVbox); - } private void displayRecipe() { nameTextField.setText(recipe.getName()); descriptionTextArea.setText(recipe.getDescription()); - recipe.getIngredients().forEach((k, v) -> { + //TODO: this is duplicate code (see around line 190) -> refactor into new method + recipe.getIngredients().forEach((code, amount) -> { HBox ingredientHBox = new HBox(); Button deleteIngredientButton = new Button("X"); - deleteIngredientButton.setStyle("-fx-text-fill: d91c1c;" + + SelectedIngredientLabel label = new SelectedIngredientLabel(ingredientManager.getIngredient(code).get(), amount); + selectedIngredientLabels.add(label); + deleteIngredientButton.setStyle("-fx-text-fill: #d91c1c;" + "-fx-font-size: 12;" + "-fx-background-size: small;"); deleteIngredientButton.setOnAction(h -> { - selectedIngredients.remove(ingredientManager.getIngredient(k)); - log.debug("User deleted ingredient '{}' from recipe.", ingredientManager.getIngredient(k).get().getName()); + RecipeComponent c = componentFromCode(code); + log.debug("User deleted ingredient '{}' from recipe.", c.getName()); + selectedIngredientLabels.remove(label); selectedIngredientsVbox.getChildren().remove(ingredientHBox); }); - SelectedIngredientLabel label = new SelectedIngredientLabel(ingredientManager.getIngredient(k).get(), v); - selectedIngredientLabels.add(label); ingredientHBox.getChildren().addAll(label, deleteIngredientButton); selectedIngredientsVbox.getChildren().add(ingredientHBox); }); @@ -184,18 +180,19 @@ public class RecipeEditorController extends BaseController { log.debug("User added ingredient '{}' to recipe.", result.getName()); if (!selectedIngredients.contains(result)) { selectedIngredients.add(result); + SelectedIngredientLabel label = new SelectedIngredientLabel(result); + selectedIngredientLabels.add(label); HBox ingredientHBox = new HBox(); Button deleteIngredientButton = new Button("X"); - deleteIngredientButton.setStyle("-fx-text-fill: d91c1c;" + + deleteIngredientButton.setStyle("-fx-text-fill: #d91c1c;" + "-fx-font-size: 12;" + "-fx-background-size: small;"); deleteIngredientButton.setOnAction(h -> { selectedIngredients.remove(result); + System.out.println(selectedIngredientLabels.remove(label)); log.debug("User deleted ingredient '{}' from recipe.", result.getName()); selectedIngredientsVbox.getChildren().remove(ingredientHBox); }); - SelectedIngredientLabel label = new SelectedIngredientLabel(result); - selectedIngredientLabels.add(label); ingredientHBox.getChildren().addAll(label, deleteIngredientButton); selectedIngredientsVbox.getChildren().add(ingredientHBox); } @@ -213,11 +210,10 @@ public class RecipeEditorController extends BaseController { recipe.setName(nameTextField.getText()); Map<RecipeComponent, Integer> ingredients = new HashMap<>(); selectedIngredientLabels.forEach(label -> { - ingredients.put(label.getComponent(), label.getAmount()); - }); - - - + System.out.println(label.getComponent().getName() + " : " + label.getAmount()); + ingredients.put(label.getComponent(), label.getAmount()); + } + ); try { recipe.setIngredientFromRecipeComponents(ingredients); @@ -273,4 +269,20 @@ public class RecipeEditorController extends BaseController { public void changeSceneToRecipe() { changeScene(View.RECIPE_VIEW, recipe); } + + private RecipeComponent componentFromCode(String code) { + RecipeComponent c; + switch (code.charAt(0)) { + case 'i' -> { + c = ingredientManager.getIngredient(code).get(); + selectedIngredients.remove(c); + } + case 'r' -> { + c = recipeManager.getRecipe(code).get(); + selectedIngredients.remove(c); + } + default -> throw new InvalidIngredientException("Recipe contained an invalid ingredient code: " + code); + } + return c; + } } diff --git a/src/main/java/mi/hdm/controllers/RecipeViewController.java b/src/main/java/mi/hdm/controllers/RecipeViewController.java index d20639b..4c6edfc 100644 --- a/src/main/java/mi/hdm/controllers/RecipeViewController.java +++ b/src/main/java/mi/hdm/controllers/RecipeViewController.java @@ -35,8 +35,6 @@ public class RecipeViewController extends BaseController { @FXML private HBox categoryHBox; - - public RecipeViewController(Recipe recipe, RecipeManager recipeManager, IngredientManager ingredientManager, CategoryManager categoryManager) { this.recipe = recipe; this.recipeManager = recipeManager; diff --git a/src/main/java/mi/hdm/controllers/ViewComponent.java b/src/main/java/mi/hdm/controllers/ViewComponent.java index e870e5e..f528ed3 100644 --- a/src/main/java/mi/hdm/controllers/ViewComponent.java +++ b/src/main/java/mi/hdm/controllers/ViewComponent.java @@ -5,33 +5,43 @@ import javafx.scene.Parent; import mi.hdm.GUIDriver; import mi.hdm.TastyPages; import mi.hdm.controllers.components.HeaderController; +import mi.hdm.controllers.components.NutritionTableController; +import mi.hdm.recipes.NutritionTable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; public enum ViewComponent { - HEADER("/fxml/components/header.fxml"); + HEADER("/fxml/components/header.fxml"), + NUTRITION_TABLE("/fxml/components/nutrition-table.fxml"); private static final Logger log = LogManager.getLogger(ViewComponent.class); private final String path; - private static final TastyPages app = GUIDriver.getModel(); + private static final TastyPages model = GUIDriver.getModel(); ViewComponent(String path) { this.path = path; } - public Parent getParentElement() throws IOException { + public Parent getParentElement(Object... args) throws IOException { log.info("Loading FXML for '{}' component from: {}", this, path); final FXMLLoader loader = new FXMLLoader(getClass().getResource(path)); log.debug("Successfully retrieved resource from {}", path); switch (this) { case HEADER -> loader.setControllerFactory((callback) -> - new HeaderController(app.getRecipeManager(), app.getIngredientManager()) + new HeaderController(model.getRecipeManager(), model.getIngredientManager()) ); + + case NUTRITION_TABLE -> { + if (args[0] instanceof NutritionTable n && args[1] instanceof String text) { + loader.setControllerFactory(callback -> new NutritionTableController(n, text)); + } else + throw new IOException("Provide arguments to load nutrition table: Nutrition table n, String text"); + } } log.debug("Set controller factory for view component {}", this); diff --git a/src/main/java/mi/hdm/mealPlan/MealPlan.java b/src/main/java/mi/hdm/mealPlan/MealPlan.java index 40bd1af..7f8cc38 100644 --- a/src/main/java/mi/hdm/mealPlan/MealPlan.java +++ b/src/main/java/mi/hdm/mealPlan/MealPlan.java @@ -10,7 +10,6 @@ import org.apache.logging.log4j.Logger; import java.time.LocalDate; import java.util.*; -import java.util.function.BiConsumer; /** * Allow the user to create a meal plan for the week. The user can check out his nutrition scores for the week. @@ -60,13 +59,13 @@ public class MealPlan { //TODO: delete before handing in because not used public void addRecipeToMealPlan(String recipeCode, LocalDate date) { - if (recipeCode == null || recipeManager.getRecipeByCode(recipeCode) == null) { + if (recipeCode == null || recipeManager.getRecipe(recipeCode).isEmpty()) { throw new NullPointerException("Your specified recipe code was null or invalid"); } if (!isDateValid(date)) { throw new InvalidMealPlanException("You can only add recipes between today and in 7 days from now!"); } - log.info("Added recipe {} to meal plan.", recipeManager.getRecipeByCode(recipeCode).getName()); + log.info("Added recipe {} to meal plan.", recipeManager.getRecipe(recipeCode).get().getName()); plan.put(date, recipeCode); } @@ -96,7 +95,7 @@ public class MealPlan { public Map<LocalDate, Recipe> getAllRecipesFromPlan() { Map<LocalDate, Recipe> result = new HashMap<>(); for (LocalDate d : plan.keySet()) { - result.put(d, recipeManager.getRecipeByCode(plan.get(d))); + result.put(d, recipeManager.getRecipe(plan.get(d)).get()); } return result; } diff --git a/src/main/java/mi/hdm/recipes/RecipeManager.java b/src/main/java/mi/hdm/recipes/RecipeManager.java index 5ca03bc..60a0a6b 100644 --- a/src/main/java/mi/hdm/recipes/RecipeManager.java +++ b/src/main/java/mi/hdm/recipes/RecipeManager.java @@ -34,8 +34,8 @@ public class RecipeManager { log.info("Recipe '{}' added successfully.", recipe.getName()); } - public Recipe getRecipeByCode(String code) { - return allRecipes.get(code); + public Optional<Recipe> getRecipe(String code) { + return Optional.ofNullable(allRecipes.get(code)); } public void deleteRecipe(String name) { diff --git a/src/main/java/mi/hdm/recipes/RecipeSearch.java b/src/main/java/mi/hdm/recipes/RecipeSearch.java index 346bce0..92a0434 100644 --- a/src/main/java/mi/hdm/recipes/RecipeSearch.java +++ b/src/main/java/mi/hdm/recipes/RecipeSearch.java @@ -48,7 +48,7 @@ public class RecipeSearch { Ingredient i = ingredientManager.getIngredient(key).orElseThrow(() -> new RuntimeException("This ingredient does not exist in ingredient manager")); if (i.getName().toLowerCase().contains(l) && !result.contains(r)) result.add(r); } else { - Recipe recipe = recipeManager.getRecipeByCode(key); + Recipe recipe = recipeManager.getRecipe(key).get(); if (recipe.getName().toLowerCase().contains(l)) result.add(recipe); } } diff --git a/src/main/java/mi/hdm/shoppingList/ShoppingList.java b/src/main/java/mi/hdm/shoppingList/ShoppingList.java index ddd37ac..762a562 100644 --- a/src/main/java/mi/hdm/shoppingList/ShoppingList.java +++ b/src/main/java/mi/hdm/shoppingList/ShoppingList.java @@ -60,7 +60,7 @@ public class ShoppingList { addToShoppingList(element); //adds recipes recursively (see below); comment next 2 lines out to avoid adding recipes recursively else - addAllToShoppingList(recipeManager.getRecipeByCode(element)); + addAllToShoppingList(recipeManager.getRecipe(element).get()); } ); } diff --git a/src/main/resources/fxml/Meal_Plan.fxml b/src/main/resources/fxml/Meal_Plan.fxml index 67dabac..38c4b61 100644 --- a/src/main/resources/fxml/Meal_Plan.fxml +++ b/src/main/resources/fxml/Meal_Plan.fxml @@ -1,11 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> -<?import javafx.geometry.*?> -<?import javafx.scene.control.*?> +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> <?import javafx.scene.layout.*?> -<?import javafx.scene.text.*?> -<AnchorPane fx:id="parent" prefHeight="700.0" prefWidth="960.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mi.hdm.controllers.MealPlanController"> - <StackPane fx:id="stackPane" prefHeight="150.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> +<?import javafx.scene.text.Font?> +<AnchorPane fx:id="parent" prefHeight="700.0" prefWidth="960.0" xmlns="http://javafx.com/javafx/17.0.2-ea" + xmlns:fx="http://javafx.com/fxml/1" fx:controller="mi.hdm.controllers.MealPlanController"> + <StackPane fx:id="stackPane" prefHeight="150.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" + AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <VBox alignment="TOP_RIGHT" prefHeight="445.0" prefWidth="872.0"> <GridPane hgap="8.0" prefHeight="57.0" prefWidth="842.0" vgap="8.0"> <columnConstraints> @@ -17,22 +20,24 @@ <RowConstraints minHeight="10.0" prefHeight="49.999996185302734" vgrow="SOMETIMES"/> </rowConstraints> <VBox.margin> - <Insets left="15.0" right="15.0" /> + <Insets left="15.0" right="15.0"/> </VBox.margin> - <Label alignment="TOP_CENTER" text="Meal Plan" textFill="#d91c1c" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="TOP"> + <Label alignment="TOP_CENTER" text="Meal Plan" textFill="#d91c1c" GridPane.columnIndex="1" + GridPane.halignment="CENTER" GridPane.valignment="TOP"> <font> - <Font name="Arial" size="34.0" /> + <Font name="Arial" size="34.0"/> </font> </Label> </GridPane> - <GridPane fx:id="mealPlanGrid" prefHeight="214.0" prefWidth="812.0" GridPane.columnIndex="1" GridPane.rowIndex="0"> + <GridPane fx:id="mealPlanGrid" prefHeight="214.0" prefWidth="812.0" GridPane.columnIndex="1" + GridPane.rowIndex="0"> <columnConstraints> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/> </columnConstraints> <rowConstraints> @@ -43,152 +48,16 @@ <Insets bottom="30.0" left="30.0" right="30.0" top="30.0"/> </VBox.margin> </GridPane> - <Button fx:id="clearButton" mnemonicParsing="false" onAction="#clearMealPlan" prefHeight="36.0" - prefWidth="170.0" - style="-fx-background-color: transparent; -fx-border-color: d91c1c; -fx-border-width: 4; -fx-border-radius: 5;" + <Button mnemonicParsing="false" onAction="#clearMealPlan" prefHeight="36.0" prefWidth="170.0" + style="-fx-background-color: transparent; -fx-border-color: #d91c1c; -fx-border-width: 4; -fx-border-radius: 5;" text="Clear Meal Plan" textFill="#d91c1c"> <font> <Font name="System Bold" size="13.0"/> </font> </Button> - <HBox prefHeight="100.0" prefWidth="200.0"> - <VBox prefHeight="346.0" prefWidth="945.0" spacing="15.0"> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="Nutrition"> - <font> - <Font name="Arial Bold" size="25.0"/> - </font> - </Text> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" - text="Check out your nutrition scores for this week's meal plan!"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - <!-- Nutrition table starts here --> - <VBox prefHeight="200" prefWidth="500" spacing="10.0"> - <HBox alignment="CENTER_LEFT" prefHeight="57.0" prefWidth="872.0" spacing="5.0"> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="Calories" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - <ProgressBar fx:id="caloriesProgressBar" prefHeight="24.0" prefWidth="631.0" progress="0.0" - style="-fx-background-color: #d9d9d9; -fx-background-radius: 5; -fx-control-inner-background: a; -fx-accent: #d91c1c;"> - <HBox.margin> - <Insets left="70.0"/> - </HBox.margin> - </ProgressBar> - <Text fx:id="caloriesPercentage" fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" - text="0%" wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="53.0" prefWidth="872.0" spacing="5.0"> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="Carbs" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - <ProgressBar fx:id="carbsProgressBar" prefHeight="24.0" prefWidth="631.0" progress="0.0" - style="-fx-background-color: #d9d9d9; -fx-control-inner-background: a; -fx-background-radius: 5; -fx-accent: #d91c1c;"> - <HBox.margin> - <Insets left="70.0"/> - </HBox.margin> - </ProgressBar> - <Text fx:id="carbsPercentage" fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" - text="0%" wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="57.0" prefWidth="872.0" spacing="5.0"> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="Fat" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - <ProgressBar fx:id="fatProgressbar" prefHeight="24.0" prefWidth="631.0" progress="0.0" - style="-fx-background-color: #d9d9d9; -fx-background-radius: 5; -fx-control-inner-background: a; -fx-accent: #d91c1c;"> - <HBox.margin> - <Insets left="70.0"/> - </HBox.margin> - </ProgressBar> - <Text fx:id="fatPercentage" fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="0%" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="53.0" prefWidth="872.0" spacing="5.0"> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="Protein" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - <ProgressBar fx:id="proteinProgressBar" prefHeight="24.0" prefWidth="631.0" progress="0.0" - style="-fx-background-color: #d9d9d9; -fx-control-inner-background: a; -fx-background-radius: 5; -fx-accent: #d91c1c;"> - <HBox.margin> - <Insets left="70.0"/> - </HBox.margin> - </ProgressBar> - <Text fx:id="proteinPercentage" fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" - text="0%" wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="53.0" prefWidth="872.0" spacing="5.0"> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="Fibers" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - <ProgressBar fx:id="fibersProgressBar" prefHeight="24.0" prefWidth="631.0" progress="0.0" - style="-fx-background-color: #d9d9d9; -fx-control-inner-background: a; -fx-background-radius: 5; -fx-accent: #d91c1c;"> - <HBox.margin> - <Insets left="70.0"/> - </HBox.margin> - </ProgressBar> - <Text fx:id="fiberPercentage" fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" - text="0%" wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="53.0" prefWidth="872.0" spacing="5.0"> - <Text fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="Salt" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - <ProgressBar fx:id="saltProgressBar" prefHeight="24.0" prefWidth="631.0" progress="0.0" - style="-fx-background-color:#d9d9d9; -fx-control-inner-background: a; -fx-background-radius: 5; -fx-accent: #d91c1c;"> - <HBox.margin> - <Insets left="70.0"/> - </HBox.margin> - </ProgressBar> - <Text fx:id="saltPercentage" fill="#1e1e1e" strokeType="OUTSIDE" strokeWidth="0.0" text="0%" - wrappingWidth="83.47006416320801"> - <font> - <Font name="Arial" size="17.0"/> - </font> - </Text> - </HBox> - </VBox> - </VBox> - </HBox> + <VBox prefHeight="346.0" prefWidth="945.0" spacing="15.0" fx:id="nutritionTableContainer"> + + </VBox> </VBox> </StackPane> <padding> diff --git a/src/main/resources/fxml/recipe-editor.fxml b/src/main/resources/fxml/recipe-editor.fxml index c7bda35..db40bbd 100644 --- a/src/main/resources/fxml/recipe-editor.fxml +++ b/src/main/resources/fxml/recipe-editor.fxml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> <?import javafx.geometry.*?> -<?import javafx.scene.*?> <?import javafx.scene.control.*?> -<?import javafx.scene.image.*?> +<?import javafx.scene.Cursor?> +<?import javafx.scene.image.Image?> +<?import javafx.scene.image.ImageView?> <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> - <AnchorPane prefHeight="800" prefWidth="1200.0" style="-fx-background-color: ffffff;" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mi.hdm.controllers.RecipeEditorController"> <padding> <Insets bottom="10.0" left="10.0" right="10.0" /> @@ -19,23 +19,30 @@ <padding> <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </padding> - <VBox prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: ffffff;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> - <Label text="Set path to recipe image" /> - <TextField fx:id="imagePathTextField" style="-fx-background-color: transparent; -fx-border-color: d91c1c; -fx-border-width: 4; -fx-border-radius: 5;"> - <VBox.margin> - <Insets top="5.0" /> - </VBox.margin></TextField> + <VBox prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: ffffff;" + AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" + AnchorPane.topAnchor="0.0"> + <Label text="Set path to recipe image"/> + <TextField fx:id="imagePathTextField" + style="-fx-background-color: transparent; -fx-border-color: d91c1c; -fx-border-width: 4; -fx-border-radius: 5;"> + <VBox.margin> + <Insets top="5.0"/> + </VBox.margin> + </TextField> <Label text="Select categories"> - <VBox.margin> - <Insets top="10.0" /> - </VBox.margin></Label> - <FlowPane fx:id="allCategories" hgap="5.0" prefHeight="129.0" prefWidth="566.0" style="-fx-background-color: transparent; -fx-background-radius: 5; -fx-border-color: D91C1C; -fx-border-radius: 5; -fx-border-width: 4;" vgap="5.0"> + <VBox.margin> + <Insets top="10.0"/> + </VBox.margin> + </Label> + <FlowPane fx:id="allCategories" hgap="5.0" prefHeight="129.0" prefWidth="566.0" + style="-fx-background-color: transparent; -fx-background-radius: 5; -fx-border-color: D91C1C; -fx-border-radius: 5; -fx-border-width: 4;" + vgap="5.0"> <padding> - <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> + <Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/> </padding> - <VBox.margin> - <Insets top="5.0" /> - </VBox.margin> + <VBox.margin> + <Insets top="5.0"/> + </VBox.margin> </FlowPane> <Separator prefWidth="200.0" /> <Label text="Search for ingredients"> @@ -104,37 +111,49 @@ <Insets bottom="5.0" /> </VBox.margin> </HBox> - <Label text="Preparation description" /> - <TextArea id="RecipeCreatorPreparationDescription" fx:id="preparationTextArea" prefHeight="104.0" prefWidth="566.0" promptText="How is your recipe prepared? Add new lines to separate instructions" style="-fx-border-color: D91C1C; -fx-border-radius: 5; -fx-border-width: 4; -fx-background-color: transparent;" stylesheets="@../styles/GUI_extras.css" wrapText="true"> + <Label text="Preparation description"/> + <TextArea id="RecipeCreatorPreparationDescription" fx:id="preparationTextArea" + prefHeight="104.0" prefWidth="566.0" + promptText="How is your recipe prepared? Add new lines to separate instructions" + style="-fx-border-color: D91C1C; -fx-border-radius: 5; -fx-border-width: 4; -fx-background-color: transparent;" + stylesheets="@../styles/GUI_extras.css" wrapText="true"> <VBox.margin> - <Insets bottom="5.0" /> + <Insets bottom="5.0"/> </VBox.margin> </TextArea> - <Label text="Ingredients" /> - <ScrollPane id="RecipeCreatorIngredients" fx:id="selectedIngredientsScrollPane" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: transparent; -fx-border-color: D91C1C; -fx-border-radius: 5; -fx-background-radius: 5; -fx-border-width: 4;" stylesheets="@../styles/GUI_extras.css" /> - <HBox prefHeight="100.0" prefWidth="200.0"> - <children> - <Button fx:id="cancelButton" mnemonicParsing="false" onAction="#changeSceneToRecipe" style="-fx-background-color: transparent; -fx-border-color: d91c1c; -fx-border-width: 4; -fx-border-radius: 5;" text="Cancel" textFill="#d91c1c"> - <font> - <Font name="System Bold" size="13.0" /> - </font> - <HBox.margin> - <Insets right="20.0" /> - </HBox.margin> - </Button> - <Button mnemonicParsing="false" onAction="#confirmEditRecipe" style="-fx-background-color: ffffff; -fx-control-inner-background: transparent; -fx-border-color: D91C1C; -fx-border-radius: 5; -fx-border-width: 4;" text="Save Recipe" textFill="#d91c1c"> - <font> - <Font name="System Bold" size="13.0" /> - </font> - <cursor> - <Cursor fx:constant="HAND" /> - </cursor> - </Button> - </children> - <padding> - <Insets left="100.0" /> - </padding> - </HBox> + <Label text="Ingredients"/> + <ScrollPane id="RecipeCreatorIngredients" fx:id="selectedIngredientsScrollPane" + prefHeight="200.0" prefWidth="200.0" + style="-fx-background-color: transparent; -fx-border-color: D91C1C; -fx-border-radius: 5; -fx-background-radius: 5; -fx-border-width: 4;" + stylesheets="@../styles/GUI_extras.css"/> + <HBox prefHeight="100.0" prefWidth="200.0"> + <children> + <Button fx:id="cancelButton" mnemonicParsing="false" onAction="#changeSceneToRecipe" + style="-fx-background-color: transparent; -fx-border-color: d91c1c; -fx-border-width: 4; -fx-border-radius: 5;" + text="Cancel" textFill="#d91c1c"> + <font> + <Font name="System Bold" size="13.0"/> + </font> + <HBox.margin> + <Insets right="20.0"/> + </HBox.margin> + </Button> + <Button accessibleText="Confirm the changes to your recipe" mnemonicParsing="false" + onAction="#confirmEditRecipe" + style="-fx-background-color: #ffffff; -fx-control-inner-background: transparent; -fx-border-color: D91C1C; -fx-border-radius: 5; -fx-border-width: 4;" + text="Save Recipe" textFill="#d91c1c"> + <font> + <Font name="System Bold" size="13.0"/> + </font> + <cursor> + <Cursor fx:constant="HAND"/> + </cursor> + </Button> + </children> + <padding> + <Insets left="100.0"/> + </padding> + </HBox> </VBox> </AnchorPane> </SplitPane> diff --git a/src/main/resources/fxml/recipe-view.fxml b/src/main/resources/fxml/recipe-view.fxml index 689c87a..511fe54 100644 --- a/src/main/resources/fxml/recipe-view.fxml +++ b/src/main/resources/fxml/recipe-view.fxml @@ -2,10 +2,9 @@ <?import javafx.geometry.*?> <?import javafx.scene.control.*?> -<?import javafx.scene.image.*?> +<?import javafx.scene.image.ImageView?> <?import javafx.scene.layout.*?> -<?import javafx.scene.text.*?> - +<?import javafx.scene.text.Font?> <AnchorPane fx:id="parent" prefHeight="540.0" prefWidth="872.0" style="-fx-background-color: ffffff;" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mi.hdm.controllers.RecipeViewController"> <children> <VBox layoutX="410.0" layoutY="1.0" prefHeight="539.0" prefWidth="872.0" style="-fx-background-color: ffffff;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> @@ -69,10 +68,12 @@ <Insets bottom="10.0" /> </VBox.margin> </GridPane> - <HBox fx:id="categoryHBox" prefHeight="50.0" prefWidth="393.0" style="-fx-background-color: transparent;"> - <VBox.margin> - <Insets bottom="10.0" top="10.0" /> - </VBox.margin></HBox> + <HBox fx:id="categoryHBox" prefHeight="50.0" prefWidth="393.0" spacing="10.0" + style="-fx-background-color: transparent;"> + <VBox.margin> + <Insets bottom="10.0" top="10.0"/> + </VBox.margin> + </HBox> <ScrollPane fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" prefHeight="300.0" prefWidth="393.0" style="-fx-border-color: D91C1C; -fx-border-width: 4; -fx-border-radius: 10; -fx-background-color: transparent;" stylesheets="@../styles/GUI_extras.css"> <content> <Label fx:id="recipePreparation" alignment="TOP_LEFT" contentDisplay="CENTER" lineSpacing="1.5" prefHeight="303.0" prefWidth="383.0" style="-fx-background-color: transparent;" text="Recipe Preparation" wrapText="true"> -- GitLab