diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 8ed4c4f79..69831ccae 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -924,12 +924,14 @@ RocketCompCfg.but.Setforall = Set for all RocketCompCfg.but.ttip.Setforall = Set this finish for all components of the rocket. RocketCompCfg.checkbox.Overridemass = Override mass: RocketCompCfg.checkbox.Overridemass.ttip = Overrides the mass of the component calculated by the component's volume and density. -RocketCompCfg.checkbox.Overridecenterofgrav = Override center of gravity: -RocketCompCfg.checkbox.Overridecenterofgrav.ttip = Overrides the component's center of gravity location. -RocketCompCfg.checkbox.SetDragCoeff = Override coefficient of drag: -RocketCompCfg.checkbox.SetDragCoeff.ttip = Overrides the component's coefficient of drag. -RocketCompCfg.checkbox.OverrideSubcomponents = Override mass, CG, and CD of all subcomponents -RocketCompCfg.checkbox.OverrideSubcomponents.ttip = Overrides the aggregate mass, center of gravity (CG), and coefficient of drag (CD) of this component
and its subcomponents with the mass, CG, and CD of this component. +RocketCompCfg.checkbox.Overridecenterofgrav = Override center of gravity CG: +RocketCompCfg.checkbox.Overridecenterofgrav.ttip = Overrides the component's center of gravity (CG) location. +RocketCompCfg.checkbox.SetDragCoeff = Override coefficient of drag CD: +RocketCompCfg.checkbox.SetDragCoeff.ttip = Overrides the component's coefficient of drag CD. +RocketCompCfg.checkbox.OverrideSubcomponents = Override for all subcomponents +RocketCompCfg.checkbox.OverrideSubcomponents.Mass.ttip = Overrides the aggregate mass of this component
and its subcomponents with the mass of this component. +RocketCompCfg.checkbox.OverrideSubcomponents.CG.ttip = Overrides the center of gravity (CG) of this component
and its subcomponents with the CG of this component. +RocketCompCfg.checkbox.OverrideSubcomponents.CD.ttip = Overrides the coefficient of drag (CD) of this component
and its subcomponents with the CD of this component. RocketCompCfg.lbl.longB1 = The overridden mass and center of gravity does not include motors.
RocketCompCfg.lbl.longB2 = The center of gravity is measured from the front end of the RocketCompCfg.lbl.Commentsonthe = Comments on the diff --git a/core/resources/l10n/messages_cs.properties b/core/resources/l10n/messages_cs.properties index 3e9b5ea5f..619f8419d 100644 --- a/core/resources/l10n/messages_cs.properties +++ b/core/resources/l10n/messages_cs.properties @@ -642,7 +642,7 @@ RocketCompCfg.but.Setforall = Nastav pro v\u0161echny RocketCompCfg.but.ttip.Setforall = Nastav povrchovou úpravu pro v\u0161echny komponenty rakety. RocketCompCfg.checkbox.Overridemass = Zmen hmotnost: RocketCompCfg.checkbox.Overridecenterofgrav = Zmen te\u017Ei\u0161te: -RocketCompCfg.checkbox.OverrideSubcomponents = Zmen hmotnost a te\u017Ei\u0161te v\u0161ech komponent +RocketCompCfg.checkbox.OverrideSubcomponents = P\u0159eps\u00E1n\u00ED pro v\u0161echny d\u00EDl\u010D\u00ED sou\u010D\u00E1sti RocketCompCfg.lbl.longB1 = Zmena hmotnosti nezahrnuje motory.
RocketCompCfg.lbl.longB2 = Te\u017Ei\u0161te je mereno od predku RocketCompCfg.lbl.Commentsonthe = Komentár na diff --git a/core/resources/l10n/messages_es.properties b/core/resources/l10n/messages_es.properties index 7bfe090c5..3dee931c1 100644 --- a/core/resources/l10n/messages_es.properties +++ b/core/resources/l10n/messages_es.properties @@ -831,7 +831,7 @@ RocketCompCfg.but.ttip.Setforall = Aplicar este acabado a todos RocketCompCfg.checkbox.Endcapped = Extremo tapado RocketCompCfg.checkbox.Overridecenterofgrav = Especificar el CG: RocketCompCfg.checkbox.Overridemass = Especificar la masa: -RocketCompCfg.checkbox.OverrideSubcomponents = Incluir la masa y el CG de todos los subcomponentes +RocketCompCfg.checkbox.OverrideSubcomponents = Incluir de todos los subcomponentes RocketCompCfg.checkbox.Usedefaultcolor = Usar color por defecto RocketCompCfg.combo.ttip.componentmaterialaffects = El peso del componente depender\u00e1 del material seleccionado. RocketCompCfg.lbl.Choosecolor = Elija color diff --git a/core/resources/l10n/messages_fr.properties b/core/resources/l10n/messages_fr.properties index 210605775..0e9ea5cdb 100644 --- a/core/resources/l10n/messages_fr.properties +++ b/core/resources/l10n/messages_fr.properties @@ -823,7 +823,7 @@ RocketCompCfg.checkbox.Endcapped = Arri\u00E8re clos RocketCompCfg.checkbox.Overridecenterofgrav = Forcer le centre de gravit\u00E9: RocketCompCfg.checkbox.Overridecoeffofdrag = Modifier le coefficient de trainee: RocketCompCfg.checkbox.Overridemass = Forcer la masse: -RocketCompCfg.checkbox.OverrideSubcomponents = Forcer la masse et le centre de gravit\u00E9 de tous les sous composants +RocketCompCfg.checkbox.OverrideSubcomponents = Forcer pour tous les sous composants RocketCompCfg.checkbox.Usedefaultcolor = Utiliser la couleur par d\u00E9faut RocketCompCfg.combo.ttip.componentmaterialaffects = Les mat\u00E9riaux utilis\u00E9s pour la pi\u00E8ce affectent le poids de la pi\u00E8ce. RocketCompCfg.lbl.Choosecolor = Choisir la couleur diff --git a/core/resources/l10n/messages_it.properties b/core/resources/l10n/messages_it.properties index 784de45de..f8b4cb3f0 100644 --- a/core/resources/l10n/messages_it.properties +++ b/core/resources/l10n/messages_it.properties @@ -700,7 +700,7 @@ RocketCompCfg.but.Setforall = Imposta per tutti RocketCompCfg.but.ttip.Setforall = Imposta questa finitura per tutti i componenti del razzo. RocketCompCfg.checkbox.Overridemass = Modifica la massa: RocketCompCfg.checkbox.Overridecenterofgrav = Sposta il centro di gravita': -RocketCompCfg.checkbox.OverrideSubcomponents = Modifica la massa ed il CG di tutti i subcomponenti +RocketCompCfg.checkbox.OverrideSubcomponents = Modifica di tutti i subcomponenti RocketCompCfg.lbl.longB1 = La massa modificata non include i motori.
RocketCompCfg.lbl.longB2 = Il Centro di Gravita' e' misurato dall'inizio di RocketCompCfg.lbl.Commentsonthe = Commenti sul diff --git a/core/resources/l10n/messages_ja.properties b/core/resources/l10n/messages_ja.properties index 7286f837c..4b6f4f3ce 100644 --- a/core/resources/l10n/messages_ja.properties +++ b/core/resources/l10n/messages_ja.properties @@ -730,7 +730,7 @@ RocketCompCfg.but.Setforall = \u5168\u3066\u306B\u9069\u7528 RocketCompCfg.but.ttip.Setforall = \u3053\u306E\u4ED5\u4E0A\u3052\u65B9\u3092\u5168\u3066\u306E\u90E8\u54C1\u306B\u9069\u7528\u3059\u308B RocketCompCfg.checkbox.Overridemass = \u8CEA\u91CF\u306E\u518D\u5B9A\u7FA9\uFF1A RocketCompCfg.checkbox.Overridecenterofgrav = \u91CD\u5FC3\u306E\u518D\u5B9A\u7FA9\uFF1A -RocketCompCfg.checkbox.OverrideSubcomponents = \u5168\u3066\u306E\u30B5\u30D6\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306E\u8CEA\u91CF\u3068CG\u3092\u518D\u5B9A\u7FA9\uFF1A +RocketCompCfg.checkbox.OverrideSubcomponents = \u3059\u3079\u3066\u306e\u30b5\u30d6\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306b\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3059\u308b RocketCompCfg.lbl.longB1 = \u518D\u5B9A\u7FA9\u3055\u308C\u305F\u8CEA\u91CF\u306B\u306F\u30E2\u30FC\u30BF\u30FC\u306F\u542B\u307E\u308C\u306A\u3044
RocketCompCfg.lbl.longB2 = \u91CD\u5FC3\u306F\u90E8\u54C1\u306E\u524D\u65B9\u7AEF\u304B\u3089\u3001\u90E8\u54C1\uFF1A RocketCompCfg.lbl.Commentsonthe = \u30B3\u30E1\u30F3\u30C8\uFF1A diff --git a/core/resources/l10n/messages_nl.properties b/core/resources/l10n/messages_nl.properties index d1d153caf..a207ab420 100644 --- a/core/resources/l10n/messages_nl.properties +++ b/core/resources/l10n/messages_nl.properties @@ -851,7 +851,7 @@ RocketCompCfg.but.ttip.Setforall = Stel deze afwerking in voor alle onderdelen v RocketCompCfg.checkbox.Overridemass = Overschrijf massa: RocketCompCfg.checkbox.Overridecenterofgrav = Overschrijf zwaartepunt: RocketCompCfg.checkbox.SetDragCoeff = Stel wrijvingscoëfficiënt in: -RocketCompCfg.checkbox.OverrideSubcomponents = Massa en zwaartepunt van alle subonderdelen overschrijven +RocketCompCfg.checkbox.OverrideSubcomponents = Voor alle subonderdelen overschrijven RocketCompCfg.lbl.longB1 = De overschreven massa omvat geen motoren.
RocketCompCfg.lbl.longB2 = Het zwaartepunt wordt gemeten vanaf de voorkant van de RocketCompCfg.lbl.Commentsonthe = Opmerkingen over de diff --git a/core/resources/l10n/messages_pl.properties b/core/resources/l10n/messages_pl.properties index f3cbe0a19..3b5bd6b0e 100644 --- a/core/resources/l10n/messages_pl.properties +++ b/core/resources/l10n/messages_pl.properties @@ -644,7 +644,7 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s. RocketCompCfg.but.ttip.Setforall = Nadaj to wyko\u0144czenie wszystkim cz\u0119\u015Bci\u0105 sk\u0142adow\u0105 rakiety. RocketCompCfg.checkbox.Overridemass = Wymu\u015B ci\u0119\u017Car: RocketCompCfg.checkbox.Overridecenterofgrav = Wymu\u015B \u015Brodek ci\u0119\u017Cko\u015Bci: - RocketCompCfg.checkbox.OverrideSubcomponents = Wymu\u015B ci\u0119\u017Car oraz \u015Brodek ci\u0119\u017Cko\u015Bci wszystkich dodatkowych cz\u0119\u015Bci sk\u0142adowych + RocketCompCfg.checkbox.OverrideSubcomponents = Nadpisanie dla wszystkich podkomponent\u00F3w RocketCompCfg.lbl.longB1 = Wymuszony ci\u0119\u017Car nie uwzgl\u0119dnia silników.
RocketCompCfg.lbl.longB2 = \u015Arodek ci\u0119\u017Cko\u015Bci jest mierzony od przodu RocketCompCfg.lbl.Commentsonthe = Uwagi - diff --git a/core/resources/l10n/messages_pt.properties b/core/resources/l10n/messages_pt.properties index 67a3df719..af3120d63 100644 --- a/core/resources/l10n/messages_pt.properties +++ b/core/resources/l10n/messages_pt.properties @@ -809,7 +809,7 @@ RocketCompCfg.checkbox.Endcapped = Fim tampado RocketCompCfg.checkbox.Overridecenterofgrav = Modificar o centro de gravidade: RocketCompCfg.checkbox.Overridecoeffofdrag = Modificar o coeficiente de arrasto: RocketCompCfg.checkbox.Overridemass = Modificar massa: -RocketCompCfg.checkbox.OverrideSubcomponents = Modificar a massa e o CG de todos os subcomponentes +RocketCompCfg.checkbox.OverrideSubcomponents = Modificar de todos os subcomponentes RocketCompCfg.checkbox.Usedefaultcolor = Use a cor padr\u00e3o RocketCompCfg.combo.ttip.componentmaterialaffects = O material do componente afeta o peso do componente. RocketCompCfg.lbl.Choosecolor = Escolha a cor diff --git a/core/resources/l10n/messages_uk_UA.properties b/core/resources/l10n/messages_uk_UA.properties index e0745534d..4dd2ea040 100644 --- a/core/resources/l10n/messages_uk_UA.properties +++ b/core/resources/l10n/messages_uk_UA.properties @@ -802,7 +802,7 @@ RocketCompCfg.but.ttip.Setforall = Set this finish for all components of the roc RocketCompCfg.checkbox.Overridemass = Override mass: RocketCompCfg.checkbox.Overridecenterofgrav = Override center of gravity: RocketCompCfg.checkbox.Overridecoeffofdrag = Override coefficient of drag: -RocketCompCfg.checkbox.OverrideSubcomponents = Override mass and CG of all subcomponents +RocketCompCfg.checkbox.OverrideSubcomponents = Override for all subcomponents RocketCompCfg.lbl.longB1 = The overridden mass does not include motors.
RocketCompCfg.lbl.longB2 = The center of gravity is measured from the front end of the RocketCompCfg.lbl.Commentsonthe = Comments on the diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java index 3cc791d79..0aa872706 100644 --- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java @@ -46,6 +46,7 @@ public class OpenRocketSaver extends RocketSaver { private static final String METHOD_PACKAGE = "net.sf.openrocket.file.openrocket.savers"; private static final String METHOD_SUFFIX = "Saver"; + public static final String INDENT = " "; // Estimated storage used by different portions @@ -636,10 +637,7 @@ public class OpenRocketSaver extends RocketSaver { dest.write("\n"); return; } - String s = ""; - for (int i = 0; i < indent; i++) - s = s + " "; - s = s + str + "\n"; + String s = INDENT.repeat(Math.max(0, indent)) + str + "\n"; dest.write(s); } diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java index 89bb2fd6d..dfc6b40d1 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java @@ -40,7 +40,8 @@ class ComponentParameterHandler extends AbstractElementHandler { if ( element.equals("appearance")) { return new AppearanceHandler(component,context); } - if (element.equals("inside-appearance")) { + // TODO: delete 'inside-appearance' when backward compatibility with 22.02.beta.01-22.02.beta.05 is not needed anymore + if (element.equals("insideappearance") || element.equals("inside-appearance")) { return new InsideAppearanceHandler(component, context); } if (element.equals("motormount")) { @@ -92,10 +93,11 @@ class ComponentParameterHandler extends AbstractElementHandler { @Override public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) { - + + // TODO: delete 'inside-appearance' when backward compatibility with 22.02.beta.01-22.02.beta.05 is not needed anymore if (element.equals("subcomponents") || element.equals("motormount") || element.equals("finpoints") || element.equals("motorconfiguration") || - element.equals("appearance") || element.equals("inside-appearance") || + element.equals("appearance") || element.equals("insideappearance") || element.equals("inside-appearance") || element.equals("deploymentconfiguration") || element.equals("separationconfiguration")) { return; } diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java index 60a20db09..3fe4093e6 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java @@ -129,8 +129,16 @@ class DocumentConfig { setters.put("RocketComponent:overridecd", new OverrideSetter( Reflection.findMethod(RocketComponent.class, "setOverrideCD", double.class), Reflection.findMethod(RocketComponent.class, "setCDOverridden", boolean.class))); + // TODO: delete overridesubcomponents setters if no compatibility is needed anymore with OR 15.03 setters.put("RocketComponent:overridesubcomponents", new BooleanSetter( Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverridden", boolean.class))); + + setters.put("RocketComponent:overridesubcomponentsmass", new BooleanSetter( + Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverriddenMass", boolean.class))); + setters.put("RocketComponent:overridesubcomponentscg", new BooleanSetter( + Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverriddenCG", boolean.class))); + setters.put("RocketComponent:overridesubcomponentscd", new BooleanSetter( + Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverriddenCD", boolean.class))); setters.put("RocketComponent:comment", new StringSetter( Reflection.findMethod(RocketComponent.class, "setComment", String.class))); setters.put("RocketComponent:preset", new ComponentPresetSetter( diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/InsideAppearanceHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/InsideAppearanceHandler.java index 3bbaee47e..9940a30cb 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/InsideAppearanceHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/InsideAppearanceHandler.java @@ -21,13 +21,15 @@ public class InsideAppearanceHandler extends AppearanceHandler { @Override public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { - if ("edgesSameAsInside".equals(element)) { + // TODO: delete 'edgesSameAsInside' when backward compatibility with 22.02.beta.01-22.02.beta.05 is not needed anymore + if ("edgessameasinside".equals(element) || "edgesSameAsInside".equals(element)) { boolean edgesSameAsInside = Boolean.parseBoolean(content); if (component instanceof InsideColorComponent) ((InsideColorComponent)component).getInsideColorComponentHandler().setEdgesSameAsInside(edgesSameAsInside); return; } - if ("insideSameAsOutside".equals(element)) { + // TODO: delete 'insideSameAsOutside' when backward compatibility with 22.02.beta.01-22.02.beta.05 is not needed anymore + if ("insidesameasoutside".equals(element) || "insideSameAsOutside".equals(element)) { boolean insideSameAsOutside = Boolean.parseBoolean(content); if (component instanceof InsideColorComponent) ((InsideColorComponent)component).getInsideColorComponentHandler().setSeparateInsideOutside(insideSameAsOutside); diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java index 9e45ee05f..5b273dff7 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java @@ -9,6 +9,7 @@ import java.util.Map; import net.sf.openrocket.appearance.Appearance; import net.sf.openrocket.appearance.Decal; import net.sf.openrocket.appearance.Decal.EdgeMode; +import net.sf.openrocket.file.openrocket.OpenRocketSaver; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.material.Material; import net.sf.openrocket.motor.Motor; @@ -56,18 +57,18 @@ public class RocketComponentSaver { InsideColorComponentHandler handler = ((InsideColorComponent)c).getInsideColorComponentHandler(); Appearance ap_in = handler.getInsideAppearance(); if (ap_in != null) { - elements.add(""); - elements.add("" + handler.isEdgesSameAsInside() + ""); - elements.add("" + handler.isSeparateInsideOutside() + ""); + elements.add(""); + appendElement(elements, "edgessameasinside", handler.isEdgesSameAsInside(), 1); + appendElement(elements, "insidesameasoutside", handler.isSeparateInsideOutside(), 1); buildAppearanceElements(elements, ap_in); - elements.add(""); + elements.add(""); } } // Save color and line style if significant if (!(c instanceof Rocket || c instanceof ComponentAssembly)) { Color color = c.getColor(); - emitColor("color", elements, color); + emitColor("color", elements, color, 0); LineStyle style = c.getLineStyle(); if (style != null) { @@ -128,22 +129,20 @@ public class RocketComponentSaver { } // Overrides - boolean overridden = false; if (c.isMassOverridden()) { elements.add("" + c.getOverrideMass() + ""); - overridden = true; + elements.add("" + c.isSubcomponentsOverriddenMass() + + ""); } if (c.isCGOverridden()) { elements.add("" + c.getOverrideCGX() + ""); - overridden = true; + elements.add("" + c.isSubcomponentsOverriddenCG() + + ""); } if (c.isCDOverridden()) { elements.add("" + c.getOverrideCD() + ""); - overridden = true; - } - if (overridden) { - elements.add("" + c.isSubcomponentsOverridden() - + ""); + elements.add("" + c.isSubcomponentsOverriddenCD() + + ""); } @@ -156,21 +155,21 @@ public class RocketComponentSaver { private void buildAppearanceElements(List elements, Appearance a) { Color paint = a.getPaint(); - emitColor("paint", elements, paint); - elements.add("" + a.getShine() + ""); + emitColor("paint", elements, paint, 1); + appendElement(elements, "shine", a.getShine(), 1); Decal decal = a.getTexture(); if (decal != null) { String name = decal.getImage().getName(); double rotation = decal.getRotation(); EdgeMode edgeMode = decal.getEdgeMode(); - elements.add(""); + elements.add(OpenRocketSaver.INDENT + ""); Coordinate center = decal.getCenter(); - elements.add("
"); + elements.add(OpenRocketSaver.INDENT.repeat(2) + "
"); Coordinate offset = decal.getOffset(); - elements.add(""); + elements.add(OpenRocketSaver.INDENT.repeat(2) + ""); Coordinate scale = decal.getScale(); - elements.add(""); - elements.add(""); + elements.add(OpenRocketSaver.INDENT.repeat(2) + ""); + elements.add(OpenRocketSaver.INDENT + ""); } } @@ -270,12 +269,11 @@ public class RocketComponentSaver { return elements; } - private final static void emitColor(String elementName, List elements, Color color) { + private final static void emitColor(String elementName, List elements, Color color, int indents) { if (color != null) { - elements.add("<" + elementName + " red=\"" + color.getRed() + "\" green=\"" + color.getGreen() + elements.add(OpenRocketSaver.INDENT.repeat(Math.max(0, indents)) + "<" + elementName + " red=\"" + color.getRed() + "\" green=\"" + color.getGreen() + "\" blue=\"" + color.getBlue() + "\" alpha=\"" + color.getAlpha() + "\"/>"); } - } protected static void emitDouble( final List elements, final String enclosingTag, final double value){ @@ -302,8 +300,20 @@ public class RocketComponentSaver { return buf.toString(); } + protected static void appendElement( final List elements, final String openTag, final String closeTag, final String elementValue, final int indents){ + elements.add(OpenRocketSaver.INDENT.repeat(Math.max(0, indents)) + "<"+openTag+">" + elementValue + ""); + } + + protected static void appendElement( final List elements, final String tag, final double elementValue, final int indents){ + appendElement(elements, tag, tag, Double.toString(elementValue), indents); + } + + protected static void appendElement( final List elements, final String tag, final boolean elementValue, final int indents){ + appendElement(elements, tag, tag, Boolean.toString(elementValue), indents); + } + protected static void appendElement( final List elements, final String openTag, final String closeTag, final String elementValue ){ - elements.add("<"+openTag+">" + elementValue + ""); + appendElement(elements, openTag, closeTag, elementValue, 0); } } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java index 9eafaad71..a3ca432fb 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java @@ -175,7 +175,8 @@ public abstract class BaseHandler extends AbstractEle if (override) { component.setCGOverridden(override); component.setMassOverridden(override); - component.setSubcomponentsOverridden(false); //Rocksim does not support this type of override + component.setSubcomponentsOverriddenMass(false); //Rocksim does not support this type of override + component.setSubcomponentsOverriddenCG(false); //Rocksim does not support this type of override component.setOverrideMass(mass); component.setOverrideCGX(cg); } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java index 2dd64e5ea..a2692bc8c 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java @@ -208,12 +208,12 @@ class RocketDesignHandler extends AbstractElementHandler { final AxialStage stage = new AxialStage(); if (stage3Mass > 0.0d) { stage.setMassOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenMass(true); //Rocksim does not support this type of override stage.setOverrideMass(stage3Mass); } if (stage3CG > 0.0d) { stage.setCGOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenCG(true); //Rocksim does not support this type of override stage.setOverrideCGX(stage3CG); } component.addChild(stage); @@ -224,12 +224,12 @@ class RocketDesignHandler extends AbstractElementHandler { final AxialStage stage = new AxialStage(); if (stage2Mass > 0.0d) { stage.setMassOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenMass(true); //Rocksim does not support this type of override stage.setOverrideMass(stage2Mass); } if (stage2CG > 0.0d) { stage.setCGOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenCG(true); //Rocksim does not support this type of override stage.setOverrideCGX(stage2CG); } component.addChild(stage); @@ -241,12 +241,12 @@ class RocketDesignHandler extends AbstractElementHandler { final AxialStage stage = new AxialStage(); if (stage1Mass > 0.0d) { stage.setMassOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenMass(true); //Rocksim does not support this type of override stage.setOverrideMass(stage1Mass); } if (stage1CG > 0.0d) { stage.setCGOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenCG(true); //Rocksim does not support this type of override stage.setOverrideCGX(stage1CG); } component.addChild(stage); diff --git a/core/src/net/sf/openrocket/masscalc/MassCalculation.java b/core/src/net/sf/openrocket/masscalc/MassCalculation.java index 70c14e1b9..cc925053b 100644 --- a/core/src/net/sf/openrocket/masscalc/MassCalculation.java +++ b/core/src/net/sf/openrocket/masscalc/MassCalculation.java @@ -355,16 +355,16 @@ public class MassCalculation { // setting zero as the CG position means the top of the component, which is component.getPosition() final Coordinate compZero = parentTransform.transform( component.getPosition() ); - if (component.isSubcomponentsOverridden()) { - if( component.isMassive() ){ + if (component.isSubcomponentsOverriddenMass() || component.isSubcomponentsOverriddenCG()) { + if (component.isMassive()) { // if this component mass, merge it in before overriding: this.addMass( compCM ); } - if (component.isMassOverridden()) { + if (component.isSubcomponentsOverriddenMass() && component.isMassOverridden()) { this.setCM( this.getCM().setWeight(component.getOverrideMass()) ); } - if (component.isCGOverridden()) { - this.setCM( this.getCM().setX( compZero.x + component.getOverrideCGX())); + if (component.isSubcomponentsOverriddenCG() && component.isCGOverridden()) { + this.setCM( this.getCM().setX(compZero.x + component.getOverrideCGX())); } }else { if (component.isMassOverridden()) { diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 1e165d81e..77301a62d 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -99,15 +99,17 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab // Override mass/CG/CD protected double overrideMass = 0; protected boolean massOverridden = false; + private boolean overrideSubcomponentsMass = false; private double overrideCGX = 0; private boolean cgOverridden = false; + private boolean overrideSubcomponentsCG = false; private double overrideCD = 0; private boolean cdOverridden = false; + private boolean overrideSubcomponentsCD = false; private boolean cdOverriddenByAncestor = false; - private boolean overrideSubcomponents = false; // User-given name of the component @@ -707,7 +709,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab this.overrideCD = x; if (isCDOverridden()) { - if (isSubcomponentsOverridden()) { + if (isSubcomponentsOverriddenCD()) { overrideSubcomponentsCD(true); } fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); @@ -749,7 +751,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab // tree. If we are overriding our own CD, we need to override all // our descendants. If we are not overriding our own CD, we are // also not overriding our descendants - if (isSubcomponentsOverridden()) { + if (isSubcomponentsOverriddenCD()) { overrideSubcomponentsCD(o); } @@ -777,28 +779,107 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * * @return whether the current mass, CG, and/or CD override overrides subcomponents as well. */ - public boolean isSubcomponentsOverridden() { + public boolean isSubcomponentsOverriddenMass() { mutex.verify(); - return overrideSubcomponents; + return overrideSubcomponentsMass; + } + + // TODO: delete no compatibility is needed anymore with OR 15.03 + public void setSubcomponentsOverridden(boolean override) { + setSubcomponentsOverriddenMass(override); + setSubcomponentsOverriddenCG(override); + setSubcomponentsOverriddenCD(override); } /** * Set whether the mass and/or CG override overrides all subcomponent values - * as well. See {@link #isSubcomponentsOverridden()} for details. + * as well. See {@link #isSubcomponentsOverriddenMass()} for details. * * @param override whether the mass and/or CG override overrides all subcomponent. */ - public void setSubcomponentsOverridden(boolean override) { + public void setSubcomponentsOverriddenMass(boolean override) { for (RocketComponent listener : configListeners) { - listener.setSubcomponentsOverridden(override); + listener.setSubcomponentsOverriddenMass(override); } - if (overrideSubcomponents == override) { + if (overrideSubcomponentsMass == override) { return; } checkState(); - overrideSubcomponents = override; + overrideSubcomponentsMass = override; + + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } + + /** + * Return whether the CG override overrides all subcomponent values + * as well. The default implementation is a normal getter/setter implementation, + * however, subclasses are allowed to override this behavior if some subclass + * always or never overrides subcomponents. In this case the subclass should + * also override {@link #isOverrideSubcomponentsEnabled()} to return + * false. + * + * @return whether the current CG override overrides subcomponents as well. + */ + public boolean isSubcomponentsOverriddenCG() { + mutex.verify(); + return overrideSubcomponentsCG; + } + + + /** + * Set whether the mass and/or CG override overrides all subcomponent values + * as well. See {@link #isSubcomponentsOverriddenCG()} for details. + * + * @param override whether the mass and/or CG override overrides all subcomponent. + */ + public void setSubcomponentsOverriddenCG(boolean override) { + for (RocketComponent listener : configListeners) { + listener.setSubcomponentsOverriddenCG(override); + } + + if (overrideSubcomponentsCG == override) { + return; + } + checkState(); + overrideSubcomponentsCG = override; + + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } + + /** + * Return whether the CD override overrides all subcomponent values + * as well. The default implementation is a normal getter/setter implementation, + * however, subclasses are allowed to override this behavior if some subclass + * always or never overrides subcomponents. In this case the subclass should + * also override {@link #isOverrideSubcomponentsEnabled()} to return + * false. + * + * @return whether the current CD override overrides subcomponents as well. + */ + public boolean isSubcomponentsOverriddenCD() { + mutex.verify(); + return overrideSubcomponentsCD; + } + + + /** + * Set whether the CD override overrides all subcomponent values + * as well. See {@link #isSubcomponentsOverriddenCD()} for details. + * + * @param override whether the CD override overrides all subcomponent. + */ + public void setSubcomponentsOverriddenCD(boolean override) { + for (RocketComponent listener : configListeners) { + listener.setSubcomponentsOverriddenCD(override); + } + + if (overrideSubcomponentsCD == override) { + return; + } + checkState(); + overrideSubcomponentsCD = override; overrideSubcomponentsCD(override); @@ -815,7 +896,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * If we are setting the override false, descend the component tree marking every * component as not overridden by ancestor. * If in the course of descending the tree we encounter a descendant whose direct - * CD override and overridesubcomponents flags are both true, descend from there + * CD override and overrideSubcomponentsCD flags are both true, descend from there * setting the ancestoroverride from that component * * @param override whether setting or clearing overrides @@ -827,7 +908,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab c.cdOverriddenByAncestor = override; - if (!override && c.isCDOverridden() && c.isSubcomponentsOverridden()) { + if (!override && c.isCDOverridden() && c.isSubcomponentsOverriddenCD()) { c.overrideSubcomponentsCD(true); } else { c.overrideSubcomponentsCD(override); @@ -2334,7 +2415,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab this.overrideCGX = src.overrideCGX; this.cgOverridden = src.cgOverridden; this.cdOverriddenByAncestor = src.cdOverriddenByAncestor; - this.overrideSubcomponents = src.overrideSubcomponents; + this.overrideSubcomponentsMass = src.overrideSubcomponentsMass; + this.overrideSubcomponentsCG = src.overrideSubcomponentsCG; + this.overrideSubcomponentsCD = src.overrideSubcomponentsCD; this.name = src.name; this.comment = src.comment; this.id = src.id; diff --git a/core/src/net/sf/openrocket/util/TestRockets.java b/core/src/net/sf/openrocket/util/TestRockets.java index 52fa2c96a..6ac2328bd 100644 --- a/core/src/net/sf/openrocket/util/TestRockets.java +++ b/core/src/net/sf/openrocket/util/TestRockets.java @@ -345,7 +345,8 @@ public class TestRockets { c.setMassOverridden(rnd.nextBoolean()); c.setOverrideCGX(rnd(0.2)); c.setOverrideMass(rnd(0.05)); - c.setSubcomponentsOverridden(rnd.nextBoolean()); + c.setSubcomponentsOverriddenMass(rnd.nextBoolean()); + c.setSubcomponentsOverriddenCG(rnd.nextBoolean()); if (c.isMassive()) { // Only massive components are drawn diff --git a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java index 9ee1587ce..6c89ed6eb 100644 --- a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java +++ b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java @@ -81,7 +81,7 @@ public class MassCalculatorTest extends BaseTestCase { // if we use a mass override, setting to same mass, we should get same result AxialStage sustainer = (AxialStage) rocket.getChild(0); - sustainer.setSubcomponentsOverridden(true); + sustainer.setSubcomponentsOverriddenMass(true); sustainer.setMassOverridden(true); sustainer.setOverrideMass(actualRocketDryMass); @@ -219,7 +219,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(expCMx, actualRocketDryCM.x, EPSILON); } - boosterStage.setSubcomponentsOverridden(true); + boosterStage.setSubcomponentsOverriddenCG(true); boosterStage.setCGOverridden(true); boosterStage.setOverrideCGX(0.0); @@ -260,7 +260,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(0.05, actualRocketDryCM.x, EPSILON); } - sustainerStage.setSubcomponentsOverridden(true); + sustainerStage.setSubcomponentsOverriddenMass(true); sustainerStage.setMassOverridden(true); sustainerStage.setOverrideMass(0.001); // something small, but not zero @@ -302,7 +302,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(0.10, actualStructure.cm.x, EPSILON); } - boosterStage.setSubcomponentsOverridden(true); + boosterStage.setSubcomponentsOverriddenMass(true); boosterStage.setMassOverridden(true); boosterStage.setOverrideMass(0.001); // something small, but not zero @@ -346,7 +346,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(expCMx, actualRocketDryCM.x, EPSILON); } - boosterBody.setSubcomponentsOverridden(false); + boosterBody.setSubcomponentsOverriddenCG(false); boosterBody.setCGOverridden(true); boosterBody.setOverrideCGX(0.0); @@ -395,7 +395,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(expCMx, actualRocketDryCM.x, EPSILON); } - boosterBody.setSubcomponentsOverridden(false); + boosterBody.setSubcomponentsOverriddenMass(false); boosterBody.setMassOverridden(true); boosterBody.setOverrideMass(0.001); @@ -409,7 +409,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(0.06976699, actualRocketDryCM.x, EPSILON); } - boosterBody.setSubcomponentsOverridden(true); // change. Also, this body lacks subcomponents. + boosterBody.setSubcomponentsOverriddenMass(true); // change. Also, this body lacks subcomponents. boosterBody.setMassOverridden(true); // repeat boosterBody.setOverrideMass(0.001); // repeat @@ -973,9 +973,10 @@ public class MassCalculatorTest extends BaseTestCase { final AxialStage coreStage = (AxialStage) rocket.getChild(1); final ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0); final double overrideMass = 0.5; - boosters.setSubcomponentsOverridden(true); + boosters.setSubcomponentsOverriddenMass(true); boosters.setMassOverridden(true); boosters.setOverrideMass(overrideMass); + boosters.setSubcomponentsOverriddenCG(true); boosters.setCGOverridden(true); boosters.setOverrideCGX(6.0); @@ -1140,7 +1141,7 @@ public class MassCalculatorTest extends BaseTestCase { fins.setName("podFins"); fins.setThickness(0.01); fins.setMassOverridden(true); fins.setOverrideMass(0.02835); - fins.setSubcomponentsOverridden(false); + fins.setSubcomponentsOverriddenMass(false); fins.setAxialOffset(-0.01); fins.setAxialMethod(AxialMethod.BOTTOM); podBody.addChild(fins); @@ -1207,12 +1208,12 @@ public class MassCalculatorTest extends BaseTestCase { // if we use a mass override, setting to same mass, we should get same result AxialStage sustainerRef = (AxialStage) rocketRef.getChild(0); - sustainerRef.setSubcomponentsOverridden(true); + sustainerRef.setSubcomponentsOverriddenMass(true); sustainerRef.setMassOverridden(true); sustainerRef.setOverrideMass(rocketDryMassRef); AxialStage sustainer = (AxialStage) rocket.getChild(0); - sustainer.setSubcomponentsOverridden(true); + sustainer.setSubcomponentsOverriddenMass(true); sustainer.setMassOverridden(true); sustainer.setOverrideMass(rocketDryMass); diff --git a/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java b/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java index f8e343832..8e17dfa71 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java @@ -54,7 +54,8 @@ public class FreeformFinSetTest extends BaseTestCase { sourceSet.setMaterial(Material.newMaterial(Type.BULK, "test-material", 0.1, true)); sourceSet.setOverrideCGX(0.012); sourceSet.setOverrideMass(0.0123); - sourceSet.setSubcomponentsOverridden(true); + sourceSet.setSubcomponentsOverriddenMass(true); + sourceSet.setSubcomponentsOverriddenCG(true); sourceSet.setAxialMethod(AxialMethod.ABSOLUTE); sourceSet.setAxialOffset(0.1); sourceSet.setTabHeight(0.01); @@ -196,7 +197,8 @@ public class FreeformFinSetTest extends BaseTestCase { } assertEquals(0.012, finSet.getOverrideCGX(), EPSILON); assertEquals(0.0123, finSet.getOverrideMass(), EPSILON); - assertTrue(finSet.isSubcomponentsOverridden()); + assertTrue(finSet.isSubcomponentsOverriddenMass()); + assertTrue(finSet.isSubcomponentsOverriddenCG()); assertEquals(AxialMethod.ABSOLUTE, finSet.getAxialMethod()); assertEquals(0.1, finSet.getAxialOffset(), EPSILON); @@ -232,7 +234,8 @@ public class FreeformFinSetTest extends BaseTestCase { } assertEquals(0.012, finSet.getOverrideCGX(), EPSILON); assertEquals(0.0123, finSet.getOverrideMass(), EPSILON); - assertTrue(finSet.isSubcomponentsOverridden()); + assertTrue(finSet.isSubcomponentsOverriddenMass()); + assertTrue(finSet.isSubcomponentsOverriddenCG()); assertEquals(AxialMethod.ABSOLUTE, finSet.getAxialMethod()); assertEquals(0.1, finSet.getAxialOffset(), EPSILON); diff --git a/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java b/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java index 36ff91df0..aaad470bb 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java @@ -65,19 +65,19 @@ public class OverrideTest extends BaseTestCase { // We start by just checking the override flags // Initially no overrides assertFalse(sustainer.isCDOverridden()); - assertFalse(sustainer.isSubcomponentsOverridden()); + assertFalse(sustainer.isSubcomponentsOverriddenCD()); assertFalse(sustainer.isCDOverriddenByAncestor()); assertFalse(bodytube.isCDOverridden()); - assertFalse(bodytube.isSubcomponentsOverridden()); + assertFalse(bodytube.isSubcomponentsOverriddenCD()); assertFalse(bodytube.isCDOverriddenByAncestor()); assertFalse(finset.isCDOverridden()); - assertFalse(finset.isSubcomponentsOverridden()); + assertFalse(finset.isSubcomponentsOverriddenCD()); assertFalse(finset.isCDOverriddenByAncestor()); // Override sustainer CD and subcomponents - sustainer.setSubcomponentsOverridden(true); + sustainer.setSubcomponentsOverriddenCD(true); sustainer.setCDOverridden(true); sustainer.setOverrideCD(0.5); @@ -87,7 +87,7 @@ public class OverrideTest extends BaseTestCase { // Set body tube to override subcomponents, override its CD; it's still // overridden by ancestor bodytube.setCDOverridden(true); - bodytube.setSubcomponentsOverridden(true); + bodytube.setSubcomponentsOverriddenCD(true); bodytube.setOverrideCD(0.25); assertTrue(bodytube.isCDOverriddenByAncestor()); @@ -103,7 +103,7 @@ public class OverrideTest extends BaseTestCase { assertEquals(sustainer.getOverrideCD(), forces.getCD(), MathUtil.EPSILON); // Turn off sustainer subcomponents override; body tube and nose cone aren't overridden by ancestor but fin set is - sustainer.setSubcomponentsOverridden(false); + sustainer.setSubcomponentsOverriddenCD(false); // CD of rocket should be overridden CD of sustainer plus body tube plus calculated CD of nose cone Map forceMap = calc.getForceAnalysis(configuration, conditions, warnings); diff --git a/fileformat.txt b/fileformat.txt index 1810335a7..6b7f385cb 100644 --- a/fileformat.txt +++ b/fileformat.txt @@ -50,3 +50,14 @@ The following file format versions exist: 1.7: Introduced with OpenRocket 15.03. Added simulation extensions and related configuration. Support for TubeFins. + +1.8: Introduced with OpenRocket 22.02. + Added new RailButton (, Pods (), and Booster () components + Added separate internal appearance option () for Body Tubes, Nose Cones, + Transitions, Inner Tubes, Launch Lugs, and Fins. + Added PhotoStudio settings saving () + Added override CD parameter () + Separated into individual parameters for mass, CG, and CD. + Rename to ( remains for backward compatibility) + Rename to ( remains for backward compatibility) + Rename to ( remains for backward compatibility) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index 628d54f38..de4777116 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -4,6 +4,7 @@ package net.sf.openrocket.gui.configdialog; import java.awt.Color; import java.awt.Component; import java.awt.Container; +import java.awt.Font; import java.awt.event.*; import java.util.ArrayList; import java.util.Iterator; @@ -236,7 +237,7 @@ public class RocketComponentConfig extends JPanel { } for (RocketComponent c = component.getParent(); c != null; c = c.getParent()) { - if (c.isMassOverridden() && c.isSubcomponentsOverridden()) { + if (c.isMassOverridden() && c.isSubcomponentsOverriddenMass()) { overridetext = trans.get("RocketCompCfg.lbl.overriddenby") + " " + c.getName() + ")"; } } @@ -359,14 +360,28 @@ public class RocketComponentConfig extends JPanel { BasicSlider bs; // OVERRIDE MASS ---------------------------------- - + JPanel checkboxes = new JPanel(new MigLayout("inset 0")); bm = new BooleanModel(component, "MassOverridden"); check = new JCheckBox(bm); //// Override mass: check.setText(trans.get("RocketCompCfg.checkbox.Overridemass")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Overridemass.ttip")); - panel.add(check, "growx 1, gapright 20lp"); + checkboxes.add(check, "wrap"); order.add(check); + + ////// Override subcomponents + BooleanModel bmSubcomp = new BooleanModel(component, "SubcomponentsOverriddenMass"); + check = new JCheckBox(bmSubcomp); + check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); + Font smallFont = check.getFont(); + smallFont = smallFont.deriveFont(smallFont.getSize2D() - 1); + check.setFont(smallFont); + check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.Mass.ttip")); + bm.addEnableComponent(check, true); + checkboxes.add(check, "gapleft 25lp, wrap"); + order.add(check); + + panel.add(checkboxes, "growx 1, gapright 20lp"); DoubleModel m = new DoubleModel(component, "OverrideMass", UnitGroup.UNITS_MASS, 0); @@ -383,18 +398,30 @@ public class RocketComponentConfig extends JPanel { bs = new BasicSlider(m.getSliderModel(0, 0.03, 1.0)); bm.addEnableComponent(bs); panel.add(bs, "growx 5, w 100lp, wrap"); - + // END OVERRIDE MASS ---------------------------------- // OVERRIDE CG ---------------------------------- - + checkboxes = new JPanel(new MigLayout("inset 0")); bm = new BooleanModel(component, "CGOverridden"); check = new JCheckBox(bm); //// Override center of gravity:" check.setText(trans.get("RocketCompCfg.checkbox.Overridecenterofgrav")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Overridecenterofgrav.ttip")); - panel.add(check, "growx 1, gapright 20lp"); + checkboxes.add(check, "wrap"); order.add(check); + + ////// Override subcomponents + bmSubcomp = new BooleanModel(component, "SubcomponentsOverriddenCG"); + check = new JCheckBox(bmSubcomp); + check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); + check.setFont(smallFont); + check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.CG.ttip")); + bm.addEnableComponent(check, true); + checkboxes.add(check, "gapleft 25lp, wrap"); + order.add(check); + + panel.add(checkboxes, "growx 1, gapright 20lp"); m = new DoubleModel(component, "OverrideCGX", UnitGroup.UNITS_LENGTH, 0); // Calculate suitable length for slider @@ -441,46 +468,47 @@ public class RocketComponentConfig extends JPanel { bs = new BasicSlider(m.getSliderModel(new DoubleModel(0), length)); bm.addEnableComponent(bs); panel.add(bs, "growx 5, w 100lp, wrap"); - // END OVERRIDE CG --------------------------------------------------- - // BEGIN OVERRIDE CD ------------------------------------------ + // BEGIN OVERRIDE CD ------------------------------------------ + checkboxes = new JPanel(new MigLayout("inset 0")); bm = new BooleanModel(component, "CDOverridden"); check = new JCheckBox(bm); //// Override coefficient of drag: check.setText(trans.get("RocketCompCfg.checkbox.SetDragCoeff")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.SetDragCoeff.ttip")); - panel.add(check, "growx 1, gapright 20lp"); + checkboxes.add(check, "wrap"); order.add(check); + + ////// Override subcomponents + bmSubcomp = new BooleanModel(component, "SubcomponentsOverriddenCD"); + check = new JCheckBox(bmSubcomp); + check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); + check.setFont(smallFont); + check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.CD.ttip")); + bm.addEnableComponent(check, true); + checkboxes.add(check, "gapleft 25lp, wrap"); + order.add(check); + + panel.add(checkboxes, "growx 1, gapright 20lp"); m = new DoubleModel(component, "OverrideCD", UnitGroup.UNITS_COEFFICIENT, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); bm.addEnableComponent(spin, true); - panel.add(spin, "growx 1"); + panel.add(spin, "top, growx 1"); order.add(((SpinnerEditor) spin.getEditor()).getTextField()); bs = new BasicSlider(m.getSliderModel(-1.0, 1.0)); bm.addEnableComponent(bs); - panel.add(bs, "skip, growx 5, w 100lp, wrap"); + panel.add(bs, "top, skip, growx 5, w 100lp, wrap"); // END OVERRIDE CD -------------------------------------------------- - // BEGIN OVERRIDE SUBCOMPONENTS -------------------------------------------------- - - bm = new BooleanModel(component, "SubcomponentsOverridden"); - check = new JCheckBox(bm); - //// Override mass, CG, and CD of all subcomponents - check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); - check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.ttip")); - panel.add(check, "spanx, wrap 35lp"); - - // END OVERRIDE SUBCOMPONENTS -------------------------------------------------- - // OVERRIDE MASS, CG DOESN'T INCLUDE MOTORS -------------------------------------------------- panel.add(new StyledLabel(trans.get("RocketCompCfg.lbl.longB1") + //// The center of gravity is measured from the front end of the