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=bcf85aeed0684b487a8c1fc91604739987a2339b;hb=4b580a621ec0b174c70b1d9e3937f46394656aef;hp=b5c1762b3bb50b89785769ed2319bc6d9e80b810;hpb=a393b0a2a9899707af54c9ee77a01f28ac967bd1;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 b5c1762b..bcf85aee 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,12 +16,18 @@ 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.IdentifierGetter; +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; /** * 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"; @@ -80,6 +87,15 @@ public abstract class SubmodelComponent extends GUIComponent */ private final LogicUIRenderer renderer; + /** + * The {@link Renderer} used to render the symbol of this SubmodelCoponent. + */ + private Renderer symbolRenderer; + /** + * The {@link Renderer} used to render the outline of this SubmodelCoponent. + */ + private Renderer outlineRenderer; + // creation and destruction public SubmodelComponent(ViewModelModifiable model, String name) @@ -96,11 +112,18 @@ public abstract class SubmodelComponent extends GUIComponent this.submodelInterface = new SubmodelInterface(submodelModifiable, SUBMODEL_INTERFACE_NAME); this.submodelScale = 1; - this.maxVisibleRegionFillRatioForAlpha0 = 0.4; - this.minVisibleRegionFillRatioForAlpha1 = 0.8; + this.maxVisibleRegionFillRatioForAlpha0 = 0.8; + this.minVisibleRegionFillRatioForAlpha1 = 0.9; this.renderer = new LogicUIRenderer(submodelModifiable); - submodelModifiable.addRedrawListener(this::requestRedraw); + Consumer redrawHandlerChangedListener = submodelModifiable::setRedrawHandler; + model.addRedrawHandlerChangedListener(redrawHandlerChangedListener); + model.addComponentRemovedListener(c -> + { + if (c == this) + model.removeRedrawHandlerChangedListener(redrawHandlerChangedListener); + }); + submodelModifiable.setRedrawHandler(model.getRedrawHandler()); } // pins @@ -119,8 +142,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 -> { @@ -256,7 +295,7 @@ public abstract class SubmodelComponent extends GUIComponent 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 + model.requestRedraw();// needed if there is no submodel interface pin } /** @@ -269,6 +308,59 @@ public abstract class SubmodelComponent extends GUIComponent return submodelScale; } + /** + * @see #renderSymbol(GeneralGC, Rectangle) + * + * @author Daniel Kirschten + */ + protected void setSymbolRenderer(Renderer symbolRenderer) + { + this.symbolRenderer = symbolRenderer; + model.requestRedraw(); + } + + /** + * @see #renderSymbol(GeneralGC, Rectangle) + * + * @author Daniel Kirschten + */ + public Renderer getSymbolRenderer() + { + return symbolRenderer; + } + + /** + * @see #renderOutline(GeneralGC, Rectangle) + * + * @author Daniel Kirschten + */ + protected void setOutlineRenderer(Renderer outlineRenderer) + { + this.outlineRenderer = outlineRenderer; + model.requestRedraw(); + } + + /** + * @see #renderOutline(GeneralGC, Rectangle) + * + * @author Daniel Kirschten + */ + public Renderer getOutlineRenderer() + { + 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) { @@ -297,35 +389,39 @@ public abstract class SubmodelComponent extends GUIComponent renderOutline(gc, visibleRegion); } - // TODO make this a path /** - * Render the outline of this {@link SubmodelComponent}, e.g. the graphical elements that should stay visible if the submodel is drawn. + * Render the symbol of this {@link SubmodelComponent}, e.g. the things that should be hidden if the submodel is drawn. * * @author Daniel Kirschten */ - protected abstract void renderOutline(GeneralGC gc, Rectangle visibleRegion); + protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion) + { + if (symbolRenderer != null) + symbolRenderer.render(gc, visibleRegion); + } /** - * Render the symbol of this {@link SubmodelComponent}, e.g. the things that should be hidden if the submodel is drawn. + * Render the outline of this {@link SubmodelComponent}, e.g. the graphical elements that should stay visible if the submodel is drawn. * * @author Daniel Kirschten */ - protected abstract void renderSymbol(GeneralGC gc, Rectangle visibleRegion); + protected void renderOutline(GeneralGC gc, Rectangle visibleRegion) + { + if (outlineRenderer != null) + outlineRenderer.render(gc, visibleRegion); + } private static double map(double val, double valMin, double valMax, double mapMin, double mapMax) { return mapMin + (val - valMin) * (mapMax - mapMin) / (valMax - valMin); } + // serializing + @Override - public boolean clicked(double x, double y) + public SubmodelComponentParams getParamsForSerializing(IdentifierGetter idGetter) { - 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 SubmodelComponentSerializer.serialize(this, idGetter); } // operations no longer supported @@ -341,4 +437,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