import java.util.List;
import java.util.Map;
import java.util.Set;
+ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
comps.remove(interfaceComp);
registerInterfaceComponent(interfaceComp);
comps.forEach(c -> registerComponent(c));
-
+
model.getWires().forEach(w -> registerWire(w));
addHandle(cornerHandle = new CornerHandle(editor.toBeEdited));
}
private void registerWire(GUIWire wire)
{
- wire.addPathChangedListener((w, diff) ->
+ Point[] path = wire.getPath();
+ AtomicInteger oldLength = new AtomicInteger(path == null ? 0 : path.length);
+ wire.addPathChangedListener(w ->
{
- if(diff != 0)
+ Point[] newPath = w.getPath();
+ int newLength = newPath == null ? 0 : newPath.length;
+ int diff = oldLength.getAndSet(newLength) - newLength;
+ if (diff != 0)
{
- if(diff > 0)
+ if (diff > 0)
{
- for(int i = 0; i < diff; i++)
+ for (int i = 0; i < diff; i++)
addWirePointHandle(w);
}
-
+
List<WirePointHandle> wpHandles = pointHandlesPerWire.get(w);
int size = wpHandles.size();
- for(int i = 0; i < size; i++)
+ for (int i = 0; i < size; i++)
{
wpHandles.get(i).setIndex(i);
}
pointHandlesPerWire.get(w).forEach(h -> h.updatePos());
});
addWireHandle(wire);
- if (wire.getPath() == null)
+ if (path == null)
return;
- for (int i = 0; i < wire.getPath().length; i++)
+ for (int i = 0; i < path.length; i++)
{
addWirePointHandle(wire);
}
private void addInterfacePinHandle(Pin p)
{
- //The following is not an alternative to the cast, because the new pin is not yet in the map, when the listener is called
- //editor.toBeEdited.getSubmodelMovablePins().get(p.name);
+ // The following is not an alternative to the cast, because the new pin is not yet in the map, when the listener is called
+ // editor.toBeEdited.getSubmodelMovablePins().get(p.name);
MovablePin pM = (MovablePin) p;
InterfacePinHandle h = new InterfacePinHandle(pM, editor.toBeEdited);
handlePerInterfacePin.put(pM, h);
this.wirePointHandles.add(h);
addHandle(h);
}
-
+
void destroyWirePointHandle(GUIWire owner, WirePointHandle h)
{
List<WirePointHandle> handles = pointHandlesPerWire.get(owner);
private void removeWirePointHandles(GUIWire owner)
{
- if(!pointHandlesPerWire.containsKey(owner))
+ if (!pointHandlesPerWire.containsKey(owner))
return;
pointHandlesPerWire.get(owner).forEach(h ->
{
{
return handlePerWire.get(parent);
}
-
+
public Handle getInterfacePinHandle(Pin p)
{
return handlePerInterfacePin.get(p);
{
return Collections.unmodifiableCollection(handlePerPin.values());
}
-
+
/**
* @return An unmodifiable view of all registered {@link InterfacePinHandle}s
*/
if (!click(getWirePointHandles(), clicked, entryState, stateMask))
if (!click(getWireHandles(), clicked, entryState, stateMask))
if (!click(handlePerComp.values(), clicked, entryState, stateMask))
- entryState.clickedEmpty(clicked, stateMask);
+ entryState.clickedEmpty(clicked, stateMask);
entryState.clicked(clicked, stateMask);
}
-- private boolean click(Collection<? extends Handle> handles, Point clicked, EditorState state, int stateMask)
++ private static boolean click(Collection<? extends Handle> handles, Point clicked, EditorState state, int stateMask)
{
for (Handle h : handles)
if (h.click(clicked.x, clicked.y, stateMask, state))
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.model.editor.states.EditorState;
import net.mograsim.logic.model.model.wires.GUIWire;
- import net.mograsim.logic.model.model.wires.GUIWire.PathChangedListener;
- public class WireHandle extends Handle implements PathChangedListener
+ public class WireHandle extends Handle
{
private boolean selected = false;
private final static double WIDTH = 2.0;
public WireHandle(GUIWire parent)
{
this.parent = parent;
- parent.addPathChangedListener(this);
+ parent.addPathChangedListener(c -> updateBounds());
updateBounds();
}
-
+
@Override
void destroy()
{
super.destroy();
- parent.removePathChangedListener(this);
+ parent.removePathChangedListener(c -> updateBounds());
}
public void updateBounds()
moveTo(r.x, r.y);
setSize(r.width, r.height);
}
-
+
@Override
public void render(GeneralGC gc)
{
- if(selected)
+ if (selected)
{
gc.setLineWidth(WIDTH);
gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_YELLOW));
gc.drawPolyline(parent.getEffectivePath());
}
}
-
+
@Override
public void onSelect()
{
selected = false;
callRedrawListeners();
}
-
+
@Override
public void reqDelete()
{
parent.destroy();
}
-
+
@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())
+ 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(GUIWire w, double x, double y)
{
Rectangle modifiedBounds = w.getBounds();
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 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)
*/
public final int segment;
}
-
+
@Override
public HandleType getType()
{
return HandleType.WIRE;
}
-
- @Override
- public void pathChanged(GUIWire wire, int diff)
- {
- updateBounds();
- }
}