Compare commits

..
Author SHA1 Message Date
Natalia Cholewa
a32f4cd781 Merge branch 'fix/even-better-i18n' into 'main'
Fix: improve i18n and finish up the last untranslated text

See merge request cse1105/2025-2026/teams/csep-team-76!96
2026-01-24 14:30:33 +01:00
Natalia Cholewa
da1f54f12f fix: improve i18n 2026-01-24 14:25:39 +01:00
Natalia Cholewa
2c4384872c Merge branch 'fix/ui-full-i18n' into 'main'
feat(client/lang): full UI i18n impl for each language

See merge request cse1105/2025-2026/teams/csep-team-76!95
2026-01-24 13:52:56 +01:00
9b1147c6c0
feat(client/lang): full UI i18n impl for each language 2026-01-23 22:59:34 +01:00
29 changed files with 541 additions and 242 deletions

View file

@ -56,6 +56,7 @@ public class FoodpalApplicationCtrl implements LocaleAware {
private final LocaleManager localeManager; private final LocaleManager localeManager;
private final WebSocketDataService<Long, Recipe> dataService; private final WebSocketDataService<Long, Recipe> dataService;
private final Logger logger = Logger.getLogger(FoodpalApplicationCtrl.class.getName()); private final Logger logger = Logger.getLogger(FoodpalApplicationCtrl.class.getName());
public Button shoppingListButton;
@FXML @FXML
private RecipeDetailCtrl recipeDetailController; private RecipeDetailCtrl recipeDetailController;
@ -304,13 +305,13 @@ public class FoodpalApplicationCtrl implements LocaleAware {
@Override @Override
public void updateText() { public void updateText() {
recipesLabel.setText(getLocaleString("app.word.recipe.n"));
addRecipeButton.setText(getLocaleString("menu.button.add.recipe")); addRecipeButton.setText(getLocaleString("menu.button.add.recipe"));
removeRecipeButton.setText(getLocaleString("menu.button.remove.recipe")); removeRecipeButton.setText(getLocaleString("menu.button.remove.recipe"));
cloneRecipeButton.setText(getLocaleString("menu.button.clone")); cloneRecipeButton.setText(getLocaleString("menu.button.clone"));
recipesLabel.setText(getLocaleString("menu.label.recipes"));
favouritesOnlyToggle.setText(getLocaleString("menu.button.favourites")); favouritesOnlyToggle.setText(getLocaleString("menu.button.favourites"));
manageIngredientsButton.setText(getLocaleString("menu.button.ingredients")); shoppingListButton.setText(getLocaleString("app.list"));
manageIngredientsButton.setText(getLocaleString("app.word.ingredient.n"));
} }
@Override @Override
@ -517,7 +518,7 @@ public class FoodpalApplicationCtrl implements LocaleAware {
public void openShoppingListWindow() throws IOException { public void openShoppingListWindow() throws IOException {
var root = UI.getFXML().load(ShoppingListCtrl.class, "client", "scenes", "shopping", "ShoppingList.fxml"); var root = UI.getFXML().load(ShoppingListCtrl.class, "client", "scenes", "shopping", "ShoppingList.fxml");
Stage stage = new Stage(); Stage stage = new Stage();
stage.setTitle(this.getLocaleString("menu.shopping.title")); stage.setTitle(this.getLocaleString("app.list"));
stage.setScene(new Scene(root.getValue())); stage.setScene(new Scene(root.getValue()));
stage.show(); stage.show();
} }

View file

@ -58,7 +58,7 @@ public class IngredientListCtrl implements LocaleAware {
ingredientsLabel.setText(getLocaleString("menu.label.ingredients")); ingredientsLabel.setText(getLocaleString("menu.label.ingredients"));
addButton.setText(getLocaleString("menu.button.add")); addButton.setText(getLocaleString("menu.button.add"));
refreshButton.setText(getLocaleString("menu.button.refresh")); refreshButton.setText(getLocaleString("menu.button.refresh"));
deleteButton.setText(getLocaleString("menu.button.delete")); deleteButton.setText(getLocaleString("verb.delete"));
closeButton.setText(getLocaleString("menu.button.close")); closeButton.setText(getLocaleString("menu.button.close"));
} }

View file

@ -21,6 +21,7 @@ import javafx.scene.layout.VBox;
import javafx.util.converter.NumberStringConverter; import javafx.util.converter.NumberStringConverter;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.logging.Logger; import java.util.logging.Logger;
public class NutritionDetailsCtrl implements LocaleAware { public class NutritionDetailsCtrl implements LocaleAware {
@ -57,6 +58,22 @@ public class NutritionDetailsCtrl implements LocaleAware {
this.server = server; this.server = server;
} }
Callable<String> getEstimatedKcalLabel() {
IngredientViewModel vm = this.ingredient.get();
return () -> String.format(getLocaleString("app.kcal") + " %.1f kcal/100g", vm.getKcal());
}
Callable<String> getUsageLabel() {
IngredientViewModel vm = this.ingredient.get();
return () -> {
Long id = this.ingredient.get().toIngredient().getId();
logger.info("Fetching usage for ingredient ID: " + id);
return !id.equals(0L) ? String.format(
getLocaleString("app.label.usage.part") + " %d " + getLocaleString("app.word.recipe.n"),
server.getIngredientUsage(id)) : "";
};
}
@Override @Override
public void initializeComponents() { public void initializeComponents() {
Platform.runLater(() -> { Platform.runLater(() -> {
@ -65,9 +82,8 @@ public class NutritionDetailsCtrl implements LocaleAware {
this.fatInputElement.textProperty().bindBidirectional(vm.fatProperty(), new NumberStringConverter()); this.fatInputElement.textProperty().bindBidirectional(vm.fatProperty(), new NumberStringConverter());
this.proteinInputElement.textProperty().bindBidirectional(vm.proteinProperty(), new NumberStringConverter()); this.proteinInputElement.textProperty().bindBidirectional(vm.proteinProperty(), new NumberStringConverter());
this.carbInputElement.textProperty().bindBidirectional(vm.carbsProperty(), new NumberStringConverter()); this.carbInputElement.textProperty().bindBidirectional(vm.carbsProperty(), new NumberStringConverter());
this.estimatedKcalLabel.textProperty().bind(Bindings.createStringBinding( this.estimatedKcalLabel.textProperty().bind(Bindings.createStringBinding(this.getEstimatedKcalLabel(), vm.kcalProperty()));
() -> String.format("Estimated energy value: %.1f kcal/100g", vm.getKcal()), vm.kcalProperty() this.usageLabel.textProperty().bind(Bindings.createStringBinding(this.getUsageLabel(), this.ingredient.get().idProperty()));
));
}); });
this.nutritionValueContainer.addEventHandler(KeyEvent.KEY_RELEASED, event -> { this.nutritionValueContainer.addEventHandler(KeyEvent.KEY_RELEASED, event -> {
if (event.getCode() != KeyCode.ENTER) { if (event.getCode() != KeyCode.ENTER) {
@ -91,7 +107,15 @@ public class NutritionDetailsCtrl implements LocaleAware {
@Override @Override
public void updateText() { public void updateText() {
try {
this.estimatedKcalLabel.textProperty().setValue(this.getEstimatedKcalLabel().call());
this.usageLabel.textProperty().setValue(this.getUsageLabel().call());
this.fatInputLabel.setText(this.getLocaleString("menu.nutrition.fat"));
this.proteinInputLabel.setText(this.getLocaleString("menu.nutrition.protein"));
this.carbInputLabel.setText(this.getLocaleString("menu.nutrition.carbs"));
} catch (Exception e) {
throw new RuntimeException(e);
}
} }
public void setVisible(boolean isVisible) { public void setVisible(boolean isVisible) {
@ -124,6 +148,7 @@ public class NutritionDetailsCtrl implements LocaleAware {
public LocaleManager getLocaleManager() { public LocaleManager getLocaleManager() {
return manager; return manager;
} }
public void handleNutritionSaveClick(ActionEvent actionEvent) throws IOException, InterruptedException { public void handleNutritionSaveClick(ActionEvent actionEvent) throws IOException, InterruptedException {
Ingredient newIngredient = updateIngredient(); Ingredient newIngredient = updateIngredient();
this.ingredient.get().updateFrom(server.updateIngredient(newIngredient)); this.ingredient.get().updateFrom(server.updateIngredient(newIngredient));

View file

@ -1,10 +1,14 @@
package client.scenes.nutrition; package client.scenes.nutrition;
import com.google.inject.Inject; import com.google.inject.Inject;
import javafx.fxml.FXML;
public class NutritionViewCtrl { public class NutritionViewCtrl {
@Inject @Inject
public NutritionViewCtrl( public NutritionViewCtrl(
) { ) {
} }
@FXML
NutritionDetailsCtrl nutritionDetailsController;
} }

View file

@ -1,5 +1,7 @@
package client.scenes.recipe; package client.scenes.recipe;
import client.utils.LocaleAware;
import client.utils.LocaleManager;
import client.utils.server.ServerUtils; import client.utils.server.ServerUtils;
import com.google.inject.Inject; import com.google.inject.Inject;
import commons.FormalIngredient; import commons.FormalIngredient;
@ -32,13 +34,18 @@ import java.util.logging.Logger;
* *
* @see IngredientListCtrl * @see IngredientListCtrl
*/ */
public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient> { public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient> implements LocaleAware {
private final ServerUtils server; private final ServerUtils server;
private final LocaleManager locale;
private final Logger logger = Logger.getLogger(IngredientListCell.class.getName()); private final Logger logger = Logger.getLogger(IngredientListCell.class.getName());
private final SimpleObjectProperty<Ingredient> selectedIngredient = new SimpleObjectProperty<>(); private final SimpleObjectProperty<Ingredient> selectedIngredient = new SimpleObjectProperty<>();
@Inject @Inject
public IngredientListCell(ServerUtils server) { public IngredientListCell(
ServerUtils server,
LocaleManager locale
) {
this.server = server; this.server = server;
this.locale = locale;
} }
@Override @Override
public void commitEdit(RecipeIngredient newValue) { public void commitEdit(RecipeIngredient newValue) {
@ -101,11 +108,11 @@ public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient
Consumer<T> onSelect, Consumer<T> onSelect,
HBox container) { HBox container) {
MenuItem newIngredientItem = new MenuItem(); MenuItem newIngredientItem = new MenuItem();
newIngredientItem.setText("Something new..."); newIngredientItem.setText(getLocaleString("app.prompt.something-new"));
// on new ingredient click // on new ingredient click
newIngredientItem.setOnAction(_ -> { newIngredientItem.setOnAction(_ -> {
menu.setText("New Ingredient"); // otherwise the text label on menu refuses to update menu.setText(getLocaleString("app.prompt.new-ingredient")); // otherwise the text label on menu refuses to update
selectedIngredient.setValue(null); // indicate null to signal a new ingredient creation selectedIngredient.setValue(null); // indicate null to signal a new ingredient creation
logger.info("Making new ingredient"); logger.info("Making new ingredient");
// TODO printError() integration // TODO printError() integration
@ -128,7 +135,7 @@ public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient
} }
} }
private HBox makeInputLine(RecipeIngredient ingredient, TextField amountInput, ChoiceBox<Unit> unitChoice) { private HBox makeInputLine(RecipeIngredient ingredient, TextField amountInput, ChoiceBox<Unit> unitChoice) {
MenuButton ingredientSelect = new MenuButton("Select your ingredient"); MenuButton ingredientSelect = new MenuButton(getLocaleString("app.prompt.select-ingredient"));
HBox container = new HBox(amountInput, unitChoice, ingredientSelect); HBox container = new HBox(amountInput, unitChoice, ingredientSelect);
try { try {
makeMenuItems(ingredientSelect, server.getIngredients(), Ingredient::getName, i -> { makeMenuItems(ingredientSelect, server.getIngredients(), Ingredient::getName, i -> {
@ -163,7 +170,7 @@ public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient
} }
private @NonNull TextField makeNewIngredientNameField(Consumer<Ingredient> onSubmit) { private @NonNull TextField makeNewIngredientNameField(Consumer<Ingredient> onSubmit) {
TextField newIngredientNameInput = new TextField("New ingredient..."); TextField newIngredientNameInput = new TextField(getLocaleString("app.prompt.new-ingredient"));
newIngredientNameInput.setOnKeyReleased(e -> { newIngredientNameInput.setOnKeyReleased(e -> {
if (e.getCode() != KeyCode.ENTER) { if (e.getCode() != KeyCode.ENTER) {
return; return;
@ -183,4 +190,14 @@ public class IngredientListCell extends OrderedEditableListCell<RecipeIngredient
}); });
return newIngredientNameInput; return newIngredientNameInput;
} }
@Override
public void updateText() {
}
@Override
public LocaleManager getLocaleManager() {
return locale;
}
} }

View file

@ -173,7 +173,7 @@ public class IngredientListCtrl implements LocaleAware {
this.ingredientListView.setEditable(true); this.ingredientListView.setEditable(true);
this.ingredientListView.setCellFactory( this.ingredientListView.setCellFactory(
list -> { list -> {
return new IngredientListCell(this.server); return new IngredientListCell(this.server, this.localeManager);
}); });
this.ingredientListView.setOnEditCommit(this::handleIngredientEdit); this.ingredientListView.setOnEditCommit(this::handleIngredientEdit);

View file

@ -60,6 +60,9 @@ public class RecipeDetailCtrl implements LocaleAware {
public Label inferredKcalLabel; public Label inferredKcalLabel;
public Spinner<Integer> servingsSpinner; public Spinner<Integer> servingsSpinner;
public Label inferredServeSizeLabel; public Label inferredServeSizeLabel;
public Label scaleLabel;
public Label servingLabel;
public Button addToListButton;
@FXML @FXML
private IngredientListCtrl ingredientListController; private IngredientListCtrl ingredientListController;
@ -178,13 +181,13 @@ public class RecipeDetailCtrl implements LocaleAware {
this.recipeView = new ScalableRecipeView(recipe, scale); this.recipeView = new ScalableRecipeView(recipe, scale);
// TODO i18n // TODO i18n
inferredKcalLabel.textProperty().bind(Bindings.createStringBinding(() -> inferredKcalLabel.textProperty().bind(Bindings.createStringBinding(() ->
String.format("Inferred %.1f kcal/100g for this recipe", String.format(getLocaleString("app.label.inferred-kcal") + " %.1f kcal/100g",
Double.isNaN(this.recipeView.scaledKcalProperty().get()) ? Double.isNaN(this.recipeView.scaledKcalProperty().get()) ?
0.0 : this.recipeView.scaledKcalProperty().get()) 0.0 : this.recipeView.scaledKcalProperty().get())
, this.recipeView.scaledKcalProperty())); , this.recipeView.scaledKcalProperty()));
recipeView.servingsProperty().set(servingsSpinner.getValue()); recipeView.servingsProperty().set(servingsSpinner.getValue());
inferredServeSizeLabel.textProperty().bind(Bindings.createStringBinding( inferredServeSizeLabel.textProperty().bind(Bindings.createStringBinding(
() -> String.format("Inferred size per serving: %.1f g", recipeView.servingSizeProperty().get()), () -> String.format(getLocaleString("app.label.inferred-size") + " %.1f g", recipeView.servingSizeProperty().get()),
recipeView.servingSizeProperty())); recipeView.servingSizeProperty()));
// expose the scaled view to list controllers // expose the scaled view to list controllers
this.ingredientListController.refetchFromRecipe(this.recipeView.getScaled()); this.ingredientListController.refetchFromRecipe(this.recipeView.getScaled());
@ -405,6 +408,20 @@ public class RecipeDetailCtrl implements LocaleAware {
editRecipeTitleButton.setText(getLocaleString("menu.button.edit")); editRecipeTitleButton.setText(getLocaleString("menu.button.edit"));
removeRecipeButton.setText(getLocaleString("menu.button.remove.recipe")); removeRecipeButton.setText(getLocaleString("menu.button.remove.recipe"));
printRecipeButton.setText(getLocaleString("menu.button.print")); printRecipeButton.setText(getLocaleString("menu.button.print"));
addToListButton.setText(getLocaleString("app.word.shop"));
scaleLabel.setText(getLocaleString("app.word.scale"));
servingLabel.setText(getLocaleString("app.word.serving.n"));
if (this.recipeView != null && this.recipeView.getRecipe() != null) {
inferredKcalLabel.textProperty().bind(Bindings.createStringBinding(() ->
String.format(getLocaleString("app.label.inferred-kcal") + " %.1f kcal/100g",
Double.isNaN(this.recipeView.scaledKcalProperty().get()) ?
0.0 : this.recipeView.scaledKcalProperty().get())
, this.recipeView.scaledKcalProperty()));
inferredServeSizeLabel.textProperty().bind(Bindings.createStringBinding(
() -> String.format(getLocaleString("app.label.inferred-size") + " %.1f g", recipeView.servingSizeProperty().get()),
recipeView.servingSizeProperty()));
}
} }
@Override @Override

View file

@ -14,6 +14,8 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView; import javafx.scene.control.TableView;
import javafx.scene.control.TextInputDialog; import javafx.scene.control.TextInputDialog;
@ -31,6 +33,11 @@ public class AddOverviewCtrl implements LocaleAware {
private final ShoppingListService shoppingListService; private final ShoppingListService shoppingListService;
private final LocaleManager localeManager; private final LocaleManager localeManager;
public Button addButton;
public Button removeSelButton;
public Button cancelButton;
public Button addConfirmButton;
public Label addOverviewTitle;
private String sourceRecipeName; private String sourceRecipeName;
@ -88,6 +95,13 @@ public class AddOverviewCtrl implements LocaleAware {
@Override @Override
public void updateText() { public void updateText() {
amountColumn.setText(getLocaleString("app.word.amount"));
unitColumn.setText(getLocaleString("app.word.unit"));
nameColumn.setText(getLocaleString("app.word.ingredient"));
addButton.setText(getLocaleString("verb.add"));
cancelButton.setText(getLocaleString("verb.cancel"));
addConfirmButton.setText(getLocaleString("verb.addconfirm"));
removeSelButton.setText(getLocaleString("verb.removesel"));
} }
@Override @Override

View file

@ -13,7 +13,9 @@ import javafx.scene.Node;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ListView; import javafx.scene.control.ListView;
import javafx.scene.control.TitledPane;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Modality; import javafx.stage.Modality;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -23,6 +25,11 @@ import java.io.File;
import java.util.Optional; import java.util.Optional;
public class ShoppingListCtrl implements LocaleAware { public class ShoppingListCtrl implements LocaleAware {
public Button addItemButton;
public Button deleteItemButton;
public Button printButton;
public Button resetButton;
public TitledPane shoppingListContainer;
ShoppingListService shopping; ShoppingListService shopping;
LocaleManager localeManager; LocaleManager localeManager;
@ -40,7 +47,11 @@ public class ShoppingListCtrl implements LocaleAware {
@Override @Override
public void updateText() { public void updateText() {
shoppingListContainer.setText(getLocaleString("app.list"));
addItemButton.setText(getLocaleString("verb.add"));
deleteItemButton.setText(getLocaleString("verb.delete"));
resetButton.setText(getLocaleString("verb.reset"));
printButton.setText(getLocaleString("verb.print"));
} }
@Override @Override

View file

@ -10,6 +10,7 @@ import commons.Unit;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.MenuButton; import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
import javafx.scene.control.Spinner; import javafx.scene.control.Spinner;
@ -27,6 +28,8 @@ public class ShoppingListNewItemPromptCtrl implements LocaleAware {
private final ObjectProperty<Unit> selectedUnit = new SimpleObjectProperty<>(); private final ObjectProperty<Unit> selectedUnit = new SimpleObjectProperty<>();
private final ServerUtils server; private final ServerUtils server;
private final LocaleManager localeManager; private final LocaleManager localeManager;
public Button confirmButton;
public Button cancelButton;
private Consumer<FormalIngredient> newValueConsumer; private Consumer<FormalIngredient> newValueConsumer;
public MenuButton unitSelect; public MenuButton unitSelect;
public Spinner<Double> amountSelect; public Spinner<Double> amountSelect;
@ -72,7 +75,10 @@ public class ShoppingListNewItemPromptCtrl implements LocaleAware {
} }
@Override @Override
public void updateText() { public void updateText() {
unitSelect.setText(getLocaleString("app.word.unit"));
ingredientSelection.setText(getLocaleString("app.word.ingredient"));
confirmButton.setText(getLocaleString("verb.confirm"));
cancelButton.setText(getLocaleString("verb.cancel"));
} }
@Override @Override
public void initializeComponents() { public void initializeComponents() {

View file

@ -5,7 +5,7 @@ import java.util.List;
public class Config { public class Config {
private String language = "en"; private String language = "en";
public static String[] languages = {"en", "nl", "pl", "tok", "zhc", "zht"}; public static String[] languages = {"en", "nl", "pl", "tr", "tok", "zhc", "zht"};
private List<String> recipeLanguages = new ArrayList<>(); private List<String> recipeLanguages = new ArrayList<>();
private String serverUrl = "http://localhost:8080"; private String serverUrl = "http://localhost:8080";

View file

@ -52,7 +52,7 @@
</padding> </padding>
<fx:include source="LangSelect.fxml" /> <fx:include source="LangSelect.fxml" />
<Button fx:id="refreshButton" onAction="#refresh" prefHeight="25.0" prefWidth="34.0" text="⟳" GridPane.columnIndex="3" GridPane.rowIndex="2" /> <Button fx:id="refreshButton" onAction="#refresh" prefHeight="25.0" prefWidth="34.0" text="⟳" GridPane.columnIndex="3" GridPane.rowIndex="2" />
<Label fx:id="recipesLabel" text="Recipes"> <Label fx:id="recipesLabel" text="%app.word.recipe.n">
<font> <font>
<Font name="System Bold" size="15.0" /> <Font name="System Bold" size="15.0" />
</font> </font>
@ -64,18 +64,18 @@
<ListView fx:id="recipeList" /> <ListView fx:id="recipeList" />
<HBox spacing="10"> <HBox spacing="10">
<Button fx:id="addRecipeButton" onAction="#addRecipe" text="Add Recipe" /> <Button fx:id="addRecipeButton" onAction="#addRecipe" text="%menu.button.add.recipe" />
<Button fx:id="removeRecipeButton" onAction="#removeSelectedRecipe" text="Remove Recipe" /> <Button fx:id="removeRecipeButton" onAction="#removeSelectedRecipe" text="%menu.button.remove.recipe" />
<Button fx:id="cloneRecipeButton" mnemonicParsing="false" onAction="#cloneRecipe" text="Clone" /> <Button fx:id="cloneRecipeButton" mnemonicParsing="false" onAction="#cloneRecipe" text="%menu.button.clone" />
<ToggleButton fx:id="favouritesOnlyToggle" text="Favourites" onAction="#toggleFavouritesView" /> <ToggleButton fx:id="favouritesOnlyToggle" text="%menu.button.favourites" onAction="#toggleFavouritesView" />
</HBox> </HBox>
<Button fx:id="shoppingListButton" <Button fx:id="shoppingListButton"
onAction="#openShoppingListWindow" onAction="#openShoppingListWindow"
text="Shopping List" /> text="%app.list" />
<Button fx:id="manageIngredientsButton" <Button fx:id="manageIngredientsButton"
onAction="#openIngredientsPopup" onAction="#openIngredientsPopup"
text="Ingredients..." /> text="%app.word.ingredient.n" />
</VBox> </VBox>
</left> </left>
@ -95,7 +95,7 @@
<Insets bottom="16" left="16" right="16" top="8" /> <Insets bottom="16" left="16" right="16" top="8" />
</padding> </padding>
<Label fx:id="updatedBadge" <Label fx:id="updatedBadge"
text="Updated just now" text="%app.updated"
visible="false" visible="false"
managed="false" managed="false"
styleClass="updated-badge"/> styleClass="updated-badge"/>

View file

@ -6,6 +6,6 @@
<HBox xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.scenes.SearchBarCtrl"> <HBox xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.scenes.SearchBarCtrl">
<children> <children>
<TextField fx:id="searchField" promptText="Search..." /> <TextField fx:id="searchField" promptText="%menu.search" />
</children> </children>
</HBox> </HBox>

View file

@ -21,7 +21,7 @@
<Label GridPane.columnIndex="0" GridPane.rowIndex="2" fx:id="carbInputLabel">Carbohydrates: </Label> <Label GridPane.columnIndex="0" GridPane.rowIndex="2" fx:id="carbInputLabel">Carbohydrates: </Label>
<TextField GridPane.columnIndex="1" GridPane.rowIndex="2" fx:id="carbInputElement" /> <TextField GridPane.columnIndex="1" GridPane.rowIndex="2" fx:id="carbInputElement" />
</GridPane> </GridPane>
<Button onAction="#handleNutritionSaveClick">Save values</Button> <Button onAction="#handleNutritionSaveClick" text="%verb.save" />
<Label fx:id="estimatedKcalLabel">Estimated: 0kcal</Label> <Label fx:id="estimatedKcalLabel" />
<Label fx:id="usageLabel">Not used in any recipes</Label> <Label fx:id="usageLabel" />
</VBox> </VBox>

View file

@ -12,6 +12,6 @@
prefHeight="400.0" prefWidth="600.0"> prefHeight="400.0" prefWidth="600.0">
<SplitPane> <SplitPane>
<fx:include source="IngredientList.fxml" /> <fx:include source="IngredientList.fxml" />
<fx:include source="NutritionDetails.fxml" /> <fx:include fx:id="nutritionDetails" source="NutritionDetails.fxml" />
</SplitPane> </SplitPane>
</AnchorPane> </AnchorPane>

View file

@ -21,18 +21,18 @@
<HBox spacing="10"> <HBox spacing="10">
<HBox fx:id="editableTitleArea"> <HBox fx:id="editableTitleArea">
</HBox> </HBox>
<Button fx:id="editRecipeTitleButton" onAction="#editRecipeTitle" text="Edit" /> <Button fx:id="editRecipeTitleButton" onAction="#editRecipeTitle" text="%menu.button.edit" />
<Button fx:id="removeRecipeButton" mnemonicParsing="false" onAction="#removeSelectedRecipe" text="Remove Recipe" /> <Button fx:id="removeRecipeButton" mnemonicParsing="false" onAction="#removeSelectedRecipe" text="%menu.button.remove.recipe" />
<Button fx:id="printRecipeButton" mnemonicParsing="false" onAction="#printRecipe" text="Print Recipe" /> <Button fx:id="printRecipeButton" mnemonicParsing="false" onAction="#printRecipe" text="%menu.button.print" />
<Button fx:id="favouriteButton" onAction="#toggleFavourite" text="☆" /> <Button fx:id="favouriteButton" onAction="#toggleFavourite" text="☆" />
<Button onAction="#handleAddAllToShoppingList">Shop</Button> <Button fx:id="addToListButton" onAction="#handleAddAllToShoppingList" text="%app.word.shop" />
</HBox> </HBox>
<HBox> <HBox>
<ComboBox fx:id="langSelector" onAction="#changeLanguage" /> <ComboBox fx:id="langSelector" onAction="#changeLanguage" />
<Label>Scale: </Label> <Label fx:id="scaleLabel" text="%app.word.scale" />
<Spinner fx:id="scaleSpinner" /> <Spinner fx:id="scaleSpinner" />
<Label>Servings: </Label> <Label fx:id="servingLabel" text="%app.word.serving.n" />
<Spinner fx:id="servingsSpinner" /> <Spinner fx:id="servingsSpinner" />
</HBox> </HBox>

View file

@ -16,7 +16,7 @@
<children> <children>
<HBox alignment="CENTER_LEFT" spacing="20.0"> <HBox alignment="CENTER_LEFT" spacing="20.0">
<children> <children>
<Label fx:id="ingredientsLabel" text="Ingredients"> <Label fx:id="ingredientsLabel" text="%app.word.ingredient.n">
<padding> <padding>
<Insets bottom="5.0" top="5.0" /> <Insets bottom="5.0" top="5.0" />
</padding> </padding>
@ -26,8 +26,8 @@
</Label> </Label>
<HBox alignment="CENTER" spacing="10.0"> <HBox alignment="CENTER" spacing="10.0">
<children> <children>
<Button fx:id="addIngredientButton" mnemonicParsing="false" text="Add" /> <Button fx:id="addIngredientButton" mnemonicParsing="false" text="%verb.add" />
<Button fx:id="deleteIngredientButton" mnemonicParsing="false" text="Delete" /> <Button fx:id="deleteIngredientButton" mnemonicParsing="false" text="%verb.delete" />
</children> </children>
</HBox> </HBox>
</children> </children>

View file

@ -15,7 +15,7 @@
<children> <children>
<HBox alignment="CENTER_LEFT" spacing="20.0"> <HBox alignment="CENTER_LEFT" spacing="20.0">
<children> <children>
<Label fx:id="stepsLabel" text="Steps"> <Label fx:id="stepsLabel" text="%app.word.step.n">
<padding> <padding>
<Insets bottom="5.0" top="5.0" /> <Insets bottom="5.0" top="5.0" />
</padding> </padding>
@ -25,8 +25,8 @@
</Label> </Label>
<HBox alignment="CENTER" spacing="10.0"> <HBox alignment="CENTER" spacing="10.0">
<children> <children>
<Button fx:id="addStepButton" mnemonicParsing="false" text="Add" /> <Button fx:id="addStepButton" mnemonicParsing="false" text="%verb.add" />
<Button fx:id="deleteStepButton" mnemonicParsing="false" text="Delete" /> <Button fx:id="deleteStepButton" mnemonicParsing="false" text="%verb.delete" />
</children> </children>
</HBox> </HBox>
</children> </children>

View file

@ -11,22 +11,22 @@
<VBox spacing="10.0" AnchorPane.topAnchor="10.0" AnchorPane.leftAnchor="10.0" <VBox spacing="10.0" AnchorPane.topAnchor="10.0" AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.bottomAnchor="10.0"> AnchorPane.rightAnchor="10.0" AnchorPane.bottomAnchor="10.0">
<Label text="Review ingredients before adding" /> <Label fx:id="addOverviewTitle" text="%app.title.addoverview" />
<TableView fx:id="overviewTable" editable="true" VBox.vgrow="ALWAYS"> <TableView fx:id="overviewTable" editable="true" VBox.vgrow="ALWAYS">
<columns> <columns>
<TableColumn fx:id="nameColumn" text="Ingredient" prefWidth="360.0"/> <TableColumn fx:id="nameColumn" text="%app.word.ingredient" prefWidth="360.0"/>
<TableColumn fx:id="amountColumn" text="Amount" prefWidth="140.0"/> <TableColumn fx:id="amountColumn" text="%app.word.amount" prefWidth="140.0"/>
<TableColumn fx:id="unitColumn" text="Unit" prefWidth="140.0"/> <TableColumn fx:id="unitColumn" text="%app.word.unit" prefWidth="140.0"/>
</columns> </columns>
</TableView> </TableView>
<HBox spacing="10.0"> <HBox spacing="10.0">
<Button text="Add item" onAction="#handleAddRow"/> <Button fx:id="addButton" text="%verb.add" onAction="#handleAddRow"/>
<Button text="Remove selected" onAction="#handleRemoveSelected"/> <Button fx:id="removeSelButton" text="%verb.removesel" onAction="#handleRemoveSelected"/>
<Pane HBox.hgrow="ALWAYS"/> <Pane HBox.hgrow="ALWAYS"/>
<Button text="Cancel" onAction="#handleCancel"/> <Button fx:id="cancelButton" text="%verb.cancel" onAction="#handleCancel"/>
<Button text="Confirm &amp; Add" onAction="#handleConfirm"/> <Button fx:id="addConfirmButton" text="%verb.addconfirm" onAction="#handleConfirm"/>
</HBox> </HBox>
</VBox> </VBox>
</AnchorPane> </AnchorPane>

View file

@ -8,7 +8,7 @@
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<TitledPane animated="false" collapsible="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" <TitledPane animated="false" collapsible="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" text="Shopping List" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" text="%app.list" fx:id="shoppingListContainer"
fx:controller="client.scenes.shopping.ShoppingListCtrl" fx:controller="client.scenes.shopping.ShoppingListCtrl"
xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/25"> xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/25">
<VBox> <VBox>
@ -16,10 +16,10 @@
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"/> AnchorPane.topAnchor="0.0"/>
<HBox> <HBox>
<Button onAction="#handleAddItem">Add</Button> <Button fx:id="addItemButton" onAction="#handleAddItem" />
<Button onAction="#handleRemoveItem">Delete</Button> <Button fx:id="deleteItemButton" onAction="#handleRemoveItem" />
<Button onAction="#handlePrint">Print</Button> <Button fx:id="printButton" onAction="#handlePrint" />
<Button onAction="#handleReset">Reset</Button> <Button fx:id="resetButton" onAction="#handleReset" />
</HBox> </HBox>
</VBox> </VBox>
</TitledPane> </TitledPane>

Some files were not shown because too many files have changed in this diff Show more