9db2df662480bce5860f79ddad80a669ee6f71ca
[Mograsim.git] / era.mi / src / era / mi / logic / tests / GUITest.java
1 package era.mi.logic.tests;
2
3 import java.awt.Color;
4 import java.awt.Graphics;
5 import java.awt.Graphics2D;
6 import java.awt.Rectangle;
7 import java.awt.RenderingHints;
8 import java.awt.event.MouseEvent;
9 import java.awt.event.MouseListener;
10 import java.util.HashMap;
11 import java.util.Map;
12 import java.util.Map.Entry;
13
14 import javax.swing.JFrame;
15 import javax.swing.JPanel;
16 import javax.swing.WindowConstants;
17
18 import era.mi.logic.Simulation;
19 import era.mi.logic.components.ManualSwitch;
20 import era.mi.logic.components.gates.NotGate;
21 import era.mi.logic.components.gates.OrGate;
22 import era.mi.logic.timeline.Timeline.ExecutionResult;
23 import era.mi.logic.wires.WireArray;
24
25 public class GUITest extends JPanel
26 {
27
28         private static final long serialVersionUID = 1L;
29
30         private static final int WIRE_DELAY = 40;
31         private static final int OR_DELAY = 100;
32         private static final int NOT_DELAY = 100;
33
34         WireArray r = new WireArray(1, WIRE_DELAY);
35         WireArray s = new WireArray(1, WIRE_DELAY);
36         WireArray t1 = new WireArray(1, WIRE_DELAY);
37         WireArray t2 = new WireArray(1, WIRE_DELAY);
38         WireArray q = new WireArray(1, WIRE_DELAY);
39         WireArray nq = new WireArray(1, WIRE_DELAY);
40
41         ManualSwitch rIn = new ManualSwitch(r);
42         ManualSwitch sIn = new ManualSwitch(s);
43
44         OrGate or1 = new OrGate(OR_DELAY, t2, r, nq);
45         OrGate or2 = new OrGate(OR_DELAY, t1, s, q);
46         NotGate not1 = new NotGate(NOT_DELAY, t2, q);
47         NotGate not2 = new NotGate(NOT_DELAY, t1, nq);
48
49         Map<ManualSwitch, Rectangle> switchMap = new HashMap<>();
50
51         int height;
52         int width;
53         boolean sizeChanged;
54
55         public GUITest()
56         {
57                 addMouseListener(new MouseListener()
58                 {
59
60                         @Override
61                         public void mouseReleased(MouseEvent e)
62                         {
63                                 for (Entry<ManualSwitch, Rectangle> dim : switchMap.entrySet())
64                                 {
65                                         if (dim.getValue().contains(e.getPoint()))
66                                         {
67                                                 dim.getKey().switchOff();
68                                                 repaint();
69                                         }
70                                 }
71                         }
72
73                         @Override
74                         public void mousePressed(MouseEvent e)
75                         {
76                                 for (Entry<ManualSwitch, Rectangle> dim : switchMap.entrySet())
77                                 {
78                                         if (dim.getValue().contains(e.getPoint()))
79                                         {
80                                                 dim.getKey().switchOn();
81                                                 repaint();
82                                         }
83                                 }
84                         }
85
86                         @Override
87                         public void mouseExited(MouseEvent e)
88                         {
89                                 // none
90                         }
91
92                         @Override
93                         public void mouseEntered(MouseEvent e)
94                         {
95                                 // none
96                         }
97
98                         @Override
99                         public void mouseClicked(MouseEvent e)
100                         {
101                                 // If you want toggle buttons, use this code instead
102 //                              for (Entry<ManualSwitch, Rectangle> dim : switchMap.entrySet()) {
103 //                                      if (dim.getValue().contains(e.getPoint())) {
104 //                                              dim.getKey().toggle();
105 //                                              repaint();
106 //                                      }
107 //                              }
108                         }
109                 });
110         }
111
112         @Override
113         public void paint(Graphics some_g)
114         {
115                 super.paint(some_g);
116                 Graphics2D g = ((Graphics2D) some_g);
117                 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
118                 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
119                 g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
120
121                 checkSizeChange();
122                 adaptFont(g);
123
124                 drawWire(g, r, "r", 2, 9, 4, 9);
125
126                 drawWire(g, s, "s", 2, 3, 4, 3);
127
128                 drawWire(g, t2, "t2", 5, 8.5, 6, 8.5);
129
130                 drawWire(g, t1, "t1", 5, 3.5, 6, 3.5);
131
132                 drawWire(g, q, "q", 7, 8.5, 9, 8.5);
133
134                 drawWire(g, nq, "nq", 7, 3.5, 9, 3.5);
135
136                 drawWire(g, q, "", 7.5, 8.5, 7.5, 7.5);
137                 drawWire(g, q, "", 7.5, 7.5, 3, 4.5);
138                 drawWire(g, q, "", 3, 4.5, 3, 4);
139                 drawWire(g, q, "q", 3, 4, 4, 4);
140
141                 drawWire(g, nq, "", 7.5, 3.5, 7.5, 4.5);
142                 drawWire(g, nq, "", 7.5, 4.5, 3, 7.5);
143                 drawWire(g, nq, "", 3, 7.5, 3, 8);
144                 drawWire(g, nq, "nq", 3, 8, 4, 8);
145
146                 drawSquare(g, 4, 8, "OR");
147                 drawSquare(g, 4, 3, "OR");
148
149                 drawSquare(g, 6, 8, "NOT");
150                 drawSquare(g, 6, 3, "NOT");
151
152                 drawSwitch(g, rIn, "Switch R", 0.5, 8.25, 2, 9.75);
153                 drawSwitch(g, sIn, "Switch S", 0.5, 2.25, 2, 3.75);
154
155                 drawString(g, "Hint: drag the cursor out of the pressed switch to keep it's state", 5, 0, 0.0, 1.0);
156         }
157
158         private void checkSizeChange()
159         {
160                 sizeChanged = height != getHeight() || width != getWidth();
161                 if (sizeChanged)
162                 {
163                         height = getHeight();
164                         width = getWidth();
165                 }
166         }
167
168         private void adaptFont(Graphics g)
169         {
170                 g.setFont(g.getFont().deriveFont(Math.min(height, width) / 40f));
171         }
172
173         private void drawString(Graphics g, String s, int x, int y, double anchorX, double anchorY)
174         {
175                 int h = g.getFontMetrics().getAscent();
176                 int w = g.getFontMetrics().stringWidth(s);
177                 g.drawString(s, x - (int) (w * anchorX), y + (int) (h * anchorY));
178         }
179
180         private void drawWire(Graphics g, WireArray wa, String name, double x1, double y1, double x2, double y2)
181         {
182                 setTo(g, wa);
183                 g.drawLine(gX(x1), gY(y1), gX(x2), gY(y2));
184                 drawString(g, name, (gX(x1) + gX(x2)) / 2, (gY(y1) + gY(y2)) / 2 - 5, 0, 0);
185         }
186
187         private void drawSquare(Graphics g, int posX, int posY, String text)
188         {
189                 int x1 = gX(posX) - 5;
190                 int x2 = gX(posX + 1) + 5;
191                 int y1 = gY(posY) - 5;
192                 int y2 = gY(posY + 1) + 5;
193
194                 g.setColor(Color.WHITE);
195                 g.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
196                 setBlack(g);
197                 g.drawRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
198                 drawString(g, text, (x1 + x2) / 2, (y1 + y2) / 2, 0.5, 0.5);
199
200         }
201
202         private void drawSwitch(Graphics g, ManualSwitch ms, String text, double posX1, double posY1, double posX2, double posY2)
203         {
204                 int x1 = gX(posX1) - 5;
205                 int x2 = gX(posX2) + 5;
206                 int y1 = gY(posY1) - 5;
207                 int y2 = gY(posY2) + 5;
208
209                 if (sizeChanged)
210                 {
211                         Rectangle r = new Rectangle(x1, y1, x2 - x1, y2 - y1);
212                         switchMap.put(ms, r);
213                 }
214
215                 g.setColor(ms.isOn() ? Color.getHSBColor(.3f, .5f, 1f) : Color.WHITE);
216                 g.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
217                 setBlack(g);
218                 g.drawRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
219                 drawString(g, text, (x1 + x2) / 2, (y1 + y2) / 2, 0.5, 0.5);
220         }
221
222         private static void setBlack(Graphics g)
223         {
224                 g.setColor(Color.BLACK);
225         }
226
227         private static void setTo(Graphics g, WireArray wa)
228         {
229                 switch (wa.getValue())
230                 {
231                 case ONE:
232                         g.setColor(Color.GREEN);
233                         break;
234                 case X:
235                         g.setColor(Color.RED);
236                         break;
237                 case Z:
238                         g.setColor(Color.DARK_GRAY);
239                         break;
240                 case ZERO:
241                         g.setColor(Color.BLACK);
242                         break;
243                 case U:
244                         g.setColor(Color.MAGENTA);
245                         break;
246                 default:
247                         throw new IllegalArgumentException();
248                 }
249         }
250
251         private int gY(double pos)
252         {
253                 return (int) (pos * height / 11);
254         }
255
256         private int gX(double pos)
257         {
258                 return (int) (pos * width / 11) + 50;
259         }
260
261         public static void main(String[] args)
262         {
263                 JFrame f = new JFrame("Test circuit 1.0.0");
264                 GUITest gt = new GUITest();
265                 f.add(gt);
266                 f.setSize(800, 600);
267                 f.setLocation(500, 400);
268                 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
269                 f.setVisible(true);
270
271                 long begin = System.currentTimeMillis();
272
273                 long lastFrame = begin;
274                 long updateT = 16;
275
276                 while (f.isVisible())
277                 {
278                         ExecutionResult er = Simulation.TIMELINE.executeUpTo((lastFrame - begin) * 3, lastFrame + 14);
279 //                              if (Simulation.TIMELINE.hasNext()) 
280 //                              Simulation.TIMELINE.executeNext();
281                         if (er != ExecutionResult.NOTHING_DONE)
282                                 gt.repaint(12);
283                         try
284                         {
285                                 Thread.sleep(Math.max(updateT - System.currentTimeMillis() + lastFrame, 0));
286                         }
287                         catch (Exception e)
288                         {
289                                 e.printStackTrace();
290                         }
291                         lastFrame = System.currentTimeMillis();
292                 }
293         }
294 }