1 package net.mograsim.logic.ui.model.components;
3 import java.util.Collections;
4 import java.util.HashMap;
6 import java.util.Map.Entry;
8 import net.haspamelodica.swt.helper.gcs.GCDefaultConfig;
9 import net.haspamelodica.swt.helper.gcs.GeneralGC;
10 import net.haspamelodica.swt.helper.gcs.TranslatedGC;
11 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
12 import net.mograsim.logic.ui.LogicUIRenderer;
13 import net.mograsim.logic.ui.model.ViewModel;
14 import net.mograsim.logic.ui.model.ViewModelModifiable;
15 import net.mograsim.logic.ui.model.wires.Pin;
17 public class SubmodelComponent extends GUIComponent
19 protected final ViewModelModifiable submodelModifiable;
20 public final ViewModel submodel;
21 private final Map<PinMovable, PinMovable> submodelPinsPerSupermodelPin;
22 private final Map<Pin, Pin> submodelPinsPerSupermodelPinUnmodifiable;
23 private final Map<PinMovable, PinMovable> supermodelPinsPerSubmodelPin;
24 private final Map<Pin, Pin> supermodelPinsPerSubmodelPinUnmodifiable;
25 private final SubmodelInterface submodelInterface;
27 private double submodelScale;
28 private final LogicUIRenderer renderer;
30 public SubmodelComponent(ViewModelModifiable model)
33 this.submodelModifiable = new ViewModelModifiable();
34 this.submodel = submodelModifiable;
35 this.submodelPinsPerSupermodelPin = new HashMap<>();
36 this.submodelPinsPerSupermodelPinUnmodifiable = Collections.unmodifiableMap(submodelPinsPerSupermodelPin);
37 this.supermodelPinsPerSubmodelPin = new HashMap<>();
38 this.supermodelPinsPerSubmodelPinUnmodifiable = Collections.unmodifiableMap(supermodelPinsPerSubmodelPin);
39 this.submodelInterface = new SubmodelInterface(submodelModifiable);
41 this.submodelScale = 1;
42 this.renderer = new LogicUIRenderer(submodelModifiable);
44 submodelModifiable.addRedrawListener(this::requestRedraw);
47 protected void setSubmodelScale(double submodelScale)
49 this.submodelScale = submodelScale;
51 for (Entry<PinMovable, PinMovable> e : supermodelPinsPerSubmodelPin.entrySet())
52 e.getKey().setRelPos(e.getValue().getRelX() * submodelScale, e.getValue().getRelY() * submodelScale);
54 requestRedraw();// needed if there is no submodel interface pin
58 * Returns the submodel pin.
60 protected Pin addSubmodelInterface(int logicWidth, double relX, double relY)
62 PinMovable submodelPin = new PinMovable(submodelInterface, logicWidth, relX / submodelScale, relY / submodelScale);
63 submodelInterface.addPin(submodelPin);
65 PinMovable supermodelPin = new PinMovable(this, logicWidth, relX, relY);
66 addPin(supermodelPin);
68 submodelPinsPerSupermodelPin.put(supermodelPin, submodelPin);
69 supermodelPinsPerSubmodelPin.put(submodelPin, supermodelPin);
71 // no need to call requestRedraw() because addPin() will request a redraw
75 protected void moveSubmodelInterface(Pin supermodelPin, double relX, double relY)
77 PinMovable submodelPin = getSubmodelMovablePin(supermodelPin);
78 PinMovable supermodelPinMovable = getSupermodelMovablePin(submodelPin);
80 submodelPin.setRelPos(relX / submodelScale, relY / submodelScale);
81 supermodelPinMovable.setRelPos(relX, relY);
83 // no need to call requestRedraw() because setRelPos() will request a redraw
86 protected void removeSubmodelInterface(Pin supermodelPin)
88 removePin(supermodelPin);
89 Pin submodelPin = getSubmodelMovablePin(supermodelPin);
90 submodelInterface.removePin(submodelPin);
92 submodelPinsPerSupermodelPin.remove(supermodelPin);
93 supermodelPinsPerSubmodelPin.remove(submodelPin);
95 // no need to call requestRedraw() because removePin() will request a redraw
98 public Map<Pin, Pin> getSupermodelPinsPerSubmodelPin()
100 return supermodelPinsPerSubmodelPinUnmodifiable;
103 public Pin getSupermodelPin(Pin submodelPin)
105 return getSupermodelMovablePin(submodelPin);
108 protected PinMovable getSupermodelMovablePin(Pin submodelPin)
110 return supermodelPinsPerSubmodelPin.get(submodelPin);
113 public Map<Pin, Pin> getSubmodelPinsPerSupermodelPin()
115 return submodelPinsPerSupermodelPinUnmodifiable;
118 public Pin getSubmodelPin(Pin supermodelPin)
120 return getSubmodelMovablePin(supermodelPin);
123 protected PinMovable getSubmodelMovablePin(Pin supermodelPin)
125 return submodelPinsPerSupermodelPin.get(supermodelPin);
129 public void render(GeneralGC gc, Rectangle visibleRegion)
131 double posX = getBounds().x;
132 double posY = getBounds().y;
134 GCDefaultConfig conf = new GCDefaultConfig(gc);
135 TranslatedGC tgc = new TranslatedGC(gc, posX, posY, submodelScale, true);
137 renderer.render(tgc, visibleRegion.translate(posX, posY, submodelScale));
139 // draw the "bounding box" after all other operations to make interface pins look better
140 gc.drawRectangle(getBounds());
143 private static class PinMovable extends Pin
145 public PinMovable(GUIComponent component, int logicWidth, double relX, double relY)
147 super(component, logicWidth, relX, relY);
151 protected void setRelPos(double relX, double relY)
153 super.setRelPos(relX, relY);