feat(client/ingredients): make into dropdown
It is now possible to see a list of existing ingredients to choose from in a dropdown menu. Adds a server dependency to the ingredient list cell. Not ideal but could be revamped in the future.
This commit is contained in:
parent
7320dd1e46
commit
f87b4e7d37
2 changed files with 94 additions and 11 deletions
|
|
@ -1,17 +1,28 @@
|
|||
package client.scenes.recipe;
|
||||
|
||||
import client.utils.ServerUtils;
|
||||
import com.google.inject.Inject;
|
||||
import commons.FormalIngredient;
|
||||
import commons.Ingredient;
|
||||
import commons.RecipeIngredient;
|
||||
import commons.Unit;
|
||||
import commons.VagueIngredient;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.MenuButton;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.SeparatorMenuItem;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -22,6 +33,13 @@ import java.util.Optional;
|
|||
* @see IngredientListCtrl
|
||||
*/
|
||||
public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient> {
|
||||
private final ServerUtils server;
|
||||
private final Logger logger = Logger.getLogger(IngredientListCell.class.getName());
|
||||
private final SimpleObjectProperty<Ingredient> selectedIngredient = new SimpleObjectProperty<>();
|
||||
@Inject
|
||||
public IngredientListCell(ServerUtils server) {
|
||||
this.server = server;
|
||||
}
|
||||
@Override
|
||||
public void commitEdit(RecipeIngredient newValue) {
|
||||
super.commitEdit(newValue);
|
||||
|
|
@ -64,29 +82,89 @@ public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient
|
|||
this.setText(null);
|
||||
this.setGraphic(container);
|
||||
}
|
||||
private <T> void makeMenuItems(
|
||||
MenuButton menu,
|
||||
Iterable<T> items,
|
||||
Function<T, String> labelMapper,
|
||||
Consumer<T> onSelect,
|
||||
HBox container) {
|
||||
MenuItem newIngredientItem = new MenuItem();
|
||||
newIngredientItem.setText("Something new...");
|
||||
newIngredientItem.setOnAction(_ -> {
|
||||
menu.setText("New Ingredient");
|
||||
selectedIngredient.setValue(null);
|
||||
logger.info("Making new ingredient");
|
||||
// TODO printError() integration
|
||||
TextField newIngredientNameInput = makeNewIngredientNameField(selectedIngredient::set);
|
||||
container.getChildren().add(newIngredientNameInput);
|
||||
});
|
||||
menu.getItems().addAll(newIngredientItem, new SeparatorMenuItem());
|
||||
for (T item : items) {
|
||||
MenuItem mi = new MenuItem();
|
||||
mi.setText(labelMapper.apply(item));
|
||||
mi.setOnAction(_ -> {
|
||||
menu.setText(labelMapper.apply(item));
|
||||
onSelect.accept(item);
|
||||
});
|
||||
menu.getItems().add(mi);
|
||||
}
|
||||
}
|
||||
private HBox makeInputLine(RecipeIngredient ingredient, TextField amountInput, ChoiceBox<Unit> unitChoice) {
|
||||
TextField nameInput = new TextField(ingredient.ingredient.name);
|
||||
HBox container = new HBox(amountInput, unitChoice, nameInput);
|
||||
MenuButton ingredientSelect = new MenuButton("Select your ingredient");
|
||||
HBox container = new HBox(amountInput, unitChoice, ingredientSelect);
|
||||
try {
|
||||
makeMenuItems(ingredientSelect, server.getIngredients(), Ingredient::getName, i -> {
|
||||
selectedIngredient.set(i);
|
||||
logger.info("Selected ingredient: " + i);
|
||||
}, container);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
logger.severe("Exception while making ingredient selection");
|
||||
}
|
||||
container.setOnKeyReleased(event -> {
|
||||
if (event.getCode() != KeyCode.ENTER) {
|
||||
return;
|
||||
}
|
||||
Unit unit = unitChoice.getValue();
|
||||
String name = nameInput.getText();
|
||||
if (unit == null || !unit.isFormal()) {
|
||||
String desc = amountInput.getText();
|
||||
if (desc.isEmpty() || name.isEmpty()) {
|
||||
// TODO printError() integration
|
||||
Ingredient i = selectedIngredient.getValue();
|
||||
if (i == null) {
|
||||
|
||||
|
||||
return; // The user is forced to kindly try again until something valid comes up.
|
||||
}
|
||||
Ingredient newIngredient = new Ingredient(name, 0., 0., 0.);
|
||||
commitEdit(new VagueIngredient(newIngredient, desc));
|
||||
if (unit == null || !unit.isFormal()) {
|
||||
String desc = amountInput.getText();
|
||||
if (desc.isEmpty()) {
|
||||
logger.warning("Invalid description");
|
||||
return; // The user is forced to kindly try again until something valid comes up.
|
||||
}
|
||||
commitEdit(new VagueIngredient(i, desc));
|
||||
return;
|
||||
}
|
||||
double amount = Double.parseDouble(amountInput.getText());
|
||||
Ingredient newIngredient = new Ingredient(name, 0., 0., 0.);
|
||||
commitEdit(new FormalIngredient(newIngredient, amount, unit.suffix));
|
||||
commitEdit(new FormalIngredient(i, amount, unit.suffix));
|
||||
});
|
||||
return container;
|
||||
}
|
||||
|
||||
private @NonNull TextField makeNewIngredientNameField(Consumer<Ingredient> onSubmit) {
|
||||
TextField newIngredientNameInput = new TextField("New ingredient...");
|
||||
newIngredientNameInput.setOnKeyReleased(e -> {
|
||||
if (e.getCode() != KeyCode.ENTER) {
|
||||
return;
|
||||
}
|
||||
String newIngredientName = newIngredientNameInput.getText();
|
||||
if (newIngredientName.isEmpty()) {
|
||||
// printerr
|
||||
logger.warning("invalid name received!");
|
||||
return;
|
||||
}
|
||||
Ingredient newIngredient = new Ingredient(
|
||||
newIngredientName,
|
||||
0.,
|
||||
0.,
|
||||
0.);
|
||||
onSubmit.accept(newIngredient);
|
||||
});
|
||||
return newIngredientNameInput;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package client.scenes.recipe;
|
|||
import client.utils.DefaultValueFactory;
|
||||
import client.utils.LocaleAware;
|
||||
import client.utils.LocaleManager;
|
||||
import client.utils.ServerUtils;
|
||||
import com.google.inject.Inject;
|
||||
import commons.FormalIngredient;
|
||||
import commons.Recipe;
|
||||
|
|
@ -28,8 +29,12 @@ import javafx.scene.control.ListView.EditEvent;
|
|||
*/
|
||||
public class IngredientListCtrl implements LocaleAware {
|
||||
private final LocaleManager localeManager;
|
||||
private final ServerUtils server;
|
||||
@Inject
|
||||
public IngredientListCtrl(LocaleManager localeManager) {
|
||||
public IngredientListCtrl(
|
||||
ServerUtils server,
|
||||
LocaleManager localeManager) {
|
||||
this.server = server;
|
||||
this.localeManager = localeManager;
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +166,7 @@ public class IngredientListCtrl implements LocaleAware {
|
|||
this.ingredientListView.setEditable(true);
|
||||
this.ingredientListView.setCellFactory(
|
||||
list -> {
|
||||
return new IngredientListCell();
|
||||
return new IngredientListCell(this.server);
|
||||
});
|
||||
|
||||
this.ingredientListView.setOnEditCommit(this::handleIngredientEdit);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue