Merge branch 'openrocket:unstable' into scripting
This commit is contained in:
commit
e35b7bda2d
@ -15,6 +15,8 @@
|
||||
<classpathentry kind="lib" path="lib-extra/RXTXcomm.jar"/>
|
||||
<classpathentry kind="lib" path="resources"/>
|
||||
<classpathentry kind="lib" path="lib/javax.inject.jar"/>
|
||||
<classpathentry kind="lib" path="lib/javax.json-1.1.3.jar"/>
|
||||
<classpathentry kind="lib" path="lib/javax.json-api-1.1.3.jar"/>
|
||||
<classpathentry kind="lib" path="lib/aopalliance.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commonmark-0.19.0.jar"/>
|
||||
<classpathentry kind="lib" path="lib/slf4j-api-1.7.30.jar"/>
|
||||
|
@ -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 = <html>If checked, pod set/booster markers will only be shown when the pod set/booster is selected.<br>If unchecked, pod set/booster markers will always be shown.</html>
|
||||
pref.dlg.checkbox.AlwaysOpenLeftmost = Always open leftmost tab when opening a component edit dialog
|
||||
pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = <html>If checked, a component edit dialog will always pop up with the first tab selected.<br>If unchecked, the previous selected tab will be used.</html>
|
||||
pref.dlg.lbl.User-definedthrust = User-defined thrust curves:
|
||||
@ -715,7 +717,7 @@ compaddbuttons.Launchlug = Launch Lug
|
||||
compaddbuttons.RailButton = Rail Button
|
||||
compaddbuttons.InnerComponent = Inner Components
|
||||
compaddbuttons.Innertube = Inner Tube
|
||||
compaddbuttons.Coupler = Coupler
|
||||
compaddbuttons.Coupler = Tube Coupler
|
||||
compaddbuttons.Centeringring = Centering\nRing
|
||||
compaddbuttons.Bulkhead = Bulkhead
|
||||
compaddbuttons.Engineblock = Engine\nBlock
|
||||
@ -887,16 +889,17 @@ RocketCfg.lbl.Material = Material:
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = Component name:
|
||||
RocketCompCfg.ttip.Thecomponentname = The component name.
|
||||
RocketCompCfg.lbl.Componentname.ttip = The component name.
|
||||
RocketCompCfg.tab.Override = Override
|
||||
RocketCompCfg.tab.MassandCGoverride = Mass and CG override options
|
||||
RocketCompCfg.tab.Override.ttip = Mass and CG override options
|
||||
RocketCompCfg.tab.Assembly = General
|
||||
RocketCompCfg.tab.AssemblyComment = Options for locating stages parallel to other stages
|
||||
RocketCompCfg.tab.Figure = Figure
|
||||
RocketCompCfg.tab.Figstyleopt = Figure style options
|
||||
RocketCompCfg.tab.Comment = Comment
|
||||
RocketCompCfg.tab.Specifyacomment = Specify a comment for the component
|
||||
RocketCompCfg.tab.Appearance = Appearance
|
||||
RocketCompCfg.tab.Comment.ttip = Specify a comment for the component
|
||||
RocketCompCfg.tab.Appearance = Appearance
|
||||
RocketCompCfg.tab.Appearance.ttip = Component's appearance
|
||||
RocketCompCfg.lbl.Mass = Mass:
|
||||
RocketCompCfg.lbl.Componentmass = Component mass:
|
||||
RocketCompCfg.lbl.overriddento = (overridden to
|
||||
@ -2071,8 +2074,10 @@ CustomFinImport.error.badimage = Could not deduce fin shape from image.
|
||||
CustomFinImport.description = The image will be converted internally to black and white image (black for the fin), so make sure you use a solid dark color for the fin, and white or a light color for the background. The fin must be touching the bottom of the image, which is the base of the fin.
|
||||
|
||||
|
||||
PresetModel.lbl.select = Select preset
|
||||
PresetModel.lbl.database = From database\u2026
|
||||
PresetModel.combo.ttip = <html>Select a preset model from a list of favorites (selected in the component preset dialog),<br>or select 'Custom' when no preset is required.</html>
|
||||
PresetModel.lbl.custompreset = Custom
|
||||
PresetModel.lbl.partsLib = Parts Library
|
||||
PresetModel.lbl.partsLib.ttip = Select a preset model for this rocket component from a library of parts.
|
||||
|
||||
DecalModel.lbl.select = <none>
|
||||
DecalModel.lbl.choose = From file\u2026
|
||||
@ -2094,7 +2099,7 @@ ComponentPresetChooserDialog.menu.sortDesc = Sort Descending
|
||||
ComponentPresetChooserDialog.menu.units = Units
|
||||
ComponentPresetChooserDialog.checkbox.showAllCompatible = Show all compatible
|
||||
ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = Show Legacy Database
|
||||
ComponentPresetChooserDialog.lbl.favorites = Select to add preset to drop-down menu
|
||||
ComponentPresetChooserDialog.lbl.favorites = Check to add preset to the preset drop-down menu in the component edit dialog
|
||||
table.column.Favorite = Favorite
|
||||
table.column.Legacy = Legacy
|
||||
table.column.Manufacturer = Manufacturer
|
||||
|
@ -621,13 +621,13 @@ ShockCordCfg.lbl.Shockcordlength = D
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = Jméno komponenty:
|
||||
RocketCompCfg.ttip.Thecomponentname = Jméno komponenty.
|
||||
RocketCompCfg.lbl.Componentname.ttip = Jméno komponenty.
|
||||
RocketCompCfg.tab.Override = Prepsat
|
||||
RocketCompCfg.tab.MassandCGoverride = Prepi\u0161 hmotnost a te\u017Ei\u0161te
|
||||
RocketCompCfg.tab.Override.ttip = Prepi\u0161 hmotnost a te\u017Ei\u0161te
|
||||
RocketCompCfg.tab.Figure = Obrázek
|
||||
RocketCompCfg.tab.Figstyleopt = Vlastnosti obrázku
|
||||
RocketCompCfg.tab.Comment = Komentár
|
||||
RocketCompCfg.tab.Specifyacomment = Upresnení komentáre komponenty
|
||||
RocketCompCfg.tab.Comment.ttip = Upresnení komentáre komponenty
|
||||
RocketCompCfg.lbl.Mass = Hmotnost:
|
||||
RocketCompCfg.lbl.Componentmass = Hmotnost komponenty:
|
||||
RocketCompCfg.lbl.overriddento = (prepsáno na
|
||||
@ -1587,8 +1587,8 @@ CustomFinImport.error.badimage = Nemohu vyvodit tvar stabiliz
|
||||
CustomFinImport.description = Obrázek bude zmenen na cernobílý \n(cerná pro stabilizátor), ujistete se prosím, \u017Ee jste pou\u017Eily cernou barvu na stabilizátor \na bílou nebo svetlou barvu na pozadí. Stabilizátor \nse musí dotýkat steny obrázku, která predstavuje uchycení pro stabilizátor.
|
||||
|
||||
|
||||
PresetModel.lbl.select = Výber predvolby:
|
||||
PresetModel.lbl.database = Z databáze...
|
||||
PresetModel.lbl.custompreset = Vlastní
|
||||
PresetModel.lbl.partsLib = Knihovna díl?
|
||||
|
||||
|
||||
! Component Preset Chooser Dialog
|
||||
|
@ -677,13 +677,13 @@ ShockCordCfg.lbl.Shockcordlength = Gummibandl
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = Komponentenname:
|
||||
RocketCompCfg.ttip.Thecomponentname = Name der Komponente.
|
||||
RocketCompCfg.lbl.Componentname.ttip = Name der Komponente.
|
||||
RocketCompCfg.tab.Override = Werte überschreiben
|
||||
RocketCompCfg.tab.MassandCGoverride = Massen- und Schwerpunktsoptionen
|
||||
RocketCompCfg.tab.Override.ttip = Massen- und Schwerpunktsoptionen
|
||||
RocketCompCfg.tab.Figure = Form
|
||||
RocketCompCfg.tab.Figstyleopt = Formoptionen
|
||||
RocketCompCfg.tab.Comment = Kommentar
|
||||
RocketCompCfg.tab.Specifyacomment = Kommentar zu dieser Komponente
|
||||
RocketCompCfg.tab.Comment.ttip = Kommentar zu dieser Komponente
|
||||
RocketCompCfg.lbl.Mass = Masse:
|
||||
RocketCompCfg.lbl.Componentmass = Masse der Komponente:
|
||||
RocketCompCfg.lbl.overriddento = (überschrieben auf
|
||||
@ -1645,8 +1645,8 @@ CustomFinImport.error.badimage = Konnte keine Leitwerksform aus dem Bild erzeuge
|
||||
CustomFinImport.description = Das Bild wird intern in ein Schwarz-Weiß-Bild konvertiert (Leitwerk: schwarz). Bitte sicherstellen, dass das Leitwerk in einer dichten, dunklen Farbe ist, während der Hintergrund weiß oder sehr hell sein sollte. Das Leitwerk muss das untere Bildende berühren, da dies die Verbindungsstelle zur Rakete wird.
|
||||
|
||||
|
||||
PresetModel.lbl.select = Voreinstellung auswählen:
|
||||
PresetModel.lbl.database = Aus Datenbank...
|
||||
PresetModel.lbl.custompreset = Benutzerdefiniert
|
||||
PresetModel.lbl.partsLib = Teile-Bibliothek
|
||||
|
||||
|
||||
! Component Preset Chooser Dialog
|
||||
|
@ -737,8 +737,8 @@ PreferencesDialog.languages.default = Idioma por defecto
|
||||
PreferencesDialog.lbl.language = Idioma de la interfaz:
|
||||
PreferencesDialog.lbl.languageEffect = El idioma cambiar\u00e1 la pr\u00f3xima vez que abra OpenRocket.
|
||||
|
||||
PresetModel.lbl.database = Desde la Base de Datos...
|
||||
PresetModel.lbl.select = Prefabricado
|
||||
PresetModel.lbl.custompreset = Personalizado
|
||||
PresetModel.lbl.partsLib = Biblioteca de piezas
|
||||
|
||||
PrintDialog.but.previewAndPrint = Vista previa e Imprimir
|
||||
PrintDialog.checkbox.showByStage = Mostrar por etapas
|
||||
@ -861,13 +861,13 @@ RocketCompCfg.tab.Appearance = Apariencia
|
||||
RocketCompCfg.tab.Comment = Comentarios
|
||||
RocketCompCfg.tab.Figstyleopt = Opciones de estilo de la figura
|
||||
RocketCompCfg.tab.Figure = Estilo
|
||||
RocketCompCfg.tab.MassandCGoverride = Especificar la Masa y el CG del componente.
|
||||
RocketCompCfg.tab.Override.ttip = Especificar la Masa y el CG del componente.
|
||||
RocketCompCfg.tab.Override = Masa y CG
|
||||
RocketCompCfg.tab.Specifyacomment = Especifique un comentario para el componente
|
||||
RocketCompCfg.tab.Comment.ttip = Especifique un comentario para el componente
|
||||
RocketCompCfg.title.Aftshoulder = Trasera del acople
|
||||
RocketCompCfg.title.Noseconeshoulder = Acople de la ojiva
|
||||
RocketCompCfg.ttip.Endcapped = Si el extremo del soporte est\u00e1 truncado.
|
||||
RocketCompCfg.ttip.Thecomponentname = El nombre del componente.
|
||||
RocketCompCfg.lbl.Componentname.ttip = El nombre del componente.
|
||||
|
||||
RocketComponent.Position.ABSOLUTE = Extremo de la ojiva
|
||||
RocketComponent.Position.AFTER = Despu\u00e9s del componente
|
||||
|
@ -729,8 +729,8 @@ PreferencesDialog.languages.default = Valeur syst\u00E8me par d\u00E9faut
|
||||
PreferencesDialog.lbl.language = Langue du programme:
|
||||
PreferencesDialog.lbl.languageEffect = La langue sera chang\u00E9e apr\u00E8s avoir red\u00E9marr\u00E9 OpenRocket.
|
||||
|
||||
PresetModel.lbl.database = A partir d'une base de donn\u00E9es...
|
||||
PresetModel.lbl.select = Choisir une pi\u00E8ce pr\u00E9d\u00E9finie:
|
||||
PresetModel.lbl.custompreset = Personnalisé
|
||||
PresetModel.lbl.partsLib = Biblioth\u00E8que de pi\u00E8ces
|
||||
|
||||
PrintDialog.but.previewAndPrint = Pr\u00E9-visualiser et imprimer
|
||||
PrintDialog.checkbox.showByStage = Montrer par \u00E9tage
|
||||
@ -853,13 +853,13 @@ RocketCompCfg.tab.Appearance = Apparence
|
||||
RocketCompCfg.tab.Comment = Commentaires
|
||||
RocketCompCfg.tab.Figstyleopt = Options de la forme
|
||||
RocketCompCfg.tab.Figure = Forme
|
||||
RocketCompCfg.tab.MassandCGoverride = For\u00E7age de la Masse et du CG
|
||||
RocketCompCfg.tab.Override.ttip = For\u00E7age de la Masse et du CG
|
||||
RocketCompCfg.tab.Override = Forcer la valeur
|
||||
RocketCompCfg.tab.Specifyacomment = Commentaires concernant la pi\u00E8ce
|
||||
RocketCompCfg.tab.Comment.ttip = Commentaires concernant la pi\u00E8ce
|
||||
RocketCompCfg.title.Aftshoulder = Epaulement arri\u00E8re
|
||||
RocketCompCfg.title.Noseconeshoulder = Epaulement du c\u00F4ne
|
||||
RocketCompCfg.ttip.Endcapped = Pr\u00E9cise si l'arri\u00E8re du c\u00F4ne est clos.
|
||||
RocketCompCfg.ttip.Thecomponentname = Le nom de la pi\u00E8ce.
|
||||
RocketCompCfg.lbl.Componentname.ttip = Le nom de la pi\u00E8ce.
|
||||
|
||||
RocketComponent.Position.ABSOLUTE = Pointe de l'ogive
|
||||
RocketComponent.Position.AFTER = Apr\u00E8s la pi\u00E8ce parente
|
||||
|
@ -679,13 +679,13 @@ ShockCordCfg.lbl.Shockcordlength = Lunghezza della Shock cord :
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = Nome componente:
|
||||
RocketCompCfg.ttip.Thecomponentname = Il nome del componente.
|
||||
RocketCompCfg.lbl.Componentname.ttip = Il nome del componente.
|
||||
RocketCompCfg.tab.Override = Modifica
|
||||
RocketCompCfg.tab.MassandCGoverride = Opzioni di sovrascrittura di massa e CG
|
||||
RocketCompCfg.tab.Override.ttip = Opzioni di sovrascrittura di massa e CG
|
||||
RocketCompCfg.tab.Figure = Disegno
|
||||
RocketCompCfg.tab.Figstyleopt = Opzioni dello stile della figure
|
||||
RocketCompCfg.tab.Comment = Commento
|
||||
RocketCompCfg.tab.Specifyacomment = Specifica un commento per il componente
|
||||
RocketCompCfg.tab.Comment.ttip = Specifica un commento per il componente
|
||||
RocketCompCfg.lbl.Mass = Massa:
|
||||
RocketCompCfg.lbl.Componentmass = La massa del componente :
|
||||
RocketCompCfg.lbl.overriddento = (sovrascritto a
|
||||
@ -1651,8 +1651,8 @@ CustomFinImport.error.badimage = Non riesco a capire la forma della pinna dall
|
||||
CustomFinImport.description = L'immagine sar\u00e0 convertita in bianco e nero internamente (nero per le pinne), cos\u00ec assicurati di usare un nero pieno per le pinne e bianco, o colore chiaro, per lo sfondo. La pinna ndeve toccare il fondo dell'immagine, che \u00e8 la base della pinna.
|
||||
|
||||
|
||||
PresetModel.lbl.select = Seleziona precaricati:
|
||||
PresetModel.lbl.database = Da database...
|
||||
PresetModel.lbl.custompreset = Personalizzato
|
||||
PresetModel.lbl.partsLib = Libreria di parti
|
||||
|
||||
|
||||
! Component Preset Chooser Dialog
|
||||
|
@ -709,13 +709,13 @@ ShockCordCfg.lbl.Shockcordlength = \u30B7\u30E7\u30C3\u30AF\u30B3\u30FC\u30C9\u
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = \u90E8\u54C1\u540D\uFF1A
|
||||
RocketCompCfg.ttip.Thecomponentname = \u90E8\u54C1\u306E\u540D\u524D
|
||||
RocketCompCfg.lbl.Componentname.ttip = \u90E8\u54C1\u306E\u540D\u524D
|
||||
RocketCompCfg.tab.Override = \u518D\u5B9A\u7FA9
|
||||
RocketCompCfg.tab.MassandCGoverride = \u8CEA\u91CF\u3068CG\u3092\u518D\u5B9A\u7FA9\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3
|
||||
RocketCompCfg.tab.Override.ttip = \u8CEA\u91CF\u3068CG\u3092\u518D\u5B9A\u7FA9\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3
|
||||
RocketCompCfg.tab.Figure = \u56F3\u793A
|
||||
RocketCompCfg.tab.Figstyleopt = \u56F3\u793A\u306E\u30B9\u30BF\u30A4\u30EB\u30AA\u30D7\u30B7\u30E7\u30F3
|
||||
RocketCompCfg.tab.Comment = \u30B3\u30E1\u30F3\u30C8
|
||||
RocketCompCfg.tab.Specifyacomment = \u90E8\u54C1\u3078\u306E\u30B3\u30E1\u30F3\u30C8\u3092\u8A18\u8FF0
|
||||
RocketCompCfg.tab.Comment.ttip = \u90E8\u54C1\u3078\u306E\u30B3\u30E1\u30F3\u30C8\u3092\u8A18\u8FF0
|
||||
RocketCompCfg.lbl.Mass = \u8CEA\u91CF\uFF1A
|
||||
RocketCompCfg.lbl.Componentmass = \u90E8\u54C1\u8CEA\u91CF\uFF1A
|
||||
RocketCompCfg.lbl.overriddento = (overridden to
|
||||
@ -1713,8 +1713,8 @@ CustomFinImport.error.badimage = \u753B\u50CF\u304B\u3089\u30D5\u30A3\u30F3\u5F
|
||||
CustomFinImport.description = \u753B\u50CF\u306F\u5185\u90E8\u3067\u767D\u80CC\u666F\u3068\u9ED2\u7DDA\u306B\u5909\u63DB\u3055\u308C\u307E\u3059\u3002\u306A\u306E\u3067\u30D5\u30A3\u30F3\u306B\u306F\u6697\u3044\u8272\u306E\u5B9F\u7DDA\u3001\u80CC\u666F\u306B\u306F\u767D\u304B\u660E\u308B\u3044\u8272\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30D5\u30A3\u30F3\u306F\u753B\u50CF\u306E\u5E95\u9762\u306B\u63A5\u3057\u3066\u3044\u306A\u304F\u3066\u306F\u3044\u3051\u307E\u305B\u3093\u3001\u3053\u308C\u306F\u30D5\u30A3\u30F3\u306E\u5E95\u9762\u306B\u306A\u308A\u307E\u3059\u3002
|
||||
|
||||
|
||||
PresetModel.lbl.select = Select preset
|
||||
PresetModel.lbl.database = From database...
|
||||
PresetModel.lbl.custompreset = \u30ab\u30b9\u30bf\u30e0
|
||||
PresetModel.lbl.partsLib = \u30d1\u30fc\u30c4\u30e9\u30a4\u30d6\u30e9\u30ea\u30fc
|
||||
|
||||
|
||||
! Component Preset Chooser Dialog
|
||||
|
@ -826,15 +826,15 @@ RocketCfg.lbl.Material = Materiaal:
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = Componentnaam:
|
||||
RocketCompCfg.ttip.Thecomponentname = De componentnaam.
|
||||
RocketCompCfg.lbl.Componentname.ttip = De componentnaam.
|
||||
RocketCompCfg.tab.Override = Overschrijf
|
||||
RocketCompCfg.tab.MassandCGoverride = Massa en ZP overschrijvingsopties
|
||||
RocketCompCfg.tab.Override.ttip = Massa en ZP overschrijvingsopties
|
||||
RocketCompCfg.tab.Assembly = Algemeen
|
||||
RocketCompCfg.tab.AssemblyComment = Opties voor het plaatsen van trappen parallel aan andere trappen
|
||||
RocketCompCfg.tab.Figure = Figuur
|
||||
RocketCompCfg.tab.Figstyleopt = Figuurstijl opties
|
||||
RocketCompCfg.tab.Comment = Opmerking
|
||||
RocketCompCfg.tab.Specifyacomment = Geef een opmerking voor het onderdeel
|
||||
RocketCompCfg.tab.Comment.ttip = Geef een opmerking voor het onderdeel
|
||||
RocketCompCfg.tab.Appearance = Uiterlijk
|
||||
RocketCompCfg.lbl.Mass = Massa:
|
||||
RocketCompCfg.lbl.Componentmass = Componentmassa:
|
||||
@ -1967,8 +1967,8 @@ CustomFinImport.error.badimage = Kon de vorm van de vin niet afleiden uit het be
|
||||
CustomFinImport.description = De afbeelding wordt intern geconverteerd naar een zwart-wit afbeelding (zwart voor de vin), dus zorg ervoor dat je een effen donkere kleur gebruikt voor de vin, en wit of een lichte kleur voor de achtergrond. De vin moet de onderkant van het beeld raken, dat is de basis van de vin.
|
||||
|
||||
|
||||
PresetModel.lbl.select = Selecteer preset
|
||||
PresetModel.lbl.database = Uit databank...
|
||||
PresetModel.lbl.custompreset = Aangepast
|
||||
PresetModel.lbl.partsLib = Onderdelenbibliotheek
|
||||
|
||||
DecalModel.lbl.select = <geen>
|
||||
DecalModel.lbl.choose = Van bestand...
|
||||
|
@ -623,13 +623,13 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = Nazwa cz\u0119\u015Bci:
|
||||
RocketCompCfg.ttip.Thecomponentname = Nazwa cz\u0119\u015Bci sk\u0142adowej rakiety.
|
||||
RocketCompCfg.lbl.Componentname.ttip = Nazwa cz\u0119\u015Bci sk\u0142adowej rakiety.
|
||||
RocketCompCfg.tab.Override = Wymu\u015B
|
||||
RocketCompCfg.tab.MassandCGoverride = Opcje wymuszenia ci\u0119\u017Caru oraz \u015Brodka ci\u0119\u017Cko\u015Bci
|
||||
RocketCompCfg.tab.Override.ttip = Opcje wymuszenia ci\u0119\u017Caru oraz \u015Brodka ci\u0119\u017Cko\u015Bci
|
||||
RocketCompCfg.tab.Figure = Wygl\u0105d
|
||||
RocketCompCfg.tab.Figstyleopt = Styl kszta\u0142tu
|
||||
RocketCompCfg.tab.Comment = Uwagi
|
||||
RocketCompCfg.tab.Specifyacomment = Dodaj uwagi do cz\u0119\u015Bci
|
||||
RocketCompCfg.tab.Comment.ttip = Dodaj uwagi do cz\u0119\u015Bci
|
||||
RocketCompCfg.lbl.Mass = Masa:
|
||||
RocketCompCfg.lbl.Componentmass = Masa cz\u0119\u015Bci:
|
||||
RocketCompCfg.lbl.overriddento = (wymuszone do
|
||||
@ -1592,8 +1592,8 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
|
||||
CustomFinImport.description = Obraz zostanie automatycznie zamieniony na czarno-bia\u0142y (statecznik w kolorze czarnym), wi\u0119c upewnij si\u0119, \u017Ce kszta\u0142t statecznika jest wype\u0142niony ciemnym kolorem, a t\u0142o jest bia\u0142e lub jasne. Podstawa statecznika musi przylega\u0107 do dolnej kraw\u0119dzi obrazu.
|
||||
|
||||
|
||||
PresetModel.lbl.select = Wybierz ustawienia:
|
||||
PresetModel.lbl.database = Z bazy danych...
|
||||
PresetModel.lbl.custompreset = Niestandardowe
|
||||
PresetModel.lbl.partsLib = Biblioteka cz??ci
|
||||
|
||||
|
||||
! Component Preset Chooser Dialog
|
||||
|
@ -715,8 +715,8 @@ PreferencesDialog.languages.default = Padr\u00e3o do sistema
|
||||
PreferencesDialog.lbl.language = Idioma da interface:
|
||||
PreferencesDialog.lbl.languageEffect = A linguagem vai mudar na pr\u00f3xima vez que voc\u00ea iniciar o OpenRocket.
|
||||
|
||||
PresetModel.lbl.database = \u00c0 partir do banco de dados...
|
||||
PresetModel.lbl.select = Selecione ajustes pr\u00e9-definidos
|
||||
PresetModel.lbl.custompreset = Personalizado
|
||||
PresetModel.lbl.partsLib = Biblioteca de pe\u00e7as
|
||||
|
||||
PrintDialog.but.previewAndPrint = Visualiza\u00e7\u00e3o e impress\u00e3o
|
||||
PrintDialog.checkbox.showByStage = Mostrar por est\u00e1gio
|
||||
@ -838,13 +838,13 @@ RocketCompCfg.lbl.ttip.componentmaterialaffects = O material do componente afe
|
||||
RocketCompCfg.tab.Comment = Coment\u00e1rio
|
||||
RocketCompCfg.tab.Figstyleopt = Op\u00e7\u00f5es do estilo de figura
|
||||
RocketCompCfg.tab.Figure = Figura
|
||||
RocketCompCfg.tab.MassandCGoverride = Op\u00e7\u00f5es de modifica\u00e7\u00e3o de massa e CG
|
||||
RocketCompCfg.tab.Override.ttip = Op\u00e7\u00f5es de modifica\u00e7\u00e3o de massa e CG
|
||||
RocketCompCfg.tab.Override = Modificar
|
||||
RocketCompCfg.tab.Specifyacomment = Especifique um coment\u00e1rio para o componente
|
||||
RocketCompCfg.tab.Comment.ttip = Especifique um coment\u00e1rio para o componente
|
||||
RocketCompCfg.title.Aftshoulder = Ressalto traseiro
|
||||
RocketCompCfg.title.Noseconeshoulder = Ressalto da ogiva
|
||||
RocketCompCfg.ttip.Endcapped = Quando a extremidade do ressalto \u00e9 limitada.
|
||||
RocketCompCfg.ttip.Thecomponentname = Nome do componente.
|
||||
RocketCompCfg.lbl.Componentname.ttip = Nome do componente.
|
||||
|
||||
RocketComponent.Position.ABSOLUTE = Dica da ogiva
|
||||
RocketComponent.Position.AFTER = Depois do componente pai
|
||||
|
@ -888,15 +888,15 @@ RocketCfg.lbl.Material = \u041C\u0430\u0442\u0435\u0440\u0438\u0430\u043B:
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430:
|
||||
RocketCompCfg.ttip.Thecomponentname = \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430.
|
||||
RocketCompCfg.lbl.Componentname.ttip = \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430.
|
||||
RocketCompCfg.tab.Override = \u041F\u0435\u0440\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435
|
||||
RocketCompCfg.tab.MassandCGoverride = \u041F\u0435\u0440\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u043C\u0430\u0441\u0441\u044B \u0438 \u0426\u0422
|
||||
RocketCompCfg.tab.Override.ttip = \u041F\u0435\u0440\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u043C\u0430\u0441\u0441\u044B \u0438 \u0426\u0422
|
||||
RocketCompCfg.tab.Assembly = \u0421\u0431\u043E\u0440\u043A\u0430
|
||||
RocketCompCfg.tab.AssemblyComment = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F \u0441\u0442\u0443\u043F\u0435\u043D\u0435\u0439 \u043F\u0430\u0440\u0430\u043B\u043B\u0435\u043B\u044C\u043D\u043E \u0434\u0440\u0443\u0433\u0438\u043C \u0441\u0442\u0443\u043F\u0435\u043D\u044F\u043C
|
||||
RocketCompCfg.tab.Figure = \u0420\u0438\u0441\u0443\u043D\u043E\u043A
|
||||
RocketCompCfg.tab.Figstyleopt = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0441\u0442\u0438\u043B\u044F \u0440\u0438\u0441\u0443\u043D\u043A\u0430
|
||||
RocketCompCfg.tab.Comment = \u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435
|
||||
RocketCompCfg.tab.Specifyacomment = \u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 \u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443
|
||||
RocketCompCfg.tab.Comment.ttip = \u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 \u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443
|
||||
RocketCompCfg.tab.Appearance = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0432\u0438\u0434
|
||||
RocketCompCfg.lbl.Mass = \u041C\u0430\u0441\u0441\u0430:
|
||||
RocketCompCfg.lbl.Componentmass = \u041C\u0430\u0441\u0441\u0430 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430:
|
||||
@ -2075,8 +2075,8 @@ CustomFinImport.error.badimage = \u041D\u0435\u0432\u043E\u0437\u043C\u043E\u043
|
||||
CustomFinImport.description = \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044F \u0432 \u0447\u0435\u0440\u043D\u043E-\u0431\u0435\u043B\u043E\u0435 (\u0433\u0434\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 - \u0446\u0432\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430), \u0442\u0430\u043A \u0447\u0442\u043E \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0440\u0438\u0441\u0443\u043D\u043A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0438 \u0431\u0435\u043B\u044B\u0439 \u0438\u043B\u0438 \u0441\u0432\u0435\u0442\u043B\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0444\u043E\u043D\u0430. \u041E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u0435 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0434\u043E\u043B\u0436\u043D\u043E \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C\u0441\u044F \u0441\u043D\u0438\u0437\u0443 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F.
|
||||
|
||||
|
||||
PresetModel.lbl.select = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443
|
||||
PresetModel.lbl.database = \u0418\u0437 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445...
|
||||
PresetModel.lbl.custompreset = \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0020\u0434\u0435\u0442\u0430\u043b\u0435\u0439
|
||||
PresetModel.lbl.partsLib = \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0020\u0434\u0435\u0442\u0430\u043b\u0435\u0439
|
||||
|
||||
DecalModel.lbl.select = <\u043D\u0435\u0442>
|
||||
DecalModel.lbl.choose = \u0418\u0437 \u0444\u0430\u0439\u043B\u0430...
|
||||
|
@ -779,13 +779,13 @@ ShockCordCfg.lbl.Shockcordlength = Shock cord length:
|
||||
|
||||
! RocketComponentConfig
|
||||
RocketCompCfg.lbl.Componentname = Component name:
|
||||
RocketCompCfg.ttip.Thecomponentname = The component name.
|
||||
RocketCompCfg.lbl.Componentname.ttip = The component name.
|
||||
RocketCompCfg.tab.Override = Override
|
||||
RocketCompCfg.tab.MassandCGoverride = Mass and CG override options
|
||||
RocketCompCfg.tab.Override.ttip = Mass and CG override options
|
||||
RocketCompCfg.tab.Figure = Figure
|
||||
RocketCompCfg.tab.Figstyleopt = Figure style options
|
||||
RocketCompCfg.tab.Comment = Comment
|
||||
RocketCompCfg.tab.Specifyacomment = Specify a comment for the component
|
||||
RocketCompCfg.tab.Comment.ttip = Specify a comment for the component
|
||||
RocketCompCfg.tab.Appearance = Appearance
|
||||
RocketCompCfg.lbl.Mass = Mass:
|
||||
RocketCompCfg.lbl.Componentmass = Component mass:
|
||||
@ -1812,8 +1812,8 @@ CustomFinImport.error.badimage = Could not deduce fin shape from image.
|
||||
CustomFinImport.description = The image will be converted internally to black and white image (black for the fin), so make sure you use a solid dark color for the fin, and white or a light color for the background. The fin must be touching the bottom of the image, which is the base of the fin.
|
||||
|
||||
|
||||
PresetModel.lbl.select = Select preset
|
||||
PresetModel.lbl.database = From database...
|
||||
PresetModel.lbl.custompreset = Custom
|
||||
PresetModel.lbl.partsLib = Parts Library
|
||||
|
||||
DecalModel.lbl.select = <none>
|
||||
DecalModel.lbl.choose = From file...
|
||||
|
@ -803,8 +803,8 @@ PreferencesDialog.languages.default = \u7CFB\u7EDF\u9ED8\u8BA4
|
||||
PreferencesDialog.lbl.language = \u754C\u9762\u8BED\u8A00:
|
||||
PreferencesDialog.lbl.languageEffect = \u8BED\u8A00\u8BBE\u7F6E\u5C06\u5728OpenRocket\u91CD\u542F\u540E\u751F\u6548
|
||||
|
||||
PresetModel.lbl.database = \u4ECE\u6570\u636E\u5E93...
|
||||
PresetModel.lbl.select = \u9009\u62E9\u9884\u8BBE
|
||||
PresetModel.lbl.custompreset = \u5b9a\u5236
|
||||
PresetModel.lbl.partsLib = \u96f6\u4ef6\u5e93
|
||||
|
||||
PrintDialog.but.previewAndPrint = \u9884\u89C8 & \u6253\u5370
|
||||
PrintDialog.checkbox.showByStage = \u6309\u7EA7\u663E\u793A
|
||||
@ -927,13 +927,13 @@ RocketCompCfg.tab.Appearance = \u5916\u89C2
|
||||
RocketCompCfg.tab.Comment = \u6CE8\u91CA
|
||||
RocketCompCfg.tab.Figstyleopt = \u6837\u5F0F\u9009\u9879
|
||||
RocketCompCfg.tab.Figure = \u6837\u5F0F
|
||||
RocketCompCfg.tab.MassandCGoverride = \u8D28\u91CF\u53CA\u91CD\u5FC3\u9009\u9879
|
||||
RocketCompCfg.tab.Override.ttip = \u8D28\u91CF\u53CA\u91CD\u5FC3\u9009\u9879
|
||||
RocketCompCfg.tab.Override = \u8986\u5199
|
||||
RocketCompCfg.tab.Specifyacomment = \u7EC4\u4EF6\u6CE8\u91CA
|
||||
RocketCompCfg.tab.Comment.ttip = \u7EC4\u4EF6\u6CE8\u91CA
|
||||
RocketCompCfg.title.Aftshoulder = \u524D\u8FDE\u63A5\u5904
|
||||
RocketCompCfg.title.Noseconeshoulder = \u5934\u9525\u8FDE\u63A5\u5904
|
||||
RocketCompCfg.ttip.Endcapped = \u8FDE\u63A5\u5904\u7EC8\u7AEF\u662F\u5426\u6709\u76D6.
|
||||
RocketCompCfg.ttip.Thecomponentname = \u7EC4\u4EF6\u540D\u79F0.
|
||||
RocketCompCfg.lbl.Componentname.ttip = \u7EC4\u4EF6\u540D\u79F0.
|
||||
|
||||
RocketComponent.Position.ABSOLUTE = \u5934\u9525\u5C16\u7AEF
|
||||
RocketComponent.Position.AFTER = \u7236\u7EC4\u4EF6\u4E4B\u540E
|
||||
|
@ -68,5 +68,5 @@ public interface AerodynamicCalculator extends Monitorable {
|
||||
*/
|
||||
public AerodynamicCalculator newInstance();
|
||||
|
||||
public boolean isContinuous( final Rocket rkt);
|
||||
public boolean isContinuous(FlightConfiguration configuration, final Rocket rkt);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import static net.sf.openrocket.util.MathUtil.pow2;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -80,7 +81,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
Map<RocketComponent, AerodynamicForces> assemblyMap = new LinkedHashMap<>();
|
||||
|
||||
// Calculate non-axial force data
|
||||
calculateForceAnalysis(conditions, configuration.getRocket(), instMap, eachMap, assemblyMap, warnings);
|
||||
calculateForceAnalysis(configuration, conditions, configuration.getRocket(), instMap, eachMap, assemblyMap, warnings);
|
||||
|
||||
// Calculate drag coefficient data
|
||||
AerodynamicForces rocketForces = assemblyMap.get(configuration.getRocket());
|
||||
@ -125,7 +126,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
return finalMap;
|
||||
}
|
||||
|
||||
private AerodynamicForces calculateForceAnalysis( FlightConditions conds,
|
||||
private AerodynamicForces calculateForceAnalysis( FlightConfiguration configuration,
|
||||
FlightConditions conds,
|
||||
RocketComponent comp,
|
||||
InstanceMap instances,
|
||||
Map<RocketComponent, AerodynamicForces> eachForces,
|
||||
@ -152,8 +154,12 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
}
|
||||
|
||||
for( RocketComponent child : comp.getChildren()) {
|
||||
// Ignore inactive stages
|
||||
if (child instanceof AxialStage && !configuration.isStageActive(child.getStageNumber())) {
|
||||
continue;
|
||||
}
|
||||
// forces particular to each component
|
||||
AerodynamicForces childForces = calculateForceAnalysis(conds, child, instances, eachForces, assemblyForces, warnings);
|
||||
AerodynamicForces childForces = calculateForceAnalysis(configuration, conds, child, instances, eachForces, assemblyForces, warnings);
|
||||
|
||||
if(null != childForces) {
|
||||
aggregateForces.merge(childForces);
|
||||
@ -240,7 +246,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
if (calcMap == null)
|
||||
buildCalcMap(configuration);
|
||||
|
||||
if( ! isContinuous( configuration.getRocket() ) ){
|
||||
if (!isContinuous(configuration, configuration.getRocket())){
|
||||
warnings.add( Warning.DIAMETER_DISCONTINUITY);
|
||||
}
|
||||
|
||||
@ -266,20 +272,32 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinuous( final Rocket rkt){
|
||||
return testIsContinuous( rkt);
|
||||
public boolean isContinuous(FlightConfiguration configuration, final Rocket rkt){
|
||||
return testIsContinuous(configuration, rkt);
|
||||
}
|
||||
|
||||
private boolean testIsContinuous( final RocketComponent treeRoot ){
|
||||
private boolean testIsContinuous(FlightConfiguration configuration, final RocketComponent treeRoot ){
|
||||
Queue<RocketComponent> queue = new LinkedList<>();
|
||||
queue.addAll(treeRoot.getChildren());
|
||||
for (RocketComponent child : treeRoot.getChildren()) {
|
||||
// Ignore inactive stages
|
||||
if (child instanceof AxialStage && !configuration.isStageActive(child.getStageNumber())) {
|
||||
continue;
|
||||
}
|
||||
queue.add(child);
|
||||
}
|
||||
|
||||
boolean isContinuous = true;
|
||||
SymmetricComponent prevComp = null;
|
||||
while((isContinuous)&&( null != queue.peek())){
|
||||
RocketComponent comp = queue.poll();
|
||||
if( comp instanceof SymmetricComponent ){
|
||||
queue.addAll( comp.getChildren());
|
||||
for (RocketComponent child : comp.getChildren()) {
|
||||
// Ignore inactive stages
|
||||
if (child instanceof AxialStage && !configuration.isStageActive(child.getStageNumber())) {
|
||||
continue;
|
||||
}
|
||||
queue.add(child);
|
||||
}
|
||||
|
||||
SymmetricComponent sym = (SymmetricComponent) comp;
|
||||
if( null == prevComp){
|
||||
@ -303,7 +321,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
|
||||
prevComp = sym;
|
||||
}else if( comp instanceof ComponentAssembly ){
|
||||
isContinuous &= testIsContinuous( comp );
|
||||
isContinuous &= testIsContinuous(configuration, comp);
|
||||
}
|
||||
|
||||
}
|
||||
@ -319,7 +337,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
* @param configuration Rocket configuration
|
||||
* @param conditions Flight conditions taken into account
|
||||
* @param map ?
|
||||
* @param set Set to handle
|
||||
* @param warningSet Set to handle warnings
|
||||
* @return friction drag for entire rocket
|
||||
*/
|
||||
private double calculateFrictionCD(FlightConfiguration configuration, FlightConditions conditions,
|
||||
@ -611,7 +629,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
|
||||
double radius = 0;
|
||||
final SymmetricComponent prevComponent = s.getPreviousSymmetricComponent();
|
||||
if (prevComponent != null)
|
||||
if (prevComponent != null && configuration.isComponentActive(prevComponent))
|
||||
radius = prevComponent.getAftRadius();
|
||||
|
||||
if (radius < s.getForeRadius()) {
|
||||
@ -672,7 +690,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
// its aft CD
|
||||
double radius = 0;
|
||||
final SymmetricComponent prevComponent = s.getPreviousSymmetricComponent();
|
||||
if (prevComponent != null) {
|
||||
if (prevComponent != null && configuration.isComponentActive(prevComponent)) {
|
||||
radius = prevComponent.getAftRadius();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.document;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.EventListener;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
@ -350,13 +351,15 @@ public class Simulation implements ChangeSource, Cloneable {
|
||||
SimulationEngine simulator;
|
||||
|
||||
try {
|
||||
simulator = simulationEngineClass.newInstance();
|
||||
simulator = simulationEngineClass.getConstructor().newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalStateException("Cannot instantiate simulator.", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Cannot access simulator instance?! BUG!", e);
|
||||
} catch (InvocationTargetException | NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
SimulationConditions simulationConditions = options.toSimulationConditions();
|
||||
simulationConditions.setSimulation(this);
|
||||
for (SimulationListener l : additionalListeners) {
|
||||
|
@ -11,6 +11,9 @@ import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
/**
|
||||
* A "simple SAX" XML reader. This system imposes the limit that an XML element may
|
||||
@ -18,27 +21,26 @@ import org.xml.sax.helpers.XMLReaderFactory;
|
||||
* both. This holds true for both the OpenRocket and RockSim design formats and the
|
||||
* RockSim engine definition format.
|
||||
* <p>
|
||||
* The actual handling is performed by subclasses of {@link ElementHandler}. The
|
||||
* The actual handling is performed by subclasses of {@link ElementHandler}. The
|
||||
* initial handler is provided to the {@link #readXML(InputSource, ElementHandler, WarningSet)}
|
||||
* method.
|
||||
*
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class SimpleSAX {
|
||||
|
||||
static final XMLReaderCache cache = new XMLReaderCache(10);
|
||||
|
||||
/**
|
||||
* Read a simple XML file.
|
||||
*
|
||||
*
|
||||
* @param source the SAX input source.
|
||||
* @param initialHandler the initial content handler.
|
||||
* @param warnings a warning set to store warning (cannot be <code>null</code>).
|
||||
* @throws IOException if an I/O exception occurs while reading.
|
||||
* @throws SAXException if e.g. malformed XML is encountered.
|
||||
*/
|
||||
public static void readXML(InputSource source, ElementHandler initialHandler,
|
||||
WarningSet warnings) throws IOException, SAXException {
|
||||
public static void readXML(InputSource source, ElementHandler initialHandler, WarningSet warnings)
|
||||
throws IOException, SAXException {
|
||||
|
||||
DelegatorHandler xmlhandler = new DelegatorHandler(initialHandler, warnings);
|
||||
|
||||
@ -55,17 +57,27 @@ public class SimpleSAX {
|
||||
}
|
||||
|
||||
private static class XMLReaderCache {
|
||||
private final SAXParserFactory parserFactory;
|
||||
|
||||
private final BlockingQueue<XMLReader> queue;
|
||||
|
||||
private XMLReaderCache( int maxSize ) {
|
||||
this.queue = new LinkedBlockingQueue<XMLReader>(maxSize);
|
||||
parserFactory = SAXParserFactory.newInstance();
|
||||
parserFactory.setNamespaceAware(true);
|
||||
queue = new LinkedBlockingQueue<XMLReader>(maxSize);
|
||||
}
|
||||
|
||||
private XMLReader createXMLReader() throws SAXException {
|
||||
|
||||
XMLReader reader = queue.poll();
|
||||
if ( reader == null ) {
|
||||
try {
|
||||
reader = XMLReaderFactory.createXMLReader();
|
||||
SAXParser parser = parserFactory.newSAXParser();
|
||||
reader = parser.getXMLReader();
|
||||
}
|
||||
catch (ParserConfigurationException ignore) {
|
||||
System.out.print(ignore);
|
||||
}
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
@ -77,5 +89,4 @@ public class SimpleSAX {
|
||||
queue.offer( reader );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ public class MassCalculator implements Monitorable {
|
||||
public static RigidBody calculate( final MassCalculation.Type _type, final SimulationStatus status ){
|
||||
final FlightConfiguration config = status.getConfiguration();
|
||||
final double time = status.getSimulationTime();
|
||||
final Collection<MotorClusterState> activeMotorList = status.getMotors();
|
||||
final Collection<MotorClusterState> activeMotorList = status.getActiveMotors();
|
||||
MassCalculation calculation= new MassCalculation( _type, config, time, activeMotorList, config.getRocket(), Transformation.IDENTITY, null);
|
||||
|
||||
calculation.calculateAssembly();
|
||||
|
@ -4,6 +4,7 @@ import java.util.Locale;
|
||||
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.simulation.FlightEvent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
@ -13,25 +14,25 @@ public enum IgnitionEvent {
|
||||
//// Automatic (launch or ejection charge)
|
||||
AUTOMATIC( "AUTOMATIC", "MotorMount.IgnitionEvent.AUTOMATIC"){
|
||||
@Override
|
||||
public boolean isActivationEvent(FlightEvent testEvent, RocketComponent targetComponent) {
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent testEvent, RocketComponent targetComponent) {
|
||||
AxialStage targetStage = targetComponent.getStage();
|
||||
|
||||
if ( targetStage.isLaunchStage() ){
|
||||
return LAUNCH.isActivationEvent(testEvent, targetComponent);
|
||||
if (targetStage.isLaunchStage(config)) {
|
||||
return LAUNCH.isActivationEvent(config, testEvent, targetComponent);
|
||||
} else {
|
||||
return EJECTION_CHARGE.isActivationEvent(testEvent, targetComponent);
|
||||
return EJECTION_CHARGE.isActivationEvent(config, testEvent, targetComponent);
|
||||
}
|
||||
}
|
||||
},
|
||||
LAUNCH ( "LAUNCH", "MotorMount.IgnitionEvent.LAUNCH"){
|
||||
@Override
|
||||
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent fe, RocketComponent source){
|
||||
return (fe.getType() == FlightEvent.Type.LAUNCH);
|
||||
}
|
||||
},
|
||||
EJECTION_CHARGE ("EJECTION_CHARGE", "MotorMount.IgnitionEvent.EJECTION_CHARGE"){
|
||||
@Override
|
||||
public boolean isActivationEvent( FlightEvent testEvent, RocketComponent targetComponent){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent testEvent, RocketComponent targetComponent){
|
||||
if (testEvent.getType() != FlightEvent.Type.EJECTION_CHARGE){
|
||||
return false;
|
||||
}
|
||||
@ -44,7 +45,7 @@ public enum IgnitionEvent {
|
||||
},
|
||||
BURNOUT ("BURNOUT", "MotorMount.IgnitionEvent.BURNOUT"){
|
||||
@Override
|
||||
public boolean isActivationEvent( FlightEvent testEvent, RocketComponent targetComponent){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent testEvent, RocketComponent targetComponent){
|
||||
if (testEvent.getType() != FlightEvent.Type.BURNOUT)
|
||||
return false;
|
||||
|
||||
@ -64,7 +65,7 @@ public enum IgnitionEvent {
|
||||
|
||||
//public static final IgnitionEvent[] events = {AUTOMATIC, LAUNCH, EJECTION_CHARGE, BURNOUT, NEVER};
|
||||
|
||||
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent fe, RocketComponent source){
|
||||
// default behavior. Also for the NEVER case.
|
||||
return false;
|
||||
}
|
||||
|
@ -67,6 +67,23 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
public boolean isCompatible(Class<? extends RocketComponent> type) {
|
||||
return BodyComponent.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current stage is active in the currently selected configuration.
|
||||
* @return true if the stage is active, false if not
|
||||
*/
|
||||
public boolean isStageActive() {
|
||||
return getRocket().getSelectedConfiguration().isStageActive(getStageNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current stage is active in the flight configuration.
|
||||
* @param fc the flight configuration to check
|
||||
* @return true if the stage is active, false if not
|
||||
*/
|
||||
public boolean isStageActive(FlightConfiguration fc) {
|
||||
return fc.isStageActive(getStageNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFlightConfiguration(FlightConfigurationId oldConfigId, FlightConfigurationId newConfigId) {
|
||||
@ -113,11 +130,11 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
|
||||
/**
|
||||
* returns if the object is a launch stage
|
||||
* @param config the flight configuration which will check which stages are active
|
||||
* @return if the object is a launch stage
|
||||
*/
|
||||
public boolean isLaunchStage(){
|
||||
return ( this instanceof ParallelStage )
|
||||
||( getRocket().getBottomCoreStage().equals(this));
|
||||
public boolean isLaunchStage(FlightConfiguration config) {
|
||||
return (getRocket().getBottomCoreStage(config).equals(this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,8 +60,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
|
||||
/* Cached data */
|
||||
final protected HashMap<Integer, StageFlags> stages = new HashMap<Integer, StageFlags>();
|
||||
final protected HashMap<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>();
|
||||
final protected Map<Integer, StageFlags> stages = new HashMap<Integer, StageFlags>(); // Map of stage number to StageFlags of the corresponding stage
|
||||
final protected Map<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>();
|
||||
final private Collection<MotorConfiguration> activeMotors = new ArrayList<MotorConfiguration>();
|
||||
final private InstanceMap activeInstances = new InstanceMap();
|
||||
|
||||
@ -179,31 +179,52 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
*/
|
||||
public void setOnlyStage(final int stageNumber) {
|
||||
_setAllStages(false);
|
||||
_setStageActive(stageNumber, true);
|
||||
_setStageActive(stageNumber, true, false);
|
||||
updateMotors();
|
||||
updateActiveInstances();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* This method flags the specified stage as requested. Other stages are unaffected.
|
||||
*
|
||||
*
|
||||
* @param stageNumber stage number to flag
|
||||
* @param _active inactive (<code>false</code>) or active (<code>true</code>)
|
||||
* @param activateSubStages whether the sub-stages of the specified stage should be activated as well.
|
||||
*/
|
||||
private void _setStageActive(final int stageNumber, final boolean _active ) {
|
||||
public void _setStageActive(final int stageNumber, final boolean _active, final boolean activateSubStages) {
|
||||
if ((0 <= stageNumber) && (stages.containsKey(stageNumber))) {
|
||||
stages.get(stageNumber).active = _active;
|
||||
if (activateSubStages) {
|
||||
// Set the active state of all the sub-stages as well.
|
||||
for (AxialStage stage : rocket.getStage(stageNumber).getSubStages()) {
|
||||
stages.get(stage.getStageNumber()).active = _active;
|
||||
}
|
||||
}
|
||||
fireChangeEvent();
|
||||
return;
|
||||
}
|
||||
log.error("error: attempt to retrieve via a bad stage number: " + stageNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method flags the specified stage as requested. Actives the sub-stages of the specified stage as well.
|
||||
*
|
||||
* @param stageNumber stage number to flag
|
||||
* @param _active inactive (<code>false</code>) or active (<code>true</code>)
|
||||
*/
|
||||
public void _setStageActive(final int stageNumber, final boolean _active ) {
|
||||
_setStageActive(stageNumber, _active, true);
|
||||
}
|
||||
|
||||
|
||||
public void toggleStage(final int stageNumber) {
|
||||
if ((0 <= stageNumber) && (stages.containsKey(stageNumber))) {
|
||||
StageFlags flags = stages.get(stageNumber);
|
||||
flags.active = !flags.active;
|
||||
// Set the active state of all the sub-stages as well.
|
||||
for (AxialStage stage : rocket.getStage(stageNumber).getSubStages()) {
|
||||
stages.get(stage.getStageNumber()).active = flags.active;
|
||||
}
|
||||
updateMotors();
|
||||
updateActiveInstances();
|
||||
|
||||
@ -338,6 +359,18 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the stages in this configuration.
|
||||
* @return all the stages in this configuration.
|
||||
*/
|
||||
public List<AxialStage> getAllStages() {
|
||||
List<AxialStage> stages = new ArrayList<>();
|
||||
for (StageFlags flags : this.stages.values()) {
|
||||
stages.add( rocket.getStage(flags.stageNumber));
|
||||
}
|
||||
return stages;
|
||||
}
|
||||
|
||||
public List<AxialStage> getActiveStages() {
|
||||
List<AxialStage> activeStages = new ArrayList<>();
|
||||
|
@ -26,7 +26,7 @@ import net.sf.openrocket.util.MathUtil;
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class InnerTube extends ThicknessRingComponent implements AxialPositionable, BoxBounded, Clusterable, RadialParent, MotorMount {
|
||||
public class InnerTube extends ThicknessRingComponent implements AxialPositionable, BoxBounded, Clusterable, RadialParent, MotorMount, InsideColorComponent {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Logger log = LoggerFactory.getLogger(InnerTube.class);
|
||||
|
||||
@ -37,6 +37,8 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
|
||||
private double overhang = 0;
|
||||
private boolean isActingMount;
|
||||
private MotorConfigurationSet motors;
|
||||
|
||||
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
@ -447,6 +449,16 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
|
||||
return this.motors.toDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||
return this.insideColorComponentHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||
this.insideColorComponentHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addConfigListener(RocketComponent listener) {
|
||||
boolean success = super.addConfigListener(listener);
|
||||
|
@ -111,8 +111,8 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLaunchStage(){
|
||||
return true;
|
||||
public boolean isLaunchStage(FlightConfiguration config) {
|
||||
return config.isStageActive(this.stageNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -197,24 +197,37 @@ public class Rocket extends ComponentAssembly {
|
||||
public AxialStage getStage( final int stageNumber ) {
|
||||
return this.stageMap.get( stageNumber);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the stage at the top of the central stack
|
||||
*
|
||||
* @Return a reference to the topmost stage
|
||||
|
||||
/**
|
||||
* Get the topmost stage, only taking into account active stages from the flight configuration.
|
||||
* @param config flight configuration dictating which stages are active
|
||||
* @return the topmost active stage, or null if there are no active stages.
|
||||
*/
|
||||
public AxialStage getTopmostStage(){
|
||||
return (AxialStage) getChild(0);
|
||||
public AxialStage getTopmostStage(FlightConfiguration config) {
|
||||
if (config == null) return null;
|
||||
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
if (getChild(i) instanceof AxialStage && config.isStageActive(getChild(i).getStageNumber())) {
|
||||
return (AxialStage) getChild(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the stage at the top of the central stack
|
||||
*
|
||||
* @Return a reference to the topmost stage
|
||||
|
||||
/**
|
||||
* Get the bottommost stage, only taking into account active stages from the flight configuration.
|
||||
* @param config flight configuration dictating which stages are active
|
||||
* @return the bottommost active stage, or null if there are no active stages.
|
||||
*/
|
||||
/*package-local*/ AxialStage getBottomCoreStage(){
|
||||
// get last stage that's a direct child of the rocket.
|
||||
return (AxialStage) children.get( children.size()-1 );
|
||||
public AxialStage getBottomCoreStage(FlightConfiguration config) {
|
||||
if (config == null) return null;
|
||||
|
||||
for (int i = getChildCount() - 1; i >= 0; i--) {
|
||||
if (getChild(i) instanceof AxialStage && config.isStageActive(getChild(i).getStageNumber())) {
|
||||
return (AxialStage) getChild(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -274,6 +287,11 @@ public class Rocket extends ComponentAssembly {
|
||||
refType = type;
|
||||
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLength() {
|
||||
return selectedConfiguration.getLength();
|
||||
}
|
||||
|
||||
|
||||
public double getCustomReferenceLength() {
|
||||
@ -291,6 +309,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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -390,10 +419,12 @@ public class Rocket extends ComponentAssembly {
|
||||
this.stageMap = r.stageMap;
|
||||
|
||||
// these flight configurations need to reference the _this_ Rocket:
|
||||
this.configSet.reset();
|
||||
this.configSet.setDefault(new FlightConfiguration(this));
|
||||
for (FlightConfigurationId key : r.configSet.map.keySet()) {
|
||||
this.configSet.set(key, new FlightConfiguration(this, key));
|
||||
}
|
||||
this.selectedConfiguration = this.configSet.get(r.getSelectedConfiguration().getId());
|
||||
|
||||
this.perfectFinish = r.perfectFinish;
|
||||
|
||||
@ -735,6 +766,14 @@ public class Rocket extends ComponentAssembly {
|
||||
fireComponentChangeEvent(ComponentChangeEvent.TREE_CHANGE);
|
||||
return nextConfig.getFlightConfigurationID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the flight configurations of this rocket.
|
||||
* @return all the flight configurations of this rocket.
|
||||
*/
|
||||
public FlightConfigurableParameterSet<FlightConfiguration> getFlightConfigurations() {
|
||||
return this.configSet;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1010,7 +1010,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
* If the length of a component is settable, the class must define the setter method
|
||||
* itself.
|
||||
*/
|
||||
public final double getLength() {
|
||||
public double getLength() {
|
||||
mutex.verify();
|
||||
return length;
|
||||
}
|
||||
@ -1545,6 +1545,11 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
AxialStage stage = (AxialStage) component;
|
||||
this.getRocket().forgetStage(stage);
|
||||
}
|
||||
|
||||
// Remove sub-stages of the removed component
|
||||
for (AxialStage stage : component.getSubStages()) {
|
||||
this.getRocket().forgetStage(stage);
|
||||
}
|
||||
|
||||
this.checkComponentStructure();
|
||||
component.checkComponentStructure();
|
||||
@ -1749,6 +1754,21 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
}
|
||||
throw new IllegalStateException("getStage() called on hierarchy without an AxialStage.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the stages that are a child or sub-child of this component.
|
||||
* @return all the stages that are a child or sub-child of this component.
|
||||
*/
|
||||
public final List<AxialStage> getSubStages() {
|
||||
List<AxialStage> result = new LinkedList<>();
|
||||
Iterator<RocketComponent> it = iterator(false);
|
||||
while (it.hasNext()) {
|
||||
RocketComponent c = it.next();
|
||||
if (c instanceof AxialStage)
|
||||
result.add((AxialStage) c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first component assembly component that this component belongs to.
|
||||
|
@ -45,7 +45,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
private final static double AOA_TUMBLE_CONDITION = Math.PI / 9.0;
|
||||
|
||||
// The thrust must be below this value for the transition to tumbling.
|
||||
// TODO: this is an arbitrary value
|
||||
// TODO HIGH: this is an arbitrary value
|
||||
private final static double THRUST_TUMBLE_CONDITION = 0.01;
|
||||
|
||||
private SimulationStepper currentStepper;
|
||||
@ -65,7 +65,9 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
// Set up rocket configuration
|
||||
this.fcid = simulationConditions.getFlightConfigurationID();
|
||||
FlightConfiguration simulationConfig = simulationConditions.getRocket().getFlightConfiguration( this.fcid).clone();
|
||||
FlightConfiguration origConfig = simulationConditions.getRocket().getFlightConfiguration(this.fcid);
|
||||
FlightConfiguration simulationConfig = origConfig.clone();
|
||||
simulationConfig.copyStages(origConfig); // Clone the stage activation configuration
|
||||
if ( ! simulationConfig.hasMotors() ) {
|
||||
throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noMotorsDefined"));
|
||||
}
|
||||
@ -74,7 +76,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
currentStatus.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket()));
|
||||
{
|
||||
// main simulation branch
|
||||
final String branchName = simulationConfig.getRocket().getTopmostStage().getName();
|
||||
final String branchName = simulationConfig.getRocket().getTopmostStage(currentStatus.getConfiguration()).getName();
|
||||
currentStatus.setFlightData(new FlightDataBranch( branchName, FlightDataType.TYPE_TIME));
|
||||
}
|
||||
toSimulate.push(currentStatus);
|
||||
@ -273,9 +275,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
// Check for motor ignition events, add ignition events to queue
|
||||
for (MotorClusterState state : currentStatus.getActiveMotors() ){
|
||||
if( state.testForIgnition(event )){
|
||||
final double simulationTime = currentStatus.getSimulationTime() ;
|
||||
|
||||
if (state.testForIgnition(currentStatus.getConfiguration(), event)) {
|
||||
MotorClusterState sourceState = (MotorClusterState) event.getData();
|
||||
double ignitionDelay = 0;
|
||||
if (event.getType() == FlightEvent.Type.BURNOUT)
|
||||
@ -543,7 +543,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
}
|
||||
|
||||
// TODO : FUTURE : do not hard code the 1200 (maybe even make it configurable by the user)
|
||||
// TODO FUTURE : do not hard code the 1200 (maybe even make it configurable by the user)
|
||||
if( 1200 < currentStatus.getSimulationTime() ){
|
||||
ret = false;
|
||||
log.error("Simulation hit max time (1200s): aborting.");
|
||||
@ -553,6 +553,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
// If no motor has ignited, abort
|
||||
if (!currentStatus.isMotorIgnited()) {
|
||||
// TODO MEDIUM: display this as a warning to the user (e.g. highlight the cell in the simulation panel in red and a hover: 'make sure the motor ignition is correct' or something)
|
||||
throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noIgnition"));
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ public class FlightEvent implements Comparable<FlightEvent> {
|
||||
* @return
|
||||
*/
|
||||
public void validate(){
|
||||
if( this.time == Double.NaN ){
|
||||
if(Double.isNaN(this.time)){
|
||||
throw new IllegalStateException(type.name()+" event has a NaN time!");
|
||||
}
|
||||
switch( this.type ){
|
||||
|
@ -4,6 +4,7 @@ import net.sf.openrocket.motor.IgnitionEvent;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.motor.MotorConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
@ -121,8 +122,8 @@ public class MotorClusterState {
|
||||
/**
|
||||
* Compute the average thrust over an interval.
|
||||
*
|
||||
* @param simulationTime
|
||||
* @param cond
|
||||
* @param startSimulationTime start time of the averaging interval
|
||||
* @param endSimulationTime end time of the averaging interval
|
||||
* @return
|
||||
*/
|
||||
public double getAverageThrust( final double startSimulationTime, final double endSimulationTime) {
|
||||
@ -141,7 +142,6 @@ public class MotorClusterState {
|
||||
* Compute the average thrust over an interval.
|
||||
*
|
||||
* @param simulationTime
|
||||
* @param cond
|
||||
* @return
|
||||
*/
|
||||
public double getThrust( final double simulationTime){
|
||||
@ -182,9 +182,9 @@ public class MotorClusterState {
|
||||
currentState = ThrustState.ARMED;
|
||||
}
|
||||
|
||||
public boolean testForIgnition( final FlightEvent _event ){
|
||||
public boolean testForIgnition(FlightConfiguration flightConfiguration, final FlightEvent _event ){
|
||||
RocketComponent mount = (RocketComponent) this.getMount();
|
||||
return getIgnitionEvent().isActivationEvent( _event, mount);
|
||||
return getIgnitionEvent().isActivationEvent(flightConfiguration, _event, mount);
|
||||
}
|
||||
|
||||
public String toDescription(){
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -267,22 +267,25 @@ public class BarrowmanCalculatorTest {
|
||||
public void testContinuousRocket() {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
assertTrue("Estes Alpha III should be continous: ", calc.isContinuous( rocket));
|
||||
assertTrue("Estes Alpha III should be continous: ", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContinuousRocketWithStrapOns() {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
assertTrue("F9H should be continuous: ", calc.isContinuous( rocket));
|
||||
assertTrue("F9H should be continuous: ", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRadialDiscontinuousRocket() {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
NoseCone nose = (NoseCone)rocket.getChild(0).getChild(0);
|
||||
BodyTube body = (BodyTube)rocket.getChild(0).getChild(1);
|
||||
@ -291,13 +294,14 @@ public class BarrowmanCalculatorTest {
|
||||
body.setOuterRadius( 0.012 );
|
||||
body.setName( body.getName()+" << discontinuous");
|
||||
|
||||
assertFalse(" Estes Alpha III has an undetected discontinuity:", calc.isContinuous( rocket));
|
||||
assertFalse(" Estes Alpha III has an undetected discontinuity:", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRadialDiscontinuityWithStrapOns() {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
final AxialStage coreStage = (AxialStage)rocket.getChild(1);
|
||||
final ParallelStage booster = (ParallelStage)coreStage.getChild(0).getChild(0);
|
||||
@ -309,7 +313,7 @@ public class BarrowmanCalculatorTest {
|
||||
body.setOuterRadius( 0.012 );
|
||||
body.setName( body.getName()+" << discontinuous");
|
||||
|
||||
assertFalse(" Missed discontinuity in Falcon 9 Heavy:", calc.isContinuous( rocket));
|
||||
assertFalse(" Missed discontinuity in Falcon 9 Heavy:", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -294,9 +294,22 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
|
||||
config.toggleStage(0);
|
||||
assertThat(" toggle stage #0: ", config.isStageActive(0), equalTo(false));
|
||||
|
||||
AxialStage sustainer = rkt.getTopmostStage();
|
||||
AxialStage booster = rkt.getBottomCoreStage();
|
||||
|
||||
AxialStage sustainer = rkt.getTopmostStage(config);
|
||||
AxialStage booster = rkt.getBottomCoreStage(config);
|
||||
assertThat(" sustainer stage is stage #1: ", sustainer.getStageNumber(), equalTo(1));
|
||||
assertThat(" booster stage is stage #1: ", booster.getStageNumber(), equalTo(1));
|
||||
|
||||
config.setAllStages();
|
||||
config._setStageActive(1, false);
|
||||
sustainer = rkt.getTopmostStage(config);
|
||||
booster = rkt.getBottomCoreStage(config);
|
||||
assertThat(" sustainer stage is stage #1: ", sustainer.getStageNumber(), equalTo(0));
|
||||
assertThat(" booster stage is stage #1: ", booster.getStageNumber(), equalTo(0));
|
||||
|
||||
config.setAllStages();
|
||||
sustainer = rkt.getTopmostStage(config);
|
||||
booster = rkt.getBottomCoreStage(config);
|
||||
assertThat(" sustainer stage is stage #0: ", sustainer.getStageNumber(), equalTo(0));
|
||||
assertThat(" booster stage is stage #1: ", booster.getStageNumber(), equalTo(1));
|
||||
|
||||
@ -351,7 +364,6 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
|
||||
selected.clearAllStages();
|
||||
selected.toggleStage(1);
|
||||
selected.toggleStage(2);
|
||||
|
||||
// vvvv Test Target vvvv
|
||||
InstanceMap instances = selected.getActiveInstances();
|
||||
|
305
core/test/net/sf/openrocket/simulation/DisableStageTest.java
Normal file
305
core/test/net/sf/openrocket/simulation/DisableStageTest.java
Normal file
@ -0,0 +1,305 @@
|
||||
package net.sf.openrocket.simulation;
|
||||
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
import net.sf.openrocket.util.TestRockets;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test class that tests the effect on the simulation results of activating/deactivating stages.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public class DisableStageTest extends BaseTestCase {
|
||||
/**
|
||||
* Tests that the simulation results are correct when a single stage is deactivated and re-activated.
|
||||
*/
|
||||
@Test
|
||||
public void testSingleStage() throws SimulationException {
|
||||
//// Test disabling the stage
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
|
||||
Simulation simDisabled = new Simulation(rocket);
|
||||
simDisabled.setFlightConfigurationId(TestRockets.TEST_FCID_0);
|
||||
simDisabled.getActiveConfiguration()._setStageActive(0, false);
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
// Since there are no stages, the simulation should throw an exception.
|
||||
try {
|
||||
simDisabled.simulate(simulationListener);
|
||||
} catch (SimulationException e) {
|
||||
if (!(e instanceof MotorIgnitionException)) {
|
||||
Assert.fail("Simulation should have thrown a MotorIgnitionException");
|
||||
}
|
||||
}
|
||||
|
||||
//// Test re-enableing the stage.
|
||||
Rocket rocketOriginal = TestRockets.makeEstesAlphaIII();
|
||||
|
||||
Simulation simOriginal = new Simulation(rocketOriginal);
|
||||
simOriginal.setFlightConfigurationId(TestRockets.TEST_FCID_0);
|
||||
simOriginal.getOptions().setISAAtmosphere(true);
|
||||
simOriginal.getOptions().setTimeStep(0.05);
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages(); // Re-enable all stages.
|
||||
|
||||
double delta = 0.05; // 5 % error margin (simulations are not exact)
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the simulation results are correct when the last stage of a multi-stage rocket is deactivated and re-activated.
|
||||
*/
|
||||
@Test
|
||||
public void testMultiStageLastDisabled() {
|
||||
//// Test disabling the stage
|
||||
Rocket rocketRemoved = TestRockets.makeBeta(); // Rocket with the last stage removed
|
||||
Rocket rocketDisabled = TestRockets.makeBeta(); // Rocket with the last stage disabled
|
||||
|
||||
int stageNr = rocketRemoved.getChildCount() - 1;
|
||||
rocketRemoved.removeChild(stageNr);
|
||||
FlightConfiguration fc = rocketDisabled.getFlightConfiguration(TestRockets.TEST_FCID_1);
|
||||
fc._setStageActive(stageNr, false);
|
||||
|
||||
Simulation simRemoved = new Simulation(rocketRemoved);
|
||||
simRemoved.setFlightConfigurationId(TestRockets.TEST_FCID_1);
|
||||
simRemoved.getOptions().setISAAtmosphere(true);
|
||||
simRemoved.getOptions().setTimeStep(0.05);
|
||||
|
||||
Simulation simDisabled = new Simulation(rocketDisabled);
|
||||
simDisabled.setFlightConfigurationId(TestRockets.TEST_FCID_1);
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
double delta = 0.05; // 5 % error margin (simulations are not exact)
|
||||
compareSims(simRemoved, simDisabled, simulationListener, delta);
|
||||
|
||||
//// Test re-enableing the stage.
|
||||
Rocket rocketOriginal = TestRockets.makeBeta();
|
||||
Simulation simOriginal = new Simulation(rocketOriginal);
|
||||
simOriginal.setFlightConfigurationId(TestRockets.TEST_FCID_1);
|
||||
simOriginal.getOptions().setISAAtmosphere(true);
|
||||
simOriginal.getOptions().setTimeStep(0.05);
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages();
|
||||
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the simulation results are correct when the first stage of a multi-stage rocket is deactivated and re-activated.
|
||||
*/
|
||||
// Don't even know if this test was useful, but simulation results vary wildly because the first stage is disabled,
|
||||
// so I'm just gonna ignore this test.
|
||||
/*@Test
|
||||
public void testMultiStageFirstDisabled() {
|
||||
//// Test disabling the stage
|
||||
Rocket rocketRemoved = TestRockets.makeBeta(); // Rocket with the last stage removed
|
||||
Rocket rocketDisabled = TestRockets.makeBeta(); // Rocket with the last stage disabled
|
||||
|
||||
// You need to disable the second stage body tube going into automatic radius mode, otherwise the
|
||||
// removed and disabled rocket will have different results (removed rocket will have a different diameter)
|
||||
BodyTube bodyTube = (BodyTube) rocketRemoved.getChild(1).getChild(0);
|
||||
bodyTube.setOuterRadiusAutomatic(false);
|
||||
|
||||
|
||||
int stageNr = 0;
|
||||
rocketRemoved.removeChild(stageNr);
|
||||
FlightConfiguration fc = rocketDisabled.getFlightConfiguration(TestRockets.TEST_FCID_1);
|
||||
fc._setStageActive(stageNr, false);
|
||||
|
||||
Simulation simRemoved = new Simulation(rocketRemoved);
|
||||
simRemoved.setFlightConfigurationId(TestRockets.TEST_FCID_1);
|
||||
simRemoved.getOptions().setISAAtmosphere(true);
|
||||
simRemoved.getOptions().setTimeStep(0.05);
|
||||
|
||||
Simulation simDisabled = new Simulation(rocketDisabled);
|
||||
simDisabled.setFlightConfigurationId(TestRockets.TEST_FCID_1);
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
double delta = 0.1; // 10 % error margin (simulations are very unstable and not exact when the first stage is disabled...)
|
||||
compareSims(simRemoved, simDisabled, simulationListener, delta);
|
||||
|
||||
//// Test re-enableing the stage.
|
||||
Rocket rocketOriginal = TestRockets.makeBeta();
|
||||
Simulation simOriginal = new Simulation(rocketOriginal);
|
||||
simOriginal.setFlightConfigurationId(TestRockets.TEST_FCID_1);
|
||||
simOriginal.getOptions().setISAAtmosphere(true);
|
||||
simOriginal.getOptions().setTimeStep(0.05);
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages();
|
||||
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Tests that the simulation results are correct when a booster stage is deactivated and re-activated.
|
||||
*/
|
||||
@Test
|
||||
public void testBooster1() {
|
||||
//// Test disabling the stage
|
||||
Rocket rocketRemoved = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage removed
|
||||
Rocket rocketDisabled = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage disabled
|
||||
|
||||
FlightConfigurationId fcid = new FlightConfigurationId(TestRockets.FALCON_9H_FCID_1);
|
||||
int stageNr = 2; // Stage 2 is the Parallel Booster Stage
|
||||
rocketRemoved.getChild(1).getChild(0).removeChild(0); // Remove the Parallel Booster Stage
|
||||
FlightConfiguration fc = rocketDisabled.getFlightConfiguration(fcid);
|
||||
fc._setStageActive(stageNr, false);
|
||||
|
||||
Simulation simRemoved = new Simulation(rocketRemoved);
|
||||
simRemoved.setFlightConfigurationId(fcid);
|
||||
simRemoved.getOptions().setISAAtmosphere(true);
|
||||
simRemoved.getOptions().setTimeStep(0.05);
|
||||
|
||||
Simulation simDisabled = new Simulation(rocketDisabled);
|
||||
simDisabled.setFlightConfigurationId(fcid);
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
double delta = 0.05; // 5 % error margin (simulations are not exact)
|
||||
compareSims(simRemoved, simDisabled, simulationListener, delta);
|
||||
|
||||
//// Test re-enableing the stage.
|
||||
Rocket rocketOriginal = TestRockets.makeFalcon9Heavy();
|
||||
Simulation simOriginal = new Simulation(rocketOriginal);
|
||||
simOriginal.setFlightConfigurationId(fcid);
|
||||
simOriginal.getOptions().setISAAtmosphere(true);
|
||||
simOriginal.getOptions().setTimeStep(0.05);
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages();
|
||||
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the simulation results are correct when the parent stage of a booster stage is deactivated and re-activated.
|
||||
*/
|
||||
@Test
|
||||
public void testBooster2() {
|
||||
//// Test disabling the stage
|
||||
Rocket rocketRemoved = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage removed
|
||||
Rocket rocketDisabled = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage disabled
|
||||
|
||||
FlightConfigurationId fid = new FlightConfigurationId(TestRockets.FALCON_9H_FCID_1);
|
||||
int stageNr = 1; // Stage 1 is the Parallel Booster Stage's parent stage
|
||||
rocketRemoved.getChild(1).removeChild(0); // Remove the Parallel Booster Stage's parent stage
|
||||
FlightConfiguration fc = rocketDisabled.getFlightConfiguration(fid);
|
||||
fc._setStageActive(stageNr, false);
|
||||
|
||||
Simulation simRemoved = new Simulation(rocketRemoved);
|
||||
simRemoved.setFlightConfigurationId(fid);
|
||||
simRemoved.getOptions().setISAAtmosphere(true);
|
||||
simRemoved.getOptions().setTimeStep(0.05);
|
||||
|
||||
Simulation simDisabled = new Simulation(rocketDisabled);
|
||||
simDisabled.setFlightConfigurationId(fid);
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
// There should be no motors left at this point, so a no motors exception should be thrown
|
||||
try {
|
||||
simRemoved.simulate(simulationListener);
|
||||
} catch (SimulationException e) {
|
||||
if (!(e instanceof MotorIgnitionException)) {
|
||||
Assert.fail("Simulation failed: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
simDisabled.simulate(simulationListener);
|
||||
} catch (SimulationException e) {
|
||||
if (!(e instanceof MotorIgnitionException)) {
|
||||
Assert.fail("Simulation failed: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
//// Test re-enableing the stage.
|
||||
Rocket rocketOriginal = TestRockets.makeFalcon9Heavy();
|
||||
Simulation simOriginal = new Simulation(rocketOriginal);
|
||||
simOriginal.setFlightConfigurationId(fid);
|
||||
simOriginal.getOptions().setISAAtmosphere(true);
|
||||
simOriginal.getOptions().setTimeStep(0.05);
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages();
|
||||
|
||||
double delta = 0.05; // 5 % error margin (simulations are not exact)
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare simActual to simExpected and fail the unit test if there was an error during simulation or
|
||||
* the two don't match.
|
||||
* Tested parameters:
|
||||
* - maxAcceleration
|
||||
* - maxAltitude
|
||||
* - maxVelocity
|
||||
* - maxMachNumber
|
||||
* - flightTime
|
||||
* - launchRodVelocity
|
||||
* - deploymentVelocity
|
||||
* - groundHitVelocity
|
||||
* @param simExpected the expected simulation results
|
||||
* @param simActual the actual simulation results
|
||||
* @param simulationListener the simulation listener to use for the comparison
|
||||
* @param delta the error margin for the comparison (e.g. 0.05 = 5 % error margin)
|
||||
*/
|
||||
private void compareSims(Simulation simExpected, Simulation simActual,
|
||||
SimulationListener simulationListener, double delta) {
|
||||
try {
|
||||
simExpected.simulate(simulationListener);
|
||||
double maxAccelerationOriginal = simExpected.getSimulatedData().getMaxAcceleration();
|
||||
double maxAltitudeOriginal = simExpected.getSimulatedData().getMaxAltitude();
|
||||
double maxVelocityOriginal = simExpected.getSimulatedData().getMaxVelocity();
|
||||
double maxMachNumberOriginal = simExpected.getSimulatedData().getMaxMachNumber();
|
||||
double flightTimeOriginal = simExpected.getSimulatedData().getFlightTime();
|
||||
double timeToApogeeOriginal = simExpected.getSimulatedData().getTimeToApogee();
|
||||
double launchRodVelocityOriginal = simExpected.getSimulatedData().getLaunchRodVelocity();
|
||||
double deploymentVelocityOriginal = simExpected.getSimulatedData().getDeploymentVelocity();
|
||||
double groundHitVelocityOriginal = simExpected.getSimulatedData().getGroundHitVelocity();
|
||||
|
||||
simActual.simulate(simulationListener);
|
||||
double maxAccelerationDisabled = simActual.getSimulatedData().getMaxAcceleration();
|
||||
double maxAltitudeDisabled = simActual.getSimulatedData().getMaxAltitude();
|
||||
double maxVelocityDisabled = simActual.getSimulatedData().getMaxVelocity();
|
||||
double maxMachNumberDisabled = simActual.getSimulatedData().getMaxMachNumber();
|
||||
double flightTimeDisabled = simActual.getSimulatedData().getFlightTime();
|
||||
double timeToApogeeDisabled = simActual.getSimulatedData().getTimeToApogee();
|
||||
double launchRodVelocityDisabled = simActual.getSimulatedData().getLaunchRodVelocity();
|
||||
double deploymentVelocityDisabled = simActual.getSimulatedData().getDeploymentVelocity();
|
||||
double groundHitVelocityDisabled = simActual.getSimulatedData().getGroundHitVelocity();
|
||||
|
||||
Assert.assertEquals(maxAccelerationOriginal, maxAccelerationDisabled, maxAccelerationOriginal * delta);
|
||||
Assert.assertEquals(maxAltitudeOriginal, maxAltitudeDisabled, maxAltitudeOriginal * delta);
|
||||
Assert.assertEquals(maxVelocityOriginal, maxVelocityDisabled, maxVelocityOriginal * delta);
|
||||
Assert.assertEquals(maxMachNumberOriginal, maxMachNumberDisabled, maxMachNumberOriginal * delta);
|
||||
Assert.assertEquals(flightTimeOriginal, flightTimeDisabled, flightTimeOriginal * delta);
|
||||
Assert.assertEquals(timeToApogeeOriginal, timeToApogeeDisabled, timeToApogeeOriginal * delta);
|
||||
Assert.assertEquals(launchRodVelocityOriginal, launchRodVelocityDisabled, launchRodVelocityOriginal * delta);
|
||||
Assert.assertEquals(deploymentVelocityOriginal, deploymentVelocityDisabled, deploymentVelocityOriginal * delta);
|
||||
Assert.assertEquals(groundHitVelocityOriginal, groundHitVelocityDisabled, groundHitVelocityOriginal * delta);
|
||||
} catch (SimulationException e) {
|
||||
Assert.fail("Simulation failed: " + e);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,8 @@
|
||||
<classpathentry kind="lib" path="/OpenRocket Core/lib/aopalliance.jar"/>
|
||||
<classpathentry kind="lib" path="/OpenRocket Core/lib/commonmark-0.19.0.jar"/>
|
||||
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.inject.jar"/>
|
||||
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.json-1.1.3.jar"/>
|
||||
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.json-api-1.1.3.jar"/>
|
||||
<classpathentry kind="lib" path="/OpenRocket Core/resources"/>
|
||||
<classpathentry kind="lib" path="resources"/>
|
||||
<classpathentry kind="lib" path="lib/miglayout-4.0-swing.jar" sourcepath="reference/miglayout-4.0-sources.jar"/>
|
||||
|
@ -154,7 +154,7 @@
|
||||
depends="build">
|
||||
|
||||
<for param="vendor-dir">
|
||||
<dirset dir="${resources-src.dir}/datafiles/rocksim_components"
|
||||
<dirset dir="${resources-src.dir}/datafiles/rocksim_src"
|
||||
includes="*"/>
|
||||
<sequential>
|
||||
<propertyregex property="vendor"
|
||||
|
@ -1,8 +1,14 @@
|
||||
package net.sf.openrocket.gui;
|
||||
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.text.DefaultFormatter;
|
||||
import javax.swing.text.DefaultFormatterFactory;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
/**
|
||||
* Editable editor for a JSpinner. Simply uses JSpinner.DefaultEditor, which has been made
|
||||
@ -22,6 +28,59 @@ public class SpinnerEditor extends JSpinner.DefaultEditor {
|
||||
DefaultFormatterFactory dff = (DefaultFormatterFactory) getTextField().getFormatterFactory();
|
||||
DefaultFormatter formatter = (DefaultFormatter) dff.getDefaultFormatter();
|
||||
formatter.setOverwriteMode(false);
|
||||
|
||||
|
||||
// Add listeners to select all the text when the field is focussed
|
||||
{
|
||||
getTextField().addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
selectAllText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
getTextField().addMouseListener(new MouseListener() {
|
||||
private boolean isFocussed = false; // Checks whether the text field was focussed when it was clicked upon
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// If the text field was focussed when it was clicked upon instead of e.g. tab-switching to gain focus,
|
||||
// then the select all action from the focus listener is ignored (it is replaced by a cursor-click event).
|
||||
// So if we detect such a focus change, then redo the select all action.
|
||||
if (!isFocussed) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JTextField tf = (JTextField) e.getSource();
|
||||
tf.selectAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
JTextField tf = (JTextField) e.getSource();
|
||||
isFocussed = tf.hasFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,5 +92,17 @@ public class SpinnerEditor extends JSpinner.DefaultEditor {
|
||||
this(spinner);
|
||||
getTextField().setColumns(cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights all the text in the text field.
|
||||
*/
|
||||
private void selectAllText() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getTextField().selectAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,16 +5,14 @@ import java.util.List;
|
||||
|
||||
import javax.swing.AbstractListModel;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.sf.openrocket.database.ComponentPresetDatabase;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.sf.openrocket.gui.configdialog.RocketComponentConfig;
|
||||
import net.sf.openrocket.database.Database;
|
||||
import net.sf.openrocket.database.DatabaseListener;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.dialogs.preset.ComponentPresetChooserDialog;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.Markers;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
@ -29,8 +27,7 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
|
||||
private static final Logger log = LoggerFactory.getLogger(PresetModel.class);
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private static final String NONE_SELECTED = trans.get("lbl.select");
|
||||
private static final String SELECT_DATABASE = trans.get("lbl.database");
|
||||
private static final String NONE_SELECTED = String.format("<html><i>%s</i></html>", trans.get("PresetModel.lbl.custompreset"));
|
||||
|
||||
private final Component parent;
|
||||
private final RocketComponent component;
|
||||
@ -50,7 +47,7 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return presets.size() + 2;
|
||||
return presets.size() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -58,9 +55,6 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
|
||||
if (index == 0) {
|
||||
return NONE_SELECTED;
|
||||
}
|
||||
if (index == getSize() - 1) {
|
||||
return SELECT_DATABASE;
|
||||
}
|
||||
return presets.get(index - 1);
|
||||
}
|
||||
|
||||
@ -72,24 +66,10 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
|
||||
throw new BugException("item is null");
|
||||
} else if (item.equals(NONE_SELECTED)) {
|
||||
component.clearPreset();
|
||||
} else if (item.equals(SELECT_DATABASE)) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((ComponentPresetDatabase) Application.getComponentPresetDao()).addDatabaseListener(PresetModel.this);
|
||||
ComponentPresetChooserDialog dialog =
|
||||
new ComponentPresetChooserDialog(SwingUtilities.getWindowAncestor(parent), component);
|
||||
dialog.setVisible(true);
|
||||
ComponentPreset preset = dialog.getSelectedComponentPreset();
|
||||
if (preset != null) {
|
||||
setSelectedItem(preset);
|
||||
}
|
||||
((ComponentPresetDatabase) Application.getComponentPresetDao()).removeChangeListener(PresetModel.this);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
document.addUndoPosition("Use Preset " + component.getComponentName());
|
||||
component.loadPreset((ComponentPreset) item);
|
||||
((RocketComponentConfig) parent).setFocusElement();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,21 +24,49 @@ public class ConfigurationComboBox extends JComboBox<FlightConfiguration> implem
|
||||
public class ConfigurationModel implements MutableComboBoxModel<FlightConfiguration> {
|
||||
|
||||
private final Rocket rkt;
|
||||
|
||||
public ConfigurationModel(final Rocket _rkt) {
|
||||
private FlightConfiguration selectedConfig;
|
||||
private final boolean updateRocketConfig;
|
||||
private final ConfigurationModel listener;
|
||||
|
||||
/**
|
||||
* @param _rkt the rocket to get the configurations from and to (optionally) change the rocket's selected configuration
|
||||
* @param _updateRocketConfig whether to update the rocket's selected configuration based on the selected combo box item,
|
||||
* or just change the combo box item without altering the rocket's configuration.
|
||||
* @param listener model that should change its selected item to this model's selected item
|
||||
*/
|
||||
public ConfigurationModel(final Rocket _rkt, boolean _updateRocketConfig, ConfigurationModel listener) {
|
||||
this.rkt = _rkt;
|
||||
this.updateRocketConfig = _updateRocketConfig;
|
||||
this.selectedConfig = this.rkt.getSelectedConfiguration();
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public ConfigurationModel(final Rocket _rkt, boolean _updateRocketConfig) {
|
||||
this(_rkt, _updateRocketConfig, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlightConfiguration getSelectedItem() {
|
||||
return rkt.getSelectedConfiguration();
|
||||
if (updateRocketConfig) {
|
||||
return rkt.getSelectedConfiguration();
|
||||
} else {
|
||||
return selectedConfig;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedItem(Object nextItem) {
|
||||
if( nextItem instanceof FlightConfiguration ){
|
||||
FlightConfigurationId selectedId = ((FlightConfiguration)nextItem).getId();
|
||||
rkt.setSelectedConfiguration(selectedId);
|
||||
if (updateRocketConfig) {
|
||||
rkt.setSelectedConfiguration(selectedId);
|
||||
} else {
|
||||
selectedConfig = rkt.getFlightConfiguration(selectedId);
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.setSelectedItem(nextItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,9 +107,15 @@ public class ConfigurationComboBox extends JComboBox<FlightConfiguration> implem
|
||||
|
||||
private final Rocket rkt;
|
||||
|
||||
public ConfigurationComboBox(Rocket _rkt) {
|
||||
/**
|
||||
* @param _rkt the rocket to get the configurations from and to (optionally) change the rocket's selected configuration
|
||||
* @param _updateRocketConfig whether to update the rocket's selected configuration based on the selected combo box item,
|
||||
* or just change the combo box item without altering the rocket's configuration.
|
||||
*/
|
||||
public ConfigurationComboBox(Rocket _rkt, boolean _updateRocketConfig) {
|
||||
rkt = _rkt;
|
||||
setModel(new ConfigurationModel(rkt));
|
||||
final ConfigurationModel model = new ConfigurationModel(rkt, _updateRocketConfig);
|
||||
setModel(model);
|
||||
rkt.addChangeListener(this);
|
||||
|
||||
addPopupMenuListener(new PopupMenuListener() {
|
||||
@ -89,12 +123,18 @@ public class ConfigurationComboBox extends JComboBox<FlightConfiguration> implem
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
|
||||
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
||||
setModel(new ConfigurationModel(rkt));
|
||||
final ConfigurationModel model2 = new ConfigurationModel(rkt, _updateRocketConfig, model);
|
||||
model2.setSelectedItem(model.getSelectedItem());
|
||||
setModel(model2);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public ConfigurationComboBox(Rocket _rkt) {
|
||||
this(_rkt, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(EventObject e) {
|
||||
|
@ -6,6 +6,8 @@ import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
@ -23,6 +25,12 @@ import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.Arrays;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class BodyTubeConfig extends RocketComponentConfig {
|
||||
|
||||
@ -43,6 +51,7 @@ public class BodyTubeConfig extends RocketComponentConfig {
|
||||
|
||||
JSpinner spin = new JSpinner(length.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(length), "growx");
|
||||
|
@ -1,18 +1,24 @@
|
||||
package net.sf.openrocket.gui.configdialog;
|
||||
|
||||
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.util.WindowLocationUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
@ -230,8 +236,9 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
|
||||
* @param document the document to configure.
|
||||
* @param component the component to configure.
|
||||
* @param rememberPreviousTab if true, the previous tab will be remembered and used for the new dialog
|
||||
* @param includeUndoModify if true, include a 'Modify component' undo action
|
||||
*/
|
||||
public static void showDialog(Window parent, OpenRocketDocument document, RocketComponent component, boolean rememberPreviousTab) {
|
||||
public static void showDialog(Window parent, OpenRocketDocument document, RocketComponent component, boolean rememberPreviousTab, boolean includeUndoModify) {
|
||||
if (dialog != null) {
|
||||
// Don't remember the previous tab for rockets or stages, because this will leave you in the override tab for
|
||||
// the next component, which is generally not what you want.
|
||||
@ -256,15 +263,32 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
|
||||
|
||||
dialog = new ComponentConfigDialog(parent, document, component);
|
||||
dialog.setVisible(true);
|
||||
if (parent instanceof BasicFrame && BasicFrame.getStartupFrame() == parent) {
|
||||
WindowLocationUtil.moveIfOutsideOfParentMonitor(dialog, parent);
|
||||
}
|
||||
|
||||
////Modify
|
||||
if (component.getConfigListeners().size() == 0) {
|
||||
document.addUndoPosition(trans.get("ComponentCfgDlg.Modify") + " " + component.getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition(trans.get("ComponentCfgDlg.ModifyComponents"));
|
||||
if (includeUndoModify) {
|
||||
if (component.getConfigListeners().size() == 0) {
|
||||
document.addUndoPosition(trans.get("ComponentCfgDlg.Modify") + " " + component.getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition(trans.get("ComponentCfgDlg.ModifyComponents"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A singleton configuration dialog. Will create and show a new dialog if one has not
|
||||
* previously been used, or update the dialog and show it if a previous one exists.
|
||||
*
|
||||
* @param document the document to configure.
|
||||
* @param component the component to configure.
|
||||
* @param rememberPreviousTab if true, the previous tab will be remembered and used for the new dialog
|
||||
*/
|
||||
public static void showDialog(Window parent, OpenRocketDocument document, RocketComponent component, boolean rememberPreviousTab) {
|
||||
ComponentConfigDialog.showDialog(parent, document, component, rememberPreviousTab, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* A singleton configuration dialog. Will create and show a new dialog if one has not
|
||||
* previously been used, or update the dialog and show it if a previous one exists.
|
||||
|
@ -81,6 +81,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
private Point dragPoint = null;
|
||||
|
||||
private FinPointFigure figure = null;
|
||||
private ScaleScrollPane figurePane = null;
|
||||
private ScaleSelector selector;
|
||||
|
||||
public FreeformFinSetConfig(OpenRocketDocument d, RocketComponent component, JDialog parent) {
|
||||
@ -219,7 +220,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
|
||||
// Create the figure
|
||||
figure = new FinPointFigure(finset);
|
||||
ScaleScrollPane figurePane = new FinPointScrollPane( figure);
|
||||
figurePane = new FinPointScrollPane( figure);
|
||||
|
||||
// Create the table
|
||||
tableModel = new FinPointTableModel();
|
||||
@ -392,9 +393,10 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
}
|
||||
figure.updateFigure();
|
||||
}
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
|
||||
if (figurePane != null) {
|
||||
figurePane.revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private class FinPointScrollPane extends ScaleScrollPane {
|
||||
@ -408,8 +410,6 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent event) {
|
||||
int mods = event.getModifiersEx();
|
||||
|
||||
final FreeformFinSet finset = (FreeformFinSet) component;
|
||||
|
||||
final int pressIndex = getPoint(event);
|
||||
|
@ -64,7 +64,6 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
super(d, c, parent);
|
||||
|
||||
//// General and General properties
|
||||
JPanel rightPanel = new JPanel(new MigLayout());
|
||||
JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
|
||||
|
||||
DoubleModel m;
|
||||
@ -86,7 +85,7 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(od), "growx");
|
||||
panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap");
|
||||
panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "wmin 100lp, growx, wrap");
|
||||
|
||||
if (od.isAutomaticAvailable()) {
|
||||
JCheckBox check = new JCheckBox(od.getAutomaticAction());
|
||||
@ -106,7 +105,7 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap");
|
||||
panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "wmin 100lp, growx, wrap");
|
||||
|
||||
if (m.isAutomaticAvailable()) {
|
||||
JCheckBox check = new JCheckBox(m.getAutomaticAction());
|
||||
@ -127,7 +126,7 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap");
|
||||
panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "wmin 100lp, growx, wrap");
|
||||
|
||||
|
||||
//// Inner tube length
|
||||
@ -138,14 +137,15 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap");
|
||||
panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "wmin 100lp, growx, wrap");
|
||||
|
||||
//// Material
|
||||
panel.add(materialPanel(Material.Type.BULK),
|
||||
"spanx 3, growx, wrap 15lp");
|
||||
"spanx 4, growx, wrap 15lp");
|
||||
|
||||
|
||||
//// Right side of panel ----
|
||||
@ -174,7 +174,7 @@ public class InnerTubeConfig extends RocketComponentConfig {
|
||||
panel2.add(new BasicSlider(m.getSliderModel(
|
||||
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
|
||||
new DoubleModel(component.getParent(), "Length"))),
|
||||
"w 100lp, wrap");
|
||||
"wmin 100lp, growx, wrap");
|
||||
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@ public class LaunchLugConfig extends RocketComponentConfig {
|
||||
|
||||
JSpinner spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
|
@ -138,6 +138,7 @@ public class MassComponentConfig extends RocketComponentConfig {
|
||||
m = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel2.add(spin, "growx");
|
||||
|
||||
panel2.add(new UnitSelector(m), "growx");
|
||||
|
@ -163,6 +163,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig {
|
||||
m = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
|
@ -92,6 +92,7 @@ public class RailButtonConfig extends RocketComponentConfig {
|
||||
DoubleModel offsetModel = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
|
||||
JSpinner offsetSpinner = new JSpinner(offsetModel.getSpinnerModel());
|
||||
offsetSpinner.setEditor(new SpinnerEditor(offsetSpinner));
|
||||
focusElement = offsetSpinner;
|
||||
panel.add(offsetSpinner, "growx");
|
||||
panel.add(new UnitSelector(offsetModel), "growx");
|
||||
panel.add(new BasicSlider(offsetModel.getSliderModel(
|
||||
|
@ -20,6 +20,7 @@ import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.EngineBlock;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.ThicknessRingComponent;
|
||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
@ -116,6 +117,9 @@ public class RingComponentConfig extends RocketComponentConfig {
|
||||
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
if (component instanceof ThicknessRingComponent) {
|
||||
focusElement = spin;
|
||||
}
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
@ -139,6 +143,9 @@ public class RingComponentConfig extends RocketComponentConfig {
|
||||
m = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
if (!(component instanceof ThicknessRingComponent)) {
|
||||
focusElement = spin;
|
||||
}
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
|
@ -22,8 +22,10 @@ import javax.swing.JSpinner;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.database.ComponentPresetDatabase;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
@ -36,6 +38,7 @@ import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.gui.dialogs.preset.ComponentPresetChooserDialog;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.widgets.SelectColorButton;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
@ -61,6 +64,7 @@ public class RocketComponentConfig extends JPanel {
|
||||
|
||||
private JComboBox<?> presetComboBox;
|
||||
private PresetModel presetModel;
|
||||
protected Component focusElement = null; // Element that will be focused on after a preset is selected
|
||||
|
||||
protected final JTextField componentNameField;
|
||||
protected JTextArea commentTextArea;
|
||||
@ -100,7 +104,7 @@ public class RocketComponentConfig extends JPanel {
|
||||
//// Component name:
|
||||
JLabel label = new JLabel(trans.get("RocketCompCfg.lbl.Componentname"));
|
||||
//// The component name.
|
||||
label.setToolTipText(trans.get("RocketCompCfg.ttip.Thecomponentname"));
|
||||
label.setToolTipText(trans.get("RocketCompCfg.lbl.Componentname.ttip"));
|
||||
this.add(label, "spanx, height 32!, split");
|
||||
|
||||
componentNameField = new JTextField(15);
|
||||
@ -108,15 +112,27 @@ public class RocketComponentConfig extends JPanel {
|
||||
componentNameField.addActionListener(textFieldListener);
|
||||
componentNameField.addFocusListener(textFieldListener);
|
||||
//// The component name.
|
||||
componentNameField.setToolTipText(trans.get("RocketCompCfg.ttip.Thecomponentname"));
|
||||
componentNameField.setToolTipText(trans.get("RocketCompCfg.lbl.Componentname.ttip"));
|
||||
this.add(componentNameField, "growx");
|
||||
|
||||
if (allSameType && component.getPresetType() != null) {
|
||||
// If the component supports a preset, show the preset selection box.
|
||||
presetModel = new PresetModel(this, document, component);
|
||||
presetComboBox = new JComboBox(presetModel);
|
||||
presetComboBox.setMaximumRowCount(25);
|
||||
presetComboBox.setEditable(false);
|
||||
this.add(presetComboBox, "");
|
||||
presetComboBox.setToolTipText(trans.get("PresetModel.combo.ttip"));
|
||||
this.add(presetComboBox, "growx 110");
|
||||
|
||||
final JButton selectPreset = new SelectColorButton(trans.get("PresetModel.lbl.partsLib"));
|
||||
selectPreset.setToolTipText(trans.get("PresetModel.lbl.partsLib.ttip"));
|
||||
selectPreset.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
selectPreset();
|
||||
}
|
||||
});
|
||||
this.add(selectPreset);
|
||||
}
|
||||
|
||||
tabbedPane = new JTabbedPane();
|
||||
@ -124,17 +140,17 @@ public class RocketComponentConfig extends JPanel {
|
||||
|
||||
//// Override and Mass and CG override options
|
||||
tabbedPane.addTab(trans.get("RocketCompCfg.tab.Override"), null, overrideTab(),
|
||||
trans.get("RocketCompCfg.tab.MassandCGoverride"));
|
||||
trans.get("RocketCompCfg.tab.Override.ttip"));
|
||||
if (allMassive) {
|
||||
//// Appearance options
|
||||
appearancePanel = new AppearancePanel(document, component, parent);
|
||||
tabbedPane.addTab(trans.get("RocketCompCfg.tab.Appearance"), null, appearancePanel,
|
||||
"Appearance Tool Tip");
|
||||
trans.get("RocketCompCfg.tab.Appearance.ttip"));
|
||||
}
|
||||
|
||||
//// Comment and Specify a comment for the component
|
||||
tabbedPane.addTab(trans.get("RocketCompCfg.tab.Comment"), null, commentTab(),
|
||||
trans.get("RocketCompCfg.tab.Specifyacomment"));
|
||||
trans.get("RocketCompCfg.tab.Comment.ttip"));
|
||||
|
||||
addButtons();
|
||||
|
||||
@ -241,6 +257,24 @@ public class RocketComponentConfig extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private void selectPreset() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (presetComboBox == null || presetModel == null) return;
|
||||
((ComponentPresetDatabase) Application.getComponentPresetDao()).addDatabaseListener(presetModel);
|
||||
ComponentPresetChooserDialog dialog =
|
||||
new ComponentPresetChooserDialog(SwingUtilities.getWindowAncestor(RocketComponentConfig.this), component);
|
||||
dialog.setVisible(true);
|
||||
ComponentPreset preset = dialog.getSelectedComponentPreset();
|
||||
if (preset != null) {
|
||||
presetModel.setSelectedItem(preset);
|
||||
}
|
||||
((ComponentPresetDatabase) Application.getComponentPresetDao()).removeChangeListener(presetModel);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clearConfigListeners() {
|
||||
if (appearancePanel != null) {
|
||||
appearancePanel.clearConfigListeners();
|
||||
@ -702,6 +736,24 @@ public class RocketComponentConfig extends JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests focus for the focus element that should be active after a preset is selected.
|
||||
*/
|
||||
public void setFocusElement() {
|
||||
if (focusElement != null) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (focusElement instanceof JSpinner) {
|
||||
SpinnerEditor ed = (SpinnerEditor) ((JSpinner)focusElement).getEditor();
|
||||
ed.getTextField().requestFocusInWindow();
|
||||
} else {
|
||||
focusElement.requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void register(Invalidatable model) {
|
||||
|
@ -80,6 +80,7 @@ public class ShockCordConfig extends RocketComponentConfig {
|
||||
m = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel2.add(spin, "growx");
|
||||
|
||||
panel2.add(new UnitSelector(m), "growx");
|
||||
|
@ -149,6 +149,7 @@ public class StreamerConfig extends RecoveryDeviceConfig {
|
||||
m = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
|
@ -54,6 +54,7 @@ public class TubeFinSetConfig extends RocketComponentConfig {
|
||||
|
||||
spin = new JSpinner(m.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
focusElement = spin;
|
||||
panel.add(spin, "growx");
|
||||
|
||||
panel.add(new UnitSelector(m), "growx");
|
||||
|
@ -346,7 +346,7 @@ public class ScaleDialog extends JDialog {
|
||||
panel.add(selectionOption, "growx, wrap para*2");
|
||||
|
||||
// Select the 'scale component / scale selection and all subcomponents' if a component is selected
|
||||
if (selection != null && selection.size() > 0) {
|
||||
if (options.size() > 1 && selection != null && selection.size() > 0) {
|
||||
boolean entireRocket = false; // Flag to scale entire rocket
|
||||
for (RocketComponent component : selection) {
|
||||
if (component instanceof Rocket || (component instanceof AxialStage && !(component instanceof ParallelStage))) {
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
|
||||
import com.jogamp.opengl.glu.GLU;
|
||||
import com.jogamp.opengl.glu.GLUquadric;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -98,6 +99,8 @@ public class ComponentRenderer {
|
||||
|
||||
if (c instanceof BodyTube) {
|
||||
renderTube(gl, (BodyTube) c, which);
|
||||
} else if (c instanceof InnerTube) {
|
||||
renderTube(gl, (InnerTube) c, which);
|
||||
} else if (c instanceof LaunchLug) {
|
||||
renderLug(gl, (LaunchLug) c, which);
|
||||
} else if ( c instanceof RailButton ){
|
||||
@ -257,6 +260,10 @@ public class ComponentRenderer {
|
||||
renderTube(gl, which, t.getOuterRadius(), t.getInnerRadius(), t.getLength());
|
||||
}
|
||||
|
||||
private void renderTube(GL2 gl, InnerTube t, Surface which) {
|
||||
renderTube(gl, which, t.getOuterRadius(), t.getInnerRadius(), t.getLength());
|
||||
}
|
||||
|
||||
private void renderRing(GL2 gl, RingComponent r) {
|
||||
|
||||
gl.glRotated(90, 0, 1.0, 0);
|
||||
|
@ -108,7 +108,7 @@ public class PhotoFrame extends JFrame {
|
||||
|
||||
settings = new JDialog(this, trans.get("PhotoSettingsConfig.title")) {
|
||||
{
|
||||
setContentPane(new PhotoSettingsConfig(p));
|
||||
setContentPane(new PhotoSettingsConfig(p, document));
|
||||
pack();
|
||||
this.setLocationByPlatform(true);
|
||||
GUIUtil.rememberWindowSize(this);
|
||||
|
@ -36,7 +36,7 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings
|
||||
private double exhaustScale = 1.0;
|
||||
private double flameAspectRatio = 1.0;
|
||||
|
||||
private double sparkConcentration = 0;
|
||||
private double sparkConcentration = 0.2;
|
||||
private double sparkWeight = 0;
|
||||
|
||||
private Sky sky = Mountains.instance;
|
||||
@ -278,5 +278,6 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings
|
||||
|
||||
public void setSmokeOpacity(double smokeOpacity) {
|
||||
this.smokeOpacity = smokeOpacity;
|
||||
setSmokeAlpha(smokeOpacity);
|
||||
}
|
||||
}
|
@ -25,8 +25,10 @@ import javax.swing.event.ChangeListener;
|
||||
|
||||
import com.jogamp.opengl.GL2;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ColorIcon;
|
||||
import net.sf.openrocket.gui.components.EditableSpinner;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
@ -125,7 +127,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
}
|
||||
}
|
||||
|
||||
public PhotoSettingsConfig(PhotoSettings p) {
|
||||
public PhotoSettingsConfig(PhotoSettings p, OpenRocketDocument document) {
|
||||
super();
|
||||
|
||||
setPreferredSize(new Dimension(240, 320));
|
||||
@ -170,25 +172,29 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.pitch")));
|
||||
DoubleModel pitchModel = new DoubleModel(p, "Pitch", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(pitchModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(pitchModel), "pushx, left, wrap");
|
||||
add(new UnitSelector(pitchModel), "growx");
|
||||
add(new BasicSlider(pitchModel.getSliderModel(0, 2 * Math.PI)), "pushx, left, wrap");
|
||||
|
||||
/// Yaw
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.yaw")));
|
||||
DoubleModel yawModel = new DoubleModel(p, "Yaw", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(yawModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(yawModel), "wrap");
|
||||
add(new UnitSelector(yawModel), "growx");
|
||||
add(new BasicSlider(yawModel.getSliderModel(0, 2 * Math.PI)), "wrap");
|
||||
|
||||
/// Roll
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.roll")));
|
||||
DoubleModel rollModel = new DoubleModel(p, "Roll", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(rollModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(rollModel), "wrap");
|
||||
add(new UnitSelector(rollModel), "growx");
|
||||
add(new BasicSlider(rollModel.getSliderModel(0, 2 * Math.PI)), "wrap");
|
||||
|
||||
/// Advance
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.advance")));
|
||||
DoubleModel advanceModel = new DoubleModel(p, "Advance", UnitGroup.UNITS_LENGTH);
|
||||
add(new EditableSpinner(advanceModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(advanceModel), "wrap");
|
||||
add(new UnitSelector(advanceModel), "growx");
|
||||
add(new BasicSlider(advanceModel.getSliderModel(-document.getRocket().getLength(), document.getRocket().getLength())), "wrap");
|
||||
|
||||
// Camera
|
||||
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.camera"), Style.BOLD), "split, gapright para, span");
|
||||
@ -198,25 +204,29 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAz")));
|
||||
DoubleModel viewAzModel = new DoubleModel(p, "ViewAz", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(viewAzModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(viewAzModel), "wrap");
|
||||
add(new UnitSelector(viewAzModel), "growx");
|
||||
add(new BasicSlider(viewAzModel.getSliderModel(0, 2 * Math.PI)), "wrap");
|
||||
|
||||
/// View altitude
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAlt")));
|
||||
DoubleModel viewAltModle = new DoubleModel(p, "ViewAlt", UnitGroup.UNITS_ANGLE);
|
||||
DoubleModel viewAltModle = new DoubleModel(p, "ViewAlt", UnitGroup.UNITS_ANGLE, -Math.PI / 2, Math.PI / 2);
|
||||
add(new EditableSpinner(viewAltModle.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(viewAltModle), "wrap");
|
||||
add(new UnitSelector(viewAltModle), "growx");
|
||||
add(new BasicSlider(viewAltModle.getSliderModel(-Math.PI / 2, Math.PI / 2)), "wrap");
|
||||
|
||||
/// View distance
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vDist")));
|
||||
DoubleModel viewDistanceModel = new DoubleModel(p, "ViewDistance", UnitGroup.UNITS_LENGTH);
|
||||
add(new EditableSpinner(viewDistanceModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(viewDistanceModel), "wrap");
|
||||
add(new UnitSelector(viewDistanceModel), "growx");
|
||||
add(new BasicSlider(viewDistanceModel.getSliderModel(0, 2 * document.getRocket().getLength())), "wrap");
|
||||
|
||||
/// FoV
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.fov")));
|
||||
DoubleModel fovModel = new DoubleModel(p, "Fov", UnitGroup.UNITS_ANGLE);
|
||||
DoubleModel fovModel = new DoubleModel(p, "Fov", UnitGroup.UNITS_ANGLE, Math.PI * 57.3/180, Math.PI * 160/180);
|
||||
add(new EditableSpinner(fovModel.getSpinnerModel()), "growx");
|
||||
add(new UnitSelector(fovModel), "wrap");
|
||||
add(new UnitSelector(fovModel), "growx");
|
||||
add(new BasicSlider(fovModel.getSliderModel(Math.PI * 57.3/180, Math.PI * 160/180)), "wrap");
|
||||
}
|
||||
});
|
||||
|
||||
@ -232,19 +242,24 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
|
||||
/// Ambiance
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.amb")));
|
||||
DoubleModel ambianceModel = new DoubleModel(p, "Ambiance", 100, UnitGroup.UNITS_NONE, 0, 100);
|
||||
add(new EditableSpinner(ambianceModel.getSpinnerModel()), "wrap");
|
||||
DoubleModel ambianceModel = new DoubleModel(p, "Ambiance", UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
add(new EditableSpinner(ambianceModel.getSpinnerModel()), "growx, split 2");
|
||||
add(new UnitSelector(ambianceModel));
|
||||
add(new BasicSlider(ambianceModel.getSliderModel(0, 1)), "pushx, left, wrap");
|
||||
|
||||
/// Light azimuth
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAz")));
|
||||
DoubleModel lightAzModel = new DoubleModel(p, "LightAz", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(lightAzModel.getSpinnerModel()), "split 2");
|
||||
add(new UnitSelector(lightAzModel), "pushx, left, wrap");
|
||||
add(new EditableSpinner(lightAzModel.getSpinnerModel()), "growx, split 2");
|
||||
add(new UnitSelector(lightAzModel));
|
||||
add(new BasicSlider(lightAzModel.getSliderModel(-Math.PI, Math.PI)), "wrap");
|
||||
|
||||
/// Light altitude
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAlt")));
|
||||
DoubleModel lightAltModle = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE);
|
||||
add(new EditableSpinner(lightAltModle.getSpinnerModel()), "wrap");
|
||||
DoubleModel lightAltModle = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE, -Math.PI / 2, Math.PI / 2);
|
||||
add(new EditableSpinner(lightAltModle.getSpinnerModel()), "growx, split 2");
|
||||
add(new UnitSelector(lightAltModle));
|
||||
add(new BasicSlider(lightAltModle.getSliderModel(-Math.PI / 2, Math.PI / 2)), "wrap");
|
||||
|
||||
// Sky
|
||||
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.sky"), Style.BOLD), "split, span, gapright para");
|
||||
@ -292,7 +307,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
setSelectedItem(noSky);
|
||||
}
|
||||
}
|
||||
}, "wrap");
|
||||
}, "spanx, wrap");
|
||||
|
||||
/// Image credit
|
||||
final JLabel creditLabel = new JLabel(trans.get("PhotoSettingsConfig.lbl.skyCredit"));
|
||||
@ -304,7 +319,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
credit.setOpaque(false);
|
||||
credit.setFocusable(false);
|
||||
credit.setFont(creditLabel.getFont());
|
||||
add(credit);
|
||||
add(credit, "spanx");
|
||||
|
||||
final StateChangeListener skyChange = new StateChangeListener() {
|
||||
@Override
|
||||
@ -332,22 +347,28 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
/// Smoke
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smoke")));
|
||||
BooleanModel smokeModel = new BooleanModel(p, "Smoke");
|
||||
add(new JCheckBox(smokeModel), "split 2, w 15");
|
||||
add(new JCheckBox(smokeModel), "split 2, spanx");
|
||||
|
||||
add(smokeColorButton, "pushx, left, wrap");
|
||||
add(smokeColorButton, "wrap");
|
||||
smokeModel.addEnableComponent(smokeColorButton);
|
||||
|
||||
/// Smoke opacity
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smokeOpacity")));
|
||||
DoubleModel smokeOpacityModel = new DoubleModel(p, "SmokeOpacity", 100, UnitGroup.UNITS_NONE, 0, 100);
|
||||
DoubleModel smokeOpacityModel = new DoubleModel(p, "SmokeOpacity", UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
EditableSpinner opacitySpinner = new EditableSpinner(smokeOpacityModel.getSpinnerModel());
|
||||
add(opacitySpinner, "wrap");
|
||||
UnitSelector opacitySelector = new UnitSelector(smokeOpacityModel);
|
||||
BasicSlider opacitySlider = new BasicSlider(smokeOpacityModel.getSliderModel(0, 1));
|
||||
add(opacitySpinner, "growx");
|
||||
add(opacitySelector);
|
||||
add(opacitySlider, "wrap");
|
||||
smokeModel.addEnableComponent(opacitySpinner);
|
||||
smokeModel.addEnableComponent(opacitySelector);
|
||||
smokeModel.addEnableComponent(opacitySlider);
|
||||
|
||||
/// Flame
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.flame")));
|
||||
BooleanModel fireModel = new BooleanModel(p, "Flame");
|
||||
add(new JCheckBox(fireModel), "split 2, w 15");
|
||||
add(new JCheckBox(fireModel), "split 2, spanx");
|
||||
|
||||
add(flameColorButton, "wrap");
|
||||
fireModel.addEnableComponent(flameColorButton);
|
||||
@ -357,8 +378,11 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
DoubleModel flameAspectModel = new DoubleModel(p, "FlameAspectRatio", 100, UnitGroup.UNITS_NONE, 25,
|
||||
250);
|
||||
EditableSpinner flameAspectSpinner = new EditableSpinner(flameAspectModel.getSpinnerModel());
|
||||
add(flameAspectSpinner, "wrap");
|
||||
BasicSlider flameAspectSlider = new BasicSlider(flameAspectModel.getSliderModel(25, 250));
|
||||
add(flameAspectSpinner, "growx");
|
||||
add(flameAspectSlider, "skip 1, wrap");
|
||||
fireModel.addEnableComponent(flameAspectSpinner);
|
||||
fireModel.addEnableComponent(flameAspectSlider);
|
||||
|
||||
/// Sparks
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparks")));
|
||||
@ -369,23 +393,36 @@ public class PhotoSettingsConfig extends JTabbedPane {
|
||||
|
||||
/// Sparks concentration
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkConcentration")));
|
||||
DoubleModel sparkConcentrationModel = new DoubleModel(p, "SparkConcentration", 100,
|
||||
UnitGroup.UNITS_NONE, 0, 100);
|
||||
DoubleModel sparkConcentrationModel = new DoubleModel(p, "SparkConcentration",
|
||||
UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
EditableSpinner sparkConcentrationSpinner = new EditableSpinner(sparkConcentrationModel.getSpinnerModel());
|
||||
add(sparkConcentrationSpinner, "wrap");
|
||||
UnitSelector sparkConcentrationSelector = new UnitSelector(sparkConcentrationModel);
|
||||
BasicSlider sparkConcentrationSlider = new BasicSlider(sparkConcentrationModel.getSliderModel(0, 1));
|
||||
add(sparkConcentrationSpinner, "growx");
|
||||
add(sparkConcentrationSelector);
|
||||
add(sparkConcentrationSlider, "wrap");
|
||||
sparksModel.addEnableComponent(sparkConcentrationSpinner);
|
||||
sparksModel.addEnableComponent(sparkConcentrationSelector);
|
||||
sparksModel.addEnableComponent(sparkConcentrationSlider);
|
||||
|
||||
/// Spark weight
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkWeight")));
|
||||
DoubleModel sparkWeightModel = new DoubleModel(p, "SparkWeight", 100, UnitGroup.UNITS_NONE, 0, 100);
|
||||
DoubleModel sparkWeightModel = new DoubleModel(p, "SparkWeight", UnitGroup.UNITS_RELATIVE, 0, 1);
|
||||
EditableSpinner sparkWeightSpinner = new EditableSpinner(sparkWeightModel.getSpinnerModel());
|
||||
add(sparkWeightSpinner, "wrap");
|
||||
UnitSelector sparkWeightSelector = new UnitSelector(sparkWeightModel);
|
||||
BasicSlider sparkWeightSlider = new BasicSlider(sparkWeightModel.getSliderModel(0, 1));
|
||||
add(sparkWeightSpinner, "growx");
|
||||
add(sparkWeightSelector);
|
||||
add(sparkWeightSlider, "wrap");
|
||||
sparksModel.addEnableComponent(sparkWeightSpinner);
|
||||
sparksModel.addEnableComponent(sparkWeightSelector);
|
||||
sparksModel.addEnableComponent(sparkWeightSlider);
|
||||
|
||||
/// Exhaust scale
|
||||
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.exhaustScale")));
|
||||
DoubleModel exhaustScaleModel = new DoubleModel(p, "ExhaustScale", 100, UnitGroup.UNITS_NONE, 0, 1000);
|
||||
add(new EditableSpinner(exhaustScaleModel.getSpinnerModel()), "wrap");
|
||||
add(new EditableSpinner(exhaustScaleModel.getSpinnerModel()), "growx");
|
||||
add(new BasicSlider(exhaustScaleModel.getSliderModel(0, 1000)), "skip 1, wrap");
|
||||
|
||||
// Effects
|
||||
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.effects"), Style.BOLD), "split, span, gapright para");
|
||||
|
@ -41,7 +41,7 @@ public class RocketInfo implements FigureElement {
|
||||
private final Caret cpCaret = new CPCaret(0,0);
|
||||
private final Caret cgCaret = new CGCaret(0,0);
|
||||
|
||||
private final UnitGroup stabilityUnits;
|
||||
private UnitGroup stabilityUnits;
|
||||
|
||||
private FlightConfiguration configuration;
|
||||
private double cg = 0, cp = 0;
|
||||
@ -459,5 +459,6 @@ public class RocketInfo implements FigureElement {
|
||||
|
||||
public void setCurrentConfig(FlightConfiguration newConfig) {
|
||||
this.configuration = newConfig;
|
||||
this.stabilityUnits = UnitGroup.stabilityUnits(newConfig);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -116,7 +117,8 @@ 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<BasicFrame> frames = new ArrayList<BasicFrame>();
|
||||
private static final List<BasicFrame> frames = new ArrayList<BasicFrame>();
|
||||
private static BasicFrame startupFrame = null; // the frame that was created at startup
|
||||
|
||||
|
||||
/**
|
||||
@ -300,23 +302,28 @@ public class BasicFrame extends JFrame {
|
||||
componentSelectionModel.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
TreePath selPath = e.getNewLeadSelectionPath();
|
||||
if (selPath == null) return;
|
||||
RocketComponent c = (RocketComponent) selPath.getLastPathComponent();
|
||||
if (tree == null || tree.getSelectionPaths() == null || tree.getSelectionPaths().length == 0
|
||||
|| rocketpanel == null) return;
|
||||
|
||||
if (c instanceof AxialStage || c instanceof Rocket || c instanceof PodSet) {
|
||||
if (rocketpanel == null) return;
|
||||
|
||||
List<RocketComponent> children = new LinkedList<>();
|
||||
for (RocketComponent child : c) {
|
||||
children.add(child);
|
||||
// Get all the components that need to be selected = currently selected components + children of stages/boosters/podsets
|
||||
List<RocketComponent> children = new ArrayList<>(Arrays.asList(rocketpanel.getFigure().getSelection()));
|
||||
for (TreePath p : tree.getSelectionPaths()) {
|
||||
if (p != null) {
|
||||
RocketComponent c = (RocketComponent) p.getLastPathComponent();
|
||||
if (c instanceof AxialStage || c instanceof Rocket || c instanceof PodSet) {
|
||||
Iterator<RocketComponent> iter = c.iterator(false);
|
||||
while (iter.hasNext()) {
|
||||
RocketComponent child = iter.next();
|
||||
children.add(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Select all the child components
|
||||
if (rocketpanel.getFigure() != null && rocketpanel.getFigure3d() != null) {
|
||||
rocketpanel.getFigure().setSelection(children.toArray(new RocketComponent[0]));
|
||||
rocketpanel.getFigure3d().setSelection(children.toArray(new RocketComponent[0]));
|
||||
}
|
||||
// Select all the child components
|
||||
if (rocketpanel.getFigure() != null && rocketpanel.getFigure3d() != null) {
|
||||
rocketpanel.getFigure().setSelection(children.toArray(new RocketComponent[0]));
|
||||
rocketpanel.getFigure3d().setSelection(children.toArray(new RocketComponent[0]));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -483,6 +490,10 @@ public class BasicFrame extends JFrame {
|
||||
return result;
|
||||
}
|
||||
|
||||
public RocketPanel getRocketPanel() {
|
||||
return rocketpanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the menu for the window.
|
||||
*/
|
||||
@ -1225,6 +1236,19 @@ public class BasicFrame extends JFrame {
|
||||
return menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the frame that was created at the application's startup.
|
||||
*/
|
||||
public static BasicFrame getStartupFrame() {
|
||||
return startupFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the frame that is created at the application's startup.
|
||||
*/
|
||||
public static void setStartupFrame(BasicFrame startupFrame) {
|
||||
BasicFrame.startupFrame = startupFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the tab on the main pane.
|
||||
@ -1267,7 +1291,7 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
for (File file : files) {
|
||||
log.info("Opening file: " + file);
|
||||
if (open(file, parent)) {
|
||||
if (open(file, parent) != null) {
|
||||
MRUDesignFile opts = MRUDesignFile.getInstance();
|
||||
opts.addFile(file.getAbsolutePath());
|
||||
}
|
||||
@ -1297,7 +1321,7 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
for (File file : files) {
|
||||
log.info("Opening file: " + file);
|
||||
if (open(file, this)) {
|
||||
if (open(file, this) != null) {
|
||||
MRUDesignFile opts = MRUDesignFile.getInstance();
|
||||
opts.addFile(file.getAbsolutePath());
|
||||
}
|
||||
@ -1367,9 +1391,9 @@ public class BasicFrame extends JFrame {
|
||||
*
|
||||
* @param file the file to open.
|
||||
* @param parent the parent component for which a progress dialog is opened.
|
||||
* @return whether the file was successfully loaded and opened.
|
||||
* @return the BasicFrame that was created, or null if not created successfully.
|
||||
*/
|
||||
public static boolean open(File file, Window parent) {
|
||||
public static BasicFrame open(File file, Window parent) {
|
||||
OpenFileWorker worker = new OpenFileWorker(file);
|
||||
return open(worker, file.getName(), parent, false);
|
||||
}
|
||||
@ -1382,15 +1406,15 @@ public class BasicFrame extends JFrame {
|
||||
* @param displayName the file name to display in dialogs.
|
||||
* @param parent
|
||||
* @param openRocketConfigDialog if true, will open the configuration dialog of the rocket. This is useful for examples.
|
||||
* @return
|
||||
* @return the BasicFrame that was created, or null if not created successfully.
|
||||
*/
|
||||
private static boolean open(OpenFileWorker worker, String displayName, Window parent, boolean openRocketConfigDialog) {
|
||||
private static BasicFrame open(OpenFileWorker worker, String displayName, Window parent, boolean openRocketConfigDialog) {
|
||||
//// Open the file in a Swing worker thread
|
||||
log.info("Starting OpenFileWorker");
|
||||
if (!SwingWorkerDialog.runWorker(parent, "Opening file", "Reading " + displayName + "...", worker)) {
|
||||
// // User cancelled the operation
|
||||
log.info("User cancelled the OpenFileWorker");
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
//// Handle the document
|
||||
@ -1409,7 +1433,7 @@ public class BasicFrame extends JFrame {
|
||||
JOptionPane.showMessageDialog(parent,
|
||||
"File not found: " + displayName,
|
||||
"Error opening file", JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
return null;
|
||||
|
||||
} else if (cause instanceof RocketLoadException) {
|
||||
|
||||
@ -1418,7 +1442,7 @@ public class BasicFrame extends JFrame {
|
||||
"Unable to open file '" + displayName + "': "
|
||||
+ cause.getMessage(),
|
||||
"Error opening file", JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
return null;
|
||||
|
||||
} else {
|
||||
|
||||
@ -1462,7 +1486,7 @@ public class BasicFrame extends JFrame {
|
||||
ComponentConfigDialog.showDialog(frame, doc, doc.getRocket());
|
||||
}
|
||||
|
||||
return true;
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
@ -1768,24 +1792,27 @@ public class BasicFrame extends JFrame {
|
||||
/**
|
||||
* Opens a new design file or the last design file, if set in the preferences.
|
||||
* Can be used for reopening the application or opening it the first time.
|
||||
* @return the BasicFrame that was created
|
||||
*/
|
||||
public static void reopen() {
|
||||
public static BasicFrame reopen() {
|
||||
if (!Application.getPreferences().isAutoOpenLastDesignOnStartupEnabled()) {
|
||||
BasicFrame.newAction();
|
||||
return BasicFrame.newAction();
|
||||
} else {
|
||||
String lastFile = MRUDesignFile.getInstance().getLastEditedDesignFile();
|
||||
if (lastFile != null) {
|
||||
log.info("Opening last design file: " + lastFile);
|
||||
if (!BasicFrame.open(new File(lastFile), null)) {
|
||||
BasicFrame frame = BasicFrame.open(new File(lastFile), null);
|
||||
if (frame == null) {
|
||||
MRUDesignFile.getInstance().removeFile(lastFile);
|
||||
BasicFrame.newAction();
|
||||
return BasicFrame.newAction();
|
||||
}
|
||||
else {
|
||||
MRUDesignFile.getInstance().addFile(lastFile);
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BasicFrame.newAction();
|
||||
return BasicFrame.newAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1793,8 +1820,9 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
/**
|
||||
* Open a new design window with a basic rocket+stage.
|
||||
* @return the BasicFrame that was created
|
||||
*/
|
||||
public static void newAction() {
|
||||
public static BasicFrame newAction() {
|
||||
log.info("New action initiated");
|
||||
|
||||
OpenRocketDocument doc = OpenRocketDocumentFactory.createNewRocket();
|
||||
@ -1802,6 +1830,7 @@ public class BasicFrame extends JFrame {
|
||||
BasicFrame frame = new BasicFrame(doc);
|
||||
frame.replaceable = true;
|
||||
frame.setVisible(true);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
@ -1865,6 +1894,13 @@ public class BasicFrame extends JFrame {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all BasicFrame instances
|
||||
*/
|
||||
public static List<BasicFrame> getAllFrames() {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether all the BasicFrames are closed.
|
||||
* @return true if all the BasicFrames are closed, false if not
|
||||
|
@ -488,7 +488,7 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
}
|
||||
}
|
||||
|
||||
ComponentConfigDialog.showDialog(parent, document, component, false);
|
||||
ComponentConfigDialog.showDialog(parent, document, component, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public final class MRUDesignFileAction extends JMenu {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String command = e.getActionCommand();
|
||||
if (BasicFrame.open(new File(command), parent)) {
|
||||
if (BasicFrame.open(new File(command), parent) != null) {
|
||||
MRUDesignFile.getInstance().addFile(command);
|
||||
}
|
||||
else {
|
||||
|
@ -1,9 +1,12 @@
|
||||
package net.sf.openrocket.gui.main.flightconfigpanel;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
@ -162,6 +165,30 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
|
||||
return recoveryTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installTableListener() {
|
||||
super.installTableListener();
|
||||
|
||||
table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
updateComponentSelection(e);
|
||||
}
|
||||
});
|
||||
|
||||
table.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
updateComponentSelection(new ListSelectionEvent(this, 0, 0, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void selectDeployment() {
|
||||
List<RecoveryDevice> devices = getSelectedComponents();
|
||||
List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
|
||||
@ -239,6 +266,16 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
|
||||
popupMenuFull.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
|
||||
public void updateComponentSelection(ListSelectionEvent e) {
|
||||
if (e.getValueIsAdjusting() || getSelectedComponents() == null) {
|
||||
return;
|
||||
}
|
||||
List<RocketComponent> components = new ArrayList<>(getSelectedComponents());
|
||||
if (components.size() == 0) return;
|
||||
|
||||
flightConfigurationPanel.setSelectedComponents(components);
|
||||
}
|
||||
|
||||
public void updateButtonState() {
|
||||
boolean componentSelected = getSelectedComponent() != null;
|
||||
selectDeploymentButton.setEnabled(componentSelected);
|
||||
|
@ -1,9 +1,12 @@
|
||||
package net.sf.openrocket.gui.main.flightconfigpanel;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
@ -27,6 +30,7 @@ import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
@ -170,6 +174,30 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
return separationTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installTableListener() {
|
||||
super.installTableListener();
|
||||
|
||||
table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
updateComponentSelection(e);
|
||||
}
|
||||
});
|
||||
|
||||
table.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
updateComponentSelection(new ListSelectionEvent(this, 0, 0, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void selectSeparation() {
|
||||
List<AxialStage> stages = getSelectedComponents();
|
||||
List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
|
||||
@ -248,6 +276,16 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
popupMenuFull.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
|
||||
public void updateComponentSelection(ListSelectionEvent e) {
|
||||
if (e.getValueIsAdjusting() || getSelectedComponents() == null) {
|
||||
return;
|
||||
}
|
||||
List<RocketComponent> components = new ArrayList<>(getSelectedComponents());
|
||||
if (components.size() == 0) return;
|
||||
|
||||
flightConfigurationPanel.setSelectedComponents(components);
|
||||
}
|
||||
|
||||
public void updateButtonState() {
|
||||
boolean componentSelected = getSelectedComponent() != null;
|
||||
selectSeparationButton.setEnabled(componentSelected);
|
||||
|
122
swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java
Normal file
122
swing/src/net/sf/openrocket/gui/rocketfigure/EmptyShapes.java
Normal file
@ -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 <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
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(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;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
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,215);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -64,6 +64,10 @@ public class RocketComponentShape {
|
||||
return new RocketComponentShape[0];
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
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;
|
||||
|
||||
@ -26,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;
|
||||
@ -52,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";
|
||||
@ -378,6 +381,20 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
for(Entry<RocketComponent, ArrayList<InstanceContext>> entry: config.getActiveInstances().entrySet() ) {
|
||||
final RocketComponent comp = entry.getKey();
|
||||
|
||||
// Only draw podsets when they are selected
|
||||
if ((comp instanceof PodSet || comp instanceof ParallelStage) && preferences.isShowMarkers()) {
|
||||
boolean selected = false;
|
||||
|
||||
// Check if component is in the selection
|
||||
for (RocketComponent component : selection) {
|
||||
if (comp == component) {
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!selected) continue;
|
||||
}
|
||||
|
||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||
|
||||
@ -390,8 +407,12 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
/**
|
||||
* 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 <allShapes>
|
||||
* @param transformation transformation to apply to the component before drawing it
|
||||
* @param color color to draw the component in
|
||||
*
|
||||
* @return the <code>ArrayList</code> containing all the shapes to draw.
|
||||
*/
|
||||
@ -399,10 +420,11 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
PriorityQueue<RocketComponentShape> 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 AxialStage && !(component instanceof ParallelStage))){
|
||||
// no-op; no shapes here
|
||||
return allShapes;
|
||||
}
|
||||
@ -431,9 +453,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 <allShapes>
|
||||
* @param transformation transformation to apply to the component before drawing it
|
||||
*
|
||||
* @return the <code>ArrayList</code> containing all the shapes to draw.
|
||||
*/
|
||||
private static PriorityQueue<RocketComponentShape> addThisShape(
|
||||
PriorityQueue<RocketComponentShape> allShapes, // this is the output parameter
|
||||
final RocketPanel.VIEW_TYPE viewType,
|
||||
final RocketComponent component,
|
||||
final Transformation transformation) {
|
||||
return addThisShape(allShapes, viewType, component, transformation, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -252,7 +252,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
});
|
||||
}
|
||||
|
||||
private void updateFigures() {
|
||||
public void updateFigures() {
|
||||
if (!is3d)
|
||||
figure.updateFigure();
|
||||
else
|
||||
|
@ -151,7 +151,7 @@ public class SimulationEditDialog extends JDialog {
|
||||
|
||||
final Rocket rkt = document.getRocket();
|
||||
final FlightConfiguration config = rkt.getFlightConfiguration(simulationList[0].getFlightConfigurationId());
|
||||
final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt);
|
||||
final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt, false);
|
||||
configComboBox.setSelectedItem(config);
|
||||
|
||||
//// Select the motor configuration to use.
|
||||
|
74
swing/src/net/sf/openrocket/gui/util/WindowLocationUtil.java
Normal file
74
swing/src/net/sf/openrocket/gui/util/WindowLocationUtil.java
Normal file
@ -0,0 +1,74 @@
|
||||
package net.sf.openrocket.gui.util;
|
||||
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Window;
|
||||
|
||||
/**
|
||||
* Helper class for setting the location of a Swing window. E.g. to check when the window is outside the screen and
|
||||
* recenter it if so.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public abstract class WindowLocationUtil {
|
||||
/**
|
||||
* Sets the location of the window, but don't go outside the screen.
|
||||
* @param window the window to move
|
||||
* @param x the target x position on the screen
|
||||
* @param y the target y position on the screen
|
||||
*/
|
||||
public static void setLocationWithinScreen(Window window, int x, int y) {
|
||||
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
java.awt.Dimension windowSize = window.getSize();
|
||||
int screenWidth = screenSize.width;
|
||||
int screenHeight = screenSize.height;
|
||||
int windowWidth = windowSize.width;
|
||||
int windowHeight = windowSize.height;
|
||||
int xPos = x;
|
||||
int yPos = y;
|
||||
if (xPos + windowWidth > screenWidth) {
|
||||
xPos = screenWidth - windowWidth;
|
||||
}
|
||||
if (yPos + windowHeight > screenHeight) {
|
||||
yPos = screenHeight - windowHeight;
|
||||
}
|
||||
window.setLocation(xPos, yPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the window to the center of the screen if its location is outside the boundary of the screen.
|
||||
* @param window window to move
|
||||
*/
|
||||
public static void moveIfOutsideOfMonitor(Window window) {
|
||||
GraphicsDevice currentDevice = window.getGraphicsConfiguration().getDevice();
|
||||
if (currentDevice != null && window.isVisible() &&
|
||||
!currentDevice.getDefaultConfiguration().getBounds().contains(window.getLocationOnScreen())) {
|
||||
int width = currentDevice.getDefaultConfiguration().getBounds().width;
|
||||
int height = currentDevice.getDefaultConfiguration().getBounds().height;
|
||||
window.setLocation(
|
||||
((width / 2) - (window.getSize().width / 2)) + currentDevice.getDefaultConfiguration().getBounds().x,
|
||||
((height / 2) - (window.getSize().height / 2)) + currentDevice.getDefaultConfiguration().getBounds().y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the window to the center of the screen if it is on another monitor as the parent window, or if its location
|
||||
* is outside the boundary of the parent's monitor screen.
|
||||
* @param window window to move
|
||||
* @param parent parent window
|
||||
*/
|
||||
public static void moveIfOutsideOfParentMonitor(Window window, Window parent) {
|
||||
GraphicsDevice parentDevice = parent.getGraphicsConfiguration().getDevice();
|
||||
GraphicsDevice currentDevice = window.getGraphicsConfiguration().getDevice();
|
||||
if (parentDevice != null && (currentDevice == null || currentDevice != parentDevice ||
|
||||
(window.isVisible() && !parentDevice.getDefaultConfiguration().getBounds().contains(
|
||||
window.getLocationOnScreen())))) {
|
||||
int width = parentDevice.getDefaultConfiguration().getBounds().width;
|
||||
int height = parentDevice.getDefaultConfiguration().getBounds().height;
|
||||
window.setLocation(
|
||||
((width / 2) - (window.getSize().width / 2)) + parentDevice.getDefaultConfiguration().getBounds().x,
|
||||
((height / 2) - (window.getSize().height / 2)) + parentDevice.getDefaultConfiguration().getBounds().y
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -223,7 +223,8 @@ public class SwingStartup {
|
||||
// Starting action (load files or open new document)
|
||||
log.info("Opening main application window");
|
||||
if (!handleCommandLine(args)) {
|
||||
BasicFrame.reopen();
|
||||
BasicFrame startupFrame = BasicFrame.reopen();
|
||||
BasicFrame.setStartupFrame(startupFrame);
|
||||
}
|
||||
|
||||
// Check whether update info has been fetched or whether it needs more time
|
||||
@ -298,7 +299,7 @@ public class SwingStartup {
|
||||
// Check command-line for files
|
||||
boolean opened = false;
|
||||
for (String file : args) {
|
||||
if (BasicFrame.open(new File(file), null)) {
|
||||
if (BasicFrame.open(new File(file), null) != null) {
|
||||
opened = true;
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class IntegrationTest {
|
||||
private Action undoAction, redoAction;
|
||||
|
||||
private AerodynamicCalculator aeroCalc = new BarrowmanCalculator();
|
||||
private FlightConfiguration config;
|
||||
private FlightConfigurationId fcid;
|
||||
private FlightConditions conditions;
|
||||
private String massComponentID = null;
|
||||
|
||||
@ -112,14 +112,12 @@ public class IntegrationTest {
|
||||
|
||||
undoAction = UndoRedoAction.newUndoAction(document);
|
||||
redoAction = UndoRedoAction.newRedoAction(document);
|
||||
FlightConfigurationId fcid = document.getSimulation(0).getFlightConfigurationId();
|
||||
config = document.getRocket().getFlightConfiguration(fcid);
|
||||
fcid = document.getSimulation(0).getFlightConfigurationId();
|
||||
FlightConfiguration config = document.getRocket().getFlightConfiguration(fcid);
|
||||
conditions = new FlightConditions(config);
|
||||
|
||||
// Test undo state
|
||||
checkUndoState(null, null);
|
||||
|
||||
InnerTube mmt = (InnerTube)config.getRocket().getChild(0).getChild(1).getChild(2);
|
||||
|
||||
// Compute cg+cp + altitude
|
||||
// double cgx, double mass, double cpx, double cna)
|
||||
@ -330,6 +328,7 @@ public class IntegrationTest {
|
||||
}
|
||||
|
||||
private void checkCgCp(double cgx, double mass, double cpx, double cna) {
|
||||
FlightConfiguration config = document.getRocket().getFlightConfiguration(fcid);
|
||||
final RigidBody launchData = MassCalculator.calculateLaunch(config);
|
||||
final Coordinate cg = launchData.getCenterOfMass();
|
||||
assertEquals(cgx, cg.x, 0.001);
|
||||
|
Loading…
x
Reference in New Issue
Block a user