diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml index adf9c5ce..46c6f6fa 100644 --- a/diylc/diylc-core/src/main/resources/update.xml +++ b/diylc/diylc-core/src/main/resources/update.xml @@ -573,6 +573,10 @@ IMPROVEMENT Added B-E-C, C-E-B and S-D-G transistor pinouts and ADJ-IN-OUT, IN-OUT-GND and IN-OUT-ADJ regulator pinouts + + IMPROVEMENT + The '+N' variant count next to a component in the component tree is now a button - click it to pick one of the component's variants or datasheet parts from a drop-down menu, without having to right-click the component + BUG_FIX 'DIP IC' with 'Display Pin #s' set to 'No' numbered its pins in the wrong order in netlists and AI analysis, e.g. pin 8 of an 8-pin IC was reported as pin 5 diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/tree/TreePanel.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/tree/TreePanel.java index 47f26107..2c165fee 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/tree/TreePanel.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/tree/TreePanel.java @@ -17,10 +17,18 @@ */ package org.diylc.swing.plugins.tree; +import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; +import java.awt.Cursor; import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; +import java.awt.Rectangle; +import java.awt.RenderingHints; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragSource; import java.awt.dnd.DropTarget; @@ -28,6 +36,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -35,11 +44,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import javax.swing.AbstractAction; +import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; +import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTextField; @@ -53,6 +64,7 @@ import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import org.apache.log4j.Logger; @@ -106,6 +118,9 @@ public class TreePanel extends JPanel { */ private TreePath suppressLeafActivationForPath; + private int hoveredVariantsButtonRow = -1; + private boolean variantsButtonPressed; + @SuppressWarnings("unchecked") public TreePanel(IPlugInPort plugInPort, ISwingUI swingUI) { this.plugInPort = plugInPort; @@ -135,7 +150,7 @@ public class TreePanel extends JPanel { add(getTreeScroll(), gbc); - setPreferredSize(new Dimension(260, 200)); + setPreferredSize(new Dimension(290, 200)); ConfigurationManager.getInstance().addConfigListener(IPlugInPort.FAVORITES_KEY, new IConfigListener() { @@ -211,7 +226,34 @@ public class TreePanel extends JPanel { public JTree getTree() { if (tree == null) { - tree = new JTree(getTreeModel()); + tree = new JTree(getTreeModel()) { + + private static final long serialVersionUID = 1L; + + @Override + protected void processMouseEvent(MouseEvent e) { + if (!processVariantsButtonEvent(e)) { + super.processMouseEvent(e); + } + } + + @Override + protected void processMouseMotionEvent(MouseEvent e) { + if (!processVariantsButtonEvent(e)) { + super.processMouseMotionEvent(e); + } + } + + @Override + public String getToolTipText(MouseEvent e) { + TreePath path = getVariantsButtonPathAt(e.getX(), e.getY()); + if (path != null) { + return String.format(LangUtil.translate("Click to choose from %s variants"), + countVariants(((TreeNode) path.getLastPathComponent()).getComponentType())); + } + return super.getToolTipText(e); + } + }; tree.setRootVisible(false); tree.setCellRenderer(new ComponentCellRenderer()); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); @@ -255,6 +297,11 @@ public class TreePanel extends JPanel { getPopup().show(e.getComponent(), e.getX(), e.getY()); } + @Override + public void mouseExited(MouseEvent e) { + updateVariantsButtonHover(-1, -1); + } + /** * Prefer release over click: {@code mouseClicked} is not posted if the cursor moves * between press and release (common with DnD or hand jitter), while selection may still @@ -292,6 +339,14 @@ public class TreePanel extends JPanel { } } }); + + tree.addMouseMotionListener(new MouseMotionAdapter() { + + @Override + public void mouseMoved(MouseEvent e) { + updateVariantsButtonHover(e.getX(), e.getY()); + } + }); } return tree; } @@ -411,30 +466,8 @@ public class TreePanel extends JPanel { popup.add(shortcutSubmenu); popup.add(new JSeparator()); - - if (componentType.getDatasheet() != null) { - List items = ComponentButtonFactory.createDatasheetItems(plugInPort, componentType, new ArrayList(), model -> { - LOG.info("Creating datasheet model " + String.join(", ", model)); - plugInPort.setNewComponentTypeSlot(componentType, null, model, false); - }); - for (Component item : items) { - popup.add(item); - } - popup.add(new JSeparator()); - } - List