package net.sf.openrocket.gui.figure3d.photo;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
import java.util.EventObject;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.components.ColorIcon;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.figure3d.photo.sky.Sky;
import net.sf.openrocket.gui.figure3d.photo.sky.Sky.Credit;
import net.sf.openrocket.gui.figure3d.photo.sky.builtin.Lake;
import net.sf.openrocket.gui.figure3d.photo.sky.builtin.Meadow;
import net.sf.openrocket.gui.figure3d.photo.sky.builtin.Miramar;
import net.sf.openrocket.gui.figure3d.photo.sky.builtin.Mountains;
import net.sf.openrocket.gui.figure3d.photo.sky.builtin.Orbit;
import net.sf.openrocket.gui.figure3d.photo.sky.builtin.Storm;
import net.sf.openrocket.gui.util.ColorConversion;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.StateChangeListener;
@SuppressWarnings("serial")
public class PhotoSettingsConfig extends JTabbedPane {
private final Translator trans = Application.getTranslator();
private static final JColorChooser colorChooser = new JColorChooser();
private class ColorActionListener implements ActionListener {
private final String valueName;
private final Object o;
ColorActionListener(final Object o, final String valueName) {
this.valueName = valueName;
this.o = o;
}
@Override
public void actionPerformed(ActionEvent colorClickEvent) {
try {
final Method getMethod = o.getClass().getMethod("get" + valueName);
final Method setMethod = o.getClass().getMethod("set" + valueName, net.sf.openrocket.util.Color.class);
net.sf.openrocket.util.Color c = (net.sf.openrocket.util.Color) getMethod.invoke(o);
Color awtColor = ColorConversion.toAwtColor(c);
colorChooser.setColor(awtColor);
JDialog d = JColorChooser.createDialog(PhotoSettingsConfig.this,
trans.get("PhotoSettingsConfig.colorChooser.title"), true, colorChooser, new ActionListener() {
@Override
public void actionPerformed(ActionEvent okEvent) {
Color selected = colorChooser.getColor();
if (selected == null)
return;
try {
setMethod.invoke(o, ColorConversion.fromAwtColor(selected));
} catch (Throwable e1) {
Application.getExceptionHandler().handleErrorCondition(e1);
}
}
}, null);
d.setVisible(true);
} catch (Throwable e1) {
Application.getExceptionHandler().handleErrorCondition(e1);
}
}
}
public PhotoSettingsConfig(final PhotoSettings p) {
super();
setPreferredSize(new Dimension(240, 320));
final JButton sunLightColorButton = new JButton();
sunLightColorButton.setMaximumSize(new Dimension(35, 25));
final JButton skyColorButton = new JButton();
skyColorButton.setMaximumSize(new Dimension(35, 25));
final JButton smokeColorButton = new JButton();
smokeColorButton.setMaximumSize(new Dimension(35, 25));
final JButton flameColorButton = new JButton();
flameColorButton.setMaximumSize(new Dimension(35, 25));
p.addChangeListener(new StateChangeListener() {
{
stateChanged(null);
}
@Override
public void stateChanged(EventObject e) {
sunLightColorButton.setIcon(new ColorIcon(p.getSunlight()));
skyColorButton.setIcon(new ColorIcon(p.getSkyColor()));
smokeColorButton.setIcon(new ColorIcon(p.getSmokeColor()));
flameColorButton.setIcon(new ColorIcon(p.getFlameColor()));
}
});
sunLightColorButton.addActionListener(new ColorActionListener(p, "Sunlight"));
skyColorButton.addActionListener(new ColorActionListener(p, "SkyColor"));
smokeColorButton.addActionListener(new ColorActionListener(p, "SmokeColor"));
flameColorButton.addActionListener(new ColorActionListener(p, "FlameColor"));
addTab(trans.get("PhotoSettingsConfig.tab.orientation"), new JPanel(new MigLayout("fill")) {
{
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.rocket"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.pitch")));
DoubleModel pitchModel = new DoubleModel(p, "Pitch", UnitGroup.UNITS_ANGLE);
add(new JSpinner(pitchModel.getSpinnerModel()), "w 40");
add(new UnitSelector(pitchModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.yaw")));
DoubleModel yawModel = new DoubleModel(p, "Yaw", UnitGroup.UNITS_ANGLE);
add(new JSpinner(yawModel.getSpinnerModel()), "w 40");
add(new UnitSelector(yawModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.roll")));
DoubleModel rollModel = new DoubleModel(p, "Roll", UnitGroup.UNITS_ANGLE);
add(new JSpinner(rollModel.getSpinnerModel()), "w 40");
add(new UnitSelector(rollModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.advance")));
DoubleModel advanceModel = new DoubleModel(p, "Advance", UnitGroup.UNITS_LENGTH);
add(new JSpinner(advanceModel.getSpinnerModel()), "w 40");
add(new UnitSelector(advanceModel), "wrap");
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.camera"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAz")));
DoubleModel viewAzModel = new DoubleModel(p, "ViewAz", UnitGroup.UNITS_ANGLE);
add(new JSpinner(viewAzModel.getSpinnerModel()), "w 40");
add(new UnitSelector(viewAzModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAlt")));
DoubleModel viewAltModle = new DoubleModel(p, "ViewAlt", UnitGroup.UNITS_ANGLE);
add(new JSpinner(viewAltModle.getSpinnerModel()), "w 40");
add(new UnitSelector(viewAltModle), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vDist")));
DoubleModel viewDistanceModel = new DoubleModel(p, "ViewDistance", UnitGroup.UNITS_LENGTH);
add(new JSpinner(viewDistanceModel.getSpinnerModel()), "w 40");
add(new UnitSelector(viewDistanceModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.fov")));
DoubleModel fovModel = new DoubleModel(p, "Fov", UnitGroup.UNITS_ANGLE);
add(new JSpinner(fovModel.getSpinnerModel()), "w 40");
add(new UnitSelector(fovModel), "wrap");
}
});
addTab(trans.get("PhotoSettingsConfig.tab.environment"), new JPanel(new MigLayout("fill")) {
{
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.light"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sun")));
add(sunLightColorButton, "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.amb")));
DoubleModel ambianceModel = new DoubleModel(p, "Ambiance", 100, UnitGroup.UNITS_NONE, 0, 100);
add(new JSpinner(ambianceModel.getSpinnerModel()), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAz")));
DoubleModel lightAzModel = new DoubleModel(p, "LightAz", UnitGroup.UNITS_ANGLE);
add(new JSpinner(lightAzModel.getSpinnerModel()), "w 40");
add(new UnitSelector(lightAzModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAlt")));
DoubleModel lightAltModle = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE);
add(new JSpinner(lightAltModle.getSpinnerModel()), "wrap");
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.sky"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.skyColor")));
add(skyColorButton, "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.skyImage")));
add(new JComboBox(new DefaultComboBoxModel(new Object[] { null, Mountains.instance, Meadow.instance,
Storm.instance, Lake.instance, Orbit.instance, Miramar.instance }) {
}) {
{
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object s = ((JComboBox) e.getSource()).getSelectedItem();
if (s instanceof Sky) {
p.setSky((Sky) s);
skyColorButton.setEnabled(false);
} else if (s == null) {
p.setSky(null);
skyColorButton.setEnabled(true);
}
}
});
setSelectedItem(p.getSky());
}
}, "wrap");
final JLabel creditLabel = new JLabel(trans.get("PhotoSettingsConfig.lbl.skyCredit"));
add(creditLabel, "wrap");
final JTextArea credit = new JTextArea();
credit.setEditable(false);
credit.setCursor(null);
credit.setOpaque(false);
credit.setFocusable(false);
credit.setFont(creditLabel.getFont());
add(credit, "span, gap left 10px");
final StateChangeListener skyChange = new StateChangeListener() {
@Override
public void stateChanged(EventObject e) {
if (p.getSky() instanceof Sky.Credit) {
credit.setText(((Credit) p.getSky()).getCredit());
} else {
credit.setText("");
}
}
};
p.addChangeListener(skyChange);
skyChange.stateChanged(null);
}
});
addTab(trans.get("PhotoSettingsConfig.tab.effects"), new JPanel(new MigLayout("fill")) {
{
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.smokeFlame"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smoke")));
BooleanModel smokeModel = new BooleanModel(p, "Smoke");
add(new JCheckBox(smokeModel), "split 2, w 15");
add(smokeColorButton, "wrap");
smokeModel.addEnableComponent(smokeColorButton);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smokeOpacity")));
DoubleModel smokeAlphaModel = new DoubleModel(p, "SmokeAlpha", 100, UnitGroup.UNITS_NONE, 0, 100);
JSpinner opacitySpinner = new JSpinner(smokeAlphaModel.getSpinnerModel());
add(opacitySpinner, "wrap");
smokeModel.addEnableComponent(opacitySpinner);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.flame")));
BooleanModel fireModel = new BooleanModel(p, "Flame");
add(new JCheckBox(fireModel), "split 2, w 15");
add(flameColorButton, "wrap");
fireModel.addEnableComponent(flameColorButton);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.flameAspect")));
DoubleModel flameAspectModel = new DoubleModel(p, "FlameAspectRatio", 100, UnitGroup.UNITS_NONE, 25,
250);
JSpinner flameAspectSpinner = new JSpinner(flameAspectModel.getSpinnerModel());
add(flameAspectSpinner, "wrap");
fireModel.addEnableComponent(flameAspectSpinner);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparks")));
BooleanModel sparksModel = new BooleanModel(p, "Sparks");
JCheckBox sparksCheck = new JCheckBox(sparksModel);
add(sparksCheck, "wrap");
fireModel.addEnableComponent(sparksCheck);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkConcentration")));
DoubleModel sparkConcentrationModel = new DoubleModel(p, "SparkConcentration", 100,
UnitGroup.UNITS_NONE, 0, 100);
JSpinner sparkConcentrationSpinner = new JSpinner(sparkConcentrationModel.getSpinnerModel());
add(sparkConcentrationSpinner, "wrap");
sparksModel.addEnableComponent(sparkConcentrationSpinner);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkWeight")));
DoubleModel sparkWeightModel = new DoubleModel(p, "SparkWeight", 100, UnitGroup.UNITS_NONE, 0, 100);
JSpinner sparkWeightSpinner = new JSpinner(sparkWeightModel.getSpinnerModel());
add(sparkWeightSpinner, "wrap");
sparksModel.addEnableComponent(sparkWeightSpinner);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.exhaustScale")));
DoubleModel exhaustScaleModel = new DoubleModel(p, "ExhaustScale", 100, UnitGroup.UNITS_NONE, 0, 1000);
add(new JSpinner(exhaustScaleModel.getSpinnerModel()), "wrap");
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.effects"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.speed")));
add(new JCheckBox(new BooleanModel(p, "MotionBlurred")), "wrap");
}
});
}
}