[#1970] Add absolute inner tube separation option
Co-authored-by: jura0207 <jv51207@fer.hr>
This commit is contained in:
parent
b62629b9c1
commit
438adb14ef
@ -1192,6 +1192,7 @@ InnerTubeCfg.tab.ttip.Radialpos = Radial position
|
||||
InnerTubeCfg.lbl.Selectclustercfg = Select cluster configuration:
|
||||
InnerTubeCfg.lbl.TubeSep = Tube separation:
|
||||
InnerTubeCfg.lbl.ttip.TubeSep = The separation of the tubes, 1.0 = touching each other
|
||||
InnerTubeCfg.lbl.ttip.TubeSepAbs = The separation of the tubes, 0 = touching each other
|
||||
InnerTubeCfg.lbl.Rotation = Rotation:
|
||||
InnerTubeCfg.lbl.ttip.Rotation = Rotation angle of the cluster configuration
|
||||
InnerTubeCfg.lbl.Rotangle = Rotation angle of the cluster configuration
|
||||
@ -1200,6 +1201,10 @@ InnerTubeCfg.lbl.longA1 = <html>Split the cluster into separate components.<br>
|
||||
InnerTubeCfg.lbl.longA2 = This also duplicates all components attached to this inner tube.
|
||||
InnerTubeCfg.but.Resetsettings = Reset settings
|
||||
InnerTubeCfg.but.ttip.Resetsettings = Reset the separation and rotation to the default values
|
||||
InnerTubeCfg.radioBut.Relative = Relative
|
||||
InnerTubeCfg.radioBut.Relative.ttip = The separation is measured relative to the outer diameter of the inner tube
|
||||
InnerTubeCfg.radioBut.Absolute = Absolute
|
||||
InnerTubeCfg.radioBut.Absolute.ttip = The separation is measured in length units
|
||||
|
||||
! LaunchLugConfig
|
||||
LaunchLugCfg.lbl.Length = Length:
|
||||
|
@ -170,6 +170,11 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
|
||||
" Please set setClusterConfiguration(ClusterConfiguration) instead.",
|
||||
new UnsupportedOperationException("InnerTube.setInstanceCount(..) on an"+this.getClass().getSimpleName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfter(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cluster scaling. A value of 1.0 indicates that the tubes are packed
|
||||
@ -177,14 +182,10 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
|
||||
* pack inside each other.
|
||||
*/
|
||||
public double getClusterScale() {
|
||||
mutex.verify();
|
||||
return clusterScale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfter(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cluster scaling.
|
||||
* @see #getClusterScale()
|
||||
@ -203,6 +204,23 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
|
||||
clusterScale = scale;
|
||||
fireComponentChangeEvent(new ComponentChangeEvent(this, ComponentChangeEvent.MASS_CHANGE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cluster scaling as an absolute distance measurement. A value of 0 indicates that the tubes are packed
|
||||
* touching each other, larger values separate the tubes and smaller values pack inside each other.
|
||||
*/
|
||||
public double getClusterScaleAbsolute() {
|
||||
return (getClusterScale() - 1) * getOuterRadius() * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the absolute cluster scaling (in terms of distance).
|
||||
* @see #getClusterScaleAbsolute()
|
||||
*/
|
||||
public void setClusterScaleAbsolute(double scale) {
|
||||
double scaleRel = scale / (getOuterRadius() * 2) + 1;
|
||||
setClusterScale(scaleRel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -9,6 +9,8 @@ import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
@ -17,12 +19,14 @@ import java.util.EventObject;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.BevelBorder;
|
||||
@ -46,6 +50,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RingComponent;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.startup.Preferences;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
@ -55,6 +60,9 @@ import net.sf.openrocket.util.StateChangeListener;
|
||||
public class InnerTubeConfig extends RocketComponentConfig {
|
||||
private static final long serialVersionUID = 7900041420864324470L;
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Preferences prefs = Application.getPreferences();
|
||||
|
||||
private static final String PREF_SEPARATION_RELATIVE = "InnerTubeSeparationRelative";
|
||||
|
||||
|
||||
public InnerTubeConfig(OpenRocketDocument d, RocketComponent c, JDialog parent) {
|
||||
@ -279,29 +287,88 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
//// The separation of the tubes, 1.0 = touching each other
|
||||
l.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
|
||||
subPanel.add(l);
|
||||
DoubleModel dm = new DoubleModel(component, "ClusterScale", 1, UnitGroup.UNITS_NONE, 0);
|
||||
|
||||
JSpinner spin = new JSpinner(dm.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
//// The separation of the tubes, 1.0 = touching each other
|
||||
spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
|
||||
subPanel.add(spin, "growx");
|
||||
order.add(((SpinnerEditor) spin.getEditor()).getTextField());
|
||||
//// Models
|
||||
final boolean useRelativeSeparation = prefs.getBoolean(PREF_SEPARATION_RELATIVE, true);
|
||||
final DoubleModel clusterScaleModelRel = new DoubleModel(component, "ClusterScale", 1, UnitGroup.UNITS_NONE, 0);
|
||||
final DoubleModel clusterScaleModelAbs = new DoubleModel(component, "ClusterScaleAbsolute", 1, UnitGroup.UNITS_LENGTH);
|
||||
final DoubleModel clusterScaleModel = useRelativeSeparation ? clusterScaleModelRel : clusterScaleModelAbs;
|
||||
|
||||
BasicSlider bs = new BasicSlider(dm.getSliderModel(0, 1, 4));
|
||||
//// The separation of the tubes, 1.0 = touching each other
|
||||
bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
|
||||
subPanel.add(bs, "skip,w 100lp, wrap");
|
||||
final String clusterScaleTtipRel = trans.get("InnerTubeCfg.lbl.ttip.TubeSep");
|
||||
final String clusterScaleTtipAbs = trans.get("InnerTubeCfg.lbl.ttip.TubeSepAbs");
|
||||
final String clusterScaleTtip = useRelativeSeparation ? clusterScaleTtipRel : clusterScaleTtipAbs;
|
||||
|
||||
JSpinner clusterScaleSpin = new JSpinner(clusterScaleModel.getSpinnerModel());
|
||||
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
|
||||
clusterScaleSpin.setToolTipText(clusterScaleTtip);
|
||||
subPanel.add(clusterScaleSpin, "growx");
|
||||
order.add(((SpinnerEditor) clusterScaleSpin.getEditor()).getTextField());
|
||||
|
||||
UnitSelector clusterScaleUnit = new UnitSelector(clusterScaleModel);
|
||||
subPanel.add(clusterScaleUnit, "growx");
|
||||
|
||||
BasicSlider clusterScaleBs = new BasicSlider(clusterScaleModel.getSliderModel(0, 1, 4));
|
||||
subPanel.add(clusterScaleBs, "w 100lp, wrap");
|
||||
|
||||
// Relative/absolute separation
|
||||
JRadioButton rbRel = new JRadioButton(trans.get("InnerTubeCfg.radioBut.Relative"));
|
||||
JRadioButton rbAbs = new JRadioButton(trans.get("InnerTubeCfg.radioBut.Absolute"));
|
||||
rbRel.setToolTipText(trans.get("InnerTubeCfg.radioBut.Relative.ttip"));
|
||||
rbAbs.setToolTipText(trans.get("InnerTubeCfg.radioBut.Absolute.ttip"));
|
||||
ButtonGroup bg = new ButtonGroup();
|
||||
bg.add(rbRel);
|
||||
bg.add(rbAbs);
|
||||
subPanel.add(rbRel, "skip, spanx, split 2");
|
||||
subPanel.add(rbAbs, "wrap");
|
||||
|
||||
rbRel.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.DESELECTED)
|
||||
return;
|
||||
clusterScaleSpin.setModel(clusterScaleModelRel.getSpinnerModel());
|
||||
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
|
||||
clusterScaleUnit.setModel(clusterScaleModelRel);
|
||||
clusterScaleBs.setModel(clusterScaleModelRel.getSliderModel(0, 1, 4));
|
||||
clusterScaleSpin.setToolTipText(clusterScaleTtipRel);
|
||||
|
||||
prefs.putBoolean(PREF_SEPARATION_RELATIVE, false);
|
||||
}
|
||||
});
|
||||
rbAbs.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.DESELECTED)
|
||||
return;
|
||||
DoubleModel radiusModelMin = new DoubleModel(component, "OuterRadius", -2, UnitGroup.UNITS_LENGTH);
|
||||
DoubleModel radiusModelMax = new DoubleModel(component, "OuterRadius", 6, UnitGroup.UNITS_LENGTH);
|
||||
|
||||
clusterScaleSpin.setModel(clusterScaleModelAbs.getSpinnerModel());
|
||||
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
|
||||
clusterScaleUnit.setModel(clusterScaleModelAbs);
|
||||
clusterScaleBs.setModel(clusterScaleModelAbs.getSliderModel(radiusModelMin, radiusModelMax));
|
||||
clusterScaleSpin.setToolTipText(clusterScaleTtipAbs);
|
||||
|
||||
prefs.putBoolean(PREF_SEPARATION_RELATIVE, false);
|
||||
}
|
||||
});
|
||||
|
||||
// Select the button by default
|
||||
if (prefs.getBoolean(PREF_SEPARATION_RELATIVE, true)) {
|
||||
rbRel.setSelected(true);
|
||||
} else {
|
||||
rbAbs.setSelected(true);
|
||||
}
|
||||
|
||||
// Rotation:
|
||||
l = new JLabel(trans.get("InnerTubeCfg.lbl.Rotation"));
|
||||
//// Rotation angle of the cluster configuration
|
||||
l.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
|
||||
subPanel.add(l);
|
||||
dm = new DoubleModel(component, "ClusterRotation", 1, UnitGroup.UNITS_ANGLE,
|
||||
DoubleModel dm = new DoubleModel(component, "ClusterRotation", 1, UnitGroup.UNITS_ANGLE,
|
||||
-Math.PI, Math.PI);
|
||||
|
||||
spin = new JSpinner(dm.getSpinnerModel());
|
||||
JSpinner spin = new JSpinner(dm.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
//// Rotation angle of the cluster configuration
|
||||
spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
|
||||
@ -309,7 +376,7 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
order.add(((SpinnerEditor) spin.getEditor()).getTextField());
|
||||
|
||||
subPanel.add(new UnitSelector(dm), "growx");
|
||||
bs = new BasicSlider(dm.getSliderModel());
|
||||
BasicSlider bs = new BasicSlider(dm.getSliderModel());
|
||||
//// Rotation angle of the cluster configuration
|
||||
bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
|
||||
subPanel.add(bs, "w 100lp, wrap para");
|
||||
|
Loading…
x
Reference in New Issue
Block a user