Merge pull request #1916 from hcraigmiller/Change-side-view-to-top-view
[#1893] Add top view option to 2D display
This commit is contained in:
commit
5b73925634
@ -50,6 +50,7 @@ RocketActions.MoveDownAct.ttip.Movedown = Move this component downwards.
|
|||||||
|
|
||||||
! RocketPanel
|
! RocketPanel
|
||||||
RocketPanel.FigTypeAct.SideView = Side view
|
RocketPanel.FigTypeAct.SideView = Side view
|
||||||
|
RocketPanel.FigTypeAct.TopView = Top view
|
||||||
RocketPanel.FigTypeAct.BackView = Back view
|
RocketPanel.FigTypeAct.BackView = Back view
|
||||||
RocketPanel.FigTypeAct.Figure3D = 3D Figure
|
RocketPanel.FigTypeAct.Figure3D = 3D Figure
|
||||||
RocketPanel.FigTypeAct.Finished = 3D Finished
|
RocketPanel.FigTypeAct.Finished = 3D Finished
|
||||||
|
@ -66,7 +66,7 @@ public class FlightEventsTest extends BaseTestCase {
|
|||||||
// Test that the event times are correct
|
// Test that the event times are correct
|
||||||
for (int i = 0; i < expectedEventTimes.length; i++) {
|
for (int i = 0; i < expectedEventTimes.length; i++) {
|
||||||
assertEquals(" Flight type " + expectedEventTypes[i] + " has wrong time",
|
assertEquals(" Flight type " + expectedEventTypes[i] + " has wrong time",
|
||||||
expectedEventTimes[i], eventList.get(i).getTime(), 0.001);
|
expectedEventTimes[i], eventList.get(i).getTime(), 0.002);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ public class FlightEventsTest extends BaseTestCase {
|
|||||||
// Test that the event times are correct
|
// Test that the event times are correct
|
||||||
for (int i = 0; i < expectedEventTimes.length; i++) {
|
for (int i = 0; i < expectedEventTimes.length; i++) {
|
||||||
assertEquals(" Flight type " + expectedEventTypes[i] + " has wrong time",
|
assertEquals(" Flight type " + expectedEventTypes[i] + " has wrong time",
|
||||||
expectedEventTimes[i], eventList.get(i).getTime(), 0.001);
|
expectedEventTimes[i], eventList.get(i).getTime(), 0.002);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the event sources are correct
|
// Test that the event sources are correct
|
||||||
|
@ -31,7 +31,7 @@ public class VariableTableModel extends AbstractTableModel {
|
|||||||
|
|
||||||
//Collections.addAll(types, FlightDataType.ALL_TYPES);
|
//Collections.addAll(types, FlightDataType.ALL_TYPES);
|
||||||
//for (CustomExpression expression : doc.getCustomExpressions()){
|
//for (CustomExpression expression : doc.getCustomExpressions()){
|
||||||
// types.add(expression.getType());
|
// types.add(expression.getCurrentViewType());
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +58,10 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
|
|
||||||
private static final String ROCKET_FIGURE_PACKAGE = "net.sf.openrocket.gui.rocketfigure";
|
private static final String ROCKET_FIGURE_PACKAGE = "net.sf.openrocket.gui.rocketfigure";
|
||||||
private static final String ROCKET_FIGURE_SUFFIX = "Shapes";
|
private static final String ROCKET_FIGURE_SUFFIX = "Shapes";
|
||||||
|
|
||||||
public static final int VIEW_SIDE=0;
|
public static final int VIEW_TOP = 0;
|
||||||
public static final int VIEW_BACK=1;
|
public static final int VIEW_SIDE = 1;
|
||||||
|
public static final int VIEW_BACK = 2;
|
||||||
|
|
||||||
// Width for drawing normal and selected components
|
// Width for drawing normal and selected components
|
||||||
public static final double NORMAL_WIDTH = 1.0;
|
public static final double NORMAL_WIDTH = 1.0;
|
||||||
@ -130,10 +131,6 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transformation getRotateTransformation() {
|
|
||||||
return axialRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRotation(double rot) {
|
public void setRotation(double rot) {
|
||||||
if (MathUtil.equals(rotation, rot))
|
if (MathUtil.equals(rotation, rot))
|
||||||
return;
|
return;
|
||||||
@ -142,14 +139,22 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
updateFigure();
|
updateFigure();
|
||||||
fireChangeEvent();
|
fireChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Transformation getFigureRotation() {
|
||||||
|
if (currentViewType == RocketPanel.VIEW_TYPE.TopView) {
|
||||||
|
return this.axialRotation.applyTransformation(Transformation.rotate_x(-Math.PI / 2));
|
||||||
|
} else {
|
||||||
|
return this.axialRotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public RocketPanel.VIEW_TYPE getType() {
|
public RocketPanel.VIEW_TYPE getCurrentViewType() {
|
||||||
return currentViewType;
|
return currentViewType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(final RocketPanel.VIEW_TYPE type) {
|
public void setType(final RocketPanel.VIEW_TYPE type) {
|
||||||
if (type != RocketPanel.VIEW_TYPE.BackView && type != RocketPanel.VIEW_TYPE.SideView) {
|
if (type != RocketPanel.VIEW_TYPE.BackView && type != RocketPanel.VIEW_TYPE.SideView && type != RocketPanel.VIEW_TYPE.TopView) {
|
||||||
throw new IllegalArgumentException("Illegal type: " + type);
|
throw new IllegalArgumentException("Illegal type: " + type);
|
||||||
}
|
}
|
||||||
if (this.currentViewType == type)
|
if (this.currentViewType == type)
|
||||||
@ -201,7 +206,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
AffineTransform baseTransform = g2.getTransform();
|
AffineTransform baseTransform = g2.getTransform();
|
||||||
|
|
||||||
PriorityQueue<RocketComponentShape> figureShapes;
|
PriorityQueue<RocketComponentShape> figureShapes;
|
||||||
if (currentViewType == RocketPanel.VIEW_TYPE.SideView)
|
if (currentViewType == RocketPanel.VIEW_TYPE.SideView || currentViewType == RocketPanel.VIEW_TYPE.TopView)
|
||||||
figureShapes = figureShapes_side;
|
figureShapes = figureShapes_side;
|
||||||
else if (currentViewType == RocketPanel.VIEW_TYPE.BackView)
|
else if (currentViewType == RocketPanel.VIEW_TYPE.BackView)
|
||||||
figureShapes = figureShapes_back;
|
figureShapes = figureShapes_back;
|
||||||
@ -300,11 +305,11 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
// System.err.println(String.format(" mount instance: %s => %s", curMountLocation.toString(), curMotorLocation.toString() ));
|
// System.err.println(String.format(" mount instance: %s => %s", curMountLocation.toString(), curMotorLocation.toString() ));
|
||||||
|
|
||||||
// rotate by figure's axial rotation:
|
// rotate by figure's axial rotation:
|
||||||
curMotorLocation = this.axialRotation.transform(curMotorLocation);
|
curMotorLocation = getFigureRotation().transform(curMotorLocation);
|
||||||
|
|
||||||
{
|
{
|
||||||
Shape s;
|
Shape s;
|
||||||
if (currentViewType == RocketPanel.VIEW_TYPE.SideView) {
|
if (currentViewType == RocketPanel.VIEW_TYPE.SideView || currentViewType == RocketPanel.VIEW_TYPE.TopView) {
|
||||||
s = new Rectangle2D.Double(curMotorLocation.x,
|
s = new Rectangle2D.Double(curMotorLocation.x,
|
||||||
(curMotorLocation.y - motorRadius),
|
(curMotorLocation.y - motorRadius),
|
||||||
motorLength,
|
motorLength,
|
||||||
@ -354,7 +359,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
LinkedHashSet<RocketComponent> l = new LinkedHashSet<RocketComponent>();
|
LinkedHashSet<RocketComponent> l = new LinkedHashSet<RocketComponent>();
|
||||||
|
|
||||||
PriorityQueue<RocketComponentShape> figureShapes;
|
PriorityQueue<RocketComponentShape> figureShapes;
|
||||||
if (currentViewType == RocketPanel.VIEW_TYPE.SideView)
|
if (currentViewType == RocketPanel.VIEW_TYPE.SideView || currentViewType == RocketPanel.VIEW_TYPE.TopView)
|
||||||
figureShapes = figureShapes_side;
|
figureShapes = figureShapes_side;
|
||||||
else if (currentViewType == RocketPanel.VIEW_TYPE.BackView)
|
else if (currentViewType == RocketPanel.VIEW_TYPE.BackView)
|
||||||
figureShapes = figureShapes_back;
|
figureShapes = figureShapes_back;
|
||||||
@ -399,7 +404,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||||
|
|
||||||
for (InstanceContext context : contextList) {
|
for (InstanceContext context : contextList) {
|
||||||
final Transformation currentTransform = this.axialRotation.applyTransformation(context.transform);
|
final Transformation currentTransform = getFigureRotation().applyTransformation(context.transform);
|
||||||
allShapes = addThisShape(allShapes, this.currentViewType, comp, currentTransform);
|
allShapes = addThisShape(allShapes, this.currentViewType, comp, currentTransform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -432,9 +437,10 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
// Find the appropriate method
|
// Find the appropriate method
|
||||||
switch (viewType) {
|
switch (viewType) {
|
||||||
case SideView:
|
case SideView:
|
||||||
|
case TopView:
|
||||||
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesSide",
|
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesSide",
|
||||||
RocketComponent.class, Transformation.class);
|
RocketComponent.class, Transformation.class);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BackView:
|
case BackView:
|
||||||
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesBack",
|
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesBack",
|
||||||
@ -503,6 +509,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
|
|
||||||
switch (currentViewType) {
|
switch (currentViewType) {
|
||||||
case SideView:
|
case SideView:
|
||||||
|
case TopView:
|
||||||
subjectBounds_m = new Rectangle2D.Double(bounds.min.x, -maxR, bounds.span().x, 2 * maxR);
|
subjectBounds_m = new Rectangle2D.Double(bounds.min.x, -maxR, bounds.span().x, 2 * maxR);
|
||||||
break;
|
break;
|
||||||
case BackView:
|
case BackView:
|
||||||
@ -528,9 +535,8 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
if (currentViewType == RocketPanel.VIEW_TYPE.BackView){
|
if (currentViewType == RocketPanel.VIEW_TYPE.BackView){
|
||||||
final int newOriginX = mid_x;
|
final int newOriginX = mid_x;
|
||||||
final int newOriginY = borderThickness_px.height + getHeight() / 2;
|
final int newOriginY = borderThickness_px.height + getHeight() / 2;
|
||||||
|
|
||||||
originLocation_px = new Point(newOriginX, newOriginY);
|
originLocation_px = new Point(newOriginX, newOriginY);
|
||||||
}else if (currentViewType == RocketPanel.VIEW_TYPE.SideView){
|
} else if (currentViewType == RocketPanel.VIEW_TYPE.SideView || currentViewType == RocketPanel.VIEW_TYPE.TopView) {
|
||||||
final int newOriginX = mid_x - (subjectWidth / 2) - (int)(subjectBounds_m.getMinX() * scale);
|
final int newOriginX = mid_x - (subjectWidth / 2) - (int)(subjectBounds_m.getMinX() * scale);
|
||||||
final int newOriginY = Math.max(getHeight(), subjectHeight + 2*borderThickness_px.height )/ 2;
|
final int newOriginY = Math.max(getHeight(), subjectHeight + 2*borderThickness_px.height )/ 2;
|
||||||
originLocation_px = new Point(newOriginX, newOriginY);
|
originLocation_px = new Point(newOriginX, newOriginY);
|
||||||
|
@ -2,6 +2,7 @@ package net.sf.openrocket.gui.scalefigure;
|
|||||||
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
@ -91,9 +92,12 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
private static final Logger log = LoggerFactory.getLogger(RocketPanel.class);
|
private static final Logger log = LoggerFactory.getLogger(RocketPanel.class);
|
||||||
|
|
||||||
|
private static final String VIEW_TYPE_SEPARATOR = "__SEPARATOR__"; // Dummy string to indicate a horizontal separator item in the view type combobox
|
||||||
public enum VIEW_TYPE {
|
public enum VIEW_TYPE {
|
||||||
|
TopView(false, RocketFigure.VIEW_TOP),
|
||||||
SideView(false, RocketFigure.VIEW_SIDE),
|
SideView(false, RocketFigure.VIEW_SIDE),
|
||||||
BackView(false, RocketFigure.VIEW_BACK),
|
BackView(false, RocketFigure.VIEW_BACK),
|
||||||
|
SEPARATOR(false, -248), // Horizontal combobox separator dummy item
|
||||||
Figure3D(true, RocketFigure3d.TYPE_FIGURE),
|
Figure3D(true, RocketFigure3d.TYPE_FIGURE),
|
||||||
Unfinished(true, RocketFigure3d.TYPE_UNFINISHED),
|
Unfinished(true, RocketFigure3d.TYPE_UNFINISHED),
|
||||||
Finished(true, RocketFigure3d.TYPE_FINISHED);
|
Finished(true, RocketFigure3d.TYPE_FINISHED);
|
||||||
@ -108,9 +112,16 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
if (type == -248) {
|
||||||
|
return VIEW_TYPE_SEPARATOR;
|
||||||
|
}
|
||||||
return trans.get("RocketPanel.FigTypeAct." + super.toString());
|
return trans.get("RocketPanel.FigTypeAct." + super.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static VIEW_TYPE getDefaultViewType() {
|
||||||
|
return SideView;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean is3d;
|
private boolean is3d;
|
||||||
@ -308,12 +319,16 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
JPanel ribbon = new JPanel(new MigLayout("insets 0, fill"));
|
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 ViewTypeComboBoxModel(VIEW_TYPE.values(), VIEW_TYPE.getDefaultViewType()) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSelectedItem(Object o) {
|
public void setSelectedItem(Object o) {
|
||||||
super.setSelectedItem(o);
|
|
||||||
VIEW_TYPE v = (VIEW_TYPE) o;
|
VIEW_TYPE v = (VIEW_TYPE) o;
|
||||||
|
if (v == VIEW_TYPE.SEPARATOR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setSelectedItem(o);
|
||||||
if (v.is3d) {
|
if (v.is3d) {
|
||||||
figure3d.setType(v.type);
|
figure3d.setType(v.type);
|
||||||
go3D();
|
go3D();
|
||||||
@ -325,7 +340,9 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
ribbon.add(new JLabel(trans.get("RocketPanel.lbl.ViewType")), "cell 0 0");
|
ribbon.add(new JLabel(trans.get("RocketPanel.lbl.ViewType")), "cell 0 0");
|
||||||
ribbon.add(new JComboBox<VIEW_TYPE>(cm), "cell 0 1");
|
final JComboBox viewSelector = new JComboBox(cm);
|
||||||
|
viewSelector.setRenderer(new SeparatorComboBoxRenderer(viewSelector.getRenderer()));
|
||||||
|
ribbon.add(viewSelector, "cell 0 1");
|
||||||
|
|
||||||
// Zoom level selector
|
// Zoom level selector
|
||||||
scaleSelector = new ScaleSelector(scrollPane);
|
scaleSelector = new ScaleSelector(scrollPane);
|
||||||
@ -773,7 +790,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
figure3d.setCP(new Coordinate(Double.NaN, Double.NaN));
|
figure3d.setCP(new Coordinate(Double.NaN, Double.NaN));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (figure.getType() == RocketPanel.VIEW_TYPE.SideView && length > 0) {
|
if (length > 0 &&
|
||||||
|
((figure.getCurrentViewType() == RocketPanel.VIEW_TYPE.TopView) || (figure.getCurrentViewType() == RocketPanel.VIEW_TYPE.SideView))) {
|
||||||
extraCP.setPosition(cpx, cpy);
|
extraCP.setPosition(cpx, cpy);
|
||||||
extraCG.setPosition(cgx, cgy);
|
extraCG.setPosition(cgx, cgy);
|
||||||
} else {
|
} else {
|
||||||
@ -1061,40 +1079,34 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
figure3d.setSelection(components);
|
figure3d.setSelection(components);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
private static class ViewTypeComboBoxModel extends DefaultComboBoxModel<VIEW_TYPE> {
|
||||||
// * An <code>Action</code> that shows whether the figure type is the
|
public ViewTypeComboBoxModel(VIEW_TYPE[] items, VIEW_TYPE initialItem) {
|
||||||
// type
|
super(items);
|
||||||
// * given in the constructor.
|
super.setSelectedItem(initialItem);
|
||||||
// *
|
}
|
||||||
// * @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
}
|
||||||
// */
|
|
||||||
// private class FigureTypeAction extends AbstractAction implements
|
/**
|
||||||
// StateChangeListener {
|
* Custom combobox renderer that supports the display of horizontal separators between items.
|
||||||
// private static final long serialVersionUID = 1L;
|
* ComboBox objects with the text {@link VIEW_TYPE_SEPARATOR} objects in the combobox are replaced by a separator object.
|
||||||
// private final VIEW_TYPE type;
|
*/
|
||||||
//
|
private static class SeparatorComboBoxRenderer extends JLabel implements ListCellRenderer {
|
||||||
// public FigureTypeAction(VIEW_TYPE type) {
|
private final JSeparator separator;
|
||||||
// this.type = type;
|
private final ListCellRenderer defaultRenderer;
|
||||||
// stateChanged(null);
|
|
||||||
// figure.addChangeListener(this);
|
public SeparatorComboBoxRenderer(ListCellRenderer defaultRenderer) {
|
||||||
// }
|
this.defaultRenderer = defaultRenderer;
|
||||||
//
|
this.separator = new JSeparator(JSeparator.HORIZONTAL);
|
||||||
// @Override
|
}
|
||||||
// public void actionPerformed(ActionEvent e) {
|
|
||||||
// boolean state = (Boolean) getValue(Action.SELECTED_KEY);
|
public Component getListCellRendererComponent(JList list, Object value,
|
||||||
// if (state == true) {
|
int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
// // This view has been selected
|
String str = (value == null) ? "" : value.toString();
|
||||||
// figure.setType(type);
|
if (VIEW_TYPE_SEPARATOR.equals(str)) {
|
||||||
// go2D();
|
return separator;
|
||||||
// updateExtras();
|
};
|
||||||
// }
|
return defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||||
// stateChanged(null);
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void stateChanged(EventObject e) {
|
|
||||||
// putValue(Action.SELECTED_KEY, figure.getType() == type && !is3d);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user