X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.ui%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fui%2Fmodel%2Fcomponents%2FSubmodelComponent.java;h=8febda89a5d9b52e8b650818b3322eabcbf5783d;hb=c223a9de7b0ef783bcb4f7612da350583ca29abd;hp=72663a2a6f1c43a3bcbd869b2f812cb4a3ac4176;hpb=0468e55a8b3536a33208f5e24b31985b077ba745;p=Mograsim.git diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java index 72663a2a..8febda89 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java @@ -2,26 +2,38 @@ package net.mograsim.logic.ui.model.components; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import net.haspamelodica.swt.helper.gcs.GCConfig; import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.gcs.TranslatedGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; import net.mograsim.logic.ui.LogicUIRenderer; import net.mograsim.logic.ui.model.ViewModel; import net.mograsim.logic.ui.model.ViewModelModifiable; +import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams; +import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams; +import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InnerPinParams; +import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InnerWireParams; +import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InterfacePinParams; +import net.mograsim.logic.ui.model.wires.GUIWire; +import net.mograsim.logic.ui.model.wires.MovablePin; import net.mograsim.logic.ui.model.wires.Pin; public abstract class SubmodelComponent extends GUIComponent { protected final ViewModelModifiable submodelModifiable; public final ViewModel submodel; - private final Map submodelPinsPerSupermodelPin; - private final Map submodelPinsPerSupermodelPinUnmodifiable; - private final Map supermodelPinsPerSubmodelPin; - private final Map supermodelPinsPerSubmodelPinUnmodifiable; + private final Map submodelPins; + private final Map submodelMovablePinsUnmodifiable; + private final Map submodelUnmovablePinsUnmodifiable; + private final Map supermodelPins; + private final Map supermodelMovablePinsUnmodifiable; + private final Map supermodelUnmovablePinsUnmodifiable; private final SubmodelInterface submodelInterface; private double submodelScale; @@ -34,10 +46,12 @@ public abstract class SubmodelComponent extends GUIComponent super(model); this.submodelModifiable = new ViewModelModifiable(); this.submodel = submodelModifiable; - this.submodelPinsPerSupermodelPin = new HashMap<>(); - this.submodelPinsPerSupermodelPinUnmodifiable = Collections.unmodifiableMap(submodelPinsPerSupermodelPin); - this.supermodelPinsPerSubmodelPin = new HashMap<>(); - this.supermodelPinsPerSubmodelPinUnmodifiable = Collections.unmodifiableMap(supermodelPinsPerSubmodelPin); + this.submodelPins = new HashMap<>(); + this.submodelMovablePinsUnmodifiable = Collections.unmodifiableMap(submodelPins); + this.submodelUnmovablePinsUnmodifiable = Collections.unmodifiableMap(submodelPins); + this.supermodelPins = new HashMap<>(); + this.supermodelMovablePinsUnmodifiable = Collections.unmodifiableMap(supermodelPins); + this.supermodelUnmovablePinsUnmodifiable = Collections.unmodifiableMap(supermodelPins); this.submodelInterface = new SubmodelInterface(submodelModifiable); this.submodelScale = 1; @@ -52,93 +66,109 @@ public abstract class SubmodelComponent extends GUIComponent { this.submodelScale = submodelScale; - for (Entry e : supermodelPinsPerSubmodelPin.entrySet()) - e.getKey().setRelPos(e.getValue().getRelX() * submodelScale, e.getValue().getRelY() * submodelScale); + for (Entry e : supermodelPins.entrySet()) + getSubmodelMovablePin(e.getKey()).setRelPos(e.getValue().getRelX() * submodelScale, e.getValue().getRelY() * submodelScale); requestRedraw();// needed if there is no submodel interface pin } + protected double getSubmodelScale() + { + return submodelScale; + } + /** * Returns the submodel pin. */ - protected Pin addSubmodelInterface(int logicWidth, double relX, double relY) + protected Pin addSubmodelInterface(String name, int logicWidth, double relX, double relY) { - PinMovable submodelPin = new PinMovable(submodelInterface, logicWidth, relX / submodelScale, relY / submodelScale); - submodelInterface.addPin(submodelPin); + MovablePin submodelPin = new MovablePin(submodelInterface, name, logicWidth, relX / submodelScale, relY / submodelScale); + MovablePin supermodelPin = new MovablePin(this, name, logicWidth, relX, relY); - PinMovable supermodelPin = new PinMovable(this, logicWidth, relX, relY); - addPin(supermodelPin); + submodelPin.addPinMovedListener(p -> + { + double newRelX = p.getRelX() * submodelScale; + double newRelY = p.getRelY() * submodelScale; + if (supermodelPin.getRelX() != newRelX || supermodelPin.getRelY() != newRelY) + supermodelPin.setRelPos(newRelX, newRelY); + }); + supermodelPin.addPinMovedListener(p -> + { + double newRelX = p.getRelX() / submodelScale; + double newRelY = p.getRelY() / submodelScale; + if (submodelPin.getRelX() != newRelX || submodelPin.getRelY() != newRelY) + submodelPin.setRelPos(newRelX, newRelY); + }); + + submodelInterface.addPin(submodelPin); + super.addPin(supermodelPin); - submodelPinsPerSupermodelPin.put(supermodelPin, submodelPin); - supermodelPinsPerSubmodelPin.put(submodelPin, supermodelPin); + submodelPins.put(name, submodelPin); + supermodelPins.put(name, supermodelPin); // no need to call requestRedraw() because addPin() will request a redraw return submodelPin; } - protected void moveSubmodelInterface(Pin supermodelPin, double relX, double relY) + protected void removeSubmodelInterface(String name) { - PinMovable submodelPin = getSubmodelMovablePin(supermodelPin); - PinMovable supermodelPinMovable = getSupermodelMovablePin(submodelPin); + super.removePin(name); + Pin submodelPin = getSubmodelMovablePin(name); + submodelInterface.removePin(submodelPin.name); - submodelPin.setRelPos(relX / submodelScale, relY / submodelScale); - supermodelPinMovable.setRelPos(relX, relY); + submodelPins.remove(name); + supermodelPins.remove(name); - // no need to call requestRedraw() because setRelPos() will request a redraw + // no need to call requestRedraw() because removePin() will request a redraw } - protected void removeSubmodelInterface(Pin supermodelPin) + public Map getSubmodelPins() { - removePin(supermodelPin); - Pin submodelPin = getSubmodelMovablePin(supermodelPin); - submodelInterface.removePin(submodelPin); - - submodelPinsPerSupermodelPin.remove(supermodelPin); - supermodelPinsPerSubmodelPin.remove(submodelPin); + return submodelUnmovablePinsUnmodifiable; + } - // no need to call requestRedraw() because removePin() will request a redraw + public Pin getSubmodelPin(String name) + { + return getSubmodelMovablePin(name); } - public Map getSupermodelPinsPerSubmodelPin() + protected Map getSubmodelMovablePins() { - return supermodelPinsPerSubmodelPinUnmodifiable; + return submodelMovablePinsUnmodifiable; } - public Pin getSupermodelPin(Pin submodelPin) + protected MovablePin getSubmodelMovablePin(String name) { - return getSupermodelMovablePin(submodelPin); + return submodelPins.get(name); } - protected PinMovable getSupermodelMovablePin(Pin submodelPin) + public Map getSupermodelPins() { - return supermodelPinsPerSubmodelPin.get(submodelPin); + return supermodelUnmovablePinsUnmodifiable; } - public Map getSubmodelPinsPerSupermodelPin() + public Pin getSupermodelPin(String name) { - return submodelPinsPerSupermodelPinUnmodifiable; + return getSupermodelMovablePin(name); } - public Pin getSubmodelPin(Pin supermodelPin) + protected Map getSupermodelMovablePins() { - return getSubmodelMovablePin(supermodelPin); + return supermodelMovablePinsUnmodifiable; } - protected PinMovable getSubmodelMovablePin(Pin supermodelPin) + protected MovablePin getSupermodelMovablePin(String name) { - return submodelPinsPerSupermodelPin.get(supermodelPin); + return supermodelPins.get(name); } @Override public void render(GeneralGC gc, Rectangle visibleRegion) { - double posX = getBounds().x; - double posY = getBounds().y; - GCConfig conf = new GCConfig(gc); - TranslatedGC tgc = new TranslatedGC(gc, posX, posY, submodelScale, true); + TranslatedGC tgc = new TranslatedGC(gc, getPosX(), getPosY(), submodelScale, true); conf.reset(tgc); - double visibleRegionFillRatio = Math.max(getBounds().width / visibleRegion.width, getBounds().height / visibleRegion.height); + double visibleRegionFillRatio = Math.max(getWidth() / visibleRegion.width, getHeight() / visibleRegion.height); double alphaFactor = map(visibleRegionFillRatio, maxVisibleRegionFillRatioForAlpha0, minVisibleRegionFillRatioForAlpha1, 0, 1); alphaFactor = Math.max(0, Math.min(1, alphaFactor)); // we need to take the old alpha into account to support nested submodules better. @@ -148,21 +178,21 @@ public abstract class SubmodelComponent extends GUIComponent if (submodelAlpha != 0) { gc.setAlpha(submodelAlpha); - renderer.render(tgc, visibleRegion.translate(posX / submodelScale, posY / submodelScale, 1 / submodelScale)); + renderer.render(tgc, visibleRegion.translate(getPosX() / submodelScale, getPosY() / submodelScale, 1 / submodelScale)); } if (labelAlpha != 0) { gc.setAlpha(labelAlpha); - renderSymbol(gc); + renderSymbol(gc, visibleRegion); } conf.reset(gc); // draw the outline after all other operations to make interface pins look better - renderOutline(gc); + renderOutline(gc, visibleRegion); } - protected abstract void renderOutline(GeneralGC gc); + protected abstract void renderOutline(GeneralGC gc, Rectangle visibleRegion); - protected abstract void renderSymbol(GeneralGC gc); + protected abstract void renderSymbol(GeneralGC gc, Rectangle visibleRegion); private static double map(double val, double valMin, double valMax, double mapMin, double mapMax) { @@ -172,26 +202,94 @@ public abstract class SubmodelComponent extends GUIComponent @Override public boolean clicked(double x, double y) { - // TODO - double scaledX = (x - getBounds().x) / submodelScale; - double scaledY = (y - getBounds().y) / submodelScale; - double roundedScaledX = Math.round(scaledX / 5 * 2) * 5 / 2.; - double roundedScaledY = Math.round(scaledY / 5 * 2) * 5 / 2.; - System.out.println(scaledX + "|" + scaledY + ", rounded " + roundedScaledX + "|" + roundedScaledY); - return true; + double scaledX = (x - getPosX()) / submodelScale; + double scaledY = (y - getPosY()) / submodelScale; + for (GUIComponent component : submodel.getComponents()) + if (component.getBounds().contains(scaledX, scaledY) && component.clicked(scaledX, scaledY)) + return true; + return false; } - private static class PinMovable extends Pin + /** + * @return {@link SubmodelComponentParams}, which describe this {@link SubmodelComponent}. + */ + public SubmodelComponentParams calculateParams() { - public PinMovable(GUIComponent component, int logicWidth, double relX, double relY) + SubmodelComponentParams params = new SubmodelComponentParams(); + params.type = SubmodelComponent.class.getSimpleName(); + params.composition = calculateCompositionParams(); + + params.width = getWidth(); + params.height = getHeight(); + + InterfacePinParams[] iPins = new InterfacePinParams[getPins().size()]; + int i = 0; + for (Pin p : getPins()) + { + InterfacePinParams iPinParams = new InterfacePinParams(); + iPins[i] = iPinParams; + iPinParams.location = p.getRelPos(); + iPinParams.name = p.name; + iPinParams.logicWidth = p.logicWidth; + i++; + } + params.interfacePins = iPins; + return params; + } + + protected ComponentCompositionParams calculateCompositionParams() + { + ComponentCompositionParams params = new ComponentCompositionParams(); + params.innerScale = getSubmodelScale(); + + List compList = submodelModifiable.getComponents(); + Iterator componentIt = compList.iterator(); + componentIt.next(); // Skip inner SubmodelInterface + InnerComponentParams[] comps = new InnerComponentParams[compList.size() - 1]; + int i = 0; + while (componentIt.hasNext()) { - super(component, logicWidth, relX, relY); + GUIComponent component = componentIt.next(); + InnerComponentParams inner = new InnerComponentParams(); + comps[i] = inner; + inner.params = component.getInstantiationParameters(); + inner.pos = new Point(getPosX(), getPosY()); + inner.type = component.getIdentifier(); + i++; } + params.subComps = comps; - @Override - protected void setRelPos(double relX, double relY) + List wireList = submodelModifiable.getWires(); + InnerWireParams wires[] = new InnerWireParams[wireList.size()]; + i = 0; + for (GUIWire wire : wireList) { - super.setRelPos(relX, relY); + InnerWireParams inner = new InnerWireParams(); + wires[i] = inner; + InnerPinParams pin1Params = new InnerPinParams(), pin2Params = new InnerPinParams(); + + pin1Params.pinName = wire.getPin1().name; + pin1Params.compId = compList.indexOf(wire.getPin1().component); + pin2Params.pinName = wire.getPin2().name; + pin2Params.compId = compList.indexOf(wire.getPin2().component); + inner.pin1 = pin1Params; + inner.pin2 = pin2Params; + inner.path = wire.getPath(); + i++; } + params.innerWires = wires; + return params; + } + + @Override + protected void addPin(Pin pin) + { + throw new UnsupportedOperationException("Can't add pins to a SubmodelComponent directly, call addSubmodelInterface instead"); + } + + @Override + protected void removePin(String name) + { + throw new UnsupportedOperationException("Can't remove pins of a SubmodelComponent directly, call removeSubmodelInterface instead"); } } \ No newline at end of file