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.FigTypeAct.SideView = Side view
|
||||
RocketPanel.FigTypeAct.TopView = Top view
|
||||
RocketPanel.FigTypeAct.BackView = Back view
|
||||
RocketPanel.FigTypeAct.Figure3D = 3D Figure
|
||||
RocketPanel.FigTypeAct.Finished = 3D Finished
|
||||
|
@ -66,7 +66,7 @@ public class FlightEventsTest extends BaseTestCase {
|
||||
// Test that the event times are correct
|
||||
for (int i = 0; i < expectedEventTimes.length; i++) {
|
||||
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
|
||||
for (int i = 0; i < expectedEventTimes.length; i++) {
|
||||
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
|
||||
|
@ -31,7 +31,7 @@ public class VariableTableModel extends AbstractTableModel {
|
||||
|
||||
//Collections.addAll(types, FlightDataType.ALL_TYPES);
|
||||
//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_SUFFIX = "Shapes";
|
||||
|
||||
public static final int VIEW_SIDE=0;
|
||||
public static final int VIEW_BACK=1;
|
||||
|
||||
public static final int VIEW_TOP = 0;
|
||||
public static final int VIEW_SIDE = 1;
|
||||
public static final int VIEW_BACK = 2;
|
||||
|
||||
// Width for drawing normal and selected components
|
||||
public static final double NORMAL_WIDTH = 1.0;
|
||||
@ -130,10 +131,6 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public Transformation getRotateTransformation() {
|
||||
return axialRotation;
|
||||
}
|
||||
|
||||
public void setRotation(double rot) {
|
||||
if (MathUtil.equals(rotation, rot))
|
||||
return;
|
||||
@ -142,14 +139,22 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
updateFigure();
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (this.currentViewType == type)
|
||||
@ -201,7 +206,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
AffineTransform baseTransform = g2.getTransform();
|
||||
|
||||
PriorityQueue<RocketComponentShape> figureShapes;
|
||||
if (currentViewType == RocketPanel.VIEW_TYPE.SideView)
|
||||
if (currentViewType == RocketPanel.VIEW_TYPE.SideView || currentViewType == RocketPanel.VIEW_TYPE.TopView)
|
||||
figureShapes = figureShapes_side;
|
||||
else if (currentViewType == RocketPanel.VIEW_TYPE.BackView)
|
||||
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() ));
|
||||
|
||||
// rotate by figure's axial rotation:
|
||||
curMotorLocation = this.axialRotation.transform(curMotorLocation);
|
||||
curMotorLocation = getFigureRotation().transform(curMotorLocation);
|
||||
|
||||
{
|
||||
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,
|
||||
(curMotorLocation.y - motorRadius),
|
||||
motorLength,
|
||||
@ -354,7 +359,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
LinkedHashSet<RocketComponent> l = new LinkedHashSet<RocketComponent>();
|
||||
|
||||
PriorityQueue<RocketComponentShape> figureShapes;
|
||||
if (currentViewType == RocketPanel.VIEW_TYPE.SideView)
|
||||
if (currentViewType == RocketPanel.VIEW_TYPE.SideView || currentViewType == RocketPanel.VIEW_TYPE.TopView)
|
||||
figureShapes = figureShapes_side;
|
||||
else if (currentViewType == RocketPanel.VIEW_TYPE.BackView)
|
||||
figureShapes = figureShapes_back;
|
||||
@ -399,7 +404,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -432,9 +437,10 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
// Find the appropriate method
|
||||
switch (viewType) {
|
||||
case SideView:
|
||||
case TopView:
|
||||
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesSide",
|
||||
RocketComponent.class, Transformation.class);
|
||||
break;
|
||||
break;
|
||||
|
||||
case BackView:
|
||||
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesBack",
|
||||
@ -503,6 +509,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
switch (currentViewType) {
|
||||
case SideView:
|
||||
case TopView:
|
||||
subjectBounds_m = new Rectangle2D.Double(bounds.min.x, -maxR, bounds.span().x, 2 * maxR);
|
||||
break;
|
||||
case BackView:
|
||||
@ -528,9 +535,8 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
if (currentViewType == RocketPanel.VIEW_TYPE.BackView){
|
||||
final int newOriginX = mid_x;
|
||||
final int newOriginY = borderThickness_px.height + getHeight() / 2;
|
||||
|
||||
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 newOriginY = Math.max(getHeight(), subjectHeight + 2*borderThickness_px.height )/ 2;
|
||||
originLocation_px = new Point(newOriginX, newOriginY);
|
||||
|
@ -2,6 +2,7 @@ package net.sf.openrocket.gui.scalefigure;
|
||||
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
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 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 {
|
||||
TopView(false, RocketFigure.VIEW_TOP),
|
||||
SideView(false, RocketFigure.VIEW_SIDE),
|
||||
BackView(false, RocketFigure.VIEW_BACK),
|
||||
SEPARATOR(false, -248), // Horizontal combobox separator dummy item
|
||||
Figure3D(true, RocketFigure3d.TYPE_FIGURE),
|
||||
Unfinished(true, RocketFigure3d.TYPE_UNFINISHED),
|
||||
Finished(true, RocketFigure3d.TYPE_FINISHED);
|
||||
@ -108,9 +112,16 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (type == -248) {
|
||||
return VIEW_TYPE_SEPARATOR;
|
||||
}
|
||||
return trans.get("RocketPanel.FigTypeAct." + super.toString());
|
||||
}
|
||||
|
||||
public static VIEW_TYPE getDefaultViewType() {
|
||||
return SideView;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean is3d;
|
||||
@ -308,12 +319,16 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
JPanel ribbon = new JPanel(new MigLayout("insets 0, fill"));
|
||||
|
||||
// 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
|
||||
public void setSelectedItem(Object o) {
|
||||
super.setSelectedItem(o);
|
||||
VIEW_TYPE v = (VIEW_TYPE) o;
|
||||
if (v == VIEW_TYPE.SEPARATOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.setSelectedItem(o);
|
||||
if (v.is3d) {
|
||||
figure3d.setType(v.type);
|
||||
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 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
|
||||
scaleSelector = new ScaleSelector(scrollPane);
|
||||
@ -773,7 +790,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
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);
|
||||
extraCG.setPosition(cgx, cgy);
|
||||
} else {
|
||||
@ -1061,40 +1079,34 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
figure3d.setSelection(components);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * An <code>Action</code> that shows whether the figure type is the
|
||||
// type
|
||||
// * given in the constructor.
|
||||
// *
|
||||
// * @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
// */
|
||||
// private class FigureTypeAction extends AbstractAction implements
|
||||
// StateChangeListener {
|
||||
// private static final long serialVersionUID = 1L;
|
||||
// private final VIEW_TYPE type;
|
||||
//
|
||||
// public FigureTypeAction(VIEW_TYPE type) {
|
||||
// this.type = type;
|
||||
// stateChanged(null);
|
||||
// figure.addChangeListener(this);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// boolean state = (Boolean) getValue(Action.SELECTED_KEY);
|
||||
// if (state == true) {
|
||||
// // This view has been selected
|
||||
// figure.setType(type);
|
||||
// go2D();
|
||||
// updateExtras();
|
||||
// }
|
||||
// stateChanged(null);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void stateChanged(EventObject e) {
|
||||
// putValue(Action.SELECTED_KEY, figure.getType() == type && !is3d);
|
||||
// }
|
||||
// }
|
||||
private static class ViewTypeComboBoxModel extends DefaultComboBoxModel<VIEW_TYPE> {
|
||||
public ViewTypeComboBoxModel(VIEW_TYPE[] items, VIEW_TYPE initialItem) {
|
||||
super(items);
|
||||
super.setSelectedItem(initialItem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom combobox renderer that supports the display of horizontal separators between items.
|
||||
* ComboBox objects with the text {@link VIEW_TYPE_SEPARATOR} objects in the combobox are replaced by a separator object.
|
||||
*/
|
||||
private static class SeparatorComboBoxRenderer extends JLabel implements ListCellRenderer {
|
||||
private final JSeparator separator;
|
||||
private final ListCellRenderer defaultRenderer;
|
||||
|
||||
public SeparatorComboBoxRenderer(ListCellRenderer defaultRenderer) {
|
||||
this.defaultRenderer = defaultRenderer;
|
||||
this.separator = new JSeparator(JSeparator.HORIZONTAL);
|
||||
}
|
||||
|
||||
public Component getListCellRendererComponent(JList list, Object value,
|
||||
int index, boolean isSelected, boolean cellHasFocus) {
|
||||
String str = (value == null) ? "" : value.toString();
|
||||
if (VIEW_TYPE_SEPARATOR.equals(str)) {
|
||||
return separator;
|
||||
};
|
||||
return defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user