1 package net.mograsim.logic.ui.model.components;
3 import java.util.ArrayList;
4 import java.util.Collections;
7 import java.util.TreeMap;
9 import net.haspamelodica.swt.helper.gcs.GeneralGC;
10 import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
11 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
12 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
13 import net.mograsim.logic.ui.model.ViewModelModifiable;
14 import net.mograsim.logic.ui.model.wires.Pin;
16 public class SimpleRectangularSubmodelComponent extends SubmodelComponent
18 public static String kLabel = "label", kInCount = "input_count", kOutCount = "output_count", kLogicWidth = "logic_width";
20 private static final double width = 35;
21 private static final double pinDistance = 10;
22 private static final double pinNameMargin = .5;
23 private static final double labelFontHeight = 5;
24 private static final double pinNameFontHeight = 3.5;
26 private final String label;
27 protected final int logicWidth;
29 private final List<Pin> inputSupermodelPins;
30 private final List<Pin> inputSupermodelPinsUnmodifiable;
31 private final List<Pin> outputSupermodelPins;
32 private final List<Pin> outputSupermodelPinsUnmodifiable;
33 private final List<Pin> inputSubmodelPins;
34 private final List<Pin> inputSubmodelPinsUnmodifiable;
35 private final List<Pin> outputSubmodelPins;
36 private final List<Pin> outputSubmodelPinsUnmodifiable;
38 protected SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
42 this.logicWidth = logicWidth;
43 this.inputSupermodelPins = new ArrayList<>();
44 this.inputSupermodelPinsUnmodifiable = Collections.unmodifiableList(inputSupermodelPins);
45 this.outputSupermodelPins = new ArrayList<>();
46 this.outputSupermodelPinsUnmodifiable = Collections.unmodifiableList(outputSupermodelPins);
47 this.inputSubmodelPins = new ArrayList<>();
48 this.inputSubmodelPinsUnmodifiable = Collections.unmodifiableList(inputSubmodelPins);
49 this.outputSubmodelPins = new ArrayList<>();
50 this.outputSubmodelPinsUnmodifiable = Collections.unmodifiableList(outputSubmodelPins);
53 protected void setInputPins(String... pinNames)
55 int inputCount = pinNames.length;
56 int oldInputCount = inputSupermodelPins.size();
57 double height = Math.max(inputCount, outputSupermodelPins.size()) * pinDistance;
58 super.setSize(width, height);
59 if (oldInputCount > inputCount)
60 while (inputSupermodelPins.size() > inputCount)
62 inputSubmodelPins.remove(inputCount);
63 super.removeSubmodelInterface(inputSupermodelPins.remove(inputCount));
65 else if (oldInputCount < inputCount)
66 for (int i = oldInputCount; i < inputCount; i++)
68 Pin submodelPin = super.addSubmodelInterface(pinNames[i], logicWidth, 0, pinDistance / 2 + i * pinDistance);
69 inputSubmodelPins.add(submodelPin);
70 inputSupermodelPins.add(getSupermodelPin(submodelPin));
72 for (int i = 0; i < Math.min(oldInputCount, inputCount); i++)
74 if (!inputSubmodelPins.get(i).name.equals(pinNames[i]))
76 super.removeSubmodelInterface(inputSupermodelPins.get(i));
77 Pin submodelPin = super.addSubmodelInterface(pinNames[i], logicWidth, 0, pinDistance / 2 + i * pinDistance);
78 inputSubmodelPins.set(i, submodelPin);
79 inputSupermodelPins.set(i, getSupermodelPin(submodelPin));
84 protected void setOutputPins(String... pinNames)
86 int outputCount = pinNames.length;
87 int oldOutputCount = outputSupermodelPins.size();
88 super.setSize(width, Math.max(inputSupermodelPins.size(), outputCount) * pinDistance);
89 if (oldOutputCount > outputCount)
90 while (outputSupermodelPins.size() > outputCount)
92 outputSubmodelPins.remove(outputCount);
93 super.removeSubmodelInterface(outputSupermodelPins.get(outputCount));
95 else if (oldOutputCount < outputCount)
96 for (int i = oldOutputCount; i < outputCount; i++)
98 Pin submodelPin = super.addSubmodelInterface(pinNames[i], logicWidth, width, pinDistance / 2 + i * pinDistance);
99 outputSubmodelPins.add(submodelPin);
100 outputSupermodelPins.add(getSupermodelPin(submodelPin));
102 for (int i = 0; i < Math.min(oldOutputCount, outputCount); i++)
104 if (!outputSubmodelPins.get(i).name.equals(pinNames[i]))
106 super.removeSubmodelInterface(outputSupermodelPins.get(i));
107 Pin submodelPin = super.addSubmodelInterface(pinNames[i], logicWidth, width, pinDistance / 2 + i * pinDistance);
108 outputSubmodelPins.set(i, submodelPin);
109 outputSupermodelPins.set(i, getSupermodelPin(submodelPin));
114 public List<Pin> getInputPins()
116 return inputSupermodelPinsUnmodifiable;
119 public List<Pin> getOutputPins()
121 return outputSupermodelPinsUnmodifiable;
124 protected List<Pin> getInputSubmodelPins()
126 return inputSubmodelPinsUnmodifiable;
129 protected List<Pin> getOutputSubmodelPins()
131 return outputSubmodelPinsUnmodifiable;
135 protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
137 double posX = getBounds().x;
138 double posY = getBounds().y;
140 Font oldFont = gc.getFont();
141 gc.setFont(new Font(oldFont.getName(), labelFontHeight, oldFont.getStyle()));
142 Point textExtent = gc.textExtent(label);
143 gc.drawText(label, posX + (getBounds().width - textExtent.x) / 2, posY + (getBounds().height - textExtent.y) / 2, true);
144 gc.setFont(new Font(oldFont.getName(), pinNameFontHeight, oldFont.getStyle()));
145 for (int i = 0; i < inputSupermodelPins.size(); i++)
147 String pinName = inputSupermodelPins.get(i).name;
148 textExtent = gc.textExtent(pinName);
149 gc.drawText(pinName, posX + pinNameMargin, posY + i * pinDistance + (pinDistance - textExtent.y) / 2, true);
151 for (int i = 0; i < outputSupermodelPins.size(); i++)
153 String pinName = outputSupermodelPins.get(i).name;
154 textExtent = gc.textExtent(pinName);
155 gc.drawText(pinName, posX + width - textExtent.x - pinNameMargin, posY + i * pinDistance + (pinDistance - textExtent.y) / 2,
162 protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
164 gc.drawRectangle(getBounds());
168 public SubmodelComponentParams calculateParams()
170 SubmodelComponentParams ret = super.calculateParams();
171 ret.type = SimpleRectangularSubmodelComponent.class.getSimpleName();
172 Map<String, Object> m = new TreeMap<>();
173 m.put(kLabel, label);
174 m.put(kInCount, inputSupermodelPins.size());
175 m.put(kOutCount, outputSupermodelPins.size());
176 m.put(kLogicWidth, logicWidth);
182 protected Pin addSubmodelInterface(String name, int logicWidth, double relX, double relY)
184 throw new UnsupportedOperationException(
185 "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
189 protected void removeSubmodelInterface(Pin supermodelPin)
191 throw new UnsupportedOperationException(
192 "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
196 protected void setSize(double width, double height)
198 throw new UnsupportedOperationException(
199 "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");