Extract 'Analyze' menu, move 'Highlight Connected Areas' feature from 'Config' menu to 'Analyze' menu

This commit is contained in:
Bane Stojkovic
2025-03-26 22:07:15 +01:00
parent a8d266f561
commit 96d7f55e84
18 changed files with 274 additions and 114 deletions
@@ -117,9 +117,6 @@ public class DIYLCStarter {
LOG.info("Running in export mode with params: " + String.join(", ", args));
}
// disable HIGHLIGHT_CONTINUITY_AREA config, keep it transient
ConfigurationManager.getInstance().writeValue(IPlugInPort.HIGHLIGHT_CONTINUITY_AREA, false);
LOG.info("Loading languages...");
LangUtil.configure();
@@ -21,6 +21,7 @@ import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import javax.swing.Icon;
import org.apache.log4j.Logger;
import org.diylc.swing.actions.analyze.HighlightConnectedAreasAction;
import org.diylc.swingframework.IDrawingProvider;
import org.diylc.common.INetlistAnalyzer;
@@ -34,9 +35,9 @@ import org.diylc.swing.actions.ExportGerberAction;
import org.diylc.swing.actions.ExportPNGAction;
import org.diylc.swing.actions.FindAction;
import org.diylc.swing.actions.FlexibleLeadsAction;
import org.diylc.swing.actions.GenerateNetlistAction;
import org.diylc.swing.actions.analyze.GenerateNetlistAction;
import org.diylc.swing.actions.RenumberAction;
import org.diylc.swing.actions.SummarizeNetlistAction;
import org.diylc.swing.actions.analyze.SummarizeNetlistAction;
import org.diylc.swing.actions.ThemeAction;
import org.diylc.swing.actions.ToggleAction;
import org.diylc.swing.actions.edit.BringToFrontAction;
@@ -247,11 +248,6 @@ public class ActionFactory {
return new ConfigAction(plugInPort, title, configKey, defaultValue);
}
public ConfigAction createConfigAction(IPlugInPort plugInPort, String title, String configKey,
boolean defaultValue, String tipKey) {
return new ConfigAction(plugInPort, title, configKey, defaultValue, tipKey);
}
public ToggleAction createToggleAction(String title, String configKey, String groupName,
String defaultValue) {
return new ToggleAction(title, configKey, groupName, defaultValue, null);
@@ -287,4 +283,8 @@ public class ActionFactory {
public CheckProximityAction createCheckProximityAction(IPlugInPort plugInPort, ISwingUI swingUI) {
return new CheckProximityAction(plugInPort, swingUI);
}
public HighlightConnectedAreasAction createHighlightConnectedAreasAction(IPlugInPort plugInPort) {
return new HighlightConnectedAreasAction(plugInPort);
}
}
@@ -1,4 +1,4 @@
package org.diylc.swing.actions;
package org.diylc.swing.actions.analyze;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
@@ -83,4 +83,4 @@ public class GenerateNetlistAction extends AbstractAction {
}
}, true);
}
}
}
@@ -0,0 +1,45 @@
package org.diylc.swing.actions.analyze;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.common.IPlugInPort;
import org.diylc.common.OperationMode;
import org.diylc.core.IView;
import org.diylc.swing.ActionFactory;
import org.diylc.swing.gui.DialogFactory;
import org.diylc.utils.IconLoader;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class HighlightConnectedAreasAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private final IPlugInPort plugInPort;
public HighlightConnectedAreasAction(IPlugInPort plugInPort) {
super();
this.plugInPort = plugInPort;
putValue(AbstractAction.NAME, "Highlight Connected Areas");
putValue(IView.CHECK_BOX_MENU_ITEM, true);
putValue(AbstractAction.SELECTED_KEY,
plugInPort.getOperationMode() == OperationMode.HIGHLIGHT_CONNECTED_AREAS);
putValue(AbstractAction.SMALL_ICON, IconLoader.LaserPointer.getIcon());
}
@Override
public void actionPerformed(ActionEvent e) {
if (Boolean.TRUE.equals(getValue(AbstractAction.SELECTED_KEY))) {
plugInPort.setOperationMode(OperationMode.HIGHLIGHT_CONNECTED_AREAS);
} else {
plugInPort.setOperationMode(OperationMode.EDIT);
}
}
public void refreshState() {
putValue(AbstractAction.SELECTED_KEY,
plugInPort.getOperationMode() == OperationMode.HIGHLIGHT_CONNECTED_AREAS);
}
}
@@ -1,4 +1,4 @@
package org.diylc.swing.actions;
package org.diylc.swing.actions.analyze;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
@@ -68,7 +68,7 @@ public class InfoDialog extends ButtonDialog {
super.setVisible(b);
}
private static String[] tipKeys = new String[] {IPlugInPort.HIGHLIGHT_CONTINUITY_AREA};
private static String[] tipKeys = new String[] {"HIGHLIGHT_CONTINUITY_AREA"};
private static String[] messages =
new String[] {"Click on a component to highlight continuity area directly or indirectly connected to it.<br>In this mode components cannot be moved or edited. In order to continue editing,<br>this mode needs to be switched OFF."};
}
@@ -59,6 +59,7 @@ import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.appframework.miscutils.IConfigurationManager;
import org.diylc.swing.IDynamicSubmenuHandler;
import org.diylc.swing.plugins.analyze.AnalyzeMenuPlugin;
import org.diylc.swingframework.ButtonDialog;
import org.diylc.common.BadPositionException;
@@ -126,6 +127,7 @@ public class MainFrame extends JFrame implements ISwingUI {
presenter.installPlugin(() -> new ToolBox(this));
presenter.installPlugin(() -> new FileMenuPlugin(this));
presenter.installPlugin(() -> new AnalyzeMenuPlugin(this));
presenter.installPlugin(() -> new EditMenuPlugin(this));
presenter.installPlugin(() -> new ConfigPlugin(this));
presenter.installPlugin(() -> new LayersMenuPlugin(this));
@@ -29,6 +29,7 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.function.Consumer;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
@@ -38,11 +39,7 @@ import javax.swing.SwingUtilities;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.Utils;
import org.diylc.common.BadPositionException;
import org.diylc.common.EventType;
import org.diylc.common.IComponentTransformer;
import org.diylc.common.IPlugIn;
import org.diylc.common.IPlugInPort;
import org.diylc.common.*;
import org.diylc.lang.LangUtil;
import org.diylc.swing.ActionFactory;
import org.diylc.swing.ISwingUI;
@@ -68,6 +65,7 @@ public class ActionBarPlugin implements IPlugIn {
private static final String DONATE_HTML = LangUtil.translate("Enjoying DIYLC? Click here to buy me a coffee :)");
private static final String DONATE_HTML_SHORT = LangUtil.translate("Donate");
private Consumer<Boolean> highlightConnectedAreasUpdateAction;
public ActionBarPlugin(ISwingUI swingUI) {
this.swingUI = swingUI;
@@ -165,7 +163,14 @@ public class ActionBarPlugin implements IPlugIn {
configToolbar.add(new JLabel(" "));
configToolbar.add(LangUtil.translate("Continuous Creation"), IPlugInPort.CONTINUOUS_CREATION_KEY, IconLoader.Elements.getIcon(), false);
configToolbar.add(LangUtil.translate("Highlight Connected Areas") + " (Alt)", IPlugInPort.HIGHLIGHT_CONTINUITY_AREA, IconLoader.LaserPointer.getIcon(), false);
highlightConnectedAreasUpdateAction =
configToolbar.add(LangUtil.translate("Highlight Connected Areas") + " (Alt)",
IconLoader.LaserPointer.getIcon(),
plugInPort.getOperationMode() == OperationMode.HIGHLIGHT_CONNECTED_AREAS,
() -> plugInPort.setOperationMode(
plugInPort.getOperationMode() == OperationMode.EDIT ?
OperationMode.HIGHLIGHT_CONNECTED_AREAS :
OperationMode.EDIT));
configToolbar.add(LangUtil.translate("Sticky Points") + " (Ctrl)", IPlugInPort.STICKY_POINTS_KEY, IconLoader.GraphNodes.getIcon(), true);
}
return configToolbar;
@@ -207,14 +212,17 @@ public class ActionBarPlugin implements IPlugIn {
@Override
public EnumSet<EventType> getSubscribedEventTypes() {
return EnumSet.of(EventType.SELECTION_CHANGED);
return EnumSet.of(EventType.SELECTION_CHANGED, EventType.STATUS_MESSAGE_CHANGED);
}
@Override
public void processMessage(EventType eventType, Object... params) {
if (eventType != EventType.SELECTION_CHANGED)
return;
boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
getContextActionToolbar().setEnabled(enabled);
if (eventType == EventType.SELECTION_CHANGED) {
boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
getContextActionToolbar().setEnabled(enabled);
} else if (eventType == EventType.STATUS_MESSAGE_CHANGED) {
highlightConnectedAreasUpdateAction.accept(plugInPort.getOperationMode() ==
OperationMode.HIGHLIGHT_CONNECTED_AREAS);
}
}
}
@@ -26,6 +26,9 @@ import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JLabel;
@@ -33,6 +36,7 @@ import javax.swing.JPanel;
import javax.swing.JSeparator;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.common.IPlugInPort;
public class ConfigToolbar extends JPanel {
@@ -73,7 +77,33 @@ public class ConfigToolbar extends JPanel {
}
});
}
public Consumer<Boolean> add(String title, Icon icon, boolean defaultState, Runnable toggleAction) {
final JLabel label = new JLabel();
label.setText(defaultState ? CHECK : UNCHECK);
label.setIcon(icon);
label.setToolTipText(title);
label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
toggleAction.run();
}
});
add(label);
// ConfigurationManager.getInstance().addConfigListener(configKey, new IConfigListener() {
//
// @Override
// public void valueChanged(String key, Object value) {
// boolean checked = (boolean) value;
// label.setText(checked ? CHECK : UNCHECK);
// }
// });
return (checked) -> label.setText(checked ? CHECK : UNCHECK);
}
public void addToggleLabel(String text, String configKey, String defaultValue, List<ToggleItem> items) {
ToggleConfigLabel label = new ToggleConfigLabel(text, configKey, defaultValue, items);
add(label);
@@ -0,0 +1,113 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 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.analyze;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.*;
import org.diylc.swing.ActionFactory;
import org.diylc.swing.IDynamicSubmenuHandler;
import org.diylc.swing.ISwingUI;
import org.diylc.swing.actions.analyze.HighlightConnectedAreasAction;
import org.diylc.swing.loadline.LoadlineEditorFrame;
import org.diylc.swing.plugins.file.ProjectDrawingProvider;
import org.diylc.swing.plugins.file.TraceMaskDrawingProvider;
import org.diylc.utils.IconLoader;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.*;
import java.util.List;
/**
* Entry point class for Analyze toors.
*
* @author Branislav Stojkovic
*/
public class AnalyzeMenuPlugin implements IPlugIn {
private static final Logger LOG = Logger.getLogger(AnalyzeMenuPlugin.class);
private static final String ANALYZE_TITLE = "Analyze";
private static final String EXPORT_TITLE = "Export";
private ISwingUI swingUI;
private IPlugInPort plugInPort;
private HighlightConnectedAreasAction highlightConnectedAreasAction;
public AnalyzeMenuPlugin(ISwingUI swingUI) {
super();
this.swingUI = swingUI;
}
@Override
public void connect(IPlugInPort plugInPort) {
this.plugInPort = plugInPort;
ActionFactory actionFactory = ActionFactory.getInstance();
List<Action> menuActions = new ArrayList<>();
// Add all menu actions to the list
menuActions.add(actionFactory.createCheckProximityAction(plugInPort, swingUI));
menuActions.add(actionFactory.createBomAction(plugInPort));
menuActions.add(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, false));
menuActions.add(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, true));
highlightConnectedAreasAction =
actionFactory.createHighlightConnectedAreasAction(plugInPort);
menuActions.add(highlightConnectedAreasAction);
List<INetlistAnalyzer> summarizers = plugInPort.getNetlistAnalyzers();
if (summarizers != null) {
for (INetlistAnalyzer summarizer : summarizers) {
if (summarizer.getSwitchPreference().contains(NetlistSwitchPreference.WITH)) {
menuActions.add(actionFactory.createSummarizeNetlistAction(plugInPort, swingUI, summarizer, true));
}
if (summarizer.getSwitchPreference().contains(NetlistSwitchPreference.WITHOUT)) {
menuActions.add(actionFactory.createSummarizeNetlistAction(plugInPort, swingUI, summarizer, false));
}
}
}
// Sort actions by name
menuActions.sort((a1, a2) -> {
String name1 = (String) a1.getValue(Action.NAME);
String name2 = (String) a2.getValue(Action.NAME);
return name1.compareTo(name2);
});
// Inject sorted actions
for (Action action : menuActions) {
swingUI.injectMenuAction(action, ANALYZE_TITLE);
}
}
@Override
public EnumSet<EventType> getSubscribedEventTypes() {
return EnumSet.of(EventType.STATUS_MESSAGE_CHANGED);
}
@Override
public void processMessage(EventType eventType, Object... params) {
if (eventType == EventType.STATUS_MESSAGE_CHANGED) {
highlightConnectedAreasAction.refreshState();;
}
}
}
@@ -187,15 +187,6 @@ public class CanvasPlugin implements IPlugIn{
}
});
configManager.addConfigListener(IPlugInPort.HIGHLIGHT_CONTINUITY_AREA,
new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
canvasPanel.repaint();
}
});
getScrollPane().getViewport().setVisible(false);
}
@@ -107,13 +107,10 @@ public class ConfigPlugin implements IPlugIn {
swingUI.injectMenuAction(
ActionFactory.getInstance().createConfigAction(plugInPort, "Hi-Quality Rendering",
IPlugInPort.HI_QUALITY_RENDER_KEY, false), CONFIG_MENU);
swingUI.injectMenuAction(
ActionFactory.getInstance().createConfigAction(plugInPort, "Highlight Connected Areas", IPlugInPort.HIGHLIGHT_CONTINUITY_AREA,
false), CONFIG_MENU);
try {
List<Language> languages = LangUtil.getAvailableLanguages();
if (languages != null && languages.size() > 0) {
if (languages != null && !languages.isEmpty()) {
swingUI.injectSubmenu(LANGUAGE_MENU, IconLoader.Earth.getIcon(), CONFIG_MENU);
for(Language language : languages) {
Icon icon = null;
@@ -44,7 +44,6 @@ public class FileMenuPlugin implements IPlugIn, IDynamicSubmenuHandler {
private static final String FILE_TITLE = "File";
private static final String TRACE_MASK_TITLE = "Trace Mask";
private static final String INTEGRATION_TITLE = "Integration";
private static final String ANALYZE_TITLE = "Analyze";
private static final String EXPORT_TITLE = "Export";
private ProjectDrawingProvider drawingProvider;
@@ -93,31 +92,6 @@ public class FileMenuPlugin implements IPlugIn, IDynamicSubmenuHandler {
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.SHIFT_DOWN_MASK),
TRACE_MASK_TITLE);
swingUI.injectSubmenu(ANALYZE_TITLE, IconLoader.Scientist.getIcon(), FILE_TITLE);
swingUI.injectMenuAction(actionFactory.createCheckProximityAction(plugInPort, swingUI),
ANALYZE_TITLE);
swingUI.injectMenuAction(actionFactory.createBomAction(plugInPort), ANALYZE_TITLE);
swingUI.injectMenuAction(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, false),
ANALYZE_TITLE);
swingUI.injectMenuAction(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, true),
ANALYZE_TITLE);
List<INetlistAnalyzer> summarizers = plugInPort.getNetlistAnalyzers();
if (summarizers != null) {
for (INetlistAnalyzer summarizer : summarizers) {
if (summarizer.getSwitchPreference().contains(NetlistSwitchPreference.WITH)) {
swingUI.injectMenuAction(
actionFactory.createSummarizeNetlistAction(plugInPort, swingUI, summarizer, true),
ANALYZE_TITLE);
}
if (summarizer.getSwitchPreference().contains(NetlistSwitchPreference.WITHOUT)) {
swingUI.injectMenuAction(
actionFactory.createSummarizeNetlistAction(plugInPort, swingUI, summarizer, false),
ANALYZE_TITLE);
}
}
}
swingUI.injectMenuAction(null, FILE_TITLE);
swingUI.injectSubmenu(INTEGRATION_TITLE, IconLoader.Node.getIcon(), FILE_TITLE);
swingUI.injectMenuAction(actionFactory.createImportBlocksAction(swingUI, plugInPort),
@@ -54,6 +54,7 @@ import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.appframework.miscutils.Utils;
import org.diylc.appframework.update.UpdateChecker;
import org.diylc.appframework.update.Version;
import org.diylc.common.*;
import org.diylc.swingframework.MemoryBar;
import org.diylc.swingframework.miscutils.PercentageListCellRenderer;
import org.diylc.swingframework.update.UpdateDialog;
@@ -61,12 +62,6 @@ import org.diylc.swingframework.update.UpdateLabel;
import net.java.balloontip.BalloonTip;
import net.java.balloontip.styles.EdgedBalloonStyle;
import org.diylc.announcements.AnnouncementProvider;
import org.diylc.common.BadPositionException;
import org.diylc.common.ComponentType;
import org.diylc.common.EventType;
import org.diylc.common.IPlugIn;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ITask;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IView;
import org.diylc.lang.LangUtil;
@@ -192,14 +187,6 @@ public class StatusBar extends JPanel implements IPlugIn {
refreshPosition((Boolean)value);
}
});
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.HIGHLIGHT_CONTINUITY_AREA, new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
refreshStatusText();
}
});
}
private JComboBox<Double> getZoomBox() {
@@ -494,7 +481,7 @@ public class StatusBar extends JPanel implements IPlugIn {
refreshStatusText();
break;
case STATUS_MESSAGE_CHANGED:
statusMessage = (String) params[0];
statusMessage = params.length > 0 ? (String) params[0] : null;
refreshStatusText();
break;
case MOUSE_MOVED:
@@ -569,8 +556,7 @@ public class StatusBar extends JPanel implements IPlugIn {
}
// override any other status with this when in highlight mode, as we cannot do anything else
Boolean highlightConnectedAreasMode = ConfigurationManager.getInstance().readBoolean(IPlugInPort.HIGHLIGHT_CONTINUITY_AREA, false);
if (highlightConnectedAreasMode)
if (plugInPort.getOperationMode() == OperationMode.HIGHLIGHT_CONNECTED_AREAS)
statusText = HIGHLIGHT_CONNECTED_TIP;
final String finalStatus = statusText;