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