Merge pull request #1381 from SiboVG/issue-898

[fixes #898 & #1168] Improve rocket view ribbon for smaller windows + add CG/CP show/hide checkbox
This commit is contained in:
Joe Pfeiffer 2022-05-30 19:03:35 -06:00 committed by GitHub
commit 2350722daf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 40 deletions

View File

@ -53,6 +53,10 @@ RocketPanel.FigTypeAct.Unfinished = 3D Unfinished
RocketPanel.lbl.Flightcfg = Flight configuration: RocketPanel.lbl.Flightcfg = Flight configuration:
RocketPanel.lbl.infoMessage = <html>Click to select &nbsp;&nbsp; Shift+click to select other &nbsp;&nbsp; Double-click to edit &nbsp;&nbsp; Click+drag to move RocketPanel.lbl.infoMessage = <html>Click to select &nbsp;&nbsp; Shift+click to select other &nbsp;&nbsp; Double-click to edit &nbsp;&nbsp; Click+drag to move
RocketPanel.lbl.ViewType = View Type: 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
BasicFrame.tab.Rocketdesign = Rocket design BasicFrame.tab.Rocketdesign = Rocket design

View File

@ -28,7 +28,7 @@ public class StageSelector extends JPanel implements StateChangeListener {
private List<JToggleButton> buttons = new ArrayList<JToggleButton>(); private List<JToggleButton> buttons = new ArrayList<JToggleButton>();
public StageSelector(Rocket _rkt) { public StageSelector(Rocket _rkt) {
super(new MigLayout("gap 0!")); super(new MigLayout("gap 0!, insets 0"));
this.rocket = _rkt; this.rocket = _rkt;
updateButtons( this.rocket.getSelectedConfiguration() ); updateButtons( this.rocket.getSelectedConfiguration() );

View File

@ -295,7 +295,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlClick"), -2), "spanx 3, wrap"); panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlClick"), -2), "spanx 3, wrap");
// row of controls at the bottom of the tab: // 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(scaleButton, "");
panel.add(importButton, ""); panel.add(importButton, "");
panel.add(exportCsvButton, ""); panel.add(exportCsvButton, "");

View File

@ -83,6 +83,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
private Overlay extrasOverlay, caretOverlay; private Overlay extrasOverlay, caretOverlay;
private BufferedImage cgCaretRaster, cpCaretRaster; private BufferedImage cgCaretRaster, cpCaretRaster;
private volatile boolean redrawExtras = true; private volatile boolean redrawExtras = true;
private boolean drawCarets = true;
private final ArrayList<FigureElement> relativeExtra = new ArrayList<FigureElement>(); private final ArrayList<FigureElement> relativeExtra = new ArrayList<FigureElement>();
private final ArrayList<FigureElement> absoluteExtra = new ArrayList<FigureElement>(); private final ArrayList<FigureElement> absoluteExtra = new ArrayList<FigureElement>();
@ -324,7 +325,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
rr.render(drawable, configuration, selection); rr.render(drawable, configuration, selection);
drawExtras(gl, glu); drawExtras(gl, glu);
if (drawCarets) {
drawCarets(gl, glu); drawCarets(gl, glu);
}
// GLJPanel with GLSL Flipper relies on this: // GLJPanel with GLSL Flipper relies on this:
gl.glFrontFace(GL.GL_CCW); gl.glFrontFace(GL.GL_CCW);
@ -710,4 +713,11 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
} }
} }
public boolean isDrawCarets() {
return drawCarets;
}
public void setDrawCarets(boolean drawCarets) {
this.drawCarets = drawCarets;
}
} }

View File

@ -73,6 +73,8 @@ public class RocketFigure extends AbstractScaleFigure {
private double rotation; private double rotation;
private Transformation axialRotation; 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 * The shapes to be drawn are stored in this Priority Queue, where the first shape to be drawn is the one with
* the highest priority, namely being the one where the corresponding RocketComponent has the highest displayOrder * the highest priority, namely being the one where the corresponding RocketComponent has the highest displayOrder
@ -320,9 +322,12 @@ public class RocketFigure extends AbstractScaleFigure {
// Draw relative extras // Draw relative extras
if (drawCarets) {
for (FigureElement e : relativeExtra) { for (FigureElement e : relativeExtra) {
e.paint(g2, scale); e.paint(g2, scale);
} }
}
// Draw absolute extras // Draw absolute extras
g2.setTransform(baseTransform); 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;
}
} }

View File

@ -5,6 +5,8 @@ import java.awt.BorderLayout;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Point; import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList; 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.BarrowmanCalculator;
import net.sf.openrocket.aerodynamics.FlightConditions; import net.sf.openrocket.aerodynamics.FlightConditions;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.arch.SystemInfo;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.document.events.SimulationChangeEvent; import net.sf.openrocket.document.events.SimulationChangeEvent;
@ -298,6 +301,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
setPreferredSize(new Dimension(800, 300)); setPreferredSize(new Dimension(800, 300));
JPanel ribbon = new JPanel(new MigLayout("insets 0, fill"));
// View Type drop-down // View Type drop-down
ComboBoxModel<VIEW_TYPE> cm = new DefaultComboBoxModel<VIEW_TYPE>(VIEW_TYPE.values()) { ComboBoxModel<VIEW_TYPE> cm = new DefaultComboBoxModel<VIEW_TYPE>(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"); ribbon.add(new JLabel(trans.get("RocketPanel.lbl.ViewType")), "cell 0 0");
add(new JComboBox<VIEW_TYPE>(cm)); ribbon.add(new JComboBox<VIEW_TYPE>(cm), "cell 0 1");
// Zoom level selector // Zoom level selector
scaleSelector = new ScaleSelector(scrollPane); scaleSelector = new ScaleSelector(scrollPane);
add(scaleSelector); JButton zoomOutButton = scaleSelector.getZoomOutButton();
JComboBox<String> 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 // Stage selector
StageSelector stageSelector = new StageSelector( rkt ); StageSelector stageSelector = new StageSelector( rkt );
rkt.addChangeListener(stageSelector); 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 selector
//// Flight configuration: //// Flight configuration:
JLabel label = new JLabel(trans.get("RocketPanel.lbl.Flightcfg")); JLabel label = new JLabel(trans.get("RocketPanel.lbl.Flightcfg"));
label.setHorizontalAlignment(JLabel.RIGHT); ribbon.add(label, "cell 7 0");
add(label, "growx, right");
final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt); 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 // Create slider and scroll pane
rotationModel = new DoubleModel(figure, "Rotation", UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI); rotationModel = new DoubleModel(figure, "Rotation", UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI);
UnitSelector us = new UnitSelector(rotationModel, true); UnitSelector us = new UnitSelector(rotationModel, true);
us.setHorizontalAlignment(JLabel.CENTER); us.setHorizontalAlignment(JLabel.CENTER);
add(us, "alignx 50%, growx"); add(us, "alignx 50%, growx");
us.setToolTipText(trans.get("RocketPanel.ttip.Rotation"));
// Add the rocket figure // Add the rocket figure
add(figureHolder, "grow, spany 2, wmin 300lp, hmin 100lp, wrap"); add(figureHolder, "grow, spany 2, wmin 300lp, hmin 100lp, wrap");
// Add rotation slider // 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); JLabel l = new JLabel("360" + Chars.DEGREE);
Dimension d = l.getPreferredSize(); Dimension d = l.getPreferredSize();
@ -358,6 +398,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
updateExtras(); updateExtras();
} }
}); });
rotationSlider.setToolTipText(trans.get("RocketPanel.ttip.Rotation"));
//// <html>Click to select &nbsp;&nbsp; Shift+click to select other &nbsp;&nbsp; Double-click to edit &nbsp;&nbsp; Click+drag to move //// <html>Click to select &nbsp;&nbsp; Shift+click to select other &nbsp;&nbsp; Double-click to edit &nbsp;&nbsp; Click+drag to move
infoMessage = new JLabel(trans.get("RocketPanel.lbl.infoMessage")); infoMessage = new JLabel(trans.get("RocketPanel.lbl.infoMessage"));

View File

@ -17,7 +17,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.StateChangeListener;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class ScaleSelector extends JPanel { public class ScaleSelector {
public static final double MINIMUM_ZOOM = 0.01; // == 1 % public static final double MINIMUM_ZOOM = 0.01; // == 1 %
public static final double MAXIMUM_ZOOM = 1000.00; // == 10,000 % public static final double MAXIMUM_ZOOM = 1000.00; // == 10,000 %
@ -36,16 +36,16 @@ public class ScaleSelector extends JPanel {
} }
private final ScaleScrollPane scrollPane; private final ScaleScrollPane scrollPane;
private JComboBox<String> scaleSelector; private final JComboBox<String> scaleSelectorCombo;
private final JButton zoomOutButton;
private final JButton zoomInButton;
public ScaleSelector(ScaleScrollPane scroll) { public ScaleSelector(ScaleScrollPane scroll) {
super(new MigLayout());
this.scrollPane = scroll; this.scrollPane = scroll;
// Zoom out button // Zoom out button
JButton button = new SelectColorButton(Icons.ZOOM_OUT); zoomOutButton = new SelectColorButton(Icons.ZOOM_OUT);
button.addActionListener(new ActionListener() { zoomOutButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
final double oldScale = scrollPane.getUserScale(); final double oldScale = scrollPane.getUserScale();
@ -54,19 +54,17 @@ public class ScaleSelector extends JPanel {
setZoomText(); setZoomText();
} }
}); });
add(button, "gap");
// Zoom level selector // Zoom level selector
String[] settings = SCALE_LABELS; scaleSelectorCombo = new JComboBox<>(SCALE_LABELS);
scaleSelectorCombo.setEditable(true);
scaleSelector = new JComboBox<>(settings);
scaleSelector.setEditable(true);
setZoomText(); setZoomText();
scaleSelector.addActionListener(new ActionListener() { scaleSelectorCombo.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
String text = (String) scaleSelector.getSelectedItem(); String text = (String) scaleSelectorCombo.getSelectedItem();
if (text == null) return;
text = text.replaceAll("%", "").trim(); text = text.replaceAll("%", "").trim();
if (text.toLowerCase(Locale.getDefault()).startsWith(SCALE_FIT.toLowerCase(Locale.getDefault()))){ if (text.toLowerCase(Locale.getDefault()).startsWith(SCALE_FIT.toLowerCase(Locale.getDefault()))){
@ -94,11 +92,10 @@ public class ScaleSelector extends JPanel {
update(); update();
} }
}); });
add(scaleSelector, "gap rel");
// Zoom in button // Zoom in button
button = new SelectColorButton(Icons.ZOOM_IN); zoomInButton = new SelectColorButton(Icons.ZOOM_IN);
button.addActionListener(new ActionListener() { zoomInButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
double scale = scrollPane.getUserScale(); double scale = scrollPane.getUserScale();
@ -107,8 +104,27 @@ public class ScaleSelector extends JPanel {
update(); 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<String> getScaleSelectorCombo() {
return scaleSelectorCombo;
}
public JButton getZoomOutButton() {
return zoomOutButton;
}
public JButton getZoomInButton() {
return zoomInButton;
} }
private void setZoomText() { private void setZoomText() {
@ -117,8 +133,8 @@ public class ScaleSelector extends JPanel {
if (scrollPane.isFitting()) { if (scrollPane.isFitting()) {
text = "Fit (" + text + ")"; text = "Fit (" + text + ")";
} }
if (!text.equals(scaleSelector.getSelectedItem())) if (!text.equals(scaleSelectorCombo.getSelectedItem()))
scaleSelector.setSelectedItem(text); scaleSelectorCombo.setSelectedItem(text);
} }
private static double getNextLargerScale(final double currentScale) { private static double getNextLargerScale(final double currentScale) {
@ -144,18 +160,15 @@ public class ScaleSelector extends JPanel {
} }
if (currentScale > SCALE_LEVELS[SCALE_LEVELS.length / 2]) { if (currentScale > SCALE_LEVELS[SCALE_LEVELS.length / 2]) {
// scale is large, give next full 100% // scale is large, give next full 100%
double nextScale = Math.floor(currentScale + 1.05); return Math.floor(currentScale + 1.05);
return nextScale;
} }
return currentScale * 1.5; return currentScale * 1.5;
} }
@Override
public void setEnabled(boolean b){ public void setEnabled(boolean b){
for ( Component c : getComponents() ){ zoomInButton.setEnabled(b);
c.setEnabled(b); scaleSelectorCombo.setEnabled(b);
} zoomOutButton.setEnabled(b);
super.setEnabled(b);
} }
public void update(){ public void update(){