diff --git a/PlayWall/assets/de/tobias/playpad/assets/dialog/launchDialog.fxml b/PlayWall/assets/de/tobias/playpad/assets/dialog/launchDialog.fxml index 4b68d4f98ea2ddcf32efa55f44b663c240ffdb10..c2a147570763b9d10242ba840bbdd5782fda3487 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/dialog/launchDialog.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/dialog/launchDialog.fxml @@ -11,11 +11,7 @@ <children> <VBox alignment="CENTER" layoutX="24.0" layoutY="5.0" spacing="7.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="34.0" AnchorPane.topAnchor="14.0"> <children> - <ImageView fx:id="imageView" fitHeight="144.0" fitWidth="140.0" layoutX="80.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true"> - <effect> - <DropShadow /> - </effect> - </ImageView> + <ImageView fx:id="imageView" fitHeight="144.0" fitWidth="140.0" layoutX="80.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true" /> <Label fx:id="infoLabel" alignment="CENTER" layoutX="24.0" layoutY="212.0" prefHeight="39.0" prefWidth="310.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="266.0" AnchorPane.topAnchor="212.0"> <font> <Font size="25.0" /> diff --git a/PlayWall/assets/de/tobias/playpad/assets/files/class_obj.png b/PlayWall/assets/de/tobias/playpad/assets/files/class_obj.png new file mode 100644 index 0000000000000000000000000000000000000000..bc915da4420060b4ea9984fc662935f10f19449a Binary files /dev/null and b/PlayWall/assets/de/tobias/playpad/assets/files/class_obj.png differ diff --git a/PlayWall/assets/de/tobias/playpad/assets/files/enum_obj.png b/PlayWall/assets/de/tobias/playpad/assets/files/enum_obj.png new file mode 100644 index 0000000000000000000000000000000000000000..c2b5d8345058a26e8ffb4262277543bce417535b Binary files /dev/null and b/PlayWall/assets/de/tobias/playpad/assets/files/enum_obj.png differ diff --git a/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties index 69c9133951278d6a9b34823993f296da28be887f..6e553fe7b55f64165bef092e56959af31f7551a3 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties +++ b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties @@ -23,6 +23,7 @@ UI.Window.Main.Title=Play Wall [Projekt: {} - Profil: {}] UI.Window.Changelog.Title=Was ist neu? UI.Window.Settings.Title=Einstellungen - {} UI.Window.PadSettings.Title=Kachel Einstellungen - {} | {} +UI.Window.PadSettings.Title.Empty=Kachel Einstellungen - {} UI.Dialog.DragAndDrop.Title=Drag and Drop UI.Dialog.ProjectExport.Title=Projekt exportieren UI.Dialog.ErrorSummary.Title=Fehlerbericht @@ -92,7 +93,7 @@ UI.Dialog.Profile.Delete.Content=Sind Sie sicher, dass Sie das Profil {} l # UI - Dialog - Info UI.Dialog.Info.Header=�ber {} -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.Info.Content=Version: {} (Build: {})\nAutor: {}\nGrafiken: Robert Goldmann.\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. Dies dauert einen kleinen Moment. Bitte haben Sie etwas Geduld. Ihre Nummer wird am Ende angezeigt. @@ -162,6 +163,7 @@ Error.Midi.Send=Der Midi Befehl konnte nicht gesendet werden. ({}) # Error - Plugins Error.Plugins.Download=Das Plugin {} konnte nicht geladen werden. +Error.Plugins.Avaiable=Es sind keine Plugins f�r dieses Update Kanal verf�gbar. #Mapper Mapper.Keyboard.Name=Tastatur @@ -204,13 +206,16 @@ CartAction.Mode.PLAY_HOLD=Play/Hold UI.Dialog.AutoUpdate.Header=Updates UI.Dialog.AutoUpdate.Content=Es sind Updates verf�gbar. M�chten Sie diese jetzt installieren? (Weitere Informationen finden Sie in den Update Einstellungen.) +# Update Channel - BaseName +UpdateChannel.STABLE=Stabil +UpdateChannel.BETA=Beta + # Error - Layout Error.Layout.Load=Es gab einen Fehler beim Laden des Layouts ({}) # UI - Dialog - Update UI.Dialog.Update.Cell={}: Installiert: {} - Neu: {} UI.Window.Settings.Updates.CurrentVersion={} (Build {}) -UI.Window.Settings.Updates.NewVersion={} (Build {}) # Error - Update - Downlaod Error.Update.Download=Es ist ein Fehler beim Herunterladen des Updates aufgetreten. Bitte versuchen Sie es sp�ter erneut. ({}) 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 96235bf6de5b7347a56ecff96b82d100a3fa9efa..1ad02a367c7a457e081958a4693bd4964f761953 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties +++ b/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties @@ -69,6 +69,9 @@ 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 +settings.update.label.channel=Update Kanal: +settings.update.label.infoC=Program +settings.update.label.infoE=Erweiterung settings.button.finish=Fertig settings.checkbox.activate=Aktivieren 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 1019034cadcd369e709a0a0091e34f3b7b181c7d..4811fc21c824512215069318915dd99aed3ea491 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/main/mainMenu.fxml @@ -48,7 +48,6 @@ <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" onAction="#pluginMenuItemHandler" text="%main.menuitem.plugins" /> <SeparatorMenuItem mnemonicParsing="false" /> - <CheckMenuItem fx:id="quickEditMenuItem" mnemonicParsing="false" onAction="#quickEditMenuHandler" text="Quick Edit" visible="false" /> <MenuItem fx:id="settingsMenuItem" mnemonicParsing="false" onAction="#settingsHandler" text="%main.menuitem.settings"> <accelerator> <KeyCodeCombination alt="UP" code="COMMA" control="UP" meta="UP" shift="UP" shortcut="DOWN" /> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutCart.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutCart.fxml index 47f1ad840bd6cebeedff224dff9332c4c32d01a4..0307ce2b59a3e730796a184cb34c75fe027f6320 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutCart.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/layout/modernLayoutCart.fxml @@ -30,12 +30,6 @@ <Button fx:id="playColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#playColorButtonHandler" prefWidth="150.0" /> </children> </VBox> - <VBox maxWidth="1.7976931348623157E308" prefWidth="150.0" spacing="14.0" HBox.hgrow="ALWAYS"> - <children> - <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" text="%layout.label.animation" wrapText="true" VBox.vgrow="ALWAYS" /> - <CheckBox fx:id="warnAnimationCheckBox" mnemonicParsing="false" text="%layout.label.warnAnimation" /> - </children> - </VBox> </children> </HBox> <Button fx:id="resetButton" mnemonicParsing="false" onAction="#resetButtonHandler" text="%layout.button.reset"> diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/updateTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/updateTab.fxml index 91c68b8a000fcfe5f6028a2d03f1ab06a68131cf..2f2c940576518b11583a9901fd0554f67d96ad10 100644 --- a/PlayWall/assets/de/tobias/playpad/assets/view/option/updateTab.fxml +++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/updateTab.fxml @@ -5,7 +5,6 @@ <?import java.lang.*?> <?import javafx.scene.layout.*?> - <VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> <HBox layoutX="14.0" layoutY="14.0" spacing="14.0"> @@ -14,12 +13,6 @@ <Label fx:id="currentVersionLabel" layoutX="175.0" layoutY="14.0" text="5.0.1 (stable)" /> </children> </HBox> - <HBox layoutX="14.0" layoutY="36.0" spacing="14.0"> - <children> - <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="36.0" prefWidth="150.0" text="%settings.update.label.new" /> - <Label fx:id="newVersionLabel" layoutX="175.0" layoutY="36.0" text="5.0.2 (stable)" /> - </children> - </HBox> <Separator prefWidth="200.0" /> <HBox spacing="14.0"> <children> @@ -27,6 +20,12 @@ <CheckBox fx:id="automaticSearchCheckBox" layoutX="275.0" layoutY="183.0" mnemonicParsing="false" text="Automatisch" /> </children> </HBox> + <HBox alignment="CENTER_LEFT" spacing="14.0"> + <children> + <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%settings.update.label.channel" /> + <ComboBox fx:id="updateChannelComboBox" prefWidth="150.0" /> + </children> + </HBox> <HBox spacing="14.0"> <children> <Label alignment="CENTER_RIGHT" layoutX="106.0" layoutY="222.0" prefWidth="150.0" /> @@ -37,7 +36,17 @@ <HBox spacing="14.0"> <children> <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%settings.update.label.available" /> - <ListView fx:id="openUpdateList" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" /> + <VBox spacing="14.0" HBox.hgrow="ALWAYS"> + <children> + <ListView fx:id="openUpdateList" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" /> + <HBox spacing="14.0"> + <children> + <Label fx:id="infoCLabel" text="%settings.update.label.infoC" /> + <Label fx:id="infoELabel" text="%settings.update.label.infoE" /> + </children> + </HBox> + </children> + </VBox> </children> </HBox> <HBox alignment="TOP_RIGHT"> diff --git a/PlayWall/beta.xml b/PlayWall/beta.xml new file mode 100644 index 0000000000000000000000000000000000000000..f21bdb1c489d3cec41399ed3e38d30a3cae58478 --- /dev/null +++ b/PlayWall/beta.xml @@ -0,0 +1,28 @@ +<project name="Build App" default="buildApp" basedir="/Users/tobias/Documents/Programmieren/Java/eclipse/"> + + <taskdef name="bundleapp" classname="com.oracle.appbundler.AppBundlerTask" classpath="/Users/tobias/Documents/Programmieren/Java/ant/lib/appbundler-1.0.jar" /> + <taskdef name="launch4j" classname="net.sf.launch4j.ant.Launch4jTask" classpath="/Users/tobias/Documents/Programmieren/Java/ant/lib/launch4j/launch4j.jar:${launch4j.dir}/lib/xstream.jar" /> + <taskdef name="upload" classname="de.tobias.playwallpm.task.PlayWallPMTask" classpath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWallPackageManager/build/PlayWallPM.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/jsch/jsch-0.1.53.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/YAMLStorage.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/snakeyaml-1.11.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/guava-15.0.jar" /> + <taskdef name="buildNumber" classname="de.tobias.playwallpm.task.BuildNumberTask" classpath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWallPackageManager/build/PlayWallPM.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/jsch/jsch-0.1.53.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/YAMLStorage.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/snakeyaml-1.11.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/guava-15.0.jar" /> + + <target name="buildApp"> + <!-- Upload Jar --> + <input addproperty="password">Enter password</input> + <upload username="p35947554-pw" password="${password}" host="p35947554.1and1-data.host"> + <file type="program" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/PlayWall.jar" remotePath="/beta" remoteFileName="PlayWall.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/ActionPlugin.jar" remotePath="/beta/plugins" remoteFileName="ActionPlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/AwakePlugin.jar" remotePath="/beta/plugins" remoteFileName="AwakePlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/EqualizerPlugin.jar" remotePath="/beta/plugins" remoteFileName="EqualizerPlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/LaunchPadPlugin.jar" remotePath="/beta/plugins" remoteFileName="LaunchPadPlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/MediaPlugin.jar" remotePath="/beta/plugins" remoteFileName="MediaPlugin.jar" /> + </upload> + </target> +</project> \ No newline at end of file diff --git a/PlayWall/build.xml b/PlayWall/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..943ff80ec1870df04b63927711cc03326634723f --- /dev/null +++ b/PlayWall/build.xml @@ -0,0 +1,42 @@ +<project name="Build App" default="buildApp" basedir="/Users/tobias/Documents/Programmieren/Java/eclipse/"> + + <taskdef name="bundleapp" classname="com.oracle.appbundler.AppBundlerTask" classpath="/Users/tobias/Documents/Programmieren/Java/ant/lib/appbundler-1.0.jar" /> + <taskdef name="launch4j" classname="net.sf.launch4j.ant.Launch4jTask" classpath="/Users/tobias/Documents/Programmieren/Java/ant/lib/launch4j/launch4j.jar:${launch4j.dir}/lib/xstream.jar" /> + <taskdef name="upload" classname="de.tobias.playwallpm.task.PlayWallPMTask" classpath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWallPackageManager/build/PlayWallPM.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/jsch/jsch-0.1.53.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/YAMLStorage.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/snakeyaml-1.11.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/guava-15.0.jar" /> + <taskdef name="buildNumber" classname="de.tobias.playwallpm.task.BuildNumberTask" classpath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWallPackageManager/build/PlayWallPM.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/jsch/jsch-0.1.53.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/YAMLStorage.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/snakeyaml-1.11.jar: + /Users/tobias/Documents/Programmieren/Java/Libraries/File Parser/YAML/guava-15.0.jar" /> + + <target name="buildApp"> + <bundleapp outputdirectory="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/dist" name="Play Wall" displayname="Play Wall" identifier="de.tobias.playwall" mainclassname="de.tobias.playpad.PlayPadMain" icon="/Users/tobias/Documents/Programmieren/Java/git/PlayWall/PlayWall/src/icon.icns"> + <runtime dir="/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home" /> + <classpath file="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/PlayWall.jar" /> + </bundleapp> + + <launch4j> + <config headerType="gui" outfile="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/dist/PlayWall.exe" dontWrapJar="false" jarPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/PlayWall.jar" icon="/Users/tobias/Documents/Programmieren/Java/git/PlayWall/PlayWall/src/icon.ico"> + <classPath mainClass="de.tobias.playpad.PlayPadMain" /> + <jre minVersion="1.8.0"> + </jre> + </config> + </launch4j> + + <input addproperty="password">Enter password</input> + + <upload username="p35947554-pw" password="${password}" host="p35947554.1and1-data.host"> + <file type="program" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/PlayWall.jar" remotePath="/stable" remoteFileName="PlayWall.jar" /> + <file type="exe" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/PlayWall.exe" remotePath="/stable" remoteFileName="PlayWall.exe" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/ActionPlugin.jar" remotePath="/stable/plugins" remoteFileName="ActionPlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/AwakePlugin.jar" remotePath="/stable/plugins" remoteFileName="AwakePlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/EqualizerPlugin.jar" remotePath="/stable/plugins" remoteFileName="EqualizerPlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/LaunchPadPlugin.jar" remotePath="/stable/plugins" remoteFileName="LaunchPadPlugin.jar" /> + <file type="plugin" localPath="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/MediaPlugin.jar" remotePath="/stable/plugins" remoteFileName="MediaPlugin.jar" /> + </upload> + </target> +</project> \ No newline at end of file diff --git a/PlayWall/src/application.yml b/PlayWall/src/application.yml index 399d169517d6e08dec15cc896bcc2c5d0c107625..c955943e2ec0c1f35475d7f79b925ad0d2f6a126 100644 --- a/PlayWall/src/application.yml +++ b/PlayWall/src/application.yml @@ -1,6 +1,6 @@ name: PlayWall -version: 5.0.0 GM -build: 26 +version: 5.0.1 +build: 31 identifier: de.tobias.playpad main: de.tobias.playpad.PlayPadMain author: Tobias Ullerich @@ -10,6 +10,8 @@ updateURL: http://tobisan.no-ip.org/files/PlayWall userInfo: Website: http://tobisan.no-ip.org/ ErrorURL: http://tobisan.no-ip.org/upload.php - PluginsURL: http://tobisan.no-ip.org/files/PlayWall/plugins.yml + PluginsURL: + Stable: http://tobisan.no-ip.org/files/PlayWall/stable/plugins.yml + Beta: http://tobisan.no-ip.org/files/PlayWall/beta/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/AppUserInfoStrings.java b/PlayWall/src/de/tobias/playpad/AppUserInfoStrings.java index df966939ee73d71abe043ee02b458093900bced8..892cf27637337f1ed49fcda4b1ebb86f93af78d1 100644 --- a/PlayWall/src/de/tobias/playpad/AppUserInfoStrings.java +++ b/PlayWall/src/de/tobias/playpad/AppUserInfoStrings.java @@ -3,7 +3,8 @@ package de.tobias.playpad; public class AppUserInfoStrings { public static final String WEBSITE = "Website"; - public static final String PLUGINS_URL = "PluginsURL"; + public static final String PLUGINS_URL_STABLE = "PluginsURL.Stable"; + public static final String PLUGINS_URL_BETA = "PluginsURL.Beta"; public static final String ERROR_URL = "ErrorURL"; public static final String CHANGELOG_URL = "ChangelogURL"; public static final String UPDATER_PROGRAM = "UpdaterProgram"; diff --git a/PlayWall/src/de/tobias/playpad/PlayPadImpl.java b/PlayWall/src/de/tobias/playpad/PlayPadImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ecff8fee390fa91ea62c2ad024ff452164a7553a --- /dev/null +++ b/PlayWall/src/de/tobias/playpad/PlayPadImpl.java @@ -0,0 +1,166 @@ +package de.tobias.playpad; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import de.tobias.playpad.plugin.PadListener; +import de.tobias.playpad.plugin.SettingsListener; +import de.tobias.playpad.plugin.WindowListener; +import de.tobias.playpad.project.Project; +import de.tobias.playpad.viewcontroller.IPadSettingsViewController; +import de.tobias.playpad.viewcontroller.ISettingsViewController; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import de.tobias.playpad.viewcontroller.main.MainViewController; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; +import de.tobias.utils.util.Worker; +import javafx.scene.image.Image; +import net.xeoh.plugins.base.PluginManager; +import net.xeoh.plugins.base.impl.PluginManagerFactory; + +public class PlayPadImpl implements PlayPad { + + private static final String PLUGIN_INFO_TXT = "pluginInfo.txt"; + + protected List<WindowListener<IMainViewController>> mainViewListeners = new ArrayList<>(); + protected List<WindowListener<ISettingsViewController>> settingsViewListeners = new ArrayList<>(); + protected List<WindowListener<IPadSettingsViewController>> padSettingsViewListeners = new ArrayList<>(); + protected List<SettingsListener> settingsListeners = new ArrayList<>(); + protected List<PadListener> padListeners = new ArrayList<>(); + + private PluginManager pluginManager; + private Set<Path> deletedPlugins; + + private MainViewController mainViewController; + + public PlayPadImpl() { + pluginManager = PluginManagerFactory.createPluginManager(); + deletedPlugins = new HashSet<>(); + } + + @Override + public void addMainViewListener(WindowListener<IMainViewController> listener) { + mainViewListeners.add(listener); + } + + @Override + public void addSettingsListener(SettingsListener listener) { + settingsListeners.add(listener); + } + + @Override + public void removeSettingsListener(SettingsListener listener) { + settingsListeners.remove(listener); + } + + @Override + public List<SettingsListener> getSettingsListener() { + return settingsListeners; + } + + @Override + public void addPadListener(PadListener listener) { + padListeners.add(listener); + } + + @Override + public void removePadListener(PadListener listener) { + padListeners.remove(listener); + } + + @Override + public List<PadListener> getPadListener() { + return padListeners; + } + + @Override + public IMainViewController getMainViewController() { + return mainViewController; + } + + @Override + public Optional<Image> getIcon() { + return PlayPadMain.stageIcon; + } + + /** + * Fügt ein Plugin hinzu, sich zu löschen. + * + * @param path + * Pfad zu einem Plugin + */ + public void addDeletedPlugin(Path path) { + deletedPlugins.add(path); + } + + /** + * Gibt alle Plugins zurück, die gelöscht werden sollen. + * + * @return Plugins + */ + public Set<Path> getDeletedPlugins() { + return deletedPlugins; + } + + void deletePlugins() throws IOException { + Path pluginInfoPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, PLUGIN_INFO_TXT); + + // Delete Plugin + if (Files.exists(pluginInfoPath)) { + BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(pluginInfoPath))); + String line; + while ((line = reader.readLine()) != null) { + Path plugin = Paths.get(line); + Files.deleteIfExists(plugin); + } + reader.close(); + Files.delete(pluginInfoPath); + } + + } + + @Override + public void shutdown() { + // Delete Plugins Info Textfile --> Löschen dann beim Start. + 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 : getDeletedPlugins()) { + deleteWriter.println(path.toString()); + } + deleteWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + pluginManager.shutdown(); + Worker.shutdown(); + } + + public void loadPlugin(URI uri) { + pluginManager.addPluginsFrom(uri); + } + + public void openProject(Project project) { + if (mainViewController == null) { + mainViewController = new MainViewController(project, mainViewListeners); + } else { + mainViewController.setProject(project); + } + } +} diff --git a/PlayWall/src/de/tobias/playpad/PlayPadMain.java b/PlayWall/src/de/tobias/playpad/PlayPadMain.java index bf8a5d0b81730e75c89f59269db88722e2b2297d..a399f8561daefd030f8207f3db9cedea6ae18af1 100644 --- a/PlayWall/src/de/tobias/playpad/PlayPadMain.java +++ b/PlayWall/src/de/tobias/playpad/PlayPadMain.java @@ -1,20 +1,12 @@ package de.tobias.playpad; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; import java.net.MalformedURLException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.ResourceBundle; -import java.util.Set; import java.util.UUID; import de.tobias.playpad.action.ActionRegistery; @@ -42,9 +34,6 @@ import de.tobias.playpad.pad.content.AudioContentConnect; import de.tobias.playpad.pad.drag.MoveDragMode; import de.tobias.playpad.pad.drag.PadDragModeRegistery; import de.tobias.playpad.pad.drag.ReplaceDragMode; -import de.tobias.playpad.plugin.PadListener; -import de.tobias.playpad.plugin.SettingsListener; -import de.tobias.playpad.plugin.WindowListener; import de.tobias.playpad.project.Project; import de.tobias.playpad.project.ProjectReference; import de.tobias.playpad.settings.Profile; @@ -53,14 +42,12 @@ 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.update.PlayPadUpdater; +import de.tobias.playpad.update.UpdateRegistery; +import de.tobias.playpad.update.Updates; import de.tobias.playpad.view.MapperOverviewViewController; -import de.tobias.playpad.viewcontroller.IPadSettingsViewController; -import de.tobias.playpad.viewcontroller.ISettingsViewController; import de.tobias.playpad.viewcontroller.LaunchDialog; import de.tobias.playpad.viewcontroller.dialog.ChangelogDialog; -import de.tobias.playpad.viewcontroller.main.IMainViewController; -import de.tobias.playpad.viewcontroller.main.MainViewController; -import de.tobias.playpad.viewcontroller.option.UpdateTabViewController; import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; @@ -68,6 +55,8 @@ import de.tobias.utils.ui.ViewController; import de.tobias.utils.util.ConsoleUtils; import de.tobias.utils.util.Localization; import de.tobias.utils.util.Localization.LocalizationDelegate; +import de.tobias.utils.util.OS; +import de.tobias.utils.util.OS.OSType; import de.tobias.utils.util.Worker; import javafx.application.Application; import javafx.application.Platform; @@ -76,8 +65,6 @@ import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ButtonType; import javafx.scene.image.Image; import javafx.stage.Stage; -import net.xeoh.plugins.base.PluginManager; -import net.xeoh.plugins.base.impl.PluginManagerFactory; /* * TODOS @@ -91,7 +78,6 @@ import net.xeoh.plugins.base.impl.PluginManagerFactory; // Profile mit UUID - // Pad System neu machen // Neue PadViewController für jedes pad // Midi Modell Überarbeiten @@ -99,45 +85,38 @@ import net.xeoh.plugins.base.impl.PluginManagerFactory; // TEST Trigger - - // PlayWall 5.1 // FEATURE Global Volume Trigger mit x% und 100% // FEATURE Option bei Import Media auch Copy Media in Library // FEATURE lnk für Windows mit Dateiparameter // FEATURE Backups irgendwann löschen -public class PlayPadMain extends Application implements LocalizationDelegate, PlayPad, ProfileListener { +public class PlayPadMain extends Application implements LocalizationDelegate, 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 displayTimeMillis = 1500; - public static final String[] projectType = { "*.xml" }; - public static final String[] projectZIPType = { "*.zip" }; - public static final String[] midiPresetType = { "*.pre" }; + public static final String projectType = "*.xml"; + public static final String projectZIPType = "*.zip"; + public static final String midiPresetType = "*.pre"; private static ResourceBundle uiResourceBundle; - private static MainViewController mainViewController; + private static PlayPadImpl impl; private static PlayPadUpdater updater; - private static Set<Path> deletedPlugins = new HashSet<>(); - - public static void addDeletedPlugin(Path path) { - deletedPlugins.add(path); - } - - /* - * - */ public static ResourceBundle getUiResourceBundle() { return uiResourceBundle; } public static void main(String[] args) throws Exception { + // Verhindert einen Bug unter Windows 10 mit comboboxen + if (OS.getType() == OSType.Windows) { + System.setProperty("glass.accessible.force", "false"); + } + // Debug System.setOut(ConsoleUtils.convertStream(System.out, "[PlayWall] ")); System.setErr(ConsoleUtils.convertStream(System.err, "[PlayWall] ")); @@ -147,11 +126,10 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl app.start(args); } - private static PluginManager pluginManager; - @Override public void init() throws Exception { - PlayPadPlugin.setImplementation(this); + impl = new PlayPadImpl(); + PlayPadPlugin.setImplementation(impl); // Localization setupLocalization(); @@ -177,7 +155,15 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl updater = new PlayPadUpdater(); UpdateRegistery.registerUpdateable(updater); registerComponents(); - setupPlugins(); + + // Load Plugin Path + Path pluginFolder; + if (getParameters().getNamed().containsKey("plugin")) { + pluginFolder = Paths.get(getParameters().getNamed().get("plugin")); + } else { + pluginFolder = ApplicationUtils.getApplication().getPath(PathType.LIBRARY); + } + setupPlugins(pluginFolder); /* * Load Data @@ -196,7 +182,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl if (getParameters().getRaw().size() > 0) { try { UUID uuid = UUID.fromString(getParameters().getNamed().get("project")); - launchProject(Project.load(ProjectReference.getProject(uuid), true, null)); + impl.openProject(Project.load(ProjectReference.getProject(uuid), true, null)); return; } catch (IllegalArgumentException | NullPointerException e) {} catch (Exception e) { e.printStackTrace(); @@ -204,7 +190,6 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl } ViewController.create(LaunchDialog.class, stage); - } @Override @@ -216,27 +201,13 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl e.printStackTrace(); // Speichern Fehler } + // Shutdown components + // TODO use AutoCloseable 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(); - } + impl.shutdown(); - Worker.shutdown(); Platform.exit(); System.exit(0); } @@ -281,31 +252,12 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl Profile.registerListener(this); } - private void setupPlugins() throws IOException, MalformedURLException { - /* - * Plugins - */ - Path pluginInfoPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, PLUGIN_INFO_TXT); - - // Delete Plugin - if (Files.exists(pluginInfoPath)) { - BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(pluginInfoPath))); - String line; - while ((line = reader.readLine()) != null) { - Path plugin = Paths.get(line); - Files.deleteIfExists(plugin); - } - reader.close(); - Files.delete(pluginInfoPath); - } + private void setupPlugins(Path pluginPath) throws IOException, MalformedURLException { + // Delete old plugins + impl.deletePlugins(); // Load Plugins - pluginManager = PluginManagerFactory.createPluginManager(); - if (ApplicationUtils.getApplication().isDebug()) - // DEBUG PLUGINS EINBINDEN - pluginManager.addPluginsFrom(Paths.get("/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWallPlugins/bin/").toUri()); - else - pluginManager.addPluginsFrom(ApplicationUtils.getApplication().getPath(PathType.LIBRARY).toUri()); + impl.loadPlugin(pluginPath.toUri()); } private void setupLocalization() { @@ -315,17 +267,16 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl uiResourceBundle = Localization.loadBundle("de/tobias/playpad/assets/lang/ui", getClass().getClassLoader()); } - public static void launchProject(Project project) { - mainViewController = new MainViewController(project, mainViewListeners, pluginManager); - } - + /** + * Handle Auto Update on profile reload + */ @Override - public void reloadSettings(Profile oldProfile, Profile currentProfile) { + public void reloadSettings(Profile oldProfile, Profile newProfile) { // Update PlayWall - if (currentProfile.getProfileSettings().isAutoUpdate()) { + if (newProfile.getProfileSettings().isAutoUpdate()) { Worker.runLater(() -> { - UpdateRegistery.lookupUpdates(); + UpdateRegistery.lookupUpdates(newProfile.getProfileSettings().getUpdateChannel()); if (!UpdateRegistery.getAvailableUpdates().isEmpty()) { Platform.runLater(() -> { @@ -334,7 +285,11 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl alert.setContentText(Localization.getString(Strings.UI_Dialog_AutoUpdate_Content)); alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(result -> { - UpdateTabViewController.update(null); + try { + Updates.startUpdate(); + } catch (IOException e) { + e.printStackTrace(); + } }); }); } @@ -352,107 +307,15 @@ public class PlayPadMain extends Application implements LocalizationDelegate, Pl return Locale.getDefault(); } - /* - * Plugins + /** + * Gibt die Implementierung des Peers für Plugins zurück. + * + * @return Schnittstelle + * + * @see PlayPad */ - protected static List<WindowListener<IMainViewController>> mainViewListeners = new ArrayList<>(); - protected static List<WindowListener<ISettingsViewController>> settingsViewListeners = new ArrayList<>(); - protected static List<WindowListener<IPadSettingsViewController>> padSettingsViewListeners = new ArrayList<>(); - protected static List<SettingsListener> settingsListeners = new ArrayList<>(); - protected static List<PadListener> padListeners = new ArrayList<>(); - - @Override - public void addMainViewListener(WindowListener<IMainViewController> listener) { - mainViewListeners.add(listener); - } - - @Override - public void removeMainViewListener(WindowListener<IMainViewController> listener) { - mainViewListeners.remove(listener); - } - - @Override - public void addSettingsViewListener(WindowListener<ISettingsViewController> listener) { - settingsViewListeners.add(listener); - } - - @Override - public void removeSettingsViewListener(WindowListener<ISettingsViewController> listener) { - settingsViewListeners.remove(listener); - } - - @Override - public List<WindowListener<ISettingsViewController>> getSettingsViewListener() { - return settingsViewListeners; - } - - @Override - public void addPadSettingsViewListener(WindowListener<IPadSettingsViewController> listener) { - padSettingsViewListeners.add(listener); - } - - @Override - public void removePadSettingsViewListener(WindowListener<IPadSettingsViewController> listener) { - padSettingsViewListeners.remove(listener); - } - - @Override - public List<WindowListener<IPadSettingsViewController>> getPadSettingsViewListener() { - return padSettingsViewListeners; - } - - @Override - public void addSettingsListener(SettingsListener listener) { - settingsListeners.add(listener); - } - - @Override - public void removeSettingsListener(SettingsListener listener) { - settingsListeners.remove(listener); - } - - @Override - public List<SettingsListener> getSettingsListener() { - return settingsListeners; - } - - @Override - public void addPadListener(PadListener listener) { - padListeners.add(listener); - } - - @Override - public void removePadListener(PadListener listener) { - padListeners.remove(listener); - } - - @Override - public List<PadListener> getPadListener() { - return padListeners; - } - - @Override - public IMainViewController getMainViewController() { - return mainViewController; - } - - @Override - public PluginManager getPluginManager() { - return pluginManager; - } - - @Override - public String[] getProjectFiles() { - return projectType; - } - - @Override - public Optional<Image> getIcon() { - return stageIcon; - } - - public static Updatable getUpdater() { - return updater; + public static PlayPadImpl getProgramInstance() { + return impl; } -} +} \ No newline at end of file diff --git a/PlayWall/src/de/tobias/playpad/Strings.java b/PlayWall/src/de/tobias/playpad/Strings.java index 6443c76d18ff5e5ca372785b6f31588b6eeec5da..57939d09a2c2bce4bdf1d6224442c71a52bc7070 100644 --- a/PlayWall/src/de/tobias/playpad/Strings.java +++ b/PlayWall/src/de/tobias/playpad/Strings.java @@ -22,6 +22,7 @@ public class Strings { public static final String UI_Window_Changelog_Title = "UI.Window.Changelog.Title"; public static final String UI_Window_Settings_Title = "UI.Window.Settings.Title"; public static final String UI_Window_PadSettings_Title = "UI.Window.PadSettings.Title"; + public static final String UI_Window_PadSettings_Title_Empty = "UI.Window.PadSettings.Title.Empty"; public static final String UI_Dialog_DragAndDrop_Title = "UI.Dialog.DragAndDrop.Title"; public static final String UI_Dialog_ProjectExport_Title = "UI.Dialog.ProjectExport.Title"; public static final String UI_Dialog_ErrorSummary_Title = "UI.Dialog.ErrorSummary.Title"; @@ -155,10 +156,7 @@ public class Strings { // Error - Plugins @Deprecated public static final String Error_Plugins_Download = "Error.Plugins.Download"; - - /* - * NEU - */ + public static final String Error_Plugins_Available = "Error.Plugins.Available"; // Mapper public static final String Mapper_Keyboard_Name = "Mapper.Keyboard.Name"; @@ -197,16 +195,18 @@ public class Strings { public static final String UI_Dialog_AutoUpdate_Header = "UI.Dialog.AutoUpdate.Header"; public static final String UI_Dialog_AutoUpdate_Content = "UI.Dialog.AutoUpdate.Content"; + // Update Channel - Basename + public static final String Update_Channel_BaseName = "UpdateChannel."; + // Error - Layout public static final String Error_Layout_Load = "Error.Layout.Load"; // UI - Dialog - Update public static final String UI_Dialog_Update_Cell = "UI.Dialog.Update.Cell"; public static final String UI_Window_Settings_Updates_CurrentVersion = "UI.Window.Settings.Updates.CurrentVersion"; - public static final String UI_Window_Settings_Updates_NewVersion = "UI.Window.Settings.Updates.NewVersion"; // Error - Update - Downlaod - public static final String Error_Update_Download = "Error.Update.Download"; + @Deprecated public static final String Error_Update_Download = "Error.Update.Download"; // Layout public static final String Layout_Modern_Name = "Layout.Modern.Name"; @@ -219,7 +219,7 @@ 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 66a4ce97325f1517ebdd15ce750102ea54354d3d..045a3e7e96923ead258ea4fe3155db83d020843a 100644 --- a/PlayWall/src/de/tobias/playpad/VersionUpdater.java +++ b/PlayWall/src/de/tobias/playpad/VersionUpdater.java @@ -19,6 +19,7 @@ import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import de.tobias.playpad.action.Mapping; +import de.tobias.playpad.action.MappingSerializer; import de.tobias.playpad.action.cartaction.CartAction; import de.tobias.playpad.action.cartaction.CartAction.ControlMode; import de.tobias.playpad.action.feedback.DoubleSimpleFeedback; @@ -188,7 +189,9 @@ public class VersionUpdater implements UpdateService { for (Mapping mapping : mappings) { Element mappingElement = rootElement.addElement("Mapping"); - mapping.save(mappingElement); + + MappingSerializer mappingSerializer = new MappingSerializer(); + mappingSerializer.saveElement(mappingElement, mapping); } XMLWriter writer = new XMLWriter(Files.newOutputStream(configPath.resolve("Mapping.xml")), OutputFormat.createPrettyPrint()); @@ -223,7 +226,8 @@ public class VersionUpdater implements UpdateService { newSettingsElement.addElement("Loop").addText(oldPadElement.element("Loop").getStringValue()); if (oldPadElement.element("TimeMode") != null) newSettingsElement.addElement("TimeMode").addText(oldPadElement.element("TimeMode").getStringValue()); - } catch (Exception e) {} + } catch (Exception e) { + } } XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java index 7691158c4d971f4fb1b6fee394c93868e2da9a21..cd3d5a1021f4e379b978844636a7547ed5a8c4f2 100644 --- a/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java +++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java @@ -2,8 +2,8 @@ package de.tobias.playpad.action.cartaction; import de.tobias.playpad.action.feedback.FeedbackMessage; import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.conntent.Durationable; +import de.tobias.playpad.settings.Warning; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.util.Duration; diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java index 5d1bb8c37cc82cd8189fc2c1821ef60fb723d0be..2dcc8211312456283a3ab3d6076a252f66ce5a50 100644 --- a/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java +++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java @@ -4,7 +4,7 @@ import de.tobias.playpad.action.feedback.FeedbackMessage; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.pad.conntent.Durationable; -import de.tobias.playpad.pad.Warning; +import de.tobias.playpad.settings.Warning; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.util.Duration; diff --git a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java index b0428e4db1774e8be59177263e9308bd682ca5a6..e78e6895cc3a546dba104369f15f6e4ae96e80ee 100644 --- a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java +++ b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java @@ -4,7 +4,7 @@ import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.playpad.viewcontroller.AudioTypeViewController; import de.tobias.playpad.viewcontroller.audio.ClipSettingsViewController; -public class ClipAudioHandlerConnect extends AudioHandlerConnect { +public class ClipAudioHandlerConnect extends AudioHandlerConnect implements AutoCloseable { @Override public AudioHandler createAudioHandler(PadContent content) { @@ -15,5 +15,10 @@ public class ClipAudioHandlerConnect extends AudioHandlerConnect { public AudioTypeViewController getAudioViewController() { return new ClipSettingsViewController(); } + + @Override + public void close() throws Exception { + TinyAudioHandler.shutdown(); + } } diff --git a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java index 3c97f5f9288fd6981970433cdd61503952aac39d..c8e8904c0b953c3dfa3e99f7e162bbe5ca7cf6c4 100644 --- a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java +++ b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java @@ -4,7 +4,7 @@ import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.playpad.viewcontroller.AudioTypeViewController; import de.tobias.playpad.viewcontroller.audio.TinySoundSettingsViewController; -public class TinyAudioHandlerConnect extends AudioHandlerConnect { +public class TinyAudioHandlerConnect extends AudioHandlerConnect implements AutoCloseable { @Override public AudioHandler createAudioHandler(PadContent content) { @@ -16,4 +16,8 @@ public class TinyAudioHandlerConnect extends AudioHandlerConnect { return new TinySoundSettingsViewController(); } + @Override + public void close() throws Exception { + TinyAudioHandler.shutdown(); + } } diff --git a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java index 7bd47b406ccf8aba5a185f690b9e0bcac2c31464..0e6d1952c35ea8cc7f3c8ad22c9ee122b1ffd996 100644 --- a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java +++ b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicCartLayout.java @@ -15,8 +15,8 @@ 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; +import de.tobias.playpad.settings.Warning; import de.tobias.playpad.viewcontroller.IPadView; import de.tobias.utils.util.ColorXMLUtils; import javafx.application.Platform; @@ -210,7 +210,7 @@ public class ClassicCartLayout extends Layout implements CartLayout { } @Override - public void handleWarning(IPadViewController controller, Warning warning) { + public void handleWarning(IPadViewController controller, Warning warning, GlobalLayout layout) { final IPadView view = controller.getParent(); try { diff --git a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicGlobalLayout.java b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicGlobalLayout.java index 8618a813cab625a4dca5d5aa260e161fa59be595..2f067be0999ac96553b147d75bde2c479098014b 100644 --- a/PlayWall/src/de/tobias/playpad/layout/classic/ClassicGlobalLayout.java +++ b/PlayWall/src/de/tobias/playpad/layout/classic/ClassicGlobalLayout.java @@ -11,9 +11,9 @@ import de.tobias.playpad.layout.CartLayout; import de.tobias.playpad.layout.GlobalLayout; import de.tobias.playpad.layout.Layout; import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.view.IPadViewController; import de.tobias.playpad.project.Project; +import de.tobias.playpad.settings.Warning; import de.tobias.playpad.viewcontroller.IPadView; import de.tobias.playpad.viewcontroller.main.IMainViewController; import de.tobias.utils.application.ApplicationUtils; diff --git a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java index cbc99d65840c46d882d609515f60dff71f9e85b0..123f41277e3ab741e7744047d36bddb17b92af9e 100644 --- a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java +++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutCart.java @@ -9,9 +9,9 @@ import de.tobias.playpad.layout.GlobalLayout; import de.tobias.playpad.layout.Layout; import de.tobias.playpad.layout.LayoutColorAssociator; import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.conntent.Durationable; import de.tobias.playpad.pad.view.IPadViewController; +import de.tobias.playpad.settings.Warning; import javafx.scene.paint.Color; import javafx.util.Duration; @@ -25,8 +25,6 @@ public class ModernLayoutCart extends Layout implements CartLayout, LayoutColorA private ModernColor backgroundColor = ModernColor.GRAY1; private ModernColor playColor = ModernColor.RED3; - private boolean isWarnAnimation = true; - public ModernColor getBackgroundColor() { return backgroundColor; } @@ -43,19 +41,9 @@ public class ModernLayoutCart extends Layout implements CartLayout, LayoutColorA this.playColor = playColor; } - public boolean isWarnAnimation() { - return isWarnAnimation; - } - - public void setWarnAnimation(boolean isWarnAnimation) { - this.isWarnAnimation = isWarnAnimation; - } - public void reset() { backgroundColor = ModernColor.GRAY1; playColor = ModernColor.RED1; - - isWarnAnimation = true; } @Override @@ -77,28 +65,18 @@ public class ModernLayoutCart extends Layout implements CartLayout, LayoutColorA e.printStackTrace(); } } - - Element animationElement = rootElement.element("Animation"); - if (animationElement != null) { - Element warnAnimationElement = animationElement.element("Warn"); - if (warnAnimationElement != null) { - isWarnAnimation = Boolean.valueOf(warnAnimationElement.getStringValue()); - } - } } @Override public void save(Element rootElement) { rootElement.addElement("BackgroundColor").addText(backgroundColor.name()); rootElement.addElement("PlayColor").addText(playColor.name()); - Element animationElement = rootElement.addElement("Animation"); - animationElement.addElement("Warn").addText(String.valueOf(isWarnAnimation)); } // Warn Handler -> Animation oder Blinken @Override - public void handleWarning(IPadViewController controller, Warning warning) { - if (isWarnAnimation) { + public void handleWarning(IPadViewController controller, Warning warning, GlobalLayout layout) { + if (layout instanceof ModernLayoutGlobal && ((ModernLayoutGlobal) layout).isWarnAnimation()) { warnAnimation(controller, warning); } else { ModernLayoutAnimator.warnFlash(controller); @@ -204,7 +182,6 @@ public class ModernLayoutCart extends Layout implements CartLayout, LayoutColorA 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 925b392b8eec6daefe124e45c52dd2861fa73f37..c8e79942e2a50cc747ce271d5a55ce805186cf45 100644 --- a/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java +++ b/PlayWall/src/de/tobias/playpad/layout/modern/ModernLayoutGlobal.java @@ -13,11 +13,11 @@ import de.tobias.playpad.layout.GlobalLayout; import de.tobias.playpad.layout.Layout; import de.tobias.playpad.layout.LayoutColorAssociator; import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.conntent.Durationable; import de.tobias.playpad.pad.view.IPadViewController; import de.tobias.playpad.project.Project; import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.Warning; import de.tobias.playpad.viewcontroller.main.IMainViewController; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java index 9f582ea5782a13581240ccea9460638627ac5bcb..bdb5f35a716c1a17f448d408aa1cb5d004314f11 100644 --- a/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java +++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java @@ -2,11 +2,11 @@ package de.tobias.playpad.pad.listener; import de.tobias.playpad.pad.Pad; 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.settings.Warning; import de.tobias.playpad.viewcontroller.pad.PadViewController; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; @@ -88,7 +88,7 @@ public class PadPositionListener implements ChangeListener<Duration>, Runnable { Warning warning = pad.getWarning(); if (pad.isCustomLayout()) { - pad.getLayout().handleWarning(controller, warning); + pad.getLayout().handleWarning(controller, warning, Profile.currentProfile().currentLayout()); } else { Profile.currentProfile().currentLayout().handleWarning(controller, warning); } diff --git a/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java b/PlayWall/src/de/tobias/playpad/update/PlayPadUpdater.java similarity index 62% rename from PlayWall/src/de/tobias/playpad/PlayPadUpdater.java rename to PlayWall/src/de/tobias/playpad/update/PlayPadUpdater.java index be3582a6293243e6558a733e46fb16159bed89a5..f7d3c16f59e26a6e2b604215d50327333c54c2db 100644 --- a/PlayWall/src/de/tobias/playpad/PlayPadUpdater.java +++ b/PlayWall/src/de/tobias/playpad/update/PlayPadUpdater.java @@ -1,4 +1,4 @@ -package de.tobias.playpad; +package de.tobias.playpad.update; import java.io.IOException; import java.net.URISyntaxException; @@ -8,6 +8,8 @@ import java.nio.file.Path; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import de.tobias.playpad.update.Updatable; +import de.tobias.playpad.update.UpdateChannel; import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.util.SystemUtils; @@ -30,47 +32,36 @@ public class PlayPadUpdater implements Updatable { @Override public int getNewBuild() { - if (newBuild == 0) { - checkUpdate(); - } return newBuild; } @Override public String getNewVersion() { - if (newVersion == null) { - checkUpdate(); - } return newVersion; } @Override - public boolean checkUpdate() { + public void loadInformation(UpdateChannel channel) throws IOException, URISyntaxException { App app = ApplicationUtils.getMainApplication(); - try { - URL url = new URL(app.getInfo().getUpdateURL() + "/version.yml"); - FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); - newBuild = config.getInt("build"); - newVersion = config.getString("version"); - - if (SystemUtils.isExe()) { - remotePath = new URL(config.getString("pathExe")); - } else { - remotePath = new URL(config.getString("pathJar")); - } - - return getCurrentBuild() < getNewBuild(); - } catch (IOException | URISyntaxException e) { - e.printStackTrace(); + URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/version.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); + newBuild = config.getInt("build"); + newVersion = config.getString("version"); + + if (SystemUtils.isExe() && channel == UpdateChannel.STABLE) { // EXE only for stable release + remotePath = new URL(config.getString("pathExe")); + } else { + remotePath = new URL(config.getString("pathJar")); } - return false; + } + + @Override + public boolean isUpdateAvailable() { + return getCurrentBuild() < getNewBuild(); } @Override public URL getDownloadPath() { - if (remotePath == null) { - checkUpdate(); - } return remotePath; } diff --git a/PlayWall/src/de/tobias/playpad/update/Updates.java b/PlayWall/src/de/tobias/playpad/update/Updates.java new file mode 100644 index 0000000000000000000000000000000000000000..a507e8d4b28ca862fb5a59a0dbf9248366f4145e --- /dev/null +++ b/PlayWall/src/de/tobias/playpad/update/Updates.java @@ -0,0 +1,125 @@ +package de.tobias.playpad.update; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import de.tobias.playpad.AppUserInfoStrings; +import de.tobias.utils.application.App; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.NativeLauncher; +import de.tobias.utils.application.container.PathType; +import de.tobias.utils.util.IOUtils; +import de.tobias.utils.util.OS; +import javafx.application.Platform; + +public class Updates { + + // Ornder im App-Folder wo Updates zwischengespeichert werden sollen. + private static final String CACHE_FOLER = "Updates"; + + // Name der Updater Datei + private static String JAR_NAME = "PlayWallUp.jar"; + private static String EXE_NAME = "PlayWallUp.exe"; + + /** + * Sollte in einem Extra Thread gemacht werden, da der Updater gedownloaded wird. + * + * @throws IOException + */ + public static void startUpdate() throws IOException { + App app = ApplicationUtils.getApplication(); + String downloadPath = app.getPath(PathType.DOWNLOAD, CACHE_FOLER).toString(); + String updateParameter = UpdateRegistery.buildParamaterString(downloadPath); + + boolean successfulStartUpdate = false; + + // Start des Update Prozesses + if (OS.isWindows()) { + successfulStartUpdate = updateWindows(updateParameter, UpdateRegistery.needsAdminPermission()); + } else if (OS.isMacOS()) { + successfulStartUpdate = updateMacOS(updateParameter); + } + + if (successfulStartUpdate) { + // Kill the program + Platform.exit(); + System.exit(0); + } + } + + private static boolean updateWindows(String parameter, boolean needAdminPermission) throws IOException { + Path path = searchForFile(EXE_NAME); + if (path == null) { + App app = ApplicationUtils.getApplication(); + + String updaterURL = app.getInfo().getUserInfo().get(AppUserInfoStrings.UPDATER_PROGRAM) + EXE_NAME; + path = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, EXE_NAME); + + downloadUpdater(updaterURL, path); + } + startExeFile(parameter, path, needAdminPermission); + return false; + } + + private static boolean updateMacOS(String parameter) throws IOException { + Path path = searchForFile(JAR_NAME); + if (path == null) { + App app = ApplicationUtils.getApplication(); + + String updaterURL = app.getInfo().getUserInfo().get(AppUserInfoStrings.UPDATER_PROGRAM) + JAR_NAME; + path = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, JAR_NAME); + + downloadUpdater(updaterURL, path); + } + startJarFile(parameter, path); + return false; + } + + private static void downloadUpdater(String updaterURL, Path path) throws IOException, MalformedURLException { + URL url = new URL(updaterURL); + InputStream iStr = url.openStream(); + + if (Files.notExists(path)) { + Files.createDirectories(path.getParent()); + } + + IOUtils.copy(iStr, path); + + iStr.close(); + } + + private static void startExeFile(String parameter, Path fileExe, boolean needAdminPermission) throws IOException { + if (needAdminPermission) { + NativeLauncher.executeAsAdministrator(fileExe.toAbsolutePath().toString(), parameter); + } else { + ProcessBuilder builder = new ProcessBuilder(fileExe.toAbsolutePath().toString(), parameter); + builder.start(); + } + + System.exit(0); + } + + private static Path searchForFile(String name) { + Path file = Paths.get(name); + Path fileFolder = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, name); + + if (Files.exists(file)) { + return file; + } else if (Files.exists(fileFolder)) { + return fileFolder; + } + return null; + } + + private static void startJarFile(String parameter, Path fileJar) throws IOException { + ProcessBuilder builder = new ProcessBuilder("java", "-jar", fileJar.toAbsolutePath().toString(), parameter); + builder.start(); + System.exit(0); + } + +} diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java index 5f8e136bf1618202be24fb22469fdfd4f2636195..a1aa93939d236d0703ecfb71a8e02581e609fa3a 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java @@ -1,8 +1,13 @@ package de.tobias.playpad.viewcontroller; +import static de.tobias.utils.util.Localization.getString; + import java.io.File; +import java.io.IOException; import java.nio.file.Path; +import org.dom4j.DocumentException; + import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.Strings; import de.tobias.playpad.project.ProfileChooseable; @@ -19,8 +24,6 @@ import de.tobias.playpad.viewcontroller.dialog.ProfileChooseDialog; import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.ui.ViewController; -import de.tobias.utils.util.Localization; -import de.tobias.utils.util.Worker; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Alert; @@ -59,7 +62,9 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { @Override public void init() { App app = ApplicationUtils.getApplication(); - infoLabel.setText(Localization.getString(Strings.UI_Dialog_Launch_Info, app.getInfo().getName(), app.getInfo().getVersion())); + + // Setup launchscreen labels and image + infoLabel.setText(getString(Strings.UI_Dialog_Launch_Info, app.getInfo().getName(), app.getInfo().getVersion())); try { imageView.setImage(new Image(IMAGE)); } catch (Exception e) { @@ -69,10 +74,12 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { openButton.setDisable(true); deleteButton.setDisable(true); - projectListView.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Project))); + // Load project to list + projectListView.setPlaceholder(new Label(getString(Strings.UI_Placeholder_Project))); projectListView.setId("list"); projectListView.setCellFactory(list -> new ProjectCell()); + // List selection listener projectListView.getSelectionModel().selectedItemProperty().addListener((a, b, c) -> { openButton.setDisable(c == null); @@ -85,8 +92,7 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) { if (mouseEvent.getClickCount() == 2) { if (!projectListView.getSelectionModel().isEmpty()) { - ProjectReference ref = projectListView.getSelectionModel().getSelectedItem(); - launchProject(ref); + launchProject(getSelectedProject()); } } } @@ -98,14 +104,9 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { setCSS("style.css", "de/tobias/playpad/assets/"); setCSS("launchDialog_style.css", "de/tobias/playpad/assets/style/"); - stage.setTitle(Localization.getString(Strings.UI_Dialog_Launch_Title)); + stage.setTitle(getString(Strings.UI_Dialog_Launch_Title)); PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add); - - stage.setOnCloseRequest(e -> - { - Worker.shutdown(); - }); - + stage.setResizable(false); stage.setWidth(650); stage.show(); @@ -118,7 +119,7 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { Project project = dialog.getProject(); if (project != null) { - PlayPadMain.launchProject(project); + PlayPadMain.getProgramInstance().openProject(project); getStage().close(); } } @@ -126,19 +127,18 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { @FXML private void importProfileButtonHandler(ActionEvent event) { FileChooser chooser = new FileChooser(); - chooser.getExtensionFilters() - .add(new ExtensionFilter(Localization.getString(Strings.File_Filter_ZIP), PlayPadMain.projectZIPType)); + chooser.getExtensionFilters().add(new ExtensionFilter(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())); + ImportDialog importDialog = ImportDialog.getInstance(getStage()); + ProjectReference ref = ProjectImporter.importProject(zipFile, importDialog, importDialog); if (ref != null) { launchProject(ref); } - } catch (Exception e) { - showErrorMessage(Localization.getString(Strings.Error_Project_Open, e.getLocalizedMessage())); + } catch (DocumentException | IOException e) { + showErrorMessage(getString(Strings.Error_Project_Open, e.getLocalizedMessage())); e.printStackTrace(); } } @@ -146,36 +146,16 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { @FXML private void openButtonHandler(ActionEvent event) { - ProjectReference ref = projectListView.getSelectionModel().getSelectedItem(); - try { - if (ref != null) { - Project project = Project.load(ref, true, this); - PlayPadMain.launchProject(project); - getStage().close(); - } - } catch (ProfileNotFoundException e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Profile_NotFound, ref.getProfileReference(), e.getLocalizedMessage())); - - // Neues Profile wählen - Profile profile = getUnkownProfile(); - ref.setProfileReference(profile.getRef()); - } catch (ProjectNotFoundException e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Project_NotFound, ref, e.getLocalizedMessage())); - } catch (Exception e) { - e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Project_Open, ref, e.getLocalizedMessage())); - } + launchProject(getSelectedProject()); } @FXML private void deleteButtonHandler(ActionEvent event) { - if (projectListView.getSelectionModel().getSelectedItem() != null) { - ProjectReference ref = projectListView.getSelectionModel().getSelectedItem(); + if (getSelectedProject() != null) { + ProjectReference ref = getSelectedProject(); Alert alert = new Alert(AlertType.CONFIRMATION); - alert.setContentText(Localization.getString(Strings.UI_Dialog_ProjectManager_Delete_Content, ref)); + alert.setContentText(getString(Strings.UI_Dialog_ProjectManager_Delete_Content, ref)); Stage dialog = (Stage) alert.getDialogPane().getScene().getWindow(); PlayPadMain.stageIcon.ifPresent(dialog.getIcons()::add); @@ -187,34 +167,50 @@ public class LaunchDialog extends ViewController implements ProfileChooseable { try { ProjectReference.removeDocument(ref); projectListView.getItems().remove(ref); // VIEW - } catch (Exception e) { - showErrorMessage(Localization.getString(Strings.Error_Project_Delete, e.getLocalizedMessage())); + } catch (DocumentException | IOException e) { + showErrorMessage(getString(Strings.Error_Project_Delete, e.getLocalizedMessage())); } }); } } + /** + * Gibt das ausgewählte Projekt zurück. + * + * @return Projekt + */ + private ProjectReference getSelectedProject() { + return projectListView.getSelectionModel().getSelectedItem(); + } + + /** + * Launch a project and close this view. + * + * @param ref + * Project to launch + */ private void launchProject(ProjectReference ref) { try { Project project = Project.load(ref, true, this); - PlayPadMain.launchProject(project); + PlayPadMain.getProgramInstance().openProject(project); getStage().close(); } catch (ProfileNotFoundException e) { e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Profile_NotFound, ref.getProfileReference(), e.getLocalizedMessage())); + showErrorMessage(getString(Strings.Error_Profile_NotFound, ref.getProfileReference(), e.getLocalizedMessage())); // Neues Profile wählen Profile profile = getUnkownProfile(); ref.setProfileReference(profile.getRef()); } catch (ProjectNotFoundException e) { e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Project_NotFound, ref, e.getLocalizedMessage())); + showErrorMessage(getString(Strings.Error_Project_NotFound, ref, e.getLocalizedMessage())); } catch (Exception e) { e.printStackTrace(); - showErrorMessage(Localization.getString(Strings.Error_Project_Open, ref, e.getLocalizedMessage())); + showErrorMessage(getString(Strings.Error_Project_Open, ref, e.getLocalizedMessage())); } } + // Zeigt dialog für das Ausfählen eines neuen Profiles. @Override public Profile getUnkownProfile() { ProfileChooseDialog dialog = new ProfileChooseDialog(getStage()); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java index 8406d56263a26a169e89365c5a09141629a35a6d..6deea2a19ee6d00415ee5d33d791fb75f90439ec 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java @@ -4,9 +4,13 @@ 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 de.tobias.playpad.PlayPadMain; import de.tobias.playpad.plugin.Plugin; +import de.tobias.playpad.plugin.Plugins; +import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; import javafx.beans.value.ChangeListener; @@ -15,7 +19,6 @@ import javafx.geometry.Pos; import javafx.scene.control.CheckBox; import javafx.scene.control.ListCell; import javafx.scene.layout.HBox; -import net.xeoh.plugins.base.PluginManager; public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boolean> { @@ -23,11 +26,7 @@ public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boole private HBox buttons; private CheckBox checkBox; - private PluginManager manager; - - public PluginCell(PluginManager manager) { - this.manager = manager; - + public PluginCell() { checkBox = new CheckBox(); checkBox.selectedProperty().addListener(this); @@ -47,7 +46,7 @@ public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boole checkBox.setSelected(false); } setGraphic(buttons); - checkBox.setText(item.getName()); + checkBox.setText(item.toString()); } else { setGraphic(null); } @@ -55,24 +54,45 @@ public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boole @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { - Path path = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, plugin.getFileName()); + App app = ApplicationUtils.getApplication(); + + Path path = app.getPath(PathType.LIBRARY, plugin.getFileName()); if (newValue) { // Wurde Aktiviert 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); - } - } - } + loadDependencies(app); - manager.addPluginsFrom(path.toUri()); + // Add Plugin to classpath + PlayPadMain.getProgramInstance().loadPlugin(path.toUri()); } else { - PlayPadMain.addDeletedPlugin(path); + // Deaktivieren + PlayPadMain.getProgramInstance().addDeletedPlugin(path); + } + } + + private void loadDependencies(App app) { + List<Plugin> dependencies = findDependencies(); + dependencies.forEach(p -> + { + Path decPath = app.getPath(PathType.LIBRARY, p.getFileName()); + downloadPlugin(p, decPath); + + // Add Plugin to classpath + PlayPadMain.getProgramInstance().loadPlugin(decPath.toUri()); + }); + } + + private List<Plugin> findDependencies() { + List<Plugin> plugins = new ArrayList<>(); + for (String dependencyName : plugin.getDependencies()) { + for (Plugin plugin : Plugins.getPlugins()) { + if (plugin.getName().equals(dependencyName)) { + plugins.add(plugin); + } + } } + return plugins; } private void downloadPlugin(Plugin plugin, Path path) { diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java index 5ee0a1ee42ca3a96948d1f22d28c7694e7c18d15..57d9105b5c6355ee95f0e4e0f9a9269b5d240eb9 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java @@ -5,8 +5,6 @@ import java.nio.file.Path; import de.tobias.playpad.Displayable; import de.tobias.playpad.project.ProjectReference; -import de.tobias.utils.application.ApplicationUtils; -import de.tobias.utils.application.container.PathType; import de.tobias.utils.ui.icon.FontAwesomeType; import de.tobias.utils.ui.icon.FontIcon; import javafx.scene.control.ContentDisplay; @@ -15,14 +13,14 @@ import javafx.scene.paint.Color; public class ProjectCell extends ListCell<ProjectReference> { - private Displayable action; + private Displayable ref; @Override - protected void updateItem(ProjectReference action, boolean empty) { - super.updateItem(action, empty); + protected void updateItem(ProjectReference ref, boolean empty) { + super.updateItem(ref, empty); if (!empty) { - if (this.action == null || this.action != action) { - Path path = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, action.getFileName()); + if (this.ref == null || this.ref != ref) { + Path path = ref.getProjectPath(); if (Files.notExists(path)) { FontIcon graphics = new FontIcon(FontAwesomeType.WARNING); graphics.setColor(Color.RED); @@ -30,11 +28,11 @@ public class ProjectCell extends ListCell<ProjectReference> { } setContentDisplay(ContentDisplay.RIGHT); - textProperty().bind(action.displayProperty()); - this.action = action; + textProperty().bind(ref.displayProperty()); + this.ref = ref; } } else { - this.action = null; + this.ref = null; textProperty().unbind(); setGraphic(null); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java index 48d27b4b90eba7e5e6e99885433f76cb0fd6494e..c33fffdfd7df206c1edeff9ee6a14c09e93a8b25 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java @@ -1,9 +1,11 @@ package de.tobias.playpad.viewcontroller.cell; import de.tobias.playpad.Strings; -import de.tobias.playpad.Updatable; +import de.tobias.playpad.update.PlayPadUpdater; +import de.tobias.playpad.update.Updatable; import de.tobias.utils.util.Localization; import javafx.scene.control.ListCell; +import javafx.scene.image.ImageView; public class UpdateCell extends ListCell<Updatable> { @@ -11,6 +13,11 @@ public class UpdateCell extends ListCell<Updatable> { protected void updateItem(Updatable item, boolean empty) { super.updateItem(item, empty); if (!empty) { + if (item instanceof PlayPadUpdater) { + setGraphic(new ImageView("de/tobias/playpad/assets/files/class_obj.png")); + } else { + setGraphic(new ImageView("de/tobias/playpad/assets/files/enum_obj.png")); + } setText(Localization.getString(Strings.UI_Dialog_Update_Cell, item.name(), item.getCurrentVersion(), item.getNewVersion())); } else { setText(""); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java index d4bbfd864346d13b9efde1988e29e3e8604edf6f..180f5230e0b9fde768b3a71c8e065bf3a65d3b50 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java @@ -29,8 +29,8 @@ public class DuplicateProjectDialog extends TextInputDialog { setResultConverter(button -> { String param = getEditor().getText(); - if (!param.endsWith(PlayPadMain.projectType[0].substring(1))) { - param += PlayPadMain.projectType[0].substring(1); + if (!param.endsWith(PlayPadMain.projectType.substring(1))) { + param += PlayPadMain.projectType.substring(1); } ButtonData data = button == null ? null : button.getButtonData(); @@ -40,7 +40,7 @@ public class DuplicateProjectDialog extends TextInputDialog { Button button = (Button) getDialogPane().lookupButton(ButtonType.OK); getEditor().textProperty().addListener((a, b, c) -> { - if (ProjectReference.getProjects().contains(c) || !c.matches(Project.projectNameEx)) { + if (ProjectReference.getProjects().contains(c) || !c.matches(Project.PROJECT_NAME_PATTERN)) { button.setDisable(true); } else { button.setDisable(false); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ImportDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ImportDialog.java index a1e8fbf6ef6d4655147014a4d0a77693a430999e..e5e1ba474bfd3bc71c66e8900381a1e0799f51b6 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ImportDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ImportDialog.java @@ -73,7 +73,7 @@ public class ImportDialog implements Importable, ProfileChooseable { @Override public String replaceProject(String name) { - TextInputDialog alert = new TextInputDialog(name.replace(PlayPadMain.projectType[0].substring(1), "")); + TextInputDialog alert = new TextInputDialog(name.replace(PlayPadMain.projectType.substring(1), "")); alert.initOwner(getStage()); alert.initModality(Modality.WINDOW_MODAL); alert.setContentText(Localization.getString(Strings.UI_Dialog_Import_ReplaceProject_ReplaceContent, name)); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java index e82fd677771bb7798c9881b7895e710c859abb9c..b59e10fc3ea267ae949d7f7d8ac8fb89186dc1b4 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java @@ -26,6 +26,12 @@ import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.Window; +/** + * Dieser ViewController listet alle Mappings auf. Man kann diese importieren, exportieren und aktivieren/deaktivieren. + * + * @author tobias + * + */ public class MappingListViewController extends ViewController { @FXML private ComboBox<Mapping> presetsListView; diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java index 973a5a43db38b233c796e259acca9db58d28e58c..3a887b229e59c956c3f867761ca6f30de3e581af 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java @@ -57,7 +57,7 @@ public class NewProjectDialog extends ViewController { if (c.isEmpty()) { finishButton.setDisable(true); } else { - if (ProjectReference.getProjects().contains(c) || !c.matches(Project.projectNameEx)) { + if (ProjectReference.getProjects().contains(c) || !c.matches(Project.PROJECT_NAME_PATTERN)) { finishButton.setDisable(true); return; } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PluginViewController.java similarity index 61% rename from PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java rename to PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PluginViewController.java index d519188a961d87ab1a645dda272b1229635001b7..dbe7f9aefae577b2c99d0e62bc95747d84c760df 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/PluginViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PluginViewController.java @@ -1,18 +1,24 @@ -package de.tobias.playpad.viewcontroller; +package de.tobias.playpad.viewcontroller.dialog; import java.io.IOException; import java.util.Collections; +import java.util.List; + +import org.bukkit.configuration.MemorySection; import de.tobias.playpad.AppUserInfoStrings; import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.Strings; import de.tobias.playpad.plugin.Plugin; +import de.tobias.playpad.plugin.Plugins; import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.update.UpdateChannel; import de.tobias.playpad.viewcontroller.cell.PluginCell; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.ui.ViewController; 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.Button; @@ -21,18 +27,14 @@ import javafx.scene.control.ListView; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.Window; -import net.xeoh.plugins.base.PluginManager; public class PluginViewController extends ViewController { @FXML private ListView<Plugin> pluginListView; @FXML private Button finishButton; - private PluginManager manager; - - public PluginViewController(PluginManager manager, Window owner) { + public PluginViewController(Window owner) { super("pluginView", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle()); - this.manager = manager; getStage().initOwner(owner); getStage().initModality(Modality.WINDOW_MODAL); @@ -40,11 +42,28 @@ public class PluginViewController extends ViewController { Worker.runLater(() -> { try { - String pluginInfoURL = ApplicationUtils.getApplication().getInfo().getUserInfo().getString(AppUserInfoStrings.PLUGINS_URL); - Plugin.load(pluginInfoURL); - - Collections.sort(Plugin.getPlugins()); - pluginListView.getItems().addAll(Plugin.getPlugins()); + String pluginInfoURL = null; + + MemorySection userInfo = ApplicationUtils.getApplication().getInfo().getUserInfo(); + UpdateChannel updateChannel = Profile.currentProfile().getProfileSettings().getUpdateChannel(); + + if (updateChannel == UpdateChannel.STABLE) { + pluginInfoURL = userInfo.getString(AppUserInfoStrings.PLUGINS_URL_STABLE); + } else if (updateChannel == UpdateChannel.BETA) { + pluginInfoURL = userInfo.getString(AppUserInfoStrings.PLUGINS_URL_BETA); + } else { + // No Plugins for this UpdateChannel Available --> Return + showInfoMessage(Localization.getString(Strings.Error_Plugins_Available)); + return; + } + + List<Plugin> plugins = Plugins.load(pluginInfoURL, true); + + Collections.sort(plugins); + Platform.runLater(() -> + { + pluginListView.getItems().setAll(plugins); + }); } catch (IOException e) { e.printStackTrace(); showErrorMessage(Localization.getString(Strings.Error_Standard_Gen), PlayPadMain.stageIcon); @@ -54,7 +73,7 @@ public class PluginViewController extends ViewController { @Override public void init() { - pluginListView.setCellFactory(list -> new PluginCell(manager)); + pluginListView.setCellFactory(list -> new PluginCell()); pluginListView.setPlaceholder(new Label(Localization.getString(Strings.UI_Placeholder_Plugins))); addCloseKeyShortcut(() -> getStage().close()); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/PrintDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PrintDialog.java similarity index 98% rename from PlayWall/src/de/tobias/playpad/viewcontroller/PrintDialog.java rename to PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PrintDialog.java index 4b88bd8e0cdcbdd10d5c9f5de79ba57e85432bcf..25185126c7e2785dc66c89d749a36c6ec3d200ba 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/PrintDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PrintDialog.java @@ -1,4 +1,4 @@ -package de.tobias.playpad.viewcontroller; +package de.tobias.playpad.viewcontroller.dialog; import com.hp.gagawa.java.elements.Body; import com.hp.gagawa.java.elements.Div; diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java index da665cd08e7700f55e45b36a6cb304696da54146..6de43dc90b92a830ef846210f318b6513ac58c83 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java @@ -201,7 +201,7 @@ public class ProjectManagerDialog extends ViewController implements Notification try { String newProjectName = (String) nameTextField.getText(); - if (ProjectReference.getProjects().contains(newProjectName) || !nameTextField.getText().matches(Project.projectNameEx)) { + if (ProjectReference.getProjects().contains(newProjectName) || !nameTextField.getText().matches(Project.PROJECT_NAME_PATTERN)) { showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, nameTextField.getText())); return; } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutCartViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutCartViewController.java index dd3e7bd2cfe6f21f8ab1fbe39d609185c2cb9930..f5c5214f553b3393422300a8142b29022fb74c6c 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutCartViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/layout/ModernLayoutCartViewController.java @@ -42,16 +42,10 @@ public class ModernLayoutCartViewController extends CartLayoutViewController { private void setLayout() { backgroundColorButton.setStyle(getLinearGradientCss(cartLayout.getBackgroundColor())); playColorButton.setStyle(getLinearGradientCss(cartLayout.getPlayColor())); - - warnAnimationCheckBox.setSelected(cartLayout.isWarnAnimation()); } @Override public void init() { - warnAnimationCheckBox.selectedProperty().addListener((a, b, c) -> - { - cartLayout.setWarnAnimation(c); - }); } @FXML diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java index 2d43a552e31cf04f7a733e6accb2b1061a41fb75..8ed2b134f07c501b1ba28832f18dad8c4845560c 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainMenuBarController.java @@ -10,11 +10,7 @@ import java.util.ResourceBundle; import de.tobias.playpad.AppUserInfoStrings; import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.Strings; -import de.tobias.playpad.action.Action; -import de.tobias.playpad.action.cartaction.CartAction; -import de.tobias.playpad.action.connect.CartActionConnect; import de.tobias.playpad.midi.Midi; import de.tobias.playpad.pad.view.IPadViewController; import de.tobias.playpad.project.Project; @@ -24,12 +20,12 @@ 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; import de.tobias.playpad.viewcontroller.dialog.ErrorSummaryDialog; import de.tobias.playpad.viewcontroller.dialog.ImportDialog; import de.tobias.playpad.viewcontroller.dialog.NewProjectDialog; +import de.tobias.playpad.viewcontroller.dialog.PluginViewController; +import de.tobias.playpad.viewcontroller.dialog.PrintDialog; import de.tobias.playpad.viewcontroller.dialog.ProfileViewController; import de.tobias.playpad.viewcontroller.dialog.ProjectManagerDialog; import de.tobias.playpad.viewcontroller.option.SettingsViewController; @@ -57,25 +53,23 @@ import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import javafx.stage.Modality; import javafx.stage.Stage; -import net.xeoh.plugins.base.PluginManager; public class MainMenuBarController implements EventHandler<ActionEvent>, Initializable, ProfileListener { @FXML private MenuBar menuBar; - @FXML CheckMenuItem dndModeMenuItem; - @FXML CheckMenuItem alwaysOnTopItem; - @FXML CheckMenuItem fullScreenMenuItem; - @FXML Menu recentOpenMenu; - @FXML MenuItem profileMenu; + @FXML private CheckMenuItem dndModeMenuItem; + @FXML private CheckMenuItem alwaysOnTopItem; + @FXML private CheckMenuItem fullScreenMenuItem; + @FXML private Menu recentOpenMenu; + @FXML private MenuItem profileMenu; - @FXML CheckMenuItem quickEditMenuItem; - @FXML MenuItem settingsMenuItem; + @FXML private CheckMenuItem quickEditMenuItem; + @FXML private MenuItem settingsMenuItem; - @FXML Menu extensionMenu; + @FXML private Menu extensionMenu; // Open Windows private SettingsViewController settingsViewController; - private PluginManager manager; private MainViewController mvc; private ChangeListener<Boolean> lockedListener; @@ -170,26 +164,10 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial { ProfileViewController controller = new ProfileViewController(mvc.getStage(), mvc.getProject()); controller.getStage().showAndWait(); + mvc.setTitle(); }); } - @FXML - private void quickEditMenuHandler(ActionEvent event) { - try { - for (Action action : Profile.currentProfile().getMappings().getActiveMapping().getActionsOfType(CartActionConnect.TYPE)) { - CartAction cartAction = (CartAction) action; - if (cartAction.getCart() < mvc.padViewList.size()) { - cartAction.getPad().getController().getParent().setBusy(quickEditMenuItem.isSelected()); - // IPadViewController controller = mvc.padViewList.get(cartAction.getCart()); - // MapperQuickSettingsView view = new MapperQuickSettingsView((Pane) controller.getParent().getParent()); - // view.showDropOptions(action.getMappers()); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - @FXML private void settingsHandler(ActionEvent event) { Midi midi = Midi.getInstance(); @@ -217,7 +195,7 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial } if (change) { - PlayPadPlugin.getImplementation().getSettingsListener().forEach(l -> l.onChange(Profile.currentProfile())); + PlayPadMain.getProgramInstance().getSettingsListener().forEach(l -> l.onChange(Profile.currentProfile())); } settingsViewController = null; @@ -318,7 +296,7 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial private void pluginMenuItemHandler(ActionEvent e) { doAction(() -> { - PluginViewController controller = new PluginViewController(manager, mvc.getStage()); + PluginViewController controller = new PluginViewController(mvc.getStage()); controller.getStage().showAndWait(); mvc.showPage(mvc.getPage()); }); @@ -380,10 +358,6 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial }); } - public void setPluginManager(PluginManager manager) { - this.manager = manager; - } - public void setMainViewController(MainViewController mvc) { this.mvc = mvc; } @@ -397,4 +371,18 @@ public class MainMenuBarController implements EventHandler<ActionEvent>, Initial profileSettings.lockedProperty().addListener(lockedListener); lockedListener.changed(profileSettings.lockedProperty(), null, profileSettings.isLocked()); } + + // Getter + + public CheckMenuItem getAlwaysOnTopItem() { + return alwaysOnTopItem; + } + + public Menu getExtensionMenu() { + return extensionMenu; + } + + public CheckMenuItem getFullScreenMenuItem() { + return fullScreenMenuItem; + } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java index 099975dc2c325b468a4cd510d78db7e2f43a6836..4b4e7031c9dc08d2f3adfd9fd96751405f640808 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java @@ -66,8 +66,8 @@ import javafx.scene.shape.Line; import javafx.stage.Modality; import javafx.stage.Screen; import javafx.stage.Stage; -import net.xeoh.plugins.base.PluginManager; +// TODO Extract Color Adjust methodes public class MainViewController extends ViewController implements IMainViewController, NotificationHandler, ProfileListener { private static final String CURRENT_PAGE_BUTTON = "current-page-button"; @@ -99,13 +99,12 @@ public class MainViewController extends ViewController implements IMainViewContr // Style private Color gridColor; - public MainViewController(Project project, List<WindowListener<IMainViewController>> listener, PluginManager manager) { + public MainViewController(Project project, List<WindowListener<IMainViewController>> listener) { super("mainView", "de/tobias/playpad/assets/view/main/", null, PlayPadMain.getUiResourceBundle()); // Include FXML Setup toolbarController.setMainViewController(this); menuBarController.setMainViewController(this); - menuBarController.setPluginManager(manager); padGridPane.setGridLinesVisible(true); @@ -159,7 +158,7 @@ public class MainViewController extends ViewController implements IMainViewContr public void init() { padGridPane.getStyleClass().add("pad-grid"); - menuBarController.extensionMenu.setVisible(false); + menuBarController.getExtensionMenu().setVisible(false); liveLabel.setVisible(false); liveLabel.getStyleClass().add("live-label"); @@ -172,7 +171,7 @@ public class MainViewController extends ViewController implements IMainViewContr getStage().fullScreenProperty().addListener((a, b, c) -> { - menuBarController.fullScreenMenuItem.setSelected(c); + menuBarController.getFullScreenMenuItem().setSelected(c); }); // Lautstärke Veränderung @@ -189,7 +188,7 @@ public class MainViewController extends ViewController implements IMainViewContr } } - private void setTitle() { + void setTitle() { if (project != null && Profile.currentProfile() != null) { getStage().setTitle(Localization.getString(Strings.UI_Window_Main_Title, project.getRef().getName(), Profile.currentProfile().getRef().getName())); @@ -656,7 +655,7 @@ public class MainViewController extends ViewController implements IMainViewContr } // WINDOW Settings - menuBarController.alwaysOnTopItem.setSelected(profilSettings.isWindowAlwaysOnTop()); + menuBarController.getAlwaysOnTopItem().setSelected(profilSettings.isWindowAlwaysOnTop()); getStage().setAlwaysOnTop(profilSettings.isWindowAlwaysOnTop()); setTitle(); @@ -685,9 +684,9 @@ public class MainViewController extends ViewController implements IMainViewContr * @since 2.0.0 */ public void addMenuItem(MenuItem item) { - menuBarController.extensionMenu.getItems().add(item); - if (!menuBarController.extensionMenu.isVisible()) { - menuBarController.extensionMenu.setVisible(true); + menuBarController.getExtensionMenu().getItems().add(item); + if (!menuBarController.getExtensionMenu().isVisible()) { + menuBarController.getExtensionMenu().setVisible(true); } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java index dedc6b40dec0b564ee47058c1c5783cd093e11ee..4bb3bedb665346bac197cd878f182a515083b053 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/GeneralTabViewController.java @@ -67,9 +67,9 @@ public class GeneralTabViewController extends SettingsTabViewController { private boolean changeSettings; - public GeneralTabViewController(Screen screen, ViewController parentController, boolean activePlayer) { + public GeneralTabViewController(Screen currentScreen, ViewController parentController, boolean activePlayer) { super("generalTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle()); - this.mainWindowScreen = screen; + this.mainWindowScreen = currentScreen; this.parentController = parentController; if (activePlayer) { diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java index 9e9aff7afe1d9708e5331201322811650bd11fd6..8dc5d9b1b85b7e8a3a1f60e77ac049717285483f 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/SettingsViewController.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.Strings; import de.tobias.playpad.midi.Midi; import de.tobias.playpad.pad.conntent.PadContentRegistry; @@ -36,18 +35,18 @@ public class SettingsViewController extends ViewController implements ISettingsV protected List<SettingsTabViewController> tabs = new ArrayList<>(); - public SettingsViewController(Midi midiHandler, Screen screen, Window owner, Project project) { + public SettingsViewController(Midi midiHandler, Screen currentScreen, Window owner, Project project) { super("settingsView", "de/tobias/playpad/assets/view/option/", null, PlayPadMain.getUiResourceBundle()); - boolean activePlayer = project.getPlayedPlayers() > 0; + boolean activePlayer = project.hasPlayedPlayers(); - addTab(new GeneralTabViewController(screen, this, activePlayer)); + addTab(new GeneralTabViewController(currentScreen, this, activePlayer)); addTab(new MappingTabViewController()); addTab(new MidiTabViewController()); addTab(new LayoutTabViewController()); addTab(new PlayerTabViewController()); - // Content Types + // Custom Tabs - Content Types for (String type : PadContentRegistry.getTypes()) { try { SettingsTabViewController controller = PadContentRegistry.getPadContentConnect(type).getSettingsTabViewController(activePlayer); @@ -59,21 +58,12 @@ public class SettingsViewController extends ViewController implements ISettingsV } } - // Listener - PlayPadPlugin.getImplementation().getSettingsViewListener().forEach(l -> - { - try { - l.onInit(this); - } catch (Exception e) { - e.printStackTrace(); - } - }); addTab(new UpdateTabViewController()); getStage().initOwner(owner); // Show Current Settings - showCurrentSettings(); + loadTabs(); } @Override @@ -83,21 +73,19 @@ public class SettingsViewController extends ViewController implements ISettingsV // KeyCode addCloseKeyShortcut(() -> finishButton.fire()); + // Look Button Listener lockedButton.setGraphic(new FontIcon(FontAwesomeType.LOCK)); lockedButton.setOnAction(e -> { boolean isLocked = lockedButton.isSelected(); - // Model profileSettings.setLocked(isLocked); - - // SettingsUI - tabPane.setDisable(isLocked); + setLookEnable(isLocked); }); + // Übernimmt die aktuellen Einstellungen des Look Button if (profileSettings.isLocked()) { - // SettingsUI lockedButton.setSelected(true); - tabPane.setDisable(true); + setLookEnable(true); } finishButton.defaultButtonProperty().bind(finishButton.focusedProperty()); @@ -114,37 +102,20 @@ public class SettingsViewController extends ViewController implements ISettingsV Profile.currentProfile().currentLayout().applyCss(getStage()); } - // Copy Of Settings - public boolean closeRequest() { - boolean valid = true; - for (SettingsTabViewController controller : tabs) { - if (controller.validSettings() == false) { - valid = false; - } - } - - if (valid) { // Einstellungen sind Valide - // Listener - PlayPadPlugin.getImplementation().getSettingsViewListener().forEach(l -> l.onClose(this)); - - saveChanges(); - getStage().close(); - updateData(); - return true; - } else { - return false; - } - } - - // Settings aus AppSettings - private void showCurrentSettings() { + /** + * Zeigt die aktuellen Einstellungen für die Tabs an. + */ + private void loadTabs() { Profile profile = Profile.currentProfile(); for (SettingsTabViewController controller : tabs) { controller.loadSettings(profile); } } - private void saveChanges() { + /** + * Speichert die Einstellungen der Tabs. + */ + private void saveTabs() { Profile profile = Profile.currentProfile(); for (SettingsTabViewController controller : tabs) { controller.saveSettings(profile); @@ -158,33 +129,42 @@ public class SettingsViewController extends ViewController implements ISettingsV } } - public boolean needUpdate() { - boolean change = false; - for (SettingsTabViewController controller : tabs) { - if (controller.needReload()) { - change = true; - } - } - return change; + public boolean closeRequest() { + return onFinish(); } + // Button Listener @FXML private void finishButtonHandler(ActionEvent event) { - boolean valid = true; + onFinish(); + getStage().close(); + } + + /** + * Speichert alle Informationen. + * + * @return <code>true</code>Alle Einstellungen sind Valid. + */ + private boolean onFinish() { for (SettingsTabViewController controller : tabs) { if (controller.validSettings() == false) { - valid = false; + return false; } } - if (valid) { // Einstellungen sind Valide - // Listener - PlayPadPlugin.getImplementation().getSettingsViewListener().forEach(l -> l.onClose(this)); + saveTabs(); + updateData(); // Reload MainViewController Settings // TODO Rewrite + return true; + } - saveChanges(); - getStage().close(); - updateData(); - } + /** + * Aktiviert/Deaktiviert den Look Button. + * + * @param isLocked + * isLooked + */ + private void setLookEnable(boolean isLocked) { + tabPane.setDisable(isLocked); } public void addTab(SettingsTabViewController controller) { diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/UpdateTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/UpdateTabViewController.java index 0edd9042f39d8a1917d7f57927b18b23d6793074..0bf463e78c590218e2303fee471d4475a84323ca 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/UpdateTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/UpdateTabViewController.java @@ -1,56 +1,37 @@ package de.tobias.playpad.viewcontroller.option; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Optional; -import de.tobias.playpad.AppUserInfoStrings; import de.tobias.playpad.PlayPadMain; -import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.Strings; -import de.tobias.playpad.Updatable; -import de.tobias.playpad.UpdateRegistery; import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.ProfileSettings; +import de.tobias.playpad.update.Updatable; +import de.tobias.playpad.update.UpdateChannel; +import de.tobias.playpad.update.UpdateRegistery; +import de.tobias.playpad.update.Updates; import de.tobias.playpad.viewcontroller.SettingsTabViewController; +import de.tobias.playpad.viewcontroller.cell.EnumCell; import de.tobias.playpad.viewcontroller.cell.UpdateCell; import de.tobias.playpad.viewcontroller.dialog.UpdaterDialog; +import de.tobias.utils.application.ApplicationInfo; import de.tobias.utils.application.ApplicationUtils; -import de.tobias.utils.application.NativeLauncher; -import de.tobias.utils.application.container.PathType; import de.tobias.utils.util.Localization; -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.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.CheckBox; +import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ListView; import javafx.scene.control.ProgressIndicator; -import javafx.scene.image.Image; -import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.stage.Window; +import javafx.scene.image.ImageView; public class UpdateTabViewController extends SettingsTabViewController { - private static final String DOWNLOAD_FOLDER = "Updates"; - private static final String UPDATER_JAR = "Updater.jar"; - private static final String UPDATER_EXE = "Updater.exe"; - @FXML private Label currentVersionLabel; - @FXML private Label newVersionLabel; @FXML private CheckBox automaticSearchCheckBox; @FXML private Button manualSearchButton; @@ -58,35 +39,47 @@ public class UpdateTabViewController extends SettingsTabViewController { @FXML private ListView<Updatable> openUpdateList; @FXML private Button updateButton; + @FXML private ComboBox<UpdateChannel> updateChannelComboBox; + + @FXML private Label infoCLabel; + @FXML private Label infoELabel; + + // Placeholder for List private ProgressIndicator progressIndecator; private Label placeholderLabel; public UpdateTabViewController() { super("updateTab", "de/tobias/playpad/assets/view/option/", PlayPadMain.getUiResourceBundle()); + ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); + updateChannelComboBox.setValue(profileSettings.getUpdateChannel()); openUpdateList.getItems().setAll(UpdateRegistery.getAvailableUpdates()); updateButton.setDisable(openUpdateList.getItems().isEmpty()); - Worker.runLater(() -> - { - Updatable updater = PlayPadMain.getUpdater(); - updater.checkUpdate(); - Platform.runLater(() -> - { - currentVersionLabel.setText(Localization.getString(Strings.UI_Window_Settings_Updates_CurrentVersion, - updater.getCurrentVersion(), updater.getCurrentBuild())); - newVersionLabel.setText(Localization.getString(Strings.UI_Window_Settings_Updates_CurrentVersion, updater.getNewVersion(), - updater.getNewBuild())); - }); - }); + ApplicationInfo info = ApplicationUtils.getApplication().getInfo(); + String currentVersionString = Localization.getString(Strings.UI_Window_Settings_Updates_CurrentVersion, info.getVersion(), + info.getBuild()); + currentVersionLabel.setText(currentVersionString); } @Override public void init() { openUpdateList.setCellFactory(list -> new UpdateCell()); + updateChannelComboBox.getItems().setAll(UpdateChannel.values()); + updateChannelComboBox.setCellFactory(list -> new EnumCell<>(Strings.Update_Channel_BaseName)); + updateChannelComboBox.setButtonCell(new EnumCell<>(Strings.Update_Channel_BaseName)); + + updateChannelComboBox.valueProperty().addListener((a, b, c) -> + { + Profile.currentProfile().getProfileSettings().setUpdateChannel(c); + }); + + infoCLabel.setGraphic(new ImageView("de/tobias/playpad/assets/files/class_obj.png")); + infoELabel.setGraphic(new ImageView("de/tobias/playpad/assets/files/enum_obj.png")); progressIndecator = new ProgressIndicator(-1); - progressIndecator.setMinSize(25, 25); + progressIndecator.setMinSize(75, 75); + progressIndecator.setMaxSize(75, 75); placeholderLabel = new Label(Localization.getString(Strings.UI_Placeholder_Updates)); openUpdateList.setPlaceholder(placeholderLabel); @@ -98,124 +91,42 @@ public class UpdateTabViewController extends SettingsTabViewController { private void manualSearchHandler(ActionEvent event) { openUpdateList.getItems().clear(); - openUpdateList.setPlaceholder(progressIndecator); - UpdateRegistery.lookupUpdates(); - openUpdateList.setPlaceholder(placeholderLabel); + Profile profile = Profile.currentProfile(); + if (profile != null) { + openUpdateList.setPlaceholder(progressIndecator); - openUpdateList.getItems().setAll(UpdateRegistery.getAvailableUpdates()); - updateButton.setDisable(openUpdateList.getItems().isEmpty()); + Worker.runLater(() -> + { + // Search for updates + UpdateRegistery.lookupUpdates(profile.getProfileSettings().getUpdateChannel()); + + Platform.runLater(() -> + { + openUpdateList.setPlaceholder(placeholderLabel); + openUpdateList.getItems().setAll(UpdateRegistery.getAvailableUpdates()); + updateButton.setDisable(openUpdateList.getItems().isEmpty()); + }); + }); + + } } @FXML private void updateHandler(ActionEvent event) { - update(getStage()); - } - - public static void update(Window dialogOwner) { - String parameter = UpdateRegistery - .buildParamaterString(ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, DOWNLOAD_FOLDER).toString()); - if (OS.getType() == OSType.Windows) { - try { - Path fileJar = Paths.get(UPDATER_JAR); - Path fileExe = Paths.get(UPDATER_EXE); - Path fileJarFolder = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_JAR); - Path fileExeFolder = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_EXE); - - if (Files.exists(fileJar)) { - startJarFile(parameter, fileJar); - } else if (Files.exists(fileExe)) { - startExeFile(parameter, fileExe); - - } else if (Files.exists(fileJarFolder)) { - startJarFile(parameter, fileJarFolder); - } else if (Files.exists(fileExeFolder)) { - startExeFile(parameter, fileExeFolder); - } else { - UpdaterDialog dialog = new UpdaterDialog(dialogOwner); - dialog.show(); + UpdaterDialog dialog = new UpdaterDialog(getStage()); + dialog.show(); - Worker.runLater(() -> - { - String updaterURL = ApplicationUtils.getApplication().getInfo().getUserInfo().get(AppUserInfoStrings.UPDATER_PROGRAM) - + UPDATER_EXE; - Path path = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_EXE); - try { - downloadUpdater(updaterURL, path); - startExeFile(parameter, path); - } catch (Exception e) { - e.printStackTrace(); - String errorMessage = Localization.getString(Strings.Error_Update_Download, e.getMessage()); - showErrorMessage(errorMessage, PlayPadPlugin.getImplementation().getIcon(), dialogOwner); - } - }); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } else { + Worker.runLater(() -> + { try { - Path fileJar = Paths.get(UPDATER_JAR); - Path fileJarFolder = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_JAR); - - if (Files.exists(fileJar)) { - startJarFile(parameter, fileJar); - } else if (Files.exists(fileJarFolder)) { - startJarFile(parameter, fileJarFolder); - } else { - UpdaterDialog dialog = new UpdaterDialog(dialogOwner); - dialog.show(); - - Worker.runLater(() -> - { - String updaterURL = ApplicationUtils.getApplication().getInfo().getUserInfo().get(AppUserInfoStrings.UPDATER_PROGRAM) - + UPDATER_JAR; - Path path = ApplicationUtils.getApplication().getPath(PathType.DOWNLOAD, UPDATER_JAR); - try { - downloadUpdater(updaterURL, path); - startJarFile(parameter, path); - } catch (Exception e) { - e.printStackTrace(); - String errorMessage = Localization.getString(Strings.Error_Update_Download, e.getMessage()); - showErrorMessage(errorMessage, PlayPadPlugin.getImplementation().getIcon(), dialogOwner); - } - }); - } - } catch (Exception ex) { - ex.printStackTrace(); + Updates.startUpdate(); + } catch (IOException e) { + e.printStackTrace(); } - } - } - - private static void downloadUpdater(String updaterURL, Path path) throws IOException, MalformedURLException { - if (Files.notExists(path)) { - Files.createDirectories(path.getParent()); - Files.createFile(path); - } - - URLConnection conn = new URL(updaterURL).openConnection(); - - InputStream iStr = conn.getInputStream(); - OutputStream oStr = Files.newOutputStream(path); - - byte[] data = new byte[1024]; - int dataLength = 0; - while ((dataLength = iStr.read(data, 0, data.length)) > 0) { - oStr.write(data, 0, dataLength); - } - oStr.close(); - } - - private static void startExeFile(String parameter, Path fileExeFolder) { - NativeLauncher.executeAsAdministrator(fileExeFolder.toAbsolutePath().toString(), parameter); - System.exit(0); - } - - private static void startJarFile(String parameter, Path fileJarFolder) throws IOException { - ProcessBuilder builder = new ProcessBuilder("java", "-jar", fileJarFolder.toAbsolutePath().toString(), parameter); - builder.start(); - System.exit(0); + }); } + // Settings Tab Methods @Override public void loadSettings(Profile profile) { automaticSearchCheckBox.setSelected(profile.getProfileSettings().isAutoUpdate()); @@ -240,21 +151,4 @@ public class UpdateTabViewController extends SettingsTabViewController { public String name() { return Localization.getString(Strings.UI_Window_Settings_Updates_Title); } - - private static void showErrorMessage(String message, Optional<Image> icon, Window owner) { - if (!Platform.isFxApplicationThread()) { - Platform.runLater(() -> showErrorMessage(message, icon, owner)); - return; - } - - Alert alert = new Alert(AlertType.ERROR); - alert.initOwner(owner); - alert.initModality(Modality.WINDOW_MODAL); - alert.setContentText(message); - if (icon.isPresent()) { - Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); - stage.getIcons().add(icon.get()); - } - alert.showAndWait(); - } } 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 f400d434c30605ec46507df430fd88326342276b..8a8c69521c07984f3713b192bb7664c7d72c80f4 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java @@ -4,9 +4,9 @@ import java.util.ArrayList; import java.util.List; 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.PadStatus; import de.tobias.playpad.pad.conntent.PadContentConnect; import de.tobias.playpad.pad.conntent.PadContentRegistry; import de.tobias.playpad.pad.conntent.UnkownPadContentException; @@ -53,16 +53,6 @@ public class PadSettingsViewController extends ViewController implements IPadSet } } - // Listener - PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> - { - try { - l.onInit(this); - } catch (Exception e) { - e.printStackTrace(); - } - }); - getStage().initOwner(owner); // Show Current Settings @@ -71,7 +61,11 @@ public class PadSettingsViewController extends ViewController implements IPadSet } private void setTitle(Pad pad) { - getStage().setTitle(Localization.getString(Strings.UI_Window_PadSettings_Title, pad.getIndexReadable(), pad.getName())); + if (pad.getStatus() != PadStatus.EMPTY) { + getStage().setTitle(Localization.getString(Strings.UI_Window_PadSettings_Title, pad.getIndexReadable(), pad.getName())); + } else { + getStage().setTitle(Localization.getString(Strings.UI_Window_PadSettings_Title_Empty, pad.getIndexReadable())); + } } @Override @@ -110,25 +104,23 @@ public class PadSettingsViewController extends ViewController implements IPadSet @Override public boolean closeRequest() { - saveChanges(); - - // Listener - PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this)); + onFinish(); return true; } - private void saveChanges() { - for (PadSettingsTabViewController controller : tabs) { - controller.saveSettings(pad); - } - } - @FXML private void finishButtonHandler(ActionEvent event) { - saveChanges(); - // Listener - PlayPadPlugin.getImplementation().getPadSettingsViewListener().forEach(l -> l.onClose(this)); - getStage().close(); + onFinish(); } + /** + * Diese Methode wird aufgerufen, wenn das Fenster geschlossen wird (Per X oder Finish Button). Hier geschehen alle Aktionen zum + * manuellen Speichern. + */ + private void onFinish() { + // Speichern der einzelen Tabs + for (PadSettingsTabViewController controller : tabs) { + controller.saveSettings(pad); + } + } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java index 6c6274b3da4766dfbba104f2a49e2f59a0648e8c..4cae57b156b833e7b8eb572b7830a9c0a8bbed94 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java @@ -2,9 +2,9 @@ package de.tobias.playpad.viewcontroller.option.pad; import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.Strings; -import de.tobias.playpad.pad.Fade; import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.Warning; +import de.tobias.playpad.settings.Fade; +import de.tobias.playpad.settings.Warning; import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; import de.tobias.playpad.viewcontroller.settings.FadeViewController; import de.tobias.playpad.viewcontroller.settings.WarningFeedbackViewController; diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java index e39abcda8c007b79c7a00ea961ba37d1f39a8b73..1f112d73fd2f853ef34bd99a3fe91cb7ed3d676e 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java @@ -54,6 +54,7 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon private PadPositionListener padPositionListener; private PadDragListener padDragListener; + private transient PadSettingsViewController padSettingsViewController; public PadViewController() { view = new PadView(this); @@ -183,13 +184,15 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon } 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(); + if (padSettingsViewController == null) { + padSettingsViewController = new PadSettingsViewController(pad, owner); + padSettingsViewController.getStage().setOnHiding(ev -> + { + if (view != null && pad != null) + view.setTriggerLabelActive(pad.hasTriggerItems()); + }); + } + padSettingsViewController.getStage().show(); } } @@ -230,7 +233,7 @@ public class PadViewController implements EventHandler<ActionEvent>, IPadViewCon @Override public void setPad(Pad pad) { unconnectPad(); - + this.pad = pad; view.setPreviewContent(pad); diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/settings/FadeViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/FadeViewController.java index 2a4ee9720e830b10eedb994e8534521a945c4ec2..dfa3c7331e8bdaf6eef9bc609d9f2e3bdbf92cc0 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/settings/FadeViewController.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/FadeViewController.java @@ -2,7 +2,7 @@ package de.tobias.playpad.viewcontroller.settings; import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.Strings; -import de.tobias.playpad.pad.Fade; +import de.tobias.playpad.settings.Fade; import de.tobias.utils.ui.ContentViewController; import de.tobias.utils.util.Localization; import javafx.fxml.FXML; diff --git a/PlayWall/src/icon.icns b/PlayWall/src/icon.icns index 0b82f6e32cec646a917652b1f7438fe6d9814b27..bf25eb296be13a7463ef87e9e2ec679dc4074607 100644 Binary files a/PlayWall/src/icon.icns and b/PlayWall/src/icon.icns differ diff --git a/PlayWall/src/icon.ico b/PlayWall/src/icon.ico index 376f9b44f0795408da217e99f1ad84c7f8382ba1..c890577816398684f920181cadb73af23c3e0b40 100644 Binary files a/PlayWall/src/icon.ico and b/PlayWall/src/icon.ico differ diff --git a/PlayWall/src/icon.png b/PlayWall/src/icon.png index e2fe4bc8d837c9cb9a166b85503af202dbf4331f..63b9171fd055ac52d6736f627d13b394f4ac289c 100644 Binary files a/PlayWall/src/icon.png and b/PlayWall/src/icon.png differ diff --git a/PlayWall/src/icon_small.png b/PlayWall/src/icon_small.png index e8acf8263a66f86581c5b5f65f0ad11ff11bf60b..d219f3f9f51865239f3be85dbae5cd342955b833 100644 Binary files a/PlayWall/src/icon_small.png and b/PlayWall/src/icon_small.png differ diff --git a/PlayWallCore/.gitignore b/PlayWallCore/.gitignore index 94faa17313fb07d638498de2460e291e5d826ed9..960394d9f74e222f50aa4ef2f6b9929f3422feda 100644 --- a/PlayWallCore/.gitignore +++ b/PlayWallCore/.gitignore @@ -1,2 +1,3 @@ /bin/ -/test/ \ No newline at end of file +/test/ +/doc/ diff --git a/PlayWallCore/src/de/tobias/playpad/PlayPad.java b/PlayWallCore/src/de/tobias/playpad/PlayPad.java index e0a6546cd2cc96a749fd7c4b648e4c946c6ecf9d..877bd5d97fc07a4e84b89911fa0c063e8663033c 100644 --- a/PlayWallCore/src/de/tobias/playpad/PlayPad.java +++ b/PlayWallCore/src/de/tobias/playpad/PlayPad.java @@ -1,21 +1,27 @@ package de.tobias.playpad; +import java.net.URI; import java.util.List; import java.util.Optional; import de.tobias.playpad.plugin.PadListener; import de.tobias.playpad.plugin.SettingsListener; import de.tobias.playpad.plugin.WindowListener; -import de.tobias.playpad.viewcontroller.IPadSettingsViewController; -import de.tobias.playpad.viewcontroller.ISettingsViewController; import de.tobias.playpad.viewcontroller.main.IMainViewController; import javafx.scene.image.Image; -import net.xeoh.plugins.base.PluginManager; +/** + * Hauptfunktionen für Listener und zur Programmsteuerung für Plugins. + * + * @author tobias + * + * @since 5.0.0 + * + */ public interface PlayPad { /** - * Fügt einen Listener für das Hauptfenster hinzu + * Fügt einen Listener für das Hauptfenster hinzu. * * @param listener * @@ -24,85 +30,80 @@ public interface PlayPad { public void addMainViewListener(WindowListener<IMainViewController> listener); /** - * Entfernt ein registrierten Listener des Hauptfensters + * Fügt einen Settings Listener hinzu. * * @param listener * * @since 2.0.0 */ - public void removeMainViewListener(WindowListener<IMainViewController> listener); + public void addSettingsListener(SettingsListener listener); /** - * Fügt einen Listener zum Settings Fenster hinzu + * Entfernt einen Settings Listener. * * @param listener * * @since 2.0.0 */ - public void addSettingsViewListener(WindowListener<ISettingsViewController> listener); + public void removeSettingsListener(SettingsListener listener); /** - * Entfernt einen Listener des Settings Fensters - * - * @param listener + * Gibt alle SettingListener zurück. * - * @since 2.0.0 + * @return Settingslistener */ - public void removeSettingsViewListener(WindowListener<ISettingsViewController> listener); - - public List<WindowListener<ISettingsViewController>> getSettingsViewListener(); + public List<SettingsListener> getSettingsListener(); /** - * Fügt einen Listener zum PadSettings Fenster hinzu + * Fügt ein PadListener zum System hinzu. Der Listener gilt für alle Pads. * * @param listener - * - * @since 2.0.0 + * Listener + * @since 5.0.0 */ - public void addPadSettingsViewListener(WindowListener<IPadSettingsViewController> listener); + public void addPadListener(PadListener listener); /** - * Entfernt einen Listener vom PadSettings Fenster + * Entfernt ein Pad Listener. * * @param listener - * - * @since 2.0.0 + * Listener */ - public void removePadSettingsViewListener(WindowListener<IPadSettingsViewController> listener); - - public List<WindowListener<IPadSettingsViewController>> getPadSettingsViewListener(); + public void removePadListener(PadListener listener); /** - * Fügt einen Settings Listener hinzu + * Gibt alle PadListener zurück. * - * @param listener + * @return PadListener * - * @since 2.0.0 + * @see 5.0.0 */ - public void addSettingsListener(SettingsListener listener); + public List<PadListener> getPadListener(); /** - * Entfernt einen Settings Listener + * Gibt eine Refernz auf das Hauptfenster zurück. * - * @param listener - * - * @since 2.0.0 + * @return Main ViewController */ - public void removeSettingsListener(SettingsListener listener); - - public List<SettingsListener> getSettingsListener(); - - public void addPadListener(PadListener listener); - - public void removePadListener(PadListener listener); - - public List<PadListener> getPadListener(); - public IMainViewController getMainViewController(); - public PluginManager getPluginManager(); + /** + * Gibt das Programm Icon zurück. + * + * @return Programmicon + */ + public Optional<Image> getIcon(); - public String[] getProjectFiles(); + /** + * Beendet PlayWall. + */ + public void shutdown(); - public Optional<Image> getIcon(); + /** + * Lädt ein Plugin sofort ins System. + * + * @param uri + * Quelle des Plugin + */ + public void loadPlugin(URI uri); } diff --git a/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..ca46cf05a6719eeaf52ac4800910b48596c31553 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java @@ -0,0 +1,51 @@ +package de.tobias.playpad.action; + +import java.util.List; + +import org.dom4j.Element; + +import de.tobias.playpad.action.mapper.Mapper; +import de.tobias.playpad.xml.XMLDeserializer; +import de.tobias.playpad.xml.XMLHandler; +import de.tobias.playpad.xml.XMLSerializer; + +public class ActionSerializer implements XMLSerializer<Action>, XMLDeserializer<Action> { + + private static final String ACTION_TYPE = "type"; + private static final String MAPPER = "Mapper"; + + private Mapping mapping; + + public ActionSerializer(Mapping mapping) { + this.mapping = mapping; + } + + @Override + public Action loadElement(Element element) { + String tpye = element.attributeValue(ACTION_TYPE); + + Action action = ActionRegistery.getActionConnect(tpye).newInstance(); + action.load(element); + + boolean added = mapping.addActionIfNotContains(action); + + if (added) { + XMLHandler<Mapper> handler = new XMLHandler<>(element); + List<Mapper> mappers = handler.loadElements(MAPPER, new MapperSerializer(action)); + mappers.forEach(action::addMapper); + } + + return action; + } + + @Override + public void saveElement(Element newElement, Action data) { + newElement.addAttribute(ACTION_TYPE, data.getType()); + + data.save(newElement); + + XMLHandler<Mapper> handler = new XMLHandler<>(newElement); + handler.saveElements(MAPPER, data.getMappers(), new MapperSerializer(data)); + } + +} diff --git a/PlayWallCore/src/de/tobias/playpad/action/MapperSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/MapperSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..c9b60ef86ddb4c0bc8895726bda8a2da324a3fc8 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/action/MapperSerializer.java @@ -0,0 +1,36 @@ +package de.tobias.playpad.action; + +import org.dom4j.Element; + +import de.tobias.playpad.action.mapper.Mapper; +import de.tobias.playpad.action.mapper.MapperRegistry; +import de.tobias.playpad.xml.XMLDeserializer; +import de.tobias.playpad.xml.XMLSerializer; + +public class MapperSerializer implements XMLSerializer<Mapper>, XMLDeserializer<Mapper> { + + private static final String MAPPER_TYPE = "type"; + + private Action action; + + public MapperSerializer(Action action) { + this.action = action; + } + + @Override + public Mapper loadElement(Element element) { + String mapperType = element.attributeValue(MAPPER_TYPE); + + Mapper mapper = MapperRegistry.getMapperConnect(mapperType).createNewMapper(); + mapper.load(element, action); + return mapper; + } + + @Override + public void saveElement(Element newElement, Mapper data) { + newElement.addAttribute(MAPPER_TYPE, data.getType()); + data.save(newElement, action); + + } + +} diff --git a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java index b451611d56c5073846b874c42e7f1d2f30123f20..ccfe4072ff62b21e960c0358bf915f196cdfd884 100644 --- a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java +++ b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java @@ -7,8 +7,6 @@ import java.util.Set; import java.util.UUID; 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; @@ -160,68 +158,6 @@ public class Mapping implements Cloneable, ActionDisplayable { getActions().forEach(action -> action.clearFeedback()); } - private static final String NAME = "name"; - private static final String UUID_NAME = "uuid"; - private static final String ACTION = "Action"; - private static final String ACTION_TYPE = "type"; - private static final String MAPPER = "Mapper"; - private static final String MAPPER_TYPE = "type"; - - public void load(Element element, Profile profile) { - name = element.attributeValue(NAME); - if (element.attributeValue(UUID_NAME) != null) - uuid = UUID.fromString(element.attributeValue(UUID_NAME)); - else - uuid = UUID.randomUUID(); - - for (Object obj : element.elements(ACTION)) { - if (obj instanceof Element) { - Element actionElement = (Element) obj; - String tpye = actionElement.attributeValue(ACTION_TYPE); - - Action action = ActionRegistery.getActionConnect(tpye).newInstance(); - action.load(actionElement); - - boolean added = addActionIfNotContains(action); - - if (added) { - for (Object mapperObj : actionElement.elements(MAPPER)) { - if (mapperObj instanceof Element) { - Element mapperElement = (Element) mapperObj; - String mapperType = mapperElement.attributeValue(MAPPER_TYPE); - - Mapper mapper = MapperRegistry.getMapperConnect(mapperType).createNewMapper(); - mapper.load(mapperElement, action); - action.addMapper(mapper); - } - } - } - } - } - - initActionType(profile); // Update Actions, damit alle da sind und keine fehlt (falls eine gelöscht wurde auf der Datei) - updateDisplayProperty(); - } - - public void save(Element element) { - element.addAttribute(NAME, name); - element.addAttribute(UUID_NAME, uuid.toString()); - - for (Action action : mapping.keySet()) { - Element actionElement = element.addElement(ACTION); - actionElement.addAttribute(ACTION_TYPE, action.getType()); - - action.save(actionElement); - - for (Mapper mapper : mapping.get(action)) { - Element mapperElement = actionElement.addElement(MAPPER); - mapperElement.addAttribute(MAPPER_TYPE, mapper.getType()); - - mapper.save(mapperElement, action); - } - } - } - @Override public Mapping clone() throws CloneNotSupportedException { Mapping clone = (Mapping) super.clone(); @@ -256,7 +192,7 @@ public class Mapping implements Cloneable, ActionDisplayable { return displayProperty; } - private void updateDisplayProperty() { + void updateDisplayProperty() { displayProperty.set(toString()); } } diff --git a/PlayWallCore/src/de/tobias/playpad/action/MappingList.java b/PlayWallCore/src/de/tobias/playpad/action/MappingList.java index 05517382dc227e540d93b8e2211a2b19c7ab0ba9..542f990dd43b94f82651f87c102881f3ff40cd0c 100644 --- a/PlayWallCore/src/de/tobias/playpad/action/MappingList.java +++ b/PlayWallCore/src/de/tobias/playpad/action/MappingList.java @@ -5,6 +5,7 @@ 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.UUID; import org.dom4j.Document; @@ -16,6 +17,7 @@ import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.xml.XMLHandler; public class MappingList extends ArrayList<Mapping> { @@ -62,16 +64,16 @@ public class MappingList extends ArrayList<Mapping> { mappings.activeMapping = UUID.fromString(rootElement.attributeValue(ACTIVE_ATTR)); } - for (Object mappingObj : rootElement.elements(MAPPING)) { - if (mappingObj instanceof Element) { - Element mappingElement = (Element) mappingObj; - - Mapping mapping = new Mapping(false, profile); - mapping.load(mappingElement, profile); - - mappings.add(mapping); - } - } + // Load Mappings + XMLHandler<Mapping> handler = new XMLHandler<>(rootElement); + List<Mapping> loadMappings = handler.loadElements(MAPPING, new MappingSerializer(profile)); + loadMappings.forEach(mapping -> + { + mapping.initActionType(profile); // Update Actions, damit alle da sind und keine fehlt (falls eine + // gelöscht wurde auf der Datei) + mapping.updateDisplayProperty(); + mappings.add(mapping); + }); } // Init mappings, if non exists @@ -89,14 +91,9 @@ public class MappingList extends ArrayList<Mapping> { if (activeMapping != null) rootElement.addAttribute(ACTIVE_ATTR, activeMapping.toString()); - for (Mapping mapping : this) { - Element mappingElement = rootElement.addElement(MAPPING); - mapping.save(mappingElement); - } - - XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); + XMLHandler<Mapping> handler = new XMLHandler<>(rootElement); + handler.saveElements(MAPPING, this, new MappingSerializer()); + XMLHandler.save(path, document); } public static Mapping importMappingPreset(Path path, Profile profile) throws DocumentException, IOException { @@ -106,7 +103,8 @@ public class MappingList extends ArrayList<Mapping> { Document document = reader.read(Files.newInputStream(path)); Element rootElement = document.getRootElement(); - mapping.load(rootElement, profile); + MappingSerializer mappingSerializer = new MappingSerializer(profile); + mapping = mappingSerializer.loadElement(rootElement); mapping.setUuid(UUID.randomUUID()); return mapping; @@ -115,7 +113,9 @@ public class MappingList extends ArrayList<Mapping> { public static void exportMidiPreset(Path path, Mapping preset) throws IOException { Document docoment = DocumentHelper.createDocument(); Element rootElement = docoment.addElement(MAPPING); - preset.save(rootElement); + + MappingSerializer mappingSerializer = new MappingSerializer(); + mappingSerializer.saveElement(rootElement, preset); XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); writer.write(docoment); diff --git a/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..e1885680e2aed52d687d4cb6d4cdf0fb52a18382 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java @@ -0,0 +1,55 @@ +package de.tobias.playpad.action; + +import java.util.UUID; + +import org.dom4j.Element; + +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.xml.XMLDeserializer; +import de.tobias.playpad.xml.XMLHandler; +import de.tobias.playpad.xml.XMLSerializer; + +public class MappingSerializer implements XMLSerializer<Mapping>, XMLDeserializer<Mapping> { + + private static final String NAME = "name"; + private static final String UUID_NAME = "uuid"; + private static final String ACTION = "Action"; + + private Profile profile; + + public MappingSerializer() { + + } + + public MappingSerializer(Profile profile) { + this.profile = profile; + } + + @Override + public Mapping loadElement(Element element) { + Mapping mapping = new Mapping(false, profile); + + mapping.setName(element.attributeValue(NAME)); + + UUID uuid; + if (element.attributeValue(UUID_NAME) != null) + uuid = UUID.fromString(element.attributeValue(UUID_NAME)); + else + uuid = UUID.randomUUID(); + mapping.setUuid(uuid); + + XMLHandler<Action> handler = new XMLHandler<>(element); + handler.loadElements(ACTION, new ActionSerializer(mapping)); + + return mapping; + } + + @Override + public void saveElement(Element newElement, Mapping data) { + newElement.addAttribute(NAME, data.getName()); + newElement.addAttribute(UUID_NAME, data.getUuid().toString()); + + XMLHandler<Action> handler = new XMLHandler<>(newElement); + handler.saveElements(ACTION, data.getActions(), new ActionSerializer(data)); + } +} diff --git a/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java b/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java index 851d42c6e2ec04a1d056b6b28d3bdd9607e6dab1..9f9fabc5ddee03ced42dca9441a1e62c451fd8f9 100644 --- a/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java +++ b/PlayWallCore/src/de/tobias/playpad/layout/CartLayout.java @@ -2,8 +2,8 @@ package de.tobias.playpad.layout; import org.dom4j.Element; -import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.view.IPadViewController; +import de.tobias.playpad.settings.Warning; public interface CartLayout { @@ -25,11 +25,11 @@ public interface CartLayout { * @param controller * @param warning */ - public abstract void handleWarning(IPadViewController controller, Warning warning); + public abstract void handleWarning(IPadViewController controller, Warning warning, GlobalLayout animate); public default void stopWarning(IPadViewController controller) {} public void reset(); - + public void copyGlobalLayout(GlobalLayout globalLayout); } diff --git a/PlayWallCore/src/de/tobias/playpad/layout/GlobalLayout.java b/PlayWallCore/src/de/tobias/playpad/layout/GlobalLayout.java index 8622bca5cdd319fd08d446261301b58052d5b4aa..e7b95f72544c09c02a9168923ffc74bdacdffb0a 100644 --- a/PlayWallCore/src/de/tobias/playpad/layout/GlobalLayout.java +++ b/PlayWallCore/src/de/tobias/playpad/layout/GlobalLayout.java @@ -14,9 +14,9 @@ import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; -import de.tobias.playpad.pad.Warning; import de.tobias.playpad.pad.view.IPadViewController; import de.tobias.playpad.project.Project; +import de.tobias.playpad.settings.Warning; import de.tobias.playpad.viewcontroller.main.IMainViewController; import javafx.stage.Stage; diff --git a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java index 71dbdce75429f5ed3679a906edc08ba57b5a5856..ae4adf2d2df16e8188455b46ec81dc8f01df1aa1 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java @@ -3,23 +3,20 @@ package de.tobias.playpad.pad; import java.nio.file.Path; import java.util.HashMap; -import org.dom4j.Element; - import de.tobias.playpad.layout.CartLayout; import de.tobias.playpad.layout.LayoutRegistry; import de.tobias.playpad.pad.conntent.PadContent; -import de.tobias.playpad.pad.conntent.PadContentRegistry; import de.tobias.playpad.pad.conntent.Pauseable; -import de.tobias.playpad.pad.conntent.UnkownPadContentException; import de.tobias.playpad.pad.triggerlistener.PadTriggerContentListener; import de.tobias.playpad.pad.triggerlistener.PadTriggerDurationListener; import de.tobias.playpad.pad.triggerlistener.PadTriggerStatusListener; import de.tobias.playpad.pad.view.IPadViewController; import de.tobias.playpad.project.Project; +import de.tobias.playpad.settings.Fade; import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.Warning; import de.tobias.playpad.tigger.Trigger; import de.tobias.playpad.tigger.TriggerPoint; -import de.tobias.utils.settings.UserDefaults; import javafx.beans.binding.BooleanBinding; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; @@ -73,9 +70,8 @@ public class Pad { private transient IPadViewController controller; private transient Project project; - public Pad(Project project, Element element) { + public Pad(Project project) { this.project = project; - load(element); initPadListener(); // Update Trigger ist nicht notwendig, da es in load(Element) ausgerufen wird @@ -373,7 +369,7 @@ public class Pad { this.ignoreTrigger = ignoreTrigger; } - private void updateTrigger() { + void updateTrigger() { for (TriggerPoint point : TriggerPoint.values()) { if (!triggers.containsKey(point)) { Trigger trigger = new Trigger(point); @@ -418,163 +414,6 @@ public class Pad { } } - // Storage - private static final String INDEX_ATTR = "index"; - private static final String NAME_ATTR = "name"; - private static final String STATUS_ATTR = "status"; - - private static final String SETTINGS_ELEMENT = "Settings"; - private static final String VOLUME_ELEMENT = "Volume"; - private static final String LOOP_ELEMENT = "Loop"; - private static final String TIMEMODE_ELEMENT = "TimeMode"; - private static final String FADE_ELEMENT = "Fade"; - private static final String WARNING_ELEMENT = "Warning"; - - private static final String LAYOUTS_ELEMENT = "Layouts"; - private static final String LAYOUT_ACTIVE_ATTR = "active"; - private static final String LAYOUT_TYPE_ATTR = "type"; - private static final String LAYOUT_ELEMENT = "Layout"; - - private static final String CUSTOM_SETTINGS_ITEM_ELEMENT = "Item"; - private static final String CUSTOM_SETTINGS_TYPE_ATTR = "key"; - private static final String CUSTOM_SETTINGS_ELEMENT = "CustomSettings"; - - public static final String CONTENT_ELEMENT = "Content"; - private static final String CONTENT_TYPE_ATTR = "type"; - - public void load(Element element) { - indexProperty.set(Integer.valueOf(element.attributeValue(INDEX_ATTR))); - nameProperty.set(element.attributeValue(NAME_ATTR)); - PadStatus status = PadStatus.valueOf(element.attributeValue(STATUS_ATTR)); - if (status == PadStatus.EMPTY || status == PadStatus.READY) - statusProperty.set(status); - - // Settings - Element settingsElement = element.element(SETTINGS_ELEMENT); - 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.load(settingsElement.element(WARNING_ELEMENT))); - - // Laoyut - Element layoutsElement = settingsElement.element(LAYOUTS_ELEMENT); - if (layoutsElement != null) { - if (layoutsElement.attributeValue(LAYOUT_ACTIVE_ATTR) != null) { - customLayoutProperty.set(Boolean.valueOf(layoutsElement.attributeValue(LAYOUT_ACTIVE_ATTR))); - } - - for (Object layoutObj : layoutsElement.elements(LAYOUT_ELEMENT)) { - if (layoutObj instanceof Element) { - Element layoutElement = (Element) layoutObj; - String type = layoutElement.attributeValue(LAYOUT_TYPE_ATTR); - CartLayout layout = LayoutRegistry.getLayout(type).newCartLayout(); - layout.load(layoutElement); - - layouts.put(type, layout); - } - } - } - - Element userInfoElement = settingsElement.element(CUSTOM_SETTINGS_ELEMENT); - if (userInfoElement != null) { - for (Object object : userInfoElement.elements()) { - if (object instanceof Element) { - Element item = (Element) object; - String key = item.attributeValue(CUSTOM_SETTINGS_TYPE_ATTR); - Object data = UserDefaults.loadElement(item); - customSettings.put(key, data); - } - } - } - - // Trigger - Element triggersElement = element.element("Triggers"); // TODO Externalize - if (triggersElement != null) { - for (Object triggerObj : triggersElement.elements("Trigger")) { - if (triggerObj instanceof Element) { - Element triggerElement = (Element) triggerObj; - Trigger trigger = new Trigger(); - trigger.load(triggerElement); - triggers.put(trigger.getTriggerPoint(), trigger); - } - } - } - updateTrigger(); // Damit alle Points da sind - - // Content - Element contentElement = element.element(CONTENT_ELEMENT); - if (contentElement != null) { - String contentType = contentElement.attributeValue(CONTENT_TYPE_ATTR); - try { - PadContent content = PadContentRegistry.getPadContentConnect(contentType).newInstance(this); - content.load(contentElement); - setContent(content); - } catch (UnkownPadContentException e) { - e.printStackTrace(); - throwException(null, e); - } - } - } - - public void save(Element element) { - element.addAttribute(INDEX_ATTR, String.valueOf(indexProperty.get())); - element.addAttribute(NAME_ATTR, nameProperty.get()); - 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); - settingsElement.addElement(VOLUME_ELEMENT).addText(String.valueOf(volumeProperty.get())); - settingsElement.addElement(LOOP_ELEMENT).addText(String.valueOf(loopProperty.get())); - if (timeModeProperty.isNotNull().get()) - settingsElement.addElement(TIMEMODE_ELEMENT).addText(String.valueOf(timeModeProperty.get())); - if (warningProperty.isNotNull().get()) - warningProperty.get().save(settingsElement.addElement(WARNING_ELEMENT)); - if (fadeProperty.isNotNull().get()) - fadeProperty.get().save(settingsElement.addElement(FADE_ELEMENT)); - - // Layout - Element layoutsElement = settingsElement.addElement(LAYOUTS_ELEMENT); - layoutsElement.addAttribute(LAYOUT_ACTIVE_ATTR, String.valueOf(customLayoutProperty.get())); - for (String layoutType : layouts.keySet()) { - Element layoutElement = layoutsElement.addElement(LAYOUT_ELEMENT); - layoutElement.addAttribute(LAYOUT_TYPE_ATTR, layoutType); - - CartLayout cartLayout = layouts.get(layoutType); - cartLayout.save(layoutElement); - } - - Element userInfoElement = settingsElement.addElement(CUSTOM_SETTINGS_ELEMENT); - for (String key : customSettings.keySet()) { - Element itemElement = userInfoElement.addElement(CUSTOM_SETTINGS_ITEM_ELEMENT); - UserDefaults.save(itemElement, customSettings.get(key), key); - } - - // Trigger - Element triggersElement = element.addElement("Triggers"); - for (TriggerPoint point : triggers.keySet()) { - Trigger trigger = triggers.get(point); - Element triggerElement = triggersElement.addElement("Trigger"); - trigger.save(triggerElement); - } - - // Content - if (contentProperty.get() != null) { - Element contentElement = element.addElement(CONTENT_ELEMENT); - contentElement.addAttribute(CONTENT_TYPE_ATTR, contentProperty.get().getType()); - contentProperty.get().save(contentElement); - } - } - @Override public String toString() { return "Pad: " + indexProperty.get() + " - " + nameProperty.get(); @@ -596,4 +435,8 @@ public class Pad { public DoubleProperty customVolumeProperty() { return customVolumeProperty; } + + HashMap<String, CartLayout> getLayouts() { + return layouts; + } } diff --git a/PlayWallCore/src/de/tobias/playpad/pad/PadSerializer.java b/PlayWallCore/src/de/tobias/playpad/pad/PadSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..298456087dcecb18d89aa53c655a4472979a247d --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/pad/PadSerializer.java @@ -0,0 +1,191 @@ +package de.tobias.playpad.pad; + +import org.dom4j.Element; + +import de.tobias.playpad.layout.CartLayout; +import de.tobias.playpad.layout.LayoutRegistry; +import de.tobias.playpad.pad.conntent.PadContent; +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.Fade; +import de.tobias.playpad.settings.Warning; +import de.tobias.playpad.tigger.Trigger; +import de.tobias.playpad.tigger.TriggerPoint; +import de.tobias.playpad.xml.XMLDeserializer; +import de.tobias.playpad.xml.XMLSerializer; +import de.tobias.utils.settings.UserDefaults; + +public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> { + + private static final String INDEX_ATTR = "index"; + private static final String NAME_ATTR = "name"; + private static final String STATUS_ATTR = "status"; + + private static final String SETTINGS_ELEMENT = "Settings"; + private static final String VOLUME_ELEMENT = "Volume"; + private static final String LOOP_ELEMENT = "Loop"; + private static final String TIMEMODE_ELEMENT = "TimeMode"; + private static final String FADE_ELEMENT = "Fade"; + private static final String WARNING_ELEMENT = "Warning"; + + private static final String LAYOUTS_ELEMENT = "Layouts"; + private static final String LAYOUT_ACTIVE_ATTR = "active"; + private static final String LAYOUT_TYPE_ATTR = "type"; + private static final String LAYOUT_ELEMENT = "Layout"; + + private static final String CUSTOM_SETTINGS_ITEM_ELEMENT = "Item"; + private static final String CUSTOM_SETTINGS_TYPE_ATTR = "key"; + private static final String CUSTOM_SETTINGS_ELEMENT = "CustomSettings"; + + public static final String CONTENT_ELEMENT = "Content"; + private static final String CONTENT_TYPE_ATTR = "type"; + + // TODO Remove project var + private Project project; + + public PadSerializer(Project project) { + this.project = project; + } + + public PadSerializer() {} + + @Override + public Pad loadElement(Element element) { + Pad pad = new Pad(project); + + pad.setIndex(Integer.valueOf(element.attributeValue(INDEX_ATTR))); + pad.setName(element.attributeValue(NAME_ATTR)); + PadStatus status = PadStatus.valueOf(element.attributeValue(STATUS_ATTR)); + if (status == PadStatus.EMPTY || status == PadStatus.READY) + pad.setStatus(status); + + // Settings + Element settingsElement = element.element(SETTINGS_ELEMENT); + if (settingsElement.element(VOLUME_ELEMENT) != null) + pad.setVolume(Double.valueOf(settingsElement.element(VOLUME_ELEMENT).getStringValue())); + if (settingsElement.element(LOOP_ELEMENT) != null) + pad.setLoop(Boolean.valueOf(settingsElement.element(LOOP_ELEMENT).getStringValue())); + if (settingsElement.element(TIMEMODE_ELEMENT) != null) + pad.setTimeMode(TimeMode.valueOf(settingsElement.element(TIMEMODE_ELEMENT).getStringValue())); + if (settingsElement.element(FADE_ELEMENT) != null) + pad.setFade(Fade.load(settingsElement.element(FADE_ELEMENT))); + if (settingsElement.element(WARNING_ELEMENT) != null) + pad.setWarning(Warning.load(settingsElement.element(WARNING_ELEMENT))); + + // Laoyut + Element layoutsElement = settingsElement.element(LAYOUTS_ELEMENT); + if (layoutsElement != null) { + if (layoutsElement.attributeValue(LAYOUT_ACTIVE_ATTR) != null) { + pad.setCustomLayout(Boolean.valueOf(layoutsElement.attributeValue(LAYOUT_ACTIVE_ATTR))); + } + + for (Object layoutObj : layoutsElement.elements(LAYOUT_ELEMENT)) { + if (layoutObj instanceof Element) { + Element layoutElement = (Element) layoutObj; + String type = layoutElement.attributeValue(LAYOUT_TYPE_ATTR); + CartLayout layout = LayoutRegistry.getLayout(type).newCartLayout(); + layout.load(layoutElement); + + pad.setLayout(layout, type); + } + } + } + + Element userInfoElement = settingsElement.element(CUSTOM_SETTINGS_ELEMENT); + if (userInfoElement != null) { + for (Object object : userInfoElement.elements()) { + if (object instanceof Element) { + Element item = (Element) object; + String key = item.attributeValue(CUSTOM_SETTINGS_TYPE_ATTR); + Object data = UserDefaults.loadElement(item); + pad.getCustomSettings().put(key, data); + } + } + } + + // Trigger + Element triggersElement = element.element("Triggers"); // TODO Externalize + if (triggersElement != null) { + for (Object triggerObj : triggersElement.elements("Trigger")) { + if (triggerObj instanceof Element) { + Element triggerElement = (Element) triggerObj; + Trigger trigger = new Trigger(); + trigger.load(triggerElement); + pad.getTriggers().put(trigger.getTriggerPoint(), trigger); + } + } + } + pad.updateTrigger(); // Damit alle Points da sind + + // Content + Element contentElement = element.element(CONTENT_ELEMENT); + if (contentElement != null) { + String contentType = contentElement.attributeValue(CONTENT_TYPE_ATTR); + try { + PadContent content = PadContentRegistry.getPadContentConnect(contentType).newInstance(pad); + content.load(contentElement); + pad.setContent(content); + } catch (UnkownPadContentException e) { + e.printStackTrace(); + pad.throwException(null, e); + } + } + + return pad; + } + + @Override + public void saveElement(Element element, Pad data) { + element.addAttribute(INDEX_ATTR, String.valueOf(data.getIndex())); + element.addAttribute(NAME_ATTR, data.getName()); + if (data.getStatus() == PadStatus.EMPTY || data.getStatus() == PadStatus.ERROR) { + element.addAttribute(STATUS_ATTR, PadStatus.EMPTY.name()); + } else { + element.addAttribute(STATUS_ATTR, PadStatus.READY.name()); + } + + // Settings + Element settingsElement = element.addElement(SETTINGS_ELEMENT); + settingsElement.addElement(VOLUME_ELEMENT).addText(String.valueOf(data.getVolume())); + settingsElement.addElement(LOOP_ELEMENT).addText(String.valueOf(data.isLoop())); + if (data.getTimeMode() != null) + settingsElement.addElement(TIMEMODE_ELEMENT).addText(String.valueOf(data.getTimeMode())); + if (data.isCustomWarning() != false) + data.getWarning().save(settingsElement.addElement(WARNING_ELEMENT)); + if (data.getFade() != null) + data.getFade().save(settingsElement.addElement(FADE_ELEMENT)); + + // Layout + Element layoutsElement = settingsElement.addElement(LAYOUTS_ELEMENT); + layoutsElement.addAttribute(LAYOUT_ACTIVE_ATTR, String.valueOf(data.isCustomLayout())); + for (String layoutType : data.getLayouts().keySet()) { + Element layoutElement = layoutsElement.addElement(LAYOUT_ELEMENT); + layoutElement.addAttribute(LAYOUT_TYPE_ATTR, layoutType); + + CartLayout cartLayout = data.getLayouts().get(layoutType); + cartLayout.save(layoutElement); + } + + Element userInfoElement = settingsElement.addElement(CUSTOM_SETTINGS_ELEMENT); + for (String key : data.getCustomSettings().keySet()) { + Element itemElement = userInfoElement.addElement(CUSTOM_SETTINGS_ITEM_ELEMENT); + UserDefaults.save(itemElement, data.getCustomSettings().get(key), key); + } + + // Trigger + Element triggersElement = element.addElement("Triggers"); + for (TriggerPoint point : data.getTriggers().keySet()) { + Trigger trigger = data.getTriggers().get(point); + Element triggerElement = triggersElement.addElement("Trigger"); + trigger.save(triggerElement); + } + + // Content + if (data.getContent() != null) { + Element contentElement = element.addElement(CONTENT_ELEMENT); + contentElement.addAttribute(CONTENT_TYPE_ATTR, data.getContent().getType()); + data.getContent().save(contentElement); + } + } +} diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/PadListener.java b/PlayWallCore/src/de/tobias/playpad/plugin/PadListener.java index 0d6349a2196269b18434cb77256ea9c3cf82c94e..26ba636bfc86ef54d0eea5717acb960b7e7c9733 100644 --- a/PlayWallCore/src/de/tobias/playpad/plugin/PadListener.java +++ b/PlayWallCore/src/de/tobias/playpad/plugin/PadListener.java @@ -2,10 +2,30 @@ package de.tobias.playpad.plugin; import de.tobias.playpad.pad.Pad; +/** + * Listener für ein Pad. + * + * @author tobias + * + * @see Pad + * + */ public interface PadListener { - public default void onPlay(Pad pad) {} + /** + * Wird aufgerufen, sobald ein Pad wiedergegeben wird. + * + * @param pad + * Pad + */ + public void onPlay(Pad pad); - public default void onStop(Pad pad) {} + /** + * Wird aufgerufen, sobald ein Pad gestoppt wird. + * + * @param pad + * Pad + */ + public void onStop(Pad pad); } \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java b/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java index 4d7684d0f8d15f3497114df28761e1561795ca64..fcbe98abe97596e8ecc83b62c0eefa2ebb30d9a6 100644 --- a/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java +++ b/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java @@ -1,36 +1,26 @@ package de.tobias.playpad.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; + private String version; + private long build; - static { - plugins = new ArrayList<>(); - } + private boolean active; + private List<String> dependencies; - public Plugin(String name, String fileName, String url, boolean active, List<String> dependencies) { + public Plugin(String name, String fileName, String url, String version, long build, boolean active, + List<String> dependencies) { this.name = name; this.fileName = fileName; this.url = url; + this.version = version; + this.build = build; this.active = active; this.dependencies = dependencies; } @@ -78,32 +68,8 @@ public class Plugin implements Comparable<Plugin> { 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; + @Override + public String toString() { + return name + " " + version + " (" + build + ")"; } } diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/Plugins.java b/PlayWallCore/src/de/tobias/playpad/plugin/Plugins.java new file mode 100644 index 0000000000000000000000000000000000000000..9cb3749a8f036e5f01a3cecb88c3a1e3eb5e577b --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/plugin/Plugins.java @@ -0,0 +1,57 @@ +package de.tobias.playpad.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 Plugins { + + private static List<Plugin> plugins; + + static { + plugins = new ArrayList<>(); + } + + public static List<Plugin> load(String pluginInfoURL, boolean fetch) throws IOException { + if (plugins.isEmpty() || fetch) { + 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"); + String version = cfg.getString("plugins." + key + ".version"); + long build = cfg.getLong("plugins." + key + ".build"); + + 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, version, build, active, dependencies); + plugins.add(plugin); + } + } + return plugins; + } + + public static List<Plugin> getPlugins() { + return plugins; + } +} diff --git a/PlayWallCore/src/de/tobias/playpad/project/Importable.java b/PlayWallCore/src/de/tobias/playpad/project/Importable.java index 0193b48f4fed7a801e8b6c791213e98c41fbc907..1b3e860e99d59b2f5a84abbb7f9d5bfdb6b4d5e1 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/Importable.java +++ b/PlayWallCore/src/de/tobias/playpad/project/Importable.java @@ -2,11 +2,37 @@ package de.tobias.playpad.project; import java.nio.file.Path; +/** + * Delegate Methode vom Model zum Import eines Projektes (mit Profile und Medien optionmal) + * + * @author tobias + * + * @since 5.0.0 + */ public interface Importable { + /** + * Wenn ein Profil bereits vorhanden ist, wird hier nach einem neuen Namen gefragt. + * + * @param name + * Alter name + * @return Neuer Name oder null (dann wird nichts importiert) + */ public String replaceProfile(String name); + /** + * Wenn ein Projekt bereits vorhanden ist, wird hier nach einem neuen Namen gefragt. + * + * @param name + * Alter name + * @return Neuer Name oder null (dann wird nichts importiert) + */ public String replaceProject(String name); + /** + * Frage nach dem Ordner für die Mediendateien. + * + * @return Ordner zum Import. + */ public Path mediaFolder(); } \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProfileChooseable.java b/PlayWallCore/src/de/tobias/playpad/project/ProfileChooseable.java index 36d4062ce19de24bb6c68650d25f2ca34bf3a7e8..11b53720e3d2b07284cc7c6ad77b8e208abd8b01 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/ProfileChooseable.java +++ b/PlayWallCore/src/de/tobias/playpad/project/ProfileChooseable.java @@ -2,7 +2,19 @@ package de.tobias.playpad.project; import de.tobias.playpad.settings.Profile; +/** + * Dieses Interface stellt Methoden für die Wahl des Profiles für ein Projekt bereit. + * + * @author tobias + * + * @since 5.0.0 + */ public interface ProfileChooseable { + /** + * Wird von der API beim Projekt laden aufgerunfen, wenn das referenzierte Projekt nicht gefunden wurde. + * + * @return Neues Profile + */ public Profile getUnkownProfile(); } \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/project/Project.java b/PlayWallCore/src/de/tobias/playpad/project/Project.java index d0d6e24a10a778d9c999657e78e32a456667c6a3..f166c6d300916a1308b6a757d67879d4f6284d77 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/Project.java +++ b/PlayWallCore/src/de/tobias/playpad/project/Project.java @@ -5,70 +5,125 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.Iterator; +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.pad.PadException; +import de.tobias.playpad.pad.PadSerializer; import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.settings.Profile; import de.tobias.playpad.settings.ProfileNotFoundException; -import de.tobias.utils.application.ApplicationUtils; -import de.tobias.utils.application.container.PathType; +import de.tobias.playpad.xml.XMLHandler; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +/** + * Hold all information about the pads and it's settings. + * + * @author tobias + * + */ public class Project { - public static final String projectNameEx = "\\w{1}[\\w\\s-_]{0,}"; + /** + * Pattern für den Namen des Projekts + */ + public static final String PROJECT_NAME_PATTERN = "\\w{1}[\\w\\s-_]{0,}"; + /** + * Dateiendung für eine projekt Datei + */ public static final String FILE_EXTENSION = ".xml"; + /** + * Die projektreferenz gibt auskunft über den Namen und die UUID des Projektes + */ private ProjectReference ref; + /** + * Liste mit allen Pads. + */ private HashMap<Integer, Pad> pads; + /** + * Liste mit den aktuellen Laufzeitfehlern. + */ private ObservableList<PadException> exceptions; + /** + * Erstellt ein neues leeres Projekt mit einer Referenz. + * + * @param ref + * Referenz mit Namen des Projekts. + */ public Project(ProjectReference ref) { this.ref = ref; this.pads = new HashMap<>(); this.exceptions = FXCollections.observableArrayList(); } + /** + * Gibt die Projekt Referenz zurück. Dazu zählen Name und UUID sowie das zugehörige Profile. + * + * @return Referenz. + */ public ProjectReference getRef() { return ref; } + // TODO Update in 5.1.0 + /** + * Gibt ein Pad an einem Index zurück. Sollte kein pad vorhanden sein (weil null, so wird vorher ein neues erzeugt.) + * + * @param index + * Index + * @return Pad am Index i + */ public Pad getPad(int index) { - if (pads.containsKey(index)) { - return pads.get(index); - } else { - pads.put(index, new Pad(this, index)); // Create Pad if not exists - return pads.get(index); + if (!pads.containsKey(index)) { + addPadForIndex(index); } + return pads.get(index); + } + + /** + * Erstellt ein neues leeres Pad (mit Referenz zu diesem Projekt) am Index i. + * + * @param index + * Index i + */ + private void addPadForIndex(int index) { + pads.put(index, new Pad(this, index)); } + /** + * Ersetz ein Pad an einem Index i. + * + * @param index + * Index i + * @param pad + * Neues Pad für den Index i + */ public void setPad(int index, Pad pad) { pad.setIndex(index); pads.put(index, pad); } + /* + * Speichern und Laden + */ + private static final String ROOT_ELEMENT = "Project"; - static final String PAD_ELEMENT = "Pad"; + protected static final String PAD_ELEMENT = "Pad"; public static Project load(ProjectReference ref, boolean loadMedia, ProfileChooseable profileChooseable) throws DocumentException, IOException, ProfileNotFoundException, ProjectNotFoundException { + Path projectPath = ref.getProjectPath(); - Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); if (Files.exists(projectPath)) { - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(projectPath)); - if (ref.getProfileReference() != null) { Profile.load(ref.getProfileReference()); // Lädt das entsprechende Profile und aktiviert es } else { @@ -78,22 +133,13 @@ public class Project { Project project = new Project(ref); - Element rootElement = document.getRootElement(); - - for (Object padObj : rootElement.elements(PAD_ELEMENT)) { - if (padObj instanceof Element) { - Element padElement = (Element) padObj; + XMLHandler<Pad> handler = new XMLHandler<>(projectPath); + List<Pad> pads = handler.loadElements(PAD_ELEMENT, new PadSerializer(project)); - // Load Pad Settings - Pad pad = new Pad(project, padElement); - - // Load Media - if (loadMedia) { - pad.loadContent(); - } - - project.pads.put(pad.getIndex(), pad); - } + for (Pad pad : pads) { + if (loadMedia) + pad.loadContent(); + project.pads.put(pad.getIndex(), pad); } return project; @@ -103,25 +149,19 @@ public class Project { } public void save() throws IOException { - Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); + Path projectPath = ref.getProjectPath(); Document document = DocumentHelper.createDocument(); Element rootElement = document.addElement(ROOT_ELEMENT); - for (int index : pads.keySet()) { - Pad pad = pads.get(index); - Element padElement = rootElement.addElement(PAD_ELEMENT); - pad.save(padElement); - } + XMLHandler<Pad> handler = new XMLHandler<>(rootElement); + handler.saveElements(PAD_ELEMENT, pads.values(), new PadSerializer()); if (Files.notExists(projectPath)) { Files.createDirectories(projectPath.getParent()); Files.createFile(projectPath); } - - XMLWriter writer = new XMLWriter(Files.newOutputStream(projectPath), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); + XMLHandler.save(projectPath, document); } public HashMap<Integer, Pad> getPads() { @@ -138,6 +178,10 @@ public class Project { return count; } + public boolean hasPlayedPlayers() { + return getPlayedPlayers() > 0; + } + // Exceptions public void addException(Pad pad, Path path, Exception exception) { if (!Platform.isFxApplicationThread()) { diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java index 01267080ca680f5b267373814cb8bf08cf02ebbf..756c508a2f5e922ea8609f02905b295ce50d2456 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java +++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java @@ -15,6 +15,7 @@ import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadSerializer; import de.tobias.playpad.settings.ProfileReference; import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; @@ -115,9 +116,11 @@ public class ProjectExporter { 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 + PadSerializer serializer = new PadSerializer(); + Pad pad = serializer.loadElement(padElement); + if (pad.getContent() != null) { - pad.getContent().exportMedia(zip, padElement.element(Pad.CONTENT_ELEMENT)); + pad.getContent().exportMedia(zip, padElement.element(PadSerializer.CONTENT_ELEMENT)); } } diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java index d7c075fcec6fbde1c463e28b655b5c03f975a8f9..57ebef70dc69976a9c3c1c20afd0c11549659e30 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java +++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java @@ -15,6 +15,7 @@ import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadSerializer; import de.tobias.playpad.settings.Profile; import de.tobias.playpad.settings.ProfileReference; import de.tobias.utils.application.App; @@ -161,9 +162,11 @@ public class ProjectImporter { 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 + PadSerializer serializer = new PadSerializer(); + Pad pad = serializer.loadElement(padElement); + if (pad.getContent() != null) { - pad.getContent().importMedia(destination, zip, padElement.element(Pad.CONTENT_ELEMENT)); + pad.getContent().importMedia(destination, zip, padElement.element(PadSerializer.CONTENT_ELEMENT)); } } } diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectReference.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectReference.java index aabe28711f4c3f573085e4d6697c7d6807498668..44724c67c6a3815083e9c4eac9bb2b697f63acf9 100644 --- a/PlayWallCore/src/de/tobias/playpad/project/ProjectReference.java +++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectReference.java @@ -13,12 +13,11 @@ 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.Displayable; import de.tobias.playpad.settings.ProfileReference; +import de.tobias.playpad.xml.XMLHandler; +import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; import javafx.beans.property.SimpleStringProperty; @@ -26,31 +25,7 @@ import javafx.beans.property.StringProperty; public class ProjectReference implements Displayable { - private static List<ProjectReference> projects = new ArrayList<ProjectReference>() { - - private static final long serialVersionUID = 1L; - - public boolean contains(Object o) { - if (o instanceof String) { - for (ProjectReference reference : this) { - if (reference.getName().equals(o)) { - return true; - } else if (reference.toString().equals(o)) { - return true; - } - } - } else if (o instanceof ProjectReference) { - for (ProjectReference reference : this) { - if (reference.getName() == o) { - return true; - } else if (reference.getName() == ((ProjectReference) o).getName()) { - return true; - } - } - } - return super.contains(o); - }; - }; + private static List<ProjectReference> projects = new ProjectReferenceList(); private static boolean loadedProjectOverview = false; /** @@ -143,14 +118,18 @@ public class ProjectReference implements Displayable { ProjectReference newProjectReference = new ProjectReference(UUID.randomUUID(), name, currentProject.getProfileReference()); 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); + duplicateFiles(currentProject, newProjectReference); saveProjects(); return newProjectReference; } + private static void duplicateFiles(ProjectReference currentProject, ProjectReference newProjectReference) throws IOException { + 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); + } + public static List<ProjectReference> getProjects() { if (!loadedProjectOverview) try { @@ -161,59 +140,33 @@ public class ProjectReference implements Displayable { return projects; } - private static final String UUID_ATTR = "uuid"; - private static final String NAME_ATTR = "name"; - private static final String PROFILE_ATTR = "profile"; + // Load and Save + private static final String FILE_NAME = "Projects.xml"; + private static final String PROJECT_ELEMENT = "Project"; + private static final String ROOT_ELEMENT = "Settings"; public static void loadProjects() throws DocumentException, IOException { - projects.clear(); - - Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "Projects.xml"); - + Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, FILE_NAME); if (Files.exists(path)) { - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(path)); - Element root = document.getRootElement(); - - for (Object object : root.elements("Project")) { - Element element = (Element) object; - - UUID uuid = UUID.fromString(element.attributeValue(UUID_ATTR)); - String name = element.attributeValue(NAME_ATTR); - UUID profile = UUID.fromString(element.attributeValue(PROFILE_ATTR)); - - ProfileReference profileRef = ProfileReference.getReference(profile); - ProjectReference ref = new ProjectReference(uuid, name, profileRef); - - Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); - if (Files.exists(projectPath)) { - ref.setLastMofied(Files.getLastModifiedTime(projectPath).toMillis()); - ref.setSize(Files.size(projectPath)); - } - - projects.add(ref); - } - - loadedProjectOverview = true; + XMLHandler<ProjectReference> loader = new XMLHandler<>(path); + projects = loader.loadElements(PROJECT_ELEMENT, new ProjectReferenceSerializer()); } + loadedProjectOverview = true; } public static void saveProjects() throws UnsupportedEncodingException, IOException { Document document = DocumentHelper.createDocument(); - Element root = document.addElement("Settings"); + Element root = document.addElement(ROOT_ELEMENT); - for (ProjectReference project : projects) { - Element projectElement = root.addElement("Project"); - projectElement.addAttribute(UUID_ATTR, project.uuid.toString()); - projectElement.addAttribute(NAME_ATTR, project.name); - projectElement.addAttribute(PROFILE_ATTR, project.profileReference.getUuid().toString()); - } - - Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "Projects.xml"); + XMLHandler<ProjectReference> handler = new XMLHandler<>(root); + handler.saveElements(PROJECT_ELEMENT, projects, new ProjectReferenceSerializer()); - XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); + Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, FILE_NAME); + if (Files.notExists(path)) { + Files.createDirectories(path.getParent()); + Files.createFile(path); + } + XMLHandler.save(path, document); } public static List<ProjectReference> getProjectsSorted() { @@ -237,6 +190,12 @@ public class ProjectReference implements Displayable { return uuid + Project.FILE_EXTENSION; } + public Path getProjectPath() { + App application = ApplicationUtils.getApplication(); + Path projectPath = application.getPath(PathType.DOCUMENTS, getFileName()); + return projectPath; + } + public static ProjectReference getProject(UUID project) { for (ProjectReference ref : projects) { if (ref.uuid.equals(project)) { diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceList.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceList.java new file mode 100644 index 0000000000000000000000000000000000000000..a9d7ea8412887f1f5173b1a3416018271e59a29b --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceList.java @@ -0,0 +1,37 @@ +package de.tobias.playpad.project; + +import de.tobias.utils.list.UniqList; + +/** + * Liste, wo nur ProjektRefernzen gespeichert werden, deren Namen Unique ist. + * + * @author tobias + * + * @since 5.0.1 + * @see ProjectReference + */ +final class ProjectReferenceList extends UniqList<ProjectReference> { + + private static final long serialVersionUID = 1L; + + public boolean contains(Object o) { + if (o instanceof String) { + for (ProjectReference reference : this) { + if (reference.getName().equals(o)) { + return true; + } else if (reference.toString().equals(o)) { + return true; + } + } + } else if (o instanceof ProjectReference) { + for (ProjectReference reference : this) { + if (reference.getName() == o) { + return true; + } else if (reference.getName().equals(((ProjectReference) o).getName())) { // TODO Check + return true; + } + } + } + return super.contains(o); + } +} \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceSerializer.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..009b68e7171f8ed1ef6bdd1442070abf48a6fe3f --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceSerializer.java @@ -0,0 +1,49 @@ +package de.tobias.playpad.project; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; + +import org.dom4j.Element; + +import de.tobias.playpad.settings.ProfileReference; +import de.tobias.playpad.xml.XMLDeserializer; +import de.tobias.playpad.xml.XMLSerializer; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; + +public class ProjectReferenceSerializer implements XMLDeserializer<ProjectReference>, XMLSerializer<ProjectReference> { + + private static final String UUID_ATTR = "uuid"; + private static final String NAME_ATTR = "name"; + private static final String PROFILE_ATTR = "profile"; + + @Override + public ProjectReference loadElement(Element element) { + UUID uuid = UUID.fromString(element.attributeValue(UUID_ATTR)); + String name = element.attributeValue(NAME_ATTR); + UUID profile = UUID.fromString(element.attributeValue(PROFILE_ATTR)); + + ProfileReference profileRef = ProfileReference.getReference(profile); + ProjectReference ref = new ProjectReference(uuid, name, profileRef); + + Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName()); + if (Files.exists(projectPath)) { + try { + ref.setLastMofied(Files.getLastModifiedTime(projectPath).toMillis()); + ref.setSize(Files.size(projectPath)); + } catch (IOException e) { + e.printStackTrace(); + } + } + return ref; + } + + @Override + public void saveElement(Element newElement, ProjectReference data) { + newElement.addAttribute(UUID_ATTR, data.getUuid().toString()); + newElement.addAttribute(NAME_ATTR, data.getName()); + newElement.addAttribute(PROFILE_ATTR, data.getProfileReference().getUuid().toString()); + } +} diff --git a/PlayWallCore/src/de/tobias/playpad/pad/Fade.java b/PlayWallCore/src/de/tobias/playpad/settings/Fade.java similarity index 98% rename from PlayWallCore/src/de/tobias/playpad/pad/Fade.java rename to PlayWallCore/src/de/tobias/playpad/settings/Fade.java index 09e47651733eafbee7c39a7639d089c25a38efe5..73d9ba15ff65457e984f61d95bb43b9981af6b97 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/Fade.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/Fade.java @@ -1,4 +1,4 @@ -package de.tobias.playpad.pad; +package de.tobias.playpad.settings; import org.dom4j.Element; diff --git a/PlayWallCore/src/de/tobias/playpad/settings/Profile.java b/PlayWallCore/src/de/tobias/playpad/settings/Profile.java index db0b7ea64dccd1216bba78ddf58a5c80854589f1..7e55988c26d8adbfa59e1b5494c3766d760595dd 100644 --- a/PlayWallCore/src/de/tobias/playpad/settings/Profile.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/Profile.java @@ -20,6 +20,10 @@ import de.tobias.utils.application.container.PathType; public class Profile { + private static final String PROFILE_SETTINGS_XML = "ProfileSettings.xml"; + private static final String MAPPING_XML = "Mapping.xml"; + private static final String LAYOUT_XML = "Layout.xml"; + public static final String profileNameEx = "\\w{1}[\\w\\s-_]{0,}"; private static List<ProfileListener> listeners = new ArrayList<>(); @@ -97,10 +101,9 @@ public class Profile { if (Files.exists(app.getPath(PathType.CONFIGURATION, ref.getFileName()))) { - ProfileSettings profileSettings = ProfileSettings - .load(app.getPath(PathType.CONFIGURATION, ref.getFileName(), "ProfileSettings.xml")); + ProfileSettings profileSettings = ProfileSettings.load(app.getPath(PathType.CONFIGURATION, ref.getFileName(), PROFILE_SETTINGS_XML)); HashMap<String, GlobalLayout> layouts = GlobalLayout - .loadGlobalLayout(app.getPath(PathType.CONFIGURATION, ref.getFileName(), "Layout.xml")); + .loadGlobalLayout(app.getPath(PathType.CONFIGURATION, ref.getFileName(), LAYOUT_XML)); profile.profileSettings = profileSettings; profile.layouts = layouts; @@ -116,7 +119,7 @@ public class Profile { }); // Mapping erst danach, weil das auf current Profile zugreifen muss - MappingList mappings = MappingList.load(app.getPath(PathType.CONFIGURATION, ref.getFileName(), "Mapping.xml"), profile); + MappingList mappings = MappingList.load(app.getPath(PathType.CONFIGURATION, ref.getFileName(), MAPPING_XML), profile); profile.mappings = mappings; setCurrentProfile(profile); @@ -141,9 +144,14 @@ public class Profile { if (Files.notExists(root)) Files.createDirectories(root); - profileSettings.save(app.getPath(PathType.CONFIGURATION, ref.getFileName(), "ProfileSettings.xml")); - mappings.save(app.getPath(PathType.CONFIGURATION, ref.getFileName(), "Mapping.xml")); - GlobalLayout.saveGlobal(layouts, app.getPath(PathType.CONFIGURATION, ref.getFileName(), "Layout.xml")); + profileSettings.save(getProfilePath(PROFILE_SETTINGS_XML)); + mappings.save(getProfilePath(MAPPING_XML)); + GlobalLayout.saveGlobal(layouts, getProfilePath(LAYOUT_XML)); + } + + private Path getProfilePath(String fileName) { + App app = ApplicationUtils.getApplication(); + return app.getPath(PathType.CONFIGURATION, ref.getFileName(), fileName); } @Override diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java index 103c9f9b0eda1250c26bd0818f074559424159e1..ba3a13d08fed86e8553a404235e11a69e8c57d3b 100644 --- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java @@ -9,79 +9,102 @@ import java.util.List; import java.util.UUID; 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.Displayable; +import de.tobias.playpad.xml.XMLHandler; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; -import de.tobias.utils.list.UniqList; import de.tobias.utils.util.FileUtils; -import de.tobias.utils.util.FileUtils.FileAction; +import de.tobias.utils.util.FileUtils.FileActionAdapter; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; +/** + * Container für Profile Referenzen + * + * @author tobias + * + * @see Profile + * @since 5.0.0 + */ public class ProfileReference implements Displayable { private static final String DEFAULT_PROFILE_NAME = "Default"; - private static List<ProfileReference> profiles = new UniqList<ProfileReference>() { - - private static final long serialVersionUID = 1L; - - public boolean contains(Object o) { - if (o instanceof String) { - for (ProfileReference reference : this) { - if (reference.getName().equals(o)) { - return true; - } else if (reference.toString().equals(o)) { - return true; - } - } - } else if (o instanceof ProfileReference) { - for (ProfileReference reference : this) { - if (reference.getName() == o) { - return true; - } else if (reference.getName() == ((ProfileReference) o).getName()) { - return true; - } - } - } - return super.contains(o); - }; - }; - private final UUID uuid; private String name; + /** + * Erstellt eine neue Referenz mit einer Random UUID. + * + * @param name + * Name + */ public ProfileReference(String name) { this.name = name; this.uuid = UUID.randomUUID(); updateDisplayProperty(); } + /** + * Erstellt eine neue Referenz mit Namen und UUID. + * + * @param uuid + * UUID + * @param name + * Name + */ public ProfileReference(UUID uuid, String name) { this.uuid = uuid; this.name = name; updateDisplayProperty(); } + /** + * Gibt den Namen zurück + * + * @return Name + */ public String getName() { return name; } + /** + * Gibt die UUID zurück + * + * @return uudi + */ public UUID getUuid() { return uuid; } + /** + * Setzt einen neuen Namen. + * + * @param name + * Neuer Name + */ public void setName(String name) { this.name = name; updateDisplayProperty(); } + // Verwaltungsmethoden für Profile Referenzen // TODO Extract in Extra Class + + /** + * Liste mit allen Referenzen + */ + private static List<ProfileReference> profiles = new ProfileReferenceList(); + + /** + * Sucht eine Referenz zu einer UUID raus. + * + * @param profile + * @return + */ public static ProfileReference getReference(UUID profile) { for (ProfileReference ref : profiles) { if (ref.uuid.equals(profile)) { @@ -91,6 +114,11 @@ public class ProfileReference implements Displayable { return null; } + /** + * Listet alle verfügbaren Profil Refernzen auf. + * + * @return Liste von Referenzen (Name, UUID) + */ public static List<ProfileReference> getProfiles() { return profiles; } @@ -103,6 +131,7 @@ public class ProfileReference implements Displayable { * @return * @throws UnsupportedEncodingException * @throws IOException + * IO Fehler */ public static Profile newProfile(String name) throws UnsupportedEncodingException, IOException { ProfileReference ref = new ProfileReference(UUID.randomUUID(), name); @@ -114,9 +143,17 @@ public class ProfileReference implements Displayable { return profile; } + /** + * Fügt ein Profile hinzu und erstellt den Ordner auf der Festplatte. + * + * @param ref + * Referenz zu diesem Profile (Name, UUID) + */ public static void addProfile(ProfileReference ref) { + // MODEL profiles.add(ref); + // DRIVE Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, ref.getFileName()); if (Files.notExists(path)) { try { @@ -128,19 +165,19 @@ public class ProfileReference implements Displayable { } /** - * Duplicate one profile on drive. To use the new profile, it must be load manually. - * + * Dupliziert eine Profile. Dabei werden die Dateien auf der Festplatte auch dupliziert. * * @param src - * Name of the original Profile + * Name des Orginalprofiles * @param des - * Name of the new Profile + * Name des neuen Profiles * @throws IOException + * IO Fehler */ public static void duplicate(ProfileReference src, ProfileReference des) throws IOException { if (!des.equals(src)) { FileUtils.loopThroughDirectory(ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, src.getFileName()), - new FileAction() { + new FileActionAdapter() { @Override public void onFile(Path file) throws IOException { @@ -151,18 +188,25 @@ public class ProfileReference implements Displayable { } Files.copy(file, desPath, StandardCopyOption.REPLACE_EXISTING); } - - @Override - public void onDirectory(Path file) throws IOException {} }); profiles.add(des); } } + /** + * Entfernt eine ProfileReferenz und das Profile. + * + * @param ref + * Profile Referenz + * @throws IOException + * IO Fehler + */ public static void removeProfile(ProfileReference ref) throws IOException { + // Model profiles.remove(ref); + // DRIVE Path root = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, ref.getFileName()); if (Files.exists(root)) { Files.walk(root).forEach(path -> @@ -178,58 +222,78 @@ public class ProfileReference implements Displayable { } } + // Load and Save + + private static final String FILE_NAME = "Profiles.xml"; private static final String ROOT_ELEMENT = "Settings"; private static final String PROFILE_ELEMENT = "Profile"; - private static final String UUID_ATTR = "uuid"; - private static final String NAME_ATTR = "name"; - public static void loadProfiles() throws Exception { + /** + * Lädt alle Profile Referenzen. + * + * @throws IOException + * IO Fehler + * @throws DocumentException + * XML Fehler + */ + public static void loadProfiles() throws IOException, DocumentException { profiles.clear(); - Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "Profiles.xml"); + Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, FILE_NAME); if (Files.exists(path)) { - SAXReader reader = new SAXReader(); - Document document = reader.read(Files.newInputStream(path)); - Element root = document.getRootElement(); - for (Object object : root.elements(PROFILE_ELEMENT)) { - Element element = (Element) object; - - UUID uuid = UUID.fromString(element.attributeValue(UUID_ATTR)); - String name = element.attributeValue(NAME_ATTR); - - ProfileReference ref = new ProfileReference(uuid, name); - profiles.add(ref); - } + // Load data from xml + XMLHandler<ProfileReference> handler = new XMLHandler<>(path); + profiles = handler.loadElements(PROFILE_ELEMENT, new ProfileReferenceSerializer()); + System.out.println(profiles); } + // Add Default Element if list is empty if (profiles.isEmpty()) { Profile profile = newProfile(DEFAULT_PROFILE_NAME); profile.save(); } } + /** + * Speichert alle Profile Referenzen in eine Datei. + * + * @throws UnsupportedEncodingException + * XML Fehler + * @throws IOException + * IO Fehler + */ public static void saveProfiles() throws UnsupportedEncodingException, IOException { Document document = DocumentHelper.createDocument(); Element root = document.addElement(ROOT_ELEMENT); - for (ProfileReference ref : profiles) { - Element element = root.addElement(PROFILE_ELEMENT); + // Save data to xml + XMLHandler<ProfileReference> handler = new XMLHandler<>(root); + handler.saveElements(PROFILE_ELEMENT, profiles, new ProfileReferenceSerializer()); - element.addAttribute(UUID_ATTR, ref.uuid.toString()); - element.addAttribute(NAME_ATTR, ref.name); + Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, FILE_NAME); + if (Files.notExists(path)) { + Files.createDirectories(path.getParent()); + Files.createFile(path); } - - Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "Profiles.xml"); - XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); - writer.write(document); - writer.close(); + XMLHandler.save(path, document); } + /** + * Gibt einen Pfad für einen Dateinamen in diesem Profile zurück. + * + * @param name + * @return + */ public Path getCustomFilePath(String name) { return ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, getFileName(), name); } + /** + * Gibt den internen (File-) Namen des Profiles zurück. + * + * @return Ordnernamen + */ public String getFileName() { return uuid.toString(); } @@ -239,6 +303,7 @@ public class ProfileReference implements Displayable { return name; } + // Displayable private StringProperty displayProperty = new SimpleStringProperty(toString()); @Override diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceList.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceList.java new file mode 100644 index 0000000000000000000000000000000000000000..01bf7b7d7a68a3253c946e964ebfa14800796f31 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceList.java @@ -0,0 +1,37 @@ +package de.tobias.playpad.settings; + +import de.tobias.utils.list.UniqList; + +/** + * Liste, wo nur ProfileRefernzen gespeichert werden, deren Namen Unique ist. + * + * @author tobias + * + * @since 5.0.1 + * @see ProfileReference + */ +final class ProfileReferenceList extends UniqList<ProfileReference> { + + private static final long serialVersionUID = 1L; + + public boolean contains(Object o) { + if (o instanceof String) { + for (ProfileReference reference : this) { + if (reference.getName().equals(o)) { + return true; + } else if (reference.toString().equals(o)) { + return true; + } + } + } else if (o instanceof ProfileReference) { + for (ProfileReference reference : this) { + if (reference.getName() == o) { + return true; + } else if (reference.getName() == ((ProfileReference) o).getName()) { + return true; + } + } + } + return super.contains(o); + } +} \ No newline at end of file diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceSerializer.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..3a281ef16c223a94c255b4d18591bcaf7423c2bd --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceSerializer.java @@ -0,0 +1,38 @@ +package de.tobias.playpad.settings; + +import java.util.UUID; + +import org.dom4j.Element; + +import de.tobias.playpad.xml.XMLDeserializer; +import de.tobias.playpad.xml.XMLSerializer; + +/** + * Util zum arbeiten mit XML und ProfileReference + * + * @author tobias + * + * @since 5.0.1 + * @see ProfileReference + */ +public class ProfileReferenceSerializer implements XMLSerializer<ProfileReference>, XMLDeserializer<ProfileReference> { + + private static final String UUID_ATTR = "uuid"; + private static final String NAME_ATTR = "name"; + + @Override + public ProfileReference loadElement(Element element) { + UUID uuid = UUID.fromString(element.attributeValue(UUID_ATTR)); + String name = element.attributeValue(NAME_ATTR); + + ProfileReference ref = new ProfileReference(uuid, name); + return ref; + } + + @Override + public void saveElement(Element newElement, ProfileReference data) { + newElement.addAttribute(UUID_ATTR, data.getUuid().toString()); + newElement.addAttribute(NAME_ATTR, data.getName()); + } + +} diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java index 3cf852a167e03b5c83f619f2c63583c4fe51e0eb..9189fb33224213e3ba3a70be6b65029f6aa29baf 100644 --- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java @@ -17,9 +17,8 @@ import org.dom4j.io.XMLWriter; import de.tobias.playpad.audio.AudioRegistry; import de.tobias.playpad.layout.LayoutRegistry; -import de.tobias.playpad.pad.Fade; import de.tobias.playpad.pad.TimeMode; -import de.tobias.playpad.pad.Warning; +import de.tobias.playpad.update.UpdateChannel; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; import de.tobias.utils.settings.SettingsSerializable; @@ -73,8 +72,9 @@ public class ProfileSettings implements SettingsSerializable { // Folder @Storable private Path cachePath = ApplicationUtils.getApplication().getPath(PathType.CACHE); - // Update + // Update - TODO GlobalSettings @Storable private boolean autoUpdate = true; + @Storable private UpdateChannel updateChannel = UpdateChannel.STABLE; public boolean isLocked() { return lockedProperty.get(); @@ -179,6 +179,10 @@ public class ProfileSettings implements SettingsSerializable { return autoUpdate; } + public UpdateChannel getUpdateChannel() { + return updateChannel; + } + // Setter public void setMidiDeviceName(String midiDevice) { this.midiDevice = midiDevice; @@ -258,6 +262,10 @@ public class ProfileSettings implements SettingsSerializable { this.autoUpdate = autoUpdate; } + public void setUpdateChannel(UpdateChannel updateChannel) { + this.updateChannel = updateChannel; + } + // Properties public DoubleProperty volumeProperty() { return volumeProperty; @@ -266,6 +274,7 @@ public class ProfileSettings implements SettingsSerializable { 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 UPDATE_CHANNEL_ELEMENT = "UpdateChannel"; private static final String CACHE_PATH_ELEMENT = "Cache-Path"; private static final String VOLUME_ELEMENT = "Volume"; private static final String KEY_ATTRIBUTE = "key"; @@ -378,6 +387,10 @@ public class ProfileSettings implements SettingsSerializable { if (root.element(AUTO_UPDATE_ELEMENT) != null) { profileSettings.setAutoUpdate(Boolean.valueOf(root.element(AUTO_UPDATE_ELEMENT).getStringValue())); } + + if (root.element(UPDATE_CHANNEL_ELEMENT) != null) { + profileSettings.setUpdateChannel(UpdateChannel.valueOf(root.element(UPDATE_CHANNEL_ELEMENT).getStringValue())); + } } return profileSettings; } @@ -410,7 +423,7 @@ public class ProfileSettings implements SettingsSerializable { 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)); // Audio @@ -424,7 +437,10 @@ public class ProfileSettings implements SettingsSerializable { // Paths root.addElement(CACHE_PATH_ELEMENT).addText(cachePath.toString()); + + // Update root.addElement(AUTO_UPDATE_ELEMENT).addText(String.valueOf(autoUpdate)); + root.addElement(UPDATE_CHANNEL_ELEMENT).addText(updateChannel.name()); XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); writer.write(document); diff --git a/PlayWallCore/src/de/tobias/playpad/pad/Warning.java b/PlayWallCore/src/de/tobias/playpad/settings/Warning.java similarity index 96% rename from PlayWallCore/src/de/tobias/playpad/pad/Warning.java rename to PlayWallCore/src/de/tobias/playpad/settings/Warning.java index 11cef9723bf8cc315d29160979934c37f1e8043d..56de8f3d2bdbb892aff6966cd72384500d339cb5 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/Warning.java +++ b/PlayWallCore/src/de/tobias/playpad/settings/Warning.java @@ -1,4 +1,4 @@ -package de.tobias.playpad.pad; +package de.tobias.playpad.settings; import org.dom4j.Element; diff --git a/PlayWallCore/src/de/tobias/playpad/Updatable.java b/PlayWallCore/src/de/tobias/playpad/update/Updatable.java similarity index 56% rename from PlayWallCore/src/de/tobias/playpad/Updatable.java rename to PlayWallCore/src/de/tobias/playpad/update/Updatable.java index 8ae1166bbd82243e86f5db429da899cbea1e722b..88c493aec8cd4b9741f2e46dadfb71df421aec90 100644 --- a/PlayWallCore/src/de/tobias/playpad/Updatable.java +++ b/PlayWallCore/src/de/tobias/playpad/update/Updatable.java @@ -1,5 +1,7 @@ -package de.tobias.playpad; +package de.tobias.playpad.update; +import java.io.IOException; +import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; @@ -13,7 +15,9 @@ public interface Updatable { public String getNewVersion(); - public boolean checkUpdate(); + public boolean isUpdateAvailable(); + + public void loadInformation(UpdateChannel channel) throws IOException, URISyntaxException; public URL getDownloadPath(); diff --git a/PlayWallCore/src/de/tobias/playpad/update/UpdateChannel.java b/PlayWallCore/src/de/tobias/playpad/update/UpdateChannel.java new file mode 100644 index 0000000000000000000000000000000000000000..ca0367b83d6e1209be9076f625caafde2e759364 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/update/UpdateChannel.java @@ -0,0 +1,18 @@ +package de.tobias.playpad.update; + +public enum UpdateChannel { + + STABLE("stable"), + BETA("beta"); + + private String name; + + private UpdateChannel(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/PlayWallCore/src/de/tobias/playpad/UpdateRegistery.java b/PlayWallCore/src/de/tobias/playpad/update/UpdateRegistery.java similarity index 67% rename from PlayWallCore/src/de/tobias/playpad/UpdateRegistery.java rename to PlayWallCore/src/de/tobias/playpad/update/UpdateRegistery.java index 2ce10162e60434ca84d3b2fa6e355e5cfeb8341a..9b2274c4c31ced8afdd4342024a88c6ea83d5083 100644 --- a/PlayWallCore/src/de/tobias/playpad/UpdateRegistery.java +++ b/PlayWallCore/src/de/tobias/playpad/update/UpdateRegistery.java @@ -1,9 +1,12 @@ -package de.tobias.playpad; +package de.tobias.playpad.update; +import java.io.IOException; import java.net.URISyntaxException; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; +import de.tobias.utils.util.OS; import de.tobias.utils.util.SystemUtils; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; @@ -22,11 +25,16 @@ public class UpdateRegistery { return availableUpdates; } - public static List<Updatable> lookupUpdates() { + public static List<Updatable> lookupUpdates(UpdateChannel channel) { availableUpdates.clear(); for (Updatable updatable : UpdateRegistery.updatables) { - if (updatable.checkUpdate()) { - availableUpdates.add(updatable); + try { + updatable.loadInformation(channel); + if (updatable.isUpdateAvailable()) { + availableUpdates.add(updatable); + } + } catch (IOException | URISyntaxException e) { + } } return availableUpdates; @@ -59,4 +67,20 @@ public class UpdateRegistery { String json = data.toJSONString(JSONStyle.MAX_COMPRESS); return json; } + + public static boolean needsAdminPermission() { + for (Updatable updatable : availableUpdates) { + if (!Files.isWritable(updatable.getLocalPath())) { + return true; + } + if (OS.isWindows()) { + try { + if (Files.getOwner(updatable.getLocalPath()).getName().toLowerCase().contains("admin")) { + return true; + } + } catch (IOException e) {} + } + } + return false; + } } diff --git a/PlayWallCore/src/de/tobias/playpad/viewcontroller/ISettingsViewController.java b/PlayWallCore/src/de/tobias/playpad/viewcontroller/ISettingsViewController.java index 5b7373d51483b85de5fd7341ff83d33ad312bca3..173055b25647b514d39da9f6005ea04a3959a80b 100644 --- a/PlayWallCore/src/de/tobias/playpad/viewcontroller/ISettingsViewController.java +++ b/PlayWallCore/src/de/tobias/playpad/viewcontroller/ISettingsViewController.java @@ -1,7 +1,20 @@ package de.tobias.playpad.viewcontroller; +/** + * Schnittstelle um die ProfileSettingsView zu ändern. + * + * @author tobias + * + * @since 5.0.0 + */ public interface ISettingsViewController { + /** + * Fügt en Tab hinzu. + * + * @param videoSettingsTabViewController + * tab + */ public void addTab(SettingsTabViewController videoSettingsTabViewController); } diff --git a/PlayWallCore/src/de/tobias/playpad/viewcontroller/SettingsTabViewController.java b/PlayWallCore/src/de/tobias/playpad/viewcontroller/SettingsTabViewController.java index 6a64bfc43502ca3065d135f54d4e6eb706730c22..fba59413967875b1b17a348a546158b8016ceda5 100644 --- a/PlayWallCore/src/de/tobias/playpad/viewcontroller/SettingsTabViewController.java +++ b/PlayWallCore/src/de/tobias/playpad/viewcontroller/SettingsTabViewController.java @@ -7,21 +7,77 @@ import de.tobias.playpad.settings.Profile; import de.tobias.playpad.viewcontroller.main.IMainViewController; import de.tobias.utils.ui.ContentViewController; +/** + * Abstract Tab für SettingsViewController. + * + * @author tobias + * + * @since 5.0.0 + * + */ public abstract class SettingsTabViewController extends ContentViewController { + /** + * Erstellt einen neuen Tab. + * + * @param name + * Name der FXML + * @param path + * Pfad zu FXML (ohne Dateiname) + * @param localization + * ResourceBundle oder null + */ public SettingsTabViewController(String name, String path, ResourceBundle localization) { super(name, path, localization); } + /** + * Lädt alle Einstellungen vom Model in die GUI. + * + * @param profile + * Aktuelles Profile + */ public abstract void loadSettings(Profile profile); + /** + * Speichert alle Änderungen in das Model. + * + * @param profile + * Aktuelles Profile + */ public abstract void saveSettings(Profile profile); + /** + * Gibt <code>true</code> zurück, wenn im Hauptprogramm etwas neu geladen werden muss. Der eigentliche Reload wird in + * {@link #reload(Profile, Project, IMainViewController)} ausgeführt. + * + * @return <code>true</code> Benötigt Reload + */ public abstract boolean needReload(); + /** + * Lädt gestimmte Einstellungen für die GUI neu. + * + * @param profile + * Aktuelles Profile + * @param project + * Aktuelles Projekt + * @param controller + * Main View Controller + */ public void reload(Profile profile, Project project, IMainViewController controller) {} + /** + * Prüft ob die eingetragen Einstellungen erlaubt sind. Bei falschen Eingaben können die Einstellungen nicht geschlossen werden. + * + * @return <code>true</code> Einstellungen erlaubt. <code>false</code> Einstellungen fehlerhaft. + */ public abstract boolean validSettings(); + /** + * Gibt den Namen für den Tab zurück. + * + * @return + */ public abstract String name(); } diff --git a/PlayWallCore/src/de/tobias/playpad/xml/XMLDeserializer.java b/PlayWallCore/src/de/tobias/playpad/xml/XMLDeserializer.java new file mode 100644 index 0000000000000000000000000000000000000000..b458b2bbbbbe92ee5f73321857d5574db09fb816 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/xml/XMLDeserializer.java @@ -0,0 +1,23 @@ +package de.tobias.playpad.xml; + +import org.dom4j.Element; + +/** + * Schnittstelle um ein Object auf einem XML Tree zu deserialisieren. + * + * @author tobias + * + * @param <T> + * Typ der Daten + */ +public interface XMLDeserializer<T> { + + /** + * Lädt ein Object auf XML Daten. + * + * @param element + * @return + */ + public T loadElement(Element element); + +} diff --git a/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java b/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..0ba39178b14a48772acb9a7abde893467bd36055 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java @@ -0,0 +1,120 @@ +package de.tobias.playpad.xml; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +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; + +/** + * Util Methods zum Laden von XML Files. + * + * @author tobias + * + * @since 5.0.1 + */ +public class XMLHandler<T> { + + private Element rootElement; + + /** + * Lädt ein XML Dokument und speichert sich den RootNode. + * + * @param path + * Path zu XML Datei + * @throws DocumentException + * Fehler in der XML Datei + * @throws IOException + * IO Fehler (Bsp. Datei nicht vorhanden) + */ + public XMLHandler(Path path) throws DocumentException, IOException { + if (Files.exists(path)) { + SAXReader reader = new SAXReader(); + Document document = reader.read(Files.newInputStream(path)); + rootElement = document.getRootElement(); + } else { + throw new FileNotFoundException(path.toString()); + } + } + + /** + * Erstellt einen neuen Handler mit einem RootElement. + * + * @param rootElement + * RootElement + */ + public XMLHandler(Element rootElement) { + this.rootElement = rootElement; + } + + /** + * Lädt ein Datenrecord auf einem Array von Daten + * + * @param listElementTag + * Datentype + * @param deserializer + * Deserializer + * @return Liste von Daten + */ + public List<T> loadElements(String listElementTag, XMLDeserializer<T> deserializer) { + List<T> list = new ArrayList<>(); + + for (Object object : rootElement.elements(listElementTag)) { + if (object instanceof Element) { + Element element = (Element) object; + T data = deserializer.loadElement(element); + list.add(data); + } + } + + return list; + } + + /** + * Speichert eine Liste von Objekten mittels Serializer. + * + * @param listElementTag + * Name der XML Element + * @param list + * Liste der Daten + * @param serializer + * Serializer + */ + public void saveElements(String listElementTag, Iterable<T> list, XMLSerializer<T> serializer) { + for (T data : list) { + Element element = rootElement.addElement(listElementTag); + serializer.saveElement(element, data); + } + } + + /** + * Speichert eine XML in einem Path. + * + * @param path + * Path der Datei + * @param document + * XML Document + * @throws UnsupportedEncodingException + * Falsches Encoding + * @throws IOException + * IO Fehler (Bsp. File nicht vorhanden) + */ + public static void save(Path path, Document document) throws UnsupportedEncodingException, IOException { + if (Files.exists(path)) { + XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); + writer.write(document); + writer.close(); + } else { + throw new FileNotFoundException(path.toString()); + } + } +} diff --git a/PlayWallCore/src/de/tobias/playpad/xml/XMLSerializer.java b/PlayWallCore/src/de/tobias/playpad/xml/XMLSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..824741866bf6a72c89126febc81415cecb63869a --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/xml/XMLSerializer.java @@ -0,0 +1,26 @@ +package de.tobias.playpad.xml; + +import org.dom4j.Element; + +/** + * Schnittstelle um ein Object in eine XML Struktur zu überführen. + * + * @author tobias + * + * @param <T> + * Typ der Daten + */ +public interface XMLSerializer<T> { + + /** + * Überführt ein Object in eine XML Struktur. Dafür wird bereits ein XML Object angelegt, zu dem Attribute und Sub Elemente hinzugefügt + * werden können. + * + * @param newElement + * XML Object + * @param data + * Daten + */ + public void saveElement(Element newElement, T data); + +} diff --git a/PlayWallPlugins/.classpath b/PlayWallPlugins/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..dff7fdd8d23f0ac9b407b77addb5d79e1997cc9f --- /dev/null +++ b/PlayWallPlugins/.classpath @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry excluding="de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadSOld.java|de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2Old.java|de/tobias/playpad/launchpadplugin/midi/device/s/MultipleFeedbackSViewController.java|de/tobias/playpad/launchpadplugin/midi/device/s/SimpleFeedbackSViewController.java|de/tobias/playpad/launchpadplugin/midi/device/mk2/MultipleFeedbackMK2ViewController.java|de/tobias/playpad/launchpadplugin/midi/device/mk2/SimpleFeedbackMK2ViewController.java|de/tobias/playpad/launchpadplugin/impl/FeedbackMessageTypeCell.java|de/tobias/playpad/launchpadplugin/midi/device/mk2/WarningFeedbackViewControllerMK2.java|de/tobias/playpad/launchpadplugin/midi/device/s/WarningFeedbackViewControllerS.java" kind="src" path="launchpadplugin"/> + <classpathentry kind="src" path="awakeplugin"/> + <classpathentry excluding="de/tobias/playpad/midiactions/muteaction/MuteActionSettingsViewController.java|de/tobias/playpad/midiactions/muteaction/MuteActionType.java|de/tobias/playpad/midiactions/muteaction/MuteEvent.java|de/tobias/playpad/midiactions/muteaction/MuteListener.java" kind="src" path="actionsplugin"/> + <classpathentry kind="src" path="mediaplugin"/> + <classpathentry kind="src" path="equalizerplugin"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Plugins"/> + <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/XML"/> + <classpathentry combineaccessrules="false" kind="src" path="/libUtils"/> + <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ControlFx"/> + <classpathentry combineaccessrules="false" kind="src" path="/PlayWallCore"/> + <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/YML"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/PlayWallPlugins/.gitignore b/PlayWallPlugins/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..65776c32fc48190de1439385c361505b36591c1c --- /dev/null +++ b/PlayWallPlugins/.gitignore @@ -0,0 +1 @@ +/bin/ \ No newline at end of file diff --git a/PlayWallPlugins/.project b/PlayWallPlugins/.project new file mode 100644 index 0000000000000000000000000000000000000000..e6c6a8fdfb3cb5e2db27ac851af8b452264268b5 --- /dev/null +++ b/PlayWallPlugins/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>PlayWallPlugins</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/PlayWallPlugins/.settings/org.eclipse.jdt.core.prefs b/PlayWallPlugins/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..3a21537071bf4118b9e1ee864cb4bc258aa48211 --- /dev/null +++ b/PlayWallPlugins/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/ActionsPlugin.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/ActionsPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..13aec012801daff5a9206c7ec8ed05d980b0e042 --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/ActionsPlugin.java @@ -0,0 +1,7 @@ +package de.tobias.playpad.actionsplugin; + +import net.xeoh.plugins.base.Plugin; + +public interface ActionsPlugin extends Plugin { + +} diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/assets/actions_de.properties b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/assets/actions_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..6659bdcf4fa25d66e2b12da2973d3ee84aade5d4 --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/assets/actions_de.properties @@ -0,0 +1,2 @@ +muteaction.name=Ton stumm schalten +stopaction.name=Stopp \ No newline at end of file diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginImpl.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e2eada8fc11a706ef0200fd4f5224cf366bca4fd --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginImpl.java @@ -0,0 +1,156 @@ +package de.tobias.playpad.actionsplugin.impl; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.action.ActionRegistery; +import de.tobias.playpad.actionsplugin.ActionsPlugin; +import de.tobias.playpad.actionsplugin.muteaction.MuteActionConnect; +import de.tobias.playpad.actionsplugin.stopaction.StopActionConnect; +import de.tobias.playpad.plugin.WindowListener; +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.ProfileListener; +import de.tobias.playpad.update.UpdateRegistery; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import de.tobias.utils.ui.HUD; +import de.tobias.utils.ui.icon.FontIcon; +import de.tobias.utils.ui.icon.MaterialDesignIcon; +import de.tobias.utils.util.Localization; +import javafx.application.Platform; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.geometry.Pos; +import javafx.scene.control.CheckMenuItem; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import net.xeoh.plugins.base.annotations.PluginImplementation; +import net.xeoh.plugins.base.annotations.events.PluginLoaded; +import net.xeoh.plugins.base.annotations.events.Shutdown; + +@PluginImplementation +public class ActionsPluginImpl implements ActionsPlugin, ChangeListener<Boolean>, ProfileListener { + + private static ResourceBundle bundle; + public static CheckMenuItem muteMenuItem; + + private static BooleanProperty muteProperty; + private static ChangeListener<Number> volumeListener; + + private HUD muteHUD; + + @PluginLoaded + public void onEnable(ActionsPlugin plugin) { + muteProperty = new SimpleBooleanProperty(); + try { + bundle = Localization.loadBundle("de/tobias/playpad/actionsplugin/assets/actions", ActionsPluginImpl.class.getClassLoader()); + } catch (MissingResourceException e) { + System.err.println("Cannot find resource for actions plugin: " + e.getLocalizedMessage()); + } + + if (muteHUD == null) { + Platform.runLater(() -> + { + FontIcon icon = new FontIcon(MaterialDesignIcon.FONT_FILE, MaterialDesignIcon.VOLUME_OFF); + icon.setSize(60); + icon.getStyleClass().remove(FontIcon.STYLE_CLASS); + icon.setColor(Color.WHITE); + icon.setAlignment(Pos.CENTER); + muteHUD = new HUD(icon); + muteHUD.setMinWidth(200); + muteHUD.setMinHeight(100); + }); + + PlayPadPlugin.getImplementation().addMainViewListener(new WindowListener<IMainViewController>() { + + @Override + public void onInit(IMainViewController t) { + t.getVolumeSlider().valueChangingProperty().addListener(new ChangeListener<Boolean>() { + + @Override + public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { + if (newValue && volume == -1 && Profile.currentProfile().getProfileSettings().getVolume() != 0) { + volume = Profile.currentProfile().getProfileSettings().getVolume(); + } else { + volume = -1; + } + } + }); + } + }); + + volumeListener = (a, b, c) -> + { + double newVolume = c.doubleValue(); + double oldVolume = b.doubleValue(); + + if (newVolume != 0 && oldVolume == 0 && muteProperty.get()) { + muteProperty.set(false); + } else if (newVolume == 0 && oldVolume != 0 && !muteProperty.get()) { + muteProperty.set(true); + } + }; + } + + UpdateRegistery.registerUpdateable(new ActionsPluginUpdater()); + Profile.registerListener(this); + + ActionRegistery.registerActionConnect(new MuteActionConnect()); + ActionRegistery.registerActionConnect(new StopActionConnect()); + + muteProperty.addListener(this); + + System.out.println("Enable Action Plugin"); + + } + + @Override + public void reloadSettings(Profile oldProfile, Profile currentProfile) { + if (oldProfile != null) { + oldProfile.getProfileSettings().volumeProperty().removeListener(volumeListener); + } + currentProfile.getProfileSettings().volumeProperty().addListener(volumeListener); + } + + public static BooleanProperty muteProperty() { + return muteProperty; + } + + @Shutdown + public void onDisable() { + System.out.println("Disable Action Plugin"); + } + + public static ResourceBundle getBundle() { + return bundle; + } + + private double volume = -1; + + @Override + public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { + Platform.runLater(() -> + { + if (newValue) { + if (volume == -1) { + volume = Profile.currentProfile().getProfileSettings().getVolume(); + } + Profile.currentProfile().getProfileSettings().setVolume(0); + + Pane root = (Pane) PlayPadPlugin.getImplementation().getMainViewController().getParent(); + if (muteHUD != null) + muteHUD.addToParent(root); + } else { + if (volume == 0) { + volume = 1; + } + Profile.currentProfile().getProfileSettings().setVolume(volume); + + muteHUD.removeFromParent(); + volume = -1; + } + }); + } +} diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginUpdater.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..79d76c4ee3d1b50b7cbe0f9f54bb540ac7e547f5 --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginUpdater.java @@ -0,0 +1,79 @@ +package de.tobias.playpad.actionsplugin.impl; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import de.tobias.playpad.update.Updatable; +import de.tobias.playpad.update.UpdateChannel; +import de.tobias.utils.application.App; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; + +public class ActionsPluginUpdater implements Updatable { + + private int newBuild; + private String newVersion; + private URL remotePath; + + private String localFileName; + private String name; + + @Override + public int getCurrentBuild() { + return 3; + } + + @Override + public String getCurrentVersion() { + return "3.0"; + } + + @Override + public int getNewBuild() { + return newBuild; + } + + @Override + public String getNewVersion() { + return newVersion; + } + + @Override + public void loadInformation(UpdateChannel channel) throws IOException { + App app = ApplicationUtils.getMainApplication(); + URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/plugins.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); + + newBuild = config.getInt("plugins.action.build"); + newVersion = config.getString("plugins.action.version"); + remotePath = new URL(config.getString("plugins.action.url")); + localFileName = config.getString("plugins.action.filename"); + name = config.getString("plugins.action.name"); + + } + + @Override + public boolean isUpdateAvailable() { + return getCurrentBuild() < getNewBuild(); + } + + @Override + public URL getDownloadPath() { + return remotePath; + } + + @Override + public Path getLocalPath() { + return ApplicationUtils.getApplication().getPath(PathType.LIBRARY, localFileName); + } + + @Override + public String name() { + return name; + } + +} diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/muteaction/MuteAction.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/muteaction/MuteAction.java new file mode 100644 index 0000000000000000000000000000000000000000..79108172ab2f6cfc937db836cddbdbf0110be61a --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/muteaction/MuteAction.java @@ -0,0 +1,99 @@ +package de.tobias.playpad.actionsplugin.muteaction; + +import org.dom4j.Element; + +import de.tobias.playpad.Displayable; +import de.tobias.playpad.action.Action; +import de.tobias.playpad.action.InputType; +import de.tobias.playpad.action.feedback.FeedbackMessage; +import de.tobias.playpad.action.feedback.FeedbackType; +import de.tobias.playpad.actionsplugin.impl.ActionsPluginImpl; +import de.tobias.playpad.project.Project; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import de.tobias.utils.ui.icon.FontIcon; +import de.tobias.utils.ui.icon.MaterialDesignIcon; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.beans.value.ChangeListener; +import javafx.scene.Node; +import javafx.scene.control.Label; + +public class MuteAction extends Action implements Displayable { + + private ChangeListener<Boolean> muteListener; + + public MuteAction() { + muteListener = (a, b, c) -> + { + if (c) { + handleFeedback(FeedbackMessage.EVENT); + } else { + handleFeedback(FeedbackMessage.STANDARD); + } + }; + } + + @Override + public void performAction(InputType type, Project project, IMainViewController mainViewController) { + if (type == InputType.PRESSED) { + ActionsPluginImpl.muteProperty().set(!ActionsPluginImpl.muteProperty().get()); + } + } + + @Override + public void clearFeedback() { + ActionsPluginImpl.muteProperty().removeListener(muteListener); + } + + @Override + public void initFeedback(Project project, IMainViewController controller) { + // Listener für Eingaben + BooleanProperty muteProperty = ActionsPluginImpl.muteProperty(); + muteProperty.removeListener(muteListener); + muteProperty.addListener(muteListener); + + // Handle Current Feedback + muteListener.changed(muteProperty, null, muteProperty.getValue()); + } + + @Override + public FeedbackType geFeedbackType() { + return FeedbackType.DOUBLE; + } + + @Override + public String getType() { + return MuteActionConnect.TYPE; + } + + @Override + public void load(Element root) {} + + @Override + public void save(Element root) {} + + @Override + public boolean equals(Object obj) { + if (obj.getClass().equals(getClass())) { + return true; + } + return super.equals(obj); + } + + @Override + public StringProperty displayProperty() { + return new SimpleStringProperty(ActionsPluginImpl.getBundle().getString("muteaction.name")); + } + + @Override + public Node getGraphics() { + return new Label("", new FontIcon(MaterialDesignIcon.FONT_FILE, MaterialDesignIcon.VOLUME_OFF)); + } + + @Override + public Action cloneAction() throws CloneNotSupportedException { + MuteAction actionClone = (MuteAction) super.clone(); + return actionClone; + } +} diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/muteaction/MuteActionConnect.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/muteaction/MuteActionConnect.java new file mode 100644 index 0000000000000000000000000000000000000000..e48dafbea5d7637d2252ee6993b28d2b0d0deebf --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/muteaction/MuteActionConnect.java @@ -0,0 +1,42 @@ +package de.tobias.playpad.actionsplugin.muteaction; + +import java.util.List; + +import de.tobias.playpad.action.Action; +import de.tobias.playpad.action.ActionConnect; +import de.tobias.playpad.action.ActionDisplayable; +import de.tobias.playpad.action.ActionType; +import de.tobias.playpad.action.Mapping; +import de.tobias.playpad.settings.Profile; +import javafx.scene.control.TreeItem; + +public class MuteActionConnect extends ActionConnect { + + public static final String TYPE = "MUTE"; + + @Override + public TreeItem<ActionDisplayable> getTreeViewForActions(List<Action> actions, Mapping mapping) { + TreeItem<ActionDisplayable> item = new TreeItem<>(actions.get(0)); + return item; + } + + @Override + public void initActionType(Mapping mapping, Profile profile) { + mapping.addActionIfNotContains(new MuteAction()); + } + + @Override + public Action newInstance() { + return new MuteAction(); + } + + @Override + public ActionType geActionType() { + return ActionType.SETTINGS; + } + + @Override + public String getType() { + return TYPE; + } +} diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopAction.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopAction.java new file mode 100644 index 0000000000000000000000000000000000000000..b417358e2a044cc8940383a012d45127d50b6c5b --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopAction.java @@ -0,0 +1,80 @@ +package de.tobias.playpad.actionsplugin.stopaction; + +import org.dom4j.Element; + +import de.tobias.playpad.action.Action; +import de.tobias.playpad.action.InputType; +import de.tobias.playpad.action.feedback.FeedbackMessage; +import de.tobias.playpad.action.feedback.FeedbackType; +import de.tobias.playpad.actionsplugin.impl.ActionsPluginImpl; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadStatus; +import de.tobias.playpad.project.Project; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import de.tobias.utils.ui.icon.FontAwesomeType; +import de.tobias.utils.ui.icon.FontIcon; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.scene.Node; +import javafx.scene.control.Label; + +public class StopAction extends Action { + + @Override + public String getType() { + return StopActionConnect.TYPE; + } + + @Override + public void performAction(InputType type, Project project, IMainViewController mainViewController) { + for (Pad pad : project.getPads().values()) { + if (pad.getStatus() == PadStatus.PLAY || pad.getStatus() == PadStatus.PAUSE) + pad.setStatus(PadStatus.STOP, true); + } + } + + @Override + public void initFeedback(Project project, IMainViewController controller) { + handleFeedback(FeedbackMessage.STANDARD); + } + + @Override + public void clearFeedback() { + handleFeedback(FeedbackMessage.OFF); + } + + @Override + public FeedbackType geFeedbackType() { + return FeedbackType.SINGLE; + } + + @Override + public void load(Element root) {} + + @Override + public void save(Element root) {} + + @Override + public StringProperty displayProperty() { + return new SimpleStringProperty(ActionsPluginImpl.getBundle().getString("stopaction.name")); + } + + @Override + public Node getGraphics() { + return new Label("", new FontIcon(FontAwesomeType.STOP)); + } + + @Override + public boolean equals(Object obj) { + if (obj.getClass().equals(getClass())) { + return true; + } + return super.equals(obj); + } + + @Override + public Action cloneAction() throws CloneNotSupportedException { + return (Action) super.clone(); + } + +} diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopActionConnect.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopActionConnect.java new file mode 100644 index 0000000000000000000000000000000000000000..4f7cab1c9d67335aebdb7c3c1883aafd1f11993f --- /dev/null +++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopActionConnect.java @@ -0,0 +1,42 @@ +package de.tobias.playpad.actionsplugin.stopaction; + +import java.util.List; + +import de.tobias.playpad.action.Action; +import de.tobias.playpad.action.ActionConnect; +import de.tobias.playpad.action.ActionDisplayable; +import de.tobias.playpad.action.ActionType; +import de.tobias.playpad.action.Mapping; +import de.tobias.playpad.settings.Profile; +import javafx.scene.control.TreeItem; + +public class StopActionConnect extends ActionConnect { + + public static final String TYPE = "STOP"; + + @Override + public TreeItem<ActionDisplayable> getTreeViewForActions(List<Action> actions, Mapping mapping) { + TreeItem<ActionDisplayable> item = new TreeItem<>(actions.get(0)); + return item; + } + + @Override + public void initActionType(Mapping mapping, Profile profile) { + mapping.addActionIfNotContains(newInstance()); + } + + @Override + public Action newInstance() { + return new StopAction(); + } + + @Override + public ActionType geActionType() { + return ActionType.CONTROL; + } + + @Override + public String getType() { + return TYPE; + } +} diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakePlugin.java b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakePlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..abda3de1f2a37514e3f7180328e2f2fc3ca0adb2 --- /dev/null +++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakePlugin.java @@ -0,0 +1,7 @@ +package de.tobias.playpad.awakeplugin; + +import net.xeoh.plugins.base.Plugin; + +public interface AwakePlugin extends Plugin { + +} diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakeSettings.java b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakeSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..3a1508e178ae426d261cce129e73365d40a69d9b --- /dev/null +++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakeSettings.java @@ -0,0 +1,48 @@ +package de.tobias.playpad.awakeplugin; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.file.Files; +import java.nio.file.Path; + +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; + +public class AwakeSettings { + + public boolean active = false; + + private static final String ACTIVE_ELEMENT = "Active"; + + public static AwakeSettings load(Path path) throws DocumentException, IOException { + AwakeSettings settings = new AwakeSettings(); + SAXReader reader = new SAXReader(); + Document document = reader.read(Files.newInputStream(path)); + + Element rootElement = document.getRootElement(); + settings.active = Boolean.valueOf(rootElement.element(ACTIVE_ELEMENT).getStringValue()); + + return settings; + } + + public void save(Path path) throws UnsupportedEncodingException, IOException { + Document document = DocumentHelper.createDocument(); + Element rootElement = document.addElement("Settings"); + + Element activeElement = rootElement.addElement(ACTIVE_ELEMENT); + activeElement.addText(String.valueOf(active)); + + 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(); + } +} diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/assets/awake_de.properties b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/assets/awake_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..745ae728a30e3c2a58a2ac45213763c3fdd1e178 --- /dev/null +++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/assets/awake_de.properties @@ -0,0 +1 @@ +menutitle=Ruhezustand verhindern \ No newline at end of file diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..42b536e0ec16ed773b68a36db6a505652ed05dab --- /dev/null +++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java @@ -0,0 +1,183 @@ +package de.tobias.playpad.awakeplugin.impl; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.ResourceBundle; + +import org.dom4j.DocumentException; + +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.awakeplugin.AwakePlugin; +import de.tobias.playpad.awakeplugin.AwakeSettings; +import de.tobias.playpad.plugin.SettingsListener; +import de.tobias.playpad.plugin.WindowListener; +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.update.UpdateRegistery; +import de.tobias.playpad.viewcontroller.main.IMainToolbarViewController; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; +import de.tobias.utils.ui.icon.FontAwesomeType; +import de.tobias.utils.ui.icon.FontIcon; +import de.tobias.utils.util.AwakeUtils; +import de.tobias.utils.util.IOUtils; +import de.tobias.utils.util.Kernel32; +import de.tobias.utils.util.Localization; +import de.tobias.utils.util.OS; +import de.tobias.utils.util.OS.OSType; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.control.CheckMenuItem; +import javafx.scene.control.Label; +import net.xeoh.plugins.base.annotations.PluginImplementation; +import net.xeoh.plugins.base.annotations.events.PluginLoaded; +import net.xeoh.plugins.base.annotations.events.Shutdown; + +@PluginImplementation +public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewController>, EventHandler<ActionEvent>, SettingsListener { + + private static final String SETTINGS_FILENAME = "Awake.xml"; + + private CheckMenuItem activeMenu; + private Label iconLabel; + + private AwakeSettings settings = new AwakeSettings(); + + private ResourceBundle bundle; + + @PluginLoaded + public void onLoad(AwakePlugin plugin) { + bundle = Localization.loadBundle("de/tobias/playpad/awakeplugin/assets/awake", getClass().getClassLoader()); + + UpdateRegistery.registerUpdateable(new AwakePluginUpdater()); + + if (OS.getType() == OSType.Windows) { + try { + loadJNA(); + PlayPadPlugin.getImplementation().loadPlugin(ApplicationUtils.getApplication().getPath(PathType.LIBRARY, "jna").toUri()); + } catch (IOException e) { + e.printStackTrace(); + } + } else if (OS.getType() == OSType.MacOSX) { + try { + Path file = loadLibMac(); + AwakeUtils.load(file.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + PlayPadPlugin.getImplementation().addMainViewListener(this); + PlayPadPlugin.getImplementation().addSettingsListener(this); + System.out.println("Enable Awake Plugin"); + } + + @Shutdown + public void onDisable() { + System.out.println("Disable Awake Plugin"); + } + + private Path loadLibMac() throws IOException { + Path folder = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, "awakelib.dylib"); + if (Files.notExists(folder)) { + Files.createFile(folder); + URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/plugins/libAwake/libAwakeLib.dylib"); + System.out.println("Downlaod " + url); + IOUtils.copy(url.openStream(), folder); + } + return folder; + } + + private void loadJNA() throws IOException { + Path folder = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, "jna"); + + Path jnaFile = folder.resolve("jna.jar"); + Path jnaPlatformFile = folder.resolve("jna-platform.jar"); + + if (Files.notExists(jnaFile)) { + Files.createDirectories(folder); + URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/plugins/jna/jna.jar"); + System.out.println("Downlaod " + url); + IOUtils.copy(url.openStream(), jnaFile); + } + + if (Files.notExists(jnaPlatformFile)) { + Files.createDirectories(folder); + URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/plugins/jna/jna-platform.jar"); + System.out.println("Downlaod " + url); + IOUtils.copy(url.openStream(), jnaPlatformFile); + } + } + + @Override + public void onLoad(Profile profile) { + Path path = profile.getRef().getCustomFilePath(SETTINGS_FILENAME); + + try { + settings = AwakeSettings.load(path); + } catch (NoSuchFileException e) { + System.out.println("No Awake.xml config on folder"); + } catch (DocumentException | IOException e) { + e.printStackTrace(); + } + + activeSleep(settings.active); + if (activeMenu != null) + activeMenu.setSelected(settings.active); + } + + @Override + public void onSave(Profile profile) { + Path path = profile.getRef().getCustomFilePath(SETTINGS_FILENAME); + + try { + settings.save(path); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onInit(IMainViewController t) { + activeMenu = new CheckMenuItem(); + activeMenu.setOnAction(this); + activeMenu.setText(bundle.getString("menutitle")); + activeMenu.setSelected(settings.active); + t.addMenuItem(activeMenu); + + iconLabel = new Label(); + iconLabel.setGraphic(new FontIcon(FontAwesomeType.MOON_ALT)); + } + + @Override + public void handle(ActionEvent event) { + activeSleep(activeMenu.isSelected()); + settings.active = activeMenu.isSelected(); + + IMainToolbarViewController toolbarController = PlayPadPlugin.getImplementation().getMainViewController().getToolbarController(); + if (settings.active) { + toolbarController.showIcon(iconLabel); + } else { + toolbarController.hideIcon(iconLabel); + } + } + + public void activeSleep(boolean activate) { + if (activate) { + if (OS.getType() == OSType.Windows) { + Kernel32.INSTANCE.SetThreadExecutionState(Kernel32.ES_CONTINUOUS | Kernel32.ES_DISPLAY_REQUIRED | Kernel32.ES_SYSTEM_REQUIRED); + } else if (OS.getType() == OSType.MacOSX) { + AwakeUtils.getInstance().lock(); + } + } else { + if (OS.getType() == OSType.Windows) { + Kernel32.INSTANCE.SetThreadExecutionState(Kernel32.ES_CONTINUOUS); + } else if (OS.getType() == OSType.MacOSX) { + AwakeUtils.getInstance().unlock(); + } + } + } +} diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginUpdater.java b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..bf34dd937f9c683362234f497c0693bfada5764a --- /dev/null +++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginUpdater.java @@ -0,0 +1,79 @@ +package de.tobias.playpad.awakeplugin.impl; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import de.tobias.playpad.update.Updatable; +import de.tobias.playpad.update.UpdateChannel; +import de.tobias.utils.application.App; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; + +public class AwakePluginUpdater implements Updatable { + + private int newBuild; + private String newVersion; + private URL remotePath; + + private String localFileName; + private String name; + + @Override + public int getCurrentBuild() { + return 2; + } + + @Override + public String getCurrentVersion() { + return "2.0"; + } + + @Override + public int getNewBuild() { + return newBuild; + } + + @Override + public String getNewVersion() { + return newVersion; + } + + @Override + public void loadInformation(UpdateChannel channel) throws IOException { + App app = ApplicationUtils.getMainApplication(); + URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/plugins.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); + + newBuild = config.getInt("plugins.awake.build"); + newVersion = config.getString("plugins.awake.version"); + remotePath = new URL(config.getString("plugins.awake.url")); + localFileName = config.getString("plugins.awake.filename"); + name = config.getString("plugins.awake.name"); + + } + + @Override + public boolean isUpdateAvailable() { + return getCurrentBuild() < getNewBuild(); + } + + @Override + public URL getDownloadPath() { + return remotePath; + } + + @Override + public Path getLocalPath() { + return ApplicationUtils.getApplication().getPath(PathType.LIBRARY, localFileName); + } + + @Override + public String name() { + return name; + } + +} diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/equalizerView.fxml b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/equalizerView.fxml new file mode 100644 index 0000000000000000000000000000000000000000..83248d0f5488bc042f557652e10a793bd4e8c7d2 --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/equalizerView.fxml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.*?> +<?import java.lang.*?> +<?import javafx.scene.layout.*?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <HBox fx:id="equalizerView" prefHeight="353.0" prefWidth="600.0" AnchorPane.bottomAnchor="47.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> + <CheckBox fx:id="enableCheckBox" layoutX="14.0" layoutY="368.0" mnemonicParsing="false" onAction="#enableCheckBoxHandler" text="%eq.checkbox.enabled" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" /> + <HBox layoutX="420.0" layoutY="364.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0"> + <children> + <Button fx:id="resetButton" layoutX="471.0" layoutY="364.0" mnemonicParsing="false" onAction="#resetButtonHandler" text="%eq.button.reset" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="76.0" /> + <Button fx:id="finishButton" layoutX="534.0" layoutY="364.0" mnemonicParsing="false" onAction="#finishButtonHandler" text="%eq.button.finish" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="14.0" /> + </children> + </HBox> + </children> +</AnchorPane> diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/equalizer_de.properties b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/equalizer_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..9afc1e473d5f70819edcc109629b30e69c6b8c01 --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/equalizer_de.properties @@ -0,0 +1,7 @@ +eq.checkbox.enabled=Equalizer aktiviert +eq.button.reset=Zur�cksetzen +eq.button.finish=Fertig +eq.slider=Hz + +eq.menuitem.name=Equalizer +eq.title=Equalizer \ No newline at end of file diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/style.css b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/style.css new file mode 100644 index 0000000000000000000000000000000000000000..d43b5b9d68fc3388f6880749de09ccfd6fb3f259 --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/assets/style.css @@ -0,0 +1,7 @@ +.equalizer-box { + -fx-padding: 5px; +} + +.equalizer-bandbox { + -fx-spacing: 10px; +} \ No newline at end of file diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/Equalizer.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/Equalizer.java new file mode 100644 index 0000000000000000000000000000000000000000..4ab02029ceeb4c474a995a5e352562697f2f5437 --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/Equalizer.java @@ -0,0 +1,120 @@ +package de.tobias.playpad.equalizerplugin.main; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Set; + +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 javafx.beans.property.BooleanProperty; +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleDoubleProperty; + +public class Equalizer { + + private static Equalizer instance; + + static { + instance = new Equalizer(); + } + + public static Equalizer getInstance() { + return instance; + } + + private HashMap<Integer, DoubleProperty> bands; + private BooleanProperty enable; + + private Equalizer() { + bands = new HashMap<>(); + bands.put(19, new SimpleDoubleProperty()); + bands.put(39, new SimpleDoubleProperty()); + bands.put(78, new SimpleDoubleProperty()); + bands.put(156, new SimpleDoubleProperty()); + bands.put(312, new SimpleDoubleProperty()); + bands.put(625, new SimpleDoubleProperty()); + bands.put(1250, new SimpleDoubleProperty()); + bands.put(2500, new SimpleDoubleProperty()); + bands.put(5000, new SimpleDoubleProperty()); + bands.put(10000, new SimpleDoubleProperty()); + + enable = new SimpleBooleanProperty(false); + } + + public Set<Integer> getBands() { + return bands.keySet(); + } + + public Double getGain(int band) { + return bands.get(band).get(); + } + + public void setGain(int band, double value) { + this.bands.get(band).set(value); + } + + public DoubleProperty gainProperty(int band) { + return bands.get(band); + } + + public boolean isEnable() { + return enable.get(); + } + + public void setEnable(boolean enable) { + this.enable.set(enable); + } + + public BooleanProperty enableProperty() { + return enable; + } + + private static final String ENABLE_ELEMENT = "enable"; + private static final String WIDTH_ATTR = "width"; + private static final String BAND_ELEMENT = "band"; + private static final String EQUALIZER_ELEMENT = "equalizer"; + + public static void save(Path path) throws IOException { + Document document = DocumentHelper.createDocument(); + Element root = document.addElement(EQUALIZER_ELEMENT); + for (int band : instance.bands.keySet()) { + root.addElement(BAND_ELEMENT).addAttribute(WIDTH_ATTR, String.valueOf(band)).addText(String.valueOf(instance.bands.get(band).get())); + } + root.addElement(ENABLE_ELEMENT).addText(String.valueOf(instance.enable.get())); + + 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 static void load(Path path) throws DocumentException, IOException { + if (Files.exists(path)) { + SAXReader reader = new SAXReader(); + Document document = reader.read(Files.newInputStream(path)); + + Element root = document.getRootElement(); + for (Object bandObj : root.elements(BAND_ELEMENT)) { + Element element = (Element) bandObj; + int bandwidth = Integer.valueOf(element.attribute(WIDTH_ATTR).getValue()); + double gain = Double.valueOf(element.getStringValue()); + instance.setGain(bandwidth, gain); + } + if (root.element(ENABLE_ELEMENT) != null) + instance.setEnable(Boolean.valueOf(root.element(ENABLE_ELEMENT).getStringValue())); + } + } +} diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/EqualizerPlugin.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/EqualizerPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..93b16f1acdd36bc81219fabae3c646090bf5b386 --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/EqualizerPlugin.java @@ -0,0 +1,8 @@ +package de.tobias.playpad.equalizerplugin.main; + +import net.xeoh.plugins.base.Plugin; + + +public interface EqualizerPlugin extends Plugin { + +} diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginImpl.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..54282b74205cbd36efc93cc0d8b20964c81a7f1c --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginImpl.java @@ -0,0 +1,122 @@ +package de.tobias.playpad.equalizerplugin.main.impl; + +import java.io.IOException; +import java.util.ResourceBundle; + +import org.dom4j.DocumentException; + +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.audio.Equalizable; +import de.tobias.playpad.equalizerplugin.main.Equalizer; +import de.tobias.playpad.equalizerplugin.main.EqualizerPlugin; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.conntent.PadContent; +import de.tobias.playpad.plugin.PadListener; +import de.tobias.playpad.plugin.WindowListener; +import de.tobias.playpad.update.UpdateRegistery; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; +import de.tobias.utils.util.Localization; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.control.MenuItem; +import javafx.scene.media.AudioEqualizer; +import javafx.scene.media.EqualizerBand; +import javafx.stage.Stage; +import net.xeoh.plugins.base.annotations.PluginImplementation; +import net.xeoh.plugins.base.annotations.events.PluginLoaded; +import net.xeoh.plugins.base.annotations.events.Shutdown; + +@PluginImplementation +public class EqualizerPluginImpl implements EqualizerPlugin, WindowListener<IMainViewController>, EventHandler<ActionEvent>, PadListener { + + private Stage mainStage; + private EqualizerViewController equalizerViewController; + private static ResourceBundle bundle; + + private MenuItem eqMenuItem; + + public static ResourceBundle getBundle() { + return bundle; + } + + @PluginLoaded + public void onEnable(EqualizerPlugin plugin) { + bundle = Localization.loadBundle("de/tobias/playpad/equalizerplugin/assets/equalizer", EqualizerPluginImpl.class.getClassLoader()); + try { + Equalizer.load(ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "equalizer.xml")); + } catch (DocumentException | IOException e) { + e.printStackTrace(); + } + + UpdateRegistery.registerUpdateable(new EqualizerPluginUpdater()); + + PlayPadPlugin.getImplementation().addMainViewListener(this); + PlayPadPlugin.getImplementation().addPadListener(this); + + System.out.println("Enable Equalizer Plugin"); + } + + @Shutdown + public void onDisable() { + System.out.println("Disable Equalizer Plugin"); + } + + @Override + public void onInit(IMainViewController t) { + mainStage = t.getStage(); + + eqMenuItem = new MenuItem(); + eqMenuItem.setText(bundle.getString("eq.menuitem.name")); + eqMenuItem.setOnAction(this); + t.addMenuItem(eqMenuItem); + } + + @Override + public void onPlay(Pad pad) { + PadContent content = pad.getContent(); + if (content != null && content instanceof Equalizable) { + + // Equalizer + Equalizable equalizable = (Equalizable) content; + AudioEqualizer audioEqualizer = equalizable.getAudioEqualizer(); + if (audioEqualizer != null) { + for (EqualizerBand band : audioEqualizer.getBands()) { + band.gainProperty().bind(Equalizer.getInstance().gainProperty((int) band.getBandwidth())); + } + audioEqualizer.enabledProperty().bind(Equalizer.getInstance().enableProperty()); + } + } + } + + @Override + public void onStop(Pad pad) { + PadContent content = pad.getContent(); + if (content != null && content instanceof Equalizable) { + + // Equalizer + Equalizable equalizable = (Equalizable) content; + AudioEqualizer audioEqualizer = equalizable.getAudioEqualizer(); + if (audioEqualizer != null) { + for (EqualizerBand band : audioEqualizer.getBands()) { + band.gainProperty().bind(Equalizer.getInstance().gainProperty((int) band.getBandwidth())); + } + audioEqualizer.enabledProperty().bind(Equalizer.getInstance().enableProperty()); + } + } + } + + @FXML + public void handle(ActionEvent event) { + if (equalizerViewController == null) { + equalizerViewController = new EqualizerViewController(mainStage); + equalizerViewController.getStage().show(); + } else if (equalizerViewController.getStage().isShowing()) { + equalizerViewController.getStage().toFront(); + } else { + equalizerViewController.getStage().show(); + } + } +} \ No newline at end of file diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginUpdater.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..c8de63641b5a027f7e71c1689712636f356a3d20 --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginUpdater.java @@ -0,0 +1,78 @@ +package de.tobias.playpad.equalizerplugin.main.impl; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import de.tobias.playpad.update.Updatable; +import de.tobias.playpad.update.UpdateChannel; +import de.tobias.utils.application.App; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; + +public class EqualizerPluginUpdater implements Updatable { + + private int newBuild; + private String newVersion; + private URL remotePath; + + private String localFileName; + private String name; + + @Override + public int getCurrentBuild() { + return 4; + } + + @Override + public String getCurrentVersion() { + return "4.0"; + } + + @Override + public int getNewBuild() { + return newBuild; + } + + @Override + public String getNewVersion() { + return newVersion; + } + + @Override + public void loadInformation(UpdateChannel channel) throws IOException { + App app = ApplicationUtils.getMainApplication(); + URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/plugins.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); + + newBuild = config.getInt("plugins.equalizer.build"); + newVersion = config.getString("plugins.equalizer.version"); + remotePath = new URL(config.getString("plugins.equalizer.url")); + localFileName = config.getString("plugins.equalizer.filename"); + name = config.getString("plugins.equalizer.name"); + } + + @Override + public boolean isUpdateAvailable() { + return getCurrentBuild() < getNewBuild(); + } + + @Override + public URL getDownloadPath() { + return remotePath; + } + + @Override + public Path getLocalPath() { + return ApplicationUtils.getApplication().getPath(PathType.LIBRARY, localFileName); + } + + @Override + public String name() { + return name; + } + +} diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerViewController.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerViewController.java new file mode 100644 index 0000000000000000000000000000000000000000..a7e2f72353621c2f6836e6fe4b4629c55506558c --- /dev/null +++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerViewController.java @@ -0,0 +1,125 @@ +package de.tobias.playpad.equalizerplugin.main.impl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.equalizerplugin.main.Equalizer; +import de.tobias.playpad.settings.Profile; +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.NumberUtils; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.geometry.Orientation; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.Slider; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; +import javafx.scene.media.EqualizerBand; +import javafx.stage.Stage; +import javafx.stage.Window; + +public class EqualizerViewController extends ViewController { + + @FXML private HBox equalizerView; + @FXML private Button resetButton; + @FXML private Button finishButton; + @FXML private CheckBox enableCheckBox; + + public EqualizerViewController(Window owner) { + super("equalizerView", "de/tobias/playpad/equalizerplugin/assets/", null, EqualizerPluginImpl.getBundle()); + + getStage().initOwner(owner); + + Equalizer eq = Equalizer.getInstance(); + + List<Integer> bands = new ArrayList<>(eq.getBands()); + Collections.sort(bands); + + for (int band : bands) { + VBox bandBox = new VBox(); + + Slider slider = new Slider(EqualizerBand.MIN_GAIN, EqualizerBand.MAX_GAIN, eq.getGain(band)); + slider.setOrientation(Orientation.VERTICAL); + slider.setMajorTickUnit(6); + slider.setShowTickLabels(true); + slider.setShowTickMarks(true); + slider.setMaxHeight(Double.MAX_VALUE); + slider.getStyleClass().add("equalizer-slider"); + slider.setUserData(band); + + Label infoLabel = new Label(NumberUtils.numberToString(band, 0) + EqualizerPluginImpl.getBundle().getString("eq.slider")); + infoLabel.getStyleClass().add("equalizer-label"); + + bandBox.getChildren().addAll(slider, infoLabel); + bandBox.prefWidthProperty().bind(equalizerView.widthProperty().divide(bands.size())); + VBox.setVgrow(slider, Priority.ALWAYS); + bandBox.setAlignment(Pos.CENTER); + bandBox.getStyleClass().add("equalizer-bandbox"); + + equalizerView.getChildren().add(bandBox); + equalizerView.getStyleClass().add("equalizer-box"); + + // Data Binding + eq.gainProperty(band).bindBidirectional(slider.valueProperty()); + } + + // Setup + enableCheckBox.setSelected(eq.isEnable()); + equalizerView.setDisable(!enableCheckBox.isSelected()); + } + + @Override + public void init() { + enableCheckBox.selectedProperty().addListener((a, b, c) -> + { + equalizerView.setDisable(!c); + }); + + addCloseKeyShortcut(() -> getStage().close()); + } + + @Override + public void initStage(Stage stage) { + PlayPadPlugin.getImplementation().getIcon().ifPresent(stage.getIcons()::add); + + stage.setTitle(EqualizerPluginImpl.getBundle().getString("eq.title")); + stage.setMinWidth(500); + stage.setMinHeight(250); + + Profile.currentProfile().currentLayout().applyCss(getStage()); + } + + @FXML + private void enableCheckBoxHandler(ActionEvent event) { + Equalizer.getInstance().setEnable(enableCheckBox.isSelected()); + } + + @FXML + private void resetButtonHandler(ActionEvent event) { + for (int band : Equalizer.getInstance().getBands()) { + Equalizer.getInstance().setGain(band, 0); + } + } + + @FXML + private void finishButtonHandler(ActionEvent event) { + try { + Equalizer.save(ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "equalizer.xml")); + } catch (IOException e) { + showErrorMessage(Localization.getString("error.file.save", e.getLocalizedMessage()), + PlayPadPlugin.getImplementation().getIcon().orElse(null)); + e.printStackTrace(); + } + getStage().close(); + } +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/LaunchpadPlugin.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/LaunchpadPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..1508fc74c06a2e3892c4bb90150670da800e2713 --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/LaunchpadPlugin.java @@ -0,0 +1,7 @@ +package de.tobias.playpad.launchpadplugin; + +import net.xeoh.plugins.base.Plugin; + +public interface LaunchpadPlugin extends Plugin { + +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/assets/launchpad_de.properties b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/assets/launchpad_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/assets/launchpad_mk2.map b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/assets/launchpad_mk2.map new file mode 100644 index 0000000000000000000000000000000000000000..f29e22ce294b0084e431542a728cd78ead39fb6c --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/assets/launchpad_mk2.map @@ -0,0 +1,39 @@ +0xef9a9aff=C107 +0xef5350ff=C4 +0xe53935ff=C72 + +0xd92349ff=C5 +0xc92349ff=C72 +0xa90329ff=C72 + +0xf48fb1ff=C59 +0xec407aff=C58 +0xd81b60ff=C57 + +0xce93d8ff=C52 +0xab47bcff=C82 +0x8e24aaff=C53 + +0x80deeaff=C36 +0x26c6daff=C37 +0x00acc1ff=C78 + +0x90caf9ff=C41 +0x42a5f5ff=C79 +0x1e88e5ff=C67 + +0xc5e1a5ff=C88 +0x9ccc65ff=C25 +0x7cb342ff=C21 + +0xfff59dff=C12 +0xffee58ff=C14 +0xfdd835ff=C13 + +0xffcc80ff=C11 +0xffa726ff=C61 +0xfb8c00ff=C84 + +0xeeeeeeff=C119 +0xccccccff=C119 +0x555555ff=C2 \ No newline at end of file diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchPadPluginUpdater.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchPadPluginUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..51690d36ff5bec4a4099dff0c8ee8c16721ed4c3 --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchPadPluginUpdater.java @@ -0,0 +1,79 @@ +package de.tobias.playpad.launchpadplugin.impl; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import de.tobias.playpad.update.Updatable; +import de.tobias.playpad.update.UpdateChannel; +import de.tobias.utils.application.App; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; + +public class LaunchPadPluginUpdater implements Updatable { + + private int newBuild; + private String newVersion; + private URL remotePath; + + private String localFileName; + private String name; + + @Override + public int getCurrentBuild() { + return 3; + } + + @Override + public String getCurrentVersion() { + return "3.0"; + } + + @Override + public int getNewBuild() { + return newBuild; + } + + @Override + public String getNewVersion() { + return newVersion; + } + + @Override + public void loadInformation(UpdateChannel channel) throws IOException { + App app = ApplicationUtils.getMainApplication(); + URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/plugins.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); + + newBuild = config.getInt("plugins.launchpad.build"); + newVersion = config.getString("plugins.launchpad.version"); + remotePath = new URL(config.getString("plugins.launchpad.url")); + localFileName = config.getString("plugins.launchpad.filename"); + name = config.getString("plugins.launchpad.name"); + + } + + @Override + public boolean isUpdateAvailable() { + return getCurrentBuild() < getNewBuild(); + } + + @Override + public URL getDownloadPath() { + return remotePath; + } + + @Override + public Path getLocalPath() { + return ApplicationUtils.getApplication().getPath(PathType.LIBRARY, localFileName); + } + + @Override + public String name() { + return name; + } + +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchpadPluginImpl.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchpadPluginImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..fabff9d69c470b5bb7a76feffae9889d44c91606 --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchpadPluginImpl.java @@ -0,0 +1,42 @@ +package de.tobias.playpad.launchpadplugin.impl; + +import java.util.ResourceBundle; + +import de.tobias.playpad.launchpadplugin.LaunchpadPlugin; +import de.tobias.playpad.launchpadplugin.midi.device.mk2.LaunchPadMK2; +import de.tobias.playpad.launchpadplugin.midi.device.s.LaunchPadS; +import de.tobias.playpad.midi.device.DeviceRegistry; +import de.tobias.playpad.update.UpdateRegistery; +import de.tobias.utils.util.Localization; +import net.xeoh.plugins.base.annotations.PluginImplementation; +import net.xeoh.plugins.base.annotations.events.PluginLoaded; +import net.xeoh.plugins.base.annotations.events.Shutdown; + +@PluginImplementation +public class LaunchpadPluginImpl implements LaunchpadPlugin { + + private static ResourceBundle bundle; + + @PluginLoaded + public void onLoaded(LaunchpadPlugin plugin) { + bundle = Localization.loadBundle("de/tobias/playpad/launchpadplugin/assets/launchpad", LaunchpadPluginImpl.class.getClassLoader()); + + UpdateRegistery.registerUpdateable(new LaunchPadPluginUpdater()); + + DeviceRegistry deviceFactory = DeviceRegistry.getFactoryInstance(); + + deviceFactory.registerDevice(LaunchPadMK2.NAME, LaunchPadMK2.class); + deviceFactory.registerDevice(LaunchPadS.NAME, LaunchPadS.class); + System.out.println("Enable LaunchPad Plugin"); + } + + @Shutdown + public void onShutdown() { + System.out.println("Disable LaunchPad Plugin"); + } + + public static ResourceBundle getBundle() { + return bundle; + } + +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/MapParser.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/MapParser.java new file mode 100644 index 0000000000000000000000000000000000000000..021469d2baa1920bd6f90ab0ba5086c947ce4145 --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/MapParser.java @@ -0,0 +1,25 @@ +package de.tobias.playpad.launchpadplugin.impl; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import de.tobias.utils.util.FileUtils; + +public class MapParser { + + public static Map<String, String> load(URL resource) throws IOException { + Map<String, String> items = new HashMap<>(); + for (String line : FileUtils.readURL(resource).split("\n")) { + String[] split = line.split("="); + if (split.length == 2) { + String color = split[0]; + String val = split[1]; + items.put(color, val); + } + } + ; + return items; + } +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2.java new file mode 100644 index 0000000000000000000000000000000000000000..01a33d47e0a9d1dde2fe6c4e5f2e69faebf200d5 --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2.java @@ -0,0 +1,128 @@ +package de.tobias.playpad.launchpadplugin.midi.device.mk2; + +import java.net.URL; +import java.util.Map; + +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.ShortMessage; + +import de.tobias.playpad.action.feedback.DisplayableFeedbackColor; +import de.tobias.playpad.action.feedback.Feedback; +import de.tobias.playpad.action.feedback.FeedbackMessage; +import de.tobias.playpad.action.mididevice.Device; +import de.tobias.playpad.action.mididevice.DeviceColorAssociatorConnector; +import de.tobias.playpad.launchpadplugin.impl.MapParser; +import de.tobias.playpad.midi.Midi; +import javafx.scene.paint.Color; + +public class LaunchPadMK2 extends Device implements DeviceColorAssociatorConnector { + + public static final String NAME = "Launchpad MK2"; + private static Map<String, String> mapProperties; + + public LaunchPadMK2() { + try { + URL resource = getClass().getClassLoader().getResource("de/tobias/playpad/launchpadplugin/assets/launchpad_mk2.map"); + mapProperties = MapParser.load(resource); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public String getName() { + return NAME; + } + + @Override + public boolean supportFeedback() { + return true; + } + + @Override + public void initFeedback() {} + + @Override + public void handleFeedback(FeedbackMessage type, int key, Feedback feedback) { + if (type != FeedbackMessage.WARNING) { + try { + int value = feedback.getValueForFeedbackMessage(type); + if (key >= 104 && key <= 111) { + Midi.getInstance().sendMessage(176, key, value); + } else { + Midi.getInstance().sendMessage(144, key, value); + } + } catch (MidiUnavailableException | InvalidMidiDataException e) { + e.printStackTrace(); + } + } else { + try { + Midi.getInstance().sendMessage(145, key, feedback.getValueForFeedbackMessage(FeedbackMessage.STANDARD)); + } catch (MidiUnavailableException | InvalidMidiDataException e) { + e.printStackTrace(); + } + } + } + + @Override + public void clearFeedback() { + final int maxMainKeyNumber = 89; + + for (int i = 11; i <= maxMainKeyNumber; i++) { + // Node_On = 144 + try { + Midi.getInstance().sendMessage(ShortMessage.NOTE_ON, i, 0); + } catch (MidiUnavailableException | InvalidMidiDataException e) { + e.printStackTrace(); + } + } + + // Obere Reihe an Tasten + final int liveKeyMin = 104; + final int liveKeyMax = 111; + + for (int i = liveKeyMin; i <= liveKeyMax; i++) { + // Control_Change = 176 + try { + Midi.getInstance().sendMessage(ShortMessage.CONTROL_CHANGE, i, 0); + } catch (MidiUnavailableException | InvalidMidiDataException e) { + e.printStackTrace(); + } + } + } + + @Override + public DisplayableFeedbackColor getColor(int id) { + return LaunchPadMK2Color.valueOf(id); + } + + @Override + public DisplayableFeedbackColor[] getColors() { + return LaunchPadMK2Color.values(); + } + + @Override + public DisplayableFeedbackColor getDefaultEventColor() { + return LaunchPadMK2Color.C5; + } + + @Override + public DisplayableFeedbackColor getDefaultStandardColor() { + return LaunchPadMK2Color.C36; + } + + @Override + public DisplayableFeedbackColor map(Color color) { + try { + URL resource = getClass().getClassLoader().getResource("de/tobias/playpad/launchpadplugin/assets/launchpad_mk2.map"); + mapProperties = MapParser.load(resource); + } catch (Exception e) { + e.printStackTrace(); + } + if (mapProperties.containsKey(color.toString())) { + return LaunchPadMK2Color.valueOf(mapProperties.get(color.toString())); + } + return null; + } +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2Color.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2Color.java new file mode 100644 index 0000000000000000000000000000000000000000..931b455a19bd03cfa642bad8e1e8acd5b51520aa --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2Color.java @@ -0,0 +1,84 @@ +package de.tobias.playpad.launchpadplugin.midi.device.mk2; + +import de.tobias.playpad.action.feedback.DisplayableFeedbackColor; +import javafx.scene.paint.Color; + +public enum LaunchPadMK2Color implements DisplayableFeedbackColor { + + C0(0, Color.rgb(0, 0, 0)), // BLACK + C2(2, Color.rgb(125, 125, 125)), // GRAY + C3(3, Color.rgb(255, 255, 255)), // WHITE + C4(4, Color.rgb(255, 74, 76)), // RED + C5(5, Color.rgb(255, 0, 24)), // RED + C6(6, Color.rgb(93, 1, 3)), // DARK_RED + C8(8, Color.rgb(254, 188, 112)), // LIGHT_ORGANGE + C9(9, Color.rgb(255, 83, 35)), // ORANGE + C10(10, Color.rgb(92, 28, 6)), // BRAUN + C11(11, Color.rgb(255, 189, 112)), // ORNAGE ! DARK + C12(12, Color.rgb(253, 252, 91)), // YELLOW + C13(13, Color.rgb(253, 252, 85)), // YELLOW + C14(14, Color.rgb(88, 88, 24)), // YELLOW + C16(16, Color.rgb(117, 253, 92)), // LIGHT_GREEN + C17(17, Color.rgb(117, 253, 92)), // LIGHT_GREEN + C21(21, Color.rgb(0, 253, 81)), // LIGHT_GREEN + C25(25, Color.rgb(0, 253, 81)), // LIGHT_GREEN + C28(28, Color.rgb(0, 253, 143)), // LIGHT GRREN + C32(32, Color.rgb(0, 252, 184)), // TURQUOISE + C36(36, Color.rgb(36, 194, 250)), // LIGHT_BLUE + C37(37, Color.rgb(0, 169, 249)), // LIGHT_BLUE + C40(40, Color.rgb(60, 137, 248)), // BLUE + C41(41, Color.rgb(0, 87, 246)), // BLUE + C45(45, Color.rgb(7, 32, 245)), // BLUE + C52(52, Color.rgb(255, 78, 247)), // PURPLE + C53(53, Color.rgb(255, 23, 246)), // PINK + C56(56, Color.rgb(255, 76, 131)), // PINK + C57(57, Color.rgb(255, 0, 83)), // PINK + C58(58, Color.rgb(93, 1, 27)), // PINK + C59(59, Color.rgb(34, 0, 16)), // PINK + C60(60, Color.rgb(255, 12, 25)), // RED + C61(61, Color.rgb(159, 52, 18)), // ORANGE ! + C67(67, Color.rgb(7, 32, 245)), // BLUE ! + C72(72, Color.rgb(255, 0, 24)), // RED + C76(76, Color.rgb(0, 136, 40)), // GREEN + C78(78, Color.rgb(0, 169, 249)), // LIGHT_BLUE + C79(79, Color.rgb(5, 44, 245)), // BLUE + C90(90, Color.rgb(0, 252, 207)), // TURKY + C81(81, Color.rgb(123, 31, 245)), // PURPULE + C82(82, Color.rgb(185, 24, 123)), // PURPULE + C84(84, Color.rgb(255, 71, 32)), // ORANGE ! + C88(88, Color.rgb(0, 253, 81)), // GREEN ! + C92(92, Color.rgb(37, 81, 194)), // BLUE + C96(96, Color.rgb(255, 189, 112)), // ORANGE + C106(106, Color.rgb(176, 0, 12)), // RED + C107(107, Color.rgb(230, 79, 61)), // RED + C116(116, Color.rgb(142, 102, 247)), // PURPLE + C119(119, Color.rgb(221, 252, 252)), // WHITE + C120(120, Color.rgb(168, 2, 12)); // RED + + private int midi; + private Color color; + + private LaunchPadMK2Color(int midi, Color color) { + this.midi = midi; + this.color = color; + } + + @Override + public int midiVelocity() { + return midi; + } + + @Override + public Color getPaint() { + return color; + } + + public static DisplayableFeedbackColor valueOf(int id) { + for (LaunchPadMK2Color color : values()) { + if (color.midiVelocity() == id) { + return color; + } + } + return null; + } +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadS.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadS.java new file mode 100644 index 0000000000000000000000000000000000000000..64b9651e27d0de4f83858259eec37c8a2ed7a902 --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadS.java @@ -0,0 +1,94 @@ +package de.tobias.playpad.launchpadplugin.midi.device.s; + +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MidiUnavailableException; + +import de.tobias.playpad.action.feedback.DisplayableFeedbackColor; +import de.tobias.playpad.action.feedback.Feedback; +import de.tobias.playpad.action.feedback.FeedbackMessage; +import de.tobias.playpad.action.mididevice.Device; +import de.tobias.playpad.action.mididevice.DeviceColorAssociatorConnector; +import de.tobias.playpad.midi.Midi; +import javafx.scene.paint.Color; + +public class LaunchPadS extends Device implements DeviceColorAssociatorConnector { + + public static final String NAME = "Launchpad S"; + + @Override + public String getName() { + return NAME; + } + + @Override + public boolean supportFeedback() { + return true; + } + + @Override + public void initFeedback() { + // Flash Enable + try { + Midi.getInstance().sendMessage(176, 0, 40); + } catch (MidiUnavailableException | InvalidMidiDataException e) { + e.printStackTrace(); + } + } + + @Override + public void handleFeedback(FeedbackMessage type, int key, Feedback feedback) { + initFeedback(); + + int command = 144; + + if (key >= 104 && key <= 111) { + command = 176; + } + + try { + if (type != FeedbackMessage.WARNING) { + int value = feedback.getValueForFeedbackMessage(type); + Midi.getInstance().sendMessage(command, key, value); + } else { + int midiVelocity = feedback.getValueForFeedbackMessage(FeedbackMessage.EVENT) - 4; + Midi.getInstance().sendMessage(command, key, midiVelocity); + } + } catch (MidiUnavailableException | InvalidMidiDataException e) { + e.printStackTrace(); + } + } + + @Override + public void clearFeedback() { + try { + Midi.getInstance().sendMessage(176, 0, 0); + } catch (MidiUnavailableException | InvalidMidiDataException e) { + e.printStackTrace(); + } + } + + @Override + public DisplayableFeedbackColor getColor(int id) { + return LaunchPadSColor.valueOf(id); + } + + @Override + public DisplayableFeedbackColor[] getColors() { + return LaunchPadSColor.values(); + } + + @Override + public DisplayableFeedbackColor getDefaultEventColor() { + return LaunchPadSColor.RED; + } + + @Override + public DisplayableFeedbackColor getDefaultStandardColor() { + return LaunchPadSColor.GREEN; + } + + @Override + public DisplayableFeedbackColor map(Color color) { + return null; + } +} diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadSColor.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadSColor.java new file mode 100644 index 0000000000000000000000000000000000000000..1094ba3119cd89eff93603069c9e8af7a9ef2b24 --- /dev/null +++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadSColor.java @@ -0,0 +1,40 @@ +package de.tobias.playpad.launchpadplugin.midi.device.s; + +import de.tobias.playpad.action.feedback.DisplayableFeedbackColor; +import javafx.scene.paint.Color; + +public enum LaunchPadSColor implements DisplayableFeedbackColor { + + YELLOW(62, Color.YELLOW), + AMBER(63, Color.WHEAT), + GREEN(60, Color.GREEN), + RED(15, Color.RED), + BLACK(0, Color.BLACK); + + private int midi; + private Color color; + + private LaunchPadSColor(int midi, Color color) { + this.midi = midi; + this.color = color; + } + + @Override + public int midiVelocity() { + return midi; + } + + @Override + public Color getPaint() { + return color; + } + + public static DisplayableFeedbackColor valueOf(int id) { + for (LaunchPadSColor color : values()) { + if (color.midiVelocity() == id) { + return color; + } + } + return null; + } +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/settingsPadPane.fxml b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/settingsPadPane.fxml new file mode 100644 index 0000000000000000000000000000000000000000..64628f11d369910dcfa1bdfc5984bcc69a69e39e --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/settingsPadPane.fxml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.*?> +<?import java.lang.*?> +<?import javafx.scene.layout.*?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <HBox spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <children> + <Label alignment="BASELINE_RIGHT" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%pad.label.lastFrame" /> + <CheckBox fx:id="lastFrameCheckBox" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" text="%pad.checkbox.lastFrame" /> + </children> + </HBox> + </children> +</AnchorPane> diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/settingsPane.fxml b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/settingsPane.fxml new file mode 100644 index 0000000000000000000000000000000000000000..797144dc10b1adcf08cdda5fd17fb121003ec508 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/settingsPane.fxml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import java.lang.*?> +<?import javafx.geometry.*?> +<?import javafx.scene.control.*?> +<?import javafx.scene.layout.*?> + +<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <VBox prefHeight="200.0" prefWidth="645.0" spacing="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <children> + <Label text="%settings.video.label.screens" /> + <VBox alignment="TOP_CENTER"> + <children> + <Pane fx:id="screenViewPane" prefWidth="617.0" VBox.vgrow="ALWAYS" /> + </children> + </VBox> + <HBox prefHeight="100.0" prefWidth="200.0" spacing="14.0"> + <children> + <Label text="%settings.video.label.screenChoice"> + <HBox.margin> + <Insets top="4.0" /> + </HBox.margin> + </Label> + <VBox prefHeight="88.0" prefWidth="325.0" spacing="14.0" HBox.hgrow="ALWAYS"> + <children> + <ComboBox fx:id="screenComboBox" prefWidth="150.0" /> + <CheckBox fx:id="fullscreenCheckBox" mnemonicParsing="false" text="%settings.video.checkbox.fullscreen" /> + <CheckBox fx:id="videoOpenAtLaunchCheckBox" mnemonicParsing="false" text="%settings.video.checkbox.openAtLaunch" /> + </children> + </VBox> + </children> + </HBox> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/video_de.properties b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/video_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..01d06be333d3f2492e0554d74bef51d7eb44a87f --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/assets/video_de.properties @@ -0,0 +1,15 @@ +settings.tab=Video/Bild + +settings.video.tab=Video +settings.video.label.screens=Bildschirme: +settings.video.label.screenChoice=Bildschirm f�r Videowiedergabe: +settings.video.checkbox.fullscreen=Vollbild +settings.video.checkbox.openAtLaunch=Fenster beim Start �ffnen + +pad.label.lastFrame=Letztes Bild am Ende des Videos einfrieren (Freeze) +pad.checkbox.lastFrame=Aktivieren + +blindaction.name=Schwarzbild Video + +Content.Video.Name=Video +Content.Image.Name=Bild \ No newline at end of file diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/blindaction/BlindAction.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/blindaction/BlindAction.java new file mode 100644 index 0000000000000000000000000000000000000000..ce74283ac852c79616bbc92a74d9eaa96f7426c5 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/blindaction/BlindAction.java @@ -0,0 +1,99 @@ +package de.tobias.playpad.mediaplugin.blindaction; + +import org.dom4j.Element; + +import de.tobias.playpad.Displayable; +import de.tobias.playpad.action.Action; +import de.tobias.playpad.action.InputType; +import de.tobias.playpad.action.feedback.FeedbackMessage; +import de.tobias.playpad.action.feedback.FeedbackType; +import de.tobias.playpad.mediaplugin.main.impl.MediaPluginImpl; +import de.tobias.playpad.project.Project; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import de.tobias.utils.ui.icon.FontAwesomeType; +import de.tobias.utils.ui.icon.FontIcon; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.beans.value.ChangeListener; +import javafx.scene.Node; +import javafx.scene.control.Label; + +public class BlindAction extends Action implements Displayable { + + private ChangeListener<Boolean> blindFeedbackListener; + + public BlindAction() { + blindFeedbackListener = (a, b, c) -> + { + if (c) { + handleFeedback(FeedbackMessage.EVENT); + } else { + handleFeedback(FeedbackMessage.STANDARD); + } + }; + } + + @Override + public void performAction(InputType type, Project project, IMainViewController mainViewController) { + if (type == InputType.PRESSED) { + MediaPluginImpl.blindProperty().set(!MediaPluginImpl.blindProperty().get()); + } + } + + @Override + public void clearFeedback() { + MediaPluginImpl.blindProperty().removeListener(blindFeedbackListener); + } + + @Override + public void initFeedback(Project project, IMainViewController controller) { + // Listener für Eingaben + BooleanProperty blindProperty = MediaPluginImpl.blindProperty(); + blindProperty.removeListener(blindFeedbackListener); + blindProperty.addListener(blindFeedbackListener); + + // Handle Current Feedback + blindFeedbackListener.changed(blindProperty, null, blindProperty.getValue()); + } + + @Override + public FeedbackType geFeedbackType() { + return FeedbackType.DOUBLE; + } + + @Override + public String getType() { + return BlindActionConnect.TYPE; + } + + @Override + public void load(Element root) {} + + @Override + public void save(Element root) {} + + @Override + public boolean equals(Object obj) { + if (obj.getClass().equals(getClass())) { + return true; + } + return super.equals(obj); + } + + @Override + public StringProperty displayProperty() { + return new SimpleStringProperty(MediaPluginImpl.getInstance().getBundle().getString("blindaction.name")); + } + + @Override + public Node getGraphics() { + return new Label("", new FontIcon(FontAwesomeType.DESKTOP)); + } + + @Override + public Action cloneAction() throws CloneNotSupportedException { + BlindAction actionClone = (BlindAction) super.clone(); + return actionClone; + } +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/blindaction/BlindActionConnect.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/blindaction/BlindActionConnect.java new file mode 100644 index 0000000000000000000000000000000000000000..65aafefd5529e8d889542ee5ede01e9bbcac26fb --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/blindaction/BlindActionConnect.java @@ -0,0 +1,42 @@ +package de.tobias.playpad.mediaplugin.blindaction; + +import java.util.List; + +import de.tobias.playpad.action.Action; +import de.tobias.playpad.action.ActionConnect; +import de.tobias.playpad.action.ActionDisplayable; +import de.tobias.playpad.action.ActionType; +import de.tobias.playpad.action.Mapping; +import de.tobias.playpad.settings.Profile; +import javafx.scene.control.TreeItem; + +public class BlindActionConnect extends ActionConnect { + + public static final String TYPE = "BLIND"; + + @Override + public TreeItem<ActionDisplayable> getTreeViewForActions(List<Action> actions, Mapping mapping) { + TreeItem<ActionDisplayable> item = new TreeItem<>(actions.get(0)); + return item; + } + + @Override + public void initActionType(Mapping mapping, Profile profile) { + mapping.addActionIfNotContains(new BlindAction()); + } + + @Override + public Action newInstance() { + return new BlindAction(); + } + + @Override + public ActionType geActionType() { + return ActionType.SETTINGS; + } + + @Override + public String getType() { + return TYPE; + } +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoPlugin.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..715650a73a239e4c1a948a52e363958577b22f1f --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoPlugin.java @@ -0,0 +1,8 @@ +package de.tobias.playpad.mediaplugin.main; + +import net.xeoh.plugins.base.Plugin; + + +public interface VideoPlugin extends Plugin { + +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoSettings.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..147e22d7f266be71a474b015a4a7abfa77743bbd --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoSettings.java @@ -0,0 +1,79 @@ +package de.tobias.playpad.mediaplugin.main; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +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; + +public class VideoSettings { + + private int screenId = 0; + private boolean fullScreen = true; + private boolean openAtLaunch = false; + + public int getScreenId() { + return screenId; + } + + public boolean isFullScreen() { + return fullScreen; + } + + public boolean isOpenAtLaunch() { + return openAtLaunch; + } + + public void setFullScreen(boolean fullScreen) { + this.fullScreen = fullScreen; + } + + public void setOpenAtLaunch(boolean openAtLaunch) { + this.openAtLaunch = openAtLaunch; + } + + public void setScreenId(int screenId) { + this.screenId = screenId; + } + + private static final String OPEN_AT_LAUNCH_ELEMENT = "OpenAtLaunch"; + private static final String FULL_SCREEN_ELEMENT = "FullScreen"; + private static final String SCREEN_ID_ELEMENT = "ScreenID"; + + public void load(Path path) throws DocumentException, IOException { + if (Files.exists(path)) { + SAXReader reader = new SAXReader(); + Document document = reader.read(Files.newInputStream(path)); + Element root = document.getRootElement(); + if (root.element(SCREEN_ID_ELEMENT) != null) + setScreenId(Integer.valueOf(root.element(SCREEN_ID_ELEMENT).getStringValue())); + if (root.element(FULL_SCREEN_ELEMENT) != null) + setFullScreen(Boolean.valueOf(root.element(FULL_SCREEN_ELEMENT).getStringValue())); + if (root.element(OPEN_AT_LAUNCH_ELEMENT) != null) + setOpenAtLaunch(Boolean.valueOf(root.element(OPEN_AT_LAUNCH_ELEMENT).getStringValue())); + } + } + + public void save(Path path) throws IOException { + if (Files.notExists(path)) { + Files.createDirectories(path.getParent()); + Files.createFile(path); + } + Document document = DocumentHelper.createDocument(); + Element root = document.addElement("Config"); + + root.addElement(SCREEN_ID_ELEMENT).addText(String.valueOf(screenId)); + root.addElement(FULL_SCREEN_ELEMENT).addText(String.valueOf(fullScreen)); + root.addElement(OPEN_AT_LAUNCH_ELEMENT).addText(String.valueOf(openAtLaunch)); + + XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint()); + writer.write(document); + writer.close(); + } +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginImpl.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..a430a722c38d923f74bfb3e38897e50dfa402a8d --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginImpl.java @@ -0,0 +1,156 @@ +package de.tobias.playpad.mediaplugin.main.impl; + +import java.io.IOException; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.ResourceBundle; + +import org.dom4j.DocumentException; + +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.action.ActionRegistery; +import de.tobias.playpad.mediaplugin.blindaction.BlindActionConnect; +import de.tobias.playpad.mediaplugin.main.VideoPlugin; +import de.tobias.playpad.mediaplugin.main.VideoSettings; +import de.tobias.playpad.mediaplugin.video.VideoContentConntect; +import de.tobias.playpad.pad.conntent.PadContentRegistry; +import de.tobias.playpad.plugin.SettingsListener; +import de.tobias.playpad.plugin.image.ImageContentConntect; +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.update.UpdateRegistery; +import de.tobias.utils.ui.HUD; +import de.tobias.utils.ui.icon.FontAwesomeType; +import de.tobias.utils.ui.icon.FontIcon; +import de.tobias.utils.util.Localization; +import javafx.application.Platform; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.geometry.Pos; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import net.xeoh.plugins.base.annotations.PluginImplementation; +import net.xeoh.plugins.base.annotations.events.PluginLoaded; +import net.xeoh.plugins.base.annotations.events.Shutdown; + +@PluginImplementation +public class MediaPluginImpl implements VideoPlugin, SettingsListener, ChangeListener<Boolean> { + + private static MediaPluginImpl instance; + private MediaViewController videoViewController; + private VideoSettings settings = new VideoSettings(); + + private ResourceBundle bundle; + private HUD blindHUD; + private static BooleanProperty blindProperty; + + private static final String SETTINGS_FILENAME = "Media.xml"; + + @PluginLoaded + public void onEnable(VideoPlugin plugin) { + instance = this; + blindProperty = new SimpleBooleanProperty(); + + bundle = Localization.loadBundle("de/tobias/playpad/mediaplugin/assets/video", getClass().getClassLoader()); + videoViewController = new MediaViewController(settings); + + PadContentRegistry.registerActionConnect(new VideoContentConntect()); + PadContentRegistry.registerActionConnect(new ImageContentConntect()); + + PlayPadPlugin.getImplementation().addSettingsListener(this); + + if (Profile.currentProfile() != null) { + onLoad(Profile.currentProfile()); + onChange(Profile.currentProfile()); + } + + if (blindHUD == null) { + Platform.runLater(() -> + { + FontIcon icon = new FontIcon(FontAwesomeType.DESKTOP); + icon.setSize(60); + icon.getStyleClass().remove(FontIcon.STYLE_CLASS); + icon.setColor(Color.WHITE); + icon.setAlignment(Pos.CENTER); + blindHUD = new HUD(icon); + blindHUD.setPosition(Pos.TOP_CENTER); + blindHUD.setMinWidth(200); + blindHUD.setMinHeight(100); + }); + } + + UpdateRegistery.registerUpdateable(new MediaPluginUpdater()); + ActionRegistery.registerActionConnect(new BlindActionConnect()); + + blindProperty.addListener(this); + + System.out.println("Enable Media Plugin"); + } + + @Shutdown + public void onDisable() { + Platform.runLater(() -> videoViewController.getStage().close()); + System.out.println("Disable Media Plugin"); + } + + @Override + public void onLoad(Profile profile) { + Path path = profile.getRef().getCustomFilePath(SETTINGS_FILENAME); + + try { + settings.load(path); + } catch (NoSuchFileException e) { + System.out.println("No Awake.xml config on folder"); + } catch (DocumentException | IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onSave(Profile profile) { + Path path = profile.getRef().getCustomFilePath(SETTINGS_FILENAME); + + try { + settings.save(path); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public VideoSettings getCurrentSettings() { + return settings; + } + + public static MediaPluginImpl getInstance() { + return instance; + } + + public MediaViewController getVideoViewController() { + return videoViewController; + } + + public ResourceBundle getBundle() { + return bundle; + } + + public static BooleanProperty blindProperty() { + return blindProperty; + } + + @Override + public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { + Platform.runLater(() -> + { + if (newValue) { + videoViewController.blind(true); + Pane root = (Pane) PlayPadPlugin.getImplementation().getMainViewController().getParent(); + if (blindHUD != null) + blindHUD.addToParent(root); + } else { + videoViewController.blind(false); + blindHUD.removeFromParent(); + } + }); + } +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginUpdater.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..93e343a88736fe4d493a6c5fecdaf54fe5c2eabb --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginUpdater.java @@ -0,0 +1,79 @@ +package de.tobias.playpad.mediaplugin.main.impl; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import de.tobias.playpad.update.Updatable; +import de.tobias.playpad.update.UpdateChannel; +import de.tobias.utils.application.App; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; + +public class MediaPluginUpdater implements Updatable { + + private int newBuild; + private String newVersion; + private URL remotePath; + + private String localFileName; + private String name; + + @Override + public int getCurrentBuild() { + return 5; + } + + @Override + public String getCurrentVersion() { + return "4.1"; + } + + @Override + public int getNewBuild() { + return newBuild; + } + + @Override + public String getNewVersion() { + return newVersion; + } + + @Override + public void loadInformation(UpdateChannel channel) throws IOException { + App app = ApplicationUtils.getMainApplication(); + URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/plugins.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream()); + + newBuild = config.getInt("plugins.media.build"); + newVersion = config.getString("plugins.media.version"); + remotePath = new URL(config.getString("plugins.media.url")); + localFileName = config.getString("plugins.media.filename"); + name = config.getString("plugins.media.name"); + + } + + @Override + public boolean isUpdateAvailable() { + return getCurrentBuild() < getNewBuild(); + } + + @Override + public URL getDownloadPath() { + return remotePath; + } + + @Override + public Path getLocalPath() { + return ApplicationUtils.getApplication().getPath(PathType.LIBRARY, localFileName); + } + + @Override + public String name() { + return name; + } + +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaSettingsTabViewController.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaSettingsTabViewController.java new file mode 100644 index 0000000000000000000000000000000000000000..0ebe6c7e678a04fa952aba4b8a5eb60bff3ce694 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaSettingsTabViewController.java @@ -0,0 +1,134 @@ +package de.tobias.playpad.mediaplugin.main.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.ResourceBundle; + +import de.tobias.playpad.mediaplugin.main.VideoSettings; +import de.tobias.playpad.project.Project; +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.viewcontroller.SettingsTabViewController; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import javafx.fxml.FXML; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.layout.Pane; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; +import javafx.stage.Screen; + +public class MediaSettingsTabViewController extends SettingsTabViewController { + + @FXML private Pane screenViewPane; + @FXML private ComboBox<Integer> screenComboBox; + @FXML private CheckBox fullscreenCheckBox; + @FXML private CheckBox videoOpenAtLaunchCheckBox; + + private VideoSettings settings; + private ResourceBundle bundle; + + private boolean changeSettings = false; + + public MediaSettingsTabViewController(VideoSettings settings) { + super("settingsPane", "de/tobias/playpad/mediaplugin/assets/", MediaPluginImpl.getInstance().getBundle()); + this.settings = settings; + this.bundle = MediaPluginImpl.getInstance().getBundle(); + } + + @Override + public void init() { + // Video + createScreenView(); + } + + private void createScreenView() { + List<Screen> screens = Screen.getScreens(); + List<StackPane> rects = new ArrayList<>(); + + screenComboBox.getItems().clear(); + + double minX = 0; + double minY = 0; + int index = 1; + + for (Screen screen : screens) { + screenComboBox.getItems().add(index); + + StackPane stackPane = new StackPane(); + stackPane.relocate(screen.getBounds().getMinX() * 0.1, screen.getBounds().getMinY() * 0.1); + stackPane.resize(screen.getBounds().getWidth() * 0.1, screen.getBounds().getHeight() * 0.1); + + Rectangle rec = new Rectangle(screen.getBounds().getWidth() * 0.1, screen.getBounds().getHeight() * 0.1); + rec.setStrokeWidth(1.0); + rec.setStroke(Color.BLACK); + rec.setFill(Color.TRANSPARENT); + + stackPane.getChildren().addAll(rec, new Label(String.valueOf(index++))); + + if (minX > screen.getBounds().getMinX() * 0.1) + minX = screen.getBounds().getMinX() * 0.1; + if (minY > screen.getBounds().getMinY() * 0.1) + minY = screen.getBounds().getMinY() * 0.1; + rects.add(stackPane); + screenViewPane.getChildren().add(stackPane); + + } + + double width = 0; + double height = 0; + for (StackPane stackPane : rects) { + stackPane.relocate(stackPane.getLayoutX() - minX, stackPane.getLayoutY() - minY); + width += stackPane.getWidth(); + if (height < stackPane.getHeight() + stackPane.getLayoutX()) + height = stackPane.getHeight() + stackPane.getLayoutX(); + } + + screenViewPane.setMaxWidth(width); + screenViewPane.setMaxHeight(height + 20); + } + + @Override + public void loadSettings(Profile profile) { + screenComboBox.setValue(settings.getScreenId() + 1); + fullscreenCheckBox.setSelected(settings.isFullScreen()); + videoOpenAtLaunchCheckBox.setSelected(settings.isOpenAtLaunch()); + } + + @Override + public void saveSettings(Profile profile) { + if (settings.getScreenId() != (screenComboBox.getValue() != null ? screenComboBox.getValue() - 1 : 0)) { + changeSettings = true; + } + if (settings.isFullScreen() != fullscreenCheckBox.isSelected()) { + changeSettings = true; + } + if (settings.isOpenAtLaunch() != videoOpenAtLaunchCheckBox.isSelected()) { + changeSettings = true; + } + settings.setScreenId(screenComboBox.getValue() != null ? screenComboBox.getValue() - 1 : 0); + settings.setFullScreen(fullscreenCheckBox.isSelected()); + settings.setOpenAtLaunch(videoOpenAtLaunchCheckBox.isSelected()); + } + + @Override + public boolean needReload() { + return changeSettings; + } + + @Override + public void reload(Profile profile, Project project, IMainViewController controller) { + MediaPluginImpl.getInstance().getVideoViewController().reloadSettings(); + } + + @Override + public boolean validSettings() { + return true; + } + + @Override + public String name() { + return bundle.getString("settings.tab"); + } +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaViewController.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaViewController.java new file mode 100644 index 0000000000000000000000000000000000000000..307b2e60c947dc85fbdbe6bad4f03c8dc7816428 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaViewController.java @@ -0,0 +1,196 @@ +package de.tobias.playpad.mediaplugin.main.impl; + +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; + +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.mediaplugin.main.VideoSettings; +import de.tobias.playpad.mediaplugin.video.VideoContent; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadStatus; +import de.tobias.playpad.plugin.image.ImageContent; +import de.tobias.playpad.settings.Profile; +import de.tobias.playpad.settings.ProfileListener; +import de.tobias.utils.application.ApplicationUtils; +import de.tobias.utils.application.container.PathType; +import de.tobias.utils.util.OS; +import de.tobias.utils.util.OS.OSType; +import javafx.application.Platform; +import javafx.geometry.Pos; +import javafx.geometry.Rectangle2D; +import javafx.scene.Scene; +import javafx.scene.layout.Background; +import javafx.scene.layout.BackgroundFill; +import javafx.scene.layout.Pane; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.media.MediaPlayer; +import javafx.scene.media.MediaPlayer.Status; +import javafx.scene.media.MediaView; +import javafx.scene.paint.Color; +import javafx.stage.Screen; +import javafx.stage.Stage; + +public class MediaViewController implements ProfileListener { + + private MediaView mediaView; + private Pane imageView; + + private Stage stage; + + private boolean finish = true; + private VideoSettings settings; + + private Pad currentDisplayedPad; + + public MediaViewController(VideoSettings settings) { + Profile.registerListener(this); + this.settings = settings; + + mediaView = new MediaView(); + imageView = new Pane(); + + VBox root = new VBox(mediaView); + root.setAlignment(Pos.CENTER); + + StackPane stackPane = new StackPane(root, imageView); + stackPane.setBackground(new Background(new BackgroundFill(Color.BLACK, null, null))); + stackPane.setAlignment(Pos.CENTER); + stackPane.prefWidthProperty().bind(root.widthProperty()); + + mediaView.fitHeightProperty().bind(root.heightProperty()); + VBox.setVgrow(mediaView, Priority.ALWAYS); + + imageView.prefWidthProperty().bind(stackPane.widthProperty()); + imageView.prefHeightProperty().bind(stackPane.heightProperty()); + imageView.getStyleClass().add("image-style"); + + stage = new Stage(); + stage.setScene(new Scene(stackPane, Color.BLACK)); + PlayPadPlugin.getImplementation().getIcon().ifPresent(stage.getIcons()::add); + + Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, "style.css"); + if (Files.exists(path)) + getStage().getScene().getStylesheets().add(path.toUri().toString()); + + stage.setMinWidth(600); + stage.setMinHeight(400); + if (OS.getType() == OSType.Windows) + stage.setAlwaysOnTop(true); + + getStage().setOnCloseRequest(event -> event.consume()); + reloadSettings(); + } + + public void reloadSettings() { + if (stage.isFullScreen()) + stage.setFullScreen(false); + + if (stage.isShowing()) + stage.close(); + + if (Screen.getScreens().size() > settings.getScreenId()) { + Screen screen = Screen.getScreens().get(settings.getScreenId()); + + Rectangle2D bounds; + if (OS.getType() == OSType.Windows) + bounds = screen.getBounds(); + else + bounds = screen.getVisualBounds(); + + stage.setX(bounds.getMinX()); + stage.setY(bounds.getMinY()); + stage.setWidth(bounds.getWidth()); + stage.setHeight(bounds.getHeight()); + } + + if (settings.isOpenAtLaunch() && !stage.isShowing()) + stage.show(); + + if (settings.isFullScreen() && !stage.isFullScreen()) + stage.setFullScreen(true); + } + + public Stage getStage() { + return stage; + } + + // Media + public void setMediaPlayer(MediaPlayer player, Pad pad) { + if (currentDisplayedPad != null && currentDisplayedPad != pad) + this.currentDisplayedPad.setStatus(PadStatus.STOP); + + mediaView.setMediaPlayer(player); + if (player == null) { + finish = true; + this.currentDisplayedPad = null; + } else { + finish = false; + this.currentDisplayedPad = pad; + } + } + + public boolean isPlaying() { + if (mediaView.getMediaPlayer() != null) { + if (finish) + return false; + else + return mediaView.getMediaPlayer().getStatus() == Status.PLAYING; + } else { + return false; + } + } + + @Override + public void reloadSettings(Profile old, Profile currentProfile) { + Platform.runLater(() -> reloadSettings()); + } + + public boolean isFinish() { + return finish; + } + + // Image + public void setImage(String path, Pad pad) { + if (currentDisplayedPad != null) + this.currentDisplayedPad.setStatus(PadStatus.STOP); + + if (path != null) { + this.imageView.setStyle("-fx-background-image: url(\"" + path + + "\"); -fx-background-size: contain; -fx-background-repeat: no-repeat; -fx-background-position: center"); + this.currentDisplayedPad = pad; + } else { + this.imageView.setStyle(""); + this.currentDisplayedPad = null; + } + } + + public boolean isPicutureShowing() { + return !imageView.getStyle().isEmpty(); + } + + // Utils + public Pad getCurrentDisplayedPad() { + return currentDisplayedPad; + } + + public void blind(boolean blind) { + if (blind) { + this.imageView.setStyle(""); + mediaView.setMediaPlayer(null); + } else { + if (currentDisplayedPad != null) { + if (currentDisplayedPad.getContent() instanceof VideoContent) { + VideoContent content = (VideoContent) currentDisplayedPad.getContent(); + mediaView.setMediaPlayer(content.getPlayer()); + } else if (currentDisplayedPad.getContent() instanceof ImageContent) { + ImageContent content = (ImageContent) currentDisplayedPad.getContent(); + URI uri = content.getPath().toUri(); + setImage(uri.toString(), currentDisplayedPad); + } + } + } + } +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/Strings.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/Strings.java new file mode 100644 index 0000000000000000000000000000000000000000..526606dfd9790c6368b4d2938a1a1ed7eee2eee4 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/Strings.java @@ -0,0 +1,7 @@ +package de.tobias.playpad.mediaplugin.main.impl; + +public class Strings { + + public static final String Content_Video_Name = "Content.Video.Name"; + public static final String Content_Image_Name = "Content.Image.Name"; +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContent.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContent.java new file mode 100644 index 0000000000000000000000000000000000000000..021b6458fab9660f5c01773afb0dc049631c7eb5 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContent.java @@ -0,0 +1,274 @@ +package de.tobias.playpad.mediaplugin.video; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.dom4j.Element; + +import de.tobias.playpad.mediaplugin.main.impl.MediaPluginImpl; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadStatus; +import de.tobias.playpad.pad.conntent.Durationable; +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.application.Platform; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.scene.media.Media; +import javafx.scene.media.MediaPlayer; +import javafx.util.Duration; + +public class VideoContent extends PadContent implements Pauseable, Durationable { + + private static final String TYPE = "video"; + public static final String VIDEO_LAST_FRAME = "Video.LastFrame"; + + private Media media; + private MediaPlayer player; + + private Path path; + + private transient ObjectProperty<Duration> durationProperty = new SimpleObjectProperty<>(); + private transient ObjectProperty<Duration> positionProperty = new SimpleObjectProperty<>(); + + private transient ChangeListener<Number> padVolumeListener; + private transient ChangeListener<Number> customVolumeListener; + + private transient boolean holdLastFrame = false; + + public VideoContent(Pad pad) { + super(pad); + padVolumeListener = (a, b, c) -> + { + player.setVolume(c.doubleValue() * Profile.currentProfile().getProfileSettings().getVolume() * getPad().getCustomVolume()); + }; + customVolumeListener = (a, b, c) -> + { + player.setVolume(getPad().getVolume() * Profile.currentProfile().getProfileSettings().getVolume() * c.doubleValue()); + }; + } + + public VideoContent(Pad pad, Path path) { + this(pad); + this.path = path; + } + + public Path getPath() { + return path; + } + + public void setPath(Path path) { + this.path = path; + } + + @Override + public void handlePath(Path path) { + unloadMedia(); + setPath(path); + loadMedia(); + } + + @Override + public void setMasterVolume(double masterVolume) { + if (player != null) { + player.setVolume(getPad().getVolume() * masterVolume * getPad().getCustomVolume()); + } + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public void play() { + getPad().setCustomVolume(1.0); + getPad().setEof(false); + MediaPluginImpl.getInstance().getVideoViewController().setMediaPlayer(player, getPad()); + if (holdLastFrame) { + holdLastFrame = false; + player.seek(Duration.ZERO); + } + + player.play(); + holdLastFrame = false; + } + + @Override + public void pause() { + player.pause(); + } + + @Override + public boolean stop() { + if (getPad().getCustomSettings().containsKey(VIDEO_LAST_FRAME) && !holdLastFrame && getPad().isEof()) { + if ((boolean) getPad().getCustomSettings().get(VIDEO_LAST_FRAME)) { + getPad().setStatus(PadStatus.PAUSE); + holdLastFrame = true; + return false; + } + } + player.stop(); + MediaPluginImpl.getInstance().getVideoViewController().setMediaPlayer(null, null); + return true; + } + + @Override + public boolean isPadLoaded() { + return player != null; + } + + @Override + public Duration getDuration() { + return durationProperty.get(); + } + + @Override + public ReadOnlyObjectProperty<Duration> durationProperty() { + return durationProperty; + } + + @Override + public Duration getPosition() { + return positionProperty.get(); + } + + @Override + public ReadOnlyObjectProperty<Duration> positionProperty() { + return positionProperty; + } + + public MediaPlayer getPlayer() { + return player; + } + + @Override + public void loadMedia() { + if (Files.exists(path)) { + Platform.runLater(() -> + { + if (getPad().isPadVisible()) { + getPad().getController().getParent().setBusy(true); + } + }); + media = new Media(path.toUri().toString()); + + // Old Player + if (player != null) { + stop(); + } + + player = new MediaPlayer(media); + + // Player Listener + player.setOnReady(() -> + { + getPad().setStatus(PadStatus.READY); + + Platform.runLater(() -> + { + if (getPad().isPadVisible()) { + getPad().getController().getParent().setBusy(false); + } + }); + }); + + player.setOnError(() -> + { + Platform.runLater(() -> + { + if (getPad().isPadVisible()) { + getPad().getController().getParent().setBusy(false); + } + }); + getPad().throwException(path, player.getError()); + }); + player.setOnEndOfMedia(() -> + { + if (!getPad().isLoop()) { + getPad().setEof(true); + getPad().setStatus(PadStatus.STOP); + } else { + // Loop + player.seek(Duration.ZERO); + } + }); + + durationProperty.bind(player.totalDurationProperty()); + positionProperty.bind(player.currentTimeProperty()); + + getPad().volumeProperty().addListener(padVolumeListener); + getPad().customVolumeProperty().addListener(customVolumeListener); + } + } + + @Override + public void unloadMedia() { + durationProperty.unbind(); + positionProperty.unbind(); + + getPad().volumeProperty().removeListener(padVolumeListener); + getPad().customVolumeProperty().removeListener(customVolumeListener); + + player = null; + media = null; + durationProperty.set(null); + + Platform.runLater(() -> + { + if (getPad() != null) { + getPad().setStatus(PadStatus.EMPTY); + } + }); + } + + @Override + public void load(Element element) { + path = Paths.get(element.getStringValue()); + } + + @Override + public void save(Element element) { + element.addText(path.toString()); + } + + @Override + public void importMedia(Path mediaFolder, ZipFile zip, Element element) { + String fileName = Paths.get(element.getStringValue()).getFileName().toString(); + Path mediaFile = Paths.get(ProjectExporter.mediaFolder, fileName); + + Path desFile = mediaFolder.resolve(fileName); + + 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(ZipFile zip, Element element) { + Path desPath = Paths.get(ProjectExporter.mediaFolder, path.getFileName().toString()); + try { + if (Files.notExists(desPath.getParent())) { + Files.createDirectories(desPath.getParent()); + } + zip.addFile(path, desPath); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContentConntect.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContentConntect.java new file mode 100644 index 0000000000000000000000000000000000000000..65a48ac94219ed5e8bcf28e4f0d1db0da86d1f69 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContentConntect.java @@ -0,0 +1,105 @@ +package de.tobias.playpad.mediaplugin.video; + +import de.tobias.playpad.mediaplugin.main.impl.MediaPluginImpl; +import de.tobias.playpad.mediaplugin.main.impl.MediaSettingsTabViewController; +import de.tobias.playpad.mediaplugin.main.impl.Strings; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.conntent.PadContent; +import de.tobias.playpad.pad.conntent.PadContentConnect; +import de.tobias.playpad.pad.view.IPadContentView; +import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; +import de.tobias.playpad.viewcontroller.SettingsTabViewController; +import de.tobias.utils.ui.icon.FontAwesomeType; +import de.tobias.utils.ui.icon.FontIcon; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.layout.Pane; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; +import javafx.scene.text.TextAlignment; + +public class VideoContentConntect extends PadContentConnect { + + public static final String TYPE = "video"; + public static final String[] FILE_EXTENSION = { "*.mp4", "*.mov" }; + + private FontIcon icon; + + public VideoContentConntect() { + icon = new FontIcon(FontAwesomeType.FILM); + icon.setSize(30); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public PadContent newInstance(Pad pad) { + return new VideoContent(pad); + } + + @Override + public IPadContentView getPadContentPreview(Pad pad, Pane parentNode) { + return new VideoContentView(pad, parentNode); + } + + @Override + public SettingsTabViewController getSettingsTabViewController(boolean activePlayer) { + MediaPluginImpl instance = MediaPluginImpl.getInstance(); + return new MediaSettingsTabViewController(instance.getCurrentSettings()); + } + + @Override + public PadSettingsTabViewController getSettingsViewController(Pad pad) { + return new VideoPadSettingsTabViewController(); + } + + @Override + public String[] getSupportedTypes() { + return FILE_EXTENSION; + } + + private class VideoContentView implements IPadContentView { + + private Label nameLabel; + + public VideoContentView(Pad pad, Pane parentNode) { + nameLabel = new Label(); + nameLabel.textProperty().bind(pad.nameProperty()); + + nameLabel.setWrapText(true); + nameLabel.setAlignment(Pos.CENTER); + nameLabel.setTextAlignment(TextAlignment.CENTER); + + nameLabel.prefWidthProperty().bind(parentNode.widthProperty()); + nameLabel.setMaxHeight(Double.MAX_VALUE); + VBox.setVgrow(nameLabel, Priority.ALWAYS); + } + + @Override + public Node getNode() { + return nameLabel; + } + + @Override + public void unconnect() { + nameLabel.textProperty().unbind(); + } + } + + @Override + public StringProperty displayProperty() { + return new SimpleStringProperty(MediaPluginImpl.getInstance().getBundle().getString(Strings.Content_Video_Name)); + } + + @Override + public Node getGraphics() { + return icon; + } + +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoPadSettingsTabViewController.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoPadSettingsTabViewController.java new file mode 100644 index 0000000000000000000000000000000000000000..b7a0f0592cc609c6b5ab25ab5697d030d431c80d --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoPadSettingsTabViewController.java @@ -0,0 +1,33 @@ +package de.tobias.playpad.mediaplugin.video; + +import de.tobias.playpad.mediaplugin.main.impl.MediaPluginImpl; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; +import javafx.fxml.FXML; +import javafx.scene.control.CheckBox; + +public class VideoPadSettingsTabViewController extends PadSettingsTabViewController { + + @FXML private CheckBox lastFrameCheckBox; + + public VideoPadSettingsTabViewController() { + super("settingsPadPane", "de/tobias/playpad/mediaplugin/assets/", MediaPluginImpl.getInstance().getBundle()); + } + + @Override + public String getName() { + return MediaPluginImpl.getInstance().getBundle().getString("settings.video.tab"); + } + + @Override + public void loadSettings(Pad pad) { + if (pad.getCustomSettings().containsKey(VideoContent.VIDEO_LAST_FRAME)) + lastFrameCheckBox.setSelected((boolean) pad.getCustomSettings().get(VideoContent.VIDEO_LAST_FRAME)); + } + + @Override + public void saveSettings(Pad pad) { + pad.getCustomSettings().put(VideoContent.VIDEO_LAST_FRAME, lastFrameCheckBox.isSelected()); + } + +} diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/plugin/image/ImageContent.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/plugin/image/ImageContent.java new file mode 100644 index 0000000000000000000000000000000000000000..92e4eb5c994c95a5e936d20664f31a555493663d --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/plugin/image/ImageContent.java @@ -0,0 +1,133 @@ +package de.tobias.playpad.plugin.image; + +import java.io.FileNotFoundException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.dom4j.Element; + +import de.tobias.playpad.mediaplugin.main.impl.MediaPluginImpl; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadStatus; +import de.tobias.playpad.pad.conntent.PadContent; +import de.tobias.playpad.project.ProjectExporter; +import de.tobias.utils.util.ZipFile; +import javafx.application.Platform; + +public class ImageContent extends PadContent { + + private Path path; + + public ImageContent(Pad pad) { + super(pad); + } + + public ImageContent(Pad pad, Path path) { + this(pad); + this.path = path; + } + + public Path getPath() { + return path; + } + + public void setPath(Path path) { + this.path = path; + } + + @Override + public void handlePath(Path path) { + unloadMedia(); + setPath(path); + loadMedia(); + } + + @Override + public void setMasterVolume(double masterVolume) {} + + @Override + public String getType() { + return ImageContentConntect.TYPE; + } + + @Override + public void play() { + MediaPluginImpl.getInstance().getVideoViewController().setImage(path.toUri().toString(), getPad()); + } + + @Override + public boolean stop() { + MediaPluginImpl.getInstance().getVideoViewController().setImage(null, null); + return true; + } + + @Override + public boolean isPadLoaded() { + return path != null; + } + + @Override + public void loadMedia() { + if (Files.exists(path)) { + getPad().setStatus(PadStatus.READY); + } else { + getPad().throwException(path, new FileNotFoundException()); + } + } + + @Override + public void unloadMedia() { + Platform.runLater(() -> + { + if (getPad() != null) { + getPad().setStatus(PadStatus.EMPTY); + } + }); + } + + @Override + public void load(Element element) { + path = Paths.get(element.getStringValue()); + } + + @Override + public void save(Element element) { + element.addText(path.toString()); + } + + @Override + public void importMedia(Path mediaFolder, ZipFile zip, Element element) { + String fileName = Paths.get(element.getStringValue()).getFileName().toString(); + Path mediaFile = Paths.get(ProjectExporter.mediaFolder, fileName); + + Path desFile = mediaFolder.resolve(fileName); + + 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(ZipFile zip, Element element) { + Path desPath = Paths.get(ProjectExporter.mediaFolder, path.getFileName().toString()); + try { + if (Files.notExists(desPath.getParent())) { + Files.createDirectories(desPath.getParent()); + } + zip.addFile(path, desPath); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/plugin/image/ImageContentConntect.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/plugin/image/ImageContentConntect.java new file mode 100644 index 0000000000000000000000000000000000000000..d3d80d8ecebf6d58d2eacb7181238fadb7b92e70 --- /dev/null +++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/plugin/image/ImageContentConntect.java @@ -0,0 +1,144 @@ +package de.tobias.playpad.plugin.image; + +import de.tobias.playpad.mediaplugin.main.impl.MediaPluginImpl; +import de.tobias.playpad.mediaplugin.main.impl.Strings; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.conntent.PadContent; +import de.tobias.playpad.pad.conntent.PadContentConnect; +import de.tobias.playpad.pad.view.IPadContentView; +import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; +import de.tobias.utils.ui.icon.FontAwesomeType; +import de.tobias.utils.ui.icon.FontIcon; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.collections.ListChangeListener; +import javafx.collections.SetChangeListener; +import javafx.css.PseudoClass; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.layout.Pane; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.text.TextAlignment; + +public class ImageContentConntect extends PadContentConnect { + + public static final String TYPE = "image"; + public static final String[] FILE_EXTENSION = { "*.png", "*.jpg", "*.jpeg", "*.bmp", "*.gif" }; + + private FontIcon icon; + + public ImageContentConntect() { + icon = new FontIcon(FontAwesomeType.PICTURE_ALT); + icon.setSize(30); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public PadContent newInstance(Pad pad) { + return new ImageContent(pad); + } + + @Override + public IPadContentView getPadContentPreview(Pad pad, Pane parentNode) { + return new ImageContentView(pad, parentNode); + } + + @Override + public PadSettingsTabViewController getSettingsViewController(Pad pad) { + return null; + } + + @Override + public String[] getSupportedTypes() { + return FILE_EXTENSION; + } + + class ImageContentView implements IPadContentView { + + private StackPane stackPane; + private Label nameLabel; + private Label imageLabel; + private Pad pad; + + public ImageContentView(Pad pad, Pane parentNode) { + this.pad = pad; + nameLabel = new Label(); + nameLabel.textProperty().bind(pad.nameProperty()); + + nameLabel.setWrapText(true); + nameLabel.setAlignment(Pos.CENTER); + nameLabel.setTextAlignment(TextAlignment.CENTER); + + imageLabel = new Label(); + imageLabel.setMaxHeight(Double.MAX_VALUE); + imageLabel.setMaxWidth(Double.MAX_VALUE); + setImage(); + + stackPane = new StackPane(imageLabel, nameLabel); + stackPane.prefWidthProperty().bind(parentNode.widthProperty()); + stackPane.setMaxHeight(Double.MAX_VALUE); + VBox.setVgrow(stackPane, Priority.ALWAYS); + + // Leitet alle StyleClasses von Parent Object an das NameLabel weiter + stackPane.getStyleClass().addListener(new ListChangeListener<String>() { + + @Override + public void onChanged(javafx.collections.ListChangeListener.Change<? extends String> c) { + while (c.next()) { + for (String remitem : c.getRemoved()) { + nameLabel.getStyleClass().remove(remitem); + + } + for (String additem : c.getAddedSubList()) { + nameLabel.getStyleClass().add(additem); + } + } + } + }); + // Leitet alle PseudoClassStates von Parent Object an das NameLabel weiter + stackPane.getPseudoClassStates().addListener(new SetChangeListener<PseudoClass>() { + + @Override + public void onChanged(javafx.collections.SetChangeListener.Change<? extends PseudoClass> c) { + nameLabel.pseudoClassStateChanged(c.getElementRemoved(), false); + nameLabel.pseudoClassStateChanged(c.getElementAdded(), true); + } + }); + } + + @Override + public Node getNode() { + return stackPane; + } + + @Override + public void unconnect() { + nameLabel.textProperty().unbind(); + } + + void setImage() { + ImageContent content = (ImageContent) pad.getContent(); + + if (content.getPath() != null) + imageLabel.setStyle("-fx-background-image: url(\"" + content.getPath().toUri().toString() + + "\"); -fx-background-size: contain; -fx-background-repeat: no-repeat; -fx-background-position: center; -fx-opacity: 0.3;"); + } + } + + @Override + public StringProperty displayProperty() { + return new SimpleStringProperty(MediaPluginImpl.getInstance().getBundle().getString(Strings.Content_Image_Name)); + } + + @Override + public Node getGraphics() { + return icon; + } +} diff --git a/PlayWallPlugins/src/de/tobias/playpad/debugplugin/DebugPlugin.java b/PlayWallPlugins/src/de/tobias/playpad/debugplugin/DebugPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..e09806faa00912906741c31f98d76ec0f485e39b --- /dev/null +++ b/PlayWallPlugins/src/de/tobias/playpad/debugplugin/DebugPlugin.java @@ -0,0 +1,7 @@ +package de.tobias.playpad.debugplugin; + +import net.xeoh.plugins.base.Plugin; + +public interface DebugPlugin extends Plugin { + +} diff --git a/PlayWallPlugins/src/de/tobias/playpad/debugplugin/DebugPluginImpl.java b/PlayWallPlugins/src/de/tobias/playpad/debugplugin/DebugPluginImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6c5de9d0b5bdd925e9dcfe5b6dfe0e79c12da9ec --- /dev/null +++ b/PlayWallPlugins/src/de/tobias/playpad/debugplugin/DebugPluginImpl.java @@ -0,0 +1,23 @@ +package de.tobias.playpad.debugplugin; + +import net.xeoh.plugins.base.annotations.PluginImplementation; +import net.xeoh.plugins.base.annotations.events.PluginLoaded; +import net.xeoh.plugins.base.annotations.events.Shutdown; + +@PluginImplementation +public class DebugPluginImpl implements DebugPlugin { + + public DebugPluginImpl() { + + } + + @PluginLoaded + public void onInit(DebugPlugin plugin) { + System.out.println("INIT"); + } + + @Shutdown + public void onShutdown() { + System.out.println("SHUTDOWN"); + } +}