Merge branch 'develop' into loading_screens

# Conflicts:
#	src/main/resources/views/RaceView.fxml
This commit is contained in:
Kusal Ekanayake
2017-09-27 14:05:46 +13:00
49 changed files with 2922 additions and 626 deletions
@@ -20,6 +20,8 @@ import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.chart.LineChart;
@@ -42,11 +44,15 @@ import javafx.scene.shape.Polyline;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javax.swing.ImageIcon;
import seng302.model.ClientYacht;
import seng302.model.ClientYacht.PowerUpListener;
import seng302.model.RaceState;
import seng302.model.mark.CompoundMark;
import seng302.model.mark.Mark;
import seng302.model.stream.xml.parser.RaceXMLData;
import seng302.model.token.Token;
import seng302.model.token.TokenType;
import seng302.utilities.Sounds;
import seng302.visualiser.GameView3D;
import seng302.visualiser.controllers.annotations.ImportantAnnotationController;
@@ -56,6 +62,8 @@ import seng302.visualiser.controllers.dialogs.FinishDialogController;
import seng302.visualiser.fxObjects.ChatHistory;
import seng302.visualiser.fxObjects.assets_2D.WindArrow;
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
import seng302.visualiser.fxObjects.assets_3D.ModelType;
/**
* Controller class that manages the display of a race
@@ -63,6 +71,8 @@ import seng302.visualiser.fxObjects.assets_3D.BoatObject;
public class RaceViewController extends Thread implements ImportantAnnotationDelegate {
private final int CHAT_LIMIT = 128;
private static final Double ICON_BLINK_TIMEOUT_RATIO = 0.6;
private static final Integer ICON_BLINK_PERIOD = 500;
@FXML
private AnchorPane loadingScreenPane;
@@ -110,6 +120,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
private Label windSpeedLabel;
@FXML
private Label positionLabel, boatSpeedLabel, boatHeadingLabel;
@FXML
private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon, badRandomIcon;
//Race Data
private Map<Integer, ClientYacht> participants;
@@ -130,6 +142,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
private JFXDialog finishScreenDialog;
private FinishDialogController finishDialogController;
//Icon stuff
private Timer blinkingTimer = new Timer();
private ImageView iconToDisplay;
public void initialize() {
contentStackPane.setVisible(false);
Image loadingImage = new Image("PP.png");
@@ -252,6 +268,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
});
}
public void loadRace (
Map<Integer, ClientYacht> participants, RaceXMLData raceData, RaceState raceState,
ClientYacht player) {
@@ -271,6 +288,9 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
}
});
player.addPowerUpListener(this::displayPowerUpIcon);
player.addPowerDownListener(this::removeIcon);
updateOrder(raceState.getPlayerPositions());
gameView = new GameView3D();
// gameView.setFrameRateFXText(fpsDisplay);
@@ -309,6 +329,68 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
});
}
/**
* Displays the relevant icon, starts blinking it when it is close to turning off and then
* switches it off after the tokens time out
*
* @param yacht The yacht only for which we are displaying the icon
* @param tokenType The type of token, indicating what icon needs to be displayed
*/
private void displayPowerUpIcon(ClientYacht yacht, TokenType tokenType) {
if (yacht == player) {
if (iconToDisplay != null) {
iconToDisplay.setVisible(false);
}
switch (tokenType) {
case BOOST:
iconToDisplay = velocityIcon;
break;
case HANDLING:
iconToDisplay = handlingIcon;
break;
case WIND_WALKER:
iconToDisplay = windWalkerIcon;
break;
case BUMPER:
iconToDisplay = bumperIcon;
break;
case RANDOM:
iconToDisplay = badRandomIcon;
break;
default:
iconToDisplay = velocityIcon;
}
//Turn icon on
iconToDisplay.setVisible(true);
//Start blinking icon towards end
if (blinkingTimer != null) {
blinkingTimer.cancel();
}
blinkingTimer = new Timer("Blinking Timer");
blinkingTimer.schedule(new TimerTask() {
Boolean isVisible = true;
@Override
public void run() {
isVisible = !isVisible;
iconToDisplay.setVisible(isVisible);
}
}, (int) (tokenType.getTimeout() * ICON_BLINK_TIMEOUT_RATIO), ICON_BLINK_PERIOD);
}
}
public void removeIcon(ClientYacht yacht) {
if (yacht == player) {
blinkingTimer.cancel();
iconToDisplay.setVisible(false);
iconToDisplay = null;
}
}
/**
* The important annotations have been changed, update this view
*
@@ -7,6 +7,7 @@ import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.RequiredFieldValidator;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
@@ -27,6 +28,7 @@ import seng302.utilities.Sounds;
import seng302.visualiser.ServerListener;
import seng302.visualiser.ServerListenerDelegate;
import seng302.visualiser.controllers.cells.ServerCell;
import seng302.visualiser.controllers.dialogs.ServerCreationController;
import seng302.visualiser.validators.HostNameFieldValidator;
import seng302.visualiser.validators.NumberRangeValidator;
import seng302.visualiser.validators.ValidationTools;
@@ -55,6 +57,14 @@ public class ServerListController implements Initializable, ServerListenerDelega
private Label noServersFound;
private Logger logger = LoggerFactory.getLogger(ServerListController.class);
private JFXDialog serverCreationDialog;
private List<ServerCreationDialogListener> serverCreationDialogListeners = new ArrayList<>();
@FunctionalInterface
public interface ServerCreationDialogListener {
void notifyClosure();
}
// TODO: 12/09/17 ajm412: break this method down, its way too long.
@Override
@@ -115,6 +125,8 @@ public class ServerListController implements Initializable, ServerListenerDelega
serverListHostButton.setOnAction(action -> {
showServerCreationDialog();
});
addServerCreationDialogListener(this::closeServerCreationDialog);
}
/**
@@ -125,9 +137,11 @@ public class ServerListController implements Initializable, ServerListenerDelega
FXMLLoader dialogContent = new FXMLLoader(getClass().getResource(
"/views/dialogs/ServerCreationDialog.fxml"));
try {
JFXDialog dialog = new JFXDialog(serverListMainStackPane, dialogContent.load(),
serverCreationDialog = new JFXDialog(serverListMainStackPane, dialogContent.load(),
DialogTransition.CENTER);
dialog.show();
ServerCreationController serverCreationController = dialogContent.getController();
serverCreationController.setListener(serverCreationDialogListeners);
serverCreationDialog.show();
Sounds.playButtonClick();
} catch (IOException e) {
logger.warn("Could not create Server Creation Dialog.");
@@ -135,6 +149,10 @@ public class ServerListController implements Initializable, ServerListenerDelega
});
}
private void closeServerCreationDialog() {
serverCreationDialog.close();
}
/**
* Validates the connection and attempts to connect to a given hostname and port number.
*/
@@ -203,4 +221,14 @@ public class ServerListController implements Initializable, ServerListenerDelega
public void serverDetected(ServerDescription serverDescription, List<ServerDescription> servers) {
Platform.runLater(() -> refreshServers(servers));
}
private void addServerCreationDialogListener(
ServerCreationDialogListener serverCreationDialogListener) {
serverCreationDialogListeners.add(serverCreationDialogListener);
}
private void removeServerCreationDialogListener(
ServerCreationDialogListener serverCreationDialogListener) {
serverCreationDialogListeners.remove(serverCreationDialogListener);
}
}
@@ -29,6 +29,7 @@ import seng302.utilities.BonjourInstallChecker;
import seng302.utilities.Sounds;
import seng302.visualiser.GameClient;
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
import seng302.visualiser.controllers.dialogs.PopupDialogController;
public class ViewManager {
@@ -109,8 +110,6 @@ public class ViewManager {
gameClient.stopGame();
System.exit(0);
});
jfxSnackbar = new JFXSnackbar(decorator);
}
/**
@@ -195,6 +194,7 @@ public class ViewManager {
}
});
jfxSnackbar = new JFXSnackbar(decorator);
}
/**
@@ -228,6 +228,7 @@ public class ViewManager {
.getController();
keyBindingDialogController.setGameClient(this.gameClient);
keyBindingDialog.show();
decorator.requestFocus();
Sounds.playButtonClick();
}
}
@@ -237,6 +238,26 @@ public class ViewManager {
keyBindingDialog.close();
}
public PopupDialogController showPopupDialog() {
FXMLLoader dialogContent = new FXMLLoader(
getClass().getResource("/views/dialogs/PopupDialog.fxml"));
for (Node node : decorator.getChildren()) {
if (node instanceof StackPane) {
try {
JFXDialog dialog = new JFXDialog((StackPane) node, dialogContent.load(),
DialogTransition.CENTER);
PopupDialogController popupDialogController = dialogContent.getController();
popupDialogController.setPopupDialog(dialog);
dialog.show();
return popupDialogController;
} catch (IOException e) {
logger.error("Cannot load Popup dialog");
}
}
}
return null;
}
/**
* Show a snackbar at the bottom of the app for 1 second.
*
@@ -48,6 +48,16 @@ public class KeyBindingDialogController implements Initializable {
private Label downwindLabel;
@FXML
private JFXToggleButton turningToggle;
@FXML
private JFXButton viewButton;
@FXML
private JFXButton rightButton;
@FXML
private JFXButton leftButton;
@FXML
private JFXButton forwardButton;
@FXML
private JFXButton backwardButton;
//---------FXML END---------//
private GameKeyBind gameKeyBind;
@@ -60,7 +70,8 @@ public class KeyBindingDialogController implements Initializable {
gameKeyBind = GameKeyBind.getInstance();
buttons = new ArrayList<>();
Collections.addAll(buttons,
zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn, downwindBtn);
zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn, downwindBtn,
viewButton, rightButton, leftButton, forwardButton, backwardButton);
bindButtonWithAction();
loadKeyBind();
@@ -76,12 +87,10 @@ public class KeyBindingDialogController implements Initializable {
resetBtn.setOnMouseClicked(event -> {
gameKeyBind.setToDefault();
loadKeyBind();
showSnackBar("All keys reset!", false);
});
closeLabel.setOnMouseClicked(event -> ViewManager.getInstance().closeKeyBindingDialog());
keyBindingDialogHeader.setFocusTraversable(true);
keyBindingDialogHeader.requestFocus();
}
/**
@@ -106,7 +115,7 @@ public class KeyBindingDialogController implements Initializable {
*/
private void bindButtonWithAction() {
buttonActionMap = new HashMap<>();
for (int i = 0; i < 7; i++) {
for (int i = 0; i < 12; i++) {
buttonActionMap.put(buttons.get(i), KeyAction.getType(i + 1));
}
}
@@ -149,6 +158,7 @@ public class KeyBindingDialogController implements Initializable {
+ "-fx-background-color: -fx-pp-front-color; "
+ "-fx-text-fill: -fx-pp-theme-color; "
+ "-fx-font-size: 13;");
keyBindingDialogHeader.requestFocus();
}
/**
@@ -0,0 +1,56 @@
package seng302.visualiser.controllers.dialogs;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialog;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
public class PopupDialogController implements Initializable {
@FXML
private Label headerLabel;
@FXML
private Label contentLabel;
@FXML
private Label closeLabel;
@FXML
private JFXButton optionButton;
@FXML
private JFXDialog popupDialog;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
public void setContent(String content) {
this.contentLabel.setText(content);
}
public void setHeader(String header) {
this.headerLabel.setText(header);
}
public void setOptionButton(JFXButton jfxButton) {
this.optionButton = jfxButton;
}
public void setOptionButtonText(String text) {
this.optionButton.setText(text);
}
public void setOptionButtonEventHandler(EventHandler<? super MouseEvent> eventHandler) {
this.optionButton.setOnMouseClicked(eventHandler);
}
public void setPopupDialog(JFXDialog popupDialog) {
this.popupDialog = popupDialog;
this.closeLabel.setOnMouseClicked(event -> this.popupDialog.close());
}
}
@@ -5,14 +5,15 @@ import com.jfoenix.controls.JFXSlider;
import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.RequiredFieldValidator;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import seng302.gameServer.ServerDescription;
import seng302.utilities.Sounds;
import seng302.visualiser.controllers.ServerListController.ServerCreationDialogListener;
import seng302.visualiser.controllers.ViewManager;
import seng302.visualiser.validators.FieldLengthValidator;
import seng302.visualiser.validators.ValidationTools;
@@ -28,8 +29,12 @@ public class ServerCreationController implements Initializable {
private Label maxPlayersLabel;
@FXML
private JFXButton submitBtn;
@FXML
private Label closeLabel;
//---------FXML END---------//
private List<ServerCreationDialogListener> serverCreationDialogListeners;
public void initialize(URL location, ResourceBundle resources) {
updateMaxPlayerLabel();
maxPlayersSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
@@ -49,6 +54,7 @@ public class ServerCreationController implements Initializable {
validateServerSettings();
});
closeLabel.setOnMouseClicked(event -> notifyListeners());
}
/**
@@ -87,4 +93,14 @@ public class ServerCreationController implements Initializable {
Sounds.playHoverSound();
}
public void setListener(List<ServerCreationDialogListener> serverCreationDialogListeners) {
this.serverCreationDialogListeners = serverCreationDialogListeners;
}
public void notifyListeners() {
for (ServerCreationDialogListener serverCreationDialogListener : serverCreationDialogListeners) {
serverCreationDialogListener.notifyClosure();
}
}
}