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