+++ /dev/null
-package net.mograsim.logic.model.editor.handles;
-
-import java.util.Optional;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.model.editor.states.EditorState;
-import net.mograsim.logic.model.model.LogicModelModifiable;
-import net.mograsim.logic.model.model.wires.ModelWire;
-
-public class WireHandle extends Handle
-{
- private boolean selected = false;
- private final static double WIDTH = 2.0;
- private final static double WIDTH_SQUARED = WIDTH * WIDTH;
- private final LogicModelModifiable model;
- public final ModelWire parent;
-
- public WireHandle(LogicModelModifiable model, ModelWire parent)
- {
- super(5);
- this.model = model;
- this.parent = parent;
- parent.addPathChangedListener(c -> updateBounds());
- updateBounds();
- }
-
- @Override
- void destroy()
- {
- super.destroy();
- parent.removePathChangedListener(c -> updateBounds());
- }
-
- public void updateBounds()
- {
- Rectangle r = parent.getBounds();
- moveTo(r.x, r.y);
- setSize(r.width, r.height);
- }
-
- @Override
- public void render(GeneralGC gc)
- {
- if (selected)
- {
- gc.setLineWidth(WIDTH);
- gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_YELLOW));
- gc.drawPolyline(parent.getEffectivePath());
- }
- }
-
- @Override
- public void onSelect()
- {
- selected = true;
- callRedrawListeners();
- }
-
- @Override
- public void onDeselect()
- {
- selected = false;
- callRedrawListeners();
- }
-
- @Override
- public void reqDelete()
- {
- // this wire could already be removed implicitly when removing a selection containing both wires and components
- if (model.getWireByName(parent.name) != null)
- model.destroyWire(parent);
- }
-
- @Override
- public boolean contains(double x, double y)
- {
- return click(parent, x, y).isPresent();
- }
-
- @Override
- public boolean click(double x, double y, int stateMask, EditorState state)
- {
- Optional<WireClickData> op = click(parent, x, y);
- if (op.isEmpty())
- return false;
- WireClickData data = op.get();
- return state.clickedHandle(new WireHandleClickInfo(this, data.segment, data.pos, stateMask));
- }
-
- public static class WireHandleClickInfo extends HandleClickInfo
- {
- public final int segment;
- public final Point posOnWire;
-
- WireHandleClickInfo(WireHandle clicked, int segment, Point posOnWire, int stateMask)
- {
- super(clicked, stateMask);
- this.segment = segment;
- this.posOnWire = posOnWire;
- }
-
- }
-
- private static Optional<WireClickData> click(ModelWire w, double x, double y)
- {
- Rectangle modifiedBounds = w.getBounds();
- modifiedBounds.x -= WIDTH;
- modifiedBounds.y -= WIDTH;
- modifiedBounds.width += WIDTH * 2;
- modifiedBounds.height += WIDTH * 2;
- if (modifiedBounds.contains(x, y))
- {
- double[] effectivePath = w.getEffectivePath();
- for (int i = 3; i < effectivePath.length; i += 2)
- {
- double a1 = effectivePath[i - 3], a2 = effectivePath[i - 2], b1 = effectivePath[i - 1], b2 = effectivePath[i], r1 = b2 - a2,
- r2 = a1 - b1;
-
- double f = ((x - a1) * r2 + (a2 - y) * r1) / (-r2 * r2 - r1 * r1);
- if (f >= 0 && f <= 1)
- {
- double e1 = a1 + f * (b1 - a1), e2 = a2 + f * (b2 - a2);
- r1 = e1 - x;
- r2 = e2 - y;
- if (r1 * r1 + r2 * r2 <= WIDTH_SQUARED)
- return Optional.of(new WireClickData(new Point(e1, e2), (i / 2) - 1));
- }
- }
- }
- return Optional.empty();
- }
-
- private final static class WireClickData
- {
- WireClickData(Point pos, int segment)
- {
- this.pos = pos;
- this.segment = segment;
- }
-
- /**
- * Position on the wire that is closest to the click
- */
- public final Point pos;
- /**
- * Segment of the wire that the {@link Point} pos is on
- */
- public final int segment;
- }
-
- @Override
- public HandleType getType()
- {
- return HandleType.WIRE;
- }
-}