From 959bbfaac3f30c7d20ef7127628c878519854c55 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 16 Jul 2022 02:40:12 +0200 Subject: [PATCH 1/6] [#1146] Add 2D visualization for pod sets --- .../sf/openrocket/rocketcomponent/Rocket.java | 11 ++ .../gui/rocketfigure/EmptyShapes.java | 122 ++++++++++++++++++ .../gui/rocketfigure/PodSetShapes.java | 49 +++++++ .../rocketfigure/RocketComponentShape.java | 4 + .../gui/scalefigure/RocketFigure.java | 62 ++++++++- 5 files changed, 244 insertions(+), 4 deletions(-) create mode 100644 swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java create mode 100644 swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java diff --git a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java index 5411440f7..90fa5a5a7 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -304,6 +304,17 @@ public class Rocket extends ComponentAssembly { fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); } } + + @Override + public double getBoundingRadius() { + double bounding = 0; + for (RocketComponent comp : children) { + if (comp instanceof ComponentAssembly) { + bounding = Math.max(bounding, ((ComponentAssembly) comp).getBoundingRadius()); + } + } + return bounding; + } diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java new file mode 100644 index 000000000..35b048551 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java @@ -0,0 +1,122 @@ +package net.sf.openrocket.gui.rocketfigure; + +import net.sf.openrocket.util.Coordinate; +import net.sf.openrocket.util.Transformation; + +import java.awt.Shape; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; + +/** + * Shapes of an "empty"/virtual object, e.g. a podset without any children. + * The shape is a center square with additional lines on the north, east, south and west side of the square. + * + * @author Sibo Van Gool + */ +public class EmptyShapes extends RocketComponentShape { + /** + * Returns the empty shape in the side view. + * @param radius radius of the center square + */ + public static Shape[] getShapesSide(final Transformation transformation, final double radius) { + final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO); + double x = instanceAbsoluteLocation.x; + double y = instanceAbsoluteLocation.y; + + double lineLength = getLineLength(radius); // Length of the line protruding the center square + + final Shape[] s = new Shape[5]; + // Center square + s[0] = new Rectangle2D.Double(x - radius, y - radius, 2 * radius, 2 * radius); + // Line North + s[1] = new Line2D.Double(x, y + radius, x, y + radius + lineLength); + // Line East + s[2] = new Line2D.Double(x + radius, y, x + radius + lineLength, y); + // Line South + s[3] = new Line2D.Double(x, y - radius, x, y - radius - lineLength); + // Line West + s[4] = new Line2D.Double(x - radius, y, x - radius - lineLength, y); + + return s; + } + + /** + * Returns the empty shape in the side view, with an additional square encompassing the shape that can be used + * for selecting the object. + * @param radius radius of the center square + */ + public static Shape[] getShapesSideWithSelectionSquare(final Transformation transformation, final double radius) { + final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO); + double x = instanceAbsoluteLocation.x; + double y = instanceAbsoluteLocation.y; + + double lineLength = getLineLength(radius); // Length of the line protruding the center square + + Shape[] shapes = getShapesSide(transformation, radius); + + // Invisible shape for selecting the component (= a square encompassing the component) + Shape selectionShape = new Rectangle2D.Double(x - radius - lineLength, y - radius - lineLength, + lineLength * 2 + radius * 2, lineLength * 2 + radius * 2); + + Shape[] finalShapes = new Shape[shapes.length + 1]; + System.arraycopy(shapes, 0, finalShapes, 0, shapes.length); + finalShapes[finalShapes.length - 1] = selectionShape; + + return finalShapes; + } + + /** + * Returns the empty shape in the side view. + * @param radius radius of the center square + */ + public static Shape[] getShapesBack(final Transformation transformation, final double radius) { + final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO); + double z = instanceAbsoluteLocation.z; + double y = instanceAbsoluteLocation.y; + + double lineLength = getLineLength(radius); // Length of the line protruding the center square + + final Shape[] s = new Shape[5]; + // Center square + s[0] = new Rectangle2D.Double(z - radius, y - radius, 2 * radius, 2 * radius); + // Line North + s[1] = new Line2D.Double(z, y + radius, z, y + radius + lineLength); + // Line East + s[2] = new Line2D.Double(z + radius, y, z + radius + lineLength, y); + // Line South + s[3] = new Line2D.Double(z, y - radius, z, y - radius - lineLength); + // Line West + s[4] = new Line2D.Double(z - radius, y, z - radius - lineLength, y); + + return s; + } + + /** + * Returns the empty shape in the back view, with an additional square encompassing the shape that can be used + * for selecting the object. + * @param radius radius of the center square + */ + public static Shape[] getShapesBackWithSelectionSquare(final Transformation transformation, final double radius) { + final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO); + double z = instanceAbsoluteLocation.z; + double y = instanceAbsoluteLocation.y; + + double lineLength = getLineLength(radius); // Length of the line protruding the center square + + Shape[] shapes = getShapesBack(transformation, radius); + + // Invisible shape for selecting the component (= a square encompassing the component) + Shape selectionShape = new Rectangle2D.Double(z - radius - lineLength, y - radius - lineLength, + lineLength * 2 + radius * 2, lineLength * 2 + radius * 2); + + Shape[] finalShapes = new Shape[shapes.length + 1]; + System.arraycopy(shapes, 0, finalShapes, 0, shapes.length); + finalShapes[finalShapes.length - 1] = selectionShape; + + return finalShapes; + } + + private static double getLineLength(double radius) { + return radius * 3; + } +} diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java new file mode 100644 index 000000000..27955db60 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java @@ -0,0 +1,49 @@ +package net.sf.openrocket.gui.rocketfigure; + +import net.sf.openrocket.rocketcomponent.PodSet; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.util.Color; +import net.sf.openrocket.util.Transformation; + +import java.awt.Shape; + +public class PodSetShapes extends RocketComponentShape { + public static final Color podsetColor = new Color(160, 160, 160); // Normal color for the podset shape + public static final Color centerColor = new Color(200, 200, 200); // Color for the center shape of the podset + + public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) { + PodSet podset = (PodSet)component; + double radius = getDisplayRadius(podset); + + Shape[] s = EmptyShapes.getShapesSideWithSelectionSquare(transformation, radius); + RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component); + + // Set the color of the shapes + for (int i = 0; i < shapes.length - 1; i++) { + shapes[i].setColor(podsetColor); + } + shapes[shapes.length - 1].setColor(Color.INVISIBLE); + + return shapes; + } + + public static RocketComponentShape[] getShapesBack(final RocketComponent component, final Transformation transformation) { + PodSet podset = (PodSet)component; + double radius = getDisplayRadius(podset); + + Shape[] s = EmptyShapes.getShapesBackWithSelectionSquare(transformation, radius); + RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component); + + // Set the color of the shapes + for (int i = 0; i < shapes.length - 1; i++) { + shapes[i].setColor(podsetColor); + } + shapes[shapes.length - 1].setColor(Color.INVISIBLE); + + return shapes; + } + + private static double getDisplayRadius(PodSet podset) { + return podset.getRocket().getBoundingRadius() * 0.03; + } +} diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java b/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java index 725713b80..c132bfd3d 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShape.java @@ -64,6 +64,10 @@ public class RocketComponentShape { return new RocketComponentShape[0]; } + public Color getColor() { + return color; + } + public void setColor(Color color) { this.color = color; } diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index 3226abee2..e9b8f6de0 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -17,6 +17,8 @@ import java.awt.geom.Rectangle2D; import java.util.*; import java.util.Map.Entry; +import net.sf.openrocket.gui.rocketfigure.PodSetShapes; +import net.sf.openrocket.rocketcomponent.PodSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -385,13 +387,38 @@ public class RocketFigure extends AbstractScaleFigure { final Transformation currentTransform = this.axialRotation.applyTransformation(context.transform); allShapes = addThisShape( allShapes, this.currentViewType, comp, currentTransform); } + + // PodSets require an additional shape for the center of the podset. + if (comp instanceof PodSet) { + Transformation parentTransform = null; + for (Entry> entry2: config.getActiveInstances().entrySet()) { + final RocketComponent parent = entry2.getKey(); + if (parent == comp.getParent()) { + parentTransform = entry2.getValue().get(0).transform; // TODO: normally only the first context should be used, unless we start doing fancy stuff like adding pods to individual fins + break; + } + } + if (parentTransform == null) { + parentTransform = Transformation.IDENTITY; + } + + final Transformation compLocTransform = Transformation.getTranslationTransform(comp.getPosition()); + final Transformation componentTransform = parentTransform.applyTransformation(compLocTransform); + + final Transformation currentTransform = this.axialRotation.applyTransformation(componentTransform); + allShapes = addThisShape(allShapes, this.currentViewType, comp, currentTransform, PodSetShapes.centerColor); + } } } /** * Gets the shapes required to draw the component. - * - * @param component + * + * @param allShapes output buffer for the shapes to add to + * @param viewType the view type to draw the component in + * @param component component to draw and add to + * @param transformation transformation to apply to the component before drawing it + * @param color color to draw the component in * * @return the ArrayList containing all the shapes to draw. */ @@ -399,10 +426,11 @@ public class RocketFigure extends AbstractScaleFigure { PriorityQueue allShapes, // this is the output parameter final RocketPanel.VIEW_TYPE viewType, final RocketComponent component, - final Transformation transformation) { + final Transformation transformation, + final net.sf.openrocket.util.Color color) { Reflection.Method m; - if(( component instanceof Rocket)||( component instanceof ComponentAssembly )){ + if(( component instanceof Rocket)||( component instanceof ComponentAssembly && !(component instanceof PodSet))){ // no-op; no shapes here return allShapes; } @@ -431,9 +459,35 @@ public class RocketFigure extends AbstractScaleFigure { RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation); + + if (color != null) { + for (RocketComponentShape rcs : returnValue) { + if (rcs.getColor() == net.sf.openrocket.util.Color.INVISIBLE) continue; // don't change the color of invisible (often selection) components + rcs.setColor(color); + } + } + allShapes.addAll(Arrays.asList(returnValue)); return allShapes; } + + /** + * Gets the shapes required to draw the component. + * + * @param allShapes output buffer for the shapes to add to + * @param viewType the view type to draw the component in + * @param component component to draw and add to + * @param transformation transformation to apply to the component before drawing it + * + * @return the ArrayList containing all the shapes to draw. + */ + private static PriorityQueue addThisShape( + PriorityQueue allShapes, // this is the output parameter + final RocketPanel.VIEW_TYPE viewType, + final RocketComponent component, + final Transformation transformation) { + return addThisShape(allShapes, viewType, component, transformation, null); + } /** From a89f1171cccdf7ecad2058267f7971cfa4aa8973 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 16 Jul 2022 13:17:58 +0200 Subject: [PATCH 2/6] Remove podset center marker --- .../gui/rocketfigure/PodSetShapes.java | 1 - .../gui/scalefigure/RocketFigure.java | 21 ------------------- 2 files changed, 22 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java index 27955db60..ebe8641c9 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java @@ -9,7 +9,6 @@ import java.awt.Shape; public class PodSetShapes extends RocketComponentShape { public static final Color podsetColor = new Color(160, 160, 160); // Normal color for the podset shape - public static final Color centerColor = new Color(200, 200, 200); // Color for the center shape of the podset public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) { PodSet podset = (PodSet)component; diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index e9b8f6de0..ed4f794b8 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -387,27 +387,6 @@ public class RocketFigure extends AbstractScaleFigure { final Transformation currentTransform = this.axialRotation.applyTransformation(context.transform); allShapes = addThisShape( allShapes, this.currentViewType, comp, currentTransform); } - - // PodSets require an additional shape for the center of the podset. - if (comp instanceof PodSet) { - Transformation parentTransform = null; - for (Entry> entry2: config.getActiveInstances().entrySet()) { - final RocketComponent parent = entry2.getKey(); - if (parent == comp.getParent()) { - parentTransform = entry2.getValue().get(0).transform; // TODO: normally only the first context should be used, unless we start doing fancy stuff like adding pods to individual fins - break; - } - } - if (parentTransform == null) { - parentTransform = Transformation.IDENTITY; - } - - final Transformation compLocTransform = Transformation.getTranslationTransform(comp.getPosition()); - final Transformation componentTransform = parentTransform.applyTransformation(compLocTransform); - - final Transformation currentTransform = this.axialRotation.applyTransformation(componentTransform); - allShapes = addThisShape(allShapes, this.currentViewType, comp, currentTransform, PodSetShapes.centerColor); - } } } From 9c5d1e9e26bc630544fbfe184b3c8fefae6b7b78 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 16 Jul 2022 13:18:10 +0200 Subject: [PATCH 3/6] Only show podset markers when selected --- .../openrocket/gui/scalefigure/RocketFigure.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index ed4f794b8..60f011d9a 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -380,6 +380,21 @@ public class RocketFigure extends AbstractScaleFigure { for(Entry> entry: config.getActiveInstances().entrySet() ) { final RocketComponent comp = entry.getKey(); + + // Only draw podsets when they are selected + if (comp instanceof PodSet) { + boolean selected = false; + + // Check if component is in the selection + for (int j = 0; j < selection.length; j++) { + if (comp == selection[j]) { + selected = true; + break; + } + } + + if (!selected) continue; + } final ArrayList contextList = entry.getValue(); From b479809b62843467e3af9836d88fded840a7f176 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 16 Jul 2022 14:41:14 +0200 Subject: [PATCH 4/6] Add 2D visualization for boosters --- .../gui/rocketfigure/ParallelStageShapes.java | 49 +++++++++++++++++++ .../gui/rocketfigure/PodSetShapes.java | 3 +- .../gui/scalefigure/RocketFigure.java | 13 +++-- 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java new file mode 100644 index 000000000..f8b1f58e4 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java @@ -0,0 +1,49 @@ +package net.sf.openrocket.gui.rocketfigure; + +import net.sf.openrocket.rocketcomponent.ParallelStage; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.util.Color; +import net.sf.openrocket.util.Transformation; + +import java.awt.Shape; + +public class ParallelStageShapes extends RocketComponentShape { + //public static final Color boosterColor = new Color(220, 185, 185); + public static final Color boosterColor = new Color(198,163,184); + + public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) { + ParallelStage booster = (ParallelStage)component; + double radius = getDisplayRadius(booster); + + Shape[] s = EmptyShapes.getShapesSideWithSelectionSquare(transformation, radius); + RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component); + + // Set the color of the shapes + for (int i = 0; i < shapes.length - 1; i++) { + shapes[i].setColor(boosterColor); + } + shapes[shapes.length - 1].setColor(Color.INVISIBLE); + + return shapes; + } + + public static RocketComponentShape[] getShapesBack(final RocketComponent component, final Transformation transformation) { + ParallelStage booster = (ParallelStage)component; + double radius = getDisplayRadius(booster); + + Shape[] s = EmptyShapes.getShapesBackWithSelectionSquare(transformation, radius); + RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component); + + // Set the color of the shapes + for (int i = 0; i < shapes.length - 1; i++) { + shapes[i].setColor(boosterColor); + } + shapes[shapes.length - 1].setColor(Color.INVISIBLE); + + return shapes; + } + + private static double getDisplayRadius(ParallelStage booster) { + return booster.getRocket().getBoundingRadius() * 0.03; + } +} diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java index ebe8641c9..308e34929 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java @@ -8,7 +8,8 @@ import net.sf.openrocket.util.Transformation; import java.awt.Shape; public class PodSetShapes extends RocketComponentShape { - public static final Color podsetColor = new Color(160, 160, 160); // Normal color for the podset shape + //public static final Color podsetColor = new Color(180, 180, 225); + public static final Color podsetColor = new Color(160,160,215); public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) { PodSet podset = (PodSet)component; diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index 60f011d9a..39c18e025 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -17,7 +17,8 @@ import java.awt.geom.Rectangle2D; import java.util.*; import java.util.Map.Entry; -import net.sf.openrocket.gui.rocketfigure.PodSetShapes; +import net.sf.openrocket.rocketcomponent.AxialStage; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.PodSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +29,6 @@ import net.sf.openrocket.gui.util.ColorConversion; import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorConfiguration; -import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.InstanceContext; import net.sf.openrocket.rocketcomponent.MotorMount; @@ -382,17 +382,16 @@ public class RocketFigure extends AbstractScaleFigure { final RocketComponent comp = entry.getKey(); // Only draw podsets when they are selected - if (comp instanceof PodSet) { + if (comp instanceof PodSet || comp instanceof ParallelStage) { boolean selected = false; // Check if component is in the selection - for (int j = 0; j < selection.length; j++) { - if (comp == selection[j]) { + for (RocketComponent component : selection) { + if (comp == component) { selected = true; break; } } - if (!selected) continue; } @@ -424,7 +423,7 @@ public class RocketFigure extends AbstractScaleFigure { final net.sf.openrocket.util.Color color) { Reflection.Method m; - if(( component instanceof Rocket)||( component instanceof ComponentAssembly && !(component instanceof PodSet))){ + if ((component instanceof Rocket) || (component instanceof AxialStage && !(component instanceof ParallelStage))){ // no-op; no shapes here return allShapes; } From 391dc37e9ba007a2f03779aca430d4498f613483 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 16 Jul 2022 14:57:58 +0200 Subject: [PATCH 5/6] Remove unwanted colors --- .../net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java | 1 - swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java | 1 - 2 files changed, 2 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java index f8b1f58e4..565a23591 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/ParallelStageShapes.java @@ -8,7 +8,6 @@ import net.sf.openrocket.util.Transformation; import java.awt.Shape; public class ParallelStageShapes extends RocketComponentShape { - //public static final Color boosterColor = new Color(220, 185, 185); public static final Color boosterColor = new Color(198,163,184); public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) { diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java index 308e34929..7ef928f2d 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/PodSetShapes.java @@ -8,7 +8,6 @@ import net.sf.openrocket.util.Transformation; import java.awt.Shape; public class PodSetShapes extends RocketComponentShape { - //public static final Color podsetColor = new Color(180, 180, 225); public static final Color podsetColor = new Color(160,160,215); public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) { From d0be2e5e07449609f9c2b2e061957d8ef412bc8e Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 18 Jul 2022 00:28:05 +0200 Subject: [PATCH 6/6] Add preference for marker visibility --- core/resources/l10n/messages.properties | 2 ++ .../sf/openrocket/startup/Preferences.java | 22 ++++++++++++++++++- .../preferences/DesignPreferencesPanel.java | 22 +++++++++++++++++-- .../sf/openrocket/gui/main/BasicFrame.java | 13 ++++++++++- .../gui/scalefigure/RocketFigure.java | 3 ++- .../gui/scalefigure/RocketPanel.java | 2 +- 6 files changed, 58 insertions(+), 6 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 7d81f82eb..563738509 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -294,6 +294,8 @@ pref.dlg.lbl.PositiontoinsertStages = Position to insert new stages: pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations. pref.dlg.checkbox.Runsimulations = Run out-dated simulations when you open the simulation tab. pref.dlg.checkbox.Updateestimates = Update estimated flight parameters in design window +pref.dlg.checkbox.Markers = Only show pod set/booster markers when the pod set/booster is selected +pref.dlg.checkbox.Markers.ttip = If checked, pod set/booster markers will only be shown when the pod set/booster is selected.
If unchecked, pod set/booster markers will always be shown. pref.dlg.checkbox.AlwaysOpenLeftmost = Always open leftmost tab when opening a component edit dialog pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = If checked, a component edit dialog will always pop up with the first tab selected.
If unchecked, the previous selected tab will be used. pref.dlg.lbl.User-definedthrust = User-defined thrust curves: diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index 64f1de5a0..3d750c651 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -68,6 +68,7 @@ public abstract class Preferences implements ChangeSource { public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors"; private static final String AUTO_OPEN_LAST_DESIGN = "AUTO_OPEN_LAST_DESIGN"; private static final String OPEN_LEFTMOST_DESIGN_TAB = "OPEN_LEFTMOST_DESIGN_TAB"; + private static final String SHOW_MARKERS = "SHOW_MARKERS"; private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING"; //Preferences related to 3D graphics @@ -469,7 +470,26 @@ public abstract class Preferences implements ChangeSource { public final boolean isAlwaysOpenLeftmostTab() { return this.getBoolean(OPEN_LEFTMOST_DESIGN_TAB, false); } - + + /** + * Set whether pod set/booster markers should only be displayed when the pod set/booster is selected. + * @param enabled true if pod set/booster markers should only be displayed when the pod set/booster is selected, + * false if they should be displayed permanently. + */ + public final void setShowMarkers(boolean enabled) { + this.putBoolean(SHOW_MARKERS, enabled); + } + + /** + * Answer if pod set/booster markers should only be displayed when the pod set/booster is selected + * + * @return true if pod set/booster markers should only be displayed when the pod set/booster is selected, + * false if they should be displayed permanently. + */ + public final boolean isShowMarkers() { + return this.getBoolean(SHOW_MARKERS, false); + } + /** * Return the OpenRocket unique ID. * diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java index 08ef4acb1..3a98bd616 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java @@ -11,6 +11,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.gui.main.BasicFrame; import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.unit.UnitGroup; @@ -93,7 +94,6 @@ public class DesignPreferencesPanel extends PreferencesPanel { // // Always open leftmost tab when opening a component edit dialog final JCheckBox alwaysOpenLeftmostTab = new JCheckBox( trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost")); - alwaysOpenLeftmostTab.setSelected(preferences.isAlwaysOpenLeftmostTab()); alwaysOpenLeftmostTab.setToolTipText(trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost.ttip")); alwaysOpenLeftmostTab.addActionListener(new ActionListener() { @@ -103,7 +103,7 @@ public class DesignPreferencesPanel extends PreferencesPanel { .isSelected()); } }); - this.add(alwaysOpenLeftmostTab, "wrap, growx, span 2"); + this.add(alwaysOpenLeftmostTab, "wrap, growx, spanx"); // // Update flight estimates in the design window final JCheckBox updateEstimates = new JCheckBox( @@ -117,5 +117,23 @@ public class DesignPreferencesPanel extends PreferencesPanel { } }); this.add(updateEstimates, "wrap, growx, sg combos "); + + // // Only show pod set/booster markers when they are selected + final JCheckBox showMarkers = new JCheckBox( + trans.get("pref.dlg.checkbox.Markers")); + showMarkers.setToolTipText(trans.get("pref.dlg.checkbox.Markers.ttip")); + showMarkers.setSelected(preferences.isShowMarkers()); + showMarkers.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.setShowMarkers(showMarkers + .isSelected()); + // Update all BasicFrame rocket panel figures because it can change due to the preference change + for (BasicFrame frame : BasicFrame.getAllFrames()) { + frame.getRocketPanel().updateFigures(); + } + } + }); + this.add(showMarkers, "wrap, growx, spanx"); } } diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 04fdf9bf3..6f76a838d 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -117,7 +117,7 @@ public class BasicFrame extends JFrame { * List of currently open frames. When the list goes empty * it is time to exit the application. */ - private static final ArrayList frames = new ArrayList(); + private static final List frames = new ArrayList(); private static BasicFrame startupFrame = null; // the frame that was created at startup @@ -490,6 +490,10 @@ public class BasicFrame extends JFrame { return result; } + public RocketPanel getRocketPanel() { + return rocketpanel; + } + /** * Creates the menu for the window. */ @@ -1890,6 +1894,13 @@ public class BasicFrame extends JFrame { return null; } + /** + * Return all BasicFrame instances + */ + public static List getAllFrames() { + return frames; + } + /** * Checks whether all the BasicFrames are closed. * @return true if all the BasicFrames are closed, false if not diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index 39c18e025..6e4bf9e4b 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -54,6 +54,7 @@ import net.sf.openrocket.util.Transformation; public class RocketFigure extends AbstractScaleFigure { private final static Logger log = LoggerFactory.getLogger(FinPointFigure.class); + protected final SwingPreferences preferences = (SwingPreferences) Application.getPreferences(); private static final String ROCKET_FIGURE_PACKAGE = "net.sf.openrocket.gui.rocketfigure"; private static final String ROCKET_FIGURE_SUFFIX = "Shapes"; @@ -382,7 +383,7 @@ public class RocketFigure extends AbstractScaleFigure { final RocketComponent comp = entry.getKey(); // Only draw podsets when they are selected - if (comp instanceof PodSet || comp instanceof ParallelStage) { + if ((comp instanceof PodSet || comp instanceof ParallelStage) && preferences.isShowMarkers()) { boolean selected = false; // Check if component is in the selection diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 92df95906..9f4f309f7 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -252,7 +252,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change }); } - private void updateFigures() { + public void updateFigures() { if (!is3d) figure.updateFigure(); else