Add tests on camera mouse controller

This commit is contained in:
martin 2022-08-28 13:42:50 +02:00
parent 417b927c02
commit ff5341f186
6 changed files with 210 additions and 38 deletions

View File

@ -0,0 +1,118 @@
package org.jzy3d.chart.controllers.mouse.camera;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.awt.event.InputEvent;
import org.junit.Test;
import org.jzy3d.chart.Chart;
import org.jzy3d.chart.factories.IChartFactory;
import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.maths.Coord2d;
import org.jzy3d.maths.Coord3d;
import org.jzy3d.maths.Scale;
import org.jzy3d.mocks.jzy3d.MouseMock;
import org.jzy3d.plot3d.rendering.canvas.IScreenCanvas;
import org.jzy3d.plot3d.rendering.view.View;
public class TestAWTCameraMouseController {
@Test
public void given3DView_WhenMouseDragWithLeftButton_ThenViewRotate() {
// Given
View view = spy(View.class);
when(view.is2D()).thenReturn(false); // 3D mode
when(view.getViewPoint()).thenReturn(new Coord3d(0,0,10));
IScreenCanvas canvas = mock(IScreenCanvas.class);
IChartFactory factory = mock(IChartFactory.class);
when(factory.newCameraThreadController(null)).thenReturn(null);
Chart chart = mock(Chart.class);
when(chart.getView()).thenReturn(view);
when(chart.getCanvas()).thenReturn(canvas);
when(chart.getFactory()).thenReturn(factory);
AWTCameraMouseController mouse = new AWTCameraMouseController(chart);
// When mouse click, drag and release
mouse.mousePressed(MouseMock.event(10, 10, InputEvent.BUTTON1_DOWN_MASK));
mouse.mouseDragged(MouseMock.event(15, 15, InputEvent.BUTTON1_DOWN_MASK));
mouse.mouseDragged(MouseMock.event(20, 20, InputEvent.BUTTON1_DOWN_MASK));
mouse.mouseReleased(MouseMock.event(25, 25, InputEvent.BUTTON1_DOWN_MASK));
// Then two rotations are invoked
verify(view, times(2)).rotate(eq(new Coord2d(0.05, 0.05)), eq(false));
}
@Test
public void given3DView_WhenMouseDragWithRightButton_ThenViewShift() {
// Given
View view = mock(View.class);
when(view.is2D()).thenReturn(false); // 3D mode
//when(view.getViewPoint()).thenReturn(new Coord3d(0,0,10));
when(view.getBounds()).thenReturn(new BoundingBox3d(0,1,0,1,0,1));
when(view.getScale()).thenReturn(new Scale(0,1));
//when(view.setScale()).thenReturn(new Scale(0,1));
IScreenCanvas canvas = mock(IScreenCanvas.class);
IChartFactory factory = mock(IChartFactory.class);
when(factory.newCameraThreadController(null)).thenReturn(null);
Chart chart = mock(Chart.class);
when(chart.getView()).thenReturn(view);
when(chart.getCanvas()).thenReturn(canvas);
when(chart.getFactory()).thenReturn(factory);
AWTCameraMouseController mouse = new AWTCameraMouseController(chart);
// When mouse click, drag and release
mouse.mousePressed(MouseMock.event(10, 10, InputEvent.BUTTON3_DOWN_MASK));
mouse.mouseDragged(MouseMock.event(15, 15, InputEvent.BUTTON3_DOWN_MASK));
mouse.mouseDragged(MouseMock.event(20, 20, InputEvent.BUTTON3_DOWN_MASK));
mouse.mouseReleased(MouseMock.event(25, 25, InputEvent.BUTTON3_DOWN_MASK));
// Then two rotations are invoked
verify(view, times(2)).shift(eq(0.01f), eq(false));
}
@Test
public void given3DView_WhenMouseWheel_ThenViewScale() {
// Given
View view = mock(View.class);
when(view.is2D()).thenReturn(false); // 3D mode
//when(view.getViewPoint()).thenReturn(new Coord3d(0,0,10));
//when(view.getBounds()).thenReturn(new BoundingBox3d(0,1,0,1,0,1));
//when(view.getScale()).thenReturn(new Scale(0,1));
//when(view.setScale()).thenReturn(new Scale(0,1));
IScreenCanvas canvas = mock(IScreenCanvas.class);
IChartFactory factory = mock(IChartFactory.class);
when(factory.newCameraThreadController(null)).thenReturn(null);
Chart chart = mock(Chart.class);
when(chart.getView()).thenReturn(view);
when(chart.getCanvas()).thenReturn(canvas);
when(chart.getFactory()).thenReturn(factory);
AWTCameraMouseController mouse = new AWTCameraMouseController(chart);
// When mouse click, drag and release
mouse.mouseWheelMoved(MouseMock.wheel(10));
mouse.mouseWheelMoved(MouseMock.wheel(10));
// Then two rotations are invoked
verify(view, times(2)).zoomZ(eq(2f), eq(false));
}
}

View File

@ -9,8 +9,7 @@ import org.jzy3d.events.ControllerEventListener;
public class AbstractController {
protected List<Chart> targets;
protected Vector<ControllerEventListener> controllerListeners =
new Vector<ControllerEventListener>(1);
protected List<ControllerEventListener> controllerListeners = new ArrayList<ControllerEventListener>(1);
public AbstractController() {}

View File

@ -112,9 +112,9 @@ public class View {
// view listeners
protected List<IViewPointChangedListener> viewPointChangedListeners;
protected List<IViewEventListener> viewEventListeners;
protected List<IViewLifecycleEventListener> viewLifecycleListeners;
protected List<IViewPointChangedListener> viewPointChangedListeners = new ArrayList<>();
protected List<IViewLifecycleEventListener> viewLifecycleListeners = new ArrayList<>();
protected List<IViewEventListener> viewEventListeners = new ArrayList<>();
protected boolean wasOnTopAtLastRendering;
// view states
@ -186,6 +186,12 @@ public class View {
public View(IChartFactory factory, Scene scene, ICanvas canvas, Quality quality) {
initInstance(factory, scene, canvas, quality);
}
/**
* An empty constructor to allow creating spied mocks
*/
protected View() {
}
/**
* Initialize a view object. Invoked by constructor
@ -222,9 +228,6 @@ public class View {
this.quality = quality;
this.annotations = factory.newScene(false);
this.viewEventListeners = new ArrayList<>();
this.viewPointChangedListeners = new ArrayList<>();
this.viewLifecycleListeners = new ArrayList<>();
this.wasOnTopAtLastRendering = false;
this.scene.getGraph().getStrategy().setView(this);

View File

@ -0,0 +1,55 @@
package org.jzy3d.mocks.jzy3d;
import java.awt.Component;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import javax.swing.JPanel;
public class MouseMock {
protected static JPanel defaultComponent = new JPanel();
public static MouseEvent event(int x, int y) {
return event(defaultComponent, x, y, 0);
}
public static MouseEvent event(int x, int y, int modifiers) {
return event(defaultComponent, x, y, modifiers);
}
public static MouseEvent event(Component sourceCanvas, int x, int y) {
return event(sourceCanvas, x, y, 0);
}
/*public static MouseEvent event(Component sourceCanvas, int x, int y, boolean isLeftDown) {
int modifiers = 0;
if(isLeftDown) {
modifiers = modifiers | InputEvent.BUTTON1_DOWN_MASK;
}
return event(sourceCanvas, x, y, modifiers);
}*/
public static MouseEvent event(Component sourceCanvas, int x, int y, int modifiers) {
MouseEvent e = new MouseEvent(sourceCanvas, 0, System.nanoTime(), modifiers, x, y, x, y, 1, false, 0);
return e;
}
public static MouseWheelEvent wheel(int wheelRotation) {
return wheel(defaultComponent, wheelRotation);
}
public static MouseWheelEvent wheel(Component sourceCanvas, int wheelRotation) {
int x = 0;
int y = 0;
int scrollType = 0;
int scrollAmount = 0;
int modifiers = 0;
MouseWheelEvent e = new MouseWheelEvent(sourceCanvas, 0, System.nanoTime(), modifiers, x, y, 100, 100, 1, false, scrollType, scrollAmount, wheelRotation);
return e;
}
}

View File

@ -1,7 +1,5 @@
package org.jzy3d.chart.controllers.mouse.camera;
import java.awt.Component;
import java.awt.event.MouseEvent;
import org.junit.Assert;
import org.junit.Test;
import org.jzy3d.chart.Chart;
@ -14,6 +12,7 @@ import org.jzy3d.colors.Color;
import org.jzy3d.colors.ColorMapper;
import org.jzy3d.colors.colormaps.ColorMapRainbow;
import org.jzy3d.maths.Range;
import org.jzy3d.mocks.jzy3d.MouseMock;
import org.jzy3d.plot3d.builder.Mapper;
import org.jzy3d.plot3d.builder.SurfaceBuilder;
import org.jzy3d.plot3d.builder.concrete.OrthonormalGrid;
@ -79,10 +78,10 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 10;
// Then : no optimization triggered
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
Assert.assertFalse(mouse.mustOptimizeMouseDrag);
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
// -------------------------------------
@ -90,7 +89,7 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 1000;
// Then : optimization IS set to ON at MOUSE PRESS
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
Assert.assertTrue(mouse.mustOptimizeMouseDrag);
// Then : HiDPI is disabled DURING mouse DRAGGED
@ -98,13 +97,13 @@ public class TestAdaptiveMouseController {
mouse.policy.optimizeByDroppingHiDPI);
Assert.assertTrue("Did NOT start drag already", mouse.isFirstDrag);
mouse.mouseDragged(mouseEvent(canvas, 100, 100));
mouse.mouseDragged(MouseMock.event(canvas, 100, 100));
Assert.assertFalse("Did start drag already", mouse.isFirstDrag);
Assert.assertFalse("GL properly configured", canvas.getGL().isAutoAdaptToHiDPI());
// Then : HiDPI is reset to intial state (true) AFTER mouse RELEASED
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
Assert.assertEquals(false, chart.getQuality().isPreserveViewportSize());
Assert.assertEquals(allowHiDPI, canvas.getGL().isAutoAdaptToHiDPI());
@ -131,7 +130,7 @@ public class TestAdaptiveMouseController {
// -------------------------------------
// When : fast rendering
mockRenderingPerf.value = 10;
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
// Then : no optimization triggered
Assert.assertFalse(mouse.mustOptimizeMouseDrag);
@ -141,7 +140,7 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 1000;
// Then : optimization IS set to ON at MOUSE PRESS
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
Assert.assertTrue(mouse.mustOptimizeMouseDrag);
@ -150,14 +149,14 @@ public class TestAdaptiveMouseController {
mouse.policy.optimizeByDroppingHiDPI);
Assert.assertTrue("Did NOT start drag already", mouse.isFirstDrag);
mouse.mouseDragged(mouseEvent(canvas, 100, 100));
mouse.mouseDragged(MouseMock.event(canvas, 100, 100));
Assert.assertFalse("Did start drag already", mouse.isFirstDrag);
Assert.assertFalse("GL properly configured", canvas.getGL().isAutoAdaptToHiDPI());
// Then : HiDPI remains configured as before
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
Assert.assertFalse(mouse.mustOptimizeMouseDrag);
Assert.assertEquals(allowHiDPI, canvas.getGL().isAutoAdaptToHiDPI());
@ -189,14 +188,14 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 1000;
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mouseDragged(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
mouse.mouseDragged(MouseMock.event(canvas, 100, 100));
Assert.assertTrue("Wireframe enabled during drag", surface.isWireframeDisplayed());
Assert.assertFalse("Face hidden during drag", surface.isFaceDisplayed());
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
// -------------------------------------
// Then the wireframe status is back to original value
@ -230,14 +229,14 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 1000;
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mouseDragged(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
mouse.mouseDragged(MouseMock.event(canvas, 100, 100));
Assert.assertTrue("Wireframe enabled during drag", surface.isWireframeDisplayed());
Assert.assertFalse("Face hidden during drag", surface.isFaceDisplayed());
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
// -------------------------------------
// Then the wireframe status is back to original value
@ -271,15 +270,15 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 1000;
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mouseDragged(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
mouse.mouseDragged(MouseMock.event(canvas, 100, 100));
Assert.assertFalse("Wireframe hidden during drag", surface.isWireframeDisplayed());
Assert.assertFalse("Face hidden during drag", surface.isFaceDisplayed());
Assert.assertTrue("Bounds displayed during drag", surface.isBoundingBoxDisplayed());
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
// -------------------------------------
// Then the wireframe status is back to original value
@ -315,13 +314,13 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 1000;
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mouseDragged(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
mouse.mouseDragged(MouseMock.event(canvas, 100, 100));
Assert.assertFalse("Chart quality is now configured for flat coloring",
chart.getQuality().isSmoothColor());
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
// -------------------------------------
// Then the wireframe status is back to original value
@ -363,8 +362,8 @@ public class TestAdaptiveMouseController {
mockRenderingPerf.value = 1000;
mouse.mousePressed(mouseEvent(canvas, 100, 100));
mouse.mouseDragged(mouseEvent(canvas, 100, 100));
mouse.mousePressed(MouseMock.event(canvas, 100, 100));
mouse.mouseDragged(MouseMock.event(canvas, 100, 100));
// Then select a configuration that is below max accepted rendering time
@ -384,7 +383,7 @@ public class TestAdaptiveMouseController {
// -------------------------------------
// When releasing mouse, then surface is configured back to original settings
mouse.mouseReleased(mouseEvent(canvas, 100, 100));
mouse.mouseReleased(MouseMock.event(canvas, 100, 100));
// Then the wireframe status is back to original value
@ -494,9 +493,6 @@ public class TestAdaptiveMouseController {
return chart;
}
protected static MouseEvent mouseEvent(Component sourceCanvas, int x, int y) {
return new MouseEvent(sourceCanvas, 0, 0, 0, x, y, 100, 100, 1, false, 0);
}
protected static Shape surface() {

View File

@ -35,7 +35,8 @@ public class AWTDualModeMouseSelector {
// Create and add controllers
threadCamera = new CameraThreadController(chart);
mouseCamera = new AWTCameraMouseController(chart);
mouseCamera.addSlaveThreadController(threadCamera);
mouseCamera.addThread(threadCamera);
chart.getCanvas().addKeyController(buildToggleKeyListener(chart));
releaseCam(); // default mode is selection