1 package net.mograsim.logic.model.model.components.submodels;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.HashSet;
8 import java.util.function.Function;
10 import org.eclipse.swt.graphics.Color;
12 import com.google.gson.JsonObject;
14 import net.haspamelodica.swt.helper.gcs.GeneralGC;
15 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
16 import net.mograsim.logic.model.model.ViewModelModifiable;
17 import net.mograsim.logic.model.model.components.GUIComponent;
18 import net.mograsim.logic.model.model.wires.MovablePin;
19 import net.mograsim.logic.model.model.wires.Pin;
20 import net.mograsim.logic.model.serializing.SubmodelComponentParams;
21 import net.mograsim.logic.model.serializing.snippets.Renderer;
22 import net.mograsim.logic.model.serializing.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer;
23 import net.mograsim.logic.model.serializing.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer.SimpleRectangularLikeParams;
24 import net.mograsim.preferences.Preferences;
26 public class SimpleRectangularSubmodelComponent extends SubmodelComponent
28 private static final double width = 35;
29 private static final double pinDistance = 10;
30 private static final double pinNameMargin = .5;
31 private static final double labelFontHeight = 5;
32 private static final double pinNameFontHeight = 3.5;
34 private final String label;
35 protected final int logicWidth;
37 private final List<String> inputPinNames;
38 private final List<String> inputPinNamesUnmodifiable;
39 private final List<String> outputPinNames;
40 private final List<String> outputPinNamesUnmodifiable;
42 private Renderer symbolRenderer;
44 public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
46 this(model, logicWidth, label, null);
49 public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label, String name)
53 this.logicWidth = logicWidth;
54 this.inputPinNames = new ArrayList<>();
55 this.inputPinNamesUnmodifiable = Collections.unmodifiableList(inputPinNames);
56 this.outputPinNames = new ArrayList<>();
57 this.outputPinNamesUnmodifiable = Collections.unmodifiableList(outputPinNames);
59 SimpleRectangularLikeParams rendererParams = new SimpleRectangularLikeParams();
60 rendererParams.centerText = label;
61 rendererParams.centerTextHeight = labelFontHeight;
62 rendererParams.horizontalComponentCenter = getWidth() / 2;
63 rendererParams.pinLabelHeight = pinNameFontHeight;
64 rendererParams.pinLabelMargin = pinNameMargin;
65 symbolRenderer = new SimpleRectangularLikeSymbolRenderer(this, rendererParams);
68 protected void setInputPins(String... pinNames)
70 setIOPins(0, inputPinNames, outputPinNames, pinNames);
73 protected void setOutputPins(String... pinNames)
75 setIOPins(width, outputPinNames, inputPinNames, pinNames);
78 private void setIOPins(double relX, List<String> pinNamesListThisSide, List<String> pinNamesListOtherSide, String... newPinNames)
80 int inputCount = newPinNames.length;
81 List<String> newPinNamesList = Arrays.asList(newPinNames);
82 if (new HashSet<>(newPinNamesList).size() != inputCount)
83 throw new IllegalArgumentException("Pin names contain duplicates");
84 for (String pinName : newPinNamesList)
85 if (pinNamesListOtherSide.contains(pinName))
86 throw new IllegalArgumentException("Can't add pin. There is a pin on the other side with the same name: " + pinName);
87 super.setSize(width, Math.max(inputCount, pinNamesListOtherSide.size()) * pinDistance);
88 for (int i = 0; i < inputCount; i++)
90 String pinName = newPinNames[i];
91 int oldPinIndex = pinNamesListThisSide.indexOf(pinName);
92 if (oldPinIndex == -1)
93 super.addSubmodelInterface(new MovablePin(this, pinName, logicWidth, relX, pinDistance / 2 + i * pinDistance));
95 getSupermodelMovablePin(pinName).setRelPos(relX, pinDistance / 2 + i * pinDistance);
97 for (String pinName : pinNamesListThisSide)
98 if (!newPinNamesList.contains(pinName))
99 super.removeSubmodelInterface(pinName);
100 pinNamesListThisSide.clear();
101 pinNamesListThisSide.addAll(newPinNamesList);
104 public List<String> getInputPinNames()
106 return inputPinNamesUnmodifiable;
109 public List<String> getOutputPinNames()
111 return outputPinNamesUnmodifiable;
115 protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
117 symbolRenderer.render(gc, visibleRegion);
121 protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
123 Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
124 if (foreground != null)
125 gc.setForeground(foreground);
126 gc.drawRectangle(getBounds());
132 public SubmodelComponentParams calculateParams(Function<GUIComponent, String> getIdentifier)
134 SubmodelComponentParams params = super.calculateParams(getIdentifier);
135 JsonObject symbolRendererParams = new JsonObject();
136 symbolRendererParams.addProperty("centerText", label);
137 symbolRendererParams.addProperty("horizontalComponentCenter", getWidth() / 2);
138 symbolRendererParams.addProperty("centerTextHeight", labelFontHeight);
139 symbolRendererParams.addProperty("pinLabelHeight", pinNameFontHeight);
140 symbolRendererParams.addProperty("pinLabelMargin", pinNameMargin);
141 params.symbolRendererSnippetID = "SimpleRectangularLikeSymbolRenderer";
142 params.symbolRendererParams = symbolRendererParams;
147 protected Pin addSubmodelInterface(MovablePin supermodelPin)
149 throw new UnsupportedOperationException(
150 "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
154 protected void removeSubmodelInterface(String name)
156 throw new UnsupportedOperationException(
157 "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
161 protected void setSize(double width, double height)
163 throw new UnsupportedOperationException(
164 "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");