diff --git a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java index 49844fdf9..4bb151884 100644 --- a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java +++ b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java @@ -6,7 +6,9 @@ package de.neemann.digital.draw.elements; import de.neemann.digital.core.SyncAccess; +import de.neemann.digital.core.Value; import de.neemann.digital.core.element.*; +import de.neemann.digital.core.io.Const; import de.neemann.digital.draw.graphics.*; import de.neemann.digital.draw.shapes.Shape; import de.neemann.digital.draw.shapes.*; @@ -18,7 +20,6 @@ import java.awt.*; import java.awt.image.BufferedImage; import static de.neemann.digital.draw.shapes.GenericShape.SIZE; -import static de.neemann.digital.draw.shapes.GenericShape.SIZE2; import static de.neemann.digital.gui.components.CircuitComponent.raster; /** @@ -143,20 +144,18 @@ public class VisualElement implements Drawable, Movable, AttributeListener { * Checks if the given point is within the bounding box of the shape of this element. * * @param p a position - * @param includeText true if a click on a text also selectes the element + * @param includeText true if a click on a text also selects the element * @return true if p is inside the bounding box of the shape of this element. */ public boolean matches(Vector p, boolean includeText) { + if (getShape() instanceof ShapeSpecificMatch) + return ((ShapeSpecificMatch) getShape()).matches(getTransform().invert().transform(p)); + GraphicMinMax m = getMinMax(includeText); - boolean inBox = (m.getMin().x - SIZE2 <= p.x) - && (m.getMin().y - SIZE2 <= p.y) - && (p.x <= m.getMax().x + SIZE2) - && (p.y <= m.getMax().y + SIZE2); - - if (inBox && getShape() instanceof ShapeMatch) - return ((ShapeMatch) getShape()).matches(getTransform().invert().transform(p)); - - return inBox; + return (m.getMin().x <= p.x) + && (m.getMin().y <= p.y) + && (p.x <= m.getMax().x) + && (p.y <= m.getMax().y); } /** @@ -391,11 +390,19 @@ public class VisualElement implements Drawable, Movable, AttributeListener { @Override public String toString() { - String lab = elementAttributes.getLabel(); - if (lab != null && lab.length() > 0) - return elementName + " (" + lab + ")"; - else - return elementName; + if (elementName.equals(Const.DESCRIPTION.getName())) { + return elementName + " (" + + elementAttributes.getValueFormatter().formatToView( + new Value(elementAttributes.get(Keys.VALUE), elementAttributes.getBits())) + ")"; + } else if (elementName.equals(Tunnel.DESCRIPTION.getName())) { + return elementName + " (" + elementAttributes.get(Keys.NETNAME) + ")"; + } else { + String label = elementAttributes.getLabel(); + if (label.isEmpty()) { + return elementName; + } else + return elementName + " (" + label + ")"; + } } /** diff --git a/src/main/java/de/neemann/digital/draw/shapes/RectShape.java b/src/main/java/de/neemann/digital/draw/shapes/RectShape.java index 21ce9f338..d7c952778 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/RectShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/RectShape.java @@ -19,7 +19,7 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE2; /** * Simple rectangle */ -public class RectShape implements ShapeMatch { +public class RectShape implements ShapeSpecificMatch { private final String label; private final int width; private final int height; diff --git a/src/main/java/de/neemann/digital/draw/shapes/ShapeMatch.java b/src/main/java/de/neemann/digital/draw/shapes/ShapeSpecificMatch.java similarity index 91% rename from src/main/java/de/neemann/digital/draw/shapes/ShapeMatch.java rename to src/main/java/de/neemann/digital/draw/shapes/ShapeSpecificMatch.java index 9e67b7056..c02b31ddc 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ShapeMatch.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeSpecificMatch.java @@ -11,7 +11,7 @@ import de.neemann.digital.draw.graphics.Vector; * A shape where the clickable area is not simply the bounding box, but * defined by the shape itself. */ -public interface ShapeMatch extends Shape { +public interface ShapeSpecificMatch extends Shape { /** * Checks is the given position matches the shape diff --git a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java index 2eeef90d2..0cc7d22ee 100644 --- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -1669,16 +1669,19 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib } - private VisualElement getVisualElement(Vector pos, boolean includeText) { - VisualElement vp = null; + private SearchResult getVisualElement(Vector pos, boolean includeText) { List list = getCircuit().getElementListAt(pos, includeText); if (list.size() == 1) - vp = list.get(0); + return new SearchResult(SearchResult.State.FOUND, list.get(0)); else if (list.size() > 1) { ItemPicker picker = new ItemPicker<>(parent, list); - vp = picker.select(); + VisualElement vp = picker.select(); + if (vp == null) + return new SearchResult(SearchResult.State.CANCELED, null); + else + return new SearchResult(SearchResult.State.FOUND, vp); } - return vp; + return new SearchResult(SearchResult.State.NONE, null); } //CHECKSTYLE.ON: FinalClass @@ -1703,23 +1706,29 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib Vector pos = getPosVector(e); if (mouse.isSecondaryClick(e)) { - VisualElement vp = getVisualElement(pos, true); - if (vp != null) - editAttributes(vp, e); + SearchResult sel = getVisualElement(pos, true); + if (sel.getVisualElement() != null) + editAttributes(sel.getVisualElement(), e); } else if (mouse.isPrimaryClick(e) && hadFocusAtClick) { - VisualElement vp = getVisualElement(pos, false); - if (vp != null) { - if (vp.isPinPos(raster(pos)) && !mouse.isClickModifier(e)) { - if (!isLocked()) mouseWireRect.activate(pos); - } else - mouseMoveElement.activate(vp, pos); - } else if (!isLocked()) { - if (mouse.isClickModifier(e)) { - Wire wire = getCircuit().getWireAt(pos, SIZE2); - if (wire != null) - mouseMoveWire.activate(wire, pos); - } else - mouseWireRect.activate(pos); + SearchResult sel = getVisualElement(pos, false); + switch (sel.getState()) { + case FOUND: + VisualElement vp = sel.getVisualElement(); + if (vp.isPinPos(raster(pos)) && !mouse.isClickModifier(e)) { + if (!isLocked()) mouseWireRect.activate(pos); + } else + mouseMoveElement.activate(vp, pos); + break; + case NONE: + if (!isLocked()) { + if (mouse.isClickModifier(e)) { + Wire wire = getCircuit().getWireAt(pos, SIZE2); + if (wire != null) + mouseMoveWire.activate(wire, pos); + } else + mouseWireRect.activate(pos); + } + break; } } } @@ -2776,9 +2785,9 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib @Override void clicked(MouseEvent e) { Vector pos = getPosVector(e); - VisualElement vp = getVisualElement(pos, true); - if (vp != null) - wizardNotification.notify(vp); + SearchResult sel = getVisualElement(pos, true); + if (sel.getVisualElement() != null) + wizardNotification.notify(sel.getVisualElement()); } @Override @@ -2816,4 +2825,24 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib */ void modified(Modification modification); } + + private static final class SearchResult { + private final State state; + private final VisualElement visualElement; + + enum State {NONE, FOUND, CANCELED} + + private SearchResult(State state, VisualElement visualElement) { + this.state = state; + this.visualElement = visualElement; + } + + private State getState() { + return state; + } + + private VisualElement getVisualElement() { + return visualElement; + } + } }