Merge branch 'client/feature-recipe-scaling' into 'main'
feat(client/scaling): Implements client-side recipe scaling Closes #70 See merge request cse1105/2025-2026/teams/csep-team-76!70
This commit is contained in:
commit
83910eca72
4 changed files with 96 additions and 5 deletions
|
|
@ -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<Long, Recipe> webSocketDataService;
|
||||
|
||||
public Spinner<Double> 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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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> recipe = new SimpleObjectProperty<>();
|
||||
private final ObjectProperty<Recipe> scaled = new SimpleObjectProperty<>();
|
||||
private final DoubleProperty scale = new SimpleDoubleProperty();
|
||||
public ScalableRecipeView(
|
||||
Recipe recipe,
|
||||
Double scale
|
||||
) {
|
||||
this.recipe.set(recipe);
|
||||
this.scale.set(scale);
|
||||
ObjectBinding<Recipe> 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<Recipe> scaledProperty() {
|
||||
return scaled;
|
||||
}
|
||||
|
||||
public ObjectProperty<Recipe> recipeProperty() {
|
||||
return recipe;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
<Button fx:id="removeRecipeButton" mnemonicParsing="false" onAction="#removeSelectedRecipe" text="Remove Recipe" />
|
||||
<Button fx:id="printRecipeButton" mnemonicParsing="false" onAction="#printRecipe" text="Print Recipe" />
|
||||
<Button fx:id="favouriteButton" onAction="#toggleFavourite" text="☆" />
|
||||
<Label>Scale: </Label>
|
||||
<Spinner fx:id="scaleSpinner" />
|
||||
</HBox>
|
||||
|
||||
<ComboBox fx:id="langSelector" onAction="#changeLanguage" />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue