mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-22 11:55:15 -04:00
fixes a mouse selection issue; closes #736
This commit is contained in:
parent
ee55b94276
commit
0b78f80c8c
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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<VisualElement> 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<VisualElement> 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<Circuit> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user