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