Added 'Node Name Tooltips' feature that can be toggled in the Config menu

This commit is contained in:
Bane Stojkovic
2026-08-16 23:39:11 +02:00
parent 63ad65152a
commit 98d9319938
8 changed files with 375 additions and 11 deletions
@@ -112,5 +112,10 @@ public enum EventType {
/**
* Signals that the Cloud account is logged out.
*/
CLOUD_LOGGED_OUT;
CLOUD_LOGGED_OUT,
/**
* Called when the mouse hovers over sticky control points (nodes) in tooltip mode.
* Parameters: String text (semicolon-separated component and node names, or null), Point point.
*/
NODE_NAME_HOVER_TOOLTIP;
}
@@ -100,6 +100,8 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
public static final String SNAP_TO_COMPONENTS = "Components";
public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
public static final String SHOW_NODE_NAME_TOOLTIPS_KEY = "showNodeNameTooltips";
public static final String LOCKED_ALPHA = "lockedAlpha";
public static final String LANGUAGE = "language";
@@ -37,6 +37,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.swing.JOptionPane;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.appframework.miscutils.IConfigurationManager;
import org.diylc.appframework.miscutils.Utils;
import org.diylc.appframework.simplemq.MessageDispatcher;
@@ -161,6 +162,8 @@ public class Presenter implements IPlugInPort {
private DIYTest test = null;
private OperationMode operationMode;
private String lastHoveredNodeText = null;
public Presenter(IView view, IConfigurationManager<?> configManager) {
this(view, configManager, false);
@@ -191,6 +194,14 @@ public class Presenter implements IPlugInPort {
variantManager.importDefaultVariants();
buildingBlockManager.importDefaultBlocks();
}
configManager.addConfigListener(IPlugInPort.SHOW_NODE_NAME_TOOLTIPS_KEY, new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
lastHoveredNodeText = null;
messageDispatcher.dispatchMessage(EventType.NODE_NAME_HOVER_TOOLTIP, null, null);
}
});
}
public void installPlugin(Supplier<IPlugIn> plugInSupplier) {
@@ -886,6 +897,45 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.AVAILABLE_CTRL_POINTS_CHANGED,
new HashMap<IDIYComponent<?>, Set<Integer>>(components));
}
// 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());
}
}
}
if (!nodeInfos.isEmpty()) {
nodeHoverText = String.join("; ", nodeInfos);
}
}
if (!Objects.equals(nodeHoverText, lastHoveredNodeText)) {
lastHoveredNodeText = nodeHoverText;
if (nodeHoverText != null && configManager.readBoolean(IPlugInPort.SHOW_NODE_NAME_TOOLTIPS_KEY, true)) {
messageDispatcher.dispatchMessage(EventType.NODE_NAME_HOVER_TOOLTIP, nodeHoverText, point);
} else {
messageDispatcher.dispatchMessage(EventType.NODE_NAME_HOVER_TOOLTIP, null, null);
}
}
}
@Override
@@ -1084,6 +1134,8 @@ public class Presenter implements IPlugInPort {
return;
}
this.dragInProgress = true;
this.lastHoveredNodeText = null;
this.messageDispatcher.dispatchMessage(EventType.NODE_NAME_HOVER_TOOLTIP, null, null);
this.dragAction = dragAction;
this.preDragProject = currentProject.clone();
Point2D scaledPoint = scalePoint(point);
@@ -397,6 +397,10 @@
<releaseDate>2026-08-06 00:00:00.000 CET</releaseDate>
<name></name>
<changes>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added 'Node Name Tooltips' feature that can be toggled in the Config menu; when enabled a tooltip is shown next to the cursor with names of component nodes under the cursor</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Significantly improved AI Assistant's knowledge base on DIYLC usage by ingesting most of the material from the eBook</description>