Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/main/java/com/github/mfl28/boundingboxeditor/ui/MainView.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
Expand Down Expand Up @@ -306,6 +307,15 @@ public void connectToController(final Controller controller) {
header.connectToController(controller);
workspaceSplitPane.connectToController(controller);
inferenceSettingsView.connectToController(controller);

setOnDragDropped(event -> {
if(event.getDragboard().hasFiles()) {
controller.initiateImageFolderLoading(event.getDragboard().getFiles().get(0));
event.setDropCompleted(true);
}

event.consume();
});
}

@Override
Expand Down Expand Up @@ -613,6 +623,16 @@ private void setUpInternalListeners() {
.bind(editorSettingsConfig.autoSimplifyPolygonsProperty());
workspaceSplitPane.getEditor().getEditorImagePane().simplifyRelativeDistanceToleranceProperty()
.bind(editorSettingsConfig.simplifyRelativeDistanceToleranceProperty());

setOnDragOver(event -> {
if(event.getDragboard().hasFiles()
&& event.getDragboard().getFiles().size() == 1
&& event.getDragboard().getFiles().get(0).isDirectory()) {
event.acceptTransferModes(TransferMode.LINK);
}

event.consume();
});
}

private static void displayInfoAlert(String title, String header, String content, Node additionalInfoNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ protected static Matcher<Double[]> ratioListCloseTo(Double[] list) {
}

protected void moveRelativeToImageView(FxRobot robot, Point2D startPointRatios, Point2D endPointRatios) {
Point2D startPoint = getScreenPointFromImageViewRatios(startPointRatios);
Point2D endPoint = getScreenPointFromImageViewRatios(endPointRatios);
Point2D startPoint = getScreenPointFromRatios(mainView.getEditorImageView(), startPointRatios);
Point2D endPoint = getScreenPointFromRatios(mainView.getEditorImageView(), endPointRatios);

robot.moveTo(startPoint)
.press(MouseButton.PRIMARY)
Expand All @@ -139,7 +139,7 @@ protected void moveRelativeToImageView(FxRobot robot, Point2D startPointRatios,

protected void moveAndClickRelativeToImageView(FxRobot robot, MouseButton mousebutton, Point2D... points) {
for(Point2D point : points) {
robot.moveTo(getScreenPointFromImageViewRatios(point)).clickOn(mousebutton);
robot.moveTo(getScreenPointFromRatios(mainView.getEditorImageView(), point)).clickOn(mousebutton);
}
}

Expand Down Expand Up @@ -223,11 +223,8 @@ protected void tearDown() throws TimeoutException {
.forEach(Thread::interrupt);
}

protected Point2D getScreenPointFromImageViewRatios(Point2D ratios) {
final ImageView imageView = mainView.getEditorImageView();
final Bounds imageViewScreenBounds = imageView.localToScreen(imageView.getBoundsInLocal());

return PointQueryUtils.atPositionFactors(imageViewScreenBounds, ratios);
protected Point2D getScreenPointFromRatios(Node node, Point2D ratios) {
return PointQueryUtils.atPositionFactors(node.localToScreen(node.getBoundsInLocal()), ratios);
}

protected Point2D getParentPointFromImageViewRatios(Point2D ratios) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,8 @@ void onFreehandDrawing_WhenImageFolderLoaded_ShouldCorrectlyCreatePolygons(FxRob
Double[] targetImageViewPointRatios = {0.25, 0.25, 0.1, 0.6, 0.4, 0.75, 0.75, 0.3};
List<Point2D> screenPoints = IntStream.range(0, targetImageViewPointRatios.length)
.filter(i -> i % 2 == 0)
.mapToObj(i -> getScreenPointFromImageViewRatios(new Point2D(targetImageViewPointRatios[i], targetImageViewPointRatios[i+1])))
.mapToObj(i -> getScreenPointFromRatios(mainView.getEditorImageView(),
new Point2D(targetImageViewPointRatios[i], targetImageViewPointRatios[i+1])))
.toList();

robot.moveTo(screenPoints.get(0)).press(MouseButton.PRIMARY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
package com.github.mfl28.boundingboxeditor.ui;

import com.github.mfl28.boundingboxeditor.BoundingBoxEditorTestBase;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.*;
import javafx.stage.Stage;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Tag;
Expand All @@ -31,6 +33,11 @@
import org.testfx.matcher.base.NodeMatchers;
import org.testfx.util.WaitForAsyncUtils;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.testfx.api.FxAssert.verifyThat;
Expand All @@ -48,6 +55,95 @@ void onMenuItemsClicked_ShouldCorrectlyApplyVisibilityAndShowDialogueWindows(FxR
verifyMenuBarFunctionality(robot, testinfo);
}

@Test
void onDragFolderIntoView_ShouldCorrectlyImportImageFiles(FxRobot robot, TestInfo testInfo) {
EventHandler<? super MouseEvent> dragDetectedHandler = mainView.getOnDragDetected();
try {
Map<DataFormat, Object> dataMap = new HashMap<>();
dataMap.put(DataFormat.FILES, List.of(new File(getClass().getResource(TEST_IMAGE_FOLDER_PATH_3).getFile())));

setDummyMainViewDragDetector(dataMap);

robot.moveTo(getScreenPointFromRatios(mainView, new Point2D(0.5, 0.25)))
.press(MouseButton.PRIMARY).drag(mainView, MouseButton.PRIMARY).dropTo(mainView).release(MouseButton.PRIMARY);
WaitForAsyncUtils.waitForFxEvents();

waitUntilCurrentImageIsLoaded(testInfo);

verifyThat(model.getImageFileNameSet(), Matchers.containsInAnyOrder(
"rachel-hisko-rEM3cK8F1pk-unsplash.jpg",
"wexor-tmg-L-2p8fapOA8-unsplash.jpg"));
} finally {
mainView.setOnDragDetected(dragDetectedHandler);
}
}

@Test
void onDragMultipleFoldersIntoView_ShouldDoNothing(FxRobot robot) {
EventHandler<? super MouseEvent> dragDetectedHandler = mainView.getOnDragDetected();
try {
Map<DataFormat, Object> dataMap = new HashMap<>();
dataMap.put(DataFormat.FILES, List.of(new File(getClass().getResource(TEST_IMAGE_FOLDER_PATH_1).getFile()),
new File(getClass().getResource(TEST_IMAGE_FOLDER_PATH_2).getFile())));

setDummyMainViewDragDetector(dataMap);

robot.moveTo(getScreenPointFromRatios(mainView, new Point2D(0.5, 0.25)))
.press(MouseButton.PRIMARY).drag(mainView, MouseButton.PRIMARY).dropTo(mainView).release(MouseButton.PRIMARY);
WaitForAsyncUtils.waitForFxEvents();

verifyThat(model.getImageFileNameSet(), Matchers.empty());
} finally {
mainView.setOnDragDetected(dragDetectedHandler);
}
}


@Test
void onDragNonFolderFileIntoView_ShouldDoNothing(FxRobot robot) {
EventHandler<? super MouseEvent> dragDetectedHandler = mainView.getOnDragDetected();
try {
Map<DataFormat, Object> dataMap = new HashMap<>();
dataMap.put(DataFormat.FILES, List.of(
new File(getClass().getResource(TEST_IMAGE_FOLDER_PATH_1 + "/austin-neill-685084-unsplash.jpg").getFile())));

setDummyMainViewDragDetector(dataMap);

robot.moveTo(getScreenPointFromRatios(mainView, new Point2D(0.5, 0.25)))
.press(MouseButton.PRIMARY).drag(mainView, MouseButton.PRIMARY).dropTo(mainView).release(MouseButton.PRIMARY);
WaitForAsyncUtils.waitForFxEvents();

verifyThat(model.getImageFileNameSet(), Matchers.empty());
} finally {
mainView.setOnDragDetected(dragDetectedHandler);
}
}

@Test
void onEmptyDragIntoView_ShouldDoNothing(FxRobot robot) {
EventHandler<? super MouseEvent> dragDetectedHandler = mainView.getOnDragDetected();
try {
Map<DataFormat, Object> dataMap = new HashMap<>();

setDummyMainViewDragDetector(dataMap);

robot.moveTo(getScreenPointFromRatios(mainView, new Point2D(0.5, 0.25)))
.press(MouseButton.PRIMARY).drag(mainView, MouseButton.PRIMARY).dropTo(mainView).release(MouseButton.PRIMARY);
WaitForAsyncUtils.waitForFxEvents();

verifyThat(model.getImageFileNameSet(), Matchers.empty());
} finally {
mainView.setOnDragDetected(dragDetectedHandler);
}
}

private void setDummyMainViewDragDetector(Map<DataFormat, Object> content) {
mainView.setOnDragDetected(event -> {
Dragboard dragboard = mainView.startDragAndDrop(TransferMode.LINK);
dragboard.setContent(content);
});
}

private void verifyMenuBarFunctionality(FxRobot robot, TestInfo testinfo) {
timeOutClickOn(robot, "#file-menu", testinfo);

Expand Down Expand Up @@ -109,19 +205,19 @@ private void verifyMenuBarFunctionality(FxRobot robot, TestInfo testinfo) {

MenuItem fitWindowItem = getSubMenuItem(robot, "View", "Maximize Images");
assertTrue(fitWindowItem.isVisible(),
() -> saveScreenshotAndReturnMessage(testinfo, "Maximize images item not " +
"visible"));
() -> saveScreenshotAndReturnMessage(testinfo, "Maximize images item not " +
"visible"));
assertTrue(fitWindowItem.isDisable(),
() -> saveScreenshotAndReturnMessage(testinfo, "Maximize images item not " +
"disabled"));
() -> saveScreenshotAndReturnMessage(testinfo, "Maximize images item not " +
"disabled"));

MenuItem imageExplorerItem = getSubMenuItem(robot, "View", "Show Images Panel");
assertTrue(imageExplorerItem.isVisible(),
() -> saveScreenshotAndReturnMessage(testinfo, "Image explorer item not " +
"visible"));
() -> saveScreenshotAndReturnMessage(testinfo, "Image explorer item not " +
"visible"));
assertTrue(imageExplorerItem.isDisable(),
() -> saveScreenshotAndReturnMessage(testinfo, "Image explorer item not " +
"disabled"));
() -> saveScreenshotAndReturnMessage(testinfo, "Image explorer item not " +
"disabled"));
}

private void verifyNodeVisibilities(TestInfo testinfo) {
Expand Down