diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 8c33b2c39..a3cfc5575 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -53,6 +53,10 @@ RocketPanel.FigTypeAct.Unfinished = 3D Unfinished RocketPanel.lbl.Flightcfg = Flight configuration: RocketPanel.lbl.infoMessage = Click to select    Shift+click to select other    Double-click to edit    Click+drag to move RocketPanel.lbl.ViewType = View Type: +RocketPanel.lbl.Zoom = Zoom: +RocketPanel.checkbox.ShowCGCP = Show CG/CP +RocketPanel.lbl.Stages = Stages: +RocketPanel.ttip.Rotation = Change the rocket's roll rotation (only affects the rocket view) ! BasicFrame BasicFrame.tab.Rocketdesign = Rocket design diff --git a/swing/src/net/sf/openrocket/gui/components/StageSelector.java b/swing/src/net/sf/openrocket/gui/components/StageSelector.java index bbccdf739..da1aace86 100644 --- a/swing/src/net/sf/openrocket/gui/components/StageSelector.java +++ b/swing/src/net/sf/openrocket/gui/components/StageSelector.java @@ -28,7 +28,7 @@ public class StageSelector extends JPanel implements StateChangeListener { private List buttons = new ArrayList(); public StageSelector(Rocket _rkt) { - super(new MigLayout("gap 0!")); + super(new MigLayout("gap 0!, insets 0")); this.rocket = _rkt; updateButtons( this.rocket.getSelectedConfiguration() ); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java index 0a73dd8dd..1001258f1 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java @@ -295,7 +295,7 @@ public class FreeformFinSetConfig extends FinSetConfig { panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlClick"), -2), "spanx 3, wrap"); // row of controls at the bottom of the tab: - panel.add(selector, "aligny bottom, gap unrel"); + panel.add(selector.getAsPanel(), "aligny bottom, gap unrel"); panel.add(scaleButton, ""); panel.add(importButton, ""); panel.add(exportCsvButton, ""); diff --git a/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java b/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java index c2557f914..76c29cc4a 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java @@ -83,6 +83,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener { private Overlay extrasOverlay, caretOverlay; private BufferedImage cgCaretRaster, cpCaretRaster; private volatile boolean redrawExtras = true; + private boolean drawCarets = true; private final ArrayList relativeExtra = new ArrayList(); private final ArrayList absoluteExtra = new ArrayList(); @@ -324,7 +325,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener { rr.render(drawable, configuration, selection); drawExtras(gl, glu); - drawCarets(gl, glu); + if (drawCarets) { + drawCarets(gl, glu); + } // GLJPanel with GLSL Flipper relies on this: gl.glFrontFace(GL.GL_CCW); @@ -709,5 +712,12 @@ public class RocketFigure3d extends JPanel implements GLEventListener { }); } } - + + public boolean isDrawCarets() { + return drawCarets; + } + + public void setDrawCarets(boolean drawCarets) { + this.drawCarets = drawCarets; + } } diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index 5275d8ad0..b5a530268 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -72,6 +72,8 @@ public class RocketFigure extends AbstractScaleFigure { private double rotation; private Transformation axialRotation; + + private boolean drawCarets = true; /** * The shapes to be drawn are stored in this Priority Queue, where the first shape to be drawn is the one with @@ -320,9 +322,12 @@ public class RocketFigure extends AbstractScaleFigure { // Draw relative extras - for (FigureElement e : relativeExtra) { - e.paint(g2, scale); + if (drawCarets) { + for (FigureElement e : relativeExtra) { + e.paint(g2, scale); + } } + // Draw absolute extras g2.setTransform(baseTransform); @@ -487,4 +492,12 @@ public class RocketFigure extends AbstractScaleFigure { } } + public boolean isDrawCarets() { + return drawCarets; + } + + public void setDrawCarets(boolean drawCarets) { + this.drawCarets = drawCarets; + } + } diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 551944835..0243b28f2 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -5,6 +5,8 @@ import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.util.ArrayList; @@ -31,6 +33,7 @@ import net.sf.openrocket.aerodynamics.AerodynamicCalculator; import net.sf.openrocket.aerodynamics.BarrowmanCalculator; import net.sf.openrocket.aerodynamics.FlightConditions; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.arch.SystemInfo; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.events.SimulationChangeEvent; @@ -298,6 +301,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change setPreferredSize(new Dimension(800, 300)); + JPanel ribbon = new JPanel(new MigLayout("insets 0, fill")); + // View Type drop-down ComboBoxModel cm = new DefaultComboBoxModel(VIEW_TYPE.values()) { @@ -315,38 +320,73 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change } } }; - add(new JLabel(trans.get("RocketPanel.lbl.ViewType")), "spanx, split"); - add(new JComboBox(cm)); + ribbon.add(new JLabel(trans.get("RocketPanel.lbl.ViewType")), "cell 0 0"); + ribbon.add(new JComboBox(cm), "cell 0 1"); // Zoom level selector scaleSelector = new ScaleSelector(scrollPane); - add(scaleSelector); + JButton zoomOutButton = scaleSelector.getZoomOutButton(); + JComboBox scaleSelectorCombo = scaleSelector.getScaleSelectorCombo(); + JButton zoomInButton = scaleSelector.getZoomInButton(); + ribbon.add(zoomOutButton, "gapleft para, cell 1 1"); + ribbon.add(new JLabel(trans.get("RocketPanel.lbl.Zoom")), "cell 2 0, spanx 2"); + ribbon.add(scaleSelectorCombo, "cell 2 1"); + ribbon.add(zoomInButton, "cell 3 1"); + + // Show CG/CP + JCheckBox showCGCP = new JCheckBox(); + showCGCP.setText(trans.get("RocketPanel.checkbox.ShowCGCP")); + showCGCP.setSelected(true); + ribbon.add(showCGCP, "cell 4 1, gapleft para"); + + showCGCP.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (figure != null) { + figure.setDrawCarets(showCGCP.isSelected()); + } + if (figure3d != null) { + figure3d.setDrawCarets(showCGCP.isSelected()); + } + updateFigures(); + } + }); + + // Vertical separator + JSeparator sep = new JSeparator(SwingConstants.VERTICAL); + Dimension d_sep = sep.getPreferredSize(); + d_sep.height = (int) (0.7 * ribbon.getPreferredSize().height); + sep.setPreferredSize(d_sep); + ribbon.add(sep, "cell 5 0, spany 2, gapleft para, gapright para"); // Stage selector StageSelector stageSelector = new StageSelector( rkt ); rkt.addChangeListener(stageSelector); - add(stageSelector); + ribbon.add(new JLabel(trans.get("RocketPanel.lbl.Stages")), "cell 6 0, pushx"); + ribbon.add(stageSelector, "cell 6 1, pushx"); // Flight configuration selector //// Flight configuration: JLabel label = new JLabel(trans.get("RocketPanel.lbl.Flightcfg")); - label.setHorizontalAlignment(JLabel.RIGHT); - add(label, "growx, right"); + ribbon.add(label, "cell 7 0"); final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt); - add(configComboBox, "wrap, width 16%, wmin 100"); + ribbon.add(configComboBox, "cell 7 1, width 16%, wmin 100"); + + add(ribbon, "growx, span, wrap"); // Create slider and scroll pane rotationModel = new DoubleModel(figure, "Rotation", UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI); UnitSelector us = new UnitSelector(rotationModel, true); us.setHorizontalAlignment(JLabel.CENTER); add(us, "alignx 50%, growx"); + us.setToolTipText(trans.get("RocketPanel.ttip.Rotation")); // Add the rocket figure add(figureHolder, "grow, spany 2, wmin 300lp, hmin 100lp, wrap"); // Add rotation slider - // Minimum size to fit "360deg" + // Dummy label to find the minimum size to fit "360deg" JLabel l = new JLabel("360" + Chars.DEGREE); Dimension d = l.getPreferredSize(); @@ -358,6 +398,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change updateExtras(); } }); + rotationSlider.setToolTipText(trans.get("RocketPanel.ttip.Rotation")); + //// Click to select    Shift+click to select other    Double-click to edit    Click+drag to move infoMessage = new JLabel(trans.get("RocketPanel.lbl.infoMessage")); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java index c2b0eb06f..e2284803e 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java @@ -17,7 +17,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.util.StateChangeListener; @SuppressWarnings("serial") -public class ScaleSelector extends JPanel { +public class ScaleSelector { public static final double MINIMUM_ZOOM = 0.01; // == 1 % public static final double MAXIMUM_ZOOM = 1000.00; // == 10,000 % @@ -36,16 +36,16 @@ public class ScaleSelector extends JPanel { } private final ScaleScrollPane scrollPane; - private JComboBox scaleSelector; + private final JComboBox scaleSelectorCombo; + private final JButton zoomOutButton; + private final JButton zoomInButton; public ScaleSelector(ScaleScrollPane scroll) { - super(new MigLayout()); - this.scrollPane = scroll; // Zoom out button - JButton button = new SelectColorButton(Icons.ZOOM_OUT); - button.addActionListener(new ActionListener() { + zoomOutButton = new SelectColorButton(Icons.ZOOM_OUT); + zoomOutButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final double oldScale = scrollPane.getUserScale(); @@ -54,19 +54,17 @@ public class ScaleSelector extends JPanel { setZoomText(); } }); - add(button, "gap"); // Zoom level selector - String[] settings = SCALE_LABELS; - - scaleSelector = new JComboBox<>(settings); - scaleSelector.setEditable(true); + scaleSelectorCombo = new JComboBox<>(SCALE_LABELS); + scaleSelectorCombo.setEditable(true); setZoomText(); - scaleSelector.addActionListener(new ActionListener() { + scaleSelectorCombo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { - String text = (String) scaleSelector.getSelectedItem(); + String text = (String) scaleSelectorCombo.getSelectedItem(); + if (text == null) return; text = text.replaceAll("%", "").trim(); if (text.toLowerCase(Locale.getDefault()).startsWith(SCALE_FIT.toLowerCase(Locale.getDefault()))){ @@ -94,11 +92,10 @@ public class ScaleSelector extends JPanel { update(); } }); - add(scaleSelector, "gap rel"); // Zoom in button - button = new SelectColorButton(Icons.ZOOM_IN); - button.addActionListener(new ActionListener() { + zoomInButton = new SelectColorButton(Icons.ZOOM_IN); + zoomInButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { double scale = scrollPane.getUserScale(); @@ -107,8 +104,27 @@ public class ScaleSelector extends JPanel { update(); } }); - add(button, "gapleft rel"); + } + public JPanel getAsPanel() { + JPanel panel = new JPanel(new MigLayout("insets 0")); + panel.add(zoomOutButton); + panel.add(scaleSelectorCombo); + panel.add(zoomInButton); + + return panel; + } + + public JComboBox getScaleSelectorCombo() { + return scaleSelectorCombo; + } + + public JButton getZoomOutButton() { + return zoomOutButton; + } + + public JButton getZoomInButton() { + return zoomInButton; } private void setZoomText() { @@ -117,8 +133,8 @@ public class ScaleSelector extends JPanel { if (scrollPane.isFitting()) { text = "Fit (" + text + ")"; } - if (!text.equals(scaleSelector.getSelectedItem())) - scaleSelector.setSelectedItem(text); + if (!text.equals(scaleSelectorCombo.getSelectedItem())) + scaleSelectorCombo.setSelectedItem(text); } private static double getNextLargerScale(final double currentScale) { @@ -144,18 +160,15 @@ public class ScaleSelector extends JPanel { } if (currentScale > SCALE_LEVELS[SCALE_LEVELS.length / 2]) { // scale is large, give next full 100% - double nextScale = Math.floor(currentScale + 1.05); - return nextScale; + return Math.floor(currentScale + 1.05); } return currentScale * 1.5; } - @Override public void setEnabled(boolean b){ - for ( Component c : getComponents() ){ - c.setEnabled(b); - } - super.setEnabled(b); + zoomInButton.setEnabled(b); + scaleSelectorCombo.setEnabled(b); + zoomOutButton.setEnabled(b); } public void update(){