ede871052457666f7fc303d6adad2b15031ff879
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / snippets / symbolrenderers / PinNamesSymbolRenderer.java
1 package net.mograsim.logic.model.snippets.symbolrenderers;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import net.haspamelodica.swt.helper.gcs.GeneralGC;
7 import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
8 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
9 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
10 import net.mograsim.logic.model.model.components.ModelComponent;
11 import net.mograsim.logic.model.model.wires.Pin;
12 import net.mograsim.logic.model.serializing.IdentifyParams;
13 import net.mograsim.logic.model.snippets.Renderer;
14 import net.mograsim.logic.model.snippets.SnippetDefinintion;
15 import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers;
16 import net.mograsim.logic.model.snippets.symbolrenderers.PinNamesSymbolRenderer.PinNamesParams.Position;
17
18 public class PinNamesSymbolRenderer implements Renderer
19 {
20         private final ModelComponent component;
21         private final Map<Pin, Position> pinPositions;
22         private final double pinLabelHeight;
23         private final double pinLabelMargin;
24
25         public PinNamesSymbolRenderer(ModelComponent component, PinNamesParams params)
26         {
27                 this.component = component;
28                 this.pinPositions = new HashMap<>();
29                 this.pinLabelHeight = params.pinLabelHeight;
30                 this.pinLabelMargin = params.pinLabelMargin;
31                 if (params.pinNamePositions != null)
32                         params.pinNamePositions.forEach(this::setPinPosition);
33                 component.addPinRemovedListener(p -> setPinPosition(p, null));
34         }
35
36         public void setPinPosition(String pinName, Position position)
37         {
38                 setPinPosition(component.getPin(pinName), position);
39         }
40
41         public void setPinPosition(Pin pin, Position position)
42         {
43                 if (position == null)
44                         pinPositions.remove(pin);
45                 else
46                         pinPositions.put(pin, position);
47         }
48
49         @Override
50         public void render(GeneralGC gc, Rectangle visibleRegion)
51         {
52                 Font oldFont = gc.getFont();
53                 gc.setFont(new Font(oldFont.getName(), pinLabelHeight, oldFont.getStyle()));
54                 for (Pin pin : component.getPins().values())
55                 {
56                         Position pos = pinPositions.get(pin);
57                         if (pos == null)
58                                 pos = Position.RIGHT;
59
60                         Point topleft = pin.getPos();
61                         Point textExtent = gc.textExtent(pin.name);
62
63                         double x2 = topleft.x - textExtent.x - pinLabelMargin;
64                         double y2 = topleft.y - textExtent.y - pinLabelMargin;
65                         double x1 = topleft.x + pinLabelMargin;
66                         double y1 = topleft.y + pinLabelMargin;
67
68                         double x = pos.posX * x1 + (1 - pos.posX) * x2;
69                         double y = pos.posY * y1 + (1 - pos.posY) * y2;
70
71                         gc.drawText(pin.name, x, y, true);
72                 }
73                 gc.setFont(oldFont);
74         }
75
76         @Override
77         public String getIDForSerializing(IdentifyParams idParams)
78         {
79                 return "pinNames";
80         }
81
82         @Override
83         public PinNamesParams getParamsForSerializing(IdentifyParams idParams)
84         {
85                 PinNamesParams params = new PinNamesParams();
86                 params.pinNamePositions = new HashMap<>();
87                 pinPositions.forEach((pin, pos) -> params.pinNamePositions.put(pin.name, pos));
88                 return params;
89         }
90
91         public static class PinNamesParams
92         {
93                 public Map<String, Position> pinNamePositions;
94                 public double pinLabelHeight;
95                 public double pinLabelMargin;
96
97                 public static enum Position
98                 {
99                         TOP(.5, 0), TOP_LEFT(0, 0), LEFT(0, .5), BOTTOM_LEFT(0, 1), BOTTOM(.5, 1), BOTTOM_RIGHT(1, 1), RIGHT(1, .5), TOP_RIGHT(1, 0);
100
101                         private final double posX, posY;
102
103                         private Position(double posX, double posY)
104                         {
105                                 this.posX = posX;
106                                 this.posY = posY;
107                         }
108                 }
109         }
110
111         static
112         {
113                 SubmodelComponentSnippetSuppliers.symbolRendererSupplier.setSnippetSupplier(PinNamesSymbolRenderer.class.getCanonicalName(),
114                                 SnippetDefinintion.create(PinNamesParams.class, PinNamesSymbolRenderer::new));
115         }
116 }