From 0fe7941c3e5fd4889f17d856dcae0c150ea1f4cd Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Sun, 17 May 2026 21:40:07 +0200 Subject: [PATCH 1/7] Add: Added Building Icon in Player Side Panel --- .../gc14/View/GUI/MainFXMLController.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 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 e40e817..45899f9 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 @@ -236,6 +236,7 @@ public class MainFXMLController { case "builders" -> new ArrayList<>(p.builders); case "shamans" -> new ArrayList<>(p.shamans); case "hunters" -> new ArrayList<>(p.hunters); + case "building" -> new ArrayList<>(p.buildingCards); default -> new ArrayList<>(); }; } @@ -345,7 +346,7 @@ public class MainFXMLController { } headerRow.getChildren().addAll(totem, usernameLabel); - // Riga 2: cibo + prestigio + // Riga 2: cibo + prestigio + building HBox statsRow = new HBox(10); statsRow.setAlignment(Pos.CENTER); @@ -367,13 +368,31 @@ public class MainFXMLController { prestigeLabel.getStyleClass().add("label-small"); prestigeBox.getChildren().addAll(PPIcon, prestigeLabel); - statsRow.getChildren().addAll(foodBox, prestigeBox); + ImageView icon = new ImageView(); + icon.setFitWidth(28); + icon.setFitHeight(28); + icon.setPreserveRatio(true); + icon.setImage(loadImage("/GUIImages/Icons/Building.png")); + + ArrayList cards = getPlayerCards(player.getUserName(), "building"); + if (cards.isEmpty()) { + ColorAdjust grayscale = new ColorAdjust(); + icon.setEffect(grayscale); + icon.setOpacity(0.3); + } else { + icon.setOnMouseClicked(e -> openPopup(new ArrayList<>(cards))); + addHoverZoom(icon); + } + + statsRow.getChildren().addAll(foodBox, prestigeBox,icon); // Righe 3-4: icone carte HBox iconsRow1 = new HBox(6); + iconsRow1.setSpacing(20); iconsRow1.setAlignment(Pos.CENTER); HBox iconsRow2 = new HBox(6); iconsRow2.setAlignment(Pos.CENTER); + iconsRow2.setSpacing(20); renderIcons(iconsRow1, iconsRow2, player); card.getChildren().addAll(headerRow, statsRow, iconsRow1, iconsRow2); From 8f8491b1ad2c26c10a56dce7b984d5e324268a5c Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Sun, 17 May 2026 22:12:38 +0200 Subject: [PATCH 2/7] Add: Added SKipTurn Button and Details Button. Fixed: TCP now display leaderboard --- .../gc14/Network/TCP/Client/TCPClient.java | 8 +--- .../View/GUI/LeaderboardFXMLController.java | 46 ++++++++++--------- .../gc14/View/GUI/MainFXMLController.java | 30 ++++++++++++ src/main/resources/GUIScene/styles.css | 14 ++++++ 4 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java index 8ce4d76..efd91db 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java @@ -161,18 +161,14 @@ public class TCPClient implements IClient { if (event.getIsError()) { controller.view.showError(event.toString()); } else { - synchronized (controller) { - event.apply(controller.miniModel); - } - controller.view.render(); - + controller.view.applyAndRender(event); } } else if (read instanceof MiniModel model) { synchronized (controller) { controller.setModel(model); + controller.view.render(); } - controller.view.render(); } } catch (ClassNotFoundException e) { diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java index 564759d..36fed83 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java @@ -66,32 +66,34 @@ public class LeaderboardFXMLController { public void render() { rankingList.getChildren().clear(); + if(controller.miniModel.standingPlayers!=null) + { + List sorted = controller.miniModel.standingPlayers; - List sorted = controller.miniModel.standingPlayers; + boolean iWon = sorted.get(0).getUserName().equals(controller.myUsername); - boolean iWon = sorted.get(0).getUserName().equals(controller.myUsername); + // Label grande Winner / Game Over + Label outcomeLabel = new Label(iWon ? "\uD83C\uDFC6 WINNER! \uD83C\uDFC6" : "GAME OVER"); + outcomeLabel.setStyle( + "-fx-font-size: 64px;" + + "-fx-font-weight: bold;" + + "-fx-text-fill: " + (iWon ? "#FFD700;" : "#FF4444;") + ); + DropShadow glow = new DropShadow(); + glow.setColor(iWon ? Color.rgb(255, 200, 0, 0.95) : Color.rgb(220, 0, 0, 0.95)); + glow.setRadius(35); + glow.setSpread(0.35); + outcomeLabel.setEffect(glow); + rankingList.getChildren().add(outcomeLabel); - // Label grande Winner / Game Over - Label outcomeLabel = new Label(iWon ? "\uD83C\uDFC6 WINNER! \uD83C\uDFC6" : "GAME OVER"); - outcomeLabel.setStyle( - "-fx-font-size: 64px;" + - "-fx-font-weight: bold;" + - "-fx-text-fill: " + (iWon ? "#FFD700;" : "#FF4444;") - ); - DropShadow glow = new DropShadow(); - glow.setColor(iWon ? Color.rgb(255, 200, 0, 0.95) : Color.rgb(220, 0, 0, 0.95)); - glow.setRadius(35); - glow.setSpread(0.35); - outcomeLabel.setEffect(glow); - rankingList.getChildren().add(outcomeLabel); + // Separatore + Region sep = new Region(); + sep.setPrefHeight(16); + rankingList.getChildren().add(sep); - // Separatore - Region sep = new Region(); - sep.setPrefHeight(16); - rankingList.getChildren().add(sep); - - for (int i = 0; i < sorted.size(); i++) { - rankingList.getChildren().add(createPlayerRow(i + 1, sorted.get(i))); + for (int i = 0; i < sorted.size(); i++) { + rankingList.getChildren().add(createPlayerRow(i + 1, sorted.get(i))); + } } } 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 45899f9..c2559d1 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 @@ -498,6 +498,25 @@ public class MainFXMLController { VBox.setMargin(info, new Insets(5, 5, 5, 5)); sidePanel.getChildren().add(info); + // ===== NUOVO: bottoni Skip Turn e Dettagli ===== + HBox buttonRow = new HBox(8); + buttonRow.setAlignment(Pos.CENTER); + VBox.setMargin(buttonRow, new Insets(0, 5, 5, 5)); + + javafx.scene.control.Button skipBtn = new javafx.scene.control.Button("Skip Turn"); + skipBtn.getStyleClass().add("action-button"); + skipBtn.setOnAction(e -> controller.skipTurn(controller.myUsername)); + addHoverZoom(skipBtn); + + javafx.scene.control.Button detailsBtn = new javafx.scene.control.Button("Ending Details"); + detailsBtn.getStyleClass().add("action-button"); + detailsBtn.setOnAction(e -> openDetailsPopup()); + addHoverZoom(detailsBtn); + + buttonRow.getChildren().addAll(skipBtn, detailsBtn); + sidePanel.getChildren().add(buttonRow); + // ================================================ + for (Player player : controller.miniModel.players.values()) { renderPlayer(player); } @@ -574,4 +593,15 @@ public class MainFXMLController { } showPopup(); } + private void openDetailsPopup() { + popupCards.getChildren().clear(); + ImageView img = new ImageView(loadImage("/GUIImages/Backs/back-118.png")); + img.setFitHeight(290); + img.setPreserveRatio(true); + addClip(img); + StackPane wrapper = new StackPane(img); + addShadow(wrapper); + popupCards.getChildren().add(wrapper); + showPopup(); + } } \ No newline at end of file diff --git a/src/main/resources/GUIScene/styles.css b/src/main/resources/GUIScene/styles.css index 77d2670..6a47c47 100644 --- a/src/main/resources/GUIScene/styles.css +++ b/src/main/resources/GUIScene/styles.css @@ -47,4 +47,18 @@ -fx-background-insets: 0, 5, 10, 15; -fx-background-radius: 15, 12, 8, 4; -fx-padding: 15 15 15 15; +} +.action-button { + -fx-background-color: #9d0208; + -fx-text-fill: white; + -fx-font-family: "Inknut Antiqua"; + -fx-font-size: 11px; + -fx-background-radius: 8; + -fx-border-radius: 8; + -fx-padding: 4 10 4 10; + -fx-cursor: hand; +} + +.action-button:hover { + -fx-background-color: #b42224; } \ No newline at end of file From e3d5f82ad0426d7103a806a9f59aafe814ae3c39 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Mon, 18 May 2026 13:00:26 +0200 Subject: [PATCH 3/7] Fixed: now main window and leaderboard contents are adapted to window size, Added: scrollable popup leaderboard --- .../View/GUI/LeaderboardFXMLController.java | 17 ++- .../gc14/View/GUI/MainFXMLController.java | 77 ++++++----- src/main/resources/GUIScene/main.fxml | 121 ++++++++++-------- src/main/resources/GUIScene/standing.fxml | 16 +-- 4 files changed, 129 insertions(+), 102 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java index 36fed83..548f459 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java @@ -6,6 +6,7 @@ import javafx.animation.ScaleTransition; import it.polimi.ingsw.gc14.Model.PlayableCard; import javafx.event.Event; import javafx.fxml.FXML; +import javafx.scene.control.ScrollPane; import javafx.stage.Popup; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -291,11 +292,8 @@ public class LeaderboardFXMLController { // Carte piccole in riga for (PlayableCard card : cards) { ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png")); - img.setFitHeight(160); + img.setFitHeight(230); img.setPreserveRatio(true); - // Tooltip al hover: mostra la carta grande in un secondo popup - img.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> img.setFitHeight(180)); - img.addEventHandler(MouseEvent.MOUSE_EXITED, e -> img.setFitHeight(160)); img.setCursor(Cursor.HAND); row.getChildren().add(img); } @@ -309,11 +307,16 @@ public class LeaderboardFXMLController { grid.getChildren().add(empty); } - grid.setMaxHeight(460); - grid.setMaxWidth(680); - popupContent.getChildren().add(grid); + ScrollPane scrollPane = new ScrollPane(grid); + scrollPane.setFitToWidth(true); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); + scrollPane.setStyle("-fx-background: transparent; -fx-background-color: transparent;"); +// altezza massima = 80% della finestra Window window = rootPane.getScene().getWindow(); + scrollPane.setMaxHeight(window.getHeight() * 0.8); + popupContent.getChildren().add(scrollPane); popup.show(window, 0, 0); popup.getScene().setFill(Color.TRANSPARENT); popup.setX(window.getX() + (window.getWidth() - popup.getWidth()) / 2); 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 c2559d1..84ee485 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 @@ -7,7 +7,10 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer; import it.polimi.ingsw.gc14.Network.EventType; import it.polimi.ingsw.gc14.Network.NetworkEvent; +import javafx.animation.AnimationTimer; +import javafx.animation.PauseTransition; import javafx.animation.ScaleTransition; +import javafx.application.Platform; import javafx.event.Event; import javafx.fxml.FXML; import javafx.geometry.Insets; @@ -24,6 +27,7 @@ import javafx.scene.paint.Color; import javafx.scene.shape.*; import javafx.scene.text.Font; import javafx.stage.Popup; +import javafx.stage.Stage; import javafx.stage.Window; import javafx.util.Duration; @@ -67,11 +71,8 @@ public class MainFXMLController { mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> { if (newScene != null) { newScene.getRoot().applyCss(); - // chiudi popup cliccando fuori da esso newScene.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> { - if (popup.isShowing()) { - popup.hide(); - } + if (popup.isShowing()) popup.hide(); }); } }); @@ -107,13 +108,15 @@ public class MainFXMLController { // ==== EFFECTS ==== - private void addClip(Node node) { + private void addClip(ImageView img) { Rectangle clip = new Rectangle(); - clip.setWidth(node.getBoundsInLocal().getWidth()); - clip.setHeight(node.getBoundsInLocal().getHeight()); clip.setArcWidth(20); clip.setArcHeight(20); - node.setClip(clip); + clip.heightProperty().bind(img.fitHeightProperty()); + clip.widthProperty().bind(img.fitHeightProperty().multiply( + img.getImage().getWidth() / img.getImage().getHeight() + )); + img.setClip(clip); } private void addHoverZoom(Node node) { @@ -160,8 +163,8 @@ public class MainFXMLController { private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) { ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png")); - img.setFitHeight(240); img.setPreserveRatio(true); + img.fitHeightProperty().bind(board.heightProperty().add(-15)); addClip(img); StackPane wrapper = new StackPane(img); @@ -180,13 +183,12 @@ public class MainFXMLController { return wrapper; } - private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow) { + private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow, Region parent) { ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png")); - img.setFitHeight(200); img.setPreserveRatio(true); + img.fitHeightProperty().bind(parent.heightProperty().multiply(0.85)); addClip(img); StackPane wrapper = new StackPane(img); - if (withShadow) addShadow(wrapper); if (withZoom) addHoverZoom(wrapper); return wrapper; @@ -251,7 +253,7 @@ public class MainFXMLController { int i = 0; for (TribeCard card : controller.miniModel.board.upperListTribe) { final int index = i; - StackPane img = createCard(card, true, true); + StackPane img = createCard(card, true, true, upperList); img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); upperList.getChildren().add(img); i++; @@ -267,7 +269,7 @@ public class MainFXMLController { int i = 0; for (TribeCard card : controller.miniModel.board.lowerListTribe) { final int index = i; - StackPane img = createCard(card, true, true); + StackPane img = createCard(card, true, true, lowerList); img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index)); lowerList.getChildren().add(img); i++; @@ -278,7 +280,7 @@ public class MainFXMLController { private void drawUpperBuilding() { ArrayList cardList = new ArrayList<>(controller.miniModel.board.upperListBuilding); if (!cardList.isEmpty()) { - StackPane img = createCard(cardList.getLast(), true, true); + StackPane img = createCard(cardList.getLast(), true, true, upperList); Label label = new Label(String.valueOf(cardList.size())); label.setTranslateY(-55); label.setTranslateX(10); @@ -293,7 +295,7 @@ public class MainFXMLController { private void drawLowerBuilding() { ArrayList cardList = new ArrayList<>(controller.miniModel.board.lowerListBuilding); if (!cardList.isEmpty()) { - StackPane img = createCard(cardList.getLast(), true, true); + StackPane img = createCard(cardList.getLast(), true, true, lowerList); Label label = new Label(String.valueOf(cardList.size())); label.setTranslateY(-55); label.setTranslateX(10); @@ -305,23 +307,22 @@ public class MainFXMLController { } } - private void drawMyHandList(ArrayList cardList) { + private void drawMyHandList(ArrayList cardList, HBox parent) { if (!cardList.isEmpty()) { - StackPane img = createCard(cardList.getLast(), true, true); + StackPane img = createCard(cardList.getLast(), true, true, parent); 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(new ArrayList<>(cardList))); - myHand.getChildren().add(img); + parent.getChildren().add(img); } else { Region placeholder = new Region(); - placeholder.setPrefHeight(200); - placeholder.setPrefWidth(200 * 0.675); + placeholder.prefHeightProperty().bind(parent.heightProperty().multiply(0.85)); + placeholder.prefWidthProperty().bind(placeholder.prefHeightProperty().multiply(0.675)); placeholder.setStyle("-fx-background-color: transparent;"); - myHand.getChildren().add(placeholder); + parent.getChildren().add(placeholder); } } @@ -479,13 +480,13 @@ public class MainFXMLController { myHand.setAlignment(Pos.CENTER); Player me = controller.miniModel.players.get(controller.myUsername); - drawMyHandList(me.artists); - drawMyHandList(me.gatherers); - drawMyHandList(me.inventors); - drawMyHandList(me.builders); - drawMyHandList(me.shamans); - drawMyHandList(me.hunters); - drawMyHandList(me.buildingCards); + drawMyHandList(me.artists,myHand); + drawMyHandList(me.gatherers,myHand); + drawMyHandList(me.inventors,myHand); + drawMyHandList(me.builders,myHand); + drawMyHandList(me.shamans,myHand); + drawMyHandList(me.hunters,myHand); + drawMyHandList(me.buildingCards,myHand); } private void renderSidePanel() { @@ -559,7 +560,7 @@ public class MainFXMLController { private void openPopup(ArrayList cardList) { popupCards.getChildren().clear(); for (PlayableCard card : cardList) { - popupCards.getChildren().add(createCard(card, false, false)); + popupCards.getChildren().add(createCardPopup(card, false, false)); } showPopup(); } @@ -569,7 +570,7 @@ public class MainFXMLController { popupCards.getChildren().clear(); for (int i = 0; i < cardList.size(); i++) { final int index = i; - StackPane img = createCard(cardList.get(i), true, false); + StackPane img = createCardPopup(cardList.get(i), true, false); img.setOnMouseClicked(e -> { popup.hide(); controller.drawUpperBuildingCard(controller.myUsername, index); @@ -584,7 +585,7 @@ public class MainFXMLController { popupCards.getChildren().clear(); for (int i = 0; i < cardList.size(); i++) { final int index = i; - StackPane img = createCard(cardList.get(i), true, false); + StackPane img = createCardPopup(cardList.get(i), true, false); img.setOnMouseClicked(e -> { popup.hide(); controller.drawLowerBuildingCard(controller.myUsername, index); @@ -604,4 +605,14 @@ public class MainFXMLController { popupCards.getChildren().add(wrapper); showPopup(); } + private StackPane createCardPopup(PlayableCard card, boolean withZoom, boolean withShadow) { + ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png")); + img.setFitHeight(200); + img.setPreserveRatio(true); + addClip(img); + StackPane wrapper = new StackPane(img); + if (withShadow) addShadow(wrapper); + if (withZoom) addHoverZoom(wrapper); + return wrapper; + } } \ No newline at end of file diff --git a/src/main/resources/GUIScene/main.fxml b/src/main/resources/GUIScene/main.fxml index b72f4cf..c7cd238 100644 --- a/src/main/resources/GUIScene/main.fxml +++ b/src/main/resources/GUIScene/main.fxml @@ -3,6 +3,7 @@ + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/GUIScene/standing.fxml b/src/main/resources/GUIScene/standing.fxml index de0ffa8..ec2d529 100644 --- a/src/main/resources/GUIScene/standing.fxml +++ b/src/main/resources/GUIScene/standing.fxml @@ -7,21 +7,21 @@ + fx:id="rootPane"> - - - - + + + -