diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6a3e68da15877a8e092804b0413c24b39bda11c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/.DS_Store \ No newline at end of file diff --git a/PlayWall/.classpath b/PlayWall/.classpath index 3107c79175ae90bdbddcbf9cc435f7afa27caef9..0fab9fc5708a0167218f5f25d61ea3bbddf835ac 100644 --- a/PlayWall/.classpath +++ b/PlayWall/.classpath @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry excluding="icon.icns|icon.ico|de/tobias/playpad/viewcontroller/settings/midi/action/CartActionViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/CartSimpleViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/CustomSettingsViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/MidiKeySettingsViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/PageSettingsViewController.java|de/tobias/playpad/viewcontroller/pad/PadDragHandler.java|de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java|de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java|de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java|de/tobias/playpad/viewcontroller/PadSettingsViewController.java|de/tobias/playpad/viewcontroller/PresetsViewController.java|de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java|de/tobias/playpad/viewcontroller/cell/TimeModeCell.java" kind="src" path="src"/> - <classpathentry excluding="**/.DS_Store|de/tobias/playpad/assets/files/dialogDnD.pxm" kind="src" path="assets"/> + <classpathentry excluding="**/.DS_Store|**/.gitignore|de/tobias/playpad/viewcontroller/PadSettingsViewController.java|de/tobias/playpad/viewcontroller/PresetsViewController.java|de/tobias/playpad/viewcontroller/cell/TimeModeCell.java|de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java|de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java|de/tobias/playpad/viewcontroller/pad/PadDragHandler.java|de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java|de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java|de/tobias/playpad/viewcontroller/settings/midi/action/CartActionViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/CartSimpleViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/CustomSettingsViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/MidiKeySettingsViewController.java|de/tobias/playpad/viewcontroller/settings/midi/action/PageSettingsViewController.java|icon.icns|icon.ico" kind="src" path="src"/> + <classpathentry excluding="**/.gitignor|de/tobias/playpad/assets/files/dialogDnD.pxm" kind="src" path="assets"/> <classpathentry kind="src" path="test"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ControlFx"/> @@ -13,5 +13,6 @@ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/TinySound"/> <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/JLayer"/> <classpathentry combineaccessrules="false" kind="src" path="/PlayWallCore"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/PlayWall/.gitignore b/PlayWall/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..da4193319979d9d53ae0e9ea1084606098ad02e0 --- /dev/null +++ b/PlayWall/.gitignore @@ -0,0 +1,7 @@ +/bin/ +/.DS_Store +/launchpad-mk2-programmers-reference-guide_0.pdf +/launchpad-programmers-reference.pdf +/build/ +/dist/ +/test/ diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/project/openDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/openDialog.fxml index b0aae277d16ff7e84307867b50aa13b027b8ca8f..f5055c1aab8683e19be3be2e3face7f8b276b2f4 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/dialog/project/openDialog.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/project/openDialog.fxml @@ -53,6 +53,7 @@ </VBox> </children> </HBox> + <Label text="%project.label.export" wrapText="true" /> <Separator prefWidth="200.0" /> <HBox alignment="TOP_RIGHT" spacing="14.0"> <children> diff --git a/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties index 054e2ce5b5f25c3fd4ee0c2f390d9523d0dd0aa3..3be3160a627b688da59853b720e73829af98dea4 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties +++ b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties @@ -5,9 +5,10 @@ Standard.File.Save=Gespeichert Standard.Copy={} - Kopie Standard.Time.Seconds={} sec +Standard.Time.Volume={} % # File - Filter -File.Filter.ZIP=Archivedatei +File.Filter.ZIP=Archive File.Filter.Media=Medien File.Filter.Preset=Vorlagen @@ -23,7 +24,7 @@ UI.Window.Changelog.Title=Was ist neu? UI.Window.Settings.Title=Einstellungen - {} UI.Window.PadSettings.Title=Kachel Einstellungen - {} | {} UI.Dialog.DragAndDrop.Title=Drag and Drop -UI.Dialog.ProjectExport.Title=Project exportieren +UI.Dialog.ProjectExport.Title=Projekt exportieren UI.Dialog.ErrorSummary.Title=Fehlerbericht UI.Dialog.NewProfile.Title=Neues Profil UI.Dialog.NewProject.Title=Neues Projekt @@ -45,6 +46,7 @@ UI.Layout.Classic.Theme.LIGHT=Hell # UI - Window - Main UI.Window.Main.CloseRequest=Es wird gerade noch Musik abgespielt. M�chten Sie PlayWall trotzdem beenden? +UI.Window.Main.SaveRequest=M�chten Sie die �nderungen speichern? UI.Window.Main.PageButton = Seite {} # UI - Dialog - Launch @@ -53,6 +55,7 @@ UI.Dialog.Launch.Info={} - {} # UI Window - Settings UI.Window.Settings.Gen.Title=Allgemein UI.Window.Settings.Gen.CacheSize=Gr��e: {}B +UI.Window.Settings.Gen.Wait=Die �nderungen werden �bernommen. Das kann einen kurzen Moment dauern. UI.Window.Settings.Mapping.Title=Mapping UI.Window.Settings.Midi.Title=Midi UI.Window.Settings.Layout.Title=Layout @@ -72,14 +75,14 @@ UI.Dialog.NewProfile.Content=Geben Sie einen Namen f UI.Dialog.NewProject.Content=Geben Sie einen Namen f�r das neue Projekt ein. # UI - Dialog - Import -UI.Dialog.Import.ReplaceProfile.Content=Es gibt bereits eine Profil mit dem Namen {}. Bitte nennen Sie das Profil um. -UI.Dialog.Import.ReplaceProfile.Skip=Import �berspringen +UI.Dialog.Import.ReplaceProfile.Content=Es gibt bereits eine Profil mit dem Namen {}. Bitte geben Sie einen anderen Namen ein. +UI.Dialog.Import.ReplaceProfile.Skip=Profil nicht importieren UI.Dialog.Import.ReplaceProfile.Rename=Umbenennen -UI.Dialog.Import.ReplaceProfile.ReplaceContent=Es gibt bereits ein Profil mit dem Namen {}.\nBitte geben Sie einen neuen Namen ein. -UI.Dialog.Import.ReplaceProject.ReplaceContent=Es gibt bereits ein Projekt mit dem Namen {}.\nBitte geben Sie einen neuen Namen ein. +UI.Dialog.Import.ReplaceProfile.ReplaceContent=Es gibt bereits ein Profil mit dem Namen {}.\nBitte geben Sie einen anderen Namen ein. +UI.Dialog.Import.ReplaceProject.ReplaceContent=Es gibt bereits ein Projekt mit dem Namen {}.\nBitte geben Sie einen anderen Namen ein. UI.Dialog.Import.ReplaceMedia.Content=M�chten Sie die Mediendaten von diesem Projekt importieren? -UI.Dialog.Import.ReplaceMedia.Copy=Kopieren -UI.Dialog.Import.ReplaceMedia.Skip=�berspringen +UI.Dialog.Import.ReplaceMedia.Copy=Ja +UI.Dialog.Import.ReplaceMedia.Skip=Nein # UI - Dialog - ProjectManager UI.Dialog.ProjectManager.Delete.Content=M�chten Sie das Projekt {} wirklich l�schen? @@ -92,7 +95,7 @@ UI.Dialog.Info.Header= UI.Dialog.Info.Content=Version: {} (Build: {})\nAutor: {}\n\nDieses Programm nutzt Bibliotheken. ControlsFX (8.40.10), dom4j (1.6.1), snakeyaml (1.11), guava (15.0), gagawa (1.0.1), TinySound (1.1.1), JLayer (1.0.1), JSPF (1.0.2), json-smart (1.2). \nBesonderen Dank an die Betatester: Stefan, Robert. # UI - Dialog - Feedback -UI.Dialog.Feedback.Content=Der Fehlerbericht wird �bermittelt. Bitte haben Sie etwas Geduld. Ihre Nummer wird am Ende angezeigt. +UI.Dialog.Feedback.Content=Der Fehlerbericht wird �bermittelt. Dies dauert einen kleinen Moment. Bitte haben Sie etwas Geduld. Ihre Nummer wird am Ende angezeigt. # UI - Placeholder UI.Placeholder.Project=Keine Projekte vorhanden @@ -102,7 +105,7 @@ UI.Placeholder.Updates=Es sind keine Updates verf UI.Placeholder.ErrorSummary=Keine Fehler # Info - MIDI -Info.Midi.Device.Connected=Midi Ger�t erkannt ({}) +Info.Midi.Device.Connected=Midi-Ger�t erkannt ({}) # Info - Settings Info.Settings.ResetWarning=Die Einstellungen wurden zur�ckgesetzt. @@ -112,8 +115,8 @@ Info.Settings.CacheDelete={} Dateien wurden gel Info.Print.Header={} - Seite {} # Error - Standard -Error.Standard.Gen=Es ist ein Fehler aufgetreten, bitte versuchen Sie es sp�ter noch einmal. ({}) -Error.Standard.NameInUse=Der Name {} kann nicht gew�hlt werden, da er bereits vergeben ist. +Error.Standard.Gen=Es ist ein Fehler aufgetreten. Bitte versuchen Sie es sp�ter noch einmal. ({}) +Error.Standard.NameInUse=Der Name {} ist bereits vorhanden. Bitte w�hlen Sie einen anderen Namen. # Error - Settings Error.Settings.CacheSize=Die Gr��e des Cache kann nicht bestimmt werden. ({}) @@ -121,7 +124,7 @@ Error.Settings.CacheClear=Beim L # Error - Profile Error.Profile.Create=Das Profil konnte aufgrund eines Fehlers nicht erstellt werden. ({}) -Error.Profile.NotFound=Das Profil konnte nicht geladen werden, da die Datein fehlen. W�hle eine neues Profile und �ffne das Projekt erneut. ({}) +Error.Profile.NotFound=Das Profil konnte nicht geladen werden, da die ben�tigten Dateien fehlen. W�hlen Sie eine anderes Profile aus und �ffnen Sie das Projekt erneut. ({}) Error.Profile.Save=Das Profil konnte aufgrund eines Fehlers nicht gespeichert werden. ({}) Error.Profile.Delete=Das Projekt konnte nicht gel�scht werden. ({}) Error.Profile.SmallScreen=Ihr Bildschirm ist f�r die gew�hlte Anzahl der Kacheln zu klein. (Maximal: {}x{}) @@ -141,13 +144,14 @@ Error.Project.Export=Das Projekt {} konnte nicht exportiert werden. ({}) # Error - Pad - Enum Error.Pad.FILE_NOT_FOUND=Die Datei {} konnte nicht gefunden werden. -Error.Pad.FILE_FORMAT_NOT_SUPPORTED=Die Datei {} ist inkompatibel. -Error.Pad.CONVERT_NOT_SUPPORTED=Die Datei {} kann nicht umgewandelt werden. (W�hlen Sie ein anderes Format zum Import aus) -Error.Pad.UNKOWN=Es ist ein Unbekannter Fehler aufgetreten. {} +Error.Pad.FILE_FORMAT_NOT_SUPPORTED=Die Datei {} ist nicht kompatibel. +Error.Pad.CONVERT_NOT_SUPPORTED=Die Datei {} kann nicht umgewandelt werden. W�hlen Sie ein anderes Format zum Import aus. +Error.Pad.UNKOWN=Es ist ein unbekannter Fehler aufgetreten. {} Error.Pad.UNKOWN_CONTENT_TYPE=Die Kachel {} konnte nicht geladen werden. # Error - L�sung Error.Fix.NewFile=Neue Datei w�hlen +Error.Fix.Delete=Kachel l�schen # Error - Midi Error.Midi.Settings.Unkown=F�r die ausgew�hlte Seite sind keine Midi Einstellungen aktiv. In Einstellungen -> Midi -> Presets kann dies angepasst werden. @@ -166,6 +170,7 @@ Mapper.Keyboard.toString=Tastatur {} Mapper.Midi.toString=Midi {} # Info - Mapper +# Das ist Midi und Tastatur gemeinsam Info.Mapper.PressKey=Dr�cken Sie eine Taste auf dem Ger�t. # UI - Window - PadSettings @@ -183,7 +188,7 @@ Action.Page.Name=Seiten Action.Navigate.Name=Navigation #Content -Content.Empyt=Leer +Content.Empyt= Content.Audio.Name=Audio # NavigationType - Enum @@ -197,7 +202,7 @@ CartAction.Mode.PLAY_HOLD=Play/Hold #UI - Dialog -AutoUpdate UI.Dialog.AutoUpdate.Header=Updates -UI.Dialog.AutoUpdate.Content=Es gibt Updates. Weitere Informationen finden Sie in den Update Einstellungen. Wollen Sie die Updates jetzt installieren? +UI.Dialog.AutoUpdate.Content=Es sind Updates verf�gbar. M�chten Sie diese jetzt installieren? (Weitere Informationen finden Sie in den Update Einstellungen.) # Error - Layout Error.Layout.Load=Es gab einen Fehler beim Laden des Layouts ({}) @@ -208,7 +213,7 @@ UI.Window.Settings.Updates.CurrentVersion={} (Build {}) UI.Window.Settings.Updates.NewVersion={} (Build {}) # Error - Update - Downlaod -Error.Update.Download=Es ist ein Fehler beim Downloaden des Updates aufgetreten. Bitte versuchen Sie es sp�ter noch einmal. ({}) +Error.Update.Download=Es ist ein Fehler beim Herunterladen des Updates aufgetreten. Bitte versuchen Sie es sp�ter erneut. ({}) # Layout Layout.Modern.Name=Modern @@ -221,4 +226,8 @@ Trigger.Volume.Name=Lautst # TriggerPoint - Enum TriggerPoint.START=Start -TriggerPoint.EOF_STOP=Ende/Stop \ No newline at end of file +TriggerPoint.EOF_STOP=Ende/Stop + +# Drag and Drop Mode +DnDMode.Replace=Ersetzen +DnDMode.Move=Tauschen \ No newline at end of file diff --git a/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties b/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties index ae2924f4608d192e0c581a1b3e39abf905ed8773..96235bf6de5b7347a56ecff96b82d100a3fa9efa 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties +++ b/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties @@ -31,18 +31,24 @@ settings.gen.label.rows=Anzahl der Reihen: settings.gen.label.additional=Erweitert: settings.gen.label.liveMode=Live Modus: settings.gen.checkbox.liveMode=Aktivieren +settings.gen.label.liveMode.settings=Einstellungen �ndern: +settings.gen.label.liveMode.media=Mediadateien �ndern: +settings.gen.label.liveMode.dragPads=Kacheln verschieben: +settings.gen.label.liveMode.pageChange=Seite wechseln: +settings.gen.radio.liveMode.enable=Deaktivieren +settings.gen.radio.liveMode.disable=Erlauben settings.gen.label.liveModeInfo=Der Live Modus verhindet ungewollte Aktionen w�hrend der Wiedergabe einer Kachel. settings.gen.warning.button.reset=Hinweismeldungen zur�cksetzen settings.gen.cache.label=Cachespeicher: settings.gen.cache.button.choose=W�hlen settings.gen.cache.button.reset=Cache leeren -settings.gen.cache.label.info=Wenn Sie als Audioausgabetyp "Java Audiostream" gew�hlt haben, werden jegliche MP3-Dateien in eine WAV-Dateien umgewandelt. Diese wird dann in den oben angegebenen Ordner abgelegt. Sollen Sie viele Dateien aus Ihrem Projekt gel�scht haben, ist es sinnvoll, den Cache zu leeren, um die ben�tigten Speicher zu verringern. Ben�tigte Dateien werden automatisch neu umgewandelt, falls sie nicht (mehr) existieren. +settings.gen.cache.label.info=Wenn Sie als Audioausgabetyp "Java Audiostream" gew�hlt haben, werden s�mtliche MP3-Dateien in eine WAV-Dateien umgewandelt. Diese wird dann in den oben angegebenen Ordner abgelegt. Sollten Sie viele Dateien aus Ihrem Projekt gel�scht haben, k�nnen Sie den Cache leeren, um die ben�tigten Speicherplatz zu verringern. Ben�tigte Dateien werden automatisch neu umgewandelt, falls sie nicht (mehr) existieren. settings.mapping.label.mapping=Mapping: settings.mapping.button.edit=Bearbeiten... settings.midi.button.activate=Aktivieren -settings.midi.label.device=Midi Ger�te: +settings.midi.label.device=Midi-Ger�te: settings.layout.label.type=Layout Type: @@ -51,15 +57,15 @@ settings.player.label.fade=Ein-/Ausblenden: settings.player.label.fadeIn=Einblenden (in s): settings.player.label.fadeOut=Ausblenden (in s): settings.player.label.startIn=... nach Start -settings.player.label.pauseIn=... nach Pause -settings.player.label.pauseOut=... vor Pause +settings.player.label.pauseIn=... bei Pause +settings.player.label.pauseOut=... bei Pause settings.player.label.stopOut=... vor Stop (nicht Ende) -settings.player.label.fadeInfo=Wird beim Ein- oder Ausblenden die Dauer auf 0 gesetzt, so findet keine �berblendung statt. Wenn der Sound zu Ende ist, findet kein Ausblenden statt. +settings.player.label.fadeInfo=Wird beim Ein- oder Ausblenden die Dauer auf 0 gesetzt, so findet keine �berblendung statt. Wenn die Datei zu Ende ist, findet kein Ausblenden statt. settings.player.label.timeDisplay=Zeitanzeige: settings.update.label.current=Installierte Version: settings.update.label.new=Aktuelle Version: -settings.update.label.search=Nach updates suchen: +settings.update.label.search=Nach Updates suchen: settings.update.label.available=Verf�gbare Updates: settings.update.button.search=Jetzt suchen settings.update.button.install=Aktualisieren und neu starten @@ -101,7 +107,7 @@ padSettings.player.label.warning=Warnhinweise: padSettings.player.label.fade=Ein-/Ausblenden: padSettings.layout.label.custom=Eigenes Layout: -padSettings.layout.checkbox.custom=aktiviert +padSettings.layout.checkbox.custom=Aktiviert project.button.finish=�ffnen project.button.cancel=Abbrechen @@ -111,15 +117,16 @@ project.button.new=Neues Projekt project.button.duplicate=Duplizieren project.button.export=Exportieren... project.button.import=Importieren.. +project.label.export=Wenn Sie ein ge�ffnetes Projekt exportieren, wird es zuerst gespeichert. project.label.name=Name: project.label.fileSize=Dateigr��e project.label.lastModified=Zuletzt bearbeitet: project.export.label.headline=Projekt exportieren: -project.export.checkbox.profile=Zus�tzlich das Profil mit exportieren? -project.export.checkbox.media=Zus�tzlich die Medieninhalte exportieren? +project.export.checkbox.profile=Aktuell verwendetes Profil exportieren +project.export.checkbox.media=Aktuell verwendete Medieninhalte exportieren project.export.button.cancel=Abbrechen -project.export.button.save=Speichern... +project.export.button.save=Exportieren #Project import ist in der _de.properties launch.button.import=Projekt importieren @@ -179,7 +186,8 @@ mappingPreset.button.import=Importieren... mappingPreset.button.delete=L�schen mappingPreset.button.finish=Fertig mappingPreset.label.mapping=Mapping: -mappingPreset.label.name: Name: +mappingPreset.label.name=Name: +#da war noch ein Fehler drin, habe ich korrigiert (urspr�nglich: mappingPreset.label.name: Name:) errorSummary.label.headline=Fehlerzusammenfassung: errorSummary.column.cart=Kachel @@ -187,10 +195,13 @@ errorSummary.column.des=Fehlerbeschreibung errorSummary.column.solution=L�sung errorSummary.button.close=Schlie�en -tinysound.label.soundcard=Sound Karte: +tinysound.label.soundcard=Soundkarte: triggertime.label.time=Zeit vom Trigger: (Sek) carttrigger.label.action=Aktion f�r Kacheln: carttrigger.label.carts=Kacheln: -carttrigger.checkbox.all=Alle (au�er diese) +carttrigger.checkbox.all=Alle, au�er diese + +volumetrigger.label.volume=Lautst�rke: +volumetrigger.label.duration=Fade Dauer: \ No newline at end of file diff --git a/PlayWall/assets/de/tobias/playpad/assets/modern_style.css b/PlayWall/assets/de/tobias/playpad/assets/modern_style.css index 8c1ff6afa671324e61247d11ffb1072ad84891d0..e6696ef97cc54d85301cd95b4ee53c8d2789b095 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/modern_style.css +++ b/PlayWall/assets/de/tobias/playpad/assets/modern_style.css @@ -91,6 +91,17 @@ -fx-border-radius: 10px; } +.pad-button:selected { + -fx-background-color: transparent; + -fx-border-width: 1px; + -fx-border-color: black; + -fx-border-radius: 10px; +} + +.font-icon:selected { + -fx-text-fill: red; +} + .fonticon { -fx-text-fill: white; -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 4, 0.1, 1, 1); @@ -132,3 +143,7 @@ .volume-item { -fx-text-fill: white !important; } + +.progress-indicator .percentage { + -fx-fill: white; +} \ No newline at end of file diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml index 65407383ec6125fd235602d2e35b4814394689fd..1019034cadcd369e709a0a0091e34f3b7b181c7d 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml @@ -13,6 +13,7 @@ <KeyCodeCombination alt="UP" code="N" control="UP" meta="UP" shift="UP" shortcut="DOWN" /> </accelerator> </MenuItem> + <Menu fx:id="recentOpenMenu" mnemonicParsing="false" text="%main.menuitem.recentFiles" /> <MenuItem mnemonicParsing="false" onAction="#openDocumentHandler" text="%main.menuitem.project"> <accelerator> <KeyCodeCombination alt="UP" code="O" control="UP" meta="UP" shift="UP" shortcut="DOWN" /> @@ -23,7 +24,6 @@ <KeyCodeCombination alt="UP" code="S" control="UP" meta="UP" shift="UP" shortcut="DOWN" /> </accelerator> </MenuItem> - <Menu fx:id="recentOpenMenu" mnemonicParsing="false" text="%main.menuitem.recentFiles" /> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem fx:id="profileMenu" mnemonicParsing="false" onAction="#profileMenuHandler" text="%main.menuitem.profile" /> <SeparatorMenuItem mnemonicParsing="false" /> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainToolbarView.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainToolbarView.fxml index 6688f5fbdf89a9bfd687e8d0c64c1f09825ca457..38c491f3c86f75ba41c1599a33c1f35317b49427 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainToolbarView.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainToolbarView.fxml @@ -10,6 +10,7 @@ <HBox fx:id="toolbarHBox" alignment="CENTER_LEFT" maxWidth="1.7976931348623157E308" prefHeight="28.0" prefWidth="586.0" spacing="14.0"> <children> <HBox fx:id="pageHBox" alignment="CENTER_LEFT" spacing="14.0" HBox.hgrow="ALWAYS" /> + <HBox fx:id="iconHbox" alignment="CENTER" spacing="14.0" /> <HBox alignment="CENTER" spacing="7.0" HBox.hgrow="NEVER"> <children> <Label fx:id="volumeDownLabel"> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/generalTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/generalTab.fxml index 0e7c0a04dfb157dc027271d81c6708ebd787d6fe..c37bccfea43073122df709a2f0ec317b880e795f 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/option/generalTab.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/generalTab.fxml @@ -5,66 +5,111 @@ <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> -<VBox prefWidth="587.0" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> - <children> - <Label text="%settings.gen.label.view" underline="true" /> - <HBox spacing="14.0"> +<ScrollPane fitToWidth="true" prefHeight="775.0" prefWidth="590.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <content> + <VBox spacing="14.0"> <children> - <Label alignment="BASELINE_RIGHT" layoutX="21.0" layoutY="40.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.pages" /> - <TextField fx:id="pageCountTextField" prefWidth="50.0" /> + <Label text="%settings.gen.label.view" underline="true" /> + <HBox spacing="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" layoutX="21.0" layoutY="40.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.pages" /> + <TextField fx:id="pageCountTextField" prefWidth="50.0" /> + </children> + </HBox> + <HBox spacing="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" layoutX="20.0" layoutY="68.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.columns" /> + <TextField fx:id="columnTextField" prefWidth="50.0" /> + </children> + </HBox> + <HBox spacing="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" layoutX="18.0" layoutY="96.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.rows" /> + <TextField fx:id="rowTextField" prefWidth="50.0" /> + </children> + </HBox> + <Separator prefHeight="2.0" prefWidth="600.0" /> + <Label text="%settings.gen.label.additional" underline="true" /> + <HBox spacing="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" maxWidth="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.liveMode" /> + <CheckBox fx:id="liveModeCheckBox" layoutX="30.0" layoutY="269.0" mnemonicParsing="false" text="%settings.gen.checkbox.liveMode" AnchorPane.leftAnchor="30.0" AnchorPane.topAnchor="269.0" /> + </children> + </HBox> + <HBox spacing="14.0"> + <children> + <Label prefWidth="150.0" text="%settings.gen.label.liveMode.pageChange" /> + <RadioButton fx:id="pageEnable" mnemonicParsing="false" prefWidth="125.0" text="%settings.gen.radio.liveMode.enable" /> + <RadioButton fx:id="pageDisable" mnemonicParsing="false" prefWidth="100.0" text="%settings.gen.radio.liveMode.disable" /> + </children> + <VBox.margin> + <Insets left="164.0" /> + </VBox.margin> + </HBox> + <HBox spacing="14.0"> + <children> + <Label prefWidth="150.0" text="%settings.gen.label.liveMode.dragPads" /> + <RadioButton fx:id="dragEnable" mnemonicParsing="false" prefWidth="125.0" text="%settings.gen.radio.liveMode.enable" /> + <RadioButton fx:id="dragDisable" mnemonicParsing="false" prefWidth="100.0" text="%settings.gen.radio.liveMode.disable" /> + </children> + <VBox.margin> + <Insets left="164.0" /> + </VBox.margin> + </HBox> + <HBox spacing="14.0"> + <VBox.margin> + <Insets left="164.0" /> + </VBox.margin> + <children> + <Label prefWidth="150.0" text="%settings.gen.label.liveMode.media" /> + <RadioButton fx:id="fileEnable" mnemonicParsing="false" prefWidth="125.0" text="%settings.gen.radio.liveMode.enable" /> + <RadioButton fx:id="fileDisable" mnemonicParsing="false" prefWidth="100.0" text="%settings.gen.radio.liveMode.disable" /> + </children> + </HBox> + <HBox spacing="14.0"> + <VBox.margin> + <Insets left="164.0" /> + </VBox.margin> + <children> + <Label prefWidth="150.0" text="%settings.gen.label.liveMode.settings" /> + <RadioButton fx:id="settingsEnable" mnemonicParsing="false" prefWidth="125.0" text="%settings.gen.radio.liveMode.enable" /> + <RadioButton fx:id="settingsDisable" mnemonicParsing="false" prefWidth="100.0" text="%settings.gen.radio.liveMode.disable" /> + </children> + </HBox> + <Label text="%settings.gen.label.liveModeInfo" wrapText="true"> + <VBox.margin> + <Insets left="164.0" /> + </VBox.margin> + </Label> + <HBox spacing="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.cache.label" /> + <TextField fx:id="cacheTextField" promptText="C:\Users\Max\Cache" HBox.hgrow="ALWAYS" /> + <Button mnemonicParsing="false" onAction="#cacheChooseHandler" text="%settings.gen.cache.button.choose" /> + </children> + </HBox> + <HBox alignment="CENTER_LEFT" spacing="14.0"> + <children> + <Label prefWidth="150.0" /> + <Button mnemonicParsing="false" onAction="#cacheResetButtonHandler" text="%settings.gen.cache.button.reset" /> + <Label fx:id="cacheSizeLabel" text="Label" /> + </children> + </HBox> + <Label text="%settings.gen.cache.label.info" wrapText="true"> + <VBox.margin> + <Insets left="164.0" /> + </VBox.margin> + </Label> + <Separator prefWidth="200.0" /> + <Button alignment="TOP_LEFT" mnemonicParsing="false" onAction="#resetDialogs" text="%settings.gen.warning.button.reset"> + <VBox.margin> + <Insets left="164.0" /> + </VBox.margin> + </Button> </children> - </HBox> - <HBox spacing="14.0"> - <children> - <Label alignment="BASELINE_RIGHT" layoutX="20.0" layoutY="68.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.columns" /> - <TextField fx:id="columnTextField" prefWidth="50.0" /> - </children> - </HBox> - <HBox spacing="14.0"> - <children> - <Label alignment="BASELINE_RIGHT" layoutX="18.0" layoutY="96.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.rows" /> - <TextField fx:id="rowTextField" prefWidth="50.0" /> - </children> - </HBox> - <Separator prefHeight="2.0" prefWidth="600.0" /> - <Label text="%settings.gen.label.additional" underline="true" /> - <HBox spacing="14.0"> - <children> - <Label alignment="BASELINE_RIGHT" maxWidth="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.liveMode" /> - <CheckBox fx:id="liveModeCheckBox" layoutX="30.0" layoutY="269.0" mnemonicParsing="false" text="%settings.gen.checkbox.liveMode" AnchorPane.leftAnchor="30.0" AnchorPane.topAnchor="269.0" /> - </children> - </HBox> - <Label text="%settings.gen.label.liveModeInfo" wrapText="true"> - <VBox.margin> - <Insets left="164.0" /> - </VBox.margin> - </Label> - <HBox spacing="14.0"> - <children> - <Label alignment="BASELINE_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.cache.label" /> - <TextField fx:id="cacheTextField" promptText="C:\Users\Max\Cache" HBox.hgrow="ALWAYS" /> - <Button mnemonicParsing="false" onAction="#cacheChooseHandler" text="%settings.gen.cache.button.choose" /> - </children> - </HBox> - <HBox alignment="CENTER_LEFT" spacing="14.0"> - <children> - <Label prefWidth="150.0" /> - <Button mnemonicParsing="false" onAction="#cacheResetButtonHandler" text="%settings.gen.cache.button.reset" /> - <Label fx:id="cacheSizeLabel" text="Label" /> - </children> - </HBox> - <Label text="%settings.gen.cache.label.info" wrapText="true"> - <VBox.margin> - <Insets left="164.0" /> - </VBox.margin> - </Label> - <Separator prefWidth="200.0" /> - <Button alignment="TOP_LEFT" mnemonicParsing="false" onAction="#resetDialogs" text="%settings.gen.warning.button.reset"> - <VBox.margin> - <Insets left="164.0" /> - </VBox.margin></Button> - </children> - <padding> - <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> - </padding> -</VBox> + <padding> + <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> + </padding> + </VBox> + </content> +</ScrollPane> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/volumeTrigger.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/volumeTrigger.fxml new file mode 100644 index 0000000000000000000000000000000000000000..2220b9e84060a84249d23cdae13a9ae6fd2aab0e --- /dev/null +++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/volumeTrigger.fxml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.*?> +<?import java.lang.*?> +<?import javafx.scene.layout.*?> + +<VBox maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <HBox spacing="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" prefWidth="150.0" text="%volumetrigger.label.volume" /> + <Slider fx:id="volumeSlider" blockIncrement="5.0" majorTickUnit="20.0" prefWidth="100.0" showTickLabels="true" showTickMarks="true" value="50.0" HBox.hgrow="ALWAYS" /> + <Label fx:id="volumeLabel" prefWidth="50.0" text="Label" /> + </children> + </HBox> + <HBox spacing="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%volumetrigger.label.duration" /> + <Slider fx:id="durationSlider" blockIncrement="5.0" majorTickUnit="1.0" max="5.0" minorTickCount="1" prefWidth="100.0" showTickLabels="true" showTickMarks="true" value="2.5" HBox.hgrow="ALWAYS" /> + <Label fx:id="durationLabel" prefWidth="50.0" text="Label" /> + </children> + </HBox> + </children> +</VBox> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/triggerTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/triggerTab.fxml index e015d3a7d7ebfd570af1fe9fc500975d52ce28a5..1283490c1355ec6fa846f458c89509a1eed9e6b1 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/triggerTab.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/triggerTab.fxml @@ -7,7 +7,7 @@ <HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> - <TreeView fx:id="treeView" showRoot="false" /> + <TreeView fx:id="treeView" prefWidth="150.0" showRoot="false" /> <VBox fx:id="contentView" minWidth="100.0" HBox.hgrow="ALWAYS"> <HBox.margin> <Insets left="14.0" right="14.0" top="14.0" /> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/playerTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/playerTab.fxml index 9c906697b32ec661415ee0eb9ce42c57d78873a9..c20941bec1301df874b09cb48d9495bc4559439a 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/option/playerTab.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/playerTab.fxml @@ -7,11 +7,11 @@ <VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> - <Label text="%settings.player.label.warning" underline="true" /> - <VBox fx:id="warningFeedbackContainer" minHeight="25.0" /> - <Separator prefWidth="200.0" /> <Label text="%settings.player.label.fade" underline="true" /> <VBox fx:id="fadeContainer" minHeight="20.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" /> + <Separator prefWidth="200.0" /> + <Label text="%settings.player.label.warning" underline="true" /> + <VBox fx:id="warningFeedbackContainer" minHeight="25.0" /> <Separator layoutY="91.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" /> <HBox alignment="CENTER_LEFT" layoutX="14.0" layoutY="105.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0"> <children> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/settingsView.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/settingsView.fxml index 23efae52a75f75d6b931db277299917bba3eea67..ae588532a3627c823b73a00fd9eeeb581c04f678 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/option/settingsView.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/settingsView.fxml @@ -9,5 +9,6 @@ <children> <TabPane fx:id="tabPane" prefHeight="348.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="52.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> <Button fx:id="finishButton" layoutX="508.0" layoutY="360.0" mnemonicParsing="false" onAction="#finishButtonHandler" text="%settings.button.finish" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" /> + <ToggleButton fx:id="lockedButton" mnemonicParsing="false" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" /> </children> </AnchorPane> diff --git a/PlayWall/src/application.yml b/PlayWall/src/application.yml index 8c4c7d52ea06939be86818ed0ebb573f90415f5e..399d169517d6e08dec15cc896bcc2c5d0c107625 100644 --- a/PlayWall/src/application.yml +++ b/PlayWall/src/application.yml @@ -1,15 +1,15 @@ name: PlayWall -version: b5.0.0 -build: 24 +version: 5.0.0 GM +build: 26 identifier: de.tobias.playpad main: de.tobias.playpad.PlayPadMain author: Tobias Ullerich backup: false iconPath: icon -updateURL: http://s522730663.online.de/programmer/files/PlayWall +updateURL: http://tobisan.no-ip.org/files/PlayWall userInfo: Website: http://tobisan.no-ip.org/ - ErrorURL: http://s522730663.online.de/programmer/upload.php - PluginsURL: http://s522730663.online.de/programmer/files/PlayWall/plugins.yml - ChangelogURL: http://s522730663.online.de/programmer/whatsnew-2.php?id=1 - UpdaterProgram: http://s522730663.online.de/programmer/files/Updater/ + ErrorURL: http://tobisan.no-ip.org/upload.php + PluginsURL: http://tobisan.no-ip.org/files/PlayWall/plugins.yml + ChangelogURL: http://tobisan.no-ip.org/whatsnew-2.php?id=1 + UpdaterProgram: http://tobisan.no-ip.org/files/Updater/ diff --git a/PlayWall/src/de/tobias/playpad/PlayPadMain.java b/PlayWall/src/de/tobias/playpad/PlayPadMain.java index 81e098fd6605ccd1fc4e045f2f657285a8c07e8b..ad32fa0438ba446b509a8493063435044199090e 100644 --- a/PlayWall/src/de/tobias/playpad/PlayPadMain.java +++ b/PlayWall/src/de/tobias/playpad/PlayPadMain.java @@ -52,6 +52,7 @@ import de.tobias.playpad.settings.ProfileListener; import de.tobias.playpad.settings.ProfileReference; import de.tobias.playpad.tigger.TriggerRegistry; import de.tobias.playpad.trigger.CartTriggerItemConnect; +import de.tobias.playpad.trigger.VolumeTriggerItemConnect; import de.tobias.playpad.view.MapperOverviewViewController; import de.tobias.playpad.viewcontroller.IPadSettingsViewController; import de.tobias.playpad.viewcontroller.ISettingsViewController; @@ -91,30 +92,29 @@ import net.xeoh.plugins.base.impl.PluginManagerFactory; // Profile mit UUID // FEATURE Backups irgendwann löschen +// FEATURE Global Volume Trigger mit x% und 100% // Pad System neu machen // Neue PadViewController für jedes pad // Midi Modell Überarbeiten // Bei Seitenwechsel Pad auf Play lassen -// FEATURE Trigger +// TEST Trigger // FEATURE Option bei Import Media auch Copy Media in Library // FEATURE lnk für Windows mit Dateiparameter -// FEATURE PFL -// FEATURE Sound Card Pro Cart - public class PlayPadMain extends Application implements LocalizationDelegate, PlayPad, ProfileListener { + private static final String PLUGIN_INFO_TXT = "pluginInfo.txt"; private static final String iconPath = "icon_small.png"; public static Optional<Image> stageIcon = Optional.empty(); - public static final long notificationDisplayTimeMillis = 1500; + public static final long displayTimeMillis = 1500; public static final String[] projectType = { "*.xml" }; - public static final String[] projectCompressedType = { "*.zip" }; + public static final String[] projectZIPType = { "*.zip" }; public static final String[] midiPresetType = { "*.pre" }; private static ResourceBundle uiResourceBundle; @@ -183,26 +183,6 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl ProfileReference.loadProfiles(); ProjectReference.loadProjects(); - Runtime.getRuntime().addShutdownHook(new Thread(() -> - { - try { - if (mainViewController != null) { - if (mainViewController.getProject().getRef() != null) { - // Projekt Speichern - mainViewController.getProject().save(); - } - } - - if (Profile.currentProfile() != null) - Profile.currentProfile().save(); - - ProfileReference.saveProfiles(); - ProjectReference.saveProjects(); - } catch (Exception e) { - e.printStackTrace(); // Speichern Fehler - } - })); - // Changelog nach Update anzeigen try { ViewController.create(ChangelogDialog.class); @@ -213,15 +193,50 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl // Auto Open Project if (getParameters().getRaw().size() > 0) { try { - UUID uuid = UUID.fromString(getParameters().getRaw().get(0)); + UUID uuid = UUID.fromString(getParameters().getNamed().get("project")); launchProject(Project.load(ProjectReference.getProject(uuid), true, null)); return; - } catch (Exception e) { + } catch (IllegalArgumentException | NullPointerException e) {} catch (Exception e) { e.printStackTrace(); } } ViewController.create(LaunchDialog.class, stage); + + } + + @Override + public void stop() throws Exception { + try { + ProfileReference.saveProfiles(); + ProjectReference.saveProjects(); + } catch (Exception e) { + e.printStackTrace(); // Speichern Fehler + } + + TinyAudioHandler.shutdown(); + ClipAudioHandler.shutdown(); + + pluginManager.shutdown(); + + Path pluginInfoPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, PLUGIN_INFO_TXT); + try { + if (Files.notExists(pluginInfoPath)) { + Files.createDirectories(pluginInfoPath.getParent()); + Files.createFile(pluginInfoPath); + } + PrintWriter deleteWriter = new PrintWriter(Files.newOutputStream(pluginInfoPath)); + for (Path path : deletedPlugins) { + deleteWriter.println(path.toString()); + } + deleteWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + Worker.shutdown(); + Platform.exit(); + System.exit(0); } private void registerComponents() { @@ -242,7 +257,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl // Trigger TriggerRegistry.register(new CartTriggerItemConnect()); -// TriggerRegistry.register(new VolumeTriggerItemConnect()); + TriggerRegistry.register(new VolumeTriggerItemConnect()); // Actions ActionRegistery.registerActionConnect(new CartActionConnect()); @@ -268,7 +283,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl /* * Plugins */ - Path pluginInfoPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, "pluginInfo.txt"); + Path pluginInfoPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, PLUGIN_INFO_TXT); // Delete Plugin if (Files.exists(pluginInfoPath)) { @@ -289,26 +304,6 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl pluginManager.addPluginsFrom(Paths.get("/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWallPlugins/bin/").toUri()); else pluginManager.addPluginsFrom(ApplicationUtils.getApplication().getPath(PathType.LIBRARY).toUri()); - - // Shutdown Plugins - Runtime.getRuntime().addShutdownHook(new Thread(() -> - { - pluginManager.shutdown(); - - try { - if (Files.notExists(pluginInfoPath)) { - Files.createDirectories(pluginInfoPath.getParent()); - Files.createFile(pluginInfoPath); - } - PrintWriter deleteWriter = new PrintWriter(Files.newOutputStream(pluginInfoPath)); - for (Path path : deletedPlugins) { - deleteWriter.println(path.toString()); - } - deleteWriter.close(); - } catch (IOException e) { - e.printStackTrace(); - } - })); } private void setupLocalization() { @@ -324,6 +319,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl @Override public void reloadSettings(Profile oldProfile, Profile currentProfile) { + // Update PlayWall if (currentProfile.getProfileSettings().isAutoUpdate()) { Worker.runLater(() -> { @@ -434,7 +430,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl } @Override - public MainViewController getMainViewController() { + public IMainViewController getMainViewController() { return mainViewController; } diff --git a/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java b/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java index be17c2fe34175743038c7fd97744c106298ecddc..be3582a6293243e6558a733e46fb16159bed89a5 100644 --- a/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java +++ b/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java @@ -48,7 +48,8 @@ public class PlayPadUpdater implements Updatable { public boolean checkUpdate() { App app = ApplicationUtils.getMainApplication(); try { - FileConfiguration config = YamlConfiguration.loadConfiguration(new URL(app.getInfo().getUpdateURL() + "/version.yml").openStream()); + URL url = new URL(app.getInfo().getUpdateURL() + "/version.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); newBuild = config.getInt("build"); newVersion = config.getString("version"); diff --git a/PlayWall/src/de/tobias/playpad/Strings.java b/PlayWall/src/de/tobias/playpad/Strings.java index 7dae7bef76b698e9dec6f00d12fe3fa15b5e32d2..d459d168dacbdaa02c9e385fc73f435ce8a4f721 100644 --- a/PlayWall/src/de/tobias/playpad/Strings.java +++ b/PlayWall/src/de/tobias/playpad/Strings.java @@ -6,6 +6,7 @@ public class Strings { public static final String Standard_File_Save = "Standard.File.Save"; public static final String Standard_Copy = "Standard.Copy"; public static final String Standard_Time_Seconds = "Standard.Time.Seconds"; + public static final String Standard_Time_Volume = "Standard.Time.Volume"; // File - Filter public static final String File_Filter_ZIP = "File.Filter.ZIP"; @@ -42,6 +43,7 @@ public class Strings { // UI - Window - Main public static final String UI_Window_Main_CloseRequest = "UI.Window.Main.CloseRequest"; + public static final String UI_Window_Main_SaveRequest = "UI.Window.Main.SaveRequest"; public static final String UI_Window_Main_PageButton = "UI.Window.Main.PageButton"; // UI - Dialog - Launch @@ -50,6 +52,7 @@ public class Strings { // UI - Window - Settings public static final String UI_Window_Settings_Gen_Title = "UI.Window.Settings.Gen.Title"; public static final String UI_Window_Settings_Gen_CacheSize = "UI.Window.Settings.Gen.CacheSize"; + public static final String UI_Window_Settings_Gen_Wait = "UI.Window.Settings.Gen.Wait"; public static final String UI_Window_Settings_Mapping_Title = "UI.Window.Settings.Mapping.Title"; public static final String UI_Window_Settings_Midi_Title = "UI.Window.Settings.Midi.Title"; public static final String UI_Window_Settings_Layout_Title = "UI.Window.Settings.Layout.Title"; @@ -141,6 +144,7 @@ public class Strings { // Error - Fix public static final String Error_Fix_NewFile = "Error.Fix.NewFile"; + public static final String Error_Fix_Delete = "Error.Fix.Delete"; // Error - Midi public static final String Error_Midi_Settings_Unkown = "Error.Midi.Settings.Unkown"; @@ -150,7 +154,7 @@ public class Strings { public static final String Error_Midi_Send = "Error.Midi.Send"; // Error - Plugins - public static final String Error_Plugins_Download = "Error.Plugins.Download"; + @Deprecated public static final String Error_Plugins_Download = "Error.Plugins.Download"; /* * NEU @@ -215,4 +219,8 @@ public class Strings { // TriggerPoint - Enum public static final String TriggerPoint_BaseName = "TriggerPoint."; + + // Drag and Drop Mode + public static final String DnDMode_Move = "DnDMode.Move"; + public static final String DnDMode_Replace = "DnDMode.Replace"; } diff --git a/PlayWall/src/de/tobias/playpad/VersionUpdater.java b/PlayWall/src/de/tobias/playpad/VersionUpdater.java index e6cce69341fa072ef98a0a2afdbf5a76f78b7289..66a4ce97325f1517ebdd15ce750102ea54354d3d 100644 --- a/PlayWall/src/de/tobias/playpad/VersionUpdater.java +++ b/PlayWall/src/de/tobias/playpad/VersionUpdater.java @@ -35,40 +35,12 @@ public class VersionUpdater implements UpdateService { @Override public void update(App app, long oldVersion, long newVersion) { - System.out.println("Update"); - if (oldVersion <= 18) { - SAXReader reader = new SAXReader(); - Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "Profiles.xml"); - - try { - Document document = reader.read(Files.newInputStream(path)); - Element root = document.getRootElement(); - for (Object object : root.elements("Document")) { - Element element = (Element) object; - String name = element.getStringValue(); - - UUID uuid = UUID.randomUUID(); - - Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, name); - Path newProjectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, uuid + Project.FILE_EXTENSION); - Files.createDirectories(newProjectPath.getParent()); - - Files.move(projectPath, newProjectPath); - - ProjectReference projectReference = new ProjectReference(uuid, name, ProfileReference.getProfiles().get(0)); - ProjectReference.addProject(projectReference); - - convertProject(newProjectPath); - } - - ProjectReference.saveProjects(); - } catch (Exception e) { - e.printStackTrace(); - } - } + update18(oldVersion); + update23(app, oldVersion); + } + private void update23(App app, long oldVersion) { if (oldVersion <= 23) { - System.out.println("Update Data"); Path configPath = app.getPath(PathType.CONFIGURATION); SAXReader reader = new SAXReader(); try { @@ -132,6 +104,39 @@ public class VersionUpdater implements UpdateService { } } + private void update18(long oldVersion) { + if (oldVersion <= 18) { + SAXReader reader = new SAXReader(); + Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "Profiles.xml"); + + try { + Document document = reader.read(Files.newInputStream(path)); + Element root = document.getRootElement(); + for (Object object : root.elements("Document")) { + Element element = (Element) object; + String name = element.getStringValue(); + + UUID uuid = UUID.randomUUID(); + + Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, name); + Path newProjectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, uuid + Project.FILE_EXTENSION); + Files.createDirectories(newProjectPath.getParent()); + + Files.move(projectPath, newProjectPath); + + ProjectReference projectReference = new ProjectReference(uuid, name, ProfileReference.getProfiles().get(0)); + ProjectReference.addProject(projectReference); + + convertProject(newProjectPath); + } + + ProjectReference.saveProjects(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + public void convertMidiToMapping(Path configPath) throws DocumentException, IOException { SAXReader reader = new SAXReader(); Document midiDocument = reader.read(Files.newInputStream(configPath.resolve("Midi.xml"))); diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java index 5dd5cf62b8df9d6766281d5ab0a85ce8dcb0531c..08b415006500178cd7ef058c11e9175e27d19833 100644 --- a/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java +++ b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java @@ -31,6 +31,7 @@ public class CartAction extends Action { private boolean autoFeedbackColors; private transient Pad pad; + private transient PadContentFeedbackListener padContentFeedbackListener = new PadContentFeedbackListener(); private transient PadStatusFeedbackListener padStatusFeedbackListener = new PadStatusFeedbackListener(); private transient PadPositionWarningListener padPositionListener = new PadPositionWarningListener(this); @@ -178,7 +179,7 @@ public class CartAction extends Action { root.addAttribute(AUTO_FEEDBACK_COLORS, String.valueOf(autoFeedbackColors)); } - public void setPad(Pad newPad) { + void setPad(Pad newPad) { Pad oldPad = this.pad; if (newPad == null || !newPad.equals(oldPad) || oldPad == null) { // Remove old Listener @@ -189,35 +190,35 @@ public class CartAction extends Action { durationable.positionProperty().removeListener(padPositionListener); } } + oldPad.contentProperty().removeListener(padContentFeedbackListener); oldPad.statusProperty().removeListener(padStatusFeedbackListener); } this.pad = newPad; + padPositionListener.setPad(newPad); + padStatusFeedbackListener.setAction(this); + padContentFeedbackListener.setAction(this); + if (newPad != null) { // Add new listener if (newPad.getContent() != null) { if (newPad.getContent() instanceof Durationable) { - padPositionListener.setPad(newPad); Durationable durationable = (Durationable) newPad.getContent(); durationable.positionProperty().addListener(padPositionListener); } } - padStatusFeedbackListener.setAction(this); + newPad.statusProperty().addListener(padStatusFeedbackListener); + newPad.contentProperty().addListener(padContentFeedbackListener); } } } - // Listener - public PadPositionWarningListener getPadPositionListener() { + PadPositionWarningListener getPadPositionListener() { return padPositionListener; } - public PadStatusFeedbackListener getPadStatusFeedbackListener() { - return padStatusFeedbackListener; - } - // Helper @Override public Action cloneAction() throws CloneNotSupportedException { diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadContentFeedbackListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadContentFeedbackListener.java new file mode 100644 index 0000000000000000000000000000000000000000..f24c40dc7823a1e352a4543290c9f64817f381f4 --- /dev/null +++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadContentFeedbackListener.java @@ -0,0 +1,32 @@ +package de.tobias.playpad.action.cartaction; + +import de.tobias.playpad.pad.conntent.Durationable; +import de.tobias.playpad.pad.conntent.PadContent; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; + +public class PadContentFeedbackListener implements ChangeListener<PadContent> { + + private CartAction action; + + public void setAction(CartAction action) { + this.action = action; + } + + @Override + public void changed(ObservableValue<? extends PadContent> observable, PadContent oldValue, PadContent newValue) { + if (oldValue != null) { + if (oldValue instanceof Durationable) { + Durationable durationable = (Durationable) oldValue; + durationable.positionProperty().addListener(action.getPadPositionListener()); + } + } + + if (newValue != null) { + if (newValue instanceof Durationable) { + Durationable durationable = (Durationable) newValue; + durationable.positionProperty().addListener(action.getPadPositionListener()); + } + } + } +} diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java index 65f551b6321c8e46fa49d35b40072c15239f6f3c..7691158c4d971f4fb1b6fee394c93868e2da9a21 100644 --- a/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java +++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java @@ -41,8 +41,8 @@ public class PadPositionWarningListener implements ChangeListener<Duration> { if (warning.getTime().toSeconds() > seconds && !send) { action.handleFeedback(FeedbackMessage.WARNING); + send = true; } - send = true; } } } diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java index 63510122a06d136e3e4553a2866429fea6050bab..5d1bb8c37cc82cd8189fc2c1821ef60fb723d0be 100644 --- a/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java +++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java @@ -23,7 +23,8 @@ public class PadStatusFeedbackListener implements ChangeListener<PadStatus> { Pad pad = action.getPad(); if (pad.isPadVisible()) { switch (newValue) { - case EMPTY: case ERROR: + case EMPTY: + case ERROR: action.handleFeedback(FeedbackMessage.OFF); break; case PAUSE: diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java index 7cc2b7e3b2d70465dc1e894b82fe269826c83a4b..ebde690e52f56a3f0d43702a4e3a7a64890a75a3 100644 --- a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java +++ b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java @@ -21,6 +21,7 @@ import de.tobias.utils.ui.ContentViewController; import de.tobias.utils.util.Localization; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; +import javafx.scene.paint.Color; public class MidiMapper extends Mapper implements ColorAssociator, MapperFeedbackable { @@ -145,6 +146,18 @@ public class MidiMapper extends Mapper implements ColorAssociator, MapperFeedbac } return null; } + + @Override + public DisplayableFeedbackColor map(Color color) { + Optional<Device> midiDevice = Midi.getInstance().getMidiDevice(); + if (midiDevice.isPresent()) { + Device device = midiDevice.get(); + if (device instanceof DeviceColorAssociatorConnector) { + return ((DeviceColorAssociatorConnector) device).map(color); + } + } + return null; + } private static final String MIDI_COMMAND = "command"; private static final String MIDI_KEY = "key"; diff --git a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java index b8e809db65dabd431dcf244180a80d610e691eed..4d422336f8490a1fad151e58f02172067e0ed296 100644 --- a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java +++ b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java @@ -163,8 +163,8 @@ public class ClipAudioHandler extends AudioHandler { } @Override - public void setVolume(double volume, double masterVolume) { - setVolume(masterVolume * volume); + public void setVolume(double volume, double masterVolume, double customVolume) { + setVolume(masterVolume * volume * customVolume); } /** @@ -244,9 +244,8 @@ public class ClipAudioHandler extends AudioHandler { mixer = null; } - @Override - public void updateVolume(double masterVolume) { - setVolume(getContent().getPad().getVolume(), masterVolume); + public static void shutdown() { + positionThread.interrupt(); } } diff --git a/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java index e88b1d7a02f5590263925bde3ec9b3d2f6c37287..cb6ba352622e388544baaa4d7df1c2c219a2276d 100644 --- a/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java +++ b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java @@ -78,9 +78,9 @@ public class JavaFXAudioHandler extends AudioHandler implements Equalizable { } @Override - public void setVolume(double volume, double masterVolume) { + public void setVolume(double volume, double masterVolume, double customVolume) { if (player != null) - player.setVolume(volume * masterVolume); + player.setVolume(volume * masterVolume * customVolume); } @Override @@ -151,10 +151,4 @@ public class JavaFXAudioHandler extends AudioHandler implements Equalizable { durationProperty.set(null); loadedProperty.set(false); } - - @Override - public void updateVolume(double masterVolume) { - if (player != null) - player.setVolume(getContent().getPad().getVolume() * masterVolume); - } } diff --git a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java index ecac4b7cf99cccecb711c607943107c78b6551f5..a995f7d0b871a5b150ad3d3f940bb6d794e18af7 100644 --- a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java +++ b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java @@ -103,7 +103,6 @@ public class TinyAudioHandler extends AudioHandler { positionThread.start(); executorService = Executors.newFixedThreadPool(1); - Runtime.getRuntime().addShutdownHook(new Thread(() -> executorService.shutdown())); } private Music music; @@ -196,9 +195,9 @@ public class TinyAudioHandler extends AudioHandler { } @Override - public void setVolume(double volume, double masterVolume) { + public void setVolume(double volume, double masterVolume, double customVolume) { if (music != null) { - music.setVolume(volume * masterVolume); + music.setVolume(volume * masterVolume * customVolume); } } @@ -284,13 +283,6 @@ public class TinyAudioHandler extends AudioHandler { loadedProperty.set(false); } - @Override - public void updateVolume(double masterVolume) { - if (music != null) { - music.setVolume(getContent().getPad().getVolume() * masterVolume); - } - } - public void setMusic(Music music, URL url) throws UnsupportedAudioFileException, IOException { this.music = music; calcDuration(url); @@ -330,4 +322,9 @@ public class TinyAudioHandler extends AudioHandler { } } } + + public static void shutdown() { + executorService.shutdown(); + positionThread.interrupt(); + } } diff --git a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java index 3dc08fb0240b1e8654b6de673f749e8d27b2db8e..7bd47b406ccf8aba5a185f690b9e0bcac2c31464 100644 --- a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java +++ b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java @@ -13,6 +13,7 @@ import org.dom4j.io.XMLWriter; import de.tobias.playpad.PseudoClasses; import de.tobias.playpad.layout.CartLayout; +import de.tobias.playpad.layout.GlobalLayout; import de.tobias.playpad.layout.Layout; import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.view.IPadViewController; @@ -235,4 +236,19 @@ public class ClassicCartLayout extends Layout implements CartLayout { }); } } + + @Override + public void copyGlobalLayout(GlobalLayout globalLayout) { + if (globalLayout instanceof ClassicGlobalLayout) { + ClassicGlobalLayout classicGlobalLayout = (ClassicGlobalLayout) globalLayout; + backgroundColor = classicGlobalLayout.getBackgroundColor(); + playbackColor = classicGlobalLayout.getPlaybackColor(); + warnColor = classicGlobalLayout.getWarnColor(); + fadeColor = classicGlobalLayout.getFadeColor(); + + accentColor = classicGlobalLayout.getAccentColor(); + infoLabelColor = classicGlobalLayout.getInfoLabelColor(); + titleLabelColor = classicGlobalLayout.getAccentColor(); + } + } } diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java index ba428cd1ed0aa3fee3b07a80e85156cd552c1fda..cbc99d65840c46d882d609515f60dff71f9e85b0 100644 --- a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java +++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java @@ -5,6 +5,7 @@ import org.dom4j.Element; import de.tobias.playpad.PseudoClasses; import de.tobias.playpad.layout.CartLayout; import de.tobias.playpad.layout.FadeableColor; +import de.tobias.playpad.layout.GlobalLayout; import de.tobias.playpad.layout.Layout; import de.tobias.playpad.layout.LayoutColorAssociator; import de.tobias.playpad.pad.Pad; @@ -22,7 +23,7 @@ public class ModernLayoutCart extends Layout implements CartLayout, LayoutColorA public static final double minHeight = 110; private ModernColor backgroundColor = ModernColor.GRAY1; - private ModernColor playColor = ModernColor.RED1; + private ModernColor playColor = ModernColor.RED3; private boolean isWarnAnimation = true; @@ -196,4 +197,14 @@ public class ModernLayoutCart extends Layout implements CartLayout, LayoutColorA public Color getAssociatedStandardColor() { return Color.web(backgroundColor.getColorHi()); } + + @Override + public void copyGlobalLayout(GlobalLayout globalLayout) { + if (globalLayout instanceof ModernLayoutGlobal) { + ModernLayoutGlobal modernLayoutGlobal = (ModernLayoutGlobal) globalLayout; + backgroundColor = modernLayoutGlobal.getBackgroundColor(); + playColor = modernLayoutGlobal.getPlayColor(); + isWarnAnimation = modernLayoutGlobal.isWarnAnimation(); + } + } } diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java index ae5f91bca5f85098511dbbff5f8fb2827996bb0a..925b392b8eec6daefe124e45c52dd2861fa73f37 100644 --- a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java +++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java @@ -33,7 +33,7 @@ public class ModernLayoutGlobal extends Layout implements GlobalLayout, LayoutCo public static final double minHeight = 110; private ModernColor backgroundColor = ModernColor.GRAY1; - private ModernColor playColor = ModernColor.RED1; + private ModernColor playColor = ModernColor.RED3; private boolean isWarnAnimation = true; @@ -255,7 +255,7 @@ public class ModernLayoutGlobal extends Layout implements GlobalLayout, LayoutCo Element titleFontSizeElement = rootElement.element("TitleFontSize"); if (titleFontSizeElement != null) { try { - infoFontSize = Integer.valueOf(titleFontSizeElement.getStringValue()); + titleFontSize = Integer.valueOf(titleFontSizeElement.getStringValue()); } catch (NumberFormatException e) { e.printStackTrace(); } diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java index 3c83a6b1edf375c331fce038e7a6016870ee1d92..cef5c4b1c0498a6bcbd65b17c759a3b15f464ea1 100644 --- a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java +++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java @@ -1,11 +1,9 @@ package de.tobias.playpad.pad.content; import java.io.FileNotFoundException; -import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; import org.dom4j.Element; @@ -20,6 +18,7 @@ import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.playpad.pad.conntent.Pauseable; import de.tobias.playpad.project.ProjectExporter; import de.tobias.playpad.settings.Profile; +import de.tobias.utils.util.ZipFile; import javafx.animation.Transition; import javafx.application.Platform; import javafx.beans.property.ObjectProperty; @@ -40,6 +39,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, private ObjectProperty<Duration> positionProperty = new SimpleObjectProperty<>(); private ChangeListener<Number> volumeListener; + private ChangeListener<Number> customVolumeListener; private transient Transition transition; @@ -47,7 +47,11 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, super(pad); volumeListener = (a, b, c) -> { - audioHandler.setVolume(c.doubleValue(), Profile.currentProfile().getProfileSettings().getVolume()); + audioHandler.setVolume(c.doubleValue(), Profile.currentProfile().getProfileSettings().getVolume(), pad.getCustomVolume()); + }; + customVolumeListener = (a, b, c) -> + { + audioHandler.setVolume(pad.getVolume(), Profile.currentProfile().getProfileSettings().getVolume(), c.doubleValue()); }; } @@ -74,7 +78,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, @Override public void setMasterVolume(double masterVolume) { if (audioHandler != null) { - audioHandler.setVolume(getPad().getVolume(), masterVolume); + audioHandler.setVolume(getPad().getVolume(), masterVolume, getPad().getCustomVolume()); } } @@ -85,6 +89,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, @Override public void play() { + getPad().setCustomVolume(1); getPad().setEof(false); audioHandler.play(); } @@ -106,18 +111,20 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, transition.stop(); } - if (getPad().getFade().getFadeIn().toMillis() > 0) { + Pad pad = getPad(); + + if (pad.getFade().getFadeIn().toMillis() > 0) { double masterVolume = Profile.currentProfile().getProfileSettings().getVolume(); - audioHandler.setVolume(0, masterVolume); + audioHandler.setVolume(0, masterVolume, pad.getCustomVolume()); transition = new Transition() { { - setCycleDuration(getPad().getFade().getFadeIn()); + setCycleDuration(pad.getFade().getFadeIn()); } @Override protected void interpolate(double frac) { - audioHandler.setVolume(frac * getPad().getVolume(), masterVolume); + audioHandler.setVolume(frac * pad.getVolume(), masterVolume, pad.getCustomVolume()); } }; transition.setOnFinished(e -> @@ -144,7 +151,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, @Override protected void interpolate(double frac) { double masterVolume = Profile.currentProfile().getProfileSettings().getVolume(); - audioHandler.setVolume(getPad().getVolume() - frac * getPad().getVolume(), masterVolume); + audioHandler.setVolume(getPad().getVolume() - frac * getPad().getVolume(), masterVolume, getPad().getCustomVolume()); } }; transition.setOnFinished(event -> @@ -152,7 +159,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, onFinish.run(); double masterVolume = Profile.currentProfile().getProfileSettings().getVolume(); - audioHandler.setVolume(getPad().getVolume(), masterVolume); + audioHandler.setVolume(getPad().getVolume(), masterVolume, getPad().getCustomVolume()); transition = null; }); transition.play(); @@ -212,6 +219,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, positionProperty.bind(audioHandler.positionProperty()); getPad().volumeProperty().addListener(volumeListener); + getPad().customVolumeProperty().addListener(customVolumeListener); } else { getPad().throwException(path, new FileNotFoundException()); } @@ -223,14 +231,17 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, positionProperty.unbind(); getPad().volumeProperty().removeListener(volumeListener); + getPad().customVolumeProperty().removeListener(customVolumeListener); if (audioHandler != null) audioHandler.unloadMedia(); - try { - getPad().setStatus(PadStatus.EMPTY); - } catch (Exception e) { - Platform.runLater(() -> getPad().setStatus(PadStatus.EMPTY)); - } + + Platform.runLater(() -> + { + if (getPad() != null) { + getPad().setStatus(PadStatus.EMPTY); + } + }); } @Override @@ -244,33 +255,34 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, } @Override - public void importMedia(Path mediaFolder, FileSystem zipfs, Element element) { + public void importMedia(Path mediaFolder, ZipFile zip, Element element) { String fileName = Paths.get(element.getStringValue()).getFileName().toString(); - Path mediaFile = zipfs.getPath(ProjectExporter.mediaFolder, fileName); - if (Files.exists(mediaFile)) { - Path desFile = mediaFolder.resolve(fileName); + Path mediaFile = Paths.get(ProjectExporter.mediaFolder, fileName); - try { - if (Files.notExists(desFile.getParent())) { - Files.createDirectories(desFile.getParent()); - } - Files.copy(mediaFile, desFile, StandardCopyOption.REPLACE_EXISTING); + Path desFile = mediaFolder.resolve(fileName); - element.setText(desFile.toString()); - } catch (Exception e) { - e.printStackTrace(); + try { + if (Files.notExists(desFile.getParent())) { + Files.createDirectories(desFile.getParent()); } + + if (Files.notExists(desFile)) + zip.getFile(mediaFile, desFile); + + element.setText(desFile.toString()); + } catch (Exception e) { + e.printStackTrace(); } } @Override - public void exportMedia(FileSystem mediaFolder, Element element) { - Path desPath = mediaFolder.getPath(ProjectExporter.mediaFolder, path.getFileName().toString()); + public void exportMedia(ZipFile zip, Element element) { + Path desPath = Paths.get(ProjectExporter.mediaFolder, path.getFileName().toString()); try { if (Files.notExists(desPath.getParent())) { Files.createDirectories(desPath.getParent()); } - Files.copy(path, desPath, StandardCopyOption.REPLACE_EXISTING); + zip.addFile(path, desPath); } catch (Exception e) { e.printStackTrace(); } diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java index 9566b9095e2e83096c5b08b2f62cc679883465d8..c111f13bee8d9a7c49f937d741697f31363270c2 100644 --- a/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java +++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java @@ -70,7 +70,7 @@ public class AudioContentConnect extends PadContentConnect { public AudioContentView(Pad pad, Pane parentNode) { nameLabel = new Label(); nameLabel.textProperty().bind(pad.nameProperty()); - + nameLabel.setWrapText(true); nameLabel.setAlignment(Pos.CENTER); nameLabel.setTextAlignment(TextAlignment.CENTER); diff --git a/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java b/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java index bf6bbc47811da7668d9c046ce1c68610dd02528d..16a3526c19e4f374654150a47327d6f7be972f9b 100644 --- a/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java +++ b/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java @@ -1,8 +1,11 @@ package de.tobias.playpad.pad.drag; +import de.tobias.playpad.Strings; +import de.tobias.playpad.pad.Pad; import de.tobias.playpad.project.Project; import de.tobias.utils.ui.icon.FontAwesomeType; import de.tobias.utils.ui.icon.FontIcon; +import de.tobias.utils.util.Localization; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.scene.Node; @@ -12,15 +15,18 @@ public class MoveDragMode extends PadDragMode { private static final String TYPE = "move"; private FontIcon icon; + private StringProperty displayProperty; public MoveDragMode() { icon = new FontIcon(FontAwesomeType.ARROWS); icon.setSize(30); + + displayProperty = new SimpleStringProperty(Localization.getString(Strings.DnDMode_Move)); } @Override public StringProperty displayProperty() { - return new SimpleStringProperty("Tauschen"); // TODO Localize + return displayProperty; } @Override @@ -34,8 +40,12 @@ public class MoveDragMode extends PadDragMode { } @Override - public void handle(int oldPad, int newPad, Project project) { - project.movePads(oldPad, newPad); + public void handle(int oldIndex, int newIndex, Project project) { + Pad oldPad = project.getPad(oldIndex); + Pad newPad = project.getPad(newIndex); + + project.setPad(newIndex, oldPad); + project.setPad(oldIndex, newPad); } } diff --git a/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java b/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java index a01255fe87f135bd006b9e9cc8c3c6672ac07d8d..0e48d10e02295c9bc053efd83d7ec5bf19383967 100644 --- a/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java +++ b/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java @@ -1,8 +1,11 @@ package de.tobias.playpad.pad.drag; +import de.tobias.playpad.Strings; +import de.tobias.playpad.pad.Pad; import de.tobias.playpad.project.Project; import de.tobias.utils.ui.icon.FontAwesomeType; import de.tobias.utils.ui.icon.FontIcon; +import de.tobias.utils.util.Localization; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.scene.Node; @@ -12,15 +15,18 @@ public class ReplaceDragMode extends PadDragMode { private static final String TYPE = "replace"; private FontIcon icon; + private StringProperty displayProperty; public ReplaceDragMode() { icon = new FontIcon(FontAwesomeType.ARROW_CIRCLE_RIGHT); icon.setSize(30); + + displayProperty = new SimpleStringProperty(Localization.getString(Strings.DnDMode_Replace)); } @Override public StringProperty displayProperty() { - return new SimpleStringProperty("Ersetzen"); // TODO Localize + return displayProperty; } @Override @@ -35,7 +41,10 @@ public class ReplaceDragMode extends PadDragMode { @Override public void handle(int oldPad, int newPad, Project project) { - project.replacePads(oldPad, newPad); + Pad srcPad = project.getPad(oldPad); + + project.setPad(newPad, srcPad); + project.setPad(oldPad, new Pad(project, oldPad)); } } diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadLockedListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadLockedListener.java new file mode 100644 index 0000000000000000000000000000000000000000..9acff1c3e103808c2f210a29fb9b6056da75e752 --- /dev/null +++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadLockedListener.java @@ -0,0 +1,19 @@ +package de.tobias.playpad.pad.listener; + +import de.tobias.playpad.viewcontroller.pad.PadViewController; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; + +public class PadLockedListener implements ChangeListener<Boolean> { + + private PadViewController controller; + + public PadLockedListener(PadViewController controller) { + this.controller = controller; + } + + @Override + public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { + controller.updateButtonDisable(); + } +} diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java index 40e9b5b6a491b1fbe583d035f07b546ea85c283a..9f582ea5782a13581240ccea9460638627ac5bcb 100644 --- a/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java +++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java @@ -5,6 +5,7 @@ import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.conntent.Durationable; import de.tobias.playpad.pad.conntent.Fadeable; +import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.playpad.settings.Profile; import de.tobias.playpad.viewcontroller.pad.PadViewController; import javafx.beans.value.ChangeListener; @@ -35,31 +36,42 @@ public class PadPositionListener implements ChangeListener<Duration>, Runnable { // Progressbar (Prozente) if (pad != null) { + PadContent content = pad.getContent(); + // Zeit aktualiesieren bei Play und wenn Fade Out ist - if (pad.getContent() instanceof Durationable && (pad.getStatus() == PadStatus.PLAY - || (pad.getContent() instanceof Fadeable && ((Fadeable) pad.getContent()).isFading()))) { + boolean isFading = content instanceof Fadeable && ((Fadeable) content).isFading(); + boolean isPlaying = pad.getStatus() == PadStatus.PLAY; + + if (content instanceof Durationable && (isPlaying || isFading)) { - Durationable durationable = (Durationable) pad.getContent(); + Durationable durationable = (Durationable) content; Duration totalDuration = durationable.getDuration(); - double value = newValue.toMillis() / totalDuration.toMillis(); - controller.getParent().getPlayBar().setProgress(value); + if (totalDuration != null) { + updateDuration(newValue, durationable, totalDuration); + } + } + } + } + + private void updateDuration(Duration newValue, Durationable durationable, Duration totalDuration) { + double value = newValue.toMillis() / totalDuration.toMillis(); + controller.getParent().getPlayBar().setProgress(value); - // Label (Restlaufzeit) - controller.updateTimeLabel(); + // Label (Restlaufzeit) + controller.updateTimeLabel(); - // Warning nur wenn kein Loop und nur wenn Play, da sonst schon anderer Zustand und Warning nicht mehr richtig Reseted wird - if (!pad.isLoop() && pad.getStatus() == PadStatus.PLAY) { - // Warning - Warning warning = pad.getWarning(); - Duration rest = durationable.getDuration().subtract(newValue); - double seconds = rest.toSeconds(); + // Warning nur wenn kein Loop und nur wenn Play, da sonst schon anderer Zustand und Warning nicht mehr richtig Reseted + // wird + if (!pad.isLoop() && pad.getStatus() == PadStatus.PLAY) { + // Warning + Warning warning = pad.getWarning(); + Duration rest = durationable.getDuration().subtract(newValue); + double seconds = rest.toSeconds(); - if (warning.getTime().toSeconds() > seconds && !send) { - startWarningThread(); - send = true; - } - } + if (warning.getTime().toSeconds() > seconds && !send) { + startWarningThread(); + send = true; } } } diff --git a/PlayWall/src/de/tobias/playpad/trigger/TriggerWrapper.java b/PlayWall/src/de/tobias/playpad/trigger/TriggerUIWrapper.java similarity index 92% rename from PlayWall/src/de/tobias/playpad/trigger/TriggerWrapper.java rename to PlayWall/src/de/tobias/playpad/trigger/TriggerUIWrapper.java index 039e62de4361faa4ec38ca83756d1b65171e74d4..edd8e29b8be0b2496e93d7e469be775993c4161c 100644 --- a/PlayWall/src/de/tobias/playpad/trigger/TriggerWrapper.java +++ b/PlayWall/src/de/tobias/playpad/trigger/TriggerUIWrapper.java @@ -8,11 +8,11 @@ import de.tobias.utils.util.Localization; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; -public class TriggerWrapper implements Displayable { +public class TriggerUIWrapper implements Displayable { private Trigger trigger; - public TriggerWrapper(Trigger trigger) { + public TriggerUIWrapper(Trigger trigger) { this.trigger = trigger; updateString(); } diff --git a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java index e6124d754ebfdca60885c9e0f5633e050d45d6ed..c9a6ce6b351d09cb7ddc1160ecf40b8d3350768d 100644 --- a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java +++ b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java @@ -1,20 +1,97 @@ package de.tobias.playpad.trigger; +import org.dom4j.Element; + import de.tobias.playpad.pad.Pad; import de.tobias.playpad.project.Project; import de.tobias.playpad.settings.Profile; import de.tobias.playpad.tigger.TriggerItem; import de.tobias.playpad.viewcontroller.main.IMainViewController; +import javafx.animation.Transition; +import javafx.util.Duration; public class VolumeTriggerItem extends TriggerItem { + private double volume = 1.0; + private Duration duration = new Duration(2000); + + private transient static Transition transition; + private transient static VolumeTriggerItem currentRunningTrigger; + private transient static double currentValue = 1.0; + @Override public String getType() { return VolumeTriggerItemConnect.TYPE; } + public double getVolume() { + return volume; + } + + public void setVolume(double volume) { + this.volume = volume; + } + + public Duration getDuration() { + return duration; + } + + public void setDuration(Duration duration) { + this.duration = duration; + } + @Override public void performAction(Pad pad, Project project, IMainViewController controller, Profile profile) { + if (transition != null) { + currentValue = currentRunningTrigger.volume; + currentRunningTrigger = null; + } + transition = new Transition() { + + { + setCycleDuration(duration); + } + + @Override + protected void interpolate(double frac) { + for (Pad p : project.getPads().values()) { + if (p.getIndex() != pad.getIndex()) { + if (p.getCustomVolume() > volume) { + p.setCustomVolume(currentValue - frac * (currentValue - volume)); + } else { + p.setCustomVolume(currentValue + frac * (volume - currentValue)); + } + } + } + } + }; + transition.setOnFinished(e -> + { + transition = null; + currentValue = volume; + currentRunningTrigger = null; + }); + + currentRunningTrigger = this; + transition.play(); + } + private static final String VOLUME_ATTR = "Volume"; + private static final String DURATION_ATTR = "Duration"; + + @Override + public void load(Element element) { + super.load(element); + if (element.attributeValue(VOLUME_ATTR) != null) + volume = Double.valueOf(element.attributeValue(VOLUME_ATTR)); + if (element.attributeValue(DURATION_ATTR) != null) + duration = Duration.millis(Double.valueOf(element.attributeValue(DURATION_ATTR))); + } + + @Override + public void save(Element element) { + super.save(element); + element.addAttribute(VOLUME_ATTR, String.valueOf(volume)); + element.addAttribute(DURATION_ATTR, String.valueOf(duration.toMillis())); } } diff --git a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItemConnect.java b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItemConnect.java index 7c242e425d7461f1e5a0f4f0ff9e99b09f67b517..7ac1ee3b715701a8afd5d86bbf29e859b1ccc05b 100644 --- a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItemConnect.java +++ b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItemConnect.java @@ -4,6 +4,7 @@ import de.tobias.playpad.Strings; import de.tobias.playpad.tigger.Trigger; import de.tobias.playpad.tigger.TriggerItem; import de.tobias.playpad.tigger.TriggerItemConnect; +import de.tobias.playpad.viewcontroller.option.pad.trigger.VolumeTriggerViewController; import de.tobias.utils.ui.ContentViewController; import de.tobias.utils.util.Localization; @@ -23,7 +24,7 @@ public class VolumeTriggerItemConnect extends TriggerItemConnect { @Override public ContentViewController getSettingsController(TriggerItem item) { - return null; + return new VolumeTriggerViewController((VolumeTriggerItem) item); } @Override diff --git a/PlayWall/src/de/tobias/playpad/view/ExceptionButton.java b/PlayWall/src/de/tobias/playpad/view/ExceptionButton.java index c663458ceaeb0ae65caa3ce8d93ab7d6c7394b9f..a69be057f2201da2eefd8706f53b2e3a65150fe3 100644 --- a/PlayWall/src/de/tobias/playpad/view/ExceptionButton.java +++ b/PlayWall/src/de/tobias/playpad/view/ExceptionButton.java @@ -30,6 +30,16 @@ public class ExceptionButton<T> { return file != null ? file.toPath() : null; } }); + + public static ExceptionButton<Path> DELETE_EXCEPTION = new ExceptionButton<>(Localization.getString(Strings.Error_Fix_Delete), + new Handler<Path>() { + + @Override + public Path handle(Pad pad, Window owner) { + pad.clear(); + return null; + } + }); public static interface Handler<T> { diff --git a/PlayWall/src/de/tobias/playpad/view/MapperOverviewViewController.java b/PlayWall/src/de/tobias/playpad/view/MapperOverviewViewController.java index 5174571a9eb60fc7c40d33f6428c9317d6c79a7e..98522dabed70961ed87ff28c781cffbf6bd55dee 100644 --- a/PlayWall/src/de/tobias/playpad/view/MapperOverviewViewController.java +++ b/PlayWall/src/de/tobias/playpad/view/MapperOverviewViewController.java @@ -21,6 +21,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; +// Diese Klasse zeigt die Mapper zu einer Action an public class MapperOverviewViewController implements IMapperOverviewViewController { private VBox root; diff --git a/PlayWall/src/de/tobias/playpad/view/MapperQuickSettingsView.java b/PlayWall/src/de/tobias/playpad/view/MapperQuickSettingsView.java deleted file mode 100644 index 095e711a9c10d6f16951a7946f87b22b3fd5c390..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/view/MapperQuickSettingsView.java +++ /dev/null @@ -1,58 +0,0 @@ -package de.tobias.playpad.view; - -import java.util.List; - -import de.tobias.playpad.action.mapper.Mapper; -import de.tobias.playpad.action.mapper.MapperRegistry; -import de.tobias.playpad.action.mapper.MapperViewController; -import de.tobias.playpad.pad.conntent.PadContentConnect; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.layout.Background; -import javafx.scene.layout.BackgroundFill; -import javafx.scene.layout.CornerRadii; -import javafx.scene.layout.Pane; -import javafx.scene.layout.VBox; -import javafx.scene.paint.Color; - -public class MapperQuickSettingsView { - - private VBox optionPane; - private Pane root; - - public MapperQuickSettingsView(Pane pane) { - root = pane; - - optionPane = new VBox(); - optionPane.prefWidthProperty().bind(root.widthProperty()); - optionPane.prefHeightProperty().bind(root.heightProperty()); - optionPane.setBackground(new Background(new BackgroundFill(new Color(0.2, 0.2, 0.2, 0.8), new CornerRadii(10), new Insets(0)))); - optionPane.setAlignment(Pos.CENTER); - optionPane.setPadding(new Insets(5)); - optionPane.setSpacing(5); - } - - private PadContentConnect selectedConnect; - - public void showDropOptions(List<Mapper> mappers) { - if (!root.getChildren().contains(optionPane)) { - selectedConnect = null; - - root.getChildren().add(optionPane); - optionPane.getChildren().clear(); - - for (Mapper mapper : mappers) { - MapperViewController controller = MapperRegistry.getMapperConnect(mapper.getType()).getQuickSettingsViewController(mapper); - optionPane.getChildren().add(controller.getParent()); - } - } - } - - public PadContentConnect getSelectedConnect() { - return selectedConnect; - } - - public void hide() { - root.getChildren().remove(optionPane); - } -} diff --git a/PlayWall/src/de/tobias/playpad/view/PadView.java b/PlayWall/src/de/tobias/playpad/view/PadView.java index ab24ea66cd1532538280e52f8823829f86954686..73fea8d8e2d3f7f6a20a1b5f4c89c3f2b3dc47d3 100644 --- a/PlayWall/src/de/tobias/playpad/view/PadView.java +++ b/PlayWall/src/de/tobias/playpad/view/PadView.java @@ -29,7 +29,7 @@ public class PadView extends StackPane implements IPadView { private Label indexLabel; private Label loopLabel; private Label triggerLabel; - private Label messageLabel; + private Label errorLabel; private HBox infoBox; private Label timeLabel; @@ -64,8 +64,8 @@ public class PadView extends StackPane implements IPadView { triggerLabel = new Label(); triggerLabel.setGraphic(new FontIcon(FontAwesomeType.EXTERNAL_LINK)); - messageLabel = new Label(); - messageLabel.setGraphic(new FontIcon(FontAwesomeType.WARNING)); + errorLabel = new Label(); + errorLabel.setGraphic(new FontIcon(FontAwesomeType.WARNING)); timeLabel = new Label(); @@ -109,7 +109,7 @@ public class PadView extends StackPane implements IPadView { // wird über den Status listener gesteuert public void setErrorLabelActive(boolean active) { - messageLabel.setVisible(active); + errorLabel.setVisible(active); } public void setTriggerLabelActive(boolean active) { @@ -165,7 +165,7 @@ public class PadView extends StackPane implements IPadView { } public Label getErrorLabel() { - return messageLabel; + return errorLabel; } public VBox getRoot() { @@ -220,7 +220,7 @@ public class PadView extends StackPane implements IPadView { buttonBox.getChildren().setAll(newButton, settingsButton); } } - infoBox.getChildren().setAll(indexLabel, loopLabel, triggerLabel, messageLabel, timeLabel); + infoBox.getChildren().setAll(indexLabel, loopLabel, triggerLabel, errorLabel, timeLabel); // Buttons unten Full Width buttonBox.prefWidthProperty().bind(widthProperty()); @@ -249,7 +249,7 @@ public class PadView extends StackPane implements IPadView { timeLabel.pseudoClassStateChanged(pseudoClass, active); loopLabel.getGraphic().pseudoClassStateChanged(pseudoClass, active); triggerLabel.getGraphic().pseudoClassStateChanged(pseudoClass, active); - messageLabel.getGraphic().pseudoClassStateChanged(pseudoClass, active); + errorLabel.getGraphic().pseudoClassStateChanged(pseudoClass, active); if (preview != null) { preview.getChildren().forEach(i -> i.pseudoClassStateChanged(pseudoClass, active)); @@ -269,38 +269,25 @@ public class PadView extends StackPane implements IPadView { indexLabel.getStyleClass().addAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info", "pad" + pad.getIndex() + "-info"); timeLabel.getStyleClass().addAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info", "pad" + pad.getIndex() + "-info"); - loopLabel.getGraphic().getStyleClass().addAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon", - "pad" + pad.getIndex() + "-icon"); - triggerLabel.getGraphic().getStyleClass().addAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon", - "pad" + pad.getIndex() + "-icon"); - messageLabel.getGraphic().getStyleClass().addAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon", - "pad" + pad.getIndex() + "-icon"); + loopLabel.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + triggerLabel.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + errorLabel.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); preview.getChildren().forEach(i -> i.getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title")); playBar.getStyleClass().addAll("pad-playbar", "pad" + pad.getIndex() + "-playbar"); - playButton.getStyleClass().addAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-playbutton"); - pauseButton.getStyleClass().addAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-pausebutton"); - stopButton.getStyleClass().addAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-stopbutton"); - newButton.getStyleClass().addAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-newbutton"); - settingsButton.getStyleClass().addAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-settingsbutton"); - - playButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-playbutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-playbutton-icon"); - pauseButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-pausebutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-pausebutton-icon"); - stopButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-stopbutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-stopbutton-icon"); - newButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-newbutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-newbutton-icon"); - settingsButton.getGraphic().getStyleClass().addAll("pad-icon", "pad-deletebutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-settingsbutton-icon"); + playButton.getStyleClass().addAll("pad-button", "pad" + pad.getIndex() + "-button"); + pauseButton.getStyleClass().addAll("pad-button", "pad" + pad.getIndex() + "-button"); + stopButton.getStyleClass().addAll("pad-button", "pad" + pad.getIndex() + "-button"); + newButton.getStyleClass().addAll("pad-button", "pad" + pad.getIndex() + "-button"); + settingsButton.getStyleClass().addAll("pad-button", "pad" + pad.getIndex() + "-button"); + + playButton.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + pauseButton.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + stopButton.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + newButton.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + settingsButton.getGraphic().getStyleClass().addAll("pad-icon", "pad" + pad.getIndex() + "-icon"); getButtonBox().getStyleClass().add("pad-button-box"); getRoot().getStyleClass().add("pad-root"); @@ -311,38 +298,25 @@ public class PadView extends StackPane implements IPadView { indexLabel.getStyleClass().removeAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info", "pad" + pad.getIndex() + "-info"); timeLabel.getStyleClass().removeAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info", "pad" + pad.getIndex() + "-info"); - loopLabel.getGraphic().getStyleClass().removeAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon", - "pad" + pad.getIndex() + "-icon"); - triggerLabel.getGraphic().getStyleClass().removeAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon", - "pad" + pad.getIndex() + "-icon"); - messageLabel.getGraphic().getStyleClass().removeAll("pad-loop", "pad" + pad.getIndex() + "-loop", "pad-icon", - "pad" + pad.getIndex() + "-icon"); + loopLabel.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + triggerLabel.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + errorLabel.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); preview.getChildren().forEach(i -> i.getStyleClass().removeAll("pad-title", "pad" + pad.getIndex() + "-title")); playBar.getStyleClass().removeAll("pad-playbar", "pad" + pad.getIndex() + "-playbar"); - playButton.getStyleClass().removeAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-playbutton"); - pauseButton.getStyleClass().removeAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-pausebutton"); - stopButton.getStyleClass().removeAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-stopbutton"); - newButton.getStyleClass().removeAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-newbutton"); - settingsButton.getStyleClass().removeAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-settingsbutton"); - - playButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-playbutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-playbutton-icon"); - pauseButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-pausebutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-pausebutton-icon"); - stopButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-stopbutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-stopbutton-icon"); - newButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-newbutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-newbutton-icon"); - settingsButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad-deletebutton-icon", "pad" + pad.getIndex() + "-icon", - "pad" + pad.getIndex() + "-settingsbutton-icon"); + playButton.getStyleClass().removeAll("pad-button", "pad" + pad.getIndex() + "-button"); + pauseButton.getStyleClass().removeAll("pad-button", "pad" + pad.getIndex() + "-button"); + stopButton.getStyleClass().removeAll("pad-button", "pad" + pad.getIndex() + "-button"); + newButton.getStyleClass().removeAll("pad-button", "pad" + pad.getIndex() + "-button"); + settingsButton.getStyleClass().removeAll("pad-button", "pad" + pad.getIndex() + "-button"); + + playButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + pauseButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + stopButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + newButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); + settingsButton.getGraphic().getStyleClass().removeAll("pad-icon", "pad" + pad.getIndex() + "-icon"); getButtonBox().getStyleClass().add("pad-button-box"); getRoot().getStyleClass().add("pad-root"); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java index 5ce4507fbd74551a1bf6eebab8660fe64b88b5c5..5f8e136bf1618202be24fb22469fdfd4f2636195 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java @@ -127,7 +127,7 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { private void importProfileButtonHandler(ActionEvent event) { FileChooser chooser = new FileChooser(); chooser.getExtensionFilters() - .add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectCompressedType)); + .add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectZIPType)); File file = chooser.showOpenDialog(getStage()); if (file != null) { Path zipFile = file.toPath(); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PadSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/PadSettingsViewController.java deleted file mode 100644 index 40fa82395914da4674ac45e6fe85d705a4129219..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/PadSettingsViewController.java +++ /dev/null @@ -1,305 +0,0 @@ -package de.tobias.playpad.viewcontroller; - -import java.awt.Desktop; -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.Optional; - -import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.Strings; -import de.tobias.playpad.action.mididevice.Device; -import de.tobias.playpad.midi.Midi; -import de.tobias.playpad.midi.device.DisplayableDevice; -import de.tobias.playpad.model.layout.CartLayout; -import de.tobias.playpad.model.layout.LayoutRegistry; -import de.tobias.playpad.pad.Fade; -import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Pad.TimeMode; -import de.tobias.playpad.pad.Warning; -import de.tobias.playpad.pad.view.PadViewController; -import de.tobias.playpad.plugin.PlayPadPlugin; -import de.tobias.playpad.plugin.viewcontroller.CartLayoutViewController; -import de.tobias.playpad.plugin.viewcontroller.IPadSettingsViewController; -import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.viewcontroller.cell.TimeModeCell; -import de.tobias.playpad.viewcontroller.settings.FadeViewController; -import de.tobias.playpad.viewcontroller.settings.WarningFeedbackViewController; -import de.tobias.utils.ui.ContentViewController; -import de.tobias.utils.ui.ViewController; -import de.tobias.utils.util.Localization; -import javafx.application.Platform; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Slider; -import javafx.scene.control.Tab; -import javafx.scene.control.TabPane; -import javafx.scene.control.TextField; -import javafx.scene.input.KeyCode; -import javafx.scene.layout.AnchorPane; -import javafx.stage.Stage; -import javafx.stage.Window; - -// TODO Renew this class -public class PadSettingsViewController extends ViewController implements IPadSettingsViewController { - - @FXML private TabPane tabPane; - - @FXML private TextField titleTextField; - @FXML private Slider volumeSlider; - @FXML private CheckBox repeatCheckBox; - - @FXML private CheckBox customTimeDisplayCheckBox; - @FXML private ComboBox<TimeMode> timeDisplayComboBox; - - @FXML private CheckBox customFadeCheckBox; - @FXML private AnchorPane fadeContainer; - private FadeViewController fadeViewController; - - @FXML private AnchorPane layoutAnchorPane; - @FXML private CheckBox enableLayoutCheckBox; - private CartLayoutViewController layoutViewController; - - @FXML private AnchorPane warningFeedbackContainer; - @FXML private CheckBox warningEnableCheckBox; - - @FXML private Button deleteButton; - @FXML private Button folderButton; - @FXML private Button finishButton; - - private Pad pad; - private PadViewController controller; - - public PadSettingsViewController(Pad pad, PadViewController controller, Window owner) { - super("padSettingsView", "de/tobias/playpad/assets/settings/", null, PlayPadMain.getUiResourceBundle()); - this.pad = pad; - this.controller = controller; - - // Listener - PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onInit(this)); - - getStage().initOwner(owner); - - titleTextField.setText(pad.getTitle()); - volumeSlider.setValue(pad.getVolume() * 100); - if (pad.isCustomFade()) - fadeViewController.setFade(pad.getFade().get()); - - repeatCheckBox.setSelected(pad.isLoop()); - - customTimeDisplayCheckBox.setSelected(pad.isCustomTimeMode()); - if (!pad.isCustomTimeMode()) { - timeDisplayComboBox.setDisable(true); - } - timeDisplayComboBox.setValue(pad.getTimeMode().orElse(TimeMode.REST)); - - customFadeCheckBox.setSelected(pad.isCustomFade()); - if (!pad.isCustomFade()) { - fadeContainer.setDisable(true); - } - - enableLayoutCheckBox.setSelected(pad.isCustomLayout()); - if (pad.isCustomLayout()) { - try { - String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType(); - Optional<CartLayout> layoutOpt = pad.getLayout(layoutType); - if (layoutOpt.isPresent()) { - setLayoutController(LayoutRegistry.cartViewControllerInstance(layoutType, layoutOpt.get())); - } - } catch (Exception e) { - e.printStackTrace(); - // TODO - } - } - - warningEnableCheckBox.setSelected(pad.isCustomWarning()); - warningEnableCheckBox.selectedProperty().addListener((a, b, c) -> - { - if (c && !pad.isCustomWarning()) { - pad.setWarningFeedback(new Warning()); - addWarningController(); - } else if (b && pad.isCustomWarning()) { - pad.setWarningFeedback(null); - warningFeedbackContainer.getChildren().clear(); - } - }); - - if (pad.isCustomWarning()) { - addWarningController(); - } - - if (!pad.isPadLoaded()) - folderButton.setDisable(true); - - getStage().getScene().setOnKeyReleased(ke -> - { - if (ke.isShortcutDown() && ke.getCode() == KeyCode.W) { - Platform.runLater(() -> finishButtonHandler(null)); - } - }); - } - - private void addWarningController() { - Midi midi = Midi.getInstance(); - - ContentViewController controller = null; - if (midi.getMidiDevice().isPresent()) { - Device device = Midi.getInstance().getMidiDevice().get(); - if (device instanceof DisplayableDevice) { - controller = ((DisplayableDevice) device).getWarnViewController(pad); - } - } - - if (controller == null) { - controller = new WarningFeedbackViewController(pad); - } - - if (controller != null) { - warningFeedbackContainer.getChildren().add(controller.getParent()); - setAnchor(controller.getParent(), 0, 0, 0, 0); - } - } - - @Override - public void init() { - // Listener - titleTextField.textProperty().addListener((a, b, c) -> pad.setTitle(c)); - - // Embed ViewController - fadeViewController = new FadeViewController(); - fadeContainer.getChildren().add(fadeViewController.getParent()); - setAnchor(fadeViewController.getParent(), 0.0, 0.0, 0.0, 0.0); - - volumeSlider.valueProperty().addListener((a, b, c) -> pad.setVolume(c.doubleValue() / 100.0)); - repeatCheckBox.selectedProperty().addListener((a, b, c) -> - { - pad.setLoop(c); - if (controller != null) - controller.getView().setLoopLabelActive(c); - }); - - customTimeDisplayCheckBox.selectedProperty().addListener((a, b, c) -> - { - timeDisplayComboBox.setDisable(!c); - if (c && !pad.isCustomTimeMode()) - pad.setTimeMode(TimeMode.REST); - else if (b && pad.isCustomTimeMode()) - pad.setTimeMode(null); - - }); - timeDisplayComboBox.getItems().addAll(TimeMode.values()); - timeDisplayComboBox.valueProperty().addListener((a, b, c) -> - { - pad.setTimeMode(c); - }); - timeDisplayComboBox.setButtonCell(new TimeModeCell()); - timeDisplayComboBox.setCellFactory(list -> new TimeModeCell()); - - customFadeCheckBox.selectedProperty().addListener((a, b, c) -> - { - fadeContainer.setDisable(!c); - if (c && !pad.isCustomFade()) - pad.setFade(new Fade()); - else if (!c && pad.isCustomFade()) - pad.setFade(null); - - if (c) - fadeViewController.setFade(pad.getFade().get()); - }); - - enableLayoutCheckBox.selectedProperty().addListener((a, b, c) -> - { - if (c && !pad.isCustomLayout()) { - try { - pad.setCustomLayout(true); - try { - String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType(); - Optional<CartLayout> layoutOpt = pad.getLayout(layoutType); - if (layoutOpt.isPresent()) { - setLayoutController(LayoutRegistry.cartViewControllerInstance(layoutType, layoutOpt.get())); - } - } catch (Exception e) { - e.printStackTrace(); - // TODO - } - } catch (Exception e) { - showErrorMessage(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage())); - e.printStackTrace(); - } - } else if (!c && pad.isCustomLayout()) { - pad.setCustomLayout(false); - setLayoutController(null); - } - }); - } - - private void setLayoutController(CartLayoutViewController cartLayoutViewController) { - if (layoutViewController != null) - layoutAnchorPane.getChildren().remove(layoutViewController.getParent()); - - if (cartLayoutViewController != null) { - layoutViewController = cartLayoutViewController; - layoutAnchorPane.getChildren().add(layoutViewController.getParent()); - setAnchor(layoutViewController.getParent(), 0, 0, 0, 0); - } - } - - @Override - public void initStage(Stage stage) { - PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add); - - stage.setMinWidth(650); - stage.setMinHeight(530); - stage.setTitle(Localization.getString(Strings.UI_Window_PadSettings_Title)); - - Profile.currentProfile().currentLayout().applyCss(getStage()); - } - - @FXML - private void deleteButtonHandler(ActionEvent event) { - pad.clearPad(); - getStage().close(); - } - - @Override - public boolean closeRequest() { - if (layoutViewController != null) { - layoutViewController.save(); - } - // Listener - PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this)); - return true; - } - - @FXML - private void folderButtonHandler(ActionEvent event) { - try { - Desktop.getDesktop().open(pad.getPath().toFile().getParentFile()); - } catch (IOException | URISyntaxException e) { - showErrorMessage(Localization.getString(Strings.Error_Standard_Gen, e.getMessage()), PlayPadMain.stageIcon); - e.printStackTrace(); - } - } - - @FXML - private void finishButtonHandler(ActionEvent event) { - if (layoutViewController != null) { - layoutViewController.save(); - } - // Listener - PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this)); - getStage().close(); - } - - public Pad getPad() { - return pad; - } - - public void addTab(String name, AnchorPane content) { - content.setMinSize(0, 0); - content.setMaxSize(AnchorPane.USE_COMPUTED_SIZE, AnchorPane.USE_COMPUTED_SIZE); - tabPane.getTabs().add(new Tab(name, content)); - } -} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java index d7c5c2392c56c19f44221a126ade41210ebb54be..d519188a961d87ab1a645dda272b1229635001b7 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java @@ -1,15 +1,7 @@ package de.tobias.playpad.viewcontroller; import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; - -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import de.tobias.playpad.AppUserInfoStrings; import de.tobias.playpad.PlayPadMain; @@ -18,7 +10,6 @@ import de.tobias.playpad.plugin.Plugin; import de.tobias.playpad.settings.Profile; import de.tobias.playpad.viewcontroller.cell.PluginCell; import de.tobias.utils.application.ApplicationUtils; -import de.tobias.utils.application.container.PathType; import de.tobias.utils.ui.ViewController; import de.tobias.utils.util.Localization; import de.tobias.utils.util.Worker; @@ -49,33 +40,11 @@ public class PluginViewController extends ViewController { Worker.runLater(() -> { try { - List<Plugin> plugins = new ArrayList<>(); - - URL url = new URL(ApplicationUtils.getApplication().getInfo().getUserInfo().getString(AppUserInfoStrings.PLUGINS_URL)); - FileConfiguration cfg = YamlConfiguration.loadConfiguration(url.openStream()); - - // Iterate over all plugins that are online avialable - for (String key : cfg.getConfigurationSection("plugins").getKeys(false)) { - String name = cfg.getString("plugins." + key + ".name"); - String pluginUrl = cfg.getString("plugins." + key + ".url"); - String fileName = cfg.getString("plugins." + key + ".filename"); - boolean active = false; - - try { - Path path = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, fileName); - if (Files.exists(path)) - active = true; - } catch (Exception e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Plugins_Download, name), PlayPadMain.stageIcon); - } - - Plugin plugin = new Plugin(name, fileName, pluginUrl, active); - plugins.add(plugin); - } - - Collections.sort(plugins, (o1, o2) -> o1.getName().compareTo(o2.getName())); - pluginListView.getItems().addAll(plugins); + String pluginInfoURL = ApplicationUtils.getApplication().getInfo().getUserInfo().getString(AppUserInfoStrings.PLUGINS_URL); + Plugin.load(pluginInfoURL); + + Collections.sort(Plugin.getPlugins()); + pluginListView.getItems().addAll(Plugin.getPlugins()); } catch (IOException e) { e.printStackTrace(); showErrorMessage(Localization.getString(Strings.Error_Standard_Gen), PlayPadMain.stageIcon); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PresetsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/PresetsViewController.java deleted file mode 100644 index 27ce636e43cbf202d9cbb3b871b47ae8afcdfa71..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/PresetsViewController.java +++ /dev/null @@ -1,388 +0,0 @@ -package de.tobias.playpad.viewcontroller; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.PseudoClasses; -import de.tobias.playpad.Strings; -import de.tobias.playpad.settings.MidiPreset; -import de.tobias.playpad.settings.MidiSettings; -import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.viewcontroller.cell.PresetCell; -import de.tobias.utils.application.ApplicationUtils; -import de.tobias.utils.application.container.PathType; -import de.tobias.utils.ui.NotificationHandler; -import de.tobias.utils.ui.ViewController; -import de.tobias.utils.ui.scene.NotificationPane; -import de.tobias.utils.util.Localization; -import de.tobias.utils.util.Worker; -import javafx.application.Platform; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.CheckBox; -import javafx.scene.control.Label; -import javafx.scene.control.ListView; -import javafx.scene.control.TextField; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyCodeCombination; -import javafx.scene.input.KeyCombination; -import javafx.scene.layout.AnchorPane; -import javafx.stage.FileChooser; -import javafx.stage.FileChooser.ExtensionFilter; -import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.stage.Window; - -public class PresetsViewController extends ViewController implements NotificationHandler { - - @FXML private AnchorPane presetsContainer; - @FXML private AnchorPane presetsAnchorPane; - - @FXML private ListView<MidiPreset> presetsListView; - - @FXML private TextField nameTextField; - @FXML private CheckBox partlyCheckBox; - @FXML private CheckBox activeCheckBox; - @FXML private TextField pageTextField; - - @FXML private Button addButton; - @FXML private Button removeButton; - @FXML private Button importButton; - @FXML private Button exportButton; - @FXML private Button duplicateButton; - @FXML private Button defaultButton; - - @FXML private Button finishButton; - - private NotificationPane notificationPane; - private MidiSettings midiSettings; - - public PresetsViewController(Window window) { - super("presetsView", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle()); - getStage().initOwner(window); - - presetsListView.setItems(midiSettings.getPresets()); - for (MidiPreset preset : midiSettings.getPresets()) { - if (preset.isActive()) { - presetsListView.getSelectionModel().select(preset); - break; - } - } - - if (midiSettings.getPresets().size() == 1) { - removeButton.setDisable(true); - } - } - - @Override - public void init() { - notificationPane = new NotificationPane(presetsAnchorPane); - notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK); - presetsContainer.getChildren().add(notificationPane); - setAnchor(notificationPane, 0, 0, 0, 0); - - presetsListView.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Preset))); - - // Ausgewählte in der Liste rechts zeigen und Button disablen - presetsListView.getSelectionModel().selectedItemProperty().addListener((a, b, c) -> - { - showPreset(c); - if (c == null) { - exportButton.setDisable(true); - if (midiSettings.getPresets().size() <= 1) - removeButton.setDisable(true); - } else { - removeButton.setDisable(false); - exportButton.setDisable(false); - } - }); - - // Name des Presets aktualisieren - nameTextField.textProperty().addListener((a, b, c) -> - { - MidiPreset item = getSelectedMidiPreset(); - if (item != null) { - item.setName(c); - } - }); - - activeCheckBox.selectedProperty().addListener((a, b, c) -> - { - MidiPreset preset = getSelectedMidiPreset(); - if (c) { - disableInvalidPresets(true, getSelectedMidiPreset(), midiSettings); - } - if (preset != null) { - preset.setActive(c); - } - }); - - partlyCheckBox.selectedProperty().addListener((a, b, c) -> - { - MidiPreset item = getSelectedMidiPreset(); - if (item != null) { - item.setPartly(c); - } - }); - - pageTextField.textProperty().addListener((a, b, c) -> - { - MidiPreset preset = getSelectedMidiPreset(); - if (preset != null) { - // Model Update - if (c.isEmpty()) { - preset.setPage(-1); - } else { - try { - int page = Integer.valueOf(c) - 1; - preset.setPage(page); - pageTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false); - } catch (NumberFormatException e) { - pageTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); - } - } - - // Kollision zeigen - if (preset.isActive()) { - disableInvalidPresets(false, getSelectedMidiPreset(), midiSettings); - } - } - }); - - presetsListView.setCellFactory(item -> new PresetCell()); - - getStage().getScene().getAccelerators().put(new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN), - () -> Platform.runLater(() -> getStage().close())); - } - - public static List<MidiPreset> disableInvalidPresets(boolean disable, MidiPreset preset, MidiSettings midiSettings) { - List<MidiPreset> disabledPresets = new ArrayList<>(); - - // Neues Preset ist Global -> alle anderen weg - if (preset.getPage() == -1) { - for (MidiPreset item : midiSettings.getPresets()) { - if (item != preset) { - if (item.isActive()) { - if (disable) { - item.setActive(false); - } - disabledPresets.add(item); - } - } - } - } else { - for (MidiPreset item : midiSettings.getPresets()) { - if (item != preset) { - if (item.isActive() && item.getPage() == -1 || item.isActive() && item.getPage() == preset.getPage()) { - if (disable) { - item.setActive(false); - } - disabledPresets.add(item); - } - } - } - } - return disabledPresets; - } - - @Override - public void initStage(Stage stage) { - PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add); - - stage.setMinWidth(600); - stage.setMinHeight(400); - stage.setTitle(Localization.getString(Strings.UI_Dialog_Preset_Title)); - - Profile.currentProfile().currentLayout().applyCss(getStage()); - } - - private void showPreset(MidiPreset midiPreset) { - if (midiPreset != null) { - nameTextField.setText(midiPreset.getName()); - activeCheckBox.setSelected(midiPreset.isActive()); - partlyCheckBox.setSelected(midiPreset.isPartly()); - if (midiPreset.getPage() != -1) { - pageTextField.setText(String.valueOf(midiPreset.getPage() + 1)); - } else { - pageTextField.clear(); - } - activeCheckBox.setDisable(false); - partlyCheckBox.setDisable(false); - } else { - nameTextField.setText(null); - activeCheckBox.setSelected(false); - partlyCheckBox.setSelected(false); - pageTextField.clear(); - activeCheckBox.setDisable(true); - partlyCheckBox.setDisable(true); - } - } - - @FXML - private void addButtonHandler(ActionEvent event) { - MidiPreset preset = new MidiPreset(); - midiSettings.getPresets().add(preset); - if (midiSettings.getPresets().size() > 1) { - removeButton.setDisable(false); - } - presetsListView.getSelectionModel().select(preset); - } - - @FXML - private void removeButtonHandler(ActionEvent event) { - midiSettings.getPresets().remove(presetsListView.getSelectionModel().getSelectedIndex()); - if (midiSettings.getPresets().size() == 1) { - removeButton.setDisable(true); - } - } - - @FXML - private void finishButtonHandler(ActionEvent event) { - getStage().close(); - } - - @FXML - private void importButtonHandler(ActionEvent event) { - FileChooser chooser = new FileChooser(); - chooser.getExtensionFilters().add(new ExtensionFilter(Localization.getString(Strings.File_Filter_Preset), PlayPadMain.midiPresetType)); - File file = chooser.showOpenDialog(getStage()); - if (file != null) { - Path path = file.toPath(); - - Worker.runLater(() -> - { - try { - MidiPreset preset = midiSettings.importMidiPreset(path); - preset.setActive(false); // DEFAULT nicht Active - Platform.runLater(() -> - { - if (midiSettings.getPresets().size() == 1) { - removeButton.setDisable(true); - } else { - removeButton.setDisable(false); - } - - notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.notificationDisplayTimeMillis); - }); - - } catch (Exception e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Preset_Import, e.getLocalizedMessage())); - } - }); - } - } - - @FXML - private void exportButtonHandler(ActionEvent event) { - MidiPreset preset = getSelectedMidiPreset(); - if (preset != null) { - FileChooser chooser = new FileChooser(); - - ExtensionFilter filter = new ExtensionFilter(Localization.getString(Strings.File_Filter_Preset), PlayPadMain.midiPresetType); - chooser.getExtensionFilters().add(filter); - - File file = chooser.showSaveDialog(getStage()); - if (file != null) { - Path path = file.toPath(); - - Worker.runLater(() -> - { - try { - midiSettings.exportMidiPreset(path, preset); - notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.notificationDisplayTimeMillis); - } catch (IOException e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Preset_Export, e.getLocalizedMessage())); - } - }); - } - } - } - - private MidiPreset getSelectedMidiPreset() { - return presetsListView.getSelectionModel().getSelectedItem(); - } - - @FXML - private void duplicateButtonHandler() { - MidiPreset preset = getSelectedMidiPreset(); - try { - MidiPreset preset2 = preset.clone(); - preset2.setName(Localization.getString(Strings.Standard_Copy, preset2.getName())); - preset2.setActive(false); - -// Profile.currentProfile().getMidiSetting().getPresets().add(preset2); - presetsListView.getSelectionModel().select(preset2); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - } - - @FXML - private void defaultButtonHandler() { - Alert alert = new Alert(AlertType.CONFIRMATION); - - Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow(); - PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add); - alert.initOwner(getStage()); - alert.initModality(Modality.WINDOW_MODAL); - - alert.setContentText(Localization.getString(Strings.Info_Settings_Preset_RestoreDefaults)); - alert.showAndWait().filter(button -> button == ButtonType.OK).ifPresent(button -> - { - try { - Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, Profile.currentProfile().getName(), "Midi.xml"); - midiSettings.createDefaultSettings(path); - } catch (Exception e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Preset_RestoreDefaults, e.getLocalizedMessage())); - } - }); - } - - // UI Info - @Override - public void notify(String text, long duration) { - if (Platform.isFxApplicationThread()) { - notificationPane.showAndHide(text, duration); - } else { - Platform.runLater(() -> notificationPane.showAndHide(text, duration)); - } - } - - @Override - public void notify(String text, long duration, Runnable finish) { - if (Platform.isFxApplicationThread()) { - notificationPane.showAndHide(text, duration, finish); - } else { - Platform.runLater(() -> notificationPane.showAndHide(text, duration, finish)); - } - } - - @Override - public void showError(String message) { - if (Platform.isFxApplicationThread()) { - notificationPane.showError(message); - } else { - Platform.runLater(() -> notificationPane.showError(message)); - } - } - - @Override - public void hide() { - if (Platform.isFxApplicationThread()) { - notificationPane.hide(); - } else { - Platform.runLater(() -> notificationPane.hide()); - } - } -} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java index b1ea5a801ab150ac7a2ceef4194d96c8f5a871e4..8406d56263a26a169e89365c5a09141629a35a6d 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java @@ -57,17 +57,32 @@ public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boole public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { Path path = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, plugin.getFileName()); if (newValue) { // Wurde Aktiviert - if (Files.notExists(path)) { - try { - Files.createDirectories(path.getParent()); - Files.copy(new URL(plugin.getUrl()).openStream(), path); - } catch (IOException e) { - e.printStackTrace(); + downloadPlugin(plugin, path); + + // Dependencies + for (String dependencyName : plugin.getDependencies()) { + for (Plugin plugin : Plugin.getPlugins()) { + if (plugin.getName().equals(dependencyName)) { + Path decPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, plugin.getFileName()); + downloadPlugin(plugin, decPath); + } } } + manager.addPluginsFrom(path.toUri()); } else { PlayPadMain.addDeletedPlugin(path); } } + + private void downloadPlugin(Plugin plugin, Path path) { + if (Files.notExists(path)) { + try { + Files.createDirectories(path.getParent()); + Files.copy(new URL(plugin.getUrl()).openStream(), path); + } catch (IOException e) { + e.printStackTrace(); + } + } + } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java index 601212b6d9566e905d331b046322e06bdac4e26d..25a1cc9ceee850e0f0ecbb6ce98d61d49ce3301f 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java @@ -5,10 +5,8 @@ import javafx.scene.control.Control; import javafx.scene.control.TableCell; import javafx.scene.text.Text; - public class ErrorCell extends TableCell<PadException, String> { - public ErrorCell() { Text text = new Text(); text.getStyleClass().add("label"); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java index 4dd2458946d4ff8295964d8f282105bccd916efe..483f161325b4b2555cb54a6fec8b59aa7e176f23 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java @@ -12,12 +12,16 @@ import de.tobias.playpad.pad.conntent.UnkownPadContentException; import de.tobias.playpad.view.ExceptionButton; import de.tobias.utils.util.FileUtils; import javafx.scene.control.Button; +import javafx.scene.control.Control; import javafx.scene.control.TableCell; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; import javafx.stage.Stage; public class FixCell extends TableCell<PadException, PadException> { private Stage stage; + private VBox vbox; public FixCell(Stage stage) { this.stage = stage; @@ -26,6 +30,8 @@ public class FixCell extends TableCell<PadException, PadException> { @Override protected void updateItem(PadException item, boolean empty) { super.updateItem(item, empty); + + vbox = new VBox(); if (!empty) { switch (item.getType()) { case FILE_NOT_FOUND: @@ -51,7 +57,7 @@ public class FixCell extends TableCell<PadException, PadException> { } } }); - setGraphic(notExistsButton); + vbox.getChildren().add(notExistsButton); break; case FILE_FORMAT_NOT_SUPPORTED: @@ -78,12 +84,31 @@ public class FixCell extends TableCell<PadException, PadException> { } } }); - setGraphic(supportButton); + vbox.getChildren().add(supportButton); break; default: break; } + + ExceptionButton<Path> deleteExButton = ExceptionButton.DELETE_EXCEPTION; + Button deleteButton = deleteExButton.getButton(); + deleteButton.setOnAction(a -> + { + deleteExButton.getHandler().handle(item.getPad(), stage); + item.getPad().getProject().removeException(item); + }); + vbox.getChildren().add(deleteButton); + + vbox.setSpacing(7); + vbox.getChildren().forEach(node -> + { + if (node instanceof Control) + ((Control) node).setMaxWidth(Double.MAX_VALUE); + VBox.setVgrow(node, Priority.ALWAYS); + }); + + setGraphic(vbox); } else { setGraphic(null); } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java deleted file mode 100644 index 76304d7e8af88fdd4e580be3d389bb8530333958..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DragAndDropDialog.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.tobias.playpad.viewcontroller.dialog; - -import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.Strings; -import de.tobias.utils.util.Localization; -import javafx.scene.control.ButtonBar.ButtonData; -import javafx.scene.control.ButtonType; -import javafx.scene.control.CheckBox; -import javafx.scene.control.Dialog; -import javafx.scene.control.Label; -import javafx.scene.image.ImageView; -import javafx.scene.layout.VBox; -import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.stage.Window; - -public class DragAndDropDialog extends Dialog<Void> { - - private CheckBox displayOnceCheckBox; - - public DragAndDropDialog(Window owner) { - setHeaderText(Localization.getString(Strings.UI_Dialog_DragAndDrop_Header)); - setGraphic(new ImageView("org/controlsfx/dialog/dialog-information.png")); - - Label textLabel = new Label(Localization.getString(Strings.UI_Dialog_DragAndDrop_Content)); - textLabel.setWrapText(true); - textLabel.setMaxWidth(450); - ImageView view = new ImageView("de/tobias/playpad/assets/files/dialogDnD.png"); - - displayOnceCheckBox = new CheckBox(Localization.getString(Strings.UI_Standard_DoNotShow)); - - VBox box = new VBox(textLabel, view, displayOnceCheckBox); - box.setSpacing(10); - getDialogPane().setContent(box); - - ButtonType buttonTypeOk = new ButtonType(Localization.getString(Strings.UI_Dialog_DragAndDrop_Button), ButtonData.OK_DONE); - getDialogPane().getButtonTypes().add(buttonTypeOk); - - initOwner(owner); - initModality(Modality.WINDOW_MODAL); - Stage dialogStage = (Stage) getDialogPane().getScene().getWindow(); - PlayPadMain.stageIcon.ifPresent(dialogStage.getIcons()::add); - } - - public boolean isPermanentSelected() { - return displayOnceCheckBox.isSelected(); - } -} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java index d8f79dd00d3b4a2034c3973a59195b8f88e5ea2a..7e83853ccb61db8e51b022cdde2bb5b7347b557e 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java @@ -57,7 +57,7 @@ public class ErrorSummaryDialog extends ViewController { padColumn.setCellValueFactory(param -> { - StringProperty value = new SimpleStringProperty(param.getValue().getPad().toString()); + StringProperty value = new SimpleStringProperty(param.getValue().getPad().toReadableString()); return value; }); @@ -72,7 +72,7 @@ public class ErrorSummaryDialog extends ViewController { string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(), padException.getPad().getIndexReadable()); else - string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(), padException.getPath()); + string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(), padException.getPath().toString()); } catch (Exception e) { e.printStackTrace(); } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ExportDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectExportDialog.java similarity index 56% rename from PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ExportDialog.java rename to PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectExportDialog.java index eebd0d8ba87e3fe640b0ad3beec4eb82b9065093..134b544ce3667fbfe00eb68a4c376a0356897031 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ExportDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectExportDialog.java @@ -2,10 +2,12 @@ package de.tobias.playpad.viewcontroller.dialog; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.Strings; import de.tobias.playpad.project.ProjectExporter; +import de.tobias.playpad.project.ProjectExporter.ExportView; import de.tobias.playpad.project.ProjectReference; import de.tobias.playpad.settings.Profile; import de.tobias.utils.ui.NotificationHandler; @@ -18,13 +20,14 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; +import javafx.scene.control.ProgressIndicator; import javafx.stage.FileChooser; import javafx.stage.FileChooser.ExtensionFilter; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.Window; -public class ExportDialog extends ViewController { +public class ProjectExportDialog extends ViewController implements ExportView { @FXML private CheckBox profileCheckBox; @FXML private CheckBox mediaCheckBox; @@ -37,7 +40,7 @@ public class ExportDialog extends ViewController { private ProjectReference projectRef; private NotificationHandler notificationHandler; - public ExportDialog(ProjectReference projectRef, Window owner, NotificationHandler notificationHandler) { + public ProjectExportDialog(ProjectReference projectRef, Window owner, NotificationHandler notificationHandler) { super("exportDialog", "de/tobias/playpad/assets/dialog/project/", null, PlayPadMain.getUiResourceBundle()); this.projectRef = projectRef; this.notificationHandler = notificationHandler; @@ -53,7 +56,7 @@ public class ExportDialog extends ViewController { PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add); stage.setTitle(Localization.getString(Strings.UI_Dialog_ProjectExport_Title)); - stage.setWidth(320); + stage.setWidth(375); stage.setHeight(180); Profile.currentProfile().currentLayout().applyCss(getStage()); @@ -67,35 +70,62 @@ public class ExportDialog extends ViewController { @FXML private void saveButtonHandler(ActionEvent event) { FileChooser chooser = new FileChooser(); - chooser.getExtensionFilters() - .add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectCompressedType)); + + // Extensionfilter in FileChooser + String extensionName = Localization.getString(Strings.File_Filter_ZIP); + ExtensionFilter extensionFilter = new ExtensionFilter(extensionName, PlayPadMain.projectZIPType); + chooser.getExtensionFilters().add(extensionFilter); + File file = chooser.showSaveDialog(getStage()); if (file != null) { cancelButton.setDisable(true); + + busyView.getIndicator().setProgress(ProgressIndicator.INDETERMINATE_PROGRESS); busyView.showProgress(true); Worker.runLater(() -> { try { - ProjectExporter.exportProject(projectRef, file.toPath(), profileCheckBox.isSelected(), mediaCheckBox.isSelected()); + Path path = file.toPath(); + boolean includeProject = profileCheckBox.isSelected(); + boolean includeMedia = mediaCheckBox.isSelected(); + + ProjectExporter.exportProject(projectRef, path, includeProject, includeMedia, (ExportView) this); Platform.runLater(() -> { - busyView.showProgress(false); getStage().close(); - notificationHandler.notify(Localization.getString(Strings.Standard_File_Save), - PlayPadMain.notificationDisplayTimeMillis); + + String notificationString = Localization.getString(Strings.Standard_File_Save); + notificationHandler.notify(notificationString, PlayPadMain.displayTimeMillis); }); } catch (IOException e) { + busyView.showProgress(false); + + String errorMessage = Localization.getString(Strings.Error_Project_Export, projectRef.getName(), e.getMessage()); + showErrorMessage(errorMessage, PlayPadMain.stageIcon); e.printStackTrace(); - Platform.runLater(() -> - { - busyView.showProgress(false); - showErrorMessage(Localization.getString(Strings.Error_Project_Export, projectRef.getName(), e.getMessage()), - PlayPadMain.stageIcon); - }); } }); } } + + private int tasks; + private int complete; + + @Override + public void setTasks(int value) { + this.tasks = value; + complete = 0; + } + + @Override + public void tastComplete() { + if (!Platform.isFxApplicationThread()) { + Platform.runLater(() -> tastComplete()); + return; + } + complete++; + busyView.getIndicator().setProgress((float) complete / (float) tasks); + } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java index 33bf43df585597d188dc49079d8c63e3e504a8bc..da665cd08e7700f55e45b36a6cb304696da54146 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java @@ -200,7 +200,7 @@ public class ProjectManagerDialog extends ViewController implements Notification String oldName = projectReference.toString(); try { - String newProjectName = (String) nameTextField.getTextFormatter().getValue(); // Name + XML + String newProjectName = (String) nameTextField.getText(); if (ProjectReference.getProjects().contains(newProjectName) || !nameTextField.getText().matches(Project.projectNameEx)) { showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, nameTextField.getText())); return; @@ -241,16 +241,19 @@ public class ProjectManagerDialog extends ViewController implements Notification @FXML private void importButtonHandler(ActionEvent event) { FileChooser chooser = new FileChooser(); - chooser.getExtensionFilters() - .add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectCompressedType)); + chooser.getExtensionFilters().add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectZIPType)); File file = chooser.showOpenDialog(getStage()); if (file != null) { Path zipFile = file.toPath(); try { - ProjectReference ref = ProjectImporter.importProject(zipFile, ImportDialog.getInstance(getStage()), - ImportDialog.getInstance(getStage())); - projectList.getItems().add(ref); - selectProject(ref); + ImportDialog inportDialog = ImportDialog.getInstance(getStage()); + ProjectReference ref = ProjectImporter.importProject(zipFile, inportDialog, inportDialog); + if (ref != null) { + projectList.getItems().add(ref); + selectProject(ref); + } else { + showErrorMessage(Localization.getString(Strings.Error_Project_Open, "null")); + } } catch (IOException | DocumentException e) { showErrorMessage(Localization.getString(Strings.Error_Project_Open, e.getLocalizedMessage())); e.printStackTrace(); @@ -260,7 +263,18 @@ public class ProjectManagerDialog extends ViewController implements Notification @FXML private void exportButtonHandler(ActionEvent event) { - ExportDialog dialog = new ExportDialog(getSelectedProject(), getStage(), this); + ProjectReference selectedProject = getSelectedProject(); + + // Speicher das Aktuelle Projekt erst, damit es in der Exportmethode seperat neu geladen werden kann + if (currentProject.getRef().equals(selectedProject)) { + try { + currentProject.save(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + ProjectExportDialog dialog = new ProjectExportDialog(selectedProject, getStage(), this); dialog.getStage().show(); } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java index e905a558857e8aa68ed3260bf968260addc08539..2d43a552e31cf04f7a733e6accb2b1061a41fb75 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java @@ -21,7 +21,9 @@ import de.tobias.playpad.project.Project; import de.tobias.playpad.project.ProjectNotFoundException; import de.tobias.playpad.project.ProjectReference; import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.ProfileListener; import de.tobias.playpad.settings.ProfileNotFoundException; +import de.tobias.playpad.settings.ProfileSettings; import de.tobias.playpad.viewcontroller.PluginViewController; import de.tobias.playpad.viewcontroller.PrintDialog; import de.tobias.playpad.viewcontroller.SettingsTabViewController; @@ -41,6 +43,8 @@ import de.tobias.utils.util.OS.OSType; import de.tobias.utils.util.Worker; import de.tobias.utils.util.net.FileUpload; import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; @@ -55,7 +59,7 @@ import javafx.stage.Modality; import javafx.stage.Stage; import net.xeoh.plugins.base.PluginManager; -public class MainMenuBarController implements EventHandler<ActionEvent>, Initializable { +public class MainMenuBarController implements EventHandler<ActionEvent>, Initializable, ProfileListener { @FXML private MenuBar menuBar; @FXML CheckMenuItem dndModeMenuItem; @@ -74,6 +78,8 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial private PluginManager manager; private MainViewController mvc; + private ChangeListener<Boolean> lockedListener; + @Override public void initialize(URL location, ResourceBundle resources) { menuBar.setUseSystemMenuBar(true); @@ -81,6 +87,20 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial if (OS.getType() == OSType.MacOSX) { menuBar.setMaxHeight(0); } + + ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); + Profile.registerListener(this); // Update, wenn sich das Profil ändert (remove Listener & add Listener) + + // Listener + lockedListener = new ChangeListener<Boolean>() { + + @Override + public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { + dndModeMenuItem.setDisable(newValue); + } + }; + profileSettings.lockedProperty().addListener(lockedListener); + lockedListener.changed(profileSettings.lockedProperty(), null, profileSettings.isLocked()); } // Event @@ -136,7 +156,7 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial private void saveMenuHandler(ActionEvent event) { try { mvc.getProject().save(); - mvc.notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.notificationDisplayTimeMillis); + mvc.notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.displayTimeMillis); } catch (IOException e) { mvc.showError(Localization.getString(Strings.Error_Project_Save)); e.printStackTrace(); @@ -173,9 +193,16 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial @FXML private void settingsHandler(ActionEvent event) { Midi midi = Midi.getInstance(); + Project project = mvc.getProject(); + ProfileSettings settings = Profile.currentProfile().getProfileSettings(); + + if (settings.isLiveMode() && settings.isLiveModeSettings() && project.getPlayedPlayers() > 0) { + mvc.showLiveInfo(); + return; + } if (settingsViewController == null) { - settingsViewController = new SettingsViewController(midi, mvc.getScreen(), mvc.getStage(), mvc.getProject()) { + settingsViewController = new SettingsViewController(midi, mvc.getScreen(), mvc.getStage(), project) { @Override public void updateData() { @@ -185,7 +212,7 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial for (SettingsTabViewController controller : tabs) { if (controller.needReload()) { change = true; - controller.reload(Profile.currentProfile(), mvc.getProject(), mvc); + controller.reload(Profile.currentProfile(), project, mvc); } } @@ -224,19 +251,22 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial @FXML private void dndModeHandler(ActionEvent event) { if (dndModeMenuItem.isSelected()) { - doAction(() -> - { + ProfileSettings settings = Profile.currentProfile().getProfileSettings(); + if (settings.isLiveMode() && settings.isLiveModeDrag() && mvc.getProject().getPlayedPlayers() > 0) { + mvc.showLiveInfo(); + } else { PadDragListener.setDndMode(true); for (IPadViewController view : mvc.padViewList) { view.showDnDLayout(true); } - }); + } } else { PadDragListener.setDndMode(false); for (IPadViewController view : mvc.padViewList) { view.showDnDLayout(false); } } + } @FXML @@ -358,4 +388,13 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial this.mvc = mvc; } + @Override + public void reloadSettings(Profile oldProfile, Profile currentProfile) { + if (oldProfile != null) { + oldProfile.getProfileSettings().lockedProperty().removeListener(lockedListener); + } + ProfileSettings profileSettings = currentProfile.getProfileSettings(); + profileSettings.lockedProperty().addListener(lockedListener); + lockedListener.changed(profileSettings.lockedProperty(), null, profileSettings.isLocked()); + } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainToolbarController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainToolbarController.java index 3b582c60879890a4c9184769cdb0d7f3eba2f68a..7936f3b506680756981a0d53f282a4ed5e7772ff 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainToolbarController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainToolbarController.java @@ -5,39 +5,69 @@ import java.util.ResourceBundle; import de.tobias.playpad.Strings; import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.viewcontroller.main.IMainToolbarViewController; +import de.tobias.playpad.settings.ProfileListener; +import de.tobias.playpad.settings.ProfileSettings; import de.tobias.utils.ui.icon.FontAwesomeType; import de.tobias.utils.ui.icon.FontIcon; import de.tobias.utils.util.Localization; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.Slider; import javafx.scene.control.ToolBar; import javafx.scene.layout.HBox; -public class MainToolbarController implements IMainToolbarViewController, Initializable, EventHandler<ActionEvent> { +public class MainToolbarController implements IMainToolbarViewController, Initializable, EventHandler<ActionEvent>, ProfileListener { @FXML private ToolBar toolbar; @FXML private HBox toolbarHBox; @FXML private HBox pageHBox; + @FXML private HBox iconHbox; + private Label lockedLabel; + @FXML private Label volumeDownLabel; @FXML private Slider volumeSlider; @FXML private Label volumeUpLabel; private MainViewController mainViewController; + private ChangeListener<Boolean> lockedListener; + @Override public void initialize(URL location, ResourceBundle resources) { + ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); + Profile.registerListener(this); + + // Listener + lockedListener = new ChangeListener<Boolean>() { + + @Override + public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { + if (newValue) { + iconHbox.getChildren().add(lockedLabel); + } else { + iconHbox.getChildren().remove(lockedLabel); + } + } + }; + profileSettings.lockedProperty().addListener(lockedListener); // HBox Child wird Max Width, subtract weil sonst zu groß für Toolbar toolbarHBox.prefWidthProperty().bind(toolbar.widthProperty().subtract(25)); toolbarHBox.prefHeightProperty().bind(toolbar.minHeightProperty()); + // Info Icons + lockedLabel = new Label(); + lockedLabel.setGraphic(new FontIcon(FontAwesomeType.LOCK)); + lockedListener.changed(profileSettings.lockedProperty(), null, profileSettings.isLocked()); + // Icons Volume volumeDownLabel.setGraphic(new FontIcon("volume-item", FontAwesomeType.VOLUME_DOWN)); volumeUpLabel.setGraphic(new FontIcon("volume-item", FontAwesomeType.VOLUME_UP)); @@ -85,4 +115,25 @@ public class MainToolbarController implements IMainToolbarViewController, Initia mainViewController.showPage(number); } } + + @Override + public void reloadSettings(Profile oldProfile, Profile currentProfile) { + if (oldProfile != null) { + oldProfile.getProfileSettings().lockedProperty().removeListener(lockedListener); + } + ProfileSettings profileSettings = currentProfile.getProfileSettings(); + profileSettings.lockedProperty().addListener(lockedListener); + lockedListener.changed(profileSettings.lockedProperty(), null, profileSettings.isLocked()); + } + + @Override + public void showIcon(Node node) { + iconHbox.getChildren().add(node); + } + + @Override + public void hideIcon(Node node) { + iconHbox.getChildren().remove(node); + } + } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java index 446699eb626512236f428c458424e60a0c7ba394..099975dc2c325b468a4cd510d78db7e2f43a6836 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java @@ -10,6 +10,7 @@ import javax.sound.midi.MidiUnavailableException; import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.Strings; +import de.tobias.playpad.action.Mapping; import de.tobias.playpad.action.cartaction.CartAction; import de.tobias.playpad.action.connect.CartActionConnect; import de.tobias.playpad.action.feedback.ColorAssociator; @@ -44,6 +45,7 @@ import de.tobias.utils.util.OS; import de.tobias.utils.util.OS.OSType; import de.tobias.utils.util.Worker; import javafx.application.Platform; +import javafx.beans.property.DoubleProperty; import javafx.fxml.FXML; import javafx.scene.Group; import javafx.scene.Node; @@ -149,6 +151,7 @@ public class MainViewController extends ViewController implements IMainViewContr // Setup Settings reloadSettings(null, Profile.currentProfile()); + // Listener listener.forEach(l -> l.onInit(this)); } @@ -181,7 +184,8 @@ public class MainViewController extends ViewController implements IMainViewContr private void setPadVolume(double volume) { for (Pad pad : project.getPads().values()) { - pad.setMasterVolume(volume); + if (pad != null) + pad.setMasterVolume(volume); } } @@ -196,6 +200,12 @@ public class MainViewController extends ViewController implements IMainViewContr @Override public void initStage(Stage stage) { + stage.fullScreenProperty().addListener((a, b, c) -> + { + if (Profile.currentProfile() != null) + stage.setAlwaysOnTop(Profile.currentProfile().getProfileSettings().isWindowAlwaysOnTop()); + }); + PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add); stage.setFullScreenExitKeyCombination(KeyCombination.keyCombination(KeyCombination.SHIFT_DOWN + "+Esc")); stage.setTitle(Localization.getString(Strings.UI_Window_Main_Title)); @@ -228,6 +238,7 @@ public class MainViewController extends ViewController implements IMainViewContr for (IPadViewController controller : padViewList) { controller.unconnectPad(); } + // Speichert das alte Projekt, bevor ein neues geladen wird try { this.project.save(); } catch (IOException e) { @@ -252,53 +263,57 @@ public class MainViewController extends ViewController implements IMainViewContr applyColorsToMappers(); } - private void applyColorsToMappers() { + public void applyColorsToMappers() { // Apply Layout to Mapper List<CartAction> actions = Profile.currentProfile().getMappings().getActiveMapping().getActions(CartActionConnect.TYPE); for (CartAction cartAction : actions) { if (cartAction.isAutoFeedbackColors()) { for (Mapper mapper : cartAction.getMappers()) { if (mapper instanceof MapperFeedbackable) { - MapperFeedbackable feedbackable = (MapperFeedbackable) mapper; - if (feedbackable.supportFeedback() && mapper instanceof ColorAssociator) { - ColorAssociator colorAssociator = (ColorAssociator) mapper; - - Pad pad = project.getPad(cartAction.getCart()); - Color layoutStandardColor = null; - Color layoutEventColor = null; - - if (pad.isCustomLayout()) { - CartLayout layout = pad.getLayout(); - if (layout instanceof LayoutColorAssociator) { - layoutStandardColor = ((LayoutColorAssociator) layout).getAssociatedStandardColor(); - layoutEventColor = ((LayoutColorAssociator) layout).getAssociatedEventColor(); - } - } else { - GlobalLayout layout = Profile.currentProfile().currentLayout(); - if (layout instanceof LayoutColorAssociator) { - layoutStandardColor = ((LayoutColorAssociator) layout).getAssociatedStandardColor(); - layoutEventColor = ((LayoutColorAssociator) layout).getAssociatedEventColor(); - } - } - - if (layoutStandardColor != null) { - DisplayableFeedbackColor associator = Mapper.searchColor(colorAssociator, FeedbackMessage.STANDARD, - layoutStandardColor); - colorAssociator.setColor(FeedbackMessage.STANDARD, associator.midiVelocity()); - } - - if (layoutEventColor != null) { - DisplayableFeedbackColor associator = Mapper.searchColor(colorAssociator, FeedbackMessage.EVENT, - layoutEventColor); - colorAssociator.setColor(FeedbackMessage.EVENT, associator.midiVelocity()); - } - } + mapColorForMapper(cartAction, mapper); } } } } } + private void mapColorForMapper(CartAction cartAction, Mapper mapper) { + MapperFeedbackable feedbackable = (MapperFeedbackable) mapper; + if (feedbackable.supportFeedback() && mapper instanceof ColorAssociator) { + ColorAssociator colorAssociator = (ColorAssociator) mapper; + + Pad pad = project.getPad(cartAction.getCart()); + Color layoutStdColor = null; + Color layoutEvColor = null; + + if (pad.isCustomLayout()) { + CartLayout layout = pad.getLayout(); + if (layout instanceof LayoutColorAssociator) { + LayoutColorAssociator associator = (LayoutColorAssociator) layout; + layoutStdColor = associator.getAssociatedStandardColor(); + layoutEvColor = associator.getAssociatedEventColor(); + } + } else { + GlobalLayout layout = Profile.currentProfile().currentLayout(); + if (layout instanceof LayoutColorAssociator) { + LayoutColorAssociator associator = (LayoutColorAssociator) layout; + layoutStdColor = associator.getAssociatedStandardColor(); + layoutEvColor = associator.getAssociatedEventColor(); + } + } + + if (layoutStdColor != null) { + DisplayableFeedbackColor associator = Mapper.searchColor(colorAssociator, FeedbackMessage.STANDARD, layoutStdColor); + colorAssociator.setColor(FeedbackMessage.STANDARD, associator.midiVelocity()); + } + + if (layoutEvColor != null) { + DisplayableFeedbackColor associator = Mapper.searchColor(colorAssociator, FeedbackMessage.EVENT, layoutEvColor); + colorAssociator.setColor(FeedbackMessage.EVENT, associator.midiVelocity()); + } + } + } + /** * Erstellt Constraints von GridView, Erstellt PadViews, Lädt CSS, Set Min Size vom Fendster */ @@ -347,11 +362,15 @@ public class MainViewController extends ViewController implements IMainViewContr } // Min Size of window - getStage().setMinWidth(Profile.currentProfile().currentLayout().getMinWidth(profileSettings.getColumns())); + GlobalLayout currentLayout = Profile.currentProfile().currentLayout(); + double minWidth = currentLayout.getMinWidth(profileSettings.getColumns()); + double minHeight = currentLayout.getMinHeight(profileSettings.getRows()); + + getStage().setMinWidth(minWidth); if (OS.getType() == OSType.MacOSX) { - getStage().setMinHeight(Profile.currentProfile().currentLayout().getMinHeight(profileSettings.getRows()) + 100); + getStage().setMinHeight(minHeight + 100); } else { - getStage().setMinHeight(Profile.currentProfile().currentLayout().getMinHeight(profileSettings.getRows()) + 150); + getStage().setMinHeight(minHeight + 150); } } @@ -367,6 +386,12 @@ public class MainViewController extends ViewController implements IMainViewContr return; } + ProfileSettings settings = Profile.currentProfile().getProfileSettings(); + if (settings.isLiveMode() && settings.isLiveModePage() && getProject().getPlayedPlayers() > 0) { + showLiveInfo(); + return; + } + // Button in Toolbar Button oldButton = (Button) toolbarController.getPageHBox().getChildren().get(pageNumber); // Der Aktuell andersfarbende Button oldButton.getStyleClass().remove(CURRENT_PAGE_BUTTON); @@ -411,7 +436,8 @@ public class MainViewController extends ViewController implements IMainViewContr if (Profile.currentProfile() != null) { ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings(); - // Frag den Nutzer ob das Programm wirdklich geschlossen werden sol wenn ein Pad noch im Status Play ist + // Frag den Nutzer ob das Programm wirdklich geschlossen werden sol + // wenn ein Pad noch im Status Play ist if (project.getPlayedPlayers() > 0 && profilSettings.isLiveMode()) { Alert alert = new Alert(AlertType.CONFIRMATION); alert.setContentText(Localization.getString(Strings.UI_Window_Main_CloseRequest)); @@ -427,10 +453,57 @@ public class MainViewController extends ViewController implements IMainViewContr return false; } + Alert alert = new Alert(AlertType.CONFIRMATION); + alert.setContentText(Localization.getString(Strings.UI_Window_Main_SaveRequest)); + alert.getButtonTypes().setAll(ButtonType.CANCEL, ButtonType.NO, ButtonType.YES); + + Button yesButton = (Button) alert.getDialogPane().lookupButton(ButtonType.YES); + yesButton.defaultButtonProperty().bind(yesButton.focusedProperty()); + + Button noButton = (Button) alert.getDialogPane().lookupButton(ButtonType.NO); + noButton.defaultButtonProperty().bind(noButton.focusedProperty()); + + Button cancelButton = (Button) alert.getDialogPane().lookupButton(ButtonType.CANCEL); + cancelButton.defaultButtonProperty().bind(cancelButton.focusedProperty()); + + alert.initOwner(getStage()); + alert.initModality(Modality.WINDOW_MODAL); + Stage alertStage = (Stage) alert.getDialogPane().getScene().getWindow(); + PlayPadMain.stageIcon.ifPresent(alertStage.getIcons()::add); + + Optional<ButtonType> result = alert.showAndWait(); + if (result.isPresent()) { + ButtonType buttonType = result.get(); + if (buttonType == ButtonType.YES) { + // Projekt Speichern + try { + if (project.getRef() != null) { + project.save(); + System.out.println("Saved Project: " + project); + } + } catch (Exception e) { + e.printStackTrace(); + showErrorMessage(Localization.getString(Strings.Error_Project_Save)); + } + } else if (buttonType == ButtonType.CANCEL) { + return false; + } + } + + // Save Config - Its unabhängig vom Dialog, da es auch an anderen Stellen schon gespeichert wird + try { + if (Profile.currentProfile() != null) + Profile.currentProfile().save(); + } catch (Exception e) { + e.printStackTrace(); + showErrorMessage(Localization.getString(Strings.Error_Profile_Save)); + } + // Mapper Clear Feedback Profile.currentProfile().getMappings().getActiveMapping().clearFeedback(); // MIDI Shutdown + // Der schließt MIDI, da er es auch öffnet und verantwortlich ist if (profilSettings.isMidiActive()) { try { midi.close(); @@ -440,17 +513,17 @@ public class MainViewController extends ViewController implements IMainViewContr } } - if (getStage().isIconified()) { + if ( + + getStage().isIconified()) { getStage().setIconified(false); } - // Verbindung von Pad und PadView wird getrennt. Zudem wird bei PLAY oder PAUSE auf STOP gesetzt + // Verbindung von Pad und PadView wird getrennt. Zudem wird bei PLAY + // oder PAUSE auf STOP gesetzt padViewList.forEach(padView -> padView.unconnectPad()); saveSettings(); - - Worker.shutdown(); - System.exit(0); return true; } @@ -469,8 +542,7 @@ public class MainViewController extends ViewController implements IMainViewContr private void loadMidiDevice(String name) { try { midi.lookupMidiDevice(name); - notificationPane.showAndHide(Localization.getString(Strings.Info_Midi_Device_Connected, name), - PlayPadMain.notificationDisplayTimeMillis); + notificationPane.showAndHide(Localization.getString(Strings.Info_Midi_Device_Connected, name), PlayPadMain.displayTimeMillis); } catch (NullPointerException e) { showError(Localization.getString(Strings.Error_Midi_Device_Unavailible, name)); } catch (IllegalArgumentException | MidiUnavailableException e) { @@ -522,7 +594,7 @@ public class MainViewController extends ViewController implements IMainViewContr private boolean shown = false; - protected void showLiveInfo() { + public void showLiveInfo() { if (!shown) { toolbarController.getToolbarHBox().setOpacity(0.5); liveLabel.setVisible(true); @@ -530,7 +602,7 @@ public class MainViewController extends ViewController implements IMainViewContr Worker.runLater(() -> { try { - Thread.sleep(PlayPadMain.notificationDisplayTimeMillis * 2); + Thread.sleep(PlayPadMain.displayTimeMillis * 2); } catch (Exception e) {} Platform.runLater(() -> { @@ -544,9 +616,11 @@ public class MainViewController extends ViewController implements IMainViewContr @Override public void reloadSettings(Profile old, Profile currentProfile) { + final DoubleProperty valueProperty = toolbarController.getVolumeSlider().valueProperty(); + if (old != null) { // Unbind Volume Slider - toolbarController.getVolumeSlider().valueProperty().unbindBidirectional(old.getProfileSettings().volumeProperty()); + valueProperty.unbindBidirectional(old.getProfileSettings().volumeProperty()); // Clear Feedback on Devie (LaunchPad Light off) old.getMappings().getActiveMapping().getActions().forEach(action -> action.clearFeedback()); } @@ -556,44 +630,37 @@ public class MainViewController extends ViewController implements IMainViewContr toolbarController.createPageButtons(); // Volume - toolbarController.getVolumeSlider().valueProperty().bindBidirectional(currentProfile.getProfileSettings().volumeProperty()); + valueProperty.bindBidirectional(currentProfile.getProfileSettings().volumeProperty()); - // Apply Layout - currentProfile.currentLayout().applyCssMainView(this, getStage(), project); + final ProfileSettings profilSettings = currentProfile.getProfileSettings(); + final Mapping activeMapping = currentProfile.getMappings().getActiveMapping(); // MIDI - ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings(); - if (profilSettings.isMidiActive()) { + if (profilSettings.isMidiActive() && profilSettings.getMidiDevice() != null) { // Load known MIDI Device Worker.runLater(() -> { - if (profilSettings.getMidiDevice() != null) { - loadMidiDevice(profilSettings.getMidiDevice()); + loadMidiDevice(profilSettings.getMidiDevice()); - applyColorsToMappers(); + applyColorsToMappers(); - Platform.runLater(() -> - { - // Handle Mapper - if (Profile.currentProfile() != null) { - Profile.currentProfile().getMappings().getActiveMapping().initFeedback(); - Profile.currentProfile().getMappings().getActiveMapping().showFeedback(project, this); - } - }); - } + Platform.runLater(() -> + { + // Handle Mapper + if (Profile.currentProfile() != null) { + activeMapping.initFeedback(); + activeMapping.showFeedback(project); + } + }); }); } - if (Profile.currentProfile() != null) { - Profile.currentProfile().getMappings().getActiveMapping().showFeedback(project, this); - } - // WINDOW Settings menuBarController.alwaysOnTopItem.setSelected(profilSettings.isWindowAlwaysOnTop()); getStage().setAlwaysOnTop(profilSettings.isWindowAlwaysOnTop()); setTitle(); - showPage(pageNumber); + showPage(pageNumber); // Show Mapper Feedback und apply css und zeigt pads } @Override diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java index 016a35a9570e0492ea51810a9994142e8048a5ab..dedc6b40dec0b564ee47058c1c5783cd093e11ee 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java @@ -20,18 +20,26 @@ import de.tobias.utils.application.container.PathType; import de.tobias.utils.ui.ViewController; import de.tobias.utils.util.Localization; import de.tobias.utils.util.NumberUtils; +import de.tobias.utils.util.Worker; +import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; +import javafx.scene.control.ToggleGroup; import javafx.stage.DirectoryChooser; +import javafx.stage.Modality; import javafx.stage.Screen; +import javafx.stage.Stage; public class GeneralTabViewController extends SettingsTabViewController { private static final String DIGIT_POSITIV = "^[1-9]\\d*$"; - + private Screen mainWindowScreen; private ViewController parentController; // Für Benachrichtungen @@ -44,6 +52,19 @@ public class GeneralTabViewController extends SettingsTabViewController { @FXML private TextField cacheTextField; @FXML private Label cacheSizeLabel; + @FXML private RadioButton pageEnable; + @FXML private RadioButton pageDisable; + @FXML private ToggleGroup pageGroup; + @FXML private RadioButton dragEnable; + @FXML private RadioButton dragDisable; + @FXML private ToggleGroup dragGroup; + @FXML private RadioButton fileEnable; + @FXML private RadioButton fileDisable; + @FXML private ToggleGroup fileGroup; + @FXML private RadioButton settingsEnable; + @FXML private RadioButton settingsDisable; + @FXML private ToggleGroup settingsGroup; + private boolean changeSettings; public GeneralTabViewController(Screen screen, ViewController parentController, boolean activePlayer) { @@ -100,6 +121,31 @@ public class GeneralTabViewController extends SettingsTabViewController { rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Negativ oder leer } }); + + pageGroup = new ToggleGroup(); + pageGroup.getToggles().addAll(pageEnable, pageDisable); + dragGroup = new ToggleGroup(); + dragGroup.getToggles().addAll(dragEnable, dragDisable); + fileGroup = new ToggleGroup(); + fileGroup.getToggles().addAll(fileEnable, fileDisable); + settingsGroup = new ToggleGroup(); + settingsGroup.getToggles().addAll(settingsEnable, settingsDisable); + + liveModeCheckBox.selectedProperty().addListener((a, b, c) -> + { + disableLiveSettings(c); + }); + } + + private void disableLiveSettings(Boolean enableLiveSettings) { + pageEnable.setDisable(!enableLiveSettings); + pageDisable.setDisable(!enableLiveSettings); + dragEnable.setDisable(!enableLiveSettings); + dragDisable.setDisable(!enableLiveSettings); + fileEnable.setDisable(!enableLiveSettings); + fileDisable.setDisable(!enableLiveSettings); + settingsEnable.setDisable(!enableLiveSettings); + settingsDisable.setDisable(!enableLiveSettings); } @FXML @@ -139,9 +185,6 @@ public class GeneralTabViewController extends SettingsTabViewController { @FXML private void resetDialogs(ActionEvent event) { - ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings(); - - profilSettings.setDialogDragAndDrop(true); parentController.showInfoMessage(Localization.getString(Strings.Info_Settings_ResetWarning)); } @@ -188,7 +231,7 @@ public class GeneralTabViewController extends SettingsTabViewController { liveModeCheckBox.setSelected(profileSettings.isLiveMode()); cacheTextField.setText(profileSettings.getCachePath().toString()); - + if (screenValid()) { columnTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false); rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false); @@ -196,6 +239,28 @@ public class GeneralTabViewController extends SettingsTabViewController { columnTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); rowTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); } + + if (profileSettings.isLiveModePage() == true) + pageEnable.setSelected(true); + else + pageDisable.setSelected(true); + + if (profileSettings.isLiveModeDrag() == true) + dragEnable.setSelected(true); + else + dragDisable.setSelected(true); + + if (profileSettings.isLiveModeFile() == true) + fileEnable.setSelected(true); + else + fileDisable.setSelected(true); + + if (profileSettings.isLiveModeSettings() == true) + settingsEnable.setSelected(true); + else + settingsDisable.setSelected(true); + + disableLiveSettings(profileSettings.isLiveMode()); } @Override @@ -218,6 +283,11 @@ public class GeneralTabViewController extends SettingsTabViewController { profileSettings.setLiveMode(liveModeCheckBox.isSelected()); profileSettings.setCachePath(Paths.get(cacheTextField.getText())); + + profileSettings.setLiveModePage(pageEnable.isSelected()); + profileSettings.setLiveModeDrag(dragEnable.isSelected()); + profileSettings.setLiveModeFile(fileEnable.isSelected()); + profileSettings.setLiveModeSettings(settingsEnable.isSelected()); } @Override @@ -227,9 +297,28 @@ public class GeneralTabViewController extends SettingsTabViewController { @Override public void reload(Profile profile, Project project, IMainViewController controller) { - controller.getToolbarController().createPageButtons(); - controller.createPadViews(); - controller.showPage(controller.getPage()); + Alert alert = new Alert(AlertType.INFORMATION); + alert.setContentText(Localization.getString(Strings.UI_Window_Settings_Gen_Wait)); + + alert.getButtonTypes().clear(); + alert.initOwner(controller.getStage()); + alert.initModality(Modality.WINDOW_MODAL); + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add); + + alert.show(); + + Worker.runLater(() -> + { + Platform.runLater(() -> + { + controller.getToolbarController().createPageButtons(); + controller.createPadViews(); + controller.showPage(controller.getPage()); + stage.close(); + }); + }); + } @Override diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/MappingTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MappingTabViewController.java index c8130b66d3f74fa123462ea0ba340cf4a5afcb9f..4b44d1f425920b252a755cc9c0ad766cc0be477a 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/MappingTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MappingTabViewController.java @@ -42,6 +42,7 @@ public class MappingTabViewController extends SettingsTabViewController implemen @FXML private VBox detailView; private IMapperOverviewViewController mapperOverviewViewController; + private Mapping oldMapping; private Mapping mapping; public MappingTabViewController() { @@ -138,6 +139,7 @@ public class MappingTabViewController extends SettingsTabViewController implemen // Tab Utils @Override public void loadSettings(Profile profile) { + oldMapping = profile.getMappings().getActiveMapping(); setMappingItemsToList(); createTreeViewContent(); } @@ -152,9 +154,13 @@ public class MappingTabViewController extends SettingsTabViewController implemen @Override public void reload(Profile profile, Project project, IMainViewController controller) { - Profile.currentProfile().getMappings().getActiveMapping().clearFeedback(); - Profile.currentProfile().getMappings().getActiveMapping().showFeedback(project, controller); - Profile.currentProfile().getMappings().getActiveMapping().initFeedback(); + controller.applyColorsToMappers(); + + Mapping activeMapping = Profile.currentProfile().getMappings().getActiveMapping(); + + oldMapping.clearFeedback(); + activeMapping.showFeedback(project); + activeMapping.initFeedback(); } @Override diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java deleted file mode 100644 index 796c012dc814fa5a745fe6f489cb296f114838d7..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/MidiTabViewController2.java +++ /dev/null @@ -1,641 +0,0 @@ -package de.tobias.playpad.viewcontroller.option; - -import java.util.Collections; -import java.util.Optional; - -import javax.sound.midi.InvalidMidiDataException; -import javax.sound.midi.MidiDevice.Info; -import javax.sound.midi.MidiMessage; -import javax.sound.midi.MidiUnavailableException; - -import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.Strings; -import de.tobias.playpad.action.mididevice.Device; -import de.tobias.playpad.midi.Midi; -import de.tobias.playpad.midi.MidiListener; -import de.tobias.playpad.model.Project; -import de.tobias.playpad.model.midi.Displayable; -import de.tobias.playpad.model.midi.MidiAction; -import de.tobias.playpad.model.midi.SubAction; -import de.tobias.playpad.model.midi.type.MidiKeyActionType; -import de.tobias.playpad.model.midi.type.MidiKeyActionTypes; -import de.tobias.playpad.model.midi.type.MidiKeyActionTypes.MidiKeyActionTypeStore; -import de.tobias.playpad.plugin.viewcontroller.IMainViewController; -import de.tobias.playpad.plugin.viewcontroller.IMidiTabViewController; -import de.tobias.playpad.plugin.viewcontroller.SettingsTabViewController; -import de.tobias.playpad.settings.MidiPreset; -import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.settings.ProfileSettings; -import de.tobias.playpad.viewcontroller.PresetsViewController; -import de.tobias.utils.ui.ContentViewController; -import de.tobias.utils.ui.NotificationHandler; -import de.tobias.utils.ui.ViewController; -import de.tobias.utils.ui.scene.NotificationPane; -import de.tobias.utils.util.Localization; -import javafx.application.Platform; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.Parent; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Label; -import javafx.scene.control.TreeItem; -import javafx.scene.control.TreeView; -import javafx.scene.layout.AnchorPane; -import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.stage.Window; - -public class MidiTabViewController2 extends SettingsTabViewController - implements IMidiTabViewController, MidiListener, NotificationHandler, ChangeListener<TreeItem<Displayable>> { - - @FXML private AnchorPane rootPane; - private NotificationPane notificationPane; - - @FXML private CheckBox midiActiveCheckBox; - @FXML private ComboBox<String> deviceComboBox; - - @FXML private ComboBox<MidiPreset> presetsList; - @FXML private Button presetsEditButton; - @FXML private Button activateButton; - - @FXML private Button addMidiButton; - @FXML private Button addMidiDraftButton; - @FXML private Button draftButton; - @FXML private Button deleteMidiButton; - @FXML private Button clearMidiButton; - - @FXML private TreeView<Displayable> contentTreeView; - @FXML private ComboBox<MidiKeyActionTypeStore> midiActionTypeComboBox; - @FXML private AnchorPane settingsAnchorPane; - - // Midi Record - private boolean recordMidi; - private boolean useDraft; - private org.controlsfx.control.action.Action midiRecordCancelAction; - - private final Window owner; - - public MidiTabViewController2(Window owner) { - super("midiTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle()); - this.owner = owner; - - owner.setOnShown(event -> - { - if (!Midi.getInstance().isOpen() && Profile.currentProfile().getProfileSettings().isMidiActive()) { - showError(Localization.getString(Strings.Info_Settings_Midi_NoDevice)); - } - updateButtonDisable(); - if (!Profile.currentProfile().getMidiSetting().getDraftAction().isPresent()) { - addMidiDraftButton.setDisable(true); - } - }); - - // Midi Listener auf Einstellungen - Midi.getInstance().setListener(this); - } - - @Override - public void init() { - // Notifiation Pane - midiRecordCancelAction = new org.controlsfx.control.action.Action(Localization.getString(Strings.Actions_Midi_Cancel), event -> - { - recordMidi = false; - notificationPane.hide(); - }); - - notificationPane = new NotificationPane(rootPane); - notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK); - - presetsList.valueProperty().addListener((a, b, c) -> - { - if (c != null) { - Collections.sort(c.getMidiActions()); // sortieren - - // Aktivieren Button ein und aus schalten - if (c.isActive()) { - activateButton.setDisable(true); - } else { - activateButton.setDisable(false); - } - - // items in treeview - showMidiPresetActions(); - } - }); - - // setup persets and select active or first - presetsList.setItems(Profile.currentProfile().getMidiSetting().getPresets()); - presetsList.getSelectionModel().select(0); // Standart Selectend - - for (MidiPreset preset : Profile.currentProfile().getMidiSetting().getPresets()) { // Preset Auswählen - if (preset.isActive()) { - presetsList.getSelectionModel().select(preset); // Wenn aktiv dann selecten - break; - } - } - - // Auswahlliste Links Setup - showMidiPresetActions(); - contentTreeView.setShowRoot(false); - contentTreeView.getSelectionModel().selectedItemProperty().addListener(this); - - // Action Types Init - midiActionTypeComboBox.getItems().setAll(MidiKeyActionTypes.getActions()); - - // ActionType Changed - midiActionTypeComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) -> - { - if (c != null) { - try { - MidiKeyActionType type = c.getActionType().newInstance(); - Optional<MidiAction> midiAction = getSelectedMidiAction(); - if (midiAction.isPresent()) { - if (!MidiKeyActionType.equals(type, midiAction.get().getActionType())) { - Device device = Midi.getInstance().getMidiDevice().get(); - - midiAction.get().setActionType(type, device.getDefaultColor(type.getClass())); - - updateChildrenOfRootItem(midiAction.get(), getTreeObject(midiAction.get(), contentTreeView.getRoot())); - showSettingsView(midiAction.get()); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - - deviceComboBox.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_MidiDevice))); - - Info[] data = Midi.getMidiDevices(); - // Gerät anzeigen - Doppelte weg - for (Info item : data) { - if (!deviceComboBox.getItems().contains(item.getName())) { - deviceComboBox.getItems().add(item.getName()); - - // aktives Gerät wählen - if (item.getName().equals(Profile.currentProfile().getProfileSettings().getMidiDevice())) { - deviceComboBox.getSelectionModel().select(item.getName()); - } - } - } - } - - @Override - public Parent getParent() { - return notificationPane; - } - - // UI Helper Getter und Setter - private void showMidiPresetActions() { - contentTreeView.setRoot(createMidiActionsTree(getSelectedPreset())); - } - - public void updateChildrenOfRootItem(MidiAction midiAction) { - updateChildrenOfRootItem(midiAction, getTreeObject(midiAction, contentTreeView.getRoot())); - } - - public void updateChildrenOfRootItem(MidiAction midiAction, TreeItem<Displayable> root) { - root.getChildren().clear(); - if (!midiAction.getActions().isEmpty() && midiAction.getActionType().showSubActions()) { - for (SubAction action : midiAction.getActions()) { - TreeItem<Displayable> treeItemAction = new TreeItem<>(action); - root.getChildren().add(treeItemAction); - } - } - root.setExpanded(true); - } - - private void addMidiActionToTree(MidiAction midiAction) { - TreeItem<Displayable> treeItemMidi = new TreeItem<>(midiAction); - int index = getSelectedPreset().getMidiActions().indexOf(midiAction); - - contentTreeView.getRoot().getChildren().add(index, treeItemMidi); - createMidiActionsTree(getSelectedPreset()); - selectMidiAction(midiAction); - } - - private void updateButtonDisable() { - Optional<Displayable> displayable = getSelectedAction(); - if (displayable.isPresent()) { - if (displayable.get() instanceof MidiAction) { // Root Node -> MidiAction - deleteMidiButton.setDisable(false); - draftButton.setDisable(false); - } else { - deleteMidiButton.setDisable(true); - draftButton.setDisable(true); - } - midiActionTypeComboBox.setDisable(false); - } else { - deleteMidiButton.setDisable(true); - draftButton.setDisable(true); - midiActionTypeComboBox.setDisable(true); - } - } - - private MidiPreset getSelectedPreset() { - return presetsList.getSelectionModel().getSelectedItem(); - } - - public Optional<MidiAction> getSelectedMidiAction() { - TreeItem<Displayable> item = contentTreeView.getSelectionModel().getSelectedItem(); - if (item != null) { - if (item.getValue() instanceof MidiAction) { - return Optional.of((MidiAction) item.getValue()); - } else { - return Optional.of((MidiAction) item.getParent().getValue()); - } - } else { - return Optional.empty(); - } - } - - public Optional<Displayable> getSelectedAction() { - TreeItem<Displayable> item = contentTreeView.getSelectionModel().getSelectedItem(); - if (item != null) { - return Optional.of(item.getValue()); - } else { - return Optional.empty(); - } - } - - public TreeItem<Displayable> getTreeObject(Displayable object, TreeItem<Displayable> root) { - if (root.getValue() == object) { - return root; - } else { - for (TreeItem<Displayable> child : root.getChildren()) { - TreeItem<Displayable> result = getTreeObject(object, child); - if (result != null) { - return result; - } - } - } - return null; - } - - private void selectMidiKeyActionType(MidiKeyActionType type) { - MidiKeyActionTypeStore store = MidiKeyActionTypes.getStoreForType(type); - midiActionTypeComboBox.setValue(store); - } - - // Show Methods - private TreeItem<Displayable> createMidiActionsTree(MidiPreset preset) { - TreeItem<Displayable> treeItemRoot = new TreeItem<>(); - - if (preset != null) { - for (MidiAction midiAction : preset.getMidiActions()) { - TreeItem<Displayable> treeItemMidi = new TreeItem<>(midiAction); - if (!midiAction.getActions().isEmpty() && midiAction.getActionType().showSubActions()) { - for (SubAction action : midiAction.getActions()) { - TreeItem<Displayable> treeItemAction = new TreeItem<>(action); - treeItemMidi.getChildren().add(treeItemAction); - } - } - treeItemRoot.getChildren().add(treeItemMidi); - } - } - - return treeItemRoot; - } - - private void selectPressedMidiAction(MidiMessage message) { - getSelectedPreset().getMidiActionForMidi(message).ifPresent(item -> Platform.runLater(() -> selectMidiAction(item))); - } - - private void selectMidiAction(MidiAction midiAction) { - // select item - TreeItem<Displayable> treeItem = getTreeObject(midiAction, contentTreeView.getRoot()); - contentTreeView.getSelectionModel().select(treeItem); - - // scroll to index (only index) - int index = contentTreeView.getSelectionModel().getSelectedIndex(); - contentTreeView.scrollTo(index); - } - - /** - * - * @param value - * MidiAction or SubAction - */ - public void showSettingsView(Displayable value) { - settingsAnchorPane.getChildren().clear(); - midiActionTypeComboBox.setValue(null); - - ContentViewController controller = null; - if (value != null) { - if (value instanceof MidiAction) { - MidiAction midiAction = (MidiAction) value; - MidiKeyActionType type = midiAction.getActionType(); - controller = type.getMainViewController(midiAction, this, this); - selectMidiKeyActionType(midiAction.getActionType()); - - } else if (value instanceof SubAction) { - SubAction action = (SubAction) value; - MidiAction midiAction = action.getMidiAction(); - - MidiKeyActionType type = midiAction.getActionType(); - controller = type.getSubViewController(action, this, this); - selectMidiKeyActionType(midiAction.getActionType()); - } - } - - // TODO Overhead mit neuen VC fixen, Reuable machen - if (controller != null) { - ViewController.setAnchor(controller.getParent(), 14, 0, 14, 0); - settingsAnchorPane.getChildren().add(controller.getParent()); - } - } - - // Midi Device und Presets Choose - @FXML - private void deviceHandler(ActionEvent event) { - ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings(); - String device = deviceComboBox.getValue(); - - // Ändern und Speichern - if (device != null) { - if (isMidiActive()) { - Midi midi = Midi.getInstance(); - if (!device.equals(profilSettings.getMidiDevice()) || !midi.isOpen()) { - try { - // Setup - midi.lookupMidiDevice(device); - profilSettings.setMidiDeviceName(device); - - // UI Rückmeldung - if (midi.getInputDevice().isPresent()) { - notify(Localization.getString(Strings.Info_Midi_Device_Connected, device), - PlayPadMain.notificationDisplayTimeMillis); - // mainPane.setDisable(false); BUG Disable / Enable der GUI wenn kein MIDI da ist - } - } catch (NullPointerException e) { - showError(Localization.getString(Strings.Error_Midi_Device_Unavailible, device)); - e.printStackTrace(); - } catch (IllegalArgumentException | MidiUnavailableException e) { - showError(Localization.getString(Strings.Error_Midi_Device_Busy, e.getLocalizedMessage())); - e.printStackTrace(); - } - } - } - } - } - - @FXML - private void presetsEditButtonHandler(ActionEvent event) { - PresetsViewController controller = new PresetsViewController(owner); - controller.getStage().showAndWait(); - } - - @FXML - private void activateButtonHandler(ActionEvent event) { - MidiPreset item = presetsList.getSelectionModel().getSelectedItem(); - item.setActive(true); - activateButton.setDisable(true); - PresetsViewController.disableInvalidPresets(true, item, Profile.currentProfile().getMidiSetting()); - } - - // MidiActionHandlers - @FXML - private void addMidiButtonHandler(ActionEvent event) { - notificationPane.show(Localization.getString(Strings.Info_Midi_Record_Start), null, midiRecordCancelAction); - recordMidi = true; - useDraft = false; - } - - @FXML - private void addMidiDraftButtonHandler(ActionEvent event) { - notificationPane.show(Localization.getString(Strings.Info_Midi_Record_Start), null, midiRecordCancelAction); - recordMidi = true; - useDraft = true; - } - - @FXML - private void draftButtonHandler(ActionEvent event) { - Optional<MidiAction> midiAction = getSelectedMidiAction(); - if (midiAction.isPresent()) { - try { - Profile.currentProfile().getMidiSetting().setDraftAction(midiAction.get().clone()); - addMidiDraftButton.setDisable(false); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - showError(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage())); - } - } - } - - @FXML - private void deleteMidiButtonHandler(ActionEvent event) { - Optional<MidiAction> midiAction = getSelectedMidiAction(); - if (midiAction.isPresent()) { - getSelectedPreset().removeAction(midiAction.get()); // Model - - // Remove from Tree UI - TreeItem<Displayable> midiTreeItem = getTreeObject(midiAction.get(), contentTreeView.getRoot()); - contentTreeView.getRoot().getChildren().remove(midiTreeItem); - } - } - - @FXML - private void clearMidiButtonHandler(ActionEvent event) { - Alert alert = new Alert(AlertType.CONFIRMATION); - - alert.initOwner(owner); - alert.initModality(Modality.WINDOW_MODAL); - Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow(); - PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add); - - alert.setContentText(Localization.getString(Strings.Info_Settings_Midi_ClearPreset)); - alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(item -> - { - getSelectedPreset().clearActions(); - showMidiPresetActions(); - }); - } - - // Accessor for User Input - public boolean isMidiActive() { - return midiActiveCheckBox.isSelected(); - } - - // Midi - @Override - public void onMidiAction(MidiMessage message) { - if (message.getLength() >= 3) { - if (message.getMessage()[2] != 0) { - // Neuer Midi Key (RECORD) - if (recordMidi) { - recordMidi = false; - notificationPane.hide(); - - int midiCommand = message.getMessage()[0]; - byte midiKey = message.getMessage()[1]; - - if (getSelectedPreset().isContaining(midiCommand, midiKey)) { - notify(Localization.getString(Strings.Error_Midi_Record_Fail), PlayPadMain.notificationDisplayTimeMillis); - return; - } - - try { - final MidiAction midiAction; - - // Neue Aktion - if (useDraft == false) { - midiAction = new MidiAction(midiCommand, midiKey, getSelectedPreset()); - if (midiAction != null) { - Platform.runLater(() -> - { - // Model neue Midi Action - getSelectedPreset().addAction(midiAction); - Collections.sort(getSelectedPreset().getMidiActions()); - - // GUI hinzufügen - addMidiActionToTree(midiAction); - selectPressedMidiAction(message); - }); - } - } else { - // Verwende Vorlage und passe Midi an - midiAction = Profile.currentProfile().getMidiSetting().getDraftAction().get().clone(); - midiAction.setMidiPreset(getSelectedPreset()); - midiAction.setMidiCommand(midiCommand); - midiAction.setMidiKey(midiKey); - - // Cart ID ändern - Platform.runLater(() -> - { - if (midiAction.getActionType().handleClone(midiAction, this)) { - if (midiAction != null) { - // Model neue Midi Action - getSelectedPreset().addAction(midiAction); - Collections.sort(getSelectedPreset().getMidiActions()); - - // GUI hinzufügen - addMidiActionToTree(midiAction); - selectPressedMidiAction(message); - } - } - }); - } - } catch (Exception e) { - showError(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage())); - e.printStackTrace(); - } - } else { - selectPressedMidiAction(message); - } - } - } - } - - // NotificationHandler - @Override - public void notify(String text, long duration) { - if (Platform.isFxApplicationThread()) { - notificationPane.showAndHide(text, duration); - } else { - Platform.runLater(() -> notificationPane.showAndHide(text, duration)); - } - } - - @Override - public void notify(String text, long duration, Runnable finish) { - if (Platform.isFxApplicationThread()) { - notificationPane.showAndHide(text, duration, finish); - } else { - Platform.runLater(() -> notificationPane.showAndHide(text, duration, finish)); - } - } - - @Override - public void show(String message, org.controlsfx.control.action.Action... action) { - if (Platform.isFxApplicationThread()) { - notificationPane.show(message, null, action); - } else { - Platform.runLater(() -> notificationPane.show(message, null, action)); - } - } - - @Override - public void showError(String message) { - if (Platform.isFxApplicationThread()) { - notificationPane.showError(message); - } else { - Platform.runLater(() -> notificationPane.showError(message)); - } - } - - @Override - public void hide() { - if (Platform.isFxApplicationThread()) { - notificationPane.hide(); - } else { - Platform.runLater(() -> notificationPane.hide()); - } - } - - // Update Data (Wird in SettingsViewController bei showCurrentSettings aufgerufen) - @Override - public void updateData() { - ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); - deviceComboBox.setValue(profileSettings.getMidiDevice()); - midiActiveCheckBox.setSelected(profileSettings.isMidiActive()); - } - - // Display Settings ViewController der jeweiligen Action, basierend auf dem Type - /* - * Wird aufgerufen, wenn in der Liste Links was ausgewählt wird - */ - @Override - public void changed(ObservableValue<? extends TreeItem<Displayable>> observable, TreeItem<Displayable> oldValue, - TreeItem<Displayable> newValue) { - settingsAnchorPane.getChildren().clear(); - if (newValue != null) - showSettingsView(newValue.getValue()); - updateButtonDisable(); - } - - @Override - public void loadSettings(Profile profile) { - updateData(); - } - - @Override - public void saveSettings(Profile profile) { - ProfileSettings profileSettings = profile.getProfileSettings(); - - // Midi - profileSettings.setMidiActive(isMidiActive()); - } - - @Override - public boolean validSettings() { - return true; - } - - @Override - public boolean needReload() { - return true; - } - - @Override - public void reload(Profile profile, Project project, IMainViewController controller) { - if (Midi.getInstance().getMidiDevice().isPresent()) - try { - Midi.getInstance().getMidiDevice().get().showFeedbackForPage(controller.getPage(), controller.getPage(), project); - } catch (MidiUnavailableException | InvalidMidiDataException e) { - e.printStackTrace(); - } - } - - @Override - public String name() { - return Localization.getString(Strings.UI_Window_Settings_Midi_Title); - } -} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java index 2e4726e0816543c7489c1b544ec5fdf32bccf8c9..9e9aff7afe1d9708e5331201322811650bd11fd6 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java @@ -11,15 +11,19 @@ import de.tobias.playpad.pad.conntent.PadContentRegistry; import de.tobias.playpad.pad.conntent.UnkownPadContentException; import de.tobias.playpad.project.Project; import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.ProfileSettings; import de.tobias.playpad.viewcontroller.ISettingsViewController; import de.tobias.playpad.viewcontroller.SettingsTabViewController; import de.tobias.utils.ui.ViewController; +import de.tobias.utils.ui.icon.FontAwesomeType; +import de.tobias.utils.ui.icon.FontIcon; import de.tobias.utils.util.Localization; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; +import javafx.scene.control.ToggleButton; import javafx.stage.Screen; import javafx.stage.Stage; import javafx.stage.Window; @@ -27,6 +31,7 @@ import javafx.stage.Window; public class SettingsViewController extends ViewController implements ISettingsViewController { @FXML private TabPane tabPane; + @FXML private ToggleButton lockedButton; @FXML private Button finishButton; protected List<SettingsTabViewController> tabs = new ArrayList<>(); @@ -73,8 +78,28 @@ public class SettingsViewController extends ViewController implements ISettingsV @Override public void init() { + ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); + // KeyCode addCloseKeyShortcut(() -> finishButton.fire()); + + lockedButton.setGraphic(new FontIcon(FontAwesomeType.LOCK)); + lockedButton.setOnAction(e -> + { + boolean isLocked = lockedButton.isSelected(); + // Model + profileSettings.setLocked(isLocked); + + // SettingsUI + tabPane.setDisable(isLocked); + }); + + if (profileSettings.isLocked()) { + // SettingsUI + lockedButton.setSelected(true); + tabPane.setDisable(true); + } + finishButton.defaultButtonProperty().bind(finishButton.focusedProperty()); } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/GeneralPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/GeneralPadTabViewController.java index 006630b24349cc74a2e18dbf99903f2524fd0226..b42cd88481eed915acead2e5623f385b0d95b012 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/GeneralPadTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/GeneralPadTabViewController.java @@ -3,6 +3,7 @@ package de.tobias.playpad.viewcontroller.option.pad; import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.Strings; import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.pad.TimeMode; import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; import de.tobias.playpad.viewcontroller.cell.EnumCell; @@ -35,6 +36,10 @@ public class GeneralPadTabViewController extends PadSettingsTabViewController { public GeneralPadTabViewController(Pad pad) { super("generalTab", "de/tobias/playpad/assets/view/option/pad/", PlayPadMain.getUiResourceBundle()); this.pad = pad; + + if (pad.getStatus() == PadStatus.PLAY || pad.getStatus() == PadStatus.PAUSE) { + deleteButton.setDisable(true); + } } @Override diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/LayoutPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/LayoutPadTabViewController.java index 775bdb6dd999e39b15e072cf6fee2fc1b0e3f57c..0ddb4f3d2626a4f1059208d6740b3f7ab9c5478f 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/LayoutPadTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/LayoutPadTabViewController.java @@ -1,14 +1,20 @@ package de.tobias.playpad.viewcontroller.option.pad; +import java.util.List; + import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.Strings; +import de.tobias.playpad.action.Mapping; +import de.tobias.playpad.action.cartaction.CartAction; +import de.tobias.playpad.action.connect.CartActionConnect; import de.tobias.playpad.layout.CartLayout; import de.tobias.playpad.layout.LayoutRegistry; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.settings.Profile; import de.tobias.playpad.viewcontroller.CartLayoutViewController; import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; +import de.tobias.playpad.viewcontroller.main.IMainViewController; import de.tobias.utils.util.Localization; import javafx.fxml.FXML; import javafx.scene.control.CheckBox; @@ -44,14 +50,12 @@ public class LayoutPadTabViewController extends PadSettingsTabViewController { if (c && !pad.isCustomLayout()) { try { pad.setCustomLayout(true); - try { - String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType(); - CartLayout layout = pad.getLayout(layoutType); - setLayoutController(LayoutRegistry.getLayout(layoutType).getCartLayoutViewController(layout)); - } catch (Exception e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Layout_Load, e.getMessage())); - } + + String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType(); + CartLayout layout = pad.getLayout(layoutType); + layout.copyGlobalLayout(Profile.currentProfile().getLayout(layoutType)); + + setLayoutViewController(pad); } catch (Exception e) { showErrorMessage(Localization.getString(Strings.Error_Standard_Gen, e.getLocalizedMessage())); e.printStackTrace(); @@ -72,19 +76,34 @@ public class LayoutPadTabViewController extends PadSettingsTabViewController { public void loadSettings(Pad pad) { enableLayoutCheckBox.setSelected(pad.isCustomLayout()); if (pad.isCustomLayout()) { - try { - String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType(); - CartLayout layout = pad.getLayout(layoutType); - setLayoutController(LayoutRegistry.getLayout(layoutType).getCartLayoutViewController(layout)); - } catch (Exception e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Layout_Load, e.getMessage())); - } + setLayoutViewController(pad); + } + } + + private void setLayoutViewController(Pad pad) { + try { + String layoutType = Profile.currentProfile().getProfileSettings().getLayoutType(); + CartLayout layout = pad.getLayout(layoutType); + + CartLayoutViewController controller = LayoutRegistry.getLayout(layoutType).getCartLayoutViewController(layout); + setLayoutController(controller); + } catch (Exception e) { + e.printStackTrace(); + showErrorMessage(Localization.getString(Strings.Error_Layout_Load, e.getMessage())); } } @Override public void saveSettings(Pad pad) { - PlayPadPlugin.getImplementation().getMainViewController().loadUserCss(); + // CSS + IMainViewController mainViewController = PlayPadPlugin.getImplementation().getMainViewController(); + mainViewController.loadUserCss(); + + // Mapping Auto Matched Colors + Mapping activeMapping = Profile.currentProfile().getMappings().getActiveMapping(); + List<CartAction> actions = activeMapping.getActions(CartActionConnect.TYPE); + // Update die Mapper der CartAction + actions.stream().filter(item -> item.getCart() == pad.getIndex()) + .forEach(item -> item.initFeedback(pad.getProject(), mainViewController)); } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java index 8a4f591202f5b74d90a8ccb4f7c995e52d14fed9..f400d434c30605ec46507df430fd88326342276b 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java @@ -7,6 +7,7 @@ import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.Strings; import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.conntent.PadContentConnect; import de.tobias.playpad.pad.conntent.PadContentRegistry; import de.tobias.playpad.pad.conntent.UnkownPadContentException; import de.tobias.playpad.settings.Profile; @@ -42,8 +43,9 @@ public class PadSettingsViewController extends ViewController implements IPadSet if (pad.getContent() != null) { try { - PadSettingsTabViewController contentTab = PadContentRegistry.getPadContentConnect(pad.getContent().getType()) - .getSettingsViewController(pad); + // Get Pad Type specific tab + PadContentConnect padContentConnect = PadContentRegistry.getPadContentConnect(pad.getContent().getType()); + PadSettingsTabViewController contentTab = padContentConnect.getSettingsViewController(pad); if (contentTab != null) addTab(contentTab); } catch (UnkownPadContentException e) { @@ -65,6 +67,10 @@ public class PadSettingsViewController extends ViewController implements IPadSet // Show Current Settings showCurrentSettings(); + setTitle(pad); + } + + private void setTitle(Pad pad) { getStage().setTitle(Localization.getString(Strings.UI_Window_PadSettings_Title, pad.getIndexReadable(), pad.getName())); } @@ -78,7 +84,7 @@ public class PadSettingsViewController extends ViewController implements IPadSet PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add); stage.setMinWidth(650); - stage.setMinHeight(500); + stage.setMinHeight(550); Profile.currentProfile().currentLayout().applyCss(getStage()); } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java index f6fb894434191e4df9bb6fe509dfdac2bc9c0413..6f28cfd46f0e3ae97de4df72a7c61ba9bfe6f708 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java @@ -7,7 +7,7 @@ import de.tobias.playpad.Strings; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.tigger.Trigger; import de.tobias.playpad.tigger.TriggerPoint; -import de.tobias.playpad.trigger.TriggerWrapper; +import de.tobias.playpad.trigger.TriggerUIWrapper; import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; import de.tobias.playpad.viewcontroller.cell.DisplayableTreeCell; import de.tobias.playpad.viewcontroller.option.pad.trigger.TriggerPointViewController; @@ -20,9 +20,9 @@ import javafx.scene.control.TreeView; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; -public class TriggerPadTabViewController extends PadSettingsTabViewController implements ChangeListener<TreeItem<TriggerWrapper>> { +public class TriggerPadTabViewController extends PadSettingsTabViewController implements ChangeListener<TreeItem<TriggerUIWrapper>> { - @FXML private TreeView<TriggerWrapper> treeView; + @FXML private TreeView<TriggerUIWrapper> treeView; @FXML private VBox contentView; private Pad pad; @@ -40,25 +40,25 @@ public class TriggerPadTabViewController extends PadSettingsTabViewController im private void createTreeView() { HashMap<TriggerPoint, Trigger> triggers = pad.getTriggers(); - TreeItem<TriggerWrapper> rootItem = new TreeItem<>(); + TreeItem<TriggerUIWrapper> rootItem = new TreeItem<>(); // Sort the tpyes for the treeview for (TriggerPoint point : TriggerPoint.values()) { Trigger trigger = triggers.get(point); - TreeItem<TriggerWrapper> triggerItem = new TreeItem<>(new TriggerWrapper(trigger)); + TreeItem<TriggerUIWrapper> triggerItem = new TreeItem<>(new TriggerUIWrapper(trigger)); rootItem.getChildren().add(triggerItem); } treeView.setRoot(rootItem); } - public void changed(ObservableValue<? extends TreeItem<TriggerWrapper>> observable, TreeItem<TriggerWrapper> oldValue, - TreeItem<TriggerWrapper> newValue) { + public void changed(ObservableValue<? extends TreeItem<TriggerUIWrapper>> observable, TreeItem<TriggerUIWrapper> oldValue, + TreeItem<TriggerUIWrapper> newValue) { contentView.getChildren().clear(); if (newValue != null) { - TriggerWrapper triggerWrapper = newValue.getValue(); + TriggerUIWrapper triggerWrapper = newValue.getValue(); TriggerPointViewController controller = new TriggerPointViewController(triggerWrapper); contentView.getChildren().setAll(controller.getParent()); VBox.setVgrow(controller.getParent(), Priority.ALWAYS); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java index 78e89182813afc0a68d348c1e1f91dd30a0e7f1b..6c4ab5728c7f15b77240f073901720eea70380ee 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java @@ -6,7 +6,7 @@ import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.tigger.TriggerItem; import de.tobias.playpad.tigger.TriggerItemConnect; import de.tobias.playpad.tigger.TriggerRegistry; -import de.tobias.playpad.trigger.TriggerWrapper; +import de.tobias.playpad.trigger.TriggerUIWrapper; import de.tobias.utils.ui.ContentViewController; import de.tobias.utils.ui.icon.FontAwesomeType; import de.tobias.utils.ui.icon.FontIcon; @@ -22,9 +22,9 @@ public class TriggerPointViewController extends ContentViewController { @FXML private VBox itemView; @FXML private HBox buttonBox; - private TriggerWrapper triggerWrapper; + private TriggerUIWrapper triggerWrapper; - public TriggerPointViewController(TriggerWrapper triggerWrapper) { + public TriggerPointViewController(TriggerUIWrapper triggerWrapper) { super("triggerPoint", "de/tobias/playpad/assets/view/option/pad/trigger/", PlayPadMain.getUiResourceBundle()); this.triggerWrapper = triggerWrapper; @@ -77,6 +77,8 @@ public class TriggerPointViewController extends ContentViewController { triggerWrapper.removeItem(item); itemView.getChildren().removeAll(rootBox); }); + +// HBox.setHgrow(itemBox, Priority.ALWAYS); } } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/VolumeTriggerViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/VolumeTriggerViewController.java new file mode 100644 index 0000000000000000000000000000000000000000..575d7ca443568ca14f20213a7284f356f68394e3 --- /dev/null +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/VolumeTriggerViewController.java @@ -0,0 +1,49 @@ +package de.tobias.playpad.viewcontroller.option.pad.trigger; + +import de.tobias.playpad.PlayPadMain; +import de.tobias.playpad.Strings; +import de.tobias.playpad.trigger.VolumeTriggerItem; +import de.tobias.utils.ui.ContentViewController; +import de.tobias.utils.util.Localization; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.control.Slider; +import javafx.util.Duration; + +public class VolumeTriggerViewController extends ContentViewController { + + @FXML private Slider volumeSlider; + @FXML private Label volumeLabel; + + @FXML private Slider durationSlider; + @FXML private Label durationLabel; + + private VolumeTriggerItem item; + + public VolumeTriggerViewController(VolumeTriggerItem item) { + super("volumeTrigger", "de/tobias/playpad/assets/view/option/pad/trigger/", PlayPadMain.getUiResourceBundle()); + this.item = item; + + volumeSlider.setValue(item.getVolume() * 100.0); + durationSlider.setValue(item.getDuration().toSeconds()); + + } + + @Override + public void init() { + volumeSlider.valueProperty().addListener((a, b, c) -> + { + item.setVolume(c.doubleValue() / 100.0); + volumeLabel.setText(Localization.getString(Strings.Standard_Time_Volume, Math.round(c.doubleValue()))); + }); + + durationSlider.valueProperty().addListener((a, b, c) -> + { + item.setDuration(Duration.seconds(c.doubleValue())); + + double secounds = Math.round(item.getDuration().toSeconds() * 10.0) / 10.0; + durationLabel.setText(Localization.getString(Strings.Standard_Time_Seconds, secounds)); + }); + + } +} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragHandler.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragHandler.java deleted file mode 100644 index dd6b1c83f66fd9ec94de0e1c644f862eceda730b..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragHandler.java +++ /dev/null @@ -1,204 +0,0 @@ -package de.tobias.playpad.viewcontroller.pad; - -import java.io.File; - -import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.PseudoClasses; -import de.tobias.playpad.Strings; -import de.tobias.playpad.audio.AudioRegistry; -import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.plugin.ExtensionHandler; -import de.tobias.playpad.plugin.PlayPadPlugin; -import de.tobias.playpad.project.Project; -import de.tobias.playpad.view.AudioPadView; -import de.tobias.utils.ui.NotificationHandler; -import de.tobias.utils.ui.Refreshable; -import de.tobias.utils.util.Localization; -import javafx.scene.SnapshotParameters; -import javafx.scene.input.ClipboardContent; -import javafx.scene.input.DragEvent; -import javafx.scene.input.Dragboard; -import javafx.scene.input.MouseEvent; -import javafx.scene.input.TransferMode; - -// TODO Renew class -public class PadDragHandler<T extends Refreshable & NotificationHandler> { - - private static final String REGEX = "[0-9]+"; - private Pad pad; - final private AudioPadView view; - final private T t; - - private static AudioPadView lastDraggedOver; - private static boolean dndMode; - private static Project project; - - public PadDragHandler(Pad pad, AudioPadView view, T t) { - this.pad = pad; - this.view = view; - this.t = t; - - // Drag and Drop - view.setOnDragOver(event -> dragOver(event)); - view.setOnDragExited(event -> dragExited()); - view.setOnDragDropped(event -> dragDropped(event)); - view.setOnDragDetected(event -> dragDetacted(event)); - } - - private void dragOver(DragEvent event) { - if (event.getGestureSource() != this && event.getDragboard().hasFiles()) { - if (event.getDragboard().getFiles().get(0).isFile()) { - if (PadViewController.getPlayedPlayers() > 0) { - showLiveModeLabel(); - } - File file = event.getDragboard().getFiles().get(0); - - // Build In Filesupport - for (String extension : AudioRegistry.geAudioType().getSupportedTypes()) { - if (file.getName().toLowerCase().matches("." + extension)) { - event.acceptTransferModes(TransferMode.LINK); - return; - } - } - - // Plugins - for (ExtensionHandler extensionHandler : PlayPadPlugin.getImplementation().getExtensionsHandler()) { - for (String extension : extensionHandler.getExtensions()) { - if (file.getName().toLowerCase().matches("." + extension)) { - event.acceptTransferModes(TransferMode.LINK); - return; - } - } - } - } - } - - if (event.getDragboard().hasString() && event.getDragboard().getString().trim().matches(REGEX)) { - int padID = Integer.valueOf(event.getDragboard().getString()); - if (padID != view.getController().getPad().getIndex()) { - - // Live Mode - if (PadViewController.getPlayedPlayers() > 0) { - showLiveModeLabel(); - } else { - event.acceptTransferModes(TransferMode.MOVE); - double y = event.getY(); - if (y < view.getHeight() / 2) { - if (lastDraggedOver != null) { - view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false); - view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false); - } - view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false); - view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, true); - lastDraggedOver = view; - } else { - if (lastDraggedOver != null) { - view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false); - view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false); - } - view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false); - view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, true); - lastDraggedOver = view; - } - } - } - } - event.consume(); - } - - private void dragExited() { - if (lastDraggedOver != null) { - view.pseudoClassState(PseudoClasses.DRAG_RELACE_CLASS, false); - view.pseudoClassState(PseudoClasses.DRAG_MOVE_CLASS, false); - lastDraggedOver = null; - } - } - - private void dragDropped(DragEvent event) { - // Live Mode - if (PadViewController.getPlayedPlayers() > 0) { - showLiveModeLabel(); - } else { - Dragboard db = event.getDragboard(); - boolean success = false; - if (db.hasFiles()) { - success = true; - File file = db.getFiles().get(0); - - boolean custom = false; - for (ExtensionHandler extensionHandler : PlayPadPlugin.getImplementation().getExtensionsHandler()) { - for (String extension : extensionHandler.getExtensions()) { - if (file.getName().toLowerCase().matches("." + extension)) { - extensionHandler.handle(file.toPath(), pad); - custom = true; - break; - } - } - } - if (!custom) { - this.pad.setPath(file.toPath()); - } - } - - if (db.hasString() && db.getString().matches(REGEX)) { - double y = event.getY(); - if (y < view.getHeight() / 2) { - int padID = Integer.valueOf(db.getString()); - project.movePads(padID, pad.getIndex()); - t.refreshUI(); - success = true; - } else { - int padID = Integer.valueOf(db.getString()); - project.replacePads(padID, pad.getIndex()); - t.refreshUI(); - success = true; - } - } - - event.setDropCompleted(success); - event.consume(); - } - } - - private void dragDetacted(MouseEvent event) { - // Live Mode - if (PadViewController.getPlayedPlayers() == 0) { - if (dndMode) { - Dragboard storeImage = view.startDragAndDrop(TransferMode.MOVE); - storeImage.setDragView(view.snapshot(new SnapshotParameters(), null)); - - ClipboardContent content = new ClipboardContent(); - content.putString(String.valueOf(pad.getIndex())); - storeImage.setContent(content); - - event.consume(); - } - } - } - - public static void setDndMode(boolean dndMode) { - PadDragHandler.dndMode = dndMode; - } - - public static void setLastDraggedOver(AudioPadView lastDraggedOver) { - PadDragHandler.lastDraggedOver = lastDraggedOver; - } - - public void setPad(Pad pad) { - this.pad = pad; - } - - public static void setProject(Project project) { - PadDragHandler.project = project; - } - - private boolean displayLiveLabel; - - private synchronized void showLiveModeLabel() { - if (!displayLiveLabel) { - displayLiveLabel = true; - t.notify(Localization.getString(Strings.Error_Pad_Livemode), PlayPadMain.notificationDisplayTimeMillis, - () -> displayLiveLabel = false); - } - } -} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java index 0de732ca29d63fb83fade6f6d295b7b8ed94a429..e8a1676c7f154541899cef2b78ddd8337070ffb8 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java @@ -13,6 +13,8 @@ import de.tobias.playpad.pad.conntent.UnkownPadContentException; import de.tobias.playpad.pad.drag.PadDragMode; import de.tobias.playpad.pad.drag.PadDragModeRegistery; import de.tobias.playpad.project.Project; +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.ProfileSettings; import de.tobias.playpad.view.FileDragOptionView; import de.tobias.playpad.view.PadDragOptionView; import de.tobias.playpad.view.PadView; @@ -50,8 +52,20 @@ public class PadDragListener { } private void dragOver(DragEvent event) { + if (Profile.currentProfile().getProfileSettings().isLocked()) { + return; + } + if (event.getGestureSource() != this && event.getDragboard().hasFiles()) { if (event.getDragboard().getFiles().get(0).isFile()) { + ProfileSettings settings = Profile.currentProfile().getProfileSettings(); + if (pad.getProject() != null) { + if (settings.isLiveMode() && settings.isLiveModeFile() && pad.getProject().getPlayedPlayers() > 0) { + PlayPadPlugin.getImplementation().getMainViewController().showLiveInfo(); + return; + } + } + File file = event.getDragboard().getFiles().get(0); // Build In Filesupport @@ -73,6 +87,7 @@ public class PadDragListener { } } + // Drag and Drop von Pads if (event.getDragboard().hasString() && event.getDragboard().getString().trim().matches(REGEX)) { int padID = Integer.valueOf(event.getDragboard().getString()); if (padID != view.getController().getPad().getIndex()) { @@ -141,6 +156,14 @@ public class PadDragListener { private void dragDetacted(MouseEvent event) { if (dndMode) { + ProfileSettings settings = Profile.currentProfile().getProfileSettings(); + if (pad.getProject() != null) { + if (settings.isLiveMode() && settings.isLiveModeDrag() && pad.getProject().getPlayedPlayers() > 0) { + PlayPadPlugin.getImplementation().getMainViewController().showLiveInfo(); + return; + } + } + Dragboard dragboard = view.startDragAndDrop(TransferMode.MOVE); SnapshotParameters parameters = new SnapshotParameters(); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java index c55b73efa8069e3c0d59c7731bcd74d8e5dbdf02..e39abcda8c007b79c7a00ea961ba37d1f39a8b73 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java @@ -17,12 +17,16 @@ import de.tobias.playpad.pad.conntent.PadContentRegistry; import de.tobias.playpad.pad.conntent.UnkownPadContentException; import de.tobias.playpad.pad.listener.PadContentListener; import de.tobias.playpad.pad.listener.PadDurationListener; +import de.tobias.playpad.pad.listener.PadLockedListener; import de.tobias.playpad.pad.listener.PadPositionListener; import de.tobias.playpad.pad.listener.PadStatusListener; import de.tobias.playpad.pad.view.IPadViewController; +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.ProfileSettings; import de.tobias.playpad.view.FileDragOptionView; import de.tobias.playpad.view.PadView; import de.tobias.playpad.viewcontroller.IPadView; +import de.tobias.playpad.viewcontroller.main.IMainViewController; import de.tobias.playpad.viewcontroller.option.pad.PadSettingsViewController; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.util.FileUtils; @@ -43,6 +47,7 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon private PadView view; private Pad pad; + private PadLockedListener padLockedListener; private PadStatusListener padStatusListener; private PadContentListener padContentListener; private PadDurationListener padDurationListener; @@ -53,10 +58,15 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon public PadViewController() { view = new PadView(this); + padLockedListener = new PadLockedListener(this); padStatusListener = new PadStatusListener(this); padContentListener = new PadContentListener(this); padDurationListener = new PadDurationListener(this); padPositionListener = new PadPositionListener(this); + + // Listener muss nur einmal hier hinzugefügt werden, weil bei einem neuen Profile, werden neue PadViewController erzeugt + ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); + profileSettings.lockedProperty().addListener(padLockedListener); } @Override @@ -98,6 +108,14 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon } private void onNew(ActionEvent event) { + ProfileSettings settings = Profile.currentProfile().getProfileSettings(); + if (pad.getProject() != null) { + if (settings.isLiveMode() && settings.isLiveModeFile() && pad.getProject().getPlayedPlayers() > 0) { + PlayPadPlugin.getImplementation().getMainViewController().showLiveInfo(); + return; + } + } + FileChooser chooser = new FileChooser(); // File Extension @@ -153,13 +171,26 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon } private void onSettings() { - Stage owner = PlayPadPlugin.getImplementation().getMainViewController().getStage(); - PadSettingsViewController controller = new PadSettingsViewController(pad, owner); - controller.getStage().setOnHidden(ev -> - { - view.setTriggerLabelActive(pad.hasTriggerItems()); - }); - controller.getStage().show(); + ProfileSettings settings = Profile.currentProfile().getProfileSettings(); + IMainViewController mvc = PlayPadPlugin.getImplementation().getMainViewController(); + + if (mvc != null) { + if (pad.getProject() != null) { + if (settings.isLiveMode() && settings.isLiveModeSettings() && pad.getProject().getPlayedPlayers() > 0) { + mvc.showLiveInfo(); + return; + } + } + + Stage owner = mvc.getStage(); + PadSettingsViewController controller = new PadSettingsViewController(pad, owner); + controller.getStage().setOnHiding(ev -> + { + if (view != null && pad != null) + view.setTriggerLabelActive(pad.hasTriggerItems()); + }); + controller.getStage().show(); + } } @Override @@ -199,6 +230,7 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon @Override public void setPad(Pad pad) { unconnectPad(); + this.pad = pad; view.setPreviewContent(pad); @@ -212,6 +244,7 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon pad.setController(this); try { + // Settings view.getIndexLabel().setText(String.valueOf(pad.getIndexReadable())); view.getLoopLabel().visibleProperty().bind(pad.loopProperty()); @@ -256,12 +289,14 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon if (timeMode == TimeMode.REST) { Duration leftTime = duration.subtract(position); + view.getTimeLabel().setText("- " + durationToString(leftTime)); } else if (timeMode == TimeMode.PLAYED) { view.getTimeLabel().setText(durationToString(position)); } else if (timeMode == TimeMode.BOTH) { String time = durationToString(position); String totalTime = durationToString(duration); + view.getTimeLabel().setText(time + "/" + totalTime); } } @@ -285,6 +320,9 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon } public void updateButtonDisable() { + if (pad == null) { + return; + } if (pad.getContent() != null) { if (pad.getStatus() == PadStatus.PLAY) { view.getPlayButton().setDisable(true); @@ -310,6 +348,12 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon view.getStopButton().setDisable(true); view.getNewButton().setDisable(false); view.getSettingsButton().setDisable(false); + } else if (pad.getStatus() == PadStatus.ERROR) { + view.getPlayButton().setDisable(true); + view.getPauseButton().setDisable(true); + view.getStopButton().setDisable(true); + view.getNewButton().setDisable(false); + view.getSettingsButton().setDisable(false); } } else if (pad.getStatus() == PadStatus.EMPTY || pad.getStatus() == PadStatus.ERROR || pad.getContent() == null || !pad.getContent().isPadLoaded()) { @@ -319,6 +363,11 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon view.getNewButton().setDisable(false); view.getSettingsButton().setDisable(false); } + + if (Profile.currentProfile().getProfileSettings().isLocked()) { + view.getNewButton().setDisable(true); + view.getSettingsButton().setDisable(true); + } } @Override diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java deleted file mode 100644 index 4fce7090ec092d55de01ac19a7e3021ba4657033..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewControllerOld.java +++ /dev/null @@ -1,755 +0,0 @@ -package de.tobias.playpad.viewcontroller.pad; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.controlsfx.dialog.ExceptionDialog; - -import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.PseudoClasses; -import de.tobias.playpad.Strings; -import de.tobias.playpad.action.mapper.listener.MidiHandler; -import de.tobias.playpad.audio.AudioHandler; -import de.tobias.playpad.audio.AudioRegistry; -import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Pad.PadStatus; -import de.tobias.playpad.pad.Pad.TimeMode; -import de.tobias.playpad.model.PadException; -import de.tobias.playpad.model.PadException.PadExceptionType; -import de.tobias.playpad.model.Project; -import de.tobias.playpad.plugin.ExtensionHandler; -import de.tobias.playpad.plugin.PadListener; -import de.tobias.playpad.plugin.PlayPadPlugin; -import de.tobias.playpad.plugin.viewcontroller.IPadViewController; -import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.view.AudioPadView; -import de.tobias.playpad.viewcontroller.PadSettingsViewController; -import de.tobias.utils.application.ApplicationUtils; -import de.tobias.utils.ui.NotificationHandler; -import de.tobias.utils.ui.Refreshable; -import de.tobias.utils.util.Localization; -import javafx.application.Platform; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.stage.FileChooser; -import javafx.stage.FileChooser.ExtensionFilter; -import javafx.stage.Stage; -import javafx.util.Duration; - -public class PadViewController implements IPadViewController, EventHandler<ActionEvent>, ChangeListener<Duration> { - - private static final String DURATION_FORMAT = "%d:%02d"; - - private static final String OPEN_FOLDER = "openFolder"; - - public static ObservableList<PadException> exceptions = FXCollections.observableArrayList(); - - private AudioPadView view; - - protected Pad pad; - protected int page; - - // Listener - private ChangeListener<Duration> totalDurationListener; - private ChangeListener<AudioHandler> audioHandlerListener; - private ChangeListener<PadStatus> stateListener; - private ChangeListener<Boolean> audioLoadedListener; - private ChangeListener<String> titleListener; - private ChangeListener<PadException> exceptionListener; - private PlayDurationEventHandler durationEventHandler; - - // Drag and Drop - private PadDragHandler<?> dragAndDrop; - - // Refresh in Window - private Refreshable refreshable; - private NotificationHandler notificationHandler; - - private MidiHandler handler; - protected int midiKeyPressedForPlay; - - // Window Referenz - private PadSettingsViewController padSettingsViewController; - - private static int playedPlayers; - - private synchronized static void addPlayer() { - playedPlayers++; - } - - private synchronized static void removePlayer() { - if (playedPlayers > 0) { - playedPlayers--; - } - } - - public synchronized static int getPlayedPlayers() { - return playedPlayers; - } - - public <T extends Refreshable & NotificationHandler> PadViewController(T t, Project project, MidiHandler handler) { - view = new AudioPadView(this); - dragAndDrop = new PadDragHandler<T>(pad, view, t); - - this.refreshable = t; - this.notificationHandler = t; - this.handler = handler; - - view.getErrorLabel().setOnMouseClicked(event -> - { - showError(); - }); - } - - public Pad getPad() { - return pad; - } - - public void setPad(Pad pad, int page) { - if (this.pad != null) { - this.pad.setController(null); - cleanUp(); - } - - this.pad = pad; - this.page = page; - this.pad.setController(this); - this.dragAndDrop.setPad(pad); - - view.addDefaultButton(); - preparePad(); - - for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) { - try { - listener.onPadVisible(pad); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - private void preparePad() { - // Display Pad Once - view.getIndexLabel().setText(String.valueOf(pad.getIndex() + 1)); - - view.getTimeLabel().setText(""); - // Binding und Listener - totalDurationListener = (a, b, c) -> - { - if (c != null) { - showPadDuration(); - } else { - Platform.runLater(() -> view.getTimeLabel().setText("")); - } - }; - - stateListener = (a, b, c) -> stateChange(b, c); - - audioLoadedListener = (a, b, c) -> - { - // TODO Init MIDI Page - }; - - audioHandlerListener = (a, b, c) -> - { - b.durationProperty(pad).removeListener(totalDurationListener); - c.durationProperty(pad).addListener(totalDurationListener); - - b.loadedProperty().removeListener(audioLoadedListener); - c.loadedProperty().addListener(audioLoadedListener); - }; - - titleListener = (a, b, c) -> - { - view.getNameLabel().setText(c); - }; - - exceptionListener = (a, b, c) -> - { - if (c != null && !exceptions.contains(c)) { - view.setErrorLabelActive(true); - exceptions.add(c); - } else { - view.setErrorLabelActive(false); - exceptions.remove(b); - } - }; - - // AudioHandler Listener - pad.audioHandlerProperty().addListener(audioHandlerListener); - - pad.titleProperty().addListener(titleListener); - view.getNameLabel().setText(pad.getTitle()); - - // Listener für Gesamtzeit (Wenn neues Media File oder so) - pad.getAudioHandler().durationProperty(pad).addListener(totalDurationListener); - - // Time label Clickable für Time Display Art - view.getTimeLabel().setOnMouseClicked(event -> - { - TimeMode timeMode = Profile.currentProfile().getProfileSettings().getPlayerTimeDisplayMode(); - if (pad.isCustomTimeMode()) { - timeMode = pad.getTimeMode().get(); - } - - if (timeMode == TimeMode.PLAYED) { - pad.setTimeMode(TimeMode.REST); - } else if (timeMode == TimeMode.REST) { - pad.setTimeMode(TimeMode.BOTH); - } else if (timeMode == TimeMode.BOTH) { - pad.setTimeMode(TimeMode.PLAYED); - } - }); - - view.setLoopLabelActive(pad.isLoop()); - - // Für LaunchPad Feedback - pad.getAudioHandler().loadedProperty().addListener(audioLoadedListener); - - // State des Pad -> UI Änderungen (wie Progressbar oder Button) - pad.statusProperty().addListener(stateListener); - - // Init - stateChange(null, pad.getStatus()); - if (pad.getAudioHandler().durationProperty(pad).isNotNull().get()) { - showPadDuration(); - } - - // Errors - pad.lastExceptionProperty().addListener(exceptionListener); - view.setErrorLabelActive(pad.getLastException() != null); - if (pad.getLastException() != null && !exceptions.contains(pad.getLastException())) { - exceptions.add(pad.getLastException()); - } - - // CSS - view.getStyleClass().addAll("pad", "pad" + pad.getIndex()); - - view.getIndexLabel().getStyleClass().addAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info", - "pad" + pad.getIndex() + "-info"); - view.getTimeLabel().getStyleClass().addAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info", "pad" + pad.getIndex() + "-info"); - view.getNameLabel().getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title"); - - view.getPlayBar().getStyleClass().addAll("pad-playbar", "pad" + pad.getIndex() + "-playbar"); - - view.getPlayButton().getStyleClass().addAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-playbutton"); - view.getPauseButton().getStyleClass().addAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-pausebutton"); - view.getStopButton().getStyleClass().addAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-stopbutton"); - view.getNewButton().getStyleClass().addAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-newbutton"); - view.getSettingsButton().getStyleClass().addAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-settingsbutton"); - - view.getPlayButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-playbutton-icon", - "pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon"); - view.getPauseButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-pausebutton-icon", - "pad" + pad.getIndex() + "-button-icon", "padv-playbutton--icon"); - view.getStopButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-stopbutton-icon", - "pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon"); - view.getNewButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-newbutton-icon", "pad" + pad.getIndex() + "-button-icon", - "pad" + pad.getIndex() + "-playbutton-icon"); - view.getSettingsButton().getGraphic().getStyleClass().addAll("pad-button-icon", "pad-deletebutton-icon", - "pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon"); - - view.getButtonBox().getStyleClass().add("pad-button-box"); - view.getRoot().getStyleClass().add("pad-root"); - } - - /* - * Button Action - */ - @Override - public void handle(ActionEvent event) { - if (event.getSource() == view.getPlayButton()) { - pad.setStatus(PadStatus.PLAY); - } else if (event.getSource() == view.getPauseButton()) { - pad.setStatus(PadStatus.PAUSE); - } else if (event.getSource() == view.getStopButton()) { - pad.setStatus(PadStatus.STOP); - } else if (event.getSource() == view.getSettingsButton()) { - openSettings(); - } else if (event.getSource() == view.getNewButton()) { - if (getPlayedPlayers() > 0) { - notificationHandler.notify(Localization.getString(Strings.Error_Pad_Livemode), PlayPadMain.notificationDisplayTimeMillis); - } else { - chooseFile(event); - } - } - } - - private void chooseFile(ActionEvent event) { - FileChooser chooser = new FileChooser(); - - // File Extension - ExtensionFilter extensionFilter = new ExtensionFilter(Localization.getString(Strings.File_Filter_Media), - AudioRegistry.geAudioType().getSupportedTypes()); - chooser.getExtensionFilters().add(extensionFilter); - for (ExtensionHandler handler : PlayPadPlugin.getImplementation().getExtensionsHandler()) { - chooser.getExtensionFilters().add(new ExtensionFilter(handler.getName(), handler.getExtensions())); - } - - // Last Folder - Object openFolder = ApplicationUtils.getApplication().getUserDefaults().getData(OPEN_FOLDER); - if (openFolder != null) { - File folder = new File(openFolder.toString()); - chooser.setInitialDirectory(folder); - } - - File file = chooser.showOpenDialog(((Node) event.getTarget()).getScene().getWindow()); - if (file != null) { - Path path = file.toPath(); - ExtensionFilter filter = chooser.getSelectedExtensionFilter(); - - for (ExtensionHandler handler : PlayPadPlugin.getImplementation().getExtensionsHandler()) { - if (filter.getDescription().equals(handler.getName())) { - handler.handle(path, pad); - return; - } - } - - pad.setPath(path); - ApplicationUtils.getApplication().getUserDefaults().setData(OPEN_FOLDER, path.getParent().toString()); - } - } - - private void openSettings() { - if (padSettingsViewController == null) { - padSettingsViewController = new PadSettingsViewController(pad, this, view.getScene().getWindow()); - padSettingsViewController.getStage().showAndWait(); - refreshable.updateData(); - - padSettingsViewController = null; - } else if (padSettingsViewController.getStage().isShowing()) { - padSettingsViewController.getStage().toFront(); - } - } - - @Override - public void changed(ObservableValue<? extends Duration> arg0, Duration arg1, Duration newValue) { - // Progressbar (Prozente) - if (pad != null) { - double value = newValue.toMillis() / pad.getAudioHandler().getDuration(pad).toMillis(); - view.getPlayBar().setProgress(value); - - // Label (Restlaufzeit) - TimeMode timeMode = Profile.currentProfile().getProfileSettings().getPlayerTimeDisplayMode(); - if (pad.isCustomTimeMode()) { - timeMode = pad.getTimeMode().get(); - } - if (timeMode == TimeMode.REST) { - Duration leftTime = pad.getAudioHandler().getDuration(pad).subtract(newValue); - view.getTimeLabel().setText("- " + durationToString(leftTime)); - } else if (timeMode == TimeMode.PLAYED) { - view.getTimeLabel().setText(durationToString(newValue)); - } else if (timeMode == TimeMode.BOTH) { - String time = durationToString(newValue); - String totalTime = durationToString(pad.getAudioHandler().getDuration(pad)); - - view.getTimeLabel().setText(time + "/" + totalTime); - } - } - } - - private String durationToString(Duration value) { - int secounds = (int) ((value.toMillis() / 1000) % 60); - int minutes = (int) ((value.toMillis() / (1000 * 60)) % 60); - String time = String.format(DURATION_FORMAT, minutes, secounds); - return time; - } - - private void showPadDuration() { - Duration c = pad.getAudioHandler().getDuration(pad); - if (c != null) { - Platform.runLater(() -> view.getTimeLabel().setText(durationToString(c))); - } else { - Platform.runLater(() -> view.getTimeLabel().setText("")); - } - } - - // GUI Veränderung und Pad Aktionen wenn sich der Sate durch die Buttons oder durch MIDI ändert - public void stateChange(PadStatus oldState, PadStatus newState) { - Profile profile = Profile.currentProfile(); - if (pad.isCustomLayout()) { - pad.getLayout(profile.getProfileSettings().getLayoutType()).ifPresent(layout -> layout.updatePadView(this, oldState, newState)); - } else { - profile.currentLayout().updatePadView(this, oldState, newState); - } - - switch (newState) { - case PLAY: - playState(oldState, newState); - break; - case PAUSE: - pauseState(oldState, newState); - break; - case STOP: - stopState(oldState, newState); - break; - case READY: - readyState(); - break; - case EMPTY: - emptyState(); - break; - } - } - - private void playState(PadStatus oldState, PadStatus newState) { - // PadListener - boolean ignoreNoMedia = false; - for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) { - try { - if (listener.ignoreNoMedia(pad)) { - ignoreNoMedia = true; - break; - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (!ignoreNoMedia) { - if (!pad.getAudioHandler().isMediaLoaded(pad)) { - pad.loadMedia(); // Try to Load wenn nicht geladen - if (!pad.getAudioHandler().isMediaLoaded(pad)) { - String file = pad.getFile(); - if (file != null) - file = file.replace("%20", " "); - notificationHandler - .showError(Localization.getString(Strings.Error_Pad_BaseName + PadExceptionType.FILE_NOT_FOUND.toString(), file)); - pad.setState(PadStatus.READY); - return; - } - } - } - - // PadListener - for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) - try { - if (!listener.onPlay(pad)) - return; - } catch (Exception e) { - e.printStackTrace(); - } - - // Bei Pause werden die Listener nicht entfernt, bei Stop schon. bei Stop wird der Listener = null. Nur dann muss er neu - // hinzugefügt werden - if (durationEventHandler == null && pad.currentDurationProperty() != null) { - durationEventHandler = new PlayDurationEventHandler(this); - pad.currentDurationProperty().addListener(durationEventHandler); - pad.currentDurationProperty().addListener(this); - } - if (durationEventHandler != null) - durationEventHandler.send = false; - - // midi Feedback - // TODO MIDI Send Feedback - // try { - // } catch (MidiUnavailableException | InvalidMidiDataException e) { - // notificationHandler.showError(Localization.getString(Strings.Error_Midi_Send, e.getLocalizedMessage())); - // e.printStackTrace(); - // } - - if (pad.getAudioHandler().isMediaLoaded(pad)) - pad.play(); - addPlayer(); - - Platform.runLater(() -> - { - view.getPlayButton().setDisable(true); - view.getPauseButton().setDisable(false); - view.getStopButton().setDisable(false); - view.pseudoClassState(PseudoClasses.PLAY_CALSS, true); - }); - } - - private void pauseState(PadStatus oldState, PadStatus newState) { - pad.pause(true, () -> - { - // Bei Fade Out Ende löschen - view.pseudoClassState(PseudoClasses.FADE_CLASS, false); - removePlayer(); - durationEventHandler.stopWaning(); - }); - - Platform.runLater(() -> - { - view.getPlayButton().setDisable(false); - view.getPauseButton().setDisable(true); - view.getStopButton().setDisable(false); - - view.pseudoClassState(PseudoClasses.PLAY_CALSS, false); - view.pseudoClassState(PseudoClasses.WARN_CLASS, false); - - // Fade Out Style hintufügen - if (!pad.isEof() && (pad.isCustomFade() && pad.getFade().get().getFadeOut().toMillis() > 0 - || !pad.isCustomFade() && Profile.currentProfile().getProfileSettings().getFade().getFadeOut().toSeconds() > 0)) - view.pseudoClassState(PseudoClasses.FADE_CLASS, true); - }); - sendFeedback(oldState, newState); - } - - private void stopState(PadStatus oldState, PadStatus newState) { - if (pad.currentDurationProperty() != null) { - pad.currentDurationProperty().removeListener(this); - if (durationEventHandler != null) - pad.currentDurationProperty().removeListener(durationEventHandler); - } - - // PadListener - for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) - try { - listener.onStop(pad); - } catch (Exception e) { - e.printStackTrace(); - } - - // TODO Init MIDI Page - - boolean fadeListener = true; - for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) { - if (!listener.allowFade(pad)) { - fadeListener = false; - } - } - - final boolean fade = fadeListener; - - // UI Clean in State READY - Platform.runLater(() -> - { - view.getPauseButton().setDisable(true); - view.getStopButton().setDisable(true); - - if (durationEventHandler != null) - durationEventHandler.stopWaning(); - durationEventHandler = null; - - view.pseudoClassState(PseudoClasses.PLAY_CALSS, false); - view.pseudoClassState(PseudoClasses.WARN_CLASS, false); - - if (oldState != PadStatus.PAUSE && fade) { - if (!pad.isEof() && (pad.isCustomFade() && pad.getFade().get().getFadeOut().toMillis() > 0 - || !pad.isCustomFade() && Profile.currentProfile().getProfileSettings().getFade().getFadeOut().toSeconds() > 0)) { - view.pseudoClassState(PseudoClasses.FADE_CLASS, true); - } - } - }); - - pad.stop(oldState != PadStatus.PAUSE && fade, () -> - { - // Bei Ende von Fade Out wird CSS removed - view.pseudoClassState(PseudoClasses.FADE_CLASS, false); - }); - - sendFeedback(oldState, newState); - } - - private void readyState() { - // Clean UI vom Play - Platform.runLater(() -> - { - view.getPlayBar().setProgress(0.0); - showPadDuration(); - - view.getPlayButton().setDisable(false); - view.getPauseButton().setDisable(true); - view.getStopButton().setDisable(true); - - view.pseudoClassState(PseudoClasses.PLAY_CALSS, false); - view.pseudoClassState(PseudoClasses.FADE_CLASS, false); - view.pseudoClassState(PseudoClasses.WARN_CLASS, false); - - // PadListener - for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) - try { - listener.onReady(pad); - } catch (Exception e) { - e.printStackTrace(); - } - }); - - removePlayer(); - } - - private void emptyState() { - view.getPlayButton().setDisable(true); - view.getPauseButton().setDisable(true); - view.getStopButton().setDisable(true); - } - - public void sendFeedback(PadStatus oldState, PadStatus newState) { - // TODO MIDI Send Feedback - } - - public void cleanUp() { - if (pad != null) { - // Wenn Play oder Pause dann erst Stop, bevor alles Aufgeräumt wird - if (pad.getStatus() == PadStatus.PLAY || pad.getStatus() == PadStatus.PAUSE) - pad.setStatus(PadStatus.STOP); - - pad.stop(false, null); - - // Listener für Gesamtzeit weg - // State des Pad -> UI Änderungen (wie Progressbar oder Button) - pad.getAudioHandler().durationProperty(pad).removeListener(totalDurationListener); - pad.stateProperty().removeListener(stateListener); - pad.getAudioHandler().loadedProperty().removeListener(audioLoadedListener); - pad.titleProperty().removeListener(titleListener); - pad.lastExceptionProperty().removeListener(exceptionListener); - pad.audioHandlerProperty().removeListener(audioHandlerListener); - - // view.getNameLabel().textProperty().unbind(); // Clear Title Label - view.getTimeLabel().setText(""); // Clear Time Label - view.getPlayBar().setProgress(0); // Zeit Leiste - view.setErrorLabelActive(false); // Error Weg - - view.getStyleClass().removeAll("pad", "pad" + pad.getIndex()); - - view.pseudoClassState(PseudoClasses.PLAY_CALSS, false); - view.pseudoClassState(PseudoClasses.FADE_CLASS, false); - view.pseudoClassState(PseudoClasses.WARN_CLASS, false); - - view.getIndexLabel().getStyleClass().removeAll("pad-index", "pad" + pad.getIndex() + "-index", "pad-info", - "pad" + pad.getIndex() + "-info"); - view.getTimeLabel().getStyleClass().removeAll("pad-time", "pad" + pad.getIndex() + "-time", "pad-info", - "pad" + pad.getIndex() + "-info"); - view.getNameLabel().getStyleClass().removeAll("pad-title", "pad" + pad.getIndex() + "-title"); - view.getPlayBar().getStyleClass().removeAll("pad-playbar", "pad" + pad.getIndex() + "-playbar"); - - view.getPlayButton().getStyleClass().removeAll("pad-button", "pad-playbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-playbutton"); - view.getPauseButton().getStyleClass().removeAll("pad-button", "pad-pausebutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-pausebutton"); - view.getStopButton().getStyleClass().removeAll("pad-button", "pad-stopbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-stopbutton"); - view.getNewButton().getStyleClass().removeAll("pad-button", "pad-newbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-newbutton"); - view.getSettingsButton().getStyleClass().removeAll("pad-button", "pad-settingsbutton", "pad" + pad.getIndex() + "-button", - "pad" + pad.getIndex() + "-settingsbutton"); - - view.getPlayButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-playbutton-icon", - "pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon"); - view.getPauseButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-pausebutton-icon", - "pad" + pad.getIndex() + "-button-icon", "padv-playbutton--icon"); - view.getStopButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-stopbutton-icon", - "pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon"); - view.getNewButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-newbutton-icon", - "pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon"); - view.getSettingsButton().getGraphic().getStyleClass().removeAll("pad-button-icon", "pad-deletebutton-icon", - "pad" + pad.getIndex() + "-button-icon", "pad" + pad.getIndex() + "-playbutton-icon"); - - view.getButtonBox().getStyleClass().removeAll("pad-button-box"); - view.getRoot().getStyleClass().removeAll("pad-root"); - } - } - - public AudioPadView getView() { - return view; - } - - // TODO ErrorHandling - private void showError() { - PadException lastException = pad.getLastException(); - - try { - ExceptionDialog dialog = new ExceptionDialog(lastException); - dialog.setHeaderText(Localization.getString(Strings.Error_Pad_BaseName + lastException.getType().name(), pad.getPath())); - - if (PlayPadMain.stageIcon.isPresent()) { - Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow(); - stage.getIcons().add(PlayPadMain.stageIcon.get()); - } - - dialog.setTitle(Localization.getString(Strings.UI_Dialog_Error_Title)); - dialog.initOwner(refreshable.getStage()); - dialog.showAndWait(); - - view.setErrorLabelActive(false); - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * Fügt einen Button zum Pad hinzu - * - * @param button - * - * @since 2.0.2 - */ - public void addButton(Button button, ButtonPosition buttonPosition) { - if (buttonPosition == ButtonPosition.TOP) { - if (!view.getButtonBox().getChildren().contains(button)) { - view.getInfoBox().getChildren().add(button); - } - } else if (buttonPosition == ButtonPosition.BOTTOM) { - if (!view.getButtonBox().getChildren().contains(button)) { - view.getButtonBox().getChildren().add(button); - } - } - } - - /** - * Fügt einen Button zum Pad hinzu - * - * @param button - * Button - * @param index - * Index - * - * @since 2.0.2 - */ - public void addNode(Node button, int index, ButtonPosition buttonPosition) { - if (buttonPosition == ButtonPosition.TOP) { - if (!view.getButtonBox().getChildren().contains(button)) { - view.getInfoBox().getChildren().add(index, button); - } - } else if (buttonPosition == ButtonPosition.BOTTOM) { - if (!view.getButtonBox().getChildren().contains(button)) { - view.getButtonBox().getChildren().add(index, button); - } - } - } - - /** - * Löscht einen Button vom Pad - * - * @param button - * - * @since 2.0.2 - */ - public void removeNode(Node button) { - if (view.getButtonBox().getChildren().contains(button)) { - view.getButtonBox().getChildren().remove(button); - } else if (view.getInfoBox().getChildren().contains(button)) { - view.getInfoBox().getChildren().remove(button); - } - } - - public List<Node> getCustomNodes() { - List<Node> buttons = new ArrayList<>(); - for (Node node : view.getButtonBox().getChildren()) { - if (node != view.getPlayButton() || node != view.getPauseButton() || node != view.getStopButton() || node != view.getNewButton() - || node != view.getSettingsButton()) { - buttons.add((Button) node); - } - } - return buttons; - } - - public void showDnDLayout(boolean show) { - view.pseudoClassState(PseudoClasses.DRAG_CLASS, show); - } -} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java deleted file mode 100644 index d603e65dbed0e8c5261784ffc4624391c1ba859f..0000000000000000000000000000000000000000 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PlayDurationEventHandler.java +++ /dev/null @@ -1,95 +0,0 @@ -package de.tobias.playpad.viewcontroller.pad; - -import de.tobias.playpad.midi.Midi; -import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Warning; -import de.tobias.playpad.settings.Profile; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.util.Duration; - -// TODO Renew class -class PlayDurationEventHandler implements ChangeListener<Duration>, Runnable { - - /** - * - */ - private final PadViewController padViewController; - - /** - * @param padViewController - */ - PlayDurationEventHandler(PadViewController padViewController) { - this.padViewController = padViewController; - } - - boolean send = false; - - private Thread warningThread; - - @Override - public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) { - if (!send) { - if (padViewController != null && padViewController.pad != null && !this.padViewController.pad.isLoop()) { - Duration rest = this.padViewController.pad.getAudioHandler().getDuration(this.padViewController.pad).subtract(newValue); - double seconds = rest.toSeconds(); - - Midi midi = Midi.getInstance(); - - if (this.padViewController.midiKeyPressedForPlay != -1) { - if (this.padViewController.pad.isCustomWarning()) { - if (this.padViewController.pad.getWarningFeedback().get().getTime().toSeconds() > seconds) { - startWarningThread(); - - if (midi.getMidiDevice().isPresent()) { - // TODO MIDI Send Feedback - } - send = true; - } - } else { - if (Profile.currentProfile().getProfileSettings().getWarningFeedback().getTime().toSeconds() > seconds) { - startWarningThread(); - - if (midi.getMidiDevice().isPresent()) { - // TODO MIDI Send Feedback - } - send = true; - } - } - } - } - } - } - - /* - * EoF GUI Flash - */ - @Override - public void run() { - Pad pad = padViewController.getPad(); - - Profile currentProfile = Profile.currentProfile(); - Warning warning = pad.getWarningFeedback().orElseGet(() -> currentProfile.getProfileSettings().getWarningFeedback()); - if (pad.isCustomLayout()) { - pad.currentLayout().ifPresent(layout -> layout.handleWarning(padViewController, warning)); - } else { - currentProfile.currentLayout().handleWarning(padViewController, warning); - } - } - - protected void startWarningThread() { - if (warningThread != null) { - warningThread.interrupt(); - } - warningThread = new Thread(this); - warningThread.start(); - } - - protected void stopWaning() { - if (warningThread != null) { - warningThread.interrupt(); - padViewController.getView().setStyle(""); - warningThread = null; - } - } -} \ No newline at end of file diff --git a/PlayWallCore/.classpath b/PlayWallCore/.classpath index 00f84a54d22f1d5e505d909d935271036d04b95b..39c2cf35ecb30b5188a50146bed735d9ccf04e41 100644 --- a/PlayWallCore/.classpath +++ b/PlayWallCore/.classpath @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry excluding="de/tobias/playpad/audio/AudioCache.java|de/tobias/playpad/midi/device/DisplayableDevice.java|de/tobias/playpad/plugin/ProjectHandler.java|de/tobias/playpad/plugin/Updatable.java|de/tobias/playpad/plugin/viewcontroller/IPadViewController.java|de/tobias/playpad/project/ProjectImporterOld.java|de/tobias/playpad/settings/MidiPreset.java|de/tobias/playpad/settings/MidiSettings.java|de/tobias/playpad/model/Pad.java|de/tobias/playpad/model/Project.java|de/tobias/playpad/layout/LayoutContainer.java" kind="src" path="src"/> + <classpathentry excluding="**/.DS_Store|**/.gitignore|de/tobias/playpad/audio/AudioCache.java|de/tobias/playpad/layout/LayoutContainer.java|de/tobias/playpad/midi/device/DisplayableDevice.java|de/tobias/playpad/model/Pad.java|de/tobias/playpad/model/Project.java|de/tobias/playpad/plugin/ProjectHandler.java|de/tobias/playpad/plugin/Updatable.java|de/tobias/playpad/plugin/viewcontroller/IPadViewController.java|de/tobias/playpad/project/ProjectImporterOld.java|de/tobias/playpad/settings/MidiPreset.java|de/tobias/playpad/settings/MidiSettings.java" kind="src" path="src"/> + <classpathentry kind="src" path="test"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry combineaccessrules="false" kind="src" path="/libUtils"/> <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Plugins"/> diff --git a/PlayWallCore/.gitignore b/PlayWallCore/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..94faa17313fb07d638498de2460e291e5d826ed9 --- /dev/null +++ b/PlayWallCore/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/test/ \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/action/Action.java b/PlayWallCore/src/de/tobias/playpad/action/Action.java index 0229b44121ac81c6abdde3719294c3446007589c..f142d444ac3b5b0486578fa0c0b406c8ef4dec12 100644 --- a/PlayWallCore/src/de/tobias/playpad/action/Action.java +++ b/PlayWallCore/src/de/tobias/playpad/action/Action.java @@ -47,8 +47,6 @@ public abstract class Action implements ActionDisplayable, Cloneable { * * @param type * input type - * @param messageID - * Message ID (for identiication of the next message) * @param project * Current Project * @param mainViewController @@ -76,8 +74,10 @@ public abstract class Action implements ActionDisplayable, Cloneable { /** * Init first Feedback to Mapper (Feedback) * - * @param message - * Type of Message (Feedback) + * @param project + * refence to the current opened project + * @param controller + * reference to the main view controller */ public abstract void initFeedback(Project project, IMainViewController controller); diff --git a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java index f2ea10f3557069f71611c7a13f09833dc5072a39..b451611d56c5073846b874c42e7f1d2f30123f20 100644 --- a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java +++ b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java @@ -9,6 +9,7 @@ import java.util.stream.Collectors; import org.dom4j.Element; +import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.action.mapper.Mapper; import de.tobias.playpad.action.mapper.MapperConnect; import de.tobias.playpad.action.mapper.MapperConnectFeedbackable; @@ -132,6 +133,11 @@ public class Mapping implements Cloneable, ActionDisplayable { } } + public void showFeedback(Project project) { + IMainViewController controller = PlayPadPlugin.getImplementation().getMainViewController(); + showFeedback(project, controller); + } + public void showFeedback(Project project, IMainViewController controller) { clearFeedback(); @@ -151,6 +157,7 @@ public class Mapping implements Cloneable, ActionDisplayable { ((MapperConnectFeedbackable) mapper).clearFeedbackType(); } } + getActions().forEach(action -> action.clearFeedback()); } private static final String NAME = "name"; diff --git a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java index dd2ffb8b10a61063b77a141db853e3b147ab378a..abdda9d2d12de6665cf8539801d2c57966df1b9f 100644 --- a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java +++ b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java @@ -1,5 +1,7 @@ package de.tobias.playpad.action.feedback; +import javafx.scene.paint.Color; + public interface ColorAssociator { public DisplayableFeedbackColor[] getColors(); @@ -9,4 +11,6 @@ public interface ColorAssociator { public DisplayableFeedbackColor getDefaultEventColor(); public void setColor(FeedbackMessage feedbackMessage, int value); + + public DisplayableFeedbackColor map(Color color); } diff --git a/PlayWallCore/src/de/tobias/playpad/action/mapper/Mapper.java b/PlayWallCore/src/de/tobias/playpad/action/mapper/Mapper.java index 18b816482c23da82cf9935addfdab506ac505a85..a64f8af9d6b822ba309a726271e562cabeba0267 100644 --- a/PlayWallCore/src/de/tobias/playpad/action/mapper/Mapper.java +++ b/PlayWallCore/src/de/tobias/playpad/action/mapper/Mapper.java @@ -35,7 +35,10 @@ public abstract class Mapper implements Displayable, Cloneable { public abstract Mapper cloneMapper() throws CloneNotSupportedException; public static DisplayableFeedbackColor searchColor(ColorAssociator colorAssociator, FeedbackMessage message, Color color) { - DisplayableFeedbackColor minColor = null; + DisplayableFeedbackColor minColor = colorAssociator.map(color); + if (minColor != null) { + return minColor; + } double minVal = 1; for (DisplayableFeedbackColor feedbackColor : colorAssociator.getColors()) { @@ -50,7 +53,7 @@ public abstract class Mapper implements Displayable, Cloneable { } } } - if (minColor != null && minVal < 0.4) { + if (minColor != null && minVal < 0.35) { return minColor; } else if (message == FeedbackMessage.STANDARD) { return colorAssociator.getDefaultStandardColor(); diff --git a/PlayWallCore/src/de/tobias/playpad/action/mididevice/DeviceColorAssociatorConnector.java b/PlayWallCore/src/de/tobias/playpad/action/mididevice/DeviceColorAssociatorConnector.java index 7e3157dc432dfd91c3ec365561d8bda75c9460ae..0ab7506fe15a9fe277bbbf48f46485e5a6ef5bc3 100644 --- a/PlayWallCore/src/de/tobias/playpad/action/mididevice/DeviceColorAssociatorConnector.java +++ b/PlayWallCore/src/de/tobias/playpad/action/mididevice/DeviceColorAssociatorConnector.java @@ -1,6 +1,7 @@ package de.tobias.playpad.action.mididevice; import de.tobias.playpad.action.feedback.DisplayableFeedbackColor; +import javafx.scene.paint.Color; public interface DeviceColorAssociatorConnector { @@ -9,4 +10,6 @@ public interface DeviceColorAssociatorConnector { public DisplayableFeedbackColor getDefaultEventColor(); public DisplayableFeedbackColor[] getColors(); + + public DisplayableFeedbackColor map(Color color); } diff --git a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java index 816f19667f7ffc51cf3077f87a14d22f918b7304..adf948d31e2541f227622c6d79a1919cc7e5f261 100644 --- a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java +++ b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java @@ -35,7 +35,7 @@ public abstract class AudioHandler { public abstract ReadOnlyObjectProperty<Duration> durationProperty(); - public abstract void setVolume(double volume, double masterVolume); + public abstract void setVolume(double volume, double masterVolume, double customVolume); public abstract boolean isMediaLoaded(); @@ -43,5 +43,4 @@ public abstract class AudioHandler { public abstract void unloadMedia(); - public abstract void updateVolume(double masterVolume); } diff --git a/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java b/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java index 5a2aa3e3243a6b52abb69588b44054691003a99b..851d42c6e2ec04a1d056b6b28d3bdd9607e6dab1 100644 --- a/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java +++ b/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java @@ -30,4 +30,6 @@ public interface CartLayout { public default void stopWarning(IPadViewController controller) {} public void reset(); + + public void copyGlobalLayout(GlobalLayout globalLayout); } diff --git a/PlayWallCore/src/de/tobias/playpad/layout/LayoutContainer.java b/PlayWallCore/src/de/tobias/playpad/layout/LayoutContainer.java deleted file mode 100644 index d0e83a7783e6400e9e66d2329f46bfc1b96d6539..0000000000000000000000000000000000000000 --- a/PlayWallCore/src/de/tobias/playpad/layout/LayoutContainer.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.tobias.playpad.layout; - -import de.tobias.playpad.viewcontroller.CartLayoutViewController; -import de.tobias.playpad.viewcontroller.GlobalLayoutViewController; - -public class LayoutContainer { - - private String id; - String name; - Class<? extends GlobalLayout> globalClass; - Class<? extends CartLayout> cartClass; - - Class<? extends GlobalLayoutViewController> globalVC; - Class<? extends CartLayoutViewController> cartVC; - - public LayoutContainer(String id, String name, Class<? extends GlobalLayout> globalClass, Class<? extends CartLayout> cartClass, - Class<? extends GlobalLayoutViewController> globalVC, Class<? extends CartLayoutViewController> cartCV) { - this.id = id; - this.name = name; - this.globalClass = globalClass; - this.cartClass = cartClass; - this.globalVC = globalVC; - this.cartVC = cartCV; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public Class<? extends GlobalLayout> getGlobalClass() { - return globalClass; - } - - public Class<? extends CartLayout> getCartClass() { - return cartClass; - } - - public Class<? extends GlobalLayoutViewController> getGlobalVC() { - return globalVC; - } - - public Class<? extends CartLayoutViewController> getCartVC() { - return cartVC; - } -} \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/model/Pad.java b/PlayWallCore/src/de/tobias/playpad/model/Pad.java deleted file mode 100644 index 3d73a9265f2238df83116d187ff09fe45ff7f7fa..0000000000000000000000000000000000000000 --- a/PlayWallCore/src/de/tobias/playpad/model/Pad.java +++ /dev/null @@ -1,585 +0,0 @@ -package de.tobias.playpad.model; - -import java.io.FileNotFoundException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Optional; - -import de.tobias.playpad.audio.AudioHandler; -import de.tobias.playpad.audio.AudioRegistry; -import de.tobias.playpad.model.layout.CartLayout; -import de.tobias.playpad.model.layout.LayoutRegistry; -import de.tobias.playpad.model.settings.Warning; -import de.tobias.playpad.pad.Fade; -import de.tobias.playpad.plugin.PadListener; -import de.tobias.playpad.plugin.PlayPadPlugin; -import de.tobias.playpad.plugin.viewcontroller.IPadViewController; -import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.settings.ProfileSettings; -import javafx.animation.Transition; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.IntegerProperty; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.ReadOnlyIntegerProperty; -import javafx.beans.property.ReadOnlyObjectProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleIntegerProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; -import javafx.util.Duration; - -public class Pad implements Comparable<Pad> { - - public enum State { - PLAY, - STOP, - EMPTY, - READY, - PAUSE; - } - - public enum TimeMode { - PLAYED, - REST, - BOTH; - } - - private IntegerProperty indexProperty; - private ObjectProperty<State> stateProperty; // Änderungen in PadView -> Wird hier dann Methoden aufgerufen - - private ObjectProperty<AudioHandler> audioHandlerProperty; - - private StringProperty pathProperty; // URI Format - private StringProperty titleProperty; - - private BooleanProperty loopProperty; - private double volumeProperty = 1; - - // Layout - private boolean customLayout = false; - private HashMap<String, CartLayout> layouts = new HashMap<>(); - - // Settings - private Optional<TimeMode> timeMode = Optional.empty(); - private Optional<Warning> warningFeedback = Optional.empty(); - private Optional<Fade> fade = Optional.empty(); - - private HashMap<String, Object> userInfo = new HashMap<>(); - - // Temporäre Variablen - private transient boolean isPlaying = false; - private transient boolean isEof = false; - - private transient Transition transition; - - // GUI und Project Referenz - private transient IPadViewController controller; - private transient ObjectProperty<PadException> lastExceptionProperty; - private transient Project project; - - public Pad(int index, Project project) { - this(index, null, null, State.EMPTY, project); - } - - public Pad(int index, String path, String title, State state, Project project) { - this(index, path, title, state, true, project); - } - - public Pad(int index, String path, String title, State state, boolean loadMedia, Project project) { - this.indexProperty = new SimpleIntegerProperty(index); - this.pathProperty = new SimpleStringProperty(path); - this.titleProperty = new SimpleStringProperty(title); - this.stateProperty = new SimpleObjectProperty<Pad.State>(state); - - this.lastExceptionProperty = new SimpleObjectProperty<>(); - this.loopProperty = new SimpleBooleanProperty(); - - this.project = project; - - this.audioHandlerProperty = new SimpleObjectProperty<>(AudioRegistry.geAudioType().createAudioHandler()); - - if (path != null && loadMedia) - loadMedia(); - } - - /* - * Getter - */ - public int getIndex() { - return indexProperty.get(); - } - - public State getState() { - return stateProperty.get(); - } - - public AudioHandler getAudioHandler() { - return audioHandlerProperty.get(); - } - - /** - * File in URI Form - * - * @return URI for Resource - */ - public String getFile() { - return pathProperty.get(); - } - - public Path getPath() throws MalformedURLException, URISyntaxException { - if (getFile() != null) - return Paths.get(new URL(getFile()).toURI()); - return null; - } - - public String getFileName() throws MalformedURLException, URISyntaxException { - return getPath().getFileName().toString(); - } - - public String getTitle() { - return titleProperty.get(); - } - - public boolean isLoop() { - return loopProperty.get(); - } - - public double getVolume() { - return volumeProperty; - } - - public boolean isCustomLayout() { - return customLayout; - } - - public Optional<CartLayout> getLayout(String type) { - if (!layouts.containsKey(type)) { - try { - CartLayout layout = LayoutRegistry.newCartLayoutInstance(type); - layouts.put(type, layout); - } catch (InstantiationException | IllegalAccessException e) { - e.printStackTrace(); - return Optional.empty(); - } - } - return Optional.of(layouts.get(type)); - } - - public Optional<CartLayout> currentLayout() { - return getLayout(Profile.currentProfile().getProfileSettings().getLayoutType()); - } - - public HashMap<String, CartLayout> getLayouts() { - return layouts; - } - - public boolean isCustomTimeMode() { - return timeMode.isPresent(); - } - - public Optional<TimeMode> getTimeMode() { - return timeMode; - } - - public boolean isCustomWarning() { - return warningFeedback.isPresent(); - } - - public Optional<Warning> getWarningFeedback() { - return warningFeedback; - } - - public boolean isCustomFade() { - return fade.isPresent(); - } - - public Optional<Fade> getFade() { - return fade; - } - - public HashMap<String, Object> getUserInfo() { - return userInfo; - } - - public boolean isPlaying() { - return isPlaying; - } - - /* - * Setter - */ - - void setIndex(int index) { - this.indexProperty.set(index); - } - - public void setState(State state) { - if (this.stateProperty.get() != State.EMPTY || state == State.READY) { - this.stateProperty.set(state); - } - } - - public void setPath(Path path) { - setPath(path, true); - } - - public void setPath(Path path, boolean load) { - throwException(null); - - String uri = path.toUri().toString(); - String name = path.getFileName().toString(); - - this.pathProperty.set(uri); - this.titleProperty.set(name.substring(0, name.lastIndexOf("."))); - if (load) - loadMedia(); - } - - public void setTitle(String title) { - this.titleProperty.set(title); - } - - public void setLoop(boolean loop) { - this.loopProperty.set(loop); - } - - public void setVolume(double volume) { - if (volume <= 1.0 && volume >= 0.0) { - this.volumeProperty = volume; - audioHandlerProperty.get().setVolume(this, volume, getMasterVolume()); - } - } - - public void setLayout(String type, CartLayout layout) { - layouts.put(type, layout); - } - - public void setCustomLayout(boolean b) { - customLayout = b; - } - - public void setTimeMode(TimeMode timeMode) { - if (timeMode != null) { - this.timeMode = Optional.of(timeMode); - } else { - this.timeMode = Optional.empty(); - } - } - - public void setWarningFeedback(Warning warningFeedback) { - if (warningFeedback != null) { - this.warningFeedback = Optional.of(warningFeedback); - } else { - this.warningFeedback = Optional.empty(); - } - } - - public void setFade(Fade fade) { - if (fade != null) { - this.fade = Optional.of(fade); - } else { - this.fade = Optional.empty(); - } - } - - /* - * Properties - */ - - public ReadOnlyIntegerProperty indexProperty() { - return indexProperty; - } - - public ObjectProperty<State> stateProperty() { - return stateProperty; - } - - public StringProperty titleProperty() { - return titleProperty; - } - - public ReadOnlyObjectProperty<Duration> currentDurationProperty() { - if (audioHandlerProperty.get().isMediaLoaded(this)) - return audioHandlerProperty.get().positionProperty(this); - else - return null; - } - - public boolean hasMedia() { - return getFile() != null; - } - - @Override - public int compareTo(Pad o) { - return Integer.compare(getIndex(), o.getIndex()); - } - - @Override - public String toString() { - return getIndex() + ": " + getTitle(); - } - - public String toPrettyString() { - return (getIndex() + 1) + ": " + getTitle(); - } - - public boolean isEof() { - return isEof; - } - - public boolean isVideo() { - for (String extension : PlayPadPlugin.getImplementation().getVideoFiles()) { - if (pathProperty.get() != null) { - if (pathProperty.get().matches("." + extension)) - return true; - } - } - return false; - } - - public IPadViewController getController() { - return controller; - } - - public void setController(IPadViewController controller) { - this.controller = controller; - } - - public boolean isPadLoaded() { - if (audioHandlerProperty.get().isMediaLoaded(this)) { - return true; - } else { - for (PadListener listener : PlayPadPlugin.getImplementation().getPadListener()) { - if (listener.isPadLoaded(this)) - return true; - } - } - return false; - } - - public void clearMedia() { - if (getState() == State.PAUSE || getState() == State.PLAY) - setState(State.STOP); - audioHandlerProperty.get().unloadMedia(this); - pathProperty.set(null); - lastExceptionProperty.set(null); - } - - public void setEof(boolean eof) { - this.isEof = eof; - } - - public void setPlaying(boolean playing) { - this.isPlaying = playing; - } - - public ObjectProperty<AudioHandler> audioHandlerProperty() { - return audioHandlerProperty; - } - - public Project getProject() { - return project; - } - - // Exception - public void throwException(Exception ex) { - if (ex != null) { - PadException padException = new PadException(this, ex); - lastExceptionProperty.set(padException); - ex.printStackTrace(); - } else { - lastExceptionProperty.set(null); - } - } - - public PadException getLastException() { - return lastExceptionProperty.get(); - } - - public ObjectProperty<PadException> lastExceptionProperty() { - return lastExceptionProperty; - } - - private double getMasterVolume() { - return Profile.currentProfile().getProfileSettings().getVolume(); - } - - // Action Methods - public void play() { - isEof = false; - isPlaying = true; - - if (!audioHandlerProperty.get().isMediaLoaded(this)) { - loadMedia(); - } - audioHandlerProperty.get().setVolume(this, volumeProperty, getMasterVolume()); - - audioHandlerProperty.get().play(this); - - if ((fade.isPresent() && fade.get().getFadeIn().toMillis() > 0.0) - || (!fade.isPresent() && Profile.currentProfile().getProfileSettings().getFade().getFadeIn().toSeconds() > 0.0)) { - fadeIn(); - } - - } - - public void fadeIn() { - if (transition != null) { - transition.stop(); - } - - audioHandlerProperty.get().setVolume(this, 0, getMasterVolume()); - transition = new Transition() { - - { - if (fade.isPresent()) - setCycleDuration(fade.get().getFadeIn()); - else - setCycleDuration(Profile.currentProfile().getProfileSettings().getFade().getFadeIn()); - } - - @Override - protected void interpolate(double frac) { - audioHandlerProperty.get().setVolume(Pad.this, frac * getVolume(), getMasterVolume()); - } - }; - transition.play(); - } - - public void pause(boolean fadeOut, Runnable onFinish) { - if (audioHandlerProperty.get().isMediaLoaded(this)) { - if (fadeOut && (fade.isPresent() && fade.get().getFadeOut().toMillis() > 0 - || Profile.currentProfile().getProfileSettings().getFade().getFadeOut().toSeconds() > 0)) { - fadeOut(() -> - { - audioHandlerProperty.get().pause(this); - if (onFinish != null) - onFinish.run(); - }); - } else { - audioHandlerProperty.get().pause(this); - if (onFinish != null) - onFinish.run(); - } - } - } - - public void stop(boolean fadeOut, Runnable onFinish) { - if (isPlaying == true) { - if (audioHandlerProperty.get().isMediaLoaded(this)) { - isPlaying = false; - if ((fadeOut && !isEof) && (fade.isPresent() && fade.get().getFadeOut().toMillis() > 0 - || Profile.currentProfile().getProfileSettings().getFade().getFadeOut().toSeconds() > 0)) { - if (!isEof) { // Nur wenn nicht am Ende vom Media Player - fadeOut(() -> - { - audioHandlerProperty.get().stop(this); - stateProperty.set(State.READY); - if (onFinish != null) - onFinish.run(); - }); - return; - } - } else { - audioHandlerProperty.get().stop(this); - if (onFinish != null) - onFinish.run(); - stateProperty.set(State.READY); - } - } - } - } - - /* - * https://gist.github.com/mariuszz/5099053 | https://gist.github.com/james-d/10800593 - */ - public void fadeOut(Runnable onFinish) { - if (transition != null) { - transition.stop(); - } - transition = new Transition() { - - { - if (fade.isPresent()) - setCycleDuration(fade.get().getFadeOut()); - else - setCycleDuration(Profile.currentProfile().getProfileSettings().getFade().getFadeOut()); - } - - @Override - protected void interpolate(double frac) { - audioHandlerProperty.get().setVolume(Pad.this, getVolume() - frac * getVolume(), getMasterVolume()); - } - }; - transition.setOnFinished(event -> - { - onFinish.run(); - }); - transition.play(); - } - - // Loader - public void loadMedia() { - try { - audioHandlerProperty.set(AudioRegistry.geAudioType().createAudioHandler()); - - // wenn neue Media geladen werden soll, muss der Path temporär gespeichert werden, da in clearMedia gelöscht wird - String tempPath = pathProperty.get(); - - // Altes Löschen - if (isPadLoaded()) - clearMedia(); - - pathProperty.set(tempPath); - if (pathProperty.get() != null) { - Path path = Paths.get(URI.create(pathProperty.get())); - if (Files.notExists(path)) { - throwException(new FileNotFoundException()); - return; - } - - // Check File Extension - if (audioHandlerProperty.get().isMediaSupported(getPath())) - audioHandlerProperty.get().loadMedia(this); - } - } catch (Exception e) { - throwException(e); - e.printStackTrace(); - } - } - - public void clearPad() { - if (getState() == State.PAUSE || getState() == State.PLAY) - setState(State.STOP); - audioHandlerProperty.get().unloadMedia(this); - - PlayPadPlugin.getImplementation().getPadListener().forEach(l -> l.onClear(this)); - - titleProperty.set(null); - pathProperty.set(null); - lastExceptionProperty.set(null); - - userInfo.clear(); - - setState(State.EMPTY); - } - - public static final boolean padInRange(int page, Pad pad) { - ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings(); - - int currentStartIndex = page * profilSettings.getColumns() * profilSettings.getRows(); - int currentEndIndex = currentStartIndex + profilSettings.getColumns() * profilSettings.getRows() - 1; - if (pad.getIndex() <= currentEndIndex && pad.getIndex() >= currentStartIndex) { - return true; - } else { - return false; - } - } -} \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/model/Project.java b/PlayWallCore/src/de/tobias/playpad/model/Project.java deleted file mode 100644 index 04cc992a04772ee7bec26d3de9468b2fa20978c9..0000000000000000000000000000000000000000 --- a/PlayWallCore/src/de/tobias/playpad/model/Project.java +++ /dev/null @@ -1,647 +0,0 @@ -package de.tobias.playpad.model; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; - -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; -import org.dom4j.Element; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.SAXReader; -import org.dom4j.io.XMLWriter; - -import com.sun.nio.zipfs.ZipFileSystem; - -import de.tobias.playpad.model.Pad.TimeMode; -import de.tobias.playpad.model.layout.CartLayout; -import de.tobias.playpad.model.layout.LayoutRegistry; -import de.tobias.playpad.model.midi.Displayable; -import de.tobias.playpad.model.settings.Warning; -import de.tobias.playpad.pad.Fade; -import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Pad.PadStatus; -import de.tobias.playpad.plugin.PlayPadPlugin; -import de.tobias.playpad.project.ProjectReference; -import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.settings.ProfileSettings; -import de.tobias.utils.application.ApplicationUtils; -import de.tobias.utils.application.container.PathType; -import de.tobias.utils.settings.UserDefaults; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; - -public class Project implements Displayable { - - private StringProperty displayProperty = new SimpleStringProperty(); - - private Profile profile; - - private HashMap<Integer, Pad> pads = new HashMap<>(); - private ObjectProperty<String> nameProperty; - private ProjectReference projectReference; - - public Project(Profile profile, ProjectReference projectReference) { - this.profile = profile; - this.projectReference = projectReference; - this.nameProperty = new SimpleObjectProperty<>(projectReference.getName()); - } - - public Pad getPad(int index) { - Pad pad = pads.get(index); - if (pad != null) { - return pad; - } else { - pad = new Pad(index, this); - pads.put(index, pad); - return pad; - } - } - - public void setPad(Pad pad, int index) { - this.pads.put(index, pad); - } - - public HashMap<Integer, Pad> getPads() { - return pads; - } - - public int size() { - return pads.size(); - } - - public void add(Pad pad) { - pads.put(pad.getIndex(), pad); - } - - public String getName() { - return nameProperty.get(); - } - - public void setName(String name) throws Exception { - Path oldPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, nameProperty.get()); - Path newPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, name); - - projectReference.setName(name); - this.nameProperty.set(name); - - // Move File on Disk - Files.move(oldPath, newPath); - } - - public ProjectReference getProjectReference() { - return projectReference; - } - - public ObjectProperty<String> nameProperty() { - return nameProperty; - } - - public void clearUnneededPads() { - ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings(); - int maxPads = profilSettings.getPageCount() * profilSettings.getColumns() * profilSettings.getRows(); - - for (int i = maxPads; i < pads.size(); i++) { - Pad pad = getPad(i); - pad.clearPad(); - } - List<Integer> removeList = new ArrayList<>(); - for (int key : pads.keySet()) { - if (key >= maxPads) - removeList.add(key); - } - removeList.forEach(pads::remove); - } - - public void clearPads() { - pads.values().forEach(pad -> - { - pad.clearPad(); - }); - pads.clear(); - } - - /** - * Öffnet Project und Profile - * - * @param name - * @param request - * @param profileName - * @return - * @throws DocumentException - * @throws IOException - * @throws IllegalAccessException - * @throws InstantiationException - * @throws IllegalArgumentException - */ - public static Project loadFile(ProjectReference projectReference, ProfileChooseable request, String profileName) - throws DocumentException, IOException, IllegalArgumentException, InstantiationException, IllegalAccessException { - return loadFile(projectReference, request, profileName, true); - } - - /** - * Öffnet Project und Profile (name + XML) - * - * @param name - * @param request - * @param profileName - * @param loadMedia - * @return - * @throws DocumentException - * @throws IOException - * @throws IllegalAccessException - * @throws InstantiationException - * @throws IllegalArgumentException - */ - public static Project loadFile(ProjectReference projectReference, ProfileChooseable request, String profileName, boolean loadMedia) - throws DocumentException, IOException, IllegalArgumentException, InstantiationException, IllegalAccessException { - Path path = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, projectReference.getName()); - - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(path)); - Element root = document.getRootElement(); - - // Lädt das Profile - Profile profile = null; - if (profileName != null) { - profile = Profile.load(profileName); - } else { - Element profileElement = root.element("Profile"); - if (profileElement != null) { - if (Profile.getProfiles().contains(profileElement.getStringValue())) { - profile = Profile.load(profileElement.getStringValue()); - } - } - } - // Wenn Profile laden nicht ging - if (profile == null) { - if (request != null) - profile = request.getUnkownProfile(); - else - profile = Profile.load(Profile.getProfiles().get(0)); - } - - Project project = new Project(profile, projectReference); - - for (Object element : root.elements("Pad")) { - Element padElement = (Element) element; - int index = Integer.valueOf(padElement.attribute("index").getValue()); // Index - PadStatus state = PadStatus.valueOf(padElement.element("State").getStringValue()); // State - - Element titleElement = padElement.element("Title"); - Element pathElement = padElement.element("Path"); - - Pad pad; - - if (titleElement != null && pathElement != null) { - pad = new Pad(index, pathElement.getStringValue(), titleElement.getStringValue(), state, loadMedia, project); - } else { - pad = new Pad(index, project); - } - - double volume = padElement.element("Volume") != null ? Double.valueOf(padElement.element("Volume").getStringValue()) : 1.0; // Volume - pad.setVolume(volume); - - if (padElement.element("Loop") != null) { - boolean loop = Boolean.valueOf(padElement.element("Loop").getStringValue()); - pad.setLoop(loop); - } - - Element timeModeElement = padElement.element("TimeMode"); - if (timeModeElement != null) { - de.tobias.playpad.pad.Pad.TimeMode timeMode = TimeMode.valueOf(timeModeElement.getStringValue()); - pad.setTimeMode(timeMode); - } - - Element fadeElement = padElement.element("Fade"); - if (fadeElement != null) { - Optional<Fade> fade = Fade.load(fadeElement); - if (fade.isPresent()) - pad.setFade(fade.get()); - } - - Element layoutElement = padElement.element("Layout"); - // Old Version - if (layoutElement != null) { - int version = Integer.valueOf(layoutElement.attributeValue("version")); - if (version == 2) { - for (Object layoutObj : layoutElement.elements("CartLayout")) { - try { - Element cartLayoutElement = (Element) layoutObj; - String type = cartLayoutElement.attributeValue("type"); - - CartLayout layout = LayoutRegistry.newCartLayoutInstance(type); - layout.load(cartLayoutElement); - - pad.setLayout(type, layout); - pad.setCustomLayout(true); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - Element warningElement = padElement.element("Warning"); - if (warningElement != null) { - Optional<Warning> warningFeedback = Warning.loadV2(warningElement); - if (warningFeedback.isPresent()) { - pad.setWarningFeedback(warningFeedback.get()); - } - } - - Element userInfoElement = padElement.element("UserInfo"); - if (userInfoElement != null) { - for (Object object : userInfoElement.elements()) { - if (object instanceof Element) { - Element item = (Element) object; - String key = item.attributeValue("key"); - if (item.attribute("type") == null) { - // Old - String value = item.getStringValue(); - pad.getUserInfo().put(key, value); - } else { - Object data = UserDefaults.loadElement(item); - pad.getUserInfo().put(key, data); - } - } - } - } - - project.add(pad); - } - - project.displayProperty.set(project.toString()); - - // Mit Leeren Pads auffüllen - ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings(); - for (int i = 0; i < profilSettings.getPageCount() * profilSettings.getColumns() * profilSettings.getRows() - 1; i++) { - project.getPad(i); - } - - System.out.println("Load Project: " + project.getName()); - - return project; - } - - public void saveFile() throws UnsupportedEncodingException, IOException { - Path path = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, getName()); - - Document document = DocumentHelper.createDocument(); - Element root = document.addElement("Pads"); - - root.addElement("Profile").addText(profile.getName()); - - for (Pad pad : pads.values()) { - if (pad.getState() == State.PLAY || pad.getState() == State.PAUSE || pad.getState() == State.STOP) { - pad.setState(State.READY); - } - - PlayPadPlugin.getImplementation().getPadListener().forEach(l -> l.onSave(pad)); - - if (pad.getState() != State.EMPTY) { - Element padElement = root.addElement("Pad"); - padElement.addAttribute("index", String.valueOf(pad.getIndex())); - - // Basic - if (pad.getFile() != null) { - Element pathElement = padElement.addElement("Path"); - pathElement.addText(pad.getFile()); - } - - Element titleElement = padElement.addElement("Title"); - titleElement.addText(pad.getTitle()); - - Element stateElement = padElement.addElement("State"); - stateElement.addText(pad.getState().name()); - - // Einstellungen - padElement.addElement("Volume").addText(String.valueOf(pad.getVolume())); - padElement.addElement("Loop").addText(String.valueOf(pad.isLoop())); - - if (pad.isCustomTimeMode()) - padElement.addElement("TimeMode").addText(pad.getTimeMode().get().name()); - - if (pad.isCustomWarning()) { - Element warningElement = padElement.addElement("Warning"); - pad.getWarningFeedback().get().save(warningElement); - } - - if (pad.isCustomLayout()) { - Element layoutElement = padElement.addElement("Layout"); - layoutElement.addAttribute("version", "2"); - for (String layoutType : pad.getLayouts().keySet()) { - Optional<CartLayout> layoutOpt = pad.getLayout(layoutType); - - layoutOpt.ifPresent(layout -> - { - Element cartLayoutElement = layoutElement.addElement("CartLayout"); - cartLayoutElement.addAttribute("type", layoutType); - layout.save(cartLayoutElement); - }); - } - } - - if (pad.isCustomFade()) { - Element fadeElement = padElement.addElement("Fade"); - pad.getFade().get().save(fadeElement); - } - - Element userInfoElement = padElement.addElement("UserInfo"); - for (String key : pad.getUserInfo().keySet()) { - Element itemElement = userInfoElement.addElement("Item"); - UserDefaults.save(itemElement, pad.getUserInfo().get(key), key); - } - } else { - if (pad.isCustomLayout()) { - Element padElement = root.addElement("Pad"); - padElement.addAttribute("index", String.valueOf(pad.getIndex())); - - Element stateElement = padElement.addElement("State"); - stateElement.addText(pad.getState().name()); - - Element layoutElement = padElement.addElement("Layout"); - layoutElement.addAttribute("version", "2"); - for (String layoutType : pad.getLayouts().keySet()) { - Optional<CartLayout> layoutOpt = pad.getLayout(layoutType); - - layoutOpt.ifPresent(layout -> - { - Element cartLayoutElement = layoutElement.addElement("CartLayout"); - cartLayoutElement.addAttribute("type", layoutType); - layout.save(cartLayoutElement); - }); - } - } - } - } - - if (Files.notExists(path)) { - Files.createDirectories(path.getParent()); - Files.createFile(path); - } - - XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); - } - - public Profile getProfile() { - return profile; - } - - public void replace(int src, int des) { - Pad srcPad = getPad(src); - srcPad.setIndex(des); - pads.put(des, srcPad); - pads.remove(src); - } - - public void move(int src, int des) { - Pad oldPad = getPad(src); - Pad newPad = getPad(des); - - oldPad.setIndex(des); - newPad.setIndex(src); - - pads.put(des, oldPad); - pads.put(src, newPad); - } - - @Override - public String toString() { - return nameProperty.get(); - } - - @Override - public StringProperty displayProperty() { - return displayProperty; - } - - public void exportProject(Path zipFile, boolean includeProfile, boolean includeMedia) throws IOException { - saveFile(); - - URI p = Paths.get(zipFile.toString()).toUri(); - URI uri = URI.create("jar:" + p); - - Map<String, String> env = new HashMap<>(); - env.put("create", "true"); - env.put("encoding", "UTF-8"); - - // Delete Esisting Zip File - if (Files.exists(zipFile)) - Files.delete(zipFile); - - FileSystem zipfs = FileSystems.newFileSystem(uri, env); - - // Info Datei - Document document = DocumentHelper.createDocument(); - Element root = document.addElement("Info"); - root.addElement("Project").addText(nameProperty.get()); - if (includeProfile) - root.addElement("Profile").addText(profile.getName()); - - XMLWriter writer = new XMLWriter(Files.newOutputStream(zipfs.getPath("Info.xml")), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); - - // Profile - if (includeMedia) { - Path profilePath = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, profile.getName()); - Files.copy(profilePath, zipfs.getPath(profile.getName()), StandardCopyOption.REPLACE_EXISTING); - Files.copy(profilePath.resolve("ProfileSettings.xml"), zipfs.getPath(profile.getName(), "ProfileSettings.xml"), - StandardCopyOption.REPLACE_EXISTING); - Files.copy(profilePath.resolve("Midi.xml"), zipfs.getPath(profile.getName(), "Midi.xml"), StandardCopyOption.REPLACE_EXISTING); - Files.copy(profilePath.resolve("Layout.xml"), zipfs.getPath(profile.getName(), "Layout.xml"), StandardCopyOption.REPLACE_EXISTING); - } - - // Mediafiles - if (includeMedia) { - Path mediaFolder = zipfs.getPath("/media"); - Files.createDirectory(mediaFolder); - - for (Pad pad : pads.values()) { - if (pad.isPadLoaded()) - try { - Path mediaPath = pad.getPath(); - Files.copy(mediaPath, mediaFolder.resolve(mediaPath.getFileName().toString())); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - // Project - Path projectFile = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, getName()); - Files.copy(projectFile, zipfs.getPath("/", nameProperty.get()), StandardCopyOption.REPLACE_EXISTING); - - zipfs.close(); - } - - public static Project importProject(Path zipFile, Importable replaceRequest) - throws DocumentException, IOException, IllegalArgumentException, InstantiationException, IllegalAccessException { - ZipFileSystem fileSystem = (ZipFileSystem) FileSystems.newFileSystem(zipFile, null); - - Path infoPath = fileSystem.getPath("/Info.xml"); - if (Files.exists(infoPath)) { - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(infoPath)); - Element root = document.getRootElement(); - - if (root.element("Project") != null) { - String projectFile = root.element("Project").getStringValue(); - - // Profile Einstellungen - String importProfile = null; - if (root.element("Profile") != null) { - String profile = root.element("Profile").getStringValue(); - - // Profile - Path profilePath = fileSystem.getPath("/", profile); - Path profilePathDes = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, profile); - - importProfile = profile; - if (Files.exists(profilePathDes)) { - importProfile = replaceRequest.replaceProfile(profile); - } - if (importProfile != null) { - profilePathDes = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, importProfile); - System.out.println("Copy Profile: " + profilePathDes); - - if (Files.exists(profilePath)) { - if (Files.notExists(profilePathDes)) - Files.createDirectories(profilePathDes); - - Files.copy(profilePath.resolve("ProfileSettings.xml"), profilePathDes.resolve("ProfileSettings.xml"), - StandardCopyOption.REPLACE_EXISTING); - Files.copy(profilePath.resolve("Midi.xml"), profilePathDes.resolve("Midi.xml"), StandardCopyOption.REPLACE_EXISTING); - Files.copy(profilePath.resolve("Layout.xml"), profilePathDes.resolve("Layout.xml"), - StandardCopyOption.REPLACE_EXISTING); - - Profile.getProfiles().add(importProfile); - } - } - } - - // Media Data Copy - boolean customMediaFolder = true; - Path mediaFolder = null; - if (Files.exists(fileSystem.getPath("/media"))) { - mediaFolder = replaceRequest.mediaFolder(); - if (mediaFolder != null) { - Stream<Path> stream = Files.list(fileSystem.getPath("/media")); - for (Object obj : stream.toArray()) { - Path path = (Path) obj; - Path desPath = Paths.get(mediaFolder.toString(), path.getFileName().toString()); - if (Files.notExists(desPath)) { - Files.copy(path, desPath); - } - } - stream.close(); - } - } - - // Project - Path projectPath = fileSystem.getPath("/" + projectFile); - Path des = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, projectFile); - - String importProject = projectFile; - if (Files.exists(des)) { - importProject = replaceRequest.replaceProject(projectFile); - // Stop Import, da kein Name vom Nutzer angegeben wurde - if (importProject == null) { - return null; - } - - // Add XML to FileName - if (!importProject.matches("." + PlayPadPlugin.getImplementation().getProjectFiles()[0])) { - importProject += PlayPadPlugin.getImplementation().getProjectFiles()[0].substring(1); - } - } else { - Files.createDirectories(des.getParent()); - Files.createFile(des); - } - - des = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, importProject); - - if (Files.exists(projectPath)) { - System.out.println("Copy Project: " + des); - - Files.copy(projectPath, des, StandardCopyOption.REPLACE_EXISTING); - fileSystem.close(); - - ProjectReference importReference = new ProjectReference(importProject); - Project project = loadFile(importReference, null, importProfile, false); - ProjectReference.addProject(importReference); - - for (Pad pad : project.getPads().values()) { - if (pad.hasMedia() && customMediaFolder) { - try { - Path path = Paths.get(mediaFolder.toString(), pad.getFileName()); - pad.setPath(path, false); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - } - pad.loadMedia(); - } - return project; - } - } - } - return null; - } - - public interface Importable { - - public String replaceProfile(String name); - - public String replaceProject(String name); - - public Path mediaFolder(); - } - - public interface ProfileChooseable { - - public Profile getUnkownProfile(); - } - - public void setProfile(Profile profile) { - this.profile = profile; - } - - public void loadAudio() { - for (Pad pad : pads.values()) { - if (pad.isPadLoaded()) { - pad.getAudioHandler().unloadMedia(pad); - } - pad.loadMedia(); - } - } - - public static void duplicate(ProjectReference currentProject, ProjectReference newProjectReference) throws IOException { - ProjectReference.addProject(newProjectReference); - - Path oldPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, currentProject.getName()); - Path newPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, newProjectReference.getName()); - - Files.copy(oldPath, newPath, StandardCopyOption.COPY_ATTRIBUTES); - Profile.saveProfiles(); - } -} diff --git a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java index 1bda4e67aa86a803d8701a6a346ce6b595d6218b..0a1ebcf9eb1a56f5fefc72a9f755aa511df2c5a7 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java @@ -56,6 +56,9 @@ public class Pad { // Trigger private HashMap<TriggerPoint, Trigger> triggers = new HashMap<>(); + // Custom Volume + private transient DoubleProperty customVolumeProperty = new SimpleDoubleProperty(1.0); + // Global Listener (unabhängig von der UI), für Core Functions wie Play, Pause private transient PadStatusListener padStatusListener; @@ -74,7 +77,7 @@ public class Pad { this.project = project; load(element); - initPadStatusListener(); + initPadListener(); // Update Trigger ist nicht notwendig, da es in load(Element) ausgerufen wird } @@ -83,7 +86,7 @@ public class Pad { setIndex(index); setStatus(PadStatus.EMPTY); - initPadStatusListener(); + initPadListener(); updateTrigger(); } @@ -93,7 +96,7 @@ public class Pad { setContent(content); } - private void initPadStatusListener() { + private void initPadListener() { padStatusListener = new PadStatusListener(this); statusProperty.addListener(padStatusListener); @@ -102,6 +105,7 @@ public class Pad { padTriggerDurationListener = new PadTriggerDurationListener(this); + // Das ist für die Position Listener notwendig, wenn sich der Content ändert padTriggerContentListener = new PadTriggerContentListener(this); padTriggerContentListener.changed(contentProperty, null, getContent()); } @@ -408,6 +412,10 @@ public class Pad { contentProperty.get().unloadMedia(); setContent(null); setStatus(PadStatus.EMPTY); + + if (project != null) { + project.removeExceptions(this); + } } // Storage @@ -443,14 +451,16 @@ public class Pad { // Settings Element settingsElement = element.element(SETTINGS_ELEMENT); - volumeProperty.set(Double.valueOf(settingsElement.element(VOLUME_ELEMENT).getStringValue())); - loopProperty.set(Boolean.valueOf(settingsElement.element(LOOP_ELEMENT).getStringValue())); + if (settingsElement.element(VOLUME_ELEMENT) != null) + volumeProperty.set(Double.valueOf(settingsElement.element(VOLUME_ELEMENT).getStringValue())); + if (settingsElement.element(LOOP_ELEMENT) != null) + loopProperty.set(Boolean.valueOf(settingsElement.element(LOOP_ELEMENT).getStringValue())); if (settingsElement.element(TIMEMODE_ELEMENT) != null) timeModeProperty.set(TimeMode.valueOf(settingsElement.element(TIMEMODE_ELEMENT).getStringValue())); if (settingsElement.element(FADE_ELEMENT) != null) fadeProperty.set(Fade.load(settingsElement.element(FADE_ELEMENT))); if (settingsElement.element(WARNING_ELEMENT) != null) - warningProperty.set(Warning.loadV2(settingsElement.element(WARNING_ELEMENT))); + warningProperty.set(Warning.load(settingsElement.element(WARNING_ELEMENT))); // Laoyut Element layoutsElement = settingsElement.element(LAYOUTS_ELEMENT); @@ -515,7 +525,11 @@ public class Pad { public void save(Element element) { element.addAttribute(INDEX_ATTR, String.valueOf(indexProperty.get())); element.addAttribute(NAME_ATTR, nameProperty.get()); - element.addAttribute(STATUS_ATTR, statusProperty.get().name()); + if (statusProperty.get() == PadStatus.EMPTY || statusProperty.get() == PadStatus.ERROR) { + element.addAttribute(STATUS_ATTR, PadStatus.EMPTY.name()); + } else { + element.addAttribute(STATUS_ATTR, PadStatus.READY.name()); + } // Settings Element settingsElement = element.addElement(SETTINGS_ELEMENT); @@ -565,4 +579,21 @@ public class Pad { public String toString() { return "Pad: " + indexProperty.get() + " - " + nameProperty.get(); } + + public String toReadableString() { + return (indexProperty.get() + 1) + " - " + nameProperty.get(); + } + + // TODO Reorder + public void setCustomVolume(double volume) { + customVolumeProperty.set(volume); + } + + public double getCustomVolume() { + return customVolumeProperty.get(); + } + + public DoubleProperty customVolumeProperty() { + return customVolumeProperty; + } } diff --git a/PlayWallCore/src/de/tobias/playpad/pad/PadStatus.java b/PlayWallCore/src/de/tobias/playpad/pad/PadStatus.java index 200afbfa5bad1e2b5b3acffbd72456c5d5e42479..062735ee449e962b6f13b5318c8595f7ded24cdc 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/PadStatus.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/PadStatus.java @@ -1,6 +1,7 @@ package de.tobias.playpad.pad; public enum PadStatus { + EMPTY, ERROR, READY, diff --git a/PlayWallCore/src/de/tobias/playpad/pad/PadStatusListener.java b/PlayWallCore/src/de/tobias/playpad/pad/PadStatusListener.java index c4195013cd803a62f5b53c18d9ed38821554209d..7b2b24428fa7d99bbf3ada1addbb8c54248ea858 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/PadStatusListener.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/PadStatusListener.java @@ -6,7 +6,7 @@ import de.tobias.playpad.pad.conntent.Pauseable; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; -class PadStatusListener implements ChangeListener<PadStatus> { +public class PadStatusListener implements ChangeListener<PadStatus> { private Pad pad; diff --git a/PlayWallCore/src/de/tobias/playpad/pad/Warning.java b/PlayWallCore/src/de/tobias/playpad/pad/Warning.java index ef32c96b51ce0f86801a67154f73097993b02012..11cef9723bf8cc315d29160979934c37f1e8043d 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/Warning.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/Warning.java @@ -2,11 +2,15 @@ package de.tobias.playpad.pad; import org.dom4j.Element; +import de.tobias.utils.settings.SettingsSerializable; +import de.tobias.utils.settings.Storable; import javafx.util.Duration; -public class Warning { +public class Warning implements SettingsSerializable{ - private Duration time; + private static final long serialVersionUID = 1L; + + @Storable private Duration time; public Warning() { time = Duration.seconds(5); @@ -26,7 +30,7 @@ public class Warning { private static final String TIME_ELEMENT = "Time"; - public static Warning loadV2(Element feedbackElement) { + public static Warning load(Element feedbackElement) { try { if (feedbackElement.element(TIME_ELEMENT) != null) { Duration dutation = Duration.valueOf(feedbackElement.element(TIME_ELEMENT).getStringValue().replace(" ", "")); diff --git a/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java index 49396a28be50b78519f5d54228e2eb708a28b3e6..1b5396c72ee4c8f7ba306b159e1656c947bbcb4b 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java @@ -1,11 +1,11 @@ package de.tobias.playpad.pad.conntent; -import java.nio.file.FileSystem; import java.nio.file.Path; import org.dom4j.Element; import de.tobias.playpad.pad.Pad; +import de.tobias.utils.util.ZipFile; public abstract class PadContent { @@ -56,8 +56,8 @@ public abstract class PadContent { * @param element * current settings, should update path */ - public abstract void importMedia(Path mediaFolder, FileSystem zipfs, Element element); + public abstract void importMedia(Path mediaFolder, ZipFile zipfs, Element element); - public abstract void exportMedia(FileSystem mediaFolder, Element element); + public abstract void exportMedia(ZipFile zip, Element element); } \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/pad/triggerlistener/PadTriggerStatusListener.java b/PlayWallCore/src/de/tobias/playpad/pad/triggerlistener/PadTriggerStatusListener.java index 76d8b39991f86161bdcbeae9d7bb41d1b157987d..cd0b0dd96e5a0b8a997a22cc8bf72ff84fa6955c 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/triggerlistener/PadTriggerStatusListener.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/triggerlistener/PadTriggerStatusListener.java @@ -26,7 +26,7 @@ public class PadTriggerStatusListener implements ChangeListener<PadStatus> { executeTrigger(pad.getTriggers().get(TriggerPoint.START)); } else if (newValue == PadStatus.STOP) { // TRIGGER FÜR STOP executeTrigger(pad.getTriggers().get(TriggerPoint.EOF_STOP)); - } else if (oldValue == PadStatus.PLAY && newValue == PadStatus.READY) { // TRIGGER FÜR EOF + } else if (oldValue == PadStatus.PLAY && newValue == PadStatus.READY && pad.isEof()) { // TRIGGER FÜR EOF executeTrigger(pad.getTriggers().get(TriggerPoint.EOF_STOP)); } } else { diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java b/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java index db7f86945a4206cb461df2bc3846748ca3ec28e0..4d7684d0f8d15f3497114df28761e1561795ca64 100644 --- a/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java +++ b/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java @@ -1,17 +1,38 @@ package de.tobias.playpad.plugin; -public class Plugin { +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; + +public class Plugin implements Comparable<Plugin> { private String name; private String fileName; private String url; private boolean active; + private List<String> dependencies; + + private static List<Plugin> plugins; + + static { + plugins = new ArrayList<>(); + } - public Plugin(String name, String fileName, String url, boolean active) { + public Plugin(String name, String fileName, String url, boolean active, List<String> dependencies) { this.name = name; this.fileName = fileName; this.url = url; this.active = active; + this.dependencies = dependencies; } public String getName() { @@ -34,6 +55,14 @@ public class Plugin { this.active = active; } + public void addDependency(String id) { + dependencies.add(id); + } + + public List<String> getDependencies() { + return dependencies; + } + @Override public boolean equals(Object obj) { if (obj instanceof Plugin) { @@ -43,4 +72,38 @@ public class Plugin { return super.equals(obj); } } + + @Override + public int compareTo(Plugin o) { + return getName().compareTo(o.getName()); + } + + public static void load(String pluginInfoURL) throws IOException { + plugins.clear(); + URL url = new URL(pluginInfoURL); + + FileConfiguration cfg = YamlConfiguration.loadConfiguration(url.openStream()); + + // Iterate over all plugins that are online avialable + for (String key : cfg.getConfigurationSection("plugins").getKeys(false)) { + String name = new String(cfg.getString("plugins." + key + ".name").getBytes(), "UTF-8"); + String pluginUrl = cfg.getString("plugins." + key + ".url"); + String fileName = cfg.getString("plugins." + key + ".filename"); + + List<String> dependencies = cfg.getStringList("plugins." + key + ".dependencies"); + + boolean active = false; + + Path path = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, fileName); + if (Files.exists(path)) + active = true; + + Plugin plugin = new Plugin(name, fileName, pluginUrl, active, dependencies); + plugins.add(plugin); + } + } + + public static List<Plugin> getPlugins() { + return plugins; + } } diff --git a/PlayWallCore/src/de/tobias/playpad/project/Project.java b/PlayWallCore/src/de/tobias/playpad/project/Project.java index 705b00aa0fbd4e4798739613dfed817a94883726..d0d6e24a10a778d9c999657e78e32a456667c6a3 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/Project.java +++ b/PlayWallCore/src/de/tobias/playpad/project/Project.java @@ -1,8 +1,6 @@ package de.tobias.playpad.project; import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; @@ -56,32 +54,16 @@ public class Project { } public void setPad(int index, Pad pad) { + pad.setIndex(index); pads.put(index, pad); } - public void replacePads(int src, int des) { - Pad srcPad = getPad(src); - srcPad.setIndex(des); - pads.put(des, srcPad); - pads.remove(src); - } - - public void movePads(int src, int des) { - Pad oldPad = getPad(src); - Pad newPad = getPad(des); - - oldPad.setIndex(des); - newPad.setIndex(src); - - pads.put(des, oldPad); - pads.put(src, newPad); - } - private static final String ROOT_ELEMENT = "Project"; - private static final String PAD_ELEMENT = "Pad"; + static final String PAD_ELEMENT = "Pad"; public static Project load(ProjectReference ref, boolean loadMedia, ProfileChooseable profileChooseable) throws DocumentException, IOException, ProfileNotFoundException, ProjectNotFoundException { + Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); if (Files.exists(projectPath)) { SAXReader reader = new SAXReader(); @@ -120,7 +102,7 @@ public class Project { } } - public void save() throws UnsupportedEncodingException, IOException { + public void save() throws IOException { Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); Document document = DocumentHelper.createDocument(); @@ -142,67 +124,6 @@ public class Project { writer.close(); } - /** - * Load an project internal, so that each PadContent cloud import the needed medai from the zip filesystems. Each PadContent must - * override the path saves in the Element Object. - * - * @param ref - * Project to import - * @param destination - * Media Destination - * @throws DocumentException - * @throws IOException - */ - public static void importMedia(ProjectReference ref, FileSystem zipfs, Path destination) throws DocumentException, IOException { - Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(projectPath)); - - Element rootElement = document.getRootElement(); - for (Object padObj : rootElement.elements(PAD_ELEMENT)) { - if (padObj instanceof Element) { - Element padElement = (Element) padObj; - - Pad pad = new Pad(null, padElement); // Null für Project, da das pad nicht weiter verwendet wird - if (pad.getContent() != null) { - pad.getContent().importMedia(destination, zipfs, padElement.element(Pad.CONTENT_ELEMENT)); - } - } - } - XMLWriter writer = new XMLWriter(Files.newOutputStream(projectPath), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); - } - - /** - * Load an project internal, so that each PadContent cloud export the needed medai into the zip filesystems. Each PadContent can read - * the save path from the Element object. - * - * @param ref - * Project to export - * @param des - * Destination zip file - * @throws DocumentException - * @throws IOException - */ - public static void exportMedia(ProjectReference ref, FileSystem des) throws DocumentException, IOException { - Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(projectPath)); - - Element rootElement = document.getRootElement(); - for (Object padObj : rootElement.elements(PAD_ELEMENT)) { - if (padObj instanceof Element) { - Element padElement = (Element) padObj; - - Pad pad = new Pad(null, padElement); // Null für Project, da das pad nicht weiter verwendet wird - if (pad.getContent() != null) { - pad.getContent().exportMedia(des, padElement.element(Pad.CONTENT_ELEMENT)); - } - } - } - } - public HashMap<Integer, Pad> getPads() { return pads; } @@ -252,4 +173,9 @@ public class Project { public ObservableList<PadException> getExceptions() { return exceptions; } + + @Override + public String toString() { + return ref.getName() + " (" + ref.getUuid() + ")"; + } } diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java index 4ff5371fdf330e892f579a5cb48d58ab45aff22c..01267080ca680f5b267373814cb8bf08cf02ebbf 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java +++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java @@ -1,47 +1,41 @@ package de.tobias.playpad.project; import java.io.IOException; -import java.net.URI; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; +import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; +import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; +import de.tobias.playpad.pad.Pad; import de.tobias.playpad.settings.ProfileReference; import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; import de.tobias.utils.util.FileUtils; import de.tobias.utils.util.FileUtils.FileAction; +import de.tobias.utils.util.ZipFile; +import de.tobias.utils.util.ZipFile.FileMode; public class ProjectExporter { - + public static final String mediaFolder = "Media"; - public static void exportProject(ProjectReference projectRef, Path zipFile, boolean includeProfile, boolean includeMedia) + public static void exportProject(ProjectReference projectRef, Path zipFile, boolean includeProfile, boolean includeMedia, ExportView view) throws IOException { - URI p = Paths.get(zipFile.toString()).toUri(); - URI uri = URI.create("jar:" + p); - - Map<String, String> env = new HashMap<>(); - env.put("create", "true"); - env.put("encoding", "UTF-8"); // Delete Esisting Zip File if (Files.exists(zipFile)) Files.delete(zipFile); - FileSystem zipfs = FileSystems.newFileSystem(uri, env); + ZipFile zip = new ZipFile(zipFile, FileMode.WRITE); App application = ApplicationUtils.getApplication(); // Export Profile @@ -51,12 +45,11 @@ public class ProjectExporter { Path profilePath = application.getPath(PathType.CONFIGURATION, profileFileName); // Copy - Files.createDirectories(zipfs.getPath(profileFileName)); FileUtils.loopThroughDirectory(profilePath, new FileAction() { @Override public void onFile(Path file) throws IOException { - Files.copy(file, zipfs.getPath(profileFileName, file.getFileName().toString())); + zip.addFile(file, Paths.get(profileFileName, file.getFileName().toString())); } @Override @@ -65,11 +58,12 @@ public class ProjectExporter { } // Export Project - Files.copy(application.getPath(PathType.DOCUMENTS, projectRef.getFileName()), zipfs.getPath(projectRef.getFileName())); + Path projectLocalPath = application.getPath(PathType.DOCUMENTS, projectRef.getFileName()); + zip.addFile(projectLocalPath, Paths.get(projectRef.getFileName())); if (includeMedia) { try { - Project.exportMedia(projectRef, zipfs); + exportMedia(projectRef, zip, view); } catch (DocumentException e) { e.printStackTrace(); } @@ -83,10 +77,58 @@ public class ProjectExporter { rootElement.addElement("Project").addAttribute("uuid", projectRef.getUuid().toString()).addAttribute("name", projectRef.getName()); rootElement.addElement("Media").addAttribute("export", String.valueOf(includeMedia)); - XMLWriter writer = new XMLWriter(Files.newOutputStream(zipfs.getPath("info.xml")), OutputFormat.createPrettyPrint()); - writer.write(infoDocument); - writer.close(); + zip.addFile(Paths.get("info.xml"), os -> + { + try { + XMLWriter writer = new XMLWriter(os, OutputFormat.createPrettyPrint()); + writer.write(infoDocument); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + zip.close(); + } + + /** + * Load an project internal, so that each PadContent cloud export the needed medai into the zip filesystems. Each PadContent can read + * the save path from the Element object. + * + * @param ref + * Project to export + * @param des + * Destination zip file + * @throws DocumentException + * @throws IOException + */ + private static void exportMedia(ProjectReference ref, ZipFile zip, ExportView view) throws DocumentException, IOException { + Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); + SAXReader reader = new SAXReader(); + Document document = reader.read(Files.newInputStream(projectPath)); + + Element rootElement = document.getRootElement(); + List<?> elements = rootElement.elements(Project.PAD_ELEMENT); + + view.setTasks(elements.size()); + + for (Object padObj : elements) { + if (padObj instanceof Element) { + Element padElement = (Element) padObj; + + Pad pad = new Pad(null, padElement); // Null für Project, da das pad nicht weiter verwendet wird + if (pad.getContent() != null) { + pad.getContent().exportMedia(zip, padElement.element(Pad.CONTENT_ELEMENT)); + } + } + + view.tastComplete(); + } + } + + public static interface ExportView { + + public void tastComplete(); - zipfs.close(); + public void setTasks(int vlaue); } } diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java index 6b60cac3842c435c46e61ea8fdea22bb18aea980..d7c075fcec6fbde1c463e28b655b5c03f975a8f9 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java +++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java @@ -1,36 +1,40 @@ package de.tobias.playpad.project; import java.io.IOException; -import java.nio.file.FileSystems; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.UUID; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; +import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; +import org.dom4j.io.XMLWriter; -import com.sun.nio.zipfs.ZipFileSystem; - +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.settings.Profile; import de.tobias.playpad.settings.ProfileReference; import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; -import de.tobias.utils.util.FileUtils; -import de.tobias.utils.util.FileUtils.FileAction; +import de.tobias.utils.util.ZipFile; +import de.tobias.utils.util.ZipFile.FileMode; public class ProjectImporter { public static ProjectReference importProject(Path zipFile, ProfileChooseable chooseable, Importable importable) throws IOException, DocumentException { - ZipFileSystem fileSystem = (ZipFileSystem) FileSystems.newFileSystem(zipFile, null); + ZipFile zip = new ZipFile(zipFile, FileMode.READ); + App app = ApplicationUtils.getApplication(); - Path infoPath = fileSystem.getPath("info.xml"); - if (Files.exists(infoPath)) { + InputStream infoInputStream = zip.inputStream(Paths.get("info.xml")); + if (infoInputStream != null) { SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(infoPath)); + Document document = reader.read(infoInputStream); Element rootElement = document.getRootElement(); UUID projectUUID = null; @@ -63,43 +67,57 @@ public class ProjectImporter { // Import Profile UUID localProfileUUID = null; if (includeProfile) { - localProfileUUID = UUID.randomUUID(); - String localProfileUUIDString = localProfileUUID.toString(); - - Path profileFolder = fileSystem.getPath(profileUUID.toString()); - Path localFolder = app.getPath(PathType.CONFIGURATION, localProfileUUID.toString()); - Files.createDirectories(localFolder); - - FileUtils.loopThroughDirectory(profileFolder, new FileAction() { - - @Override - public void onFile(Path file) throws IOException { - Files.copy(file, app.getPath(PathType.CONFIGURATION, localProfileUUIDString, file.getFileName().toString())); - } - - @Override - public void onDirectory(Path file) throws IOException {} - }); - + // Dieser Dialog wird aufgerufen, wenn das Profile bereits existiert, wenn nicht wird es direkt importiert if (ProfileReference.getProfiles().contains(profileName)) { profileName = importable.replaceProfile(profileName); } - ProfileReference profileRef = new ProfileReference(localProfileUUID, profileName); - ProfileReference.addProfile(profileRef); - + // Wenn der nUtzer das Profile nicht importieren möchte, weil es bereits vorhanden ist, ist diese Variable durch + // improable.replaceProfile(String) null + if (profileName != null) { + localProfileUUID = UUID.randomUUID(); + String localProfileUUIDString = localProfileUUID.toString(); + + Path profileFolder = Paths.get(profileUUID.toString()); + Path localFolder = app.getPath(PathType.CONFIGURATION, localProfileUUID.toString()); + Files.createDirectories(localFolder); + System.out.println("Create new profile for import: " + localProfileUUID); + + zip.stream().filter(entry -> entry.getName().startsWith(profileFolder.toString())).forEach(entry -> + { + String name = entry.getName().substring(entry.getName().lastIndexOf("/") + 1); + try { + Path dest = app.getPath(PathType.CONFIGURATION, localProfileUUIDString, name); + zip.getFile(Paths.get(entry.getName()), dest); + System.out.println("Copyed Profile Data: \"" + entry.getName() + "\" to location: " + dest); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + ProfileReference profileRef = new ProfileReference(localProfileUUID, profileName); + ProfileReference.addProfile(profileRef); + } else { + Profile profile = chooseable.getUnkownProfile(); + if (profile != null) { + localProfileUUID = profile.getRef().getUuid(); + } + } } else { - localProfileUUID = chooseable.getUnkownProfile().getRef().getUuid(); + Profile profile = chooseable.getUnkownProfile(); + if (profile != null) { + localProfileUUID = profile.getRef().getUuid(); + } } // Import Project if (projectUUID != null) { UUID localProjectUUID = UUID.randomUUID(); - Path projectFile = fileSystem.getPath(projectUUID.toString() + Project.FILE_EXTENSION); + Path projectFile = Paths.get(projectUUID.toString() + Project.FILE_EXTENSION); Path localFile = app.getPath(PathType.DOCUMENTS, localProjectUUID + Project.FILE_EXTENSION); - Files.copy(projectFile, localFile); + zip.getFile(projectFile, localFile); if (ProjectReference.getProjects().contains(projectName)) { projectName = importable.replaceProject(projectName); @@ -112,7 +130,8 @@ public class ProjectImporter { // Import Media if (includeMedia) { Path mediaPath = importable.mediaFolder(); - Project.importMedia(projectRef, fileSystem, mediaPath); + if (mediaPath != null) + importMedia(projectRef, zip, mediaPath); } return projectRef; @@ -120,4 +139,36 @@ public class ProjectImporter { } return null; } + + /** + * Load an project internal, so that each PadContent cloud import the needed medai from the zip filesystems. Each PadContent must + * override the path saves in the Element Object. + * + * @param ref + * Project to import + * @param destination + * Media Destination + * @throws DocumentException + * @throws IOException + */ + private static void importMedia(ProjectReference ref, ZipFile zip, Path destination) throws DocumentException, IOException { + Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); + SAXReader reader = new SAXReader(); + Document document = reader.read(Files.newInputStream(projectPath)); + + Element rootElement = document.getRootElement(); + for (Object padObj : rootElement.elements(Project.PAD_ELEMENT)) { + if (padObj instanceof Element) { + Element padElement = (Element) padObj; + + Pad pad = new Pad(null, padElement); // Null für Project, da das pad nicht weiter verwendet wird + if (pad.getContent() != null) { + pad.getContent().importMedia(destination, zip, padElement.element(Pad.CONTENT_ELEMENT)); + } + } + } + XMLWriter writer = new XMLWriter(Files.newOutputStream(projectPath), OutputFormat.createPrettyPrint()); + writer.write(document); + writer.close(); + } } diff --git a/PlayWallCore/src/de/tobias/playpad/settings/MidiPreset.java b/PlayWallCore/src/de/tobias/playpad/settings/MidiPreset.java deleted file mode 100644 index 3bf6907358c3e8c8b82e1734e49b3f305b583d4e..0000000000000000000000000000000000000000 --- a/PlayWallCore/src/de/tobias/playpad/settings/MidiPreset.java +++ /dev/null @@ -1,189 +0,0 @@ -package de.tobias.playpad.settings; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.List; -import java.util.Optional; - -import javax.sound.midi.MidiMessage; - -import org.dom4j.Element; - -import de.tobias.playpad.model.midi.Displayable; -import de.tobias.playpad.model.midi.MidiAction; -import de.tobias.playpad.model.midi.SubAction; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; - -public class MidiPreset implements Displayable, Cloneable { - - private ObservableList<MidiAction> settings; - private String name; - private BooleanProperty activeProperty; - private int page; - private boolean partly; - - public MidiPreset() { - // Default Values - settings = FXCollections.observableArrayList(); - name = "Preset"; - activeProperty = new SimpleBooleanProperty(false); - page = -1; - partly = true; - } - - public Optional<List<SubAction>> getActionsForMidi(int midiCommand, int midiKey) { - for (MidiAction action : settings) { - if (action.getMidiKey() == midiKey && action.getMidiCommand() == midiCommand) { - return Optional.of(action.getActions()); - } - } - return Optional.empty(); - } - - public Optional<MidiAction> getMidiActionForMidi(int midiCommand, int midiKey) { - for (MidiAction action : settings) { - if (action.getMidiKey() == midiKey && action.getMidiCommand() == midiCommand) { - return Optional.of(action); - } - } - return Optional.empty(); - } - - public Optional<MidiAction> getMidiActionForMidi(MidiMessage message) { - return getMidiActionForMidi(message.getMessage()[0], message.getMessage()[1]); - } - - public ObservableList<MidiAction> getMidiActions() { - return settings; - } - - public void addAction(MidiAction action) { - this.settings.add(action); - } - - public void removeAction(MidiAction action) { - settings.remove(action); - } - - public void clearActions() { - settings.clear(); - } - - public boolean isActive() { - return activeProperty.get(); - } - - public void setActive(boolean active) { - this.activeProperty.set(active); - } - - public BooleanProperty activeProperty() { - return activeProperty; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - displayProperty.set(toString()); - } - - public int getPage() { - return page; - } - - public void setPage(int page) { - this.page = page; - } - - public boolean isPartly() { - return partly; - } - - public void setPartly(boolean partly) { - this.partly = partly; - } - - public boolean isContaining(int midiCommand, int midiKey) { - for (MidiAction midiAction : getMidiActions()) { - if (midiAction.getMidiKey() == midiKey && midiAction.getMidiCommand() == midiCommand) { - return true; - } - } - return false; - } - - // Storage - public static MidiPreset load(Element root) { - MidiPreset preset = new MidiPreset(); - - preset.name = root.attributeValue("name"); - preset.activeProperty.set(Boolean.valueOf(root.attributeValue("active"))); - preset.partly = Boolean.valueOf(root.attributeValue("partly")); - preset.page = Integer.valueOf(root.attributeValue("page")); - - // Actions - for (Object element : root.elements("Midi")) { - Element midiElement = (Element) element; - Optional<MidiAction> action = MidiAction.load(midiElement, preset); - if (action.isPresent()) - preset.settings.add(action.get()); - } - return preset; - } - - public void save(Element root) throws UnsupportedEncodingException, IOException { - // Eigenschaften des Presets - root.addAttribute("name", name); - root.addAttribute("active", String.valueOf(activeProperty.get())); - root.addAttribute("partly", String.valueOf(partly)); - root.addAttribute("page", String.valueOf(page)); - - // Actions - for (MidiAction action : settings) { - Element midiElement = root.addElement("Midi"); - action.save(midiElement); - } - } - - @Override - public String toString() { - return name; - } - - private StringProperty displayProperty = new SimpleStringProperty(); - - @Override - public StringProperty displayProperty() { - displayProperty.set(toString()); - return displayProperty; - } - - @Override - public MidiPreset clone() throws CloneNotSupportedException { - MidiPreset preset = (MidiPreset) super.clone(); - preset.settings = FXCollections.observableArrayList(); - for (MidiAction midiAction : settings) { - preset.settings.add(midiAction.clone()); - } - preset.page = page; - preset.partly = partly; - - preset.name = name; - - preset.displayProperty = new SimpleStringProperty(); - preset.updateString(); - return preset; - } - - public void updateString() { - displayProperty.set(toString()); - } -} diff --git a/PlayWallCore/src/de/tobias/playpad/settings/MidiSettings.java b/PlayWallCore/src/de/tobias/playpad/settings/MidiSettings.java deleted file mode 100644 index 6595f770026a8a378fc3d7622f717ec1fd4ac551..0000000000000000000000000000000000000000 --- a/PlayWallCore/src/de/tobias/playpad/settings/MidiSettings.java +++ /dev/null @@ -1,195 +0,0 @@ -package de.tobias.playpad.settings; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; -import org.dom4j.Element; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.SAXReader; -import org.dom4j.io.XMLWriter; - -import de.tobias.playpad.model.midi.SubAction; -import de.tobias.playpad.model.midi.MidiAction; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; - -public class MidiSettings { - - private ObservableList<MidiPreset> presets; - - private Optional<MidiAction> draftAction = Optional.empty(); - - public MidiSettings() { - presets = FXCollections.observableArrayList(); - } - - public List<SubAction> getSubActionsForMidi(int midi, int page) { - for (MidiPreset preset : presets) - if (preset.isActive()) { - if (preset.getPage() == -1 || preset.getPage() == page) { - for (MidiAction action : preset.getMidiActions()) { - if (action.getMidiKey() == midi) { - return action.getActions(); - } - } - } - } - return null; - } - - public MidiAction getMidiActionsForMidi(int midi, int page) { - for (MidiPreset preset : presets) - if (preset.isActive()) { - if (preset.getPage() == -1 || preset.getPage() == page) { - for (MidiAction action : preset.getMidiActions()) { - if (action.getMidiKey() == midi) { - return action; - } - } - } - } - return null; - } - - public List<MidiAction> getSettingsForPage(int page) { - List<MidiAction> actions = new ArrayList<>(); - for (MidiPreset preset : presets) { - if (preset.isActive()) { - if (preset.getPage() == -1 || preset.getPage() == page) { - actions.addAll(preset.getMidiActions()); - } - } - } - return actions; - } - - public List<MidiPreset> getActivePresets(int page) { - List<MidiPreset> presets = new ArrayList<>(); - for (MidiPreset preset : this.presets) { - if (preset.isActive()) { - if (preset.getPage() == -1 || preset.getPage() == page) { - presets.add(preset); - } - } - } - return presets; - } - - public ObservableList<MidiPreset> getPresets() { - return presets; - } - - public Optional<MidiAction> getDraftAction() { - return draftAction; - } - - public void setDraftAction(MidiAction draftAction) { - if (draftAction != null) - this.draftAction = Optional.of(draftAction); - else - this.draftAction = Optional.empty(); - } - - public static MidiSettings load(Path path) throws DocumentException, IOException { - MidiSettings settings = new MidiSettings(); - - if (Files.exists(path)) { - readMidiSettings(Files.newInputStream(path), settings); - } - - if (settings.presets.isEmpty()) { - settings.createDefaultSettings(path); - } - - return settings; - } - - private static void readMidiSettings(InputStream stream, MidiSettings settings) throws DocumentException { - SAXReader reader = new SAXReader(); - Document document = reader.read(stream); - - Element root = document.getRootElement(); - for (Object presetRoot : root.elements("Preset")) { - MidiPreset preset = MidiPreset.load((Element) presetRoot); - settings.presets.add(preset); - } - - // Draft - Element draftElement = root.element("Draft"); - if (draftElement != null) { - Optional<MidiAction> action = MidiAction.load(draftElement, null); - if (action.isPresent()) - settings.draftAction = action; - } - } - - public void save(Path path) throws UnsupportedEncodingException, IOException { - Document document = DocumentHelper.createDocument(); - - // Actions - Element root = document.addElement("Control"); - for (MidiPreset preset : presets) { - preset.save(root.addElement("Preset")); - } - - // Draft - if (draftAction.isPresent()) { - Element draftElement = root.addElement("Draft"); - draftAction.get().save(draftElement); - } - - XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); - } - - public MidiPreset importMidiPreset(Path path) - throws InstantiationException, IllegalAccessException, ClassNotFoundException, DocumentException, IOException, NullPointerException { - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(path)); - MidiPreset preset = MidiPreset.load(document.getRootElement()); - - if (preset != null) { - presets.add(preset); - } else { - throw new NullPointerException(); - } - return preset; - } - - public void exportMidiPreset(Path path, MidiPreset preset) throws UnsupportedEncodingException, IOException { - Document document = DocumentHelper.createDocument(); - - preset.save(document.addElement("Preset")); - - XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); - } - - public void createDefaultSettings(Path settingsSavePath) throws DocumentException, UnsupportedEncodingException, IOException { - presets.clear(); - - readMidiSettings(MidiSettings.class.getClassLoader().getResourceAsStream("de/tobias/playpad/assets/files/default_midi.xml"), this); - for (MidiPreset preset : presets) { - preset.setActive(false); - } - - // Aktiviere erstes Preset, damit überhaupt eins aktiv ist - presets.get(0).setActive(true); - save(settingsSavePath); - } - - public void addPreset(MidiPreset preset) { - presets.add(preset); - } -} diff --git a/PlayWallCore/src/de/tobias/playpad/settings/Profile.java b/PlayWallCore/src/de/tobias/playpad/settings/Profile.java index c7d2c6570459533427de22fe4d6e87bf591bdf33..db0b7ea64dccd1216bba78ddf58a5c80854589f1 100644 --- a/PlayWallCore/src/de/tobias/playpad/settings/Profile.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/Profile.java @@ -93,7 +93,7 @@ public class Profile { App app = ApplicationUtils.getApplication(); Profile profile = new Profile(ref); - System.out.println("+++ Load Profile: " + ref + " +++"); + System.out.println("+++ Load Profile: " + ref + " (" + ref.getUuid() + ") +++"); if (Files.exists(app.getPath(PathType.CONFIGURATION, ref.getFileName()))) { diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java index f46eeadfd47b8cf8459b81b54d21a537e8c43912..103c9f9b0eda1250c26bd0818f074559424159e1 100644 --- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java @@ -130,7 +130,6 @@ public class ProfileReference implements Displayable { /** * Duplicate one profile on drive. To use the new profile, it must be load manually. * - * @see Profile#load(String) * * @param src * Name of the original Profile diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java index 6ec65c187e4947a5030829a35edc912e1a2732ec..3cf852a167e03b5c83f619f2c63583c4fe51e0eb 100644 --- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java @@ -22,47 +22,71 @@ import de.tobias.playpad.pad.TimeMode; import de.tobias.playpad.pad.Warning; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; +import de.tobias.utils.settings.SettingsSerializable; +import de.tobias.utils.settings.Storable; import de.tobias.utils.settings.UserDefaults; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.util.Duration; -public class ProfileSettings { +public class ProfileSettings implements SettingsSerializable { + + private static final long serialVersionUID = 1L; public static final int MAX_PAGES = 8; + @Storable private BooleanProperty lockedProperty = new SimpleBooleanProperty(false); + // MIDI - private String midiDevice; + @Storable private String midiDevice; // GridPane - private int pageCount = 2; - private int columns = 6; - private int rows = 5; + @Storable private int pageCount = 2; + @Storable private int columns = 6; + @Storable private int rows = 5; // Audio Output - private String audioClass = AudioRegistry.getDefaultAudioInterface(); - private HashMap<String, Object> audioUserInfo = new HashMap<>(); + @Storable private String audioClass = AudioRegistry.getDefaultAudioInterface(); + @Storable private HashMap<String, Object> audioUserInfo = new HashMap<>(); // Layout - private String layoutType = LayoutRegistry.getDefaultLayout(); + @Storable private String layoutType = LayoutRegistry.getDefaultLayout(); // Cart Settings - private Warning warningFeedback = new Warning(Duration.seconds(5)); + @Storable private Warning warningFeedback = new Warning(Duration.seconds(5)); - private boolean midiActive = false; - private boolean liveMode = true; - private DoubleProperty volume = new SimpleDoubleProperty(1.0); + @Storable private boolean midiActive = false; + @Storable private boolean liveMode = true; + @Storable private boolean liveModePage = true; + @Storable private boolean liveModeDrag = true; + @Storable private boolean liveModeFile = true; + @Storable private boolean liveModeSettings = true; + @Storable private DoubleProperty volumeProperty = new SimpleDoubleProperty(1.0); - private boolean windowAlwaysOnTop = false; + @Storable private boolean windowAlwaysOnTop = false; - private Fade fade = new Fade(); - private TimeMode player_timeDisplayMode = TimeMode.REST; + @Storable private Fade fade = new Fade(); + @Storable private TimeMode player_timeDisplayMode = TimeMode.REST; - private boolean dialogDragAndDrop = true; + // Folder + @Storable private Path cachePath = ApplicationUtils.getApplication().getPath(PathType.CACHE); - private Path cachePath = ApplicationUtils.getApplication().getPath(PathType.CACHE); + // Update + @Storable private boolean autoUpdate = true; - private boolean autoUpdate = true; + public boolean isLocked() { + return lockedProperty.get(); + } + + public void setLocked(boolean locked) { + this.lockedProperty.set(locked); + } + + public BooleanProperty lockedProperty() { + return lockedProperty; + } // Getter public String getMidiDevice() { @@ -111,8 +135,24 @@ public class ProfileSettings { return liveMode; } + public boolean isLiveModeDrag() { + return liveModeDrag; + } + + public boolean isLiveModeFile() { + return liveModeFile; + } + + public boolean isLiveModePage() { + return liveModePage; + } + + public boolean isLiveModeSettings() { + return liveModeSettings; + } + public double getVolume() { - return volume.get(); + return volumeProperty.get(); } public boolean isWindowAlwaysOnTop() { @@ -127,10 +167,6 @@ public class ProfileSettings { return player_timeDisplayMode; } - public boolean isDialogDragAndDrop() { - return dialogDragAndDrop; - } - public String getAudioClass() { return audioClass; } @@ -182,8 +218,24 @@ public class ProfileSettings { this.liveMode = liveMode; } + public void setLiveModeDrag(boolean liveModeDrag) { + this.liveModeDrag = liveModeDrag; + } + + public void setLiveModeFile(boolean liveModeFile) { + this.liveModeFile = liveModeFile; + } + + public void setLiveModePage(boolean liveModePage) { + this.liveModePage = liveModePage; + } + + public void setLiveModeSettings(boolean liveModeSettings) { + this.liveModeSettings = liveModeSettings; + } + public void setVolume(double volume) { - this.volume.set(volume); + this.volumeProperty.set(volume); } public void setWindowAlwaysOnTop(boolean windowAlwaysOnTop) { @@ -198,10 +250,6 @@ public class ProfileSettings { this.player_timeDisplayMode = player_timeDisplayMode; } - public void setDialogDragAndDrop(boolean dialogDragAndDrop) { - this.dialogDragAndDrop = dialogDragAndDrop; - } - public void setAudioClass(String audioClass) { this.audioClass = audioClass; } @@ -212,9 +260,10 @@ public class ProfileSettings { // Properties public DoubleProperty volumeProperty() { - return volume; + return volumeProperty; } + private static final String LOCKED_ELEMENT = "Locked"; private static final String ITEM_ELEMENT = "Item"; private static final String AUTO_UPDATE_ELEMENT = "AutoUpdate"; private static final String CACHE_PATH_ELEMENT = "Cache-Path"; @@ -222,9 +271,12 @@ public class ProfileSettings { private static final String KEY_ATTRIBUTE = "key"; private static final String AUDIO_USER_INFO_ELEMENT = "AudioUserInfo"; private static final String AUDIO_CLASS_ELEMENT = "AudioClass"; - private static final String DRAG_AND_DROP_DIALOG_ELEMENT = "DragAndDropDialog"; private static final String WINDOW_ALWAYS_ON_TOP_ELEMENT = "WindowAlwaysOnTop"; private static final String LIVE_MODE_ELEMENT = "LiveMode"; + private static final String LIVE_MODE_PAGE_ATTR = "page"; + private static final String LIVE_MODE_DRAG_ATTR = "drag"; + private static final String LIVE_MODE_FILE_ATTR = "file"; + private static final String LIVE_MODE_SETTINGS_ATTR = "settings"; private static final String TIME_DISPLAY_ELEMENT = "TimeDisplay"; private static final String FADE_ELEMENT = "Fade"; private static final String WARNING_ELEMENT = "Warning"; @@ -244,6 +296,8 @@ public class ProfileSettings { Document document = reader.read(Files.newInputStream(path)); Element root = document.getRootElement(); + if (root.element(LOCKED_ELEMENT) != null) + profileSettings.setLocked(Boolean.valueOf(root.element(LOCKED_ELEMENT).getStringValue())); if (root.element(MIDI_DEVICE_ELEMENT) != null) profileSettings.setMidiDeviceName(root.element(MIDI_DEVICE_ELEMENT).getStringValue()); if (root.element(MIDI_ACTIVE_ELEMENT) != null) @@ -261,7 +315,7 @@ public class ProfileSettings { } if (root.element(WARNING_ELEMENT) != null) { - Warning warning = Warning.loadV2(root.element(WARNING_ELEMENT)); + Warning warning = Warning.load(root.element(WARNING_ELEMENT)); if (warning != null) { profileSettings.setWarningFeedback(warning); } @@ -281,12 +335,25 @@ public class ProfileSettings { } } - if (root.element(LIVE_MODE_ELEMENT) != null) - profileSettings.setLiveMode(Boolean.valueOf(root.element(LIVE_MODE_ELEMENT).getStringValue())); + Element liveElement = root.element(LIVE_MODE_ELEMENT); + if (liveElement != null) { + profileSettings.setLiveMode(Boolean.valueOf(liveElement.getStringValue())); + if (liveElement.attributeValue(LIVE_MODE_PAGE_ATTR) != null) { + profileSettings.setLiveModePage(Boolean.valueOf(liveElement.attributeValue(LIVE_MODE_PAGE_ATTR))); + } + if (liveElement.attributeValue(LIVE_MODE_DRAG_ATTR) != null) { + profileSettings.setLiveModeDrag(Boolean.valueOf(liveElement.attributeValue(LIVE_MODE_DRAG_ATTR))); + } + if (liveElement.attributeValue(LIVE_MODE_FILE_ATTR) != null) { + profileSettings.setLiveModeFile(Boolean.valueOf(liveElement.attributeValue(LIVE_MODE_FILE_ATTR))); + } + if (liveElement.attributeValue(LIVE_MODE_SETTINGS_ATTR) != null) { + profileSettings.setLiveModeSettings(Boolean.valueOf(liveElement.attributeValue(LIVE_MODE_SETTINGS_ATTR))); + } + } + if (root.element(WINDOW_ALWAYS_ON_TOP_ELEMENT) != null) profileSettings.setWindowAlwaysOnTop(Boolean.valueOf(root.element(WINDOW_ALWAYS_ON_TOP_ELEMENT).getStringValue())); - if (root.element(DRAG_AND_DROP_DIALOG_ELEMENT) != null) - profileSettings.setDialogDragAndDrop(Boolean.valueOf(root.element(DRAG_AND_DROP_DIALOG_ELEMENT).getStringValue())); if (root.element(AUDIO_CLASS_ELEMENT) != null) profileSettings.setAudioClass(root.element(AUDIO_CLASS_ELEMENT).getStringValue()); @@ -319,6 +386,8 @@ public class ProfileSettings { Document document = DocumentHelper.createDocument(); Element root = document.addElement("Config"); + root.addElement(LOCKED_ELEMENT).addText(String.valueOf(lockedProperty.get())); + // MIDI if (midiDevice != null) root.addElement(MIDI_DEVICE_ELEMENT).addText(midiDevice); @@ -335,9 +404,14 @@ public class ProfileSettings { fade.save(root.addElement(FADE_ELEMENT)); root.addElement(TIME_DISPLAY_ELEMENT).addText(player_timeDisplayMode.name()); - root.addElement(LIVE_MODE_ELEMENT).addText(String.valueOf(liveMode)); + Element liveElement = root.addElement(LIVE_MODE_ELEMENT); + liveElement.addText(String.valueOf(liveMode)); + liveElement.addAttribute(LIVE_MODE_PAGE_ATTR, String.valueOf(liveModePage)); + liveElement.addAttribute(LIVE_MODE_DRAG_ATTR, String.valueOf(liveModeDrag)); + liveElement.addAttribute(LIVE_MODE_FILE_ATTR, String.valueOf(liveModeFile)); + liveElement.addAttribute(LIVE_MODE_SETTINGS_ATTR, String.valueOf(liveModeSettings)); + root.addElement(WINDOW_ALWAYS_ON_TOP_ELEMENT).addText(String.valueOf(windowAlwaysOnTop)); - root.addElement(DRAG_AND_DROP_DIALOG_ELEMENT).addText(String.valueOf(dialogDragAndDrop)); // Audio root.addElement(AUDIO_CLASS_ELEMENT).addText(audioClass); @@ -346,7 +420,7 @@ public class ProfileSettings { Element itemElement = userInfoElement.addElement(ITEM_ELEMENT); UserDefaults.save(itemElement, audioUserInfo.get(key), key); } - root.addElement(VOLUME_ELEMENT).addText(String.valueOf(volume.get())); + root.addElement(VOLUME_ELEMENT).addText(String.valueOf(volumeProperty.get())); // Paths root.addElement(CACHE_PATH_ELEMENT).addText(cachePath.toString()); diff --git a/PlayWallCore/src/de/tobias/playpad/tigger/Trigger.java b/PlayWallCore/src/de/tobias/playpad/tigger/Trigger.java index f9de496000313c0a4d29f9ac3e919bce5db49f30..e6c84edf666fbafe345f06136114394f43f332b6 100644 --- a/PlayWallCore/src/de/tobias/playpad/tigger/Trigger.java +++ b/PlayWallCore/src/de/tobias/playpad/tigger/Trigger.java @@ -7,6 +7,7 @@ import java.util.List; import org.dom4j.Element; import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.project.Project; import de.tobias.playpad.settings.Profile; import de.tobias.playpad.viewcontroller.main.IMainViewController; @@ -86,25 +87,27 @@ public class Trigger { public void handle(Pad pad, Duration duration, Project project, IMainViewController mainViewController, Profile currentProfile) { for (TriggerItem item : items) { - - // Reset Time - Damit ein Trigger nicht mehrmals aufgeführt wird (TriggerPoint = 5s -> wird sonst immer ab 5s ausgeführt, nun - // aber nur einmal, bis die aktuelle Zeit wieder <5s ist, dann wird es zurückgesetzt) - if (triggerPoint == TriggerPoint.START && item.getPerformedAt().greaterThan(duration)) { - item.setPerformedAt(Duration.ZERO); - } else if (triggerPoint == TriggerPoint.EOF_STOP && item.getPerformedAt().lessThan(duration)) { - item.setPerformedAt(Duration.ZERO); - } - - if (triggerPoint == TriggerPoint.START - && (item.getDurationFromPoint().lessThan(duration) || item.getDurationFromPoint().equals(duration)) - && item.getPerformedAt().equals(Duration.ZERO)) { - item.performAction(pad, project, mainViewController, currentProfile); - item.setPerformedAt(duration); - } else if (triggerPoint == TriggerPoint.EOF_STOP - && (item.getDurationFromPoint().greaterThan(duration) || item.getDurationFromPoint().equals(duration)) - && item.getPerformedAt().equals(Duration.ZERO)) { - item.performAction(pad, project, mainViewController, currentProfile); - item.setPerformedAt(duration); + if (triggerPoint == TriggerPoint.START) { + if (pad.getStatus() == PadStatus.PLAY) { + // Mitten drin, wenn die Zeit die gepsiel wurde größer ist als die gesetzte und noch der Trigger noch nicht ausgeführt + // wurde (null) + if ((item.getPerformedAt() == null && item.getDurationFromPoint().lessThan(duration)) + // Wenn der Trigger am Anfang ist + || (duration.equals(Duration.ZERO) && item.getDurationFromPoint().equals(Duration.ZERO))) { + item.performAction(pad, project, mainViewController, currentProfile); + item.setPerformedAt(duration); + } else if (item.getDurationFromPoint().greaterThan(duration)) { + item.setPerformedAt(null); + } + } + } else if ((triggerPoint == TriggerPoint.EOF_STOP)) { + // Wenn Trigger noch nicht gespiel wurde (null) und Zeit größer ist als gesetzte Zeit (oder 0) + if (item.getPerformedAt() == null && (item.getDurationFromPoint().greaterThan(duration) || duration.equals(Duration.ZERO))) { + item.performAction(pad, project, mainViewController, currentProfile); + item.setPerformedAt(duration); + } else if (item.getDurationFromPoint().lessThan(duration)) { + item.setPerformedAt(null); + } } } } diff --git a/PlayWallCore/src/de/tobias/playpad/tigger/TriggerItem.java b/PlayWallCore/src/de/tobias/playpad/tigger/TriggerItem.java index f458b0a2ef1d160fed3b3c648b13f715719fc6be..9fe601a389ad0a822df722e0a69906367a61fa6e 100644 --- a/PlayWallCore/src/de/tobias/playpad/tigger/TriggerItem.java +++ b/PlayWallCore/src/de/tobias/playpad/tigger/TriggerItem.java @@ -16,7 +16,7 @@ public abstract class TriggerItem { public TriggerItem() { durationFromPoint = Duration.ZERO; - performedAt = Duration.ZERO; + performedAt = null; } public Duration getDurationFromPoint() { @@ -46,12 +46,22 @@ public abstract class TriggerItem { private static final String DURATION_ATTR = "duration"; + /** + * You must call super.load + * + * @param element + */ public void load(Element element) { if (element.attributeValue(DURATION_ATTR) != null) { durationFromPoint = Duration.millis(Double.valueOf(element.attributeValue(DURATION_ATTR))); } } + /** + * You must call super.save + * + * @param element + */ public void save(Element element) { element.addAttribute(DURATION_ATTR, String.valueOf(durationFromPoint.toMillis())); } diff --git a/PlayWallCore/src/de/tobias/playpad/viewcontroller/IPadView.java b/PlayWallCore/src/de/tobias/playpad/viewcontroller/IPadView.java index 0108268702fbf842a84d947e643ceec6a64c2131..c5d3b78cae62ea71f1bffbf888768e6ca362342d 100644 --- a/PlayWallCore/src/de/tobias/playpad/viewcontroller/IPadView.java +++ b/PlayWallCore/src/de/tobias/playpad/viewcontroller/IPadView.java @@ -35,7 +35,7 @@ public interface IPadView { public void addDefaultButton(Pad pad); public void setErrorLabelActive(boolean b); - + public void setTriggerLabelActive(boolean b); public IPadContentView getPadContentView(); diff --git a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainToolbarViewController.java b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainToolbarViewController.java index 9c5ba12e0c9c0ca3e3cc1bd3bc75b65da5e03674..ee9f550a6d1b6e2472180394b09e8ddedbf6e028 100644 --- a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainToolbarViewController.java +++ b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainToolbarViewController.java @@ -1,8 +1,12 @@ package de.tobias.playpad.viewcontroller.main; +import javafx.scene.Node; public interface IMainToolbarViewController { public void createPageButtons(); + public void showIcon(Node node); + + public void hideIcon(Node node); } diff --git a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java index d8334d4bcd61b3fc84fbd2c312f5d200f5a98c5b..039b2d7cd5165b11b7df8043a5252446c6f5562d 100644 --- a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java +++ b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java @@ -30,4 +30,8 @@ public interface IMainViewController { public void showPage(int page); public void loadUserCss(); + + public void applyColorsToMappers(); + + public void showLiveInfo(); }