mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 10:42:09 +10:00
Added 'Node Name Tooltips' feature that can be toggled in the Config menu
This commit is contained in:
@@ -69,6 +69,7 @@ public class CanvasPlugin implements IPlugIn{
|
||||
private CanvasPanel canvasPanel;
|
||||
private ComponentPopupMenu popupMenu;
|
||||
private ResizeInfoTooltip resizeInfoTooltip;
|
||||
private NodeNameTooltip nodeNameTooltip;
|
||||
private boolean resizingInProgress = false;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
@@ -196,6 +197,7 @@ public class CanvasPlugin implements IPlugIn{
|
||||
if (canvasPanel == null) {
|
||||
canvasPanel = new CanvasPanel(plugInPort, configManager);
|
||||
resizeInfoTooltip = new ResizeInfoTooltip(canvasPanel, configManager);
|
||||
nodeNameTooltip = new NodeNameTooltip(canvasPanel, configManager);
|
||||
canvasPanel.addMouseListener(new MouseAdapter() {
|
||||
|
||||
private MouseEvent pressedEvent;
|
||||
@@ -219,6 +221,9 @@ public class CanvasPlugin implements IPlugIn{
|
||||
canvasPanel.requestFocus();
|
||||
canvasPanel.setClickInProgress(true);
|
||||
pressedEvent = e;
|
||||
if (nodeNameTooltip != null) {
|
||||
nodeNameTooltip.hideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -289,6 +294,10 @@ public class CanvasPlugin implements IPlugIn{
|
||||
resizeInfoTooltip.hideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeNameTooltip != null && nodeNameTooltip.isVisible()) {
|
||||
nodeNameTooltip.updatePosition(e.getPoint());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -469,7 +478,7 @@ public class CanvasPlugin implements IPlugIn{
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.of(EventType.PROJECT_LOADED, EventType.ZOOM_CHANGED, EventType.REPAINT,
|
||||
EventType.SCROLL_TO);
|
||||
EventType.SCROLL_TO, EventType.NODE_NAME_HOVER_TOOLTIP);
|
||||
}
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
@@ -567,6 +576,26 @@ public class CanvasPlugin implements IPlugIn{
|
||||
(int) (targetRect.getCenterY() - visibleRect2.height / 2), visibleRect2.width,
|
||||
visibleRect2.height));
|
||||
break;
|
||||
case NODE_NAME_HOVER_TOOLTIP:
|
||||
final String nodeText = params.length > 0 ? (String) params[0] : null;
|
||||
final Point mousePt = params.length > 1 && params[1] instanceof Point ? (Point) params[1] : null;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (nodeText != null) {
|
||||
Point pt = mousePt != null ? mousePt : getCanvasPanel().getMousePosition();
|
||||
if (pt != null && nodeNameTooltip != null) {
|
||||
nodeNameTooltip.update(nodeText, pt);
|
||||
}
|
||||
} else {
|
||||
if (nodeNameTooltip != null) {
|
||||
nodeNameTooltip.hideTooltip();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
// }
|
||||
// });
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
*
|
||||
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
*
|
||||
* This file is part of DIYLC.
|
||||
*
|
||||
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Window;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import org.diylc.appframework.miscutils.IConfigurationManager;
|
||||
|
||||
/**
|
||||
* A lightweight tooltip window that displays node/terminal information and tracks the mouse cursor.
|
||||
*/
|
||||
public class NodeNameTooltip {
|
||||
|
||||
private static final int OFFSET_X = 16;
|
||||
private static final int OFFSET_Y = 16;
|
||||
|
||||
private JWindow tooltipWindow;
|
||||
private JLabel tooltipLabel;
|
||||
private Component parentComponent;
|
||||
private String currentText;
|
||||
|
||||
public NodeNameTooltip(Component parentComponent, IConfigurationManager<?> configManager) {
|
||||
this.parentComponent = parentComponent;
|
||||
initializeTooltip();
|
||||
}
|
||||
|
||||
private void initializeTooltip() {
|
||||
Window parentWindow = SwingUtilities.getWindowAncestor(parentComponent);
|
||||
if (parentWindow == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
tooltipWindow = new JWindow(parentWindow);
|
||||
tooltipLabel = new JLabel() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
super.paintComponent(g2d);
|
||||
g2d.dispose();
|
||||
}
|
||||
};
|
||||
|
||||
// Use system tooltip font and colors
|
||||
Font tooltipFont = UIManager.getFont("ToolTip.font");
|
||||
if (tooltipFont != null) {
|
||||
tooltipLabel.setFont(tooltipFont);
|
||||
}
|
||||
Color tooltipBackground = UIManager.getColor("ToolTip.background");
|
||||
Color tooltipForeground = UIManager.getColor("ToolTip.foreground");
|
||||
Color tooltipBorderColor = UIManager.getColor("ToolTip.border");
|
||||
if (tooltipBorderColor == null) {
|
||||
tooltipBorderColor = Color.GRAY;
|
||||
}
|
||||
|
||||
tooltipLabel.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createLineBorder(tooltipBorderColor, 1),
|
||||
BorderFactory.createEmptyBorder(4, 6, 4, 6)));
|
||||
tooltipLabel.setOpaque(true);
|
||||
tooltipLabel.setBackground(tooltipBackground != null ? tooltipBackground : new Color(255, 255, 220));
|
||||
tooltipLabel.setForeground(tooltipForeground != null ? tooltipForeground : Color.BLACK);
|
||||
|
||||
tooltipWindow.add(tooltipLabel);
|
||||
tooltipWindow.setFocusableWindowState(false);
|
||||
tooltipWindow.setAlwaysOnTop(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the tooltip with text and mouse position.
|
||||
*/
|
||||
public void update(String text, Point mousePosition) {
|
||||
this.currentText = text;
|
||||
|
||||
if (text == null || text.trim().isEmpty() || mousePosition == null) {
|
||||
hideTooltip();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tooltipWindow == null) {
|
||||
initializeTooltip();
|
||||
if (tooltipWindow == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tooltipLabel.setText("<html>" + text + "</html>");
|
||||
tooltipLabel.setPreferredSize(null);
|
||||
tooltipWindow.pack();
|
||||
|
||||
updateTooltipPosition(mousePosition);
|
||||
tooltipWindow.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the tooltip position based on the current mouse position.
|
||||
*/
|
||||
public void updatePosition(Point mousePosition) {
|
||||
if (currentText != null && mousePosition != null
|
||||
&& tooltipWindow != null && tooltipWindow.isVisible()) {
|
||||
updateTooltipPosition(mousePosition);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTooltipPosition(Point mousePosition) {
|
||||
if (tooltipWindow == null || parentComponent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert mouse position to screen coordinates
|
||||
Point screenPoint = new Point(mousePosition);
|
||||
SwingUtilities.convertPointToScreen(screenPoint, parentComponent);
|
||||
|
||||
// Position tooltip 16 pixels down and right from cursor
|
||||
int x = screenPoint.x + OFFSET_X;
|
||||
int y = screenPoint.y + OFFSET_Y;
|
||||
|
||||
// Ensure tooltip stays on screen
|
||||
Dimension tooltipSize = tooltipWindow.getSize();
|
||||
if (tooltipSize == null) {
|
||||
tooltipWindow.pack();
|
||||
tooltipSize = tooltipWindow.getSize();
|
||||
}
|
||||
|
||||
if (tooltipSize != null) {
|
||||
java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
|
||||
Dimension screenSize = toolkit.getScreenSize();
|
||||
|
||||
// Adjust if tooltip would go off screen
|
||||
if (x + tooltipSize.width > screenSize.width) {
|
||||
x = screenPoint.x - tooltipSize.width - OFFSET_X;
|
||||
}
|
||||
if (y + tooltipSize.height > screenSize.height) {
|
||||
y = screenPoint.y - tooltipSize.height - OFFSET_Y;
|
||||
}
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
tooltipWindow.setLocation(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the tooltip.
|
||||
*/
|
||||
public void hideTooltip() {
|
||||
if (tooltipWindow != null) {
|
||||
tooltipWindow.setVisible(false);
|
||||
}
|
||||
currentText = null;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return tooltipWindow != null && tooltipWindow.isVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the tooltip window.
|
||||
*/
|
||||
public void dispose() {
|
||||
if (tooltipWindow != null) {
|
||||
tooltipWindow.dispose();
|
||||
tooltipWindow = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,6 +134,9 @@ public class ConfigPlugin implements IPlugIn {
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Mouse Wheel Zoom", IPlugInPort.WHEEL_ZOOM_KEY,
|
||||
false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Node Name Tooltips",
|
||||
IPlugInPort.SHOW_NODE_NAME_TOOLTIPS_KEY, true), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Outline Mode", IPlugInPort.OUTLINE_KEY, false),
|
||||
CONFIG_MENU);
|
||||
@@ -153,18 +156,22 @@ public class ConfigPlugin implements IPlugIn {
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show AI Assistant",
|
||||
ConfigPlugin.CHATBOT, true), CONFIG_MENU);
|
||||
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Grid", IPlugInPort.SHOW_GRID_KEY, true),
|
||||
CONFIG_MENU);
|
||||
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Project Explorer",
|
||||
ConfigPlugin.PROJECT_EXPLORER, false), CONFIG_MENU);
|
||||
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Rulers", IPlugInPort.SHOW_RULERS_KEY, true),
|
||||
CONFIG_MENU);
|
||||
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Resize Dimensions",
|
||||
IPlugInPort.SHOW_RESIZE_DIMENSIONS_TOOLTIP_KEY, true), CONFIG_MENU);
|
||||
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Rulers", IPlugInPort.SHOW_RULERS_KEY, true),
|
||||
CONFIG_MENU);
|
||||
|
||||
swingUI.injectSubmenu(SNAP_MENU, IconLoader.GraphEdgeDirected.getIcon(), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createToggleAction(IPlugInPort.SNAP_TO_NONE, IPlugInPort.SNAP_TO_KEY, SNAP_MENU, IPlugInPort.SNAP_TO_DEFAULT),
|
||||
@@ -175,11 +182,7 @@ public class ConfigPlugin implements IPlugIn {
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createToggleAction(IPlugInPort.SNAP_TO_COMPONENTS, IPlugInPort.SNAP_TO_KEY, SNAP_MENU, IPlugInPort.SNAP_TO_DEFAULT),
|
||||
SNAP_MENU);
|
||||
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Grid", IPlugInPort.SHOW_GRID_KEY, true),
|
||||
CONFIG_MENU);
|
||||
|
||||
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance()
|
||||
.createConfigAction(plugInPort, "Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU);
|
||||
|
||||
Reference in New Issue
Block a user