Implemented GUIAm2901DestDecode
[Mograsim.git] / net.mograsim.logic.ui / src / net / mograsim / logic / ui / model / components / SimpleRectangularSubmodelComponent.java
1 package net.mograsim.logic.ui.model.components;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Iterator;
6 import java.util.List;
7
8 import net.haspamelodica.swt.helper.gcs.GeneralGC;
9 import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
10 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
11 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
12 import net.mograsim.logic.ui.model.ViewModelModifiable;
13 import net.mograsim.logic.ui.model.components.ComponentParams.InnerComponentParams;
14 import net.mograsim.logic.ui.model.components.ComponentParams.InnerPinParams;
15 import net.mograsim.logic.ui.model.components.ComponentParams.InnerWireParams;
16 import net.mograsim.logic.ui.model.wires.GUIWire;
17 import net.mograsim.logic.ui.model.wires.Pin;
18
19 public class SimpleRectangularSubmodelComponent extends SubmodelComponent
20 {
21         private static final double width = 35;
22         private static final double pinDistance = 10;
23         private static final double fontHeight = 5;
24
25         private final String label;
26         protected final int logicWidth;
27
28         private final List<Pin> inputSupermodelPins;
29         private final List<Pin> inputSupermodelPinsUnmodifiable;
30         private final List<Pin> outputSupermodelPins;
31         private final List<Pin> outputSupermodelPinsUnmodifiable;
32         private final List<Pin> inputSubmodelPins;
33         private final List<Pin> inputSubmodelPinsUnmodifiable;
34         private final List<Pin> outputSubmodelPins;
35         private final List<Pin> outputSubmodelPinsUnmodifiable;
36
37         protected SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
38         {
39                 super(model);
40                 this.label = label;
41                 this.logicWidth = logicWidth;
42                 this.inputSupermodelPins = new ArrayList<>();
43                 this.inputSupermodelPinsUnmodifiable = Collections.unmodifiableList(inputSupermodelPins);
44                 this.outputSupermodelPins = new ArrayList<>();
45                 this.outputSupermodelPinsUnmodifiable = Collections.unmodifiableList(outputSupermodelPins);
46                 this.inputSubmodelPins = new ArrayList<>();
47                 this.inputSubmodelPinsUnmodifiable = Collections.unmodifiableList(inputSubmodelPins);
48                 this.outputSubmodelPins = new ArrayList<>();
49                 this.outputSubmodelPinsUnmodifiable = Collections.unmodifiableList(outputSubmodelPins);
50         }
51
52         protected void setInputCount(int inputCount)
53         {
54                 int oldInputCount = inputSupermodelPins.size();
55                 double height = Math.max(inputCount, outputSupermodelPins.size()) * pinDistance;
56                 setSize(width, height);
57                 if (oldInputCount > inputCount)
58                         while (inputSupermodelPins.size() > inputCount)
59                         {
60                                 inputSubmodelPins.remove(inputCount);
61                                 removePin(inputSupermodelPins.remove(inputCount));
62                         }
63                 else if (oldInputCount < inputCount)
64                         for (int i = oldInputCount; i < inputCount; i++)
65                         {
66                                 Pin submodelPin = addSubmodelInterface(logicWidth, 0, pinDistance / 2 + i * pinDistance);
67                                 inputSubmodelPins.add(submodelPin);
68                                 inputSupermodelPins.add(getSupermodelPin(submodelPin));
69                         }
70         }
71
72         protected void setOutputCount(int outputCount)
73         {
74                 int oldOutputCount = outputSupermodelPins.size();
75                 setSize(width, Math.max(inputSupermodelPins.size(), outputCount) * pinDistance);
76                 if (oldOutputCount > outputCount)
77                         while (outputSupermodelPins.size() > outputCount)
78                         {
79                                 outputSubmodelPins.remove(outputCount);
80                                 removePin(outputSupermodelPins.get(outputCount));
81                         }
82                 else if (oldOutputCount < outputCount)
83                         for (int i = oldOutputCount; i < outputCount; i++)
84                         {
85                                 Pin submodelPin = addSubmodelInterface(logicWidth, width, pinDistance / 2 + i * pinDistance);
86                                 outputSubmodelPins.add(submodelPin);
87                                 outputSupermodelPins.add(getSupermodelPin(submodelPin));
88                         }
89         }
90
91         public List<Pin> getInputPins()
92         {
93                 return inputSupermodelPinsUnmodifiable;
94         }
95
96         public List<Pin> getOutputPins()
97         {
98                 return outputSupermodelPinsUnmodifiable;
99         }
100
101         protected List<Pin> getInputSubmodelPins()
102         {
103                 return inputSubmodelPinsUnmodifiable;
104         }
105
106         protected List<Pin> getOutputSubmodelPins()
107         {
108                 return outputSubmodelPinsUnmodifiable;
109         }
110
111         @Override
112         protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
113         {
114                 double posX = getBounds().x;
115                 double posY = getBounds().y;
116
117                 Font oldFont = gc.getFont();
118                 Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
119                 gc.setFont(labelFont);
120                 Point textExtent = gc.textExtent(label);
121                 gc.drawText(label, posX + (getBounds().width - textExtent.x) / 2, posY + (getBounds().height - textExtent.y) / 2, true);
122                 gc.setFont(oldFont);
123         }
124
125         @Override
126         protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
127         {
128                 gc.drawRectangle(getBounds());
129         }
130
131         public ComponentParams calculateParams()
132         {
133                 ComponentParams params = new ComponentParams();
134                 params.displayName = label;
135                 params.inputCount = inputSupermodelPins.size();
136                 params.outputCount = outputSubmodelPins.size();
137                 params.logicWidth = logicWidth;
138                 params.innerScale = getSubmodelScale();
139
140                 List<GUIComponent> compList = submodelModifiable.getComponents();
141                 Iterator<GUIComponent> componentIt = compList.iterator();
142                 componentIt.next(); // Skip inner SubmodelInterface
143                 InnerComponentParams[] comps = new InnerComponentParams[compList.size() - 1];
144                 int i = 0;
145                 while (componentIt.hasNext())
146                 {
147                         GUIComponent component = componentIt.next();
148                         InnerComponentParams inner = new InnerComponentParams();
149                         comps[i] = inner;
150                         inner.logicWidth = component.getPins().get(0).logicWidth; // This could be done a little more elegantly
151                         Rectangle bounds = component.getBounds();
152                         inner.pos = new Point(bounds.x, bounds.y);
153                         if (component instanceof GUICustomComponent)
154                                 inner.type = "file:" + ((GUICustomComponent) component).getPath();
155                         else
156                                 inner.type = "class:" + component.getClass().getCanonicalName();
157                         i++;
158                 }
159                 params.subComps = comps;
160
161                 List<GUIWire> wireList = submodelModifiable.getWires();
162                 InnerWireParams wires[] = new InnerWireParams[wireList.size()];
163                 i = 0;
164                 for (GUIWire wire : wireList)
165                 {
166                         InnerWireParams inner = new InnerWireParams();
167                         wires[i] = inner;
168                         InnerPinParams pin1Params = new InnerPinParams(), pin2Params = new InnerPinParams();
169
170                         pin1Params.pinIndex = wire.getPin1().component.getPins().indexOf(wire.getPin1());
171                         pin1Params.compId = compList.indexOf(wire.getPin1().component);
172                         pin2Params.pinIndex = wire.getPin2().component.getPins().indexOf(wire.getPin2());
173                         pin2Params.compId = compList.indexOf(wire.getPin2().component);
174                         inner.pin1 = pin1Params;
175                         inner.pin2 = pin2Params;
176                         inner.path = wire.getPath();
177                         i++;
178                 }
179                 params.innerWires = wires;
180                 return params;
181         }
182 }