Renamed ChangedListeners to LookChangedListeners
[Mograsim.git] / LogicUI / src / era / mi / gui / LogicUICanvas.java
1 package era.mi.gui;\r
2 \r
3 import java.util.function.Consumer;\r
4 \r
5 import org.eclipse.swt.SWT;\r
6 import org.eclipse.swt.widgets.Composite;\r
7 import org.eclipse.swt.widgets.Event;\r
8 \r
9 import era.mi.gui.model.ViewModel;\r
10 import era.mi.gui.model.components.GUIComponent;\r
11 import era.mi.gui.model.wires.Pin;\r
12 import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
13 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
14 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
15 import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas;\r
16 \r
17 /**\r
18  * Simulation visualizer canvas.\r
19  * \r
20  * @author Daniel Kirschten\r
21  */\r
22 public class LogicUICanvas extends ZoomableCanvas\r
23 {\r
24         private final ViewModel model;\r
25 \r
26         public LogicUICanvas(Composite parent, int style, ViewModel model)\r
27         {\r
28                 super(parent, style);\r
29 \r
30                 this.model = model;\r
31 \r
32                 Consumer<Object> redrawConsumer = o -> redrawThreadsafe();\r
33                 Consumer<Pin> pinAddedListener = p ->\r
34                 {\r
35                         p.addPinMovedListener(redrawConsumer);\r
36                         redrawThreadsafe();\r
37                 };\r
38                 Consumer<Pin> pinRemovedListener = p ->\r
39                 {\r
40                         p.removePinMovedListener(redrawConsumer);\r
41                         redrawThreadsafe();\r
42                 };\r
43                 model.addComponentAddedListener(c ->\r
44                 {\r
45                         c.addComponentLookChangedListener(redrawConsumer);\r
46                         c.addComponentMovedListener(redrawConsumer);\r
47                         c.addPinAddedListener(pinAddedListener);\r
48                         c.addPinRemovedListener(pinRemovedListener);\r
49                         redrawThreadsafe();\r
50                 });\r
51                 model.addComponentRemovedListener(c ->\r
52                 {\r
53                         c.removeComponentLookChangedListener(redrawConsumer);\r
54                         c.removeComponentMovedListener(redrawConsumer);\r
55                         c.removePinAddedListener(pinAddedListener);\r
56                         c.removePinRemovedListener(pinRemovedListener);\r
57                         redrawThreadsafe();\r
58                 });\r
59                 model.addWireAddedListener(w ->\r
60                 {\r
61                         w.addWireLookChangedListener(redrawConsumer);\r
62                         redrawThreadsafe();\r
63                 });\r
64                 model.addWireRemovedListener(w ->\r
65                 {\r
66                         w.removeWireLookChangedListener(redrawConsumer);\r
67                         redrawThreadsafe();\r
68                 });\r
69 \r
70                 addZoomedRenderer(gc ->\r
71                 {\r
72                         Rectangle visibleRegion = new Rectangle(offX, offY, gW / zoom, gH / zoom);\r
73                         model.getComponents().forEach(c -> drawComponent(gc, c, visibleRegion));\r
74                 });\r
75                 addZoomedRenderer(gc -> model.getWires().forEach(w -> w.render(gc)));\r
76                 addListener(SWT.MouseDown, this::mouseDown);\r
77         }\r
78 \r
79         private void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion)\r
80         {\r
81                 component.render(gc, visibleRegion);\r
82                 gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_CYAN));\r
83                 for (Pin p : component.getPins())\r
84                 {\r
85                         Point pos = p.getPos();\r
86                         gc.fillOval(pos.x - 1, pos.y - 1, 2, 2);\r
87                 }\r
88         }\r
89 \r
90         private void mouseDown(Event e)\r
91         {\r
92                 if (e.button == 1)\r
93                 {\r
94                         Point click = displayToWorldCoords(e.x, e.y);\r
95                         for (GUIComponent component : model.getComponents())\r
96                                 if (component.getBounds().contains(click) && component.clicked(click.x, click.y))\r
97                                 {\r
98                                         redraw();\r
99                                         break;\r
100                                 }\r
101                 }\r
102         }\r
103 }