Merge branch 'issue-1537' into railbutton-database
# Conflicts: # core/src/net/sf/openrocket/rocketcomponent/RailButton.java
This commit is contained in:
commit
6b9e327508
@ -294,6 +294,8 @@ pref.dlg.lbl.PositiontoinsertStages = Position to insert new stages:
|
||||
pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations.
|
||||
pref.dlg.checkbox.Runsimulations = Run out-dated simulations when you open the simulation tab.
|
||||
pref.dlg.checkbox.Updateestimates = Update estimated flight parameters in design window
|
||||
pref.dlg.checkbox.Markers = Only show pod set/booster markers when the pod set/booster is selected
|
||||
pref.dlg.checkbox.Markers.ttip = <html>If checked, pod set/booster markers will only be shown when the pod set/booster is selected.<br>If unchecked, pod set/booster markers will always be shown.</html>
|
||||
pref.dlg.checkbox.AlwaysOpenLeftmost = Always open leftmost tab when opening a component edit dialog
|
||||
pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = <html>If checked, a component edit dialog will always pop up with the first tab selected.<br>If unchecked, the previous selected tab will be used.</html>
|
||||
pref.dlg.lbl.User-definedthrust = User-defined thrust curves:
|
||||
@ -1050,7 +1052,10 @@ LaunchLugCfg.tab.Generalprop = General properties
|
||||
|
||||
! RailButtonConfig
|
||||
RailBtnCfg.lbl.OuterDiam = Outer Diameter:
|
||||
RailBtnCfg.lbl.TotalHeight = Total Height
|
||||
RailBtnCfg.lbl.InnerDiam = Inner Diameter:
|
||||
RailBtnCfg.lbl.TotalHeight = Total Height:
|
||||
RailBtnCfg.lbl.BaseHeight = Base Height:
|
||||
RailBtnCfg.lbl.FlangeHeight = Flange Height:
|
||||
RailBtnCfg.lbl.Angle = Rotation:
|
||||
RailBtnCfg.lbl.PosRelativeTo = Position relative to:
|
||||
RailBtnCfg.lbl.Plus = plus
|
||||
|
||||
@ -190,8 +190,15 @@ class DocumentConfig {
|
||||
setters.put("RailButton:angleoffset", new AnglePositionSetter() );
|
||||
setters.put("RailButton:height", new DoubleSetter(
|
||||
Reflection.findMethod( RailButton.class, "setTotalHeight", double.class)));
|
||||
setters.put("RailButton:baseheight", new DoubleSetter(
|
||||
Reflection.findMethod( RailButton.class, "setBaseHeight", double.class)));
|
||||
setters.put("RailButton:flangeheight", new DoubleSetter(
|
||||
Reflection.findMethod( RailButton.class, "setFlangeHeight", double.class)));
|
||||
setters.put("RailButton:outerdiameter", new DoubleSetter(
|
||||
Reflection.findMethod( RailButton.class, "setOuterDiameter", double.class)));
|
||||
setters.put("RailButton:innerdiameter", new DoubleSetter(
|
||||
Reflection.findMethod( RailButton.class, "setInnerDiameter", double.class)));
|
||||
|
||||
|
||||
// Transition
|
||||
setters.put("Transition:shape", new EnumSetter<Transition.Shape>(
|
||||
|
||||
@ -26,8 +26,10 @@ public class RailButtonSaver extends ExternalComponentSaver {
|
||||
RailButton rb = (RailButton) c;
|
||||
|
||||
emitDouble( elements, "outerdiameter", rb.getOuterDiameter());
|
||||
emitDouble( elements, "innerdiameter", rb.getInnerDiameter());
|
||||
emitDouble( elements, "height", rb.getTotalHeight());
|
||||
|
||||
emitDouble( elements, "baseheight", rb.getBaseHeight());
|
||||
emitDouble( elements, "flangeheight", rb.getFlangeHeight());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2,10 +2,7 @@ package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EventObject;
|
||||
|
||||
import net.sf.openrocket.appearance.Appearance;
|
||||
import net.sf.openrocket.appearance.Decal;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
@ -14,7 +11,6 @@ import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.BoundingBox;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
|
||||
public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, LineInstanceable, InsideColorComponent {
|
||||
|
||||
@ -40,20 +40,19 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
* ^ [[[[[[]]]]]] flangeHeight
|
||||
* total >||||||<= inner dia ^
|
||||
* height |||||| v
|
||||
* v [[[[[[]]]]]] standoff == baseHeight
|
||||
* v [[[[[[]]]]]] baseHeight / standoff
|
||||
* ================== ^
|
||||
* (body)
|
||||
*
|
||||
*/
|
||||
// Note: the reference point for Rail Button Components is in the center bottom of the button.
|
||||
protected double outerDiameter_m;
|
||||
protected double totalHeight_m;
|
||||
protected double innerDiameter_m;
|
||||
protected double totalHeight_m;
|
||||
protected double flangeHeight_m;
|
||||
protected double standoff_m;
|
||||
protected double baseHeight_m;
|
||||
protected double screwHeight_m; // This has no effect at the moment; is for future use.
|
||||
|
||||
protected final static double MINIMUM_STANDOFF= 0.001;
|
||||
|
||||
|
||||
private double radialDistance_m=0;
|
||||
protected static final AngleMethod angleMethod = AngleMethod.RELATIVE;
|
||||
@ -67,7 +66,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
this.totalHeight_m = 0.0097;
|
||||
this.innerDiameter_m = 0.008;
|
||||
this.flangeHeight_m = 0.002;
|
||||
this.setStandoff( 0.002);
|
||||
this.setBaseHeight(0.002);
|
||||
this.setInstanceSeparation( this.outerDiameter_m * 6);
|
||||
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
|
||||
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
|
||||
@ -76,22 +75,21 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
|
||||
public RailButton( final double od, final double ht ) {
|
||||
this();
|
||||
this.setOuterDiameter( od);
|
||||
this.setTotalHeight( ht);
|
||||
this.setOuterDiameter(od);
|
||||
this.setTotalHeight(ht);
|
||||
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
|
||||
super.displayOrder_back = 11; // Order for displaying the component in the 2D back view
|
||||
}
|
||||
|
||||
public RailButton( final double od, final double id, final double ht, final double flangeThickness, final double _standoff ) {
|
||||
public RailButton( final double od, final double id, final double ht, final double _flangeHeight, final double _baseHeight ) {
|
||||
super(AxialMethod.MIDDLE);
|
||||
this.outerDiameter_m = od;
|
||||
this.totalHeight_m = ht;
|
||||
this.innerDiameter_m = id;
|
||||
this.flangeHeight_m = flangeThickness;
|
||||
this.setStandoff( _standoff);
|
||||
this.flangeHeight_m = _flangeHeight;
|
||||
this.setBaseHeight(_baseHeight);
|
||||
this.setInstanceSeparation( od*2);
|
||||
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
|
||||
this.screwHeight_m = 0;
|
||||
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
|
||||
super.displayOrder_back = 11; // Order for displaying the component in the 2D back view
|
||||
}
|
||||
@ -123,13 +121,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
|
||||
return rb1010;
|
||||
}
|
||||
|
||||
public double getStandoff(){
|
||||
return this.standoff_m;
|
||||
}
|
||||
|
||||
public double getBaseHeight(){
|
||||
return this.getStandoff();
|
||||
return this.baseHeight_m;
|
||||
}
|
||||
|
||||
public double getOuterDiameter() {
|
||||
@ -141,7 +135,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
}
|
||||
|
||||
public double getInnerHeight() {
|
||||
return (this.totalHeight_m - this.flangeHeight_m - this.standoff_m);
|
||||
return (this.totalHeight_m - this.flangeHeight_m - this.baseHeight_m);
|
||||
}
|
||||
|
||||
public double getTotalHeight() {
|
||||
@ -155,16 +149,30 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
public double getScrewHeight() {
|
||||
return this.screwHeight_m;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setStandoff(double newStandoff){
|
||||
public void setBaseHeight(double newBaseHeight){
|
||||
for (RocketComponent listener : configListeners) {
|
||||
if (listener instanceof RailButton) {
|
||||
((RailButton) listener).setStandoff(newStandoff);
|
||||
((RailButton) listener).setBaseHeight(newBaseHeight);
|
||||
}
|
||||
}
|
||||
|
||||
this.standoff_m = Math.max( newStandoff, RailButton.MINIMUM_STANDOFF );
|
||||
this.baseHeight_m = Math.max(newBaseHeight, 0);
|
||||
this.baseHeight_m = Math.min(this.baseHeight_m, this.totalHeight_m - this.flangeHeight_m);
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
public void setFlangeHeight(double newFlangeHeight){
|
||||
for (RocketComponent listener : configListeners) {
|
||||
if (listener instanceof RailButton) {
|
||||
((RailButton) listener).setFlangeHeight(newFlangeHeight);
|
||||
}
|
||||
}
|
||||
|
||||
this.flangeHeight_m = Math.max(newFlangeHeight, 0);
|
||||
this.flangeHeight_m = Math.min(this.flangeHeight_m, this.totalHeight_m - this.baseHeight_m);
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
public void setScrewHeight(double height) {
|
||||
@ -184,7 +192,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
}
|
||||
}
|
||||
|
||||
this.innerDiameter_m = newID;
|
||||
this.innerDiameter_m = Math.min(newID, this.outerDiameter_m);
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
@ -197,6 +205,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
}
|
||||
|
||||
this.outerDiameter_m = newOD;
|
||||
setInnerDiameter(this.innerDiameter_m);
|
||||
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
@ -208,22 +217,11 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
}
|
||||
}
|
||||
|
||||
this.totalHeight_m = newHeight;
|
||||
this.totalHeight_m = Math.max(newHeight, this.flangeHeight_m + this.baseHeight_m);
|
||||
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
public void setThickness(double newThickness ) {
|
||||
for (RocketComponent listener : configListeners) {
|
||||
if (listener instanceof RailButton) {
|
||||
((RailButton) listener).setThickness(newThickness);
|
||||
}
|
||||
}
|
||||
|
||||
this.flangeHeight_m = newThickness;
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAerodynamic(){
|
||||
// TODO: implement aerodynamics
|
||||
@ -268,15 +266,17 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
super.setAxialMethod(position);
|
||||
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BoundingBox getInstanceBoundingBox(){
|
||||
BoundingBox instanceBounds = new BoundingBox();
|
||||
|
||||
instanceBounds.update(new Coordinate(0, this.getTotalHeight(), 0));
|
||||
instanceBounds.update(new Coordinate(0, this.totalHeight_m, 0));
|
||||
instanceBounds.update(new Coordinate(0, -this.totalHeight_m, 0));
|
||||
|
||||
final double r = this.getOuterDiameter();
|
||||
instanceBounds.update(new Coordinate(r,r,0));
|
||||
instanceBounds.update(new Coordinate(-r,-r,0));
|
||||
final double r = this.getOuterDiameter() / 2;
|
||||
instanceBounds.update(new Coordinate(r, 0, r));
|
||||
instanceBounds.update(new Coordinate(-r, 0, -r));
|
||||
|
||||
return instanceBounds;
|
||||
}
|
||||
@ -322,7 +322,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
public double getComponentVolume() {
|
||||
final double volOuter = Math.PI*Math.pow( outerDiameter_m/2, 2)*flangeHeight_m;
|
||||
final double volInner = Math.PI*Math.pow( innerDiameter_m/2, 2)*getInnerHeight();
|
||||
final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)*standoff_m;
|
||||
final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)* baseHeight_m;
|
||||
return (volOuter+
|
||||
volInner+
|
||||
volStandoff);
|
||||
@ -386,12 +386,12 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
|
||||
@Override
|
||||
public Coordinate getComponentCG() {
|
||||
// Math.PI and density are assumed constant through calculation, and thus may be factored out.
|
||||
final double volumeFlange = Math.pow( outerDiameter_m/2, 2)*flangeHeight_m;
|
||||
final double volumeInner = Math.pow( innerDiameter_m/2, 2)*(getInnerHeight());
|
||||
final double volumeStandoff = Math.pow( outerDiameter_m/2, 2)*this.standoff_m;
|
||||
final double totalVolume = volumeFlange + volumeInner + volumeStandoff;
|
||||
final double heightCM = (volumeFlange*( this.totalHeight_m-getFlangeHeight()/2) + volumeInner*( this.standoff_m + this.getInnerHeight()/2) + volumeStandoff*(this.standoff_m/2))/totalVolume;
|
||||
// Math.PI and density are assumed constant through calculation, and thus may be factored out.
|
||||
final double volumeBase = Math.pow(outerDiameter_m / 2, 2) * this.baseHeight_m;
|
||||
final double volumeFlange = Math.pow(outerDiameter_m / 2, 2)* this.flangeHeight_m;
|
||||
final double volumeInner = Math.pow(innerDiameter_m / 2, 2)* getInnerHeight();
|
||||
final double totalVolume = volumeFlange + volumeInner + volumeBase;
|
||||
final double heightCM = (volumeFlange*( this.totalHeight_m-getFlangeHeight()/2) + volumeInner*( this.baseHeight_m + this.getInnerHeight()/2) + volumeBase*(this.baseHeight_m /2))/totalVolume;
|
||||
|
||||
if( heightCM > this.totalHeight_m ){
|
||||
throw new BugException(" bug found while computing the CG of a RailButton: "+this.getName()+"\n height of CG: "+heightCM);
|
||||
|
||||
@ -287,6 +287,11 @@ public class Rocket extends ComponentAssembly {
|
||||
refType = type;
|
||||
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLength() {
|
||||
return selectedConfiguration.getLength();
|
||||
}
|
||||
|
||||
|
||||
public double getCustomReferenceLength() {
|
||||
@ -304,6 +309,17 @@ public class Rocket extends ComponentAssembly {
|
||||
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBoundingRadius() {
|
||||
double bounding = 0;
|
||||
for (RocketComponent comp : children) {
|
||||
if (comp instanceof ComponentAssembly) {
|
||||
bounding = Math.max(bounding, ((ComponentAssembly) comp).getBoundingRadius());
|
||||
}
|
||||
}
|
||||
return bounding;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1010,7 +1010,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
* If the length of a component is settable, the class must define the setter method
|
||||
* itself.
|
||||
*/
|
||||
public final double getLength() {
|
||||
public double getLength() {
|
||||
mutex.verify();
|
||||
return length;
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@ public abstract class Preferences implements ChangeSource {
|
||||
public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors";
|
||||
private static final String AUTO_OPEN_LAST_DESIGN = "AUTO_OPEN_LAST_DESIGN";
|
||||
private static final String OPEN_LEFTMOST_DESIGN_TAB = "OPEN_LEFTMOST_DESIGN_TAB";
|
||||
private static final String SHOW_MARKERS = "SHOW_MARKERS";
|
||||
private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING";
|
||||
|
||||
//Preferences related to 3D graphics
|
||||
@ -469,7 +470,26 @@ public abstract class Preferences implements ChangeSource {
|
||||
public final boolean isAlwaysOpenLeftmostTab() {
|
||||
return this.getBoolean(OPEN_LEFTMOST_DESIGN_TAB, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether pod set/booster markers should only be displayed when the pod set/booster is selected.
|
||||
* @param enabled true if pod set/booster markers should only be displayed when the pod set/booster is selected,
|
||||
* false if they should be displayed permanently.
|
||||
*/
|
||||
public final void setShowMarkers(boolean enabled) {
|
||||
this.putBoolean(SHOW_MARKERS, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer if pod set/booster markers should only be displayed when the pod set/booster is selected
|
||||
*
|
||||
* @return true if pod set/booster markers should only be displayed when the pod set/booster is selected,
|
||||
* false if they should be displayed permanently.
|
||||
*/
|
||||
public final boolean isShowMarkers() {
|
||||
return this.getBoolean(SHOW_MARKERS, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the OpenRocket unique ID.
|
||||
*
|
||||
|
||||
@ -81,6 +81,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
private Point dragPoint = null;
|
||||
|
||||
private FinPointFigure figure = null;
|
||||
private ScaleScrollPane figurePane = null;
|
||||
private ScaleSelector selector;
|
||||
|
||||
public FreeformFinSetConfig(OpenRocketDocument d, RocketComponent component, JDialog parent) {
|
||||
@ -219,7 +220,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
|
||||
// Create the figure
|
||||
figure = new FinPointFigure(finset);
|
||||
ScaleScrollPane figurePane = new FinPointScrollPane( figure);
|
||||
figurePane = new FinPointScrollPane( figure);
|
||||
|
||||
// Create the table
|
||||
tableModel = new FinPointTableModel();
|
||||
@ -392,9 +393,10 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
}
|
||||
figure.updateFigure();
|
||||
}
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
|
||||
if (figurePane != null) {
|
||||
figurePane.revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private class FinPointScrollPane extends ScaleScrollPane {
|
||||
@ -408,8 +410,6 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent event) {
|
||||
int mods = event.getModifiersEx();
|
||||
|
||||
final FreeformFinSet finset = (FreeformFinSet) component;
|
||||
|
||||
final int pressIndex = getPoint(event);
|
||||
|
||||
@ -29,13 +29,6 @@ public class RailButtonConfig extends RocketComponentConfig {
|
||||
|
||||
public RailButtonConfig( OpenRocketDocument document, RocketComponent component, JDialog parent) {
|
||||
super(document, component, parent);
|
||||
|
||||
// For DEBUG purposes
|
||||
// if( component instanceof AxialStage ){
|
||||
// System.err.println(" Dumping AxialStage tree info for devel / debugging.");
|
||||
// System.err.println(component.toDebugTree());
|
||||
// }
|
||||
|
||||
|
||||
//// General and General properties
|
||||
tabbedPane.insertTab( trans.get("RailBtnCfg.tab.General"), null, buttonTab( (RailButton)component ), trans.get("RailBtnCfg.tab.GeneralProp"), 0);
|
||||
@ -59,6 +52,33 @@ public class RailButtonConfig extends RocketComponentConfig {
|
||||
panel.add(new UnitSelector(ODModel), "growx");
|
||||
panel.add(new BasicSlider(ODModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
|
||||
}
|
||||
{ //// Inner Diameter
|
||||
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.InnerDiam")));
|
||||
DoubleModel IDModel = new DoubleModel(component, "InnerDiameter", UnitGroup.UNITS_LENGTH, 0);
|
||||
JSpinner IDSpinner = new JSpinner(IDModel.getSpinnerModel());
|
||||
IDSpinner.setEditor(new SpinnerEditor(IDSpinner));
|
||||
panel.add(IDSpinner, "growx");
|
||||
panel.add(new UnitSelector(IDModel), "growx");
|
||||
panel.add(new BasicSlider(IDModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
|
||||
}
|
||||
{ //// Base Height
|
||||
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.BaseHeight")));
|
||||
DoubleModel heightModel = new DoubleModel(component, "BaseHeight", UnitGroup.UNITS_LENGTH, 0);
|
||||
JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel());
|
||||
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
|
||||
panel.add(heightSpinner, "growx");
|
||||
panel.add(new UnitSelector(heightModel), "growx");
|
||||
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
|
||||
}
|
||||
{ //// Flange Height
|
||||
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.FlangeHeight")));
|
||||
DoubleModel heightModel = new DoubleModel(component, "FlangeHeight", UnitGroup.UNITS_LENGTH, 0);
|
||||
JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel());
|
||||
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
|
||||
panel.add(heightSpinner, "growx");
|
||||
panel.add(new UnitSelector(heightModel), "growx");
|
||||
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
|
||||
}
|
||||
{ //// Height
|
||||
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.TotalHeight")));
|
||||
DoubleModel heightModel = new DoubleModel(component, "TotalHeight", UnitGroup.UNITS_LENGTH, 0);
|
||||
@ -66,7 +86,7 @@ public class RailButtonConfig extends RocketComponentConfig {
|
||||
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
|
||||
panel.add(heightSpinner, "growx");
|
||||
panel.add(new UnitSelector(heightModel), "growx");
|
||||
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
|
||||
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
|
||||
}
|
||||
|
||||
{ //// Angular Position:
|
||||
@ -79,14 +99,17 @@ public class RailButtonConfig extends RocketComponentConfig {
|
||||
panel.add(new BasicSlider( angleModel.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
|
||||
}
|
||||
|
||||
primary.add(panel, "grow, gapright 201p");
|
||||
panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
|
||||
|
||||
{ //// Position relative to:
|
||||
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.PosRelativeTo")));
|
||||
|
||||
|
||||
final EnumModel<AxialMethod> methodModel = new EnumModel<AxialMethod>(component, "AxialMethod", AxialMethod.axialOffsetMethods );
|
||||
JComboBox<AxialMethod> relToCombo = new JComboBox<AxialMethod>( methodModel );
|
||||
panel.add( relToCombo, "spanx, growx, wrap");
|
||||
}
|
||||
|
||||
|
||||
{ //// plus
|
||||
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.Plus")), "right");
|
||||
DoubleModel offsetModel = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
|
||||
@ -96,17 +119,13 @@ public class RailButtonConfig extends RocketComponentConfig {
|
||||
panel.add(offsetSpinner, "growx");
|
||||
panel.add(new UnitSelector(offsetModel), "growx");
|
||||
panel.add(new BasicSlider(offsetModel.getSliderModel(
|
||||
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
|
||||
new DoubleModel(component.getParent(), "Length"))),
|
||||
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
|
||||
new DoubleModel(component.getParent(), "Length"))),
|
||||
"w 100lp, wrap para");
|
||||
|
||||
}
|
||||
|
||||
primary.add(panel, "grow, gapright 201p");
|
||||
panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
|
||||
|
||||
}
|
||||
//// Instance count
|
||||
panel.add( instanceablePanel(rbc), "span, wrap");
|
||||
panel.add(instanceablePanel(rbc), "span, wrap");
|
||||
|
||||
//// Material
|
||||
panel.add(materialPanel(Material.Type.BULK),"span, wrap");
|
||||
|
||||
@ -353,7 +353,7 @@ public class RocketComponentConfig extends JPanel {
|
||||
}
|
||||
|
||||
protected JPanel instanceablePanel( Instanceable inst ){
|
||||
JPanel panel = new JPanel( new MigLayout("fill"));
|
||||
JPanel panel = new JPanel( new MigLayout("fill, insets 0") );
|
||||
{ // Instance Count
|
||||
panel.add(new JLabel(trans.get("RocketCompCfg.lbl.InstanceCount")));
|
||||
IntegerModel countModel = new IntegerModel(component, "InstanceCount", 1);
|
||||
|
||||
@ -346,7 +346,7 @@ public class ScaleDialog extends JDialog {
|
||||
panel.add(selectionOption, "growx, wrap para*2");
|
||||
|
||||
// Select the 'scale component / scale selection and all subcomponents' if a component is selected
|
||||
if (selection != null && selection.size() > 0) {
|
||||
if (options.size() > 1 && selection != null && selection.size() > 0) {
|
||||
boolean entireRocket = false; // Flag to scale entire rocket
|
||||
for (RocketComponent component : selection) {
|
||||
if (component instanceof Rocket || (component instanceof AxialStage && !(component instanceof ParallelStage))) {
|
||||
|
||||
@ -11,6 +11,7 @@ import javax.swing.JSpinner;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.startup.Preferences;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
@ -93,7 +94,6 @@ public class DesignPreferencesPanel extends PreferencesPanel {
|
||||
// // Always open leftmost tab when opening a component edit dialog
|
||||
final JCheckBox alwaysOpenLeftmostTab = new JCheckBox(
|
||||
trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost"));
|
||||
|
||||
alwaysOpenLeftmostTab.setSelected(preferences.isAlwaysOpenLeftmostTab());
|
||||
alwaysOpenLeftmostTab.setToolTipText(trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost.ttip"));
|
||||
alwaysOpenLeftmostTab.addActionListener(new ActionListener() {
|
||||
@ -103,7 +103,7 @@ public class DesignPreferencesPanel extends PreferencesPanel {
|
||||
.isSelected());
|
||||
}
|
||||
});
|
||||
this.add(alwaysOpenLeftmostTab, "wrap, growx, span 2");
|
||||
this.add(alwaysOpenLeftmostTab, "wrap, growx, spanx");
|
||||
|
||||
// // Update flight estimates in the design window
|
||||
final JCheckBox updateEstimates = new JCheckBox(
|
||||
@ -117,5 +117,23 @@ public class DesignPreferencesPanel extends PreferencesPanel {
|
||||
}
|
||||
});
|
||||
this.add(updateEstimates, "wrap, growx, sg combos ");
|
||||
|
||||
// // Only show pod set/booster markers when they are selected
|
||||
final JCheckBox showMarkers = new JCheckBox(
|
||||
trans.get("pref.dlg.checkbox.Markers"));
|
||||
showMarkers.setToolTipText(trans.get("pref.dlg.checkbox.Markers.ttip"));
|
||||
showMarkers.setSelected(preferences.isShowMarkers());
|
||||
showMarkers.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
preferences.setShowMarkers(showMarkers
|
||||
.isSelected());
|
||||
// Update all BasicFrame rocket panel figures because it can change due to the preference change
|
||||
for (BasicFrame frame : BasicFrame.getAllFrames()) {
|
||||
frame.getRocketPanel().updateFigures();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.add(showMarkers, "wrap, growx, spanx");
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,26 +295,37 @@ public class ComponentRenderer {
|
||||
final double ir = r.getInnerDiameter() / 2.0;
|
||||
gl.glRotated(r.getAngleOffset()*180/Math.PI -90 , 1, 0, 0);
|
||||
|
||||
//Inner Diameter
|
||||
glu.gluCylinder(q, ir, ir, r.getTotalHeight(), LOD, 1);
|
||||
// Base Cylinder
|
||||
if (r.getBaseHeight() > 0) {
|
||||
glu.gluCylinder(q, or, or, r.getBaseHeight(), LOD, 1);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
|
||||
gl.glTranslated(0, 0, r.getBaseHeight());
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
} else { // Draw a closing cap if there is no base
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
|
||||
glu.gluDisk(q, 0, ir, LOD, 2);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
|
||||
gl.glTranslated(0, 0, r.getBaseHeight());
|
||||
}
|
||||
|
||||
// Inner Cylinder
|
||||
glu.gluCylinder(q, ir, ir, r.getInnerHeight(), LOD, 1);
|
||||
|
||||
//Bottom Disc
|
||||
glu.gluCylinder(q, or, or, r.getBaseHeight(), LOD, 1);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
|
||||
gl.glTranslated(0,0,r.getBaseHeight());
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
|
||||
|
||||
//Upper Disc
|
||||
gl.glTranslated(0,0,r.getTotalHeight() - r.getFlangeHeight() * 2.0);
|
||||
glu.gluCylinder(q, or, or, r.getFlangeHeight(), LOD, 1);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
|
||||
gl.glTranslated(0,0,r.getFlangeHeight());
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
// Flange Cylinder
|
||||
if (r.getFlangeHeight() > 0) {
|
||||
gl.glTranslated(0, 0, r.getInnerHeight());
|
||||
glu.gluCylinder(q, or, or, r.getFlangeHeight(), LOD, 1);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
|
||||
gl.glTranslated(0, 0, r.getFlangeHeight());
|
||||
glu.gluDisk(q, 0, or, LOD, 2);
|
||||
} else { // Draw a closing cap if there is no flange
|
||||
gl.glTranslated(0, 0, r.getInnerHeight());
|
||||
glu.gluDisk(q, 0, ir, LOD, 2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ public class PhotoFrame extends JFrame {
|
||||
|
||||
settings = new JDialog(this, trans.get("PhotoSettingsConfig.title")) {
|
||||
{
|
||||
setContentPane(new PhotoSettingsConfig(p));
|
||||
setContentPane(new PhotoSettingsConfig(p, document));
|
||||
pack();
|
||||
this.setLocationByPlatform(true);
|
||||
GUIUtil.rememberWindowSize(this);
|
||||
|
||||
@ -36,7 +36,7 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings
|
||||
private double exhaustScale = 1.0;
|
||||
private double flameAspectRatio = 1.0;
|
||||
|
||||
private double sparkConcentration = 0;
|
||||
private double sparkConcentration = 0.2;
|
||||
private double sparkWeight = 0;
|
||||
|
||||
private Sky sky = Mountains.instance;
|
||||
@ -278,5 +278,6 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings
|
||||
|
||||
public void setSmokeOpacity(double smokeOpacity) {
|
||||
this.smokeOpacity = smokeOpacity;
|
||||
setSmokeAlpha(smokeOpacity);
|
||||
}
|
||||
}
|
||||
@ -25,8 +25,10 @@ import javax.swing.event.ChangeListener;
|
||||
|
||||
import com.jogamp.opengl.GL2;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ColorIcon;
|
||||
import net.sf.openrocket.gui.components.EditableSpinner;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
@ -125,7 +127,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
}
|
||||
}
|
||||
|
||||
public PhotoSettingsConfig(PhotoSettings p) {
|
||||
public PhotoSettingsConfig(PhotoSettings p, OpenRocketDocument document) {
|
||||
super();
|
||||
|
||||
setPreferredSize(new Dimension(240, 320));
|
||||
@ -170,25 +172,29 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.pitch")));
|
||||
DoubleModel pitchModel = new DoubleModel(p, "Pitch", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(pitchModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(pitchModel), "pushx, left, wrap");
|
||||
add(new UnitSelector(pitchModel), "growx");
|
||||
add(new BasicSlider(pitchModel.getSliderModel(0, 2 * Math.PI)), "pushx, left, wrap");
|
||||
|
||||
/// Yaw
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.yaw")));
|
||||
DoubleModel yawModel = new DoubleModel(p, "Yaw", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(yawModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(yawModel), "wrap");
|
||||
add(new UnitSelector(yawModel), "growx");
|
||||
add(new BasicSlider(yawModel.getSliderModel(0, 2 * Math.PI)), "wrap");
|
||||
|
||||
/// Roll
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.roll")));
|
||||
DoubleModel rollModel = new DoubleModel(p, "Roll", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(rollModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(rollModel), "wrap");
|
||||
add(new UnitSelector(rollModel), "growx");
|
||||
add(new BasicSlider(rollModel.getSliderModel(0, 2 * Math.PI)), "wrap");
|
||||
|
||||
/// Advance
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.advance")));
|
||||
DoubleModel advanceModel = new DoubleModel(p, "Advance", UnitGroup.UNITS_LENGTH);
|
||||
add(new EditableSpinner(advanceModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(advanceModel), "wrap");
|
||||
add(new UnitSelector(advanceModel), "growx");
|
||||
add(new BasicSlider(advanceModel.getSliderModel(-document.getRocket().getLength(), document.getRocket().getLength())), "wrap");
|
||||
|
||||
// Camera
|
||||
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.camera"), Style.BOLD), "split, gapright para, span");
|
||||
@ -198,25 +204,29 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAz")));
|
||||
DoubleModel viewAzModel = new DoubleModel(p, "ViewAz", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(viewAzModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(viewAzModel), "wrap");
|
||||
add(new UnitSelector(viewAzModel), "growx");
|
||||
add(new BasicSlider(viewAzModel.getSliderModel(0, 2 * Math.PI)), "wrap");
|
||||
|
||||
/// View altitude
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAlt")));
|
||||
DoubleModel viewAltModle = new DoubleModel(p, "ViewAlt", UnitGroup.UNITS_ANGLE);
|
||||
DoubleModel viewAltModle = new DoubleModel(p, "ViewAlt", UnitGroup.UNITS_ANGLE, -Math.PI / 2, Math.PI / 2);
|
||||
add(new EditableSpinner(viewAltModle.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(viewAltModle), "wrap");
|
||||
add(new UnitSelector(viewAltModle), "growx");
|
||||
add(new BasicSlider(viewAltModle.getSliderModel(-Math.PI / 2, Math.PI / 2)), "wrap");
|
||||
|
||||
/// View distance
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vDist")));
|
||||
DoubleModel viewDistanceModel = new DoubleModel(p, "ViewDistance", UnitGroup.UNITS_LENGTH);
|
||||
add(new EditableSpinner(viewDistanceModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(viewDistanceModel), "wrap");
|
||||
add(new UnitSelector(viewDistanceModel), "growx");
|
||||
add(new BasicSlider(viewDistanceModel.getSliderModel(0, 2 * document.getRocket().getLength())), "wrap");
|
||||
|
||||
/// FoV
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.fov")));
|
||||
DoubleModel fovModel = new DoubleModel(p, "Fov", UnitGroup.UNITS_ANGLE);
|
||||
DoubleModel fovModel = new DoubleModel(p, "Fov", UnitGroup.UNITS_ANGLE, Math.PI * 57.3/180, Math.PI * 160/180);
|
||||
add(new EditableSpinner(fovModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(fovModel), "wrap");
|
||||
add(new UnitSelector(fovModel), "growx");
|
||||
add(new BasicSlider(fovModel.getSliderModel(Math.PI * 57.3/180, Math.PI * 160/180)), "wrap");
|
||||
}
|
||||
});
|
||||
|
||||
@ -232,19 +242,24 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
|
||||
/// Ambiance
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.amb")));
|
||||
DoubleModel ambianceModel = new DoubleModel(p, "Ambiance", 100, UnitGroup.UNITS_NONE, 0, 100);
|
||||
add(new EditableSpinner(ambianceModel.getSpinnerModel()), "wrap");
|
||||
DoubleModel ambianceModel = new DoubleModel(p, "Ambiance", UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
add(new EditableSpinner(ambianceModel.getSpinnerModel()), "growx, split 2");
|
||||
add(new UnitSelector(ambianceModel));
|
||||
add(new BasicSlider(ambianceModel.getSliderModel(0, 1)), "pushx, left, wrap");
|
||||
|
||||
/// Light azimuth
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAz")));
|
||||
DoubleModel lightAzModel = new DoubleModel(p, "LightAz", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(lightAzModel.getSpinnerModel()), "split 2");
|
||||
add(new UnitSelector(lightAzModel), "pushx, left, wrap");
|
||||
add(new EditableSpinner(lightAzModel.getSpinnerModel()), "growx, split 2");
|
||||
add(new UnitSelector(lightAzModel));
|
||||
add(new BasicSlider(lightAzModel.getSliderModel(-Math.PI, Math.PI)), "wrap");
|
||||
|
||||
/// Light altitude
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAlt")));
|
||||
DoubleModel lightAltModle = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(lightAltModle.getSpinnerModel()), "wrap");
|
||||
DoubleModel lightAltModle = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE, -Math.PI / 2, Math.PI / 2);
|
||||
add(new EditableSpinner(lightAltModle.getSpinnerModel()), "growx, split 2");
|
||||
add(new UnitSelector(lightAltModle));
|
||||
add(new BasicSlider(lightAltModle.getSliderModel(-Math.PI / 2, Math.PI / 2)), "wrap");
|
||||
|
||||
// Sky
|
||||
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.sky"), Style.BOLD), "split, span, gapright para");
|
||||
@ -292,7 +307,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
setSelectedItem(noSky);
|
||||
}
|
||||
}
|
||||
}, "wrap");
|
||||
}, "spanx, wrap");
|
||||
|
||||
/// Image credit
|
||||
final JLabel creditLabel = new JLabel(trans.get("PhotoSettingsConfig.lbl.skyCredit"));
|
||||
@ -304,7 +319,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
credit.setOpaque(false);
|
||||
credit.setFocusable(false);
|
||||
credit.setFont(creditLabel.getFont());
|
||||
add(credit);
|
||||
add(credit, "spanx");
|
||||
|
||||
final StateChangeListener skyChange = new StateChangeListener() {
|
||||
@Override
|
||||
@ -332,22 +347,28 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
/// Smoke
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smoke")));
|
||||
BooleanModel smokeModel = new BooleanModel(p, "Smoke");
|
||||
add(new JCheckBox(smokeModel), "split 2, w 15");
|
||||
add(new JCheckBox(smokeModel), "split 2, spanx");
|
||||
|
||||
add(smokeColorButton, "pushx, left, wrap");
|
||||
add(smokeColorButton, "wrap");
|
||||
smokeModel.addEnableComponent(smokeColorButton);
|
||||
|
||||
/// Smoke opacity
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smokeOpacity")));
|
||||
DoubleModel smokeOpacityModel = new DoubleModel(p, "SmokeOpacity", 100, UnitGroup.UNITS_NONE, 0, 100);
|
||||
DoubleModel smokeOpacityModel = new DoubleModel(p, "SmokeOpacity", UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
EditableSpinner opacitySpinner = new EditableSpinner(smokeOpacityModel.getSpinnerModel());
|
||||
add(opacitySpinner, "wrap");
|
||||
UnitSelector opacitySelector = new UnitSelector(smokeOpacityModel);
|
||||
BasicSlider opacitySlider = new BasicSlider(smokeOpacityModel.getSliderModel(0, 1));
|
||||
add(opacitySpinner, "growx");
|
||||
add(opacitySelector);
|
||||
add(opacitySlider, "wrap");
|
||||
smokeModel.addEnableComponent(opacitySpinner);
|
||||
smokeModel.addEnableComponent(opacitySelector);
|
||||
smokeModel.addEnableComponent(opacitySlider);
|
||||
|
||||
/// Flame
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.flame")));
|
||||
BooleanModel fireModel = new BooleanModel(p, "Flame");
|
||||
add(new JCheckBox(fireModel), "split 2, w 15");
|
||||
add(new JCheckBox(fireModel), "split 2, spanx");
|
||||
|
||||
add(flameColorButton, "wrap");
|
||||
fireModel.addEnableComponent(flameColorButton);
|
||||
@ -357,8 +378,11 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
DoubleModel flameAspectModel = new DoubleModel(p, "FlameAspectRatio", 100, UnitGroup.UNITS_NONE, 25,
|
||||
250);
|
||||
EditableSpinner flameAspectSpinner = new EditableSpinner(flameAspectModel.getSpinnerModel());
|
||||
add(flameAspectSpinner, "wrap");
|
||||
BasicSlider flameAspectSlider = new BasicSlider(flameAspectModel.getSliderModel(25, 250));
|
||||
add(flameAspectSpinner, "growx");
|
||||
add(flameAspectSlider, "skip 1, wrap");
|
||||
fireModel.addEnableComponent(flameAspectSpinner);
|
||||
fireModel.addEnableComponent(flameAspectSlider);
|
||||
|
||||
/// Sparks
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparks")));
|
||||
@ -369,23 +393,36 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
|
||||
/// Sparks concentration
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkConcentration")));
|
||||
DoubleModel sparkConcentrationModel = new DoubleModel(p, "SparkConcentration", 100,
|
||||
UnitGroup.UNITS_NONE, 0, 100);
|
||||
DoubleModel sparkConcentrationModel = new DoubleModel(p, "SparkConcentration",
|
||||
UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
EditableSpinner sparkConcentrationSpinner = new EditableSpinner(sparkConcentrationModel.getSpinnerModel());
|
||||
add(sparkConcentrationSpinner, "wrap");
|
||||
UnitSelector sparkConcentrationSelector = new UnitSelector(sparkConcentrationModel);
|
||||
BasicSlider sparkConcentrationSlider = new BasicSlider(sparkConcentrationModel.getSliderModel(0, 1));
|
||||
add(sparkConcentrationSpinner, "growx");
|
||||
add(sparkConcentrationSelector);
|
||||
add(sparkConcentrationSlider, "wrap");
|
||||
sparksModel.addEnableComponent(sparkConcentrationSpinner);
|
||||
sparksModel.addEnableComponent(sparkConcentrationSelector);
|
||||
sparksModel.addEnableComponent(sparkConcentrationSlider);
|
||||
|
||||
/// Spark weight
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkWeight")));
|
||||
DoubleModel sparkWeightModel = new DoubleModel(p, "SparkWeight", 100, UnitGroup.UNITS_NONE, 0, 100);
|
||||
DoubleModel sparkWeightModel = new DoubleModel(p, "SparkWeight", UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
EditableSpinner sparkWeightSpinner = new EditableSpinner(sparkWeightModel.getSpinnerModel());
|
||||
add(sparkWeightSpinner, "wrap");
|
||||
UnitSelector sparkWeightSelector = new UnitSelector(sparkWeightModel);
|
||||
BasicSlider sparkWeightSlider = new BasicSlider(sparkWeightModel.getSliderModel(0, 1));
|
||||
add(sparkWeightSpinner, "growx");
|
||||
add(sparkWeightSelector);
|
||||
add(sparkWeightSlider, "wrap");
|
||||
sparksModel.addEnableComponent(sparkWeightSpinner);
|
||||
sparksModel.addEnableComponent(sparkWeightSelector);
|
||||
sparksModel.addEnableComponent(sparkWeightSlider);
|
||||
|
||||
/// Exhaust scale
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.exhaustScale")));
|
||||
DoubleModel exhaustScaleModel = new DoubleModel(p, "ExhaustScale", 100, UnitGroup.UNITS_NONE, 0, 1000);
|
||||
add(new EditableSpinner(exhaustScaleModel.getSpinnerModel()), "wrap");
|
||||
add(new EditableSpinner(exhaustScaleModel.getSpinnerModel()), "growx");
|
||||
add(new BasicSlider(exhaustScaleModel.getSliderModel(0, 1000)), "skip 1, wrap");
|
||||
|
||||
// Effects
|
||||
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.effects"), Style.BOLD), "split, span, gapright para");
|
||||
|
||||
@ -117,7 +117,7 @@ public class BasicFrame extends JFrame {
|
||||
* List of currently open frames. When the list goes empty
|
||||
* it is time to exit the application.
|
||||
*/
|
||||
private static final ArrayList<BasicFrame> frames = new ArrayList<BasicFrame>();
|
||||
private static final List<BasicFrame> frames = new ArrayList<BasicFrame>();
|
||||
private static BasicFrame startupFrame = null; // the frame that was created at startup
|
||||
|
||||
|
||||
@ -490,6 +490,10 @@ public class BasicFrame extends JFrame {
|
||||
return result;
|
||||
}
|
||||
|
||||
public RocketPanel getRocketPanel() {
|
||||
return rocketpanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the menu for the window.
|
||||
*/
|
||||
@ -1890,6 +1894,13 @@ public class BasicFrame extends JFrame {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all BasicFrame instances
|
||||
*/
|
||||
public static List<BasicFrame> getAllFrames() {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether all the BasicFrames are closed.
|
||||
* @return true if all the BasicFrames are closed, false if not
|
||||
|
||||
122
swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java
Normal file
122
swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java
Normal file
@ -0,0 +1,122 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* Shapes of an "empty"/virtual object, e.g. a podset without any children.
|
||||
* The shape is a center square with additional lines on the north, east, south and west side of the square.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public class EmptyShapes extends RocketComponentShape {
|
||||
/**
|
||||
* Returns the empty shape in the side view.
|
||||
* @param radius radius of the center square
|
||||
*/
|
||||
public static Shape[] getShapesSide(final Transformation transformation, final double radius) {
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
double x = instanceAbsoluteLocation.x;
|
||||
double y = instanceAbsoluteLocation.y;
|
||||
|
||||
double lineLength = getLineLength(radius); // Length of the line protruding the center square
|
||||
|
||||
final Shape[] s = new Shape[5];
|
||||
// Center square
|
||||
s[0] = new Rectangle2D.Double(x - radius, y - radius, 2 * radius, 2 * radius);
|
||||
// Line North
|
||||
s[1] = new Line2D.Double(x, y + radius, x, y + radius + lineLength);
|
||||
// Line East
|
||||
s[2] = new Line2D.Double(x + radius, y, x + radius + lineLength, y);
|
||||
// Line South
|
||||
s[3] = new Line2D.Double(x, y - radius, x, y - radius - lineLength);
|
||||
// Line West
|
||||
s[4] = new Line2D.Double(x - radius, y, x - radius - lineLength, y);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the empty shape in the side view, with an additional square encompassing the shape that can be used
|
||||
* for selecting the object.
|
||||
* @param radius radius of the center square
|
||||
*/
|
||||
public static Shape[] getShapesSideWithSelectionSquare(final Transformation transformation, final double radius) {
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
double x = instanceAbsoluteLocation.x;
|
||||
double y = instanceAbsoluteLocation.y;
|
||||
|
||||
double lineLength = getLineLength(radius); // Length of the line protruding the center square
|
||||
|
||||
Shape[] shapes = getShapesSide(transformation, radius);
|
||||
|
||||
// Invisible shape for selecting the component (= a square encompassing the component)
|
||||
Shape selectionShape = new Rectangle2D.Double(x - radius - lineLength, y - radius - lineLength,
|
||||
lineLength * 2 + radius * 2, lineLength * 2 + radius * 2);
|
||||
|
||||
Shape[] finalShapes = new Shape[shapes.length + 1];
|
||||
System.arraycopy(shapes, 0, finalShapes, 0, shapes.length);
|
||||
finalShapes[finalShapes.length - 1] = selectionShape;
|
||||
|
||||
return finalShapes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the empty shape in the side view.
|
||||
* @param radius radius of the center square
|
||||
*/
|
||||
public static Shape[] getShapesBack(final Transformation transformation, final double radius) {
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
double z = instanceAbsoluteLocation.z;
|
||||
double y = instanceAbsoluteLocation.y;
|
||||
|
||||
double lineLength = getLineLength(radius); // Length of the line protruding the center square
|
||||
|
||||
final Shape[] s = new Shape[5];
|
||||
// Center square
|
||||
s[0] = new Rectangle2D.Double(z - radius, y - radius, 2 * radius, 2 * radius);
|
||||
// Line North
|
||||
s[1] = new Line2D.Double(z, y + radius, z, y + radius + lineLength);
|
||||
// Line East
|
||||
s[2] = new Line2D.Double(z + radius, y, z + radius + lineLength, y);
|
||||
// Line South
|
||||
s[3] = new Line2D.Double(z, y - radius, z, y - radius - lineLength);
|
||||
// Line West
|
||||
s[4] = new Line2D.Double(z - radius, y, z - radius - lineLength, y);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the empty shape in the back view, with an additional square encompassing the shape that can be used
|
||||
* for selecting the object.
|
||||
* @param radius radius of the center square
|
||||
*/
|
||||
public static Shape[] getShapesBackWithSelectionSquare(final Transformation transformation, final double radius) {
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
double z = instanceAbsoluteLocation.z;
|
||||
double y = instanceAbsoluteLocation.y;
|
||||
|
||||
double lineLength = getLineLength(radius); // Length of the line protruding the center square
|
||||
|
||||
Shape[] shapes = getShapesBack(transformation, radius);
|
||||
|
||||
// Invisible shape for selecting the component (= a square encompassing the component)
|
||||
Shape selectionShape = new Rectangle2D.Double(z - radius - lineLength, y - radius - lineLength,
|
||||
lineLength * 2 + radius * 2, lineLength * 2 + radius * 2);
|
||||
|
||||
Shape[] finalShapes = new Shape[shapes.length + 1];
|
||||
System.arraycopy(shapes, 0, finalShapes, 0, shapes.length);
|
||||
finalShapes[finalShapes.length - 1] = selectionShape;
|
||||
|
||||
return finalShapes;
|
||||
}
|
||||
|
||||
private static double getLineLength(double radius) {
|
||||
return radius * 3;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
import java.awt.Shape;
|
||||
|
||||
public class ParallelStageShapes extends RocketComponentShape {
|
||||
public static final Color boosterColor = new Color(198,163,184);
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) {
|
||||
ParallelStage booster = (ParallelStage)component;
|
||||
double radius = getDisplayRadius(booster);
|
||||
|
||||
Shape[] s = EmptyShapes.getShapesSideWithSelectionSquare(transformation, radius);
|
||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
||||
|
||||
// Set the color of the shapes
|
||||
for (int i = 0; i < shapes.length - 1; i++) {
|
||||
shapes[i].setColor(boosterColor);
|
||||
}
|
||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(final RocketComponent component, final Transformation transformation) {
|
||||
ParallelStage booster = (ParallelStage)component;
|
||||
double radius = getDisplayRadius(booster);
|
||||
|
||||
Shape[] s = EmptyShapes.getShapesBackWithSelectionSquare(transformation, radius);
|
||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
||||
|
||||
// Set the color of the shapes
|
||||
for (int i = 0; i < shapes.length - 1; i++) {
|
||||
shapes[i].setColor(boosterColor);
|
||||
}
|
||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
private static double getDisplayRadius(ParallelStage booster) {
|
||||
return booster.getRocket().getBoundingRadius() * 0.03;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.PodSet;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
import java.awt.Shape;
|
||||
|
||||
public class PodSetShapes extends RocketComponentShape {
|
||||
public static final Color podsetColor = new Color(160,160,215);
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) {
|
||||
PodSet podset = (PodSet)component;
|
||||
double radius = getDisplayRadius(podset);
|
||||
|
||||
Shape[] s = EmptyShapes.getShapesSideWithSelectionSquare(transformation, radius);
|
||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
||||
|
||||
// Set the color of the shapes
|
||||
for (int i = 0; i < shapes.length - 1; i++) {
|
||||
shapes[i].setColor(podsetColor);
|
||||
}
|
||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(final RocketComponent component, final Transformation transformation) {
|
||||
PodSet podset = (PodSet)component;
|
||||
double radius = getDisplayRadius(podset);
|
||||
|
||||
Shape[] s = EmptyShapes.getShapesBackWithSelectionSquare(transformation, radius);
|
||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
||||
|
||||
// Set the color of the shapes
|
||||
for (int i = 0; i < shapes.length - 1; i++) {
|
||||
shapes[i].setColor(podsetColor);
|
||||
}
|
||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
private static double getDisplayRadius(PodSet podset) {
|
||||
return podset.getRocket().getBoundingRadius() * 0.03;
|
||||
}
|
||||
}
|
||||
@ -29,7 +29,7 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
final RailButton btn = (RailButton)component;
|
||||
|
||||
final double baseHeight = btn.getStandoff();
|
||||
final double baseHeight = btn.getBaseHeight();
|
||||
final double innerHeight = btn.getInnerHeight();
|
||||
final double flangeHeight = btn.getFlangeHeight();
|
||||
|
||||
@ -53,72 +53,73 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
|
||||
Path2D.Double path = new Path2D.Double();
|
||||
Path2D.Double pathInvis = new Path2D.Double(); // Path for the invisible triangles
|
||||
{// central pillar
|
||||
final double drawWidth = outerDiameter;
|
||||
final double drawHeight = outerDiameter*sinr;
|
||||
final Point2D.Double center = new Point2D.Double( loc.x, loc.y );
|
||||
Point2D.Double lowerLeft = new Point2D.Double( center.x - outerRadius, center.y-outerRadius*sinr);
|
||||
path.append( new Ellipse2D.Double( lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
|
||||
|
||||
path.append( new Line2D.Double( lowerLeft.x, center.y, lowerLeft.x, (center.y+baseHeightcos) ), false);
|
||||
path.append( new Line2D.Double( (center.x+outerRadius), center.y, (center.x+outerRadius), (center.y+baseHeightcos) ), false);
|
||||
|
||||
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+baseHeightcos), drawWidth, drawHeight), false);
|
||||
{// base cylinder
|
||||
if (baseHeight > 0) {
|
||||
final double drawWidth = outerDiameter;
|
||||
final double drawHeight = outerDiameter * sinr;
|
||||
final Point2D.Double center = new Point2D.Double(loc.x, loc.y);
|
||||
Point2D.Double lowerLeft = new Point2D.Double(center.x - outerRadius, center.y - outerRadius * sinr);
|
||||
path.append(new Ellipse2D.Double(lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
|
||||
|
||||
// Invisible rectangle
|
||||
double y_invis;
|
||||
if (baseHeightcos >= 0) {
|
||||
y_invis = center.y;
|
||||
path.append(new Line2D.Double(lowerLeft.x, center.y, lowerLeft.x, (center.y + baseHeightcos)), false);
|
||||
path.append(new Line2D.Double((center.x + outerRadius), center.y, (center.x + outerRadius), (center.y + baseHeightcos)), false);
|
||||
|
||||
path.append(new Ellipse2D.Double(lowerLeft.x, (lowerLeft.y + baseHeightcos), drawWidth, drawHeight), false);
|
||||
|
||||
// Invisible rectangle
|
||||
double y_invis;
|
||||
if (baseHeightcos >= 0) {
|
||||
y_invis = center.y;
|
||||
} else {
|
||||
y_invis = center.y + baseHeightcos;
|
||||
}
|
||||
pathInvis.append(new Rectangle2D.Double(center.x - outerRadius, y_invis, drawWidth, Math.abs(baseHeightcos)), false);
|
||||
}
|
||||
else {
|
||||
y_invis = center.y + baseHeightcos;
|
||||
}
|
||||
pathInvis.append(new Rectangle2D.Double(center.x-outerRadius, y_invis, drawWidth, Math.abs(baseHeightcos)), false);
|
||||
}
|
||||
|
||||
{// inner flange
|
||||
{// inner cylinder
|
||||
final double drawWidth = innerDiameter;
|
||||
final double drawHeight = innerDiameter*sinr;
|
||||
final Point2D.Double center = new Point2D.Double( loc.x, loc.y + baseHeightcos);
|
||||
final Point2D.Double lowerLeft = new Point2D.Double( center.x - innerRadius, center.y-innerRadius*sinr);
|
||||
path.append( new Ellipse2D.Double( lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
|
||||
|
||||
path.append( new Line2D.Double( lowerLeft.x, center.y, lowerLeft.x, (center.y+innerHeightcos) ), false);
|
||||
path.append( new Line2D.Double( (center.x+innerRadius), center.y, (center.x+innerRadius), (center.y+innerHeightcos) ), false);
|
||||
|
||||
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+innerHeightcos), drawWidth, drawHeight), false);
|
||||
final double drawHeight = innerDiameter * sinr;
|
||||
final Point2D.Double center = new Point2D.Double(loc.x, loc.y + baseHeightcos);
|
||||
final Point2D.Double lowerLeft = new Point2D.Double(center.x - innerRadius, center.y - innerRadius * sinr);
|
||||
path.append(new Ellipse2D.Double(lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
|
||||
|
||||
path.append(new Line2D.Double(lowerLeft.x, center.y, lowerLeft.x, (center.y + innerHeightcos)), false);
|
||||
path.append(new Line2D.Double((center.x + innerRadius), center.y, (center.x + innerRadius), (center.y + innerHeightcos)), false);
|
||||
|
||||
path.append(new Ellipse2D.Double(lowerLeft.x, (lowerLeft.y + innerHeightcos), drawWidth, drawHeight), false);
|
||||
|
||||
// Invisible rectangle
|
||||
double y_invis;
|
||||
if (innerHeightcos >= 0) {
|
||||
y_invis = center.y;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
y_invis = center.y + innerHeightcos;
|
||||
}
|
||||
pathInvis.append(new Rectangle2D.Double(center.x-innerRadius, y_invis, drawWidth, Math.abs(innerHeightcos)), false);
|
||||
pathInvis.append(new Rectangle2D.Double(center.x - innerRadius, y_invis, drawWidth, Math.abs(innerHeightcos)), false);
|
||||
}
|
||||
{// outer flange
|
||||
final double drawWidth = outerDiameter;
|
||||
final double drawHeight = outerDiameter*sinr;
|
||||
final Point2D.Double center = new Point2D.Double( loc.x, loc.y+baseHeightcos+innerHeightcos);
|
||||
final Point2D.Double lowerLeft = new Point2D.Double( center.x - outerRadius, center.y-outerRadius*sinr);
|
||||
path.append( new Ellipse2D.Double( lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
|
||||
|
||||
path.append( new Line2D.Double( lowerLeft.x, center.y, lowerLeft.x, (center.y+flangeHeightcos) ), false);
|
||||
path.append( new Line2D.Double( (center.x+outerRadius), center.y, (center.x+outerRadius), (center.y+flangeHeightcos) ), false);
|
||||
|
||||
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+flangeHeightcos), drawWidth, drawHeight), false);
|
||||
{// flange cylinder
|
||||
if (flangeHeight > 0) {
|
||||
final double drawWidth = outerDiameter;
|
||||
final double drawHeight = outerDiameter * sinr;
|
||||
final Point2D.Double center = new Point2D.Double(loc.x, loc.y + baseHeightcos + innerHeightcos);
|
||||
final Point2D.Double lowerLeft = new Point2D.Double(center.x - outerRadius, center.y - outerRadius * sinr);
|
||||
path.append(new Ellipse2D.Double(lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
|
||||
|
||||
// Invisible rectangle
|
||||
double y_invis;
|
||||
if (flangeHeightcos >= 0) {
|
||||
y_invis = center.y;
|
||||
path.append(new Line2D.Double(lowerLeft.x, center.y, lowerLeft.x, (center.y + flangeHeightcos)), false);
|
||||
path.append(new Line2D.Double((center.x + outerRadius), center.y, (center.x + outerRadius), (center.y + flangeHeightcos)), false);
|
||||
|
||||
path.append(new Ellipse2D.Double(lowerLeft.x, (lowerLeft.y + flangeHeightcos), drawWidth, drawHeight), false);
|
||||
|
||||
// Invisible rectangle
|
||||
double y_invis;
|
||||
if (flangeHeightcos >= 0) {
|
||||
y_invis = center.y;
|
||||
} else {
|
||||
y_invis = center.y + flangeHeightcos;
|
||||
}
|
||||
pathInvis.append(new Rectangle2D.Double(center.x - outerRadius, y_invis, drawWidth, Math.abs(flangeHeightcos)), false);
|
||||
}
|
||||
else {
|
||||
y_invis = center.y + flangeHeightcos;
|
||||
}
|
||||
pathInvis.append(new Rectangle2D.Double(center.x-outerRadius, y_invis, drawWidth, Math.abs(flangeHeightcos)), false);
|
||||
}
|
||||
|
||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(new Shape[]{ path }, component);
|
||||
@ -136,7 +137,7 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
final RailButton btn = (RailButton)component;
|
||||
|
||||
final double baseHeight = btn.getStandoff();
|
||||
final double baseHeight = btn.getBaseHeight();
|
||||
final double innerHeight = btn.getInnerHeight();
|
||||
final double flangeHeight = btn.getFlangeHeight();
|
||||
|
||||
@ -159,7 +160,9 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
Path2D.Double path = new Path2D.Double();
|
||||
|
||||
// base
|
||||
path.append( getRotatedRectangle( loc.z, loc.y, outerRadius, baseHeight, combined_angle_rad), false );
|
||||
if (baseHeight > 0) {
|
||||
path.append(getRotatedRectangle(loc.z, loc.y, outerRadius, baseHeight, combined_angle_rad), false);
|
||||
}
|
||||
|
||||
{// inner
|
||||
final double delta_r = baseHeight;
|
||||
@ -167,11 +170,13 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
final double delta_z = delta_r*sinr;
|
||||
path.append( getRotatedRectangle( loc.z+delta_z, loc.y+delta_y, innerRadius, innerHeight, combined_angle_rad), false);
|
||||
}
|
||||
{// outer flange
|
||||
final double delta_r = baseHeight + innerHeight;
|
||||
final double delta_y = delta_r*cosr;
|
||||
final double delta_z = delta_r*sinr;
|
||||
path.append( getRotatedRectangle( loc.z+delta_z, loc.y+delta_y, outerRadius, flangeHeight, combined_angle_rad), false);
|
||||
{// flange
|
||||
if (flangeHeight > 0) {
|
||||
final double delta_r = baseHeight + innerHeight;
|
||||
final double delta_y = delta_r * cosr;
|
||||
final double delta_z = delta_r * sinr;
|
||||
path.append(getRotatedRectangle(loc.z + delta_z, loc.y + delta_y, outerRadius, flangeHeight, combined_angle_rad), false);
|
||||
}
|
||||
}
|
||||
|
||||
return RocketComponentShape.toArray( new Shape[]{ path }, component);
|
||||
|
||||
@ -64,6 +64,10 @@ public class RocketComponentShape {
|
||||
return new RocketComponentShape[0];
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@ -17,6 +17,9 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.rocketcomponent.PodSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -26,7 +29,6 @@ import net.sf.openrocket.gui.util.ColorConversion;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
@ -52,6 +54,7 @@ import net.sf.openrocket.util.Transformation;
|
||||
public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(FinPointFigure.class);
|
||||
protected final SwingPreferences preferences = (SwingPreferences) Application.getPreferences();
|
||||
|
||||
private static final String ROCKET_FIGURE_PACKAGE = "net.sf.openrocket.gui.rocketfigure";
|
||||
private static final String ROCKET_FIGURE_SUFFIX = "Shapes";
|
||||
@ -378,6 +381,20 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
for(Entry<RocketComponent, ArrayList<InstanceContext>> entry: config.getActiveInstances().entrySet() ) {
|
||||
final RocketComponent comp = entry.getKey();
|
||||
|
||||
// Only draw podsets when they are selected
|
||||
if ((comp instanceof PodSet || comp instanceof ParallelStage) && preferences.isShowMarkers()) {
|
||||
boolean selected = false;
|
||||
|
||||
// Check if component is in the selection
|
||||
for (RocketComponent component : selection) {
|
||||
if (comp == component) {
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!selected) continue;
|
||||
}
|
||||
|
||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||
|
||||
@ -390,8 +407,12 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
/**
|
||||
* Gets the shapes required to draw the component.
|
||||
*
|
||||
* @param component
|
||||
*
|
||||
* @param allShapes output buffer for the shapes to add to
|
||||
* @param viewType the view type to draw the component in
|
||||
* @param component component to draw and add to <allShapes>
|
||||
* @param transformation transformation to apply to the component before drawing it
|
||||
* @param color color to draw the component in
|
||||
*
|
||||
* @return the <code>ArrayList</code> containing all the shapes to draw.
|
||||
*/
|
||||
@ -399,10 +420,11 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
PriorityQueue<RocketComponentShape> allShapes, // this is the output parameter
|
||||
final RocketPanel.VIEW_TYPE viewType,
|
||||
final RocketComponent component,
|
||||
final Transformation transformation) {
|
||||
final Transformation transformation,
|
||||
final net.sf.openrocket.util.Color color) {
|
||||
Reflection.Method m;
|
||||
|
||||
if(( component instanceof Rocket)||( component instanceof ComponentAssembly )){
|
||||
if ((component instanceof Rocket) || (component instanceof AxialStage && !(component instanceof ParallelStage))){
|
||||
// no-op; no shapes here
|
||||
return allShapes;
|
||||
}
|
||||
@ -431,9 +453,35 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
|
||||
RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation);
|
||||
|
||||
if (color != null) {
|
||||
for (RocketComponentShape rcs : returnValue) {
|
||||
if (rcs.getColor() == net.sf.openrocket.util.Color.INVISIBLE) continue; // don't change the color of invisible (often selection) components
|
||||
rcs.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
allShapes.addAll(Arrays.asList(returnValue));
|
||||
return allShapes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shapes required to draw the component.
|
||||
*
|
||||
* @param allShapes output buffer for the shapes to add to
|
||||
* @param viewType the view type to draw the component in
|
||||
* @param component component to draw and add to <allShapes>
|
||||
* @param transformation transformation to apply to the component before drawing it
|
||||
*
|
||||
* @return the <code>ArrayList</code> containing all the shapes to draw.
|
||||
*/
|
||||
private static PriorityQueue<RocketComponentShape> addThisShape(
|
||||
PriorityQueue<RocketComponentShape> allShapes, // this is the output parameter
|
||||
final RocketPanel.VIEW_TYPE viewType,
|
||||
final RocketComponent component,
|
||||
final Transformation transformation) {
|
||||
return addThisShape(allShapes, viewType, component, transformation, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -252,7 +252,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
});
|
||||
}
|
||||
|
||||
private void updateFigures() {
|
||||
public void updateFigures() {
|
||||
if (!is3d)
|
||||
figure.updateFigure();
|
||||
else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user