Add: Added Coverage Screenshots And htlmReport.
This commit is contained in:
@@ -0,0 +1,902 @@
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html id="htmlId">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||||
<title>Coverage Report > MainFXMLController</title>
|
||||
<style type="text/css">
|
||||
@import "../../css/coverage.css";
|
||||
@import "../../css/idea.min.css";
|
||||
</style>
|
||||
<script type="text/javascript" src="../../js/highlight.min.js"></script>
|
||||
<script type="text/javascript" src="../../js/highlightjs-line-numbers.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="breadCrumbs">
|
||||
Current scope: <a href="../../index.html">all classes</a>
|
||||
<span class="separator">|</span>
|
||||
<a href="../index.html">it.polimi.ingsw.gc14.View.GUI</a>
|
||||
</div>
|
||||
|
||||
<h1>Coverage Summary for Class: MainFXMLController (it.polimi.ingsw.gc14.View.GUI)</h1>
|
||||
|
||||
<table class="coverageStats">
|
||||
<tr>
|
||||
<th class="name">Class</th>
|
||||
<th class="coverageStat
|
||||
">
|
||||
Class, %
|
||||
</th>
|
||||
<th class="coverageStat
|
||||
">
|
||||
Method, %
|
||||
</th>
|
||||
<th class="coverageStat
|
||||
">
|
||||
Branch, %
|
||||
</th>
|
||||
<th class="coverageStat
|
||||
">
|
||||
Line, %
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name">MainFXMLController</td>
|
||||
<td class="coverageStat">
|
||||
<span class="percent">
|
||||
0%
|
||||
</span>
|
||||
<span class="absValue">
|
||||
(0/1)
|
||||
</span>
|
||||
</td>
|
||||
<td class="coverageStat">
|
||||
<span class="percent">
|
||||
0%
|
||||
</span>
|
||||
<span class="absValue">
|
||||
(0/50)
|
||||
</span>
|
||||
</td>
|
||||
<td class="coverageStat">
|
||||
<span class="percent">
|
||||
0%
|
||||
</span>
|
||||
<span class="absValue">
|
||||
(0/124)
|
||||
</span>
|
||||
</td>
|
||||
<td class="coverageStat">
|
||||
<span class="percent">
|
||||
0%
|
||||
</span>
|
||||
<span class="absValue">
|
||||
(0/426)
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
<pre>
|
||||
<code class="sourceCode" id="sourceCode"> 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.Orders.OrderPlayer;
|
||||
import it.polimi.ingsw.gc14.Network.EventType;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
import javafx.animation.ScaleTransition;
|
||||
import javafx.animation.TranslateTransition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.Event;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Bounds;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.geometry.Rectangle2D;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
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.Screen;
|
||||
import javafx.stage.Window;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* FXML controller for the main game scene.
|
||||
*
|
||||
* <p>Renders the board (upper/lower tribe and building card rows), player stats,
|
||||
* the player's hand, and action buttons (skip, details).
|
||||
*/
|
||||
<b class="nc"> public class MainFXMLController {</b>
|
||||
//TODO
|
||||
@FXML private GridPane leftGrid;
|
||||
//TODO
|
||||
@FXML private ScrollPane playerSide;
|
||||
//TODO
|
||||
@FXML private HBox mainHBox;
|
||||
//TODO
|
||||
@FXML private ImageView backgroundImage;
|
||||
//TODO
|
||||
@FXML private HBox board;
|
||||
//TODO
|
||||
@FXML private HBox upperList;
|
||||
//TODO
|
||||
@FXML private HBox lowerList;
|
||||
//TODO
|
||||
@FXML private HBox myHand;
|
||||
//TODO
|
||||
@FXML private Button skipBtn;
|
||||
//TODO
|
||||
@FXML private Button detailsBtn;
|
||||
//TODO
|
||||
@FXML private Label infoText;
|
||||
//TODO
|
||||
<b class="nc"> private final Map<String, Label> foodLabels = new HashMap<>();</b>
|
||||
//TODO
|
||||
<b class="nc"> private final Map<String, Label> prestigeLabels = new HashMap<>();</b>
|
||||
//TODO
|
||||
<b class="nc"> private final Map<String, VBox> playerCards = new HashMap<>();</b>
|
||||
//TODO
|
||||
<b class="nc"> private final Map<String, List<ImageView>> iconViews = new HashMap<>();</b>
|
||||
//TODO
|
||||
private Popup popup;
|
||||
//TODO
|
||||
private HBox popupCards;
|
||||
//TODO
|
||||
private ClientController controller;
|
||||
|
||||
/** {@code true} when the last received event was an error response. */
|
||||
private boolean isError;
|
||||
|
||||
/** Sets the error flag; called by {@link GUI} before delegating to {@link #render()}. */
|
||||
<b class="nc"> public void setError(boolean error) { this.isError = error; }</b>
|
||||
|
||||
// ==== IMAGE CACHE ====
|
||||
<b class="nc"> private static final Map<String, Image> imageCache = new HashMap<>();</b>
|
||||
|
||||
/** Returns a cached {@link Image} for the given classpath {@code path}, loading it on first access. */
|
||||
private Image loadImage(String path) {
|
||||
<b class="nc"> return imageCache.computeIfAbsent(path,</b>
|
||||
<b class="nc"> p -> new Image(getClass().getResourceAsStream(p)));</b>
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the client controller and wires up the skip-turn button action.
|
||||
*
|
||||
* @param controller the client controller to use.
|
||||
*/
|
||||
public void setController(ClientController controller) {
|
||||
<b class="nc"> this.controller = controller;</b>
|
||||
<b class="nc"> skipBtn.setOnAction(e -> controller.skipTurn());</b>
|
||||
}
|
||||
|
||||
/** Initializes the scene: loads fonts, sets up the popup, and registers input listeners. */
|
||||
@FXML
|
||||
public void initialize() {
|
||||
<b class="nc"> Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14);</b>
|
||||
|
||||
<b class="nc"> addHoverZoom(skipBtn);</b>
|
||||
<b class="nc"> addHoverZoom(detailsBtn);</b>
|
||||
<b class="nc"> popup = new Popup();</b>
|
||||
<b class="nc"> mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> {</b>
|
||||
<b class="nc"> if (newScene != null) {</b>
|
||||
<b class="nc"> newScene.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {</b>
|
||||
<b class="nc"> if (popup.isShowing()) popup.hide();</b>
|
||||
});
|
||||
<b class="nc"> newScene.getRoot().applyCss();</b>
|
||||
<b class="nc"> newScene.windowProperty().addListener((o2, ow, nw) -> {</b>
|
||||
<b class="nc"> if (nw != null) {</b>
|
||||
<b class="nc"> nw.focusedProperty().addListener((o3, wf, nf) -> {</b>
|
||||
<b class="nc"> if (!nf) popup.hide();</b>
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
<b class="nc"> popup.hide();</b>
|
||||
}
|
||||
});
|
||||
<b class="nc"> initPopup();</b>
|
||||
<b class="nc"> detailsBtn.setOnAction(e -> openDetailsPopup());</b>
|
||||
<b class="nc"> renderBackground();</b>
|
||||
<b class="nc"> isError=false;</b>
|
||||
}
|
||||
|
||||
|
||||
// ==== RENDER ====
|
||||
/** Incrementally re-renders only the parts of the scene affected by the last network event. */
|
||||
public void render() {
|
||||
<b class="nc"> if(foodLabels.isEmpty() || controller.getMiniModel().lastEvent == null</b>
|
||||
<b class="nc"> || controller.getMiniModel().lastEvent.getEventType().equals(EventType.TOTEM_CHOICE))</b>
|
||||
<b class="nc"> buildSidePanel();</b>
|
||||
<b class="nc"> if(isError)</b>
|
||||
{
|
||||
<b class="nc"> updateSidePanel();</b>
|
||||
<b class="nc"> isError=false;</b>
|
||||
return;
|
||||
}
|
||||
<b class="nc"> if(controller.getMiniModel().lastEvent==null ||controller.getMiniModel().lastEvent.getEventType().equals(EventType.TOTEM_CHOICE) || controller.getMiniModel().lastEvent.getEventType().equals(EventType.NEXT_ROUND)) {</b>
|
||||
<b class="nc"> renderMyHand();</b>
|
||||
<b class="nc"> renderUpper();</b>
|
||||
<b class="nc"> renderBoard();</b>
|
||||
<b class="nc"> renderLower();</b>
|
||||
<b class="nc"> updateSidePanel();</b>
|
||||
return;
|
||||
}
|
||||
<b class="nc"> if(controller.getMiniModel().lastEvent.getEventType().equals(EventType.DRAW_UPPER_TRIBE) || controller.getMiniModel().lastEvent.getEventType().equals(EventType.DRAW_UPPER_BUILD))</b>
|
||||
{
|
||||
<b class="nc"> renderUpper();</b>
|
||||
}
|
||||
<b class="nc"> if(controller.getMiniModel().lastEvent.getEventType().equals(EventType.DRAW_LOWER_TRIBE) || controller.getMiniModel().lastEvent.getEventType().equals(EventType.DRAW_LOWER_BUILD))</b>
|
||||
{
|
||||
<b class="nc"> renderLower();</b>
|
||||
}
|
||||
<b class="nc"> if(controller.getMiniModel().lastEvent.getUsername().equals(controller.getMyUsername()))</b>
|
||||
{
|
||||
<b class="nc"> renderMyHand();</b>
|
||||
}
|
||||
<b class="nc"> renderBoard();</b>
|
||||
<b class="nc"> updateSidePanel();</b>
|
||||
}
|
||||
|
||||
|
||||
// ==== EFFECTS ====
|
||||
/** Binds a rounded-rectangle clip to {@code img} so its corners are cropped. */
|
||||
private void addClip(ImageView img) {
|
||||
<b class="nc"> Rectangle clip = new Rectangle();</b>
|
||||
<b class="nc"> clip.setArcWidth(20);</b>
|
||||
<b class="nc"> clip.setArcHeight(20);</b>
|
||||
<b class="nc"> img.setClip(clip);</b>
|
||||
<b class="nc"> clip.heightProperty().bind(img.layoutBoundsProperty().map(b -> b.getHeight()));</b>
|
||||
<b class="nc"> clip.widthProperty().bind(img.layoutBoundsProperty().map(b -> b.getWidth()));</b>
|
||||
}
|
||||
|
||||
/** Scales {@code node} to 1.1× on hover and restores on exit; sets a hand cursor. */
|
||||
private void addHoverZoom(Node node) {
|
||||
<b class="nc"> ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), node);</b>
|
||||
<b class="nc"> scaleUp.setToX(1.1);</b>
|
||||
<b class="nc"> scaleUp.setToY(1.1);</b>
|
||||
<b class="nc"> ScaleTransition scaleDown = new ScaleTransition(Duration.millis(150), node);</b>
|
||||
<b class="nc"> scaleDown.setToX(1.0);</b>
|
||||
<b class="nc"> scaleDown.setToY(1.0);</b>
|
||||
<b class="nc"> node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> { scaleUp.play(); node.setCursor(Cursor.HAND); });</b>
|
||||
<b class="nc"> node.addEventHandler(MouseEvent.MOUSE_EXITED, e -> { scaleDown.play(); node.setCursor(Cursor.DEFAULT); });</b>
|
||||
}
|
||||
|
||||
/** Applies a drop-shadow to {@code node} that intensifies on hover. */
|
||||
private void addShadow(Node node) {
|
||||
<b class="nc"> DropShadow shadow = new DropShadow();</b>
|
||||
<b class="nc"> shadow.setColor(Color.rgb(0, 0, 0, 0.3));</b>
|
||||
<b class="nc"> shadow.setRadius(6);</b>
|
||||
<b class="nc"> shadow.setOffsetX(2);</b>
|
||||
<b class="nc"> shadow.setOffsetY(2);</b>
|
||||
<b class="nc"> node.setEffect(shadow);</b>
|
||||
<b class="nc"> node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {</b>
|
||||
<b class="nc"> shadow.setRadius(16);</b>
|
||||
<b class="nc"> shadow.setOffsetX(4);</b>
|
||||
<b class="nc"> shadow.setOffsetY(4);</b>
|
||||
<b class="nc"> shadow.setColor(Color.rgb(0, 0, 0, 0.5));</b>
|
||||
});
|
||||
<b class="nc"> node.addEventHandler(MouseEvent.MOUSE_EXITED, e -> {</b>
|
||||
<b class="nc"> shadow.setRadius(6);</b>
|
||||
<b class="nc"> shadow.setOffsetX(2);</b>
|
||||
<b class="nc"> shadow.setOffsetY(2);</b>
|
||||
<b class="nc"> shadow.setColor(Color.rgb(0, 0, 0, 0.3));</b>
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ==== ELEMENTS ====
|
||||
|
||||
/** Builds the side-panel card widget for {@code player} with totem, stats, and card-type icons. */
|
||||
private VBox buildPlayerCard(Player player) {
|
||||
<b class="nc"> VBox card = new VBox(3);</b>
|
||||
<b class="nc"> VBox.setMargin(card, new Insets(15, 15, 0, 15));</b>
|
||||
<b class="nc"> card.getStyleClass().add("player-card");</b>
|
||||
<b class="nc"> card.setPadding(new Insets(4));</b>
|
||||
|
||||
<b class="nc"> HBox headerRow = new HBox(8);</b>
|
||||
<b class="nc"> headerRow.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> ImageView totem = new ImageView(loadImage("/GUIImages/Totems/totem_"</b>
|
||||
<b class="nc"> + player.getTotem().toString().toLowerCase(Locale.ROOT) + ".png"));</b>
|
||||
<b class="nc"> totem.setFitHeight(20);</b>
|
||||
<b class="nc"> totem.setPreserveRatio(true);</b>
|
||||
<b class="nc"> Label usernameLabel = new Label(player.getUserName());</b>
|
||||
<b class="nc"> usernameLabel.getStyleClass().add("label-medium");</b>
|
||||
<b class="nc"> usernameLabel.setStyle("-fx-text-fill: #711423;");</b>
|
||||
<b class="nc"> if (player.getUserName().equals(controller.getMyUsername())) {</b>
|
||||
<b class="nc"> usernameLabel.setText(usernameLabel.getText() + " (you)");</b>
|
||||
}
|
||||
<b class="nc"> if (controller.getMiniModel().disconnectedPlayers.contains(player.getUserName())) {</b>
|
||||
<b class="nc"> card.getStyleClass().add("player-card-crashed");</b>
|
||||
}
|
||||
<b class="nc"> headerRow.getChildren().addAll(totem, usernameLabel);</b>
|
||||
|
||||
<b class="nc"> HBox statsRow = new HBox(10);</b>
|
||||
<b class="nc"> statsRow.setAlignment(Pos.CENTER);</b>
|
||||
|
||||
<b class="nc"> HBox foodBox = new HBox(4);</b>
|
||||
<b class="nc"> foodBox.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> ImageView foodIcon = new ImageView(loadImage("/GUIImages/Icons/Food.png"));</b>
|
||||
<b class="nc"> foodIcon.setFitHeight(20);</b>
|
||||
<b class="nc"> foodIcon.setPreserveRatio(true);</b>
|
||||
<b class="nc"> Label foodLabel = new Label(String.valueOf(player.getFoodValue()));</b>
|
||||
<b class="nc"> foodLabel.getStyleClass().add("label-small");</b>
|
||||
<b class="nc"> foodLabels.put(player.getUserName(), foodLabel);</b>
|
||||
<b class="nc"> foodBox.getChildren().addAll(foodIcon, foodLabel);</b>
|
||||
|
||||
<b class="nc"> HBox prestigeBox = new HBox(1);</b>
|
||||
<b class="nc"> prestigeBox.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> ImageView ppIcon = new ImageView(loadImage("/GUIImages/Icons/PrestigePoint.png"));</b>
|
||||
<b class="nc"> ppIcon.setFitHeight(35);</b>
|
||||
<b class="nc"> ppIcon.setPreserveRatio(true);</b>
|
||||
<b class="nc"> Label prestigeLabel = new Label(String.valueOf(player.getPrestigeValue()));</b>
|
||||
<b class="nc"> prestigeLabel.getStyleClass().add("label-small");</b>
|
||||
<b class="nc"> prestigeLabels.put(player.getUserName(), prestigeLabel);</b>
|
||||
<b class="nc"> prestigeBox.getChildren().addAll(ppIcon, prestigeLabel);</b>
|
||||
|
||||
<b class="nc"> ImageView buildingIcon = new ImageView(loadImage("/GUIImages/Icons/Building.png"));</b>
|
||||
<b class="nc"> buildingIcon.setFitWidth(28);</b>
|
||||
<b class="nc"> buildingIcon.setFitHeight(28);</b>
|
||||
<b class="nc"> buildingIcon.setPreserveRatio(true);</b>
|
||||
<b class="nc"> buildingIcon.setOnMouseClicked(e -> {</b>
|
||||
<b class="nc"> ArrayList<PlayableCard> cards = getPlayerCards(player.getUserName(), "building");</b>
|
||||
<b class="nc"> if (!cards.isEmpty()) openPopup(cards);</b>
|
||||
});
|
||||
<b class="nc"> addHoverZoom(buildingIcon);</b>
|
||||
|
||||
<b class="nc"> statsRow.getChildren().addAll(foodBox, prestigeBox, buildingIcon);</b>
|
||||
|
||||
<b class="nc"> HBox iconsRow1 = new HBox(6);</b>
|
||||
<b class="nc"> iconsRow1.setSpacing(20);</b>
|
||||
<b class="nc"> iconsRow1.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> HBox iconsRow2 = new HBox(6);</b>
|
||||
<b class="nc"> iconsRow2.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> iconsRow2.setSpacing(20);</b>
|
||||
|
||||
<b class="nc"> String[][] iconTypes = {</b>
|
||||
{"Artist", "artists"},
|
||||
{"Gatherer", "gatherers"},
|
||||
{"Inventor", "inventors"},
|
||||
{"Builder", "builders"},
|
||||
{"Shaman", "shamans"},
|
||||
{"Hunter", "hunters"}
|
||||
};
|
||||
|
||||
<b class="nc"> List<ImageView> icons = new ArrayList<>();</b>
|
||||
// building must be index 0; updateSidePanel iterates icons in ["building","artists",...] order
|
||||
<b class="nc"> icons.add(buildingIcon);</b>
|
||||
|
||||
<b class="nc"> for (int i = 0; i < iconTypes.length; i++) {</b>
|
||||
<b class="nc"> String iconName = iconTypes[i][0];</b>
|
||||
<b class="nc"> String fieldName = iconTypes[i][1];</b>
|
||||
|
||||
<b class="nc"> ImageView icon = new ImageView(loadImage("/GUIImages/Icons/" + iconName + ".png"));</b>
|
||||
<b class="nc"> icon.setFitWidth(28);</b>
|
||||
<b class="nc"> icon.setFitHeight(28);</b>
|
||||
<b class="nc"> icon.setPreserveRatio(true);</b>
|
||||
<b class="nc"> icon.setOnMouseClicked(e -> {</b>
|
||||
<b class="nc"> ArrayList<PlayableCard> cards = getPlayerCards(player.getUserName(), fieldName);</b>
|
||||
<b class="nc"> if (!cards.isEmpty()) openPopup(cards);</b>
|
||||
});
|
||||
<b class="nc"> addHoverZoom(icon);</b>
|
||||
<b class="nc"> icons.add(icon);</b>
|
||||
|
||||
<b class="nc"> if (i < 3) iconsRow1.getChildren().add(icon);</b>
|
||||
<b class="nc"> else iconsRow2.getChildren().add(icon);</b>
|
||||
}
|
||||
|
||||
<b class="nc"> iconViews.put(player.getUserName(), icons);</b>
|
||||
|
||||
<b class="nc"> card.getChildren().addAll(headerRow, statsRow, iconsRow1, iconsRow2);</b>
|
||||
<b class="nc"> return card;</b>
|
||||
}
|
||||
|
||||
/** Creates a {@link StackPane} containing the order card image for a game of {@code num} players. */
|
||||
private StackPane createOrder(String num) {
|
||||
<b class="nc"> ImageView img = new ImageView(loadImage("/GUIImages/Orders/order-" + num + ".png"));</b>
|
||||
<b class="nc"> img.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(56).divide(4).multiply(0.94));</b>
|
||||
<b class="nc"> img.setPreserveRatio(true);</b>
|
||||
<b class="nc"> addClip(img);</b>
|
||||
<b class="nc"> return new StackPane(img);</b>
|
||||
}
|
||||
|
||||
/** Creates a {@link StackPane} for a board slot, optionally overlaying the occupying player's totem. */
|
||||
private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) {
|
||||
<b class="nc"> ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"));</b>
|
||||
<b class="nc"> img.setPreserveRatio(true);</b>
|
||||
<b class="nc"> img.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(56).divide(4).multiply(0.94));</b>
|
||||
<b class="nc"> addClip(img);</b>
|
||||
<b class="nc"> StackPane wrapper = new StackPane(img);</b>
|
||||
|
||||
<b class="nc"> Player player = controller.getMiniModel().slotPlayerMap.get(slot);</b>
|
||||
<b class="nc"> if (player != null && controller.getMiniModel().getPositionByUsername(player.getUserName()) != -1) {</b>
|
||||
<b class="nc"> ImageView totem = new ImageView(loadImage("/GUIImages/Totems/totem_" + player.getTotem().toString().toLowerCase(Locale.ROOT) + ".png"));</b>
|
||||
<b class="nc"> totem.fitHeightProperty().bind(img.fitHeightProperty().multiply(0.332));</b>
|
||||
<b class="nc"> totem.setPreserveRatio(true);</b>
|
||||
<b class="nc"> StackPane.setAlignment(totem, Pos.TOP_LEFT);</b>
|
||||
<b class="nc"> img.fitHeightProperty().addListener((obs, ov, nv) -> {</b>
|
||||
<b class="nc"> StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * nv.doubleValue()));</b>
|
||||
});
|
||||
<b class="nc"> if (img.getFitHeight() > 0) {</b>
|
||||
<b class="nc"> StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * img.getFitHeight()));</b>
|
||||
}
|
||||
<b class="nc"> wrapper.getChildren().add(totem);</b>
|
||||
}
|
||||
|
||||
<b class="nc"> if (withShadow) addShadow(wrapper);</b>
|
||||
<b class="nc"> if (withZoom) addHoverZoom(wrapper);</b>
|
||||
<b class="nc"> return wrapper;</b>
|
||||
}
|
||||
|
||||
/** Creates a {@link StackPane} for a playable card, scaling its height to a fraction of {@code parent}'s scene. */
|
||||
private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow, Region parent) {
|
||||
<b class="nc"> ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));</b>
|
||||
<b class="nc"> img.setPreserveRatio(true);</b>
|
||||
<b class="nc"> if(controller.getMiniModel().players.size()==5)</b>
|
||||
{
|
||||
<b class="nc"> img.fitHeightProperty().bind(parent.getScene().heightProperty().subtract(56).divide(4).multiply(0.85));</b>
|
||||
}
|
||||
else
|
||||
<b class="nc"> img.fitHeightProperty().bind(parent.getScene().heightProperty().subtract(56).divide(4).multiply(0.90));</b>
|
||||
<b class="nc"> addClip(img);</b>
|
||||
<b class="nc"> StackPane wrapper = new StackPane(img);</b>
|
||||
<b class="nc"> if (withShadow) addShadow(wrapper);</b>
|
||||
<b class="nc"> if (withZoom) addHoverZoom(wrapper);</b>
|
||||
<b class="nc"> return wrapper;</b>
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==== GROUPS ====
|
||||
/** Builds the full side panel from scratch, creating a player card for each connected player. */
|
||||
private void buildSidePanel() {
|
||||
<b class="nc"> infoText.setText("Round: "+Integer.toString(controller.getMiniModel().currentState.getRound()) + " • " + controller.getMiniModel().currentState.getGameStage().toString());</b>
|
||||
<b class="nc"> VBox playerList = new VBox();</b>
|
||||
<b class="nc"> playerList.setFillWidth(true);</b>
|
||||
<b class="nc"> for (Player p : controller.getMiniModel().players.values()) {</b>
|
||||
<b class="nc"> VBox card = buildPlayerCard(p);</b>
|
||||
<b class="nc"> playerCards.put(p.getUserName(), card);</b>
|
||||
<b class="nc"> playerList.getChildren().add(card);</b>
|
||||
}
|
||||
<b class="nc"> playerSide.setContent(playerList);</b>
|
||||
}
|
||||
|
||||
/** Updates food/prestige labels, current-player highlight, card-icon opacity, and plays error shake if needed. */
|
||||
private void updateSidePanel() {
|
||||
<b class="nc"> infoText.setText("Round: "+Integer.toString(controller.getMiniModel().currentState.getRound()) + " • " + controller.getMiniModel().currentState.getGameStage().toString());</b>
|
||||
<b class="nc"> if (controller.getMiniModel().currentState.getCurrentPlayer() == null) return;</b>
|
||||
<b class="nc"> String current = controller.getMiniModel().currentState.getCurrentPlayer().getUserName();</b>
|
||||
// ordine: building, artists, gatherers, inventors, builders, shamans, hunters
|
||||
<b class="nc"> String[] fields = {"building", "artists", "gatherers", "inventors", "builders", "shamans", "hunters"};</b>
|
||||
|
||||
<b class="nc"> for (Player p : controller.getMiniModel().players.values()) {</b>
|
||||
<b class="nc"> String u = p.getUserName();</b>
|
||||
|
||||
<b class="nc"> foodLabels.get(u).setText(String.valueOf(p.getFoodValue()));</b>
|
||||
<b class="nc"> prestigeLabels.get(u).setText(String.valueOf(p.getPrestigeValue()));</b>
|
||||
|
||||
<b class="nc"> List<ImageView> icons = iconViews.get(u);</b>
|
||||
<b class="nc"> for (int i = 0; i < icons.size(); i++) {</b>
|
||||
<b class="nc"> boolean empty = getPlayerCards(u, fields[i]).isEmpty();</b>
|
||||
<b class="nc"> icons.get(i).setOpacity(empty ? 0.3 : 1.0);</b>
|
||||
<b class="nc"> icons.get(i).setEffect(empty ? new ColorAdjust() : null);</b>
|
||||
}
|
||||
|
||||
<b class="nc"> VBox card = playerCards.get(u);</b>
|
||||
<b class="nc"> if(controller.getMiniModel().disconnectedPlayers.contains(u))</b>
|
||||
{
|
||||
<b class="nc"> card.getStyleClass().clear();</b>
|
||||
<b class="nc"> card.getStyleClass().add("player-card-crashed");</b>
|
||||
}
|
||||
else {
|
||||
<b class="nc"> card.getStyleClass().clear();</b>
|
||||
<b class="nc"> card.getStyleClass().add("player-card");</b>
|
||||
}
|
||||
|
||||
<b class="nc"> if (u.equals(current)) {</b>
|
||||
<b class="nc"> card.setStyle("-fx-effect: dropshadow(gaussian, #fff8dc, 15, 0.10, 0, 0)");</b>
|
||||
<b class="nc"> ScaleTransition st = new ScaleTransition(Duration.millis(150), card);</b>
|
||||
<b class="nc"> st.setToX(1.1);</b>
|
||||
<b class="nc"> st.setToY(1.1);</b>
|
||||
<b class="nc"> st.play();</b>
|
||||
} else {
|
||||
<b class="nc"> ScaleTransition st = new ScaleTransition(Duration.millis(150), card);</b>
|
||||
<b class="nc"> st.setToX(1.0);</b>
|
||||
<b class="nc"> st.setToY(1.0);</b>
|
||||
<b class="nc"> st.play();</b>
|
||||
<b class="nc"> card.setStyle("");</b>
|
||||
}
|
||||
|
||||
<b class="nc"> if (isError && u.equals(controller.getMyUsername())) {</b>
|
||||
<b class="nc"> TranslateTransition tt = new TranslateTransition(Duration.millis(56), card);</b>
|
||||
<b class="nc"> tt.setFromX(0);</b>
|
||||
<b class="nc"> tt.setByX(10);</b>
|
||||
<b class="nc"> tt.setCycleCount(6);</b>
|
||||
<b class="nc"> tt.setAutoReverse(true);</b>
|
||||
<b class="nc"> tt.play();</b>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Renders the top card of the upper building stack with a count badge; clicking opens the selection popup. */
|
||||
private void drawUpperBuilding() {
|
||||
<b class="nc"> ArrayList<BuildingCard> cardList = new ArrayList<>(controller.getMiniModel().upperListBuildingCards);</b>
|
||||
<b class="nc"> if (!cardList.isEmpty()) {</b>
|
||||
<b class="nc"> StackPane img = createCard(cardList.getLast(), true, true, upperList);</b>
|
||||
<b class="nc"> Label label = new Label(String.valueOf(cardList.size()));</b>
|
||||
<b class="nc"> label.setTranslateY(-56);</b>
|
||||
<b class="nc"> label.setTranslateX(10);</b>
|
||||
<b class="nc"> label.getStyleClass().add("label-large");</b>
|
||||
<b class="nc"> StackPane.setAlignment(label, Pos.TOP_RIGHT);</b>
|
||||
<b class="nc"> img.getChildren().add(label);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> openPopupUpperBuilding(cardList));</b>
|
||||
<b class="nc"> upperList.getChildren().add(img);</b>
|
||||
}
|
||||
}
|
||||
|
||||
/** Renders the top card of the lower building stack with a count badge; clicking opens the selection popup. */
|
||||
private void drawLowerBuilding() {
|
||||
<b class="nc"> ArrayList<BuildingCard> cardList = new ArrayList<>(controller.getMiniModel().lowerListBuildingCards);</b>
|
||||
<b class="nc"> if (!cardList.isEmpty()) {</b>
|
||||
<b class="nc"> StackPane img = createCard(cardList.getLast(), true, true, lowerList);</b>
|
||||
<b class="nc"> Label label = new Label(String.valueOf(cardList.size()));</b>
|
||||
<b class="nc"> label.setTranslateY(-56);</b>
|
||||
<b class="nc"> label.setTranslateX(10);</b>
|
||||
<b class="nc"> label.getStyleClass().add("label-large");</b>
|
||||
<b class="nc"> StackPane.setAlignment(label, Pos.TOP_RIGHT);</b>
|
||||
<b class="nc"> img.getChildren().add(label);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> openPopupLowerBuilding(cardList));</b>
|
||||
<b class="nc"> lowerList.getChildren().add(img);</b>
|
||||
}
|
||||
}
|
||||
|
||||
/** Renders a single card-type pile in the hand area, or an invisible placeholder if the list is empty. */
|
||||
private void drawMyHandList(ArrayList<? extends PlayableCard> cardList) {
|
||||
<b class="nc"> if (!cardList.isEmpty()) {</b>
|
||||
<b class="nc"> StackPane img = createCard(cardList.getLast(), true, true, myHand);</b>
|
||||
<b class="nc"> Label label = new Label(String.valueOf(cardList.size()));</b>
|
||||
<b class="nc"> label.setTranslateY(-56);</b>
|
||||
<b class="nc"> label.setTranslateX(10);</b>
|
||||
<b class="nc"> label.getStyleClass().add("label-large");</b>
|
||||
<b class="nc"> StackPane.setAlignment(label, Pos.TOP_RIGHT);</b>
|
||||
<b class="nc"> img.getChildren().add(label);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> openPopup(new ArrayList<>(cardList)));</b>
|
||||
<b class="nc"> myHand.getChildren().add(img);</b>
|
||||
} else {
|
||||
<b class="nc"> Region placeholder = new Region();</b>
|
||||
<b class="nc"> placeholder.prefHeightProperty().bind(myHand.getScene().heightProperty().subtract(56).divide(4).multiply(0.90));</b>
|
||||
<b class="nc"> placeholder.prefWidthProperty().bind(placeholder.prefHeightProperty().multiply(0.675));</b>
|
||||
<b class="nc"> placeholder.setStyle("-fx-background-color: transparent;");</b>
|
||||
<b class="nc"> myHand.getChildren().add(placeholder);</b>
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a copy of the named card collection for {@code username}. */
|
||||
private ArrayList<PlayableCard> getPlayerCards(String username, String type) {
|
||||
<b class="nc"> Player p = controller.getMiniModel().players.get(username);</b>
|
||||
<b class="nc"> return switch (type) {</b>
|
||||
<b class="nc"> case "artists" -> new ArrayList<>(p.getArtists());</b>
|
||||
<b class="nc"> case "gatherers" -> new ArrayList<>(p.getGatherers());</b>
|
||||
<b class="nc"> case "inventors" -> new ArrayList<>(p.getInventors());</b>
|
||||
<b class="nc"> case "builders" -> new ArrayList<>(p.getBuilders());</b>
|
||||
<b class="nc"> case "shamans" -> new ArrayList<>(p.getShamans());</b>
|
||||
<b class="nc"> case "hunters" -> new ArrayList<>(p.getHunters());</b>
|
||||
<b class="nc"> case "building" -> new ArrayList<>(p.getBuildingCards());</b>
|
||||
<b class="nc"> default -> new ArrayList<>();</b>
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// ==== ABSOLUTES ====
|
||||
/** Clears and rebuilds the upper tribe row with click handlers for drawing, then appends the upper building stack. */
|
||||
private void renderUpper() {
|
||||
<b class="nc"> upperList.setSpacing(14);</b>
|
||||
<b class="nc"> upperList.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> upperList.getChildren().clear();</b>
|
||||
|
||||
<b class="nc"> int i = 0;</b>
|
||||
<b class="nc"> for (TribeCard card : controller.getMiniModel().upperListTribeCards) {</b>
|
||||
<b class="nc"> final int index = i;</b>
|
||||
<b class="nc"> StackPane img = createCard(card, true, true, upperList);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> controller.drawUpperTribeCard(index));</b>
|
||||
<b class="nc"> upperList.getChildren().add(img);</b>
|
||||
<b class="nc"> i++;</b>
|
||||
}
|
||||
<b class="nc"> drawUpperBuilding();</b>
|
||||
}
|
||||
|
||||
/** Clears and rebuilds the lower tribe row with click handlers for drawing, then appends the lower building stack. */
|
||||
private void renderLower() {
|
||||
<b class="nc"> lowerList.setSpacing(14);</b>
|
||||
<b class="nc"> lowerList.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> lowerList.getChildren().clear();</b>
|
||||
|
||||
<b class="nc"> int i = 0;</b>
|
||||
<b class="nc"> for (TribeCard card : controller.getMiniModel().lowerListTribeCards) {</b>
|
||||
<b class="nc"> final int index = i;</b>
|
||||
<b class="nc"> StackPane img = createCard(card, true, true, lowerList);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> controller.drawLowerTribeCard(index));</b>
|
||||
<b class="nc"> lowerList.getChildren().add(img);</b>
|
||||
<b class="nc"> i++;</b>
|
||||
}
|
||||
<b class="nc"> drawLowerBuilding();</b>
|
||||
}
|
||||
|
||||
/** Sets the full-cover background image on the main HBox container. */
|
||||
private void renderBackground() {
|
||||
<b class="nc"> BackgroundSize size = new BackgroundSize(</b>
|
||||
BackgroundSize.AUTO, BackgroundSize.AUTO,
|
||||
false, false, true, true
|
||||
);
|
||||
<b class="nc"> mainHBox.setBackground(new Background(new BackgroundImage(</b>
|
||||
<b class="nc"> loadImage("/GUIImages/Background.png"),</b>
|
||||
BackgroundRepeat.NO_REPEAT,
|
||||
BackgroundRepeat.NO_REPEAT,
|
||||
BackgroundPosition.CENTER,
|
||||
size
|
||||
)));
|
||||
}
|
||||
|
||||
/** Clears the board area and orchestrates deck, order card, and slot-map rendering. */
|
||||
private void renderBoard() {
|
||||
<b class="nc"> board.setSpacing(14);</b>
|
||||
<b class="nc"> board.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> board.getChildren().clear();</b>
|
||||
<b class="nc"> renderDeck();</b>
|
||||
<b class="nc"> renderOrder();</b>
|
||||
<b class="nc"> renderSlotMap();</b>
|
||||
}
|
||||
|
||||
/** Adds the era-specific deck back image to the board. */
|
||||
private void renderDeck() {
|
||||
<b class="nc"> String path = switch (controller.getMiniModel().currentState.getEra()) {</b>
|
||||
<b class="nc"> case 1 -> "/GUIImages/Backs/back-001.png";</b>
|
||||
<b class="nc"> case 2 -> "/GUIImages/Backs/back-030.png";</b>
|
||||
<b class="nc"> case 3 -> "/GUIImages/Backs/back-058.png";</b>
|
||||
<b class="nc"> default -> "/GUIImages/Backs/back-001.png";</b>
|
||||
<b class="nc"> };</b>
|
||||
<b class="nc"> ImageView back = new ImageView(loadImage(path));</b>
|
||||
<b class="nc"> back.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(56).divide(4).multiply(0.94));</b>
|
||||
<b class="nc"> back.setPreserveRatio(true);</b>
|
||||
<b class="nc"> addClip(back);</b>
|
||||
<b class="nc"> addShadow(back);</b>
|
||||
<b class="nc"> addHoverZoom(back);</b>
|
||||
<b class="nc"> board.getChildren().add(back);</b>
|
||||
}
|
||||
|
||||
/** Renders the order card and overlays each player's totem at their proportional position. */
|
||||
private void renderOrder() {
|
||||
<b class="nc"> int numPlayers = controller.getMiniModel().players.size();</b>
|
||||
<b class="nc"> StackPane card = createOrder(Integer.toString(numPlayers));</b>
|
||||
|
||||
<b class="nc"> Map<Integer, double[]> slotPositions = Map.of(</b>
|
||||
<b class="nc"> 2, new double[]{0.229, 0.413},</b>
|
||||
<b class="nc"> 3, new double[]{0.183, 0.367, 0.548},</b>
|
||||
<b class="nc"> 4, new double[]{0.142, 0.316, 0.503, 0.690},</b>
|
||||
<b class="nc"> 5, new double[]{0.066, 0.251, 0.433, 0.617, 0.802}</b>
|
||||
);
|
||||
<b class="nc"> double[] positions = slotPositions.get(numPlayers);</b>
|
||||
<b class="nc"> if (positions == null) return;</b>
|
||||
|
||||
<b class="nc"> Pane overlay = new Pane();</b>
|
||||
<b class="nc"> overlay.setPickOnBounds(false);</b>
|
||||
<b class="nc"> overlay.setMouseTransparent(true);</b>
|
||||
|
||||
<b class="nc"> for (int i = 0; i < controller.getMiniModel().orderLogicCard.getPlayerList().size(); i++) {</b>
|
||||
<b class="nc"> OrderPlayer op = controller.getMiniModel().orderLogicCard.getPlayerList().get(i);</b>
|
||||
|
||||
<b class="nc"> ImageView totem = new ImageView(loadImage(</b>
|
||||
<b class="nc"> "/GUIImages/Totems/totem_" + op.getPlayer().getTotem().toString().toLowerCase(Locale.ROOT) + ".png"</b>
|
||||
));
|
||||
<b class="nc"> totem.setPreserveRatio(true);</b>
|
||||
|
||||
<b class="nc"> if (op.isPlayed()) {</b>
|
||||
<b class="nc"> totem.setVisible(false);</b>
|
||||
}
|
||||
|
||||
<b class="nc"> final double yRatio = positions[i];</b>
|
||||
|
||||
<b class="nc"> overlay.prefHeightProperty().bind(card.heightProperty());</b>
|
||||
<b class="nc"> overlay.prefWidthProperty().bind(card.widthProperty());</b>
|
||||
|
||||
<b class="nc"> totem.fitHeightProperty().bind(card.heightProperty().multiply(0.323));</b>
|
||||
|
||||
<b class="nc"> card.heightProperty().addListener((obs, ov, nv) -> {</b>
|
||||
<b class="nc"> totem.setLayoutY(nv.doubleValue() * (yRatio-0.196));</b>
|
||||
});
|
||||
<b class="nc"> card.widthProperty().addListener((obs, ov, nv) -> {</b>
|
||||
<b class="nc"> totem.setLayoutX(nv.doubleValue() * 0.364);</b>
|
||||
});
|
||||
|
||||
// initialize immediately if already laid out
|
||||
<b class="nc"> if (card.getHeight() > 0) totem.setLayoutY(card.getHeight() *(yRatio-0.196));</b>
|
||||
<b class="nc"> if (card.getWidth() > 0) totem.setLayoutX(card.getWidth() * 0.364);</b>
|
||||
|
||||
<b class="nc"> overlay.getChildren().add(totem);</b>
|
||||
}
|
||||
|
||||
<b class="nc"> card.getChildren().add(overlay);</b>
|
||||
<b class="nc"> board.getChildren().add(card);</b>
|
||||
}
|
||||
|
||||
/** Adds a clickable slot widget for each entry in the slot-player map. */
|
||||
private void renderSlotMap() {
|
||||
<b class="nc"> int i = 0;</b>
|
||||
<b class="nc"> for (Map.Entry<Slot, Player> entry : controller.getMiniModel().slotPlayerMap.entrySet()) {</b>
|
||||
<b class="nc"> Slot slot = entry.getKey();</b>
|
||||
<b class="nc"> final int index = i;</b>
|
||||
<b class="nc"> StackPane img = createSlot(slot, true, true);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> controller.slotChoice(index));</b>
|
||||
<b class="nc"> board.getChildren().add(img);</b>
|
||||
<b class="nc"> i++;</b>
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears and re-renders all seven card-type piles in the local player's hand area. */
|
||||
private void renderMyHand() {
|
||||
<b class="nc"> myHand.getChildren().clear();</b>
|
||||
<b class="nc"> myHand.setSpacing(14);</b>
|
||||
<b class="nc"> myHand.setAlignment(Pos.CENTER);</b>
|
||||
|
||||
<b class="nc"> Player me = controller.getMiniModel().players.get(controller.getMyUsername());</b>
|
||||
<b class="nc"> drawMyHandList(me.getArtists());</b>
|
||||
<b class="nc"> drawMyHandList(me.getGatherers());</b>
|
||||
<b class="nc"> drawMyHandList(me.getInventors());</b>
|
||||
<b class="nc"> drawMyHandList(me.getBuilders());</b>
|
||||
<b class="nc"> drawMyHandList(me.getShamans());</b>
|
||||
<b class="nc"> drawMyHandList(me.getHunters());</b>
|
||||
<b class="nc"> drawMyHandList(me.getBuildingCards());</b>
|
||||
}
|
||||
|
||||
|
||||
// ==== POPUP ====
|
||||
/** Creates and configures the shared card-preview popup container. */
|
||||
private void initPopup() {
|
||||
<b class="nc"> popupCards = new HBox(10);</b>
|
||||
<b class="nc"> popupCards.setAlignment(Pos.CENTER);</b>
|
||||
<b class="nc"> popupCards.setPadding(new Insets(10));</b>
|
||||
<b class="nc"> popupCards.setStyle(</b>
|
||||
"-fx-background-color: #b42224;" +
|
||||
"-fx-border-color: black;" +
|
||||
"-fx-border-width: 2;" +
|
||||
"-fx-border-radius: 10;" +
|
||||
"-fx-background-radius: 10;"
|
||||
);
|
||||
|
||||
<b class="nc"> popup.getContent().add(popupCards);</b>
|
||||
<b class="nc"> popup.setAutoHide(false);</b>
|
||||
<b class="nc"> popup.addEventHandler(Event.ANY, e -> {</b>
|
||||
<b class="nc"> if (popup.getScene() != null) {</b>
|
||||
<b class="nc"> popup.getScene().setFill(Color.TRANSPARENT);</b>
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Centers the popup over the current window and makes it visible. */
|
||||
private void showPopup() {
|
||||
<b class="nc"> Window window = myHand.getScene().getWindow();</b>
|
||||
<b class="nc"> popup.show(window, 0, 0);</b>
|
||||
<b class="nc"> popup.getScene().setFill(Color.TRANSPARENT);</b>
|
||||
<b class="nc"> popup.setX(window.getX() + (window.getWidth() - popup.getWidth()) / 2);</b>
|
||||
<b class="nc"> popup.setY(window.getY() + (window.getHeight() - popup.getHeight()) / 2);</b>
|
||||
}
|
||||
|
||||
/** Populates the popup with non-clickable card images and shows it. */
|
||||
private void openPopup(ArrayList<? extends PlayableCard> cardList) {
|
||||
<b class="nc"> popupCards.getChildren().clear();</b>
|
||||
<b class="nc"> for (PlayableCard card : cardList) {</b>
|
||||
<b class="nc"> popupCards.getChildren().add(createCardPopup(card, false, false));</b>
|
||||
}
|
||||
<b class="nc"> showPopup();</b>
|
||||
}
|
||||
|
||||
/** Populates the popup with clickable upper-building cards; clicking one draws it via the controller. */
|
||||
private void openPopupUpperBuilding(ArrayList<BuildingCard> cardList) {
|
||||
<b class="nc"> popupCards.getChildren().clear();</b>
|
||||
<b class="nc"> for (int i = 0; i < cardList.size(); i++) {</b>
|
||||
<b class="nc"> final int index = i;</b>
|
||||
<b class="nc"> StackPane img = createCardPopup(cardList.get(i), true, false);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> {</b>
|
||||
<b class="nc"> popup.hide();</b>
|
||||
<b class="nc"> controller.drawUpperBuildingCard(index);</b>
|
||||
});
|
||||
<b class="nc"> popupCards.getChildren().add(img);</b>
|
||||
}
|
||||
<b class="nc"> showPopup();</b>
|
||||
}
|
||||
|
||||
/** Populates the popup with clickable lower-building cards; clicking one draws it via the controller. */
|
||||
private void openPopupLowerBuilding(ArrayList<BuildingCard> cardList) {
|
||||
<b class="nc"> popupCards.getChildren().clear();</b>
|
||||
<b class="nc"> for (int i = 0; i < cardList.size(); i++) {</b>
|
||||
<b class="nc"> final int index = i;</b>
|
||||
<b class="nc"> StackPane img = createCardPopup(cardList.get(i), true, false);</b>
|
||||
<b class="nc"> img.setOnMouseClicked(e -> {</b>
|
||||
<b class="nc"> popup.hide();</b>
|
||||
<b class="nc"> controller.drawLowerBuildingCard(index);</b>
|
||||
});
|
||||
<b class="nc"> popupCards.getChildren().add(img);</b>
|
||||
}
|
||||
<b class="nc"> showPopup();</b>
|
||||
}
|
||||
|
||||
/** Shows the deck details/rules card in the popup. */
|
||||
private void openDetailsPopup() {
|
||||
<b class="nc"> popupCards.getChildren().clear();</b>
|
||||
<b class="nc"> ImageView img = new ImageView(loadImage("/GUIImages/Backs/back-118.png"));</b>
|
||||
<b class="nc"> img.setFitHeight(290);</b>
|
||||
<b class="nc"> img.setPreserveRatio(true);</b>
|
||||
<b class="nc"> addClip(img);</b>
|
||||
<b class="nc"> StackPane wrapper = new StackPane(img);</b>
|
||||
<b class="nc"> addShadow(wrapper);</b>
|
||||
<b class="nc"> popupCards.getChildren().add(wrapper);</b>
|
||||
<b class="nc"> showPopup();</b>
|
||||
}
|
||||
|
||||
/** Creates a fixed-height {@link StackPane} card widget suitable for use inside the popup. */
|
||||
private StackPane createCardPopup(PlayableCard card, boolean withZoom, boolean withShadow) {
|
||||
<b class="nc"> ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));</b>
|
||||
<b class="nc"> img.setFitHeight(200);</b>
|
||||
<b class="nc"> img.setPreserveRatio(true);</b>
|
||||
<b class="nc"> addClip(img);</b>
|
||||
<b class="nc"> StackPane wrapper = new StackPane(img);</b>
|
||||
<b class="nc"> if (withShadow) addShadow(wrapper);</b>
|
||||
<b class="nc"> if (withZoom) addHoverZoom(wrapper);</b>
|
||||
<b class="nc"> return wrapper;</b>
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var msie = false, msie9 = false;
|
||||
/*@cc_on
|
||||
msie = true;
|
||||
@if (@_jscript_version >= 9)
|
||||
msie9 = true;
|
||||
@end
|
||||
@*/
|
||||
|
||||
if (!msie || msie && msie9) {
|
||||
hljs.highlightAll()
|
||||
hljs.initLineNumbersOnLoad();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<div class="footer">
|
||||
|
||||
<div style="float:right;">generated on 2026-06-14 21:53</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user