Merge branch 'unstable' into 3D-export
# Conflicts: # README.md # swing/src/net/sf/openrocket/gui/dialogs/AboutDialog.java
@ -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 (3D OBJ export, maintainer)
|
||||
- Sibo Van Gool (RASAero file format, 3D OBJ export, dark theme, maintainer)
|
||||
- Neil Weinstock (tester, icons, forum support)
|
||||
- H. Craig Miller (tester)
|
||||
|
||||
|
@ -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:
|
||||
@ -2025,6 +2042,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
|
||||
@ -2319,7 +2337,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
|
||||
|
@ -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 = .ستتغير اللغة في المرة التالية التي تعيد تشغيل أوبنروكت
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 2.9 KiB |
BIN
core/resources/pix/icons/cd-override-subcomponent_dark.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 405 B After Width: | Height: | Size: 405 B |
BIN
core/resources/pix/icons/cd-override_dark.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 790 B After Width: | Height: | Size: 790 B |
BIN
core/resources/pix/icons/cg-override-subcomponent_dark.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 306 B |
BIN
core/resources/pix/icons/cg-override_dark.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 345 B |
BIN
core/resources/pix/icons/mass-override-subcomponent_dark.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
BIN
core/resources/pix/icons/mass-override_dark.png
Executable file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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"));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -485,6 +485,11 @@ 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);
|
||||
|
||||
|
@ -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>();
|
||||
|
@ -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)) {
|
||||
|
@ -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 );
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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),
|
||||
@ -147,7 +147,7 @@ public class FlightEventsTest extends BaseTestCase {
|
||||
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)
|
||||
};
|
||||
|
@ -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>
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
@ -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"/>
|
||||
|
BIN
swing/lib/darklaf/darklaf-compatibility-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-core-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-iconset-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-macos-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-native-utils-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-platform-base-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-property-loader-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-theme-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-theme-spec-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-utils-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/darklaf-windows-3.0.3-SNAPSHOT.jar
Normal file
BIN
swing/lib/darklaf/jsvg-0.0.9.jar
Normal file
BIN
swing/lib/darklaf/swing-extensions-laf-support-0.1.3.jar
Normal file
BIN
swing/lib/darklaf/swing-extensions-visual-padding-0.1.3.jar
Normal 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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -22,7 +22,7 @@ public class Tester {
|
||||
BasicApplication baseApp = new BasicApplication();
|
||||
baseApp.initializeApplication();
|
||||
|
||||
GUIUtil.setBestLAF();
|
||||
GUIUtil.applyLAF();
|
||||
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"));
|
||||
|
@ -43,7 +43,7 @@ public class AboutDialog extends JDialog {
|
||||
"Daniel Williams (pod support, maintainer)<br>" +
|
||||
"Joe Pfeiffer (maintainer)<br>" +
|
||||
"Billy Olsen (maintainer)<br>" +
|
||||
"Sibo Van Gool (RASAero file format, 3D OBJ export, maintainer)<br>" +
|
||||
"Sibo Van Gool (RASAero file format, 3D OBJ export, dark theme, maintainer)<br>" +
|
||||
"Justin Hanney (maintainer)<br>" +
|
||||
"Neil Weinstock (tester, icons, forum support)<br>" +
|
||||
"H. Craig Miller (tester)<br><br>" +
|
||||
@ -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,7 +75,8 @@ 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>" +
|
||||
"Obj" + href("https://github.com/javagl/Obj", true, true) + "<br>" +
|
||||
"Darklaf (dark theme)" + href("https://github.com/weisJ/darklaf", true, true) + "<br>" +
|
||||
"Obj" + href("https://github.com/javagl/Obj", true, true) + "<br>" +
|
||||
"<br>" +
|
||||
"<b>OpenRocket gratefully acknowledges our use of the following databases:</b><br>" +
|
||||
"<br>" +
|
||||
|
@ -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");
|
||||
|
@ -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()))
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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");
|
||||
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -123,7 +123,7 @@ final class TransitionRenderer {
|
||||
private TransitionRenderer() {
|
||||
}
|
||||
|
||||
static final void drawTransition(final GL2 gl, final Transition tr,
|
||||
static void drawTransition(final GL2 gl, final Transition tr,
|
||||
final int slices, final int stacks, final double offsetRadius) {
|
||||
|
||||
double da, r, dzBase;
|
||||
@ -131,14 +131,16 @@ final class TransitionRenderer {
|
||||
int i;
|
||||
|
||||
da = 2.0f * Math.PI / slices;
|
||||
dzBase = (double) tr.getLength() / stacks;
|
||||
dzBase = tr.getLength() / stacks;
|
||||
|
||||
double ds = 1.0f / slices;
|
||||
|
||||
z = 0.0f;
|
||||
r = (double) tr.getForeRadius();
|
||||
while (z < tr.getLength()) {
|
||||
double t = z / tr.getLength();
|
||||
if (tr.getForeRadius() > tr.getAftRadius()) {
|
||||
t = 1 - t;
|
||||
}
|
||||
|
||||
double dz = t < 0.025 ? dzBase / 8.0 : dzBase;
|
||||
double zNext = Math.min(z + dz, tr.getLength());
|
||||
|
@ -371,9 +371,9 @@ public class PhotoFrame extends JFrame {
|
||||
|
||||
guiModule.startLoader();
|
||||
|
||||
// Set the best available look-and-feel
|
||||
log.info("Setting best LAF");
|
||||
GUIUtil.setBestLAF();
|
||||
// Set the look-and-feel
|
||||
log.info("Setting LAF");
|
||||
GUIUtil.applyLAF();
|
||||
|
||||
// Load defaults
|
||||
((SwingPreferences) Application.getPreferences()).loadDefaultUnits();
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.sf.openrocket.gui.figureelements;
|
||||
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
@ -16,7 +18,7 @@ public class CGCaret extends Caret {
|
||||
private static final float RADIUS = 7;
|
||||
|
||||
private static Area caret = null;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new CGCaret at the specified coordinates.
|
||||
*/
|
||||
@ -56,7 +58,7 @@ public class CGCaret extends Caret {
|
||||
*/
|
||||
@Override
|
||||
protected Color getColor() {
|
||||
return Color.BLUE;
|
||||
return GUIUtil.getUITheme().getCGColor();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.sf.openrocket.gui.figureelements;
|
||||
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
@ -15,7 +17,7 @@ public class CPCaret extends Caret {
|
||||
private static final float RADIUS = 7;
|
||||
|
||||
private static Area caret = null;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new CPCaret at the specified coordinates.
|
||||
*/
|
||||
@ -51,6 +53,6 @@ public class CPCaret extends Caret {
|
||||
*/
|
||||
@Override
|
||||
protected Color getColor() {
|
||||
return Color.RED;
|
||||
return GUIUtil.getUITheme().getCPColor();
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package net.sf.openrocket.gui.figureelements;
|
||||
import static net.sf.openrocket.util.Chars.ALPHA;
|
||||
import static net.sf.openrocket.util.Chars.THETA;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
@ -11,6 +10,7 @@ import java.awt.Rectangle;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.logging.Warning;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
@ -176,7 +176,7 @@ public class RocketInfo implements FigureElement {
|
||||
|
||||
GlyphVector massLineWithoutMotors = createText(massTextWithoutMotors);
|
||||
|
||||
g2.setColor(Color.BLACK);
|
||||
g2.setColor(GUIUtil.getUITheme().getTextColor());
|
||||
|
||||
g2.drawGlyphVector(name, x1, y1);
|
||||
g2.drawGlyphVector(lengthLine, x1, y1+line);
|
||||
@ -234,7 +234,7 @@ public class RocketInfo implements FigureElement {
|
||||
unitWidth = unitWidth + spaceWidth;
|
||||
stabUnitWidth = stabUnitWidth + spaceWidth;
|
||||
|
||||
g2.setColor(Color.BLACK);
|
||||
g2.setColor(GUIUtil.getUITheme().getTextColor());
|
||||
|
||||
// Draw the stability, CG & CP values (and units)
|
||||
g2.drawGlyphVector(stabValue, (float)(x2-stabRect.getWidth()), y1);
|
||||
@ -261,7 +261,7 @@ public class RocketInfo implements FigureElement {
|
||||
atPos = (float)(x2 - atTextRect.getWidth());
|
||||
}
|
||||
|
||||
g2.setColor(Color.GRAY);
|
||||
g2.setColor(GUIUtil.getUITheme().getDimTextColor());
|
||||
g2.drawGlyphVector(atText, atPos, y1 + 3*line);
|
||||
|
||||
}
|
||||
@ -411,7 +411,7 @@ public class RocketInfo implements FigureElement {
|
||||
|
||||
|
||||
float y = y2 - line * (texts.length-1);
|
||||
g2.setColor(Color.RED);
|
||||
g2.setColor(GUIUtil.getUITheme().getWarningColor());
|
||||
|
||||
for (GlyphVector v: texts) {
|
||||
Rectangle2D rect = v.getVisualBounds();
|
||||
@ -427,7 +427,7 @@ public class RocketInfo implements FigureElement {
|
||||
if (calculatingData) {
|
||||
//// Calculating...
|
||||
GlyphVector calculating = createText(trans.get("RocketInfo.Calculating"));
|
||||
g2.setColor(Color.BLACK);
|
||||
g2.setColor(GUIUtil.getUITheme().getTextColor());
|
||||
g2.drawGlyphVector(calculating, x1, (float)(y2-height));
|
||||
}
|
||||
}
|
||||
@ -485,11 +485,10 @@ public class RocketInfo implements FigureElement {
|
||||
width += 5;
|
||||
|
||||
if (!calculatingData)
|
||||
g2.setColor(new Color(0,0,127));
|
||||
g2.setColor(GUIUtil.getUITheme().getFlightDataTextActiveColor());
|
||||
else
|
||||
g2.setColor(new Color(0,0,127,127));
|
||||
g2.setColor(GUIUtil.getUITheme().getFlightDataTextInactiveColor());
|
||||
|
||||
|
||||
g2.drawGlyphVector(apogee, (float)x1, (float)(y2-2*line));
|
||||
g2.drawGlyphVector(maxVelocity, (float)x1, (float)(y2-line));
|
||||
g2.drawGlyphVector(maxAcceleration, (float)x1, (float)(y2));
|
||||
@ -502,7 +501,7 @@ public class RocketInfo implements FigureElement {
|
||||
}
|
||||
|
||||
private synchronized void updateFontSizes() {
|
||||
float size = Application.getPreferences().getRocketInfoFontSize();
|
||||
float size = ((SwingPreferences) Application.getPreferences()).getRocketInfoFontSize();
|
||||
// No change necessary as the font is the same size, just use the existing version
|
||||
if (font.getSize2D() == size) {
|
||||
return;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.gui.help.tours;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -11,6 +12,7 @@ import java.util.Map;
|
||||
|
||||
import javax.swing.text.html.StyleSheet;
|
||||
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
|
||||
/**
|
||||
@ -130,6 +132,9 @@ public class SlideSetManager {
|
||||
try {
|
||||
|
||||
StyleSheet ss = new StyleSheet();
|
||||
Color textColor = GUIUtil.getUITheme().getTextColor();
|
||||
ss.addRule(String.format("p { color: rgb(%d, %d, %d, %d)",
|
||||
textColor.getRed(), textColor.getGreen(), textColor.getBlue(), textColor.getAlpha()));
|
||||
InputStreamReader reader = new InputStreamReader(in, "UTF-8");
|
||||
ss.loadRules(reader, null);
|
||||
return ss;
|
||||
|
@ -12,6 +12,7 @@ import javax.swing.text.html.HTMLDocument;
|
||||
import javax.swing.text.html.StyleSheet;
|
||||
|
||||
import net.sf.openrocket.gui.components.ImageDisplayComponent;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
|
||||
/**
|
||||
* Component that displays a single slide, with the image on top and
|
||||
@ -28,7 +29,7 @@ public class SlideShowComponent extends JSplitPane {
|
||||
|
||||
private final ImageDisplayComponent imageDisplay;
|
||||
private final JEditorPane textPane;
|
||||
|
||||
|
||||
|
||||
public SlideShowComponent() {
|
||||
super(VERTICAL_SPLIT);
|
||||
@ -44,6 +45,7 @@ public class SlideShowComponent extends JSplitPane {
|
||||
textPane.setPreferredSize(new Dimension(WIDTH, HEIGHT_TEXT));
|
||||
|
||||
JScrollPane scrollPanel = new JScrollPane(textPane);
|
||||
textPane.setBorder(GUIUtil.getUITheme().getBorder());
|
||||
this.setRightComponent(scrollPanel);
|
||||
|
||||
this.setResizeWeight(((double) HEIGHT_IMAGE) / (HEIGHT_IMAGE + HEIGHT_TEXT));
|
||||
|
@ -579,12 +579,12 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
editMenu.addSeparator();
|
||||
|
||||
JMenu subMenu = new JMenu(trans.get("RocketActions.Select"));
|
||||
editMenu.add(subMenu);
|
||||
JMenu selectSubMenu = new JMenu(trans.get("RocketActions.Select"));
|
||||
editMenu.add(selectSubMenu);
|
||||
item = new JMenuItem(actions.getSelectSameColorAction());
|
||||
subMenu.add(item);
|
||||
selectSubMenu.add(item);
|
||||
item = new JMenuItem(actions.getDeselectAllAction());
|
||||
subMenu.add(item);
|
||||
selectSubMenu.add(item);
|
||||
|
||||
editMenu.addSeparator();
|
||||
|
||||
|
@ -4,6 +4,7 @@ package net.sf.openrocket.gui.main;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -209,7 +210,7 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
for (col = 0; col < buttons[row].length; col++) {
|
||||
buttons[row][col].setMinimumSize(d);
|
||||
buttons[row][col].setPreferredSize(d);
|
||||
buttons[row][col].getComponent(0).validate();
|
||||
buttons[row][col].validate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,29 +316,32 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
* The label may contain "\n" as a newline.
|
||||
*/
|
||||
public ComponentButton(String text, Icon enabled, Icon disabled) {
|
||||
super();
|
||||
setLayout(new MigLayout("fill, flowy, insets 0, gap 0", "", ""));
|
||||
|
||||
add(new JLabel(), "push, sizegroup spacing");
|
||||
|
||||
// Add Icon
|
||||
if (enabled != null) {
|
||||
JLabel label = new JLabel(enabled);
|
||||
if (disabled != null)
|
||||
label.setDisabledIcon(disabled);
|
||||
add(label, "growx");
|
||||
super(text, enabled);
|
||||
|
||||
setVerticalTextPosition(SwingConstants.BOTTOM); // this will put the text below the icon
|
||||
setHorizontalTextPosition(SwingConstants.CENTER); // this will center the text horizontally beneath the icon
|
||||
//setIconTextGap(0); // this is optional, it sets the gap between the icon and the text
|
||||
|
||||
// set the disabled icon if it is not null
|
||||
if (disabled != null) {
|
||||
setDisabledIcon(disabled);
|
||||
}
|
||||
|
||||
// Add labels
|
||||
String[] l = text.split("\n");
|
||||
for (int i = 0; i < l.length; i++) {
|
||||
add(new StyledLabel(l[i], SwingConstants.CENTER, -2.0f), "growx");
|
||||
|
||||
setHorizontalAlignment(SwingConstants.CENTER); // this will center the button itself in its parent component
|
||||
|
||||
// if you have multiline text, you could use html to format it
|
||||
if (text != null && text.contains("\n")) {
|
||||
text = "<html>" + text.replace("\n", "<br>") + "</html>";
|
||||
setText(text);
|
||||
}
|
||||
|
||||
// Initialize enabled status
|
||||
valueChanged(null);
|
||||
|
||||
// Attach a tree selection listener if selection model is not null
|
||||
if (selectionModel != null) {
|
||||
selectionModel.addTreeSelectionListener(this);
|
||||
}
|
||||
|
||||
add(new JLabel(), "push, sizegroup spacing");
|
||||
|
||||
valueChanged(null); // Update enabled status
|
||||
selectionModel.addTreeSelectionListener(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,13 +61,13 @@ public class DesignPanel extends JSplitPane {
|
||||
|
||||
// Remove JTree key events that interfere with menu accelerators
|
||||
InputMap im = SwingUtilities.getUIInputMap(tree, JComponent.WHEN_FOCUSED);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, SHORTCUT_KEY), null);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, SHORTCUT_KEY), null);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, SHORTCUT_KEY), null);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, SHORTCUT_KEY), null);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_KEY), null);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY), null);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, SHORTCUT_KEY), null);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, SHORTCUT_KEY), "none");
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, SHORTCUT_KEY), "none");
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, SHORTCUT_KEY), "none");
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, SHORTCUT_KEY), "none");
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_KEY), "none");
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY), "none");
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, SHORTCUT_KEY), "none");
|
||||
|
||||
// Highlight all child components of a stage/rocket/podset when it is selected
|
||||
tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
|
||||
@ -174,6 +174,7 @@ public class DesignPanel extends JSplitPane {
|
||||
|
||||
// Place tree inside scroll pane
|
||||
JScrollPane scroll = new JScrollPane(tree);
|
||||
tree.setBorder(GUIUtil.getUITheme().getBorder());
|
||||
panel.add(scroll, "spany, wmin 140px, grow, wrap");
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@ package net.sf.openrocket.gui.main;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.Serial;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@ -13,15 +14,13 @@ import java.util.List;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
|
||||
import net.sf.openrocket.gui.dialogs.ScaleDialog;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
@ -34,7 +33,6 @@ import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.startup.Preferences;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.Pair;
|
||||
import org.slf4j.Logger;
|
||||
@ -59,6 +57,7 @@ public class RocketActions {
|
||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
|
||||
public static final KeyStroke EDIT_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_E,
|
||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
|
||||
public static final KeyStroke DELETE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
|
||||
|
||||
private final OpenRocketDocument document;
|
||||
private final Rocket rocket;
|
||||
@ -67,8 +66,6 @@ public class RocketActions {
|
||||
private final SimulationPanel simulationPanel;
|
||||
|
||||
|
||||
private final RocketAction deleteComponentAction;
|
||||
private final RocketAction deleteSimulationAction;
|
||||
private final RocketAction deleteAction;
|
||||
private final RocketAction cutAction;
|
||||
private final RocketAction copyAction;
|
||||
@ -94,8 +91,6 @@ public class RocketActions {
|
||||
|
||||
// Add action also to updateActions()
|
||||
this.deleteAction = new DeleteAction();
|
||||
this.deleteComponentAction = new DeleteComponentAction();
|
||||
this.deleteSimulationAction = new DeleteSimulationAction();
|
||||
this.cutAction = new CutAction();
|
||||
this.copyAction = new CopyAction();
|
||||
this.pasteAction = new PasteAction();
|
||||
@ -107,10 +102,15 @@ public class RocketActions {
|
||||
this.moveUpAction = new MoveUpAction();
|
||||
this.moveDownAction = new MoveDownAction();
|
||||
|
||||
OpenRocketClipboard.addClipboardListener(this.pasteAction);
|
||||
OpenRocketClipboard.addClipboardListener(new ClipboardListener() {
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
updateActions();
|
||||
}
|
||||
});
|
||||
updateActions();
|
||||
|
||||
// Update all actions when tree selection or rocket changes
|
||||
// Update all actions when tree selection, simulation selection or rocket changes
|
||||
|
||||
selectionModel.addDocumentSelectionListener(new DocumentSelectionListener() {
|
||||
@Override
|
||||
@ -118,6 +118,12 @@ public class RocketActions {
|
||||
updateActions();
|
||||
}
|
||||
});
|
||||
simulationPanel.addSimulationTableListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
updateActions();
|
||||
}
|
||||
});
|
||||
document.getRocket().addComponentChangeListener(new ComponentChangeListener() {
|
||||
@Override
|
||||
public void componentChanged(ComponentChangeEvent e) {
|
||||
@ -130,12 +136,13 @@ public class RocketActions {
|
||||
* Update the state of all of the actions.
|
||||
*/
|
||||
private void updateActions() {
|
||||
deleteAction.clipboardChanged();
|
||||
simulationPanel.updateActions();
|
||||
editAction.clipboardChanged();
|
||||
cutAction.clipboardChanged();
|
||||
copyAction.clipboardChanged();
|
||||
pasteAction.clipboardChanged();
|
||||
deleteAction.clipboardChanged();
|
||||
duplicateAction.clipboardChanged();
|
||||
editAction.clipboardChanged();
|
||||
selectSameColorAction.clipboardChanged();
|
||||
deselectAllAction.clipboardChanged();
|
||||
scaleAction.clipboardChanged();
|
||||
@ -143,16 +150,8 @@ public class RocketActions {
|
||||
moveDownAction.clipboardChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Action getDeleteComponentAction() {
|
||||
return deleteAction;
|
||||
}
|
||||
|
||||
public Action getDeleteSimulationAction() {
|
||||
return deleteAction;
|
||||
}
|
||||
|
||||
public Action getDeleteAction() {
|
||||
return deleteAction;
|
||||
@ -313,7 +312,7 @@ public class RocketActions {
|
||||
}
|
||||
|
||||
private boolean isCopyable(List<RocketComponent> components) {
|
||||
if (components == null || components.size() == 0) return false;
|
||||
if (components == null || components.isEmpty()) return false;
|
||||
for (RocketComponent component : components) {
|
||||
if (!isCopyable(component)) return false;
|
||||
}
|
||||
@ -409,43 +408,14 @@ public class RocketActions {
|
||||
|
||||
private boolean isSimulationSelected() {
|
||||
Simulation[] selection = selectionModel.getSelectedSimulations();
|
||||
return (selection != null && selection.length > 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean verifyDeleteSimulation() {
|
||||
boolean verify = Application.getPreferences().getBoolean(Preferences.CONFIRM_DELETE_SIMULATION, true);
|
||||
if (verify) {
|
||||
JPanel panel = new JPanel(new MigLayout());
|
||||
//// Do not ask me again
|
||||
JCheckBox dontAsk = new JCheckBox(trans.get("RocketActions.checkbox.Donotaskmeagain"));
|
||||
panel.add(dontAsk,"wrap");
|
||||
//// You can change the default operation in the preferences.
|
||||
panel.add(new StyledLabel(trans.get("RocketActions.lbl.Youcanchangedefop"),-2));
|
||||
|
||||
int ret = JOptionPane.showConfirmDialog(
|
||||
parentFrame,
|
||||
new Object[] {
|
||||
//// Delete the selected simulations?
|
||||
trans.get("RocketActions.showConfirmDialog.lbl1"),
|
||||
//// <html><i>This operation cannot be undone.</i>
|
||||
trans.get("RocketActions.showConfirmDialog.lbl2"),
|
||||
"",
|
||||
panel },
|
||||
//// Delete simulations
|
||||
trans.get("RocketActions.showConfirmDialog.title"),
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
if (ret != JOptionPane.OK_OPTION)
|
||||
return false;
|
||||
|
||||
if (dontAsk.isSelected()) {
|
||||
Application.getPreferences().putBoolean(Preferences.CONFIRM_DELETE_SIMULATION, false);
|
||||
if (selection != null && selection.length > 0) {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
if (components != null && !components.isEmpty()) {
|
||||
throw new IllegalStateException("Both simulation and component selected");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -517,130 +487,60 @@ public class RocketActions {
|
||||
public abstract void clipboardChanged();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Action that deletes the selected component.
|
||||
* Action to edit the currently selected component.
|
||||
*/
|
||||
private class DeleteComponentAction extends RocketAction {
|
||||
private class EditAction extends RocketAction {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DeleteComponentAction() {
|
||||
//// Delete
|
||||
this.putValue(NAME, trans.get("RocketActions.DelCompAct.Delete"));
|
||||
//// Delete the selected component.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelCompAct.ttip.Delete"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
|
||||
// this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<RocketComponent> components = new ArrayList<>(selectionModel.getSelectedComponents());
|
||||
if (components.size() == 0) return;
|
||||
components.sort(Comparator.comparing(c -> c.getParent().getChildPosition(c)));
|
||||
|
||||
if (components.size() == 1) {
|
||||
document.addUndoPosition("Delete " + components.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Delete components");
|
||||
}
|
||||
|
||||
for (RocketComponent component : components) {
|
||||
deleteComponent(component);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteComponent(RocketComponent component) {
|
||||
if (isDeletable(component)) {
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
try {
|
||||
component.getRocket().removeComponentChangeListener(ComponentConfigDialog.getDialog());
|
||||
|
||||
delete(component);
|
||||
} catch (IllegalStateException ignored) { }
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action that deletes the selected component.
|
||||
*/
|
||||
private class DeleteSimulationAction extends RocketAction {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DeleteSimulationAction() {
|
||||
//// Delete
|
||||
this.putValue(NAME, trans.get("RocketActions.DelSimuAct.Delete"));
|
||||
//// Delete the selected simulation.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelSimuAct.ttip.Delete"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
|
||||
// this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
if (sims.length > 0) {
|
||||
if (verifyDeleteSimulation()) {
|
||||
for (Simulation s: sims) {
|
||||
document.removeSimulation(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isSimulationSelected());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action that deletes the selected component.
|
||||
*/
|
||||
private class DeleteAction extends RocketAction {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DeleteAction() {
|
||||
//// Delete
|
||||
this.putValue(NAME, trans.get("RocketActions.DelAct.Delete"));
|
||||
//// Delete the selected component or simulation.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelAct.ttip.Delete"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
|
||||
public EditAction() {
|
||||
//// Edit
|
||||
this.putValue(NAME, trans.get("RocketActions.EditAct.Edit"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_E);
|
||||
this.putValue(ACCELERATOR_KEY, EDIT_KEY_STROKE);
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.EditAct.ttip.Edit"));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_EDIT);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (isSimulationSelected()) {
|
||||
deleteSimulationAction.actionPerformed(e);
|
||||
simulationPanel.getEditSimulationAction().actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
} else {
|
||||
deleteComponentAction.actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
editComponents();
|
||||
// I wouldn't switch to the design tab here, because the user may be editing in the rocket view window
|
||||
}
|
||||
}
|
||||
|
||||
private void editComponents() {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
|
||||
if (components == null || components.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ComponentConfigDialog.isDialogVisible())
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
RocketComponent component = components.get(0);
|
||||
component.clearConfigListeners();
|
||||
if (components.size() > 1) {
|
||||
for (int i = 1; i < components.size(); i++) {
|
||||
RocketComponent listener = components.get(i);
|
||||
listener.clearConfigListeners(); // Make sure all the listeners are cleared (should not be possible, but just in case)
|
||||
component.addConfigListener(listener);
|
||||
}
|
||||
}
|
||||
ComponentConfigDialog.showDialog(parentFrame, document, component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()) ||
|
||||
isSimulationSelected());
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
this.setEnabled(!components.isEmpty() || simulationPanel.getEditSimulationAction().isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,14 +550,14 @@ public class RocketActions {
|
||||
* Action the cuts the selected component (copies to clipboard and deletes).
|
||||
*/
|
||||
private class CutAction extends RocketAction {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CutAction() {
|
||||
//// Cut
|
||||
this.putValue(NAME, trans.get("RocketActions.CutAction.Cut"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_T);
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_T); // Use the 't' in Cut as mnemonic
|
||||
this.putValue(ACCELERATOR_KEY, CUT_KEY_STROKE);
|
||||
//// Cut this component or simulation to the clipboard and remove from this design
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CutAction.ttip.Cut"));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_CUT);
|
||||
clipboardChanged();
|
||||
@ -665,49 +565,49 @@ public class RocketActions {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (isSimulationSelected()) {
|
||||
simulationPanel.getCutSimulationAction().actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
} else {
|
||||
cutComponents();
|
||||
}
|
||||
}
|
||||
|
||||
private void cutComponents() {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
if (components.size() > 0) {
|
||||
if (!components.isEmpty()) {
|
||||
components = new ArrayList<>(components);
|
||||
fillInMissingSelections(components);
|
||||
|
||||
components.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
|
||||
}
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
|
||||
if (isDeletable(components) && isCopyable(components)) {
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
if (components.size() == 1) {
|
||||
document.addUndoPosition("Cut " + components.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Cut components");
|
||||
}
|
||||
|
||||
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
|
||||
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
|
||||
|
||||
OpenRocketClipboard.setClipboard(copiedComponents);
|
||||
delete(components);
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
} else if (isSimulationSelected()) {
|
||||
|
||||
Simulation[] simsCopy = new Simulation[sims.length];
|
||||
for (int i=0; i < sims.length; i++) {
|
||||
simsCopy[i] = sims[i].copy();
|
||||
}
|
||||
OpenRocketClipboard.setClipboard(simsCopy);
|
||||
|
||||
for (Simulation s: sims) {
|
||||
document.removeSimulation(s);
|
||||
}
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
if (!(isDeletable(components) && isCopyable(components))) {
|
||||
return;
|
||||
}
|
||||
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
if (components.size() == 1) {
|
||||
document.addUndoPosition("Cut " + components.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Cut components");
|
||||
}
|
||||
|
||||
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
|
||||
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
|
||||
|
||||
OpenRocketClipboard.setClipboard(copiedComponents);
|
||||
delete(components);
|
||||
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
this.setEnabled((isDeletable(components) && isCopyable(components)) || isSimulationSelected());
|
||||
this.setEnabled((isDeletable(components) && isCopyable(components)) ||
|
||||
simulationPanel.getCutSimulationAction().isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
@ -722,46 +622,47 @@ public class RocketActions {
|
||||
public CopyAction() {
|
||||
//// Copy
|
||||
this.putValue(NAME, trans.get("RocketActions.CopyAct.Copy"));
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CopyAct.ttip.Copy"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_C);
|
||||
this.putValue(ACCELERATOR_KEY, COPY_KEY_STROKE);
|
||||
//// Copy this component (and subcomponents) to the clipboard.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CopyAct.ttip.Copy"));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_COPY);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (isSimulationSelected()) {
|
||||
simulationPanel.getCopySimulationAction().actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
} else {
|
||||
copyComponents();
|
||||
}
|
||||
}
|
||||
|
||||
private void copyComponents() {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
if (components.size() > 0) {
|
||||
if (!components.isEmpty()) {
|
||||
components = new ArrayList<>(components);
|
||||
fillInMissingSelections(components);
|
||||
|
||||
components.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
|
||||
}
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
|
||||
if (isCopyable(components)) {
|
||||
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
|
||||
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
|
||||
|
||||
OpenRocketClipboard.setClipboard(copiedComponents);
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
} else if (sims != null && sims.length > 0) {
|
||||
Simulation[] simsCopy = new Simulation[sims.length];
|
||||
for (int i=0; i < sims.length; i++) {
|
||||
simsCopy[i] = sims[i].copy();
|
||||
}
|
||||
|
||||
OpenRocketClipboard.setClipboard(simsCopy);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
if (!isCopyable(components)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
|
||||
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
|
||||
|
||||
OpenRocketClipboard.setClipboard(copiedComponents);
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
|
||||
isSimulationSelected());
|
||||
simulationPanel.getCopySimulationAction().isEnabled());
|
||||
}
|
||||
|
||||
}
|
||||
@ -779,9 +680,8 @@ public class RocketActions {
|
||||
public PasteAction() {
|
||||
//// Paste
|
||||
this.putValue(NAME, trans.get("RocketActions.PasteAct.Paste"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_P);
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_V);
|
||||
this.putValue(ACCELERATOR_KEY, PASTE_KEY_STROKE);
|
||||
//// Paste the component or simulation on the clipboard to the design.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.PasteAct.ttip.Paste"));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_PASTE);
|
||||
clipboardChanged();
|
||||
@ -789,76 +689,67 @@ public class RocketActions {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<RocketComponent> components = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
|
||||
Simulation[] sims = OpenRocketClipboard.getClipboardSimulations();
|
||||
|
||||
if (components.size() > 0) {
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
List<RocketComponent> pasted = new LinkedList<>();
|
||||
for (RocketComponent component : components) {
|
||||
pasted.add(component.copy());
|
||||
}
|
||||
|
||||
List<Pair<RocketComponent, Integer>> positions = getPastePositions(pasted);
|
||||
|
||||
if (pasted.size() == 1) {
|
||||
document.addUndoPosition("Paste " + pasted.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Paste components");
|
||||
}
|
||||
|
||||
List<RocketComponent> successfullyPasted = new LinkedList<>();
|
||||
for (int i = 0; i < pasted.size(); i++) {
|
||||
if (positions.get(i) == null) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
String.format(trans.get("RocketActions.PasteAct.invalidPosition.msg"),
|
||||
pasted.get(i).getComponentName()),
|
||||
trans.get("RocketActions.PasteAct.invalidPosition.title"), JOptionPane.WARNING_MESSAGE);
|
||||
} else {
|
||||
RocketComponent parent = positions.get(i).getU();
|
||||
RocketComponent child = pasted.get(i);
|
||||
if (parent != null && parent.isCompatible(child)) {
|
||||
parent.addChild(child, positions.get(i).getV());
|
||||
successfullyPasted.add(pasted.get(i));
|
||||
} else {
|
||||
log.warn("Pasted component {} is not compatible with {}", child, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectionModel.setSelectedComponents(successfullyPasted);
|
||||
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
|
||||
} else if (sims != null) {
|
||||
|
||||
ArrayList<Simulation> copySims = new ArrayList<Simulation>();
|
||||
|
||||
for (Simulation s: sims) {
|
||||
Simulation copy = s.duplicateSimulation(rocket);
|
||||
String name = copy.getName();
|
||||
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
|
||||
copy.setName(document.getNextSimulationName());
|
||||
}
|
||||
document.addSimulation(copy);
|
||||
copySims.add(copy);
|
||||
}
|
||||
selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
|
||||
|
||||
if (isSimulationSelected()) {
|
||||
simulationPanel.getPasteSimulationAction().actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
} else {
|
||||
pasteComponents();
|
||||
}
|
||||
}
|
||||
|
||||
private void pasteComponents() {
|
||||
List<RocketComponent> components = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
|
||||
|
||||
if (components.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
List<RocketComponent> pasted = new LinkedList<>();
|
||||
for (RocketComponent component : components) {
|
||||
pasted.add(component.copy());
|
||||
}
|
||||
|
||||
List<Pair<RocketComponent, Integer>> positions = getPastePositions(pasted);
|
||||
|
||||
if (pasted.size() == 1) {
|
||||
document.addUndoPosition("Paste " + pasted.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Paste components");
|
||||
}
|
||||
|
||||
List<RocketComponent> successfullyPasted = new LinkedList<>();
|
||||
for (int i = 0; i < pasted.size(); i++) {
|
||||
if (positions.get(i) == null) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
String.format(trans.get("RocketActions.PasteAct.invalidPosition.msg"),
|
||||
pasted.get(i).getComponentName()),
|
||||
trans.get("RocketActions.PasteAct.invalidPosition.title"), JOptionPane.WARNING_MESSAGE);
|
||||
} else {
|
||||
RocketComponent parent = positions.get(i).getU();
|
||||
RocketComponent child = pasted.get(i);
|
||||
if (parent != null && parent.isCompatible(child)) {
|
||||
parent.addChild(child, positions.get(i).getV());
|
||||
successfullyPasted.add(pasted.get(i));
|
||||
} else {
|
||||
log.warn("Pasted component {} is not compatible with {}", child, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectionModel.setSelectedComponents(successfullyPasted);
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(
|
||||
(getPastePositions(OpenRocketClipboard.getClipboardComponents()).size() > 0) ||
|
||||
(OpenRocketClipboard.getClipboardSimulations() != null));
|
||||
this.setEnabled(!getPastePositions(OpenRocketClipboard.getClipboardComponents()).isEmpty() ||
|
||||
simulationPanel.getPasteSimulationAction().isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action that duplicates the selected component.
|
||||
*/
|
||||
@ -870,7 +761,6 @@ public class RocketActions {
|
||||
this.putValue(NAME, trans.get("RocketActions.DuplicateAct.Duplicate"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
|
||||
this.putValue(ACCELERATOR_KEY, DUPLICATE_KEY_STROKE);
|
||||
//// Copy this component (and subcomponents) to the clipboard.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DuplicateAct.ttip.Duplicate"));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DUPLICATE);
|
||||
clipboardChanged();
|
||||
@ -878,6 +768,15 @@ public class RocketActions {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (isSimulationSelected()) {
|
||||
simulationPanel.getDuplicateSimulationAction().actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
} else {
|
||||
duplicateComponents();
|
||||
}
|
||||
}
|
||||
|
||||
private void duplicateComponents() {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
List<RocketComponent> topComponents = new LinkedList<>(); // Components without a parent component in <components>
|
||||
if (components.size() > 0) {
|
||||
@ -892,136 +791,130 @@ public class RocketActions {
|
||||
topComponents.add(c);
|
||||
}
|
||||
}
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
|
||||
if (isCopyable(components)) {
|
||||
if (ComponentConfigDialog.isDialogVisible())
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
|
||||
OpenRocketClipboard.setClipboard(copiedComponents);
|
||||
copiedComponents = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
|
||||
|
||||
List<RocketComponent> duplicateComponents = new LinkedList<>();
|
||||
for (RocketComponent component : copiedComponents) {
|
||||
duplicateComponents.add(component.copy());
|
||||
}
|
||||
|
||||
List<Pair<RocketComponent, Integer>> positions = new LinkedList<>();
|
||||
for (RocketComponent component : duplicateComponents) {
|
||||
Pair<RocketComponent, Integer> pos;
|
||||
if (RocketComponent.listContainsParent(duplicateComponents, component)) {
|
||||
pos = getPastePosition(component, component.getParent());
|
||||
} else {
|
||||
int compIdx = duplicateComponents.indexOf(component);
|
||||
RocketComponent pasteParent = topComponents.get(compIdx).getParent();
|
||||
pos = getPastePosition(component, pasteParent);
|
||||
}
|
||||
positions.add(pos);
|
||||
}
|
||||
|
||||
if (duplicateComponents.size() == 1) {
|
||||
document.addUndoPosition("Duplicate " + duplicateComponents.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Duplicate components");
|
||||
}
|
||||
|
||||
Collections.reverse(duplicateComponents);
|
||||
Collections.reverse(positions);
|
||||
|
||||
for (int i = 0; i < duplicateComponents.size(); i++) {
|
||||
positions.get(i).getU().addChild(duplicateComponents.get(i), positions.get(i).getV());
|
||||
}
|
||||
|
||||
selectionModel.setSelectedComponents(duplicateComponents);
|
||||
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
} else if (sims != null && sims.length > 0) {
|
||||
ArrayList<Simulation> copySims = new ArrayList<Simulation>();
|
||||
|
||||
// TODO: the undoing doesn't do anything...
|
||||
if (sims.length == 1) {
|
||||
document.addUndoPosition("Duplicate " + sims[0].getName());
|
||||
} else {
|
||||
document.addUndoPosition("Duplicate simulations");
|
||||
}
|
||||
|
||||
for (Simulation s: sims) {
|
||||
Simulation copy = s.duplicateSimulation(rocket);
|
||||
String name = copy.getName();
|
||||
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
|
||||
copy.setName(document.getNextSimulationName());
|
||||
}
|
||||
document.addSimulation(copy);
|
||||
copySims.add(copy);
|
||||
}
|
||||
|
||||
selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
|
||||
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
if (!isCopyable(components)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ComponentConfigDialog.isDialogVisible())
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
|
||||
OpenRocketClipboard.setClipboard(copiedComponents);
|
||||
copiedComponents = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
|
||||
|
||||
List<RocketComponent> duplicateComponents = new LinkedList<>();
|
||||
for (RocketComponent component : copiedComponents) {
|
||||
duplicateComponents.add(component.copy());
|
||||
}
|
||||
|
||||
List<Pair<RocketComponent, Integer>> positions = new LinkedList<>();
|
||||
for (RocketComponent component : duplicateComponents) {
|
||||
Pair<RocketComponent, Integer> pos;
|
||||
if (RocketComponent.listContainsParent(duplicateComponents, component)) {
|
||||
pos = getPastePosition(component, component.getParent());
|
||||
} else {
|
||||
int compIdx = duplicateComponents.indexOf(component);
|
||||
RocketComponent pasteParent = topComponents.get(compIdx).getParent();
|
||||
pos = getPastePosition(component, pasteParent);
|
||||
}
|
||||
positions.add(pos);
|
||||
}
|
||||
|
||||
if (duplicateComponents.size() == 1) {
|
||||
document.addUndoPosition("Duplicate " + duplicateComponents.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Duplicate components");
|
||||
}
|
||||
|
||||
Collections.reverse(duplicateComponents);
|
||||
Collections.reverse(positions);
|
||||
|
||||
for (int i = 0; i < duplicateComponents.size(); i++) {
|
||||
positions.get(i).getU().addChild(duplicateComponents.get(i), positions.get(i).getV());
|
||||
}
|
||||
|
||||
selectionModel.setSelectedComponents(duplicateComponents);
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
|
||||
isSimulationSelected());
|
||||
simulationPanel.getDuplicateSimulationAction().isEnabled());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action to edit the currently selected component.
|
||||
* Action that deletes the selected component.
|
||||
*/
|
||||
private class EditAction extends RocketAction {
|
||||
private class DeleteAction extends RocketAction {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public EditAction() {
|
||||
//// Edit
|
||||
this.putValue(NAME, trans.get("RocketActions.EditAct.Edit"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_E);
|
||||
this.putValue(ACCELERATOR_KEY, EDIT_KEY_STROKE);
|
||||
//// Edit the selected component.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.EditAct.ttip.Edit"));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_EDIT);
|
||||
public DeleteAction() {
|
||||
//// Delete
|
||||
this.putValue(NAME, trans.get("RocketActions.DelAct.Delete"));
|
||||
//// Delete the selected component or simulation.
|
||||
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelAct.ttip.Delete"));
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_DELETE);
|
||||
this.putValue(ACCELERATOR_KEY, DELETE_KEY_STROKE);
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
if (isSimulationSelected()) {
|
||||
simulationPanel.getDeleteSimulationAction().actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
} else {
|
||||
deleteComponents();
|
||||
}
|
||||
}
|
||||
|
||||
if (components.size() > 0) {
|
||||
if (ComponentConfigDialog.isDialogVisible())
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
private void deleteComponents() {
|
||||
List<RocketComponent> components = new ArrayList<>(selectionModel.getSelectedComponents());
|
||||
if (components.size() == 0) return;
|
||||
components.sort(Comparator.comparing(c -> c.getParent().getChildPosition(c)));
|
||||
|
||||
RocketComponent component = components.get(0);
|
||||
component.clearConfigListeners();
|
||||
if (components.size() > 1) {
|
||||
for (int i = 1; i < components.size(); i++) {
|
||||
RocketComponent listener = components.get(i);
|
||||
listener.clearConfigListeners(); // Make sure all the listeners are cleared (should not be possible, but just in case)
|
||||
component.addConfigListener(listener);
|
||||
}
|
||||
}
|
||||
ComponentConfigDialog.showDialog(parentFrame, document, component);
|
||||
} else if (sims != null && sims.length > 0 && (simulationPanel != null)) {
|
||||
simulationPanel.editSimulation();
|
||||
if (components.size() == 1) {
|
||||
document.addUndoPosition("Delete " + components.get(0).getComponentName());
|
||||
} else {
|
||||
document.addUndoPosition("Delete components");
|
||||
}
|
||||
|
||||
for (RocketComponent component : components) {
|
||||
deleteComponent(component);
|
||||
}
|
||||
|
||||
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
|
||||
}
|
||||
|
||||
private void deleteComponent(RocketComponent component) {
|
||||
if (isDeletable(component)) {
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
try {
|
||||
component.getRocket().removeComponentChangeListener(ComponentConfigDialog.getDialog());
|
||||
|
||||
delete(component);
|
||||
} catch (IllegalStateException ignored) { }
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
|
||||
this.setEnabled(components.size() > 0 || isSimulationSelected());
|
||||
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()) ||
|
||||
simulationPanel.getDeleteSimulationAction().isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action to select all components with the same color as the currently selected component.
|
||||
*/
|
||||
@ -1038,7 +931,7 @@ public class RocketActions {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<RocketComponent> components = selectionModel.getSelectedComponents();
|
||||
if (components.size() == 0) {
|
||||
if (components.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|