refactor: make ingredient input cells capable of informal & formal inputs

This commit is contained in:
Zhongheng Liu 2025-12-21 23:41:48 +02:00
commit e4fc67e816
Signed by: steven
GPG key ID: F69B980899C1C09D
3 changed files with 56 additions and 30 deletions

View file

@ -1,6 +1,12 @@
package client.scenes.recipe;
import commons.Unit;
import javafx.collections.FXCollections;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
/**
* A custom {@link OrderedEditableListCell<String>} for displaying and editing ingredients in an
@ -9,10 +15,34 @@ import javafx.scene.control.TextField;
* @see IngredientListCtrl
*/
public class IngredientListCell extends OrderedEditableListCell<String> {
// TODO: change all this to use actual Ingredient objects
// and all that :)
@Override
protected String fromInput(TextField inputField) {
return inputField.getText();
public void commitEdit(String newValue) {
super.commitEdit(newValue);
}
@Override
public void startEdit() {
super.startEdit();
TextField amountInput = new TextField("0");
ChoiceBox<Unit> unitChoice = new ChoiceBox<>();
unitChoice.setItems(FXCollections.observableArrayList(Unit.GRAM, Unit.KILOGRAM));
TextField nameInput = new TextField("ingredient");
HBox container = new HBox(amountInput, unitChoice, nameInput);
container.setOnKeyReleased(event -> {
if (event.getCode() != KeyCode.ENTER) {
return;
}
Unit unit = unitChoice.getValue();
String name = nameInput.getText();
if (unit == null) {
String desc = amountInput.getText();
super.commitEdit(desc + " " + name);
return;
}
int amount = Integer.parseInt(amountInput.getText());
super.commitEdit(amount + " " + unit + " of " + name);
});
this.setText(null);
this.setGraphic(container);
}
}

View file

@ -1,10 +1,8 @@
package client.scenes.recipe;
import javafx.scene.control.ListCell;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
public abstract class OrderedEditableListCell<T> extends ListCell<T> {
public abstract class OrderedEditableListCell<DataType> extends ListCell<DataType> {
/**
* Get the display text for the given item, prefixed with its index.
* Looks like "1. description".
@ -16,7 +14,7 @@ public abstract class OrderedEditableListCell<T> extends ListCell<T> {
return (this.getIndex() + 1) + ". " + item;
}
@Override
protected void updateItem(T item, boolean empty) {
protected void updateItem(DataType item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
@ -27,26 +25,7 @@ public abstract class OrderedEditableListCell<T> extends ListCell<T> {
}
public void startEdit() {
super.startEdit();
TextField textField = new TextField(this.getItem().toString());
// Commit edit on Enter key press
textField.setOnAction(event -> {
this.commitEdit(fromInput(textField));
});
// Cancel edit on Escape key press
textField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ESCAPE) {
this.cancelEdit();
}
});
this.setText(null);
this.setGraphic(textField);
}
protected abstract T fromInput(TextField inputField);
/**
* Check if the input is valid (non-empty).
*
@ -66,7 +45,7 @@ public abstract class OrderedEditableListCell<T> extends ListCell<T> {
}
@Override
public void commitEdit(T newValue) {
public void commitEdit(DataType newValue) {
this.setGraphic(null);
if (!isInputValid(newValue.toString())) {

View file

@ -1,6 +1,8 @@
package client.scenes.recipe;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
/**
* A custom ListCell for displaying and editing ingredients in an
* RecipeStepList. Allows inline editing of ingredient names.
@ -9,7 +11,22 @@ import javafx.scene.control.TextField;
*/
public class RecipeStepListCell extends OrderedEditableListCell<String> {
@Override
protected String fromInput(TextField inputField) {
return inputField.getText();
public void startEdit() {
TextField textField = new TextField(this.getItem());
// Commit edit on Enter key press
textField.setOnAction(event -> {
this.commitEdit(textField.getText());
});
// Cancel edit on Escape key press
textField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ESCAPE) {
this.cancelEdit();
}
});
this.setText(null);
this.setGraphic(textField);
}
}