From 526ce67a4f090928a6c20ece43fa1fe4f748b85c Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 14 May 2026 12:44:17 +0200 Subject: [PATCH 01/13] First working implementation --- .../it/polimi/ingsw/gc14/View/GUI/GUI.java | 1 + .../gc14/View/GUI/MainFXMLController.java | 76 +++++++++---------- .../polimi/ingsw/gc14/View/GUI/MainView.java | 49 ------------ .../gc14/View/GUI/TotemFXMLController.java | 3 +- 4 files changed, 40 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/it/polimi/ingsw/gc14/View/GUI/MainView.java diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java index 1d2fa3d..ac8a59c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java @@ -84,6 +84,7 @@ public class GUI extends Application implements IView { }); } else { Platform.runLater(() -> { + controllerMain.render(); primaryStage.setScene(mainScene); }); } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 608e885..0eb6867 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -47,14 +47,12 @@ public class MainFXMLController { private Popup popup; private HBox popupCards; - private MiniModel model; private ClientController controller; - private String username; private final Map cardCache = new HashMap<>(); - public void setModel(MiniModel model) {this.model = model;} - public void setController(ClientController controller) {this.controller = controller;} - public void setUsername(String username) {this.username = username;} + public void setController(ClientController controller) { + this.controller = controller; + } @@ -116,10 +114,10 @@ public class MainFXMLController { img.setClip(clip); StackPane wrapper = new StackPane(img); - Player player = model.slotPlayerMap.get(slot); - if (player != null && model.getPositionByUsername(player.getUserName())!=-1) { - int index = model.getPositionByUsername(player.getUserName()); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".png"))); + Player player = controller.miniModel.slotPlayerMap.get(slot); + if (player != null && controller.miniModel.getPositionByUsername(player.getUserName())!=-1) { + int index = controller.miniModel.getPositionByUsername(player.getUserName()); + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); totem.setFitHeight(70); totem.setPreserveRatio(true); StackPane.setAlignment(totem, Pos.TOP_LEFT); @@ -221,24 +219,24 @@ public class MainFXMLController { upperList.getChildren().clear(); int i = 0; - for (TribeCard card : model.board.upperListTribe) { + for (TribeCard card : controller.miniModel.board.upperListTribe) { final int index = i; StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperTribeCard(username, index)); + img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); upperList.getChildren().add(img); i++; } i = 0; - for (BuildingCard card : model.board.upperListBuilding) { + for (BuildingCard card : controller.miniModel.board.upperListBuilding) { final int index = i; StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(username, index)); + img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(controller.myUsername, index)); upperList.getChildren().add(img); i++; } } private void renderOrder() { - StackPane card = createOrder(Integer.toString(model.players.size()), false, false); + StackPane card = createOrder(Integer.toString(controller.miniModel.players.size()), false, false); VBox overlay = new VBox(-20); overlay.setPickOnBounds(false); @@ -246,13 +244,13 @@ public class MainFXMLController { StackPane.setMargin(overlay, new Insets(9, 0, 0, 57)); int i = 0; - for (Player player : model.players.values()) { + for (Player player : controller.miniModel.players.values()) { final int index = i; - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".png"))); + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); totem.setFitHeight(70); totem.setPreserveRatio(true); - if (!(model.orderLogicCard.getPosition(player.getUserName()) != -1 && !model.slotPlayerMap.containsValue(player))) { + if (!(controller.miniModel.orderLogicCard.getPosition(player.getUserName()) != -1 && !controller.miniModel.slotPlayerMap.containsValue(player))) { totem.setOpacity(0.0); } overlay.getChildren().add(totem); @@ -267,7 +265,7 @@ public class MainFXMLController { board.getChildren().clear(); String path = ""; - switch (model.currentState.getEra()) { + switch (controller.miniModel.currentState.getEra()) { case 1 -> path = "/GUIImages/Backs/back-001.png"; case 2 -> path = "/GUIImages/Backs/back-030.png"; case 3 -> path = "/GUIImages/Backs/back-058.png"; @@ -289,11 +287,11 @@ public class MainFXMLController { renderOrder(); int i = 0; - for (Map.Entry entry : model.slotPlayerMap.entrySet()) { + for (Map.Entry entry : controller.miniModel.slotPlayerMap.entrySet()) { Slot slot = entry.getKey(); final int index = i; StackPane img = createSlot(slot, true, true); - img.setOnMouseClicked(e -> controller.slotChoice(username, index)); + img.setOnMouseClicked(e -> controller.slotChoice(controller.myUsername, index)); board.getChildren().add(img); i++; } @@ -304,18 +302,18 @@ public class MainFXMLController { lowerList.getChildren().clear(); int i = 0; - for (TribeCard card : model.board.lowerListTribe) { + for (TribeCard card : controller.miniModel.board.lowerListTribe) { final int index = i; StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerTribeCard(username, index)); + img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index)); lowerList.getChildren().add(img); i++; } i = 0; - for (BuildingCard card : model.board.lowerListBuilding) { + for (BuildingCard card : controller.miniModel.board.lowerListBuilding) { final int index = i; StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(username, index)); + img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(controller.myUsername, index)); lowerList.getChildren().add(img); i++; } @@ -327,13 +325,13 @@ public class MainFXMLController { myHand.setSpacing(14); myHand.setAlignment(Pos.CENTER); - drawMyHandList(myHand, model.players.get(username).artists); - drawMyHandList(myHand, model.players.get(username).gatherers); - drawMyHandList(myHand, model.players.get(username).inventors); - drawMyHandList(myHand, model.players.get(username).builders); - drawMyHandList(myHand, model.players.get(username).shamans); - drawMyHandList(myHand, model.players.get(username).hunters); - drawMyHandList(myHand, model.players.get(username).buildingCards); + drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).artists); + drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).gatherers); + drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).inventors); + drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).builders); + drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).shamans); + drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).hunters); + drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).buildingCards); } private void drawMyHandList(HBox myHand, ArrayList cardList) { if (!cardList.isEmpty()) { @@ -361,16 +359,16 @@ public class MainFXMLController { sidePanel.getChildren().clear(); sidePanel.setSpacing(6); - era.setText(Integer.toString(model.currentState.getEra())); - round.setText(Integer.toString(model.currentState.getRound())); - player.setText(model.currentState.getCurrentPlayer().getUserName()); + era.setText(Integer.toString(controller.miniModel.currentState.getEra())); + round.setText(Integer.toString(controller.miniModel.currentState.getRound())); + player.setText(controller.miniModel.currentState.getCurrentPlayer().getUserName()); VBox.setMargin(info, new Insets(5, 5, 5, 5)); sidePanel.getChildren().add(info); renderPlayers(sidePanel); } private void renderPlayers(VBox playersHand) { - for (Player player : model.players.values()) { + for (Player player : controller.miniModel.players.values()) { // Card container VBox card = new VBox(3); VBox.setMargin(card, new Insets(5)); @@ -382,13 +380,13 @@ public class MainFXMLController { // Riga 1: icona totem + nome HBox headerRow = new HBox(8); headerRow.setAlignment(Pos.CENTER); - int index = new ArrayList<>(model.players.values()).indexOf(player); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".png"))); + int index = new ArrayList<>(controller.miniModel.players.values()).indexOf(player); + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); totem.setFitHeight(20); totem.setPreserveRatio(true); Label usernameLabel = new Label(player.getUserName()); usernameLabel.getStyleClass().add("label-medium"); - if (player.getUserName().equals(username)) { + if (player.getUserName().equals(controller.myUsername)) { usernameLabel.setStyle("-fx-text-fill: #9d0208"); } headerRow.getChildren().addAll(totem, usernameLabel); @@ -465,7 +463,7 @@ public class MainFXMLController { } } private ArrayList getPlayerCards(String username, String type) { - Player p = model.players.get(username); + Player p = controller.miniModel.players.get(username); return switch (type) { case "artists" -> new ArrayList<>(p.artists); case "gatherers" -> new ArrayList<>(p.gatherers); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainView.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainView.java deleted file mode 100644 index bc5bb86..0000000 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainView.java +++ /dev/null @@ -1,49 +0,0 @@ -package it.polimi.ingsw.gc14.View.GUI; - -import it.polimi.ingsw.gc14.Controller.ClientController; -import it.polimi.ingsw.gc14.Model.Game; -import it.polimi.ingsw.gc14.Model.MiniModel; -import javafx.fxml.FXMLLoader; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Label; -import javafx.scene.layout.VBox; - -import java.io.IOException; - -public class MainView { - - private final Scene scene; - private final MainFXMLController fxmlController; - private MiniModel model; - private ClientController controller; - private String username; - - public MainView() { - try { - FXMLLoader loader = new FXMLLoader( - getClass().getResource("/GUIScene/main.fxml") - ); - scene = new Scene(loader.load(), 1920, 1080); - fxmlController = loader.getController(); - } catch (IOException e) { - throw new RuntimeException("Impossibile caricare login.fxml", e); - } - } - - public Scene getScene() { return scene; } - public void setModel(MiniModel model, ClientController controller, String username) { - this.model = model; - fxmlController.setModel(model); - this.controller = controller; - fxmlController.setController(controller); - this.username = username; - fxmlController.setUsername(username); - - } - public void render() { - fxmlController.render(); - } - -} \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java index c794026..5b606b3 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java @@ -25,11 +25,12 @@ public class TotemFXMLController { } public void render() { + mainHBox.getChildren().clear(); for (Totems totem : controller.miniModel.availableTotems) { ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_"+ String.valueOf(totem).toLowerCase(Locale.ROOT) +".png"))); img.setFitHeight(240); img.setPreserveRatio(true); - img.setOnMouseClicked(e -> controller.totemChoice(controller.myUsername)); + img.setOnMouseClicked(e -> controller.totemChoice(controller.myUsername, controller.miniModel.availableTotems.indexOf(totem))); mainHBox.getChildren().add(img); } } From 9fa51e9fe705b8ad1fb57d7c2e43f27aae3487e0 Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 14 May 2026 15:34:49 +0200 Subject: [PATCH 02/13] added property changes impl --- .../gc14/Controller/ClientController.java | 9 +- .../it/polimi/ingsw/gc14/Model/MiniModel.java | 93 ++- .../ingsw/gc14/Model/OrderLogicCard.java | 2 +- .../it/polimi/ingsw/gc14/View/GUI/GUI.java | 7 +- .../gc14/View/GUI/MainFXMLController.java | 612 +++++++++--------- src/main/java/module-info.java | 1 + 6 files changed, 385 insertions(+), 339 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java index 0322b97..f7737dc 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java @@ -29,6 +29,7 @@ public class ClientController { public String myUsername; + /** * Constructs the ClientController. * Initializes all attributes. @@ -37,6 +38,7 @@ public class ClientController { public ClientController(IView view) { this.view = view; this.client = null; + this.miniModel = new MiniModel(); } @@ -54,7 +56,12 @@ public class ClientController { * @param model the model to set */ public void setModel(MiniModel model) { - this.miniModel = model; + this.miniModel.currentState=model.currentState; + this.miniModel.availableTotems=model.availableTotems; + this.miniModel.board=model.board; + this.miniModel.orderLogicCard= model.orderLogicCard; + this.miniModel.players=model.players; + this.miniModel.slotPlayerMap=model.slotPlayerMap; view.setModel(miniModel); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java b/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java index 830175c..4a51fb8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java @@ -6,64 +6,109 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Model.GamePackage.Board; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.io.Serializable; -import java.rmi.RemoteException; import java.util.*; -//TODO + public class MiniModel implements Serializable { + + private final PropertyChangeSupport support = new PropertyChangeSupport(this); + public Board board; - public Map slotPlayerMap; + public Map slotPlayerMap; public OrderLogicCard orderLogicCard; - public CurrentState currentState; - public Map players; - public ListavailableTotems; + public CurrentState currentState; + public Map players; + public List availableTotems; + + // --- Costruttori invariati --- + + public MiniModel() { + + } + public MiniModel(Board board) { this.board = board; } - public MiniModel(Board board, Map slotPlayerMap, OrderLogicCard orderLogicCard, CurrentState currentState, List players, ListavailableTotems) { + + public MiniModel(Board board, Map slotPlayerMap, OrderLogicCard orderLogicCard, + CurrentState currentState, List players, List availableTotems) { this.board = board; this.slotPlayerMap = slotPlayerMap; this.orderLogicCard = orderLogicCard; this.currentState = currentState; - this.players=new HashMap<>(); - this.availableTotems=availableTotems; + this.players = new HashMap<>(); + this.availableTotems = availableTotems; setPlayers(players); } + + // --- Gestione listener --- + + public void addPropertyChangeListener(PropertyChangeListener listener) { + support.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + support.removePropertyChangeListener(listener); + } + + // --- Setter con notifica --- + public void setBoard(Board board) { + Board old = this.board; this.board = board; + support.firePropertyChange("board", old, board); } - public void setAvailableTotems(ListavailableTotems) { + + public void setAvailableTotems(List availableTotems) { + List old = this.availableTotems; this.availableTotems = availableTotems; + support.firePropertyChange("availableTotems", old, availableTotems); } - public void setSlotPlayerMap(Map slotPlayerMap) { + + public void setSlotPlayerMap(Map slotPlayerMap) { + Map old = this.slotPlayerMap; this.slotPlayerMap = slotPlayerMap; + support.firePropertyChange("slotPlayerMap", old, slotPlayerMap); } + public void setOrderLogicCard(OrderLogicCard orderLogicCard) { + OrderLogicCard old = this.orderLogicCard; this.orderLogicCard = orderLogicCard; + support.firePropertyChange("orderLogicCard", old, orderLogicCard); } + public void setCurrentState(CurrentState currentState) { + CurrentState old = this.currentState; this.currentState = currentState; + support.firePropertyChange("currentState", old, currentState); } + public void setPlayers(List players) { + Map old = new HashMap<>(this.players != null ? this.players : new HashMap<>()); for (Player player : players) { - this.players.put(player.getUserName(),player); + this.players.put(player.getUserName(), player); } + support.firePropertyChange("players", old, this.players); } - public void setPlayer(Player player) - { - players.put(player.getUserName(),player); + + public void setPlayer(Player player) { + Map old = new HashMap<>(this.players); + players.put(player.getUserName(), player); + support.firePropertyChange("players", old, this.players); } - public int getPositionByUsername(String username) - { - int i=0; - for (Player player : players.values()) - { - if(player.getUserName().equals(username)) - { + + // --- Metodi invariati --- + + public int getPositionByUsername(String username) { + int i = 0; + for (Player player : players.values()) { + if (player.getUserName().equals(username)) { return i; } i++; } - return -1; + return -1; } -} +} \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java index dd6863c..f90ecfd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java @@ -20,7 +20,7 @@ public abstract class OrderLogicCard implements Serializable { /** * The queue of {@link Player Players} associated with this order logic card. */ - protected Queue players; + public Queue players; /** * The list of {@link Player Players} associated with this order logic card. diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java index ac8a59c..de29419 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java @@ -45,7 +45,6 @@ public class GUI extends Application implements IView { controllerLogin.setController(controller); - loaderTotem = new FXMLLoader(getClass().getResource("/GUIScene/totem.fxml")); totemScene = new Scene(loaderTotem.load()); controllerTotem = loaderTotem.getController(); @@ -53,9 +52,13 @@ public class GUI extends Application implements IView { loaderMain = new FXMLLoader(getClass().getResource("/GUIScene/main.fxml")); + loaderMain.setControllerFactory(clazz -> { + MainFXMLController controllerMain = new MainFXMLController(); + controllerMain.setController(controller); + return controllerMain; + }); mainScene = new Scene(loaderMain.load()); controllerMain = loaderMain.getController(); - controllerMain.setController(controller); showLogin(); stage.setTitle("Mesos"); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 0eb6867..1b6f676 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -4,7 +4,10 @@ import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Model.*; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; +import it.polimi.ingsw.gc14.Model.GamePackage.Board; +import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; import javafx.animation.ScaleTransition; +import javafx.application.Platform; import javafx.event.Event; import javafx.fxml.FXML; import javafx.geometry.Insets; @@ -24,9 +27,8 @@ import javafx.stage.Popup; import javafx.stage.Window; import javafx.util.Duration; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; public class MainFXMLController { @@ -48,7 +50,6 @@ public class MainFXMLController { private HBox popupCards; private ClientController controller; - private final Map cardCache = new HashMap<>(); public void setController(ClientController controller) { this.controller = controller; @@ -69,6 +70,23 @@ public class MainFXMLController { // Initialize popup initPopup(); + + + controller.miniModel.addPropertyChangeListener(evt -> { + switch (evt.getPropertyName()) { + case "board" -> ciao("board"); + case "currentState" -> ciao("currentState"); + case "players" -> Platform.runLater(() -> renderSidePanel()); + case "slotPlayerMap" -> Platform.runLater(() -> renderBoard()); + case "orderLogicCard"-> Platform.runLater(() -> renderBoard()); + case "availableTotems"-> ciao("availableTotems"); + } + }); + } + + + public void ciao(String s) { + System.out.println(s); } @@ -81,86 +99,15 @@ public class MainFXMLController { renderSidePanel(); } - // ==== HELPER ==== - private StackPane createOrder(String num, boolean withZoom, boolean withShadow) { - ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Orders/order-" + num + ".png"))); - img.setFitHeight(240); - img.setPreserveRatio(true); + + // ==== EFFECTS ==== + private void addClip(Node node) { Rectangle clip = new Rectangle(); - clip.setWidth(img.getBoundsInLocal().getWidth()); - clip.setHeight(240); + clip.setWidth(node.getBoundsInLocal().getWidth()); + clip.setHeight(node.getBoundsInLocal().getHeight()); clip.setArcWidth(20); clip.setArcHeight(20); - img.setClip(clip); - StackPane wrapper = new StackPane(img); - if (withShadow) { - addShadow(wrapper); - } - if (withZoom) { - addHoverZoom(wrapper); - } - return wrapper; - } - - private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) { - ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"))); - img.setFitHeight(240); - img.setPreserveRatio(true); - Rectangle clip = new Rectangle(); - clip.setWidth(img.getBoundsInLocal().getWidth()); - clip.setHeight(240); - clip.setArcWidth(20); - clip.setArcHeight(20); - img.setClip(clip); - StackPane wrapper = new StackPane(img); - - Player player = controller.miniModel.slotPlayerMap.get(slot); - if (player != null && controller.miniModel.getPositionByUsername(player.getUserName())!=-1) { - int index = controller.miniModel.getPositionByUsername(player.getUserName()); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); - totem.setFitHeight(70); - totem.setPreserveRatio(true); - StackPane.setAlignment(totem, Pos.TOP_LEFT); - StackPane.setMargin(totem, new Insets(8, 0, 0, 57)); - wrapper.getChildren().add(totem); - } - - if (withShadow) { - addShadow(wrapper); - } - if (withZoom) { - addHoverZoom(wrapper); - } - return wrapper; - } - private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow) { - String id = card.getIdIMG(); - ImageView img; - if (cardCache.containsKey(id)) { - img = new ImageView(cardCache.get(id).getImage()); - } else { - img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + id + ".png"))); - cardCache.put(id, img); - } - img.setFitHeight(200); - img.setPreserveRatio(true); - - Rectangle clip = new Rectangle(); - clip.setWidth(img.getBoundsInLocal().getWidth()); - clip.setHeight(200); - clip.setArcWidth(20); - clip.setArcHeight(20); - img.setClip(clip); - - StackPane wrapper = new StackPane(img); - - if (withShadow) { - addShadow(wrapper); - } - if (withZoom) { - addHoverZoom(wrapper); - } - return wrapper; + node.setClip(clip); } private void addHoverZoom(Node node) { ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), node); @@ -172,7 +119,6 @@ public class MainFXMLController { node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> { scaleUp.play(); node.setCursor(Cursor.HAND); }); node.addEventHandler(MouseEvent.MOUSE_EXITED, e -> { scaleDown.play(); node.setCursor(Cursor.DEFAULT); }); } - private void addShadow(Node node) { DropShadow shadow = new DropShadow(); shadow.setColor(Color.rgb(0, 0, 0, 0.3)); @@ -195,237 +141,57 @@ public class MainFXMLController { } - - // ==== RENDER METHODS ==== - // BACKGROUND - private void renderBackground() { - BackgroundSize size = new BackgroundSize( - BackgroundSize.AUTO, BackgroundSize.AUTO, - false, false, true, true - ); - mainHBox.setBackground(new Background(new BackgroundImage( - new Image(getClass().getResourceAsStream("/GUIImages/Background.png")), - BackgroundRepeat.NO_REPEAT, - BackgroundRepeat.NO_REPEAT, - BackgroundPosition.CENTER, - size - ))); + // ==== ELEMENTS ==== + private StackPane createOrder(String num) { + ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Orders/order-" + num + ".png"))); + img.setFitHeight(240); + img.setPreserveRatio(true); + addClip(img); + StackPane wrapper = new StackPane(img); + return wrapper; } + private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) { + ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"))); + img.setFitHeight(240); + img.setPreserveRatio(true); + addClip(img); + StackPane wrapper = new StackPane(img); - // UPPER, LOWER AND BOARD - private void renderUpper() { - upperList.setSpacing(14); - upperList.setAlignment(Pos.CENTER); - upperList.getChildren().clear(); - - int i = 0; - for (TribeCard card : controller.miniModel.board.upperListTribe) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); - upperList.getChildren().add(img); - i++; - } - i = 0; - for (BuildingCard card : controller.miniModel.board.upperListBuilding) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(controller.myUsername, index)); - upperList.getChildren().add(img); - i++; - } - } - private void renderOrder() { - StackPane card = createOrder(Integer.toString(controller.miniModel.players.size()), false, false); - - VBox overlay = new VBox(-20); - overlay.setPickOnBounds(false); - StackPane.setAlignment(overlay, Pos.TOP_LEFT); - StackPane.setMargin(overlay, new Insets(9, 0, 0, 57)); - - int i = 0; - for (Player player : controller.miniModel.players.values()) { - final int index = i; - - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); + Player player = controller.miniModel.slotPlayerMap.get(slot); + if (player != null && controller.miniModel.getPositionByUsername(player.getUserName())!=-1) { + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); totem.setFitHeight(70); totem.setPreserveRatio(true); - if (!(controller.miniModel.orderLogicCard.getPosition(player.getUserName()) != -1 && !controller.miniModel.slotPlayerMap.containsValue(player))) { - totem.setOpacity(0.0); - } - overlay.getChildren().add(totem); - i++; + StackPane.setAlignment(totem, Pos.TOP_LEFT); + StackPane.setMargin(totem, new Insets(8, 0, 0, 57)); + wrapper.getChildren().add(totem); } - card.getChildren().add(overlay); - board.getChildren().add(card); + + if (withShadow) { + addShadow(wrapper); + } + if (withZoom) { + addHoverZoom(wrapper); + } + return wrapper; } - private void renderBoard() { - board.setSpacing(14); - board.setAlignment(Pos.CENTER); - board.getChildren().clear(); + private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow) { + String id = card.getIdIMG(); + ImageView img; + img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + id + ".png"))); + img.setFitHeight(200); + img.setPreserveRatio(true); + addClip(img); - String path = ""; - switch (controller.miniModel.currentState.getEra()) { - case 1 -> path = "/GUIImages/Backs/back-001.png"; - case 2 -> path = "/GUIImages/Backs/back-030.png"; - case 3 -> path = "/GUIImages/Backs/back-058.png"; + StackPane wrapper = new StackPane(img); + + if (withShadow) { + addShadow(wrapper); } - ImageView back = new ImageView(new Image(getClass().getResourceAsStream(path))); - back.setFitHeight(240); - back.setPreserveRatio(true); - Rectangle clip = new Rectangle(); - clip.setWidth(back.getBoundsInLocal().getWidth()); - clip.setHeight(240); - clip.setArcWidth(20); - clip.setArcHeight(20); - back.setClip(clip); - addShadow(back); - addHoverZoom(back); - board.getChildren().add(back); - - - renderOrder(); - - int i = 0; - for (Map.Entry entry : controller.miniModel.slotPlayerMap.entrySet()) { - Slot slot = entry.getKey(); - final int index = i; - StackPane img = createSlot(slot, true, true); - img.setOnMouseClicked(e -> controller.slotChoice(controller.myUsername, index)); - board.getChildren().add(img); - i++; + if (withZoom) { + addHoverZoom(wrapper); } - } - private void renderLower() { - lowerList.setSpacing(14); - lowerList.setAlignment(Pos.CENTER); - lowerList.getChildren().clear(); - - int i = 0; - for (TribeCard card : controller.miniModel.board.lowerListTribe) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index)); - lowerList.getChildren().add(img); - i++; - } - i = 0; - for (BuildingCard card : controller.miniModel.board.lowerListBuilding) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(controller.myUsername, index)); - lowerList.getChildren().add(img); - i++; - } - } - - // MY HAND - private void renderMyHand() { - myHand.getChildren().clear(); - myHand.setSpacing(14); - myHand.setAlignment(Pos.CENTER); - - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).artists); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).gatherers); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).inventors); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).builders); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).shamans); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).hunters); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).buildingCards); - } - private void drawMyHandList(HBox myHand, ArrayList cardList) { - if (!cardList.isEmpty()) { - StackPane img = createCard(cardList.getLast(), true, true); - Label label = new Label(String.valueOf(cardList.size())); - label.setTranslateY(-55); - label.setTranslateX(10); - label.getStyleClass().add("label-large"); - StackPane.setAlignment(label, Pos.TOP_RIGHT); - img.getChildren().add(label); // aggiungi il label dentro lo StackPane di createCard - img.setOnMouseClicked(e -> openPopup(cardList)); - myHand.getChildren().add(img); - } else { - Region placeholder = new Region(); - placeholder.setPrefHeight(200); - placeholder.setPrefWidth(200 * 0.675); - placeholder.setStyle("-fx-background-color: transparent;"); - myHand.getChildren().add(placeholder); - } - } - - - // SIDE PANEL - private void renderSidePanel() { - sidePanel.getChildren().clear(); - sidePanel.setSpacing(6); - - era.setText(Integer.toString(controller.miniModel.currentState.getEra())); - round.setText(Integer.toString(controller.miniModel.currentState.getRound())); - player.setText(controller.miniModel.currentState.getCurrentPlayer().getUserName()); - VBox.setMargin(info, new Insets(5, 5, 5, 5)); - sidePanel.getChildren().add(info); - - renderPlayers(sidePanel); - } - private void renderPlayers(VBox playersHand) { - for (Player player : controller.miniModel.players.values()) { - // Card container - VBox card = new VBox(3); - VBox.setMargin(card, new Insets(5)); - card.getStyleClass().add("player-card"); - card.setPadding(new Insets(8)); - addHoverZoom(card); - addShadow(card); - - // Riga 1: icona totem + nome - HBox headerRow = new HBox(8); - headerRow.setAlignment(Pos.CENTER); - int index = new ArrayList<>(controller.miniModel.players.values()).indexOf(player); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); - totem.setFitHeight(20); - totem.setPreserveRatio(true); - Label usernameLabel = new Label(player.getUserName()); - usernameLabel.getStyleClass().add("label-medium"); - if (player.getUserName().equals(controller.myUsername)) { - usernameLabel.setStyle("-fx-text-fill: #9d0208"); - } - headerRow.getChildren().addAll(totem, usernameLabel); - - // Riga 2: cibo + prestigio - HBox statsRow = new HBox(10); - statsRow.setAlignment(Pos.CENTER); - - HBox foodBox = new HBox(4); - foodBox.setAlignment(Pos.CENTER); - ImageView foodIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/Food.png"))); - foodIcon.setFitHeight(20); - foodIcon.setPreserveRatio(true); - Label foodLabel = new Label(String.valueOf(player.getFoodValue())); - foodLabel.getStyleClass().add("label-small"); - foodBox.getChildren().addAll(foodIcon, foodLabel); - - HBox prestigeBox = new HBox(1); - prestigeBox.setAlignment(Pos.CENTER); - ImageView PPIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/PrestigePoint.png"))); - PPIcon.setFitHeight(35); - PPIcon.setPreserveRatio(true); - Label prestigeLabel = new Label(String.valueOf(player.getPrestigeValue())); - prestigeLabel.getStyleClass().add("label-small"); - prestigeBox.getChildren().addAll(PPIcon, prestigeLabel); - - statsRow.getChildren().addAll(foodBox, prestigeBox); - - // Righe 3-4: icone carte (3 per riga) - HBox iconsRow1 = new HBox(6); - iconsRow1.setAlignment(Pos.CENTER); - HBox iconsRow2 = new HBox(6); - iconsRow2.setAlignment(Pos.CENTER); - renderIcons(iconsRow1, iconsRow2, player); // vedi sotto - - card.getChildren().addAll(headerRow, statsRow, iconsRow1, iconsRow2); - playersHand.getChildren().add(card); - } - + return wrapper; } private void renderIcons(HBox iconsRow1, HBox iconsRow2, Player player) { String[][] iconTypes = { @@ -450,7 +216,6 @@ public class MainFXMLController { ArrayList cards = getPlayerCards(player.getUserName(), fieldName); if (cards.isEmpty()) { ColorAdjust grayscale = new ColorAdjust(); - //grayscale.setSaturation(-1.0); icon.setEffect(grayscale); icon.setOpacity(0.3); } else { @@ -476,6 +241,236 @@ public class MainFXMLController { } + // ==== GROUPS ==== + private void renderUpper() { + upperList.setSpacing(14); + upperList.setAlignment(Pos.CENTER); + upperList.getChildren().clear(); + + int i = 0; + for (TribeCard card : controller.miniModel.board.upperListTribe) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); + upperList.getChildren().add(img); + i++; + } + i = 0; + for (BuildingCard card : controller.miniModel.board.upperListBuilding) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(controller.myUsername, index)); + upperList.getChildren().add(img); + i++; + } + } + private void renderLower() { + lowerList.setSpacing(14); + lowerList.setAlignment(Pos.CENTER); + lowerList.getChildren().clear(); + + int i = 0; + for (TribeCard card : controller.miniModel.board.lowerListTribe) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index)); + lowerList.getChildren().add(img); + i++; + } + i = 0; + for (BuildingCard card : controller.miniModel.board.lowerListBuilding) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(controller.myUsername, index)); + lowerList.getChildren().add(img); + i++; + } + } + private void renderDeck() { + String path = ""; + switch (controller.miniModel.currentState.getEra()) { + case 1 -> path = "/GUIImages/Backs/back-001.png"; + case 2 -> path = "/GUIImages/Backs/back-030.png"; + case 3 -> path = "/GUIImages/Backs/back-058.png"; + } + ImageView back = new ImageView(new Image(getClass().getResourceAsStream(path))); + back.setFitHeight(240); + back.setPreserveRatio(true); + addClip(back); + addShadow(back); + addHoverZoom(back); + board.getChildren().add(back); + } + private void renderOrder() { + StackPane card = createOrder(Integer.toString(controller.miniModel.players.size())); + + VBox overlay = new VBox(-20); + overlay.setPickOnBounds(false); + StackPane.setAlignment(overlay, Pos.TOP_LEFT); + StackPane.setMargin(overlay, new Insets(9, 0, 0, 57)); + + List ordered = controller.miniModel.players.values().stream() + .filter(p -> !controller.miniModel.orderLogicCard.players.contains(p)) + .collect(Collectors.toList()); + ordered.addAll(controller.miniModel.orderLogicCard.players); + for (Player player : ordered) { + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); + totem.setFitHeight(70); + totem.setPreserveRatio(true); + if (!controller.miniModel.orderLogicCard.players.contains(player)) { + totem.setOpacity(0.5); + } + overlay.getChildren().add(totem); + } + card.getChildren().add(overlay); + board.getChildren().add(card); + } + private void renderSlotMap() { + int i = 0; + for (Map.Entry entry : controller.miniModel.slotPlayerMap.entrySet()) { + Slot slot = entry.getKey(); + final int index = i; + StackPane img = createSlot(slot, true, true); + img.setOnMouseClicked(e -> controller.slotChoice(controller.myUsername, index)); + board.getChildren().add(img); + i++; + } + } + private void drawMyHandList(ArrayList cardList) { + if (!cardList.isEmpty()) { + StackPane img = createCard(cardList.getLast(), true, true); + Label label = new Label(String.valueOf(cardList.size())); + label.setTranslateY(-55); + label.setTranslateX(10); + label.getStyleClass().add("label-large"); + StackPane.setAlignment(label, Pos.TOP_RIGHT); + img.getChildren().add(label); + img.setOnMouseClicked(e -> openPopup(cardList)); + myHand.getChildren().add(img); + } else { + Region placeholder = new Region(); + placeholder.setPrefHeight(200); + placeholder.setPrefWidth(200 * 0.675); + placeholder.setStyle("-fx-background-color: transparent;"); + myHand.getChildren().add(placeholder); + } + } + private void renderPlayer(Player player) { + VBox card = new VBox(3); + VBox.setMargin(card, new Insets(5)); + card.getStyleClass().add("player-card"); + card.setPadding(new Insets(8)); + addHoverZoom(card); + addShadow(card); + + // Riga 1: icona totem + nome + HBox headerRow = new HBox(8); + headerRow.setAlignment(Pos.CENTER); + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); + totem.setFitHeight(20); + totem.setPreserveRatio(true); + Label usernameLabel = new Label(player.getUserName()); + usernameLabel.getStyleClass().add("label-medium"); + if (player.getUserName().equals(controller.myUsername)) { + usernameLabel.setStyle("-fx-text-fill: #9d0208"); + } + headerRow.getChildren().addAll(totem, usernameLabel); + + // Riga 2: cibo + prestigio + HBox statsRow = new HBox(10); + statsRow.setAlignment(Pos.CENTER); + + HBox foodBox = new HBox(4); + foodBox.setAlignment(Pos.CENTER); + ImageView foodIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/Food.png"))); + foodIcon.setFitHeight(20); + foodIcon.setPreserveRatio(true); + Label foodLabel = new Label(String.valueOf(player.getFoodValue())); + foodLabel.getStyleClass().add("label-small"); + foodBox.getChildren().addAll(foodIcon, foodLabel); + + HBox prestigeBox = new HBox(1); + prestigeBox.setAlignment(Pos.CENTER); + ImageView PPIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/PrestigePoint.png"))); + PPIcon.setFitHeight(35); + PPIcon.setPreserveRatio(true); + Label prestigeLabel = new Label(String.valueOf(player.getPrestigeValue())); + prestigeLabel.getStyleClass().add("label-small"); + prestigeBox.getChildren().addAll(PPIcon, prestigeLabel); + + statsRow.getChildren().addAll(foodBox, prestigeBox); + + // Righe 3-4: icone carte (3 per riga) + HBox iconsRow1 = new HBox(6); + iconsRow1.setAlignment(Pos.CENTER); + HBox iconsRow2 = new HBox(6); + iconsRow2.setAlignment(Pos.CENTER); + renderIcons(iconsRow1, iconsRow2, player); // vedi sotto + + card.getChildren().addAll(headerRow, statsRow, iconsRow1, iconsRow2); + sidePanel.getChildren().add(card); + } + + + // ==== ABSOLUTES ==== + private void renderBackground() { + BackgroundSize size = new BackgroundSize( + BackgroundSize.AUTO, BackgroundSize.AUTO, + false, false, true, true + ); + mainHBox.setBackground(new Background(new BackgroundImage( + new Image(getClass().getResourceAsStream("/GUIImages/Background.png")), + BackgroundRepeat.NO_REPEAT, + BackgroundRepeat.NO_REPEAT, + BackgroundPosition.CENTER, + size + ))); + } + private void renderBoard() { + board.setSpacing(14); + board.setAlignment(Pos.CENTER); + board.getChildren().clear(); + renderDeck(); + renderOrder(); + renderSlotMap(); + } + private void renderMyHand() { + myHand.getChildren().clear(); + myHand.setSpacing(14); + myHand.setAlignment(Pos.CENTER); + + drawMyHandList(controller.miniModel.players.get(controller.myUsername).artists); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).gatherers); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).inventors); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).builders); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).shamans); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).hunters); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).buildingCards); + } + private void renderSidePanel() { + sidePanel.getChildren().clear(); + sidePanel.setSpacing(6); + + era.setText(Integer.toString(controller.miniModel.currentState.getEra())); + round.setText(Integer.toString(controller.miniModel.currentState.getRound())); + player.setText(controller.miniModel.currentState.getCurrentPlayer().getUserName()); + VBox.setMargin(info, new Insets(5, 5, 5, 5)); + sidePanel.getChildren().add(info); + + for (Player player : controller.miniModel.players.values()) { + renderPlayer(player); + } + } + + + + + + + + + + // POPUP private void initPopup() { popupCards = new HBox(10); @@ -489,12 +484,7 @@ public class MainFXMLController { "-fx-background-radius: 10;" ); - Rectangle clip = new Rectangle(); - clip.setArcWidth(20); - clip.setArcHeight(20); - clip.widthProperty().bind(popupCards.widthProperty()); - clip.heightProperty().bind(popupCards.heightProperty()); - popupCards.setClip(clip); + addClip(popupCards); popup = new Popup(); popup.getContent().add(popupCards); diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 3adc89b..d9c6aee 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -5,6 +5,7 @@ module it.polimi.ingsw.gc14 { requires java.rmi; requires java.smartcardio; requires com.google.gson; + requires java.desktop; opens it.polimi.ingsw.gc14 to javafx.fxml, com.google.gson; opens it.polimi.ingsw.gc14.Model to com.google.gson; From 711d57e4cdf2a64af3152d2ba85d6171597ebe1e Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 14 May 2026 16:42:19 +0200 Subject: [PATCH 03/13] Removed property changes --- .../it/polimi/ingsw/gc14/Model/MiniModel.java | 33 ++----------------- .../ingsw/gc14/Model/OrderLogicCard.java | 2 +- .../gc14/View/GUI/MainFXMLController.java | 27 +++------------ 3 files changed, 8 insertions(+), 54 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java b/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java index 4a51fb8..78c9d10 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java @@ -6,15 +6,12 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Model.GamePackage.Board; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; + import java.io.Serializable; import java.util.*; public class MiniModel implements Serializable { - private final PropertyChangeSupport support = new PropertyChangeSupport(this); - public Board board; public Map slotPlayerMap; public OrderLogicCard orderLogicCard; @@ -22,7 +19,7 @@ public class MiniModel implements Serializable { public Map players; public List availableTotems; - // --- Costruttori invariati --- + // --- Costruttori --- public MiniModel() { @@ -43,63 +40,39 @@ public class MiniModel implements Serializable { setPlayers(players); } - // --- Gestione listener --- - public void addPropertyChangeListener(PropertyChangeListener listener) { - support.addPropertyChangeListener(listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - support.removePropertyChangeListener(listener); - } - - // --- Setter con notifica --- + // --- Setter --- public void setBoard(Board board) { - Board old = this.board; this.board = board; - support.firePropertyChange("board", old, board); } public void setAvailableTotems(List availableTotems) { - List old = this.availableTotems; this.availableTotems = availableTotems; - support.firePropertyChange("availableTotems", old, availableTotems); } public void setSlotPlayerMap(Map slotPlayerMap) { - Map old = this.slotPlayerMap; this.slotPlayerMap = slotPlayerMap; - support.firePropertyChange("slotPlayerMap", old, slotPlayerMap); } public void setOrderLogicCard(OrderLogicCard orderLogicCard) { - OrderLogicCard old = this.orderLogicCard; this.orderLogicCard = orderLogicCard; - support.firePropertyChange("orderLogicCard", old, orderLogicCard); } public void setCurrentState(CurrentState currentState) { - CurrentState old = this.currentState; this.currentState = currentState; - support.firePropertyChange("currentState", old, currentState); } public void setPlayers(List players) { - Map old = new HashMap<>(this.players != null ? this.players : new HashMap<>()); for (Player player : players) { this.players.put(player.getUserName(), player); } - support.firePropertyChange("players", old, this.players); } public void setPlayer(Player player) { - Map old = new HashMap<>(this.players); players.put(player.getUserName(), player); - support.firePropertyChange("players", old, this.players); } - // --- Metodi invariati --- public int getPositionByUsername(String username) { int i = 0; diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java index f90ecfd..2d4e293 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java @@ -25,7 +25,7 @@ public abstract class OrderLogicCard implements Serializable { /** * The list of {@link Player Players} associated with this order logic card. */ - protected List playerList; + public List playerList; /** diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 1b6f676..7e359cd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -6,6 +6,7 @@ import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.GamePackage.Board; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; +import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer; import javafx.animation.ScaleTransition; import javafx.application.Platform; import javafx.event.Event; @@ -70,25 +71,9 @@ public class MainFXMLController { // Initialize popup initPopup(); - - - controller.miniModel.addPropertyChangeListener(evt -> { - switch (evt.getPropertyName()) { - case "board" -> ciao("board"); - case "currentState" -> ciao("currentState"); - case "players" -> Platform.runLater(() -> renderSidePanel()); - case "slotPlayerMap" -> Platform.runLater(() -> renderBoard()); - case "orderLogicCard"-> Platform.runLater(() -> renderBoard()); - case "availableTotems"-> ciao("availableTotems"); - } - }); } - public void ciao(String s) { - System.out.println(s); - } - public void render() { renderBackground(); @@ -309,15 +294,11 @@ public class MainFXMLController { StackPane.setAlignment(overlay, Pos.TOP_LEFT); StackPane.setMargin(overlay, new Insets(9, 0, 0, 57)); - List ordered = controller.miniModel.players.values().stream() - .filter(p -> !controller.miniModel.orderLogicCard.players.contains(p)) - .collect(Collectors.toList()); - ordered.addAll(controller.miniModel.orderLogicCard.players); - for (Player player : ordered) { - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); + for (OrderPlayer player : controller.miniModel.orderLogicCard.playerList) { + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); totem.setFitHeight(70); totem.setPreserveRatio(true); - if (!controller.miniModel.orderLogicCard.players.contains(player)) { + if(controller.miniModel.slotPlayerMap.containsValue(player.player)) { totem.setOpacity(0.5); } overlay.getChildren().add(totem); From b53d58528dd691998549bb1df07a2119d03d0c14 Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 14 May 2026 18:11:53 +0200 Subject: [PATCH 04/13] Modular rendering based on game stage --- .../gc14/View/GUI/MainFXMLController.java | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 7e359cd..d12ec6f 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -6,6 +6,7 @@ import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.GamePackage.Board; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; +import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer; import javafx.animation.ScaleTransition; import javafx.application.Platform; @@ -31,6 +32,9 @@ import javafx.util.Duration; import java.util.*; import java.util.stream.Collectors; +import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.RES_ACTIONS; +import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.SLOT_CHOICE; + public class MainFXMLController { @FXML private HBox mainHBox; @@ -51,6 +55,9 @@ public class MainFXMLController { private HBox popupCards; private ClientController controller; + private CurrentState old_state; + private CurrentState new_state; + public void setController(ClientController controller) { this.controller = controller; @@ -61,6 +68,9 @@ public class MainFXMLController { @FXML public void initialize() { + old_state=null; + new_state=null; + // Import font and apply CSS Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14); mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> { @@ -76,12 +86,34 @@ public class MainFXMLController { public void render() { - renderBackground(); - renderUpper(); - renderBoard(); - renderLower(); - renderMyHand(); - renderSidePanel(); + new_state=controller.miniModel.currentState; + + System.out.println("OLD: "+old_state+", NEW: "+new_state); + if (old_state==null) { + renderBackground(); + renderUpper(); + renderBoard(); + renderLower(); + renderMyHand(); + renderSidePanel(); + } else if (old_state.getGameStage()==SLOT_CHOICE) { + System.out.println("RIDISEGNO BOARD\n"); + renderBoard(); + } else if (old_state.getGameStage()==RES_ACTIONS) { + System.out.println("RIDISEGNO TUTTO"); + renderUpper(); + renderBoard(); + renderLower(); + renderSidePanel(); + renderMyHand(); + // TODO: se sono io a pescare renderizzo myHand, altrimenti no (non è scontato) + } else { + System.out.println("NON GESTITO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + } + + old_state=new_state; + // TODO: le info in sidepanel non vengono aggiornate sempre aggiornate, bisogna prima capire dove metterle + } @@ -233,7 +265,7 @@ public class MainFXMLController { upperList.getChildren().clear(); int i = 0; - for (TribeCard card : controller.miniModel.board.upperListTribe) { + for (TribeCard card : new ArrayList<>(controller.miniModel.board.upperListTribe)) { final int index = i; StackPane img = createCard(card, true, true); img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); From 67e318f236774be257dde1c1f7b6c2f5ea8212ee Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 14 May 2026 18:30:57 +0200 Subject: [PATCH 05/13] tmp --- .../gc14/View/GUI/MainFXMLController.java | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index d12ec6f..db5e486 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -55,8 +55,8 @@ public class MainFXMLController { private HBox popupCards; private ClientController controller; - private CurrentState old_state; - private CurrentState new_state; + private GameStages old_state_stage; + private String old_state_username; public void setController(ClientController controller) { @@ -68,8 +68,9 @@ public class MainFXMLController { @FXML public void initialize() { - old_state=null; - new_state=null; + old_state_stage=null; + old_state_username=""; + // Import font and apply CSS Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14); @@ -86,32 +87,38 @@ public class MainFXMLController { public void render() { - new_state=controller.miniModel.currentState; - System.out.println("OLD: "+old_state+", NEW: "+new_state); - if (old_state==null) { + if (old_state_stage==null) { renderBackground(); renderUpper(); renderBoard(); renderLower(); renderMyHand(); renderSidePanel(); - } else if (old_state.getGameStage()==SLOT_CHOICE) { + } else if (old_state_stage==SLOT_CHOICE) { + System.out.println("OLD: "+old_state_stage+", NEW: "+controller.miniModel.currentState.getGameStage()); System.out.println("RIDISEGNO BOARD\n"); renderBoard(); - } else if (old_state.getGameStage()==RES_ACTIONS) { - System.out.println("RIDISEGNO TUTTO"); + } else if (old_state_stage==RES_ACTIONS) { + System.out.println("OLD: "+old_state_stage+", NEW: "+controller.miniModel.currentState.getGameStage()); + System.out.println("RIDISEGNO TUTTO. USERNAME: "+old_state_username); renderUpper(); renderBoard(); renderLower(); renderSidePanel(); - renderMyHand(); + //renderMyHand(); + + if (old_state_username==controller.myUsername) { + renderMyHand(); + } + // TODO: se sono io a pescare renderizzo myHand, altrimenti no (non è scontato) } else { System.out.println("NON GESTITO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } - old_state=new_state; + old_state_stage=controller.miniModel.currentState.getGameStage(); + old_state_username=controller.miniModel.currentState.getCurrentPlayer().getUserName(); // TODO: le info in sidepanel non vengono aggiornate sempre aggiornate, bisogna prima capire dove metterle } From 7f86debfabb87927e6459e89b259ffa1fd460877 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 14 May 2026 18:50:18 +0200 Subject: [PATCH 06/13] Fixed: MyHand modular drawing --- .../it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index db5e486..d4bc157 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -95,7 +95,7 @@ public class MainFXMLController { renderLower(); renderMyHand(); renderSidePanel(); - } else if (old_state_stage==SLOT_CHOICE) { + } else if (old_state_stage==SLOT_CHOICE ) { System.out.println("OLD: "+old_state_stage+", NEW: "+controller.miniModel.currentState.getGameStage()); System.out.println("RIDISEGNO BOARD\n"); renderBoard(); @@ -106,9 +106,8 @@ public class MainFXMLController { renderBoard(); renderLower(); renderSidePanel(); - //renderMyHand(); - if (old_state_username==controller.myUsername) { + if (Objects.equals(old_state_username, controller.myUsername)) { renderMyHand(); } From 9de74b945b5db21113e82c8941c0f04315b109d6 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 14 May 2026 19:14:33 +0200 Subject: [PATCH 07/13] Fixed: Board Final events, idFormat --- .../java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java index ac2c9e5..6e3023c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java @@ -176,8 +176,8 @@ public class Board implements Serializable { tribeDeck_temp.addAll(era1); tribeDeck_temp.addAll(era2); tribeDeck_temp.addAll(era3); - tribeDeck_temp.add(new Sustenance("95",3,3)); - tribeDeck_temp.add(new ShamanicRitual("96",3,15,7)); + tribeDeck_temp.add(new Sustenance("095",3,3)); + tribeDeck_temp.add(new ShamanicRitual("096",3,15,7)); return tribeDeck_temp; } From ad49cb670cd471a97ad59f6d9eb155b05ec08737 Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 14 May 2026 19:47:28 +0200 Subject: [PATCH 08/13] Window dimension is dynamic now --- .../gc14/View/GUI/MainFXMLController.java | 1 - src/main/resources/GUIScene/main.fxml | 30 ++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index d4bc157..0bb5baf 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -106,7 +106,6 @@ public class MainFXMLController { renderBoard(); renderLower(); renderSidePanel(); - if (Objects.equals(old_state_username, controller.myUsername)) { renderMyHand(); } diff --git a/src/main/resources/GUIScene/main.fxml b/src/main/resources/GUIScene/main.fxml index 62d9eb4..b72f4cf 100644 --- a/src/main/resources/GUIScene/main.fxml +++ b/src/main/resources/GUIScene/main.fxml @@ -1,15 +1,23 @@ - - - + - - + + @@ -37,8 +45,13 @@ - - + + @@ -67,5 +80,6 @@ + - + \ No newline at end of file From f965e8ee60131cce1bf2c67bcd5218d1220c0504 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 14 May 2026 20:31:23 +0200 Subject: [PATCH 09/13] Fixed: upperListFixed --- .../java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 0bb5baf..5274d97 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -270,7 +270,7 @@ public class MainFXMLController { upperList.getChildren().clear(); int i = 0; - for (TribeCard card : new ArrayList<>(controller.miniModel.board.upperListTribe)) { + for (TribeCard card : controller.miniModel.board.upperListTribe) { final int index = i; StackPane img = createCard(card, true, true); img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); From dbcefe254b9a173c962ff4410de8a94b6a11c408 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Fri, 15 May 2026 15:11:07 +0200 Subject: [PATCH 10/13] Updated: Totem CHoice fxml and controller --- .../it/polimi/ingsw/gc14/ServerLauncher.java | 2 +- .../it/polimi/ingsw/gc14/View/GUI/GUI.java | 2 + .../gc14/View/GUI/TotemFXMLController.java | 195 +++++++++++++++++- src/main/resources/GUIScene/totem.fxml | 81 +++++++- 4 files changed, 265 insertions(+), 15 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java index 1fe83c8..9730192 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java +++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java @@ -265,7 +265,7 @@ public class ServerLauncher { break; } catch(RemoteException e){ - throw new RuntimeException(e); + System.out.println("Exception:"+e.getMessage()); } } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java index de29419..9dd099e 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java @@ -84,11 +84,13 @@ public class GUI extends Application implements IView { Platform.runLater(() -> { controllerTotem.render(); primaryStage.setScene(totemScene); + primaryStage.setFullScreen(true); }); } else { Platform.runLater(() -> { controllerMain.render(); primaryStage.setScene(mainScene); + primaryStage.setFullScreen(true); }); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java index 5b606b3..4639277 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java @@ -1,40 +1,213 @@ package it.polimi.ingsw.gc14.View.GUI; import it.polimi.ingsw.gc14.Controller.ClientController; -import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Model.Totems; +import javafx.animation.*; import javafx.fxml.FXML; +import javafx.geometry.Pos; +import javafx.geometry.Rectangle2D; +import javafx.scene.Cursor; +import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.layout.HBox; +import javafx.scene.layout.*; +import javafx.stage.Screen; +import javafx.util.Duration; import java.util.Locale; +import java.util.Objects; public class TotemFXMLController { + + public ImageView backgroundImage; @FXML private HBox mainHBox; + @FXML private Label turnBanner; + @FXML private Label selectedLabel; + @FXML private Button confirmButton; private ClientController controller; + private int selectedIndex = -1; + private StackPane selectedFrame = null; public void setController(ClientController controller) { - this.controller=controller; + this.controller = controller; } @FXML public void initialize() { - + Image img = new Image(getClass().getResourceAsStream("/GUIImages/Background.png")); + backgroundImage.setImage(img); + Rectangle2D screenBounds = Screen.getPrimary().getBounds(); + backgroundImage.setFitWidth(screenBounds.getWidth()); + backgroundImage.setFitHeight(screenBounds.getHeight()); } public void render() { mainHBox.getChildren().clear(); - for (Totems totem : controller.miniModel.availableTotems) { - ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_"+ String.valueOf(totem).toLowerCase(Locale.ROOT) +".png"))); - img.setFitHeight(240); - img.setPreserveRatio(true); - img.setOnMouseClicked(e -> controller.totemChoice(controller.myUsername, controller.miniModel.availableTotems.indexOf(totem))); - mainHBox.getChildren().add(img); + selectedIndex = -1; + selectedFrame = null; + selectedLabel.setText(""); + + String chooser = controller.miniModel.currentState.getCurrentPlayer().getUserName(); // adatta al tuo campo + boolean myTurn = chooser.equals(controller.myUsername); + + updateBanner(chooser, myTurn); + updateConfirmButton(false); + + for (int i = 0; i < controller.miniModel.availableTotems.size(); i++) { + Totems totem = controller.miniModel.availableTotems.get(i); + VBox card = buildCard(totem, i, myTurn); + mainHBox.getChildren().add(card); + + card.setOpacity(0); + card.setTranslateY(14); + PauseTransition delay = new PauseTransition(Duration.millis(80 + i * 65)); + delay.setOnFinished(e -> { + FadeTransition ft = new FadeTransition(Duration.millis(320), card); + ft.setToValue(1); + TranslateTransition tt = new TranslateTransition(Duration.millis(320), card); + tt.setToY(0); + new ParallelTransition(ft, tt).play(); + }); + delay.play(); } } + private void updateBanner(String chooser, boolean myTurn) { + if (myTurn) { + turnBanner.setText("✦ It's your turn to choice ✦"); + turnBanner.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 13; -fx-letter-spacing: 3;" + + "-fx-text-fill: #f4c05a;" + + "-fx-background-color: rgba(244,192,90,0.1);" + + "-fx-border-color: rgba(244,192,90,0.45); -fx-border-width: 1;" + + "-fx-border-radius: 3; -fx-background-radius: 3;" + + "-fx-padding: 10 28 10 28;" + + "-fx-effect: dropshadow(gaussian, rgba(244,192,90,0.3), 18, 0, 0, 0);" + ); + } else { + turnBanner.setText("Waiting " + chooser + " chooses his totem…"); + turnBanner.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 11; -fx-letter-spacing: 2;" + + "-fx-text-fill: rgba(200,155,90,0.6);" + + "-fx-background-color: rgba(120,60,10,0.18);" + + "-fx-border-color: rgba(200,120,20,0.22); -fx-border-width: 1;" + + "-fx-border-radius: 3; -fx-background-radius: 3;" + + "-fx-padding: 10 28 10 28;" + ); + } + } + private VBox buildCard(Totems totem, int idx, boolean interactive) { + ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + String.valueOf(totem).toLowerCase(Locale.ROOT) + ".png"))); + img.setFitHeight(150); + img.setPreserveRatio(true); -} + StackPane frame = new StackPane(img); + frame.setPrefSize(100, 145); + frame.setBackground(Background.EMPTY); + img.setStyle(frameStyle(false)); + + Region base = new Region(); + base.setPrefSize(100, 10); + + Label name = new Label(capitalize(totem)); + name.setStyle(nameStyle(false)); + + VBox card = new VBox(4, frame, base, name); + card.setAlignment(Pos.CENTER); + + if (!interactive) { + card.setOpacity(0.35); + card.setCursor(Cursor.DEFAULT); + return card; + } + + card.setCursor(Cursor.HAND); + + card.setOnMouseEntered(e -> { + if (frame != selectedFrame) { + ScaleTransition st = new ScaleTransition(Duration.millis(140), card); + st.setToX(1.06); st.setToY(1.06); st.play(); + } + }); + card.setOnMouseExited(e -> { + if (frame != selectedFrame) { + ScaleTransition st = new ScaleTransition(Duration.millis(140), card); + st.setToX(1.0); st.setToY(1.0); st.play(); + } + }); + + card.setOnMouseClicked(e -> { + // reset tutti + mainHBox.getChildren().forEach(n -> { + if (n instanceof VBox v) { + StackPane f = (StackPane) v.getChildren().get(0); + Label l = (Label) v.getChildren().get(2); + f.setStyle(frameStyle(false)); + l.setStyle(nameStyle(false)); + ScaleTransition st = new ScaleTransition(Duration.millis(130), v); + st.setToX(1.0); st.setToY(1.0); st.play(); + } + }); + + frame.setStyle(frameStyle(true)); + name.setStyle(nameStyle(true)); + selectedFrame = frame; + selectedIndex = idx; + + ScaleTransition pop = new ScaleTransition(Duration.millis(160), card); + pop.setToX(1.08); pop.setToY(1.08); + pop.setAutoReverse(true); pop.setCycleCount(2); pop.play(); + + selectedLabel.setText(capitalize(totem).toUpperCase() + " choice"); + updateConfirmButton(true); + }); + + return card; + } + + private void updateConfirmButton(boolean enabled) { + confirmButton.setDisable(!enabled); + confirmButton.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 12; -fx-font-weight: bold;" + + "-fx-letter-spacing: 4; -fx-text-fill: #0c0601;" + + "-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" + + "-fx-padding: 12 48 12 48; -fx-background-radius: 2;" + + "-fx-opacity: " + (enabled ? "1.0" : "0.3") + ";" + + "-fx-cursor: " + (enabled ? "hand" : "default") + ";" + ); + } + + private String frameStyle(boolean selected) { + return " " + + "-fx-border-color: " + (selected ? "#f4c05a" : "rgba(200,120,20,0.28)") + ";" + + "-fx-border-width: " + (selected ? "2" : "0") + ";" + + "-fx-border-radius: 4 4 0 0; -fx-background-radius: 4 4 0 0;" + + (selected ? "-fx-effect: dropshadow(gaussian, rgba(244,192,90,0.35), 22, 0, 0, 0);" : ""); + } + + private String nameStyle(boolean selected) { + return "-fx-font-family: 'Cinzel'; -fx-font-size: 10; -fx-letter-spacing: 2;" + + "-fx-text-fill: " + (selected ? "#f4c05a" : "rgba(200,175,130,0.65)") + ";"; + } + + private String capitalize(Totems t) { + String s = t.name().toLowerCase(Locale.ROOT); + return Character.toUpperCase(s.charAt(0)) + s.substring(1); + } + + private String totemElement(Totems t) { + return switch (t) { + default -> t.name(); + }; + } + + @FXML + private void onConfirm() { + if (selectedIndex >= 0) { + controller.totemChoice(controller.myUsername, selectedIndex); + } + } +} \ No newline at end of file diff --git a/src/main/resources/GUIScene/totem.fxml b/src/main/resources/GUIScene/totem.fxml index 9e41caa..c28226b 100644 --- a/src/main/resources/GUIScene/totem.fxml +++ b/src/main/resources/GUIScene/totem.fxml @@ -1,6 +1,81 @@ - + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + +