Merge branch 'development' of https://gitlab.lrz.de/lrr-tum/students/eragp-misim...
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / components / submodels / SimpleRectangularSubmodelComponent.java
1 package net.mograsim.logic.model.model.components.submodels;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.HashSet;
7 import java.util.List;
8
9 import org.eclipse.swt.graphics.Color;
10
11 import net.haspamelodica.swt.helper.gcs.GeneralGC;
12 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
13 import net.mograsim.logic.model.model.ViewModelModifiable;
14 import net.mograsim.logic.model.model.wires.MovablePin;
15 import net.mograsim.logic.model.model.wires.Pin;
16 import net.mograsim.logic.model.snippets.Renderer;
17 import net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer;
18 import net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer.SimpleRectangularLikeParams;
19 import net.mograsim.preferences.Preferences;
20
21 public class SimpleRectangularSubmodelComponent extends SubmodelComponent
22 {
23         public static final double width = 35;
24         public static final double pinDistance = 10;
25         public static final double pinNameMargin = .5;
26         public static final double labelFontHeight = 5;
27         public static final double pinNameFontHeight = 3.5;
28
29         public final String label;
30         protected final int logicWidth;
31
32         private final List<String> inputPinNames;
33         private final List<String> inputPinNamesUnmodifiable;
34         private final List<String> outputPinNames;
35         private final List<String> outputPinNamesUnmodifiable;
36
37         private Renderer symbolRenderer;
38
39         public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
40         {
41                 this(model, logicWidth, label, null);
42         }
43
44         public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label, String name)
45         {
46                 super(model, name);
47                 this.label = label;
48                 this.logicWidth = logicWidth;
49                 this.inputPinNames = new ArrayList<>();
50                 this.inputPinNamesUnmodifiable = Collections.unmodifiableList(inputPinNames);
51                 this.outputPinNames = new ArrayList<>();
52                 this.outputPinNamesUnmodifiable = Collections.unmodifiableList(outputPinNames);
53
54                 SimpleRectangularLikeParams rendererParams = new SimpleRectangularLikeParams();
55                 rendererParams.centerText = label;
56                 rendererParams.centerTextHeight = labelFontHeight;
57                 rendererParams.horizontalComponentCenter = getWidth() / 2;
58                 rendererParams.pinLabelHeight = pinNameFontHeight;
59                 rendererParams.pinLabelMargin = pinNameMargin;
60                 symbolRenderer = new SimpleRectangularLikeSymbolRenderer(this, rendererParams);
61         }
62
63         protected void setInputPins(String... pinNames)
64         {
65                 setIOPins(0, inputPinNames, outputPinNames, pinNames);
66         }
67
68         protected void setOutputPins(String... pinNames)
69         {
70                 setIOPins(width, outputPinNames, inputPinNames, pinNames);
71         }
72
73         private void setIOPins(double relX, List<String> pinNamesListThisSide, List<String> pinNamesListOtherSide, String... newPinNames)
74         {
75                 int inputCount = newPinNames.length;
76                 List<String> newPinNamesList = Arrays.asList(newPinNames);
77                 if (new HashSet<>(newPinNamesList).size() != inputCount)
78                         throw new IllegalArgumentException("Pin names contain duplicates");
79                 for (String pinName : newPinNamesList)
80                         if (pinNamesListOtherSide.contains(pinName))
81                                 throw new IllegalArgumentException("Can't add pin. There is a pin on the other side with the same name: " + pinName);
82                 super.setSize(width, Math.max(inputCount, pinNamesListOtherSide.size()) * pinDistance);
83                 for (int i = 0; i < inputCount; i++)
84                 {
85                         String pinName = newPinNames[i];
86                         int oldPinIndex = pinNamesListThisSide.indexOf(pinName);
87                         if (oldPinIndex == -1)
88                                 super.addSubmodelInterface(new MovablePin(this, pinName, logicWidth, relX, pinDistance / 2 + i * pinDistance));
89                         else
90                                 getSupermodelMovablePin(pinName).setRelPos(relX, pinDistance / 2 + i * pinDistance);
91                 }
92                 for (String pinName : pinNamesListThisSide)
93                         if (!newPinNamesList.contains(pinName))
94                                 super.removeSubmodelInterface(pinName);
95                 pinNamesListThisSide.clear();
96                 pinNamesListThisSide.addAll(newPinNamesList);
97         }
98
99         public List<String> getInputPinNames()
100         {
101                 return inputPinNamesUnmodifiable;
102         }
103
104         public List<String> getOutputPinNames()
105         {
106                 return outputPinNamesUnmodifiable;
107         }
108
109         @Override
110         protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
111         {
112                 symbolRenderer.render(gc, visibleRegion);
113         }
114
115         @Override
116         protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
117         {
118                 Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
119                 if (foreground != null)
120                         gc.setForeground(foreground);
121                 gc.drawRectangle(getBounds());
122         }
123
124         @Override
125         protected Pin addSubmodelInterface(MovablePin supermodelPin)
126         {
127                 throw new UnsupportedOperationException(
128                                 "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
129         }
130
131         @Override
132         protected void removeSubmodelInterface(String name)
133         {
134                 throw new UnsupportedOperationException(
135                                 "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
136         }
137
138         @Override
139         protected void setSize(double width, double height)
140         {
141                 throw new UnsupportedOperationException(
142                                 "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
143         }
144 }