1 package net.mograsim.logic.ui.model.components;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.HashSet;
9 import java.util.TreeMap;
11 import org.eclipse.swt.graphics.Color;
13 import net.haspamelodica.swt.helper.gcs.GeneralGC;
14 import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
15 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
16 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
17 import net.mograsim.logic.ui.model.ViewModelModifiable;
18 import net.mograsim.logic.ui.model.wires.MovablePin;
19 import net.mograsim.logic.ui.model.wires.Pin;
20 import net.mograsim.preferences.Preferences;
22 public class SimpleRectangularSubmodelComponent extends SubmodelComponent
24 public static String kLabel = "label", kInCount = "input_count", kOutCount = "output_count", kLogicWidth = "logic_width";
26 private static final double width = 35;
27 private static final double pinDistance = 10;
28 private static final double pinNameMargin = .5;
29 private static final double labelFontHeight = 5;
30 private static final double pinNameFontHeight = 3.5;
32 private final String label;
33 protected final int logicWidth;
35 private final List<String> inputPinNames;
36 private final List<String> inputPinNamesUnmodifiable;
37 private final List<String> outputPinNames;
38 private final List<String> outputPinNamesUnmodifiable;
40 protected SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
44 this.logicWidth = logicWidth;
45 this.inputPinNames = new ArrayList<>();
46 this.inputPinNamesUnmodifiable = Collections.unmodifiableList(inputPinNames);
47 this.outputPinNames = new ArrayList<>();
48 this.outputPinNamesUnmodifiable = Collections.unmodifiableList(outputPinNames);
51 protected void setInputPins(String... pinNames)
53 setIOPins(0, inputPinNames, outputPinNames, pinNames);
56 protected void setOutputPins(String... pinNames)
58 setIOPins(width, outputPinNames, inputPinNames, pinNames);
61 private void setIOPins(double relX, List<String> pinNamesListThisSide, List<String> pinNamesListOtherSide, String... newPinNames)
63 int inputCount = newPinNames.length;
64 List<String> newPinNamesList = Arrays.asList(newPinNames);
65 if (new HashSet<>(newPinNamesList).size() != inputCount)
66 throw new IllegalArgumentException("Pin names contain duplicates");
67 for (String pinName : newPinNamesList)
68 if (pinNamesListOtherSide.contains(pinName))
69 throw new IllegalArgumentException("Can't add pin. There is a pin on the other side with the same name: " + pinName);
70 super.setSize(width, Math.max(inputCount, pinNamesListOtherSide.size()) * pinDistance);
71 for (int i = 0; i < inputCount; i++)
73 String pinName = newPinNames[i];
74 int oldPinIndex = pinNamesListThisSide.indexOf(pinName);
75 if (oldPinIndex == -1)
76 super.addSubmodelInterface(new MovablePin(this, pinName, logicWidth, relX, pinDistance / 2 + i * pinDistance));
78 getSupermodelMovablePin(pinName).setRelPos(relX, pinDistance / 2 + i * pinDistance);
80 for (String pinName : pinNamesListThisSide)
81 if (!newPinNamesList.contains(pinName))
82 super.removeSubmodelInterface(pinName);
83 pinNamesListThisSide.clear();
84 pinNamesListThisSide.addAll(newPinNamesList);
87 public List<String> getInputPinNames()
89 return inputPinNamesUnmodifiable;
92 public List<String> getOutputPinNames()
94 return outputPinNamesUnmodifiable;
98 protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
100 Font oldFont = gc.getFont();
101 gc.setFont(new Font(oldFont.getName(), labelFontHeight, oldFont.getStyle()));
102 Point textExtent = gc.textExtent(label);
103 Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
104 if (textColor != null)
105 gc.setForeground(textColor);
106 gc.drawText(label, getPosX() + (getWidth() - textExtent.x) / 2, getPosY() + (getHeight() - textExtent.y) / 2, true);
107 gc.setFont(new Font(oldFont.getName(), pinNameFontHeight, oldFont.getStyle()));
108 for (int i = 0; i < inputPinNames.size(); i++)
110 String pinName = inputPinNames.get(i);
111 textExtent = gc.textExtent(pinName);
112 gc.drawText(pinName, getPosX() + pinNameMargin, getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true);
114 for (int i = 0; i < outputPinNames.size(); i++)
116 String pinName = outputPinNames.get(i);
117 textExtent = gc.textExtent(pinName);
118 gc.drawText(pinName, getPosX() + width - textExtent.x - pinNameMargin,
119 getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true);
125 protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
127 Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
128 if (foreground != null)
129 gc.setForeground(foreground);
130 gc.drawRectangle(getBounds());
134 public SubmodelComponentParams calculateParams()
136 SubmodelComponentParams ret = super.calculateParams();
137 ret.type = SimpleRectangularSubmodelComponent.class.getSimpleName();
138 Map<String, Object> m = new TreeMap<>();
139 m.put(kLabel, label);
140 m.put(kInCount, inputPinNames.toArray());
141 m.put(kOutCount, outputPinNames.toArray());
142 m.put(kLogicWidth, logicWidth);
148 protected Pin addSubmodelInterface(MovablePin supermodelPin)
150 throw new UnsupportedOperationException(
151 "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
155 protected void removeSubmodelInterface(String name)
157 throw new UnsupportedOperationException(
158 "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
162 protected void setSize(double width, double height)
164 throw new UnsupportedOperationException(
165 "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");