diff --git a/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java index 696efdccc..1b7ded933 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java +++ b/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java @@ -1000,6 +1000,42 @@ public class Presenter implements IPlugInPort { return components; } + /** + * Lists the names of the sticky nodes under the specified point, for the hover tooltip. With a + * mirror board, the point is already reflected and only the parts shown in that board's + * Underside Display are considered. + */ + private List findNodeNamesAt(Point2D point, IBoard mirrorBoard) { + List nodeInfos = new ArrayList(); + for (int i = currentProject.getComponents().size() - 1; i >= 0; i--) { + IDIYComponent component = currentProject.getComponents().get(i); + if (mirrorBoard != null && !UndersideMirror.isMirrored(mirrorBoard, component)) { + continue; + } + for (int pointIndex = 0; pointIndex < component.getControlPointCount(); pointIndex++) { + try { + if (component.isControlPointSticky(pointIndex)) { + Point2D controlPoint = component.getControlPoint(pointIndex); + if (controlPoint != null + && point.distance(controlPoint) < DrawingManager.CONTROL_POINT_SIZE) { + String nodeName = component.getControlPointNodeName(pointIndex); + if (nodeName != null && !nodeName.trim().isEmpty()) { + String info = "" + component.getName() + ": " + nodeName; + if (!nodeInfos.contains(info)) { + nodeInfos.add(info); + } + } + } + } + } catch (Exception e) { + LOG.warn("Error reading control point for component of type: " + + component.getClass().getName()); + } + } + } + return nodeInfos; + } + @Override public void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown) { if (point == null) @@ -1085,27 +1121,14 @@ public class Presenter implements IPlugInPort { // Node name hover detection for sticky points String nodeHoverText = null; if (!dragInProgress && instantiationManager.getComponentTypeSlot() == null) { - List nodeInfos = new ArrayList(); - for (int i = currentProject.getComponents().size() - 1; i >= 0; i--) { - IDIYComponent component = currentProject.getComponents().get(i); - for (int pointIndex = 0; pointIndex < component.getControlPointCount(); pointIndex++) { - try { - if (component.isControlPointSticky(pointIndex)) { - Point2D controlPoint = component.getControlPoint(pointIndex); - if (controlPoint != null && previousScaledPoint.distance(controlPoint) < DrawingManager.CONTROL_POINT_SIZE) { - String nodeName = component.getControlPointNodeName(pointIndex); - if (nodeName != null && !nodeName.trim().isEmpty()) { - String info = "" + component.getName() + ": " + nodeName; - if (!nodeInfos.contains(info)) { - nodeInfos.add(info); - } - } - } - } - } catch (Exception e) { - LOG.warn("Error reading control point for component of type: " + component.getClass().getName()); - } + List nodeInfos = findNodeNamesAt(previousScaledPoint, null); + for (IBoard board : + UndersideMirror.findBoardsMirroredAt(currentProject, previousScaledPoint)) { + if (!nodeInfos.isEmpty()) { + break; } + nodeInfos = + findNodeNamesAt(UndersideMirror.reflect(board, previousScaledPoint), board); } if (!nodeInfos.isEmpty()) { nodeHoverText = String.join("; ", nodeInfos); diff --git a/diylc/diylc-swing/src/test/java/org/diylc/PresenterTests.java b/diylc/diylc-swing/src/test/java/org/diylc/PresenterTests.java index f0622d3c0..16ce915af 100644 --- a/diylc/diylc-swing/src/test/java/org/diylc/PresenterTests.java +++ b/diylc/diylc-swing/src/test/java/org/diylc/PresenterTests.java @@ -436,6 +436,37 @@ public class PresenterTests extends TestBase { Assert.assertEquals(jumperStart, jumper.getControlPoint(0)); } + @Test + public void testNodeNameHoverThroughUndersideMirror() { + final String[] receivedTooltip = new String[1]; + IPlugIn testPlugin = new IPlugIn() { + @Override + public void connect(IPlugInPort plugInPort) {} + + @Override + public EnumSet getSubscribedEventTypes() { + return EnumSet.of(EventType.NODE_NAME_HOVER_TOOLTIP); + } + + @Override + public void processMessage(EventType eventType, Object... params) { + receivedTooltip[0] = params.length > 0 ? (String) params[0] : null; + } + }; + presenter.installPlugin(() -> testPlugin); + InMemoryConfigurationManager.getInstance() + .writeValue(IPlugInPort.SHOW_NODE_NAME_TOOLTIPS_KEY, true); + instantiateTwoClick("Passive", "Resistor", new Point(1000, 1000), new Point(1200, 1000)); + IDIYComponent resistor = presenter.getCurrentProject().getComponents().get(0); + IBoard board = boardUnder(resistor); + Point inMirror = toScreen( + UndersideMirror.createTransform(board).transform(resistor.getControlPoint(1), null)); + + presenter.mouseMoved(inMirror, false, false, false); + + Assert.assertEquals("R1: 2", receivedTooltip[0]); + } + private IBoard boardUnder(IDIYComponent component) { Point2D first = component.getControlPoint(0); Point2D last = component.getControlPoint(component.getControlPointCount() - 1);