Skip to content
Snippets Groups Projects
Select Git revision
  • 6d321cb8bc9aee550f41f933c79a2e1ceaca12b5
  • main default protected
  • section4
  • save_state
  • section2
  • section1
6 results

Contact.java

Blame
  • MainWindowController.java 14.18 KiB
    package ch.hepia.ui;
    
    import ch.hepia.Main;
    import ch.hepia.api.transport.Connection;
    import ch.hepia.api.transport.Journey;
    import ch.hepia.api.transport.LinkAPI;
    import ch.hepia.api.transport.Location;
    import ch.hepia.api.transport.Section;
    import ch.hepia.config.AppConfig;
    import ch.hepia.config.AppContext;
    import ch.hepia.events.ChatMessage;
    import ch.hepia.models.User;
    import javafx.animation.TranslateTransition;
    import javafx.application.Platform;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.geometry.Insets;
    import javafx.scene.canvas.Canvas;
    import javafx.scene.canvas.GraphicsContext;
    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.scene.paint.CycleMethod;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.util.Duration;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.ResourceBundle;
    import javafx.scene.layout.Pane;
    
    public class MainWindowController implements Initializable {
    
        @FXML
        private Label currentJourneyLabel;
    
        @FXML
        private Label startStopLabel;
    
        @FXML
        private ComboBox<String> originComboBox;
    
        @FXML
        private ComboBox<String> destinationComboBox;
    
        @FXML
        private Canvas connectionCanvas;
    
        @FXML
        private Button searchOriginButton;
    
        @FXML
        private Button searchDestinationButton;
    
        @FXML
        private Button launchItinaryButton;
    
        @FXML
        private Button sendMessageButton;
    
        @FXML
        private TextField messageTextBox;
    
        @FXML
        private Pane chatContainer;
    
        /**
         * Shows a sad message when the API crashes.
         */
        private void showSadMessage(String text){
            UiUtils.dialog(Alert.AlertType.ERROR, "Erreur",
                "Une erreur est survenue.", text);
        }
    
        /**
         * Searches stops that matches the query.
         * @param newValue The stop name query.
         * @param transportApi The API to connect to
         * @param target The combo box where to put the results.
         */
        private void searchStops(String newValue, LinkAPI transportApi, ComboBox<String> target){
            if (!newValue.isEmpty() && newValue.length() > 3 && !target.getItems().contains(newValue)){
                try {
                    List<Location> locations = transportApi.getStations(newValue);
                    ArrayList<String> results = new ArrayList<>();
                    locations.forEach((location) -> results.add(location.getName()));
                    target.getItems().clear();
                    target.getItems().addAll(results);
                    target.show();
                } catch (IOException e) {
                    showSadMessage(AppConfig.ERROR_API_UNREACHABLE);
                }
            }
        }
    
    
        /**
         * Draws a connection between two places. Basically lines.
         * @param connection The connection to draw
         * @param x Where to draw
         * @param y Where to draw but vertically
         */
        private void drawConnection(Connection connection, int x, int y){
            List<Section> sections = connection.getSections();
            GraphicsContext gcx = connectionCanvas.getGraphicsContext2D();
            //Draw starting station
            gcx.setFill(Color.RED);
            gcx.fillText(sections.get(0).getDeparture().getLocation().getName(), x, y - 20);
            gcx.setFill(Color.BLACK);
            gcx.fillText(sections.get(0).getDeparture().getDepartureTime().toString(), x, y - 40);
            gcx.setFill(Color.RED);
            gcx.fillOval(x - 5, y - 5, 10, 10);
            gcx.strokeLine(x, y, x + 622 / (sections.size() + 1), y);
    		for (int i = 0; i < sections.size(); i++){
                //Draw each step
                drawConnectionStep(sections.get(i), sections.size(), x, y, i);
    		}
        }
        /**
         * Draws a connection step between two places.
         * @param section The section to draw
         * @param size Number of section in the connection
         * @param x Where to draw
         * @param y Where to draw but vertically
         * @param cnt Section position in connection list.
         */
        private void drawConnectionStep(Section section, int size, int x, int y, int cnt) {
            GraphicsContext gcx = connectionCanvas.getGraphicsContext2D();
            int xSize = (AppConfig.APP_MAIN_VIEW_WIDTH / (size + 1));
            gcx.strokeLine( x + xSize * (cnt + 1), y, AppConfig.APP_MAIN_VIEW_WIDTH / (size + 1), y);
            gcx.setFill(Color.RED);
            gcx.fillOval(x + xSize * (cnt + 1) - 5, y - 5, 10, 10);
            gcx.fillText(section.getArrival().getLocation().getName(), x + xSize * (cnt + 1), y - 20);
            gcx.setFill(Color.BLACK);
            gcx.fillText(section.getArrival().getArrivalTime().toString(), x + xSize * (cnt + 1), y - 40);
            Journey jrn = section.getJourney();
                String transportType = "MARCHE"; //Draw the type of transport used on previous step
                if (!(jrn instanceof Journey.EmptyJourney)) {
                    transportType = jrn.getCategory() + ", " + jrn.getNumber();
                }
            gcx.setFill(Color.BLUE);
            gcx.fillText(transportType,x + xSize * (cnt), y - 55);
            gcx.setFill(Color.RED);
        }
    
        /**
         * Draws a newly received message
         * @param message The message to draw
         */
        private void drawMessage(User user, String message, String image, Color color){
            Pane p = new Pane();
            setChatPanelStyle(p, color);
            Image lblImg = new Image(Main.class.getResourceAsStream(image));
            Label msg = new Label();
            msg.setWrapText(true);
            msg.setStyle("-fx-padding: 8px");
            msg.setText(message);
            msg.setMaxWidth(310);
            msg.setGraphic(new ImageView(lblImg));
            p.getChildren().add(msg);
            if (chatContainer.getChildren().size() >= 7) {
                chatContainer.getChildren().remove(0);
            }
            insertMessageIntoQueue();
            chatContainer.getChildren().add(p);
        }
    
        /**
         * Style a chat panel before pushing
         * @param p Panel to style
         * @param color Background color of the gradient
         */
        private void setChatPanelStyle(Pane p, Color color) {
            p.setBackground(
                new Background(
                    new BackgroundFill(
                        new LinearGradient(0, 0, 0, 1, true, 
                        CycleMethod.NO_CYCLE,
                        new Stop(1, color), 
                        new Stop(0, Color.WHITE)
                        ),
                    new CornerRadii(5), 
                    Insets.EMPTY)));
            p.setBorder(new Border(new BorderStroke(Color.color(0.6, 0.6, 0.6), BorderStrokeStyle.SOLID, new CornerRadii(5),
                    BorderWidths.DEFAULT)));
            p.setPrefWidth(312);
            p.setMaxWidth(320);
        }
    
        /**
         * Wrapper for local chat message
         * @param message Message to print
         */
        private void drawHelpMessage(String message) {
            drawMessage(Main.getContext().getUser().get(), message, AppConfig.HELP_MESSAGE_ICON, Color.color(1, 0.9, 0.5, 0.3));
        }
    
        /**
         * Print available commands in the chat
         */
        private void drawCommands(){
            StringBuilder buffer = new StringBuilder("/"+AppConfig.CHAT_COMMANDS.get(0));
            for(int i = 1; i < AppConfig.CHAT_COMMANDS.size(); i++)
                buffer.append(", /" + AppConfig.CHAT_COMMANDS.get(i));
            drawHelpMessage(buffer.toString());
        }
    
        /**
         * Moves the older messages downwards
         */
        private void insertMessageIntoQueue(){
            for (int i = 0; i < chatContainer.getChildren().size(); i++){
                Pane sp = (Pane) chatContainer.getChildren().get(i);
                TranslateTransition t = new TranslateTransition(Duration.seconds(0.25), sp);
    
                t.setToY((chatContainer.getChildren().size() - i) * (sp.getHeight() + 4));
                t.play();
            }
        }
    
        /**
         * Parse the line and search for chat command.
         * @param cmd The line to parse.
         */
        private void parseChatCommand(String cmd){
            String[] command = cmd.split(" ", 2);
            if (AppConfig.CHAT_COMMANDS.contains(command[0])){
                if (command[0].equals("help")) {
                    drawCommands();
                } else if (command[0].equals("ignore")){
                    if (command.length > 1){
                        Main.getContext().getUser().get().addIgnoredUser(new User(command[1]));
                        drawMessage(Main.getContext().getUser().get(), command[1] + " bloqué.", "/img/help.png", Color.color(1, 0.9, 0.5, 0.3));
                    }
                } else if (command[0].equals("ignoredlist")) {
                        List<User> list = Main.getContext().getUser().get().getIgnoredUserList();
                        StringBuilder buffer = new StringBuilder(list.get(0).getName());
                        for(int i = 1; i < list.size(); i++)
                            buffer.append(", " + list.get(i).getName());
                        drawMessage(Main.getContext().getUser().get(), "Bloqués : " + buffer.toString(), "/img/help.png", Color.color(1, 0.9, 0.5, 0.3));
                }
            } else {                
                drawCommands();
            }
        }
    
        /**
         * Sets the form up
         * @param url The JavaFX URL handler
         * @param resourceBundle The JavaDX ResB handle
         */
        @Override
        public void initialize(URL url, ResourceBundle resourceBundle) {
            currentJourneyLabel.setText("Vous n'avez prévu aucun voyage pour le moment.");
            startStopLabel.setText(""); // No text should be visible when no journey has been selected.
            messageTextBox.textProperty().addListener((ov, oldValue, newValue) -> {
                if (messageTextBox.getText().length() > 60) {
                    messageTextBox.setText(messageTextBox.getText().substring(0, 60));
                }
            });
    
            LinkAPI transportApi = new LinkAPI();
            AppContext app = Main.getContext();
            UiUtils.buttonWhenEnter(originComboBox, searchOriginButton);
            UiUtils.buttonWhenEnter(destinationComboBox, searchDestinationButton);
            UiUtils.buttonWhenEnter(messageTextBox, sendMessageButton);
    
            searchOriginButton.
                    setOnAction(event -> { originComboBox.setValue(originComboBox.getEditor().getText());
                    searchStops(originComboBox.getValue(), transportApi, originComboBox);
                    });
    
            searchDestinationButton.
                    setOnAction(event -> { destinationComboBox.setValue(destinationComboBox.getEditor().getText());
                    searchStops(destinationComboBox.getValue(), transportApi, destinationComboBox);
                    });
    
            launchItinaryButton.setOnAction(event -> {
                try {
                	connectionCanvas.getGraphicsContext2D()
    						.clearRect(0, 0, connectionCanvas.getWidth(), connectionCanvas.getHeight());
    
                    List<Connection> connections = transportApi.getConnections(
                            originComboBox.getValue(), destinationComboBox.getValue());
                    startStopLabel.setText(originComboBox.getValue() + " - " + destinationComboBox.getValue());
                    for (int i = 0; i < connections.size(); i++){
                        // Now iterating over connections
                        drawConnection(connections.get(i), 30, 100 + 100 * i);
                    }
                } catch (IOException e) {
                    showSadMessage(AppConfig.ERROR_API_UNREACHABLE);
                }
            });
    
            sendMessageButton.setOnAction(event -> {
                if (app.getUser().isPresent() && !messageTextBox.getText().isEmpty()){
                    if ( messageTextBox.getText().charAt(0) != '/') {
                        app.getMessageManager().sendChatMessage(new ChatMessage(app.getUser().get(), messageTextBox.getText()));
                    } else {
                        parseChatCommand(messageTextBox.getText().substring(1, messageTextBox.getText().length()));
                    }
                    messageTextBox.clear();
                }
            });
            // Subscribe to chat message
            app.getMessageManager().conditionalSubscribeChatMessage(
                chatMessage -> {
                    Platform.runLater(() -> {
                        User sender = chatMessage.getUser();
                        String message = sender.getName() + ": " + chatMessage.getMessage();
                        if (sender.equals(app.getUser().get())) {
                            drawMessage(sender, message, AppConfig.CHAT_MESSAGE_ICON_SELF, AppConfig.COLOR_BLUE_10_OPACITY);
                        } else {
                            drawMessage(sender, message, AppConfig.CHAT_MESSAGE_ICON, AppConfig.COLOR_BLUE_10_OPACITY);
                        }
                    });
                },
                chatMessage -> !(app.getUser().get().getIgnoredUserList().contains(chatMessage.getUser()))
            );
    
            // Subscribe to joined journey
            app.getMessageManager().conditionalSubscribeJoinedJourney( joinedJourney -> {
                Platform.runLater(() -> {
                    User sender = joinedJourney.getUser();
                    String message = sender.getName() + " voyage !";
                    if (sender.equals(app.getUser().get())) {
                        drawMessage(sender, message, AppConfig.CHAT_MESSAGE_ICON_SELF, AppConfig.COLOR_BLUE_10_OPACITY);
                    } else {
                        drawMessage(sender, message, AppConfig.CHAT_MESSAGE_ICON, AppConfig.COLOR_BLUE_10_OPACITY);
                    }
                });
            }, 
            joinedJourney -> !(app.getUser().get().getIgnoredUserList().contains(joinedJourney.getUser())) 
            );
    
            // Subscribe to left journey
            app.getMessageManager().conditionalSubscribeLeftJourney( leftJourney -> {
                Platform.runLater(() -> {
                    User sender = leftJourney.getUser();
                    String message = sender.getName() + " a terminé son voyage !";
                    if (sender.equals(app.getUser().get())) {
                        drawMessage(sender, message, AppConfig.CHAT_MESSAGE_ICON_SELF, AppConfig.COLOR_BLUE_10_OPACITY);
                    } else {
                        drawMessage(sender, message, AppConfig.CHAT_MESSAGE_ICON, AppConfig.COLOR_BLUE_10_OPACITY);
                    }
                });
            }, 
            leftJourney -> !(app.getUser().get().getIgnoredUserList().contains(leftJourney.getUser())) 
            );
    
            //Login messages:
            drawCommands();
            Platform.runLater(() -> {
                drawHelpMessage("Bonjour " + app.getUser().get().getName() + " ! Les commandes à dispositions sont :");
            });
        }
    }