diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index ad77afbd9..a14f89be9 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -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 = If checked, pod set/booster markers will only be shown when the pod set/booster is selected.
If unchecked, pod set/booster markers will always be shown. pref.dlg.checkbox.AlwaysOpenLeftmost = Always open leftmost tab when opening a component edit dialog pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = If checked, a component edit dialog will always pop up with the first tab selected.
If unchecked, the previous selected tab will be used. 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 diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java index 16f733ec9..da4978cd4 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java @@ -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( diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RailButtonSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RailButtonSaver.java index 74a9c0638..73db68866 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RailButtonSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RailButtonSaver.java @@ -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()); } diff --git a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java index 12d152c8e..48804f2b8 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java +++ b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java @@ -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 { diff --git a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java index f76ee3e87..a93b562a4 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java @@ -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); diff --git a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java index 5411440f7..df808818e 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -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; + } diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 23a954e70..637d01465 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -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; } diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index 64f1de5a0..3d750c651 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -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. * diff --git a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java index ba6b077da..b695e5dbf 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java @@ -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); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java index b5e005a4a..be4803c42 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java @@ -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 methodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); JComboBox relToCombo = new JComboBox( 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"); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index dd27f02c3..30f169bf9 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -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); diff --git a/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java index ad53576e6..3a1db6af8 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java @@ -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))) { diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java index 08ef4acb1..3a98bd616 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java @@ -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"); } } diff --git a/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java index 5c2d39c1e..84c57a1ec 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java @@ -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); + } } } diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java index 2030dba2b..3ce2cd3cc 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java @@ -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); diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java index eca18a495..23599f7f3 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java @@ -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); } } \ No newline at end of file diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java index 6294a6e96..ef27b0dc4 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java @@ -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"); diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 04fdf9bf3..6f76a838d 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -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 frames = new ArrayList(); + private static final List frames = new ArrayList(); 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 getAllFrames() { + return frames; + } + /** * Checks whether all the BasicFrames are closed. * @return true if all the BasicFrames are closed, false if not diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java new file mode 100644 index 000000000..35b048551 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java @@ -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 + */ +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; + } +} diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java new file mode 100644 index 000000000..565a23591 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java @@ -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; + } +} diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java new file mode 100644 index 000000000..7ef928f2d --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java @@ -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; + } +} diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/RailButtonShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/RailButtonShapes.java index 8250c41b8..26c95a24d 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/RailButtonShapes.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/RailButtonShapes.java @@ -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); diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java b/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java index 725713b80..c132bfd3d 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java @@ -64,6 +64,10 @@ public class RocketComponentShape { return new RocketComponentShape[0]; } + public Color getColor() { + return color; + } + public void setColor(Color color) { this.color = color; } diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index 3226abee2..6e4bf9e4b 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -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> 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 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 + * @param transformation transformation to apply to the component before drawing it + * @param color color to draw the component in * * @return the ArrayList containing all the shapes to draw. */ @@ -399,10 +420,11 @@ public class RocketFigure extends AbstractScaleFigure { PriorityQueue 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 + * @param transformation transformation to apply to the component before drawing it + * + * @return the ArrayList containing all the shapes to draw. + */ + private static PriorityQueue addThisShape( + PriorityQueue allShapes, // this is the output parameter + final RocketPanel.VIEW_TYPE viewType, + final RocketComponent component, + final Transformation transformation) { + return addThisShape(allShapes, viewType, component, transformation, null); + } /** diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 92df95906..9f4f309f7 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -252,7 +252,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change }); } - private void updateFigures() { + public void updateFigures() { if (!is3d) figure.updateFigure(); else