Commit | Line | Data |
---|---|---|
100b82fe TW |
1 | package kaka.cakelight; |
2 | ||
3 | import javafx.application.Application; | |
4 | import javafx.scene.Scene; | |
5 | import javafx.scene.canvas.Canvas; | |
6 | import javafx.scene.canvas.GraphicsContext; | |
7 | import javafx.scene.input.KeyCode; | |
8 | import javafx.scene.layout.Pane; | |
9 | import javafx.scene.paint.Color; | |
10 | import javafx.scene.paint.Paint; | |
11 | import javafx.stage.Stage; | |
67b0a758 | 12 | import kaka.cakelight.mode.AmbientMode; |
100b82fe TW |
13 | import org.opencv.core.Core; |
14 | import org.opencv.core.Mat; | |
15 | ||
16 | import static kaka.cakelight.Main.log; | |
17 | ||
18 | public class GuiTest extends Application { | |
19 | private static final int BLOCK = 45; | |
20 | private static final int GUTTER = 3 * BLOCK; | |
21 | private Canvas canvas; | |
22 | private Configuration config; | |
23 | private CakeLight cakelight; | |
24 | private boolean paused; | |
25 | ||
26 | public static void main(String[] args) { | |
27 | System.loadLibrary(Core.NATIVE_LIBRARY_NAME); | |
28 | launch(args); | |
29 | } | |
30 | ||
31 | @Override | |
32 | public void start(Stage stage) throws Exception { | |
33 | config = Configuration.from("config.properties"); | |
34 | canvas = new Canvas(16 * BLOCK + 2 * GUTTER, 9 * BLOCK + 2 * GUTTER); | |
35 | ||
36 | Pane root = new Pane(); | |
37 | root.getChildren().add(canvas); | |
38 | ||
39 | Scene scene = new Scene(root); | |
40 | scene.setOnKeyPressed(keyEvent -> { | |
f722ee0d | 41 | if (keyEvent.getCode() == KeyCode.ESCAPE || keyEvent.getCode() == KeyCode.Q) { |
100b82fe TW |
42 | stage.close(); |
43 | cakelight.cleanup(); | |
44 | } | |
45 | if (keyEvent.getCode() == KeyCode.SPACE) { | |
46 | paused = !paused; | |
47 | } | |
48 | }); | |
49 | ||
50 | stage.setTitle("Cakelight"); | |
51 | stage.setScene(scene); | |
52 | stage.setOnCloseRequest(windowEvent -> cakelight.cleanup()); | |
53 | stage.show(); | |
54 | ||
55 | setupCakeLight(); | |
56 | } | |
57 | ||
58 | private void setupCakeLight() { | |
59 | log("Running with config:\n" + config); | |
01ee91e7 | 60 | cakelight = new CakeLight(config); |
100b82fe TW |
61 | VideoMode mode = new VideoMode(); |
62 | cakelight.setMode(mode); | |
63 | cakelight.startLoop(); | |
03b67a73 | 64 | mode.onVideoFrame(frame -> drawFrame(canvas.getGraphicsContext2D(), frame)); |
100b82fe TW |
65 | } |
66 | ||
242486dc TW |
67 | private javafx.scene.paint.Color getLedColor(LedFrame frame, int led) { |
68 | kaka.cakelight.Color c = frame.getLedColor(led); | |
69 | return javafx.scene.paint.Color.rgb(c.r(), c.g(), c.b()); | |
70 | } | |
71 | ||
adc29b9a | 72 | private void drawFrame(GraphicsContext gc, VideoFrame frame) { |
100b82fe TW |
73 | if (paused) return; |
74 | System.out.println("Drawing a frame"); | |
75 | drawCols(gc, frame); | |
76 | drawRows(gc, frame); | |
77 | // drawVideo(gc, frame); | |
78 | drawBorderAndGrid(gc); | |
100b82fe TW |
79 | } |
80 | ||
03b67a73 | 81 | private void drawLEDs(GraphicsContext gc, LedFrame frame) { |
100b82fe TW |
82 | int ledLength = GUTTER; |
83 | float colSize = 16f * BLOCK / config.leds.cols; | |
84 | float rowSize = 9f * BLOCK / config.leds.rows; | |
85 | // DropShadow shadow = new DropShadow(BlurType.ONE_PASS_BOX, Color.RED, colSize * 2, colSize, 0, 0); | |
86 | for (int x = 0; x < config.leds.cols; x++) { | |
ed56b145 TW |
87 | // Top |
88 | gc.setFill(getLedColor(frame, config.leds.cols * 2 + config.leds.rows - x - 1)); | |
100b82fe | 89 | gc.fillRect(GUTTER + x * colSize, GUTTER - ledLength, colSize, ledLength); |
ed56b145 TW |
90 | // Bottom |
91 | gc.setFill(getLedColor(frame, x)); | |
100b82fe TW |
92 | gc.fillRect(GUTTER + x * colSize, GUTTER + 9 * BLOCK, colSize, ledLength); |
93 | } | |
94 | for (int y = 0; y < config.leds.rows; y++) { | |
ed56b145 TW |
95 | // Left |
96 | gc.setFill(getLedColor(frame, config.leds.cols * 2 + config.leds.rows + y)); | |
100b82fe | 97 | gc.fillRect(GUTTER - ledLength, GUTTER + y * rowSize, ledLength, rowSize); |
ed56b145 TW |
98 | // Right |
99 | gc.setFill(getLedColor(frame, config.leds.rows + config.leds.cols - y - 1)); | |
100b82fe TW |
100 | gc.fillRect(GUTTER + 16 * BLOCK, GUTTER + y * rowSize, ledLength, rowSize); |
101 | } | |
102 | } | |
103 | ||
adc29b9a | 104 | private void drawVideo(GraphicsContext gc, VideoFrame frame) { |
100b82fe TW |
105 | byte[] rgb = new byte[3]; |
106 | Mat img = frame.getConvertedImage(); | |
107 | float colSize = 16 * BLOCK / (float)img.cols(); | |
108 | float rowSize = 9 * BLOCK / (float)img.rows(); | |
109 | for (int x = 0, cols = img.cols(); x < cols; x++) { | |
110 | for (int y = 0, rows = img.rows(); y < rows; y++) { | |
111 | img.get(y, x, rgb); | |
112 | gc.setFill(Color.rgb(rgb[0] & 0xff, rgb[1] & 0xff, rgb[2] & 0xff, 0.5)); | |
113 | gc.fillRect(GUTTER + x * colSize, GUTTER + y * rowSize, colSize, rowSize); | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
adc29b9a | 118 | private void drawCols(GraphicsContext gc, VideoFrame frame) { |
100b82fe TW |
119 | byte[] rgb = new byte[3]; |
120 | for (int x = 0; x < config.leds.cols; x++) { | |
121 | for (int y = 0; y < 9; y++) { | |
122 | frame.getColImage().get(y, x, rgb); | |
123 | drawColPixel(gc, x, y, rgb); | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
adc29b9a | 128 | private void drawRows(GraphicsContext gc, VideoFrame frame) { |
100b82fe TW |
129 | byte[] rgb = new byte[3]; |
130 | for (int y = 0; y < config.leds.rows; y++) { | |
131 | for (int x = 0; x < 16; x++) { | |
132 | frame.getRowImage().get(y, x, rgb); | |
133 | drawRowPixel(gc, x, y, rgb); | |
134 | } | |
135 | } | |
136 | } | |
137 | ||
138 | private void drawColPixel(GraphicsContext gc, int x, int y, byte[] rgb) { | |
139 | float ledSize = 16f * BLOCK / config.leds.cols; | |
140 | gc.setFill(Color.rgb(rgb[0] & 0xff, rgb[1] & 0xff, rgb[2] & 0xff, 0.5)); | |
141 | gc.fillRect(GUTTER + x * ledSize, GUTTER + y * BLOCK, ledSize, BLOCK); | |
142 | } | |
143 | ||
144 | private void drawRowPixel(GraphicsContext gc, int x, int y, byte[] rgb) { | |
145 | float ledSize = 9f * BLOCK / config.leds.rows; | |
146 | gc.setFill(Color.rgb(rgb[0] & 0xff, rgb[1] & 0xff, rgb[2] & 0xff, 0.5)); | |
147 | gc.fillRect(GUTTER + x * BLOCK, GUTTER + y * ledSize, BLOCK, ledSize); | |
148 | } | |
149 | ||
150 | private void drawBorderAndGrid(GraphicsContext gc) { | |
151 | gc.setStroke(Color.BLACK); | |
152 | gc.setLineWidth(BLOCK * 0.1); | |
153 | gc.strokeRect(GUTTER, GUTTER, 16 * BLOCK, 9 * BLOCK); | |
154 | gc.setLineWidth(1); | |
155 | for (int x = 1; x < 16; x++) { | |
156 | gc.strokeLine(GUTTER + x * BLOCK, GUTTER, GUTTER + x * BLOCK, GUTTER + 9 * BLOCK); | |
157 | } | |
158 | for (int y = 1; y < 9; y++) { | |
159 | gc.strokeLine(GUTTER, GUTTER + y * BLOCK, GUTTER + 16 * BLOCK, GUTTER + y * BLOCK); | |
160 | } | |
161 | } | |
162 | ||
163 | private void drawPixel(GraphicsContext gc, int x, int y, Paint paint) { | |
164 | gc.setFill(paint); | |
165 | gc.fillRect(GUTTER + x * BLOCK, GUTTER + y * BLOCK, BLOCK, BLOCK); | |
166 | } | |
167 | } |