1 package kaka.cakelight;
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;
12 import org.opencv.core.Core;
13 import org.opencv.core.Mat;
15 import static kaka.cakelight.Main.log;
17 public 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;
25 public static void main(String[] args) {
26 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
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);
35 Pane root = new Pane();
36 root.getChildren().add(canvas);
38 Scene scene = new Scene(root);
39 scene.setOnKeyPressed(keyEvent -> {
40 if (keyEvent.getCode() == KeyCode.ESCAPE) {
44 if (keyEvent.getCode() == KeyCode.SPACE) {
49 stage.setTitle("Cakelight");
50 stage.setScene(scene);
51 stage.setOnCloseRequest(windowEvent -> cakelight.cleanup());
57 private void setupCakeLight() {
58 log("Running with config:\n" + config);
59 cakelight = new CakeLight(config, new LedController() {
61 public void onFrame(LedFrame ledFrame) {
62 if (!paused) drawLEDs(canvas.getGraphicsContext2D(), ledFrame);
65 VideoMode mode = new VideoMode();
66 cakelight.setMode(mode);
67 cakelight.startLoop();
68 mode.onVideoFrame(frame -> drawFrame(canvas.getGraphicsContext2D(), frame));
71 private void drawFrame(GraphicsContext gc, Frame frame) {
73 System.out.println("Drawing a frame");
76 // drawVideo(gc, frame);
77 drawBorderAndGrid(gc);
80 private void drawLEDs(GraphicsContext gc, LedFrame frame) {
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++) {
86 gc.setFill(frame.getLedColor(x + config.leds.rows));
87 gc.fillRect(GUTTER + x * colSize, GUTTER - ledLength, colSize, ledLength);
88 gc.setFill(frame.getLedColor(config.leds.rows * 2 + config.leds.cols * 2 - 1 - x));
89 gc.fillRect(GUTTER + x * colSize, GUTTER + 9 * BLOCK, colSize, ledLength);
91 for (int y = 0; y < config.leds.rows; y++) {
92 gc.setFill(frame.getLedColor(config.leds.rows - 1 - y));
93 gc.fillRect(GUTTER - ledLength, GUTTER + y * rowSize, ledLength, rowSize);
94 gc.setFill(frame.getLedColor(y + config.leds.rows + config.leds.cols));
95 gc.fillRect(GUTTER + 16 * BLOCK, GUTTER + y * rowSize, ledLength, rowSize);
99 private void drawVideo(GraphicsContext gc, Frame frame) {
100 byte[] rgb = new byte[3];
101 Mat img = frame.getConvertedImage();
102 float colSize = 16 * BLOCK / (float)img.cols();
103 float rowSize = 9 * BLOCK / (float)img.rows();
104 for (int x = 0, cols = img.cols(); x < cols; x++) {
105 for (int y = 0, rows = img.rows(); y < rows; y++) {
107 gc.setFill(Color.rgb(rgb[0] & 0xff, rgb[1] & 0xff, rgb[2] & 0xff, 0.5));
108 gc.fillRect(GUTTER + x * colSize, GUTTER + y * rowSize, colSize, rowSize);
113 private void drawCols(GraphicsContext gc, Frame frame) {
114 byte[] rgb = new byte[3];
115 for (int x = 0; x < config.leds.cols; x++) {
116 for (int y = 0; y < 9; y++) {
117 frame.getColImage().get(y, x, rgb);
118 drawColPixel(gc, x, y, rgb);
123 private void drawRows(GraphicsContext gc, Frame frame) {
124 byte[] rgb = new byte[3];
125 for (int y = 0; y < config.leds.rows; y++) {
126 for (int x = 0; x < 16; x++) {
127 frame.getRowImage().get(y, x, rgb);
128 drawRowPixel(gc, x, y, rgb);
133 private void drawColPixel(GraphicsContext gc, int x, int y, byte[] rgb) {
134 float ledSize = 16f * BLOCK / config.leds.cols;
135 gc.setFill(Color.rgb(rgb[0] & 0xff, rgb[1] & 0xff, rgb[2] & 0xff, 0.5));
136 gc.fillRect(GUTTER + x * ledSize, GUTTER + y * BLOCK, ledSize, BLOCK);
139 private void drawRowPixel(GraphicsContext gc, int x, int y, byte[] rgb) {
140 float ledSize = 9f * BLOCK / config.leds.rows;
141 gc.setFill(Color.rgb(rgb[0] & 0xff, rgb[1] & 0xff, rgb[2] & 0xff, 0.5));
142 gc.fillRect(GUTTER + x * BLOCK, GUTTER + y * ledSize, BLOCK, ledSize);
145 private void drawBorderAndGrid(GraphicsContext gc) {
146 gc.setStroke(Color.BLACK);
147 gc.setLineWidth(BLOCK * 0.1);
148 gc.strokeRect(GUTTER, GUTTER, 16 * BLOCK, 9 * BLOCK);
150 for (int x = 1; x < 16; x++) {
151 gc.strokeLine(GUTTER + x * BLOCK, GUTTER, GUTTER + x * BLOCK, GUTTER + 9 * BLOCK);
153 for (int y = 1; y < 9; y++) {
154 gc.strokeLine(GUTTER, GUTTER + y * BLOCK, GUTTER + 16 * BLOCK, GUTTER + y * BLOCK);
158 private void drawPixel(GraphicsContext gc, int x, int y, Paint paint) {
160 gc.fillRect(GUTTER + x * BLOCK, GUTTER + y * BLOCK, BLOCK, BLOCK);