Generated
+2
-2
@@ -8,7 +8,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="25" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_26" default="true" project-jdk-name="openjdk-26" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -3,111 +3,180 @@ package it.polimi.ingsw.gc14.View.GUI;
|
|||||||
import it.polimi.ingsw.gc14.Controller.ClientController;
|
import it.polimi.ingsw.gc14.Controller.ClientController;
|
||||||
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
|
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
|
||||||
import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient;
|
import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient;
|
||||||
|
import javafx.animation.*;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.css.PseudoClass;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.geometry.Rectangle2D;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.stage.Screen;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.*;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.NetworkInterface;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class LoginFXMLController {
|
public class LoginFXMLController {
|
||||||
|
|
||||||
|
@FXML private ImageView backgroundImage;
|
||||||
@FXML private TextField campoNome;
|
@FXML private TextField campoNome;
|
||||||
@FXML private TextField campoNumPlayers;
|
@FXML private TextField campoNumPlayers;
|
||||||
@FXML private TextField campoIP;
|
@FXML private TextField campoIP;
|
||||||
@FXML private RadioButton btnRMI;
|
|
||||||
@FXML private RadioButton btnTCP;
|
|
||||||
@FXML private Button btnAccedi;
|
@FXML private Button btnAccedi;
|
||||||
@FXML private Label labelErrore;
|
@FXML private Label labelErrore;
|
||||||
@FXML private ComboBox<String> comboInterfaccia;
|
@FXML private VBox formPanel;
|
||||||
|
@FXML private StackPane protocolToggle;
|
||||||
|
@FXML private Region toggleThumb;
|
||||||
|
@FXML private Label labelRMI;
|
||||||
|
@FXML private Label labelTCP;
|
||||||
|
|
||||||
|
private boolean isRMI = true;
|
||||||
private ClientController controller;
|
private ClientController controller;
|
||||||
|
|
||||||
|
// Definiamo lo pseudo-stato custom per il CSS corrispondente a ":active-protocol"
|
||||||
|
private final PseudoClass activeProtocolPseudo = PseudoClass.getPseudoClass("active-protocol");
|
||||||
|
|
||||||
public void setController(ClientController controller) {
|
public void setController(ClientController controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
ToggleGroup group = new ToggleGroup();
|
// Background setup
|
||||||
btnRMI.setToggleGroup(group);
|
Image img = new Image(getClass().getResourceAsStream("/GUIImages/Background.png"));
|
||||||
btnTCP.setToggleGroup(group);
|
backgroundImage.setImage(img);
|
||||||
|
Rectangle2D screenBounds = Screen.getPrimary().getBounds();
|
||||||
|
backgroundImage.setFitWidth(screenBounds.getWidth());
|
||||||
|
backgroundImage.setFitHeight(screenBounds.getHeight());
|
||||||
|
|
||||||
new Thread(() -> {
|
// Protocol toggle configuration
|
||||||
try {
|
protocolToggle.setOnMouseClicked(e -> switchProtocol());
|
||||||
List<String> ips = new ArrayList<>();
|
protocolToggle.setStyle(protocolToggle.getStyle() + " -fx-cursor: hand;");
|
||||||
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
|
||||||
while (interfaces.hasMoreElements()) {
|
// Inizializza lo stato grafico iniziale (RMI attivo)
|
||||||
NetworkInterface ni = interfaces.nextElement();
|
labelRMI.pseudoClassStateChanged(activeProtocolPseudo, true);
|
||||||
if (!ni.isUp() || ni.isLoopback() || ni.isVirtual()) continue;
|
labelTCP.pseudoClassStateChanged(activeProtocolPseudo, false);
|
||||||
Enumeration<InetAddress> addresses = ni.getInetAddresses();
|
|
||||||
while (addresses.hasMoreElements()) {
|
// Login Action
|
||||||
InetAddress addr = addresses.nextElement();
|
|
||||||
if (addr instanceof Inet4Address)
|
|
||||||
ips.add(ni.getDisplayName() + " -> " + addr.getHostAddress());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
comboInterfaccia.getItems().addAll(ips);
|
|
||||||
if (!ips.isEmpty()) comboInterfaccia.getSelectionModel().selectFirst();
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
Platform.runLater(() -> labelErrore.setText("Errore nel rilevare le interfacce."));
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
btnAccedi.setOnAction(e -> onAccediClick());
|
btnAccedi.setOnAction(e -> onAccediClick());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void switchProtocol() {
|
||||||
|
isRMI = !isRMI;
|
||||||
|
|
||||||
|
TranslateTransition tt = new TranslateTransition(Duration.millis(200), toggleThumb);
|
||||||
|
tt.setToX(isRMI ? 0 : 110);
|
||||||
|
tt.play();
|
||||||
|
|
||||||
|
// Modifica in modo sicuro lo stato senza distruggere i parametri di layout dei nodi
|
||||||
|
labelRMI.pseudoClassStateChanged(activeProtocolPseudo, isRMI);
|
||||||
|
labelTCP.pseudoClassStateChanged(activeProtocolPseudo, !isRMI);
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void onAccediClick() {
|
private void onAccediClick() {
|
||||||
String nome = campoNome.getText().trim();
|
String nome = campoNome.getText().trim();
|
||||||
controller.setMyUsername(nome);
|
|
||||||
String ip = campoIP.getText().trim();
|
String ip = campoIP.getText().trim();
|
||||||
|
|
||||||
|
if (nome.isEmpty()) {
|
||||||
|
showError("Please select a name.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int numPlayers;
|
int numPlayers;
|
||||||
try {
|
try {
|
||||||
numPlayers = Integer.parseInt(campoNumPlayers.getText().trim());
|
numPlayers = Integer.parseInt(campoNumPlayers.getText().trim());
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
labelErrore.setText("Numero giocatori non valido.");
|
showError("Invalid number of players.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nome.isEmpty() || ip.isEmpty()) {
|
controller.setMyUsername(nome);
|
||||||
labelErrore.setText("Compila tutti i campi.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
System.setProperty("java.rmi.server.hostname", ip);
|
|
||||||
|
|
||||||
int networkType = btnRMI.isSelected() ? 0 : 1;
|
|
||||||
String interfaccia = getInterfaccia();
|
|
||||||
|
|
||||||
// Stesso thread di rete che era in ClientLauncher
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
if (networkType == 0) {
|
try {
|
||||||
RMIClient client = new RMIClient(controller, ip, 1099, interfaccia);
|
String localInterface = resolveLocalInterface(ip);
|
||||||
if (client.connect(nome, numPlayers)) {
|
System.setProperty("java.rmi.server.hostname", localInterface);
|
||||||
controller.setClient(client);
|
connect(nome, ip, numPlayers, localInterface);
|
||||||
} else {
|
} catch (Exception ex) {
|
||||||
Platform.runLater(() -> labelErrore.setText("Connessione RMI fallita."));
|
Platform.runLater(() -> showError("Network error: " + ex.getMessage()));
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TCPClient client = new TCPClient(controller, ip, 8080, 8081);
|
|
||||||
if (client.connect(nome, numPlayers)) {
|
|
||||||
controller.setClient(client);
|
|
||||||
} else {
|
|
||||||
Platform.runLater(() -> labelErrore.setText("Connessione TCP fallita."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getInterfaccia() {
|
private String resolveLocalInterface(String serverIp) throws Exception {
|
||||||
String selected = comboInterfaccia.getValue();
|
if (serverIp.equalsIgnoreCase("localhost") || serverIp.startsWith("127.") || serverIp.isEmpty()) {
|
||||||
if (selected == null) return "";
|
return "127.0.0.1";
|
||||||
return selected.contains("->") ? selected.split("->")[1].trim() : selected;
|
}
|
||||||
|
|
||||||
|
InetAddress serverAddr = InetAddress.getByName(serverIp);
|
||||||
|
Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
|
||||||
|
while (ifaces.hasMoreElements()) {
|
||||||
|
NetworkInterface ni = ifaces.nextElement();
|
||||||
|
if (!ni.isUp() || ni.isLoopback()) continue;
|
||||||
|
|
||||||
|
for (InterfaceAddress ia : ni.getInterfaceAddresses()) {
|
||||||
|
InetAddress localAddr = ia.getAddress();
|
||||||
|
if (!(localAddr instanceof Inet4Address)) continue;
|
||||||
|
|
||||||
|
int prefix = ia.getNetworkPrefixLength();
|
||||||
|
if (sameSubnet(localAddr, serverAddr, prefix)) {
|
||||||
|
return localAddr.getHostAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try (DatagramSocket socket = new DatagramSocket()) {
|
||||||
|
socket.connect(serverAddr, 9);
|
||||||
|
return socket.getLocalAddress().getHostAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean sameSubnet(InetAddress a, InetAddress b, int prefix) {
|
||||||
|
if (prefix < 0 || prefix > 32) return false;
|
||||||
|
int maskBits = prefix == 0 ? 0 : (0xFFFFFFFF << (32 - prefix));
|
||||||
|
int addrA = toInt(a.getAddress()) & maskBits;
|
||||||
|
int addrB = toInt(b.getAddress()) & maskBits;
|
||||||
|
return addrA == addrB;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int toInt(byte[] bytes) {
|
||||||
|
return ((bytes[0] & 0xFF) << 24) |
|
||||||
|
((bytes[1] & 0xFF) << 16) |
|
||||||
|
((bytes[2] & 0xFF) << 8) |
|
||||||
|
(bytes[3] & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void connect(String nome, String ip, int numPlayers, String localInterface) {
|
||||||
|
if (isRMI) {
|
||||||
|
RMIClient client = new RMIClient(controller, ip, 1099, localInterface);
|
||||||
|
if (client.connect(nome, numPlayers)) {
|
||||||
|
controller.setClient(client);
|
||||||
|
Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
|
||||||
|
} else {
|
||||||
|
Platform.runLater(() -> showError("RMI connection failed."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TCPClient client = new TCPClient(controller, ip, 8080, 8081);
|
||||||
|
if (client.connect(nome, numPlayers)) {
|
||||||
|
controller.setClient(client);
|
||||||
|
Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
|
||||||
|
} else {
|
||||||
|
Platform.runLater(() -> showError("TCP connection failed."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showError(String msg) {
|
||||||
|
labelErrore.setTextFill(Color.web("#e05050"));
|
||||||
|
labelErrore.setText(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showSuccess(String msg) {
|
||||||
|
labelErrore.setTextFill(Color.web("#6fcf8a"));
|
||||||
|
labelErrore.setText(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,16 +471,15 @@ public class MainFXMLController {
|
|||||||
StackPane card = createOrder(Integer.toString(numPlayers));
|
StackPane card = createOrder(Integer.toString(numPlayers));
|
||||||
|
|
||||||
Map<Integer, double[]> slotPositions = Map.of(
|
Map<Integer, double[]> slotPositions = Map.of(
|
||||||
2, new double[]{0.229 ,0.413},
|
2, new double[]{0.229, 0.413},
|
||||||
3, new double[]{0.183,0.367, 0.548},
|
3, new double[]{0.183, 0.367, 0.548},
|
||||||
4, new double[]{0.142,0.316, 0.503, 0.690},
|
4, new double[]{0.142, 0.316, 0.503, 0.690},
|
||||||
5, new double[]{0.066, 0.251, 0.433, 0.617,0.802}
|
5, new double[]{0.066, 0.251, 0.433, 0.617, 0.802}
|
||||||
);
|
);
|
||||||
|
|
||||||
double[] positions = slotPositions.get(numPlayers);
|
double[] positions = slotPositions.get(numPlayers);
|
||||||
if (positions == null) return;
|
if (positions == null) return;
|
||||||
|
|
||||||
|
|
||||||
Pane overlay = new Pane();
|
Pane overlay = new Pane();
|
||||||
overlay.setPickOnBounds(false);
|
overlay.setPickOnBounds(false);
|
||||||
overlay.setMouseTransparent(true);
|
overlay.setMouseTransparent(true);
|
||||||
@@ -488,43 +487,42 @@ public class MainFXMLController {
|
|||||||
for (int i = 0; i < controller.miniModel.orderLogicCard.playerList.size(); i++) {
|
for (int i = 0; i < controller.miniModel.orderLogicCard.playerList.size(); i++) {
|
||||||
OrderPlayer op = controller.miniModel.orderLogicCard.playerList.get(i);
|
OrderPlayer op = controller.miniModel.orderLogicCard.playerList.get(i);
|
||||||
|
|
||||||
// colore dal totem del giocatore
|
// Carica immagine totem come in createSlot
|
||||||
Color color = totemColor(op.player.totem);
|
ImageView totem = new ImageView(loadImage(
|
||||||
|
"/GUIImages/Totems/totem_" + op.player.totem.toString().toLowerCase(Locale.ROOT) + ".png"
|
||||||
|
));
|
||||||
|
totem.setPreserveRatio(true);
|
||||||
|
|
||||||
Rectangle rect = new Rectangle(48, 26, color);
|
|
||||||
rect.setArcWidth(4);
|
|
||||||
rect.setArcHeight(4);
|
|
||||||
if (controller.miniModel.slotPlayerMap.containsValue(op.player)) {
|
if (controller.miniModel.slotPlayerMap.containsValue(op.player)) {
|
||||||
rect.setVisible(false);
|
totem.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final double yRatio = positions[i];
|
final double yRatio = positions[i];
|
||||||
|
|
||||||
overlay.prefHeightProperty().bind(card.heightProperty());
|
overlay.prefHeightProperty().bind(card.heightProperty());
|
||||||
overlay.prefWidthProperty().bind(card.widthProperty());
|
overlay.prefWidthProperty().bind(card.widthProperty());
|
||||||
// posizione X fissa, Y proporzionale
|
|
||||||
|
// Scala altezza totem proporzionalmente come in createSlot (0.127 della card)
|
||||||
|
totem.fitHeightProperty().bind(card.heightProperty().multiply(0.323));
|
||||||
|
|
||||||
|
// Posizione Y proporzionale, X fissa
|
||||||
card.heightProperty().addListener((obs, ov, nv) -> {
|
card.heightProperty().addListener((obs, ov, nv) -> {
|
||||||
rect.setY(nv.doubleValue() * yRatio);
|
totem.setLayoutY(nv.doubleValue() * (yRatio-0.196));
|
||||||
rect.setHeight(0.127*nv.doubleValue());
|
|
||||||
});
|
});
|
||||||
card.widthProperty().addListener((obs, ov, nv) -> {
|
card.widthProperty().addListener((obs, ov, nv) -> {
|
||||||
rect.setX(nv.doubleValue() * 0.323);
|
totem.setLayoutX(nv.doubleValue() * 0.364);
|
||||||
rect.setWidth(0.375*nv.doubleValue());
|
|
||||||
});
|
});
|
||||||
if (card.getHeight() > 0 && card.getWidth() > 0) {
|
|
||||||
rect.setY(card.getHeight() * yRatio);
|
|
||||||
rect.setHeight(0.127*yRatio);
|
|
||||||
|
|
||||||
rect.setX(card.getHeight() * 0.323);
|
// Inizializzazione immediata se già dimensionato
|
||||||
rect.setWidth(0.375*card.getHeight());
|
if (card.getHeight() > 0) totem.setLayoutY(card.getHeight() *(yRatio-0.196));
|
||||||
}
|
if (card.getWidth() > 0) totem.setLayoutX(card.getWidth() * 0.364);
|
||||||
|
|
||||||
overlay.getChildren().add(rect);
|
overlay.getChildren().add(totem);
|
||||||
}
|
}
|
||||||
|
|
||||||
card.getChildren().add(overlay);
|
card.getChildren().add(overlay);
|
||||||
board.getChildren().add(card);
|
board.getChildren().add(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color totemColor(Totems totem) {
|
private Color totemColor(Totems totem) {
|
||||||
return switch (totem) {
|
return switch (totem) {
|
||||||
case ORANGE -> Color.rgb(223, 76, 17);
|
case ORANGE -> Color.rgb(223, 76, 17);
|
||||||
|
|||||||
@@ -1,31 +1,150 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?import javafx.scene.control.*?>
|
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.geometry.*?>
|
<?import javafx.geometry.*?>
|
||||||
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<StackPane xmlns="http://javafx.com/javafx/21"
|
||||||
|
xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
fx:controller="it.polimi.ingsw.gc14.View.GUI.LoginFXMLController"
|
||||||
|
prefWidth="1280" prefHeight="720"
|
||||||
|
style="-fx-background-color: #09060300;"
|
||||||
|
stylesheets="@styles.css">
|
||||||
|
|
||||||
<VBox spacing="10" alignment="CENTER_LEFT"
|
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
|
||||||
fx:controller="it.polimi.ingsw.gc14.View.GUI.LoginFXMLController">
|
|
||||||
|
|
||||||
<padding><Insets top="40" right="40" bottom="40" left="40"/></padding>
|
<ImageView fx:id="backgroundImage" fitWidth="1920" fitHeight="1080" preserveRatio="false"/>
|
||||||
|
|
||||||
<Label text="Nome utente:"/>
|
<!-- Corner decorations -->
|
||||||
<TextField fx:id="campoNome" promptText="Nome utente"/>
|
<Region prefWidth="52" prefHeight="52"
|
||||||
|
style="-fx-border-color: rgba(200,120,20,0.35); -fx-border-width: 1.5 0 0 1.5;"
|
||||||
|
StackPane.alignment="TOP_LEFT">
|
||||||
|
<StackPane.margin><Insets top="18" left="18"/></StackPane.margin>
|
||||||
|
</Region>
|
||||||
|
<Region prefWidth="52" prefHeight="52"
|
||||||
|
style="-fx-border-color: rgba(200,120,20,0.35); -fx-border-width: 1.5 1.5 0 0;"
|
||||||
|
StackPane.alignment="TOP_RIGHT">
|
||||||
|
<StackPane.margin><Insets top="18" right="18"/></StackPane.margin>
|
||||||
|
</Region>
|
||||||
|
<Region prefWidth="52" prefHeight="52"
|
||||||
|
style="-fx-border-color: rgba(200,120,20,0.35); -fx-border-width: 0 0 1.5 1.5;"
|
||||||
|
StackPane.alignment="BOTTOM_LEFT">
|
||||||
|
<StackPane.margin><Insets bottom="18" left="18"/></StackPane.margin>
|
||||||
|
</Region>
|
||||||
|
<Region prefWidth="52" prefHeight="52"
|
||||||
|
style="-fx-border-color: rgba(200,120,20,0.35); -fx-border-width: 0 1.5 1.5 0;"
|
||||||
|
StackPane.alignment="BOTTOM_RIGHT">
|
||||||
|
<StackPane.margin><Insets bottom="18" right="18"/></StackPane.margin>
|
||||||
|
</Region>
|
||||||
|
|
||||||
<Label text="Num. giocatori:"/>
|
<!-- Central panel -->
|
||||||
<TextField fx:id="campoNumPlayers" promptText="Numero di giocatori"/>
|
<VBox fx:id="formPanel" alignment="CENTER" spacing="0" maxWidth="420" maxHeight="600"
|
||||||
|
StackPane.alignment="CENTER"
|
||||||
|
style="-fx-background-color: rgba(9,6,3,0.72);
|
||||||
|
-fx-border-color: rgba(200,120,20,0.40);
|
||||||
|
-fx-border-width: 1;
|
||||||
|
-fx-border-radius: 4;
|
||||||
|
-fx-background-radius: 4;
|
||||||
|
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.7), 40, 0, 0, 8);">
|
||||||
|
<padding><Insets top="44" bottom="44" left="48" right="48"/></padding>
|
||||||
|
|
||||||
<Label text="Protocollo:"/>
|
<!-- Title -->
|
||||||
<RadioButton fx:id="btnRMI" text="RMI" selected="true"/>
|
<Label text="MESOS"
|
||||||
<RadioButton fx:id="btnTCP" text="TCP"/>
|
style="-fx-font-family: 'Cinzel Decorative'; -fx-font-size: 28; -fx-font-weight: bold;
|
||||||
|
-fx-text-fill: #f4c05a;
|
||||||
|
-fx-effect: dropshadow(gaussian, rgba(244,192,90,0.4), 28, 0, 0, 0);">
|
||||||
|
<VBox.margin><Insets bottom="4"/></VBox.margin>
|
||||||
|
</Label>
|
||||||
|
|
||||||
<Label text="IP server:"/>
|
<!-- Divider -->
|
||||||
<TextField fx:id="campoIP" promptText="IP server"/>
|
<Region prefHeight="1" prefWidth="260"
|
||||||
|
style="-fx-background-color: linear-gradient(to right, transparent, #c8791a, #f4c05a, #c8791a, transparent);">
|
||||||
|
<VBox.margin><Insets top="10" bottom="30"/></VBox.margin>
|
||||||
|
</Region>
|
||||||
|
|
||||||
<Label text="Interfaccia di rete:"/>
|
<!-- Username -->
|
||||||
<ComboBox fx:id="comboInterfaccia" maxWidth="Infinity"/>
|
<Label text="USERNAME"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 9; -fx-letter-spacing: 3;
|
||||||
|
-fx-text-fill: rgba(244,192,90,0.7);">
|
||||||
|
<VBox.margin><Insets bottom="6"/></VBox.margin>
|
||||||
|
</Label>
|
||||||
|
<TextField fx:id="campoNome" promptText="Enter your name"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 12;
|
||||||
|
-fx-text-fill: #f0e0c0; -fx-prompt-text-fill: rgba(200,150,80,0.45);
|
||||||
|
-fx-background-color: rgba(244,192,90,0.07);
|
||||||
|
-fx-border-color: rgba(200,120,20,0.45); -fx-border-width: 0 0 1 0;
|
||||||
|
-fx-background-radius: 0; -fx-border-radius: 0;
|
||||||
|
-fx-padding: 10 12 10 12;">
|
||||||
|
<VBox.margin><Insets bottom="20"/></VBox.margin>
|
||||||
|
</TextField>
|
||||||
|
|
||||||
<Label fx:id="labelErrore" style="-fx-text-fill: red;"/>
|
<!-- Num players -->
|
||||||
<Button fx:id="btnAccedi" text="Connetti"/>
|
<Label text="NUMBER OF PLAYERS"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 9; -fx-letter-spacing: 3;
|
||||||
|
-fx-text-fill: rgba(244,192,90,0.7);">
|
||||||
|
<VBox.margin><Insets bottom="6"/></VBox.margin>
|
||||||
|
</Label>
|
||||||
|
<TextField fx:id="campoNumPlayers" promptText="2 – 5"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 12;
|
||||||
|
-fx-text-fill: #f0e0c0; -fx-prompt-text-fill: rgba(200,150,80,0.45);
|
||||||
|
-fx-background-color: rgba(244,192,90,0.07);
|
||||||
|
-fx-border-color: rgba(200,120,20,0.45); -fx-border-width: 0 0 1 0;
|
||||||
|
-fx-background-radius: 0; -fx-border-radius: 0;
|
||||||
|
-fx-padding: 10 12 10 12;">
|
||||||
|
<VBox.margin><Insets bottom="20"/></VBox.margin>
|
||||||
|
</TextField>
|
||||||
|
|
||||||
</VBox>
|
<!-- Server IP -->
|
||||||
|
<Label text="SERVER IP"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 9; -fx-letter-spacing: 3;
|
||||||
|
-fx-text-fill: rgba(244,192,90,0.7);">
|
||||||
|
<VBox.margin><Insets bottom="6"/></VBox.margin>
|
||||||
|
</Label>
|
||||||
|
<TextField fx:id="campoIP" promptText="localhost"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 12;
|
||||||
|
-fx-text-fill: #f0e0c0; -fx-prompt-text-fill: rgba(200,150,80,0.45);
|
||||||
|
-fx-background-color: rgba(244,192,90,0.07);
|
||||||
|
-fx-border-color: rgba(200,120,20,0.45); -fx-border-width: 0 0 1 0;
|
||||||
|
-fx-background-radius: 0; -fx-border-radius: 0;
|
||||||
|
-fx-padding: 10 12 10 12;">
|
||||||
|
<VBox.margin><Insets bottom="20"/></VBox.margin>
|
||||||
|
</TextField>
|
||||||
|
|
||||||
|
<!-- Protocol toggle -->
|
||||||
|
<Label text="PROTOCOL"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 9; -fx-letter-spacing: 3;
|
||||||
|
-fx-text-fill: rgba(244,192,90,0.7);">
|
||||||
|
<VBox.margin><Insets bottom="8"/></VBox.margin>
|
||||||
|
</Label>
|
||||||
|
<StackPane fx:id="protocolToggle" prefWidth="220" maxWidth="220" prefHeight="36" alignment="CENTER_LEFT">
|
||||||
|
<VBox.margin><Insets bottom="28"/></VBox.margin>
|
||||||
|
<Region prefWidth="220" prefHeight="36"
|
||||||
|
style="-fx-background-color: rgba(244,192,90,0.07);
|
||||||
|
-fx-border-color: rgba(200,120,20,0.45);
|
||||||
|
-fx-border-width: 1; -fx-border-radius: 2; -fx-background-radius: 2;"/>
|
||||||
|
<Region fx:id="toggleThumb" prefWidth="110" maxWidth="110" prefHeight="36"
|
||||||
|
style="-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a);
|
||||||
|
-fx-background-radius: 2;"
|
||||||
|
StackPane.alignment="CENTER_LEFT"/>
|
||||||
|
<HBox prefWidth="220" prefHeight="36">
|
||||||
|
<Label fx:id="labelRMI" text="RMI" prefWidth="110" maxWidth="110" prefHeight="36" alignment="CENTER"
|
||||||
|
styleClass="toggle-label"/>
|
||||||
|
<Label fx:id="labelTCP" text="TCP" prefWidth="110" prefHeight="36" alignment="CENTER"
|
||||||
|
styleClass="toggle-label"/>
|
||||||
|
</HBox>
|
||||||
|
</StackPane>
|
||||||
|
|
||||||
|
<!-- Error label -->
|
||||||
|
<Label fx:id="labelErrore" maxWidth="Infinity" wrapText="true" textAlignment="CENTER"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 10; -fx-text-fill: #e05050;
|
||||||
|
-fx-min-height: 18;">
|
||||||
|
<VBox.margin><Insets bottom="16"/></VBox.margin>
|
||||||
|
</Label>
|
||||||
|
|
||||||
|
<!-- Connect button -->
|
||||||
|
<Button fx:id="btnAccedi" text="CONNECT" maxWidth="Infinity"
|
||||||
|
style="-fx-font-family: 'Cinzel'; -fx-font-size: 12; -fx-font-weight: bold;
|
||||||
|
-fx-letter-spacing: 4; -fx-text-fill: #0c0601;
|
||||||
|
-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);
|
||||||
|
-fx-padding: 13 48 13 48; -fx-background-radius: 2;
|
||||||
|
-fx-cursor: hand;"/>
|
||||||
|
</VBox>
|
||||||
|
</StackPane>
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/* ==========================================
|
||||||
|
STILI ORIGINALI PREESISTENTI
|
||||||
|
========================================== */
|
||||||
|
|
||||||
.card-list {
|
.card-list {
|
||||||
-fx-background-color: rgba(255,255,255,0.35);
|
-fx-background-color: rgba(255,255,255,0.35);
|
||||||
-fx-background-radius: 15;
|
-fx-background-radius: 15;
|
||||||
@@ -48,6 +52,7 @@
|
|||||||
-fx-background-radius: 15, 12, 8, 4;
|
-fx-background-radius: 15, 12, 8, 4;
|
||||||
-fx-padding: 15 15 15 15;
|
-fx-padding: 15 15 15 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
-fx-background-color: #9d0208;
|
-fx-background-color: #9d0208;
|
||||||
-fx-text-fill: white;
|
-fx-text-fill: white;
|
||||||
@@ -61,4 +66,24 @@
|
|||||||
|
|
||||||
.action-button:hover {
|
.action-button:hover {
|
||||||
-fx-background-color: #b42224;
|
-fx-background-color: #b42224;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================
|
||||||
|
NUOVI STILI AGGIUNTI PER IL TOGGLE
|
||||||
|
========================================== */
|
||||||
|
|
||||||
|
/* Struttura base fissa dei label RMI e TCP per evitare modifiche di layout */
|
||||||
|
.toggle-label {
|
||||||
|
-fx-font-family: 'Cinzel';
|
||||||
|
-fx-font-size: 11px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-text-fill: rgba(244,192,90,0.55); /* Colore non attivo (dorato trasparente) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stato attivo del protocollo selezionato */
|
||||||
|
.toggle-label:active-protocol {
|
||||||
|
-fx-font-family: 'Cinzel';
|
||||||
|
-fx-font-size: 11px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-text-fill: #0c0601; /* Grigio scurissimo/nero sul cursore luminoso */
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user