Fixed: now main window and leaderboard contents are adapted to window size, Added: scrollable popup leaderboard

This commit is contained in:
rubenpirreram
2026-05-18 13:00:26 +02:00
parent 8f8491b1ad
commit e3d5f82ad0
4 changed files with 129 additions and 102 deletions
@@ -6,6 +6,7 @@ import javafx.animation.ScaleTransition;
import it.polimi.ingsw.gc14.Model.PlayableCard; import it.polimi.ingsw.gc14.Model.PlayableCard;
import javafx.event.Event; import javafx.event.Event;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.ScrollPane;
import javafx.stage.Popup; import javafx.stage.Popup;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -291,11 +292,8 @@ public class LeaderboardFXMLController {
// Carte piccole in riga // Carte piccole in riga
for (PlayableCard card : cards) { for (PlayableCard card : cards) {
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png")); ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
img.setFitHeight(160); img.setFitHeight(230);
img.setPreserveRatio(true); 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); img.setCursor(Cursor.HAND);
row.getChildren().add(img); row.getChildren().add(img);
} }
@@ -309,11 +307,16 @@ public class LeaderboardFXMLController {
grid.getChildren().add(empty); grid.getChildren().add(empty);
} }
grid.setMaxHeight(460); ScrollPane scrollPane = new ScrollPane(grid);
grid.setMaxWidth(680); scrollPane.setFitToWidth(true);
popupContent.getChildren().add(grid); 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(); Window window = rootPane.getScene().getWindow();
scrollPane.setMaxHeight(window.getHeight() * 0.8);
popupContent.getChildren().add(scrollPane);
popup.show(window, 0, 0); popup.show(window, 0, 0);
popup.getScene().setFill(Color.TRANSPARENT); popup.getScene().setFill(Color.TRANSPARENT);
popup.setX(window.getX() + (window.getWidth() - popup.getWidth()) / 2); popup.setX(window.getX() + (window.getWidth() - popup.getWidth()) / 2);
@@ -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.Model.Orders.OrderPlayer;
import it.polimi.ingsw.gc14.Network.EventType; import it.polimi.ingsw.gc14.Network.EventType;
import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvent;
import javafx.animation.AnimationTimer;
import javafx.animation.PauseTransition;
import javafx.animation.ScaleTransition; import javafx.animation.ScaleTransition;
import javafx.application.Platform;
import javafx.event.Event; import javafx.event.Event;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.geometry.Insets; import javafx.geometry.Insets;
@@ -24,6 +27,7 @@ import javafx.scene.paint.Color;
import javafx.scene.shape.*; import javafx.scene.shape.*;
import javafx.scene.text.Font; import javafx.scene.text.Font;
import javafx.stage.Popup; import javafx.stage.Popup;
import javafx.stage.Stage;
import javafx.stage.Window; import javafx.stage.Window;
import javafx.util.Duration; import javafx.util.Duration;
@@ -67,11 +71,8 @@ public class MainFXMLController {
mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> { mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> {
if (newScene != null) { if (newScene != null) {
newScene.getRoot().applyCss(); newScene.getRoot().applyCss();
// chiudi popup cliccando fuori da esso
newScene.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> { newScene.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
if (popup.isShowing()) { if (popup.isShowing()) popup.hide();
popup.hide();
}
}); });
} }
}); });
@@ -107,13 +108,15 @@ public class MainFXMLController {
// ==== EFFECTS ==== // ==== EFFECTS ====
private void addClip(Node node) { private void addClip(ImageView img) {
Rectangle clip = new Rectangle(); Rectangle clip = new Rectangle();
clip.setWidth(node.getBoundsInLocal().getWidth());
clip.setHeight(node.getBoundsInLocal().getHeight());
clip.setArcWidth(20); clip.setArcWidth(20);
clip.setArcHeight(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) { private void addHoverZoom(Node node) {
@@ -160,8 +163,8 @@ public class MainFXMLController {
private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) { private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) {
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png")); ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"));
img.setFitHeight(240);
img.setPreserveRatio(true); img.setPreserveRatio(true);
img.fitHeightProperty().bind(board.heightProperty().add(-15));
addClip(img); addClip(img);
StackPane wrapper = new StackPane(img); StackPane wrapper = new StackPane(img);
@@ -180,13 +183,12 @@ public class MainFXMLController {
return wrapper; 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")); ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
img.setFitHeight(200);
img.setPreserveRatio(true); img.setPreserveRatio(true);
img.fitHeightProperty().bind(parent.heightProperty().multiply(0.85));
addClip(img); addClip(img);
StackPane wrapper = new StackPane(img); StackPane wrapper = new StackPane(img);
if (withShadow) addShadow(wrapper); if (withShadow) addShadow(wrapper);
if (withZoom) addHoverZoom(wrapper); if (withZoom) addHoverZoom(wrapper);
return wrapper; return wrapper;
@@ -251,7 +253,7 @@ public class MainFXMLController {
int i = 0; int i = 0;
for (TribeCard card : controller.miniModel.board.upperListTribe) { for (TribeCard card : controller.miniModel.board.upperListTribe) {
final int index = i; 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)); img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index));
upperList.getChildren().add(img); upperList.getChildren().add(img);
i++; i++;
@@ -267,7 +269,7 @@ public class MainFXMLController {
int i = 0; int i = 0;
for (TribeCard card : controller.miniModel.board.lowerListTribe) { for (TribeCard card : controller.miniModel.board.lowerListTribe) {
final int index = i; 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)); img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index));
lowerList.getChildren().add(img); lowerList.getChildren().add(img);
i++; i++;
@@ -278,7 +280,7 @@ public class MainFXMLController {
private void drawUpperBuilding() { private void drawUpperBuilding() {
ArrayList<BuildingCard> cardList = new ArrayList<>(controller.miniModel.board.upperListBuilding); ArrayList<BuildingCard> cardList = new ArrayList<>(controller.miniModel.board.upperListBuilding);
if (!cardList.isEmpty()) { 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 label = new Label(String.valueOf(cardList.size()));
label.setTranslateY(-55); label.setTranslateY(-55);
label.setTranslateX(10); label.setTranslateX(10);
@@ -293,7 +295,7 @@ public class MainFXMLController {
private void drawLowerBuilding() { private void drawLowerBuilding() {
ArrayList<BuildingCard> cardList = new ArrayList<>(controller.miniModel.board.lowerListBuilding); ArrayList<BuildingCard> cardList = new ArrayList<>(controller.miniModel.board.lowerListBuilding);
if (!cardList.isEmpty()) { 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 label = new Label(String.valueOf(cardList.size()));
label.setTranslateY(-55); label.setTranslateY(-55);
label.setTranslateX(10); label.setTranslateX(10);
@@ -305,23 +307,22 @@ public class MainFXMLController {
} }
} }
private void drawMyHandList(ArrayList<? extends PlayableCard> cardList) { private void drawMyHandList(ArrayList<? extends PlayableCard> cardList, HBox parent) {
if (!cardList.isEmpty()) { 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 label = new Label(String.valueOf(cardList.size()));
label.setTranslateY(-55); label.setTranslateY(-55);
label.setTranslateX(10); label.setTranslateX(10);
label.getStyleClass().add("label-large"); label.getStyleClass().add("label-large");
StackPane.setAlignment(label, Pos.TOP_RIGHT); StackPane.setAlignment(label, Pos.TOP_RIGHT);
img.getChildren().add(label);
img.setOnMouseClicked(e -> openPopup(new ArrayList<>(cardList))); img.setOnMouseClicked(e -> openPopup(new ArrayList<>(cardList)));
myHand.getChildren().add(img); parent.getChildren().add(img);
} else { } else {
Region placeholder = new Region(); Region placeholder = new Region();
placeholder.setPrefHeight(200); placeholder.prefHeightProperty().bind(parent.heightProperty().multiply(0.85));
placeholder.setPrefWidth(200 * 0.675); placeholder.prefWidthProperty().bind(placeholder.prefHeightProperty().multiply(0.675));
placeholder.setStyle("-fx-background-color: transparent;"); 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); myHand.setAlignment(Pos.CENTER);
Player me = controller.miniModel.players.get(controller.myUsername); Player me = controller.miniModel.players.get(controller.myUsername);
drawMyHandList(me.artists); drawMyHandList(me.artists,myHand);
drawMyHandList(me.gatherers); drawMyHandList(me.gatherers,myHand);
drawMyHandList(me.inventors); drawMyHandList(me.inventors,myHand);
drawMyHandList(me.builders); drawMyHandList(me.builders,myHand);
drawMyHandList(me.shamans); drawMyHandList(me.shamans,myHand);
drawMyHandList(me.hunters); drawMyHandList(me.hunters,myHand);
drawMyHandList(me.buildingCards); drawMyHandList(me.buildingCards,myHand);
} }
private void renderSidePanel() { private void renderSidePanel() {
@@ -559,7 +560,7 @@ public class MainFXMLController {
private void openPopup(ArrayList<? extends PlayableCard> cardList) { private void openPopup(ArrayList<? extends PlayableCard> cardList) {
popupCards.getChildren().clear(); popupCards.getChildren().clear();
for (PlayableCard card : cardList) { for (PlayableCard card : cardList) {
popupCards.getChildren().add(createCard(card, false, false)); popupCards.getChildren().add(createCardPopup(card, false, false));
} }
showPopup(); showPopup();
} }
@@ -569,7 +570,7 @@ public class MainFXMLController {
popupCards.getChildren().clear(); popupCards.getChildren().clear();
for (int i = 0; i < cardList.size(); i++) { for (int i = 0; i < cardList.size(); i++) {
final int index = i; final int index = i;
StackPane img = createCard(cardList.get(i), true, false); StackPane img = createCardPopup(cardList.get(i), true, false);
img.setOnMouseClicked(e -> { img.setOnMouseClicked(e -> {
popup.hide(); popup.hide();
controller.drawUpperBuildingCard(controller.myUsername, index); controller.drawUpperBuildingCard(controller.myUsername, index);
@@ -584,7 +585,7 @@ public class MainFXMLController {
popupCards.getChildren().clear(); popupCards.getChildren().clear();
for (int i = 0; i < cardList.size(); i++) { for (int i = 0; i < cardList.size(); i++) {
final int index = i; final int index = i;
StackPane img = createCard(cardList.get(i), true, false); StackPane img = createCardPopup(cardList.get(i), true, false);
img.setOnMouseClicked(e -> { img.setOnMouseClicked(e -> {
popup.hide(); popup.hide();
controller.drawLowerBuildingCard(controller.myUsername, index); controller.drawLowerBuildingCard(controller.myUsername, index);
@@ -604,4 +605,14 @@ public class MainFXMLController {
popupCards.getChildren().add(wrapper); popupCards.getChildren().add(wrapper);
showPopup(); 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;
}
} }
+17 -4
View File
@@ -3,6 +3,7 @@
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ScrollPane?>
<HBox fx:id="mainHBox" <HBox fx:id="mainHBox"
maxHeight="Infinity" maxWidth="Infinity" maxHeight="Infinity" maxWidth="Infinity"
prefHeight="1080.0" prefWidth="1920.0" prefHeight="1080.0" prefWidth="1920.0"
@@ -22,22 +23,25 @@
<Insets top="5" right="5" bottom="5" left="5" /> <Insets top="5" right="5" bottom="5" left="5" />
</HBox.margin> </HBox.margin>
<children> <children>
<HBox fx:id="upperList" prefHeight="220" minHeight="220" maxHeight="220" styleClass="card-list"> <HBox fx:id="upperList" styleClass="card-list" VBox.vgrow="ALWAYS">
<VBox.margin> <VBox.margin>
<Insets top="5" right="5" bottom="5" left="5" /> <Insets top="5" right="5" bottom="5" left="5" />
</VBox.margin> </VBox.margin>
</HBox> </HBox>
<HBox fx:id="board" prefHeight="255" minHeight="255" maxHeight="255" styleClass="card-list">
<HBox fx:id="board" prefHeight="255" minHeight="255" maxHeight="255" styleClass="card-list" VBox.vgrow="NEVER">
<VBox.margin> <VBox.margin>
<Insets top="5" right="5" bottom="5" left="5" /> <Insets top="5" right="5" bottom="5" left="5" />
</VBox.margin> </VBox.margin>
</HBox> </HBox>
<HBox fx:id="lowerList" prefHeight="220" minHeight="220" maxHeight="220" styleClass="card-list">
<HBox fx:id="lowerList" styleClass="card-list" VBox.vgrow="ALWAYS">
<VBox.margin> <VBox.margin>
<Insets top="5" right="5" bottom="5" left="5" /> <Insets top="5" right="5" bottom="5" left="5" />
</VBox.margin> </VBox.margin>
</HBox> </HBox>
<HBox fx:id="myHand" prefHeight="220" minHeight="220" maxHeight="220" styleClass="card-list">
<HBox fx:id="myHand" styleClass="card-list" VBox.vgrow="ALWAYS">
<VBox.margin> <VBox.margin>
<Insets top="5" right="5" bottom="5" left="5" /> <Insets top="5" right="5" bottom="5" left="5" />
</VBox.margin> </VBox.margin>
@@ -55,6 +59,10 @@
<HBox.margin> <HBox.margin>
<Insets bottom="10" left="10" right="10" top="10" /> <Insets bottom="10" left="10" right="10" top="10" />
</HBox.margin> </HBox.margin>
<children>
<ScrollPane fitToWidth="true" hbarPolicy="NEVER" vbarPolicy="AS_NEEDED" VBox.vgrow="ALWAYS">
<content>
<VBox spacing="10">
<children> <children>
<HBox fx:id="info" prefHeight="107.0" prefWidth="483.0" styleClass="frame"> <HBox fx:id="info" prefHeight="107.0" prefWidth="483.0" styleClass="frame">
<children> <children>
@@ -78,6 +86,11 @@
</VBox> </VBox>
</children> </children>
</HBox> </HBox>
<!-- altri elementi qui sotto -->
</children>
</VBox>
</content>
</ScrollPane>
</children> </children>
</VBox> </VBox>
+7 -7
View File
@@ -7,21 +7,21 @@
<StackPane xmlns="http://javafx.com/javafx" <StackPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml" xmlns:fx="http://javafx.com/fxml"
fx:controller="it.polimi.ingsw.gc14.View.GUI.LeaderboardFXMLController" fx:controller="it.polimi.ingsw.gc14.View.GUI.LeaderboardFXMLController"
fx:id="rootPane" fx:id="rootPane">
prefWidth="1280"
prefHeight="720">
<!-- Overlay scuro semitrasparente sopra il background -->
<Region style="-fx-background-color: rgba(0,0,0,0.45);"/> <Region style="-fx-background-color: rgba(0,0,0,0.45);"/>
<!-- Contenuto centrato -->
<VBox fx:id="mainVBox" alignment="CENTER" spacing="32"> <VBox fx:id="mainVBox" alignment="CENTER" spacing="32">
<padding><Insets top="50" right="120" bottom="50" left="120"/></padding> <padding><Insets top="50" right="120" bottom="50" left="120"/></padding>
<!-- Lista giocatori (Winner/GameOver label aggiunta da render()) --> <ScrollPane fitToWidth="true"
hbarPolicy="NEVER"
vbarPolicy="AS_NEEDED"
style="-fx-background: transparent; -fx-background-color: transparent;"
VBox.vgrow="ALWAYS">
<VBox fx:id="rankingList" alignment="CENTER" spacing="16"/> <VBox fx:id="rankingList" alignment="CENTER" spacing="16"/>
</ScrollPane>
<!-- Bottone nuova partita -->
<Button fx:id="newGameButton" text="NUOVA PARTITA" <Button fx:id="newGameButton" text="NUOVA PARTITA"
styleClass="action-button" styleClass="action-button"
onAction="#onNewGame"/> onAction="#onNewGame"/>