Merge branch 'unstable' into issue-2252

This commit is contained in:
SiboVG 2023-08-09 01:58:29 +02:00
commit 2e73e56d65
136 changed files with 2340 additions and 1149 deletions

View File

@ -53,7 +53,7 @@ OpenRocket needs help to become even better. Implementing features, writing docu
- Daniel Williams, pod support, maintainer
- Joe Pfeiffer (maintainer)
- Billy Olsen (maintainer)
- Sibo Van Gool (maintainer)
- Sibo Van Gool (RASAero file format, maintainer)
- Neil Weinstock (tester, icons, forum support)
- H. Craig Miller (tester)

View File

@ -16,23 +16,18 @@
debug.currentFile = messages.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Do not ask me again
RocketActions.lbl.Youcanchangedefop = You can change the default operation in the preferences.
RocketActions.showConfirmDialog.lbl1 = Delete the selected simulations?
RocketActions.showConfirmDialog.lbl2 = <html><i>This operation cannot be undone.</i>
RocketActions.showConfirmDialog.title = Delete simulations
RocketActions.DelCompAct.Delete = Delete
RocketActions.DelCompAct.ttip.Delete = Delete the selected component.
RocketActions.DelCompAct.ttip.Delete = Delete the selected components.
RocketActions.DelSimuAct.Delete = Delete
RocketActions.DelSimuAct.ttip.Delete = Delete the selected simulation.
RocketActions.DelSimuAct.ttip.Delete = Delete the selected simulations.
RocketActions.DelAct.Delete = Delete
RocketActions.DelAct.ttip.Delete = Delete the selected component or simulation.
RocketActions.DelAct.ttip.Delete = Delete the selected components or simulations.
RocketActions.CutAction.Cut = Cut
RocketActions.CutAction.ttip.Cut = Cut this component or simulation to the clipboard and delete from this design
RocketActions.CutAction.ttip.Cut = Cut these components or simulations to the clipboard and delete from this design
RocketActions.CopyAct.Copy = Copy
RocketActions.CopyAct.ttip.Copy = Copy this component (and subcomponents) to the clipboard.
RocketActions.CopyAct.ttip.Copy = Copy these components (and subcomponents) to the clipboard.
RocketActions.PasteAct.Paste = Paste
RocketActions.PasteAct.ttip.Paste = Paste the component or simulation on the clipboard to the design.
RocketActions.PasteAct.ttip.Paste = Paste the components or simulations on the clipboard to the design.
RocketActions.PasteAct.invalidPosition.msg = Invalid paste position for object '%s', ignoring pasting.
RocketActions.PasteAct.invalidPosition.title = Could not paste
RocketActions.DuplicateAct.Duplicate = Duplicate
@ -385,15 +380,15 @@ pref.dlg.PrefBooleanSelector2 = Confirm
pref.dlg.Add = Add
pref.dlg.DescriptionArea.Adddirectories = Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket.
PreferencesDialog.lbl.language = Interface language:
PreferencesDialog.languages.default = System default
PreferencesDialog.lbl.languageEffect = The language will change the next time you start OpenRocket.
PreferencesDialog.CancelOperation.title = Discard Preference Changes
PreferencesDialog.CancelOperation.msg.discardChanges = <html>Are you sure you want to <b>discard the preference changes</b>?</html>
generalprefs.lbl.language = Interface language
generalprefs.languages.default = System default
generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket.
generalprefs.lbl.UITheme = UI Theme
generalprefs.lbl.FontSize = UI Font Size
generalprefs.lbl.themeRestartOR = You must restart OpenRocket for the UI changes to take effect.
generalprefs.ImportWarning.title = Reload OpenRocket
generalprefs.ImportWarning.msg = You may need to restart OpenRocket for some of the changes to take effect.
@ -407,6 +402,10 @@ PreferencesOptionPanel.checkbox.userDirectories.ttip = If unchecked, user direct
PreferencesOptionPanel.checkbox.windowInfo = Export window information (position, size\u2026)
PreferencesOptionPanel.checkbox.windowInfo.ttip = If unchecked, window information (position, size\u2026) will not be exported.
! UI Themes
UITheme.Light = Light (Default)
UITheme.Dark = Dark
! Welcome dialog
welcome.dlg.title = Welcome to OpenRocket
welcome.dlg.lbl.thankYou = Thank you for downloading OpenRocket
@ -581,12 +580,23 @@ simpanel.but.ttip.editsim = Edit the selected simulation
simpanel.but.ttip.runsimu = Re-run the selected simulations
simpanel.but.ttip.deletesim = Delete the selected simulations
simpanel.pop.edit = Edit
simpanel.pop.edit.ttip= Edit the selected simulation(s)
simpanel.pop.cut= Cut
simpanel.pop.cut.ttip= Copy the selected simulation(s) to the clipboard and delete from this design
simpanel.pop.copy= Copy
simpanel.pop.copy.ttip= Copy the selected simulation(s) to the clipboard
simpanel.pop.paste= Paste
simpanel.pop.paste.ttip= Paste the simulation(s) on the clipboard to the design.
simpanel.pop.plot = Plot / Export
simpanel.pop.plot.ttip= Plot or Export the selected simulation(s)
simpanel.pop.run = Run
simpanel.pop.run.ttip= Run the selected simulation(s)
simpanel.pop.delete = Delete
simpanel.pop.delete.ttip= Delete the selected simulation(s)
simpanel.pop.duplicate = Duplicate
simpanel.pop.duplicate.ttip= Duplicate the selected simulation(s)
simpanel.pop.exportSimTableToCSV = Export simulation table as CSV file
simpanel.pop.exportSelectedSimsToCSV = Export simulations as CSV file
simpanel.pop.exportSelectedSimsToCSV = Export simulation(s) as CSV file
simpanel.pop.exportToCSV.save.dialog.title = Save as CSV file
simpanel.dlg.no.simulation.table.rows = Simulation table has no entries\u2026 Please run a simulation first.
simpanel.checkbox.donotask = Do not ask me again
@ -594,6 +604,7 @@ simpanel.lbl.defpref = You can change the default operation in the preferences.
simpanel.dlg.lbl.DeleteSim1 = Delete the selected simulations?
simpanel.dlg.lbl.DeleteSim2 = <html><i>This operation cannot be undone.</i>
simpanel.dlg.lbl.DeleteSim3 = Delete simulations
simpanel.col.Status = Status
simpanel.col.Name = Name
simpanel.col.Motors = Motors
simpanel.col.Configuration = Configuration
@ -615,6 +626,7 @@ simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulat
simpanel.ttip.noData = No simulation data available.
simpanel.ttip.noWarnings = <font color=\"gray\">No warnings.</font>
simpanel.ttip.warnings = <font color=\"red\">Warnings:</font>
simpanel.msg.invalidCopySelection = Invalid copy selection
! SimulationRunDialog
SimuRunDlg.title.RunSim = Running simulations\u2026
@ -1192,6 +1204,7 @@ InnerTubeCfg.tab.ttip.Radialpos = Radial position
InnerTubeCfg.lbl.Selectclustercfg = Select cluster configuration:
InnerTubeCfg.lbl.TubeSep = Tube separation:
InnerTubeCfg.lbl.ttip.TubeSep = The separation of the tubes, 1.0 = touching each other
InnerTubeCfg.lbl.ttip.TubeSepAbs = The separation of the tubes, 0 = touching each other
InnerTubeCfg.lbl.Rotation = Rotation:
InnerTubeCfg.lbl.ttip.Rotation = Rotation angle of the cluster configuration
InnerTubeCfg.lbl.Rotangle = Rotation angle of the cluster configuration
@ -1200,6 +1213,10 @@ InnerTubeCfg.lbl.longA1 = <html>Split the cluster into separate components.<br>
InnerTubeCfg.lbl.longA2 = This also duplicates all components attached to this inner tube.
InnerTubeCfg.but.Resetsettings = Reset settings
InnerTubeCfg.but.ttip.Resetsettings = Reset the separation and rotation to the default values
InnerTubeCfg.radioBut.Relative = Relative
InnerTubeCfg.radioBut.Relative.ttip = The separation is measured relative to the outer diameter of the inner tube
InnerTubeCfg.radioBut.Absolute = Absolute
InnerTubeCfg.radioBut.Absolute.ttip = The separation is measured in length units
! LaunchLugConfig
LaunchLugCfg.lbl.Length = Length:
@ -2023,6 +2040,7 @@ Warning.TUBE_SEPARATION = Space between tube fins may not simulate accurately.
Warning.TUBE_OVERLAP = Overlapping tube fins may not simulate accurately.
Warning.EMPTY_BRANCH = Simulation branch contains no data
Warning.SEPARATION_ORDER = Stages separated in an unreasonable order
Warning.EARLY_SEPARATION = Stages separated before clearing launch rod/rail
! Scale dialog
ScaleDialog.lbl.scaleRocket = Entire rocket
@ -2317,7 +2335,7 @@ ComponentPresetChooserDialog.menu.units = Units
ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = Show Legacy Database
ComponentPresetChooserDialog.lbl.favorites = Check to add preset to the preset drop-down menu in the component edit dialog<br>Directly apply a preset by double-clicking it or by selecting it and closing this window.
ComponentPresetChooserDialog.checkbox.alwaysOpenPreset = Always open this dialog when creating a new %s
table.column.Favorite = Favorite
table.column.Favorite = \u2026 Favorite
table.column.Legacy = Legacy
table.column.Manufacturer = Manufacturer
table.column.PartNo = Part Number

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_ar.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = لا تسألني مجددا
RocketActions.lbl.Youcanchangedefop = يمكنك تغيير العملية الافتراضية في التفضيلات.
RocketActions.showConfirmDialog.lbl1 = إحذف المحاكاة المختارة؟
RocketActions.showConfirmDialog.lbl2 = <html><i>لا يمكنك التراجع عن هذه العملية.</i>
RocketActions.showConfirmDialog.title = إحذف كل المحاكاة
RocketActions.DelCompAct.Delete = إحذف
RocketActions.DelCompAct.ttip.Delete = إحذف القطعة المختارة
RocketActions.DelSimuAct.Delete = إحذف
@ -348,9 +343,6 @@ pref.dlg.PrefBooleanSelector2 = تأكيد
pref.dlg.Add = أضف
pref.dlg.DescriptionArea.Adddirectories =.ملفات محرك روكسيم أو أرشيفات زيب مفصولة بفاصلة منقوطة لتحميل منحنيات الدفع الخارجية. ستدخل التغييرات حيز التنفيذ في المرة التالية التي تفتح فيها أوبنروكت (* .rse)أو RASP ملفات محرك (* .eng), أضف الدلائل
PreferencesDialog.lbl.language = :لغة الواجهة
PreferencesDialog.languages.default = النظام الافتراضي
PreferencesDialog.lbl.languageEffect = .ستتغير اللغة في المرة التالية التي تعيد تشغيل أوبنروكت
generalprefs.lbl.language = :لغة الواجهة
generalprefs.languages.default = النظام الافتراضي
generalprefs.lbl.languageEffect = .ستتغير اللغة في المرة التالية التي تعيد تشغيل أوبنروكت

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_cs.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Prí\u0161te se me neptejte
RocketActions.lbl.Youcanchangedefop = Mu\u017Eete zmenit výchozí operaci v nastavení.
RocketActions.showConfirmDialog.lbl1 = Chcete smazat oznacenou simulaci?
RocketActions.showConfirmDialog.lbl2 = <html><i>Tuto operaci nelze vzít zpet.</i>
RocketActions.showConfirmDialog.title = Sma\u017E simulace
RocketActions.DelCompAct.Delete = Sma\u017E
RocketActions.DelCompAct.ttip.Delete = Sma\u017E oznacenou komponentu.
RocketActions.DelSimuAct.Delete = Sma\u017E
@ -269,9 +264,9 @@ pref.dlg.PrefBooleanSelector2 = Potvrd
pref.dlg.Add = Pridej
pref.dlg.DescriptionArea.Adddirectories = Pridej adresáre, soubory RASP motor (*.eng), RockSim engine soubory (*.rse) nebo ZIP archiv oddelený oddelovacem (;) k nahrání externích výkonových prubehu. Zmeny se projeví po restaru programu OpenRocket.
PreferencesDialog.lbl.language = Jazyk rohranní:
PreferencesDialog.languages.default = Výchozí
PreferencesDialog.lbl.languageEffect = Jazyk se zmení pri dal\u0161ím spu\u0161tení programu OpenRocket.
generalprefs.lbl.language = Jazyk rohranní:
generalprefs.languages.default = Výchozí
generalprefs.lbl.languageEffect = Jazyk se zmení pri dal\u0161ím spu\u0161tení programu OpenRocket.
! Software update checker
update.dlg.error.title = Nemohu získat informace o aktualizacích

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_de.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Nicht wieder fragen
RocketActions.lbl.Youcanchangedefop = Die Standardaktion kann in den Einstellungen geändert werden.
RocketActions.showConfirmDialog.lbl1 = Simulationen löschen?
RocketActions.showConfirmDialog.lbl2 = <html><i>Diese Aktion kann nicht rückgängig gemacht werden.</i>
RocketActions.showConfirmDialog.title = Simulationen löschen
RocketActions.DelCompAct.Delete = Löschen
RocketActions.DelCompAct.ttip.Delete = Die ausgewählte Komponente löschen.
RocketActions.DelSimuAct.Delete = Löschen
@ -271,9 +266,9 @@ pref.dlg.PrefBooleanSelector2 = Best
pref.dlg.Add = Hinzufügen
pref.dlg.DescriptionArea.Adddirectories = Um eigene Schubkurven zu laden, Verzeichnisse, RASP-Motordateien (*.eng), RockSim-Motordateien (*.rse) oder ZIP-Archive mit Semikolon getrennt eingeben. Änderungen werden beim nächsten Neustart von OpenRocket übernommen.
PreferencesDialog.lbl.language = Sprache:
PreferencesDialog.languages.default = Systemeinstellung
PreferencesDialog.lbl.languageEffect = Die Sprache wird beim nächsten Neustart von OpenRocket geändert.
generalprefs.lbl.language = Sprache:
generalprefs.languages.default = Systemeinstellung
generalprefs.lbl.languageEffect = Die Sprache wird beim nächsten Neustart von OpenRocket geändert.
! Software update checker
update.dlg.error.title = Es konnten keine Informationen über Programmaktualisierungen empfangen werden.

View File

@ -733,9 +733,9 @@ PlotDialog.title.Flightdataplot = Representaci\u00f3n de los datos de vuelo
ComponentTreeRenderer.total = total
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.
generalprefs.languages.default = Idioma por defecto
generalprefs.lbl.language = Idioma de la interfaz:
generalprefs.lbl.languageEffect = El idioma cambiar\u00e1 la pr\u00f3xima vez que abra OpenRocket.
PresetModel.lbl.custompreset = Personalizado
PresetModel.lbl.partsLib = Biblioteca de piezas
@ -811,12 +811,6 @@ RocketActions.NewStageAct.Newstage = Nueva etapa
RocketActions.NewStageAct.ttip.Newstage = A\u00f1adir una nueva etapa al dise\u00f1o del cohete
RocketActions.PasteAct.Paste = Pegar
RocketActions.PasteAct.ttip.Paste = Pegar al portapapeles
! RocketActions
RocketActions.checkbox.Donotaskmeagain = No volver a preguntarme
RocketActions.lbl.Youcanchangedefop = Puede modificar la operaci\u00f3n por defecto con sus preferencias
RocketActions.showConfirmDialog.lbl1 = \u00bfBorrar las simulaciones seleccionadas?
RocketActions.showConfirmDialog.lbl2 = <html><i>Esta operaci\u00f3n no puede deshacerse.</i>
RocketActions.showConfirmDialog.title = Borrar simulaciones
RocketCfg.lbl.Comments = Comentarios:
RocketCfg.lbl.Designer = Dise\u00f1ador:

View File

@ -725,9 +725,9 @@ PlotDialog.title.Flightdataplot = Trac\u00E9 du vol
ComponentTreeRenderer.total = total
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.
generalprefs.languages.default = Valeur syst\u00E8me par d\u00E9faut
generalprefs.lbl.language = Langue du programme:
generalprefs.lbl.languageEffect = La langue sera chang\u00E9e apr\u00E8s avoir red\u00E9marr\u00E9 OpenRocket.
PresetModel.lbl.custompreset = Personnalisé
PresetModel.lbl.partsLib = Biblioth\u00E8que de pi\u00E8ces
@ -802,12 +802,6 @@ RocketActions.NewStageAct.Newstage = Nouvel \u00E9tage
RocketActions.NewStageAct.ttip.Newstage = Ajouter un nouvel \u00E9tage au projet.
RocketActions.PasteAct.Paste = Coller
RocketActions.PasteAct.ttip.Paste = Coller la pi\u00E8ce ou simulation pr\u00E9sente dans le presse papier dans le projet.
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Ne plus me demander
RocketActions.lbl.Youcanchangedefop = Vous pouvez changer le mode op\u00E9ratoire par d\u00E9faut dans les pr\u00E9ferences.
RocketActions.showConfirmDialog.lbl1 = Supprimer les simulations s\u00E9lectionn\u00E9es?
RocketActions.showConfirmDialog.lbl2 = <html><i>Cette op\u00E9ration n'est pas r\u00E9versible.</i>
RocketActions.showConfirmDialog.title = Effacer les simulations
RocketCfg.lbl.Comments = Commentaires:
RocketCfg.lbl.Designer = Concepteur:

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_it.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Non chiedermelo piu'
RocketActions.lbl.Youcanchangedefop = Puoi cambiare le operazioni prestabilite in PREFERENZE.
RocketActions.showConfirmDialog.lbl1 = Cancello le simulazioni selezionate?
RocketActions.showConfirmDialog.lbl2 = <html><i>Questa operazione non puo' essere annullata.</i>
RocketActions.showConfirmDialog.title = Cancello Simulazioni
RocketActions.DelCompAct.Delete = Cancella
RocketActions.DelCompAct.ttip.Delete = Cancello il componente selezionato.
RocketActions.DelSimuAct.Delete = Cancella
@ -273,9 +268,9 @@ pref.dlg.PrefBooleanSelector2 = Conferma
pref.dlg.Add = Aggiungi
pref.dlg.DescriptionArea.Adddirectories = Aggiungi cartelle, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separate da puntoevirgola (;) per caricare curve di spinta esterne. I cambiamenti avranno effetto la prossima volta che avvierai OpenRocket.
PreferencesDialog.lbl.language = Lingua dell'interfaccia:
PreferencesDialog.languages.default = Predefinita di sistema
PreferencesDialog.lbl.languageEffect = La lingua sara' cambiata la prossima volta che avvierai OpenRocket.
generalprefs.lbl.language = Lingua dell'interfaccia:
generalprefs.languages.default = Predefinita di sistema
generalprefs.lbl.languageEffect = La lingua sara' cambiata la prossima volta che avvierai OpenRocket.
! Software update checker
update.dlg.error.title = Non sono in grado di recuperare informazioni sugli aggiornamenti

View File

@ -12,11 +12,6 @@
debug.currentFile = messages_ja.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u6B21\u56DE\u304B\u3089\u8868\u793A\u3057\u306A\u3044
RocketActions.lbl.Youcanchangedefop = \u8A2D\u5B9A\u306E\u4E2D\u3067\u30C7\u30D5\u30A9\u30EB\u30C8\u306B\u5909\u66F4\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059
RocketActions.showConfirmDialog.lbl1 = \u9078\u629E\u3057\u305F\u30B7\u30DF\u30E5\u30EC\u30FC\u30B7\u30E7\u30F3\u3092\u6D88\u53BB\u3057\u307E\u3059\u304B\uFF1F
RocketActions.showConfirmDialog.lbl2 = <html><i>\u6D88\u53BB\u3057\u305F\u3089\u5FA9\u5143\u3067\u304D\u307E\u305B\u3093</i>
RocketActions.showConfirmDialog.title = \u30B7\u30DF\u30E5\u30EC\u30FC\u30B7\u30E7\u30F3\u306E\u524A\u9664
RocketActions.DelCompAct.Delete = \u524A\u9664
RocketActions.DelCompAct.ttip.Delete = \u9078\u629E\u3057\u305F\u90E8\u54C1\u306E\u524A\u9664
RocketActions.DelSimuAct.Delete = \u524A\u9664
@ -270,9 +265,9 @@ pref.dlg.PrefBooleanSelector2 = \u78BA\u8A8D
pref.dlg.Add = \u8FFD\u52A0
pref.dlg.DescriptionArea.Adddirectories = \u30D5\u30A9\u30EB\u30C0, RASP motor files (*.eng), RockSim engine files (*.rse) \u3082\u3057\u304F\u306F ZIP archives \u3092\u30BB\u30DF\u30B3\u30ED\u30F3(;)\u306B\u3088\u3063\u3066\u5206\u3051\u3089\u308C\u305F\u5F62\u3067\u8FFD\u52A0\u306E\u63A8\u529B\u5C65\u6B74\u3068\u3057\u3066\u8FFD\u52A0\u3067\u304D\u307E\u3059\u3002\u3053\u306E\u5909\u66F4\u306FOpenRocket\u306E\u518D\u8D77\u52D5\u6642\u306B\u6709\u52B9\u306B\u306A\u308A\u307E\u3059
PreferencesDialog.lbl.language = \u8A00\u8A9E\uFF1A
PreferencesDialog.languages.default = \u30B7\u30B9\u30C6\u30E0\u8A00\u8A9E
PreferencesDialog.lbl.languageEffect = \u8A00\u8A9E\u306F\u518D\u8D77\u52D5\u6642\u306B\u5909\u66F4\u3055\u308C\u307E\u3059
generalprefs.lbl.language = \u8A00\u8A9E\uFF1A
generalprefs.languages.default = \u30B7\u30B9\u30C6\u30E0\u8A00\u8A9E
generalprefs.lbl.languageEffect = \u8A00\u8A9E\u306F\u518D\u8D77\u52D5\u6642\u306B\u5909\u66F4\u3055\u308C\u307E\u3059
! Software update checker
update.dlg.error.title = \u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u60C5\u5831\u306E\u8AAD\u307F\u51FA\u3057\u304C\u3067\u304D\u307E\u305B\u3093

View File

@ -18,11 +18,6 @@
debug.currentFile = messages_nl.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Niet opnieuw vragen
RocketActions.lbl.Youcanchangedefop = U kan de standaardbewerking veranderen in de voorkeuren.
RocketActions.showConfirmDialog.lbl1 = Geselecteerde simulatie verwijderen?
RocketActions.showConfirmDialog.lbl2 = <html><i>Deze bewerking kan niet ongedaan worden.</i>
RocketActions.showConfirmDialog.title = Verwijder simulaties
RocketActions.DelCompAct.Delete = Verwijder
RocketActions.DelCompAct.ttip.Delete = Verwijder het geselecteerde onderdeel.
RocketActions.DelSimuAct.Delete = Verwijder
@ -350,10 +345,6 @@ pref.dlg.PrefBooleanSelector2 = Bevestig
pref.dlg.Add = Voeg toe
pref.dlg.DescriptionArea.Adddirectories = Voeg folders, RASP motorbestanden (*.eng), RockSim motorbestanden (*.rse) of ZIP-archieven gescheiden door een puntkomma (;) om externe stuwkrachtcurves te laden. Wijzigingen zullen van kracht gaan de volgende keer dat u OpenRocket start.
PreferencesDialog.lbl.language = Interface taal:
PreferencesDialog.languages.default = Systeemstandaard
PreferencesDialog.lbl.languageEffect = De taal zal veranderen de volgende keer dat u OpenRocket start.
generalprefs.lbl.language = Interface taal
generalprefs.languages.default = Systeemstandaard
generalprefs.lbl.languageEffect = De taal zal veranderen de volgende keer dat u OpenRocket start.

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_pl.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Nie pytaj ponownie
RocketActions.lbl.Youcanchangedefop = Domy\u015Bln\u0105 operacj\u0119 mo\u017Cna zmieni\u0107 w ustawieniach.
RocketActions.showConfirmDialog.lbl1 = Usun\u0105\u0107 zaznaczone symulacje?
RocketActions.showConfirmDialog.lbl2 = <html><i>Tej operacji nie mo\u017Cna cofn\u0105\u0107.</i>
RocketActions.showConfirmDialog.title = Usu\u0144 symulacje
RocketActions.DelCompAct.Delete = Usu\u0144
RocketActions.DelCompAct.ttip.Delete = Usu\u0144 wybran\u0105 cz\u0119\u015B\u0107
RocketActions.DelSimuAct.Delete = Usu\u0144
@ -270,10 +265,10 @@
pref.dlg.PrefBooleanSelector2 = Potwierd\u017A
pref.dlg.Add = Dodaj
pref.dlg.DescriptionArea.Adddirectories = Dodaj katalogi, pliki silnikowe RASP (*.eng), Pliki silnikowe RockSim (*.rse) albo archiwa ZIP rozdzielone \u015Brednikiem (;) by za\u0142adowa\u0107 zewn\u0119trzne krzywe si\u0142y ci\u0105gu. Zmiany zostan\u0105 wprowadzone przy kolejnym uruchomieniu OpenRocket.
PreferencesDialog.lbl.language = J\u0119zyk programu:
PreferencesDialog.languages.default = Domy\u015Blny j\u0119zyk systemu
PreferencesDialog.lbl.languageEffect = Nowy j\u0119zyk zostanie ustawiony przy kolejnym uruchomieniu OpenRocket.
generalprefs.lbl.language = J\u0119zyk programu:
generalprefs.languages.default = Domy\u015Blny j\u0119zyk systemu
generalprefs.lbl.languageEffect = Nowy j\u0119zyk zostanie ustawiony przy kolejnym uruchomieniu OpenRocket.
! Software update checker
update.dlg.error.title = Nie mo\u017Cna uzyska\u0107 informacji o aktualizacji

View File

@ -709,9 +709,9 @@ PlotDialog.lbl.Chart = Clique e arraste para baixo+direita para am
# PlotDialog
PlotDialog.title.Flightdataplot = Plotagem dos dados de voo
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.
generalprefs.languages.default = Padr\u00e3o do sistema
generalprefs.lbl.language = Idioma da interface:
generalprefs.lbl.languageEffect = A linguagem vai mudar na pr\u00f3xima vez que voc\u00ea iniciar o OpenRocket.
PresetModel.lbl.custompreset = Personalizado
PresetModel.lbl.partsLib = Biblioteca de pe\u00e7as
@ -786,12 +786,6 @@ RocketActions.NewStageAct.Newstage = Novo est\u00e1gio
RocketActions.NewStageAct.ttip.Newstage = Adicionar um novo est\u00e1gio ao projeto do foguete.
RocketActions.PasteAct.Paste = Colar
RocketActions.PasteAct.ttip.Paste = Cole o componente ou simula\u00e7\u00e3o na \u00e1rea da transfer\u00eancia para o projeto.
# RocketActions
RocketActions.checkbox.Donotaskmeagain = N\u00e3o me pergunte novamente
RocketActions.lbl.Youcanchangedefop = Voc\u00ea pode alterar a opera\u00e7\u00e3o padr\u00e3o em Prefer\u00eancias.
RocketActions.showConfirmDialog.lbl1 = Excluir as simula\u00e7\u00f5es selecionadas?
RocketActions.showConfirmDialog.lbl2 = <html><i>Esta opera\u00e7\u00e3o n\u00e3o poder\u00e1 ser desfeita.</i>
RocketActions.showConfirmDialog.title = Excluir simula\u00e7\u00f5es
RocketCfg.lbl.Comments = Coment\u00e1rios:
RocketCfg.lbl.Designer = Projetista:

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_ru.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044C
RocketActions.lbl.Youcanchangedefop = \u0412\u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445.
RocketActions.showConfirmDialog.lbl1 = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B?
RocketActions.showConfirmDialog.lbl2 = <html><i>\u042D\u0442\u0443 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044E \u043D\u0435\u043B\u044C\u0437\u044F \u043E\u0442\u043C\u0435\u043D\u0438\u0442\u044C.</i>
RocketActions.showConfirmDialog.title = \u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432
RocketActions.DelCompAct.Delete = \u0423\u0434\u0430\u043B\u0438\u0442\u044C
RocketActions.DelCompAct.ttip.Delete = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442.
RocketActions.DelSimuAct.Delete = \u0423\u0434\u0430\u043B\u0438\u0442\u044C
@ -346,10 +341,6 @@ pref.dlg.PrefBooleanSelector2 = \u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434
pref.dlg.Add = \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C
pref.dlg.DescriptionArea.Adddirectories = \u0414\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u0432\u043E\u0438\u0445 \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 \u0434\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0438, \u0444\u0430\u0439\u043B\u044B \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 RASP (*.eng), \u0444\u0430\u0439\u043B\u044B \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 RockSim (*.rse) \u0438\u043B\u0438 ZIP-\u0430\u0440\u0445\u0438\u0432\u044B, \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0435 \u0442\u043E\u0447\u043A\u043E\u0439 \u0441 \u0437\u0430\u043F\u044F\u0442\u043E\u0439 (;). \u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u0441\u0442\u0443\u043F\u044F\u0442 \u0432 \u0441\u0438\u043B\u0443 \u043F\u0440\u0438 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u043C \u0437\u0430\u043F\u0443\u0441\u043A\u0435 OpenRocket.
PreferencesDialog.lbl.language = \u042F\u0437\u044B\u043A \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430:
PreferencesDialog.languages.default = \u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439
PreferencesDialog.lbl.languageEffect = \u042F\u0437\u044B\u043A \u0441\u043C\u0435\u043D\u0438\u0442\u0441\u044F \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0435 OpenRocket.
generalprefs.lbl.language = \u042F\u0437\u044B\u043A \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
generalprefs.languages.default = \u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439
generalprefs.lbl.languageEffect = \u042F\u0437\u044B\u043A \u0441\u043C\u0435\u043D\u0438\u0442\u0441\u044F \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0435 OpenRocket.

View File

@ -17,12 +17,6 @@ purposes)
debug.currentFile = messages.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Yeniden Tekrarlama
RocketActions.lbl.Youcanchangedefop = Hatal\u0131 \u00c7al\u0131\u015fmay\u0131 De\u011fi\u015ftirebilirsin
in the preferences.
RocketActions.showConfirmDialog.lbl1 = Se\u00e7ili sim\u00fclasyonlar\u0131 silmek ister misiniz?
RocketActions.showConfirmDialog.lbl2 = <html><i>Bu \u00e7al\u0131\u015fma tamamlanmad\u0131.</i>
RocketActions.showConfirmDialog.title = Sim\u00fclasyonlar\u0131 Sil
RocketActions.DelCompAct.Delete = Sil
RocketActions.DelCompAct.ttip.Delete = Se\u00e7ili par\u00e7ay\u0131 sil.
RocketActions.DelSimuAct.Delete = Sil

View File

@ -18,11 +18,6 @@
debug.currentFile = messages.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u0411\u0456\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u0438\u0442\u0430\u0442\u0438
RocketActions.lbl.Youcanchangedefop = \u0412\u0438 \u043C\u043E\u0436\u0435\u0442\u0435 \u0437\u043C\u0456\u043D\u0438\u0442\u0438 \u0442\u0438\u043F\u043E\u0432\u0443 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044E \u0432 \u043E\u043F\u0446\u0438\u044F\u0445.
RocketActions.showConfirmDialog.lbl1 = \u0412\u0434\u0430\u043B\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043D\u0443 \u0441\u0438\u043C\u0443\u043B\u044F\u0446\u0456\u044E?
RocketActions.showConfirmDialog.lbl2 = <html><i>\u0426\u044F \u043E\u043F\u0435\u0440\u0430\u0446\u0456\u044F \u043D\u0435 \u043C\u043E\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0456\u0434\u043C\u0456\u043D\u0435\u043D\u0430.</i>
RocketActions.showConfirmDialog.title = \u0412\u0434\u0430\u043B\u0438\u0442\u0438 \u0441\u0438\u043C\u0443\u043B\u044F\u0446\u0456\u044E
RocketActions.DelCompAct.Delete = \u0412\u0434\u0430\u043B\u0438\u0442\u0438
RocketActions.DelCompAct.ttip.Delete = \u0412\u0434\u0430\u043B\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043D\u0443 \u0447\u0430\u0441\u0442\u0438\u043D\u0443.
RocketActions.DelSimuAct.Delete = \u0412\u0434\u0430\u043B\u0438\u0442\u0438
@ -309,9 +304,9 @@ pref.dlg.PrefBooleanSelector2 = Confirm
pref.dlg.Add = Add
pref.dlg.DescriptionArea.Adddirectories = Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket.
PreferencesDialog.lbl.language = Interface language:
PreferencesDialog.languages.default = System default
PreferencesDialog.lbl.languageEffect = The language will change the next time you start OpenRocket.
generalprefs.lbl.language = Interface language:
generalprefs.languages.default = System default
generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket.
! Software update checker
update.dlg.error.title = Unable to retrieve update information

View File

@ -797,9 +797,9 @@ PlotConfiguration.Verticalmotion = \u5782\u76F4\u8FD0\u52A8 vs. \u65F6\u95F
PlotDialog.CheckBox.Showdatapoints = \u663E\u793A\u6570\u636E\u70B9
PlotDialog.lbl.Chart = \u5DE6\u952E\u62D6\u62FD\u79FB\u52A8\u6570\u636E\u533A. \u6EDA\u8F6E\u7F29\u653E. ctrl-\u6EDA\u8F6E\u4EC5\u7F29\u653EX\u8F74. ctrl-\u5DE6\u952E\u62D6\u62FD\u79FB\u52A8\u89C6\u56FE. \u53F3\u952E\u8FC7\u62FD\u8C03\u6574\u663E\u793A\u5927\u5C0F.
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
generalprefs.languages.default = \u7CFB\u7EDF\u9ED8\u8BA4
generalprefs.lbl.language = \u754C\u9762\u8BED\u8A00:
generalprefs.lbl.languageEffect = \u8BED\u8A00\u8BBE\u7F6E\u5C06\u5728OpenRocket\u91CD\u542F\u540E\u751F\u6548
PresetModel.lbl.custompreset = \u5b9a\u5236
PresetModel.lbl.partsLib = \u96f6\u4ef6\u5e93
@ -875,12 +875,6 @@ RocketActions.NewStageAct.Newstage = \u65B0\u5EFA\u4E00\u7EA7
RocketActions.NewStageAct.ttip.Newstage = \u5728\u8BBE\u8BA1\u4E2D\u65B0\u5EFA\u4E00\u7EA7
RocketActions.PasteAct.Paste = \u7C98\u8D34
RocketActions.PasteAct.ttip.Paste = \u5C06\u526A\u8D34\u677F\u91CC\u7684\u90E8\u4EF6\u6216\u4EFF\u771F\u7C98\u8D34\u5230\u8BE5\u8BBE\u8BA1\u4E2D
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u4E0D\u518D\u63D0\u793A
RocketActions.lbl.Youcanchangedefop = \u4F60\u53EF\u4EE5\u4FEE\u6539\u7F3A\u7701\u8BBE\u7F6E
RocketActions.showConfirmDialog.lbl1 = \u5220\u9664\u9009\u5B9A\u4EFF\u771F?
RocketActions.showConfirmDialog.lbl2 = <html><i>\u8BE5\u64CD\u4F5C\u65E0\u6CD5\u64A4\u9500</i>
RocketActions.showConfirmDialog.title = \u5220\u9664\u4EFF\u771F
RocketCfg.lbl.Comments = \u6CE8\u91CA:
RocketCfg.lbl.Designer = \u8BBE\u8BA1\u4EBA:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -383,12 +383,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
* @param simulation the simulation to be added
*/
public void addSimulation(Simulation simulation) {
simulations.add(simulation);
FlightConfigurationId simId = simulation.getId();
if( !rocket.containsFlightConfigurationID( simId )){
rocket.createFlightConfiguration(simId);
}
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
addSimulation(simulation, simulations.size());
}
/**
@ -399,6 +394,10 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
*/
public void addSimulation(Simulation simulation, int n) {
simulations.add(n, simulation);
FlightConfigurationId simId = simulation.getId();
if( !rocket.containsFlightConfigurationID( simId )){
rocket.createFlightConfiguration(simId);
}
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
}

View File

@ -92,9 +92,11 @@ public class CSVExport {
private static void writeData(PrintWriter writer, FlightDataBranch branch,
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces, boolean isExponentialNotation,
boolean eventComments, String commentStarter) {
// Time variable
List<Double> time = branch.get(FlightDataType.TYPE_TIME);
// Number of data points
int n = branch.getLength();
int n = time != null ? time.size() : branch.getLength();
// Flight events in occurrence order
List<FlightEvent> events = branch.getEvents();
@ -102,15 +104,14 @@ public class CSVExport {
int eventPosition = 0;
// List of field values
List<List<Double>> fieldValues = new ArrayList<List<Double>>();
List<List<Double>> fieldValues = new ArrayList<>();
for (FlightDataType t : fields) {
fieldValues.add(branch.get(t));
List<Double> values = branch.get(t);
fieldValues.add(values);
}
// Time variable
List<Double> time = branch.get(FlightDataType.TYPE_TIME);
// If time information is not available, print events at beginning of file
if (eventComments && time == null) {
// If time information is not available, print events at beginning of file
for (FlightEvent e : events) {
printEvent(writer, e, commentStarter);
}

View File

@ -216,21 +216,22 @@ public class OpenRocketSaver extends RocketSaver {
/*
* NOTE: Remember to update the supported versions in DocumentConfig as well!
*
* File version 1.8 is required for:
* File version 1.9 is required for:
* - new-style positioning
* - external/parallel booster stages
* - external pods
* - Rail Buttons
* - Flight event source saving
*
* Otherwise use version 1.8.
* Otherwise use version 1.9.
*/
/////////////////
// Version 1.8 //
// Version 1.9 //
/////////////////
// for any new-style positioning: 'axialoffset', 'angleoffset', 'radiusoffset' tags
// these tags are used for any RocketComponent child classes positioning... so... ALL the classes.
return FILE_VERSION_DIVISOR + 8;
return FILE_VERSION_DIVISOR + 9;
}
@ -531,8 +532,13 @@ public class OpenRocketSaver extends RocketSaver {
// Write events
for (FlightEvent event : branch.getEvents()) {
writeln("<event time=\"" + TextUtil.doubleToString(event.getTime())
+ "\" type=\"" + enumToXMLName(event.getType()) + "\"/>");
String eventStr = "<event time=\"" + TextUtil.doubleToString(event.getTime())
+ "\" type=\"" + enumToXMLName(event.getType());
if (event.getSource() != null) {
eventStr += "\" source=\"" + TextUtil.escapeXML(event.getSource().getID());
}
eventStr += "\"/>";
writeln(eventStr);
}
// Write the data

View File

@ -52,7 +52,7 @@ import net.sf.openrocket.util.Reflection;
class DocumentConfig {
/* Remember to update OpenRocketSaver as well! */
public static final String[] SUPPORTED_VERSIONS = { "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8" };
public static final String[] SUPPORTED_VERSIONS = { "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9" };
/**
* Divisor used in converting an integer version to the point-represented version.
@ -113,6 +113,8 @@ class DocumentConfig {
// RocketComponent
setters.put("RocketComponent:name", new StringSetter(
Reflection.findMethod(RocketComponent.class, "setName", String.class)));
setters.put("RocketComponent:id", new StringSetter(
Reflection.findMethod(RocketComponent.class, "setID", String.class)));
setters.put("RocketComponent:color", new ColorSetter(
Reflection.findMethod(RocketComponent.class, "setColor", Color.class)));
setters.put("RocketComponent:linestyle", new EnumSetter<LineStyle>(

View File

@ -8,6 +8,8 @@ import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.simulation.FlightEvent;
@ -126,6 +128,8 @@ class FlightDataBranchHandler extends AbstractElementHandler {
if (element.equals("event")) {
double time;
FlightEvent.Type type;
String sourceID;
RocketComponent source = null;
try {
time = DocumentConfig.stringToDouble(attributes.get("time"));
@ -139,8 +143,15 @@ class FlightDataBranchHandler extends AbstractElementHandler {
warnings.add("Illegal event specification, ignoring.");
return;
}
// Get the event source
Rocket rocket = context.getOpenRocketDocument().getRocket();
sourceID = attributes.get("source");
if (sourceID != null) {
source = rocket.findComponent(sourceID);
}
branch.addEvent(new FlightEvent(type, time));
branch.addEvent(new FlightEvent(type, time, source));
return;
}

View File

@ -36,6 +36,7 @@ public class RocketComponentSaver {
protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, List<String> elements) {
elements.add("<name>" + TextUtil.escapeXML(c.getName()) + "</name>");
elements.add("<id>" + TextUtil.escapeXML(c.getID()) + "</id>");
ComponentPreset preset = c.getPresetComponent();
if (preset != null) {

View File

@ -386,7 +386,11 @@ public abstract class Warning extends Message {
public static final Warning TUBE_SEPARATION = new Other(trans.get("Warning.TUBE_SEPARATION"));
public static final Warning TUBE_OVERLAP = new Other(trans.get("Warning.TUBE_OVERLAP"));
/** A <code>Warning</code> that stage separation occurred at other than the last stage */
public static final Warning SEPARATION_ORDER = new Other(trans.get("Warning.SEPARATION_ORDER"));
/** A <code>Warning</code> that stage separation occurred before the rocket cleared the launch rod or rail */
public static final Warning EARLY_SEPARATION = new Other(trans.get("Warning.EARLY_SEPARATION"));
public static final Warning EMPTY_BRANCH = new Other(trans.get("Warning.EMPTY_BRANCH"));
}

View File

@ -170,14 +170,14 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
* @return the previous stage in the rocket
*/
public AxialStage getUpperStage() {
if( null == this.parent ) {
if (this.parent == null) {
return null;
}else if(Rocket.class.isAssignableFrom(this.parent.getClass()) ){
final int thisIndex = getStageNumber();
if( 0 < thisIndex ){
return (AxialStage)parent.getChild(thisIndex-1);
} else if (Rocket.class.isAssignableFrom(this.parent.getClass())) {
final int thisIndex = parent.getChildPosition(this);
if (thisIndex > 0) {
return (AxialStage) parent.getChild(thisIndex-1);
}
}else {
} else {
return this.parent.getStage();
}
return null;

View File

@ -170,6 +170,11 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
" Please set setClusterConfiguration(ClusterConfiguration) instead.",
new UnsupportedOperationException("InnerTube.setInstanceCount(..) on an"+this.getClass().getSimpleName()));
}
@Override
public boolean isAfter(){
return false;
}
/**
* Get the cluster scaling. A value of 1.0 indicates that the tubes are packed
@ -177,14 +182,10 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
* pack inside each other.
*/
public double getClusterScale() {
mutex.verify();
return clusterScale;
}
@Override
public boolean isAfter(){
return false;
}
/**
* Set the cluster scaling.
* @see #getClusterScale()
@ -203,6 +204,23 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
clusterScale = scale;
fireComponentChangeEvent(new ComponentChangeEvent(this, ComponentChangeEvent.MASS_CHANGE));
}
/**
* Get the cluster scaling as an absolute distance measurement. A value of 0 indicates that the tubes are packed
* touching each other, larger values separate the tubes and smaller values pack inside each other.
*/
public double getClusterScaleAbsolute() {
return (getClusterScale() - 1) * getOuterRadius() * 2;
}
/**
* Set the absolute cluster scaling (in terms of distance).
* @see #getClusterScaleAbsolute()
*/
public void setClusterScaleAbsolute(double scale) {
double scaleRel = scale / (getOuterRadius() * 2) + 1;
setClusterScale(scaleRel);
}
@ -242,27 +260,21 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
}
public List<Coordinate> getClusterPoints() {
List<Coordinate> list = new ArrayList<Coordinate>(getInstanceCount());
List<Coordinate> list = new ArrayList<>(getInstanceCount());
List<Double> points = cluster.getPoints(clusterRotation - getRadialDirection());
double separation = getClusterSeparation();
double yOffset = this.radialPosition * Math.cos(this.radialDirection);
double zOffset = this.radialPosition * Math.sin(this.radialDirection);
for (int i = 0; i < points.size() / 2; i++) {
list.add(new Coordinate(0, points.get(2 * i) * separation, points.get(2 * i + 1) * separation));
list.add(new Coordinate(0, points.get(2 * i) * separation + yOffset, points.get(2 * i + 1) * separation + zOffset));
}
return list;
}
@Override
public Coordinate[] getInstanceOffsets(){
if ( 1 == getInstanceCount()) {
double yOffset = this.radialPosition * Math.cos(this.radialDirection);
double zOffset = this.radialPosition * Math.sin(this.radialDirection);
return new Coordinate[] { Coordinate.ZERO.add(0.0, yOffset, zOffset) };
}
List<Coordinate> points = getClusterPoints();
return points.toArray( new Coordinate[ points.size() ]);
return points.toArray(new Coordinate[0]);
}
// @Override

View File

@ -109,7 +109,7 @@ public abstract class MassObject extends InternalComponent {
return radius;
}
if (parent instanceof NoseCone) {
return ((NoseCone) parent).getAftRadius();
return ((NoseCone) parent).getBaseRadius();
} else if (parent instanceof Transition) {
double foreRadius = ((Transition) parent).getForeRadius();
double aftRadius = ((Transition) parent).getAftRadius();

View File

@ -1282,8 +1282,16 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
mutex.verify();
this.id = UniqueID.uuid();
}
/**
* Set the ID for this component.
* Generally not recommended to directly set the ID, this is done automatically. Only use this in case you have to.
* @param newID new ID
*/
public void setID(String newID) {
mutex.verify();
this.id = newID;
}
/**
@ -2047,6 +2055,16 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
}
return children;
}
/**
* Checks whether this component contains <component> as one of its (sub-)children.
* @param component component to check
* @return true if component is a (sub-)child of this component
*/
public final boolean containsChild(RocketComponent component) {
List<RocketComponent> allChildren = getAllChildren();
return allChildren.contains(component);
}
/**

View File

@ -849,12 +849,20 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
// have a radial offset of 0 from their centerline, we are in line.
if ((this.parent instanceof RingInstanceable) &&
(!MathUtil.equals(this.parent.getRadiusMethod().getRadius(this.parent.parent, this, this.parent.getRadiusOffset()), 0)))
(!MathUtil.equals(this.parent.getRadiusMethod().getRadius(
this.parent.parent, this, this.parent.getRadiusOffset()), 0)))
return false;
if ((candidate.parent instanceof RingInstanceable) &&
(!MathUtil.equals(candidate.parent.getRadiusMethod().getRadius(candidate.parent.parent, candidate, candidate.parent.getRadiusOffset()), 0)))
return false;
if (candidate.parent instanceof RingInstanceable) {
// We need to check if the grandparent of the candidate is a body tube and if the outer radius is automatic.
// If so, then this would cause an infinite loop when checking the radius of the radiusMethod.
if (candidate.parent.parent == this && (this.isAftRadiusAutomatic() || this.isForeRadiusAutomatic())) {
return false;
} else {
return MathUtil.equals(candidate.parent.getRadiusMethod().getRadius(
candidate.parent.parent, candidate, candidate.parent.getRadiusOffset()), 0);
}
}
return true;
}

View File

@ -118,6 +118,8 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
setForeShoulderRadius(getForeShoulderRadius());
}
public void setForeRadius(double radius) {
@ -207,6 +209,8 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
setAftShoulderRadius(getAftShoulderRadius());
}
public void setAftRadius(double radius) {
@ -398,6 +402,7 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
((Transition) listener).setForeShoulderRadius(foreShoulderRadius);
}
}
foreShoulderRadius = Math.min(foreShoulderRadius, getForeRadius());
if (MathUtil.equals(this.foreShoulderRadius, foreShoulderRadius))
return;
@ -471,6 +476,8 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
}
}
aftShoulderRadius = Math.min(aftShoulderRadius, getAftRadius());
if (MathUtil.equals(this.aftShoulderRadius, aftShoulderRadius))
return;
this.aftShoulderRadius = aftShoulderRadius;

View File

@ -485,11 +485,16 @@ public class BasicEventSimulationEngine implements SimulationEngine {
currentStatus.getWarnings().add(Warning.SEPARATION_ORDER);
}
// If I haven't cleared the rail yet, flag a warning
if (!currentStatus.isLaunchRodCleared()) {
currentStatus.getWarnings().add(Warning.EARLY_SEPARATION);
}
// Create a new simulation branch for the booster
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
// Prepare the new simulation branch
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), currentStatus.getFlightData()));
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), boosterStage, currentStatus.getFlightData()));
boosterStatus.getFlightData().addEvent(event);
// Mark the current status as having dropped the current stage and all stages below it

View File

@ -134,8 +134,12 @@ public class FlightData {
return branches.size();
}
public FlightDataBranch getBranch(int n) {
return branches.get(n);
public FlightDataBranch getBranch(int stageNr) {
return branches.get(stageNr);
}
public int getStageNr(FlightDataBranch branch) {
return branches.indexOf(branch);
}
public List<FlightDataBranch> getBranches() {

View File

@ -6,6 +6,9 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Monitorable;
import net.sf.openrocket.util.Mutable;
@ -30,11 +33,10 @@ public class FlightDataBranch implements Monitorable {
/** The name of this flight data branch. */
private final String branchName;
private final Map<FlightDataType, ArrayList<Double>> values =
new LinkedHashMap<FlightDataType, ArrayList<Double>>();
private final Map<FlightDataType, ArrayList<Double>> values = new LinkedHashMap<>();
private final Map<FlightDataType, Double> maxValues = new HashMap<FlightDataType, Double>();
private final Map<FlightDataType, Double> minValues = new HashMap<FlightDataType, Double>();
private final Map<FlightDataType, Double> maxValues = new HashMap<>();
private final Map<FlightDataType, Double> minValues = new HashMap<>();
/**
* time for the rocket to reach apogee if the flight had been no recovery deployment
@ -77,23 +79,19 @@ public class FlightDataBranch implements Monitorable {
}
/**
* Make a flight data branch with one data point copied from its parent. Intended for use
* Make a flight data branch with all data points copied from its parent. Intended for use
* when creating a new branch upon stage separation, so the data at separation is present
* in both branches (and if the new branch has an immediate exception, it can be plotted)
*
* @param branchName the name of the new branch.
* @param srcComponent the component that is the source of the new branch.
* @param parent the parent branch to copy data from.
*/
public FlightDataBranch(String branchName, FlightDataBranch parent) {
public FlightDataBranch(String branchName, RocketComponent srcComponent, FlightDataBranch parent) {
this.branchName = branchName;
// need to have at least one type to set up values
values.put(FlightDataType.TYPE_TIME, new ArrayList<Double>());
minValues.put(FlightDataType.TYPE_TIME, Double.NaN);
maxValues.put(FlightDataType.TYPE_TIME, Double.NaN);
// copy all values into new FlightDataBranch
this.addPoint();
for (FlightDataType t : parent.getTypes()) {
this.setValue(t, parent.getLast(t));
}
// Copy all the values from the parent
copyValuesFromBranch(parent, srcComponent);
}
/**
@ -115,12 +113,27 @@ public class FlightDataBranch implements Monitorable {
public void addPoint() {
mutable.check();
for (FlightDataType t : values.keySet()) {
values.get(t).add(Double.NaN);
for (FlightDataType type : values.keySet()) {
sanityCheckValues(type, Double.NaN);
values.get(type).add(Double.NaN);
}
modID++;
}
private void sanityCheckValues(FlightDataType type, Double value) {
ArrayList<Double> list = values.get(type);
if (list == null) {
list = new ArrayList<>();
int n = getLength();
for (int i = 0; i < n; i++) {
list.add(Double.NaN);
}
values.put(type, list);
minValues.put(type, value);
maxValues.put(type, value);
}
}
/**
* Set the value for a specific data type at the latest point. New variable types can be
@ -132,20 +145,10 @@ public class FlightDataBranch implements Monitorable {
*/
public void setValue(FlightDataType type, double value) {
mutable.check();
sanityCheckValues(type, value);
ArrayList<Double> list = values.get(type);
if (list == null) {
list = new ArrayList<Double>();
int n = getLength();
for (int i = 0; i < n; i++) {
list.add(Double.NaN);
}
values.put(type, list);
minValues.put(type, value);
maxValues.put(type, value);
}
if (list.size() > 0) {
list.set(list.size() - 1, value);
}
@ -161,7 +164,68 @@ public class FlightDataBranch implements Monitorable {
}
modID++;
}
/**
* Clears all the current values in the branch and copies the values from the given branch.
* @param srcBranch the branch to copy values from
* @param srcComponent the component that is the source of this branch (used for copying events)
*/
private void copyValuesFromBranch(FlightDataBranch srcBranch, RocketComponent srcComponent) {
this.values.clear();
// Need to have at least one type to set up values
values.put(FlightDataType.TYPE_TIME, new ArrayList<>());
minValues.put(FlightDataType.TYPE_TIME, Double.NaN);
maxValues.put(FlightDataType.TYPE_TIME, Double.NaN);
if (srcBranch == null) {
return;
}
// Copy flight data
for (int i = 0; i < srcBranch.getLength(); i++) {
this.addPoint();
for (FlightDataType type : srcBranch.getTypes()) {
this.setValue(type, srcBranch.getByIndex(type, i));
}
}
// Copy flight events belonging to this branch
List<FlightEvent> sustainerEvents = srcBranch.getEvents();
for (FlightEvent event : sustainerEvents) {
// Stage separation is already added elsewhere, so don't copy it over (otherwise you have a duplicate)
if (event.getType() == FlightEvent.Type.STAGE_SEPARATION) {
continue;
}
RocketComponent srcEventComponent = event.getSource();
// Ignore null events
if (srcComponent == null || srcEventComponent == null) {
continue;
}
// Ignore events from other stages. Important for when the current stage has a booster stage; we don't want to copy over the booster events.
if (getStageForComponent(srcComponent) != getStageForComponent(srcEventComponent)) {
continue;
}
if (srcComponent == srcEventComponent || srcComponent.containsChild(srcEventComponent)) {
events.add(event);
}
}
}
/**
* A safer method for checking the stage of a component (that shouldn't throw exceptions when calling on stages/rockets)
* @param component the component to get the stage of
* @return the stage of the component, or null if the component is a rocket
*/
private AxialStage getStageForComponent(RocketComponent component) {
if (component instanceof AxialStage) {
return (AxialStage) component;
} else if (component instanceof Rocket) {
return null;
} else {
return component.getStage();
}
}
/**
* Return the branch name.
@ -203,6 +267,23 @@ public class FlightDataBranch implements Monitorable {
return null;
return list.clone();
}
/**
* Return the value of the specified type at the specified index.
* @param type the variable type
* @param index the data index of the value
* @return the value at the specified index
*/
public Double getByIndex(FlightDataType type, int index) {
if (index < 0 || index >= getLength()) {
throw new IllegalArgumentException("Index out of bounds");
}
ArrayList<Double> list = values.get(type);
if (list == null) {
return null;
}
return list.get(index);
}
/**
* Return the last value of the specified type in the branch, or NaN if the type is

View File

@ -118,6 +118,8 @@ public abstract class Preferences implements ChangeSource {
public static final String LAUNCH_USE_ISA = "LaunchUseISA";
public static final String SIMULATION_TIME_STEP = "SimulationTimeStep";
public static final String GEODETIC_COMPUTATION = "GeodeticComputationStrategy";
public static final String UI_THEME = "UITheme";
private static final AtmosphericModel ISA_ATMOSPHERIC_MODEL = new ExtendedISAModel();
@ -549,11 +551,6 @@ public abstract class Preferences implements ChangeSource {
fireChangeEvent();
}
public final float getRocketInfoFontSize() {
return (float) (11.0 + 3 * Application.getPreferences().getChoice(Preferences.ROCKET_INFO_FONT_SIZE, 2, 0));
}
/**
* Enable/Disable the auto-opening of the last edited design file on startup.
*/
@ -820,25 +817,6 @@ public abstract class Preferences implements ChangeSource {
}
}
public Color getDefaultColor(Class<? extends RocketComponent> c) {
String color = get("componentColors", c, StaticFieldHolder.DEFAULT_COLORS);
if (color == null)
return Color.BLACK;
Color clr = parseColor(color);
if (clr != null) {
return clr;
} else {
return Color.BLACK;
}
}
public final void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
if (color == null)
return;
putString("componentColors", c.getSimpleName(), stringifyColor(color));
}
/**
* Retrieve a Line style for the given component.
@ -1014,6 +992,29 @@ public abstract class Preferences implements ChangeSource {
public abstract void setComponentFavorite(ComponentPreset preset, ComponentPreset.Type type, boolean favorite);
public abstract Set<String> getComponentFavorites(ComponentPreset.Type type);
/*
NOTE: It is unusual for the UI Theme to be stored in the preferences instead of SwingPreferences. In fact, this code
is not pretty. Sometimes I just really hate Java and circular dependencies...
But the reason why this is implemented is because it would otherwise be an even bigger nightmare to fix unit tests
that use their own preferences... Also wasn't a fan of always casting the preferences to SwingPreferences.
*/
/**
* Get the current theme used for the UI.
* @return the current theme
*/
public Object getUITheme() {
return null;
}
/**
* Set the theme used for the UI.
* @param theme the theme to set
*/
public void setUITheme(Object theme) {}
/*
* Within a holder class so they will load only when needed.
@ -1032,19 +1033,6 @@ public abstract class Preferences implements ChangeSource {
DEFAULT_LINE_STYLES.put(RocketComponent.class, LineStyle.SOLID.name());
DEFAULT_LINE_STYLES.put(MassObject.class, LineStyle.DASHED.name());
}
private static final HashMap<Class<?>, String> DEFAULT_COLORS = new HashMap<Class<?>, String>();
static {
DEFAULT_COLORS.put(BodyComponent.class, "0,0,240");
DEFAULT_COLORS.put(TubeFinSet.class, "0,0,200");
DEFAULT_COLORS.put(FinSet.class, "0,0,200");
DEFAULT_COLORS.put(LaunchLug.class, "0,0,180");
DEFAULT_COLORS.put(RailButton.class, "0,0,180");
DEFAULT_COLORS.put(InternalComponent.class, "170,0,100");
DEFAULT_COLORS.put(MassObject.class, "0,0,0");
DEFAULT_COLORS.put(RecoveryDevice.class, "255,0,0");
}
}
private final List<EventListener> listeners = new ArrayList<EventListener>();

View File

@ -66,6 +66,10 @@ public class Color {
return new java.awt.Color(red, green, blue, alpha);
}
public static Color fromAWTColor(java.awt.Color AWTColor) {
return new Color(AWTColor.getRed(), AWTColor.getGreen(), AWTColor.getBlue(), AWTColor.getAlpha());
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {

View File

@ -1049,7 +1049,7 @@ public class TestRockets {
boosterCone.setThickness(0.002);
//payloadFairingNoseCone.setLength(0.118);
//payloadFairingNoseCone.setAftRadius(0.052);
boosterCone.setAftShoulderRadius( 0.051 );
boosterCone.setAftShoulderRadius( 0.0375 );
boosterCone.setAftShoulderLength( 0.02 );
boosterCone.setAftShoulderThickness( 0.001 );
boosterCone.setAftShoulderCapped( false );

View File

@ -331,9 +331,9 @@ public class OpenRocketSaverTest {
////////////////////////////////
@Test
public void testFileVersion108_withSimulationExtension() {
public void testFileVersion109_withSimulationExtension() {
OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v107_withSimulationExtension(SIMULATION_EXTENSION_SCRIPT);
assertEquals(108, getCalculatedFileVersion(rocketDoc));
assertEquals(109, getCalculatedFileVersion(rocketDoc));
}

View File

@ -498,7 +498,7 @@ public class MassCalculatorTest extends BaseTestCase {
// ====== ====== ======
ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0);
{
expMass = 0.0222459863653;
expMass = 0.0210923935430;
// think of the casts as an assert that ( child instanceof NoseCone) == true
NoseCone nose = (NoseCone) boosters.getChild(0);
compMass = nose.getComponentMass();
@ -582,7 +582,7 @@ public class MassCalculatorTest extends BaseTestCase {
// ====== ====== ======
ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0);
{
expCMx = 0.055710581052;
expCMx = 0.053835211739;
// think of the casts as an assert that ( child instanceof NoseCone) == true
NoseCone nose = (NoseCone) boosters.getChild(0);
actCMx = nose.getComponentCG().x;
@ -692,10 +692,10 @@ public class MassCalculatorTest extends BaseTestCase {
ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0);
{
final NoseCone boosterNose = (NoseCone) boosters.getChild(0);
expInertia = 1.82665797857e-5;
expInertia = 1.73189409900e-5;
compInertia = boosterNose.getRotationalInertia();
assertEquals(boosterNose.getName() + " Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
expInertia = 1.96501191666e-7;
expInertia = 4.51796586171e-6;
compInertia = boosterNose.getLongitudinalInertia();
assertEquals(boosterNose.getName() + " Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
@ -832,8 +832,8 @@ public class MassCalculatorTest extends BaseTestCase {
final RigidBody actualData = MassCalculator.calculateStructure(config);
final Coordinate actualCM = actualData.getCM();
double expMass = 0.608663395;
double expCMx = 1.073157592;
double expMass = 0.6063562096;
double expCMx = 1.075056887;
assertEquals("Heavy Booster Mass is incorrect: ", expMass, actualCM.weight, EPSILON);
assertEquals("Heavy Booster CM.x is incorrect: ", expCMx, actualCM.x, EPSILON);
@ -852,11 +852,11 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody actualBoosterLaunchData = MassCalculator.calculateLaunch(config);
double actualMass = actualBoosterLaunchData.getMass();
double expectedMass = 1.592663395;
double expectedMass = 1.5903562096;
assertEquals(" Booster Launch Mass is incorrect: ", expectedMass, actualMass, EPSILON);
final Coordinate actualCM = actualBoosterLaunchData.getCM();
double expectedCMx = 1.22216804;
double expectedCMx = 1.22310836;
Coordinate expCM = new Coordinate(expectedCMx, 0, 0, expectedMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, actualCM.x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, actualCM.y, EPSILON);
@ -876,8 +876,8 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody spentData = MassCalculator.calculateBurnout(config);
Coordinate spentCM = spentData.getCM();
double expSpentMass = 1.12066339;
double expSpentCMx = 1.18334714;
double expSpentMass = 1.11835621;
double expSpentCMx = 1.18460423;
Coordinate expLaunchCM = new Coordinate(expSpentCMx, 0, 0, expSpentMass);
assertEquals(" Booster Launch Mass is incorrect: ", expLaunchCM.weight, spentCM.weight, EPSILON);
assertEquals(" Booster Launch CM.x is incorrect: ", expLaunchCM.x, spentCM.x, EPSILON);
@ -942,11 +942,11 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody spent = MassCalculator.calculateBurnout(config);
double expMOIRotational = 0.009205665421431532;
double expMOIRotational = 0.00919009169;
double boosterMOIRotational = spent.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOIRotational, boosterMOIRotational, EPSILON);
double expMOI_tr = 0.0582250994240395;
double expMOI_tr = 0.0573781722;
double boosterMOI_tr = spent.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -962,9 +962,9 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody launchData = MassCalculator.calculateLaunch(config);
final double expIxx = 0.01226617242143153;
final double expIxx = 0.0122505987;
final double actIxx = launchData.getRotationalInertia();
final double expIyy = 0.06455356411879717;
final double expIyy = 0.0635943662;
final double actIyy = launchData.getLongitudinalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expIxx, actIxx, EPSILON);
@ -1006,11 +1006,11 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster Launch CM is incorrect: ", expCM, boosterSetCM);
// Validate MOI
double expMOI_axial = 0.005885793421431532;
double expMOI_axial = 0.00587021969016;
double boosterMOI_xx = burnout.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 17.86133586701;
double expMOI_tr = 17.78076176335;
double boosterMOI_tr = burnout.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -1052,7 +1052,7 @@ public class MassCalculatorTest extends BaseTestCase {
double expTotalMass = 3.3565872;
assertEquals(" Booster Launch Mass is incorrect: ", expTotalMass, boosterData.getMass(), EPSILON);
double expCMx = 0.2835089882645608;
double expCMx = 0.2827156156318;
Coordinate expCM = new Coordinate(expCMx, 0, 0, expTotalMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, boosterCM.x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, boosterCM.y, EPSILON);
@ -1064,7 +1064,7 @@ public class MassCalculatorTest extends BaseTestCase {
double boosterMOI_xx = boosterData.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 0.34567788938578525;
double expMOI_tr = 0.347611843243;
double boosterMOI_tr = boosterData.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -1095,11 +1095,11 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody structure = MassCalculator.calculateStructure(config);
final double expMass = 0.6086633952494;
final double expMass = 0.6063562096046;
double calcTotalMass = structure.getMass();
assertEquals(" Booster Launch Mass is incorrect: ", expMass, calcTotalMass, EPSILON);
final double expCMx = 0.5551303646438673;
final double expCMx = 0.55670993586431;
Coordinate expCM = new Coordinate(expCMx, 0, 0, expMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, structure.getCM().x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, structure.getCM().y, EPSILON);
@ -1107,11 +1107,11 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster Launch CM is incorrect: ", expCM, structure.getCM());
// Validate MOI
final double expMOI_axial = 0.005885793421;
final double expMOI_axial = 0.005870219690;
double boosterMOI_xx = structure.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
final double expMOI_tr = 0.040989095911;
final double expMOI_tr = 0.040598624476;
double boosterMOI_tr = structure.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}

View File

@ -108,8 +108,8 @@ public class FlightEventsTest extends BaseTestCase {
// events whose time is too variable to check are given a time of 1200
for (int b = 0; b < 3; b++) {
FlightEvent[] expectedEvents;
final RocketComponent[] expectedSources;
switch (b) {
// Sustainer (payload fairing stage)
case 0:
expectedEvents = new FlightEvent[] {
new FlightEvent(FlightEvent.Type.LAUNCH, 0.0, rocket),
@ -117,7 +117,7 @@ public class FlightEventsTest extends BaseTestCase {
new FlightEvent(FlightEvent.Type.IGNITION, 0.0, coreBody),
new FlightEvent(FlightEvent.Type.LIFTOFF, 0.1225, null),
new FlightEvent(FlightEvent.Type.LAUNCHROD, 0.125, null),
new FlightEvent(FlightEvent.Type.APOGEE, 1.86, rocket),
new FlightEvent(FlightEvent.Type.APOGEE, 1.867, rocket),
new FlightEvent(FlightEvent.Type.BURNOUT, 2.0, boosterMotorTubes),
new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, 2.0, boosterStage),
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, boosterStage),
@ -129,17 +129,25 @@ public class FlightEventsTest extends BaseTestCase {
new FlightEvent(FlightEvent.Type.SIMULATION_END, 1200, null)
};
break;
// Core stage
case 1:
expectedEvents = new FlightEvent[] {
new FlightEvent(FlightEvent.Type.IGNITION, 0.0, coreBody),
new FlightEvent(FlightEvent.Type.BURNOUT, 2.0, coreBody),
new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, 2.0, coreStage),
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, coreStage),
new FlightEvent(FlightEvent.Type.GROUND_HIT, 1200, null),
new FlightEvent(FlightEvent.Type.SIMULATION_END, 1200, null)
};
break;
// Booster stage
case 2:
expectedEvents = new FlightEvent[] {
new FlightEvent(FlightEvent.Type.IGNITION, 0.0, boosterMotorTubes),
new FlightEvent(FlightEvent.Type.BURNOUT, 2.0, boosterMotorTubes),
new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, 2.0, boosterStage),
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, boosterStage),
new FlightEvent(FlightEvent.Type.TUMBLE, 3.551, null),
new FlightEvent(FlightEvent.Type.TUMBLE, 3.428, null),
new FlightEvent(FlightEvent.Type.GROUND_HIT, 1200, null),
new FlightEvent(FlightEvent.Type.SIMULATION_END, 1200, null)
};
@ -150,10 +158,7 @@ public class FlightEventsTest extends BaseTestCase {
// Test event count
final FlightDataBranch branch = sim.getSimulatedData().getBranch(b);
final FlightEvent[] events = (FlightEvent[]) branch.getEvents().toArray(new FlightEvent[0]);
for (int i = 0; i < events.length; i++) {
System.out.println("branch " + b + " index " + i + " event " + events[i]);
}
final FlightEvent[] events = branch.getEvents().toArray(new FlightEvent[0]);
assertEquals(" Multi-stage simulation, branch " + b + " invalid number of events ", expectedEvents.length, events.length);
// Test that all expected events are present, in the right order, at the right time, from the right sources

View File

@ -63,3 +63,6 @@ The following file format versions exist:
Rename <fincount> to <instancecount> (<fincount> remains for backward compatibility)
Rename <position> to <axialoffset> (<position> remains for backward compatibility)
Rename <rotation> to <angleoffset> (<rotation> remains for backward compatibility)
1.9: Introduced with OpenRocket 23.xx.
Added ID for each rocket component, to in turn add this ID as a source for flight events.

View File

@ -48,6 +48,7 @@
</launcher>
</launchers>
<installerGui>
<laf type="native" />
<applications>
<application id="installer" beanClass="com.install4j.runtime.beans.applications.InstallerApplication" customIcnsFile="../../core/resources/pix/icon/icon-macos.icns" customIcoFile="../../core/resources/pix/icon/icon-windows.ico">
<serializedBean>

View File

@ -11,6 +11,7 @@
<classpathentry kind="lib" path="lib/iText-5.0.2.jar"/>
<classpathentry kind="lib" path="lib/jcommon-1.0.18.jar"/>
<classpathentry kind="lib" path="lib/jfreechart-1.0.15.jar"/>
<classpathentry kind="lib" path="lib/darklaf/*.jar"/>
<classpathentry kind="lib" path="lib/jogl/gluegen-rt.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/OpenRocket Core"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/slf4j-api-1.7.30.jar"/>

View File

@ -5,6 +5,7 @@
<libelement value="jar://$MODULE_DIR$/lib/iText-5.0.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jcommon-1.0.18.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jfreechart-1.0.15.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/darklaf/*.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/OrangeExtensions-1.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jogl/gluegen-rt.jar!/" />
<libelement value="jar://$MODULE_DIR$/../core/lib/slf4j-api-1.7.5.jar!/" />
@ -107,6 +108,39 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="flatlaf-3.1.1.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/flatlaf-3.1.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="darklaf-3.0.2.jar">
<CLASSES>""
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-core-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-theme-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-theme-spec-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-utils-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-property-loader-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-platform-base-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-platform-decorations-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-platform-preferences-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-iconset-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-compatibility-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-macos-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-native-utils-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-windows-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/jsvg-0.0.9.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/swing-extensions-laf-support-0.1.3.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/swing-extensions-visual-padding-0.1.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="aopalliance.jar">
<CLASSES>

View File

@ -74,7 +74,7 @@
<echo level="info">Java/JVM detail version: ${java.version}</echo>
<mkdir dir="${classes.dir}"/>
<echo level="info">Compiling main classes</echo>
<javac debug="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="false" source="1.8" target="1.8"/>
<javac debug="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="false" source="17" target="17"/>
</target>
<!-- Executible Eclipse-Jar-In-Jar style JAR -->
@ -116,6 +116,22 @@
<zipfileset src="${core.dir}/lib/jaxb-runtime.2.3.1.jar"/>
<zipfileset src="${lib.dir}/jcommon-1.0.18.jar"/>
<zipfileset src="${lib.dir}/jfreechart-1.0.15.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-compatibility-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-core-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-iconset-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-macos-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-native-utils-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-platform-base-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-platform-decorations-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-platform-preferences-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-property-loader-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-theme-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-theme-spec-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-utils-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-windows-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/jsvg-0.0.9.jar"/>
<zipfileset src="${lib.dir}/darklaf/swing-extensions-laf-support-0.1.3.jar"/>
<zipfileset src="${lib.dir}/darklaf/swing-extensions-visual-padding-0.1.3.jar"/>
<zipfileset src="${core.dir}/lib/opencsv-5.7.1.jar"/>
<zipfileset src="${core.dir}/lib/annotation-detector-3.0.5.jar"/>
<zipfileset src="${core.dir}/lib/slf4j-api-1.7.30.jar"/>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,12 +2,10 @@ package net.sf.openrocket.communication;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BuildProperties;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* This class handles assets extracted from a GitHub release page.

View File

@ -3,9 +3,7 @@ package net.sf.openrocket.database;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.Collection;
import java.util.List;
import net.sf.openrocket.file.iterator.DirectoryIterator;
import net.sf.openrocket.file.iterator.FileIterator;
@ -14,7 +12,6 @@ import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.xml.OpenRocketComponentLoader;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Pair;
import org.slf4j.Logger;

View File

@ -1,5 +1,7 @@
package net.sf.openrocket.gui.components;
import net.sf.openrocket.gui.util.GUIUtil;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
@ -14,7 +16,6 @@ import javax.swing.tree.TreePath;
@SuppressWarnings("serial")
public class BasicTree extends JTree {
public BasicTree() {
super();
setDefaultOptions();
@ -36,7 +37,7 @@ public class BasicTree extends JTree {
plainUI.setLeftChildIndent(15);
this.setBackground(Color.WHITE);
this.setBackground(GUIUtil.getUITheme().getBackgroundColor());
this.setShowsRootHandles(false);
}

View File

@ -1,9 +1,9 @@
package net.sf.openrocket.gui.components;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.URLUtil;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
@ -31,6 +31,8 @@ import javax.swing.SwingUtilities;
public class DescriptionArea extends JScrollPane {
private final JEditorPane editorPane;
private final float size;
/**
@ -86,15 +88,14 @@ public class DescriptionArea extends JScrollPane {
public DescriptionArea(String text, int rows, float size, boolean opaque) {
super(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
this.size = size;
editorPane = new JEditorPane("text/html", "");
Font font = editorPane.getFont();
editorPane.setFont(font.deriveFont(font.getSize2D() + size));
editorPane.setEditable(false);
editorPane.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
URI uri = null;
URI uri;
try {
uri = e.getURL().toURI();
}
@ -125,8 +126,8 @@ public class DescriptionArea extends JScrollPane {
// create temporary file and copy resource to it
File of = null;
BufferedOutputStream os = null;
File of;
BufferedOutputStream os;
try {
of = File.createTempFile(prefix, suffix);
os = new BufferedOutputStream(new FileOutputStream(of));
@ -163,11 +164,11 @@ public class DescriptionArea extends JScrollPane {
}
// Calculate correct height
editorPane.setText("abc");
this.setText("abc");
Dimension oneline = editorPane.getPreferredSize();
editorPane.setText("abc<br>def");
this.setText("abc<br>def");
Dimension twolines = editorPane.getPreferredSize();
editorPane.setText("");
this.setText("");
int lineheight = twolines.height - oneline.height;
int extraheight = oneline.height - lineheight;
@ -175,13 +176,20 @@ public class DescriptionArea extends JScrollPane {
Dimension dim = editorPane.getPreferredSize();
dim.height = lineheight * rows + extraheight + 2;
this.setPreferredSize(dim);
editorPane.setBorder(GUIUtil.getUITheme().getBorder());
this.setViewportView(editorPane);
this.setText(text);
}
public void setText(String txt) {
editorPane.setText(txt);
// Set the font size (we can't simply set the font to change the font size, because we're using text/html)
Font defaultFont = editorPane.getFont();
String fontName = defaultFont.getFontName();
float fontSize = defaultFont.getSize2D() + size;
editorPane.setText("<html><body style='font-family:" + fontName + ";font-size:" + fontSize + "pt;'>" + txt + "</body></html>");
editorPane.revalidate();
SwingUtilities.invokeLater(new Runnable() {

View File

@ -1,23 +1,18 @@
package net.sf.openrocket.gui.components;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.URLUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.util.BugException;
/**
* A label of a URL that is clickable. Clicking the URL will launch the URL in
* the default browser if the Desktop class is supported.
@ -26,7 +21,7 @@ import net.sf.openrocket.util.BugException;
*/
public class URLLabel extends SelectableLabel {
private static final Logger log = LoggerFactory.getLogger(URLLabel.class);
/**
* Create a label showing the url it will direct to.
*
@ -53,7 +48,7 @@ public class URLLabel extends SelectableLabel {
Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
this.setFont(this.getFont().deriveFont(map));
this.setForeground(Color.BLUE);
this.setForeground(GUIUtil.getUITheme().getURLColor());
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

View File

@ -22,7 +22,7 @@ public class Tester {
BasicApplication baseApp = new BasicApplication();
baseApp.initializeApplication();
GUIUtil.setBestLAF();
GUIUtil.applyLAF();
SwingUtilities.invokeAndWait(new Runnable() {
@Override

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.gui.configdialog;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
@ -170,6 +169,7 @@ public class AppearancePanel extends JPanel {
Color awtColor = ColorConversion.toAwtColor(c);
colorChooser.setColor(awtColor);
colorChooser.updateUI(); // Needed for darklaf color chooser to update
// Bind a change of color selection to a change in the components color
ColorSelectionModel model = colorChooser.getSelectionModel();
@ -183,7 +183,8 @@ public class AppearancePanel extends JPanel {
JDialog d = JColorChooser.createDialog(AppearancePanel.this,
trans.get("RocketCompCfg.lbl.Choosecolor"), true,
colorChooser, new ActionListener() {
colorChooser,
new ActionListener() {
@Override
public void actionPerformed(ActionEvent okEvent) {
changeComponentColor(colorChooser.getColor());
@ -262,8 +263,7 @@ public class AppearancePanel extends JPanel {
net.sf.openrocket.util.Color figureColor = c.getColor();
if (figureColor == null) {
figureColor = Application.getPreferences().getDefaultColor(
c.getClass());
figureColor = ((SwingPreferences) Application.getPreferences()).getDefaultColor(c.getClass());
}
final JButton figureColorButton = new SelectColorButton(
new ColorIcon(figureColor));
@ -278,8 +278,7 @@ public class AppearancePanel extends JPanel {
public void stateChanged(EventObject e) {
net.sf.openrocket.util.Color col = c.getColor();
if (col == null) {
col = Application.getPreferences().getDefaultColor(
c.getClass());
col = ((SwingPreferences) Application.getPreferences()).getDefaultColor(c.getClass());
}
figureColorButton.setIcon(new ColorIcon(col));
}

View File

@ -9,6 +9,8 @@ import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
@ -17,12 +19,14 @@ import java.util.EventObject;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
@ -36,6 +40,7 @@ import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.DescriptionArea;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.widgets.SelectColorButton;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material;
@ -46,6 +51,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RingComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
@ -55,6 +61,9 @@ import net.sf.openrocket.util.StateChangeListener;
public class InnerTubeConfig extends RocketComponentConfig {
private static final long serialVersionUID = 7900041420864324470L;
private static final Translator trans = Application.getTranslator();
private static final Preferences prefs = Application.getPreferences();
private static final String PREF_SEPARATION_RELATIVE = "InnerTubeSeparationRelative";
public InnerTubeConfig(OpenRocketDocument d, RocketComponent c, JDialog parent) {
@ -279,29 +288,88 @@ public class InnerTubeConfig extends RocketComponentConfig {
//// The separation of the tubes, 1.0 = touching each other
l.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
subPanel.add(l);
DoubleModel dm = new DoubleModel(component, "ClusterScale", 1, UnitGroup.UNITS_NONE, 0);
JSpinner spin = new JSpinner(dm.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
//// The separation of the tubes, 1.0 = touching each other
spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
subPanel.add(spin, "growx");
order.add(((SpinnerEditor) spin.getEditor()).getTextField());
//// Models
final boolean useRelativeSeparation = prefs.getBoolean(PREF_SEPARATION_RELATIVE, true);
final DoubleModel clusterScaleModelRel = new DoubleModel(component, "ClusterScale", 1, UnitGroup.UNITS_NONE, 0);
final DoubleModel clusterScaleModelAbs = new DoubleModel(component, "ClusterScaleAbsolute", 1, UnitGroup.UNITS_LENGTH);
final DoubleModel clusterScaleModel = useRelativeSeparation ? clusterScaleModelRel : clusterScaleModelAbs;
BasicSlider bs = new BasicSlider(dm.getSliderModel(0, 1, 4));
//// The separation of the tubes, 1.0 = touching each other
bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
subPanel.add(bs, "skip,w 100lp, wrap");
final String clusterScaleTtipRel = trans.get("InnerTubeCfg.lbl.ttip.TubeSep");
final String clusterScaleTtipAbs = trans.get("InnerTubeCfg.lbl.ttip.TubeSepAbs");
final String clusterScaleTtip = useRelativeSeparation ? clusterScaleTtipRel : clusterScaleTtipAbs;
JSpinner clusterScaleSpin = new JSpinner(clusterScaleModel.getSpinnerModel());
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
clusterScaleSpin.setToolTipText(clusterScaleTtip);
subPanel.add(clusterScaleSpin, "growx");
order.add(((SpinnerEditor) clusterScaleSpin.getEditor()).getTextField());
UnitSelector clusterScaleUnit = new UnitSelector(clusterScaleModel);
subPanel.add(clusterScaleUnit, "growx");
BasicSlider clusterScaleBs = new BasicSlider(clusterScaleModel.getSliderModel(0, 1, 4));
subPanel.add(clusterScaleBs, "w 100lp, wrap");
// Relative/absolute separation
JRadioButton rbRel = new JRadioButton(trans.get("InnerTubeCfg.radioBut.Relative"));
JRadioButton rbAbs = new JRadioButton(trans.get("InnerTubeCfg.radioBut.Absolute"));
rbRel.setToolTipText(trans.get("InnerTubeCfg.radioBut.Relative.ttip"));
rbAbs.setToolTipText(trans.get("InnerTubeCfg.radioBut.Absolute.ttip"));
ButtonGroup bg = new ButtonGroup();
bg.add(rbRel);
bg.add(rbAbs);
subPanel.add(rbRel, "skip, spanx, split 2");
subPanel.add(rbAbs, "wrap");
rbRel.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.DESELECTED)
return;
clusterScaleSpin.setModel(clusterScaleModelRel.getSpinnerModel());
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
clusterScaleUnit.setModel(clusterScaleModelRel);
clusterScaleBs.setModel(clusterScaleModelRel.getSliderModel(0, 1, 4));
clusterScaleSpin.setToolTipText(clusterScaleTtipRel);
prefs.putBoolean(PREF_SEPARATION_RELATIVE, false);
}
});
rbAbs.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.DESELECTED)
return;
DoubleModel radiusModelMin = new DoubleModel(component, "OuterRadius", -2, UnitGroup.UNITS_LENGTH);
DoubleModel radiusModelMax = new DoubleModel(component, "OuterRadius", 6, UnitGroup.UNITS_LENGTH);
clusterScaleSpin.setModel(clusterScaleModelAbs.getSpinnerModel());
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
clusterScaleUnit.setModel(clusterScaleModelAbs);
clusterScaleBs.setModel(clusterScaleModelAbs.getSliderModel(radiusModelMin, radiusModelMax));
clusterScaleSpin.setToolTipText(clusterScaleTtipAbs);
prefs.putBoolean(PREF_SEPARATION_RELATIVE, false);
}
});
// Select the button by default
if (prefs.getBoolean(PREF_SEPARATION_RELATIVE, true)) {
rbRel.setSelected(true);
} else {
rbAbs.setSelected(true);
}
// Rotation:
l = new JLabel(trans.get("InnerTubeCfg.lbl.Rotation"));
//// Rotation angle of the cluster configuration
l.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
subPanel.add(l);
dm = new DoubleModel(component, "ClusterRotation", 1, UnitGroup.UNITS_ANGLE,
DoubleModel dm = new DoubleModel(component, "ClusterRotation", 1, UnitGroup.UNITS_ANGLE,
-Math.PI, Math.PI);
spin = new JSpinner(dm.getSpinnerModel());
JSpinner spin = new JSpinner(dm.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
//// Rotation angle of the cluster configuration
spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
@ -309,7 +377,7 @@ public class InnerTubeConfig extends RocketComponentConfig {
order.add(((SpinnerEditor) spin.getEditor()).getTextField());
subPanel.add(new UnitSelector(dm), "growx");
bs = new BasicSlider(dm.getSliderModel());
BasicSlider bs = new BasicSlider(dm.getSliderModel());
//// Rotation angle of the cluster configuration
bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
subPanel.add(bs, "w 100lp, wrap para");
@ -398,10 +466,17 @@ class ClusterSelectionPanel extends JPanel {
private static final int BUTTON_SIZE = 50;
private static final int MOTOR_DIAMETER = 10;
private static final Color SELECTED_COLOR = Color.RED;
private static final Color UNSELECTED_COLOR = Color.WHITE;
private static final Color MOTOR_FILL_COLOR = Color.GREEN;
private static final Color MOTOR_BORDER_COLOR = Color.BLACK;
private static final Color SELECTED_COLOR;
private static final Color UNSELECTED_COLOR;
private static final Color MOTOR_FILL_COLOR;
private static final Color MOTOR_BORDER_COLOR;
static {
SELECTED_COLOR = Color.RED;
UNSELECTED_COLOR = GUIUtil.getUITheme().getBackgroundColor();
MOTOR_FILL_COLOR = Color.GREEN;
MOTOR_BORDER_COLOR = Color.BLACK;
}
public ClusterSelectionPanel(Clusterable component) {
super(new MigLayout("gap 0 0",
@ -438,6 +513,7 @@ class ClusterSelectionPanel extends JPanel {
setMaximumSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
// setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
setToolTipText(config.getXMLName());
component.addChangeListener(this);
addMouseListener(this);
}

View File

@ -506,7 +506,7 @@ public class RocketComponentConfig extends JPanel {
StyledLabel labelMassOverriddenBy = new StyledLabel(
String.format(trans.get("RocketCompCfg.lbl.MassOverriddenBy"), component.getMassOverriddenBy().getName()),
0, StyledLabel.Style.BOLD);
labelMassOverriddenBy.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
labelMassOverriddenBy.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
labelMassOverriddenBy.setToolTipText(
String.format(trans.get("RocketCompCfg.lbl.MassOverriddenBy.ttip"), component.getMassOverriddenBy().getName()));
checkboxes.add(labelMassOverriddenBy, "gapleft 25lp, wrap");
@ -569,7 +569,7 @@ public class RocketComponentConfig extends JPanel {
StyledLabel labelCGOverriddenBy = new StyledLabel(
String.format(trans.get("RocketCompCfg.lbl.CGOverriddenBy"), component.getCGOverriddenBy().getName()),
0, StyledLabel.Style.BOLD);
labelCGOverriddenBy.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
labelCGOverriddenBy.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
labelCGOverriddenBy.setToolTipText(
String.format(trans.get("RocketCompCfg.lbl.CGOverriddenBy.ttip"), component.getCGOverriddenBy().getName()));
checkboxes.add(labelCGOverriddenBy, "gapleft 25lp, wrap");
@ -663,7 +663,7 @@ public class RocketComponentConfig extends JPanel {
StyledLabel labelCDOverriddenBy = new StyledLabel(
String.format(trans.get("RocketCompCfg.lbl.CDOverriddenBy"), component.getCDOverriddenBy().getName()),
0, StyledLabel.Style.BOLD);
labelCDOverriddenBy.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
labelCDOverriddenBy.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
labelCDOverriddenBy.setToolTipText(
String.format(trans.get("RocketCompCfg.lbl.CDOverriddenBy"), component.getCDOverriddenBy().getName()));
checkboxes.add(labelCDOverriddenBy, "gapleft 25lp, wrap");
@ -719,6 +719,7 @@ public class RocketComponentConfig extends JPanel {
commentTextArea.setLineWrap(true);
commentTextArea.setWrapStyleWord(true);
commentTextArea.setEditable(true);
commentTextArea.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.setTabToFocusing(commentTextArea);
commentTextArea.addFocusListener(textFieldListener);
commentTextArea.addKeyListener(new TextComponentSelectionKeyListener(commentTextArea));

View File

@ -27,7 +27,7 @@ import net.sf.openrocket.startup.Application;
public class RocketConfig extends RocketComponentConfig {
private static final Translator trans = Application.getTranslator();
private TextFieldListener textFieldListener;
private JTextArea designerTextArea;
@ -55,6 +55,7 @@ public class RocketConfig extends RocketComponentConfig {
designerTextArea.setLineWrap(true);
designerTextArea.setWrapStyleWord(true);
designerTextArea.setEditable(true);
designerTextArea.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.setTabToFocusing(designerTextArea);
designerTextArea.addFocusListener(textFieldListener);
this.add(new JScrollPane(designerTextArea), "wmin 400lp, height 60lp:60lp:, grow 30, wrap para");
@ -69,6 +70,7 @@ public class RocketConfig extends RocketComponentConfig {
revisionTextArea.setLineWrap(true);
revisionTextArea.setWrapStyleWord(true);
revisionTextArea.setEditable(true);
revisionTextArea.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.setTabToFocusing(revisionTextArea);
revisionTextArea.addFocusListener(textFieldListener);

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.gui.customexpression;
import java.awt.Color;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -18,6 +17,7 @@ import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -39,7 +39,7 @@ public class CustomExpressionPanel extends JPanel {
private static final Logger log = LoggerFactory.getLogger(CustomExpressionPanel.class);
private static final Translator trans = Application.getTranslator();
private JPanel expressionSelectorPanel;
private OpenRocketDocument doc;
@ -51,6 +51,7 @@ public class CustomExpressionPanel extends JPanel {
expressionSelectorPanel.setToolTipText(trans.get("customExpressionPanel.lbl.CalcNote"));
JScrollPane scroll = new JScrollPane(expressionSelectorPanel);
expressionSelectorPanel.setBorder(GUIUtil.getUITheme().getBorder());
//Border bdr = BorderFactory.createTitledBorder(trans.get("customExpressionPanel.lbl.CustomExpressions"));
//scroll.setBorder(bdr);
@ -170,10 +171,10 @@ public class CustomExpressionPanel extends JPanel {
* A JPanel which configures a single expression
*/
private class SingleExpression extends JPanel {
// Convenience method to make the labels consistent
private JLabel setLabelStyle(JLabel l) {
l.setBackground(Color.WHITE);
l.setBackground(GUIUtil.getUITheme().getBackgroundColor());
l.setOpaque(true);
l.setBorder(BorderFactory.createRaisedBevelBorder());
l.setText(" " + l.getText() + " ");
@ -191,13 +192,13 @@ public class CustomExpressionPanel extends JPanel {
JLabel symbolLabel = new JLabel(trans.get("customExpression.Symbol") + " :");
JLabel symbol = new JLabel(expression.getSymbol());
symbol = setLabelStyle(symbol);
symbol.setBackground(Color.WHITE);
symbol.setBackground(GUIUtil.getUITheme().getBackgroundColor());
JLabel unitLabel = new JLabel(trans.get("customExpression.Units") + " :");
UnitSelector unitSelector = new UnitSelector(expression.getType().getUnitGroup());
//JLabel unitSelector = new JLabel ( expression.getUnit() );
//unitSelector = setLabelStyle(unitSelector);
//unitSelector.setBackground(Color.WHITE);
//unitSelector.setBackground(GUIUtil.getUITheme().getBackgroundColor());
JButton editButton = new SelectColorButton(Icons.EDIT_EDIT);
editButton.setToolTipText(trans.get("customExpression.Units.but.ttip.Edit"));

View File

@ -60,6 +60,9 @@ public class AboutDialog extends JDialog {
"<br>" +
"See all contributors at <br>" + href("https://github.com/openrocket/openrocket/graphs/contributors", false, false) + "<br>" +
"<br>" +
"<b>Thank you to our financial contributors who have provided us with the necessary resources to continue this project:</b><br>" +
href("https://opencollective.com/openrocket", true, true) + "<br>" +
"<br>" +
"<b>OpenRocket utilizes the following libraries:</b><br>" +
"<br>" +
"MiG Layout" + href("http://www.miglayout.com", true, true) + "<br>" +
@ -72,6 +75,7 @@ public class AboutDialog extends JDialog {
"Simple Logging Facade for Java" + href("http://www.slf4j.org", true, true) + "<br>" +
"Java library for parsing and rendering CommonMark" + href("https://github.com/commonmark/commonmark-java", true, true) + "<br>" +
"RSyntaxTextArea" + href("http://bobbylight.github.io/RSyntaxTextArea", true, true) + "<br>" +
"Darklaf (dark theme)" + href("https://github.com/weisJ/darklaf", true, true) + "<br>" +
"<br>" +
"<b>OpenRocket gratefully acknowledges our use of the following databases:</b><br>" +
"<br>" +

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.dialogs;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Window;
@ -177,8 +178,9 @@ public class BugReportDialog extends JDialog {
private static void addBugReportInformation(StringBuilder sb) {
sb.append("<html>---------- Bug report ----------\n");
sb.append('\n');
sb.append("<b style='color:rgb(210, 20, 5)'>Please include a description about what actions you were " +
"performing when the exception occurred:</b>\n");
Color color = GUIUtil.getUITheme().getDarkWarningColor();
sb.append(String.format("<b style='color:rgb(%d, %d, %d)'>Please include a description about what actions you were " +
"performing when the exception occurred:</b>\n", color.getRed(), color.getGreen(), color.getBlue()));
sb.append("<i>(You can edit text directly in this window)</i>\n");
sb.append('\n');
sb.append("1. \n");
@ -204,6 +206,7 @@ public class BugReportDialog extends JDialog {
sbTemp.append("OpenRocket source: " + BuildProperties.getBuildSource() + "\n");
sbTemp.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
sbTemp.append("User-defined thrust curves location: " + preferences.getUserThrustCurveFilesAsString() + "\n");
sbTemp.append("LAF: " + UIManager.getLookAndFeel().getClass().getName() + "\n");
sbTemp.append("JOGL version: " + JoglVersion.getInstance().getImplementationVersion() + "\n");
sbTemp.append("Current default locale: " + Locale.getDefault() + "\n");
sbTemp.append("System properties:\n");

View File

@ -150,6 +150,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
warningList = new JList<>();
JScrollPane scrollPane = new JScrollPane(warningList);
warningList.setBorder(GUIUtil.getUITheme().getBorder());
////Warnings:
scrollPane.setBorder(BorderFactory.createTitledBorder(trans.get("componentanalysisdlg.TitledBorder.warnings")));
panel.add(scrollPane, "gap paragraph, spany 4, w 300lp, grow, height :100lp:, wrap");
@ -646,7 +647,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
}
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBackground(GUIUtil.getUITheme().getBackgroundColor());
label.setHorizontalAlignment(SwingConstants.LEFT);
if ((row < 0) || (row >= data.size()))
@ -693,7 +694,6 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
private class DragCellRenderer extends CustomCellRenderer {
private static final long serialVersionUID = 1L;
public DragCellRenderer() {
super(dragData, 3);
}
@ -712,6 +712,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
float val = 1.0f;
label.setBackground(Color.getHSBColor(hue, sat, val));
label.setForeground(Color.BLACK);
}
if ((row < 0) || (row >= dragData.size()))

View File

@ -67,7 +67,7 @@ public class DebugLogDialog extends JDialog {
private static final int POLL_TIME = 250;
private static final String STACK_TRACE_MARK = "\uFF01";
private static final Translator trans = Application.getTranslator();
private static final EnumMap<LogLevel, Color> backgroundColors = new EnumMap<LogLevel, Color>(LogLevel.class);
static {
for (LogLevel l : LogLevel.values()) {
@ -343,6 +343,7 @@ public class DebugLogDialog extends JDialog {
bottomPanel.add(new JLabel(trans.get("debuglogdlg.lbl.Stacktrace")), "wrap rel");
stackTraceLabel = new JTextArea(8, 80);
stackTraceLabel.setEditable(false);
stackTraceLabel.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.changeFontSize(stackTraceLabel, -2);
bottomPanel.add(new JScrollPane(stackTraceLabel), "grow, pushy 200, growprioy 200");
@ -503,7 +504,7 @@ public class DebugLogDialog extends JDialog {
if (STACK_TRACE_MARK.equals(value)) {
fg = Color.RED;
} else {
fg = table1.getForeground();
fg = Color.BLACK;
}
bg = backgroundColors.get(buffer.get(row).getLevel());

View File

@ -3,6 +3,7 @@ package net.sf.openrocket.gui.dialogs;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.util.BetterListCellRenderer;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.logging.Error;
import net.sf.openrocket.logging.ErrorSet;
import net.sf.openrocket.logging.Warning;
@ -15,7 +16,6 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.ListSelectionModel;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@ -25,11 +25,12 @@ import java.awt.event.MouseEvent;
*/
@SuppressWarnings("serial")
public abstract class ErrorWarningDialog {
public static void showErrorsAndWarnings(Component parent, Object message, String title, ErrorSet errors, WarningSet warnings) {
JPanel content = new JPanel(new MigLayout("ins 0, fillx"));
StyledLabel label = new StyledLabel("Errors");
label.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
label.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
content.add(label, "wrap, gaptop 15lp");
Error[] e = errors.toArray(new Error[0]);
@ -37,6 +38,7 @@ public abstract class ErrorWarningDialog {
errorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
errorList.setCellRenderer(new ErrorListCellRenderer());
JScrollPane errorPane = new JScrollPane(errorList);
errorList.setBorder(GUIUtil.getUITheme().getBorder());
content.add(errorPane, "wrap, growx");
// Deselect items if clicked on blank region
@ -58,6 +60,7 @@ public abstract class ErrorWarningDialog {
final JList<Warning> warningList = new JList<>(w);
warningList.setCellRenderer(new BetterListCellRenderer());
JScrollPane warningPane = new JScrollPane(warningList);
warningList.setBorder(GUIUtil.getUITheme().getBorder());
content.add(warningPane, "wrap, growx");
// Deselect items if clicked on blank region
@ -84,9 +87,9 @@ public abstract class ErrorWarningDialog {
// Text color
if (isSelected) {
label.setForeground(Color.WHITE);
label.setForeground(GUIUtil.getUITheme().getTextSelectionForegroundColor());
} else {
label.setForeground(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
label.setForeground(GUIUtil.getUITheme().getDarkWarningColor());
}
return label;

View File

@ -1,16 +1,15 @@
package net.sf.openrocket.gui.dialogs;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
@ -75,6 +74,7 @@ public class UpdateInfoDialog extends JDialog {
// Release information box
final JTextPane textPane = new JTextPane();
textPane.setBorder(BorderFactory.createLineBorder(GUIUtil.getUITheme().getTextColor()));
textPane.setEditable(false);
textPane.setContentType("text/html");
textPane.setMargin(new Insets(10, 10, 40, 10));

View File

@ -2,23 +2,25 @@ package net.sf.openrocket.gui.dialogs;
import java.awt.Component;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import net.sf.openrocket.gui.util.BetterListCellRenderer;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.logging.Warning;
import net.sf.openrocket.logging.WarningSet;
@SuppressWarnings("serial")
public abstract class WarningDialog {
public static void showWarnings(Component parent, Object message, String title, WarningSet warnings) {
Warning[] w = warnings.toArray(new Warning[0]);
final JList<Warning> list = new JList<Warning>(w);
list.setCellRenderer(new BetterListCellRenderer());
JScrollPane pane = new JScrollPane(list);
pane.setBorder(GUIUtil.getUITheme().getBorder());
JOptionPane.showMessageDialog(parent, new Object[] { message, pane },
title, JOptionPane.WARNING_MESSAGE);

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.gui.dialogs.flightconfiguration;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Window;
import java.awt.event.ActionEvent;
@ -25,7 +24,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
public class RenameConfigDialog extends JDialog {
private static final long serialVersionUID = -5423008694485357248L;
private static final Translator trans = Application.getTranslator();
public RenameConfigDialog(final Window parent, final Rocket rocket, final FlightConfigurationId fcid) {
super(parent, trans.get("RenameConfigDialog.title"), Dialog.ModalityType.APPLICATION_MODAL);
@ -47,7 +46,7 @@ public class RenameConfigDialog extends JDialog {
RenameConfigDialog.this.setVisible(false);
}
});
panel.add(okButton);
panel.add(okButton, "growx");
JButton renameToDefaultButton = new SelectColorButton(trans.get("RenameConfigDialog.but.reset"));
renameToDefaultButton.addActionListener(new ActionListener() {
@ -57,7 +56,7 @@ public class RenameConfigDialog extends JDialog {
RenameConfigDialog.this.setVisible(false);
}
});
panel.add(renameToDefaultButton);
panel.add(renameToDefaultButton, "growx");
JButton cancel = new SelectColorButton(trans.get("button.cancel"));
cancel.addActionListener(new ActionListener() {
@ -66,14 +65,14 @@ public class RenameConfigDialog extends JDialog {
RenameConfigDialog.this.setVisible(false);
}
});
panel.add(cancel, "wrap para");
panel.add(cancel, "growx, wrap para");
// {motors} & {manufacturers} info
String text = "<html>" + CommonStrings.dagger + " " + trans.get("RenameConfigDialog.lbl.infoMotors")
+ trans.get("RenameConfigDialog.lbl.infoManufacturers")
+ trans.get("RenameConfigDialog.lbl.infoCombination");
StyledLabel info = new StyledLabel(text, -2);
info.setFontColor(Color.DARK_GRAY);
info.setFontColor(GUIUtil.getUITheme().getDimTextColor());
panel.add(info, "spanx, growx, wrap");
this.add(panel);

View File

@ -37,14 +37,13 @@ import net.sf.openrocket.unit.UnitGroup;
@SuppressWarnings("serial")
class MotorInformationPanel extends JPanel {
private static final Translator trans = Application.getTranslator();
private static final int ZOOM_ICON_POSITION_NEGATIVE_X = 50;
private static final int ZOOM_ICON_POSITION_POSITIVE_Y = 12;
private static final Color NO_COMMENT_COLOR = Color.GRAY;
private static final Color WITH_COMMENT_COLOR = Color.BLACK;
private static final Translator trans = Application.getTranslator();
private static final Color NO_COMMENT_COLOR = GUIUtil.getUITheme().getDimTextColor();
private static final Color WITH_COMMENT_COLOR = GUIUtil.getUITheme().getTextColor();
// Motors in set
private List<ThrustCurveMotor> selectedMotorSet;
@ -190,7 +189,9 @@ class MotorInformationPanel extends JPanel {
changeLabelFont(plot.getDomainAxis(), -2);
//// Thrust curve:
chart.setTitle(new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont()));
TextTitle title = new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont());
title.setPaint(GUIUtil.getUITheme().getTextColor());
chart.setTitle(title);
chart.setBackgroundPaint(this.getBackground());
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.gui.dialogs.optimization;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.Enumeration;
@ -17,6 +16,7 @@ import javax.swing.tree.TreePath;
import net.sf.openrocket.gui.components.BasicTree;
import net.sf.openrocket.gui.main.ComponentIcons;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
import net.sf.openrocket.rocketcomponent.Rocket;
@ -37,7 +37,7 @@ public class SimulationModifierTree extends BasicTree {
private final List<SimulationModifier> selectedModifiers;
private static final Translator trans = Application.getTranslator();
/**
* Sole constructor.
*
@ -151,11 +151,13 @@ public class SimulationModifierTree extends BasicTree {
// Set icon (for rocket components, null for others)
setIcon(ComponentIcons.getSmallIcon(object.getClass()));
// By default, set background to transparent
setOpaque(false);
// Set text color/style
if (object instanceof RocketComponent) {
setForeground(Color.GRAY);
setForeground(GUIUtil.getUITheme().getDimTextColor());
setFont(componentFont);
// Set tooltip
@ -169,21 +171,24 @@ public class SimulationModifierTree extends BasicTree {
this.setToolTipText(null);
}
} else if (object instanceof String) {
setForeground(Color.GRAY);
setForeground(GUIUtil.getUITheme().getDimTextColor());
setFont(stringFont);
} else if (object instanceof SimulationModifier) {
if (selectedModifiers.contains(object)) {
setForeground(Color.GRAY);
setForeground(GUIUtil.getUITheme().getDimTextColor());
setFont(stringFont);
} else {
if (tree.getSelectionRows() != null &&
IntStream.of(tree.getSelectionRows()).anyMatch(r -> r == row)) {
setForeground(Color.WHITE);
setForeground(GUIUtil.getUITheme().getTextSelectionForegroundColor());
setBackground(GUIUtil.getUITheme().getTextSelectionBackgroundColor());
setOpaque(true);
} else {
setForeground(Color.BLACK);
setForeground(GUIUtil.getUITheme().getTextColor());
}
setFont(modifierFont);
}
setFont(modifierFont);
setText(((SimulationModifier) object).getName());
setToolTipText(((SimulationModifier) object).getDescription());
}

View File

@ -20,9 +20,12 @@ import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
@ -31,6 +34,8 @@ import net.sf.openrocket.communication.ReleaseInfo;
import net.sf.openrocket.communication.UpdateInfo;
import net.sf.openrocket.communication.UpdateInfoRetriever;
import net.sf.openrocket.communication.UpdateInfoRetriever.ReleaseStatus;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.IntegerModel;
import net.sf.openrocket.gui.components.DescriptionArea;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style;
@ -40,6 +45,7 @@ import net.sf.openrocket.gui.util.SimpleFileFilter;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.gui.util.PreferencesExporter;
import net.sf.openrocket.gui.util.PreferencesImporter;
import net.sf.openrocket.gui.util.UITheme;
import net.sf.openrocket.l10n.L10N;
import net.sf.openrocket.logging.Markers;
import net.sf.openrocket.startup.Preferences;
@ -50,13 +56,17 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
@SuppressWarnings("serial")
public class GeneralPreferencesPanel extends PreferencesPanel {
private final UITheme.Theme currentTheme;
private final int currentFontSize;
public GeneralPreferencesPanel(PreferencesDialog parent) {
super(parent, new MigLayout("fillx, ins 30lp n n n"));
this.currentTheme = GUIUtil.getUITheme();
this.currentFontSize = preferences.getUIFontSize();
//// Language selector
Locale userLocale = null;
Locale userLocale;
{
String locale = preferences.getString("locale", null);
userLocale = L10N.toLocale(locale);
@ -79,6 +89,7 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
Named<Locale> selection = (Named<Locale>) languageCombo.getSelectedItem();
if (selection == null) return;
Locale l = selection.get();
preferences.putString(Preferences.USER_LOCAL, l == null ? null : l.toString());
}
@ -86,8 +97,64 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
this.add(new JLabel(trans.get("generalprefs.lbl.language")), "gapright para");
this.add(languageCombo, "wrap rel, growx, sg combos");
this.add(new StyledLabel(trans.get("generalprefs.lbl.languageEffect"), -3, Style.ITALIC), "span, wrap para*2");
this.add(new StyledLabel(trans.get("generalprefs.lbl.languageEffect"), -3, Style.ITALIC), "span, wrap rel");
//// UI Theme
UITheme.Theme currentTheme = GUIUtil.getUITheme();
List<Named<UITheme.Theme>> themes = new ArrayList<>();
for (UITheme.Theme t : UITheme.Themes.values()) {
themes.add(new Named<>(t, t.getDisplayName()));
}
Collections.sort(themes);
final JComboBox<?> themesCombo = new JComboBox<>(themes.toArray());
for (int i = 0; i < themes.size(); i++) {
if (Utils.equals(currentTheme, themes.get(i).get())) {
themesCombo.setSelectedIndex(i);
}
}
this.add(new JLabel(trans.get("generalprefs.lbl.UITheme")), "gapright para");
this.add(themesCombo, "wrap, growx, sg combos");
//// Font size
this.add(new JLabel(trans.get("generalprefs.lbl.FontSize")), "gapright para");
final IntegerModel fontSizeModel = new IntegerModel(preferences, "UIFontSize", 5, 25);
final JSpinner fontSizeSpinner = new JSpinner(fontSizeModel.getSpinnerModel());
fontSizeSpinner.setEditor(new SpinnerEditor(fontSizeSpinner));
this.add(fontSizeSpinner, "growx, wrap");
//// You need to restart OpenRocket for the theme change to take effect.
final JLabel lblRestartORTheme = new JLabel();
lblRestartORTheme.setForeground(GUIUtil.getUITheme().getDarkWarningColor());
this.add(lblRestartORTheme, "spanx, wrap para*2, growx");
fontSizeSpinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (fontSizeModel.getValue() == currentFontSize) {
lblRestartORTheme.setText("");
return;
}
lblRestartORTheme.setText(trans.get("generalprefs.lbl.themeRestartOR"));
}
});
themesCombo.addActionListener(new ActionListener() {
@Override
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
Named<UITheme.Theme> selection = (Named<UITheme.Theme>) themesCombo.getSelectedItem();
if (selection == null) return;
UITheme.Theme t = selection.get();
if (t == currentTheme) {
lblRestartORTheme.setText("");
return;
}
preferences.setUITheme(t);
lblRestartORTheme.setText(trans.get("generalprefs.lbl.themeRestartOR"));
}
});
//// User-defined thrust curves:
this.add(new JLabel(trans.get("pref.dlg.lbl.User-definedthrust")), "spanx, wrap");
final JTextField field = new JTextField();
@ -180,8 +247,9 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
this.add(button, "wrap");
//// Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket.
DescriptionArea desc = new DescriptionArea(trans.get("pref.dlg.DescriptionArea.Adddirectories"), 3, -3, false);
desc.setBackground(getBackground());
DescriptionArea desc = new DescriptionArea(trans.get("pref.dlg.DescriptionArea.Adddirectories"), 3, -1.5f, false);
desc.setBackground(GUIUtil.getUITheme().getBackgroundColor());
desc.setForeground(GUIUtil.getUITheme().getTextColor());
this.add(desc, "spanx, growx, wrap 40lp");

View File

@ -23,6 +23,7 @@ import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.models.atmosphere.ExtendedISAModel;
import net.sf.openrocket.simulation.SimulationOptions;
import net.sf.openrocket.unit.UnitGroup;
@ -43,7 +44,7 @@ public class LaunchPreferencesPanel extends PreferencesPanel {
StyledLabel warning = new StyledLabel(String.format(
"<html>%s</html>", trans.get("pref.dlg.lbl.launchWarning")),
0.5f, StyledLabel.Style.BOLD);
warning.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
warning.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
warning.setToolTipText(trans.get("pref.dlg.lbl.launchWarning.ttip"));
add(warning, "spanx, growx 0, gapbottom para, wrap");

View File

@ -17,6 +17,7 @@ import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.simulation.RK4SimulationStepper;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.GeodeticComputationStrategy;
@ -24,7 +25,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
public class SimulationPreferencesPanel extends PreferencesPanel {
private static final long serialVersionUID = 7983195730016979888L;
/*
* private GeodeticComputationStrategy geodeticComputation =
* GeodeticComputationStrategy.SPHERICAL;
@ -41,7 +42,7 @@ public class SimulationPreferencesPanel extends PreferencesPanel {
confirmDelete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setAutoRunSimulations(confirmDelete.isSelected());
preferences.setConfirmSimDeletion(confirmDelete.isSelected());
}
});
this.add(confirmDelete, "wrap, growx, sg combos ");
@ -84,7 +85,7 @@ public class SimulationPreferencesPanel extends PreferencesPanel {
StyledLabel warning = new StyledLabel(String.format(
"<html>%s</html>", trans.get("pref.dlg.lbl.launchWarning")),
0, StyledLabel.Style.BOLD);
warning.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
warning.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
warning.setToolTipText(trans.get("pref.dlg.lbl.launchWarning.ttip"));
subsub.add(warning, "spanx, wrap para");

View File

@ -10,6 +10,7 @@ import com.jogamp.opengl.fixedfunc.GLLightingFunc;
import net.sf.openrocket.gui.figure3d.geometry.Geometry;
import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
@ -80,7 +81,7 @@ public class FigureRenderer extends RocketRenderer {
if (defaultColorCache.containsKey(c.getClass())) {
figureColor = defaultColorCache.get(c.getClass());
} else {
figureColor = Application.getPreferences().getDefaultColor(c.getClass());
figureColor = ((SwingPreferences) Application.getPreferences()).getDefaultColor(c.getClass());
defaultColorCache.put(c.getClass(), figureColor);
}
}

View File

@ -42,9 +42,9 @@ public class RealisticRenderer extends RocketRenderer {
gl.glLightModelfv(GL2ES1.GL_LIGHT_MODEL_AMBIENT, new float[] { 0, 0, 0 }, 0);
float amb = 0.3f;
float dif = 1.0f - amb;
float spc = 1.0f;
float amb = 0.4f;
float dif = 0.65f;
float spc = 0.65f;
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT, new float[] { amb, amb, amb, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_DIFFUSE, new float[] { dif, dif, dif, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR, new float[] { spc, spc, spc, 1 }, 0);

View File

@ -34,6 +34,7 @@ import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputAdapter;
import net.sf.openrocket.gui.util.GUIUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -64,7 +65,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(RocketFigure3d.class);
static {
//this allows the GL canvas and things like the motor selection
//drop down to z-order themselves.
@ -288,7 +289,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
gl.glClearColor(1, 1, 1, 1);
Color backgroundColor = GUIUtil.getUITheme().getBackgroundColor();
gl.glClearColor(backgroundColor.getRed()/255f, backgroundColor.getGreen()/255f,
backgroundColor.getBlue()/255f, backgroundColor.getAlpha()/255f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
setupView(gl, glu);
@ -315,8 +318,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
}
pickPoint = null;
gl.glClearColor(1, 1, 1, 1);
gl.glClearColor(backgroundColor.getRed()/255f, backgroundColor.getGreen()/255f,
backgroundColor.getBlue()/255f, backgroundColor.getAlpha()/255f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL.GL_MULTISAMPLE);

View File

@ -16,6 +16,8 @@ import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface;
import java.util.Collections;
public class FinRenderer {
private GLUtessellator tess = GLU.gluNewTess();
@ -96,12 +98,11 @@ public class FinRenderer {
GLU.gluTessBeginPolygon(tess, null);
GLU.gluTessBeginContour(tess);
gl.glNormal3f(0, 0, 1);
for (int i = tabPoints.length - 1; i >= 0; i--) {
Coordinate c = tabPoints[i];
double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(),
c.z + finSet.getThickness() / 2.0};
GLU.gluTessVertex(tess, p, 0, p);
}
for (Coordinate c : tabPoints) {
double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(),
c.z + finSet.getThickness() / 2.0};
GLU.gluTessVertex(tess, p, 0, p);
}
GLU.gluTessEndContour(tess);
GLU.gluTessEndPolygon(tess);
}
@ -125,7 +126,8 @@ public class FinRenderer {
GLU.gluTessBeginPolygon(tess, null);
GLU.gluTessBeginContour(tess);
gl.glNormal3f(0, 0, -1);
for (Coordinate c : tabPoints) {
for (int i = tabPoints.length - 1; i >= 0; i--) {
Coordinate c = tabPoints[i];
double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(),
c.z - finSet.getThickness() / 2.0};
GLU.gluTessVertex(tess, p, 0, p);
@ -163,7 +165,7 @@ public class FinRenderer {
if (!(finSet instanceof EllipticalFinSet))
gl.glShadeModel(GLLightingFunc.GL_FLAT);
gl.glBegin(GL.GL_TRIANGLE_STRIP);
for (int i = 0; i <= tabPoints.length; i++) {
for (int i = tabPoints.length; i >= 0; i--) {
Coordinate c = tabPoints[i % tabPoints.length];
// if ( i > 1 ){
Coordinate c2 = tabPoints[(i - 1 + tabPoints.length)

Some files were not shown because too many files have changed in this diff Show More