1 /*
2  * Copyright (c) 2016 Helmut Neemann
3  * Use of this source code is governed by the GPL v3 license
4  * that can be found in the LICENSE file.
5  */
6 package de.neemann.digital.draw.shapes;
7 
8 import de.neemann.digital.core.ObservableValue;
9 import de.neemann.digital.core.SyncAccess;
10 import de.neemann.digital.core.element.Element;
11 import de.neemann.digital.core.element.ElementAttributes;
12 import de.neemann.digital.core.element.Keys;
13 import de.neemann.digital.core.element.PinDescriptions;
14 import de.neemann.digital.draw.elements.IOState;
15 import de.neemann.digital.draw.elements.Pin;
16 import de.neemann.digital.draw.elements.Pins;
17 import de.neemann.digital.draw.graphics.*;
18 import de.neemann.digital.draw.graphics.Polygon;
19 import de.neemann.digital.gui.components.CircuitComponent;
20 
21 import java.awt.*;
22 
23 import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
24 import static de.neemann.digital.draw.shapes.OutputShape.LATEX_RAD;
25 import static de.neemann.digital.draw.shapes.OutputShape.OUT_SIZE;
26 
27 /**
28  * The Clock shape
29  */
30 public class ClockShape implements Shape {
31     private static final int WI = OUT_SIZE / 3;
32 
33     private final String label;
34     private final PinDescriptions outputs;
35 
36     /**
37      * Creates a new instance
38      *
39      * @param attr    the attributes
40      * @param inputs  the inputs
41      * @param outputs the outputs
42      */
ClockShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs)43     public ClockShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs) {
44         this.outputs = outputs;
45         String pinNumber = attr.get(Keys.PINNUMBER);
46         if (pinNumber.length() == 0)
47             this.label = attr.getLabel();
48         else
49             this.label = attr.getLabel() + " (" + pinNumber + ")";
50     }
51 
52     @Override
getPins()53     public Pins getPins() {
54         return new Pins().add(new Pin(new Vector(0, 0), outputs.get(0)));
55     }
56 
57     @Override
applyStateMonitor(IOState ioState)58     public Interactor applyStateMonitor(IOState ioState) {
59         return new Interactor() {
60             @Override
61             public void clicked(CircuitComponent cc, Point pos, IOState ioState, Element element, SyncAccess modelSync) {
62                 ObservableValue value = ioState.getOutput(0);
63                 if (value.getBits() == 1)
64                     modelSync.modify(() -> value.setValue(1 - value.getValue()));
65             }
66         };
67     }
68 
69     @Override
70     public void drawTo(Graphic graphic, Style heighLight) {
71         Vector wavePos;
72         if (graphic.isFlagSet(Graphic.Flag.smallIO)) {
73             Vector center = new Vector(-LATEX_RAD.x, 0);
74             graphic.drawCircle(center.sub(LATEX_RAD), center.add(LATEX_RAD), Style.NORMAL);
75             Vector textPos = new Vector(-SIZE2 - LATEX_RAD.x, 0);
76             graphic.drawText(textPos, label, Orientation.RIGHTCENTER, Style.INOUT);
77             wavePos = center.sub(new Vector(2 * WI, LATEX_RAD.y + WI + 1));
78         } else {
79             graphic.drawPolygon(new Polygon(true)
80                     .add(-OUT_SIZE * 2 - 1, -OUT_SIZE)
81                     .add(-1, -OUT_SIZE)
82                     .add(-1, OUT_SIZE)
83                     .add(-OUT_SIZE * 2 - 1, OUT_SIZE), Style.NORMAL);
84 
85             Vector textPos = new Vector(-OUT_SIZE * 3, 0);
86             graphic.drawText(textPos, label, Orientation.RIGHTCENTER, Style.NORMAL);
87             wavePos = new Vector(-OUT_SIZE - WI * 2, WI);
88         }
89         graphic.drawPolygon(new Polygon(false)
90                 .add(wavePos)
91                 .add(wavePos.add(WI, 0))
92                 .add(wavePos.add(WI, -WI * 2))
93                 .add(wavePos.add(2 * WI, -WI * 2))
94                 .add(wavePos.add(2 * WI, 0))
95                 .add(wavePos.add(3 * WI, 0))
96                 .add(wavePos.add(3 * WI, -WI * 2))
97                 .add(wavePos.add(4 * WI, -WI * 2)), Style.THIN);
98     }
99 }
100