Added quit button to GUI

This commit is contained in:
2026-06-14 23:19:54 +02:00
parent d9fa4225da
commit 6e8eda0198
9 changed files with 38 additions and 50 deletions
@@ -311,7 +311,7 @@ public class Player implements Serializable {
}
if(!this.gatherers.isEmpty()){
table.addRow(this.gatherers.size() + " Gatherers: \uD83C\uDF56:-" + 3*this.gatherers.size());
table.addRow(this.gatherers.size() + " Gatherers: \uD83C\uDF56:" + 3*this.gatherers.size());
if(last == 3){
table.addSeparator();
}
@@ -6,6 +6,8 @@ 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 javafx.application.Platform;
import javafx.animation.PauseTransition;
import javafx.animation.ScaleTransition;
import javafx.animation.TranslateTransition;
import javafx.event.Event;
@@ -54,6 +56,8 @@ public class MainFXMLController {
@FXML private Button skipBtn;
/** Button that opens the game details popup. */
@FXML private Button detailsBtn;
/** Button that disconnects and closes the client. */
@FXML private Button quitBtn;
/** Label showing the current round number and game stage. */
@FXML private Label infoText;
/** Maps each player's username to their current food-value label in the side panel. */
@@ -98,6 +102,30 @@ public class MainFXMLController {
public void setController(ClientController controller) {
this.controller = controller;
skipBtn.setOnAction(e -> controller.skipTurn());
PauseTransition quitTimer = new PauseTransition(javafx.util.Duration.seconds(3));
quitTimer.setOnFinished(e -> {
quitBtn.setText("Quit");
quitBtn.setStyle("");
});
final boolean[] quitPending = {false};
quitBtn.setOnAction(e -> {
if (quitPending[0]) {
controller.disconnect();
Platform.exit();
System.exit(0);
} else {
quitPending[0] = true;
quitBtn.setText("Sure?");
quitBtn.setStyle("-fx-background-color: #c0392b; -fx-text-fill: white;");
quitTimer.playFromStart();
quitTimer.setOnFinished(ev -> {
quitPending[0] = false;
quitBtn.setText("Quit");
quitBtn.setStyle("");
});
}
});
}
/** Initializes the scene: loads fonts, sets up the popup, and registers input listeners. */
@@ -107,6 +135,7 @@ public class MainFXMLController {
addHoverZoom(skipBtn);
addHoverZoom(detailsBtn);
addHoverZoom(quitBtn);
popup = new Popup();
mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> {
if (newScene != null) {
@@ -295,8 +295,8 @@ public class TUI implements IView {
var upperCards = new AsciiTable(BorderStyle.ROUNDED, 2);
var lowerCards = new AsciiTable(BorderStyle.ROUNDED, 2);
upperCards.addHeader("Char/Events", "Building");
lowerCards.addHeader("Char/Events", "Building");
upperCards.addHeader("Char/\033[38;5;180mEvents\033[0m", "Building");
lowerCards.addHeader("Char/\033[38;5;180mEvents\033[0m", "Building");
int maxU = Math.max(model.upperListTribeCards.size(), model.upperListBuildingCards.size());
for (int i = 0; i < maxU; i++) {
+2 -1
View File
@@ -70,7 +70,8 @@
<HBox alignment="CENTER" fx:id="buttonRow">
<HBox spacing="10">
<Button fx:id="skipBtn" styleClass="action-button" text="Skip Turn"/>
<Button fx:id="detailsBtn" styleClass="action-button" text="Ending Details"/>
<Button fx:id="detailsBtn" styleClass="action-button" text="Details"/>
<Button fx:id="quitBtn" styleClass="action-button" text="Quit"/>
</HBox>
<VBox.margin>
<Insets top="5" right="5" bottom="5" left="5"/>
@@ -143,6 +143,6 @@ class CavePaintingsTest {
int NPrestigeMul = 3;
CavePaintings cv1 = new CavePaintings(Era, NLower,NPrestigeRem,NPrestigeMul);
assertEquals(cv1.getType() + " 0-"+(NLower-1)+":"+NPrestigeRem+" "+NLower+"+:"+NPrestigeMul, cv1.toStringBoard());
assertEquals("\033[38;5;180m" + cv1.getType() + " 0-"+(NLower-1)+":"+NPrestigeRem+" "+NLower+"+:"+NPrestigeMul+"\033[0m", cv1.toStringBoard());
}
}
@@ -146,6 +146,6 @@ class HuntTest {
int prestigeMultiplier = 3;
Hunt cv1 = new Hunt(Era, prestigeMultiplier);
assertEquals(cv1.getType() + " 1🍖+" + prestigeMultiplier + "🏅×🏹", cv1.toStringBoard());
assertEquals("\033[38;5;180mHUNT 1\uD83C\uDF56+" + prestigeMultiplier + "\uD83C\uDFC5×\uD83C\uDFF9" + "\033[0m", cv1.toStringBoard());
}
}
@@ -228,6 +228,6 @@ class ShamanicRitualTest {
int prestigeToRem = 2;
ShamanicRitual cv1 = new ShamanicRitual(Era, prestigeToAdd, prestigeToRem);
assertEquals(cv1.getType() + " 🌟>:" + prestigeToAdd + " 🌟<:" + prestigeToRem, cv1.toStringBoard());
assertEquals("\033[38;5;180m" + cv1.getType() + " 🌟>:" + prestigeToAdd + " 🌟<:" + prestigeToRem + "\033[0m", cv1.toStringBoard());
}
}
@@ -164,7 +164,7 @@ class SustenanceTest {
int prestigeDebt = 15;
Sustenance cv1 = new Sustenance(Era, prestigeDebt);
assertEquals(cv1.getType() + " -1🍖/-" + prestigeDebt + "🏅", cv1.toStringBoard());
assertEquals("\033[38;5;180m" + cv1.getType() + " -1🍖/-" + prestigeDebt + "🏅\033[0m", cv1.toStringBoard());
}
}
@@ -195,48 +195,6 @@ class PlayerTest {
});
}
@Test
void tostring() {
Player p = new Player("test_usr");
p.addPrestige(15);
p.addFood(7);
p.getArtists().add(new Artist(1));
p.getArtists().add(new Artist(1));
p.getArtists().add(new Artist(1));
p.getArtists().add(new Artist(1));
p.getArtists().add(new Artist(1));
p.getArtists().add(new Artist(1));
p.getArtists().add(new Artist(2));
p.getBuilders().add(new Builder(2, 5, 1));
p.getGatherers().add(new Gatherer(1, 3));
p.getShamans().add(new Shaman(2, 3, 3));
p.getShamans().add(new Shaman(2, 3, 4));
p.getInventors().add(new Inventor(3, 1));
p.getHunters().add(new Hunter(3, true));
p.getHunters().add(new Hunter(2, false));
p.getBuildingCards().add(new BuildingCard(2, 1,2, 5));
p.getBuildingCards().add(new BuildingCard(2, 2,3, 6));
p.getBuildingCards().add(new Building1(2, 5, 5, CharacterType.INVENTOR));
p.getBuildingCards().add(new Building1(2, 5, 5, CharacterType.SHAMAN));
p.getBuildingCards().add(new Building11(1, 5, 7, CharacterType.ARTIST , 3));
assertEquals(
"╭────────────────────────────────────────────────────────────────────────────╮\n" +
"│ test_usr | 🍖:7 | 🏅:15 │\n" +
"├────────────────────────────────────────────────────────────────────────────┤\n" +
"│ CHARACTERS │\n" +
"│ 7 Artists: 🎨:7 │\n" +
"│ 1 Builders: 🔨:5 🏅:1 │\n" +
"│ 1 Gatherers: -\uD83C\uDF56:3 │\n" +
"│ 2 Shamans: 🌟:6 │\n" +
"│ 1 Inventors: 1:1 │\n" +
"│ 2 Hunters: 🍖1 │\n" +
"├────────────────────────────────────────────────────────────────────────────┤\n" +
"│ BUILDING CARDS 🏅:28 │\n" +
"│ 5 Buildings: ID:2, ID:2, ID:1 (Icon:INV), ID:1 (Icon:SHA), ID:11 (🏅:ART×3)│\n" +
"╰────────────────────────────────────────────────────────────────────────────╯", p.toString());
}
@Test
void toStringShouldCoverAllLastCharacterCases() {
Player empty = new Player("empty");