diff --git a/src/main/java/mi/hdm/TastyPages.java b/src/main/java/mi/hdm/TastyPages.java index c99697c14737e0459257bb92beb47ab8293e0632..c4ad84858295fa55fe553cc78019a6155fc9a85c 100644 --- a/src/main/java/mi/hdm/TastyPages.java +++ b/src/main/java/mi/hdm/TastyPages.java @@ -5,17 +5,23 @@ import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import mi.hdm.controllers.View; +import mi.hdm.mealPlan.MealPlan; import mi.hdm.recipes.*; +import mi.hdm.shoppingList.ShoppingList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; +import java.util.HashMap; import java.util.List; import java.util.Map; public class TastyPages extends Application { //TODO: instantiate all dependencies HERE! The getScene() method from View.java should go here as well for dependency injection public final static RecipeManager recipeManager = new RecipeManager(); + public final static ShoppingList shoppingList = new ShoppingList(); + public final static CategoryManager categoryManager = new CategoryManager(List.of(new Category("Mittagessen", 0xFF0000), new Category("mjam", 0x00FF00))); + public final static MealPlan mealPlan = new MealPlan(new HashMap<>()); private final static Logger log = LogManager.getLogger(TastyPages.class); @@ -24,8 +30,8 @@ public class TastyPages extends Application { public static void main(String[] args) { log.info("Starting TastyPages"); - recipeManager.addRecipe(new Recipe("Mein erstes Rezept", Map.of(new Ingredient(Measurement.GRAM, "Mehl", new NutritionTable(100, 20, 8, 14, 2.5, 3)), 100), "Description", List.of("joa"), List.of(), 40)); - recipeManager.addRecipe(new Recipe("Mein letztes Rezept", Map.of(new Ingredient(Measurement.GRAM, "Zucker", new NutritionTable(100, 500, 8, 14, 2.5, 3)), 100), "Description", List.of("joa"), List.of(), 40)); + recipeManager.addRecipe(new Recipe("Mein erstes Rezept", Map.of(new Ingredient(Measurement.GRAM, "Mehl", new NutritionTable(100, 20, 8, 14, 2.5, 3)), 100), "Description", List.of("joa"), List.of(categoryManager.getAllCategories().get(1)), 40)); + recipeManager.addRecipe(new Recipe("Mein letztes Rezept", Map.of(new Ingredient(Measurement.GRAM, "Zucker", new NutritionTable(100, 500, 8, 14, 2.5, 3)), 100), "Description", List.of("joa"), List.of(categoryManager.getAllCategories().get(0)), 40)); launch(args); } diff --git a/src/main/java/mi/hdm/controllers/MainPageController.java b/src/main/java/mi/hdm/controllers/MainPageController.java index 6e43b0405c355594aef18b7f8cc160d5fed531fe..5aefb1c5e1124382761631cac92c33ae8931d865 100644 --- a/src/main/java/mi/hdm/controllers/MainPageController.java +++ b/src/main/java/mi/hdm/controllers/MainPageController.java @@ -1,25 +1,32 @@ package mi.hdm.controllers; import javafx.fxml.FXML; +import javafx.scene.Node; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.TilePane; import javafx.scene.layout.VBox; -import mi.hdm.recipes.Category; -import mi.hdm.recipes.CategoryManager; -import mi.hdm.recipes.Recipe; -import mi.hdm.recipes.RecipeManager; +import mi.hdm.recipes.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class MainPageController extends BaseController { private final static Logger log = LogManager.getLogger(MainPageController.class); private final RecipeManager recipeManager; private final CategoryManager categoryManager; + private Map<Category, CheckBox> categoryToCheckbox = new HashMap<>(); + private final List<VBox> currentRecipesInGUI = new ArrayList<>(); //keeps track of all Nodes in the GUI that represent a recipe + private List<Category> currentlySelectedCategories = new ArrayList<>(); + @FXML private AnchorPane parent; @FXML @@ -35,7 +42,7 @@ public class MainPageController extends BaseController { @FXML public void initialize() { loadHeader(parent); - mapRecipes(); + mapRecipes(recipeManager.getRecipes()); mapCategories(); log.debug("Added {} recipes to GUI", recipeManager.getRecipes().size()); } @@ -45,11 +52,30 @@ public class MainPageController extends BaseController { log.info("User is trying to add recipe!"); } - private void mapRecipes() { - for (Recipe recipe : recipeManager.getRecipes()) { + private void mapRecipes(List<Recipe> recipes) { + //TODO: every recipe tile needs an event listener + recipeTilePane.getChildren().removeAll(currentRecipesInGUI); + currentRecipesInGUI.clear(); + for (Recipe recipe : recipes) { Label recipeName = new Label(recipe.getName()); Label recipeDescription = new Label(recipe.getDescription()); - VBox currentRecipeBox = new VBox(recipeName, recipeDescription); + List<Label> categoryLabels = new ArrayList<>(); + + //add a maximum of 3 categories to the recipe tile + for (int i = 0; i < Math.min(recipe.getCategories().size(), 3); i++) { + Category c = recipe.getCategories().get(i); + Label l = new Label(c.getName()); + //TODO: make border radius work on the styling + l.setStyle("-fx-background-color: " + c.getColourCode() + ";" + + "-fx-padding: 3px;" + + "-fx-border-radius: 5px;" + ); + categoryLabels.add(l); + } + HBox categories = new HBox(); + categories.getChildren().addAll(categoryLabels); + + VBox currentRecipeBox = new VBox(recipeName, recipeDescription, categories); //TODO: make this recipe box a component class recipeName.setStyle( @@ -66,17 +92,37 @@ public class MainPageController extends BaseController { "-fx-border-width: 2;" + "-fx-padding: 8" ); - - recipeTilePane.getChildren().add(currentRecipeBox); + currentRecipesInGUI.add(currentRecipeBox); } + recipeTilePane.getChildren().addAll(currentRecipesInGUI); } private void mapCategories() { for (final Category category : categoryManager.getAllCategories()) { CheckBox categoryCheckBox = new CheckBox(category.getName()); - categoryCheckBox.setStyle("-fx-background-color: " + category.getColourCode()); + categoryCheckBox.setStyle("-fx-background-color:" + category.getColourCode() + ";" + "-fx-padding: 4px;"); + categoryCheckBox.setOnAction(event -> updateRecipes()); + + categoryToCheckbox.put(category, categoryCheckBox); categories.getChildren().add(categoryCheckBox); } } + + private void updateRecipes() { + mapRecipes(fetchSelectedRecipes()); + } + + private List<Recipe> fetchSelectedRecipes() { + currentlySelectedCategories = categoryToCheckbox.keySet() + .stream().filter(category -> + categoryToCheckbox.get(category).isSelected()) + .toList(); + RecipeSearch recipeSearch = new RecipeSearch(recipeManager.getRecipes()); + return recipeSearch.searchByCategory(currentlySelectedCategories); + } +} + +class RecipeTile extends Node { + } diff --git a/src/main/java/mi/hdm/controllers/RecipeViewController.java b/src/main/java/mi/hdm/controllers/RecipeViewController.java index c698d660ca9770edc1a5ffadb69b214051f8c2dd..5012e3563356694d36a2e17088040d014861257b 100644 --- a/src/main/java/mi/hdm/controllers/RecipeViewController.java +++ b/src/main/java/mi/hdm/controllers/RecipeViewController.java @@ -1,11 +1,8 @@ package mi.hdm.controllers; import javafx.fxml.FXML; -import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.TilePane; -import javafx.scene.layout.VBox; -import mi.hdm.recipes.Recipe; import mi.hdm.recipes.RecipeManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -37,33 +34,6 @@ public class RecipeViewController extends BaseController { @FXML public void initialize() { loadHeader(parent); - mapRecipes(); log.debug("Added {} recipes to GUI", recipeManager.getRecipes().size()); } - - private void mapRecipes() { - for (Recipe recipe : recipeManager.getRecipes()) { - Label recipeName = new Label(recipe.getName()); - Label recipeDescription = new Label(recipe.getDescription()); - VBox currentRecipeBox = new VBox(recipeName, recipeDescription); - - //TODO: make this recipe box a component class - recipeName.setStyle( - "-fx-font-weight: 800;" + - "-fx-font-scale: 16" - ); - - currentRecipeBox.setPrefWidth(180); - currentRecipeBox.setPrefHeight(250); - currentRecipeBox.setStyle( - "-fx-background-color: #DEDEDE;" + - "-fx-border-color: #D91C1C;" + - "-fx-border-radius: 8;" + - "-fx-border-width: 2;" + - "-fx-padding: 8" - ); - - recipeTilePane.getChildren().add(currentRecipeBox); - } - } } diff --git a/src/main/java/mi/hdm/controllers/View.java b/src/main/java/mi/hdm/controllers/View.java index 4351e9273726ece1c4a2ec101cc3dfd09d546860..fe0283bbd6d3c1477b98dd95390455b38d22fa9b 100644 --- a/src/main/java/mi/hdm/controllers/View.java +++ b/src/main/java/mi/hdm/controllers/View.java @@ -4,7 +4,6 @@ import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import mi.hdm.TastyPages; import mi.hdm.mealPlan.MealPlan; -import mi.hdm.recipes.Category; import mi.hdm.recipes.CategoryManager; import mi.hdm.recipes.RecipeManager; import mi.hdm.shoppingList.ShoppingList; @@ -12,8 +11,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; -import java.util.HashMap; -import java.util.List; public enum View { MAIN("/fxml/Tasty_Pages_Main_Page.fxml", "Tasty Pages"), @@ -24,9 +21,9 @@ public enum View { private static final Logger log = LogManager.getLogger(View.class); private final RecipeManager recipeManager = TastyPages.recipeManager; - private final ShoppingList shoppingList = new ShoppingList(); - private final MealPlan mealPlan = new MealPlan(new HashMap<>()); - private final CategoryManager categoryManager = new CategoryManager(List.of(new Category("Mittagessen", 0xFF0000), new Category("mjam", 0x00FF00))); + private final ShoppingList shoppingList = TastyPages.shoppingList; + private final MealPlan mealPlan = TastyPages.mealPlan; + private final CategoryManager categoryManager = TastyPages.categoryManager; private final String path; private final String windowTitle; diff --git a/src/main/java/mi/hdm/mealPlan/MealPlan.java b/src/main/java/mi/hdm/mealPlan/MealPlan.java index 5db9f3c7ca5ebf03031d24df54e3fa31c3c6638b..ef6f68712568be1b04d1ad27315960966d55707e 100644 --- a/src/main/java/mi/hdm/mealPlan/MealPlan.java +++ b/src/main/java/mi/hdm/mealPlan/MealPlan.java @@ -8,9 +8,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.time.LocalDate; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; +import java.util.*; /** * Allow the user to create a meal plan for the week. The user can check out his nutrition scores for the week. @@ -32,7 +30,6 @@ public class MealPlan { if (date == null) { throw new NullPointerException("Date can not be null"); } - if (!isDateValid(date)) { throw new InvalidMealPlanException("You can only add recipes between today and in 7 days from now!"); } @@ -67,9 +64,12 @@ public class MealPlan { public void removePastRecipes() { final LocalDate now = LocalDate.now(); + List<LocalDate> toRemove = new ArrayList<>(); for (LocalDate d : plan.keySet()) { - if (d.isBefore(now)) plan.remove(d); + if (d.isBefore(now)) toRemove.add(d); } + toRemove.forEach(plan::remove); + log.info("Removed {} recipes", toRemove.size()); } public NutritionTable getNutritionTable() { diff --git a/src/main/java/mi/hdm/recipes/Category.java b/src/main/java/mi/hdm/recipes/Category.java index d66b3712c1b233c8566f755e9dc2189be234310e..70895d44769d7164c9518ffaffdd2788afd83115 100644 --- a/src/main/java/mi/hdm/recipes/Category.java +++ b/src/main/java/mi/hdm/recipes/Category.java @@ -4,8 +4,9 @@ import mi.hdm.exceptions.InvalidCategoryException; public class Category { + //TODO: color code should be saved as a string private final String name; - private final int colourCode; //0x für Hexzahlen + private final String colourCode; //0x für Hexzahlen public Category (String name, int colourCode) { @@ -16,11 +17,11 @@ public class Category { throw new InvalidCategoryException("Can not add category with color code " + colourCode); } this.name = name; - this.colourCode = colourCode; + this.colourCode = CategoryManager.numberToColorCodeString(colourCode); } - public int getColourCode() { + public String getColourCode() { return colourCode; } @@ -31,14 +32,14 @@ public class Category { @Override public boolean equals(Object o){ if (o instanceof Category c) { - return this.name.equals(c.getName()) && this.colourCode == c.getColourCode(); + return this.name.equals(c.getName()) && this.colourCode.equals(c.getColourCode()); } return false; } @Override public String toString() { - return String.format("Category %s with color code %d", name, colourCode); + return String.format("Category %s with color code %s", name, colourCode); } } diff --git a/src/main/java/mi/hdm/recipes/CategoryManager.java b/src/main/java/mi/hdm/recipes/CategoryManager.java index 326c6abe2bfdfea7d8f76e03f1de300e653e6a8c..63fa28b604591ecd9241d0577ce6376ede848a46 100644 --- a/src/main/java/mi/hdm/recipes/CategoryManager.java +++ b/src/main/java/mi/hdm/recipes/CategoryManager.java @@ -41,7 +41,7 @@ public class CategoryManager { public void deleteCategory(Category c) { log.info("Category {} deleted successfully.", c.getName()); - if (allCategories.remove(c) == false) { + if (!allCategories.remove(c)) { throw new InvalidCategoryException("Category is not listed."); } } @@ -68,7 +68,13 @@ public class CategoryManager { private Optional<Category> getCategoryByCode(int colourCode) { return allCategories.stream() - .filter(c -> c.getColourCode() == colourCode) + .filter(c -> c.getColourCode().equals(numberToColorCodeString(colourCode))) .findFirst(); } + + public static String numberToColorCodeString(int colourCode) { + String intToHex = Integer.toHexString(colourCode); + intToHex = intToHex.indent(6 - intToHex.length()).replace(" ", "0"); + return String.format("#%s", intToHex); + } } diff --git a/src/main/resources/fxml/Tasty_Pages_Main_Page.fxml b/src/main/resources/fxml/Tasty_Pages_Main_Page.fxml index f0c8ee03fa2f4a8789e4aec29820d9b54a6a3bc8..23dbf0c4d704ff81239d24fd94d1d3c77a87d903 100644 --- a/src/main/resources/fxml/Tasty_Pages_Main_Page.fxml +++ b/src/main/resources/fxml/Tasty_Pages_Main_Page.fxml @@ -9,25 +9,35 @@ <AnchorPane fx:id="parent" prefHeight="400.0" prefWidth="640.0" VBox.vgrow="ALWAYS" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mi.hdm.controllers.MainPageController"> - <HBox fx:id="categories" AnchorPane.rightAnchor="0.0" AnchorPane.leftAnchor="0.0"/> - <TilePane fx:id="recipeTilePane" prefHeight="400.0" prefTileHeight="250.0" prefTileWidth="180.0" - prefWidth="640.0" vgap="8.0" hgap="8.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" - AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0"> - <Pane prefHeight="250.0" prefWidth="180.0" style="-fx-background-color: dedede; -fx-background-radius: 15;"> - <Button contentDisplay="CENTER" mnemonicParsing="false" onAction="#addRecipe" prefHeight="250.0" - prefWidth="180.0" style="-fx-background-color: transparent;" text="Button" textFill="TRANSPARENT"> - <graphic> - <ImageView fitHeight="67.0" fitWidth="64.0" pickOnBounds="true" preserveRatio="true"> - <Image url="@../images/Tasty_Pages_Plus_Icon.png"/> - </ImageView> - </graphic> - <cursor> - <Cursor fx:constant="HAND"/> - </cursor> - </Button> - </Pane> - <padding> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> - </padding> - </TilePane> + <VBox prefHeight="400.0" prefWidth="640.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" + AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0"> + <children> + <HBox fx:id="categories" prefWidth="640.0" spacing="8.0"> + <padding> + <Insets bottom="8.0" left="8.0" right="8.0" top="8.0"/> + </padding> + </HBox> + <TilePane fx:id="recipeTilePane" hgap="8.0" prefHeight="400.0" prefTileHeight="250.0" prefTileWidth="180.0" + prefWidth="640.0" vgap="8.0"> + <Pane prefHeight="250.0" prefWidth="180.0" + style="-fx-background-color: dedede; -fx-background-radius: 15;"> + <Button contentDisplay="CENTER" mnemonicParsing="false" onAction="#addRecipe" prefHeight="250.0" + prefWidth="180.0" style="-fx-background-color: transparent;" text="Button" + textFill="TRANSPARENT"> + <graphic> + <ImageView fitHeight="67.0" fitWidth="64.0" pickOnBounds="true" preserveRatio="true"> + <Image url="@../images/Tasty_Pages_Plus_Icon.png"/> + </ImageView> + </graphic> + <cursor> + <Cursor fx:constant="HAND"/> + </cursor> + </Button> + </Pane> + <padding> + <Insets bottom="8.0" left="8.0" right="8.0" top="8.0"/> + </padding> + </TilePane> + </children> + </VBox> </AnchorPane>