diff --git a/src/config-tool/ConfigTool/.gitignore b/src/config-tool/ConfigTool/.gitignore index 77237710..604b51ee 100644 --- a/src/config-tool/ConfigTool/.gitignore +++ b/src/config-tool/ConfigTool/.gitignore @@ -1,2 +1,3 @@ /.settings /classes +/hyerpcon.dat diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/ConfigurationFile.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/ConfigurationFile.java new file mode 100644 index 00000000..ba2ce6b3 --- /dev/null +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/ConfigurationFile.java @@ -0,0 +1,102 @@ +package org.hyperion.hypercon; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Properties; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class ConfigurationFile { + private final Properties pProps = new Properties(); + + public void load(String pFilename) { + pProps.clear(); +// try (InputStream in = new InflaterInputStream(new FileInputStream(pFilename))){ +// try (InputStream in = new GZIPInputStream(new FileInputStream(pFilename))){ + try (InputStream in = new FileInputStream(pFilename)) { + pProps.load(in); + } catch (Throwable t) { + // TODO Auto-generated catch block + t.printStackTrace(); + } + } + + public void save(String pFilename) { +// try (OutputStream out = new DeflaterOutputStream(new FileOutputStream(pFilename))) { +// try (OutputStream out = new GZIPOutputStream(new FileOutputStream(pFilename))) { + try (OutputStream out = (new FileOutputStream(pFilename))) { + pProps.store(out, "Pesistent settings file for HyperCon"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void store(Object pObj) { + String className = pObj.getClass().getSimpleName(); + // Retrieve the member variables + Field[] fields = pObj.getClass().getDeclaredFields(); + // Iterate each variable + for (Field field : fields) { + if (!Modifier.isPublic(field.getModifiers())) { + System.out.println("Unable to synchronise non-public field(" + field.getName() + ") in configuration structure(" + className + ")"); + continue; + } + + String key = className + "." + field.getName(); + try { + Object value = field.get(pObj); + + if (value.getClass().isEnum()) { + pProps.setProperty(key, ((Enum)value).name()); + } else { + pProps.setProperty(key, value.toString()); + } + } catch (Throwable t) {} + } + } + + public void restore(Object pObj) { + String className = pObj.getClass().getSimpleName(); + + // Retrieve the member variables + Field[] fields = pObj.getClass().getDeclaredFields(); + // Iterate each variable + for (Field field : fields) { + String key = className + "." + field.getName(); + String value = pProps.getProperty(key); + if (value == null) { + System.out.println("Persistent settings does not contain value for " + key); + continue; + } + + try { + if (field.getType() == boolean.class) { + field.set(pObj, Boolean.parseBoolean(value)); + } else if (field.getType() == int.class) { + field.set(pObj, Integer.parseInt(value)); + } else if (field.getType() == double.class) { + field.set(pObj, Double.parseDouble(value)); + } else if (field.getType().isEnum()) { + Method valMet = field.getType().getMethod("valueOf", String.class); + Object enumVal = valMet.invoke(null, value); + field.set(pObj, enumVal); + } else { + field.set(pObj, value); + } + } catch (Throwable t) { + System.out.println("Failed to parse value(" + value + ") for " + key); + } + } + } + + @Override + public String toString() { + return pProps.toString(); + } +} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConApplet.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConApplet.java deleted file mode 100644 index f165c8af..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConApplet.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.hyperion.hypercon; - -import java.awt.BorderLayout; -import java.awt.Dimension; - -import javax.swing.JApplet; - -import org.hyperion.hypercon.gui.ConfigPanel; - -/** - * Class for starting HyperCon (Hyperion configuration file builder) as a Applet (within a browser) - * - */ -public class HyperConApplet extends JApplet { - - /** - * Constructs the HyperCon Applet - */ - public HyperConApplet() { - super(); - - initialise(); - } - - /** - * Initialises this applet - */ - private void initialise() { - setPreferredSize(new Dimension(600, 300)); - - // Add the HyperCon configuration panel - add(new ConfigPanel(), BorderLayout.CENTER); - } -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedFrameFactory.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedFrameFactory.java index 0cbf058d..9f118d2b 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedFrameFactory.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedFrameFactory.java @@ -60,7 +60,7 @@ public class LedFrameFactory { } // Construct the top-left led (if top-left is enabled) - if (frameSpec.topLeftCorner) { + if (frameSpec.topCorners) { mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 0.0, processConfig.getOverlapFraction(), BorderSide.top_left)); iLed = increase(frameSpec, iLed); } @@ -83,7 +83,7 @@ public class LedFrameFactory { } // Construct the top-right led (if top-right is enabled) - if (frameSpec.topRightCorner) { + if (frameSpec.topCorners) { mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 0.0, processConfig.getOverlapFraction(), BorderSide.top_right)); iLed = increase(frameSpec, iLed); } @@ -106,7 +106,7 @@ public class LedFrameFactory { } // Construct the bottom-right led (if bottom-right is enabled) - if (frameSpec.bottomRightCorner) { + if (frameSpec.bottomCorners) { mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 1.0, processConfig.getOverlapFraction(), BorderSide.bottom_right)); iLed = increase(frameSpec, iLed); } @@ -133,7 +133,7 @@ public class LedFrameFactory { } // Construct the bottom-left led (if bottom-left is enabled) - if (frameSpec.bottomLeftCorner) { + if (frameSpec.bottomCorners) { mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 1.0, processConfig.getOverlapFraction(), BorderSide.bottom_left)); iLed = increase(frameSpec, iLed); } diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java index 3bc8f4e5..568932ef 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java @@ -1,5 +1,9 @@ package org.hyperion.hypercon; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; + import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.UIManager; @@ -11,6 +15,7 @@ import org.hyperion.hypercon.gui.ConfigPanel; * JAVA application (contains the entry-point). */ public class Main { + public static final String configFilename = "hyerpcon.dat"; /** * Entry point to start HyperCon @@ -18,6 +23,8 @@ public class Main { * @param pArgs HyperCon does not have command line arguments */ public static void main(String[] pArgs) { + final LedString ledString = new LedString(); + try { // Configure swing to use the system default look and feel UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); @@ -29,9 +36,31 @@ public class Main { frame.setSize(1300, 700); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setIconImage(new ImageIcon(Main.class.getResource("HyperConIcon_64.png")).getImage()); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + ConfigurationFile configFile = new ConfigurationFile(); + configFile.store(ledString.mDeviceConfig); + configFile.store(ledString.mLedFrameConfig); + configFile.store(ledString.mProcessConfig); + configFile.store(ledString.mColorConfig); + configFile.store(ledString.mMiscConfig); + configFile.save(configFilename); + } + }); + + if (new File(configFilename).exists()) { + ConfigurationFile configFile = new ConfigurationFile(); + configFile.load(configFilename); + configFile.restore(ledString.mDeviceConfig); + configFile.restore(ledString.mLedFrameConfig); + configFile.restore(ledString.mProcessConfig); + configFile.restore(ledString.mColorConfig); + configFile.restore(ledString.mMiscConfig); + } // Add the HyperCon configuration panel - frame.setContentPane(new ConfigPanel()); + frame.setContentPane(new ConfigPanel(ledString)); // Show the frame frame.setVisible(true); diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorConfigPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorConfigPanel.java index 97f16f11..4e644b7d 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorConfigPanel.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorConfigPanel.java @@ -7,6 +7,10 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import org.hyperion.hypercon.spec.ColorConfig; /** * Configuration panel for the ColorConfig. @@ -14,6 +18,9 @@ import javax.swing.SpinnerNumberModel; * NB This has not been integrated in the GUI jet! */ public class ColorConfigPanel extends JPanel { + + private final ColorConfig mColorConfig; + private JPanel mRgbTransformPanel; private JLabel mThresholdLabel; private JLabel mGammaLabel; @@ -41,9 +48,11 @@ public class ColorConfigPanel extends JPanel { private JLabel mValueAdjustLabel; private JSpinner mValueAdjustSpinner; - public ColorConfigPanel() { + public ColorConfigPanel(ColorConfig pColorConfig) { super(); + mColorConfig = pColorConfig; + initialise(); } @@ -75,35 +84,47 @@ public class ColorConfigPanel extends JPanel { mRedTransformLabel = new JLabel("RED"); mRgbTransformPanel.add(mRedTransformLabel); - mRedThresholdSpinner = new JSpinner(new SpinnerNumberModel()); + mRedThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedThreshold, 0.0, 1.0, 0.1)); + mRedThresholdSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mRedThresholdSpinner); - mRedGammaSpinner = new JSpinner(new SpinnerNumberModel()); + mRedGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedGamma, 0.0, 100.0, 0.1)); + mRedThresholdSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mRedGammaSpinner); - mRedBlacklevelSpinner = new JSpinner(new SpinnerNumberModel()); + mRedBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedBlacklevel, 0.0, 1.0, 0.1)); + mRedThresholdSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mRedBlacklevelSpinner); - mRedWhitelevelSpinner = new JSpinner(new SpinnerNumberModel()); + mRedWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedWhitelevel, 0.0, 1.0, 0.1)); + mRedThresholdSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mRedWhitelevelSpinner); mGreenTransformLabel = new JLabel("GREEN"); mRgbTransformPanel.add(mGreenTransformLabel); - mGreenThresholdSpinner = new JSpinner(new SpinnerNumberModel()); + mGreenThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenThreshold, 0.0, 1.0, 0.1)); + mGreenThresholdSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mGreenThresholdSpinner); - mGreenGammaSpinner = new JSpinner(new SpinnerNumberModel()); + mGreenGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenGamma, 0.0, 100.0, 0.1)); + mGreenGammaSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mGreenGammaSpinner); - mGreenBlacklevelSpinner = new JSpinner(new SpinnerNumberModel()); + mGreenBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenBlacklevel, 0.0, 1.0, 0.1)); + mGreenBlacklevelSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mGreenBlacklevelSpinner); - mGreenWhitelevelSpinner = new JSpinner(new SpinnerNumberModel()); + mGreenWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenWhitelevel, 0.0, 1.0, 0.1)); + mGreenWhitelevelSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mGreenWhitelevelSpinner); mBlueTransformLabel = new JLabel("BLUE"); mRgbTransformPanel.add(mBlueTransformLabel); - mBlueThresholdSpinner = new JSpinner(new SpinnerNumberModel()); + mBlueThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueThreshold, 0.0, 1.0, 0.1)); + mBlueThresholdSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mBlueThresholdSpinner); - mBlueGammaSpinner = new JSpinner(new SpinnerNumberModel()); + mBlueGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueGamma, 0.0, 100.0, 0.1)); + mBlueGammaSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mBlueGammaSpinner); - mBlueBlacklevelSpinner = new JSpinner(new SpinnerNumberModel()); + mBlueBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueBlacklevel, 0.0, 1.0, 0.1)); + mBlueBlacklevelSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mBlueBlacklevelSpinner); - mBlueWhitelevelSpinner = new JSpinner(new SpinnerNumberModel()); + mBlueWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueWhitelevel, 0.0, 1.0, 0.1)); + mBlueWhitelevelSpinner.addChangeListener(mChangeListener); mRgbTransformPanel.add(mBlueWhitelevelSpinner); layout.setHorizontalGroup(layout.createSequentialGroup() @@ -177,13 +198,15 @@ public class ColorConfigPanel extends JPanel { mSaturationAdjustLabel = new JLabel("Saturation"); mHsvTransformPanel.add(mSaturationAdjustLabel); - mSaturationAdjustSpinner = new JSpinner(new SpinnerNumberModel(1.0, 0.0, 1024.0, 0.01)); + mSaturationAdjustSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mSaturationGain, 0.0, 1024.0, 0.01)); + mSaturationAdjustSpinner.addChangeListener(mChangeListener); mHsvTransformPanel.add(mSaturationAdjustSpinner); mValueAdjustLabel = new JLabel("Value"); mHsvTransformPanel.add(mValueAdjustLabel); - mValueAdjustSpinner = new JSpinner(new SpinnerNumberModel(1.0, 0.0, 1024.0, 0.01)); + mValueAdjustSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mValueGain, 0.0, 1024.0, 0.01)); + mValueAdjustSpinner.addChangeListener(mChangeListener); mHsvTransformPanel.add(mValueAdjustSpinner); layout.setHorizontalGroup(layout.createSequentialGroup() @@ -211,4 +234,26 @@ public class ColorConfigPanel extends JPanel { return mHsvTransformPanel; } + private final ChangeListener mChangeListener = new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + mColorConfig.mRedThreshold = (Double)mRedThresholdSpinner.getValue(); + mColorConfig.mRedGamma = (Double)mRedGammaSpinner.getValue(); + mColorConfig.mRedBlacklevel = (Double)mRedBlacklevelSpinner.getValue(); + mColorConfig.mRedWhitelevel = (Double)mRedWhitelevelSpinner.getValue(); + + mColorConfig.mGreenThreshold = (Double)mGreenThresholdSpinner.getValue(); + mColorConfig.mGreenGamma = (Double)mGreenGammaSpinner.getValue(); + mColorConfig.mGreenBlacklevel = (Double)mGreenBlacklevelSpinner.getValue(); + mColorConfig.mGreenWhitelevel = (Double)mGreenWhitelevelSpinner.getValue(); + + mColorConfig.mBlueThreshold = (Double)mBlueThresholdSpinner.getValue(); + mColorConfig.mBlueGamma = (Double)mBlueGammaSpinner.getValue(); + mColorConfig.mBlueBlacklevel = (Double)mBlueBlacklevelSpinner.getValue(); + mColorConfig.mBlueWhitelevel = (Double)mBlueWhitelevelSpinner.getValue(); + + mColorConfig.mSaturationGain = (Double)mSaturationAdjustSpinner.getValue(); + mColorConfig.mValueGain = (Double)mValueAdjustSpinner.getValue(); + } + }; } diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ConfigPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ConfigPanel.java index 6794e368..ad8c573a 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ConfigPanel.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ConfigPanel.java @@ -14,8 +14,10 @@ import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JPanel; +import org.hyperion.hypercon.ConfigurationFile; import org.hyperion.hypercon.LedFrameFactory; import org.hyperion.hypercon.LedString; +import org.hyperion.hypercon.Main; /** * The main-config panel of HyperCon. Includes the configuration and the panels to edit and @@ -24,7 +26,7 @@ import org.hyperion.hypercon.LedString; public class ConfigPanel extends JPanel { /** The LED configuration information*/ - private final LedString ledString = new LedString(); + private final LedString ledString; /** Action for write the Hyperion deamon configuration file */ private final Action mSaveConfigAction = new AbstractAction("Create Hyperion Configuration") { @@ -37,6 +39,14 @@ public class ConfigPanel extends JPanel { try { ledString.saveConfigFile(fileChooser.getSelectedFile().getAbsolutePath()); + + ConfigurationFile configFile = new ConfigurationFile(); + configFile.store(ledString.mDeviceConfig); + configFile.store(ledString.mLedFrameConfig); + configFile.store(ledString.mProcessConfig); + configFile.store(ledString.mColorConfig); + configFile.store(ledString.mMiscConfig); + configFile.save(Main.configFilename); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); @@ -67,9 +77,11 @@ public class ConfigPanel extends JPanel { /** * Constructs the configuration panel with a default initialised led-frame and configuration */ - public ConfigPanel() { + public ConfigPanel(final LedString pLedString) { super(); + ledString = pLedString; + initialise(); // Compute the individual leds for the current configuration @@ -121,7 +133,7 @@ public class ConfigPanel extends JPanel { mSpecificationPanel = new JPanel(); mSpecificationPanel.setLayout(new BoxLayout(mSpecificationPanel, BoxLayout.Y_AXIS)); - mConstructionPanel = new LedFramePanel(ledString.mLedFrameConfig); + mConstructionPanel = new LedFramePanel(ledString.mDeviceConfig, ledString.mLedFrameConfig); mConstructionPanel.setBorder(BorderFactory.createTitledBorder("Construction")); mSpecificationPanel.add(mConstructionPanel); diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/DevicePanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/DevicePanel.java new file mode 100644 index 00000000..ae8b64be --- /dev/null +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/DevicePanel.java @@ -0,0 +1,69 @@ +package org.hyperion.hypercon.gui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import org.hyperion.hypercon.spec.DeviceConfig; +import org.hyperion.hypercon.spec.RgbByteOrder; + +public class DevicePanel extends JPanel { + + private final DeviceConfig mDeviceConfig; + + private JLabel mOutputLabel; + private JComboBox mOutputCombo; + + private JLabel mBaudrateLabel; + private JComboBox mBaudrateCombo; + + private JLabel mRgbLabel; + private JComboBox mRgbCombo; + + public DevicePanel(DeviceConfig pDeviceConfig) { + super(); + + mDeviceConfig = pDeviceConfig; + + initialise(); + } + + private void initialise() { + mOutputLabel = new JLabel("Output"); + add(mOutputLabel); + + mOutputCombo = new JComboBox<>(new String[] {"/dev/spidev0.0", " /dev/ttyUSB0", "/home/pi/test-output.txt", "/dev/null" }); + mOutputCombo.setEditable(true); + mOutputCombo.setSelectedItem(mDeviceConfig.mOutput); + mOutputCombo.addActionListener(mActionListener); + add(mOutputCombo); + + mBaudrateLabel = new JLabel("Baudrate"); + add(mBaudrateLabel); + + mBaudrateCombo = new JComboBox<>(); + mRgbCombo.setSelectedItem(mDeviceConfig.mBaudrate); + mRgbCombo.addActionListener(mActionListener); + add(mBaudrateCombo); + + mRgbLabel = new JLabel("RGB Byte Order"); + add(mRgbLabel); + + mRgbCombo = new JComboBox<>(RgbByteOrder.values()); + mRgbCombo.setSelectedItem(mDeviceConfig.mRgbByteOrder); + mRgbCombo.addActionListener(mActionListener); + add(mRgbCombo); + } + + private final ActionListener mActionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mDeviceConfig.mOutput = (String)mOutputCombo.getSelectedItem(); + mDeviceConfig.mBaudrate = (Integer)mBaudrateCombo.getSelectedItem(); + mDeviceConfig.mRgbByteOrder = (RgbByteOrder)mRgbCombo.getSelectedItem(); + } + }; +} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageProcessPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageProcessPanel.java index 9ffeed6b..1ecc8b37 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageProcessPanel.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageProcessPanel.java @@ -2,8 +2,6 @@ package org.hyperion.hypercon.gui; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Observable; -import java.util.Observer; import javax.swing.GroupLayout; import javax.swing.JComboBox; @@ -16,7 +14,7 @@ import javax.swing.event.ChangeListener; import org.hyperion.hypercon.spec.ImageProcessConfig; -public class ImageProcessPanel extends JPanel implements Observer { +public class ImageProcessPanel extends JPanel { private final ImageProcessConfig mProcessConfig; @@ -42,43 +40,41 @@ public class ImageProcessPanel extends JPanel implements Observer { mProcessConfig = pProcessConfig; initialise(); - - update(mProcessConfig, null); } private void initialise() { mHorizontalDepthLabel = new JLabel("Horizontal depth [%]:"); add(mHorizontalDepthLabel); - mHorizontalDepthSpinner = new JSpinner(new SpinnerNumberModel(5.0, 1.0, 100.0, 1.0)); + mHorizontalDepthSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mHorizontalDepth*100.0, 1.0, 100.0, 1.0)); mHorizontalDepthSpinner.addChangeListener(mChangeListener); add(mHorizontalDepthSpinner); mVerticalDepthLabel = new JLabel("Vertical depth [%]:"); add(mVerticalDepthLabel); - mVerticalDepthSpinner = new JSpinner(new SpinnerNumberModel(5.0, 1.0, 100.0, 1.0)); + mVerticalDepthSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mVerticalDepth*100.0, 1.0, 100.0, 1.0)); mVerticalDepthSpinner.addChangeListener(mChangeListener); add(mVerticalDepthSpinner); mHorizontalGapLabel = new JLabel("Horizontal gap [%]:"); add(mHorizontalGapLabel); - mHorizontalGapSpinner = new JSpinner(new SpinnerNumberModel(0.0, 0.0, 50.0, 1.0)); + mHorizontalGapSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mHorizontalGap*100.0, 0.0, 50.0, 1.0)); mHorizontalGapSpinner.addChangeListener(mChangeListener); add(mHorizontalGapSpinner); mVerticalGapLabel = new JLabel("Vertical gap [%]:"); add(mVerticalGapLabel); - mVerticalGapSpinner = new JSpinner(new SpinnerNumberModel(0.0, 0.0, 50.0, 1.0)); + mVerticalGapSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mVerticalGap*100.0, 0.0, 50.0, 1.0)); mVerticalGapSpinner.addChangeListener(mChangeListener); add(mVerticalGapSpinner); mOverlapLabel = new JLabel("Overlap [%]:"); add(mOverlapLabel); - mOverlapSpinner = new JSpinner(new SpinnerNumberModel(0.0, -100.0, 100.0, 1.0)); + mOverlapSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mOverlapFraction*100.0, -100.0, 100.0, 1.0)); mOverlapSpinner.addChangeListener(mChangeListener); add(mOverlapSpinner); @@ -86,7 +82,7 @@ public class ImageProcessPanel extends JPanel implements Observer { add(mBlackborderDetectorLabel); mBlackborderDetectorCombo = new JComboBox<>(new String[] {"On", "Off"}); - mBlackborderDetectorCombo.setSelectedItem("On"); + mBlackborderDetectorCombo.setSelectedItem(mProcessConfig.mBlackBorderRemoval?"On":"Off"); mBlackborderDetectorCombo.setToolTipText("Enables or disables the blackborder detection and removal"); mBlackborderDetectorCombo.addActionListener(mActionListener); add(mBlackborderDetectorCombo); @@ -140,15 +136,7 @@ public class ImageProcessPanel extends JPanel implements Observer { ) ); } - - @Override - public void update(Observable pObs, Object pArg) { - if (pObs == mProcessConfig && pArg != this) { - mHorizontalDepthSpinner.setValue(mProcessConfig.getHorizontalDepth() * 100.0); - mVerticalDepthSpinner.setValue(mProcessConfig.getVerticalDepth() * 100.0); - mOverlapSpinner.setValue(mProcessConfig.getOverlapFraction() * 100.0); - } - } + private final ActionListener mActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedFramePanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedFramePanel.java index 53079df7..a7775f24 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedFramePanel.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedFramePanel.java @@ -12,11 +12,14 @@ import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import org.hyperion.hypercon.spec.DeviceConfig; import org.hyperion.hypercon.spec.DeviceType; import org.hyperion.hypercon.spec.LedFrameConstruction; +import org.hyperion.hypercon.spec.LedFrameConstruction.Direction; public class LedFramePanel extends JPanel { + private final DeviceConfig mDeviceConfig; private final LedFrameConstruction mLedFrameSpec; private JLabel mTypeLabel; @@ -41,9 +44,10 @@ public class LedFramePanel extends JPanel { private JLabel mOffsetLabel; private JSpinner mOffsetSpinner; - public LedFramePanel(LedFrameConstruction ledFrameSpec) { + public LedFramePanel(DeviceConfig pDeviceConfig, LedFrameConstruction ledFrameSpec) { super(); + mDeviceConfig = pDeviceConfig; mLedFrameSpec = ledFrameSpec; initialise(); @@ -53,24 +57,28 @@ public class LedFramePanel extends JPanel { mTypeLabel = new JLabel("LED Type:"); add(mTypeLabel); mTypeCombo = new JComboBox<>(DeviceType.values()); + mTypeCombo.setSelectedItem(mDeviceConfig.mType); mTypeCombo.addActionListener(mActionListener); add(mTypeCombo); mTopCornerLabel = new JLabel("Led in top corners"); add(mTopCornerLabel); mTopCornerCombo = new JComboBox<>(new Boolean[] {true, false}); + mTopCornerCombo.setSelectedItem(mLedFrameSpec.topCorners); mTopCornerCombo.addActionListener(mActionListener); add(mTopCornerCombo); mBottomCornerLabel = new JLabel("Led in bottom corners"); add(mBottomCornerLabel); mBottomCornerCombo = new JComboBox<>(new Boolean[] {true, false}); + mBottomCornerCombo.setSelectedItem(mLedFrameSpec.bottomCorners); mBottomCornerCombo.addActionListener(mActionListener); add(mBottomCornerCombo); mDirectionLabel = new JLabel("Direction"); add(mDirectionLabel); mDirectionCombo = new JComboBox<>(LedFrameConstruction.Direction.values()); + mDirectionCombo.setSelectedItem(mLedFrameSpec.clockwiseDirection?Direction.clockwise:Direction.counter_clockwise); mDirectionCombo.addActionListener(mActionListener); add(mDirectionCombo); @@ -151,10 +159,10 @@ public class LedFramePanel extends JPanel { } void updateLedConstruction() { - mLedFrameSpec.topLeftCorner = (Boolean)mTopCornerCombo.getSelectedItem(); - mLedFrameSpec.topRightCorner = (Boolean)mTopCornerCombo.getSelectedItem(); - mLedFrameSpec.bottomLeftCorner = (Boolean)mBottomCornerCombo.getSelectedItem(); - mLedFrameSpec.bottomRightCorner = (Boolean)mBottomCornerCombo.getSelectedItem(); + mDeviceConfig.mType = (DeviceType)mTypeCombo.getSelectedItem(); + + mLedFrameSpec.topCorners = (Boolean)mTopCornerCombo.getSelectedItem(); + mLedFrameSpec.bottomCorners = (Boolean)mBottomCornerCombo.getSelectedItem(); mLedFrameSpec.clockwiseDirection = ((LedFrameConstruction.Direction)mDirectionCombo.getSelectedItem()) == LedFrameConstruction.Direction.clockwise; mLedFrameSpec.firstLedOffset = (Integer)mOffsetSpinner.getValue(); diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/MiscConfigPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/MiscConfigPanel.java index 57c07af6..495bf11b 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/MiscConfigPanel.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/MiscConfigPanel.java @@ -80,8 +80,9 @@ public class MiscConfigPanel extends JPanel { add(mBootSequenceLabel); mBootSequenceCombo = new JComboBox<>(BootSequence.values()); - mBootSequenceCombo.setSelectedItem(BootSequence.rainbow); + mBootSequenceCombo.setSelectedItem(mMiscConfig.mBootSequence); mBootSequenceCombo.setToolTipText("The sequence used on startup to verify proper working of all the leds"); + mBootSequenceCombo.addActionListener(mActionListener); add(mBootSequenceCombo); layout.setHorizontalGroup(layout.createSequentialGroup() diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorConfig.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorConfig.java index 8aacfe8a..37ba404d 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorConfig.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorConfig.java @@ -7,43 +7,43 @@ import java.util.Locale; */ public class ColorConfig { /** The saturation gain (in HSV space) */ - double mSaturationGain = 1.0; + public double mSaturationGain = 1.0; /** The value gain (in HSV space) */ - double mValueGain = 1.5; + public double mValueGain = 1.5; /** The minimum required RED-value (in RGB space) */ - double mRedThreshold = 0.1; + public double mRedThreshold = 0.1; /** The gamma-curve correct for the RED-value (in RGB space) */ - double mRedGamma = 2.0; + public double mRedGamma = 2.0; /** The black-level of the RED-value (in RGB space) */ - double mRedBlacklevel = 0.0; + public double mRedBlacklevel = 0.0; /** The white-level of the RED-value (in RGB space) */ - double mRedWhitelevel = 0.8; + public double mRedWhitelevel = 0.8; /** The minimum required GREEN-value (in RGB space) */ - double mGreenThreshold = 0.1; + public double mGreenThreshold = 0.1; /** The gamma-curve correct for the GREEN-value (in RGB space) */ - double mGreenGamma = 2.0; + public double mGreenGamma = 2.0; /** The black-level of the GREEN-value (in RGB space) */ - double mGreenBlacklevel = 0.0; + public double mGreenBlacklevel = 0.0; /** The white-level of the GREEN-value (in RGB space) */ - double mGreenWhitelevel = 1.0; + public double mGreenWhitelevel = 1.0; /** The minimum required BLUE-value (in RGB space) */ - double mBlueThreshold = 0.1; + public double mBlueThreshold = 0.1; /** The gamma-curve correct for the BLUE-value (in RGB space) */ - double mBlueGamma = 2.0; + public double mBlueGamma = 2.0; /** The black-level of the BLUE-value (in RGB space) */ - double mBlueBlacklevel = 0.0; + public double mBlueBlacklevel = 0.0; /** The white-level of the BLUE-value (in RGB space) */ - double mBlueWhitelevel = 1.0; + public double mBlueWhitelevel = 1.0; /** The type of smoothing algorithm */ - ColorSmoothingType mSmoothingType = ColorSmoothingType.none; + public ColorSmoothingType mSmoothingType = ColorSmoothingType.none; /** The time constant for smoothing algorithm in milliseconds */ - int mSmoothingTime = 200; + public int mSmoothingTime_ms = 200; /** The update frequency of the leds in Hz */ - double mSmoothingUpdateFrequency = 20.0; + public double mSmoothingUpdateFrequency_Hz = 20.0; /** * Creates the JSON string of the configuration as used in the Hyperion daemon configfile @@ -138,8 +138,8 @@ public class ColorConfig { strBuf.append("\t\t\"smoothing\" :\n"); strBuf.append("\t\t{\n"); strBuf.append(String.format(Locale.ROOT, "\t\t\t\"type\" : \"%s\",\n", mSmoothingType.name())); - strBuf.append(String.format(Locale.ROOT, "\t\t\t\"time_ms\" : %d,\n", mSmoothingTime)); - strBuf.append(String.format(Locale.ROOT, "\t\t\t\"updateFrequency\" : %.4f\n", mSmoothingUpdateFrequency)); + strBuf.append(String.format(Locale.ROOT, "\t\t\t\"time_ms\" : %d,\n", mSmoothingTime_ms)); + strBuf.append(String.format(Locale.ROOT, "\t\t\t\"updateFrequency\" : %.4f\n", mSmoothingUpdateFrequency_Hz)); strBuf.append("\t\t}"); return strBuf.toString(); diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorSmoothingType.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorSmoothingType.java index b1f59255..6ac6ae9e 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorSmoothingType.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorSmoothingType.java @@ -1,6 +1,6 @@ package org.hyperion.hypercon.spec; -enum ColorSmoothingType { +public enum ColorSmoothingType { /** No smoothing in the time domain */ none("None"), diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/DeviceConfig.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/DeviceConfig.java index 9c693328..ae8607c7 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/DeviceConfig.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/DeviceConfig.java @@ -1,20 +1,21 @@ package org.hyperion.hypercon.spec; + /** * The device specific configuration */ public class DeviceConfig { /** The name of the device */ - String mName = "MyPi"; + public String mName = "MyPi"; /** The type specification of the device */ - DeviceType mType = DeviceType.ws2801; + public DeviceType mType = DeviceType.ws2801; /** The device 'file' name */ - String mOutput = "/dev/spidev0.0"; + public String mOutput = "/dev/spidev0.0"; /** The baudrate of the device */ - int mBaudrate = 1000000; - /** Flag indicating if the red and blue should be reversed */ - boolean mBgrOutput = false; + public int mBaudrate = 1000000; + /** Ordering of the rgb-color channels */ + public RgbByteOrder mRgbByteOrder = RgbByteOrder.rbg; /** * Creates the JSON string of the configuration as used in the Hyperion daemon configfile @@ -31,7 +32,7 @@ public class DeviceConfig { strBuf.append("\t/// - 'ws2801' this is the device (eg '/dev/spidev0.0')\n"); strBuf.append("\t/// - 'test' this is the file used to write test output (eg '/home/pi/hyperion.out')\n"); strBuf.append("\t/// * 'rate' : The baudrate of the output to the device (only applicable for 'ws2801')\n"); - strBuf.append("\t/// * 'bgr-output' : Use BGR output instead of RGB (reverse red and blue).\n"); + strBuf.append("\t/// * 'colorOrder' : The order of the byte color channel (rgb, rbg, bgr, brg, gbr, grb).\n"); strBuf.append("\t\"device\" :\n"); strBuf.append("\t{\n"); @@ -40,7 +41,7 @@ public class DeviceConfig { strBuf.append("\t\t\"type\" : \"").append(mType.name()).append("\",\n"); strBuf.append("\t\t\"output\" : \"").append(mOutput).append("\",\n"); strBuf.append("\t\t\"rate\" : ").append(mBaudrate).append(",\n"); - strBuf.append("\t\t\"bgr-output\" : ").append(mBgrOutput).append("\n"); + strBuf.append("\t\t\"colorOrder\" : ").append(mRgbByteOrder.name()).append("\n"); strBuf.append("\t}"); diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ImageProcessConfig.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ImageProcessConfig.java index 18810039..21302be6 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ImageProcessConfig.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ImageProcessConfig.java @@ -13,20 +13,20 @@ import org.hyperion.hypercon.LedFrameFactory; public class ImageProcessConfig extends Observable { /** The 'integration depth' of the leds along the horizontal axis of the tv */ - private double mHorizontalDepth = 0.08; + public double mHorizontalDepth = 0.08; /** The 'integration depth' of the leds along the vertical axis of the tv */ - private double mVerticalDepth = 0.05; + public double mVerticalDepth = 0.05; /** The gap between the border integration area for the horizontal leds */ - private double mHorizontalGap = 0.0; + public double mHorizontalGap = 0.0; /** The gap between the border integration area for the vertical leds */ - private double mVerticalGap = 0.0; + public double mVerticalGap = 0.0; /** The fraction of overlap from one to another led */ - private double mOverlapFraction = 0.0; + public double mOverlapFraction = 0.0; /** Flag indicating that black borders are excluded in the image processing */ - private boolean mBlackBorderRemoval = true; + public boolean mBlackBorderRemoval = true; /** * Returns the horizontal depth (top and bottom) of the image integration as a fraction of the diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/LedFrameConstruction.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/LedFrameConstruction.java index 6b8d815f..068a9c11 100644 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/LedFrameConstruction.java +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/LedFrameConstruction.java @@ -21,14 +21,10 @@ public class LedFrameConstruction extends Observable { /** True if the leds are organised clockwise else false (counter clockwise) */ public boolean clockwiseDirection = true; - /** True if the top left corner has a led else false */ - public boolean topLeftCorner = true; - /** True if the top right corner has a led else false */ - public boolean topRightCorner = true; - /** True if the bottom left corner has a led else false */ - public boolean bottomLeftCorner = true; - /** True if the bottom right corner has a led else false */ - public boolean bottomRightCorner = true; + /** True if the top corners have a led else false */ + public boolean topCorners = true; + /** True if the bottom corners have a led else false */ + public boolean bottomCorners = true; /** The number of leds between the top-left corner and the top-right corner of the screen (excluding the corner leds) */ @@ -54,10 +50,8 @@ public class LedFrameConstruction extends Observable { */ public int getLedCount() { int cornerLedCnt = 0; - if (topLeftCorner) ++cornerLedCnt; - if (topRightCorner) ++cornerLedCnt; - if (bottomLeftCorner) ++cornerLedCnt; - if (bottomRightCorner) ++cornerLedCnt; + if (topCorners) cornerLedCnt+=2; + if (bottomCorners) cornerLedCnt+=2; return topLedCnt + bottomLedCnt + leftLedCnt + rightLedCnt + cornerLedCnt; } diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/RgbByteOrder.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/RgbByteOrder.java new file mode 100644 index 00000000..baa46b8a --- /dev/null +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/RgbByteOrder.java @@ -0,0 +1,11 @@ +package org.hyperion.hypercon.spec; + +public enum RgbByteOrder { + rgb, + rbg, + grb, + gbr, + brg, + bgr; + +} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/test/TesConfigWriter.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/test/TesConfigWriter.java new file mode 100644 index 00000000..4de723af --- /dev/null +++ b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/test/TesConfigWriter.java @@ -0,0 +1,46 @@ +package org.hyperion.hypercon.test; + +import org.hyperion.hypercon.ConfigurationFile; +import org.hyperion.hypercon.spec.ColorConfig; +import org.hyperion.hypercon.spec.DeviceConfig; +import org.hyperion.hypercon.spec.DeviceType; +import org.hyperion.hypercon.spec.ImageProcessConfig; +import org.hyperion.hypercon.spec.LedFrameConstruction; +import org.hyperion.hypercon.spec.MiscConfig; +import org.hyperion.hypercon.spec.RgbByteOrder; + +public class TesConfigWriter { + + public static void main(String[] pArgs) { + DeviceConfig deviceConfig = new DeviceConfig(); + LedFrameConstruction frameConfig = new LedFrameConstruction(); + ColorConfig colorConfig = new ColorConfig(); + ImageProcessConfig imageConfig = new ImageProcessConfig(); + MiscConfig miscConfig = new MiscConfig(); + + deviceConfig.mBaudrate = 4800; + deviceConfig.mRgbByteOrder = RgbByteOrder.bgr; + deviceConfig.mName = "DAG"; + deviceConfig.mOutput = "/dev/null"; + deviceConfig.mType = DeviceType.ldp6803; + + + ConfigurationFile configFile = new ConfigurationFile(); + configFile.store(deviceConfig); + configFile.store(frameConfig); + configFile.store(colorConfig); + configFile.store(imageConfig); + configFile.store(miscConfig); + configFile.save("./HyperCon.dat"); + + ConfigurationFile configFile2 = new ConfigurationFile(); + configFile2.load("./HyperCon.dat"); + configFile2.restore(deviceConfig); + configFile2.restore(frameConfig); + configFile2.restore(colorConfig); + configFile2.restore(imageConfig); + configFile2.restore(miscConfig); + + System.out.println(configFile2); + } +}