Skip to content

Commit

Permalink
Use MonitorAware Coordinates in multi zoom
Browse files Browse the repository at this point in the history
This commit contributes to the use of MonitorAware points and rectangles
in the multi zoom
coordinate system mapper for translation between points and pixels.

contributes to eclipse-platform#62 and eclipse-platform#127
  • Loading branch information
amartya4256 authored and fedejeanne committed Jan 20, 2025
1 parent d441a95 commit 5b103b1
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*******************************************************************************/
package org.eclipse.swt.widgets;

import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.function.*;
Expand All @@ -39,16 +40,24 @@ private Monitor createMonitor(CoordinateSystemMapper mapper, Rectangle boundsInP
return monitor;
}

void setupMonitors(CoordinateSystemMapper mapper) {
private void setupMonitors(CoordinateSystemMapper mapper) {
Rectangle boundsInPixelsForLeftMonitor = new Rectangle(0, 0, 2000, 2000);
Rectangle boundsInPixelsForRightMonitor = new Rectangle(2000, 0, 2000, 2000);
monitors = new Monitor[] { createMonitor(mapper, boundsInPixelsForLeftMonitor, 200),
createMonitor(mapper, boundsInPixelsForRightMonitor, 100) };
}

Stream<CoordinateSystemMapper> provideCoordinateSystemMappers() {
return Stream.of(new MultiZoomCoordinateSystemMapper(null, () -> monitors),
new SingleZoomCoordinateSystemMapper(null));
private Stream<CoordinateSystemMapper> provideCoordinateSystemMappers() {
return Stream.of(getMultiZoomCoordinateSystemMapper(),
getSingleZoomCoordinateSystemMapper());
}

private MultiZoomCoordinateSystemMapper getMultiZoomCoordinateSystemMapper() {
return new MultiZoomCoordinateSystemMapper(null, () -> monitors);
}

private SingleZoomCoordinateSystemMapper getSingleZoomCoordinateSystemMapper() {
return new SingleZoomCoordinateSystemMapper(null);
}

@ParameterizedTest
Expand All @@ -60,16 +69,27 @@ void translatePointInNoMonitorBackAndForthShouldBeTheSame(CoordinateSystemMapper
assertEquals(pt, mapper.translateFromDisplayCoordinates(px, monitors[0].getZoom()));
}

@ParameterizedTest
@MethodSource("provideCoordinateSystemMappers")
@Disabled("Disabled due to current limitations of MultiZoomCoordinateSystemMapper")
void translatePointInGapBackAndForthShouldBeTheSame(CoordinateSystemMapper mapper) {
@Test
void translatePointInGapBackAndForthInSingleZoomShouldBeTheSame() {
SingleZoomCoordinateSystemMapper mapper = getSingleZoomCoordinateSystemMapper();
setupMonitors(mapper);
Point pt = new Point(1900, 400);
Point px = mapper.translateToDisplayCoordinates(pt, monitors[0].getZoom());
assertEquals(pt, mapper.translateFromDisplayCoordinates(px, monitors[0].getZoom()));
}

@Test
void translatePointInGapBackAndForthInMultiZoomShouldEndInsideTheSameMonitor() {
MultiZoomCoordinateSystemMapper mapper = getMultiZoomCoordinateSystemMapper();
setupMonitors(mapper);
Point pt = new Point(1900, 400);
Point px = mapper.translateToDisplayCoordinates(pt, monitors[0].getZoom());
Point translatedPt = mapper.translateFromDisplayCoordinates(px, monitors[0].getZoom());
Point translatedPx = mapper.translateToDisplayCoordinates(translatedPt, monitors[0].getZoom());
assertEquals(translatedPt, translatedPx);
assertEquals(translatedPx, px);
}

@ParameterizedTest
@MethodSource("provideCoordinateSystemMappers")
void translateRectangleInNoMonitorBackAndForthShouldBeTheSame(CoordinateSystemMapper mapper) {
Expand All @@ -79,22 +99,46 @@ void translateRectangleInNoMonitorBackAndForthShouldBeTheSame(CoordinateSystemMa
assertEquals(rectInPts, mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom()));
}

@ParameterizedTest
@MethodSource("provideCoordinateSystemMappers")
@Disabled("Disabled due to current limitations of MultiZoomCoordinateSystemMapper")
void translateRectangleInGapBackAndForthShouldBeTheSame(CoordinateSystemMapper mapper) {
@Test
void translateRectangleInGapBackAndForthInSingleZoomShouldBeTheSame() {
SingleZoomCoordinateSystemMapper mapper = getSingleZoomCoordinateSystemMapper();
setupMonitors(mapper);
Rectangle rectInPts = new Rectangle(1800, 400, 100, 100);
Rectangle rectInPxs = mapper.translateToDisplayCoordinates(rectInPts, monitors[0].getZoom());
assertEquals(rectInPts, mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom()));
}

@ParameterizedTest
@MethodSource("provideCoordinateSystemMappers")
@Disabled("Disabled due to current limitations of MultiZoomCoordinateSystemMapper")
void translateRectangleInGapPartiallyInRightBackAndForthShouldBeTheSame(CoordinateSystemMapper mapper) {
@Test
void translateRectangleInGapBackAndForthInMultiZoomShouldBeInMonitorBounds() {
MultiZoomCoordinateSystemMapper mapper = getMultiZoomCoordinateSystemMapper();
setupMonitors(mapper);
Rectangle rectInPts = new Rectangle(1950, 400, 100, 100);
Rectangle rectInPts = new Rectangle(1800, 400, 100, 100);
Rectangle rectInPxs = mapper.translateToDisplayCoordinates(rectInPts, monitors[0].getZoom());
Rectangle rectInPtsTranslated = mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom());
boolean isInsideMonitor = false;
for (Monitor monitor : monitors) {
if (monitor.getClientArea().intersects(rectInPtsTranslated)) {
isInsideMonitor = true;
break;
}
}
assertTrue("The translated rectangle in points is inside the monitor bounds in points", isInsideMonitor);
}

@Test
void translateRectangleInGapPartiallyInRightBackAndForthInSingleZoomShouldBeTheSame() {
SingleZoomCoordinateSystemMapper mapper = getSingleZoomCoordinateSystemMapper();
setupMonitors(mapper);
Rectangle rectInPts = new Rectangle(1950, 400, 150, 100);
Rectangle rectInPxs = mapper.translateToDisplayCoordinates(rectInPts, monitors[0].getZoom());
assertEquals(rectInPts, mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom()));
}

@Test
void translateRectangleInGapPartiallyInRightBackAndForthInMultiZoomShouldBeInside() {
MultiZoomCoordinateSystemMapper mapper = getMultiZoomCoordinateSystemMapper();
setupMonitors(mapper);
Rectangle rectInPts = new MonitorAwareRectangle(1950, 400, 150, 100, monitors[1]);
Rectangle rectInPxs = mapper.translateToDisplayCoordinates(rectInPts, monitors[0].getZoom());
assertEquals(rectInPts, mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom()));
}
Expand All @@ -108,19 +152,29 @@ void translateRectangleInGapPartiallyInLeftBackAndForthShouldBeTheSame(Coordinat
assertEquals(rectInPts, mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom()));
}

@ParameterizedTest
@MethodSource("provideCoordinateSystemMappers")
void translateRectangleInPointsInBothMonitorsPartiallyBackAndForthShouldBeTheSame(CoordinateSystemMapper mapper) {
@Test
void translateRectangleInPointsInBothMonitorsPartiallyBackAndForthInSingleZoomShouldBeTheSame() {
SingleZoomCoordinateSystemMapper mapper = getSingleZoomCoordinateSystemMapper();
setupMonitors(mapper);
Rectangle rectInPts = new Rectangle(950, 400, 1500, 100);
Rectangle rectInPxs = mapper.translateToDisplayCoordinates(rectInPts, monitors[0].getZoom());
assertEquals(rectInPts, mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom()));
}

@Test
@Disabled("Disabled due to current limitations of MultiZoomCoordinateSystemMapper")
void translateRectangleInPointsInBothMonitorsPartiallyBackAndForthInMultiZoomShouldNotEndUpInGap() {
MultiZoomCoordinateSystemMapper mapper = getMultiZoomCoordinateSystemMapper();
setupMonitors(mapper);
Rectangle rectInPts = new Rectangle(950, 400, 1500, 100);
Rectangle rectInPxs = mapper.translateToDisplayCoordinates(rectInPts, monitors[0].getZoom());
Rectangle rectInPtsTranslated = mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom());
Rectangle rectInPxsTranslated = mapper.translateToDisplayCoordinates(rectInPtsTranslated, monitors[0].getZoom());
assertEquals(rectInPxs, rectInPxsTranslated);
}

@Test
void moveRectangleInPixelsInRightMonitorsPartiallyBackAndForthShouldBeTheSame() {
CoordinateSystemMapper mapper = provideCoordinateSystemMappers().findFirst().get();
MultiZoomCoordinateSystemMapper mapper = getMultiZoomCoordinateSystemMapper();
setupMonitors(mapper);
Rectangle rectInPxs = new Rectangle(1990, -10, 2000, 2000);
Rectangle expectedSmallRectInPxs = new Rectangle(0, 0, 0, monitors[0].getZoom());
Expand All @@ -139,11 +193,10 @@ void moveRectangleInPixelsInRightMonitorsPartiallyBackAndForthShouldBeTheSame()
}

@ParameterizedTest
@MethodSource("provideCoordinateSystemMappers")
@Disabled("Disabled due to current limitations of MultiZoomCoordinateSystemMapper")
@MethodSource("provideCoordinateSystemMappers")
void translateRectangleInPixelsOutisdeMonitorsBackAndForthShouldBeTheSame(CoordinateSystemMapper mapper) {
setupMonitors(mapper);
Rectangle rectInPxs = new Rectangle(4400, 400, 1000, 1000);
Rectangle rectInPxs = new Rectangle(400, 2400, 1000, 1000);
Rectangle rectInPts = mapper.translateFromDisplayCoordinates(rectInPxs, monitors[0].getZoom());
assertEquals(rectInPxs, mapper.translateToDisplayCoordinates(rectInPts, monitors[0].getZoom()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*******************************************************************************
* Copyright (c) 2025 Yatta Solutions and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Yatta Solutions - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.graphics;

import org.eclipse.swt.widgets.*;

/**
* Instances of this class represent {@link org.eclipse.swt.graphics.Point}
* objects along with the context of the monitor in relation to which they are
* placed on the display. The monitor awareness makes it easy to scale and
* translate the points between pixels and points
*
* @since 3.129
* @noreference This class is not intended to be referenced by clients
*/
public final class MonitorAwarePoint extends Point {

private static final long serialVersionUID = 6077427420686999194L;

/**
* Constructs a new MonitorAwarePoint
*
* @param x the x coordinate of the point
* @param y the y coordinate of the point
* @param monitor the monitor with whose context the point is created
*
* @since 3.129
*/
public MonitorAwarePoint(int x, int y, Monitor monitor) {
super(x, y);
this.monitor = monitor;
}

/**
* Gets the monitor with whose context the instance is created
*
* @since 3.129
*/
public Monitor getMonitor() {
return monitor;
}

private final Monitor monitor;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2025 Yatta Solutions and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Yatta Solutions - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.graphics;

import org.eclipse.swt.widgets.*;

/**
* Instances of this class represent {@link org.eclipse.swt.graphics.Rectangle}
* objects along with the context of the monitor in relation to which they are
* placed on the display. The monitor awareness makes it easy to scale and
* translate the rectangles between pixels and points
*
* @since 3.129
* @noreference This class is not intended to be referenced by clients
*/
public final class MonitorAwareRectangle extends Rectangle {

private static final long serialVersionUID = 5041911840525116925L;

/**
* Constructs a new MonitorAwareRectangle
*
* @param x the x coordinate of the top left corner of the rectangle
* @param y the y coordinate of the top left corner of the rectangle
* @param width the width of the rectangle
* @param height the height of the rectangle
* @param monitor the monitor with whose context the rectangle is created
*
* @since 3.129
*/
public MonitorAwareRectangle(int x, int y, int width, int height, Monitor monitor) {
super(x, y, width, height);
this.monitor = monitor;
}

/**
* Gets the monitor with whose context the instance is created
*
* @since 3.129
*/
public Monitor getMonitor() {
return monitor;
}

private final Monitor monitor;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
*/

public final class Point implements Serializable {
public sealed class Point implements Serializable permits MonitorAwarePoint {

/**
* the x coordinate of the point
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
* @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
*/

public final class Rectangle implements Serializable {
public sealed class Rectangle implements Serializable permits MonitorAwareRectangle {

/**
* the x coordinate of the rectangle
Expand Down
Loading

0 comments on commit 5b103b1

Please sign in to comment.