X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.model%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Fmodel%2Fcomponents%2Fsubmodels%2FSubmodelComponent.java;h=f67be7d3942cd829605c504e62138120c0fdfb04;hb=0a04a4ed66ecebd4254541c4977599f6052c115a;hp=9cdbabbbd913f14b01862bab7cd3bcfda07b84fd;hpb=f37f1f93f2c1ceb780f1c7ecab888bcb8f4f8b89;p=Mograsim.git diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java index 9cdbabbb..f67be7d3 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.function.Consumer; import net.haspamelodica.swt.helper.gcs.GCConfig; import net.haspamelodica.swt.helper.gcs.GeneralGC; @@ -15,13 +16,19 @@ import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.GUIComponent; import net.mograsim.logic.model.model.wires.MovablePin; import net.mograsim.logic.model.model.wires.Pin; +import net.mograsim.logic.model.model.wires.PinUsage; +import net.mograsim.logic.model.serializing.IdentifyParams; +import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.serializing.SubmodelComponentParams; +import net.mograsim.logic.model.serializing.SubmodelComponentSerializer; import net.mograsim.logic.model.snippets.Renderer; +import net.mograsim.logic.model.util.JsonHandler; +import net.mograsim.preferences.Preferences; /** * A {@link GUIComponent} consisting of another model. A SubmodelComponent can have so-called "interface pins" connecting the * inner and outer models. */ -//TODO override getParams public abstract class SubmodelComponent extends GUIComponent { public static final String SUBMODEL_INTERFACE_NAME = "_submodelinterface"; @@ -110,6 +117,13 @@ public abstract class SubmodelComponent extends GUIComponent this.minVisibleRegionFillRatioForAlpha1 = 0.9; this.renderer = new LogicUIRenderer(submodelModifiable); + Consumer redrawHandlerChangedListener = submodelModifiable::setRedrawHandler; + model.addRedrawHandlerChangedListener(redrawHandlerChangedListener); + model.addComponentRemovedListener(c -> + { + if (c == this) + model.removeRedrawHandlerChangedListener(redrawHandlerChangedListener); + }); submodelModifiable.setRedrawHandler(model.getRedrawHandler()); } @@ -129,8 +143,24 @@ public abstract class SubmodelComponent extends GUIComponent super.addPin(supermodelPin);// do this first to be fail-fast if the supermodel does not belong to this component String name = supermodelPin.name; - MovablePin submodelPin = new MovablePin(submodelInterface, name, supermodelPin.logicWidth, supermodelPin.getRelX() / submodelScale, - supermodelPin.getRelY() / submodelScale); + // TODO if we upgrade to Java 12, replace with switch-expression + PinUsage submodelPinUsage; + switch (supermodelPin.usage) + { + case INPUT: + submodelPinUsage = PinUsage.OUTPUT; + break; + case OUTPUT: + submodelPinUsage = PinUsage.INPUT; + break; + case TRISTATE: + submodelPinUsage = PinUsage.TRISTATE; + break; + default: + throw new IllegalArgumentException("Unknown enum constant: " + supermodelPin.usage); + } + MovablePin submodelPin = new MovablePin(submodelInterface, name, supermodelPin.logicWidth, submodelPinUsage, + supermodelPin.getRelX() / submodelScale, supermodelPin.getRelY() / submodelScale); submodelPin.addPinMovedListener(p -> { @@ -321,11 +351,22 @@ public abstract class SubmodelComponent extends GUIComponent return outlineRenderer; } + @Override + public boolean clicked(double x, double y) + { + double scaledX = (x - getPosX()) / submodelScale; + double scaledY = (y - getPosY()) / submodelScale; + for (GUIComponent component : submodel.getComponentsByName().values()) + if (component.getBounds().contains(scaledX, scaledY) && component.clicked(scaledX, scaledY)) + return true; + return false; + } + @Override public void render(GeneralGC gc, Rectangle visibleRegion) { GCConfig conf = new GCConfig(gc); - TranslatedGC tgc = new TranslatedGC(gc, getPosX(), getPosY(), submodelScale, true); + GeneralGC tgc = new TranslatedGC(gc, getPosX(), getPosY(), submodelScale, true); conf.reset(tgc); double visibleRegionFillRatio = Math.max(getWidth() / visibleRegion.width, getHeight() / visibleRegion.height); double alphaFactor = map(visibleRegionFillRatio, maxVisibleRegionFillRatioForAlpha0, minVisibleRegionFillRatioForAlpha1, 0, 1); @@ -345,6 +386,8 @@ public abstract class SubmodelComponent extends GUIComponent renderSymbol(gc, visibleRegion); } conf.reset(gc); + // reset line width explicitly to avoid rounding errors causing weird glitches + gc.setLineWidth(Preferences.current().getDouble("net.mograsim.logic.model.linewidth.default")); // draw the outline after all other operations to make interface pins look better renderOutline(gc, visibleRegion); } @@ -376,15 +419,18 @@ public abstract class SubmodelComponent extends GUIComponent return mapMin + (val - valMin) * (mapMax - mapMin) / (valMax - valMin); } + // serializing + @Override - public boolean clicked(double x, double y) + public String getIDForSerializing(IdentifyParams idParams) { - double scaledX = (x - getPosX()) / submodelScale; - double scaledY = (y - getPosY()) / submodelScale; - for (GUIComponent component : submodel.getComponentsByName().values()) - if (component.getBounds().contains(scaledX, scaledY) && component.clicked(scaledX, scaledY)) - return true; - return false; + return "submodel";// TODO what ID? + } + + @Override + public SubmodelComponentParams getParamsForSerializing(IdentifyParams idParams) + { + return SubmodelComponentSerializer.serialize(this, idParams); } // operations no longer supported @@ -400,4 +446,10 @@ public abstract class SubmodelComponent extends GUIComponent { throw new UnsupportedOperationException("Can't remove pins of a SubmodelComponent directly, call removeSubmodelInterface instead"); } + + static + { + IndirectGUIComponentCreator.setComponentSupplier(SubmodelComponent.class.getCanonicalName(), + (m, p, n) -> SubmodelComponentSerializer.deserialize(m, JsonHandler.fromJsonTree(p, SubmodelComponentParams.class), n)); + } } \ No newline at end of file