From 78af2d62c2fd69c7fe70fe48f8310075e023bd7c Mon Sep 17 00:00:00 2001 From: "T. van der Zwan" Date: Fri, 10 Jan 2014 21:04:49 +0100 Subject: [PATCH] Moved HyperCon to seperate repository Former-commit-id: 89991359edc8346928cdac3c4955c25a922598ee --- src/config-tool/.gitignore | 1 - src/config-tool/ConfigTool/.classpath | 6 - src/config-tool/ConfigTool/.gitignore | 3 - src/config-tool/ConfigTool/.project | 17 - src/config-tool/ConfigTool/build.xml | 32 -- .../hyperion/hypercon/ConfigurationFile.java | 288 --------------- .../org/hyperion/hypercon/HyperConConfig.java | 6 - .../org/hyperion/hypercon/HyperConIcon_32.png | Bin 2323 -> 0 bytes .../org/hyperion/hypercon/HyperConIcon_64.png | Bin 7642 -> 0 bytes .../hyperion/hypercon/JsonStringBuffer.java | 226 ------------ .../hyperion/hypercon/LedFrameFactory.java | 274 --------------- .../src/org/hyperion/hypercon/LedString.java | 105 ------ .../src/org/hyperion/hypercon/Main.java | 87 ----- .../hypercon/gui/ColorSmoothingPanel.java | 141 -------- .../hypercon/gui/ColorTransformPanel.java | 277 --------------- .../hyperion/hypercon/gui/ColorsPanel.java | 130 ------- .../hyperion/hypercon/gui/ConfigPanel.java | 194 ---------- .../hyperion/hypercon/gui/DevicePanel.java | 117 ------- .../hypercon/gui/EffectEnginePanel.java | 175 ---------- .../hypercon/gui/FrameGrabberPanel.java | 137 -------- .../hyperion/hypercon/gui/ImageComponent.java | 27 -- .../hypercon/gui/ImageProcessPanel.java | 177 ---------- .../hyperion/hypercon/gui/InterfacePanel.java | 215 ------------ .../hypercon/gui/LedDivideDialog.java | 48 --- .../hyperion/hypercon/gui/LedFramePanel.java | 186 ---------- .../hypercon/gui/LedSimulationComponent.java | 330 ------------------ .../hypercon/gui/LedSimulationWorker.java | 134 ------- .../hyperion/hypercon/gui/LedTvComponent.java | 134 ------- .../gui/TestImageBBB_01.png.REMOVED.git-id | 1 - .../gui/TestImageBBB_02.png.REMOVED.git-id | 1 - .../gui/TestImageBBB_03.png.REMOVED.git-id | 1 - .../gui/TestImage_01.png.REMOVED.git-id | 1 - .../gui/TestImage_02.png.REMOVED.git-id | 1 - .../gui/TestImage_03.png.REMOVED.git-id | 1 - .../hyperion/hypercon/gui/TestImage_04.png | Bin 66588 -> 0 bytes .../gui/TestImage_05.png.REMOVED.git-id | 1 - .../org/hyperion/hypercon/gui/XbmcPanel.java | 263 -------------- .../hypercon/gui/device/DeviceTypePanel.java | 24 -- .../hypercon/gui/device/LightPackPanel.java | 63 ---- .../hypercon/gui/device/SerialPanel.java | 104 ------ .../hypercon/gui/device/TestDevicePanel.java | 63 ---- .../hypercon/gui/device/Ws2801Panel.java | 104 ------ .../hyperion/hypercon/spec/BorderSide.java | 37 -- .../hypercon/spec/ColorByteOrder.java | 5 - .../hyperion/hypercon/spec/ColorConfig.java | 98 ------ .../hypercon/spec/ColorSmoothingType.java | 17 - .../hyperion/hypercon/spec/DeviceConfig.java | 49 --- .../hyperion/hypercon/spec/DeviceType.java | 89 ----- .../hypercon/spec/ImageProcessConfig.java | 175 ---------- .../src/org/hyperion/hypercon/spec/Led.java | 33 -- .../hypercon/spec/LedFrameConstruction.java | 63 ---- .../hyperion/hypercon/spec/MiscConfig.java | 191 ---------- .../hypercon/spec/TransformConfig.java | 111 ------ .../hypercon/test/TesConfigWriter.java | 46 --- 54 files changed, 5009 deletions(-) delete mode 100644 src/config-tool/.gitignore delete mode 100644 src/config-tool/ConfigTool/.classpath delete mode 100644 src/config-tool/ConfigTool/.gitignore delete mode 100644 src/config-tool/ConfigTool/.project delete mode 100644 src/config-tool/ConfigTool/build.xml delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/ConfigurationFile.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConConfig.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConIcon_32.png delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConIcon_64.png delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/JsonStringBuffer.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedFrameFactory.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedString.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorSmoothingPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorTransformPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorsPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ConfigPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/DevicePanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/EffectEnginePanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/FrameGrabberPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageComponent.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageProcessPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/InterfacePanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedDivideDialog.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedFramePanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationComponent.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationWorker.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedTvComponent.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_01.png.REMOVED.git-id delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_02.png.REMOVED.git-id delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_03.png.REMOVED.git-id delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_01.png.REMOVED.git-id delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_02.png.REMOVED.git-id delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_03.png.REMOVED.git-id delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_04.png delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_05.png.REMOVED.git-id delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/XbmcPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/DeviceTypePanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/LightPackPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/SerialPanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/TestDevicePanel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/Ws2801Panel.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/BorderSide.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorByteOrder.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorConfig.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorSmoothingType.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/DeviceConfig.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/DeviceType.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ImageProcessConfig.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/Led.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/LedFrameConstruction.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/MiscConfig.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/TransformConfig.java delete mode 100644 src/config-tool/ConfigTool/src/org/hyperion/hypercon/test/TesConfigWriter.java diff --git a/src/config-tool/.gitignore b/src/config-tool/.gitignore deleted file mode 100644 index e8d03113..00000000 --- a/src/config-tool/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.metadata diff --git a/src/config-tool/ConfigTool/.classpath b/src/config-tool/ConfigTool/.classpath deleted file mode 100644 index cd43896c..00000000 --- a/src/config-tool/ConfigTool/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/config-tool/ConfigTool/.gitignore b/src/config-tool/ConfigTool/.gitignore deleted file mode 100644 index 604b51ee..00000000 --- a/src/config-tool/ConfigTool/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.settings -/classes -/hyerpcon.dat diff --git a/src/config-tool/ConfigTool/.project b/src/config-tool/ConfigTool/.project deleted file mode 100644 index 9e7af111..00000000 --- a/src/config-tool/ConfigTool/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - ConfigTool - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/src/config-tool/ConfigTool/build.xml b/src/config-tool/ConfigTool/build.xml deleted file mode 100644 index 0dd72a19..00000000 --- a/src/config-tool/ConfigTool/build.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/ConfigurationFile.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/ConfigurationFile.java deleted file mode 100644 index 49d36919..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/ConfigurationFile.java +++ /dev/null @@ -1,288 +0,0 @@ -package org.hyperion.hypercon; - -import java.awt.Color; -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.lang.reflect.ParameterizedType; -import java.util.Properties; -import java.util.Vector; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -/** - * Class for supporting the serialisation and deserialisation of HyperCon settings. - */ -public class ConfigurationFile { - - /** Temporary storage of the HyperCon configuration */ - private final Properties mProps = new Properties(); - - /** - * Loads the configuration of HyperCon from the given filename into this {@link ConfigurationFile} - * - * @param pFilename The absolute filename containing the configuration - */ - public void load(String pFilename) { - mProps.clear(); -// try (InputStream in = new InflaterInputStream(new FileInputStream(pFilename))){ - try (InputStream in = new GZIPInputStream(new FileInputStream(pFilename))){ -// try (InputStream in = new FileInputStream(pFilename)) { - mProps.load(in); - } catch (Throwable t) { - // TODO Auto-generated catch block - t.printStackTrace(); - } - } - - /** - * Saves the configuration of this {@link ConfigurationFile} to the given filename - * - * @param pFilename The absolute filename to which to save the HyperCon configuration - */ - 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))) { - mProps.store(out, "Pesistent settings file for HyperCon"); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Stores the given object to the local properties object - * - * @param pObj The object to store - */ - public void store(Object pObj) { - store(pObj, pObj.getClass().getSimpleName(), ""); - } - - /** - * Stores the given object to the local properties object (with given preamble and postamble) - * - * @param pObj The object to store - * @param preamble The preamble prepended to the key of the object members - * @param postamble The postamble appended to the key of the object members - */ - public void store(Object pObj, String preamble, String postamble) { - 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 = preamble + "." + field.getName() + postamble; - try { - Object value = field.get(pObj); - - if (field.getType() == boolean.class) { - mProps.setProperty(key, Boolean.toString((boolean) value)); - } else if (field.getType() == int.class) { - mProps.setProperty(key, Integer.toString((int) value)); - } else if (field.getType() == double.class) { - mProps.setProperty(key, Double.toString((double) value)); - } else if (field.getType() == String.class) { - mProps.setProperty(key, (String)value); - } else if (field.getType() == Color.class) { - Color color = (Color)value; - mProps.setProperty(key, String.format("[%d; %d; %d]", color.getRed(), color.getGreen(), color.getBlue())); - } else if (value.getClass().isEnum()) { - mProps.setProperty(key, ((Enum)value).name()); - } else if (value instanceof Vector) { - @SuppressWarnings("unchecked") - Vector v = (Vector) value; - for (int i=0; i vector; - try { - vector = (Vector)field.get(pObj); - } catch (Throwable t) { - t.printStackTrace(); - break; - } - // Clear existing elements from the vector - vector.clear(); - - // Iterate through the properties to find the indices of the vector - int i=0; - while (true) { - String curIndexKey = pPreamble + field.getName() + "[" + i + "]"; - Properties elemProps = new Properties(); - // Find all the elements for the current vector index - for (Object keyObj : pProps.keySet()) { - String keyStr = (String)keyObj; - if (keyStr.startsWith(curIndexKey)) { - // Remove the name and dot - elemProps.put(keyStr.substring(curIndexKey.length()+1), pProps.get(keyStr)); - } - } - if (elemProps.isEmpty()) { - // Found no more elements for the vector - break; - } - - // Construct new instance of vectors generic type - ParameterizedType vectorElementType = (ParameterizedType) field.getGenericType(); - Class vectorElementClass = (Class) vectorElementType.getActualTypeArguments()[0]; - // Find the constructor with no arguments and create a new instance - Object newElement = null; - try { - newElement = vectorElementClass.getConstructor().newInstance(); - } catch (Throwable t) { - System.err.println("Failed to find empty default constructor for " + vectorElementClass.getName()); - break; - } - if (newElement == null) { - System.err.println("Failed to construct instance for " + vectorElementClass.getName()); - break; - } - - // Restore the instance members from the collected properties - restore(newElement, elemProps, ""); - - // Add the instance to the vector - vector.addElement(newElement); - - ++i; - } - - continue; - } - - String key = pPreamble + 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() == Color.class) { - String[] channelValues = value.substring(1, value.length()-1).split(";"); - field.set(pObj, new Color(Integer.parseInt(channelValues[0].trim()), Integer.parseInt(channelValues[1].trim()), Integer.parseInt(channelValues[2].trim()))); - } else if (field.getType() == String.class) { - field.set(pObj, 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 if (field.getType() == Object.class) { - // We can not infer from the type of the field, let's try the actual stored value - if (value.isEmpty()) { - // We will never known ... - } else if (value.startsWith("[") && value.endsWith("]")) { - String[] channelValues = value.substring(1, value.length()-1).split(";"); - field.set(pObj, new Color(Integer.parseInt(channelValues[0].trim()), Integer.parseInt(channelValues[1].trim()), Integer.parseInt(channelValues[2].trim()))); - } else if (value.startsWith("\"") && value.endsWith("\"")) { - field.set(pObj, value.substring(1, value.length()-1)); - } else { - try { - int i = Integer.parseInt(value); - field.set(pObj, i); - } catch (Throwable t1) { - try { - double d = Double.parseDouble(value); - field.set(pObj, d); - } catch (Throwable t2) { - try { - boolean bool = Boolean.parseBoolean(value); - field.set(pObj, bool); - } catch (Throwable t3) { - - } - } - } - } - } - } catch (Throwable t) { - System.out.println("Failed to parse value(" + value + ") for " + key); - t.printStackTrace(); - } - } - } - - /** - * Returns a String representation of this ConfigurationFile, which is the {@link #toString()} - * of the underlying {@link Properties} - * - * @return The String representation of this ConfigurationFile - */ - @Override - public String toString() { - return mProps.toString(); - } -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConConfig.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConConfig.java deleted file mode 100644 index 25025f89..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.hyperion.hypercon; - -public class HyperConConfig { - - public boolean loadDefaultEffect = true; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConIcon_32.png b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/HyperConIcon_32.png deleted file mode 100644 index c054e66aea61ccded6fb5757bd48ae62b70e23ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2323 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 IM6N<$f^p5RjsO4v diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/JsonStringBuffer.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/JsonStringBuffer.java deleted file mode 100644 index 853423d2..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/JsonStringBuffer.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.hyperion.hypercon; - -public class JsonStringBuffer { - - private final StringBuffer mStrBuf = new StringBuffer(); - - private final int mStartIndentLevel; - private int mIndentLevel = 0; - - /** Flag indicating that the parts written are 'commented-out' */ - private boolean mComment = false; - - public JsonStringBuffer() { - this(0); - - mStrBuf.append("{\n"); - ++mIndentLevel; - } - - public JsonStringBuffer(int pIndentLevel) { - mStartIndentLevel = pIndentLevel; - mIndentLevel = pIndentLevel; - } - - public void newLine() { - mStrBuf.append('\n'); - } - - public void finish() { - - for (int i=0; i construct(LedFrameConstruction frameSpec, ImageProcessConfig processConfig) { - Vector mLeds = new Vector<>(); - - int totalLedCount = frameSpec.getLedCount(); - if (totalLedCount <= 0) { - return mLeds; - } - - // Determine the led-number of the top-left led - int iLed = (totalLedCount - frameSpec.firstLedOffset)%totalLedCount; - if (iLed < 0) { - iLed += totalLedCount; - } - - // Construct the top-left led (if top-left is enabled) - if (frameSpec.topCorners) { - mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 0.0, processConfig.getOverlapFraction(), BorderSide.top_left)); - iLed = increase(frameSpec, iLed); - } - - // Construct all leds along the top of the screen (if any) - if (frameSpec.topLedCnt > 0) { - // Determine the led-spacing - int ledCnt = frameSpec.topLedCnt; - double ledSpacing = (double)1.0/(ledCnt); - - for (int iTop=0; iTop 0) { - // Determine the led-spacing - int ledCnt = frameSpec.rightLedCnt; - double ledSpacing = 1.0/ledCnt; - - for (int iRight=0; iRight 0) { - // Determine the led-spacing (based on top-leds [=bottom leds + gap size]) - int ledCnt = frameSpec.topLedCnt; - double ledSpacing = (double)1.0/ledCnt; - - for (int iBottom=(ledCnt-1); iBottom>=0; --iBottom) { - // Special case for the bottom-gap - if (iBottom > (frameSpec.bottomLedCnt-1)/2 && iBottom < ledCnt - frameSpec.bottomLedCnt/2) { - continue; - } - // Compute the location of this led - double led_x = ledSpacing/2.0 + iBottom * ledSpacing; - double led_y = 1.0; - - // Construct and add the single led specification to the list of leds - mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.bottom)); - iLed = increase(frameSpec, iLed); - } - } - - // Construct the bottom-left led (if bottom-left is enabled) - if (frameSpec.bottomCorners) { - mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 1.0, processConfig.getOverlapFraction(), BorderSide.bottom_left)); - iLed = increase(frameSpec, iLed); - } - - // Construct all leds along the left of the screen (if any) - if (frameSpec.leftLedCnt > 0) { - // Determine the led-spacing - int ledCnt = frameSpec.leftLedCnt; - double ledSpacing = (double)1.0/ledCnt; - - for (int iRight=(ledCnt-1); iRight>=0; --iRight) { - // Compute the location of this led - double led_x = 0.0; - double led_y = ledSpacing/2.0 + iRight * ledSpacing; - - // Construct and add the single led specification to the list of leds - mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.left)); - iLed = increase(frameSpec, iLed); - } - } - - Collections.sort(mLeds, new Comparator() { - @Override - public int compare(Led o1, Led o2) { - return Integer.compare(o1.mLedSeqNr, o2.mLedSeqNr); - } - }); - return mLeds; - } - - /** - * Constructs the specification of a single led - * - * @param pFrameSpec The overall led-frame specification - * @param pProcessSpec The overall image-processing specification - * @param seqNr The number of the led - * @param x_frac The x location of the led in fractional range [0.0; 1.0] - * @param y_frac The y location of the led in fractional range [0.0; 1.0] - * @param overlap_frac The fractional overlap of the led integration with its neighbor - * @param pBorderSide The side on which the led is located - * - * @return The image integration specifications of the single led - */ - private static Led createLed(LedFrameConstruction pFrameSpec, ImageProcessConfig pProcessSpec, int seqNr, double x_frac, double y_frac, double overlap_frac, BorderSide pBorderSide) { - Led led = new Led(); - led.mLedSeqNr = seqNr; - led.mLocation = new Point2D.Double(x_frac, y_frac); - led.mSide = pBorderSide; - - double xFrac = pProcessSpec.getVerticalGap() + (1.0-2*pProcessSpec.getVerticalGap()) * x_frac; - double yFrac = pProcessSpec.getHorizontalGap() + (1.0-2*pProcessSpec.getHorizontalGap()) * y_frac; - double widthFrac = ((1.0-2*pProcessSpec.getVerticalGap())/pFrameSpec.topLedCnt * (1.0 + overlap_frac))/2.0; - double heightFrac = ((1.0-2*pProcessSpec.getHorizontalGap())/pFrameSpec.leftLedCnt * (1.0 + overlap_frac))/2.0; - - double horizontalDepth = Math.min(1.0 - pProcessSpec.getHorizontalGap(), pProcessSpec.getHorizontalDepth()); - double verticalDepth = Math.min(1.0 - pProcessSpec.getVerticalGap(), pProcessSpec.getVerticalDepth()); - - switch (pBorderSide) { - case top_left: { - led.mImageRectangle = new Rectangle2D.Double( - pProcessSpec.getVerticalGap(), - pProcessSpec.getHorizontalGap(), - verticalDepth, - horizontalDepth); - break; - } - case top_right: { - led.mImageRectangle = new Rectangle2D.Double( - 1.0-pProcessSpec.getVerticalGap()-verticalDepth, - pProcessSpec.getHorizontalGap(), - verticalDepth, - horizontalDepth); - break; - } - case bottom_left: { - led.mImageRectangle = new Rectangle2D.Double( - pProcessSpec.getVerticalGap(), - 1.0-pProcessSpec.getHorizontalGap()-horizontalDepth, - verticalDepth, - horizontalDepth); - break; - } - case bottom_right: { - led.mImageRectangle = new Rectangle2D.Double( - 1.0-pProcessSpec.getVerticalGap()-verticalDepth, - 1.0-pProcessSpec.getHorizontalGap()-horizontalDepth, - verticalDepth, - horizontalDepth); - break; - } - case top:{ - double intXmin_frac = Math.max(0.0, xFrac-widthFrac); - double intXmax_frac = Math.min(xFrac+widthFrac, 1.0); - led.mImageRectangle = new Rectangle2D.Double( - intXmin_frac, - pProcessSpec.getHorizontalGap(), - intXmax_frac-intXmin_frac, - horizontalDepth); - - break; - } - case bottom: - { - double intXmin_frac = Math.max(0.0, xFrac-widthFrac); - double intXmax_frac = Math.min(xFrac+widthFrac, 1.0); - - led.mImageRectangle = new Rectangle2D.Double( - intXmin_frac, - 1.0-pProcessSpec.getHorizontalGap()-horizontalDepth, - intXmax_frac-intXmin_frac, - horizontalDepth); - break; - } - case left: { - double intYmin_frac = Math.max(0.0, yFrac-heightFrac); - double intYmax_frac = Math.min(yFrac+heightFrac, 1.0); - led.mImageRectangle = new Rectangle2D.Double( - pProcessSpec.getVerticalGap(), - intYmin_frac, - verticalDepth, - intYmax_frac-intYmin_frac); - break; - } - case right: - double intYmin_frac = Math.max(0.0, yFrac-heightFrac); - double intYmax_frac = Math.min(yFrac+heightFrac, 1.0); - led.mImageRectangle = new Rectangle2D.Double( - 1.0-pProcessSpec.getVerticalGap()-verticalDepth, - intYmin_frac, - verticalDepth, - intYmax_frac-intYmin_frac); - break; - } - - return led; - } - -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedString.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedString.java deleted file mode 100644 index af5c852e..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/LedString.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.hyperion.hypercon; - -import java.io.FileWriter; -import java.io.IOException; -import java.util.Locale; -import java.util.Vector; - -import org.hyperion.hypercon.spec.ColorConfig; -import org.hyperion.hypercon.spec.DeviceConfig; -import org.hyperion.hypercon.spec.ImageProcessConfig; -import org.hyperion.hypercon.spec.Led; -import org.hyperion.hypercon.spec.LedFrameConstruction; -import org.hyperion.hypercon.spec.MiscConfig; -/** - * The full configuration of Hyperion with sub-items for device, color and miscelanuous items. - */ -public class LedString { - /** The configuration of the output device */ - public final DeviceConfig mDeviceConfig = new DeviceConfig(); - - /** THe configuration of the 'physical' led frame */ - public final LedFrameConstruction mLedFrameConfig = new LedFrameConstruction(); - - /** The configuration of the image processing */ - public final ImageProcessConfig mProcessConfig = new ImageProcessConfig(); - - /** The color adjustment configuration */ - public final ColorConfig mColorConfig = new ColorConfig(); - - /** The miscellaneous configuration (bootsequence, blackborder detector, etc) */ - public final MiscConfig mMiscConfig = new MiscConfig(); - - /** The translation of the led frame construction and image processing to individual led configuration */ - public Vector leds; - - /** - * Writes the configuration to the given file - * - * @param mFilename The absolute filename - * - * @throws IOException If unable to write the given file - */ - public void saveConfigFile(String mFilename) throws IOException { - - try (FileWriter fw = new FileWriter(mFilename)) { - fw.write("// Automatically generated configuration file for 'Hyperion daemon'\n"); - fw.write("// Generated by: HyperCon (The Hyperion deamon configuration file builder\n"); - fw.write("\n"); - fw.write("{\n"); - - String deviceJson = mDeviceConfig.toJsonString(); - fw.write(deviceJson + ",\n\n"); - - String colorJson = mColorConfig.toJsonString(); - fw.write(colorJson + ",\n\n"); - - JsonStringBuffer jsonBuf = new JsonStringBuffer(1); - - ledsAppendTo(jsonBuf); - - jsonBuf.newLine(); - - mProcessConfig.appendTo(jsonBuf); - - jsonBuf.newLine(); - - mMiscConfig.appendTo(jsonBuf); - - jsonBuf.newLine(); - - jsonBuf.addValue("endOfJson", "endOfJson", true); - - fw.write(jsonBuf.toString()); - - fw.write("}\n"); - } catch (IOException e) { - throw e; - } - } - - void ledsAppendTo(JsonStringBuffer pJsonBuf) { - String ledComment = - " The configuration for each individual led. This contains the specification of the area \n" + - " averaged of an input image for each led to determine its color. Each item in the list \n" + - " contains the following fields:\n" + - " * index: The index of the led. This determines its location in the string of leds; zero \n" + - " being the first led.\n" + - " * hscan: The fractional part of the image along the horizontal used for the averaging \n" + - " (minimum and maximum inclusive)\n" + - " * vscan: The fractional part of the image along the vertical used for the averaging \n" + - " (minimum and maximum inclusive)\n"; - pJsonBuf.writeComment(ledComment); - - pJsonBuf.startArray("leds"); - for (Led led : leds) - { - pJsonBuf.startObject(""); - pJsonBuf.addValue("index", led.mLedSeqNr, false); - pJsonBuf.addRawValue("hscan", String.format(Locale.ENGLISH, "{ %1$cminimum%1$c : %2$.4f, %1$cmaximum%1$c : %3$.4f }", '"', led.mImageRectangle.getMinX(), led.mImageRectangle.getMaxX()), false); - pJsonBuf.addRawValue("vscan", String.format(Locale.ENGLISH, "{ %1$cminimum%1$c : %2$.4f, %1$cmaximum%1$c : %3$.4f }", '"', led.mImageRectangle.getMinY(), led.mImageRectangle.getMaxY()), true); - pJsonBuf.stopObject(led.equals(leds.get(leds.size()-1))); - } - pJsonBuf.stopArray(false); - } -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java deleted file mode 100644 index a3cd9fe9..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/Main.java +++ /dev/null @@ -1,87 +0,0 @@ -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; - -import org.hyperion.hypercon.gui.ConfigPanel; -import org.hyperion.hypercon.spec.TransformConfig; - -/** - * (static) Main-class for starting HyperCon (the Hyperion configuration file builder) as a standard - * JAVA application (contains the entry-point). - */ -public class Main { - public static final String configFilename = "hypercon.dat"; - - /** Some application settings (for easy/dirty access) */ - public static final HyperConConfig HyperConConfig = new HyperConConfig(); - - /** - * Entry point to start HyperCon - * - * @param pArgs HyperCon does not have command line arguments - */ - public static void main(String[] pArgs) { - final String versionStr = Main.class.getPackage().getImplementationVersion(); - final LedString ledString = new LedString(); - - try { - // Configure swing to use the system default look and feel - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) {} - - // Create a frame for the configuration panel - JFrame frame = new JFrame(); - String title = "Hyperion configuration Tool" + ((versionStr != null && !versionStr.isEmpty())? (" (" + versionStr + ")") : ""); - frame.setTitle(title); - 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) { - try { - ConfigurationFile configFile = new ConfigurationFile(); - configFile.store(Main.HyperConConfig); - configFile.store(ledString.mDeviceConfig); - configFile.store(ledString.mLedFrameConfig); - configFile.store(ledString.mProcessConfig); - configFile.store(ledString.mColorConfig); - configFile.store(ledString.mMiscConfig); - configFile.save(configFilename); - } catch (Throwable t) { - System.err.println("Failed to save " + configFilename); - } - } - }); - - if (new File(configFilename).exists()) { - try { - ConfigurationFile configFile = new ConfigurationFile(); - configFile.load(configFilename); - configFile.restore(Main.HyperConConfig); - configFile.restore(ledString.mDeviceConfig); - configFile.restore(ledString.mLedFrameConfig); - configFile.restore(ledString.mProcessConfig); - configFile.restore(ledString.mColorConfig); - configFile.restore(ledString.mMiscConfig); - } catch (Throwable t) { - System.err.println("Failed to load " + configFilename); - } - if (ledString.mColorConfig.mTransforms.isEmpty()) { - ledString.mColorConfig.mTransforms.add(new TransformConfig()); - } - } - - // Add the HyperCon configuration panel - frame.setContentPane(new ConfigPanel(ledString)); - - // Show the frame - frame.setVisible(true); - } -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorSmoothingPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorSmoothingPanel.java deleted file mode 100644 index 376c6391..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorSmoothingPanel.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.Transient; - -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -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; -import org.hyperion.hypercon.spec.ColorSmoothingType; - -public class ColorSmoothingPanel extends JPanel { - - private final ColorConfig mColorConfig; - - private JCheckBox mEnabledCheck; - private JLabel mTypeLabel; - private JComboBox mTypeCombo; - private JLabel mTimeLabel; - private JSpinner mTimeSpinner; - private JLabel mUpdateFrequencyLabel; - private JSpinner mUpdateFrequencySpinner; - - public ColorSmoothingPanel(final ColorConfig pColorConfig) { - super(); - - mColorConfig = pColorConfig; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("Smoothing")); - - mEnabledCheck = new JCheckBox("Enabled"); - mEnabledCheck.setSelected(mColorConfig.mSmoothingEnabled); - mEnabledCheck.addActionListener(mActionListener); - add(mEnabledCheck); - - mTypeLabel = new JLabel("Type: "); - add(mTypeLabel); - - mTypeCombo = new JComboBox<>(ColorSmoothingType.values()); - mTypeCombo.setSelectedItem(mColorConfig.mSmoothingType); - mTypeCombo.addActionListener(mActionListener); - add(mTypeCombo); - - mTimeLabel = new JLabel("Time [ms]: "); - add(mTimeLabel); - - mTimeSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mSmoothingTime_ms, 1, 600, 100)); - mTimeSpinner.addChangeListener(mChangeListener); - add(mTimeSpinner); - - mUpdateFrequencyLabel = new JLabel("Update Freq. [Hz]: "); - add(mUpdateFrequencyLabel); - - mUpdateFrequencySpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mSmoothingUpdateFrequency_Hz, 1, 100, 1)); - mUpdateFrequencySpinner.addChangeListener(mChangeListener); - add(mUpdateFrequencySpinner); - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mEnabledCheck) - .addComponent(mTypeLabel) - .addComponent(mTimeLabel) - .addComponent(mUpdateFrequencyLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mEnabledCheck) - .addComponent(mTypeCombo) - .addComponent(mTimeSpinner) - .addComponent(mUpdateFrequencySpinner) - )); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(mEnabledCheck) - .addGroup(layout.createParallelGroup() - .addComponent(mTypeLabel) - .addComponent(mTypeCombo) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mTimeLabel) - .addComponent(mTimeSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mUpdateFrequencyLabel) - .addComponent(mUpdateFrequencySpinner) - )); - - toggleEnabled(mColorConfig.mSmoothingEnabled); - } - - private void toggleEnabled(boolean pEnabled) { - mTypeLabel.setEnabled(pEnabled); - mTypeCombo.setEnabled(pEnabled); - mTimeLabel.setEnabled(pEnabled); - mTimeSpinner.setEnabled(pEnabled); - mUpdateFrequencyLabel.setEnabled(pEnabled); - mUpdateFrequencySpinner.setEnabled(pEnabled); - } - - private final ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mColorConfig.mSmoothingEnabled = mEnabledCheck.isSelected(); - mColorConfig.mSmoothingType = (ColorSmoothingType)mTypeCombo.getSelectedItem(); - - toggleEnabled(mColorConfig.mSmoothingEnabled); - } - }; - - private final ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - mColorConfig.mSmoothingTime_ms = (Integer)mTimeSpinner.getValue(); - mColorConfig.mSmoothingUpdateFrequency_Hz = (Double)mUpdateFrequencySpinner.getValue(); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorTransformPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorTransformPanel.java deleted file mode 100644 index e3c011f1..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorTransformPanel.java +++ /dev/null @@ -1,277 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.beans.Transient; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.GroupLayout; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSpinner; -import javax.swing.JTextField; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import org.hyperion.hypercon.spec.TransformConfig; - -/** - * Configuration panel for the ColorConfig. - * - * NB This has not been integrated in the GUI jet! - */ -public class ColorTransformPanel extends JPanel { - - private final Dimension maxDim = new Dimension(1024, 20); - - private final TransformConfig mColorConfig; - - private JPanel mIndexPanel; - private JLabel mIndexLabel; - private JTextField mIndexField; - - private JPanel mRgbTransformPanel; - private JLabel mThresholdLabel; - private JLabel mGammaLabel; - private JLabel mBlacklevelLabel; - private JLabel mWhitelevelLabel; - private JLabel mRedTransformLabel; - private JSpinner mRedThresholdSpinner; - private JSpinner mRedGammaSpinner; - private JSpinner mRedBlacklevelSpinner; - private JSpinner mRedWhitelevelSpinner; - private JLabel mGreenTransformLabel; - private JSpinner mGreenThresholdSpinner; - private JSpinner mGreenGammaSpinner; - private JSpinner mGreenBlacklevelSpinner; - private JSpinner mGreenWhitelevelSpinner; - private JLabel mBlueTransformLabel; - private JSpinner mBlueThresholdSpinner; - private JSpinner mBlueGammaSpinner; - private JSpinner mBlueBlacklevelSpinner; - private JSpinner mBlueWhitelevelSpinner; - - private JPanel mHsvTransformPanel; - private JLabel mSaturationAdjustLabel; - private JSpinner mSaturationAdjustSpinner; - private JLabel mValueAdjustLabel; - private JSpinner mValueAdjustSpinner; - - public ColorTransformPanel(TransformConfig pTransformConfig) { - super(); - - mColorConfig = pTransformConfig; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("Transform [" + mColorConfig.mId + "]")); - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - - add(getIndexPanel()); - add(Box.createVerticalStrut(10)); - add(getRgbPanel()); - add(Box.createVerticalStrut(10)); - add(getHsvPanel()); - add(Box.createVerticalGlue()); - } - - private JPanel getIndexPanel() { - if (mIndexPanel == null) { - mIndexPanel = new JPanel(); - mIndexPanel.setMaximumSize(new Dimension(1024, 25)); - mIndexPanel.setLayout(new BorderLayout(10,10)); - - mIndexLabel = new JLabel("Indices:"); - mIndexPanel.add(mIndexLabel, BorderLayout.WEST); - - mIndexField = new JTextField(mColorConfig.mLedIndexString); - mIndexField.setToolTipText("Comma seperated indices or index ranges (eg '1-10, 13, 14, 17-19'); Special case '*', which means all leds"); - mIndexField.getDocument().addDocumentListener(mDocumentListener); - mIndexPanel.add(mIndexField, BorderLayout.CENTER); - } - return mIndexPanel; - } - - private JPanel getRgbPanel() { - if (mRgbTransformPanel == null) { - mRgbTransformPanel = new JPanel(); - - GridLayout layout = new GridLayout(0, 5); -// GroupLayout layout = new GroupLayout(mRgbTransformPanel); - mRgbTransformPanel.setLayout(layout); - - mRgbTransformPanel.add(Box.createHorizontalBox()); - - mThresholdLabel = new JLabel("Thres."); - mRgbTransformPanel.add(mThresholdLabel); - - mGammaLabel = new JLabel("Gamma"); - mRgbTransformPanel.add(mGammaLabel); - - mBlacklevelLabel = new JLabel("Blacklvl"); - mRgbTransformPanel.add(mBlacklevelLabel); - - mWhitelevelLabel = new JLabel("Whitelvl"); - mRgbTransformPanel.add(mWhitelevelLabel); - - mRedTransformLabel = new JLabel("RED"); - mRgbTransformPanel.add(mRedTransformLabel); - mRedThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedThreshold, 0.0, 1.0, 0.1)); - mRedThresholdSpinner.setMaximumSize(maxDim); - mRedThresholdSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mRedThresholdSpinner); - mRedGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedGamma, 0.0, 100.0, 0.1)); - mRedGammaSpinner.setMaximumSize(maxDim); - mRedGammaSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mRedGammaSpinner); - mRedBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedBlacklevel, 0.0, 1.0, 0.1)); - mRedBlacklevelSpinner.setMaximumSize(maxDim); - mRedBlacklevelSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mRedBlacklevelSpinner); - mRedWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedWhitelevel, 0.0, 1.0, 0.1)); - mRedWhitelevelSpinner.setMaximumSize(maxDim); - mRedWhitelevelSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mRedWhitelevelSpinner); - - mGreenTransformLabel = new JLabel("GREEN"); - mRgbTransformPanel.add(mGreenTransformLabel); - mGreenThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenThreshold, 0.0, 1.0, 0.1)); - mGreenThresholdSpinner.setMaximumSize(maxDim); - mGreenThresholdSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mGreenThresholdSpinner); - mGreenGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenGamma, 0.0, 100.0, 0.1)); - mGreenGammaSpinner.setMaximumSize(maxDim); - mGreenGammaSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mGreenGammaSpinner); - mGreenBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenBlacklevel, 0.0, 1.0, 0.1)); - mGreenBlacklevelSpinner.setMaximumSize(maxDim); - mGreenBlacklevelSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mGreenBlacklevelSpinner); - mGreenWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenWhitelevel, 0.0, 1.0, 0.1)); - mGreenWhitelevelSpinner.setMaximumSize(maxDim); - mGreenWhitelevelSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mGreenWhitelevelSpinner); - - mBlueTransformLabel = new JLabel("BLUE"); - mRgbTransformPanel.add(mBlueTransformLabel); - mBlueThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueThreshold, 0.0, 1.0, 0.1)); - mBlueThresholdSpinner.setMaximumSize(maxDim); - mBlueThresholdSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mBlueThresholdSpinner); - mBlueGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueGamma, 0.0, 100.0, 0.1)); - mBlueGammaSpinner.setMaximumSize(maxDim); - mBlueGammaSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mBlueGammaSpinner); - mBlueBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueBlacklevel, 0.0, 1.0, 0.1)); - mBlueBlacklevelSpinner.setMaximumSize(maxDim); - mBlueBlacklevelSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mBlueBlacklevelSpinner); - mBlueWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueWhitelevel, 0.0, 1.0, 0.1)); - mBlueWhitelevelSpinner.setMaximumSize(maxDim); - mBlueWhitelevelSpinner.addChangeListener(mChangeListener); - mRgbTransformPanel.add(mBlueWhitelevelSpinner); - } - return mRgbTransformPanel; - } - - private JPanel getHsvPanel() { - if (mHsvTransformPanel == null) { - mHsvTransformPanel = new JPanel(); - - GroupLayout layout = new GroupLayout(mHsvTransformPanel); - mHsvTransformPanel.setLayout(layout); - - mSaturationAdjustLabel = new JLabel("HSV Saturation gain"); - mHsvTransformPanel.add(mSaturationAdjustLabel); - - mSaturationAdjustSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mSaturationGain, 0.0, 1024.0, 0.01)); - mSaturationAdjustSpinner.setMaximumSize(maxDim); - mSaturationAdjustSpinner.addChangeListener(mChangeListener); - mHsvTransformPanel.add(mSaturationAdjustSpinner); - - mValueAdjustLabel = new JLabel("HSV Value gain"); - mHsvTransformPanel.add(mValueAdjustLabel); - - mValueAdjustSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mValueGain, 0.0, 1024.0, 0.01)); - mValueAdjustSpinner.setMaximumSize(maxDim); - mValueAdjustSpinner.addChangeListener(mChangeListener); - mHsvTransformPanel.add(mValueAdjustSpinner); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mSaturationAdjustLabel) - .addComponent(mValueAdjustLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mSaturationAdjustSpinner) - .addComponent(mValueAdjustSpinner) - ) - ); - - layout.setVerticalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mSaturationAdjustLabel) - .addComponent(mSaturationAdjustSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mValueAdjustLabel) - .addComponent(mValueAdjustSpinner) - ) - ); - } - 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(); - } - }; - private final DocumentListener mDocumentListener = new DocumentListener() { - @Override - public void removeUpdate(DocumentEvent e) { - mColorConfig.mLedIndexString = mIndexField.getText(); - } - @Override - public void insertUpdate(DocumentEvent e) { - mColorConfig.mLedIndexString = mIndexField.getText(); - } - @Override - public void changedUpdate(DocumentEvent e) { - mColorConfig.mLedIndexString = mIndexField.getText(); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorsPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorsPanel.java deleted file mode 100644 index 29f50840..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ColorsPanel.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JOptionPane; -import javax.swing.JPanel; - -import org.hyperion.hypercon.spec.ColorConfig; -import org.hyperion.hypercon.spec.TransformConfig; - -public class ColorsPanel extends JPanel { - - private final ColorConfig mColorConfig; - private final DefaultComboBoxModel mTransformsModel; - - private JPanel mControlPanel; - private JComboBox mTransformCombo; - private JButton mAddTransformButton; - private JButton mDelTransformButton; - - private JPanel mTransformPanel; - - private final Map mTransformPanels = new HashMap<>(); - - - public ColorsPanel(ColorConfig pColorConfig) { - super(); - - mColorConfig = pColorConfig; - mTransformsModel = new DefaultComboBoxModel(mColorConfig.mTransforms); - - initialise(); - } - - private void initialise() { - setLayout(new BorderLayout(10,10)); - setBorder(BorderFactory.createTitledBorder("Colors")); - - add(getControlPanel(), BorderLayout.NORTH); - - mTransformPanel = new JPanel(); - mTransformPanel.setLayout(new BorderLayout()); - add(mTransformPanel, BorderLayout.CENTER); - - for (TransformConfig config : mColorConfig.mTransforms) { - mTransformPanels.put(config, new ColorTransformPanel(config)); - } - ColorTransformPanel currentPanel = mTransformPanels.get(mColorConfig.mTransforms.get(0)); - mTransformPanel.add(currentPanel, BorderLayout.CENTER); - } - - private JPanel getControlPanel() { - if (mControlPanel == null) { - mControlPanel = new JPanel(); - mControlPanel.setLayout(new BoxLayout(mControlPanel, BoxLayout.LINE_AXIS)); - - mTransformCombo = new JComboBox<>(mTransformsModel); - mTransformCombo.addActionListener(mComboListener); - mControlPanel.add(mTransformCombo); - - mAddTransformButton = new JButton(mAddAction); - mControlPanel.add(mAddTransformButton); - - mDelTransformButton = new JButton(mDelAction); - mDelTransformButton.setEnabled(mTransformCombo.getItemCount() > 1); - mControlPanel.add(mDelTransformButton); - } - return mControlPanel; - } - - private final Action mAddAction = new AbstractAction("Add") { - @Override - public void actionPerformed(ActionEvent e) { - String newId = JOptionPane.showInputDialog("Give an identifier for the new color-transform:"); - if (newId == null || newId.isEmpty()) { - // No proper value given - return; - } - - TransformConfig config = new TransformConfig(); - config.mId = newId; - - ColorTransformPanel panel = new ColorTransformPanel(config); - mTransformPanels.put(config, panel); - - mTransformsModel.addElement(config); - mTransformsModel.setSelectedItem(config); - - mDelTransformButton.setEnabled(true); - } - }; - private final Action mDelAction = new AbstractAction("Del") { - @Override - public void actionPerformed(ActionEvent e) { - TransformConfig config = (TransformConfig) mTransformCombo.getSelectedItem(); - mTransformPanels.remove(config); - mTransformsModel.removeElement(config); - - mDelTransformButton.setEnabled(mTransformCombo.getItemCount() > 1); - } - }; - - private final ActionListener mComboListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - TransformConfig selConfig = (TransformConfig) mTransformsModel.getSelectedItem(); - if (selConfig == null) { - // Something went wrong here, there should always be a selection! - return; - } - - ColorTransformPanel panel = mTransformPanels.get(selConfig); - mTransformPanel.removeAll(); - mTransformPanel.add(panel, BorderLayout.CENTER); - mTransformPanel.revalidate(); - mTransformPanel.repaint(); - } - }; -} 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 deleted file mode 100644 index a7d06cf8..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ConfigPanel.java +++ /dev/null @@ -1,194 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.io.File; -import java.io.IOException; -import java.util.Observable; -import java.util.Observer; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JFileChooser; -import javax.swing.JPanel; -import javax.swing.JTabbedPane; - -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 - * write-out the configuration. This can be placed on JFrame, JDialog or JApplet as required. - */ -public class ConfigPanel extends JPanel { - - /** The LED configuration information*/ - private final LedString ledString; - - /** Action for write the Hyperion deamon configuration file */ - private final Action mSaveConfigAction = new AbstractAction("Create Hyperion Configuration") { - JFileChooser fileChooser = new JFileChooser(); - { - fileChooser.setSelectedFile(new File("hyperion.config.json")); - } - @Override - public void actionPerformed(ActionEvent e) { - if (fileChooser.showSaveDialog(ConfigPanel.this) != JFileChooser.APPROVE_OPTION) { - return; - } - - 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(); - } - } - }; - - /** The panel for containing the example 'Hyperion TV' */ - private JPanel mTvPanel; - /** The simulated 'Hyperion TV' */ - private LedSimulationComponent mHyperionTv; - - private JTabbedPane mSpecificationTabs = null; - /** The left (WEST) side panel containing the diferent configuration panels */ - private JPanel mHardwarePanel = null; - private JPanel mProcessPanel = null; - private JPanel mExternalPanel = null; - - - /** The button connected to mSaveConfigAction */ - private JButton mSaveConfigButton; - - /** - * Constructs the configuration panel with a default initialised led-frame and configuration - */ - public ConfigPanel(final LedString pLedString) { - super(); - - ledString = pLedString; - - initialise(); - - // Compute the individual leds for the current configuration - ledString.leds = LedFrameFactory.construct(ledString.mLedFrameConfig, ledString.mProcessConfig); - mHyperionTv.setLeds(ledString.leds); - - // Add Observer to update the individual leds if the configuration changes - final Observer observer = new Observer() { - @Override - public void update(Observable o, Object arg) { - ledString.leds = LedFrameFactory.construct(ledString.mLedFrameConfig, ledString.mProcessConfig); - mHyperionTv.setLeds(ledString.leds); - mHyperionTv.repaint(); - } - }; - ledString.mLedFrameConfig.addObserver(observer); - ledString.mProcessConfig.addObserver(observer); - } - - /** - * Initialises the config-panel - */ - private void initialise() { - setLayout(new BorderLayout()); - - add(getTvPanel(), BorderLayout.CENTER); - add(getWestPanel(), BorderLayout.WEST); - - } - private JPanel getWestPanel() { - JPanel mWestPanel = new JPanel(); - mWestPanel.setLayout(new BorderLayout()); - - mWestPanel.add(getSpecificationTabs(), BorderLayout.CENTER); - - JPanel panel = new JPanel(new BorderLayout()); - panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); - mSaveConfigButton = new JButton(mSaveConfigAction); - panel.add(mSaveConfigButton, BorderLayout.SOUTH); - mWestPanel.add(panel, BorderLayout.SOUTH); - - return mWestPanel; - } - private JTabbedPane getSpecificationTabs() { - if (mSpecificationTabs == null) { - mSpecificationTabs = new JTabbedPane(); - - mSpecificationTabs.addTab("Hardware", getHardwarePanel()); - mSpecificationTabs.addTab("Process", getProcessPanel()); - mSpecificationTabs.addTab("External", getExternalPanel()); - } - return mSpecificationTabs; - } - - /** - * Created, if not exists, and returns the panel holding the simulated 'Hyperion TV' - * - * @return The Tv panel - */ - private JPanel getTvPanel() { - if (mTvPanel == null) { - mTvPanel = new JPanel(); - mTvPanel.setLayout(new BorderLayout()); - - mHyperionTv = new LedSimulationComponent(ledString.leds); - mTvPanel.add(mHyperionTv, BorderLayout.CENTER); - } - return mTvPanel; - } - - private JPanel getHardwarePanel() { - if (mHardwarePanel == null) { - mHardwarePanel = new JPanel(); - mHardwarePanel.setLayout(new BoxLayout(mHardwarePanel, BoxLayout.Y_AXIS)); - - mHardwarePanel.add(new DevicePanel(ledString.mDeviceConfig)); - mHardwarePanel.add(new LedFramePanel(ledString.mLedFrameConfig)); - mHardwarePanel.add(new ImageProcessPanel(ledString.mProcessConfig)); - mHardwarePanel.add(Box.createVerticalGlue()); - } - return mHardwarePanel; - } - - private JPanel getProcessPanel() { - if (mProcessPanel == null) { - mProcessPanel = new JPanel(); - mProcessPanel.setLayout(new BoxLayout(mProcessPanel, BoxLayout.Y_AXIS)); - - mProcessPanel.add(new FrameGrabberPanel(ledString.mMiscConfig)); - mProcessPanel.add(new ColorSmoothingPanel(ledString.mColorConfig)); - mProcessPanel.add(new ColorsPanel(ledString.mColorConfig)); - mProcessPanel.add(Box.createVerticalGlue()); - } - return mProcessPanel; - } - - private JPanel getExternalPanel() { - if (mExternalPanel == null) { - mExternalPanel = new JPanel(); - mExternalPanel.setLayout(new BoxLayout(mExternalPanel, BoxLayout.Y_AXIS)); - - mExternalPanel.add(new XbmcPanel(ledString.mMiscConfig)); - mExternalPanel.add(new InterfacePanel(ledString.mMiscConfig)); - mExternalPanel.add(new EffectEnginePanel(ledString.mMiscConfig)); - mExternalPanel.add(Box.createVerticalGlue()); - } - return mExternalPanel; - } -} 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 deleted file mode 100644 index 90219e28..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/DevicePanel.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.Transient; - -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import org.hyperion.hypercon.gui.device.DeviceTypePanel; -import org.hyperion.hypercon.spec.ColorByteOrder; -import org.hyperion.hypercon.spec.DeviceConfig; -import org.hyperion.hypercon.spec.DeviceType; - -public class DevicePanel extends JPanel { - - public static final String[] KnownOutputs = {"/dev/spidev0.0", "/dev/spidev0.1", "/dev/ttyS0", "/dev/ttyUSB0", "/dev/ttyprintk", "/home/pi/test.out", "/dev/null"}; - - private final DeviceConfig mDeviceConfig; - - private JLabel mTypeLabel; - private JComboBox mTypeCombo; - - private JPanel mDevicePanel; - - private JLabel mRgbLabel; - private JComboBox mRgbCombo; - - public DevicePanel(DeviceConfig pDeviceConfig) { - super(); - - mDeviceConfig = pDeviceConfig; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("Device")); - - mTypeLabel = new JLabel("Type: "); - mTypeLabel.setMinimumSize(new Dimension(80, 10)); - add(mTypeLabel); - - mTypeCombo = new JComboBox<>(DeviceType.values()); - mTypeCombo.setSelectedItem(mDeviceConfig.mType); - mTypeCombo.addActionListener(mActionListener); - add(mTypeCombo); - - mDevicePanel = new JPanel(); - mDevicePanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); - mDevicePanel.setLayout(new BorderLayout()); - DeviceTypePanel typePanel = mDeviceConfig.mType.getConfigPanel(mDeviceConfig); - if (typePanel != null) { - mDevicePanel.add(typePanel, BorderLayout.CENTER); - } - add(mDevicePanel); - - mRgbLabel = new JLabel("RGB Byte Order: "); - mRgbLabel.setMinimumSize(new Dimension(80, 10)); - add(mRgbLabel); - - mRgbCombo = new JComboBox<>(ColorByteOrder.values()); - mRgbCombo.setSelectedItem(mDeviceConfig.mColorByteOrder); - mRgbCombo.addActionListener(mActionListener); - add(mRgbCombo); - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createParallelGroup() - .addGroup(layout.createSequentialGroup() - .addComponent(mTypeLabel) - .addComponent(mTypeCombo)) - .addComponent(mDevicePanel) - .addGroup(layout.createSequentialGroup() - .addComponent(mRgbLabel) - .addComponent(mRgbCombo))); - layout.setVerticalGroup(layout.createParallelGroup() - .addGroup(layout.createSequentialGroup() - .addComponent(mTypeLabel) - .addComponent(mDevicePanel) - .addComponent(mRgbLabel)) - .addGroup(layout.createSequentialGroup() - .addComponent(mTypeCombo) - .addComponent(mDevicePanel) - .addComponent(mRgbCombo))); - } - - private final ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mDeviceConfig.mType = (DeviceType)mTypeCombo.getSelectedItem(); - mDeviceConfig.mColorByteOrder = (ColorByteOrder)mRgbCombo.getSelectedItem(); - - mDevicePanel.removeAll(); - DeviceTypePanel typePanel = mDeviceConfig.mType.getConfigPanel(mDeviceConfig); - if (typePanel != null) { - mDevicePanel.add(typePanel, BorderLayout.CENTER); - } - revalidate(); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/EffectEnginePanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/EffectEnginePanel.java deleted file mode 100644 index 26f01025..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/EffectEnginePanel.java +++ /dev/null @@ -1,175 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSpinner; -import javax.swing.JTextField; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import org.hyperion.hypercon.spec.MiscConfig; - -/** - * THe EffectEnginePanel contains the components for configuring the parameters of the Effect Engine - */ -public class EffectEnginePanel extends JPanel { - - /** The MISC config contains the effect engine settings */ - private final MiscConfig mMiscConfig; - - private JLabel mPathLabel; - private JTextField mPathField; - - private JPanel mBootSequencePanel; - private JCheckBox mBootSequenceCheck; - private JLabel mBootSequenceLabel; - private JTextField mBootSequenceField; - private JLabel mBootSequenceLengthLabel; - private JSpinner mBootSequenceLengthSpinner; - - public EffectEnginePanel(final MiscConfig pMiscConfig) { - super(); - - mMiscConfig = pMiscConfig; - - initialise(); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("Effect Engine")); - - mPathLabel = new JLabel("Directory: "); - mPathLabel.setMinimumSize(new Dimension(80, 10)); - add(mPathLabel); - - mPathField = new JTextField(); - mPathField.setMaximumSize(new Dimension(1024, 20)); - mPathField.setText(mMiscConfig.mEffectEnginePath); - mPathField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void removeUpdate(DocumentEvent e) { - mMiscConfig.mEffectEnginePath = mPathField.getText(); - } - @Override - public void insertUpdate(DocumentEvent e) { - mMiscConfig.mEffectEnginePath = mPathField.getText(); - } - @Override - public void changedUpdate(DocumentEvent e) { - mMiscConfig.mEffectEnginePath = mPathField.getText(); - } - }); - add(mPathField); - - add(getBootSequencePanel()); - - GroupLayout layout = new GroupLayout(this); - setLayout(layout); - - layout.setVerticalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mPathLabel) - .addComponent(mPathField)) - .addComponent(getBootSequencePanel())); - - layout.setHorizontalGroup(layout.createParallelGroup() - .addGroup(layout.createSequentialGroup() - .addComponent(mPathLabel) - .addComponent(mPathField)) - .addComponent(getBootSequencePanel())); - } - - private JPanel getBootSequencePanel() { - if (mBootSequencePanel == null) { - mBootSequencePanel = new JPanel(); - mBootSequencePanel.setBorder(BorderFactory.createTitledBorder("Bootsequence")); - - mBootSequenceCheck = new JCheckBox("Enabled"); - mBootSequenceCheck.setSelected(mMiscConfig.mBootSequenceEnabled); - mBootSequenceCheck.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mMiscConfig.mBootSequenceEnabled = mBootSequenceCheck.isSelected(); - mBootSequenceLabel.setEnabled(mMiscConfig.mBootSequenceEnabled); - mBootSequenceField.setEnabled(mMiscConfig.mBootSequenceEnabled); - } - }); - mBootSequencePanel.add(mBootSequenceCheck); - - mBootSequenceLabel = new JLabel("Type:"); - mBootSequenceLabel.setMinimumSize(new Dimension(75, 10)); - mBootSequenceLabel.setEnabled(mMiscConfig.mBootSequenceEnabled); - mBootSequencePanel.add(mBootSequenceLabel); - - mBootSequenceField = new JTextField(); - mBootSequenceField.setMaximumSize(new Dimension(1024, 20)); - mBootSequenceField.setText(mMiscConfig.mBootSequenceEffect); - mBootSequenceField.setEnabled(mMiscConfig.mBootSequenceEnabled); - mBootSequenceField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void removeUpdate(DocumentEvent e) { - mMiscConfig.mBootSequenceEffect = mBootSequenceField.getText(); - } - @Override - public void insertUpdate(DocumentEvent e) { - mMiscConfig.mBootSequenceEffect = mBootSequenceField.getText(); - } - @Override - public void changedUpdate(DocumentEvent e) { - mMiscConfig.mBootSequenceEffect = mBootSequenceField.getText(); - } - }); - mBootSequencePanel.add(mBootSequenceField); - - mBootSequenceLengthLabel = new JLabel("Length[ms]: "); - mBootSequenceLengthLabel.setMinimumSize(new Dimension(75, 10)); - mBootSequenceLengthLabel.setEnabled(mMiscConfig.mBootSequenceEnabled); - mBootSequencePanel.add(mBootSequenceLengthLabel); - - mBootSequenceLengthSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mBootSequenceLength_ms, 100, 1500000, 500)); - mBootSequenceLengthSpinner.setMaximumSize(new Dimension(1024, 20)); - mBootSequenceLengthSpinner.setEnabled(mMiscConfig.mBootSequenceEnabled); - mBootSequenceLengthSpinner.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - mMiscConfig.mBootSequenceLength_ms = (Integer)mBootSequenceLengthSpinner.getValue(); - } - }); - mBootSequencePanel.add(mBootSequenceLengthSpinner); - - GroupLayout layout = new GroupLayout(mBootSequencePanel); - mBootSequencePanel.setLayout(layout); - - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(mBootSequenceCheck) - .addGroup(layout.createParallelGroup() - .addComponent(mBootSequenceLabel) - .addComponent(mBootSequenceField)) - .addGroup(layout.createParallelGroup() - .addComponent(mBootSequenceLengthLabel) - .addComponent(mBootSequenceLengthSpinner)) - ); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mBootSequenceCheck) - .addComponent(mBootSequenceLabel) - .addComponent(mBootSequenceLengthLabel)) - .addGroup(layout.createParallelGroup() - .addComponent(mBootSequenceCheck) - .addComponent(mBootSequenceField) - .addComponent(mBootSequenceLengthSpinner))); - } - return mBootSequencePanel; - } -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/FrameGrabberPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/FrameGrabberPanel.java deleted file mode 100644 index 70624811..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/FrameGrabberPanel.java +++ /dev/null @@ -1,137 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.Transient; - -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.JCheckBox; -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.MiscConfig; - -public class FrameGrabberPanel extends JPanel { - - private final MiscConfig mMiscConfig; - - private JCheckBox mFrameGrabberCheck; - private JLabel mWidthLabel; - private JSpinner mWidthSpinner; - private JLabel mHeightLabel; - private JSpinner mHeightSpinner; - private JLabel mIntervalLabel; - private JSpinner mIntervalSpinner; - - public FrameGrabberPanel(final MiscConfig pMiscConfig) { - super(); - - mMiscConfig = pMiscConfig; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("Frame Grabber")); - - mFrameGrabberCheck = new JCheckBox("Enabled"); - mFrameGrabberCheck.setSelected(mMiscConfig.mFrameGrabberEnabled); - mFrameGrabberCheck.addActionListener(mActionListener); - add(mFrameGrabberCheck); - - mWidthLabel = new JLabel("Width: "); - add(mWidthLabel); - - mWidthSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mFrameGrabberWidth, 16, 1024, 8)); - mWidthSpinner.addChangeListener(mChangeListener); - add(mWidthSpinner); - - mHeightLabel = new JLabel("Heigth: "); - add(mHeightLabel); - - mHeightSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mFrameGrabberHeight, 16, 1024, 8)); - mHeightSpinner.addChangeListener(mChangeListener); - add(mHeightSpinner); - - mIntervalLabel = new JLabel("Interval [ms]:"); - add(mIntervalLabel); - - mIntervalSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mFrameGrabberInterval_ms, 10, 60000, 10)); - mIntervalSpinner.addChangeListener(mChangeListener); - add(mIntervalSpinner); - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mFrameGrabberCheck) - .addComponent(mWidthLabel) - .addComponent(mHeightLabel) - .addComponent(mIntervalLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mFrameGrabberCheck) - .addComponent(mWidthSpinner) - .addComponent(mHeightSpinner) - .addComponent(mIntervalSpinner) - )); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(mFrameGrabberCheck) - .addGroup(layout.createParallelGroup() - .addComponent(mWidthLabel) - .addComponent(mWidthSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mHeightLabel) - .addComponent(mHeightSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mIntervalLabel) - .addComponent(mIntervalSpinner) - )); - - toggleEnabled(mMiscConfig.mFrameGrabberEnabled); - } - - private void toggleEnabled(boolean pEnabled) { - mWidthLabel.setEnabled(pEnabled); - mWidthSpinner.setEnabled(pEnabled); - mHeightLabel.setEnabled(pEnabled); - mHeightSpinner.setEnabled(pEnabled); - mIntervalLabel.setEnabled(pEnabled); - mIntervalSpinner.setEnabled(pEnabled); - } - - private final ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mMiscConfig.mFrameGrabberEnabled = mFrameGrabberCheck.isSelected(); - - toggleEnabled(mMiscConfig.mFrameGrabberEnabled); - } - }; - private final ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - mMiscConfig.mFrameGrabberWidth = (Integer)mWidthSpinner.getValue(); - mMiscConfig.mFrameGrabberHeight = (Integer)mHeightSpinner.getValue(); - mMiscConfig.mFrameGrabberInterval_ms = (Integer)mIntervalSpinner.getValue(); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageComponent.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageComponent.java deleted file mode 100644 index 3984c814..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageComponent.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Graphics; -import java.awt.Image; - -import javax.swing.JComponent; - -public class ImageComponent extends JComponent { - - private Image mImage; - - public ImageComponent() { - super(); - } - - public void setImage(Image pImage) { - mImage = pImage; - } - - @Override - public void paint(Graphics g) { - if (mImage == null) { - return; - } - g.drawImage(mImage, 0, 0, getWidth(), getHeight(), null); - } -} 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 deleted file mode 100644 index 4de4751a..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/ImageProcessPanel.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.Transient; - -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.JComboBox; -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.ImageProcessConfig; - -public class ImageProcessPanel extends JPanel { - - private final ImageProcessConfig mProcessConfig; - - private JLabel mHorizontalDepthLabel; - private JSpinner mHorizontalDepthSpinner; - private JLabel mVerticalDepthLabel; - private JSpinner mVerticalDepthSpinner; - - private JLabel mHorizontalGapLabel; - private JSpinner mHorizontalGapSpinner; - private JLabel mVerticalGapLabel; - private JSpinner mVerticalGapSpinner; - - private JLabel mOverlapLabel; - private JSpinner mOverlapSpinner; - - private JLabel mBlackborderDetectorLabel; - private JComboBox mBlackborderDetectorCombo; - - public ImageProcessPanel(ImageProcessConfig pProcessConfig) { - super(); - - mProcessConfig = pProcessConfig; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("Image Process")); - - mHorizontalDepthLabel = new JLabel("Horizontal depth [%]:"); - add(mHorizontalDepthLabel); - - 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(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(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(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(mProcessConfig.mOverlapFraction*100.0, -100.0, 100.0, 1.0)); - mOverlapSpinner.addChangeListener(mChangeListener); - add(mOverlapSpinner); - - mBlackborderDetectorLabel = new JLabel("Blackborder Detector:"); - add(mBlackborderDetectorLabel); - - mBlackborderDetectorCombo = new JComboBox<>(new String[] {"On", "Off"}); - mBlackborderDetectorCombo.setSelectedItem(mProcessConfig.mBlackBorderRemoval?"On":"Off"); - mBlackborderDetectorCombo.setToolTipText("Enables or disables the blackborder detection and removal"); - mBlackborderDetectorCombo.addActionListener(mActionListener); - add(mBlackborderDetectorCombo); - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mHorizontalDepthLabel) - .addComponent(mVerticalDepthLabel) - .addComponent(mHorizontalGapLabel) - .addComponent(mVerticalGapLabel) - .addComponent(mOverlapLabel) - .addComponent(mBlackborderDetectorLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mHorizontalDepthSpinner) - .addComponent(mVerticalDepthSpinner) - .addComponent(mHorizontalGapSpinner) - .addComponent(mVerticalGapSpinner) - .addComponent(mOverlapSpinner) - .addComponent(mBlackborderDetectorCombo) - ) - ); - layout.setVerticalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mHorizontalDepthLabel) - .addComponent(mHorizontalDepthSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mVerticalDepthLabel) - .addComponent(mVerticalDepthSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mHorizontalGapLabel) - .addComponent(mHorizontalGapSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mVerticalGapLabel) - .addComponent(mVerticalGapSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mOverlapLabel) - .addComponent(mOverlapSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mBlackborderDetectorLabel) - .addComponent(mBlackborderDetectorCombo) - ) - ); - } - - private final ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // Update the processing configuration - mProcessConfig.setBlackBorderRemoval((mBlackborderDetectorCombo.getSelectedItem() == "On")); - - // Notify observers - mProcessConfig.notifyObservers(this); - } - }; - private final ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - // Update the processing configuration - mProcessConfig.setHorizontalDepth(((Double)mHorizontalDepthSpinner.getValue())/100.0); - mProcessConfig.setVerticalDepth(((Double)mVerticalDepthSpinner.getValue())/100.0); - mProcessConfig.setHorizontalGap(((Double)mHorizontalGapSpinner.getValue())/100.0); - mProcessConfig.setVerticalGap(((Double)mVerticalGapSpinner.getValue())/100.0); - mProcessConfig.setOverlapFraction(((Double)mOverlapSpinner.getValue())/100.0); - - // Notify observers - mProcessConfig.notifyObservers(this); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/InterfacePanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/InterfacePanel.java deleted file mode 100644 index 488bac88..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/InterfacePanel.java +++ /dev/null @@ -1,215 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.Transient; - -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; -import javax.swing.GroupLayout; -import javax.swing.JCheckBox; -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.MiscConfig; - -public class InterfacePanel extends JPanel { - - public final MiscConfig mMiscConfig; - - private JPanel mJsonPanel; - private JCheckBox mJsonCheck; - private JLabel mJsonPortLabel; - private JSpinner mJsonPortSpinner; - - private JPanel mProtoPanel; - private JCheckBox mProtoCheck; - private JLabel mProtoPortLabel; - private JSpinner mProtoPortSpinner; - - private JPanel mBoblightPanel; - private JCheckBox mBoblightCheck; - private JLabel mBoblightPortLabel; - private JSpinner mBoblightPortSpinner; - - public InterfacePanel(final MiscConfig pMiscConfig) { - super(); - - mMiscConfig = pMiscConfig; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - //setBorder(BorderFactory.createTitledBorder("External interfaces")); - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - - add(getJsonPanel()); - add(getProtoPanel()); - add(getBoblightPanel()); - - toggleEnabledFlags(); - } - - private JPanel getJsonPanel() { - if (mJsonPanel == null) { - mJsonPanel = new JPanel(); - mJsonPanel.setBorder(BorderFactory.createTitledBorder("Json server")); - - mJsonCheck = new JCheckBox("Enabled"); - mJsonCheck.setSelected(mMiscConfig.mJsonInterfaceEnabled); - mJsonCheck.addActionListener(mActionListener); - mJsonPanel.add(mJsonCheck); - - mJsonPortLabel = new JLabel("TCP Port: "); - mJsonPanel.add(mJsonPortLabel); - - mJsonPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mJsonPort, 1, 65536, 1)); - mJsonPortSpinner.addChangeListener(mChangeListener); - mJsonPanel.add(mJsonPortSpinner); - - GroupLayout layout = new GroupLayout(mJsonPanel); - layout.setAutoCreateGaps(true); - mJsonPanel.setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mJsonCheck) - .addComponent(mJsonPortLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mJsonCheck) - .addComponent(mJsonPortSpinner) - )); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(mJsonCheck) - .addGroup(layout.createParallelGroup() - .addComponent(mJsonPortLabel) - .addComponent(mJsonPortSpinner) - )); - } - return mJsonPanel; - } - private JPanel getProtoPanel() { - if (mProtoPanel == null) { - mProtoPanel = new JPanel(); - mProtoPanel.setBorder(BorderFactory.createTitledBorder("Proto server")); - - mProtoCheck = new JCheckBox("Enabled"); - mProtoCheck.setSelected(mMiscConfig.mProtoInterfaceEnabled); - mProtoCheck.addActionListener(mActionListener); - mProtoPanel.add(mProtoCheck); - - mProtoPortLabel = new JLabel("TCP Port: "); - mProtoPanel.add(mProtoPortLabel); - - mProtoPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mProtoPort, 1, 65536, 1)); - mProtoPortSpinner.addChangeListener(mChangeListener); - mProtoPanel.add(mProtoPortSpinner); - - GroupLayout layout = new GroupLayout(mProtoPanel); - layout.setAutoCreateGaps(true); - mProtoPanel.setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mProtoCheck) - .addComponent(mProtoPortLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mProtoCheck) - .addComponent(mProtoPortSpinner) - )); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(mProtoCheck) - .addGroup(layout.createParallelGroup() - .addComponent(mProtoPortLabel) - .addComponent(mProtoPortSpinner) - )); - } - return mProtoPanel; - } - - private JPanel getBoblightPanel() { - if (mBoblightPanel == null) { - mBoblightPanel = new JPanel(); - mBoblightPanel.setBorder(BorderFactory.createTitledBorder("Boblight server")); - - mBoblightCheck = new JCheckBox("Enabled"); - mBoblightCheck.setSelected(mMiscConfig.mBoblightInterfaceEnabled); - mBoblightCheck.addActionListener(mActionListener); - mBoblightPanel.add(mBoblightCheck); - - mBoblightPortLabel = new JLabel("TCP Port: "); - mBoblightPanel.add(mBoblightPortLabel); - - mBoblightPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mBoblightPort, 1, 65536, 1)); - mBoblightPortSpinner.addChangeListener(mChangeListener); - mBoblightPanel.add(mBoblightPortSpinner); - - GroupLayout layout = new GroupLayout(mBoblightPanel); - layout.setAutoCreateGaps(true); - mBoblightPanel.setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mBoblightCheck) - .addComponent(mBoblightPortLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mBoblightCheck) - .addComponent(mBoblightPortSpinner) - )); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(mBoblightCheck) - .addGroup(layout.createParallelGroup() - .addComponent(mBoblightPortLabel) - .addComponent(mBoblightPortSpinner) - )); - } - return mBoblightPanel; - } - - private void toggleEnabledFlags() { - mJsonPortLabel.setEnabled(mMiscConfig.mJsonInterfaceEnabled); - mJsonPortSpinner.setEnabled(mMiscConfig.mJsonInterfaceEnabled); - - mProtoPortLabel.setEnabled(mMiscConfig.mProtoInterfaceEnabled); - mProtoPortSpinner.setEnabled(mMiscConfig.mProtoInterfaceEnabled); - - mBoblightPortLabel.setEnabled(mMiscConfig.mBoblightInterfaceEnabled); - mBoblightPortSpinner.setEnabled(mMiscConfig.mBoblightInterfaceEnabled); - } - - private final ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mMiscConfig.mJsonInterfaceEnabled = mJsonCheck.isSelected(); - mMiscConfig.mProtoInterfaceEnabled = mProtoCheck.isSelected(); - mMiscConfig.mBoblightInterfaceEnabled = mBoblightCheck.isSelected(); - - toggleEnabledFlags(); - } - }; - private final ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - mMiscConfig.mJsonPort = (Integer)mJsonPortSpinner.getValue(); - mMiscConfig.mProtoPort = (Integer)mJsonPortSpinner.getValue(); - mMiscConfig.mBoblightPort = (Integer)mJsonPortSpinner.getValue(); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedDivideDialog.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedDivideDialog.java deleted file mode 100644 index d0072df1..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedDivideDialog.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.GridLayout; - -import javax.swing.ButtonGroup; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JRadioButton; - -public class LedDivideDialog extends JFrame { - - private final int mLedCount; - private final int mTransformCount; - - private JPanel mContentPanel; - - public LedDivideDialog(int pLedCnt, int pTransformCnt) { - super(); - - mLedCount = pLedCnt; - mTransformCount = pTransformCnt; - - initialise(); - } - - private void initialise() { - mContentPanel = new JPanel(); - mContentPanel.setLayout(new GridLayout(mLedCount, mTransformCount, 5, 5)); - - for (int iLed=0; iLed mTopCornerCombo; - private JLabel mBottomCornerLabel; - private JComboBox mBottomCornerCombo; - - private JLabel mDirectionLabel; - private JComboBox mDirectionCombo; - - private JLabel mOffsetLabel; - private JSpinner mOffsetSpinner; - - public LedFramePanel(LedFrameConstruction ledFrameSpec) { - super(); - - mLedFrameSpec = ledFrameSpec; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("Construction")); - - 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); - - mHorizontalCountLabel = new JLabel("Horizontal #:"); - add(mHorizontalCountLabel); - mHorizontalCountSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.topLedCnt, 0, 1024, 1)); - mHorizontalCountSpinner.addChangeListener(mChangeListener); - add(mHorizontalCountSpinner); - - mBottomGapCountLabel = new JLabel("Bottom Gap #:"); - add(mBottomGapCountLabel); - mBottomGapCountSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.topLedCnt - mLedFrameSpec.bottomLedCnt, 0, 1024, 1)); - mBottomGapCountSpinner.addChangeListener(mChangeListener); - add(mBottomGapCountSpinner); - - mVerticalCountLabel = new JLabel("Vertical #:"); - add(mVerticalCountLabel); - mVerticalCountSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.rightLedCnt, 0, 1024, 1)); - mVerticalCountSpinner.addChangeListener(mChangeListener); - add(mVerticalCountSpinner); - - mOffsetLabel = new JLabel("1st LED offset"); - add(mOffsetLabel); - mOffsetSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.firstLedOffset, Integer.MIN_VALUE, Integer.MAX_VALUE, 1)); - mOffsetSpinner.addChangeListener(mChangeListener); - add(mOffsetSpinner); - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mDirectionLabel) - .addComponent(mTopCornerLabel) - .addComponent(mBottomCornerLabel) - .addComponent(mHorizontalCountLabel) - .addComponent(mBottomGapCountLabel) - .addComponent(mVerticalCountLabel) - .addComponent(mOffsetLabel)) - .addGroup(layout.createParallelGroup() - .addComponent(mDirectionCombo) - .addComponent(mTopCornerCombo) - .addComponent(mBottomCornerCombo) - .addComponent(mHorizontalCountSpinner) - .addComponent(mBottomGapCountSpinner) - .addComponent(mVerticalCountSpinner) - .addComponent(mOffsetSpinner)) - ); - layout.setVerticalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mDirectionLabel) - .addComponent(mDirectionCombo)) - .addGroup(layout.createParallelGroup() - .addComponent(mTopCornerLabel) - .addComponent(mTopCornerCombo)) - .addGroup(layout.createParallelGroup() - .addComponent(mBottomCornerLabel) - .addComponent(mBottomCornerCombo)) - .addGroup(layout.createParallelGroup() - .addComponent(mHorizontalCountLabel) - .addComponent(mHorizontalCountSpinner)) - .addGroup(layout.createParallelGroup() - .addComponent(mVerticalCountLabel) - .addComponent(mVerticalCountSpinner)) - .addGroup(layout.createParallelGroup() - .addComponent(mBottomGapCountLabel) - .addComponent(mBottomGapCountSpinner)) - .addGroup(layout.createParallelGroup() - .addComponent(mOffsetLabel) - .addComponent(mOffsetSpinner))); - - } - - void updateLedConstruction() { - mLedFrameSpec.topCorners = (Boolean)mTopCornerCombo.getSelectedItem(); - mLedFrameSpec.bottomCorners = (Boolean)mBottomCornerCombo.getSelectedItem(); - - mLedFrameSpec.clockwiseDirection = ((LedFrameConstruction.Direction)mDirectionCombo.getSelectedItem()) == LedFrameConstruction.Direction.clockwise; - mLedFrameSpec.firstLedOffset = (Integer)mOffsetSpinner.getValue(); - - mLedFrameSpec.topLedCnt = (Integer)mHorizontalCountSpinner.getValue(); - mLedFrameSpec.bottomLedCnt = Math.max(0, mLedFrameSpec.topLedCnt - (Integer)mBottomGapCountSpinner.getValue()); - mLedFrameSpec.rightLedCnt = (Integer)mVerticalCountSpinner.getValue(); - mLedFrameSpec.leftLedCnt = (Integer)mVerticalCountSpinner.getValue(); - - mLedFrameSpec.setChanged(); - mLedFrameSpec.notifyObservers(); - - mBottomGapCountSpinner.setValue(mLedFrameSpec.topLedCnt - mLedFrameSpec.bottomLedCnt); - } - - private final ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updateLedConstruction(); - } - }; - private final ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - updateLedConstruction(); - } - }; - -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationComponent.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationComponent.java deleted file mode 100644 index 2ebcd650..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationComponent.java +++ /dev/null @@ -1,330 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.event.ActionEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.image.BufferedImage; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.net.URL; -import java.util.Vector; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.ImageIcon; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JProgressBar; -import javax.swing.SwingWorker; - -import org.hyperion.hypercon.LedFrameFactory; -import org.hyperion.hypercon.spec.ImageProcessConfig; -import org.hyperion.hypercon.spec.Led; -import org.hyperion.hypercon.spec.LedFrameConstruction; - - -public class LedSimulationComponent extends JPanel { - - private BufferedImage mTvImage = new BufferedImage(640, 480, BufferedImage.TYPE_INT_ARGB); - - private void setImage(Image pImage) { - mTvImage.createGraphics().drawImage(pImage, 0, 0, mTvImage.getWidth(), mTvImage.getHeight(), null); - } - { - Image image = new ImageIcon(LedSimulationComponent.class.getResource("TestImage_01.png")).getImage(); - mTvImage.createGraphics().drawImage(image, 0, 0, mTvImage.getWidth(), mTvImage.getHeight(), null); - } - - private JPanel mTopPanel; - private ImageComponent mTopLeftImage; - private ImageComponent mTopImage; - private ImageComponent mTopRightImage; - - private ImageComponent mLeftImage; - private ImageComponent mRightImage; - - private JPanel mBottomPanel; - private ImageComponent mBottomLeftImage; - private ImageComponent mBottomImage; - private ImageComponent mBottomRightImage; - private JProgressBar mProgressBar; - - LedTvComponent mTvComponent; - private int mLedCnt = 0; - - public LedSimulationComponent(Vector pLeds) { - super(); - - initialise(pLeds); - - setLeds(pLeds); - } - - void initialise(Vector pLeds) { - setBackground(Color.BLACK); - setLayout(new BorderLayout()); - - add(getTopPanel(), BorderLayout.NORTH); - - mLeftImage = new ImageComponent(); - mLeftImage.setPreferredSize(new Dimension(100,100)); - add(mLeftImage, BorderLayout.WEST); - mRightImage = new ImageComponent(); - mRightImage.setPreferredSize(new Dimension(100,100)); - add(mRightImage, BorderLayout.EAST); - - add(getBottomPanel(), BorderLayout.SOUTH); - - mTvComponent = new LedTvComponent(pLeds); - mTvComponent.setImage(mTvImage); - add(mTvComponent, BorderLayout.CENTER); - - mTvComponent.addMouseListener(mPopupListener); - } - - private JPanel getTopPanel() { - mTopPanel = new JPanel(); - mTopPanel.setPreferredSize(new Dimension(100,100)); - mTopPanel.setBackground(Color.BLACK); - mTopPanel.setLayout(new BorderLayout()); - - mTopLeftImage = new ImageComponent(); - mTopLeftImage.setPreferredSize(new Dimension(100,100)); - mTopPanel.add(mTopLeftImage, BorderLayout.WEST); - mTopImage = new ImageComponent(); - mTopPanel.add(mTopImage, BorderLayout.CENTER); - mTopRightImage = new ImageComponent(); - mTopRightImage.setPreferredSize(new Dimension(100,100)); - mTopPanel.add(mTopRightImage, BorderLayout.EAST); - - return mTopPanel; - } - - private JPanel getBottomPanel() { - mBottomPanel = new JPanel(); - mBottomPanel.setPreferredSize(new Dimension(100,100)); - mBottomPanel.setBackground(Color.BLACK); - mBottomPanel.setLayout(new BorderLayout()); - - mBottomLeftImage = new ImageComponent(); - mBottomLeftImage.setPreferredSize(new Dimension(100,100)); - mBottomPanel.add(mBottomLeftImage, BorderLayout.WEST); - mBottomImage = new ImageComponent(); - mBottomPanel.add(mBottomImage, BorderLayout.CENTER); - mBottomRightImage = new ImageComponent(); - mBottomRightImage.setPreferredSize(new Dimension(100,100)); - mBottomPanel.add(mBottomRightImage, BorderLayout.EAST); - - mProgressBar = new JProgressBar(0, 100); - mBottomPanel.add(mProgressBar, BorderLayout.SOUTH); - - return mBottomPanel; - } - - - LedSimulationWorker mWorker = null; - - public void setLeds(Vector pLeds) { - mLedCnt = pLeds == null? 0 : pLeds.size(); - mTvComponent.setLeds(pLeds); - - synchronized (LedSimulationComponent.this) { - if (mWorker != null) { - mWorker.cancel(true); - } - mWorker = null; - } - mWorker = new LedSimulationWorker(mTvImage, pLeds); - mProgressBar.setValue(0); - mWorker.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName() == "state") { - if (evt.getNewValue() == SwingWorker.StateValue.STARTED) { - mProgressBar.setVisible(true); - } else if (evt.getNewValue() == SwingWorker.StateValue.DONE) { - handleWorkerDone(); - mProgressBar.setVisible(false); - } - } else if (evt.getPropertyName() == "progress") { - mProgressBar.setValue(mWorker.getProgress()); - } - } - - private void handleWorkerDone() { - BufferedImage backgroundImage = null; - synchronized(LedSimulationComponent.this) { - if (mWorker == null) { - return; - } - try { - backgroundImage = mWorker.get(); - mWorker = null; - } catch (Exception e) {} - } - if (backgroundImage == null) { - return; - } - - int width = backgroundImage.getWidth(); - int height = backgroundImage.getHeight(); - int borderWidth = (int) (backgroundImage.getWidth() * 0.1); - int borderHeight = (int) (backgroundImage.getHeight() * 0.2); - - mTopLeftImage.setImage(backgroundImage.getSubimage(0, 0, borderWidth, borderHeight)); - mTopImage.setImage(backgroundImage.getSubimage(borderWidth, 0, width-2*borderWidth, borderHeight)); - mTopRightImage.setImage(backgroundImage.getSubimage(width-borderWidth, 0, borderWidth, borderHeight)); - - mLeftImage.setImage(backgroundImage.getSubimage(0, borderHeight, borderWidth, height-2*borderHeight)); - mRightImage.setImage(backgroundImage.getSubimage(width-borderWidth, borderHeight, borderWidth, height-2*borderHeight)); - - mBottomLeftImage.setImage(backgroundImage.getSubimage(0, height-borderHeight, borderWidth, borderHeight)); - mBottomImage.setImage(backgroundImage.getSubimage(borderWidth, height-borderHeight, width-2*borderWidth, borderHeight)); - mBottomRightImage.setImage(backgroundImage.getSubimage(width-borderWidth, height-borderHeight, borderWidth, borderHeight)); - - mProgressBar.setValue(100); - mProgressBar.setVisible(false); - mWorker = null; - - LedSimulationComponent.this.repaint(); - } - }); - mWorker.execute(); - } - - @Override - public void paint(Graphics g) { - super.paint(g); - - Graphics2D gCopy = (Graphics2D)g.create(); - gCopy.setXORMode(Color.WHITE); - gCopy.setFont(gCopy.getFont().deriveFont(20.0f)); - String ledCntStr = "Led count: " + mLedCnt; - gCopy.drawString(ledCntStr, getWidth()-150.0f, getHeight()-10.0f); - } - - public static void main(String[] pArgs) { - JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.setSize(800, 600); - - Vector leds = LedFrameFactory.construct(new LedFrameConstruction(), new ImageProcessConfig()); - - LedSimulationComponent ledSimComp = new LedSimulationComponent(leds); - - frame.getContentPane().setLayout(new BorderLayout()); - frame.getContentPane().add(ledSimComp); - - frame.setVisible(true); - } - - private final MouseListener mPopupListener = new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent e) { - showPopup(e); - } - @Override - public void mousePressed(MouseEvent e) { - showPopup(e); - } - private void showPopup(MouseEvent e) { - if (!e.isPopupTrigger()) { - return; - } - getPopupMenu().show(mTvComponent, e.getX(), e.getY()); - } - }; - - private JPopupMenu mPopupMenu; - private final Action mLoadAction = new AbstractAction("Load image...") { - JFileChooser mImageChooser; - @Override - public void actionPerformed(ActionEvent e) { - if (mImageChooser == null) { - mImageChooser = new JFileChooser(); - } - - if (mImageChooser.showOpenDialog(mTvComponent) != JFileChooser.APPROVE_OPTION) { - return; - } - File file = mImageChooser.getSelectedFile(); - - try { - ImageIcon imageIcon = new ImageIcon(file.getAbsolutePath()); - Image image = imageIcon.getImage(); - - mTvComponent.setImage(image); -// setIma - } catch (Exception ex) { - - } - } - }; - - private synchronized JPopupMenu getPopupMenu() { - if (mPopupMenu == null) { - mPopupMenu = new JPopupMenu(); - mPopupMenu.add(mLoadAction); - - JMenu selectMenu = new JMenu("Select Image"); - selectMenu.add(new SelectImageAction("TestImage_01")); - selectMenu.add(new SelectImageAction("TestImage_02")); - selectMenu.add(new SelectImageAction("TestImage_03")); - selectMenu.add(new SelectImageAction("TestImage_04")); - selectMenu.add(new SelectImageAction("TestImage_05")); - selectMenu.add(new SelectImageAction("TestImageBBB_01")); - selectMenu.add(new SelectImageAction("TestImageBBB_02")); - selectMenu.add(new SelectImageAction("TestImageBBB_03")); - mPopupMenu.add(selectMenu); - } - return mPopupMenu; - } - - private class SelectImageAction extends AbstractAction { - private final String mImageName; - SelectImageAction(String pImageName) { - super(pImageName); - mImageName = pImageName; - - ImageIcon image = loadImage(); - if (image != null) { - Image scaledImage = image.getImage().getScaledInstance(32, 18, Image.SCALE_SMOOTH); - ImageIcon scaledIcon = new ImageIcon(scaledImage, mImageName); - putValue(SMALL_ICON, scaledIcon); - } - } - @Override - public void actionPerformed(ActionEvent e) { - ImageIcon imageIcon = loadImage(); - if (imageIcon != null) { - Image image = imageIcon.getImage(); - - setImage(image); - mTvComponent.setImage(image); - - repaint(); - } - } - - ImageIcon loadImage() { - URL imageUrl = LedSimulationComponent.class.getResource(mImageName + ".png"); - if (imageUrl == null) { - System.out.println("Failed to load image: " + mImageName); - return null; - } - return new ImageIcon(imageUrl); - } - } - -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationWorker.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationWorker.java deleted file mode 100644 index 9f5320d5..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedSimulationWorker.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.util.List; -import java.util.Vector; - -import javax.swing.SwingWorker; - -import org.hyperion.hypercon.spec.Led; - -public class LedSimulationWorker extends SwingWorker { - - private final BufferedImage mTvImage; - - private final Vector mLeds; - - public LedSimulationWorker(BufferedImage pTvImage, Vector pLeds) { - super(); - - mTvImage = pTvImage; - mLeds = pLeds; - } - - class LedPaint { - int color; - - Point point; - double angle_rad; - } - - private final List mLedPaints = new Vector<>(); - - - @Override - protected BufferedImage doInBackground() throws Exception { - Dimension imageDim = new Dimension(1280, 720); - BufferedImage backgroundImage = new BufferedImage(imageDim.width, imageDim.height, BufferedImage.TYPE_INT_ARGB); - - mLedPaints.clear(); - - setProgress(5); - - int imageWidth = mTvImage.getWidth(); - int imageHeight = mTvImage.getHeight(); - for (Led led : mLeds) { - LedPaint ledPaint = new LedPaint(); - - // Determine the location and orientation of the led on the image - ledPaint.point = tv2image(imageDim, led.mLocation); - ledPaint.angle_rad = 0.5*Math.PI - led.mSide.getAngle_rad(); - - // Determine the color of the led - int xMin = (int)(led.mImageRectangle.getMinX() * (imageWidth-1)); - int xMax = (int)(led.mImageRectangle.getMaxX() * (imageWidth-1)); - int yMin = (int)(led.mImageRectangle.getMinY() * (imageHeight-1)); - int yMax = (int)(led.mImageRectangle.getMaxY() * (imageHeight-1)); - ledPaint.color = determineColor(xMin, xMax, yMin, yMax); - - mLedPaints.add(ledPaint); - } - - setProgress(10); - - Graphics2D g2d = backgroundImage.createGraphics(); - // Clear the image with a black rectangle - g2d.setColor(Color.BLACK); - g2d.drawRect(0, 0, backgroundImage.getWidth(), backgroundImage.getHeight()); - paintAllLeds(g2d); - - return backgroundImage; - } - - Point tv2image(Dimension pImageDim, Point2D point) { - double tvWidthFraction = (1.0 - 2*0.1); - double tvHeightFraction = (1.0 - 2*0.2); - - double tvWidth = tvWidthFraction * pImageDim.width; - double tvXIndex = point.getX()*tvWidth; - double imageXIndex = tvXIndex + 0.1*pImageDim.width; - - double tvHeight = tvHeightFraction * pImageDim.height; - double tvYIndex = point.getY()*tvHeight; - double imageYIndex = tvYIndex + 0.2*pImageDim.height; - - return new Point((int)imageXIndex, (int)imageYIndex); - } - - private int determineColor(int xMin, int xMax, int yMin, int yMax) { - int red = 0; - int green = 0; - int blue = 0; - int count = 0; - - for (int y = yMin; y <= yMax; ++y) { - for (int x = xMin; x <= xMax; ++x) { - int color = mTvImage.getRGB(x, y); - red += (color >> 16) & 0xFF; - green += (color >> 8) & 0xFF; - blue += color & 0xFF; - ++count; - } - } - - return count > 0 ? new Color(red / count, green/count, blue/count).getRGB() : 0; - } - - private void paintAllLeds(Graphics2D g2d) { - - for (int i=2; i<=180; i+=4) { - if (isCancelled()) { - return; - } - int arcSize = 24 + (int)((i/12.0)*(i/12.0)); - - for(LedPaint led : mLedPaints) { - int argb = 0x05000000 | (0x00ffffff & led.color); - g2d.setColor(new Color(argb , true)); - - g2d.translate(led.point.getX(), led.point.getY()); - g2d.rotate(led.angle_rad); - g2d.fillArc(-arcSize, -arcSize, 2*arcSize, 2*arcSize, 90-(i/2), i); - g2d.rotate(-led.angle_rad); - g2d.translate(-led.point.getX(), -led.point.getY()); - - setProgress(10+i/3); - } - } - } -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedTvComponent.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedTvComponent.java deleted file mode 100644 index b31ab760..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/LedTvComponent.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; -import java.awt.event.MouseMotionListener; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.util.Vector; - -import javax.swing.JComponent; - -import org.hyperion.hypercon.spec.Led; - -public class LedTvComponent extends JComponent { - - private final BufferedImage mDisplayedImage = new BufferedImage(1280, 720, BufferedImage.TYPE_INT_ARGB); - private final Graphics2D mImageG2d = mDisplayedImage.createGraphics(); - - private final int mBorderWidth = 12; - - private Vector mLeds; - - private Led mSelectedLed; - - public LedTvComponent(Vector pLeds) { - mLeds = pLeds; - - addMouseMotionListener(mMouseMotionListener); - } - - public void setLeds(Vector pLeds) { - mLeds = pLeds; - } - - public void setImage(Image pImage) { - mImageG2d.clearRect(0, 0, mDisplayedImage.getWidth(), mDisplayedImage.getHeight()); - mImageG2d.drawImage(pImage, 0,0, mDisplayedImage.getWidth(), mDisplayedImage.getHeight(), null); - } - - @Override - public void paint(Graphics g) { - Graphics2D g2d = (Graphics2D) g.create(); - - g2d.setColor(Color.DARK_GRAY.darker()); - g2d.fillRect(0,0, getWidth()-1, getHeight()-1); - - g2d.drawImage(mDisplayedImage, mBorderWidth, mBorderWidth, getWidth()-2*mBorderWidth, getHeight()-2*mBorderWidth, null); - if (mLeds == null) { - return; - } - - g2d.setColor(Color.GRAY); - for (Led led : mLeds) { - Rectangle rect = led2tv(led.mImageRectangle); - - g2d.drawRect(rect.x, rect.y, rect.width, rect.height); - - switch (led.mSide) { - case top_left: - g2d.drawString(""+led.mLedSeqNr, 0, 11); - break; - case top: - g2d.drawString(""+led.mLedSeqNr, (int)rect.getCenterX(), 11); - break; - case top_right: - g2d.drawString(""+led.mLedSeqNr, (int)getWidth()-11, (int)11); - break; - case right: - g2d.drawString(""+led.mLedSeqNr, (int)getWidth()-11, (int)rect.getCenterY()); - break; - case bottom_right: - g2d.drawString(""+led.mLedSeqNr, (int)getWidth()-11, (int)getHeight()-1); - break; - case bottom: - g2d.drawString(""+led.mLedSeqNr, (int)rect.getCenterX(), (int)getHeight()-1); - break; - case bottom_left: - g2d.drawString(""+led.mLedSeqNr, (int)0, (int)getHeight()-1); - break; - case left: - g2d.drawString(""+led.mLedSeqNr, 0, (int)rect.getCenterY()); - break; - } - } - if (mSelectedLed != null) { - Rectangle rect = led2tv(mSelectedLed.mImageRectangle); - - g2d.setStroke(new BasicStroke(3.0f)); - g2d.setColor(Color.WHITE); - g2d.drawRect(rect.x, rect.y, rect.width, rect.height); - } - } - - public Rectangle led2tv(Rectangle2D pLedRect) { - int tvWidth = getWidth()-2*mBorderWidth; - int tvHeight = getHeight()-2*mBorderWidth; - - int x = (int) Math.round(mBorderWidth + tvWidth*pLedRect.getX()); - int y = (int) Math.round(mBorderWidth + tvHeight*pLedRect.getY()); - int width = (int) Math.round(tvWidth * pLedRect.getWidth()); - int height = (int) Math.round(tvHeight * pLedRect.getHeight()); - - return new Rectangle(x,y, width, height); - } - - private final MouseMotionListener mMouseMotionListener = new MouseMotionListener() { - @Override - public void mouseMoved(MouseEvent e) { - mSelectedLed = null; - - double x = (double)(e.getX() - mBorderWidth) / (getWidth() - mBorderWidth*2); - double y = (double)(e.getY() - mBorderWidth) / (getHeight() - mBorderWidth*2); - - for (Led led : mLeds) { - if (led.mImageRectangle.contains(x, y) || (Math.abs(led.mLocation.getX() - x) < 0.01 && Math.abs(led.mLocation.getY() - y) < 0.01)) { - mSelectedLed = led; - break; - } - } - - repaint(); - } - @Override - public void mouseDragged(MouseEvent e) { - - } - }; - -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_01.png.REMOVED.git-id b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_01.png.REMOVED.git-id deleted file mode 100644 index b94c7fe7..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_01.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d37be0ef34a74fb15c9ec81e9ebadb57de62d294 \ No newline at end of file diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_02.png.REMOVED.git-id b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_02.png.REMOVED.git-id deleted file mode 100644 index 0f2c589b..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_02.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1df18121f930623884da3de93f146f93d11f621c \ No newline at end of file diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_03.png.REMOVED.git-id b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_03.png.REMOVED.git-id deleted file mode 100644 index 59984f1e..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImageBBB_03.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -97019f8cd170a7792bb81ae09efd690669eef567 \ No newline at end of file diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_01.png.REMOVED.git-id b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_01.png.REMOVED.git-id deleted file mode 100644 index d8f772ef..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_01.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b607e73b98996bfa40d19d508be01919552552d0 \ No newline at end of file diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_02.png.REMOVED.git-id b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_02.png.REMOVED.git-id deleted file mode 100644 index fc6e931f..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_02.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0d3aafb4a85649e53888a660b87de98f59f0ec32 \ No newline at end of file diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_03.png.REMOVED.git-id b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_03.png.REMOVED.git-id deleted file mode 100644 index 09560055..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_03.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7962c1194cb2a2b7af6c3b34151701e113f00087 \ No newline at end of file diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_04.png b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_04.png deleted file mode 100644 index 6106e5fa3b3246769d524bac2c8d5d348c75591e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66588 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 diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_05.png.REMOVED.git-id b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_05.png.REMOVED.git-id deleted file mode 100644 index facc6405..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/TestImage_05.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ad1aba652ea186845d0c340cbeca7efb9d662e10 \ No newline at end of file diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/XbmcPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/XbmcPanel.java deleted file mode 100644 index 6072a722..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/XbmcPanel.java +++ /dev/null @@ -1,263 +0,0 @@ -package org.hyperion.hypercon.gui; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.Transient; - -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSpinner; -import javax.swing.JTextField; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import org.hyperion.hypercon.spec.MiscConfig; - -public class XbmcPanel extends JPanel { - - private final MiscConfig mMiscConfig; - - private JCheckBox mXbmcCheck; - - private JLabel mAddressLabel; - private JTextField mAddressField; - - private JLabel mTcpPortLabel; - private JSpinner mTcpPortSpinner; - - private JLabel mMenuLabel; - private JComboBox mMenuCombo; - private JLabel mVideoLabel; - private JComboBox mVideoCombo; - private JLabel mPictureLabel; - private JComboBox mPictureCombo; - private JLabel mAudioLabel; - private JComboBox mAudioCombo; - private JLabel mScreensaverLabel; - private JComboBox mScreensaverCombo; - private JLabel mEnable3DLabel; - private JComboBox mEnable3DCombo; - - public XbmcPanel(final MiscConfig pMiscConfig) { - super(); - - mMiscConfig = pMiscConfig; - - initialise(); - } - - @Override - @Transient - public Dimension getMaximumSize() { - Dimension maxSize = super.getMaximumSize(); - Dimension prefSize = super.getPreferredSize(); - return new Dimension(maxSize.width, prefSize.height); - } - - private void initialise() { - setBorder(BorderFactory.createTitledBorder("XBMC Checker")); - - mXbmcCheck = new JCheckBox("Enabled"); - mXbmcCheck.setSelected(mMiscConfig.mXbmcCheckerEnabled); - mXbmcCheck.addActionListener(mActionListener); - add(mXbmcCheck); - - mAddressLabel = new JLabel("Server address:"); - add(mAddressLabel); - - mAddressField = new JTextField(mMiscConfig.mXbmcAddress); - mAddressField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void removeUpdate(DocumentEvent e) { - mMiscConfig.mXbmcAddress = mAddressField.getText(); - } - @Override - public void insertUpdate(DocumentEvent e) { - mMiscConfig.mXbmcAddress = mAddressField.getText(); - } - @Override - public void changedUpdate(DocumentEvent e) { - mMiscConfig.mXbmcAddress = mAddressField.getText(); - } - }); - add(mAddressField); - - mTcpPortLabel = new JLabel("TCP port:"); - add(mTcpPortLabel); - - mTcpPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mXbmcTcpPort, 1, 65535, 1)); - mTcpPortSpinner.addChangeListener(mChangeListener); - add(mTcpPortSpinner); - - - mMenuLabel = new JLabel("XBMC Menu"); - add(mMenuLabel); - - mMenuCombo = new JComboBox<>(new String[] {"On", "Off"}); - mMenuCombo.setSelectedItem(mMiscConfig.mMenuOn? "On": "Off"); - mMenuCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light in the XBMC Menu"); - mMenuCombo.addActionListener(mActionListener); - add(mMenuCombo); - - mVideoLabel = new JLabel("Video"); - add(mVideoLabel); - - mVideoCombo = new JComboBox<>(new String[] {"On", "Off"}); - mVideoCombo.setSelectedItem(mMiscConfig.mVideoOn? "On": "Off"); - mVideoCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light during video playback"); - mVideoCombo.addActionListener(mActionListener); - add(mVideoCombo); - - mPictureLabel = new JLabel("Picture"); - add(mPictureLabel); - - mPictureCombo = new JComboBox<>(new String[] {"On", "Off"}); - mPictureCombo.setSelectedItem(mMiscConfig.mPictureOn? "On": "Off"); - mPictureCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light when viewing pictures"); - mPictureCombo.addActionListener(mActionListener); - add(mPictureCombo); - - mAudioLabel = new JLabel("Audio"); - add(mAudioLabel); - - mAudioCombo = new JComboBox<>(new String[] {"On", "Off"}); - mAudioCombo.setSelectedItem(mMiscConfig.mAudioOn? "On": "Off"); - mAudioCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light when listing to audio"); - mAudioCombo.addActionListener(mActionListener); - add(mAudioCombo); - - mScreensaverLabel = new JLabel("Screensaver"); - add(mScreensaverLabel); - - mScreensaverCombo = new JComboBox<>(new String[] {"On", "Off"}); - mScreensaverCombo.setSelectedItem(mMiscConfig.mScreensaverOn? "On": "Off"); - mScreensaverCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light when the XBMC screensaver is active"); - mScreensaverCombo.addActionListener(mActionListener); - add(mScreensaverCombo); - - mEnable3DLabel = new JLabel("3D checking"); - add(mEnable3DLabel); - - mEnable3DCombo = new JComboBox<>(new String[] {"On", "Off"}); - mEnable3DCombo.setSelectedItem(mMiscConfig.m3DCheckingEnabled ? "On": "Off"); - mEnable3DCombo.setToolTipText("Enables('On') or disables('Off') switching to 3D mode when a 3D video file is started"); - mEnable3DCombo.addActionListener(mActionListener); - add(mEnable3DCombo); - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mXbmcCheck) - .addComponent(mAddressLabel) - .addComponent(mTcpPortLabel) - .addComponent(mMenuLabel) - .addComponent(mVideoLabel) - .addComponent(mPictureLabel) - .addComponent(mAudioLabel) - .addComponent(mScreensaverLabel) - .addComponent(mEnable3DLabel) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mXbmcCheck) - .addComponent(mAddressField) - .addComponent(mTcpPortSpinner) - .addComponent(mMenuCombo) - .addComponent(mVideoCombo) - .addComponent(mPictureCombo) - .addComponent(mAudioCombo) - .addComponent(mScreensaverCombo) - .addComponent(mEnable3DCombo) - )); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(mXbmcCheck) - .addGroup(layout.createParallelGroup() - .addComponent(mAddressLabel) - .addComponent(mAddressField) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mTcpPortLabel) - .addComponent(mTcpPortSpinner) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mMenuLabel) - .addComponent(mMenuCombo) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mVideoLabel) - .addComponent(mVideoCombo) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mPictureLabel) - .addComponent(mPictureCombo) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mAudioLabel) - .addComponent(mAudioCombo) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mScreensaverLabel) - .addComponent(mScreensaverCombo) - ) - .addGroup(layout.createParallelGroup() - .addComponent(mEnable3DLabel) - .addComponent(mEnable3DCombo) - )); - - toggleEnabled(mMiscConfig.mXbmcCheckerEnabled); - } - - private void toggleEnabled(boolean pEnabled) { - mAddressLabel.setEnabled(pEnabled); - mAddressField.setEnabled(pEnabled); - - mTcpPortSpinner.setEnabled(pEnabled); - mTcpPortLabel.setEnabled(pEnabled); - - mMenuLabel.setEnabled(pEnabled); - mMenuCombo.setEnabled(pEnabled); - mVideoLabel.setEnabled(pEnabled); - mVideoCombo.setEnabled(pEnabled); - mPictureLabel.setEnabled(pEnabled); - mPictureCombo.setEnabled(pEnabled); - mAudioLabel.setEnabled(pEnabled); - mAudioCombo.setEnabled(pEnabled); - mScreensaverLabel.setEnabled(pEnabled); - mScreensaverCombo.setEnabled(pEnabled); - mEnable3DLabel.setEnabled(pEnabled); - mEnable3DCombo.setEnabled(pEnabled); - } - - private final ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - mMiscConfig.mXbmcTcpPort = (Integer)mTcpPortSpinner.getValue(); - } - }; - - private final ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mMiscConfig.mXbmcCheckerEnabled = mXbmcCheck.isSelected(); - - mMiscConfig.mMenuOn = (mMenuCombo.getSelectedItem() == "On"); - mMiscConfig.mVideoOn = (mVideoCombo.getSelectedItem() == "On"); - mMiscConfig.mPictureOn = (mPictureCombo.getSelectedItem() == "On"); - mMiscConfig.mAudioOn = (mAudioCombo.getSelectedItem() == "On"); - mMiscConfig.mScreensaverOn = (mScreensaverCombo.getSelectedItem() == "On"); - mMiscConfig.m3DCheckingEnabled = (mEnable3DCombo.getSelectedItem() == "On"); - - toggleEnabled(mMiscConfig.mXbmcCheckerEnabled); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/DeviceTypePanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/DeviceTypePanel.java deleted file mode 100644 index 09e75dd2..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/DeviceTypePanel.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.hyperion.hypercon.gui.device; - -import java.awt.Dimension; - -import javax.swing.JPanel; - -import org.hyperion.hypercon.spec.DeviceConfig; - -public abstract class DeviceTypePanel extends JPanel { - - protected final Dimension firstColMinDim = new Dimension(80, 10); - protected final Dimension maxDim = new Dimension(1024, 20); - - protected DeviceConfig mDeviceConfig = null; - - public DeviceTypePanel() { - super(); - } - - public void setDeviceConfig(DeviceConfig pDeviceConfig) { - mDeviceConfig = pDeviceConfig; - } - -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/LightPackPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/LightPackPanel.java deleted file mode 100644 index 05b015ab..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/LightPackPanel.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.hyperion.hypercon.gui.device; - -import javax.swing.GroupLayout; -import javax.swing.JLabel; -import javax.swing.JTextField; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import org.hyperion.hypercon.spec.DeviceConfig; - -public class LightPackPanel extends DeviceTypePanel { - - private JLabel mSerialNoLabel; - private JTextField mSerialNoField; - - public LightPackPanel() { - super(); - - initialise(); - } - - @Override - public void setDeviceConfig(DeviceConfig pDeviceConfig) { - super.setDeviceConfig(pDeviceConfig); - - mSerialNoField.setText(mDeviceConfig.mOutput); - } - - private void initialise() { - mSerialNoLabel = new JLabel("Serial #: "); - mSerialNoLabel.setMinimumSize(firstColMinDim); - add(mSerialNoLabel); - - mSerialNoField = new JTextField(); - mSerialNoField.setMaximumSize(maxDim); - mSerialNoField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void removeUpdate(DocumentEvent e) { - mDeviceConfig.mOutput = mSerialNoField.getText(); - } - @Override - public void insertUpdate(DocumentEvent e) { - mDeviceConfig.mOutput = mSerialNoField.getText(); - } - @Override - public void changedUpdate(DocumentEvent e) { - mDeviceConfig.mOutput = mSerialNoField.getText(); - } - }); - add(mSerialNoField); - - GroupLayout layout = new GroupLayout(this); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addComponent(mSerialNoLabel) - .addComponent(mSerialNoField)); - layout.setVerticalGroup(layout.createParallelGroup() - .addComponent(mSerialNoLabel) - .addComponent(mSerialNoField)); - } - -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/SerialPanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/SerialPanel.java deleted file mode 100644 index 204a6bf9..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/SerialPanel.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.hyperion.hypercon.gui.device; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.GroupLayout; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JSpinner; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import org.hyperion.hypercon.spec.DeviceConfig; - -/** - * Panel for configuring Ws2801 specific settings - */ -public class SerialPanel extends DeviceTypePanel { - - public static final String[] KnownOutputs = { "/dev/ttyS0", "/dev/ttyUSB0", "/dev/ttyAMA0", "/dev/null"}; - - private JLabel mOutputLabel; - private JComboBox mOutputCombo; - - private JLabel mBaudrateLabel; - private JSpinner mBaudrateSpinner; - - - public SerialPanel() { - super(); - - initialise(); - } - - @Override - public void setDeviceConfig(DeviceConfig pDeviceConfig) { - super.setDeviceConfig(pDeviceConfig); - - mOutputCombo.setSelectedItem(mDeviceConfig.mOutput); - ((SpinnerNumberModel)mBaudrateSpinner.getModel()).setValue(mDeviceConfig.mBaudrate); - } - - private void initialise() { - mOutputLabel = new JLabel("Output: "); - mOutputLabel.setMinimumSize(firstColMinDim); - add(mOutputLabel); - - mOutputCombo = new JComboBox<>(KnownOutputs); - mOutputCombo.setMaximumSize(maxDim); - mOutputCombo.setEditable(true); - mOutputCombo.addActionListener(mActionListener); - add(mOutputCombo); - - mBaudrateLabel = new JLabel("Baudrate: "); - mBaudrateLabel.setMinimumSize(firstColMinDim); - add(mBaudrateLabel); - - mBaudrateSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 1000000, 128)); - mBaudrateSpinner .setMaximumSize(maxDim); - mBaudrateSpinner.addChangeListener(mChangeListener); - add(mBaudrateSpinner); - - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mOutputLabel) - .addComponent(mBaudrateLabel)) - .addGroup(layout.createParallelGroup() - .addComponent(mOutputCombo) - .addComponent(mBaudrateSpinner)) - ); - layout.setVerticalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mOutputLabel) - .addComponent(mOutputCombo)) - .addGroup(layout.createParallelGroup() - .addComponent(mBaudrateLabel) - .addComponent(mBaudrateSpinner)) - ); - } - - private ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (e.getSource() == mOutputCombo) { - mDeviceConfig.mOutput = (String)mOutputCombo.getSelectedItem(); - } else if (e.getSource() == mBaudrateSpinner) { - mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue(); - } - } - }; - - private ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue(); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/TestDevicePanel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/TestDevicePanel.java deleted file mode 100644 index edf2487e..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/TestDevicePanel.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.hyperion.hypercon.gui.device; - -import javax.swing.GroupLayout; -import javax.swing.JLabel; -import javax.swing.JTextField; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import org.hyperion.hypercon.spec.DeviceConfig; - -public class TestDevicePanel extends DeviceTypePanel { - - private JLabel mFilenameLabel; - private JTextField mFilenameField; - - public TestDevicePanel() { - super(); - - initialise(); - } - - @Override - public void setDeviceConfig(DeviceConfig pDeviceConfig) { - super.setDeviceConfig(pDeviceConfig); - - mFilenameField.setText(mDeviceConfig.mOutput); - } - - private void initialise() { - mFilenameLabel = new JLabel("Filename: "); - mFilenameLabel.setMinimumSize(firstColMinDim); - add(mFilenameLabel); - - mFilenameField = new JTextField(); - mFilenameField.setMaximumSize(maxDim); - mFilenameField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void removeUpdate(DocumentEvent e) { - mDeviceConfig.mOutput = mFilenameField.getText(); - } - @Override - public void insertUpdate(DocumentEvent e) { - mDeviceConfig.mOutput = mFilenameField.getText(); - } - @Override - public void changedUpdate(DocumentEvent e) { - mDeviceConfig.mOutput = mFilenameField.getText(); - } - }); - add(mFilenameField); - - GroupLayout layout = new GroupLayout(this); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addComponent(mFilenameLabel) - .addComponent(mFilenameField)); - layout.setVerticalGroup(layout.createParallelGroup() - .addComponent(mFilenameLabel) - .addComponent(mFilenameField)); - } - -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/Ws2801Panel.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/Ws2801Panel.java deleted file mode 100644 index ffea3a46..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/gui/device/Ws2801Panel.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.hyperion.hypercon.gui.device; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.GroupLayout; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JSpinner; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import org.hyperion.hypercon.spec.DeviceConfig; - -/** - * Panel for configuring Ws2801 specific settings - */ -public class Ws2801Panel extends DeviceTypePanel { - - public static final String[] KnownOutputs = {"/dev/spidev0.0", "/dev/spidev0.1", "/dev/null"}; - - private JLabel mOutputLabel; - private JComboBox mOutputCombo; - - private JLabel mBaudrateLabel; - private JSpinner mBaudrateSpinner; - - - public Ws2801Panel() { - super(); - - initialise(); - } - - @Override - public void setDeviceConfig(DeviceConfig pDeviceConfig) { - super.setDeviceConfig(pDeviceConfig); - - mOutputCombo.setSelectedItem(mDeviceConfig.mOutput); - ((SpinnerNumberModel)mBaudrateSpinner.getModel()).setValue(mDeviceConfig.mBaudrate); - } - - private void initialise() { - mOutputLabel = new JLabel("Output: "); - mOutputLabel.setMinimumSize(firstColMinDim); - add(mOutputLabel); - - mOutputCombo = new JComboBox<>(KnownOutputs); - mOutputCombo.setMaximumSize(maxDim); - mOutputCombo.setEditable(true); - mOutputCombo.addActionListener(mActionListener); - add(mOutputCombo); - - mBaudrateLabel = new JLabel("Baudrate: "); - mBaudrateLabel.setMinimumSize(firstColMinDim); - add(mBaudrateLabel); - - mBaudrateSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 1000000, 128)); - mBaudrateSpinner.setMaximumSize(maxDim); - mBaudrateSpinner.addChangeListener(mChangeListener); - add(mBaudrateSpinner); - - - GroupLayout layout = new GroupLayout(this); - layout.setAutoCreateGaps(true); - setLayout(layout); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mOutputLabel) - .addComponent(mBaudrateLabel)) - .addGroup(layout.createParallelGroup() - .addComponent(mOutputCombo) - .addComponent(mBaudrateSpinner)) - ); - layout.setVerticalGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup() - .addComponent(mOutputLabel) - .addComponent(mOutputCombo)) - .addGroup(layout.createParallelGroup() - .addComponent(mBaudrateLabel) - .addComponent(mBaudrateSpinner)) - ); - } - - private ActionListener mActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (e.getSource() == mOutputCombo) { - mDeviceConfig.mOutput = (String)mOutputCombo.getSelectedItem(); - } else if (e.getSource() == mBaudrateSpinner) { - mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue(); - } - } - }; - - private ChangeListener mChangeListener = new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue(); - } - }; -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/BorderSide.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/BorderSide.java deleted file mode 100644 index bda7ce3c..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/BorderSide.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.hyperion.hypercon.spec; - -/** - * Enumeration of possible led-locations (aka border-sides). This also contains the specification of - * the angle at which the led is placed along a specific border (0.0rad = pointing right). - */ -public enum BorderSide { - top_left (0.75*Math.PI), - top(0.5*Math.PI), - top_right(0.25*Math.PI), - right(0.0*Math.PI), - bottom_right(-0.25*Math.PI), - bottom(-0.5*Math.PI), - bottom_left(-0.75*Math.PI), - left(1.0*Math.PI); - - /** The angle of the led [rad] */ - private final double mAngle_rad; - - /** - * Constructs the BorderSide with the given led angle - * - * @param pAngle_rad The angle of the led [rad] - */ - BorderSide(double pAngle_rad) { - mAngle_rad = pAngle_rad; - } - - /** - * Returns the angle of the led placement - * - * @return The angle of the led [rad] - */ - public double getAngle_rad() { - return mAngle_rad; - } -} diff --git a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorByteOrder.java b/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorByteOrder.java deleted file mode 100644 index c301ffc9..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorByteOrder.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.hyperion.hypercon.spec; - -public enum ColorByteOrder { - RGB, RBG, BRG, BGR, GRB, GBR -} 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 deleted file mode 100644 index e55a76cf..00000000 --- a/src/config-tool/ConfigTool/src/org/hyperion/hypercon/spec/ColorConfig.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.hyperion.hypercon.spec; - -import java.util.Locale; -import java.util.Vector; - -/** - * The color tuning parameters of the different color channels (both in RGB space as in HSV space) - */ -public class ColorConfig { - - /** List with color transformations */ - public Vector mTransforms = new Vector<>(); - { - mTransforms.add(new TransformConfig()); - } - - public boolean mSmoothingEnabled = false; - /** The type of smoothing algorithm */ - public ColorSmoothingType mSmoothingType = ColorSmoothingType.linear; - /** The time constant for smoothing algorithm in milliseconds */ - public int mSmoothingTime_ms = 200; - /** The update frequency of the leds in Hz */ - public double mSmoothingUpdateFrequency_Hz = 20.0; - - /** - * Creates the JSON string of the configuration as used in the Hyperion daemon configfile - * - * @return The JSON string of this ColorConfig - */ - public String toJsonString() { - StringBuffer strBuf = new StringBuffer(); - - strBuf.append("\t/// Color manipulation configuration used to tune the output colors to specific surroundings. \n"); - strBuf.append("\t/// The configuration contains a list of color-transforms. Each transform contains the \n"); - strBuf.append("\t/// following fields:\n"); - strBuf.append("\t/// * 'id' : The unique identifier of the color transformation (eg 'device_1')"); - strBuf.append("\t/// * 'leds' : The indices (or index ranges) of the leds to which this color transform applies\n"); - strBuf.append("\t/// (eg '0-5, 9, 11, 12-17'). The indices are zero based."); - strBuf.append("\t/// * 'hsv' : The manipulation in the Hue-Saturation-Value color domain with the following \n"); - strBuf.append("\t/// tuning parameters:\n"); - strBuf.append("\t/// - 'saturationGain' The gain adjustement of the saturation\n"); - strBuf.append("\t/// - 'valueGain' The gain adjustement of the value\n"); - strBuf.append("\t/// * 'red'/'green'/'blue' : The manipulation in the Red-Green-Blue color domain with the \n"); - strBuf.append("\t/// following tuning parameters for each channel:\n"); - strBuf.append("\t/// - 'threshold' The minimum required input value for the channel to be on \n"); - strBuf.append("\t/// (else zero)\n"); - strBuf.append("\t/// - 'gamma' The gamma-curve correction factor\n"); - strBuf.append("\t/// - 'blacklevel' The lowest possible value (when the channel is black)\n"); - strBuf.append("\t/// - 'whitelevel' The highest possible value (when the channel is white)\n"); - strBuf.append("\t///\n"); - strBuf.append("\t/// Next to the list with color transforms there is also a smoothing option.\n"); - strBuf.append("\t/// * 'smoothing' : Smoothing of the colors in the time-domain with the following tuning \n"); - strBuf.append("\t/// parameters:\n"); - strBuf.append("\t/// - 'type' The type of smoothing algorithm ('linear' or 'none')\n"); - strBuf.append("\t/// - 'time_ms' The time constant for smoothing algorithm in milliseconds\n"); - strBuf.append("\t/// - 'updateFrequency' The update frequency of the leds in Hz\n"); - - strBuf.append("\t\"color\" :\n"); - strBuf.append("\t{\n"); - - strBuf.append("\t\t\"transform\" :\n"); - strBuf.append("\t\t[\n"); - for (int i=0; i