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.SyncAccess; 9 import de.neemann.digital.core.element.Element; 10 import de.neemann.digital.core.element.ElementAttributes; 11 import de.neemann.digital.core.element.PinDescriptions; 12 import de.neemann.digital.core.io.Button; 13 import de.neemann.digital.draw.elements.IOState; 14 import de.neemann.digital.draw.elements.Pin; 15 import de.neemann.digital.draw.elements.Pins; 16 import de.neemann.digital.draw.graphics.*; 17 import de.neemann.digital.draw.graphics.Polygon; 18 import de.neemann.digital.gui.components.CircuitComponent; 19 20 import java.awt.*; 21 22 import static de.neemann.digital.draw.shapes.OutputShape.OUT_SIZE; 23 24 /** 25 * The Button shape 26 */ 27 public class ButtonShape implements Shape { 28 29 protected static final int HEIGHT = OUT_SIZE / 2; 30 31 private final String label; 32 private final PinDescriptions outputs; 33 private Button button; 34 35 /** 36 * Creates a new instance 37 * 38 * @param attr the attributes 39 * @param inputs the inputs 40 * @param outputs the outputs 41 */ ButtonShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs)42 public ButtonShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs) { 43 this.outputs = outputs; 44 this.label = attr.getLabel(); 45 } 46 47 @Override getPins()48 public Pins getPins() { 49 return new Pins().add(new Pin(new Vector(0, 0), outputs.get(0))); 50 } 51 52 @Override applyStateMonitor(IOState ioState)53 public InteractorInterface applyStateMonitor(IOState ioState) { 54 this.button = (Button) ioState.getElement(); 55 return new InteractorInterface() { 56 @Override 57 public void clicked(CircuitComponent cc, Point pos, IOState ioState, Element element, SyncAccess modelSync) { 58 } 59 60 @Override 61 public void pressed(CircuitComponent cc, Point pos, IOState ioState, Element element, SyncAccess modelSync) { 62 modelSync.modify(() -> button.setPressed(true)); 63 } 64 65 @Override 66 public void released(CircuitComponent cc, Point pos, IOState ioState, Element element, SyncAccess modelSync) { 67 modelSync.modify(() -> button.setPressed(false)); 68 } 69 70 @Override 71 public void dragged(CircuitComponent cc, Point posOnScreen, Vector pos, Transform trans, IOState ioState, Element element, SyncAccess modelSync) { 72 } 73 }; 74 } 75 76 @Override 77 public void drawTo(Graphic graphic, Style heighLight) { 78 boolean isPressed = false; 79 if (button != null) isPressed = button.isPressed(); 80 81 if (isPressed) { 82 graphic.drawPolygon(new Polygon(true) 83 .add(-OUT_SIZE * 2 - 1, -OUT_SIZE) 84 .add(-1, -OUT_SIZE) 85 .add(-1, OUT_SIZE) 86 .add(-OUT_SIZE * 2 - 1, OUT_SIZE), Style.NORMAL); 87 } else { 88 int t = Style.NORMAL.getThickness() / 4; 89 graphic.drawPolygon(new Polygon(true) 90 .add(-OUT_SIZE * 2 - 1 - HEIGHT, -OUT_SIZE - HEIGHT) 91 .add(-1 - HEIGHT, -OUT_SIZE - HEIGHT) 92 .add(-1, -OUT_SIZE) 93 .add(-1, OUT_SIZE) 94 .add(-OUT_SIZE * 2 - 1, OUT_SIZE) 95 .add(-OUT_SIZE * 2 - 1 - HEIGHT, OUT_SIZE - HEIGHT), Style.NORMAL); 96 graphic.drawPolygon(new Polygon(false) 97 .add(-1 - HEIGHT, -OUT_SIZE + t - HEIGHT) 98 .add(-1 - HEIGHT, OUT_SIZE - HEIGHT) 99 .add(t - OUT_SIZE * 2 - 1 - HEIGHT, OUT_SIZE - HEIGHT), Style.NORMAL); 100 graphic.drawLine(new Vector(-1 - HEIGHT, OUT_SIZE - HEIGHT), new Vector(-1 - t, OUT_SIZE - t), Style.NORMAL); 101 } 102 103 Vector textPos = new Vector(-OUT_SIZE * 3, -4); 104 graphic.drawText(textPos, label, Orientation.RIGHTCENTER, Style.NORMAL); 105 } 106 } 107