Merge pull request #95 from rubenpirreram/GUI

G UI
This commit is contained in:
rubenpirreram
2026-05-12 14:33:57 +02:00
committed by GitHub
49 changed files with 665 additions and 216 deletions
@@ -7,6 +7,7 @@ import it.polimi.ingsw.gc14.View.GUI.GUI;
import it.polimi.ingsw.gc14.View.GUI.LoginView;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class ClientLauncherGUI extends Application {
@@ -122,7 +122,7 @@ public class Game implements Serializable {
/**
* The order logic card associated with this game.
*/
private OrderLogicCard orderLogicCard;
public OrderLogicCard orderLogicCard;
/**
* The board associated with this game.
@@ -123,16 +123,17 @@ public abstract class OrderLogicCard implements Serializable {
}
/**
* TODO rifare javadoc
* Returns the {@code Player}'s position based on it's {@code Username}.
* @param username The desired {@code Player}'s username.
* @return {@code int} - the {@code Player}'s position.
* @see Player
*/
protected int getPosition(String username)
public int getPosition(String username)
{
int pos = 0;
for (Player p : players) {
if (p.getUserName().equals(username))
for (OrderPlayer p : playerList) {
if (p.player.getUserName().equals(username))
return pos;
pos++;
}
@@ -10,13 +10,14 @@ import javafx.stage.Stage;
public class GUI implements IView { // stessa interfaccia che implementa TUI
private final Stage stage;
private final MainView mainView = new MainView();
private final MainView mainView;
private Game model;
private ClientController controller;
private String username;
public GUI(Stage stage) {
this.stage = stage;
this.mainView = new MainView();
}
@Override
@@ -1,269 +1,524 @@
package it.polimi.ingsw.gc14.View.GUI;
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.Game;
import it.polimi.ingsw.gc14.Model.Player;
import it.polimi.ingsw.gc14.Model.Slot;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.animation.ScaleTransition;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
import javafx.stage.Popup;
import javafx.stage.Window;
import javafx.util.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
public class MainFXMLController {
@FXML private HBox mainHBox;
@FXML private HBox board;
@FXML private HBox upperList;
@FXML private HBox lowerList;
@FXML private HBox myHand;
@FXML private VBox playersHand;
@FXML private Button reload;
@FXML private VBox sidePanel;
@FXML private HBox info;
@FXML private Label era;
@FXML private Label round;
@FXML private Label player;
private Popup popup;
private HBox popupCards;
private Game model;
private ClientController controller;
private String username;
private final Map<String, ImageView> cardCache = new HashMap<>();
public void setModel(Game model) {
this.model = model;
}
public void setModel(Game model) {this.model = model;}
public void setController(ClientController controller) {this.controller = controller;}
public void setUsername(String username) {this.username = username;}
@FXML
public void initialize() {
// Import font and apply CSS
Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14);
mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> {
if (newScene != null) {
newScene.getRoot().applyCss();
}
});
// Initialize popup
initPopup();
}
public void render() {
renderBackground();
renderUpper();
renderBoard();
renderLower();
renderMyHand();
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);
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);
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 = model.getSlotMap().get(slot);
if (player != null) {
int index = model.getPlayers().indexOf(player);
ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".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;
}
private void addHoverZoom(Node node) {
ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), node);
scaleUp.setToX(1.1);
scaleUp.setToY(1.1);
ScaleTransition scaleDown = new ScaleTransition(Duration.millis(150), node);
scaleDown.setToX(1.0);
scaleDown.setToY(1.0);
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));
shadow.setRadius(6);
shadow.setOffsetX(2);
shadow.setOffsetY(2);
node.setEffect(shadow);
node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {
shadow.setRadius(16);
shadow.setOffsetX(4);
shadow.setOffsetY(4);
shadow.setColor(Color.rgb(0, 0, 0, 0.5));
});
node.addEventHandler(MouseEvent.MOUSE_EXITED, e -> {
shadow.setRadius(6);
shadow.setOffsetX(2);
shadow.setOffsetY(2);
shadow.setColor(Color.rgb(0, 0, 0, 0.3));
});
}
// Upper list
upperList.setSpacing(6);
// ==== 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
)));
}
// UPPER, LOWER AND BOARD
private void renderUpper() {
upperList.setSpacing(14);
upperList.setAlignment(Pos.CENTER);
upperList.getChildren().clear();
int i = 0;
for (TribeCard card : model.getUpperListTribeCards()) {
final int index = i;
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(upperList.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setOnMouseClicked(e -> controller.drawUpperTribeCard(username, index));
upperList.getChildren().add(view);
StackPane img = createCard(card, true, true);
img.setOnMouseClicked(e -> controller.drawUpperTribeCard(username, index));
upperList.getChildren().add(img);
i++;
}
i = 0;
for (BuildingCard card : model.getUpperListBuilding()) {
final int index = i;
StackPane img = createCard(card, true, true);
img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(username, index));
upperList.getChildren().add(img);
i++;
}
}
private void renderOrder() {
StackPane card = createOrder(Integer.toString(model.getNPlayers()), 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));
// Board
board.setSpacing(6);
int i = 0;
for (Player player : model.getPlayers()) {
final int index = i;
ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".png")));
totem.setFitHeight(70);
totem.setPreserveRatio(true);
if (!(model.orderLogicCard.getPosition(player.getUserName()) != -1 && !model.getSlotMap().containsValue(player))) {
totem.setOpacity(0.0);
}
overlay.getChildren().add(totem);
i++;
}
card.getChildren().add(overlay);
board.getChildren().add(card);
}
private void renderBoard() {
board.setSpacing(14);
board.setAlignment(Pos.CENTER);
board.getChildren().clear();
i = 0;
String path = "";
switch (model.getCurrentState().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);
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<Slot, Player> entry : model.getSlotMap().entrySet()) {
Slot slot = entry.getKey();
final int index = i;
Image slotImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-"+slot.getSlotId()+".png"));
ImageView view = new ImageView(slotImg);
view.fitHeightProperty().bind(board.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setOnMouseClicked(e -> controller.slotChoice(username, index));
board.getChildren().add(view);
StackPane img = createSlot(slot, true, true);
img.setOnMouseClicked(e -> controller.slotChoice(username, index));
board.getChildren().add(img);
i++;
}
// Lower list
lowerList.setSpacing(6);
}
private void renderLower() {
lowerList.setSpacing(14);
lowerList.setAlignment(Pos.CENTER);
lowerList.getChildren().clear();
i = 0;
int i = 0;
for (TribeCard card : model.getLowerListTribeCards()) {
final int index = i;
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(lowerList.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setOnMouseClicked(e -> controller.drawLowerTribeCard(username, index));
lowerList.getChildren().add(view);
StackPane img = createCard(card, true, true);
img.setOnMouseClicked(e -> controller.drawLowerTribeCard(username, index));
lowerList.getChildren().add(img);
i++;
}
i = 0;
for (BuildingCard card : model.getLowerListBuilding()) {
final int index = i;
StackPane img = createCard(card, true, true);
img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(username, index));
lowerList.getChildren().add(img);
i++;
}
}
// My hand
// MY HAND
private void renderMyHand() {
myHand.getChildren().clear();
myHand.setSpacing(6);
//myHand.setAlignment(Pos.CENTER_LEFT);
myHand.setSpacing(14);
myHand.setAlignment(Pos.CENTER);
myHand.getChildren().add(createCardPane(model.getPlayerByUsername(username).artists.stream().map(x -> (TribeCard) x).toList(), myHand));
myHand.getChildren().add(createCardPane(model.getPlayerByUsername(username).gatherers.stream().map(x -> (TribeCard) x).toList(), myHand));
myHand.getChildren().add(createCardPane(model.getPlayerByUsername(username).inventors.stream().map(x -> (TribeCard) x).toList(), myHand));
myHand.getChildren().add(createCardPane(model.getPlayerByUsername(username).builders.stream().map(x -> (TribeCard) x).toList(), myHand));
myHand.getChildren().add(createCardPane(model.getPlayerByUsername(username).shamans.stream().map(x -> (TribeCard) x).toList(), myHand));
myHand.getChildren().add(createCardPane(model.getPlayerByUsername(username).hunters.stream().map(x -> (TribeCard) x).toList(), myHand));
/**
// Artists
Pane artists = new Pane();
artists.prefHeightProperty().bind(myHand.heightProperty());
artists.prefWidthProperty().bind(
artists.heightProperty().multiply(0.63).add((model.getPlayerByUsername(username).artists.size() - 1) * 50)
);
for (int j=0;j<model.getPlayerByUsername(username).artists.size();j++) {
TribeCard card=model.getPlayerByUsername(username).artists.get(j);
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(artists.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setLayoutX((model.getPlayerByUsername(username).artists.size() -j ) * 50); // solo X cambia
view.setLayoutY(5);
artists.getChildren().addLast(view);
i++;
drawMyHandList(myHand, model.getPlayerByUsername(username).artists);
drawMyHandList(myHand, model.getPlayerByUsername(username).gatherers);
drawMyHandList(myHand, model.getPlayerByUsername(username).inventors);
drawMyHandList(myHand, model.getPlayerByUsername(username).builders);
drawMyHandList(myHand, model.getPlayerByUsername(username).shamans);
drawMyHandList(myHand, model.getPlayerByUsername(username).hunters);
drawMyHandList(myHand, model.getPlayerByUsername(username).buildingCards);
}
private void drawMyHandList(HBox myHand, ArrayList<? extends PlayableCard> 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);
}
myHand.getChildren().add(artists);
// Gatherers
Pane gatherers=new Pane();
gatherers.prefHeightProperty().bind(myHand.heightProperty());
gatherers.prefWidthProperty().bind(
gatherers.heightProperty().multiply(0.63).add((model.getPlayerByUsername(username).gatherers.size() - 1) * 50)
);
for (int j=0;j<model.getPlayerByUsername(username).gatherers.size();j++) {
TribeCard card=model.getPlayerByUsername(username).gatherers.get(j);
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(artists.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setLayoutX((model.getPlayerByUsername(username).gatherers.size() -j ) * 50); // solo X cambia
view.setLayoutY(5);
gatherers.getChildren().addLast(view);
i++;
}
myHand.getChildren().add(gatherers);
// Inventors
Pane inventors=new Pane();
inventors.prefHeightProperty().bind(myHand.heightProperty());
for (int j=0;j<model.getPlayerByUsername(username).inventors.size();j++) {
TribeCard card=model.getPlayerByUsername(username).inventors.get(j);
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(inventors.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setLayoutX((model.getPlayerByUsername(username).inventors.size() -j )* 50); // solo X cambia
view.setLayoutY(5);
inventors.getChildren().addLast(view);
i++;
}
myHand.getChildren().add(inventors);
// Builders
Pane builders=new Pane();
builders.prefHeightProperty().bind(myHand.heightProperty());
for (int j=0;j<model.getPlayerByUsername(username).builders.size();j++) {
TribeCard card=model.getPlayerByUsername(username).builders.get(j);
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(builders.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setLayoutX((model.getPlayerByUsername(username).builders.size() -j ) * 50); // solo X cambia
view.setLayoutY(5);
builders.getChildren().addLast(view);
i++;
}
myHand.getChildren().add(builders);
// Shamans
Pane shamans=new Pane();
shamans.prefHeightProperty().bind(myHand.heightProperty());
for (int j=0;j<model.getPlayerByUsername(username).shamans.size();j++) {
TribeCard card=model.getPlayerByUsername(username).shamans.get(j);
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(shamans.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setLayoutX((model.getPlayerByUsername(username).shamans.size() -j ) * 50); // solo X cambia
view.setLayoutY(5);
shamans.getChildren().addLast(view);
i++;
}
myHand.getChildren().add(shamans);
// Hunters
Pane hunters=new Pane();
hunters.prefHeightProperty().bind(myHand.heightProperty());
for (int j=0;j<model.getPlayerByUsername(username).hunters.size();j++) {
TribeCard card=model.getPlayerByUsername(username).hunters.get(j);
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(hunters.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setLayoutX((model.getPlayerByUsername(username).hunters.size() -j )* 50); // solo X cambia
view.setLayoutY(5);
hunters.getChildren().addLast(view);
i++;
}
myHand.getChildren().add(hunters);
*/
}
// SIDE PANEL
private void renderSidePanel() {
sidePanel.getChildren().clear();
sidePanel.setSpacing(6);
era.setText(Integer.toString(model.getCurrentState().getEra()));
round.setText(Integer.toString(model.getCurrentState().getRound()));
player.setText(model.getCurrentState().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.getPlayers()) {
// 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);
private Pane createCardPane(List<TribeCard> cards, HBox container) {
Pane pane = new Pane();
int n = cards.size();
pane.prefHeightProperty().bind(container.heightProperty());
for (int j = 0; j < n; j++) {
TribeCard card = cards.get(j);
Image tribeImg = new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
ImageView view = new ImageView(tribeImg);
view.fitHeightProperty().bind(pane.heightProperty().subtract(10));
view.setPreserveRatio(true);
view.setLayoutX(j * 50);
view.setLayoutY(5);
pane.getChildren().add(view);
if (j == 0) {
view.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
@Override
public void changed(ObservableValue<? extends Bounds> obs, Bounds old, Bounds bounds) {
if (bounds.getWidth() > 0) {
pane.setPrefWidth(bounds.getWidth() + (n - 1) * 50);
view.layoutBoundsProperty().removeListener(this);
}
}
});
// Riga 1: icona totem + nome
HBox headerRow = new HBox(8);
headerRow.setAlignment(Pos.CENTER);
int index = model.getPlayers().indexOf(player);
ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".png")));
totem.setFitHeight(20);
totem.setPreserveRatio(true);
Label usernameLabel = new Label(player.getUserName());
usernameLabel.getStyleClass().add("label-medium");
if (player.getUserName().equals(username)) {
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 pane;
}
private void renderIcons(HBox iconsRow1, HBox iconsRow2, Player player) {
String[][] iconTypes = {
{"Artist", "artists"},
{"Gatherer", "gatherers"},
{"Inventor", "inventors"},
{"Builder", "builders"},
{"Shaman", "shamans"},
{"Hunter", "hunters"}
};
for (int i = 0; i < iconTypes.length; i++) {
String iconName = iconTypes[i][0];
String fieldName = iconTypes[i][1];
ImageView icon = new ImageView();
icon.setFitWidth(28);
icon.setFitHeight(28);
icon.setPreserveRatio(true);
icon.setImage(new Image(getClass().getResourceAsStream("/GUIImages/Icons/" + iconName + ".png")));
ArrayList<PlayableCard> cards = getPlayerCards(player.getUserName(), fieldName);
if (cards.isEmpty()) {
ColorAdjust grayscale = new ColorAdjust();
//grayscale.setSaturation(-1.0);
icon.setEffect(grayscale);
icon.setOpacity(0.3);
} else {
icon.setOnMouseClicked(e -> openPopup(cards));
addHoverZoom(icon);
}
if (i < 3) iconsRow1.getChildren().add(icon);
else iconsRow2.getChildren().add(icon);
}
}
private ArrayList<PlayableCard> getPlayerCards(String username, String type) {
Player p = model.getPlayerByUsername(username);
return switch (type) {
case "artists" -> new ArrayList<>(p.artists);
case "gatherers" -> new ArrayList<>(p.gatherers);
case "inventors" -> new ArrayList<>(p.inventors);
case "builders" -> new ArrayList<>(p.builders);
case "shamans" -> new ArrayList<>(p.shamans);
case "hunters" -> new ArrayList<>(p.hunters);
default -> new ArrayList<>();
};
}
// POPUP
private void initPopup() {
popupCards = new HBox(10);
popupCards.setAlignment(Pos.CENTER);
popupCards.setPadding(new Insets(10));
popupCards.setStyle(
"-fx-background-color: #b42224;" +
"-fx-border-color: black;" +
"-fx-border-width: 2;" +
"-fx-border-radius: 10;" +
"-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);
popup = new Popup();
popup.getContent().add(popupCards);
popup.setAutoHide(true);
// Aspetta che la scena del popup esista, poi la rendi trasparente
popup.addEventHandler(Event.ANY, e -> {
if (popup.getScene() != null) {
popup.getScene().setFill(Color.TRANSPARENT);
}
});
}
private void openPopup(ArrayList<? extends PlayableCard> cardList) {
popupCards.getChildren().clear();
for (PlayableCard card : cardList) {
StackPane img = createCard(card, false, false);
popupCards.getChildren().add(img);
}
Window window = myHand.getScene().getWindow();
popup.show(window, (window.getWidth() - popup.getWidth()) / 2, (window.getHeight() - popup.getHeight()) / 2);
// La scena esiste solo dopo show()
popup.getScene().setFill(Color.TRANSPARENT);
}
}