Hovering over a control point in a board's Underside Display shows its node name tooltip, as it does on the board itself

This commit is contained in:
Bane Stojkovic
2026-11-11 18:39:29 +01:00
parent 13b31e6dd5
commit 1fe823270e
2 changed files with 74 additions and 20 deletions
@@ -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<String> findNodeNamesAt(Point2D point, IBoard mirrorBoard) {
List<String> nodeInfos = new ArrayList<String>();
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 = "<b>" + component.getName() + "</b>: " + 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<String> nodeInfos = new ArrayList<String>();
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 = "<b>" + component.getName() + "</b>: " + 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<String> 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);
@@ -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<EventType> 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("<b>R1</b>: 2", receivedTooltip[0]);
}
private IBoard boardUnder(IDIYComponent<?> component) {
Point2D first = component.getControlPoint(0);
Point2D last = component.getControlPoint(component.getControlPointCount() - 1);