[fixes #976] Sometimes can't select components when behind body tube

This commit is contained in:
Sibo Van Gool 2021-07-04 21:25:55 +02:00 committed by Sibo Van Gool
parent 0dfd5d52c5
commit 9ac2d2f844
19 changed files with 65 additions and 24 deletions

View File

@ -45,6 +45,7 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
this.outerRadius = Math.max(radius, 0); this.outerRadius = Math.max(radius, 0);
this.length = Math.max(length, 0); this.length = Math.max(length, 0);
motors = new MotorConfigurationSet(this); motors = new MotorConfigurationSet(this);
super.displayOrder = 0; // Order for displaying the component in the 2D view
} }
public BodyTube(double length, double radius, boolean filled) { public BodyTube(double length, double radius, boolean filled) {

View File

@ -13,6 +13,7 @@ public class Bulkhead extends RadiusRingComponent {
public Bulkhead() { public Bulkhead() {
setOuterRadiusAutomatic(true); setOuterRadiusAutomatic(true);
setLength(0.002); setLength(0.002);
super.displayOrder = 10; // Order for displaying the component in the 2D view
} }
@Override @Override

View File

@ -13,6 +13,7 @@ public class CenteringRing extends RadiusRingComponent {
setOuterRadiusAutomatic(true); setOuterRadiusAutomatic(true);
setInnerRadiusAutomatic(true); setInnerRadiusAutomatic(true);
setLength(0.002); setLength(0.002);
super.displayOrder = 9; // Order for displaying the component in the 2D view
} }
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();

View File

@ -16,6 +16,7 @@ public class EngineBlock extends ThicknessRingComponent implements AxialPosition
setOuterRadiusAutomatic(true); setOuterRadiusAutomatic(true);
setThickness(0.005); setThickness(0.005);
setLength(0.005); setLength(0.005);
super.displayOrder = 11; // Order for displaying the component in the 2D view
} }
@Override @Override

View File

@ -134,6 +134,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
public FinSet() { public FinSet() {
super( AxialMethod.BOTTOM); super( AxialMethod.BOTTOM);
this.filletMaterial = Application.getPreferences().getDefaultComponentMaterial(this.getClass(), Material.Type.BULK); this.filletMaterial = Application.getPreferences().getDefaultComponentMaterial(this.getClass(), Material.Type.BULK);
super.displayOrder = 4; // Order for displaying the component in the 2D view
} }
@Override @Override

View File

@ -48,6 +48,8 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
this.setLength(0.070); this.setLength(0.070);
motors = new MotorConfigurationSet(this); motors = new MotorConfigurationSet(this);
super.displayOrder = 7; // Order for displaying the component in the 2D view
} }

View File

@ -37,6 +37,7 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B
radius = 0.01 / 2; radius = 0.01 / 2;
thickness = 0.001; thickness = 0.001;
length = 0.03; length = 0.03;
super.displayOrder = 6; // Order for displaying the component in the 2D view
} }

View File

@ -41,11 +41,13 @@ public class MassComponent extends MassObject {
public MassComponent() { public MassComponent() {
super(); super();
super.displayOrder = 15; // Order for displaying the component in the 2D view
} }
public MassComponent(double length, double radius, double mass) { public MassComponent(double length, double radius, double mass) {
super(length, radius); super(length, radius);
this.mass = mass; this.mass = mass;
super.displayOrder = 14; // Order for displaying the component in the 2D view
} }

View File

@ -42,6 +42,8 @@ public class NoseCone extends Transition implements InsideColorComponent {
super.setAftRadiusAutomatic(false); super.setAftRadiusAutomatic(false);
super.setAftRadius(radius); super.setAftRadius(radius);
super.displayOrder = 1; // Order for displaying the component in the 2D view
} }

View File

@ -23,6 +23,7 @@ public class Parachute extends RecoveryDevice {
this.diameter = 0.3; this.diameter = 0.3;
this.lineMaterial = Application.getPreferences().getDefaultComponentMaterial(Parachute.class, Material.Type.LINE); this.lineMaterial = Application.getPreferences().getDefaultComponentMaterial(Parachute.class, Material.Type.LINE);
this.lineLength = 0.3; this.lineLength = 0.3;
super.displayOrder = 12; // Order for displaying the component in the 2D view
} }

View File

@ -69,12 +69,14 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
this.setStandoff( 0.002); this.setStandoff( 0.002);
this.setInstanceSeparation( this.outerDiameter_m * 6); this.setInstanceSeparation( this.outerDiameter_m * 6);
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin")); this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
super.displayOrder = 5; // Order for displaying the component in the 2D view
} }
public RailButton( final double od, final double ht ) { public RailButton( final double od, final double ht ) {
this(); this();
this.setOuterDiameter( od); this.setOuterDiameter( od);
this.setTotalHeight( ht); this.setTotalHeight( ht);
super.displayOrder = 5; // Order for displaying the component in the 2D view
} }
public RailButton( final double od, final double id, final double ht, final double flangeThickness, final double _standoff ) { public RailButton( final double od, final double id, final double ht, final double flangeThickness, final double _standoff ) {
@ -86,6 +88,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
this.setStandoff( _standoff); this.setStandoff( _standoff);
this.setInstanceSeparation( od*2); this.setInstanceSeparation( od*2);
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin")); this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
super.displayOrder = 5; // Order for displaying the component in the 2D view
} }
private static final RailButton make1010Button(){ private static final RailButton make1010Button(){

View File

@ -126,8 +126,14 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* Used to invalidate the component after calling {@link #copyFrom(RocketComponent)}. * Used to invalidate the component after calling {@link #copyFrom(RocketComponent)}.
*/ */
private Invalidator invalidator = new Invalidator(this); private Invalidator invalidator = new Invalidator(this);
/**
* This is for determining the order in which the component should be drawn in the 2D views.
* Lower values will be placed more in the back, higher values more in the front.
*/
protected int displayOrder = 100; // Take a high enough init value to not mess with pre-defined values
//// NOTE !!! All fields must be copied in the method copyFrom()! //// //// NOTE !!! All fields must be copied in the method copyFrom()! ////
@ -2014,6 +2020,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
this.name = src.name; this.name = src.name;
this.comment = src.comment; this.comment = src.comment;
this.id = src.id; this.id = src.id;
this.displayOrder = src.displayOrder;
// Add source components to invalidation tree // Add source components to invalidation tree
for (RocketComponent c : src) { for (RocketComponent c : src) {
@ -2229,4 +2236,11 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
return false; return false;
} }
public int getDisplayOrder() {
return displayOrder;
}
public void setDisplayOrder(int displayOrder) {
this.displayOrder = displayOrder;
}
} }

View File

@ -15,6 +15,7 @@ public class ShockCord extends MassObject {
public ShockCord() { public ShockCord() {
material = Application.getPreferences().getDefaultComponentMaterial(ShockCord.class, Material.Type.LINE); material = Application.getPreferences().getDefaultComponentMaterial(ShockCord.class, Material.Type.LINE);
cordLength = 0.4; cordLength = 0.4;
super.displayOrder = 13; // Order for displaying the component in the 2D view
} }

View File

@ -21,6 +21,7 @@ public class Streamer extends RecoveryDevice {
public Streamer() { public Streamer() {
this.stripLength = 0.5; this.stripLength = 0.5;
this.stripWidth = 0.05; this.stripWidth = 0.05;
super.displayOrder = 12; // Order for displaying the component in the 2D view
} }

View File

@ -58,6 +58,8 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
this.type = Shape.CONICAL; this.type = Shape.CONICAL;
this.shapeParameter = 0; this.shapeParameter = 0;
this.clipped = true; this.clipped = true;
super.displayOrder = 2; // Order for displaying the component in the 2D view
} }
//////// Length //////// //////// Length ////////

View File

@ -13,6 +13,7 @@ public class TubeCoupler extends ThicknessRingComponent implements RadialParent
setOuterRadiusAutomatic(true); setOuterRadiusAutomatic(true);
setThickness(0.002); setThickness(0.002);
setLength(0.06); setLength(0.06);
super.displayOrder = 8; // Order for displaying the component in the 2D view
} }
@Override @Override

View File

@ -56,6 +56,7 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable,
public TubeFinSet() { public TubeFinSet() {
super(AxialMethod.BOTTOM); super(AxialMethod.BOTTOM);
length = 0.10; length = 0.10;
super.displayOrder = 3; // Order for displaying the component in the 2D view
} }
public void setLength(double length) { public void setLength(double length) {

View File

@ -12,7 +12,7 @@ import net.sf.openrocket.util.Transformation;
/** /**
* A catch-all, no-operation drawing component. * A catch-all, no-operation drawing component.
*/ */
public class RocketComponentShape { public class RocketComponentShape implements Comparable<RocketComponentShape> {
final public boolean hasShape; final public boolean hasShape;
final public Shape shape; final public Shape shape;
@ -71,6 +71,10 @@ public class RocketComponentShape {
} }
return toReturn; return toReturn;
} }
@Override
public int compareTo(RocketComponentShape o) {
return Integer.compare(o.component.getDisplayOrder(), this.component.getDisplayOrder());
}
} }

View File

@ -14,8 +14,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.ArrayList; import java.util.*;
import java.util.LinkedHashSet;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -74,10 +73,12 @@ public class RocketFigure extends AbstractScaleFigure {
private double rotation; private double rotation;
private Transformation axialRotation; private Transformation axialRotation;
/* /**
* figureComponents contains the corresponding RocketComponents of the figureShapes * 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
* (declared in RocketComponent, can be overridden in separate components).
*/ */
private final ArrayList<RocketComponentShape> figureShapes = new ArrayList<RocketComponentShape>(); private final PriorityQueue<RocketComponentShape> figureShapes = new PriorityQueue<>();
private final ArrayList<FigureElement> relativeExtra = new ArrayList<FigureElement>(); private final ArrayList<FigureElement> relativeExtra = new ArrayList<FigureElement>();
@ -207,12 +208,12 @@ public class RocketFigure extends AbstractScaleFigure {
RenderingHints.VALUE_RENDER_QUALITY); RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON); RenderingHints.VALUE_ANTIALIAS_ON);
int shapeCount = figureShapes.size();
// Draw all shapes // Draw all shapes
for (int i = 0; i < shapeCount; i++) { PriorityQueue<RocketComponentShape> figureShapesCopy = new PriorityQueue<>(figureShapes);
RocketComponentShape rcs = figureShapes.get(i); while (!figureShapesCopy.isEmpty()) {
RocketComponent c = rcs.getComponent(); RocketComponentShape rcs = figureShapesCopy.poll();
RocketComponent c = rcs.getComponent();
boolean selected = false; boolean selected = false;
// Check if component is in the selection // Check if component is in the selection
@ -330,16 +331,18 @@ public class RocketFigure extends AbstractScaleFigure {
} }
LinkedHashSet<RocketComponent> l = new LinkedHashSet<RocketComponent>(); LinkedHashSet<RocketComponent> l = new LinkedHashSet<RocketComponent>();
for (int i = 0; i < figureShapes.size(); i++) {
RocketComponentShape rcs = this.figureShapes.get(i); PriorityQueue<RocketComponentShape> figureShapesCopy = new PriorityQueue<>(figureShapes);
while (!figureShapesCopy.isEmpty()) {
RocketComponentShape rcs = figureShapesCopy.poll();
if (rcs.shape.contains(p)) if (rcs.shape.contains(p))
l.add(rcs.component); l.add(rcs.component);
} }
return l.toArray(new RocketComponent[0]); return l.toArray(new RocketComponent[0]);
} }
private void updateShapes(ArrayList<RocketComponentShape> allShapes) { private void updateShapes(PriorityQueue<RocketComponentShape> allShapes) {
// source input // source input
final FlightConfiguration config = rocket.getSelectedConfiguration(); final FlightConfiguration config = rocket.getSelectedConfiguration();
@ -369,8 +372,8 @@ public class RocketFigure extends AbstractScaleFigure {
* *
* @return the <code>ArrayList</code> containing all the shapes to draw. * @return the <code>ArrayList</code> containing all the shapes to draw.
*/ */
private static ArrayList<RocketComponentShape> addThisShape( private static PriorityQueue<RocketComponentShape> addThisShape(
ArrayList<RocketComponentShape> allShapes, // this is the output parameter PriorityQueue<RocketComponentShape> allShapes, // this is the output parameter
final RocketPanel.VIEW_TYPE viewType, final RocketPanel.VIEW_TYPE viewType,
final RocketComponent component, final RocketComponent component,
final Transformation transformation) { final Transformation transformation) {
@ -405,9 +408,7 @@ public class RocketFigure extends AbstractScaleFigure {
RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation); RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation);
for ( RocketComponentShape curShape : returnValue ){ allShapes.addAll(Arrays.asList(returnValue));
allShapes.add( curShape );
}
return allShapes; return allShapes;
} }