Shadows, Zoom, Icons added
This commit is contained in:
@@ -14,8 +14,6 @@ public class ClientLauncherGUI extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) {
|
||||
Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14);
|
||||
|
||||
LoginView loginView = new LoginView();
|
||||
GUI view = new GUI(stage);
|
||||
|
||||
|
||||
@@ -8,16 +8,26 @@ import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Model.PlayableCard;
|
||||
import it.polimi.ingsw.gc14.Model.Player;
|
||||
import it.polimi.ingsw.gc14.Model.Slot;
|
||||
import javafx.animation.ScaleTransition;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
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.util.Duration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MainFXMLController {
|
||||
@@ -42,6 +52,7 @@ public class MainFXMLController {
|
||||
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 setController(ClientController controller) {this.controller = controller;}
|
||||
@@ -52,7 +63,8 @@ public class MainFXMLController {
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
// Reapply CSS
|
||||
// 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();
|
||||
@@ -73,6 +85,80 @@ public class MainFXMLController {
|
||||
renderSidePanel();
|
||||
}
|
||||
|
||||
// ==== HELPER ====
|
||||
private ImageView createSlot(Slot slot) {
|
||||
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);
|
||||
return img;
|
||||
}
|
||||
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));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -93,41 +179,15 @@ public class MainFXMLController {
|
||||
}
|
||||
|
||||
// UPPER, LOWER AND BOARD
|
||||
private ImageView createCard(PlayableCard card) {
|
||||
ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png")));
|
||||
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);
|
||||
return img;
|
||||
}
|
||||
private ImageView createSlot(Slot slot) {
|
||||
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);
|
||||
return img;
|
||||
}
|
||||
private void renderUpper() {
|
||||
upperList.setSpacing(6);
|
||||
upperList.setSpacing(14);
|
||||
upperList.setAlignment(Pos.CENTER);
|
||||
upperList.getChildren().clear();
|
||||
|
||||
int i = 0;
|
||||
for (TribeCard card : model.getUpperListTribeCards()) {
|
||||
final int index = i;
|
||||
ImageView img = createCard(card);
|
||||
StackPane img = createCard(card, true, true);
|
||||
img.setOnMouseClicked(e -> controller.drawUpperTribeCard(username, index));
|
||||
upperList.getChildren().add(img);
|
||||
i++;
|
||||
@@ -135,14 +195,14 @@ public class MainFXMLController {
|
||||
i = 0;
|
||||
for (BuildingCard card : model.getUpperListBuilding()) {
|
||||
final int index = i;
|
||||
ImageView img = createCard(card);
|
||||
StackPane img = createCard(card, true, true);
|
||||
img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(username, index));
|
||||
upperList.getChildren().add(img);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
private void renderBoard() {
|
||||
board.setSpacing(6);
|
||||
board.setSpacing(14);
|
||||
board.setAlignment(Pos.CENTER);
|
||||
board.getChildren().clear();
|
||||
|
||||
@@ -157,14 +217,14 @@ public class MainFXMLController {
|
||||
}
|
||||
}
|
||||
private void renderLower() {
|
||||
lowerList.setSpacing(6);
|
||||
lowerList.setSpacing(14);
|
||||
lowerList.setAlignment(Pos.CENTER);
|
||||
lowerList.getChildren().clear();
|
||||
|
||||
int i = 0;
|
||||
for (TribeCard card : model.getLowerListTribeCards()) {
|
||||
final int index = i;
|
||||
ImageView img = createCard(card);
|
||||
StackPane img = createCard(card, true, true);
|
||||
img.setOnMouseClicked(e -> controller.drawLowerTribeCard(username, index));
|
||||
lowerList.getChildren().add(img);
|
||||
i++;
|
||||
@@ -172,7 +232,7 @@ public class MainFXMLController {
|
||||
i = 0;
|
||||
for (BuildingCard card : model.getLowerListBuilding()) {
|
||||
final int index = i;
|
||||
ImageView img = createCard(card);
|
||||
StackPane img = createCard(card, true, true);
|
||||
img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(username, index));
|
||||
lowerList.getChildren().add(img);
|
||||
i++;
|
||||
@@ -180,32 +240,9 @@ public class MainFXMLController {
|
||||
}
|
||||
|
||||
// MY HAND
|
||||
private void drawMyHandList(HBox myHand, ArrayList<? extends PlayableCard> cardList) {
|
||||
if (!cardList.isEmpty()) {
|
||||
|
||||
ImageView img = createCard(cardList.getLast());
|
||||
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);
|
||||
|
||||
StackPane stack = new StackPane(img, label);
|
||||
stack.setClip(null);
|
||||
stack.setOnMouseClicked(e -> openPopup(cardList));
|
||||
|
||||
myHand.getChildren().add(stack);
|
||||
} else {
|
||||
Region placeholder = new Region();
|
||||
placeholder.setPrefHeight(200);
|
||||
placeholder.setPrefWidth(200 * 0.675);
|
||||
placeholder.setStyle("-fx-background-color: transparent;");
|
||||
myHand.getChildren().add(placeholder);
|
||||
}
|
||||
}
|
||||
private void renderMyHand() {
|
||||
myHand.getChildren().clear();
|
||||
myHand.setSpacing(6);
|
||||
myHand.setSpacing(14);
|
||||
myHand.setAlignment(Pos.CENTER);
|
||||
|
||||
drawMyHandList(myHand, model.getPlayerByUsername(username).artists);
|
||||
@@ -216,16 +253,36 @@ public class MainFXMLController {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SIDE PANEL
|
||||
private void renderSidePanel() {
|
||||
sidePanel.getChildren().clear();
|
||||
sidePanel.setSpacing(6);
|
||||
sidePanel.setAlignment(Pos.CENTER);
|
||||
|
||||
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);
|
||||
@@ -249,42 +306,104 @@ public class MainFXMLController {
|
||||
foodLabel.getStyleClass().add("label-small");
|
||||
Label prestigeLabel = new Label("Prestige: " + player.getPrestigeValue());
|
||||
prestigeLabel.getStyleClass().add("label-small");
|
||||
card.getChildren().addAll(usernameLabel, foodLabel, prestigeLabel);
|
||||
HBox icons = new HBox();
|
||||
icons.setSpacing(6);
|
||||
icons.setAlignment(Pos.CENTER);
|
||||
renderIcons(icons, player);
|
||||
card.getChildren().addAll(usernameLabel, foodLabel, prestigeLabel, icons);
|
||||
|
||||
ArrayList<PlayableCard> playerCard = new ArrayList<>();
|
||||
playerCard.addAll(model.getPlayerByUsername(player.getUserName()).artists);
|
||||
playerCard.addAll(model.getPlayerByUsername(player.getUserName()).gatherers);
|
||||
playerCard.addAll(model.getPlayerByUsername(player.getUserName()).inventors);
|
||||
playerCard.addAll(model.getPlayerByUsername(player.getUserName()).builders);
|
||||
playerCard.addAll(model.getPlayerByUsername(player.getUserName()).shamans);
|
||||
playerCard.addAll(model.getPlayerByUsername(player.getUserName()).hunters);
|
||||
playerCard.addAll(model.getPlayerByUsername(player.getUserName()).buildingCards);
|
||||
|
||||
card.setOnMouseClicked(e -> openPopup(playerCard));
|
||||
playersHand.getChildren().add(card);
|
||||
}
|
||||
}
|
||||
private void renderIcons(HBox icons, Player player) {
|
||||
String[][] iconTypes = {
|
||||
{"Artist", "artists"},
|
||||
{"Gatherer", "gatherers"},
|
||||
{"Inventor", "inventors"},
|
||||
{"Builder", "builders"},
|
||||
{"Shaman", "shamans"},
|
||||
{"Hunter", "hunters"}
|
||||
};
|
||||
|
||||
for (String[] type : iconTypes) {
|
||||
String iconName = type[0];
|
||||
String fieldName = type[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.5);
|
||||
} else {
|
||||
icon.setOnMouseClicked(e -> openPopup(cards));
|
||||
addHoverZoom(icon);
|
||||
}
|
||||
|
||||
icons.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.getStyleClass().add("popup");
|
||||
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(javafx.event.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) {
|
||||
ImageView img = createCard(card);
|
||||
StackPane img = createCard(card, false, false);
|
||||
popupCards.getChildren().add(img);
|
||||
}
|
||||
|
||||
javafx.stage.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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user