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.Value;
10 import de.neemann.digital.core.element.ElementAttributes;
11 import de.neemann.digital.core.element.Keys;
12 import de.neemann.digital.core.element.PinDescriptions;
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 
18 import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
19 
20 /**
21  * The shape to show a sixteen seg display.
22  */
23 public class SixteenShape implements Shape {
24 
25     private static final Polygon[] POLYGONS = new Polygon[]{
26             Polygon.createFromPath("m 12.04,5.0 L 25.41,5.0 30.76,10.61 24.89,16.22 11.52,16.22 6.17,10.61 z"), // 0,
27             Polygon.createFromPath("m 39.43,5.0 L 52.8,5.0 58.15,10.61 52.28,16.22 38.91,16.22 33.56,10.61 z"), // 1,
28             Polygon.createFromPath("m 59.49,12.01 L 64.84,17.62 62.74,62.99 56.87,68.6 51.52,62.99 53.62,17.62 z"), // 2,
29             Polygon.createFromPath("m 56.74,71.4 L 62.09,77.01 60.0,122.38 54.13,127.99 48.78,122.38 50.88,77.01 z"), // 3,
30             Polygon.createFromPath("m 33.94,123.78 L 47.32,123.78 52.67,129.39 46.8,135.0 33.43,135.0 28.08,129.39 z"), // 4,
31             Polygon.createFromPath("m 6.55,123.78 L 19.93,123.78 25.28,129.39 19.41,135.0 6.04,135.0 0.69,129.39 z"), // 5,
32             Polygon.createFromPath("m 1.96,71.4 L 7.31,77.01 5.22,122.38 -0.64,127.99 -5.99,122.38 -3.9,77.01 z"), // 6,
33             Polygon.createFromPath("m 4.7,12.01 L 10.05,17.62 7.96,62.99 2.09,68.6 -3.25,62.99 -1.15,17.62 z"), // 7,
34             Polygon.createFromPath("m 9.29,64.39 L 22.67,64.39 28.02,70.0 22.15,75.61 8.78,75.61 3.43,70.0 z"), // 8,
35             Polygon.createFromPath("m 36.69,64.39 L 50.06,64.39 55.41,70.0 49.54,75.61 36.17,75.61 30.82,70.0 z"), // 9,
36             Polygon.createFromPath("m 12.01,18.2 L 17.06,18.2 22.73,50.48 22.18,62.41 17.13,62.41 11.46,30.13 z"), // 10,
37             Polygon.createFromPath("m 32.09,12.01 L 37.44,17.62 35.35,62.99 29.48,68.6 24.13,62.99 26.23,17.62 z"), // 11,
38             Polygon.createFromPath("m 46.56,18.2 L 51.61,18.2 51.06,30.13 42.41,62.41 37.36,62.41 37.91,50.48 z"), // 12,
39             Polygon.createFromPath("m 36.66,77.59 L 41.7,77.59 47.38,109.87 46.83,121.8 41.78,121.8 36.11,89.52 z"), // 13,
40             Polygon.createFromPath("m 29.35,71.4 L 34.7,77.01 32.61,122.38 26.74,127.99 21.39,122.38 23.49,77.01 z"), // 14,
41             Polygon.createFromPath("m 16.43,77.59 L 21.48,77.59 20.93,89.52 12.27,121.8 7.22,121.8 7.78,109.87 z"), // 15,
42     };
43     private static final Vector DOT = new Vector(58, 127);
44 
45 
46     private static final int HEIGHT = 7;
47 
48     private final Style onStyle;
49     private final Style offStyle;
50     private final PinDescriptions pins;
51     private final int size;
52     private ObservableValue input;
53     private ObservableValue dp;
54     private Value inValue;
55     private Value dpValue;
56 
57     /**
58      * Creates a new instance
59      *
60      * @param attr    the attributes
61      * @param inputs  the shapes inputs
62      * @param outputs the shapes outputs
63      */
SixteenShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs)64     public SixteenShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs) {
65         pins = inputs;
66         onStyle = Style.NORMAL.deriveFillStyle(attr.get(Keys.COLOR));
67         offStyle = Style.NORMAL.deriveFillStyle(ColorKey.GRID);
68         size = attr.get(Keys.SEVEN_SEG_SIZE);
69     }
70 
71     @Override
getPins()72     public Pins getPins() {
73         return new Pins()
74                 .add(new Pin(new Vector(SIZE * 2, SIZE * HEIGHT), pins.get(0)))
75                 .add(new Pin(new Vector(SIZE * 3, SIZE * HEIGHT), pins.get(1)));
76     }
77 
78     @Override
applyStateMonitor(IOState ioState)79     public InteractorInterface applyStateMonitor(IOState ioState) {
80         input = ioState.getInput(0);
81         dp = ioState.getInput(1);
82         return null;
83     }
84 
85     @Override
readObservableValues()86     public void readObservableValues() {
87         if (input != null) {
88             inValue = input.getCopy();
89             dpValue = dp.getCopy();
90         }
91     }
92 
93     @Override
drawTo(Graphic graphic, Style highLight)94     public void drawTo(Graphic graphic, Style highLight) {
95         Transform tr = SevenShape.createTransform(size);
96         graphic.drawPolygon(SevenShape.FRAME.transform(tr), Style.NORMAL);
97 
98         int bits = -1;
99         if (inValue != null)
100             bits = (int) inValue.getValue();
101 
102         int mask = 1;
103         for (Polygon p : POLYGONS) {
104             Style s = onStyle;
105             if ((bits & mask) == 0) s = offStyle;
106             graphic.drawPolygon(p.transform(tr), s);
107             mask <<= 1;
108         }
109 
110         Style s = onStyle;
111         if (dpValue != null && !dpValue.getBool()) s = offStyle;
112         graphic.drawCircle(DOT.transform(tr), DOT.add(8, 8).transform(tr), s);
113     }
114 
115 }
116