mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Finished the effect argument table (with storage to HyperCon settings)
Former-commit-id: e0e397b9df8c8dc1eb30f0a0fb5d2df0f7187809
This commit is contained in:
parent
3ebcc1f69a
commit
26fb5c534a
@ -1,5 +1,6 @@
|
|||||||
package org.hyperion.hypercon;
|
package org.hyperion.hypercon;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -12,9 +13,19 @@ import java.lang.reflect.ParameterizedType;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for supporting the serialisation and deserialisation of HyperCon settings.
|
||||||
|
*/
|
||||||
public class ConfigurationFile {
|
public class ConfigurationFile {
|
||||||
|
|
||||||
|
/** Temporary storage of the HyperCon configuration */
|
||||||
private final Properties mProps = new Properties();
|
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) {
|
public void load(String pFilename) {
|
||||||
mProps.clear();
|
mProps.clear();
|
||||||
// try (InputStream in = new InflaterInputStream(new FileInputStream(pFilename))){
|
// try (InputStream in = new InflaterInputStream(new FileInputStream(pFilename))){
|
||||||
@ -27,6 +38,11 @@ public class ConfigurationFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
public void save(String pFilename) {
|
||||||
// try (OutputStream out = new DeflaterOutputStream(new FileOutputStream(pFilename))) {
|
// try (OutputStream out = new DeflaterOutputStream(new FileOutputStream(pFilename))) {
|
||||||
// try (OutputStream out = new GZIPOutputStream(new FileOutputStream(pFilename))) {
|
// try (OutputStream out = new GZIPOutputStream(new FileOutputStream(pFilename))) {
|
||||||
@ -37,9 +53,22 @@ public class ConfigurationFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the given object to the local properties object
|
||||||
|
*
|
||||||
|
* @param pObj The object to store
|
||||||
|
*/
|
||||||
public void store(Object pObj) {
|
public void store(Object pObj) {
|
||||||
store(pObj, pObj.getClass().getSimpleName(), "");
|
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) {
|
public void store(Object pObj, String preamble, String postamble) {
|
||||||
String className = pObj.getClass().getSimpleName();
|
String className = pObj.getClass().getSimpleName();
|
||||||
// Retrieve the member variables
|
// Retrieve the member variables
|
||||||
@ -55,37 +84,80 @@ public class ConfigurationFile {
|
|||||||
try {
|
try {
|
||||||
Object value = field.get(pObj);
|
Object value = field.get(pObj);
|
||||||
|
|
||||||
if (value.getClass().isEnum()) {
|
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());
|
mProps.setProperty(key, ((Enum<?>)value).name());
|
||||||
} else if (value.getClass().isAssignableFrom(Vector.class)) {
|
} else if (value instanceof Vector) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Vector<Object> v = (Vector<Object>) value;
|
Vector<Object> v = (Vector<Object>) value;
|
||||||
for (int i=0; i<v.size(); ++i) {
|
for (int i=0; i<v.size(); ++i) {
|
||||||
store(v.get(i), key + "[" + i + "]", "");
|
store(v.get(i), key + "[" + i + "]", "");
|
||||||
}
|
}
|
||||||
|
} else if (field.getType() == Object.class) {
|
||||||
|
if (value instanceof Boolean) {
|
||||||
|
mProps.setProperty(key, Boolean.toString((boolean) value));
|
||||||
|
} if (value instanceof Integer) {
|
||||||
|
mProps.setProperty(key, Integer.toString((int) value));
|
||||||
|
} else if (value instanceof Double) {
|
||||||
|
mProps.setProperty(key, Double.toString((double) value));
|
||||||
|
} else if (value instanceof Color) {
|
||||||
|
Color color = (Color)value;
|
||||||
|
mProps.setProperty(key, String.format("[%d; %d; %d]", color.getRed(), color.getGreen(), color.getBlue()));
|
||||||
|
} else if (value instanceof String) {
|
||||||
|
mProps.setProperty(key, '"' + (String)value + '"');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
System.out.println("Might not be able to load: " + key + " = " + value.toString());
|
||||||
mProps.setProperty(key, value.toString());
|
mProps.setProperty(key, value.toString());
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {}
|
} catch (Throwable t) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the object from the local properties object
|
||||||
|
*
|
||||||
|
* @param pObj The object to restore
|
||||||
|
*/
|
||||||
public void restore(Object pObj) {
|
public void restore(Object pObj) {
|
||||||
restore(pObj, mProps);
|
restore(pObj, mProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the object from the given object object
|
||||||
|
*
|
||||||
|
* @param pObj The object to restore
|
||||||
|
* @param pProps The properties containing values for the members of obj
|
||||||
|
*/
|
||||||
public void restore(Object pObj, Properties pProps) {
|
public void restore(Object pObj, Properties pProps) {
|
||||||
String className = pObj.getClass().getSimpleName();
|
String className = pObj.getClass().getSimpleName();
|
||||||
restore(pObj, pProps, className + ".");
|
restore(pObj, pProps, className + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the object from the given settings object, using the given preamble
|
||||||
|
*
|
||||||
|
* @param pObj The object to restore
|
||||||
|
* @param pProps The properties containing values for the members of obj
|
||||||
|
* @param pPreamble The preamble to use
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void restore(Object pObj, Properties pProps, String pPreamble) {
|
public void restore(Object pObj, Properties pProps, String pPreamble) {
|
||||||
// Retrieve the member variables
|
// Retrieve the member variables
|
||||||
Field[] fields = pObj.getClass().getDeclaredFields();
|
Field[] fields = pObj.getClass().getDeclaredFields();
|
||||||
// Iterate each variable
|
// Iterate each variable
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
if (field.getType().isAssignableFrom(Vector.class)) {
|
if (field.getType().equals(Vector.class)) {
|
||||||
// Obtain the Vector
|
// Obtain the Vector
|
||||||
Vector<Object> vector;
|
Vector<Object> vector;
|
||||||
try {
|
try {
|
||||||
@ -157,19 +229,56 @@ public class ConfigurationFile {
|
|||||||
field.set(pObj, Integer.parseInt(value));
|
field.set(pObj, Integer.parseInt(value));
|
||||||
} else if (field.getType() == double.class) {
|
} else if (field.getType() == double.class) {
|
||||||
field.set(pObj, Double.parseDouble(value));
|
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()) {
|
} else if (field.getType().isEnum()) {
|
||||||
Method valMet = field.getType().getMethod("valueOf", String.class);
|
Method valMet = field.getType().getMethod("valueOf", String.class);
|
||||||
Object enumVal = valMet.invoke(null, value);
|
Object enumVal = valMet.invoke(null, value);
|
||||||
field.set(pObj, enumVal);
|
field.set(pObj, enumVal);
|
||||||
} else {
|
} else if (field.getType() == Object.class) {
|
||||||
field.set(pObj, value);
|
// 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) {
|
} catch (Throwable t) {
|
||||||
System.out.println("Failed to parse value(" + value + ") for " + key);
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return mProps.toString();
|
return mProps.toString();
|
||||||
|
@ -16,7 +16,6 @@ import org.hyperion.hypercon.spec.MiscConfig;
|
|||||||
* The full configuration of Hyperion with sub-items for device, color and miscelanuous items.
|
* The full configuration of Hyperion with sub-items for device, color and miscelanuous items.
|
||||||
*/
|
*/
|
||||||
public class LedString {
|
public class LedString {
|
||||||
|
|
||||||
/** The configuration of the output device */
|
/** The configuration of the output device */
|
||||||
public final DeviceConfig mDeviceConfig = new DeviceConfig();
|
public final DeviceConfig mDeviceConfig = new DeviceConfig();
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ import org.hyperion.hypercon.gui.ConfigPanel;
|
|||||||
*/
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
public static final String configFilename = "hypercon.dat";
|
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
|
* Entry point to start HyperCon
|
||||||
@ -42,11 +45,13 @@ public class Main {
|
|||||||
@Override
|
@Override
|
||||||
public void windowClosing(WindowEvent e) {
|
public void windowClosing(WindowEvent e) {
|
||||||
ConfigurationFile configFile = new ConfigurationFile();
|
ConfigurationFile configFile = new ConfigurationFile();
|
||||||
|
configFile.store(Main.HyperConConfig);
|
||||||
configFile.store(ledString.mDeviceConfig);
|
configFile.store(ledString.mDeviceConfig);
|
||||||
configFile.store(ledString.mLedFrameConfig);
|
configFile.store(ledString.mLedFrameConfig);
|
||||||
configFile.store(ledString.mProcessConfig);
|
configFile.store(ledString.mProcessConfig);
|
||||||
configFile.store(ledString.mColorConfig);
|
configFile.store(ledString.mColorConfig);
|
||||||
configFile.store(ledString.mMiscConfig);
|
configFile.store(ledString.mMiscConfig);
|
||||||
|
configFile.store(ledString.mEffectEngineConfig);
|
||||||
configFile.save(configFilename);
|
configFile.save(configFilename);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -54,11 +59,18 @@ public class Main {
|
|||||||
if (new File(configFilename).exists()) {
|
if (new File(configFilename).exists()) {
|
||||||
ConfigurationFile configFile = new ConfigurationFile();
|
ConfigurationFile configFile = new ConfigurationFile();
|
||||||
configFile.load(configFilename);
|
configFile.load(configFilename);
|
||||||
|
configFile.restore(Main.HyperConConfig);
|
||||||
configFile.restore(ledString.mDeviceConfig);
|
configFile.restore(ledString.mDeviceConfig);
|
||||||
configFile.restore(ledString.mLedFrameConfig);
|
configFile.restore(ledString.mLedFrameConfig);
|
||||||
configFile.restore(ledString.mProcessConfig);
|
configFile.restore(ledString.mProcessConfig);
|
||||||
configFile.restore(ledString.mColorConfig);
|
configFile.restore(ledString.mColorConfig);
|
||||||
configFile.restore(ledString.mMiscConfig);
|
configFile.restore(ledString.mMiscConfig);
|
||||||
|
configFile.restore(ledString.mEffectEngineConfig);
|
||||||
|
|
||||||
|
if (HyperConConfig.loadDefaultEffect) {
|
||||||
|
ledString.mEffectEngineConfig.loadDefault();
|
||||||
|
HyperConConfig.loadDefaultEffect = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the HyperCon configuration panel
|
// Add the HyperCon configuration panel
|
||||||
|
@ -21,6 +21,7 @@ import org.hyperion.hypercon.ConfigurationFile;
|
|||||||
import org.hyperion.hypercon.LedFrameFactory;
|
import org.hyperion.hypercon.LedFrameFactory;
|
||||||
import org.hyperion.hypercon.LedString;
|
import org.hyperion.hypercon.LedString;
|
||||||
import org.hyperion.hypercon.Main;
|
import org.hyperion.hypercon.Main;
|
||||||
|
import org.hyperion.hypercon.gui.effectengine.EffectEnginePanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main-config panel of HyperCon. Includes the configuration and the panels to edit and
|
* The main-config panel of HyperCon. Includes the configuration and the panels to edit and
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
package org.hyperion.hypercon.gui;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Component;
|
|
||||||
|
|
||||||
import javax.swing.AbstractCellEditor;
|
|
||||||
import javax.swing.JCheckBox;
|
|
||||||
import javax.swing.JColorChooser;
|
|
||||||
import javax.swing.JSpinner;
|
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.JTextField;
|
|
||||||
import javax.swing.SpinnerNumberModel;
|
|
||||||
import javax.swing.table.TableCellEditor;
|
|
||||||
|
|
||||||
public class EffectArgumentCellEditor extends AbstractCellEditor implements TableCellEditor {
|
|
||||||
|
|
||||||
int selEditor = 0;
|
|
||||||
|
|
||||||
private JSpinner mIntegerSpinner = new JSpinner(new SpinnerNumberModel(0, Integer.MIN_VALUE, Integer.MAX_VALUE, 1));
|
|
||||||
private JSpinner mDoubleSpinner = new JSpinner(new SpinnerNumberModel(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 1.0));
|
|
||||||
private JCheckBox mBooleanCheck = new JCheckBox();
|
|
||||||
private JColorChooser mColorChooser = new JColorChooser();
|
|
||||||
private JTextField mStringEditor = new JTextField();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getCellEditorValue() {
|
|
||||||
switch (selEditor) {
|
|
||||||
case 0:
|
|
||||||
return mIntegerSpinner.getValue();
|
|
||||||
case 1:
|
|
||||||
return mDoubleSpinner.getValue();
|
|
||||||
case 2:
|
|
||||||
return mBooleanCheck.isSelected();
|
|
||||||
case 3:
|
|
||||||
return mStringEditor.getText();
|
|
||||||
case 4:
|
|
||||||
return mColorChooser.getColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
|
|
||||||
if (value instanceof Integer) {
|
|
||||||
selEditor = 0;
|
|
||||||
mIntegerSpinner.setValue((Integer)value);
|
|
||||||
return mIntegerSpinner;
|
|
||||||
} else if (value instanceof Double) {
|
|
||||||
selEditor = 1;
|
|
||||||
mDoubleSpinner.setValue((Double)value);
|
|
||||||
return mDoubleSpinner;
|
|
||||||
} else if (value instanceof Boolean) {
|
|
||||||
selEditor = 2;
|
|
||||||
mBooleanCheck.setSelected((Boolean)value);
|
|
||||||
return mBooleanCheck;
|
|
||||||
} else if (value instanceof Color) {
|
|
||||||
selEditor = 4;
|
|
||||||
// return mColorCombo;
|
|
||||||
}
|
|
||||||
|
|
||||||
selEditor = 3;
|
|
||||||
mStringEditor.setText('"' + value.toString() + '"');
|
|
||||||
return mStringEditor;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,364 +0,0 @@
|
|||||||
package org.hyperion.hypercon.gui;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import javax.swing.ComboBoxEditor;
|
|
||||||
import javax.swing.DefaultComboBoxModel;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JComboBox;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.JTextField;
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
|
||||||
import javax.swing.table.TableColumn;
|
|
||||||
|
|
||||||
import org.hyperion.hypercon.spec.EffectConfig;
|
|
||||||
import org.hyperion.hypercon.spec.EffectEngineConfig;
|
|
||||||
|
|
||||||
public class EffectEnginePanel extends JPanel {
|
|
||||||
|
|
||||||
private final EffectEngineConfig mEffectEngingeConfig;
|
|
||||||
|
|
||||||
private final DefaultComboBoxModel<EffectConfig> mEffectModel;
|
|
||||||
|
|
||||||
private JPanel mControlPanel;
|
|
||||||
private JComboBox<EffectConfig> mEffectCombo;
|
|
||||||
private JButton mCloneButton;
|
|
||||||
private JButton mAddButton;
|
|
||||||
private JButton mDelButton;
|
|
||||||
|
|
||||||
private JPanel mEffectPanel;
|
|
||||||
private JLabel mPythonLabel;
|
|
||||||
private JComboBox<String> mPythonCombo;
|
|
||||||
private JPanel mEffectArgumentPanel;
|
|
||||||
private JTable mEffectArgumentTable;
|
|
||||||
|
|
||||||
private AbstractTableModel mEffectArgumentTableModel = new AbstractTableModel() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
|
||||||
EffectConfig effect = (EffectConfig) mEffectModel.getSelectedItem();
|
|
||||||
if (effect == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (rowIndex == effect.mArgs.size()) {
|
|
||||||
return columnIndex == 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnCount() {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int column) {
|
|
||||||
switch (column) {
|
|
||||||
case 0:
|
|
||||||
return "name";
|
|
||||||
case 1:
|
|
||||||
return "value";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowCount() {
|
|
||||||
EffectConfig effect = (EffectConfig) mEffectModel.getSelectedItem();
|
|
||||||
if (effect == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return effect.mArgs.size() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
|
||||||
EffectConfig effect = (EffectConfig) mEffectModel.getSelectedItem();
|
|
||||||
if (effect == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (rowIndex == effect.mArgs.size()) {
|
|
||||||
if (columnIndex == 0) {
|
|
||||||
return "[key]";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (columnIndex == 0) {
|
|
||||||
return effect.mArgs.get(rowIndex).key;
|
|
||||||
} else if (columnIndex == 1){
|
|
||||||
return effect.mArgs.get(rowIndex).value;
|
|
||||||
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
|
||||||
EffectConfig effect = (EffectConfig) mEffectModel.getSelectedItem();
|
|
||||||
if (effect == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowIndex == effect.mArgs.size()) {
|
|
||||||
String key = aValue.toString().trim();
|
|
||||||
if (key.isEmpty() || key.equals("[key]")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
effect.mArgs.addElement(new EffectConfig.EffectArg(aValue.toString(), ""));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (columnIndex == 0) {
|
|
||||||
String key = aValue.toString().trim();
|
|
||||||
if (key.isEmpty()) {
|
|
||||||
effect.mArgs.remove(rowIndex);
|
|
||||||
} else {
|
|
||||||
effect.mArgs.get(rowIndex).key = (String)aValue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (aValue instanceof String) {
|
|
||||||
// Get the value without any trailing or leading spaces
|
|
||||||
String str = ((String)aValue).trim();
|
|
||||||
if (str.charAt(0) == '"' && str.charAt(str.length()-1) == '"') {
|
|
||||||
// If the string is quoted it is an actual string
|
|
||||||
String actStr = str.substring(1, str.length()-1);
|
|
||||||
if (actStr.contains("\"")) {
|
|
||||||
// String can not contain quotes
|
|
||||||
} else {
|
|
||||||
effect.mArgs.get(rowIndex).value = actStr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// The string is not a string, let's find out what it is
|
|
||||||
if (str.equalsIgnoreCase("true") || str.equalsIgnoreCase("false")) {
|
|
||||||
// It is a BOOLEAN
|
|
||||||
effect.mArgs.get(rowIndex).value = str.equalsIgnoreCase("true");
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
int intVal = Integer.parseInt(str);
|
|
||||||
// It is an INT
|
|
||||||
effect.mArgs.get(rowIndex).value = intVal;
|
|
||||||
} catch (Throwable t1) {
|
|
||||||
// It was not an integer apparently
|
|
||||||
try {
|
|
||||||
double doubleVal = Double.parseDouble(str);
|
|
||||||
effect.mArgs.get(rowIndex).value = doubleVal;
|
|
||||||
} catch (Throwable t2) {
|
|
||||||
// It was not an double apparently ....
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
effect.mArgs.get(rowIndex).value = aValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
public EffectEnginePanel(final EffectEngineConfig pEffectEngineConfig) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
mEffectEngingeConfig = pEffectEngineConfig;
|
|
||||||
mEffectModel = new DefaultComboBoxModel<EffectConfig>(mEffectEngingeConfig.mEffects);
|
|
||||||
|
|
||||||
initialise();
|
|
||||||
|
|
||||||
effectSelectionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initialise() {
|
|
||||||
setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
add(getControlPanel(), BorderLayout.NORTH);
|
|
||||||
add(getEffectPanel(), BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void effectSelectionChanged() {
|
|
||||||
EffectConfig effect = (EffectConfig)mEffectModel.getSelectedItem();
|
|
||||||
|
|
||||||
// Enable option for the selected effect or disable if none selected
|
|
||||||
mEffectPanel.setEnabled(effect != null);
|
|
||||||
mPythonLabel.setEnabled(effect != null);
|
|
||||||
mPythonCombo.setEnabled(effect != null);
|
|
||||||
mEffectArgumentTable.setEnabled(effect != null);
|
|
||||||
|
|
||||||
|
|
||||||
if (effect == null) {
|
|
||||||
// Clear all fields
|
|
||||||
mPythonCombo.setSelectedIndex(-1);
|
|
||||||
mEffectArgumentTableModel.fireTableDataChanged();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Update fields based on the selected effect
|
|
||||||
mPythonCombo.setSelectedItem(effect.mScript);
|
|
||||||
mEffectArgumentTableModel.fireTableDataChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel getControlPanel() {
|
|
||||||
if (mControlPanel == null) {
|
|
||||||
mControlPanel = new JPanel();
|
|
||||||
mControlPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 2, 5));
|
|
||||||
mControlPanel.setPreferredSize(new Dimension(150, 25));
|
|
||||||
mControlPanel.setLayout(new BoxLayout(mControlPanel, BoxLayout.LINE_AXIS));
|
|
||||||
|
|
||||||
mEffectCombo = new JComboBox<>(mEffectModel);
|
|
||||||
mEffectCombo.setEditable(true);
|
|
||||||
mEffectCombo.setEditor(new ComboBoxEditor() {
|
|
||||||
private final JTextField mTextField = new JTextField();
|
|
||||||
|
|
||||||
private EffectConfig mCurrentEffect = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setItem(Object anObject) {
|
|
||||||
if (anObject instanceof EffectConfig) {
|
|
||||||
mCurrentEffect = (EffectConfig) anObject;
|
|
||||||
mTextField.setText(mCurrentEffect.mId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void selectAll() {
|
|
||||||
if (mCurrentEffect == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mTextField.setText(mCurrentEffect.mId);
|
|
||||||
mTextField.setSelectionStart(0);
|
|
||||||
mTextField.setSelectionEnd(mCurrentEffect.mId.length()-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getItem() {
|
|
||||||
String newId = mTextField.getText().trim();
|
|
||||||
if (newId.isEmpty() || newId.contains("\"")) {
|
|
||||||
return mCurrentEffect;
|
|
||||||
}
|
|
||||||
mCurrentEffect.mId = newId;
|
|
||||||
return mCurrentEffect; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getEditorComponent() {
|
|
||||||
return mTextField;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Vector<ActionListener> mActionListeners = new Vector<>();
|
|
||||||
@Override
|
|
||||||
public void addActionListener(ActionListener l) {
|
|
||||||
mActionListeners.add(l);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void removeActionListener(ActionListener l) {
|
|
||||||
mActionListeners.remove(l);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mEffectCombo.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
effectSelectionChanged();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mControlPanel.add(mEffectCombo);
|
|
||||||
|
|
||||||
mCloneButton = new JButton("Clone");
|
|
||||||
mCloneButton.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
EffectConfig effect = (EffectConfig) mEffectModel.getSelectedItem();
|
|
||||||
EffectConfig effectClone = effect.clone();
|
|
||||||
effectClone.mId += " [clone]";
|
|
||||||
mEffectModel.addElement(effectClone);
|
|
||||||
mEffectModel.setSelectedItem(effectClone);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mControlPanel.add(mCloneButton);
|
|
||||||
|
|
||||||
mAddButton = new JButton("Add");
|
|
||||||
mAddButton.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
String newId = JOptionPane.showInputDialog(mAddButton, "Name of the new effect: ", "Effect Name", JOptionPane.QUESTION_MESSAGE);
|
|
||||||
// Make that an ID is set
|
|
||||||
if (newId == null || newId.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Make sure the ID does not yet exist
|
|
||||||
for (EffectConfig effect : mEffectEngingeConfig.mEffects) {
|
|
||||||
if (effect.mId.equalsIgnoreCase(newId)) {
|
|
||||||
JOptionPane.showMessageDialog(mAddButton, "Given name(" + effect.mId + ") allready exists", "Duplicate effect name", JOptionPane.ERROR_MESSAGE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EffectConfig newConfig = new EffectConfig();
|
|
||||||
newConfig.mId = newId;
|
|
||||||
mEffectModel.addElement(newConfig);
|
|
||||||
mEffectModel.setSelectedItem(newConfig);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mControlPanel.add(mAddButton);
|
|
||||||
|
|
||||||
mDelButton = new JButton("Del");
|
|
||||||
mDelButton.setEnabled(mEffectModel.getSize() > 0);
|
|
||||||
mDelButton.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
if (mEffectModel.getSelectedItem() != null) {
|
|
||||||
mEffectModel.removeElement(mEffectModel.getSelectedItem());
|
|
||||||
}
|
|
||||||
mDelButton.setEnabled(mEffectModel.getSize() > 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mControlPanel.add(mDelButton);
|
|
||||||
}
|
|
||||||
return mControlPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel getEffectPanel() {
|
|
||||||
if (mEffectPanel == null) {
|
|
||||||
mEffectPanel = new JPanel();
|
|
||||||
mEffectPanel.setBorder(BorderFactory.createTitledBorder(""));
|
|
||||||
mEffectPanel.setLayout(new BoxLayout(mEffectPanel, BoxLayout.PAGE_AXIS));
|
|
||||||
|
|
||||||
JPanel subPanel = new JPanel(new BorderLayout());
|
|
||||||
subPanel.setPreferredSize(new Dimension(150, 25));
|
|
||||||
subPanel.setMaximumSize(new Dimension(20000, 20));
|
|
||||||
mEffectPanel.add(subPanel);
|
|
||||||
|
|
||||||
mPythonLabel = new JLabel("Python: ");
|
|
||||||
subPanel.add(mPythonLabel, BorderLayout.WEST);
|
|
||||||
|
|
||||||
mPythonCombo = new JComboBox<>(new String[] {"test.py", "rainbow-swirl.py", "rainbow-mood.py"});
|
|
||||||
// mPythonCombo.setEditable(true);
|
|
||||||
mPythonCombo.setMaximumSize(new Dimension(150, 25));
|
|
||||||
subPanel.add(mPythonCombo);
|
|
||||||
|
|
||||||
mEffectArgumentPanel = new JPanel();
|
|
||||||
mEffectArgumentPanel.setBorder(BorderFactory.createTitledBorder("Arguments"));
|
|
||||||
mEffectArgumentPanel.setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
mEffectArgumentTable = new JTable(mEffectArgumentTableModel);
|
|
||||||
mEffectArgumentPanel.add(new JScrollPane(mEffectArgumentTable));
|
|
||||||
|
|
||||||
mEffectPanel.add(mEffectArgumentPanel);
|
|
||||||
|
|
||||||
TableColumn col = mEffectArgumentTable.getColumnModel().getColumn(1);
|
|
||||||
col.setCellEditor(new EffectArgumentCellEditor());
|
|
||||||
|
|
||||||
mEffectArgumentTable.setCellEditor(new EffectArgumentCellEditor());
|
|
||||||
}
|
|
||||||
return mEffectPanel;
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,14 +18,29 @@ public class EffectConfig {
|
|||||||
/** The arguments (key-value) of the python-script */
|
/** The arguments (key-value) of the python-script */
|
||||||
public final Vector<EffectArg> mArgs = new Vector<>();
|
public final Vector<EffectArg> mArgs = new Vector<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The effect argument contains a key-value combination that holds a single argument of an
|
||||||
|
* effect
|
||||||
|
*/
|
||||||
static public class EffectArg {
|
static public class EffectArg {
|
||||||
|
/** The key of the effect argument */
|
||||||
public String key;
|
public String key;
|
||||||
|
/** The value of the effect argument */
|
||||||
public Object value;
|
public Object value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an new effect argument with empty key and value
|
||||||
|
*/
|
||||||
public EffectArg() {
|
public EffectArg() {
|
||||||
key = "";
|
this("", "");
|
||||||
value = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an effect argument with the given key and value
|
||||||
|
*
|
||||||
|
* @param pKey The key of the new argument
|
||||||
|
* @param pValue The value of the new argument
|
||||||
|
*/
|
||||||
public EffectArg(String pKey, Object pValue) {
|
public EffectArg(String pKey, Object pValue) {
|
||||||
key = pKey;
|
key = pKey;
|
||||||
value = pValue;
|
value = pValue;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package org.hyperion.hypercon.spec;
|
package org.hyperion.hypercon.spec;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.hyperion.hypercon.JsonStringBuffer;
|
import org.hyperion.hypercon.JsonStringBuffer;
|
||||||
@ -12,7 +11,18 @@ import org.hyperion.hypercon.JsonStringBuffer;
|
|||||||
public class EffectEngineConfig {
|
public class EffectEngineConfig {
|
||||||
|
|
||||||
public final Vector<EffectConfig> mEffects = new Vector<>();
|
public final Vector<EffectConfig> mEffects = new Vector<>();
|
||||||
{
|
|
||||||
|
public void appendTo(JsonStringBuffer pJsonBuf) {
|
||||||
|
pJsonBuf.startObject("effects");
|
||||||
|
|
||||||
|
for (EffectConfig effect : mEffects) {
|
||||||
|
effect.append(pJsonBuf, effect.equals(mEffects.get(mEffects.size()-1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pJsonBuf.stopObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadDefault() {
|
||||||
EffectConfig rainbowSwirl = new EffectConfig();
|
EffectConfig rainbowSwirl = new EffectConfig();
|
||||||
rainbowSwirl.mId = "Rainbow swirl";
|
rainbowSwirl.mId = "Rainbow swirl";
|
||||||
rainbowSwirl.mScript = "rainbow-swirl.py";
|
rainbowSwirl.mScript = "rainbow-swirl.py";
|
||||||
@ -26,20 +36,8 @@ public class EffectEngineConfig {
|
|||||||
rainbowMood.mArgs.add(new EffectConfig.EffectArg("rotation-time", 10.0));
|
rainbowMood.mArgs.add(new EffectConfig.EffectArg("rotation-time", 10.0));
|
||||||
rainbowMood.mArgs.add(new EffectConfig.EffectArg("brightness", 1.0));
|
rainbowMood.mArgs.add(new EffectConfig.EffectArg("brightness", 1.0));
|
||||||
rainbowMood.mArgs.add(new EffectConfig.EffectArg("reverse", false));
|
rainbowMood.mArgs.add(new EffectConfig.EffectArg("reverse", false));
|
||||||
rainbowMood.mArgs.add(new EffectConfig.EffectArg("test", "test"));
|
|
||||||
rainbowMood.mArgs.add(new EffectConfig.EffectArg("AColor", Color.RED));
|
|
||||||
|
|
||||||
mEffects.add(rainbowSwirl);
|
mEffects.add(rainbowSwirl);
|
||||||
mEffects.add(rainbowMood);
|
mEffects.add(rainbowMood);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void appendTo(JsonStringBuffer pJsonBuf) {
|
|
||||||
pJsonBuf.startObject("effects");
|
|
||||||
|
|
||||||
for (EffectConfig effect : mEffects) {
|
|
||||||
effect.append(pJsonBuf, effect.equals(mEffects.get(mEffects.size()-1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
pJsonBuf.stopObject();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user