From 36fea30afcdd1fbe6bdf3bf979bf26452126d493 Mon Sep 17 00:00:00 2001 From: ollo Date: Tue, 2 Jan 2018 14:29:49 +0100 Subject: [PATCH] UI is drawn --- .../src/de/c3ma/ollo/WS2812Simulation.java | 20 +- .../de/c3ma/ollo/mockup/ESP8266Ws2812.java | 29 ++- .../de/c3ma/ollo/mockup/ui/WS2812Layout.java | 195 ++++++++++++++++++ simulation/ws28128ClockLayout.txt | 17 ++ 4 files changed, 252 insertions(+), 9 deletions(-) create mode 100644 simulation/src/de/c3ma/ollo/mockup/ui/WS2812Layout.java create mode 100644 simulation/ws28128ClockLayout.txt diff --git a/simulation/src/de/c3ma/ollo/WS2812Simulation.java b/simulation/src/de/c3ma/ollo/WS2812Simulation.java index fc585de..9701eb3 100644 --- a/simulation/src/de/c3ma/ollo/WS2812Simulation.java +++ b/simulation/src/de/c3ma/ollo/WS2812Simulation.java @@ -4,6 +4,8 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import javax.management.RuntimeErrorException; + import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; @@ -33,11 +35,12 @@ public class WS2812Simulation implements LuaSimulation { private ESP8266File espFile = new ESP8266File(); private ESP8266Node espNode = new ESP8266Node(this); private DoFileFunction doFile = new DoFileFunction(globals); + private ESP8266Ws2812 ws2812 = new ESP8266Ws2812(); private String scriptName; public WS2812Simulation(File sourceFolder) { globals.load(new ESP8266Uart()); - globals.load(new ESP8266Ws2812()); + globals.load(ws2812); globals.load(espTmr); globals.load(espFile); globals.load(espNode); @@ -76,11 +79,16 @@ public class WS2812Simulation implements LuaSimulation { return; } - if (args.length == 1) { + if (args.length >= 1) { File f = new File(args[0]); if (f.exists()) { WS2812Simulation simu = new WS2812Simulation(f.getParentFile()); System.out.println("File : " + f.getAbsolutePath()); + + if (args.length >= 2) { + simu.setWS2812Layout(new File(args[1])); + } + simu.callScript(f.getName()); } } else { @@ -89,6 +97,14 @@ public class WS2812Simulation implements LuaSimulation { } + private void setWS2812Layout(File file) { + if (file.exists()) { + ws2812.setLayout(file); + } else { + throw new RuntimeException("WS2812 Layout: " + file.getAbsolutePath() + " does not exists"); + } + } + private static void printUsage() { System.out.println("Usage:"); System.out.println("one argument required: file to execute."); diff --git a/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java b/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java index 97d015c..f9df097 100644 --- a/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java +++ b/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java @@ -1,11 +1,15 @@ package de.c3ma.ollo.mockup; +import java.io.File; + import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.OneArgFunction; import org.luaj.vm2.lib.TwoArgFunction; import org.luaj.vm2.lib.ZeroArgFunction; +import de.c3ma.ollo.mockup.ui.WS2812Layout; + /** * created at 28.12.2017 - 23:34:04
* creator: ollo
@@ -15,6 +19,8 @@ import org.luaj.vm2.lib.ZeroArgFunction; */ public class ESP8266Ws2812 extends TwoArgFunction { + private static WS2812Layout layout = null; + @Override public LuaValue call(LuaValue modname, LuaValue env) { env.checkglobals(); @@ -42,20 +48,29 @@ public class ESP8266Ws2812 extends TwoArgFunction { public LuaValue call(LuaValue arg) { if (arg.isstring()) { int length = arg.checkstring().rawlen(); - System.out.println("[WS2812] write length:" + length); if ((length % 3) == 0) { byte[] array = arg.toString().getBytes(); for (int i = 0; i < length; i+=3) { - /*System.out.println( - array[i+0] + " " - + array[i+1] + " " - + array[i+2] - );*/ + if (ESP8266Ws2812.layout != null) { + ESP8266Ws2812.layout.updateLED(i/3, array[i+0], array[i+1], array[i+2]); + } } } + + if (ESP8266Ws2812.layout == null) { + System.out.println("[WS2812] write length:" + length); + } else { + /*ESP8266Ws2812.layout.update(ESP8266Ws2812.layout.getGraphics());*/ + ESP8266Ws2812.layout.repaint(); + } } return LuaValue.valueOf(true); } - + } + + public void setLayout(File file) { + if (ESP8266Ws2812.layout == null) { + ESP8266Ws2812.layout = WS2812Layout.parse(file); + } } } diff --git a/simulation/src/de/c3ma/ollo/mockup/ui/WS2812Layout.java b/simulation/src/de/c3ma/ollo/mockup/ui/WS2812Layout.java new file mode 100644 index 0000000..2d9f0bf --- /dev/null +++ b/simulation/src/de/c3ma/ollo/mockup/ui/WS2812Layout.java @@ -0,0 +1,195 @@ +package de.c3ma.ollo.mockup.ui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + +/** + * created at 02.01.2018 - 12:57:02
+ * creator: ollo
+ * project: WS2812Emulation
+ * $Id: $
+ * @author ollo
+ */ +public class WS2812Layout extends JFrame { + + /** + * + */ + private static final long serialVersionUID = -6815557232118826140L; + + private ArrayList mLines = new ArrayList(); + private int mColumn = 0; + private int mRow = 0; + private Element[][] mElements; + + public static WS2812Layout parse(File file) { + WS2812Layout layout = null; + try { + BufferedReader br = new BufferedReader(new FileReader(file)); + try { + String line = br.readLine(); + if (line != null) { + layout = new WS2812Layout(); + } + + while (line != null) { + if (!line.startsWith("#")) { + layout.mLines.add(line); + layout.mRow++; + layout.mColumn = Math.max(layout.mColumn, line.length()); + } + /* get the next line */ + line = br.readLine(); + } + + /* parse each line */ + layout.parse(); + layout.createAndDisplayGUI(); + } finally { + if (br != null) { + br.close(); + } + } + } catch (IOException ioe) { + + } + return layout; + } + + private void createAndDisplayGUI() { + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + JPanel contentPane = new JPanel(); + contentPane.setLayout(new BorderLayout()); + contentPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2)); + + JPanel ledPanel = new JPanel(); + ledPanel.setLayout(new GridLayout(this.mRow, this.mColumn, 10, 10)); + for (int i = 0; i < this.mRow; i++) + { + for (int j = 0; j < this.mColumn; j++) + { + if (this.mElements[i][j] != null) { + ledPanel.add(this.mElements[i][j]); + } + } + } + contentPane.add(ledPanel, BorderLayout.CENTER); + JButton button = new JButton("Do something"); + button.setActionCommand("Do something"); + button.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent ae) + { + JButton but = (JButton) ae.getSource(); + //FIXME some clever logic + } + }); + contentPane.add(button, BorderLayout.SOUTH); + + + setContentPane(contentPane); + pack(); + setLocationByPlatform(true); + setVisible(true); + } + + private void parse() { + this.mElements = new Element[this.mRow][this.mColumn]; + int row=0; + for (String line : this.mLines) { + for (int i = 0; i < line.length(); i++) { + char c = line.charAt(i); + if ((('A' <= c) && (c <= 'Z')) || + (('0' <= c) && (c <= '9')) || + (c == 'Ä') || (c == 'Ö') || (c == 'Ü')) { + this.mElements[row][i] = new Element(c); + } else { + this.mElements[row][i] = new Element(); + } + this.mElements[row][i].setColor(0, 0, 0); + } + row++; + } + } + + public class Element extends JLabel { + + /** + * + */ + private static final long serialVersionUID = -3933903441113933637L; + + private boolean noText=false; + + /** + * Draw a simple rect + */ + public Element() { + super(); + this.noText = true; + this.setBackground(Color.BLACK); + } + + /** + * Draw a character + * @param character to show + */ + public Element(char character) { + super(""+character); + setFont(new Font("Dialog", Font.BOLD, 24)); + setHorizontalAlignment(CENTER); + this.setBackground(Color.BLACK); + } + + public void setColor(int red, int green, int blue) { + this.setForeground(new Color(red, green, blue)); + this.update(this.getGraphics()); + //this.repaint(); + System.out.println( this.toString()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (noText) { + sb.append(" "); + } else { + sb.append("" + this.getText()); + } + sb.append(Integer.toHexString(this.getForeground().getRed()) + + " " + Integer.toHexString(this.getForeground().getGreen()) + + " " + Integer.toHexString(this.getForeground().getBlue())); + + return sb.toString(); + } + } + + public void updateLED(int index, byte red, byte green, byte blue) { + if (this.mElements != null) { + int i = (index / this.mColumn); + int j = (index % this.mColumn); + if ((i < this.mElements.length) && + (j < this.mElements[i].length) && + (this.mElements[i][j] != null)) { + this.mElements[i][j].setColor(red, green, blue); + } + } + } + +} diff --git a/simulation/ws28128ClockLayout.txt b/simulation/ws28128ClockLayout.txt new file mode 100644 index 0000000..2fda3e4 --- /dev/null +++ b/simulation/ws28128ClockLayout.txt @@ -0,0 +1,17 @@ +# This file describes the layout of the WS2812 LEDs. +# _ will only draw a rect +# A-Z or 1-9 will draw the text or number +# each element will be updated with its color with the known commands of the nodemcu firmware +# +# Here the configuration for the wordclock: +ESKISTLFÜNF +ZEHNZWANZIG +DREIVIERTEL +TGNACHVORJM +HALBXZWÖLFP +ZWEINSIEBEN +KDREIRHFÜNF +ELFNEUNVIER +WACHTZEHNRS +BSECHSFMUHR +____