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/.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..322a160eaa4e3e66f21386a6ec4164bc9545957a --- /dev/null +++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java @@ -0,0 +1,185 @@ +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.PluginManager; +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(); + PluginManager manager = PlayPadPlugin.getImplementation().getPluginManager(); + manager.addPluginsFrom(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/bin/.gitignore b/PlayWallPlugins/bin/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fd04598cccd1eb791debf5b0edfff26368dbb294 --- /dev/null +++ b/PlayWallPlugins/bin/.gitignore @@ -0,0 +1 @@ +/de/ 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"); + } +}