From 43b17c6eab3bf2065e965276abfe464714183ee3 Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Wed, 22 Mar 2023 16:26:22 -0600 Subject: [PATCH 01/34] Consider points along fin root when calculating fin geometry --- .../sf/openrocket/aerodynamics/barrowman/FinSetCalc.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/net/sf/openrocket/aerodynamics/barrowman/FinSetCalc.java b/core/src/net/sf/openrocket/aerodynamics/barrowman/FinSetCalc.java index 326c73a0d..6708e645f 100644 --- a/core/src/net/sf/openrocket/aerodynamics/barrowman/FinSetCalc.java +++ b/core/src/net/sf/openrocket/aerodynamics/barrowman/FinSetCalc.java @@ -235,9 +235,9 @@ public class FinSetCalc extends RocketComponentCalc { finArea = component.getPlanformArea(); ar = 2 * pow2(span) / finArea; + // Check geometry; don't consider points along fin root for this + // (doing so will cause spurious jagged fin warnings) Coordinate[] points = component.getFinPoints(); - - // Check geometry geometryWarnings.clear(); boolean down = false; for (int i = 1; i < points.length; i++) { @@ -259,8 +259,9 @@ public class FinSetCalc extends RocketComponentCalc { geometryWarnings.add(Warning.THICK_FIN, component.toString()); } - // Calculate the chord lead and trail positions and length - + // Calculate the chord lead and trail positions and length. We do need the points + // along the root for this + points = component.getFinPointsWithRoot(); Arrays.fill(chordLead, Double.POSITIVE_INFINITY); Arrays.fill(chordTrail, Double.NEGATIVE_INFINITY); Arrays.fill(chordLength, 0); From 77d2a5cd5736fae240f5bd6831a4dd0c029a525a Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Thu, 23 Mar 2023 20:11:28 -0600 Subject: [PATCH 02/34] Add unit test --- .../rocketcomponent/FreeformFinSetTest.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java b/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java index f048a9282..c2c347f08 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java @@ -1557,4 +1557,49 @@ public class FreeformFinSetTest extends BaseTestCase { } } + /** + * Test that fins on transitions don't get NaN MAClength + */ + @Test + public void testFinsOnTransitions() { + // Rocket consisting of just a transition and a freeform fin set + final Rocket rocket = new Rocket(); + + final AxialStage stage = new AxialStage(); + rocket.addChild(stage); + + Transition trans = new Transition(); + stage.addChild(trans); + + FreeformFinSet fins = new FreeformFinSet(); + trans.addChild(fins); + + // set the finset at the beginning of the transition + fins.setAxialMethod(AxialMethod.TOP); + fins.setAxialOffset(0.0); + + // Test 1: transition getting smaller + trans.setForeRadius(trans.getForeRadius()*2.0); + fins.setPoints(new Coordinate[] { + new Coordinate(0, 0), + new Coordinate(trans.getLength(), 0), + new Coordinate(trans.getLength(), trans.getAftRadius() - trans.getForeRadius()) + }); + FinSetCalc calc = new FinSetCalc(fins); + + assertEquals(0.075, calc.getMACLength(), EPSILON); + + // Test 2: transition getting larger + trans.setForeRadius(trans.getAftRadius()); + trans.setAftRadius(trans.getAftRadius()*2.0); + fins.setPoints(new Coordinate[] { + new Coordinate(0, 0), + new Coordinate(0, trans.getAftRadius() - trans.getForeRadius()), + new Coordinate(trans.getLength(), trans.getAftRadius() - trans.getForeRadius()) + }); + calc = new FinSetCalc(fins); + + assertEquals(0.05053191489361704, calc.getMACLength(), EPSILON); + } + } From 522c3a49b612003f3e2eb500ff64cc8493d1081b Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 27 Mar 2023 22:50:45 +0200 Subject: [PATCH 03/34] Fix bad naming of menu variables --- .../sf/openrocket/gui/main/BasicFrame.java | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index dd3417dbf..cfdeb14ba 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -515,12 +515,12 @@ public class BasicFrame extends JFrame { fileMenu.add(item); //// Edit - fileMenu = new JMenu(trans.get("main.menu.edit")); - fileMenu.setMnemonic(KeyEvent.VK_E); + JMenu editMenu = new JMenu(trans.get("main.menu.edit")); + editMenu.setMnemonic(KeyEvent.VK_E); //// Rocket editing - fileMenu.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.desc")); - menubar.add(fileMenu); + editMenu.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.desc")); + menubar.add(editMenu); Action action = UndoRedoAction.newUndoAction(document); item = new JMenuItem(action); @@ -530,7 +530,7 @@ public class BasicFrame extends JFrame { //// Undo the previous operation item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.undo.desc")); - fileMenu.add(item); + editMenu.add(item); action = UndoRedoAction.newRedoAction(document); item = new JMenuItem(action); @@ -539,42 +539,42 @@ public class BasicFrame extends JFrame { //// Redo the previously undone operation item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.redo.desc")); - fileMenu.add(item); + editMenu.add(item); - fileMenu.addSeparator(); + editMenu.addSeparator(); item = new JMenuItem(actions.getEditAction()); - fileMenu.add(item); + editMenu.add(item); item = new JMenuItem(actions.getCutAction()); - fileMenu.add(item); + editMenu.add(item); item = new JMenuItem(actions.getCopyAction()); - fileMenu.add(item); + editMenu.add(item); item = new JMenuItem(actions.getPasteAction()); - fileMenu.add(item); + editMenu.add(item); item = new JMenuItem(actions.getDuplicateAction()); - fileMenu.add(item); + editMenu.add(item); item = new JMenuItem(actions.getDeleteAction()); - fileMenu.add(item); + editMenu.add(item); - fileMenu.addSeparator(); + editMenu.addSeparator(); JMenu subMenu = new JMenu(trans.get("RocketActions.Select")); - fileMenu.add(subMenu); + editMenu.add(subMenu); item = new JMenuItem(actions.getSelectSameColorAction()); subMenu.add(item); item = new JMenuItem(actions.getDeselectAllAction()); subMenu.add(item); - fileMenu.addSeparator(); + editMenu.addSeparator(); item = new JMenuItem(actions.getScaleAction()); - fileMenu.add(item); + editMenu.add(item); //// Preferences @@ -590,7 +590,7 @@ public class BasicFrame extends JFrame { PreferencesDialog.showPreferences(BasicFrame.this); } }); - fileMenu.add(item); + editMenu.add(item); //// Edit Component Preset File if (System.getProperty("openrocket.preseteditor.fileMenu") != null) { @@ -605,13 +605,13 @@ public class BasicFrame extends JFrame { dialog.setVisible(true); } }); - fileMenu.add(item); + editMenu.add(item); } // Tools - fileMenu = new JMenu(trans.get("main.menu.tools")); - menubar.add(fileMenu); + JMenu toolsMenu = new JMenu(trans.get("main.menu.tools")); + menubar.add(toolsMenu); //// Component analysis item = new JMenuItem(trans.get("main.menu.tools.componentAnalysis"), KeyEvent.VK_C); @@ -625,7 +625,7 @@ public class BasicFrame extends JFrame { ComponentAnalysisDialog.showDialog(rocketpanel); } }); - fileMenu.add(item); + toolsMenu.add(item); //// Optimize item = new JMenuItem(trans.get("main.menu.tools.optimization"), KeyEvent.VK_O); @@ -641,7 +641,7 @@ public class BasicFrame extends JFrame { } } }); - fileMenu.add(item); + toolsMenu.add(item); //// Custom expressions item = new JMenuItem(trans.get("main.menu.tools.customExpressions"), KeyEvent.VK_E); @@ -653,7 +653,7 @@ public class BasicFrame extends JFrame { new CustomExpressionDialog(document, BasicFrame.this).setVisible(true); } }); - fileMenu.add(item); + toolsMenu.add(item); item = new JMenuItem(trans.get("PhotoFrame.title"), KeyEvent.VK_P); item.getAccessibleContext().setAccessibleDescription(trans.get("PhotoFrame.desc")); @@ -665,7 +665,7 @@ public class BasicFrame extends JFrame { pa.setVisible(true); } }); - fileMenu.add(item); + toolsMenu.add(item); //// Debug // // (shown if openrocket.debug.fileMenu is defined) From 5fcf3e9850743b3320b7fde20e7a12816c417464 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 27 Mar 2023 22:58:14 +0200 Subject: [PATCH 04/34] Clean up code --- swing/src/net/sf/openrocket/gui/main/BasicFrame.java | 11 ----------- .../openrocket/gui/main/ExampleDesignFileAction.java | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index cfdeb14ba..2f968abe1 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -1284,34 +1284,24 @@ public class BasicFrame extends JFrame { //// Handle the document OpenRocketDocument doc = null; try { - doc = worker.get(); - } catch (ExecutionException e) { - Throwable cause = e.getCause(); - if (cause instanceof FileNotFoundException) { - log.warn("File not found", cause); JOptionPane.showMessageDialog(parent, "File not found: " + displayName, "Error opening file", JOptionPane.ERROR_MESSAGE); return null; - } else if (cause instanceof RocketLoadException) { - log.warn("Error loading the file", cause); JOptionPane.showMessageDialog(parent, "Unable to open file '" + displayName + "': " + cause.getMessage(), "Error opening file", JOptionPane.ERROR_MESSAGE); return null; - } else { - throw new BugException("Unknown error when opening file", e); - } } catch (InterruptedException e) { @@ -1322,7 +1312,6 @@ public class BasicFrame extends JFrame { throw new BugException("Document loader returned null"); } - //// Show warnings WarningSet warnings = worker.getRocketLoader().getWarnings(); if (!warnings.isEmpty()) { diff --git a/swing/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java b/swing/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java index b56bc8ddf..b70b47ad8 100644 --- a/swing/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java +++ b/swing/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java @@ -107,7 +107,7 @@ public final class ExampleDesignFileAction extends JMenu { /** * When a user clicks on one of the recently used design files, open it. * - * @param file the design file name (absolute path) + * @param example the design file name (absolute path) * * @return the action to open a design file */ From f7a66472d56da9695fd140617689fc387af66495 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 28 Mar 2023 18:32:39 +0200 Subject: [PATCH 05/34] [#2148] Apply sim changes when window closes --- .../gui/simulation/SimulationEditDialog.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java index 287182c92..32effec96 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java @@ -5,6 +5,9 @@ import java.awt.CardLayout; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; import javax.swing.JButton; import javax.swing.JComboBox; @@ -42,6 +45,8 @@ public class SimulationEditDialog extends JDialog { JPanel cards; private final static String EDITMODE = "EDIT"; private final static String PLOTMODE = "PLOT"; + + private WindowListener applyChangesToSimsListener; public SimulationEditDialog(Window parent, final OpenRocketDocument document, Simulation... sims) { //// Edit simulation @@ -59,6 +64,14 @@ public class SimulationEditDialog extends JDialog { this.pack(); this.setLocationByPlatform(true); + + this.applyChangesToSimsListener = new WindowAdapter() { + @Override + public void windowClosed(WindowEvent e) { + copyChangesToAllSims(); + } + }; + this.addWindowListener(applyChangesToSimsListener); GUIUtil.setDisposableDialogOptions(this, null); } @@ -75,12 +88,14 @@ public class SimulationEditDialog extends JDialog { CardLayout cl = (CardLayout) (cards.getLayout()); cl.show(cards, EDITMODE); cards.validate(); + this.addWindowListener(applyChangesToSimsListener); } public void setPlotMode() { if (!allowsPlotMode()) { return; } + this.removeWindowListener(applyChangesToSimsListener); setTitle(trans.get("simplotpanel.title.Plotsim")); CardLayout cl = (CardLayout) (cards.getLayout()); cl.show(cards, PLOTMODE); @@ -223,7 +238,6 @@ public class SimulationEditDialog extends JDialog { close.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - copyChangesToAllSims(); SimulationEditDialog.this.dispose(); } }); From fa7f7635ca7fe0f1ec5c058432f9139b2a371a13 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 28 Mar 2023 18:37:32 +0200 Subject: [PATCH 06/34] [#1826] Fill in gaps in multi-sim editing --- .../simulation/SimulationOptions.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/core/src/net/sf/openrocket/simulation/SimulationOptions.java b/core/src/net/sf/openrocket/simulation/SimulationOptions.java index 0025c1f5b..84c20313e 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationOptions.java +++ b/core/src/net/sf/openrocket/simulation/SimulationOptions.java @@ -442,10 +442,6 @@ public class SimulationOptions implements ChangeSource, Cloneable { isChanged = true; this.launchLongitude = src.launchLongitude; } - if (this.launchPressure != src.launchPressure) { - isChanged = true; - this.launchPressure = src.launchPressure; - } if (this.launchRodAngle != src.launchRodAngle) { isChanged = true; this.launchRodAngle = src.launchRodAngle; @@ -458,19 +454,26 @@ public class SimulationOptions implements ChangeSource, Cloneable { isChanged = true; this.launchRodLength = src.launchRodLength; } + if (this.launchIntoWind != src.launchIntoWind) { + isChanged = true; + this.launchIntoWind = src.launchIntoWind; + } + if (this.useISA != src.useISA) { + isChanged = true; + this.useISA = src.useISA; + } if (this.launchTemperature != src.launchTemperature) { isChanged = true; this.launchTemperature = src.launchTemperature; } + if (this.launchPressure != src.launchPressure) { + isChanged = true; + this.launchPressure = src.launchPressure; + } if (this.maximumAngle != src.maximumAngle) { isChanged = true; this.maximumAngle = src.maximumAngle; } - this.maximumAngle = src.maximumAngle; - if (this.timeStep != src.timeStep) { - isChanged = true; - this.timeStep = src.timeStep; - } if (this.windAverage != src.windAverage) { isChanged = true; this.windAverage = src.windAverage; @@ -487,6 +490,14 @@ public class SimulationOptions implements ChangeSource, Cloneable { isChanged = true; this.calculateExtras = src.calculateExtras; } + if (this.timeStep != src.timeStep) { + isChanged = true; + this.timeStep = src.timeStep; + } + if (this.geodeticComputation != src.geodeticComputation) { + isChanged = true; + this.geodeticComputation = src.geodeticComputation; + } if (isChanged) { // Only copy the randomSeed if something else has changed. From fd0018c9a4efdf73c61785ec9a0103932db981c7 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 28 Mar 2023 18:44:08 +0200 Subject: [PATCH 07/34] Enable the edit sim action for multiple sims --- swing/src/net/sf/openrocket/gui/main/SimulationPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index 17336d761..b1a31377b 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -662,7 +662,7 @@ public class SimulationPanel extends JPanel { @Override public void updateEnabledState() { - setEnabled(simulationTable.getSelectedRowCount() == 1); + setEnabled(simulationTable.getSelectedRowCount() > 0); } } From b1cf70144856e93a2b1b893acff1c22a1a208dac Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 18:26:18 +0200 Subject: [PATCH 08/34] [#2151] Update the ruler unit upon a unit change in prefs --- .../preferences/PreferencesDialog.java | 1 + .../gui/scalefigure/RocketPanel.java | 9 +++++++++ .../gui/scalefigure/ScaleScrollPane.java | 20 ++++++++++++++----- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java index 6a438e3d2..54de016bb 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java @@ -97,6 +97,7 @@ public class PreferencesDialog extends JDialog { if (parent != null) { parent.getRocketPanel().updateExtras(); parent.getRocketPanel().updateFigures(); + parent.getRocketPanel().updateRulers(); } } }); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index bc9ebf44e..fda3e62e2 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -271,6 +271,15 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change figure3d.updateFigure(); } + /** + * Updates the rulers of the rocket panel to the currently selected default unit. + */ + public void updateRulers() { + scrollPane.updateRulerUnit(); + scrollPane.revalidate(); + scrollPane.repaint(); + } + private void go3D() { if (is3d) return; diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java index a8a38b648..db7ebad82 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java @@ -15,6 +15,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Point2D; +import java.util.EventObject; import javax.swing.BorderFactory; import javax.swing.JComponent; @@ -56,6 +57,7 @@ public class ScaleScrollPane extends JScrollPane private final AbstractScaleFigure figure; private DoubleModel rulerUnit; + private UnitSelector unitSelector; private Ruler horizontalRuler; private Ruler verticalRuler; @@ -83,7 +85,7 @@ public class ScaleScrollPane extends JScrollPane this.component = component; this.figure = (AbstractScaleFigure) component; - + rulerUnit = new DoubleModel(0.0, UnitGroup.UNITS_LENGTH); rulerUnit.addChangeListener(new ChangeListener() { @Override @@ -95,10 +97,10 @@ public class ScaleScrollPane extends JScrollPane verticalRuler = new Ruler(Ruler.VERTICAL); this.setColumnHeaderView(horizontalRuler); this.setRowHeaderView(verticalRuler); - - UnitSelector selector = new UnitSelector(rulerUnit); - selector.setFont(new Font("SansSerif", Font.PLAIN, 8)); - this.setCorner(JScrollPane.UPPER_LEFT_CORNER, selector); + + unitSelector = new UnitSelector(rulerUnit); + unitSelector.setFont(new Font("SansSerif", Font.PLAIN, 8)); + this.setCorner(JScrollPane.UPPER_LEFT_CORNER, unitSelector); this.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); @@ -176,6 +178,14 @@ public class ScaleScrollPane extends JScrollPane public Unit getCurrentUnit() { return rulerUnit.getCurrentUnit(); } + + /** + * Updates the units of the ruler to the default units of the current unit group. + */ + public void updateRulerUnit() { + rulerUnit.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit()); + unitSelector.stateChanged(new EventObject(this)); + } public String toViewportString(){ Rectangle view = this.getViewport().getViewRect(); From 3a41ea40e3aaf86a47dbdeb847e34df1075ae416 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 19:03:31 +0200 Subject: [PATCH 09/34] [#2152] Fix table column width changing --- .../flightconfiguration/MotorMountConfigurationPanel.java | 2 ++ .../gui/dialogs/flightconfiguration/MotorMountTableModel.java | 2 +- .../gui/main/flightconfigpanel/MotorConfigurationPanel.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountConfigurationPanel.java index 26bf33854..322794979 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountConfigurationPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountConfigurationPanel.java @@ -25,6 +25,8 @@ public class MotorMountConfigurationPanel extends JPanel { table.setShowVerticalLines(false); table.setRowSelectionAllowed(false); table.setColumnSelectionAllowed(false); + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + table.setAutoCreateColumnsFromModel(false); TableColumnModel columnModel = table.getColumnModel(); TableColumn col0 = columnModel.getColumn(0); diff --git a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java index 3c9d7c69f..42fcfc7c8 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java @@ -24,7 +24,7 @@ class MotorMountTableModel extends AbstractTableModel implements ComponentChange private final Rocket rocket; /** - * @param motorConfigurationPanel + * @param rocket the rocket to select motor mounts from */ MotorMountTableModel( Rocket rocket) { this.rocket = rocket; diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java index fa6480665..8f87a56f2 100644 --- a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java @@ -76,7 +76,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel BorderFactory.createEtchedBorder(), "" + trans.get("lbl.motorMounts") + "")); - MotorMountConfigurationPanel mountConfigPanel = new MotorMountConfigurationPanel(this, rocket); + MotorMountConfigurationPanel mountConfigPanel = new MotorMountConfigurationPanel(subpanel, rocket); subpanel.add(mountConfigPanel, "grow, pushy"); this.add(subpanel, "split, growy, pushy"); } From 206fcc291c9ff727b9d3799a1939364cbbacbf4c Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 19:09:12 +0200 Subject: [PATCH 10/34] [#2142] Set length setting as first item --- .../gui/configdialog/InnerTubeConfig.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java index 5c37c5a7e..1d3ef71b8 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java @@ -71,6 +71,19 @@ public class InnerTubeConfig extends RocketComponentConfig { //// ---------------------------- Attributes ---------------------------- + //// Length + panel.add(new JLabel(trans.get("ThicknessRingCompCfg.tab.Length"))); + m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + focusElement = spin; + panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); + + panel.add(new UnitSelector(m), "growx"); + panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); + //// Outer diameter panel.add(new JLabel(trans.get("ThicknessRingCompCfg.tab.Outerdiam"))); @@ -128,22 +141,6 @@ public class InnerTubeConfig extends RocketComponentConfig { panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap"); - - //// Inner tube length - panel.add(new JLabel(trans.get("ThicknessRingCompCfg.tab.Length"))); - - //// Length - m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0); - - spin = new JSpinner(m.getSpinnerModel()); - spin.setEditor(new SpinnerEditor(spin)); - focusElement = spin; - panel.add(spin, "growx"); - order.add(((SpinnerEditor) spin.getEditor()).getTextField()); - - panel.add(new UnitSelector(m), "growx"); - panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); - mainPanel.add(panel, "aligny 0, gapright 40lp"); //// Right side of panel ---- From 32e7d328f5a486e92597cfa083c4b5de987b847a Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 25 Feb 2023 16:40:48 +0100 Subject: [PATCH 11/34] [#2076] Support transparent rendering and exporting of PS images --- .../sf/openrocket/gui/figure3d/photo/PhotoPanel.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java index 4a8461a9e..d59f10712 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java @@ -1,7 +1,9 @@ package net.sf.openrocket.gui.figure3d.photo; +import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Component; +import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.SplashScreen; import java.awt.event.MouseEvent; @@ -169,10 +171,12 @@ public class PhotoPanel extends JPanel implements GLEventListener { Preferences.OPENGL_USE_FBO, false)) { log.trace("GL - Creating GLJPanel"); canvas = new GLJPanel(caps); + ((GLJPanel) canvas).setOpaque(false); } else { log.trace("GL - Creating GLCanvas"); canvas = new GLCanvas(caps); } + canvas.setBackground(new java.awt.Color(0, 0, 0, 0)); ((GLAutoDrawable) canvas).addGLEventListener(this); this.add(canvas, BorderLayout.CENTER); @@ -277,7 +281,7 @@ public class PhotoPanel extends JPanel implements GLEventListener { if (!imageCallbacks.isEmpty()) { BufferedImage i = (new AWTGLReadBufferUtil( - GLProfile.get(GLProfile.GL2), false)) + GLProfile.get(GLProfile.GL2), true)) // Set the second parameter to true .readPixelsToBufferedImage(drawable.getGL(), 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), true); final Vector cbs = new Vector( @@ -298,10 +302,12 @@ public class PhotoPanel extends JPanel implements GLEventListener { out[0] = 1; out[1] = 1; out[2] = 0; + out[3] = 1; } else { out[0] = (float) color.getRed() / 255f; out[1] = (float) color.getGreen() / 255f; out[2] = (float) color.getBlue() / 255f; + out[3] = (float) color.getAlpha() / 255f; } } @@ -309,7 +315,7 @@ public class PhotoPanel extends JPanel implements GLEventListener { GL2 gl = drawable.getGL().getGL2(); GLU glu = new GLU(); - float[] color = new float[3]; + float[] color = new float[4]; gl.glEnable(GL.GL_MULTISAMPLE); @@ -334,7 +340,7 @@ public class PhotoPanel extends JPanel implements GLEventListener { 0); convertColor(p.getSkyColor(), color); - gl.glClearColor(color[0], color[1], color[2], 1); + gl.glClearColor(color[0], color[1], color[2], color[3]); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); From 84225699ce3069c4787aa8eb5d85d4ed6e02dec9 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 19:46:33 +0200 Subject: [PATCH 12/34] Set length as first config property for others --- .../gui/configdialog/BulkheadConfig.java | 3 +- .../gui/configdialog/CenteringRingConfig.java | 5 +-- .../gui/configdialog/RingComponentConfig.java | 40 +++++++++---------- .../gui/configdialog/SleeveConfig.java | 4 +- .../ThicknessRingComponentConfig.java | 8 ++-- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java index d1bdb5e63..4dcead2c9 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java @@ -21,8 +21,7 @@ public class BulkheadConfig extends RingComponentConfig { JPanel tab; - tab = generalTab(trans.get("BulkheadCfg.tab.Diameter"), null, null, - trans.get("BulkheadCfg.tab.Thickness")); + tab = generalTab(trans.get("BulkheadCfg.tab.Thickness"), trans.get("BulkheadCfg.tab.Diameter"), null, null); //// General and General properties tabbedPane.insertTab(trans.get("BulkheadCfg.tab.General"), null, tab, trans.get("BulkheadCfg.tab.Generalproperties"), 0); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java index 5ac0bcc75..c1c626761 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java @@ -22,9 +22,8 @@ public class CenteringRingConfig extends RingComponentConfig { JPanel tab; //// Outer diameter: and Inner diameter: and Thickness: - tab = generalTab(trans.get("CenteringRingCfg.tab.Outerdiam"), - trans.get("CenteringRingCfg.tab.Innerdiam"), null, - trans.get("CenteringRingCfg.tab.Thickness")); + tab = generalTab(trans.get("CenteringRingCfg.tab.Thickness"), trans.get("CenteringRingCfg.tab.Outerdiam"), + trans.get("CenteringRingCfg.tab.Innerdiam"), null); //// General and General properties tabbedPane.insertTab(trans.get("CenteringRingCfg.tab.General"), null, tab, trans.get("CenteringRingCfg.tab.Generalproperties"), 0); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java index 9638663fa..242c333b6 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java @@ -29,7 +29,7 @@ public class RingComponentConfig extends RocketComponentConfig { } - protected JPanel generalTab(String outer, String inner, String thickness, String length) { + protected JPanel generalTab(String length, String outer, String inner, String thickness) { JPanel primary = new JPanel(new MigLayout()); JPanel panel = new JPanel(new MigLayout("gap rel unrel, ins 0", "[][65lp::][30lp::]", "")); @@ -39,6 +39,24 @@ public class RingComponentConfig extends RocketComponentConfig { //// Attributes ---- + //// Length + if (length != null) { + panel.add(new JLabel(length)); + + m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + if (component instanceof ThicknessRingComponent) { + focusElement = spin; + } + panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); + + panel.add(new UnitSelector(m), "growx"); + panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); + } + //// Outer diameter if (outer != null) { panel.add(new JLabel(outer)); @@ -110,26 +128,6 @@ public class RingComponentConfig extends RocketComponentConfig { panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap"); } - - - //// Inner tube length - if (length != null) { - panel.add(new JLabel(length)); - - //// Length - m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0); - - spin = new JSpinner(m.getSpinnerModel()); - spin.setEditor(new SpinnerEditor(spin)); - if (component instanceof ThicknessRingComponent) { - focusElement = spin; - } - panel.add(spin, "growx"); - order.add(((SpinnerEditor) spin.getEditor()).getTextField()); - - panel.add(new UnitSelector(m), "growx"); - panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); - } primary.add(panel, "grow, gapright 40lp"); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java index d2261dfd6..340ca58a4 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java @@ -23,8 +23,8 @@ public class SleeveConfig extends RingComponentConfig { //// Inner diameter: //// Wall thickness: //// Length: - tab = generalTab(trans.get("SleeveCfg.tab.Outerdiam"), trans.get("SleeveCfg.tab.Innerdiam"), - trans.get("SleeveCfg.tab.Wallthickness"), trans.get("SleeveCfg.tab.Length")); + tab = generalTab(trans.get("SleeveCfg.tab.Length"), trans.get("SleeveCfg.tab.Outerdiam"), + trans.get("SleeveCfg.tab.Innerdiam"), trans.get("SleeveCfg.tab.Wallthickness")); //// General and General properties tabbedPane.insertTab(trans.get("SleeveCfg.tab.General"), null, tab, trans.get("SleeveCfg.tab.Generalproperties"), 0); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java index 66ce8703e..3718ec092 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java @@ -19,14 +19,14 @@ public class ThicknessRingComponentConfig extends RingComponentConfig { super(d, c, parent); JPanel tab; - + + //// Length: //// Outer diameter: //// Inner diameter: //// Wall thickness: - //// Length: - tab = generalTab(trans.get("ThicknessRingCompCfg.tab.Outerdiam"), + tab = generalTab(trans.get("ThicknessRingCompCfg.tab.Length"), trans.get("ThicknessRingCompCfg.tab.Outerdiam"), trans.get("ThicknessRingCompCfg.tab.Innerdiam"), - trans.get("ThicknessRingCompCfg.tab.Wallthickness"), trans.get("ThicknessRingCompCfg.tab.Length")); + trans.get("ThicknessRingCompCfg.tab.Wallthickness")); //// General and General properties tabbedPane.insertTab(trans.get("ThicknessRingCompCfg.tab.General"), null, tab, trans.get("ThicknessRingCompCfg.tab.Generalprop"), 0); From 1ae30084386a57f00d2e24dd00f5ca9dc86dee5c Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 21:59:47 +0200 Subject: [PATCH 13/34] Remove unnecessary variable --- core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java index 3e9c82389..108eb5667 100644 --- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java @@ -488,7 +488,6 @@ public class OpenRocketSaver extends RocketSaver { for (int i = 0; i < types.length; i++) { data.add(branch.get(types[i])); } - List timeData = branch.get(FlightDataType.TYPE_TIME); // Build the tag StringBuilder sb = new StringBuilder(); From 0e1cd013779d5ba7e2c87cf933c979227bce6a3b Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 22:42:14 +0200 Subject: [PATCH 14/34] Fire change when modID is synced --- core/src/net/sf/openrocket/document/Simulation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/net/sf/openrocket/document/Simulation.java b/core/src/net/sf/openrocket/document/Simulation.java index 068fc91c8..23eee5016 100644 --- a/core/src/net/sf/openrocket/document/Simulation.java +++ b/core/src/net/sf/openrocket/document/Simulation.java @@ -349,6 +349,7 @@ public class Simulation implements ChangeSource, Cloneable { */ public void syncModID() { this.simulatedConfigurationID = getActiveConfiguration().getModID(); + fireChangeEvent(); } From 3eb513c78f4ad75cdfc76b766eb0e8d2798e4358 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 22:44:49 +0200 Subject: [PATCH 15/34] Implement simulation & flightdata(branch) cloning --- .../sf/openrocket/document/Simulation.java | 31 +++++++++++++++++++ .../sf/openrocket/simulation/FlightData.java | 18 ++++++++++- .../simulation/FlightDataBranch.java | 15 +++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/core/src/net/sf/openrocket/document/Simulation.java b/core/src/net/sf/openrocket/document/Simulation.java index 23eee5016..c6371b354 100644 --- a/core/src/net/sf/openrocket/document/Simulation.java +++ b/core/src/net/sf/openrocket/document/Simulation.java @@ -523,6 +523,37 @@ public class Simulation implements ChangeSource, Cloneable { mutex.unlock("copy"); } } + + public Simulation clone() { + mutex.lock("clone"); + try { + Simulation clone = (Simulation) super.clone(); + + clone.mutex = SafetyMutex.newInstance(); + clone.status = status; + clone.options = this.options.clone(); + clone.simulationExtensions = new ArrayList<>(); + for (SimulationExtension c : this.simulationExtensions) { + clone.simulationExtensions.add(c.clone()); + } + clone.listeners = new ArrayList<>(); + if (simulatedConditions != null) { + clone.simulatedConditions = simulatedConditions.clone(); + } else { + clone.simulatedConditions = null; + } + clone.simulatedConfigurationDescription = simulatedConfigurationDescription; + clone.simulatedData = simulatedData.clone(); + clone.simulatedConfigurationID = simulatedConfigurationID; + + return clone; + + } catch (CloneNotSupportedException e) { + throw new BugException("Clone not supported, BUG", e); + } finally { + mutex.unlock("clone"); + } + } /** diff --git a/core/src/net/sf/openrocket/simulation/FlightData.java b/core/src/net/sf/openrocket/simulation/FlightData.java index 27f6c1318..0bc41ae76 100644 --- a/core/src/net/sf/openrocket/simulation/FlightData.java +++ b/core/src/net/sf/openrocket/simulation/FlightData.java @@ -273,7 +273,23 @@ public class FlightData { return mutable.isMutable(); } - + public FlightData clone() { + FlightData clone = new FlightData(); + clone.warnings.addAll(warnings); + for (FlightDataBranch b : branches) { + clone.branches.add(b.clone()); + } + clone.maxAltitude = maxAltitude; + clone.maxVelocity = maxVelocity; + clone.maxAcceleration = maxAcceleration; + clone.maxMachNumber = maxMachNumber; + clone.timeToApogee = timeToApogee; + clone.flightTime = flightTime; + clone.groundHitVelocity = groundHitVelocity; + clone.launchRodVelocity = launchRodVelocity; + clone.deploymentVelocity = deploymentVelocity; + return clone; + } /** * Find the maximum acceleration before apogee. diff --git a/core/src/net/sf/openrocket/simulation/FlightDataBranch.java b/core/src/net/sf/openrocket/simulation/FlightDataBranch.java index 77bc60f56..e2547e4c4 100644 --- a/core/src/net/sf/openrocket/simulation/FlightDataBranch.java +++ b/core/src/net/sf/openrocket/simulation/FlightDataBranch.java @@ -363,5 +363,20 @@ public class FlightDataBranch implements Monitorable { public int getModID() { return modID; } + + public FlightDataBranch clone() { + FlightDataType[] types = getTypes(); + FlightDataBranch clone = new FlightDataBranch(branchName, types); + for (FlightDataType type : values.keySet()) { + clone.values.put(type, values.get(type).clone()); + } + clone.minValues.putAll(minValues); + clone.maxValues.putAll(maxValues); + clone.events.addAll(events); + clone.timeToOptimumAltitude = timeToOptimumAltitude; + clone.optimumAltitude = optimumAltitude; + clone.modID = modID; + return clone; + } } From 5aad8b972208519b8d1000cce97ee9c808c8ab7e Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 29 Mar 2023 22:45:06 +0200 Subject: [PATCH 16/34] Implement loadFrom sims --- .../sf/openrocket/document/Simulation.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/core/src/net/sf/openrocket/document/Simulation.java b/core/src/net/sf/openrocket/document/Simulation.java index c6371b354..1b261669b 100644 --- a/core/src/net/sf/openrocket/document/Simulation.java +++ b/core/src/net/sf/openrocket/document/Simulation.java @@ -268,6 +268,18 @@ public class Simulation implements ChangeSource, Cloneable { mutex.verify(); return simulationExtensions; } + + /** + * Applies the simulation extensions to the simulation. + * @param extensions the simulation extensions to apply. + */ + public void copyExtensionsFrom(List extensions) { + if (extensions == null) { + return; + } + this.simulationExtensions.clear(); + this.simulationExtensions.addAll(extensions); + } /** @@ -554,6 +566,31 @@ public class Simulation implements ChangeSource, Cloneable { mutex.unlock("clone"); } } + + /** + * Load the data from the specified simulation into this simulation. + * @param simulation the simulation to load from. + */ + public void loadFrom(Simulation simulation) { + mutex.lock("loadFrom"); + try { + this.name = simulation.name; + this.configId = simulation.configId; + this.options.copyFrom(simulation.options); + this.simulatedConfigurationDescription = simulation.simulatedConfigurationDescription; + this.simulatedConfigurationID = simulation.simulatedConfigurationID; + if (simulation.simulatedConditions == null) { + this.simulatedConditions = null; + } else { + this.simulatedConditions = simulation.simulatedConditions.clone(); + } + this.simulatedData = simulation.simulatedData; + this.status = simulation.status; + copyExtensionsFrom(simulation.getSimulationExtensions()); + } finally { + mutex.unlock("loadFrom"); + } + } /** From 3acdda83c34abe3e210dbc15efd80bcb8aae4db2 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 00:12:37 +0200 Subject: [PATCH 17/34] Clean up sim cloning & loading --- .../sf/openrocket/document/Simulation.java | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/core/src/net/sf/openrocket/document/Simulation.java b/core/src/net/sf/openrocket/document/Simulation.java index 1b261669b..07fff25af 100644 --- a/core/src/net/sf/openrocket/document/Simulation.java +++ b/core/src/net/sf/openrocket/document/Simulation.java @@ -542,24 +542,27 @@ public class Simulation implements ChangeSource, Cloneable { Simulation clone = (Simulation) super.clone(); clone.mutex = SafetyMutex.newInstance(); - clone.status = status; + clone.name = this.name; + clone.configId = this.configId; + clone.simulatedConfigurationDescription = this.simulatedConfigurationDescription; + clone.simulatedConfigurationID = this.simulatedConfigurationID; clone.options = this.options.clone(); + clone.listeners = new ArrayList<>(); + if (this.simulatedConditions != null) { + clone.simulatedConditions = this.simulatedConditions.clone(); + } else { + clone.simulatedConditions = null; + } clone.simulationExtensions = new ArrayList<>(); for (SimulationExtension c : this.simulationExtensions) { clone.simulationExtensions.add(c.clone()); } - clone.listeners = new ArrayList<>(); - if (simulatedConditions != null) { - clone.simulatedConditions = simulatedConditions.clone(); - } else { - clone.simulatedConditions = null; - } - clone.simulatedConfigurationDescription = simulatedConfigurationDescription; - clone.simulatedData = simulatedData.clone(); - clone.simulatedConfigurationID = simulatedConfigurationID; + clone.status = this.status; + clone.simulatedData = this.simulatedData != null ? this.simulatedData.clone() : this.simulatedData; + clone.simulationStepperClass = this.simulationStepperClass; + clone.aerodynamicCalculatorClass = this.aerodynamicCalculatorClass; return clone; - } catch (CloneNotSupportedException e) { throw new BugException("Clone not supported, BUG", e); } finally { @@ -576,17 +579,25 @@ public class Simulation implements ChangeSource, Cloneable { try { this.name = simulation.name; this.configId = simulation.configId; - this.options.copyFrom(simulation.options); this.simulatedConfigurationDescription = simulation.simulatedConfigurationDescription; this.simulatedConfigurationID = simulation.simulatedConfigurationID; + this.options.copyConditionsFrom(simulation.options); if (simulation.simulatedConditions == null) { this.simulatedConditions = null; } else { - this.simulatedConditions = simulation.simulatedConditions.clone(); + this.simulatedConditions.copyConditionsFrom(simulation.simulatedConditions); + } + copyExtensionsFrom(simulation.getSimulationExtensions()); + this.status = simulation.status; + // Status change, so reset the change listeners to be sure + for (EventListener listener : this.options.getChangeListeners()) { + if (listener instanceof ConditionListener) { + ((ConditionListener) listener).reset(); + } } this.simulatedData = simulation.simulatedData; - this.status = simulation.status; - copyExtensionsFrom(simulation.getSimulationExtensions()); + this.simulationStepperClass = simulation.simulationStepperClass; + this.aerodynamicCalculatorClass = simulation.aerodynamicCalculatorClass; } finally { mutex.unlock("loadFrom"); } @@ -610,7 +621,7 @@ public class Simulation implements ChangeSource, Cloneable { final Simulation newSim = new Simulation(this.document, newRocket); newSim.name = this.name; newSim.configId = this.configId; - newSim.options.copyFrom(this.options); + newSim.options.copyConditionsFrom(this.options); newSim.simulatedConfigurationDescription = this.simulatedConfigurationDescription; for (SimulationExtension c : this.simulationExtensions) { newSim.simulationExtensions.add(c.clone()); @@ -653,16 +664,20 @@ public class Simulation implements ChangeSource, Cloneable { private class ConditionListener implements StateChangeListener { - + private boolean resetState = false; private Status oldStatus = null; @Override public void stateChanged(EventObject e) { - if (getStatus() != oldStatus) { + if (resetState || getStatus() != oldStatus) { oldStatus = getStatus(); fireChangeEvent(); } } + + public void reset() { + resetState = true; + } } } From 2535c1c4689d131142054634e17866448a3dd284 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 00:39:30 +0200 Subject: [PATCH 18/34] Always let condition change fire a change event --- .../net/sf/openrocket/document/Simulation.java | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/core/src/net/sf/openrocket/document/Simulation.java b/core/src/net/sf/openrocket/document/Simulation.java index 07fff25af..2eca7fd54 100644 --- a/core/src/net/sf/openrocket/document/Simulation.java +++ b/core/src/net/sf/openrocket/document/Simulation.java @@ -589,12 +589,6 @@ public class Simulation implements ChangeSource, Cloneable { } copyExtensionsFrom(simulation.getSimulationExtensions()); this.status = simulation.status; - // Status change, so reset the change listeners to be sure - for (EventListener listener : this.options.getChangeListeners()) { - if (listener instanceof ConditionListener) { - ((ConditionListener) listener).reset(); - } - } this.simulatedData = simulation.simulatedData; this.simulationStepperClass = simulation.simulationStepperClass; this.aerodynamicCalculatorClass = simulation.aerodynamicCalculatorClass; @@ -664,19 +658,9 @@ public class Simulation implements ChangeSource, Cloneable { private class ConditionListener implements StateChangeListener { - private boolean resetState = false; - private Status oldStatus = null; - @Override public void stateChanged(EventObject e) { - if (resetState || getStatus() != oldStatus) { - oldStatus = getStatus(); - fireChangeEvent(); - } - } - - public void reset() { - resetState = true; + fireChangeEvent(); } } From a27796b7d2ea28feef1707b87abf0b5ba7eff7d3 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 00:46:58 +0200 Subject: [PATCH 19/34] Remove unused (and worse) copyFrom method --- .../simulation/SimulationOptions.java | 26 +++---------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/core/src/net/sf/openrocket/simulation/SimulationOptions.java b/core/src/net/sf/openrocket/simulation/SimulationOptions.java index 84c20313e..d4c3a5982 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationOptions.java +++ b/core/src/net/sf/openrocket/simulation/SimulationOptions.java @@ -404,28 +404,6 @@ public class SimulationOptions implements ChangeSource, Cloneable { } } - - public void copyFrom(SimulationOptions src) { - - this.launchAltitude = src.launchAltitude; - this.launchLatitude = src.launchLatitude; - this.launchLongitude = src.launchLongitude; - this.launchPressure = src.launchPressure; - this.launchRodAngle = src.launchRodAngle; - this.launchRodDirection = src.launchRodDirection; - this.launchRodLength = src.launchRodLength; - this.launchTemperature = src.launchTemperature; - this.maximumAngle = src.maximumAngle; - this.timeStep = src.timeStep; - this.windAverage = src.windAverage; - this.windTurbulence = src.windTurbulence; - this.windDirection = src.windDirection; - this.calculateExtras = src.calculateExtras; - this.randomSeed = src.randomSeed; - - fireChangeEvent(); - } - public void copyConditionsFrom(SimulationOptions src) { // Be a little smart about triggering the change event. // only do it if one of the "important" (user specified) parameters has really changed. @@ -550,6 +528,10 @@ public class SimulationOptions implements ChangeSource, Cloneable { public void removeChangeListener(StateChangeListener listener) { listeners.remove(listener); } + + public List getChangeListeners() { + return listeners; + } private final EventObject event = new EventObject(this); From f6b932c4a7947d16a7a555549c2bd9a3f91d24fb Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 00:47:40 +0200 Subject: [PATCH 20/34] [#2158] Add ok/cancel button for simulation editing --- core/resources/l10n/messages.properties | 8 ++ .../sf/openrocket/startup/Preferences.java | 17 +++ .../preferences/DesignPreferencesPanel.java | 13 ++ .../openrocket/gui/main/SimulationPanel.java | 10 +- .../gui/simulation/SimulationEditDialog.java | 118 ++++++++++++++++-- 5 files changed, 151 insertions(+), 15 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 88290ee6d..435a71a49 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -318,6 +318,8 @@ pref.dlg.checkbox.AlwaysOpenLeftmost = Always open leftmost tab when opening a c 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.checkbox.ShowDiscardConfirmation = Show confirmation dialog for discarding component changes pref.dlg.checkbox.ShowDiscardConfirmation.ttip = If checked, you will be asked if you want really want to discard component configuration configuration changes. +pref.dlg.checkbox.ShowDiscardSimulationConfirmation = Show confirmation dialog for discarding simulation changes +pref.dlg.checkbox.ShowDiscardSimulationConfirmation.ttip = If checked, you will be asked if you want really want to discard simulation configuration configuration changes. pref.dlg.lbl.User-definedthrust = User-defined thrust curves: pref.dlg.lbl.Windspeed = Wind speed pref.dlg.Allthrustcurvefiles = All thrust curve files (*.eng; *.rse; *.zip; directories) @@ -516,6 +518,12 @@ SimulationEditDialog.btn.export = Export SimulationEditDialog.btn.edit = Edit SimulationEditDialog.btn.simulate = Simulate SimulationEditDialog.btn.simulateAndPlot = Simulate & Plot +SimulationEditDialog.btn.OK.ttip = Keep changes and close the dialog +SimulationEditDialog.btn.Cancel.ttip = Discard changes and close the dialog +SimulationEditDialog.CancelOperation.msg.discardChanges = Are you sure you want to discard your changes to this simulation? +SimulationEditDialog.CancelOperation.msg.undoAdd = Are you sure you want to undo adding this simulation? +SimulationEditDialog.CancelOperation.title = Cancel operation +SimulationEditDialog.CancelOperation.checkbox.dontAskAgain = Don't ask me again GeodeticComputationStrategy.flat.name = Flat Earth GeodeticComputationStrategy.flat.desc = Perform computations with a flat Earth approximation. Sufficient for low-altitude flights. diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index eac3b3642..8b7d01d13 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -77,6 +77,7 @@ public abstract class Preferences implements ChangeSource { 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_DISCARD_CONFIRMATION = "IgnoreDiscardEditingWarning"; + private static final String SHOW_DISCARD_SIMULATION_CONFIRMATION = "IgnoreDiscardSimulationEditingWarning"; public static final String MARKER_STYLE_ICON = "MARKER_STYLE_ICON"; private static final String SHOW_MARKERS = "SHOW_MARKERS"; private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING"; @@ -537,6 +538,22 @@ public abstract class Preferences implements ChangeSource { this.putBoolean(SHOW_DISCARD_CONFIRMATION, enabled); } + /** + * Answer if a confirmation dialog should be shown when canceling a simulation config operation. + * + * @return true if the confirmation dialog should be shown. + */ + public final boolean isShowDiscardSimulationConfirmation() { + return this.getBoolean(SHOW_DISCARD_SIMULATION_CONFIRMATION, true); + } + + /** + * Enable/Disable showing a confirmation warning when canceling a simulation config operation. + */ + public final void setShowDiscardSimulationConfirmation(boolean enabled) { + this.putBoolean(SHOW_DISCARD_SIMULATION_CONFIRMATION, enabled); + } + /** * Answer if the always open leftmost tab is enabled. * 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 c91962d7c..74dcf1580 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java @@ -115,6 +115,19 @@ public class DesignPreferencesPanel extends PreferencesPanel { }); this.add(showDiscardConfirmation, "wrap, growx, spanx"); + // // Show confirmation dialog for discarding simulation configuration changes + final JCheckBox showDiscardSimulationConfirmation = new JCheckBox( + trans.get("pref.dlg.checkbox.ShowDiscardSimulationConfirmation")); + showDiscardSimulationConfirmation.setSelected(preferences.isShowDiscardSimulationConfirmation()); + showDiscardSimulationConfirmation.setToolTipText(trans.get("pref.dlg.checkbox.ShowDiscardSimulationConfirmation.ttip")); + showDiscardSimulationConfirmation.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + preferences.setShowDiscardSimulationConfirmation(e.getStateChange() == ItemEvent.SELECTED); + } + }); + this.add(showDiscardSimulationConfirmation, "wrap, growx, spanx"); + // // Update flight estimates in the design window final JCheckBox updateEstimates = new JCheckBox( trans.get("pref.dlg.checkbox.Updateestimates")); diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index b1a31377b..a22987392 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -297,7 +297,7 @@ public class SimulationPanel extends JPanel { simulationTable.addRowSelectionInterval(n, n); updatePreviousSelection(); - openDialog(false, sim); + openDialog(false, true, sim); } private void plotSimulation() { @@ -595,8 +595,8 @@ public class SimulationPanel extends JPanel { return simulationTable.getSelectionModel(); } - private void openDialog(boolean plotMode, final Simulation... sims) { - SimulationEditDialog d = new SimulationEditDialog(SwingUtilities.getWindowAncestor(this), document, sims); + private void openDialog(boolean plotMode, boolean isNewSimulation, final Simulation... sims) { + SimulationEditDialog d = new SimulationEditDialog(SwingUtilities.getWindowAncestor(this), document, isNewSimulation, sims); if (plotMode) { d.setPlotMode(); } @@ -605,6 +605,10 @@ public class SimulationPanel extends JPanel { takeTheSpotlight(); } + private void openDialog(boolean plotMode, final Simulation... sims) { + openDialog(plotMode, false, sims); + } + private void openDialog(final Simulation sim) { boolean plotMode = false; if (sim.hasSimulationData() && Simulation.isStatusUpToDate(sim.getStatus())) { diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java index 32effec96..9f54e68de 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java @@ -5,14 +5,18 @@ import java.awt.CardLayout; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; +import java.util.EventObject; import javax.swing.JButton; -import javax.swing.JComboBox; +import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTextField; @@ -33,6 +37,8 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.simulation.extension.SimulationExtension; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.startup.Preferences; +import net.sf.openrocket.util.StateChangeListener; public class SimulationEditDialog extends JDialog { @@ -41,19 +47,34 @@ public class SimulationEditDialog extends JDialog { private final Simulation[] simulationList; private final OpenRocketDocument document; private static final Translator trans = Application.getTranslator(); + private static final Preferences preferences = Application.getPreferences(); JPanel cards; private final static String EDITMODE = "EDIT"; private final static String PLOTMODE = "PLOT"; - private WindowListener applyChangesToSimsListener; + private final WindowListener applyChangesToSimsListener; + private final Simulation initialSim; + private boolean isModified = false; + private final boolean isNewSimulation; - public SimulationEditDialog(Window parent, final OpenRocketDocument document, Simulation... sims) { + public SimulationEditDialog(Window parent, final OpenRocketDocument document, boolean isNewSimulation, Simulation... sims) { //// Edit simulation super(parent, trans.get("simedtdlg.title.Editsim"), JDialog.ModalityType.DOCUMENT_MODAL); this.document = document; this.parentWindow = parent; this.simulationList = sims; + this.initialSim = simulationList[0].clone(); + this.isNewSimulation = isNewSimulation; + + simulationList[0].addChangeListener(new StateChangeListener() { + @Override + public void stateChanged(EventObject e) { + isModified = true; + setTitle("* " + getTitle()); // Add component changed indicator to the title + simulationList[0].removeChangeListener(this); + } + }); this.cards = new JPanel(new CardLayout()); this.add(cards); @@ -85,6 +106,7 @@ public class SimulationEditDialog extends JDialog { } public void setEditMode() { + setTitle((isModified ? "* " : "") + trans.get("simedtdlg.title.Editsim")); CardLayout cl = (CardLayout) (cards.getLayout()); cl.show(cards, EDITMODE); cards.validate(); @@ -96,7 +118,7 @@ public class SimulationEditDialog extends JDialog { return; } this.removeWindowListener(applyChangesToSimsListener); - setTitle(trans.get("simplotpanel.title.Plotsim")); + setTitle((isModified ? "* " : "") + trans.get("simplotpanel.title.Plotsim")); CardLayout cl = (CardLayout) (cards.getLayout()); cl.show(cards, PLOTMODE); cards.validate(); @@ -150,7 +172,6 @@ public class SimulationEditDialog extends JDialog { String name = field.getText(); if (name == null || name.equals("")) return; - //System.out.println("Setting name:" + name); simulationList[0].setName(name); } @@ -208,7 +229,7 @@ public class SimulationEditDialog extends JDialog { } }); - simEditPanel.add(button, "spanx, split 3, align left"); + simEditPanel.add(button, "spanx, split 4, align left"); if (allowsPlotMode()) { button.setVisible(true); } else { @@ -231,17 +252,49 @@ public class SimulationEditDialog extends JDialog { } } }); - simEditPanel.add(button, " align right, tag ok"); - - //// Close button - JButton close = new SelectColorButton(trans.get("dlg.but.close")); - close.addActionListener(new ActionListener() { + simEditPanel.add(button, " align right, gapright 10lp, tag ok"); + + //// Cancel button + JButton cancelButton = new SelectColorButton(trans.get("dlg.but.cancel")); + cancelButton.setToolTipText(trans.get("SimulationEditDialog.btn.Cancel.ttip")); + cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + // Don't do anything on cancel if you are editing an existing simulation, and it is not modified + if (!isNewSimulation && !isModified) { + SimulationEditDialog.this.removeWindowListener(applyChangesToSimsListener); + SimulationEditDialog.this.dispose(); + return; + } + + // Apply the cancel operation if set to auto discard in preferences + if (!preferences.isShowDiscardSimulationConfirmation()) { + discardChanges(); + return; + } + + // Yes/No dialog: Are you sure you want to discard your changes? + JPanel msg = createCancelOperationContent(); + int resultYesNo = JOptionPane.showConfirmDialog(SimulationEditDialog.this, msg, + trans.get("SimulationEditDialog.CancelOperation.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (resultYesNo == JOptionPane.YES_OPTION) { + discardChanges(); + } + } + }); + simEditPanel.add(cancelButton, "tag ok"); + + //// Ok button + JButton okButton = new SelectColorButton(trans.get("dlg.but.ok")); + okButton.setToolTipText(trans.get("SimulationEditDialog.btn.OK.ttip")); + okButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + copyChangesToAllSims(); SimulationEditDialog.this.dispose(); } }); - simEditPanel.add(close, "tag ok"); + simEditPanel.add(okButton, "tag ok"); cards.add(simEditPanel, EDITMODE); } @@ -336,4 +389,45 @@ public class SimulationEditDialog extends JDialog { } } + + private JPanel createCancelOperationContent() { + JPanel panel = new JPanel(new MigLayout()); + String msg = isNewSimulation ? trans.get("SimulationEditDialog.CancelOperation.msg.undoAdd") : + trans.get("SimulationEditDialog.CancelOperation.msg.discardChanges"); + JLabel msgLabel = new JLabel(msg); + JCheckBox dontAskAgain = new JCheckBox(trans.get("SimulationEditDialog.CancelOperation.checkbox.dontAskAgain")); + dontAskAgain.setSelected(false); + dontAskAgain.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + preferences.setShowDiscardSimulationConfirmation(false); + } + // Unselected state should be not be possible and thus not be handled + } + }); + + panel.add(msgLabel, "left, wrap"); + panel.add(dontAskAgain, "left, gaptop para"); + + return panel; + } + + private void discardChanges() { + if (isNewSimulation) { + document.removeSimulation(simulationList[0]); + } else { + undoSimulationChanges(); + } + + SimulationEditDialog.this.removeWindowListener(applyChangesToSimsListener); + SimulationEditDialog.this.dispose(); + } + + private void undoSimulationChanges() { + if (simulationList == null || simulationList.length == 0) { + return; + } + simulationList[0].loadFrom(initialSim); + } } From 24605bde584255b5cd227619b1f0a8d3da53f58c Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 01:28:26 +0200 Subject: [PATCH 21/34] Add sky color opacity slider --- core/resources/l10n/messages.properties | 1 + .../gui/figure3d/photo/PhotoSettings.java | 14 +++++++++++++- .../gui/figure3d/photo/PhotoSettingsConfig.java | 16 ++++++++++++---- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 88290ee6d..f567841a7 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -2334,6 +2334,7 @@ PhotoSettingsConfig.lbl.lightAz = Light Azimuth PhotoSettingsConfig.lbl.lightAlt = Light Altitude PhotoSettingsConfig.lbl.sky = Sky PhotoSettingsConfig.lbl.skyColor = Sky Color +PhotoSettingsConfig.lbl.skyColorOpacity = Sky Color Opacity PhotoSettingsConfig.lbl.skyImage = Sky Image PhotoSettingsConfig.lbl.skyCredit = Image Credit 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 2aecbe434..493cae0f0 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java @@ -24,6 +24,7 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings private double ambiance = .3f; private Color skyColor = new Color(55, 95, 155); + private double skyColorOpacity = 1.0; private boolean motionBlurred = false; @@ -186,9 +187,20 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings public void setSkyColor(Color skyColor) { this.skyColor = skyColor; + this.skyColorOpacity = skyColor.getAlpha() / 255f; fireChangeEvent(); } - + + public double getSkyColorOpacity() { + return skyColorOpacity; + } + + public void setSkyColorOpacity(double skyColorOpacity) { + this.skyColorOpacity = skyColorOpacity; + skyColor.setAlpha((int) (skyColorOpacity * 255)); + fireChangeEvent(); + } + public Color getFlameColor() { return flameColor; } 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 a758cc320..e78e18087 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java @@ -256,10 +256,10 @@ public class PhotoSettingsConfig extends JTabbedPane { /// Light altitude add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAlt"))); - 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"); + DoubleModel lightAltModel = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE, -Math.PI / 2, Math.PI / 2); + add(new EditableSpinner(lightAltModel.getSpinnerModel()), "growx, split 2"); + add(new UnitSelector(lightAltModel)); + add(new BasicSlider(lightAltModel.getSliderModel(-Math.PI / 2, Math.PI / 2)), "wrap"); // Sky add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.sky"), Style.BOLD), "split, span, gapright para"); @@ -269,6 +269,14 @@ public class PhotoSettingsConfig extends JTabbedPane { add(new JLabel(trans.get("PhotoSettingsConfig.lbl.skyColor"))); add(skyColorButton, "wrap"); + /// Sky color opacity + add(new JLabel(trans.get("PhotoSettingsConfig.lbl.skyColorOpacity"))); + DoubleModel skyColorOpacityModel = new DoubleModel(p, "SkyColorOpacity", UnitGroup.UNITS_RELATIVE, 0, 1); + add(new EditableSpinner(skyColorOpacityModel.getSpinnerModel()), "growx, split 2"); + add(new UnitSelector(skyColorOpacityModel)); + add(new BasicSlider(skyColorOpacityModel.getSliderModel()), "wrap"); + p.addChangeListener(skyColorOpacityModel); + /// Sky image add(new JLabel(trans.get("PhotoSettingsConfig.lbl.skyImage"))); From 0550c2995c5db6438373d13d1005ba52c91afc3f Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 01:52:20 +0200 Subject: [PATCH 22/34] Disable sky color opacity widgets when sky image selected --- .../gui/figure3d/photo/PhotoSettingsConfig.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) 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 e78e18087..e66251414 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java @@ -272,9 +272,12 @@ public class PhotoSettingsConfig extends JTabbedPane { /// Sky color opacity add(new JLabel(trans.get("PhotoSettingsConfig.lbl.skyColorOpacity"))); DoubleModel skyColorOpacityModel = new DoubleModel(p, "SkyColorOpacity", UnitGroup.UNITS_RELATIVE, 0, 1); - add(new EditableSpinner(skyColorOpacityModel.getSpinnerModel()), "growx, split 2"); - add(new UnitSelector(skyColorOpacityModel)); - add(new BasicSlider(skyColorOpacityModel.getSliderModel()), "wrap"); + EditableSpinner skyColorOpacitySpinner = new EditableSpinner(skyColorOpacityModel.getSpinnerModel()); + add(skyColorOpacitySpinner, "growx, split 2"); + UnitSelector skyColorOpacityUnitSelector = new UnitSelector(skyColorOpacityModel); + add(skyColorOpacityUnitSelector); + BasicSlider skyColorOpacitySlider = new BasicSlider(skyColorOpacityModel.getSliderModel()); + add(skyColorOpacitySlider, "wrap"); p.addChangeListener(skyColorOpacityModel); /// Sky image @@ -301,9 +304,15 @@ public class PhotoSettingsConfig extends JTabbedPane { if (s instanceof Sky && s != noSky) { p.setSky((Sky) s); skyColorButton.setEnabled(false); + skyColorOpacitySpinner.setEnabled(false); + skyColorOpacityUnitSelector.setEnabled(false); + skyColorOpacitySlider.setEnabled(false); } else if (s == noSky) { p.setSky(null); skyColorButton.setEnabled(true); + skyColorOpacitySpinner.setEnabled(true); + skyColorOpacityUnitSelector.setEnabled(true); + skyColorOpacitySlider.setEnabled(true); } } }); From 8cfc093433f23ff8902de846118a7ebe556bc376 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 04:25:05 +0200 Subject: [PATCH 23/34] Restore the save state of the document --- .../gui/simulation/SimulationEditDialog.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java index 9f54e68de..5acb6eabc 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java @@ -28,6 +28,7 @@ import javax.swing.event.DocumentListener; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; +import net.sf.openrocket.document.events.DocumentChangeEvent; import net.sf.openrocket.gui.components.ConfigurationComboBox; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.widgets.SelectColorButton; @@ -54,9 +55,10 @@ public class SimulationEditDialog extends JDialog { private final static String PLOTMODE = "PLOT"; private final WindowListener applyChangesToSimsListener; - private final Simulation initialSim; - private boolean isModified = false; - private final boolean isNewSimulation; + private final Simulation initialSim; // A copy of the first selected simulation before it was modified + private final boolean initialIsSaved; // Whether the document was saved before the dialog was opened + private boolean isModified = false; // Whether the simulation has been modified + private final boolean isNewSimulation; // Whether you are editing a new simulation, or an existing one public SimulationEditDialog(Window parent, final OpenRocketDocument document, boolean isNewSimulation, Simulation... sims) { //// Edit simulation @@ -65,6 +67,7 @@ public class SimulationEditDialog extends JDialog { this.parentWindow = parent; this.simulationList = sims; this.initialSim = simulationList[0].clone(); + this.initialIsSaved = document.isSaved(); this.isNewSimulation = isNewSimulation; simulationList[0].addChangeListener(new StateChangeListener() { @@ -419,6 +422,8 @@ public class SimulationEditDialog extends JDialog { } else { undoSimulationChanges(); } + document.setSaved(this.initialIsSaved); // Restore the saved state of the document + document.fireDocumentChangeEvent(new DocumentChangeEvent(this)); SimulationEditDialog.this.removeWindowListener(applyChangesToSimsListener); SimulationEditDialog.this.dispose(); From 26f6473446ea7765c7d2e25108491b21be2c7a34 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 11:44:00 +0200 Subject: [PATCH 24/34] Fix set launch rod length & launch into wind not triggering change event --- core/src/net/sf/openrocket/simulation/SimulationOptions.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/net/sf/openrocket/simulation/SimulationOptions.java b/core/src/net/sf/openrocket/simulation/SimulationOptions.java index d4c3a5982..19c769903 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationOptions.java +++ b/core/src/net/sf/openrocket/simulation/SimulationOptions.java @@ -96,6 +96,7 @@ public class SimulationOptions implements ChangeSource, Cloneable { if (MathUtil.equals(this.launchRodLength, launchRodLength)) return; this.launchRodLength = launchRodLength; + fireChangeEvent(); } @@ -104,7 +105,10 @@ public class SimulationOptions implements ChangeSource, Cloneable { } public void setLaunchIntoWind(boolean i) { + if (launchIntoWind == i) + return; launchIntoWind = i; + fireChangeEvent(); } public double getLaunchRodAngle() { From f5b7d464d2acd471a3520cd9292f2632f09c1e55 Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Thu, 30 Mar 2023 12:28:54 +0200 Subject: [PATCH 25/34] Update bug report template --- .github/ISSUE_TEMPLATE/bug-report.md | 31 ----------- .github/ISSUE_TEMPLATE/bug-report.yml | 75 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 31 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/bug-report.yml diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md deleted file mode 100644 index 64b583a6d..000000000 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Bug report -about: Help us make OpenRocket better -title: '[Bug] ' -labels: bug -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**ORK File** -If the problem is triggered by a particular ORK file, please zip it and attach it to this issue. - -**Platform** - - OS: [e.g. Windows10] - - OpenRocket version (e.g. 22-02) - - Graphics card (if a graphics or display-related problem) - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 000000000..09c39b9cb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,75 @@ +name: Bug report +about: Help us make OpenRocket better +title: '[Bug] ' +labels: bug +assignees: '' +body: + - type: markdown + attributes: + value: Thanks for taking the time to fill out this bug report! + - type: textarea + id: description + attributes: + label: Describe the bug + description: What happened? Also tell us what you've expect to happen. + placeholder: Describe your bug in detail. + value: | + 1. + 2. + 3. + ... + render: bash + validations: + required: true + - type: textarea + id: repro + attributes: + label: To Reproduce + description: Steps to reproduce the behavior: + value: | + 1. + 2. + 3. + ... + render: bash + validations: + required: true + - type: textarea + id: files + attributes: + label: Screenshots / .ork file + description: Provide screenshots for clarification and/or the .ork file that caused the issue. + value: | + Screenshot(s): + (drag-and-drop the screenshot(s) here) + + .ork file: + (drag-and-drop the file here as a .zip file) + validations: + required: false +- type: input + id: version-openrocket + attributes: + label: OpenRocket version + description: In what version(s) of OpenRocket does this bug happen? + placeholder: 22.02, unstable... + validations: + required: true +- type: dropdown + id: platform + attributes: + label: What platform are you running on? + options: + - Windows + - macOS + - Linux + validations: + required: true +- type: input + id: context + attributes: + label: Additional context + description: Add any other context about the problem here. + placeholder: + validations: + required: false From efb64104d26fb9eee1ab97cc9a726b48dae077e9 Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Thu, 30 Mar 2023 12:29:53 +0200 Subject: [PATCH 26/34] Update bug-report.yml --- .github/ISSUE_TEMPLATE/bug-report.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 09c39b9cb..c02f34954 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -5,8 +5,8 @@ labels: bug assignees: '' body: - type: markdown - attributes: - value: Thanks for taking the time to fill out this bug report! + attributes: + value: Thanks for taking the time to fill out this bug report! - type: textarea id: description attributes: From b30353032681bcbd9ce4cfb918c523441a5bdeb5 Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Thu, 30 Mar 2023 12:31:25 +0200 Subject: [PATCH 27/34] Update bug-report.yml --- .github/ISSUE_TEMPLATE/bug-report.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index c02f34954..9244a1b86 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -4,9 +4,9 @@ title: '[Bug] ' labels: bug assignees: '' body: - - type: markdown - attributes: - value: Thanks for taking the time to fill out this bug report! +- type: markdown + attributes: + value: "Thanks for taking the time to fill out this bug report!" - type: textarea id: description attributes: @@ -25,7 +25,7 @@ body: id: repro attributes: label: To Reproduce - description: Steps to reproduce the behavior: + description: "Steps to reproduce the behavior:" value: | 1. 2. From 24d27fa1dbedd9a2bb6b1b6a16d8cd49d3fe411f Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Thu, 30 Mar 2023 12:34:58 +0200 Subject: [PATCH 28/34] Update bug-report.yml --- .github/ISSUE_TEMPLATE/bug-report.yml | 54 +++++++++++++-------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 9244a1b86..31a1bbfde 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -7,7 +7,7 @@ body: - type: markdown attributes: value: "Thanks for taking the time to fill out this bug report!" - - type: textarea +- type: textarea id: description attributes: label: Describe the bug @@ -21,7 +21,7 @@ body: render: bash validations: required: true - - type: textarea +- type: textarea id: repro attributes: label: To Reproduce @@ -34,7 +34,7 @@ body: render: bash validations: required: true - - type: textarea +- type: textarea id: files attributes: label: Screenshots / .ork file @@ -42,34 +42,34 @@ body: value: | Screenshot(s): (drag-and-drop the screenshot(s) here) - + .ork file: (drag-and-drop the file here as a .zip file) validations: required: false - type: input - id: version-openrocket - attributes: - label: OpenRocket version - description: In what version(s) of OpenRocket does this bug happen? - placeholder: 22.02, unstable... - validations: - required: true + id: version-openrocket + attributes: + label: OpenRocket version + description: In what version(s) of OpenRocket does this bug happen? + placeholder: 22.02, unstable... + validations: + required: true - type: dropdown - id: platform - attributes: - label: What platform are you running on? - options: - - Windows - - macOS - - Linux - validations: - required: true + id: platform + attributes: + label: What platform are you running on? + options: + - Windows + - macOS + - Linux + validations: + required: true - type: input - id: context - attributes: - label: Additional context - description: Add any other context about the problem here. - placeholder: - validations: - required: false + id: context + attributes: + label: Additional context + description: Add any other context about the problem here. + placeholder: + validations: + required: false From ff86a62f523a5a502b2fb935472f76de5eda42db Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Thu, 30 Mar 2023 12:35:51 +0200 Subject: [PATCH 29/34] Update bug-report.yml --- .github/ISSUE_TEMPLATE/bug-report.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 31a1bbfde..00a5c6a82 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,8 +1,7 @@ name: Bug report -about: Help us make OpenRocket better +description: Help us make OpenRocket better title: '[Bug] ' labels: bug -assignees: '' body: - type: markdown attributes: From 2d158564c22633e82ab45f012604274b44b6c303 Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Thu, 30 Mar 2023 12:36:11 +0200 Subject: [PATCH 30/34] Update bug-report.yml --- .github/ISSUE_TEMPLATE/bug-report.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 00a5c6a82..989321896 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -12,12 +12,6 @@ body: label: Describe the bug description: What happened? Also tell us what you've expect to happen. placeholder: Describe your bug in detail. - value: | - 1. - 2. - 3. - ... - render: bash validations: required: true - type: textarea From 9ffb87d7f8e24a9288bbaaba1271f7055b497866 Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Thu, 30 Mar 2023 12:38:27 +0200 Subject: [PATCH 31/34] Update bug-report.yml --- .github/ISSUE_TEMPLATE/bug-report.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 989321896..7aa9fd2f7 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -24,7 +24,6 @@ body: 2. 3. ... - render: bash validations: required: true - type: textarea @@ -33,11 +32,14 @@ body: label: Screenshots / .ork file description: Provide screenshots for clarification and/or the .ork file that caused the issue. value: | - Screenshot(s): - (drag-and-drop the screenshot(s) here) + ## Screenshot(s): + *(drag-and-drop the screenshot(s) here)* + - .ork file: - (drag-and-drop the file here as a .zip file) + ## .ork file: + *(drag-and-drop the file here as a .zip file)* + + validations: required: false - type: input @@ -58,7 +60,7 @@ body: - Linux validations: required: true -- type: input +- type: textarea id: context attributes: label: Additional context From c74ef62900c16962ac778f7a534252da5ba3466f Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 13:27:44 +0200 Subject: [PATCH 32/34] Artificially render transparency when no off-screen rendering --- .../gui/figure3d/photo/PhotoPanel.java | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java index d59f10712..628d34bd9 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java @@ -1,9 +1,7 @@ package net.sf.openrocket.gui.figure3d.photo; -import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Component; -import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.SplashScreen; import java.awt.event.MouseEvent; @@ -158,6 +156,7 @@ public class PhotoPanel extends JPanel implements GLEventListener { final GLProfile glp = GLProfile.get(GLProfile.GL2); final GLCapabilities caps = new GLCapabilities(glp); + caps.setBackgroundOpaque(false); if (Application.getPreferences().getBoolean( Preferences.OPENGL_ENABLE_AA, true)) { @@ -311,6 +310,27 @@ public class PhotoPanel extends JPanel implements GLEventListener { } } + /** + * Blend two colors + * @param color1 first color to blend + * @param color2 second color to blend + * @param ratio blend ratio. 0 = full color 1, 0.5 = mid-blend, 1 = full color 2 + * @return blended color + */ + private static Color blendColors(Color color1, Color color2, double ratio) { + if (ratio < 0 || ratio > 1) { + throw new IllegalArgumentException("Blend ratio must be between 0 and 1"); + } + + double inverseRatio = 1 - ratio; + + int r = (int) ((color1.getRed() * inverseRatio) + (color2.getRed() * ratio)); + int g = (int) ((color1.getGreen() * inverseRatio) + (color2.getGreen() * ratio)); + int b = (int) ((color1.getBlue() * inverseRatio) + (color2.getBlue() * ratio)); + + return new Color(r, g, b); + } + private void draw(final GLAutoDrawable drawable, float dx) { GL2 gl = drawable.getGL().getGL2(); GLU glu = new GLU(); @@ -339,7 +359,15 @@ public class PhotoPanel extends JPanel implements GLEventListener { new float[] { spc * color[0], spc * color[1], spc * color[2], 1 }, 0); - convertColor(p.getSkyColor(), color); + // Machines that don't use off-screen rendering can't render transparent background, so we create it + // artificially by blending the sky color with white (= color that is rendered as transparent background) + if (!Application.getPreferences().getBoolean( + Preferences.OPENGL_USE_FBO, false)) { + convertColor(blendColors(p.getSkyColor(), new Color(255, 255, 255), 1-p.getSkyColorOpacity()), + color); + } else { + convertColor(p.getSkyColor(), color); + } gl.glClearColor(color[0], color[1], color[2], color[3]); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); From 33e3c4314c680b14abb45c8a216e0b757f4f40f0 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 30 Mar 2023 18:57:58 +0200 Subject: [PATCH 33/34] [#2159] Add multi-sim edit indicators --- core/resources/l10n/messages.properties | 2 ++ .../gui/simulation/SimulationEditDialog.java | 32 ++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 435a71a49..5ad5ba588 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -409,6 +409,8 @@ simedtdlg.but.savedefault = Save as default simedtdlg.but.add = Add simedtdlg.but.delete = Delete simedtdlg.title.Editsim = Edit simulation +simedtdlg.title.MultiSimEdit = Multi-simulation edit +simedtdlg.title.MultiSimEdit.ttip = You are editing the following simulations:
simedtdlg.lbl.Simname = Simulation name: simedtdlg.tab.Launchcond = Launch conditions simedtdlg.tab.Simopt = Simulation options diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java index 5acb6eabc..096bfc576 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java @@ -2,6 +2,7 @@ package net.sf.openrocket.gui.simulation; import java.awt.CardLayout; +import java.awt.Color; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -30,6 +31,7 @@ import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.events.DocumentChangeEvent; import net.sf.openrocket.gui.components.ConfigurationComboBox; +import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.l10n.Translator; @@ -62,7 +64,8 @@ public class SimulationEditDialog extends JDialog { public SimulationEditDialog(Window parent, final OpenRocketDocument document, boolean isNewSimulation, Simulation... sims) { //// Edit simulation - super(parent, trans.get("simedtdlg.title.Editsim"), JDialog.ModalityType.DOCUMENT_MODAL); + super(parent, sims.length == 1 ? trans.get("simedtdlg.title.Editsim") : trans.get("simedtdlg.title.MultiSimEdit"), + JDialog.ModalityType.DOCUMENT_MODAL); this.document = document; this.parentWindow = parent; this.simulationList = sims; @@ -109,7 +112,9 @@ public class SimulationEditDialog extends JDialog { } public void setEditMode() { - setTitle((isModified ? "* " : "") + trans.get("simedtdlg.title.Editsim")); + String baseTitle = simulationList.length == 1 ? + trans.get("simedtdlg.title.Editsim") : trans.get("simedtdlg.title.MultiSimEdit"); + setTitle((isModified ? "* " : "") + baseTitle); CardLayout cl = (CardLayout) (cards.getLayout()); cl.show(cards, EDITMODE); cards.validate(); @@ -147,7 +152,7 @@ public class SimulationEditDialog extends JDialog { } private void buildEditCard() { - JPanel simEditPanel = new JPanel(new MigLayout("fill")); + JPanel simEditPanel = new JPanel(new MigLayout("fill, hidemode 1")); if (isSingleEdit()) { JPanel panel = new JPanel(new MigLayout("fill, ins 0")); @@ -232,12 +237,29 @@ public class SimulationEditDialog extends JDialog { } }); - simEditPanel.add(button, "spanx, split 4, align left"); + simEditPanel.add(button, "spanx, split 5, align left"); if (allowsPlotMode()) { button.setVisible(true); } else { button.setVisible(false); } + + //// Multi-simulation edit + if (simulationList.length > 1) { + StyledLabel multiSimEditLabel = new StyledLabel("", -1, StyledLabel.Style.BOLD); + multiSimEditLabel.setFontColor(new Color(170, 0, 100)); + multiSimEditLabel.setText(trans.get("simedtdlg.title.MultiSimEdit")); + StringBuilder components = new StringBuilder(trans.get("simedtdlg.title.MultiSimEdit.ttip")); + for (int i = 0; i < simulationList.length; i++) { + if (i < simulationList.length - 1) { + components.append(simulationList[i].getName()).append(", "); + } else { + components.append(simulationList[i].getName()); + } + } + multiSimEditLabel.setToolTipText(components.toString()); + simEditPanel.add(multiSimEditLabel, "align left"); + } //// Run simulation button button = new SelectColorButton(trans.get("SimulationEditDialog.btn.simulateAndPlot")); @@ -255,7 +277,7 @@ public class SimulationEditDialog extends JDialog { } } }); - simEditPanel.add(button, " align right, gapright 10lp, tag ok"); + simEditPanel.add(button, "align right, gapright 10lp, tag ok"); //// Cancel button JButton cancelButton = new SelectColorButton(trans.get("dlg.but.cancel")); From 5791c4ad4f12a20a2d12240dc554ad0eece69e8d Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Fri, 31 Mar 2023 02:32:26 +0200 Subject: [PATCH 34/34] Update bug-report.yml --- .github/ISSUE_TEMPLATE/bug-report.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 7aa9fd2f7..d45d6bb50 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -20,9 +20,9 @@ body: label: To Reproduce description: "Steps to reproduce the behavior:" value: | - 1. - 2. - 3. + 1. + 2. + 3. ... validations: required: true @@ -32,11 +32,11 @@ body: label: Screenshots / .ork file description: Provide screenshots for clarification and/or the .ork file that caused the issue. value: | - ## Screenshot(s): + #### Screenshot(s): *(drag-and-drop the screenshot(s) here)* - ## .ork file: + #### .ork file: *(drag-and-drop the file here as a .zip file)*