diff --git a/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java b/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java index 3789745..d072669 100644 --- a/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java +++ b/client/src/main/java/client/scenes/recipe/RecipeDetailCtrl.java @@ -20,11 +20,13 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import javafx.fxml.FXML; import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ListView; +import javafx.scene.control.Spinner; +import javafx.scene.control.SpinnerValueFactory; import javafx.scene.control.TextField; import javafx.scene.control.TextInputDialog; -import javafx.scene.control.ComboBox; import javafx.scene.input.KeyCode; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; @@ -43,6 +45,8 @@ public class RecipeDetailCtrl implements LocaleAware { private final ConfigService configService; private final WebSocketDataService webSocketDataService; + public Spinner scaleSpinner; + @FXML private IngredientListCtrl ingredientListController; @@ -50,6 +54,7 @@ public class RecipeDetailCtrl implements LocaleAware { private RecipeStepListCtrl stepListController; private Recipe recipe; + private ScalableRecipeView recipeView; @Inject public RecipeDetailCtrl( @@ -143,12 +148,26 @@ public class RecipeDetailCtrl implements LocaleAware { } this.recipe = recipe; - this.showName(recipe.getName()); - this.ingredientListController.refetchFromRecipe(recipe); - this.stepListController.refetchFromRecipe(recipe); this.langSelector.setValue(recipe.getLocale()); this.refreshFavouriteButton(); + + // If there is a scale + // Prevents issues from first startup + if (scaleSpinner.getValue() != null) { + Double scale = scaleSpinner.getValue(); + + // see impl. creates a scaled context for the recipe such that its non-scaled value is kept as a reference. + this.recipeView = new ScalableRecipeView(recipe, scale); + + // expose the scaled view to list controllers + this.ingredientListController.refetchFromRecipe(this.recipeView.getScaled()); + this.stepListController.refetchFromRecipe(this.recipeView.getScaled()); + return; + } + + this.ingredientListController.refetchFromRecipe(recipe); + this.stepListController.refetchFromRecipe(recipe); } /** @@ -170,6 +189,8 @@ public class RecipeDetailCtrl implements LocaleAware { recipeConsumer.accept(selectedRecipe, recipes); try { // propagate changes to server + // NOTE Scale does not impact the server update (per backlog req.) as the scaled reference is held in + // the scaled view which is only exposed to lists. server.updateRecipe(selectedRecipe); webSocketDataService.add(selectedRecipe.getId(), recipe -> { int idx = getParentRecipeList().getItems().indexOf(selectedRecipe); @@ -364,7 +385,16 @@ public class RecipeDetailCtrl implements LocaleAware { @Override public void initializeComponents() { initStepsIngredientsList(); - + // creates a new scale spinner with an arbitrary max scale + scaleSpinner.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0, Double.MAX_VALUE, 1)); + scaleSpinner.setEditable(true); + scaleSpinner.valueProperty().addListener((observable, oldValue, newValue) -> { + if (newValue == null) { + return; + } + // triggers a UI update each time the spinner changes to a different value. + setCurrentlyViewedRecipe(recipe); + }); langSelector.getItems().addAll("en", "nl", "pl", "tok"); } } diff --git a/client/src/main/java/client/scenes/recipe/ScalableRecipeView.java b/client/src/main/java/client/scenes/recipe/ScalableRecipeView.java new file mode 100644 index 0000000..db5de91 --- /dev/null +++ b/client/src/main/java/client/scenes/recipe/ScalableRecipeView.java @@ -0,0 +1,50 @@ +package client.scenes.recipe; + +import commons.Recipe; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.ObjectBinding; +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleObjectProperty; + +public class ScalableRecipeView { + private final ObjectProperty recipe = new SimpleObjectProperty<>(); + private final ObjectProperty scaled = new SimpleObjectProperty<>(); + private final DoubleProperty scale = new SimpleDoubleProperty(); + public ScalableRecipeView( + Recipe recipe, + Double scale + ) { + this.recipe.set(recipe); + this.scale.set(scale); + ObjectBinding binding = Bindings.createObjectBinding( + () -> Recipe.getScaled(this.recipe.get(), this.scale.get()), + this.recipe, this.scale); + this.scaled.bind(binding); + } + + public double getScale() { + return scale.get(); + } + + public Recipe getRecipe() { + return recipe.get(); + } + + public Recipe getScaled() { + return scaled.get(); + } + + public DoubleProperty scaleProperty() { + return scale; + } + + public ObjectProperty scaledProperty() { + return scaled; + } + + public ObjectProperty recipeProperty() { + return recipe; + } +} diff --git a/client/src/main/resources/client/scenes/recipe/RecipeDetailView.fxml b/client/src/main/resources/client/scenes/recipe/RecipeDetailView.fxml index dd5f2ba..127274c 100644 --- a/client/src/main/resources/client/scenes/recipe/RecipeDetailView.fxml +++ b/client/src/main/resources/client/scenes/recipe/RecipeDetailView.fxml @@ -25,6 +25,8 @@