Skip to content

Commit

Permalink
Merge pull request #132 from yprie/sprint4/feat-search-moment
Browse files Browse the repository at this point in the history
Sprint4/feat search moment
  • Loading branch information
JeridiOmar authored Apr 30, 2023
2 parents 4f0934b + c4e7cd1 commit 06b8d83
Show file tree
Hide file tree
Showing 16 changed files with 699 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,11 @@ public void onUnmount() {

}

public Label getName() {
return name;
}

public void setName(Label name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
package components.modelisationSpace.controllers;

import application.configuration.AppSettings;
import application.configuration.Configuration;
import components.interviewPanel.search.ButtonSearchType;
import components.interviewPanel.search.SearchButtonHandler;
import components.modelisationSpace.appCommand.ScrollPaneCommandFactory;
import components.modelisationSpace.hooks.ModelisationSpaceHook;
import components.modelisationSpace.hooks.ModelisationSpaceHookNotifier;
import components.modelisationSpace.moment.controllers.RootMomentController;
import components.modelisationSpace.search.MomentSearchHandler;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.transform.Scale;
import javafx.stage.Modality;
import models.RootMoment;
import models.TemplateMoment;
import utils.GlobalVariables;
import utils.ModelisationNavigator;
import utils.MomentSearch;
import utils.dragAndDrop.DragStore;
import utils.scrollOnDragPane.ScrollOnDragPane;

import java.io.IOException;
import java.net.URL;
import java.util.Objects;
import java.util.ResourceBundle;

public class ModelisationSpaceController extends ScrollOnDragPane implements Initializable {
Expand All @@ -31,9 +50,13 @@ public class ModelisationSpaceController extends ScrollOnDragPane implements Ini
ScrollOnDragPane superPane;

AnchorPane anchorPane = new AnchorPane(); // Container

private SimpleBooleanProperty isSearchClicked;
private ModelisationSpaceHook hooks;
private ModelisationSpaceHookNotifier hooksNotifier;
private MomentSearchHandler nextButtonHandler;
private MomentSearchHandler previousButtonHandler;
GlobalVariables globalVariables = GlobalVariables.getGlobalVariables();
private MomentSearch searchResult;

public ModelisationSpaceController() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/modelisationSpace/ModelisationSpace.fxml"));
Expand All @@ -54,7 +77,22 @@ public ModelisationSpaceController() {
public void initialize(URL location, ResourceBundle resources) {
super.initialize(location, resources);
paneCmdFactory = new ScrollPaneCommandFactory(superPane);
this.searchResult = new MomentSearch();
setupDragAndDrop();
this.isSearchClicked = new SimpleBooleanProperty(false);
globalVariables.isMomentSearchClicked = this.isSearchClicked;
this.superPane.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.F && e.isShortcutDown()) {
isSearchClicked.set(true);
}
});
this.isSearchClicked.addListener((obs, oldValue, newValue) -> {
if (newValue) {
this.superPane.requestFocus();
showFindDialog();
}
});
GlobalVariables.modelisationNavigator = new ModelisationNavigator(this.superPane, this.anchorPane);
}

public void setRootMoment(RootMoment m) {
Expand All @@ -72,7 +110,6 @@ public void setRootMoment(RootMoment m) {
anchorPane.getTransforms().setAll(new Scale(ratio, ratio, 0, 0));
});
}
this.setHvalue(this.superPane.getHmax());
}

public void clearSpace() {
Expand Down Expand Up @@ -112,4 +149,126 @@ private void setupDragAndDrop() {
public ScrollOnDragPane getSuperPane() {
return this.superPane;
}


public void centerNodeInScrollPaneX(AnchorPane scrollPane, Node node) {
double h = this.anchorPane.getBoundsInLocal().getWidth();//scrollpane
//System.out.println(node.getBoundsInParent());
Bounds bounds =
this.anchorPane.sceneToLocal(node.localToScene(node.getBoundsInLocal()));//scrollpane
//System.out.println(bounds);
double y = (bounds.getMaxX() +
bounds.getMinX()) / 2.0;
double v = this.superPane.getViewportBounds().getWidth();
this.superPane.setHvalue(this.superPane.getHmax() * ((y - 0.5 * v) / (h - v)));
}

public void centerNodeInScrollPaneY(ScrollPane scrollPane, Node node) {
double h = this.anchorPane.getBoundsInLocal().getHeight();
Bounds bounds =
this.anchorPane.sceneToLocal(node.localToScene(node.getBoundsInLocal()));
double y = (bounds.getMaxY() +
bounds.getMinY()) / 2.0;
double v = this.superPane.getViewportBounds().getHeight();
System.out.println(node.getBoundsInParent());
System.out.println(bounds);
//testing two
double height = this.anchorPane.getBoundsInLocal().getHeight();
double y2 = node.getBoundsInParent().getMaxY();
this.superPane.setVvalue(y2 / height);
//this.superPane.setVvalue(this.superPane.getVmax() * ((y - 0.5 * v) / (h - v)));
}


private void showFindDialog() {
// Set up the dialog
Dialog<String> dialog = new Dialog<>();
dialog.initModality(Modality.WINDOW_MODAL);
dialog.getDialogPane().getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/application.css")).toExternalForm());
dialog.getDialogPane().setPrefWidth(450);
dialog.setResizable(true);
dialog.setTitle(Configuration.langBundle.getString("find"));
dialog.setHeaderText(Configuration.langBundle.getString("find"));
dialog.setResizable(false);

// Set up the buttons
ButtonType findPreviousButtonType = new ButtonType(Configuration.langBundle.getString("previous"), ButtonBar.ButtonData.OK_DONE);
ButtonType findNextButtonType = new ButtonType(Configuration.langBundle.getString("next"), ButtonBar.ButtonData.OK_DONE);
ButtonType closeButtonType = ButtonType.CLOSE;
dialog.getDialogPane().getButtonTypes().addAll(findNextButtonType, findPreviousButtonType, closeButtonType);

// Set up the text field and label
TextField findTextField = new TextField();
Label findLabel = new Label(Configuration.langBundle.getString("find"));
findLabel.setLabelFor(findTextField);

// Set up the match count label
Label matchCountLabel = new Label();
matchCountLabel.setVisible(false);

// Set up the grid pane
HBox gridPane = new HBox();
gridPane.setSpacing(15);
gridPane.setAlignment(Pos.BASELINE_CENTER);
gridPane.getChildren().add(findLabel);
gridPane.getChildren().add(findTextField);
gridPane.getChildren().add(matchCountLabel);
dialog.getDialogPane().setContent(gridPane);

Button findPreviousButton = (Button) dialog.getDialogPane().lookupButton(findPreviousButtonType);
Button findNextButton = (Button) dialog.getDialogPane().lookupButton(findNextButtonType);
Button closeButton = (Button) dialog.getDialogPane().lookupButton(closeButtonType);
//Init Buttons on disabled
findNextButton.setDisable(true);
findPreviousButton.setDisable(true);

// handle search result label
findTextField.textProperty().addListener((obs, oldText, newText) -> {
if (!newText.isEmpty()) {
this.searchResult.countOccurrences(newText);
matchCountLabel.setVisible(true);

matchCountLabel.textProperty().bind(Bindings.createStringBinding(() -> {
String s = "";
int resultCount = this.searchResult.getResultCount();
s += resultCount + " ";
s += Configuration.langBundle.getString("matches_found") + ".";
return s;
}, this.searchResult.resultCountProperty()));
} else {
this.searchResult.resetSearch();
matchCountLabel.setVisible(false);
}

});


//Handle buttons disabled property listeners
this.searchResult.resultCountProperty().addListener((obs, oldCount, newCount) -> {
findNextButton.setDisable(newCount.intValue() <= 0);
});
this.searchResult.resultPositionProperty().addListener((obs, oldCount, newCount) -> {
findNextButton.setDisable(!this.searchResult.hasNext());
findPreviousButton.setDisable(!this.searchResult.hasPrevious());
});
//Set up search buttons actions
this.nextButtonHandler = new MomentSearchHandler(
ButtonSearchType.NEXT, searchResult, superPane, anchorPane);
this.previousButtonHandler = new MomentSearchHandler(
ButtonSearchType.PREVIOUS, searchResult, superPane, anchorPane);
findNextButton.addEventFilter(ActionEvent.ACTION, this.nextButtonHandler);
findPreviousButton.addEventFilter(ActionEvent.ACTION, this.previousButtonHandler);
closeButton.addEventFilter(ActionEvent.ACTION, (e) -> {
this.isSearchClicked.set(false);
});
// Show the dialog and reset the search result
dialog.setOnCloseRequest(e -> {
this.previousButtonHandler.cleanSearchHighlight();
this.nextButtonHandler.cleanSearchHighlight();
this.searchResult.resetSearch();
});
dialog.show();
dialog.getDialogPane().toFront();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class MomentController extends ListViewController<Moment> implements Init
@FXML private VBox categoryContainer;
@FXML private AnchorPane momentBoundingBox;
@FXML private TextArea commentArea;
@FXML HBox nameBox;
@FXML public HBox nameBox;
@FXML private BorderPane momentBody;
@FXML private ImageView collapseIcon;
@FXML private HBox transitionBox;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package components.modelisationSpace.search;

import components.interviewPanel.search.ButtonSearchType;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
import models.Moment;
import org.fxmisc.richtext.InlineCssTextArea;
import utils.ModelisationNavigator;
import utils.MomentSearch;
import utils.SearchResult;

public class MomentSearchHandler implements EventHandler<ActionEvent> {

private final String HIGHLIGHT_STYLE = "-fx-background-color:" + "#fdff32" + "; -fx-fill:" + "#fdff32" + ";";
private ButtonSearchType type;
private MomentSearch searchResult;
private ScrollPane scrollPane;
private AnchorPane anchorPane;
private Node previousNode;
ModelisationNavigator modelisationNavigator;

public MomentSearchHandler(ButtonSearchType type, MomentSearch searchResult, ScrollPane scrollPane, AnchorPane anchorPane) {
this.type = type;
this.searchResult = searchResult;
this.scrollPane = scrollPane;
this.anchorPane = anchorPane;
this.modelisationNavigator = new ModelisationNavigator(this.scrollPane, this.anchorPane);
}

@Override
public void handle(ActionEvent event) {
if (this.searchResult.isEmpty()) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Find");
alert.setHeaderText("Find");
alert.setContentText("No matches found.");
alert.showAndWait();
event.consume(); // prevent the dialog from closing
return;
}
if (previousNode != null) {
this.removeHighlight(previousNode);
}
Node currentNode;
if (this.type.equals(ButtonSearchType.NEXT)) {
currentNode = this.searchResult.getNextResult();
} else {
currentNode = this.searchResult.getPreviousResult();
}
previousNode = currentNode;
scrollPane.requestFocus();
this.modelisationNavigator.centerNodeInScrollPaneX(currentNode);
this.modelisationNavigator.centerNodeInScrollPaneY(currentNode);

String initialNodeStyle = currentNode.getStyle();
currentNode.setStyle(initialNodeStyle + HIGHLIGHT_STYLE);

event.consume(); // prevent the dialog from closing
}

public void removeHighlight(Node node) {
String nodeStyle = node.getStyle();
node.setStyle(nodeStyle.replace(HIGHLIGHT_STYLE, ""));
}

public void cleanSearchHighlight() {
if (previousNode != null) {
this.removeHighlight(previousNode);
}
}
}
Loading

0 comments on commit 06b8d83

Please sign in to comment.