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