diff --git a/src/main/java/client/DeckGridAppFX.java b/src/main/java/client/DeckGridAppFX.java index bc74dec..0c6ea40 100644 --- a/src/main/java/client/DeckGridAppFX.java +++ b/src/main/java/client/DeckGridAppFX.java @@ -1,5 +1,7 @@ package client; +import javafx.scene.input.MouseEvent; +import javafx.stage.Modality; import server.*; import server.*; import server.automaton.ActionResult; @@ -199,49 +201,55 @@ public class DeckGridAppFX extends Application { List players =game.getPlayers(); renderPlayers(players, game); - logger.info(game.getCurrentPlayer()); + logger.debug(game.getCurrentPlayer()); } - - private void drawBottomRow(HBox row, Game game) { for (Card c : game.getGameBoard().getBottomRow()) { ImageView cardImage = createCardImageFromPdf(c.getCardId(), IMG_HEIGHT, true); if (cardImage != null) { - // 1. Create a Label for your debugging text + Label debugLabel = new Label("ID: " + c.getCardId()); + debugLabel.setStyle( + "-fx-background-color: rgba(0, 0, 0, 0.7); " + + "-fx-text-fill: white; " + + "-fx-padding: 3px; " + + "-fx-font-weight: bold;" + ); - // 2. Style the label so it's readable over any card background - // (White text with a semi-transparent black background) - debugLabel.setStyle("-fx-background-color: rgba(0, 0, 0, 0.7); " + - "-fx-text-fill: white; " + - "-fx-padding: 3px; " + - "-fx-font-weight: bold;"); - - // 3. Create a StackPane and add both the image and the text - StackPane cardContainer = new StackPane(); - cardContainer.getChildren().addAll(cardImage, debugLabel); - - // 4. Align the text wherever you want (e.g., Top-Left corner of the card) + StackPane cardContainer = new StackPane(cardImage, debugLabel); StackPane.setAlignment(debugLabel, Pos.TOP_LEFT); - // You can also use Pos.CENTER, Pos.BOTTOM_RIGHT, etc. + + // --- CLICK HANDLER (your existing logic) --- cardImage.setOnMouseClicked(event -> { Player p = game.getCurrentPlayer(); ActionResult result = game.resolveCardAction(p, false, c.getCardId()); if (!result.isSuccess()) { - new Alert(Alert.AlertType.ERROR, - result.getErrorMessage() - ).showAndWait(); + new Alert(Alert.AlertType.ERROR, result.getErrorMessage()).showAndWait(); } drawGameState(game); }); - // 5. Add the StackPane (which now holds both) to the row + + // --- HOVER ZOOM EFFECT (same as top row) --- + ScaleTransition st = new ScaleTransition(Duration.millis(150), cardContainer); + st.setToX(1.25); + st.setToY(1.25); + + ScaleTransition stBack = new ScaleTransition(Duration.millis(150), cardContainer); + stBack.setToX(1.0); + stBack.setToY(1.0); + + cardContainer.setOnMouseEntered(e -> st.playFromStart()); + cardContainer.setOnMouseExited(e -> stBack.playFromStart()); + row.getChildren().add(cardContainer); } } } + + private void drawTopMenu(HBox row, Game game) { Label stateLabel = new Label("Game State = " + game.getState() ); @@ -251,45 +259,55 @@ public class DeckGridAppFX extends Application { row.getChildren().add(btnRefresh); row.getChildren().add(btnMsg); } + + private void drawTopRow(HBox row, Game game) { for (Card c : game.getGameBoard().getTopRow()) { ImageView cardImage = createCardImageFromPdf(c.getCardId(), IMG_HEIGHT, true); if (cardImage != null) { - // 1. Create a Label for your debugging text + Label debugLabel = new Label("ID: " + c.getCardId()); + debugLabel.setStyle( + "-fx-background-color: rgba(0, 0, 0, 0.7); " + + "-fx-text-fill: white; " + + "-fx-padding: 3px; " + + "-fx-font-weight: bold;" + ); - // 2. Style the label so it's readable over any card background - // (White text with a semi-transparent black background) - debugLabel.setStyle("-fx-background-color: rgba(0, 0, 0, 0.7); " + - "-fx-text-fill: white; " + - "-fx-padding: 3px; " + - "-fx-font-weight: bold;"); - - // 3. Create a StackPane and add both the image and the text - StackPane cardContainer = new StackPane(); - cardContainer.getChildren().addAll(cardImage, debugLabel); - - // 4. Align the text wherever you want (e.g., Top-Left corner of the card) + StackPane cardContainer = new StackPane(cardImage, debugLabel); StackPane.setAlignment(debugLabel, Pos.TOP_LEFT); - // You can also use Pos.CENTER, Pos.BOTTOM_RIGHT, etc. + + // --- CLICK HANDLER (your existing logic) --- cardImage.setOnMouseClicked(event -> { Player p = game.getCurrentPlayer(); ActionResult result = game.resolveCardAction(p, true, c.getCardId()); if (!result.isSuccess()) { - new Alert(Alert.AlertType.ERROR, - result.getErrorMessage() - ).showAndWait(); + new Alert(Alert.AlertType.ERROR, result.getErrorMessage()).showAndWait(); } - drawGameState(game); }); - // 5. Add the StackPane (which now holds both) to the row + + // --- HOVER ZOOM EFFECT --- + ScaleTransition st = new ScaleTransition(Duration.millis(150), cardContainer); + st.setToX(1.25); + st.setToY(1.25); + + ScaleTransition stBack = new ScaleTransition(Duration.millis(150), cardContainer); + stBack.setToX(1.0); + stBack.setToY(1.0); + + cardContainer.setOnMouseEntered(e -> st.playFromStart()); + cardContainer.setOnMouseExited(e -> stBack.playFromStart()); + row.getChildren().add(cardContainer); } } } + + + private StackPane drawTurnTileCardImageWithPlayers(InputStream imgStream, int height, Player[] players) { try { Image fxImage = new Image(imgStream); @@ -498,22 +516,53 @@ public class DeckGridAppFX extends Application { private ImageView createCardImageFromPdf(int pageIndex, int height, boolean front) { try { - BufferedImage bim =null; - if (front) bim = pdfRendererFront.renderImageWithDPI(pageIndex-1, 100); - else bim = pdfRendererBack.renderImageWithDPI(pageIndex-1, 100); + BufferedImage bim; + if (front) + bim = pdfRendererFront.renderImageWithDPI(pageIndex - 1, 100); + else + bim = pdfRendererBack.renderImageWithDPI(pageIndex - 1, 100); Image fxImage = SwingFXUtils.toFXImage(bim, null); ImageView imageView = new ImageView(fxImage); imageView.setFitHeight(height); imageView.setPreserveRatio(true); imageView.setStyle("-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.4), 4, 0, 0, 0);"); + + // 👉 Add popup on click + imageView.setOnMouseClicked(e -> showCardPopup(fxImage, e)); + return imageView; + } catch (IOException e) { logger.error("Errore rendering pagina {}", pageIndex, e); return null; } } + private void showCardPopup(Image image, MouseEvent event) { + Stage popup = new Stage(); + popup.initModality(Modality.NONE); + popup.setTitle("Card Preview"); + ImageView bigView = new ImageView(image); + bigView.setPreserveRatio(true); + bigView.setFitHeight(600); // big card + + StackPane root = new StackPane(bigView); + root.setPadding(new Insets(20)); + + Scene scene = new Scene(root); + popup.setScene(scene); + + // 1) Show first (important!) + popup.show(); + + // 2) Now resize to fit content + popup.sizeToScene(); + + // 3) Now center around click (after size is known) + popup.setX(event.getScreenX() - popup.getWidth() / 2); + popup.setY(event.getScreenY() - popup.getHeight() / 2); + } private StackPane drawOfferingCardImageWithTotem(InputStream imagePath, int height, Player occupant, Game game, OfferingTile offering) { try { Image fxImage = new Image(imagePath); diff --git a/src/main/java/server/automaton/Game.java b/src/main/java/server/automaton/Game.java index 7ab051d..5f820ed 100644 --- a/src/main/java/server/automaton/Game.java +++ b/src/main/java/server/automaton/Game.java @@ -115,8 +115,6 @@ public class Game { totemPlacedCount = 0; state = GameState.TOTEM_PLACEMENT; - logTurnOrder(); - } catch (LoadingCardsException e) { logger.error("Fatal: could not load cards — " + e.getMessage()); state = GameState.GAME_OVER; @@ -642,7 +640,7 @@ public class Game { // notify( GameState.TOTEM_PLACEMENT); state = GameState.TOTEM_PLACEMENT; logger.info("=== NEW Round " + round + " ==="); - logTurnOrder(); + } // ========================================================================= @@ -704,16 +702,6 @@ public class Game { else gameBoard.getBottomRow().add(card); } - private void logTurnOrder() { - Player[] order = gameBoard.getTurnTile().getPositions(); - StringBuilder sb = new StringBuilder("Turn order: "); - for (int i = 0; i < order.length; i++) { - if (order[i] != null) - sb.append(i + 1).append(". ").append(order[i].getNickname()).append(" "); - } - logger.info("logTurnOrder: " + sb); - } - // ========================================================================= // GETTERS // =========================================================================