Small changes; mainly in the listener system:
[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.addComponentChangedListener(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.removeComponentChangedListener(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(c -> redrawThreadsafe());\r
60                 model.addWireRemovedListener(c -> redrawThreadsafe());\r
61 \r
62                 addZoomedRenderer(gc ->\r
63                 {\r
64                         Rectangle visibleRegion = new Rectangle(offX, offY, gW / zoom, gH / zoom);\r
65                         model.getComponents().forEach(c -> drawComponent(gc, c, visibleRegion));\r
66                 });\r
67                 addZoomedRenderer(gc -> model.getWires().forEach(w -> w.render(gc)));\r
68                 addListener(SWT.MouseDown, this::mouseDown);\r
69         }\r
70 \r
71         private void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion)\r
72         {\r
73                 component.render(gc, visibleRegion);\r
74                 gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_CYAN));\r
75                 for (Pin p : component.getPins())\r
76                 {\r
77                         Point pos = p.getPos();\r
78                         gc.fillOval(pos.x - 1, pos.y - 1, 2, 2);\r
79                 }\r
80         }\r
81 \r
82         private void mouseDown(Event e)\r
83         {\r
84                 if (e.button == 1)\r
85                 {\r
86                         Point click = displayToWorldCoords(e.x, e.y);\r
87                         for (GUIComponent component : model.getComponents())\r
88                                 if (component.getBounds().contains(click) && component.clicked(click.x, click.y))\r
89                                 {\r
90                                         redraw();\r
91                                         break;\r
92                                 }\r
93                 }\r
94         }\r
95 }