diff --git a/.gitignore b/.gitignore index 2a2b1bc2f3c3f3eec2889dc8c9fe13f4870f7542..3fde153d06b468f4673d3c1bcbfdefdeb2eef532 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ **/target/ **/build **/.idea/** -*.iml \ No newline at end of file +*.iml +.idea/encodings.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index c1500a33cb5596556ab38560f449acbae8fbe473..0000000000000000000000000000000000000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="Encoding" native2AsciiForPropertiesFiles="true"> - <file url="file://$PROJECT_DIR$" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWall" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWall/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWall/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWall/src/main/resources/config" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallComponents" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallComponents/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallComponents/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallCore" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallCore/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallCore/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginAwake" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginAwake/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginAwake/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginEqualizer" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginEqualizer/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginEqualizer/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginLaunchpad" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginLaunchpad/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginLaunchpad/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginMedia" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginMedia/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginMedia/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginNativeAudio" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginNativeAudio/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginNativeAudio/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginPlayoutLog" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginWebAPI" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginWebAPI/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/PlayWallPlugins/PlayWallPluginWebAPI/src/main/resources" charset="UTF-8" /> - <file url="PROJECT" charset="UTF-8" /> - </component> -</project> \ No newline at end of file diff --git a/PlayWall/src/main/java/de/tobias/playpad/PlayPadImpl.java b/PlayWall/src/main/java/de/tobias/playpad/PlayPadImpl.java index f7eb8026b7ac5464277a43715c071459265ec514..c49bbd13df0cc78bf46c5a161e79b0f23c1000fe 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/PlayPadImpl.java +++ b/PlayWall/src/main/java/de/tobias/playpad/PlayPadImpl.java @@ -9,7 +9,7 @@ import de.thecodelabs.utils.threading.Worker; import de.thecodelabs.utils.ui.NVC; import de.thecodelabs.utils.util.SystemUtils; import de.thecodelabs.versionizer.service.UpdateService; -import de.tobias.playpad.design.ModernDesignHandler; +import de.tobias.playpad.design.ModernDesignProvider; import de.tobias.playpad.initialize.*; import de.tobias.playpad.plugin.*; import de.tobias.playpad.profile.ProfileNotFoundException; @@ -65,7 +65,7 @@ public class PlayPadImpl implements PlayPad { private UpdateService updateService; protected GlobalSettings globalSettings; - private ModernDesignHandler modernDesign; + private ModernDesignProvider modernDesign; private Session session; @@ -239,11 +239,11 @@ public class PlayPadImpl implements PlayPad { return parameters; } - public ModernDesignHandler getModernDesign() { + public ModernDesignProvider getModernDesign() { return modernDesign; } - void setModernDesign(ModernDesignHandler modernDesign) { + void setModernDesign(ModernDesignProvider modernDesign) { this.modernDesign = modernDesign; } diff --git a/PlayWall/src/main/java/de/tobias/playpad/PlayPadMain.java b/PlayWall/src/main/java/de/tobias/playpad/PlayPadMain.java index d52ffecfb20f1bf03f7a1f5ee00721fac4035c69..54d75f6ffa4519698e1f250d02b654af0f49e1fe 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/PlayPadMain.java +++ b/PlayWall/src/main/java/de/tobias/playpad/PlayPadMain.java @@ -12,7 +12,7 @@ import de.thecodelabs.utils.ui.Alerts; import de.thecodelabs.utils.util.OS; import de.thecodelabs.utils.util.OS.OSType; import de.thecodelabs.utils.util.SystemUtils; -import de.tobias.playpad.design.ModernDesignHandlerImpl; +import de.tobias.playpad.design.ModernDesignProviderImpl; import de.tobias.playpad.design.ModernStyleableImpl; import de.tobias.playpad.profile.ref.ProfileReferenceManager; import de.tobias.playpad.project.Project; @@ -71,7 +71,7 @@ public class PlayPadMain extends Application { ApplicationUtils.addAppListener(PlayPadMain::applicationWillStart); App app = ApplicationUtils.registerMainApplication(PlayPadMain.class); - ApplicationUtils.registerUpdateSercive(new VersionUpdater()); + ApplicationUtils.registerUpdateService(new VersionUpdater()); app.start(args); } @@ -108,7 +108,7 @@ public class PlayPadMain extends Application { impl.setIcon(stageIcon, getClass().getClassLoader().getResourceAsStream(ICON_PATH)); PlayPadPlugin.setStyleable(new ModernStyleableImpl()); - impl.setModernDesign(new ModernDesignHandlerImpl()); + impl.setModernDesign(new ModernDesignProviderImpl()); PlayPadPlugin.setInstance(impl); } diff --git a/PlayWall/src/main/java/de/tobias/playpad/Strings.java b/PlayWall/src/main/java/de/tobias/playpad/Strings.java index e71f1944b156d2853018669b92e0ba6366fa9595..e7dd1a751648d3da1ab832cd2b6f0f2009a39886 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/Strings.java +++ b/PlayWall/src/main/java/de/tobias/playpad/Strings.java @@ -183,6 +183,7 @@ public class Strings { public static final String ACTION_PAGE_TO_STRING = "Action.Page.toString"; public static final String ACTION_NAVIGATE_TO_STRING = "Action.Navigate.toString"; public static final String ACTION_CART_NAME = "Action.Cart.Name"; + public static final String ACTION_PLAYLIST_NEXT_NAME = "Action.PlaylistNext.Name"; public static final String ACTION_STOP_NAME = "Action.Stop.Name"; public static final String ACTION_PAGE_NAME = "Action.Page.Name"; public static final String ACTION_NAVIGATE_NAME = "Action.Navigate.Name"; diff --git a/PlayWall/src/main/java/de/tobias/playpad/action/actions/PlaylistNextAction.java b/PlayWall/src/main/java/de/tobias/playpad/action/actions/PlaylistNextAction.java new file mode 100644 index 0000000000000000000000000000000000000000..0ed0a95fdd2436fcdea5ecd5c5e2df2152f6ec1c --- /dev/null +++ b/PlayWall/src/main/java/de/tobias/playpad/action/actions/PlaylistNextAction.java @@ -0,0 +1,80 @@ +package de.tobias.playpad.action.actions; + +import de.thecodelabs.midi.action.Action; +import de.thecodelabs.midi.action.ActionHandler; +import de.thecodelabs.midi.event.KeyEvent; +import de.thecodelabs.midi.feedback.FeedbackType; +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.content.Playlistable; +import de.tobias.playpad.project.Project; +import de.tobias.playpad.viewcontroller.main.IMainViewController; + +public class PlaylistNextAction extends ActionHandler { + public static final String TYPE = "PlaylistNextAction"; + public static final String PAYLOAD_X = "x"; + public static final String PAYLOAD_Y = "y"; + + @Override + public String actionType() { + return TYPE; + } + + @Override + public FeedbackType handle(KeyEvent keyEvent, Action action) { + final Pad pad = getPad(action); + if (pad == null) { + return FeedbackType.NONE; + } + + if (pad.hasVisibleContent() && pad.getContent() instanceof Playlistable) { + ((Playlistable) pad.getContent()).next(); + } + return getCurrentFeedbackType(action); + } + + @Override + public FeedbackType getCurrentFeedbackType(Action action) { + Project project = PlayPadPlugin.getInstance().getCurrentProject(); + IMainViewController mainViewController = PlayPadPlugin.getInstance().getMainViewController(); + + Pad pad = project.getPad(getX(action), getY(action), mainViewController.getPage()); + + if (pad == null || !(pad.getContent() instanceof Playlistable)) { + return FeedbackType.NONE; + } + return FeedbackType.DEFAULT; + } + + public Pad getPad(Action action) { + Project project = PlayPadPlugin.getInstance().getCurrentProject(); + IMainViewController mainViewController = PlayPadPlugin.getInstance().getMainViewController(); + + int x = getX(action); + int y = getY(action); + final int page = mainViewController.getPage(); + + return project.getPad(x, y, page); + } + + /* + Property accessors + */ + + public static int getY(Action action) { + return Integer.parseInt(action.getPayload(PAYLOAD_Y)); + } + + public static int getX(Action action) { + return Integer.parseInt(action.getPayload(PAYLOAD_X)); + } + + public static void setX(Action action, int x) { + action.addPayloadEntry(CartAction.PAYLOAD_X, String.valueOf(x)); + } + + public static void setY(Action action, int y) { + action.addPayloadEntry(CartAction.PAYLOAD_Y, String.valueOf(y)); + } + +} diff --git a/PlayWall/src/main/java/de/tobias/playpad/action/factory/CartActionProvider.java b/PlayWall/src/main/java/de/tobias/playpad/action/factory/CartActionProvider.java index 7b078335255b168e0d61f42051ea0ab5cea69afd..43e38b7c61c6d0badc69bb0fcd92c15bfdc6deff 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/action/factory/CartActionProvider.java +++ b/PlayWall/src/main/java/de/tobias/playpad/action/factory/CartActionProvider.java @@ -8,7 +8,6 @@ import de.thecodelabs.midi.mapping.KeyType; import de.tobias.playpad.action.ActionProvider; import de.tobias.playpad.action.ActionType; import de.tobias.playpad.action.actions.CartAction; -import de.tobias.playpad.action.actions.CartAction.*; import de.tobias.playpad.action.settings.ActionSettingsEntry; import de.tobias.playpad.action.settings.CartActionSettingsEntry; import de.tobias.playpad.project.ProjectSettings; diff --git a/PlayWall/src/main/java/de/tobias/playpad/action/factory/PlaylistNextActionProvider.java b/PlayWall/src/main/java/de/tobias/playpad/action/factory/PlaylistNextActionProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..f317e7e0b7ab25ca1cb21348373e457f03bb4dd9 --- /dev/null +++ b/PlayWall/src/main/java/de/tobias/playpad/action/factory/PlaylistNextActionProvider.java @@ -0,0 +1,73 @@ +package de.tobias.playpad.action.factory; + +import de.thecodelabs.midi.Mapping; +import de.thecodelabs.midi.action.Action; +import de.thecodelabs.midi.action.ActionHandler; +import de.thecodelabs.midi.feedback.FeedbackType; +import de.thecodelabs.midi.mapping.KeyType; +import de.tobias.playpad.action.ActionProvider; +import de.tobias.playpad.action.ActionType; +import de.tobias.playpad.action.actions.PlaylistNextAction; +import de.tobias.playpad.action.settings.ActionSettingsEntry; +import de.tobias.playpad.action.settings.PlaylistNextActionSettingsEntry; +import de.tobias.playpad.project.ProjectSettings; +import javafx.scene.control.TreeItem; + +import java.util.List; + +import static de.tobias.playpad.action.actions.PlaylistNextAction.*; + +public class PlaylistNextActionProvider extends ActionProvider { + + public PlaylistNextActionProvider(String type) { + super(TYPE); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public ActionHandler getActionHandler() { + return new PlaylistNextAction(); + } + + @Override + public void createDefaultActions(Mapping mapping) { + for (int x = 0; x < ProjectSettings.MAX_COLUMNS; x++) { + for (int y = 0; y < ProjectSettings.MAX_ROWS; y++) { + Action action = newInstance(x, y); + mapping.addUniqueAction(action); + } + } + } + + private Action newInstance(int x, int y) { + Action action = new Action(getType()); + action.addPayloadEntry(PAYLOAD_X, String.valueOf(x)); + action.addPayloadEntry(PAYLOAD_Y, String.valueOf(y)); + return action; + } + + @Override + public FeedbackType[] supportedFeedbackOptions(Action action, KeyType keyType) { + switch (keyType) { + case KEYBOARD: + return new FeedbackType[0]; + case MIDI: + return new FeedbackType[]{FeedbackType.DEFAULT}; + } + return new FeedbackType[0]; + } + + @Override + public ActionType getActionType() { + return ActionType.CONTROL; + } + + @Override + public TreeItem<ActionSettingsEntry> getTreeItemForActions(List<Action> actions, Mapping mapping) { + return new TreeItem<>(new PlaylistNextActionSettingsEntry()); + } +} diff --git a/PlayWall/src/main/java/de/tobias/playpad/action/settings/CartActionSettingsEntry.java b/PlayWall/src/main/java/de/tobias/playpad/action/settings/CartActionSettingsEntry.java index ea3451324c18430407d74b4a7ab10b698748057a..725a321b99527e0f06e4ce99adb1739040a332b7 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/action/settings/CartActionSettingsEntry.java +++ b/PlayWall/src/main/java/de/tobias/playpad/action/settings/CartActionSettingsEntry.java @@ -5,8 +5,10 @@ import de.thecodelabs.utils.ui.NVC; import de.thecodelabs.utils.ui.icon.FontIcon; import de.thecodelabs.utils.util.Localization; import de.tobias.playpad.Strings; +import de.tobias.playpad.action.actions.CartAction; import de.tobias.playpad.viewcontroller.IMappingTabViewController; import de.tobias.playpad.viewcontroller.actions.CartActionTypeViewController; +import de.tobias.playpad.viewcontroller.actions.CartActionViewController; public class CartActionSettingsEntry implements ActionSettingsEntry { @@ -22,6 +24,6 @@ public class CartActionSettingsEntry implements ActionSettingsEntry { @Override public NVC getDetailSettingsController(Mapping mapping, IMappingTabViewController controller) { - return new CartActionTypeViewController(mapping, controller); + return new CartActionTypeViewController(mapping, controller, CartAction.TYPE, new CartActionViewController()); } } diff --git a/PlayWall/src/main/java/de/tobias/playpad/action/settings/PlaylistNextActionSettingsEntry.java b/PlayWall/src/main/java/de/tobias/playpad/action/settings/PlaylistNextActionSettingsEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..8548c9d59ec156307007d3d212e249123ab46866 --- /dev/null +++ b/PlayWall/src/main/java/de/tobias/playpad/action/settings/PlaylistNextActionSettingsEntry.java @@ -0,0 +1,28 @@ +package de.tobias.playpad.action.settings; + +import de.thecodelabs.midi.Mapping; +import de.thecodelabs.utils.ui.NVC; +import de.thecodelabs.utils.ui.icon.FontIcon; +import de.thecodelabs.utils.util.Localization; +import de.tobias.playpad.Strings; +import de.tobias.playpad.action.actions.PlaylistNextAction; +import de.tobias.playpad.viewcontroller.IMappingTabViewController; +import de.tobias.playpad.viewcontroller.actions.CartActionTypeViewController; + +public class PlaylistNextActionSettingsEntry implements ActionSettingsEntry { + + @Override + public String getName() { + return Localization.getString(Strings.ACTION_PLAYLIST_NEXT_NAME); + } + + @Override + public FontIcon getIcon() { + return null; + } + + @Override + public NVC getDetailSettingsController(Mapping mapping, IMappingTabViewController controller) { + return new CartActionTypeViewController(mapping, controller, PlaylistNextAction.TYPE); + } +} diff --git a/PlayWall/src/main/java/de/tobias/playpad/design/ModernDesignHandlerImpl.java b/PlayWall/src/main/java/de/tobias/playpad/design/ModernDesignProviderImpl.java similarity index 63% rename from PlayWall/src/main/java/de/tobias/playpad/design/ModernDesignHandlerImpl.java rename to PlayWall/src/main/java/de/tobias/playpad/design/ModernDesignProviderImpl.java index 4d14df99a3f684c79a02dbfa75b37b259b20a9ff..c1d2a5521b5de332a8efdfc3f2eaac933dcc6117 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/design/ModernDesignHandlerImpl.java +++ b/PlayWall/src/main/java/de/tobias/playpad/design/ModernDesignProviderImpl.java @@ -2,12 +2,22 @@ package de.tobias.playpad.design; import de.tobias.playpad.design.modern.ModernCartDesignHandler; import de.tobias.playpad.design.modern.ModernGlobalDesignHandler; +import de.tobias.playpad.design.modern.ModernWarningDesignHandler; -public class ModernDesignHandlerImpl implements ModernDesignHandler { +public class ModernDesignProviderImpl implements ModernDesignProvider { + private ModernWarningDesignHandler warningHandler; private ModernCartDesignHandler cartDesignHandler; private ModernGlobalDesignHandler globalDesignHandler; + @Override + public ModernWarningDesignHandler warning() { + if (warningHandler == null) { + warningHandler = new ModernWarningDesignHandlerImpl(); + } + return warningHandler; + } + @Override public ModernGlobalDesignHandler global() { if (globalDesignHandler == null) { diff --git a/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializeTask.java b/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializeTask.java index c979364d11375530570ee5ae60705a9c9e89e194..012c8173a7d06cf73908f455c0a32073f8f8c180 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializeTask.java +++ b/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializeTask.java @@ -5,5 +5,6 @@ import de.tobias.playpad.PlayPadImpl; public interface PlayPadInitializeTask { String name(); + void run(App app, PlayPadImpl instance); } diff --git a/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializer.java b/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializer.java index a5189df3e1c29916b5a0c1baa9fe6b5cccaf4399..133ef5b9110634ecd6a793e8fa618858181a3a80 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializer.java +++ b/PlayWall/src/main/java/de/tobias/playpad/initialize/PlayPadInitializer.java @@ -43,7 +43,7 @@ public class PlayPadInitializer implements Runnable { Thread thread = new Thread(this); thread.setName("PlayPad Initializer Thread"); thread.setUncaughtExceptionHandler((t, e) -> { - e.printStackTrace(); + Logger.error(e); }); thread.start(); } diff --git a/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/DesktopColorPickerView.java b/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/DesktopColorPickerView.java index b71c1305615c898f1db7f4d3bf7d5f443116c5a9..0e3de9499da41130e72e786773960f9a09cccd8e 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/DesktopColorPickerView.java +++ b/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/DesktopColorPickerView.java @@ -66,11 +66,11 @@ public class DesktopColorPickerView implements Consumer<DisplayableColor>, Event PadSettings padSettings = pad.getPadSettings(); if (event.getButton() == MouseButton.PRIMARY) { - padSettings.setCustomDesign(true); ModernCartDesign design = padSettings.getDesign(); + design.setEnableCustomBackgroundColor(true); colorModeHandler.setColor(design, selectedColor); } else if (event.getButton() == MouseButton.SECONDARY) { - padSettings.setCustomDesign(false); + padSettings.getDesign().setEnableCustomBackgroundColor(false); } PlayPadMain.getProgramInstance().getMainViewController().loadUserCss(); } diff --git a/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadView.java b/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadView.java index e1489f3445343db9ef7b1b3a46be0e6030a8f690..89968e77a9c79ae23d8d5f6f54728f2f2d791042 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadView.java +++ b/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadView.java @@ -8,6 +8,7 @@ import de.thecodelabs.utils.ui.scene.BusyView; import de.thecodelabs.utils.util.ColorUtils; import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.design.FeedbackDesignColorSuggester; +import de.tobias.playpad.design.modern.model.ModernCartDesign; import de.tobias.playpad.layout.desktop.DesktopMainLayoutFactory; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.pad.PadStatus; @@ -354,19 +355,18 @@ public class DesktopPadView implements IPadView { @Override public void showNotFoundIcon(Pad pad, boolean show) { if (show) { - FeedbackDesignColorSuggester associator; - if (pad.getPadSettings().isCustomDesign()) { - associator = pad.getPadSettings().getDesign(); - } else { - associator = Profile.currentProfile().getProfileSettings().getDesign(); - } + FeedbackDesignColorSuggester globalDesign = Profile.currentProfile().getProfileSettings().getDesign(); + Color layoutStdColor = globalDesign.getDesignDefaultColor(); - if (associator != null) { - Color color = associator.getDesignDefaultColor(); - notFoundLabel.setColor(ColorUtils.getAppropriateTextColor(color)); - } else { - notFoundLabel.setColor(Color.RED); + if (pad != null) { + final ModernCartDesign padDesign = pad.getPadSettings().getDesign(); + + if (padDesign.isEnableCustomBackgroundColor()) { + layoutStdColor = padDesign.getDesignDefaultColor(); + } } + + notFoundLabel.setColor(ColorUtils.getAppropriateTextColor(layoutStdColor)); } notFoundLabel.setVisible(show); root.setOpacity(show ? 0.5 : 1.0); diff --git a/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadViewController.java b/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadViewController.java index e9db0c64517458e0beb171adaafc133d4638e9f6..4791b906a5d4591b612e9729a1d27558fb13106c 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/layout/desktop/pad/DesktopPadViewController.java @@ -34,6 +34,8 @@ public class DesktopPadViewController extends AbstractPadViewController implemen private final DesktopPadView padView; private Pad pad; + private PadSettingsViewController padSettingsViewController; + private final PadLockedListener padLockedListener; private final PadStatusListener padStatusListener; private final PadContentListener padContentListener; @@ -204,21 +206,26 @@ public class DesktopPadViewController extends AbstractPadViewController implemen } private void onSettings() { - GlobalSettings settings = PlayPadPlugin.getInstance().getGlobalSettings(); - IMainViewController mvc = PlayPadPlugin.getInstance().getMainViewController(); + final GlobalSettings globalSettings = PlayPadPlugin.getInstance().getGlobalSettings(); + final IMainViewController mvc = PlayPadPlugin.getInstance().getMainViewController(); if (mvc != null) { - if (pad.getProject() != null && settings.isLiveMode() && settings.isLiveModeSettings() && pad.getProject().getActivePlayers() > 0) { + if (pad.getProject() != null && globalSettings.isLiveMode() && globalSettings.isLiveModeSettings() && pad.getProject().getActivePlayers() > 0) { return; } - PadSettingsViewController padSettingsViewController = new PadSettingsViewController(pad, mvc); - padSettingsViewController.getStageContainer().ifPresent(nvcStage -> nvcStage.addCloseHook(() -> { - if (padView != null && pad != null) - padView.setTriggerLabelActive(pad.getPadSettings().hasTriggerItems()); - return true; - })); - padSettingsViewController.getStageContainer().ifPresent(NVCStage::show); + if (padSettingsViewController == null) { + padSettingsViewController = new PadSettingsViewController(pad, mvc); + padSettingsViewController.getStageContainer().ifPresent(nvcStage -> nvcStage.addCloseHook(() -> { + if (padView != null && pad != null) + padView.setTriggerLabelActive(pad.getPadSettings().hasTriggerItems()); + padSettingsViewController = null; + return true; + })); + padSettingsViewController.getStageContainer().ifPresent(NVCStage::show); + } else { + padSettingsViewController.getStageContainer().ifPresent(stage -> stage.getStage().toFront()); + } } } diff --git a/PlayWall/src/main/java/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java b/PlayWall/src/main/java/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java index 51f0e31995aa4d5ab5744a4fde399b749e1a73c0..3fb75001df01637862485a3527bba1ff909218f0 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java @@ -157,7 +157,6 @@ public class TouchMenuToolbarViewController extends BasicMenuToolbarViewControll } @Override - public void initLayoutMenu() - { + public void initLayoutMenu() { } } \ No newline at end of file diff --git a/PlayWall/src/main/java/de/tobias/playpad/layout/touch/pad/TouchPadView.java b/PlayWall/src/main/java/de/tobias/playpad/layout/touch/pad/TouchPadView.java index c9f233e15d351c154a65fd41e47ad3f2f9196eb2..4ba78420683b47d6ee938cf836364b085f80261d 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/layout/touch/pad/TouchPadView.java +++ b/PlayWall/src/main/java/de/tobias/playpad/layout/touch/pad/TouchPadView.java @@ -10,6 +10,7 @@ import de.thecodelabs.utils.util.OS; import de.thecodelabs.utils.util.win.User32X; import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.design.FeedbackDesignColorSuggester; +import de.tobias.playpad.design.modern.model.ModernCartDesign; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.pad.content.PadContent; import de.tobias.playpad.pad.content.PadContentFactory; @@ -284,19 +285,18 @@ public class TouchPadView implements IPadView { @Override public void showNotFoundIcon(Pad pad, boolean show) { if (show) { - FeedbackDesignColorSuggester associator = null; - if (pad.getPadSettings().isCustomDesign()) { - associator = pad.getPadSettings().getDesign(); - } else { - associator = Profile.currentProfile().getProfileSettings().getDesign(); - } + FeedbackDesignColorSuggester globalDesign = Profile.currentProfile().getProfileSettings().getDesign(); + Color layoutStdColor = globalDesign.getDesignDefaultColor(); + + if (pad != null) { + final ModernCartDesign padDesign = pad.getPadSettings().getDesign(); - if (associator != null) { - Color color = associator.getDesignDefaultColor(); - notFoundLabel.setColor(ColorUtils.getAppropriateTextColor(color)); - } else { - notFoundLabel.setColor(Color.RED); + if (padDesign.isEnableCustomBackgroundColor()) { + layoutStdColor = padDesign.getDesignDefaultColor(); + } } + + notFoundLabel.setColor(ColorUtils.getAppropriateTextColor(layoutStdColor)); } notFoundLabel.setVisible(show); root.setOpacity(show ? 0.5 : 1.0); diff --git a/PlayWall/src/main/java/de/tobias/playpad/pad/listener/PadPositionListener.java b/PlayWall/src/main/java/de/tobias/playpad/pad/listener/PadPositionListener.java index 5326b5f914229d7a4e1b9499bb44c01234d00ecf..4feab061bd425d30897b40219658216fcaca8690 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/pad/listener/PadPositionListener.java +++ b/PlayWall/src/main/java/de/tobias/playpad/pad/listener/PadPositionListener.java @@ -2,9 +2,8 @@ package de.tobias.playpad.pad.listener; import de.tobias.playpad.PlayPadMain; import de.tobias.playpad.action.actions.CartAction; -import de.tobias.playpad.design.ModernDesignHandler; -import de.tobias.playpad.design.modern.ModernCartDesignHandler; -import de.tobias.playpad.design.modern.ModernGlobalDesignHandler; +import de.tobias.playpad.design.ModernDesignProvider; +import de.tobias.playpad.design.modern.ModernWarningDesignHandler; import de.tobias.playpad.design.modern.model.ModernCartDesign; import de.tobias.playpad.design.modern.model.ModernGlobalDesign; import de.tobias.playpad.pad.Pad; @@ -21,7 +20,7 @@ import javafx.util.Duration; public class PadPositionListener implements Runnable, IPadPositionListener { private Pad pad; - private AbstractPadViewController controller; + private final AbstractPadViewController controller; public PadPositionListener(AbstractPadViewController controller) { this.controller = controller; @@ -104,21 +103,16 @@ public class PadPositionListener implements Runnable, IPadPositionListener { */ @Override public void run() { - PadSettings padSettings = pad.getPadSettings(); - Duration warning = padSettings.getWarning(); + final PadSettings padSettings = pad.getPadSettings(); + final Duration warningDuration = padSettings.getWarning(); - ModernGlobalDesign globalDesign = Profile.currentProfile().getProfileSettings().getDesign(); - final ModernDesignHandler modernDesign = PlayPadMain.getProgramInstance().getModernDesign(); + final ModernGlobalDesign globalDesign = Profile.currentProfile().getProfileSettings().getDesign(); + final ModernCartDesign cartDesign = padSettings.getDesign(); - if (padSettings.isCustomDesign()) { - ModernCartDesignHandler handler = modernDesign.cart(); - ModernCartDesign design = pad.getPadSettings().getDesign(); + final ModernDesignProvider modernDesign = PlayPadMain.getProgramInstance().getModernDesign(); - handler.handleWarning(design, controller, warning, globalDesign); - } else { - ModernGlobalDesignHandler handler = modernDesign.global(); - handler.handleWarning(globalDesign, controller, warning); - } + final ModernWarningDesignHandler handler = modernDesign.warning(); + handler.handleWarning(globalDesign, cartDesign, controller, warningDuration); } private void startWarningThread() { @@ -136,20 +130,10 @@ public class PadPositionListener implements Runnable, IPadPositionListener { warningThread = null; } - PadSettings padSettings = pad.getPadSettings(); - final ModernDesignHandler modernDesign = PlayPadMain.getProgramInstance().getModernDesign(); - - if (padSettings.isCustomDesign()) { - ModernCartDesignHandler handler = modernDesign.cart(); - ModernCartDesign design = pad.getPadSettings().getDesign(); + final ModernDesignProvider modernDesign = PlayPadMain.getProgramInstance().getModernDesign(); - handler.stopWarning(design, controller); - } else { - ModernGlobalDesignHandler handler = modernDesign.global(); - ModernGlobalDesign globalDesign = Profile.currentProfile().getProfileSettings().getDesign(); - - handler.stopWarning(globalDesign, controller); - } + final ModernWarningDesignHandler handler = modernDesign.warning(); + handler.stopWarning(controller); controller.getView().setStyle(""); } } diff --git a/PlayWall/src/main/java/de/tobias/playpad/project/ProjectJsonReader.java b/PlayWall/src/main/java/de/tobias/playpad/project/ProjectJsonReader.java index 6f33e38af123e5c80346b484ffed63211fee6171..29030b5abfe80efd80615cf5ac5385cb5b371ca5 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/project/ProjectJsonReader.java +++ b/PlayWall/src/main/java/de/tobias/playpad/project/ProjectJsonReader.java @@ -78,7 +78,6 @@ public class ProjectJsonReader { ModernCartDesign design = readModernCartDesign(pad, object.getJSONObject("design")); if (design != null) { pad.getPadSettings().setDesign(design); - pad.getPadSettings().setCustomDesign(true); // TODO Sync } } @@ -101,7 +100,11 @@ public class ProjectJsonReader { ModernColor backgroundColor = ModernColor.valueOf(object.getString("background_color")); ModernColor playColor = ModernColor.valueOf(object.getString("play_color")); - return new ModernCartDesign(pad, id, backgroundColor, playColor, ModernColor.RED2); // TODO Fix Cue In Color + return new ModernCartDesign.ModernCartDesignBuilder(pad, id) + .withBackgroundColor(backgroundColor, false) + .withPlayColor(playColor, false) + .withCueInColor(ModernColor.RED2, false) + .build(); // TODO Fix Cue In Color } return null; } diff --git a/PlayWall/src/main/java/de/tobias/playpad/trigger/VolumeTriggerItem.java b/PlayWall/src/main/java/de/tobias/playpad/trigger/VolumeTriggerItem.java index 667c4aa90b0cb045c1655a0ccea97a897061979a..96c9ca10899eb9ec564720a974414acce4d05f1c 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/trigger/VolumeTriggerItem.java +++ b/PlayWall/src/main/java/de/tobias/playpad/trigger/VolumeTriggerItem.java @@ -59,11 +59,11 @@ public class VolumeTriggerItem extends TriggerItem { uuids.stream().map(project::getPad) .filter(i -> i.getContent() instanceof Fadeable) .forEach(destination -> { - Fadeable fadeable = (Fadeable) destination.getContent(); + Fadeable fadeable = (Fadeable) destination.getContent(); - final double start = VolumeManager.getInstance().computeVolume(destination); - fadeable.fade(start, volume, duration, null); - }); + final double start = VolumeManager.getInstance().computeVolume(destination); + fadeable.fade(start, volume, duration, null); + }); } @Override diff --git a/PlayWall/src/main/java/de/tobias/playpad/update/VersionUpdater.java b/PlayWall/src/main/java/de/tobias/playpad/update/VersionUpdater.java index b5f7c5be9793d58da416f0c68334c94194d36afe..dbdd1e078924b043429b4edcd07256d607cce639 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/update/VersionUpdater.java +++ b/PlayWall/src/main/java/de/tobias/playpad/update/VersionUpdater.java @@ -1,13 +1,91 @@ package de.tobias.playpad.update; +import de.thecodelabs.logger.Logger; import de.thecodelabs.utils.application.App; +import de.thecodelabs.utils.application.container.PathType; import de.thecodelabs.utils.application.update.UpdateService; +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.SAXReader; +import org.dom4j.io.XMLWriter; -public class VersionUpdater implements UpdateService { +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.UUID; +public class VersionUpdater implements UpdateService { @Override public void update(App app, long oldVersion, long newVersion) { + try { + if (oldVersion < 44) { + updateTo44(app); + } + } catch (Exception e) { + Logger.error(e); + } + } + + private void updateTo44(App app) throws DocumentException, IOException { + Logger.debug("Updating to app version 44..."); + SAXReader reader = new SAXReader(); + + Document projectsDocument = reader.read(Files.newInputStream(app.getPath(PathType.CONFIGURATION, "Projects.xml"))); + for (Element element : projectsDocument.getRootElement().elements("Project")) { + final String projectName = element.attributeValue("name"); + final UUID projectUUID = UUID.fromString(element.attributeValue("uuid")); + + Logger.debug(MessageFormat.format("Updating project \"{0}\" (id: {1})...", projectName, projectUUID)); + Path projectPath = app.getPath(PathType.DOCUMENTS, projectUUID.toString() + ".xml"); + final Document migratedProject = updateProject(Files.newInputStream(projectPath)); + + XMLWriter writer = new XMLWriter(Files.newOutputStream(projectPath), OutputFormat.createPrettyPrint()); + writer.write(migratedProject); + writer.close(); + } } + public static Document updateProject(InputStream projectInputStream) throws DocumentException { + SAXReader reader = new SAXReader(); + + Document projectDocument = reader.read(projectInputStream); + Element rootProjectElement = projectDocument.getRootElement(); + + for (Element page : rootProjectElement.elements()) { + for (Element pad : page.elements()) { + final Element settings = pad.element("Settings"); + if (settings == null) { + continue; + } + + final Element designElement = settings.element("Design"); + if (designElement == null) { + continue; + } + + final Attribute customFlag = designElement.attribute("custom"); + if (customFlag == null) { + continue; + } + + designElement.remove(customFlag); + + if (customFlag.getValue().equals("false")) { + continue; + } + + designElement.addElement("EnableCustomBackgroundColor").addText("true"); + designElement.addElement("EnableCustomPlayColor").addText("true"); + designElement.addElement("EnableCustomCueInColor").addText("true"); + } + } + + return projectDocument; + } } diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/AbstractActionViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/AbstractActionViewController.java new file mode 100644 index 0000000000000000000000000000000000000000..6f378756b825dd501e3eb97fbabb9bbe99341939 --- /dev/null +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/AbstractActionViewController.java @@ -0,0 +1,8 @@ +package de.tobias.playpad.viewcontroller.actions; + +import de.thecodelabs.midi.action.Action; +import de.thecodelabs.utils.ui.NVC; + +public abstract class AbstractActionViewController extends NVC { + public abstract void setCartAction(Action action); +} diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionTypeViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionTypeViewController.java index 8573b914f06060b1e035a45d13907bb55378f629..ee1dda9212e66fe9acc5ab4a1916a74445d94ab1 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionTypeViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionTypeViewController.java @@ -17,7 +17,9 @@ import javafx.scene.control.ToggleGroup; import javafx.scene.layout.*; import org.controlsfx.control.SegmentedButton; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; /** * Diese View ist die Basis für die Einstellunge für eine CartAction. Dabei enthällt diese View ein Grid aus Buttons (Carts), eine @@ -36,17 +38,24 @@ public class CartActionTypeViewController extends NVC { @FXML private VBox cartActionContainer; - private CartActionViewController cartActionViewController; + private final AbstractActionViewController actionViewController; + private final String actionType; - private Mapping mapping; - private IMappingTabViewController parentController; + private final Mapping mapping; + private final IMappingTabViewController parentController; - public CartActionTypeViewController(Mapping mapping, IMappingTabViewController parentController) { + + public CartActionTypeViewController(Mapping mapping, IMappingTabViewController parentController, String actionType) { + this(mapping, parentController, actionType, null); + } + + public CartActionTypeViewController(Mapping mapping, IMappingTabViewController parentController, String actionType, AbstractActionViewController actionViewController) { load("view/actions", "CartActions", Localization.getBundle()); this.mapping = mapping; this.parentController = parentController; - cartActionViewController = new CartActionViewController(); + this.actionType = actionType; + this.actionViewController = actionViewController; Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject(); ProjectSettings settings = currentProject.getSettings(); @@ -106,15 +115,21 @@ public class CartActionTypeViewController extends NVC { int currentY = data[1]; try { - List<Action> cartActions = mapping.getActionsForType(CartAction.TYPE); - for (Action action : cartActions) { - if (CartAction.getX(action) == currentX && CartAction.getY(action) == currentY) { - cartActionContainer.getChildren().setAll(cartActionViewController.getParent()); - cartActionContainer.setVisible(true); - cartActionViewController.setCartAction(action); - parentController.showMapperFor(action); - } + final List<Action> cartActions = mapping.getActionsForType(actionType).stream() + .filter(action -> CartAction.getX(action) == currentX && CartAction.getY(action) == currentY) + .collect(Collectors.toList()); + + if (cartActions.size() > 1) { + throw new IllegalArgumentException("Only one action allowed per pad. Currently " + cartActions.size() + " are registered for pad coordinate " + Arrays.toString(data)); + } + + final Action action = cartActions.get(0); + if (actionViewController != null) { + cartActionContainer.getChildren().setAll(actionViewController.getParent()); + cartActionContainer.setVisible(true); + actionViewController.setCartAction(action); } + parentController.showMapperFor(action); } catch (NoSuchComponentException e) { Logger.error(e); } diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionViewController.java index b43977c2420ae78ac8bb1ca86e4585a88e847088..e3fe4664112f86babef0a24a3ce16e1f4c1c2159 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/actions/CartActionViewController.java @@ -1,7 +1,6 @@ package de.tobias.playpad.viewcontroller.actions; import de.thecodelabs.midi.action.Action; -import de.thecodelabs.utils.ui.NVC; import de.thecodelabs.utils.util.Localization; import de.tobias.playpad.Strings; import de.tobias.playpad.action.actions.CartAction; @@ -13,7 +12,7 @@ import javafx.scene.control.ComboBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; -public class CartActionViewController extends NVC { +public class CartActionViewController extends AbstractActionViewController { @FXML private ComboBox<CartActionMode> controlMode; @@ -41,6 +40,7 @@ public class CartActionViewController extends NVC { VBox.setVgrow(rootContainer, Priority.ALWAYS); } + @Override public void setCartAction(Action action) { this.action = action; diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java index fbf39d6b0e6d113d1b5d08bcf1852194f17f2e02..57d922e1253e9bcad2fb833cff26edcc37d6f416 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java @@ -17,6 +17,13 @@ import java.util.function.Consumer; public class ModernCartDesignViewController extends NVC implements IColorButton { + @FXML + private CheckBox backgroundColorCheckbox; + @FXML + private CheckBox playColorCheckbox; + @FXML + private CheckBox cueInColorCheckbox; + @FXML private Button backgroundColorButton; @FXML @@ -29,25 +36,49 @@ public class ModernCartDesignViewController extends NVC implements IColorButton @FXML private Button resetButton; - private ModernCartDesign design; + private final ModernCartDesign design; private PopOver colorChooser; - public ModernCartDesignViewController(ModernCartDesign layout) { + public ModernCartDesignViewController(ModernCartDesign design) { load("view/option/layout", "ModernLayoutCart", Localization.getBundle()); - this.design = layout; - setLayout(); + this.design = design; + setDesign(); } - private void setLayout() { + private void setDesign() { backgroundColorButton.setStyle(getLinearGradientCss(design.getBackgroundColor())); playColorButton.setStyle(getLinearGradientCss(design.getPlayColor())); cueInColorButton.setStyle(getLinearGradientCss(design.getCueInColor())); + + backgroundColorCheckbox.setSelected(design.isEnableCustomBackgroundColor()); + playColorCheckbox.setSelected(design.isEnableCustomPlayColor()); + cueInColorCheckbox.setSelected(design.isEnableCustomCueInColor()); } @Override public void init() { + backgroundColorCheckbox.selectedProperty().addListener((observable, oldValue, newValue) -> + { + design.setEnableCustomBackgroundColor(newValue); + backgroundColorButton.setDisable(!newValue); + }); + playColorCheckbox.selectedProperty().addListener((observable, oldValue, newValue) -> + { + design.setEnableCustomPlayColor(newValue); + playColorButton.setDisable(!newValue); + }); + cueInColorCheckbox.selectedProperty().addListener((observable, oldValue, newValue) -> + { + design.setEnableCustomCueInColor(newValue); + cueInColorButton.setDisable(!newValue); + }); + + backgroundColorButton.setDisable(true); + playColorButton.setDisable(true); + cueInColorButton.setDisable(true); + addIconToButton(backgroundColorButton); addIconToButton(playColorButton); addIconToButton(cueInColorButton); @@ -56,22 +87,22 @@ public class ModernCartDesignViewController extends NVC implements IColorButton @FXML private void resetButtonHandler(ActionEvent event) { design.reset(); - setLayout(); + setDesign(); } @FXML private void backgroundColorButtonHandler(ActionEvent event) { - colorChooser(backgroundColorButton, design.getBackgroundColor(), color -> design.setBackgroundColor(color)); + colorChooser(backgroundColorButton, design.getBackgroundColor(), design::setBackgroundColor); } @FXML private void playColorButtonHandler(ActionEvent event) { - colorChooser(playColorButton, design.getPlayColor(), color -> design.setPlayColor(color)); + colorChooser(playColorButton, design.getPlayColor(), design::setPlayColor); } @FXML private void cueInColorButtonHandler(ActionEvent event) { - colorChooser(cueInColorButton, design.getPlayColor(), color -> design.setCueInColor(color)); + colorChooser(cueInColorButton, design.getPlayColor(), design::setCueInColor); } private void colorChooser(Button anchorNode, ModernColor startColor, Consumer<ModernColor> onFinish) { @@ -101,5 +132,4 @@ public class ModernCartDesignViewController extends NVC implements IColorButton return "-fx-background-color: " + color.linearGradient() + ";"; } } - } diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/dialog/ModernPluginViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/dialog/ModernPluginViewController.java index 63e4ba8a4d673f84251840133cde64e92b98eab3..404bd0b40960162ecec8d5fd7a4f0dad526c2aa7 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/dialog/ModernPluginViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/dialog/ModernPluginViewController.java @@ -119,10 +119,9 @@ public class ModernPluginViewController extends NVC implements ChangeListener<Mo pluginList.getSelectionModel().selectedItemProperty().addListener(this); searchField.textProperty().addListener((observable, oldValue, newValue) -> { - if(newValue == null || newValue.length() == 0) { + if (newValue == null || newValue.length() == 0) { filteredData.setPredicate(s -> true); - } - else { + } else { filteredData.setPredicate(p -> p.getDisplayName().contains(newValue)); } }); diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/AutosaveRunner.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/AutosaveRunner.java index bffc1481226896694b9aad6683c047cc5b389b41..798e1d6bfef655758abb566b1fda26b180c73cf9 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/AutosaveRunner.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/AutosaveRunner.java @@ -6,32 +6,26 @@ import de.tobias.playpad.PlayPadPlugin; import java.text.SimpleDateFormat; import java.util.Date; -public class AutosaveRunner implements Runnable -{ +public class AutosaveRunner implements Runnable { private final MainViewController mainViewController; - public AutosaveRunner(MainViewController mainViewController) - { + public AutosaveRunner(MainViewController mainViewController) { this.mainViewController = mainViewController; } @Override - public void run() - { + public void run() { long lastSaveTime = System.currentTimeMillis(); final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - while(!Thread.interrupted()) - { + while (!Thread.interrupted()) { final long currentMillis = System.currentTimeMillis(); // autosave interval may be changed by user in global settings, therefore the current setting needs to be fetched every time - if(currentMillis > lastSaveTime + getAutosaveIntervalInMillis()) - { + if (currentMillis > lastSaveTime + getAutosaveIntervalInMillis()) { lastSaveTime = currentMillis; - if(PlayPadPlugin.getInstance().getGlobalSettings().isEnableAutosave()) - { + if (PlayPadPlugin.getInstance().getGlobalSettings().isEnableAutosave()) { Logger.debug("Performing autosave..."); mainViewController.save(); @@ -40,20 +34,16 @@ public class AutosaveRunner implements Runnable } } - try - { + try { //noinspection BusyWait Thread.sleep(10 * 1000L); - } - catch(InterruptedException e) - { + } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } - private long getAutosaveIntervalInMillis() - { + private long getAutosaveIntervalInMillis() { return PlayPadPlugin.getInstance().getGlobalSettings().getAutosaveIntervalInMinutes() * 60 * 1000L; } } diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/MainViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/MainViewController.java index d1a3aff9f30090ab4b0bbd065b68dfd7fcee9b6d..68a0de522f978907d687bbe78c6888cc9eb7704b 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/MainViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/main/MainViewController.java @@ -370,8 +370,7 @@ public class MainViewController extends NVC implements IMainViewController, Noti } } - if(autosaveThread != null && autosaveThread.isAlive()) - { + if (autosaveThread != null && autosaveThread.isAlive()) { Logger.debug("Stopping autosave thread"); autosaveThread.interrupt(); } @@ -803,8 +802,7 @@ public class MainViewController extends NVC implements IMainViewController, Noti @Override public void save() { - try - { + try { ProjectReferenceManager.saveProjects(); ProjectReferenceManager.saveSingleProject(openProject); ProfileReferenceManager.saveProfiles(); @@ -812,9 +810,7 @@ public class MainViewController extends NVC implements IMainViewController, Noti PlayPadPlugin.getInstance().getGlobalSettings().save(); notify(Localization.getString(Strings.STANDARD_FILE_SAVE), PlayPadMain.NOTIFICATION_DISPLAY_TIME); - } - catch(IOException e) - { + } catch (IOException e) { showError(Localization.getString(Strings.ERROR_PROJECT_SAVE)); Logger.error(e); } diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/DesignPadTabViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/DesignPadTabViewController.java index 9350b63841d763894290086376d135a3df8b02cf..c08a6a30d3ee2a2822d4ad105b73eb1dc09941c2 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/DesignPadTabViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/DesignPadTabViewController.java @@ -6,23 +6,18 @@ import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.Strings; import de.tobias.playpad.design.modern.model.ModernCartDesign; import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.PadSettings; -import de.tobias.playpad.profile.Profile; import de.tobias.playpad.viewcontroller.PadSettingsTabViewController; import de.tobias.playpad.viewcontroller.design.ModernCartDesignViewController; import de.tobias.playpad.viewcontroller.main.IMainViewController; import javafx.fxml.FXML; -import javafx.scene.control.CheckBox; import javafx.scene.layout.VBox; public class DesignPadTabViewController extends PadSettingsTabViewController { @FXML private VBox layoutContainer; - @FXML - private CheckBox enableLayoutCheckBox; - private Pad pad; + private final Pad pad; DesignPadTabViewController(Pad pad) { load("view/option/pad", "LayoutTab", Localization.getBundle()); @@ -31,26 +26,6 @@ public class DesignPadTabViewController extends PadSettingsTabViewController { @Override public void init() { - enableLayoutCheckBox.selectedProperty().addListener((a, b, c) -> - { - PadSettings padSettings = pad.getPadSettings(); - if (c && !padSettings.isCustomDesign()) { - try { - padSettings.setCustomDesign(true); - - ModernCartDesign layout = padSettings.getDesign(); - layout.copyGlobalLayout(Profile.currentProfile().getProfileSettings().getDesign()); - - setLayoutViewController(pad); - } catch (Exception e) { - showErrorMessage(Localization.getString(Strings.ERROR_STANDARD_GEN, e.getLocalizedMessage())); - Logger.error(e); - } - } else if (!c && padSettings.isCustomDesign()) { - padSettings.setCustomDesign(false); - setLayoutViewController(null); - } - }); } @Override @@ -60,12 +35,7 @@ public class DesignPadTabViewController extends PadSettingsTabViewController { @Override public void loadSettings(Pad pad) { - PadSettings padSettings = pad.getPadSettings(); - - enableLayoutCheckBox.setSelected(padSettings.isCustomDesign()); - if (padSettings.isCustomDesign()) { - setLayoutViewController(pad); - } + setLayoutViewController(pad); } private void setLayoutViewController(Pad pad) { diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/PlaylistTabViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/PlaylistTabViewController.java index 8faa9b357d9364f0058ced62965a27d6ce56b3e7..74de2555dab74e6fc625506f4a848f7b3547c663 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/PlaylistTabViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/pad/PlaylistTabViewController.java @@ -4,7 +4,6 @@ import de.thecodelabs.utils.application.system.NativeApplication; import de.thecodelabs.utils.ui.icon.FontAwesomeType; import de.thecodelabs.utils.ui.icon.FontIcon; import de.thecodelabs.utils.util.Localization; -import de.tobias.playpad.PlayPad; import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.Strings; import de.tobias.playpad.layout.desktop.listener.PadNewContentListener; @@ -19,10 +18,7 @@ import javafx.beans.binding.Bindings; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; +import javafx.scene.control.*; import javafx.scene.layout.VBox; import java.io.File; @@ -32,10 +28,15 @@ import java.util.List; public class PlaylistTabViewController extends PadSettingsTabViewController { @FXML - private ListView<MediaPath> mediaPathListView; + private CheckBox shuffleCheckbox; + @FXML + private CheckBox autoNextCheckbox; @FXML private Button addButton; + + @FXML + private ListView<MediaPath> mediaPathListView; @FXML private Button upButton; @FXML @@ -123,12 +124,14 @@ public class PlaylistTabViewController extends PadSettingsTabViewController { @Override public void loadSettings(Pad pad) { - // Not implemented + shuffleCheckbox.setSelected((Boolean) pad.getPadSettings().getCustomSettings().getOrDefault(Playlistable.SHUFFLE_SETTINGS_KEY, false)); + autoNextCheckbox.setSelected((Boolean) pad.getPadSettings().getCustomSettings().getOrDefault(Playlistable.AUTO_NEXT_SETTINGS_KEY, true)); } @Override public void saveSettings(Pad pad) { - // Not implemented + pad.getPadSettings().getCustomSettings().put(Playlistable.SHUFFLE_SETTINGS_KEY, shuffleCheckbox.isSelected()); + pad.getPadSettings().getCustomSettings().put(Playlistable.AUTO_NEXT_SETTINGS_KEY, autoNextCheckbox.isSelected()); } @FXML diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/profile/GeneralTabViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/profile/GeneralTabViewController.java index 1b9cb3eae11e0dafe64e84863e440d3becea5a88..ee68975eac82cdee8cf838c1c616733af5af04e1 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/profile/GeneralTabViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/option/profile/GeneralTabViewController.java @@ -84,8 +84,7 @@ public class GeneralTabViewController extends GlobalSettingsTabViewController { enableAutosaveCheckbox.selectedProperty().addListener((observable, oldValue, newValue) -> autosaveIntervalTextField.setDisable(!newValue)); } - private void disableLiveSettings(Boolean enableLiveSettings) - { + private void disableLiveSettings(Boolean enableLiveSettings) { pageEnable.setDisable(!enableLiveSettings); pageDisable.setDisable(!enableLiveSettings); dragEnable.setDisable(!enableLiveSettings); @@ -211,8 +210,7 @@ public class GeneralTabViewController extends GlobalSettingsTabViewController { try { final int autosaveInterval = Integer.parseInt(autosaveIntervalTextField.getText()); return autosaveInterval > 0; - } - catch(NumberFormatException e) { + } catch (NumberFormatException e) { return false; } } diff --git a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java index dfe3087c7e911b035ddfa39ba83f795ed0eaa19a..74762ff9671799447a7436b74c3a2a54df3763db 100644 --- a/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java +++ b/PlayWall/src/main/java/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java @@ -34,7 +34,7 @@ public class WarningFeedbackViewController extends NVC { return controller; } - public static WarningFeedbackViewController newViewControllerForPad() { + public static WarningFeedbackViewController newViewControllerForPad() { return new WarningFeedbackViewController(); } diff --git a/PlayWall/src/main/resources/components/Actions.xml b/PlayWall/src/main/resources/components/Actions.xml index f992162e06c0982a968ecd169612c8e66f657c9a..39e66640e5914e47b8530f1d521661f7cfdd377a 100644 --- a/PlayWall/src/main/resources/components/Actions.xml +++ b/PlayWall/src/main/resources/components/Actions.xml @@ -1,16 +1,24 @@ <Actions> - <Component id="CartAction" name="Action.Cart.Name" icon="TH" class="de.thecodelabs.utils.ui.icon.FontAwesomeType" + <Component id="CartAction" name="Action.Cart.Name" icon="TH" + class="de.thecodelabs.utils.ui.icon.FontAwesomeType" size="11"> de.tobias.playpad.action.factory.CartActionProvider </Component> - <Component id="PageAction" name="Action.Page.Name" icon="FILE_TEXT" class="de.thecodelabs.utils.ui.icon.FontAwesomeType" + <Component id="PlaylistNextAction" name="Action.PlaylistNext.Name" icon="TH" + class="de.thecodelabs.utils.ui.icon.FontAwesomeType" + size="11"> + de.tobias.playpad.action.factory.PlaylistNextActionProvider + </Component> + <Component id="PageAction" name="Action.Page.Name" icon="FILE_TEXT" + class="de.thecodelabs.utils.ui.icon.FontAwesomeType" size="11">de.tobias.playpad.action.factory.PageActionProvider </Component> <Component id="NavigateAction" name="Action.Navigate.Name" icon="NAVIGATION" class="de.thecodelabs.utils.ui.icon.MaterialDesignIcon" size="11"> de.tobias.playpad.action.factory.NavigateActionProvider </Component> - <Component id="StopAction" name="Action.Stop.Name" icon="STOP" class="de.thecodelabs.utils.ui.icon.MaterialDesignIcon" + <Component id="StopAction" name="Action.Stop.Name" icon="STOP" + class="de.thecodelabs.utils.ui.icon.MaterialDesignIcon" size="11">de.tobias.playpad.action.factory.StopActionProvider </Component> </Actions> \ No newline at end of file diff --git a/PlayWall/src/main/resources/lang/_de.properties b/PlayWall/src/main/resources/lang/_de.properties index 7058dabd67cd9c35efa91bc4f5dcc3260f4c931e..89375f4cd298891b17d51dc0afa36aad00086b3f 100755 --- a/PlayWall/src/main/resources/lang/_de.properties +++ b/PlayWall/src/main/resources/lang/_de.properties @@ -167,6 +167,7 @@ Action.Cart.toString=Kachel {} Action.Page.toString=Seite {} Action.Navigate.toString={} Action.Cart.Name=Kacheln +Action.PlaylistNext.Name=Playlist Action.Stop.Name=Stop Action.Page.Name=Seiten Action.Navigate.Name=Navigation @@ -214,6 +215,7 @@ Trigger.Volume.Name=Lautst\u00E4rke TriggerPoint.START=Start TriggerPoint.STOP=Stop TriggerPoint.EOF=Ende +TriggerPoint.PLAYLIST_NEXT=Playlist Next # Drag and Drop Mode DnDMode.Replace=Ersetzen diff --git a/PlayWall/src/main/resources/lang/ui_de.properties b/PlayWall/src/main/resources/lang/ui_de.properties index 229c7ab2ff1364e4062a34be4058354422c0b120..f7eb45e0b6f85393bd5a290726f0d7502463a35d 100755 --- a/PlayWall/src/main/resources/lang/ui_de.properties +++ b/PlayWall/src/main/resources/lang/ui_de.properties @@ -137,6 +137,9 @@ padSettings.player.label.cueIn=Intro Dauer (in s): padSettings.player.label.fade=Ein-/Ausblenden: padSettings.layout.label.custom=Eigenes Layout: padSettings.layout.checkbox.custom=Aktiviert +padSettings.playlist.settings.title=Allgemeine Einstellungen +padSettings.playlist.settings.shuffle=Zuf\u00E4llige Wiedergabe +padSettings.playlist.settings.autoNext=N\u00E4chsten Eintrag automatisch starten (Standard) project.label.details=Projektinformationen: project.label.name=Name: project.label.profile=Profil: diff --git a/PlayWall/src/main/resources/style/modern-pad-cue-in.css b/PlayWall/src/main/resources/style/modern-pad-cue-in.css new file mode 100644 index 0000000000000000000000000000000000000000..65ea71f1be01bb6a98b7e566b10c8e995bd4c33d --- /dev/null +++ b/PlayWall/src/main/resources/style/modern-pad-cue-in.css @@ -0,0 +1,4 @@ + +.pad${#prefix}-cue-in { + -fx-background-color: ${#padCueInColor} !important; +} \ No newline at end of file diff --git a/PlayWall/src/main/resources/style/modern-pad.css b/PlayWall/src/main/resources/style/modern-pad.css index abd17dbdf936ab7d80a0c9fd7a022c98935d9669..11df504e7820334526c06d2003bd0ce425313b1c 100644 --- a/PlayWall/src/main/resources/style/modern-pad.css +++ b/PlayWall/src/main/resources/style/modern-pad.css @@ -21,15 +21,10 @@ -fx-background-color: ${#padColor}; } -.pad${#prefix}-cue-in${#class} { - -fx-background-color: ${#padCueInColor}; -} - - .pad${#prefix}-info${#class} { -fx-text-fill: ${#fontColor}; } .pad${#prefix}-title${#class} { -fx-text-fill: ${#fontColor}; -} \ No newline at end of file +} diff --git a/PlayWall/src/main/resources/view/option/layout/ModernLayoutCart.fxml b/PlayWall/src/main/resources/view/option/layout/ModernLayoutCart.fxml index 4d3d165be6852b06cfdf2750f2bb8af7b6be3023..f970df1f7b86d32e56856cb15ae68af01b792007 100644 --- a/PlayWall/src/main/resources/view/option/layout/ModernLayoutCart.fxml +++ b/PlayWall/src/main/resources/view/option/layout/ModernLayoutCart.fxml @@ -9,43 +9,39 @@ <children> <VBox alignment="BOTTOM_LEFT" prefWidth="150.0"> <children> - <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%layout.label.color" - VBox.vgrow="ALWAYS"> + <Label alignment="CENTER_RIGHT" prefWidth="150.0" text="%layout.label.color" VBox.vgrow="ALWAYS"> <VBox.margin> - <Insets bottom="5.0"/> + <Insets bottom="5.0" /> </VBox.margin> </Label> </children> </VBox> <VBox layoutX="110.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="125.0" spacing="14.0"> <children> - <Label alignment="BOTTOM_LEFT" layoutX="110.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" - text="%layout.label.background" wrapText="true" VBox.vgrow="ALWAYS"/> - <Button fx:id="backgroundColorButton" focusTraversable="false" mnemonicParsing="false" - onAction="#backgroundColorButtonHandler" prefWidth="150.0"/> + <CheckBox fx:id="backgroundColorCheckbox" mnemonicParsing="false" text="%padSettings.layout.checkbox.custom" /> + <Label alignment="BOTTOM_LEFT" layoutX="110.0" layoutY="8.0" prefWidth="150.0" text="%layout.label.background" wrapText="true" VBox.vgrow="ALWAYS" /> + <Button fx:id="backgroundColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#backgroundColorButtonHandler" prefWidth="150.0" /> </children> </VBox> <VBox layoutX="243.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="125.0" spacing="14.0"> <children> - <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" - text="%layout.label.play" wrapText="true" VBox.vgrow="ALWAYS"/> - <Button fx:id="playColorButton" focusTraversable="false" mnemonicParsing="false" - onAction="#playColorButtonHandler" prefWidth="150.0"/> + <CheckBox fx:id="playColorCheckbox" mnemonicParsing="false" text="%padSettings.layout.checkbox.custom" /> + <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefWidth="150.0" text="%layout.label.play" wrapText="true" VBox.vgrow="ALWAYS" /> + <Button fx:id="playColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#playColorButtonHandler" prefWidth="150.0" /> </children> </VBox> <VBox layoutX="243.0" layoutY="8.0" maxWidth="1.7976931348623157E308" prefWidth="125.0" spacing="14.0"> <children> - <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefHeight="60.0" prefWidth="150.0" - text="%layout.label.cueIn" wrapText="true" VBox.vgrow="ALWAYS"/> - <Button fx:id="cueInColorButton" focusTraversable="false" mnemonicParsing="false" - onAction="#cueInColorButtonHandler" prefWidth="150.0"/> + <CheckBox fx:id="cueInColorCheckbox" mnemonicParsing="false" text="%padSettings.layout.checkbox.custom" /> + <Label alignment="BOTTOM_LEFT" layoutX="243.0" layoutY="8.0" prefWidth="150.0" text="%layout.label.cueIn" wrapText="true" VBox.vgrow="ALWAYS" /> + <Button fx:id="cueInColorButton" focusTraversable="false" mnemonicParsing="false" onAction="#cueInColorButtonHandler" prefWidth="150.0" /> </children> </VBox> </children> </HBox> - <Button fx:id="resetButton" mnemonicParsing="false" onAction="#resetButtonHandler" text="%layout.button.reset"> + <Button fx:id="resetButton" alignment="CENTER" mnemonicParsing="false" onAction="#resetButtonHandler" text="%layout.button.reset"> <VBox.margin> - <Insets left="164.0"/> + <Insets left="164.0" top="28.0" /> </VBox.margin> </Button> </children> diff --git a/PlayWall/src/main/resources/view/option/pad/LayoutTab.fxml b/PlayWall/src/main/resources/view/option/pad/LayoutTab.fxml index fa3222571bdfb80064b4638bb51585ef124bc1aa..ff2aa1d447ffe99dadc1db1358a8bc5b02e35c4a 100644 --- a/PlayWall/src/main/resources/view/option/pad/LayoutTab.fxml +++ b/PlayWall/src/main/resources/view/option/pad/LayoutTab.fxml @@ -1,27 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> - <?import javafx.geometry.Insets?> -<?import javafx.scene.control.CheckBox?> <?import javafx.scene.control.Label?> <?import javafx.scene.layout.*?> <VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> - <HBox layoutX="14.0" layoutY="13.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" - AnchorPane.topAnchor="14.0"> + <HBox layoutX="14.0" layoutY="13.0" spacing="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> <children> - <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="14.0" prefWidth="150.0" - text="%padSettings.layout.label.custom"/> - <CheckBox fx:id="enableLayoutCheckBox" layoutX="127.0" layoutY="13.0" mnemonicParsing="false" - text="%padSettings.layout.checkbox.custom"/> + <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="14.0" prefWidth="150.0" text="%padSettings.layout.label.custom" /> </children> <VBox.margin> - <Insets/> + <Insets /> </VBox.margin> </HBox> - <VBox fx:id="layoutContainer" prefHeight="200.0" prefWidth="100.0"/> + <VBox fx:id="layoutContainer" prefHeight="200.0" prefWidth="100.0" /> </children> <padding> - <Insets bottom="14.0" left="14.0" right="14.0" top="14.0"/> + <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> </padding> </VBox> diff --git a/PlayWall/src/main/resources/view/option/pad/PlaylistTab.fxml b/PlayWall/src/main/resources/view/option/pad/PlaylistTab.fxml index dfa32cd75217bc0b16a69e5cd05d021074505810..e2d0b4d1b0cfdf211574d154ca3f48ef9a4cc31f 100644 --- a/PlayWall/src/main/resources/view/option/pad/PlaylistTab.fxml +++ b/PlayWall/src/main/resources/view/option/pad/PlaylistTab.fxml @@ -1,46 +1,63 @@ <?xml version="1.0" encoding="UTF-8"?> -<?import javafx.geometry.Insets?> +<?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> -<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> - <children> - <VBox spacing="14.0"> - <children> - <ListView fx:id="mediaPathListView" prefWidth="250.0" VBox.vgrow="ALWAYS" /> - <HBox spacing="14.0"> - <children> - <Button fx:id="addButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onAddHandler" HBox.hgrow="ALWAYS" /> - <Button fx:id="upButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onUpHandler" HBox.hgrow="ALWAYS" /> - <Button fx:id="downButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onDownAction" HBox.hgrow="ALWAYS" /> - </children> - </HBox> - </children> - </VBox> - <VBox spacing="14.0"> - <children> - <HBox spacing="14.0"> - <children> - <Label fx:id="pathLabel" textOverrun="CENTER_ELLIPSIS" /> - </children> - </HBox> - <HBox spacing="14.0"> - <children> - <Button fx:id="showFileButton" mnemonicParsing="false" onAction="#onShowFileHandler" text="%padSettings.button.path.show" /> - <Button fx:id="deleteButton" mnemonicParsing="false" onAction="#onDeleteHandler" text="%padSettings.button.delete" /> - </children> - </HBox> - <VBox fx:id="customItemView" /> - </children> - <HBox.margin> - <Insets /> - </HBox.margin> - <padding> - <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> - </padding> - </VBox> - </children> - <padding> - <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> - </padding> -</HBox> +<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <VBox spacing="14"> + <children> + <Label styleClass="headline" text="%padSettings.playlist.settings.title" /> + <CheckBox fx:id="shuffleCheckbox" mnemonicParsing="false" text="%padSettings.playlist.settings.shuffle" /> + <CheckBox fx:id="autoNextCheckbox" mnemonicParsing="false" text="%padSettings.playlist.settings.autoNext" /> + </children> + <VBox.margin> + <Insets /> + </VBox.margin> + <padding> + <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> + </padding> + </VBox> + <HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="14.0"> + <children> + <VBox spacing="14.0"> + <children> + <ListView fx:id="mediaPathListView" prefWidth="250.0" VBox.vgrow="ALWAYS" /> + <HBox spacing="14.0"> + <children> + <Button fx:id="addButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onAddHandler" HBox.hgrow="ALWAYS" /> + <Button fx:id="upButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onUpHandler" HBox.hgrow="ALWAYS" /> + <Button fx:id="downButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onDownAction" HBox.hgrow="ALWAYS" /> + </children> + </HBox> + </children> + </VBox> + <VBox spacing="14.0"> + <children> + <HBox spacing="14.0"> + <children> + <Label fx:id="pathLabel" textOverrun="CENTER_ELLIPSIS" /> + </children> + </HBox> + <HBox spacing="14.0"> + <children> + <Button fx:id="showFileButton" mnemonicParsing="false" onAction="#onShowFileHandler" text="%padSettings.button.path.show" /> + <Button fx:id="deleteButton" mnemonicParsing="false" onAction="#onDeleteHandler" text="%padSettings.button.delete" /> + </children> + </HBox> + <VBox fx:id="customItemView" /> + </children> + <HBox.margin> + <Insets /> + </HBox.margin> + <padding> + <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> + </padding> + </VBox> + </children> + <padding> + <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" /> + </padding> + </HBox> + </children> +</VBox> diff --git a/PlayWall/src/main/scala/de/tobias/playpad/design/ModernCartDesignHandlerImpl.scala b/PlayWall/src/main/scala/de/tobias/playpad/design/ModernCartDesignHandlerImpl.scala index b639f9099419bd956a0b420216f9c01568b2c679..510396427c75841ea6755d11c5795ba0d3e78743 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/design/ModernCartDesignHandlerImpl.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/design/ModernCartDesignHandlerImpl.scala @@ -1,13 +1,10 @@ package de.tobias.playpad.design import de.thecodelabs.utils.application.ApplicationUtils -import de.tobias.playpad.design.modern.model.{ModernCartDesign, ModernGlobalDesign} +import de.tobias.playpad.design.modern.model.ModernCartDesign import de.tobias.playpad.design.modern.{ModernCartDesignHandler, ModernColor} -import de.tobias.playpad.pad.content.play.Durationable -import de.tobias.playpad.pad.viewcontroller.AbstractPadViewController import de.tobias.playpad.util.Minifier import de.tobias.playpad.view.PseudoClasses -import javafx.util.Duration import org.springframework.expression.ExpressionParser import org.springframework.expression.common.TemplateParserContext import org.springframework.expression.spel.standard.SpelExpressionParser @@ -18,20 +15,25 @@ import scala.jdk.CollectionConverters._ class ModernCartDesignHandlerImpl extends ModernCartDesignHandler { override def generateCss(design: ModernCartDesign, classSuffix: String, flat: Boolean): String = { - String.join( - generateCss(design, flat, classSuffix, design.getBackgroundColor), - generateCss(design, flat, classSuffix, design.getPlayColor, s":${PseudoClasses.PLAY_CLASS.getPseudoClassName}"), - generateCss(design, flat, classSuffix, design.getBackgroundColor, s":${PseudoClasses.WARN_CLASS.getPseudoClassName}") - ) - } + var result = "" - private def generateCss(design: ModernCartDesign, flat: Boolean, padIdentifier: String, color: ModernColor, styleState: String = ""): String = { - val expressionParser: ExpressionParser = new SpelExpressionParser() - val context = new StandardEvaluationContext() + if (design.isEnableCustomBackgroundColor) { + result += generatePadCss(design, flat, classSuffix, design.getBackgroundColor) + result += generatePadCss(design, flat, classSuffix, design.getBackgroundColor, s":${PseudoClasses.WARN_CLASS.getPseudoClassName}") + } - val resource = ApplicationUtils.getApplication.getClasspathResource("style/modern-pad.css") - val string = Minifier minify resource.getAsString + if (design.isEnableCustomPlayColor) { + result += generatePadCss(design, flat, classSuffix, design.getPlayColor, s":${PseudoClasses.PLAY_CLASS.getPseudoClassName}") + } + if (design.isEnableCustomCueInColor) { + result += generateCueInCss(design, flat, classSuffix) + } + + result + } + + private def generatePadCss(design: ModernCartDesign, flat: Boolean, padIdentifier: String, color: ModernColor, styleState: String = ""): String = { val values: Map[String, AnyRef] = Map( "prefix" -> padIdentifier, "class" -> styleState, @@ -43,33 +45,26 @@ class ModernCartDesignHandlerImpl extends ModernCartDesignHandler { "fontColor" -> color.getFontColor ) - context.setVariables(values.asJava) - expressionParser.parseExpression(string, new TemplateParserContext("${", "}")).getValue(context, classOf[String]) + generateCss("style/modern-pad.css", values) } - override def handleWarning(design: ModernCartDesign, controller: AbstractPadViewController, warning: Duration, globalDesign: ModernGlobalDesign): Unit = { - if (globalDesign.isWarnAnimation) { - val playColor = design.getPlayColor - val backgroundColor = design.getBackgroundColor - - val fadeStopColor = if (globalDesign.isFlatDesign) backgroundColor.toFlatFadeableColor else backgroundColor.toFadeableColor - val fadePlayColor = if (globalDesign.isFlatDesign) playColor.toFlatFadeableColor else playColor.toFadeableColor + private def generateCueInCss(design: ModernCartDesign, flat: Boolean, padIdentifier: String): String = { + val values: Map[String, AnyRef] = Map( + "prefix" -> padIdentifier, + "padCueInColor" -> (if (flat) design.getCueInColor.paint() else design.getCueInColor.linearGradient()) + ) - val pad = controller.getPad - val animationDuration = pad.getContent match { - case durationable: Durationable => - if (warning greaterThan durationable.getDuration) { - durationable.getDuration - } else { - warning - } - case _ => warning - } - ModernDesignAnimator.animateWarn(controller, fadePlayColor, fadeStopColor, animationDuration) - } else { - ModernDesignAnimator.warnFlash(controller) - } + generateCss("style/modern-pad-cue-in.css", values) } - override def stopWarning(design: ModernCartDesign, controller: AbstractPadViewController): Unit = ModernDesignAnimator.stopAnimation(controller) + private def generateCss(templatePath: String, values: Map[String, AnyRef]): String = { + val expressionParser: ExpressionParser = new SpelExpressionParser() + val context = new StandardEvaluationContext() + + val resource = ApplicationUtils.getApplication.getClasspathResource(templatePath) + val content = Minifier minify resource.getAsString + + context.setVariables(values.asJava) + expressionParser.parseExpression(content, new TemplateParserContext("${", "}")).getValue(context, classOf[String]) + } } diff --git a/PlayWall/src/main/scala/de/tobias/playpad/design/ModernGlobalDesignHandlerImpl.scala b/PlayWall/src/main/scala/de/tobias/playpad/design/ModernGlobalDesignHandlerImpl.scala index 3eea45b74878a931b801b72ea341ce13375be7d2..2f36bbb65034d438a9473f72d4036f8b598e6276 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/design/ModernGlobalDesignHandlerImpl.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/design/ModernGlobalDesignHandlerImpl.scala @@ -4,8 +4,6 @@ import de.thecodelabs.utils.application.ApplicationUtils import de.thecodelabs.utils.application.container.PathType import de.tobias.playpad.design.modern.model.{ModernCartDesign, ModernGlobalDesign} import de.tobias.playpad.design.modern.{ModernColor, ModernGlobalDesignHandler} -import de.tobias.playpad.pad.content.play.Durationable -import de.tobias.playpad.pad.viewcontroller.AbstractPadViewController import de.tobias.playpad.project.Project import de.tobias.playpad.util.Minifier import de.tobias.playpad.view.{ColorPickerView, PseudoClasses} @@ -13,7 +11,6 @@ import de.tobias.playpad.viewcontroller.main.IMainViewController import de.tobias.playpad.{DisplayableColor, PlayPadMain} import javafx.scene.paint.Color import javafx.stage.Stage -import javafx.util.Duration import org.springframework.expression.ExpressionParser import org.springframework.expression.common.TemplateParserContext import org.springframework.expression.spel.standard.SpelExpressionParser @@ -50,10 +47,8 @@ class ModernGlobalDesignHandlerImpl extends ModernGlobalDesignHandler with Color project.getPage(controller.getPage).getPads.forEach(pad => { val padSettings = pad.getPadSettings - if (padSettings.isCustomDesign) { - val cartDesign = padSettings.getDesign - stringBuilder.append(cartDesignHandler.generateCss(cartDesign, s"${pad.getPadIndex}", design.isFlatDesign)) - } + val cartDesign = padSettings.getDesign + stringBuilder.append(cartDesignHandler.generateCss(cartDesign, s"${pad.getPadIndex}", design.isFlatDesign)) }) Files.write(customCss, stringBuilder.toString().getBytes()) @@ -92,33 +87,6 @@ class ModernGlobalDesignHandlerImpl extends ModernGlobalDesignHandler with Color expressionParser.parseExpression(string, new TemplateParserContext("${", "}")).getValue(context, classOf[String]) } - override def handleWarning(design: ModernGlobalDesign, controller: AbstractPadViewController, warning: Duration): Unit = { - if (design.isWarnAnimation) { - warnAnimation(design, controller, warning) - } else { - ModernDesignAnimator.warnFlash(controller) - } - } - - private def warnAnimation(design: ModernGlobalDesign, controller: AbstractPadViewController, warning: Duration): Unit = { - val stopColor = if (design.isFlatDesign) design.getBackgroundColor.toFlatFadeableColor else design.getBackgroundColor.toFadeableColor - val playColor = if (design.isFlatDesign) design.getPlayColor.toFlatFadeableColor else design.getPlayColor.toFadeableColor - - val pad = controller.getPad - val duration = pad.getContent match { - case durationable: Durationable => - if (warning.greaterThan(durationable.getDuration)) { - durationable.getDuration - } else { - warning - } - case _ => warning - } - ModernDesignAnimator.animateWarn(controller, playColor, stopColor, duration) - } - - override def stopWarning(design: ModernGlobalDesign, controller: AbstractPadViewController): Unit = ModernDesignAnimator.stopAnimation(controller) - override def getColorInterface(onSelection: Consumer[DisplayableColor]) = new ColorPickerView(null, ModernColor.values.asInstanceOf[Array[DisplayableColor]], onSelection) override def setColor(design: ModernCartDesign, color: DisplayableColor): Unit = { diff --git a/PlayWall/src/main/scala/de/tobias/playpad/design/ModernWarningDesignHandlerImpl.scala b/PlayWall/src/main/scala/de/tobias/playpad/design/ModernWarningDesignHandlerImpl.scala new file mode 100644 index 0000000000000000000000000000000000000000..30a8c490f5c00a9ae5a5171644f808a78adb8b16 --- /dev/null +++ b/PlayWall/src/main/scala/de/tobias/playpad/design/ModernWarningDesignHandlerImpl.scala @@ -0,0 +1,20 @@ +package de.tobias.playpad.design + +import de.tobias.playpad.design.modern.ModernWarningDesignHandler +import de.tobias.playpad.design.modern.model.ModernGlobalDesign +import de.tobias.playpad.pad.viewcontroller.AbstractPadViewController +import de.tobias.playpad.util.FadeableColor +import javafx.util.Duration + +class ModernWarningDesignHandlerImpl extends ModernWarningDesignHandler { + + override def performWarning(design: ModernGlobalDesign, fadeStartColor: FadeableColor, fadeStopColor: FadeableColor, controller: AbstractPadViewController, warningDuration: Duration): Unit = { + if (design.isWarnAnimation) { + ModernDesignAnimator.animateWarn(controller, fadeStartColor, fadeStopColor, warningDuration) + } else { + ModernDesignAnimator.warnFlash(controller) + } + } + + override def stopWarning(controller: AbstractPadViewController): Unit = ModernDesignAnimator.stopAnimation(controller) +} diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/CheckUpdateTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/CheckUpdateTask.scala index a9e68db3161f8184b972dea93a5cd82d4ea9a704..f5c6704b2f45be82bba39fad6b945adb023385ed 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/CheckUpdateTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/CheckUpdateTask.scala @@ -1,7 +1,5 @@ package de.tobias.playpad.initialize -import java.io.IOException - import de.thecodelabs.logger.Logger import de.thecodelabs.utils.application import de.thecodelabs.utils.threading.Worker @@ -10,6 +8,8 @@ import de.tobias.playpad.viewcontroller.dialog.AutoUpdateDialog import javafx.application.Platform import javafx.scene.control.ButtonType +import java.io.IOException + class CheckUpdateTask extends PlayPadInitializeTask { override def name(): String = "Updates" diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/MidiActionsInitializerTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/MidiActionsInitializerTask.scala index fab6bfe1c728a1edd52772cad91b767b95cc40e2..7ca988c7db723dd776e3fc3ade467bbd13200e5f 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/MidiActionsInitializerTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/MidiActionsInitializerTask.scala @@ -1,10 +1,11 @@ package de.tobias.playpad.initialize + import de.thecodelabs.midi.action.{ActionKeyHandler, ActionRegistry} import de.thecodelabs.midi.midi.MidiCommandHandler import de.thecodelabs.utils.application -import de.tobias.playpad.{PlayPadImpl, PlayPadPlugin} import de.tobias.playpad.action.ActionProvider import de.tobias.playpad.midi.PD12 +import de.tobias.playpad.{PlayPadImpl, PlayPadPlugin} class MidiActionsInitializerTask extends PlayPadInitializeTask { diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/NativeAppInitializerTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/NativeAppInitializerTask.scala index 5afd167f0dc959eb7ac44277ea4e5b9d5acab202..96b15a5dd8aedca5c8be678ad84926d0d6ad991c 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/NativeAppInitializerTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/NativeAppInitializerTask.scala @@ -1,4 +1,5 @@ package de.tobias.playpad.initialize + import de.thecodelabs.utils.application import de.thecodelabs.utils.application.system.NativeApplication import de.tobias.playpad.PlayPadImpl diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/OpenLastDocumentTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/OpenLastDocumentTask.scala index c518daba0cd81d8a5465ee35f2f89b8d7d51c978..1d3b58cc5d22bc912f93c6de9ea289f2bd183ec9 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/OpenLastDocumentTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/OpenLastDocumentTask.scala @@ -1,12 +1,12 @@ package de.tobias.playpad.initialize -import java.util.UUID - import de.thecodelabs.utils.application import de.tobias.playpad.PlayPadImpl import de.tobias.playpad.project.ref.ProjectReferenceManager import javafx.application.Platform +import java.util.UUID + class OpenLastDocumentTask extends PlayPadInitializeTask { override def name(): String = "Open Last Document" diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/PluginLoadingTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/PluginLoadingTask.scala index 7b4d7bacf7a75ff8a6ee3ad8e67cd9a523ed6ffc..04ab9448cfae14e988a7701da0ea583e131b1733 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/PluginLoadingTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/PluginLoadingTask.scala @@ -1,8 +1,5 @@ package de.tobias.playpad.initialize -import java.io.IOException -import java.nio.file.{Path, Paths} - import de.thecodelabs.logger.Logger import de.thecodelabs.utils.application import de.thecodelabs.utils.application.ApplicationUtils @@ -12,6 +9,9 @@ import de.tobias.playpad.plugin.ModernPluginManager import javafx.application.Platform import org.controlsfx.dialog.ExceptionDialog +import java.io.IOException +import java.nio.file.{Path, Paths} + class PluginLoadingTask extends PlayPadInitializeTask { override def name(): String = "Plugins" diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProfileLoadingTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProfileLoadingTask.scala index c6f3b28b77789c34d7ab32e3d7e4c3161a457409..490bddc2ed93996df80b17d08a25657d91ca314d 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProfileLoadingTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProfileLoadingTask.scala @@ -1,13 +1,13 @@ package de.tobias.playpad.initialize -import java.io.IOException - import de.thecodelabs.logger.Logger import de.thecodelabs.utils.application import de.tobias.playpad.PlayPadImpl import de.tobias.playpad.profile.ref.ProfileReferenceManager import org.dom4j.DocumentException +import java.io.IOException + class ProfileLoadingTask extends PlayPadInitializeTask { override def name(): String = "Profile loading" diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectParameterOpenTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectParameterOpenTask.scala index a659cbc9bc55ffca0883c8dc824f0af23ca1a609..7a37af3e49bce98f4b3c63145354db9172cad3d7 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectParameterOpenTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectParameterOpenTask.scala @@ -1,11 +1,10 @@ package de.tobias.playpad.initialize -import java.util.UUID - import de.thecodelabs.utils.application import de.tobias.playpad.PlayPadImpl import de.tobias.playpad.project.ref.ProjectReferenceManager -; + +import java.util.UUID; class ProjectParameterOpenTask extends PlayPadInitializeTask { override def name(): String = "Open" diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectsLoadingTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectsLoadingTask.scala index b2bc99af6d57599077d177dd93a8e732b9606132..4609a499f17254359e38d0e5764ff18e6a2473e0 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectsLoadingTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ProjectsLoadingTask.scala @@ -1,4 +1,5 @@ package de.tobias.playpad.initialize + import de.thecodelabs.utils.application import de.tobias.playpad.PlayPadImpl import de.tobias.playpad.project.ref.ProjectReferenceManager diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServerInitializeTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServerInitializeTask.scala index a55c2ad0272c3176d8f8b0da730269b4bc23a9c3..374708dbf113f87f1c002024b89d2ef1473fe99c 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServerInitializeTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServerInitializeTask.scala @@ -1,13 +1,13 @@ package de.tobias.playpad.initialize -import java.io.IOException - import com.neovisionaries.ws.client.WebSocketException import de.thecodelabs.logger.Logger import de.thecodelabs.utils.application import de.tobias.playpad.server.{Session, SessionDelegate, SessionNotExistsException} import de.tobias.playpad.{PlayPadImpl, PlayPadPlugin} +import java.io.IOException + class ServerInitializeTask(delegate: SessionDelegate) extends PlayPadInitializeTask { override def name(): String = "Server" diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServiceInitializationTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServiceInitializationTask.scala index 7c7795ee81249b886ce185cd11ff51a3de2cbb52..30dee76bd1c7082fbf9ba30c17448ed0259520ea 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServiceInitializationTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/ServiceInitializationTask.scala @@ -1,4 +1,5 @@ package de.tobias.playpad.initialize + import de.thecodelabs.utils.application import de.tobias.playpad.server.ServerHandlerImpl import de.tobias.playpad.server.sync.command.CommandExecutorHandlerImpl diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/VersionizerSetupTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/VersionizerSetupTask.scala index 3c78ccb991a479e5df94f17e0b0efd6320d2f1fb..7a5f95697a0a78f3ef4d58dc4c631b7e28339f48 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/VersionizerSetupTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/VersionizerSetupTask.scala @@ -1,4 +1,5 @@ package de.tobias.playpad.initialize + import de.thecodelabs.storage.settings.StorageTypes import de.thecodelabs.utils.application import de.thecodelabs.utils.util.SystemUtils diff --git a/PlayWall/src/main/scala/de/tobias/playpad/initialize/VolumeInitializerTask.scala b/PlayWall/src/main/scala/de/tobias/playpad/initialize/VolumeInitializerTask.scala index a09ddf7f3f9bbd541478bbd6f6c16b232f1129bf..4018cba0446f88b295d7ae357c88c43d91b205a4 100644 --- a/PlayWall/src/main/scala/de/tobias/playpad/initialize/VolumeInitializerTask.scala +++ b/PlayWall/src/main/scala/de/tobias/playpad/initialize/VolumeInitializerTask.scala @@ -1,4 +1,5 @@ package de.tobias.playpad.initialize + import de.thecodelabs.utils.application import de.tobias.playpad.PlayPadImpl import de.tobias.playpad.volume.{GlobalVolume, PadVolume, VolumeManager} diff --git a/PlayWall/src/test/java/de/tobias/playpad/update/VersionUpdaterTest.java b/PlayWall/src/test/java/de/tobias/playpad/update/VersionUpdaterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e3161ec958483f5dad5406ae20de2a8043f4203e --- /dev/null +++ b/PlayWall/src/test/java/de/tobias/playpad/update/VersionUpdaterTest.java @@ -0,0 +1,43 @@ +package de.tobias.playpad.update; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.junit.Test; + +import java.io.InputStream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class VersionUpdaterTest { + @Test + public void testMigrateProject_UpdatePadDesignSettings() throws DocumentException { + final InputStream projectInputStream = VersionUpdaterTest.class.getClassLoader().getResourceAsStream("de/tobias/playpad/update/ProjectToMigrateToVersion44.xml"); + final Document migratedProject = VersionUpdater.updateProject(projectInputStream); + + final Element rootElement = migratedProject.getRootElement(); + final Element pageElement = rootElement.elements().get(0); + + // pad with custom design enabled + final Element padElement = pageElement.elements().get(0); + final Element designElement = padElement.element("Settings").element("Design"); + + assertThat(designElement.attribute("custom")).isNull(); + + assertThat(designElement.element("EnableCustomBackgroundColor").getStringValue()).isEqualTo("true"); + assertThat(designElement.element("BackgroundColor").getStringValue()).isEqualTo("RED2"); + + assertThat(designElement.element("EnableCustomPlayColor").getStringValue()).isEqualTo("true"); + assertThat(designElement.element("PlayColor").getStringValue()).isEqualTo("YELLOW2"); + + assertThat(designElement.element("EnableCustomCueInColor").getStringValue()).isEqualTo("true"); + assertThat(designElement.element("CueInColor").getStringValue()).isEqualTo("LIGHT_GREEN2"); + + + // pad without custom design + final Element padElement2 = pageElement.elements().get(1); + final Element designElement2 = padElement2.element("Settings").element("Design"); + + assertThat(designElement2.attribute("custom")).isNull(); + } +} diff --git a/PlayWall/src/test/java/de/tobias/playpad/viewcontroller/LaunchDialogTest.java b/PlayWall/src/test/java/de/tobias/playpad/viewcontroller/LaunchDialogTest.java index e0c6cd130d60b3a91b07231ae7357f80333470d8..7ac926ec621079a2d1552ebbc9d8bef6544ba6d1 100644 --- a/PlayWall/src/test/java/de/tobias/playpad/viewcontroller/LaunchDialogTest.java +++ b/PlayWall/src/test/java/de/tobias/playpad/viewcontroller/LaunchDialogTest.java @@ -21,7 +21,7 @@ public class LaunchDialogTest extends ApplicationTest { @Before public void init() { App app = ApplicationUtils.registerMainApplication(PlayPadMain.class); - ApplicationUtils.registerUpdateSercive(new VersionUpdater()); + ApplicationUtils.registerUpdateService(new VersionUpdater()); Logger.init(app.getPath(PathType.LOG)); Logger.setLevelFilter(LogLevelFilter.DEBUG); diff --git a/PlayWall/src/test/resources/de/tobias/playpad/update/ProjectToMigrateToVersion44.xml b/PlayWall/src/test/resources/de/tobias/playpad/update/ProjectToMigrateToVersion44.xml new file mode 100644 index 0000000000000000000000000000000000000000..86a23a31d6079ae067eb9329594ba46cc50d65d9 --- /dev/null +++ b/PlayWall/src/test/resources/de/tobias/playpad/update/ProjectToMigrateToVersion44.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<Project> + <Page uuid="a40033c7-4a85-49c9-bdfe-00e0e8a35fa2" id="0" name=""> + <Pad uuid="1028ee71-aebb-4975-8bfd-40d6872bc1b0" index="0" name="" status="EMPTY"> + <Settings id="cc73d33f-e3dc-4b58-b199-2a77577b1d89"> + <Volume>1.0</Volume> + <Loop>false</Loop> + <Design id="5603c0a3-f3e6-4191-857b-978ba3846e28" custom="true"> + <BackgroundColor>RED2</BackgroundColor> + <PlayColor>YELLOW2</PlayColor> + <CueInColor>LIGHT_GREEN2</CueInColor> + </Design> + <CustomSettings/> + <Triggers> + <Trigger point="START"/> + <Trigger point="EOF_STOP"/> + </Triggers> + </Settings> + </Pad> + <Pad uuid="bde56734-a606-4c19-a19b-7ef20aa7b827" index="1" name="" status="EMPTY"> + <Settings id="0be18dbe-f914-4a11-a470-b4279fe98e0f"> + <Volume>1.0</Volume> + <Loop>false</Loop> + <Design custom="false"/> + <CustomSettings/> + <Triggers> + <Trigger point="START"/> + <Trigger point="EOF_STOP"/> + </Triggers> + </Settings> + </Pad> + </Page> + <Settings> + <Columns>2</Columns> + <Rows>1</Rows> + <MediaPath active="false"/> + </Settings> +</Project> diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/action/feedback/ColorAdjuster.java b/PlayWallCore/src/main/java/de/tobias/playpad/action/feedback/ColorAdjuster.java index 43b68616b2f60bfe777cb52cef208acb88f6ea2a..3c43cca588470edbbd0f989788a8366e11cbb329 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/action/feedback/ColorAdjuster.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/action/feedback/ColorAdjuster.java @@ -12,6 +12,7 @@ import de.thecodelabs.midi.mapping.MidiKey; import de.thecodelabs.midi.midi.Midi; import de.thecodelabs.midi.midi.feedback.MidiFeedbackTranscript; import de.tobias.playpad.design.FeedbackDesignColorSuggester; +import de.tobias.playpad.design.modern.model.ModernCartDesign; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.profile.Profile; import javafx.scene.paint.Color; @@ -69,19 +70,20 @@ public class ColorAdjuster { Pad pad = suggester.getPad(action); - Color layoutStdColor = null; - Color layoutEvColor = null; + FeedbackDesignColorSuggester globalDesign = Profile.currentProfile().getProfileSettings().getDesign(); + Color layoutStdColor = globalDesign.getDesignDefaultColor(); + Color layoutEvColor = globalDesign.getDesignEventColor(); - FeedbackDesignColorSuggester design; - if (pad != null && pad.getPadSettings().isCustomDesign()) { - design = pad.getPadSettings().getDesign(); - } else { - design = Profile.currentProfile().getProfileSettings().getDesign(); - } + if (pad != null) { + final ModernCartDesign padDesign = pad.getPadSettings().getDesign(); + + if (padDesign.isEnableCustomBackgroundColor()) { + layoutStdColor = padDesign.getDesignDefaultColor(); + } - if (design != null) { - layoutStdColor = design.getDesignDefaultColor(); - layoutEvColor = design.getDesignEventColor(); + if (padDesign.isEnableCustomPlayColor()) { + layoutEvColor = padDesign.getDesignEventColor(); + } } if (layoutStdColor != null) { @@ -96,9 +98,7 @@ public class ColorAdjuster { final byte channel = suggester.suggestFeedbackChannel(FeedbackType.EVENT); key.setEventFeedback(new Feedback(channel, matchedColor.getValue())); }); - } - if (layoutEvColor != null) { searchColor(transcript, layoutEvColor).ifPresent(matchedColor -> { final byte channel = suggester.suggestFeedbackChannel(FeedbackType.WARNING); key.setWarningFeedback(new Feedback(channel, matchedColor.getValue())); diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/design/ModernDesignHandler.java b/PlayWallCore/src/main/java/de/tobias/playpad/design/ModernDesignProvider.java similarity index 61% rename from PlayWallCore/src/main/java/de/tobias/playpad/design/ModernDesignHandler.java rename to PlayWallCore/src/main/java/de/tobias/playpad/design/ModernDesignProvider.java index a96e7a9bf1223c41a82a522f03f0a2ebc1769f04..6b374d257db4b5dc8b09ef944bc0ad9d98eaf0fd 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/design/ModernDesignHandler.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/design/ModernDesignProvider.java @@ -2,8 +2,12 @@ package de.tobias.playpad.design; import de.tobias.playpad.design.modern.ModernCartDesignHandler; import de.tobias.playpad.design.modern.ModernGlobalDesignHandler; +import de.tobias.playpad.design.modern.ModernWarningDesignHandler; + +public interface ModernDesignProvider { + + ModernWarningDesignHandler warning(); -public interface ModernDesignHandler { ModernGlobalDesignHandler global(); ModernCartDesignHandler cart(); diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernCartDesignHandler.java b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernCartDesignHandler.java index 200ead1fd6e412137370b6393167bb1092adc90d..f456ca512fd0dc06d505a13ca0fa071d0be113ee 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernCartDesignHandler.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernCartDesignHandler.java @@ -1,20 +1,7 @@ package de.tobias.playpad.design.modern; import de.tobias.playpad.design.modern.model.ModernCartDesign; -import de.tobias.playpad.design.modern.model.ModernGlobalDesign; -import de.tobias.playpad.pad.viewcontroller.AbstractPadViewController; -import javafx.util.Duration; public interface ModernCartDesignHandler { - String generateCss(ModernCartDesign design, String classSuffix, boolean flat); - - /* - * Wird in einem neuen Thread aufgerufen - */ - void handleWarning(ModernCartDesign design, AbstractPadViewController controller, Duration warning, ModernGlobalDesign globalDesign); - - default void stopWarning(ModernCartDesign design, AbstractPadViewController controller) { - } - } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernGlobalDesignHandler.java b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernGlobalDesignHandler.java index bca1e4aa9cee672852326f41dffe582e115f10e4..bd7e9348e4b1b92315b9c094e19968e360a46835 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernGlobalDesignHandler.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernGlobalDesignHandler.java @@ -1,23 +1,13 @@ package de.tobias.playpad.design.modern; import de.tobias.playpad.design.modern.model.ModernGlobalDesign; -import de.tobias.playpad.pad.viewcontroller.AbstractPadViewController; import de.tobias.playpad.project.Project; import de.tobias.playpad.viewcontroller.main.IMainViewController; import javafx.stage.Stage; -import javafx.util.Duration; public interface ModernGlobalDesignHandler { void applyStyleSheet(Stage stage); void applyStyleSheetToMainViewController(ModernGlobalDesign design, IMainViewController controller, Stage stage, Project project); - - /* - * Wird in einem neuen Thread aufgerufen - */ - void handleWarning(ModernGlobalDesign design, AbstractPadViewController controller, Duration warning); - - default void stopWarning(ModernGlobalDesign design, AbstractPadViewController controller) { - } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernWarningDesignHandler.java b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernWarningDesignHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..aeed4d5a8545b740424eb8db62df65e6a85a8774 --- /dev/null +++ b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/ModernWarningDesignHandler.java @@ -0,0 +1,50 @@ +package de.tobias.playpad.design.modern; + +import de.tobias.playpad.design.modern.model.ModernCartDesign; +import de.tobias.playpad.design.modern.model.ModernGlobalDesign; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.content.play.Durationable; +import de.tobias.playpad.pad.viewcontroller.AbstractPadViewController; +import de.tobias.playpad.util.FadeableColor; +import javafx.util.Duration; + +public interface ModernWarningDesignHandler { + + default void handleWarning(ModernGlobalDesign globalDesign, ModernCartDesign cartDesign, AbstractPadViewController controller, Duration warningDuration) { + ModernColor backgroundColor = globalDesign.getBackgroundColor(); + ModernColor playColor = globalDesign.getPlayColor(); + + if (cartDesign.isEnableCustomBackgroundColor()) { + backgroundColor = cartDesign.getBackgroundColor(); + } + + if (cartDesign.isEnableCustomPlayColor()) { + playColor = cartDesign.getPlayColor(); + } + + final FadeableColor fadeStartColor = globalDesign.isFlatDesign() ? playColor.toFlatFadeableColor() : playColor.toFadeableColor(); + final FadeableColor fadeStopColor = globalDesign.isFlatDesign() ? backgroundColor.toFlatFadeableColor() : backgroundColor.toFadeableColor(); + final Duration duration = determineDuration(controller.getPad(), warningDuration); + + performWarning(globalDesign, fadeStartColor, fadeStopColor, controller, duration); + } + + default Duration determineDuration(Pad pad, Duration warningDuration) { + if (pad.getContent() instanceof Durationable) { + final Durationable durationable = (Durationable) pad.getContent(); + if (warningDuration.greaterThan(durationable.getDuration())) { + return durationable.getDuration(); + } + } + + return warningDuration; + } + + /* + * Wird in einem neuen Thread aufgerufen + */ + void performWarning(ModernGlobalDesign design, FadeableColor fadeStartColor, FadeableColor fadeStopColor, AbstractPadViewController controller, Duration duration); + + default void stopWarning(AbstractPadViewController controller) { + } +} diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/model/ModernCartDesign.java b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/model/ModernCartDesign.java index 0d79598ab08bdc44c125ee494909fe9925942abc..0997d291bb879d0820829479946966374827d659 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/model/ModernCartDesign.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/model/ModernCartDesign.java @@ -6,7 +6,9 @@ import de.tobias.playpad.pad.Pad; import de.tobias.playpad.server.sync.command.CommandManager; import de.tobias.playpad.server.sync.command.Commands; import de.tobias.playpad.server.sync.listener.upstream.DesignUpdateListener; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.paint.Color; @@ -14,28 +16,87 @@ import java.util.UUID; public class ModernCartDesign implements FeedbackDesignColorSuggester { - private UUID uuid; + public static class ModernCartDesignBuilder { + private final Pad pad; + private final UUID id; + + private ModernColor backgroundColor = DEFAULT_COLOR_BACKGROUND; + private Boolean enableCustomBackgroundColor = false; + + private ModernColor playColor = DEFAULT_COLOR_PLAY; + private Boolean enableCustomPlayColor = false; + + private ModernColor cueInColor = DEFAULT_COLOR_CUE_IN; + private Boolean enableCustomCueInColor = false; + + public ModernCartDesignBuilder(Pad pad) { + this.pad = pad; + this.id = UUID.randomUUID(); + } + + public ModernCartDesignBuilder(Pad pad, UUID id) { + this.pad = pad; + this.id = id; + } + + public ModernCartDesignBuilder withBackgroundColor(ModernColor backgroundColor, Boolean enable) { + this.backgroundColor = backgroundColor; + this.enableCustomBackgroundColor = enable; + return this; + } + + public ModernCartDesignBuilder withPlayColor(ModernColor playColor, Boolean enable) { + this.playColor = playColor; + this.enableCustomPlayColor = enable; + return this; + } + + public ModernCartDesignBuilder withCueInColor(ModernColor cueInColor, Boolean enable) { + this.cueInColor = cueInColor; + this.enableCustomCueInColor = enable; + return this; + } + + public ModernCartDesign build() { + return new ModernCartDesign(pad, id, + backgroundColor, enableCustomBackgroundColor, + playColor, enableCustomPlayColor, + cueInColor, enableCustomCueInColor); + } + } + + public static final ModernColor DEFAULT_COLOR_BACKGROUND = ModernColor.GRAY1; + public static final ModernColor DEFAULT_COLOR_PLAY = ModernColor.RED3; + public static final ModernColor DEFAULT_COLOR_CUE_IN = ModernColor.RED2; + + private final Pad pad; + private final UUID uuid; + + private BooleanProperty enableCustomBackgroundColor; private ObjectProperty<ModernColor> backgroundColor; + + private BooleanProperty enableCustomPlayColor; private ObjectProperty<ModernColor> playColor; + + private BooleanProperty enableCustomCueInColor; private ObjectProperty<ModernColor> cueInColor; - private Pad pad; private DesignUpdateListener syncListener; - public ModernCartDesign(Pad pad) { - this(pad, UUID.randomUUID()); - } - - public ModernCartDesign(Pad pad, UUID uuid) { - this(pad, uuid, ModernColor.GRAY1, ModernColor.RED3, ModernColor.RED2); - } - - public ModernCartDesign(Pad pad, UUID id, ModernColor backgroundColor, ModernColor playColor, ModernColor cueInColor) { + private ModernCartDesign(Pad pad, UUID id, + ModernColor backgroundColor, Boolean enableCustomBackgroundColor, + ModernColor playColor, Boolean enableCustomPlayColor, + ModernColor cueInColor, Boolean enableCustomCueInColor) { this.uuid = id; this.pad = pad; + this.enableCustomBackgroundColor = new SimpleBooleanProperty(enableCustomBackgroundColor); this.backgroundColor = new SimpleObjectProperty<>(backgroundColor); + + this.enableCustomPlayColor = new SimpleBooleanProperty(enableCustomPlayColor); this.playColor = new SimpleObjectProperty<>(playColor); + + this.enableCustomCueInColor = new SimpleBooleanProperty(enableCustomCueInColor); this.cueInColor = new SimpleObjectProperty<>(cueInColor); syncListener = new DesignUpdateListener(this); @@ -49,6 +110,18 @@ public class ModernCartDesign implements FeedbackDesignColorSuggester { return pad; } + public boolean isEnableCustomBackgroundColor() { + return enableCustomBackgroundColor.get(); + } + + public void setEnableCustomBackgroundColor(Boolean enableCustomBackgroundColor) { + this.enableCustomBackgroundColor.set(enableCustomBackgroundColor); + } + + public BooleanProperty enableCustomBackgroundColorProperty() { + return enableCustomBackgroundColor; + } + public ModernColor getBackgroundColor() { return backgroundColor.get(); } @@ -61,6 +134,18 @@ public class ModernCartDesign implements FeedbackDesignColorSuggester { return backgroundColor; } + public boolean isEnableCustomPlayColor() { + return enableCustomPlayColor.get(); + } + + public void setEnableCustomPlayColor(boolean enableCustomPlayColor) { + this.enableCustomPlayColor.set(enableCustomPlayColor); + } + + public BooleanProperty enableCustomPlayColorProperty() { + return enableCustomPlayColor; + } + public ModernColor getPlayColor() { return playColor.get(); } @@ -73,6 +158,18 @@ public class ModernCartDesign implements FeedbackDesignColorSuggester { return playColor; } + public boolean isEnableCustomCueInColor() { + return enableCustomCueInColor.get(); + } + + public void setEnableCustomCueInColor(boolean enableCustomCueInColor) { + this.enableCustomCueInColor.set(enableCustomCueInColor); + } + + public BooleanProperty enableCustomCueInColorProperty() { + return enableCustomCueInColor; + } + public ModernColor getCueInColor() { return cueInColor.get(); } @@ -94,13 +191,12 @@ public class ModernCartDesign implements FeedbackDesignColorSuggester { } public void reset() { - backgroundColor.set(ModernColor.GRAY1); - playColor.set(ModernColor.RED3); - cueInColor.set(ModernColor.RED2); + backgroundColor.set(DEFAULT_COLOR_BACKGROUND); + playColor.set(DEFAULT_COLOR_PLAY); + cueInColor.set(DEFAULT_COLOR_CUE_IN); } - - // Color Associator + // Color Associate @Override public Color getDesignEventColor() { return Color.web(playColor.get().getColorHi()); @@ -112,14 +208,16 @@ public class ModernCartDesign implements FeedbackDesignColorSuggester { } public ModernCartDesign copy(Pad pad) { - ModernCartDesign clone = new ModernCartDesign(pad); + ModernCartDesign clone = new ModernCartDesignBuilder(pad).build(); + clone.enableCustomBackgroundColor = new SimpleBooleanProperty(isEnableCustomBackgroundColor()); clone.backgroundColor = new SimpleObjectProperty<>(getBackgroundColor()); + + clone.enableCustomPlayColor = new SimpleBooleanProperty(isEnableCustomPlayColor()); clone.playColor = new SimpleObjectProperty<>(getPlayColor()); - clone.cueInColor = new SimpleObjectProperty<>(getCueInColor()); - clone.pad = pad; - clone.uuid = UUID.randomUUID(); + clone.enableCustomCueInColor = new SimpleBooleanProperty(isEnableCustomCueInColor()); + clone.cueInColor = new SimpleObjectProperty<>(getCueInColor()); syncListener = new DesignUpdateListener(clone); if (pad.getProject().getProjectReference().isSync()) { @@ -129,10 +227,4 @@ public class ModernCartDesign implements FeedbackDesignColorSuggester { return clone; } - - public void copyGlobalLayout(ModernGlobalDesign globalDesign) { - setBackgroundColor(globalDesign.getBackgroundColor()); - setPlayColor(globalDesign.getPlayColor()); - setCueInColor(globalDesign.getCueInColor()); - } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/serializer/ModernCartDesignSerializer.java b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/serializer/ModernCartDesignSerializer.java index ce67905eb387db419410d0598eb04264f937b270..279347a6b281505606cf61770ce7cc3ca192acfd 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/serializer/ModernCartDesignSerializer.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/design/modern/serializer/ModernCartDesignSerializer.java @@ -14,9 +14,18 @@ public class ModernCartDesignSerializer { ModernCartDesign design; String uuidValue = rootElement.attributeValue("id"); if (uuidValue != null) { - design = new ModernCartDesign(pad, UUID.fromString(uuidValue)); + design = new ModernCartDesign.ModernCartDesignBuilder(pad, UUID.fromString(uuidValue)).build(); } else { - design = new ModernCartDesign(pad); + design = new ModernCartDesign.ModernCartDesignBuilder(pad).build(); + } + + Element enableCustomBackgroundColorElement = rootElement.element("EnableCustomBackgroundColor"); + if (enableCustomBackgroundColorElement != null) { + try { + design.setEnableCustomBackgroundColor(Boolean.parseBoolean(enableCustomBackgroundColorElement.getStringValue())); + } catch (IllegalArgumentException e) { + Logger.error(e); + } } Element backgroundElement = rootElement.element("BackgroundColor"); @@ -28,6 +37,15 @@ public class ModernCartDesignSerializer { } } + Element enableCustomPlayColorElement = rootElement.element("EnableCustomPlayColor"); + if (enableCustomPlayColorElement != null) { + try { + design.setEnableCustomPlayColor(Boolean.parseBoolean(enableCustomPlayColorElement.getStringValue())); + } catch (IllegalArgumentException e) { + Logger.error(e); + } + } + Element playElement = rootElement.element("PlayColor"); if (playElement != null) { try { @@ -36,6 +54,16 @@ public class ModernCartDesignSerializer { Logger.error(e); } } + + Element enableCustomCueInColorElement = rootElement.element("EnableCustomCueInColor"); + if (enableCustomCueInColorElement != null) { + try { + design.setEnableCustomCueInColor(Boolean.parseBoolean(enableCustomCueInColorElement.getStringValue())); + } catch (IllegalArgumentException e) { + Logger.error(e); + } + } + Element cueInElement = rootElement.element("CueInColor"); if (cueInElement != null) { try { @@ -49,8 +77,14 @@ public class ModernCartDesignSerializer { public void save(Element rootElement, ModernCartDesign design) { rootElement.addAttribute("id", design.getId().toString()); + + rootElement.addElement("EnableCustomBackgroundColor").addText(String.valueOf(design.isEnableCustomBackgroundColor())); rootElement.addElement("BackgroundColor").addText(design.getBackgroundColor().name()); + + rootElement.addElement("EnableCustomPlayColor").addText(String.valueOf(design.isEnableCustomPlayColor())); rootElement.addElement("PlayColor").addText(design.getPlayColor().name()); + + rootElement.addElement("EnableCustomCueInColor").addText(String.valueOf(design.isEnableCustomCueInColor())); rootElement.addElement("CueInColor").addText(design.getCueInColor().name()); } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/Pad.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/Pad.java index 8125b05854eaf41a28e2fbe7cb1760730bbafa64..833e52beb59f423a9c0c9c14b81d82ecb46df735 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/Pad.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/Pad.java @@ -4,6 +4,7 @@ import de.thecodelabs.utils.io.PathUtils; import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.pad.content.PadContent; import de.tobias.playpad.pad.content.PadContentFactory; +import de.tobias.playpad.pad.content.Playlistable; import de.tobias.playpad.pad.content.play.Pauseable; import de.tobias.playpad.pad.fade.listener.PadFadeContentListener; import de.tobias.playpad.pad.fade.listener.PadFadeDurationListener; @@ -11,6 +12,7 @@ import de.tobias.playpad.pad.listener.PadStatusControlListener; import de.tobias.playpad.pad.listener.PadStatusNotFoundListener; import de.tobias.playpad.pad.listener.trigger.PadTriggerContentListener; import de.tobias.playpad.pad.listener.trigger.PadTriggerDurationListener; +import de.tobias.playpad.pad.listener.trigger.PadTriggerPlaylistListener; import de.tobias.playpad.pad.listener.trigger.PadTriggerStatusListener; import de.tobias.playpad.pad.mediapath.MediaPath; import de.tobias.playpad.pad.viewcontroller.AbstractPadViewController; @@ -74,6 +76,7 @@ public class Pad implements IPad { private transient PadTriggerStatusListener padTriggerStatusListener; private transient PadTriggerDurationListener padTriggerDurationListener; private transient PadTriggerContentListener padTriggerContentListener; + private transient PadTriggerPlaylistListener padTriggerPlaylistListener; private transient boolean ignoreTrigger = false; // Utils @@ -128,6 +131,11 @@ public class Pad implements IPad { contentProperty.removeListener(padTriggerContentListener); padTriggerContentListener.changed(contentProperty, getContent(), null); } + if (padTriggerPlaylistListener != null && contentProperty != null) { + if (getContent() instanceof Playlistable) { + ((Playlistable) getContent()).removePlaylistListener(padTriggerPlaylistListener); + } + } if (padFadeDurationListener != null && contentProperty != null) { contentProperty.removeListener(padFadeContentListener); @@ -161,6 +169,8 @@ public class Pad implements IPad { contentProperty.addListener(padTriggerContentListener); padTriggerContentListener.changed(contentProperty, null, getContent()); + padTriggerPlaylistListener = new PadTriggerPlaylistListener(); + // Pad Listener if (mediaPathUpdateListener != null) { mediaPaths.removeListener(mediaPathUpdateListener); @@ -610,6 +620,10 @@ public class Pad implements IPad { return padTriggerDurationListener; } + public PadTriggerPlaylistListener getPadTriggerPlaylistListener() { + return padTriggerPlaylistListener; + } + public PadFadeDurationListener getPadFadeDurationListener() { return padFadeDurationListener; } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettings.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettings.java index a935edd4808ae2d9f1c92c99286591e429334cd8..f857d09438102ceae8e7cab8105be25c29a49591 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettings.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettings.java @@ -35,7 +35,6 @@ public class PadSettings { private ObjectProperty<Duration> warningProperty = new SimpleObjectProperty<>(); private ObjectProperty<Duration> cueInProperty = new SimpleObjectProperty<>(); - private BooleanProperty customDesignProperty = new SimpleBooleanProperty(false); private ModernCartDesign design; private Map<TriggerPoint, Trigger> triggers = new EnumMap<>(TriggerPoint.class); @@ -187,21 +186,9 @@ public class PadSettings { return cueInProperty.get(); } - public boolean isCustomDesign() { - return customDesignProperty.get(); - } - - public void setCustomDesign(boolean customLayout) { - this.customDesignProperty.set(customLayout); - } - - public BooleanProperty customDesignProperty() { - return customDesignProperty; - } - public ModernCartDesign getDesign() { if (design == null) { - ModernCartDesign newDesign = new ModernCartDesign(pad); + ModernCartDesign newDesign = new ModernCartDesign.ModernCartDesignBuilder(pad).build(); if (pad.getProject().getProjectReference().isSync()) { CommandManager.execute(Commands.DESIGN_ADD, pad.getProject().getProjectReference(), newDesign); @@ -271,10 +258,7 @@ public class PadSettings { else clone.warningProperty = new SimpleObjectProperty<>(); - clone.customDesignProperty = new SimpleBooleanProperty(isCustomDesign()); - if (design != null) { - clone.design = design.copy(pad); - } + clone.design = design.copy(pad); clone.triggers = new EnumMap<>(TriggerPoint.class); triggers.forEach((key, value) -> clone.triggers.put(key, value.copy())); @@ -307,10 +291,10 @@ public class PadSettings { //// Computed public ModernColor getBackgroundColor() { - if (isCustomDesign()) { + if (design.isEnableCustomBackgroundColor()) { return design.getBackgroundColor(); - } else { - return Profile.currentProfile().getProfileSettings().getDesign().getBackgroundColor(); } + + return Profile.currentProfile().getProfileSettings().getDesign().getBackgroundColor(); } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettingsSerializer.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettingsSerializer.java index 82e70e61fcdcf7c06ccc037ad6296898528be82b..fdaaff85c79831c49e00e6322f16d7ad3934c59e 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettingsSerializer.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/PadSettingsSerializer.java @@ -27,7 +27,6 @@ public class PadSettingsSerializer { private static final String CUE_IN_ELEMENT = "CueIn"; private static final String DESIGN_ELEMENT = "Design"; - private static final String CUSTOM_DESIGN_ELEMENT = "custom"; private static final String CUSTOM_SETTINGS_ITEM_ELEMENT = "Item"; private static final String CUSTOM_SETTINGS_TYPE_ATTR = "key"; @@ -72,9 +71,6 @@ public class PadSettingsSerializer { // Layout Element designElement = settingsElement.element(DESIGN_ELEMENT); if (designElement != null) { - if (designElement.attributeValue(CUSTOM_DESIGN_ELEMENT) != null) { - padSettings.setCustomDesign(Boolean.parseBoolean(designElement.attributeValue(CUSTOM_DESIGN_ELEMENT))); - } ModernCartDesignSerializer serializer = new ModernCartDesignSerializer(); ModernCartDesign design = serializer.load(designElement, pad); padSettings.setDesign(design); @@ -122,13 +118,10 @@ public class PadSettingsSerializer { if (padSettings.getCueIn() != null) settingsElement.addElement(CUE_IN_ELEMENT).addText(padSettings.getCueIn().toString()); - // Layout + // Design Element designElement = settingsElement.addElement(DESIGN_ELEMENT); - if (padSettings.isCustomDesign()) { - ModernCartDesignSerializer serializer = new ModernCartDesignSerializer(); - serializer.save(designElement, padSettings.getDesign()); - } - designElement.addAttribute(CUSTOM_DESIGN_ELEMENT, String.valueOf(padSettings.isCustomDesign())); + ModernCartDesignSerializer serializer = new ModernCartDesignSerializer(); + serializer.save(designElement, padSettings.getDesign()); Element userInfoElement = settingsElement.addElement(CUSTOM_SETTINGS_ELEMENT); for (String key : padSettings.getCustomSettings().keySet()) { diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/PadContentPlaylistFactory.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/PadContentPlaylistFactory.java index 80ae9cc692966db632d8c11bc55b49f7de855ece..67d90ac300a467168926e76e95342e7730d3eb8a 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/PadContentPlaylistFactory.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/PadContentPlaylistFactory.java @@ -4,7 +4,7 @@ import de.tobias.playpad.pad.Pad; import de.tobias.playpad.pad.mediapath.MediaPath; import javafx.scene.Node; -public interface PadContentPlaylistFactory -{ +public interface PadContentPlaylistFactory { + Node getCustomPlaylistItemView(Pad pad, MediaPath mediaPath); } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/PlaylistListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/PlaylistListener.java new file mode 100644 index 0000000000000000000000000000000000000000..1402fe7ae96105fd8e563096d617dcfaf9f5aaba --- /dev/null +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/PlaylistListener.java @@ -0,0 +1,8 @@ +package de.tobias.playpad.pad.content; + +import de.tobias.playpad.pad.Pad; + +public interface PlaylistListener { + + void onNextItem(Pad pad, int next, int total); +} diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/Playlistable.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/Playlistable.java index 1d15d9ad02184a18dc076b6cce7d739f8eba9552..b4b60ea6dc70853cfa768a90c9643c91bad8582c 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/Playlistable.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/content/Playlistable.java @@ -4,6 +4,10 @@ import de.tobias.playpad.pad.mediapath.MediaPath; import javafx.beans.property.IntegerProperty; public interface Playlistable { + + String SHUFFLE_SETTINGS_KEY = "shuffle"; + String AUTO_NEXT_SETTINGS_KEY = "autoNext"; + int getCurrentPlayingMediaIndex(); IntegerProperty currentPlayingMediaIndexProperty(); @@ -13,4 +17,8 @@ public interface Playlistable { void next(); boolean isLoaded(MediaPath mediaPath); + + void addPlaylistListener(PlaylistListener listener); + + void removePlaylistListener(PlaylistListener listener); } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/fade/listener/PadFadeDurationListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/fade/listener/PadFadeDurationListener.java index 214f832d81b61a8449170e5443a83a1fa32c57de..5aac293cf6f31ab2c25a852fd274a90a8c696fda 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/fade/listener/PadFadeDurationListener.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/fade/listener/PadFadeDurationListener.java @@ -30,7 +30,7 @@ public class PadFadeDurationListener implements ChangeListener<Duration> { if (pad.getContent() instanceof Playlistable && ((Playlistable) pad.getContent()).hasNext()) { return; } - + if (pad.getContent() instanceof Durationable) { final Durationable durationable = (Durationable) pad.getContent(); diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/PadStatusControlListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/PadStatusControlListener.java index 3c6b86d4a99fd3cb992a8731d96b2c0952359c07..a791354a38462196371d63f1471273a9dfbdbe4f 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/PadStatusControlListener.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/PadStatusControlListener.java @@ -17,7 +17,7 @@ import javafx.util.Duration; public class PadStatusControlListener implements ChangeListener<PadStatus> { - private Pad pad; + private final Pad pad; // Utils für Single Pad Playing private static Pad currentPlayingPad; // Nur wenn ProfileSettings.isMultiplePlayer == false diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerContentListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerContentListener.java index 09d08d491d8846561e33ac6dcfcfdf1fdff718fa..ae9789f26c4e97b356fe92452cdd8b8f25f1dd32 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerContentListener.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerContentListener.java @@ -2,6 +2,7 @@ package de.tobias.playpad.pad.listener.trigger; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.pad.content.PadContent; +import de.tobias.playpad.pad.content.Playlistable; import de.tobias.playpad.pad.content.play.Durationable; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; @@ -9,7 +10,7 @@ import javafx.beans.value.ObservableValue; // Fügt Time Listener hinzu für neuen Content public class PadTriggerContentListener implements ChangeListener<PadContent> { - private Pad pad; + private final Pad pad; public PadTriggerContentListener(Pad pad) { this.pad = pad; @@ -21,12 +22,20 @@ public class PadTriggerContentListener implements ChangeListener<PadContent> { if (oldValue instanceof Durationable) { ((Durationable) oldValue).positionProperty().removeListener(pad.getPadTriggerDurationListener()); } + + if (oldValue instanceof Playlistable) { + ((Playlistable) oldValue).removePlaylistListener(pad.getPadTriggerPlaylistListener()); + } } if (newValue != null) { if (newValue instanceof Durationable) { ((Durationable) newValue).positionProperty().addListener(pad.getPadTriggerDurationListener()); } + + if (newValue instanceof Playlistable) { + ((Playlistable) newValue).addPlaylistListener(pad.getPadTriggerPlaylistListener()); + } } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerPlaylistListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerPlaylistListener.java new file mode 100644 index 0000000000000000000000000000000000000000..eec30a0feaec27cb639cbe7ab76b5329f028981f --- /dev/null +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerPlaylistListener.java @@ -0,0 +1,30 @@ +package de.tobias.playpad.pad.listener.trigger; + +import de.tobias.playpad.PlayPadPlugin; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadSettings; +import de.tobias.playpad.pad.content.PlaylistListener; +import de.tobias.playpad.profile.Profile; +import de.tobias.playpad.tigger.Trigger; +import de.tobias.playpad.tigger.TriggerPoint; +import de.tobias.playpad.viewcontroller.main.IMainViewController; +import javafx.util.Duration; + +public class PadTriggerPlaylistListener implements PlaylistListener { + @Override + public void onNextItem(Pad pad, int next, int total) { + if (!pad.isIgnoreTrigger()) { + PadSettings padSettings = pad.getPadSettings(); + executeTrigger(pad, padSettings.getTriggers().get(TriggerPoint.PLAYLIST_NEXT)); + } else { + pad.setIgnoreTrigger(false); + } + } + + private void executeTrigger(Pad pad, Trigger trigger) { + IMainViewController mainViewController = PlayPadPlugin.getInstance().getMainViewController(); + Profile currentProfile = Profile.currentProfile(); + + trigger.handle(pad, Duration.ZERO, pad.getProject(), mainViewController, currentProfile); + } +} diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java index 5f28296ac7c24a72a9ae24fc40c1305b6eb4e3df..c3a7239722ac9e9e93e6aba3d5b0b8f9bc27645d 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java @@ -30,7 +30,7 @@ public class PadTriggerStatusListener implements ChangeListener<PadStatus> { executeTrigger(padSettings.getTriggers().get(TriggerPoint.START)); } else if (newValue == PadStatus.STOP && !pad.isEof()) { executeTrigger(padSettings.getTriggers().get(TriggerPoint.STOP)); - } else if (oldState == PadStatus.STOP && newValue == PadStatus.READY && pad.isEof()){ + } else if (oldState == PadStatus.STOP && newValue == PadStatus.READY && pad.isEof()) { executeTrigger(padSettings.getTriggers().get(TriggerPoint.EOF)); } } else { diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/plugin/Jni4NetBridgeInitializer.java b/PlayWallCore/src/main/java/de/tobias/playpad/plugin/Jni4NetBridgeInitializer.java index 70ef43d42df040669e4daaf7fd413789b000c557..fec2d6c9b019227def912bd336e34277ff8a5231 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/plugin/Jni4NetBridgeInitializer.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/plugin/Jni4NetBridgeInitializer.java @@ -15,48 +15,48 @@ import java.util.Objects; public class Jni4NetBridgeInitializer { - private static final String[] RESOURCE_DLLS = { - "jni4net.n-0.8.8.0.dll", - "jni4net.n.w32.v40-0.8.8.0.dll", - "jni4net.n.w64.v40-0.8.8.0.dll", - }; - - private static boolean loaded; - - public static void initialize() throws IOException { - if (loaded) { - return; - } - - final App app = ApplicationUtils.getApplication(); - Path resourceFolder = copyResources("j4n/",RESOURCE_DLLS, "j4n", Jni4NetBridgeInitializer.class.getClassLoader()); - - Bridge.setVerbose(app.isDebug()); - Bridge.init(resourceFolder.toFile()); - loaded = true; - } - - public static void loadDll(ClassLoader classLoader, String classpathDirectory, String target, String proxyDll, String... resources) throws IOException { - Path resourceFolder = copyResources(classpathDirectory, resources, target, classLoader); - Bridge.LoadAndRegisterAssemblyFrom(resourceFolder.resolve(proxyDll).toFile(), classLoader); - } - - private static Path copyResources(String classpathDirectory, String[] resources, String destination, ClassLoader classLoader) throws IOException { - final App app = ApplicationUtils.getApplication(); - final Path resourceFolder = app.getPath(PathType.LIBRARY, destination); - - if (Files.notExists(resourceFolder)) { - Files.createDirectories(resourceFolder); - } - - Arrays.stream(resources).forEach(resource -> { - final Path dest = resourceFolder.resolve(resource); - try { - Files.copy(Objects.requireNonNull(classLoader.getResourceAsStream(classpathDirectory + resource)), dest, StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }); - return resourceFolder; - } + private static final String[] RESOURCE_DLLS = { + "jni4net.n-0.8.8.0.dll", + "jni4net.n.w32.v40-0.8.8.0.dll", + "jni4net.n.w64.v40-0.8.8.0.dll", + }; + + private static boolean loaded; + + public static void initialize() throws IOException { + if (loaded) { + return; + } + + final App app = ApplicationUtils.getApplication(); + Path resourceFolder = copyResources("j4n/", RESOURCE_DLLS, "j4n", Jni4NetBridgeInitializer.class.getClassLoader()); + + Bridge.setVerbose(app.isDebug()); + Bridge.init(resourceFolder.toFile()); + loaded = true; + } + + public static void loadDll(ClassLoader classLoader, String classpathDirectory, String target, String proxyDll, String... resources) throws IOException { + Path resourceFolder = copyResources(classpathDirectory, resources, target, classLoader); + Bridge.LoadAndRegisterAssemblyFrom(resourceFolder.resolve(proxyDll).toFile(), classLoader); + } + + private static Path copyResources(String classpathDirectory, String[] resources, String destination, ClassLoader classLoader) throws IOException { + final App app = ApplicationUtils.getApplication(); + final Path resourceFolder = app.getPath(PathType.LIBRARY, destination); + + if (Files.notExists(resourceFolder)) { + Files.createDirectories(resourceFolder); + } + + Arrays.stream(resources).forEach(resource -> { + final Path dest = resourceFolder.resolve(resource); + try { + Files.copy(Objects.requireNonNull(classLoader.getResourceAsStream(classpathDirectory + resource)), dest, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + return resourceFolder; + } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/profile/Profile.java b/PlayWallCore/src/main/java/de/tobias/playpad/profile/Profile.java index 7e50c4dc4866467c22a06cc7372e830b28cd36e7..e33b1d13a09be32fc49206571ce989c54a2b1f91 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/profile/Profile.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/profile/Profile.java @@ -146,6 +146,10 @@ public class Profile { setCurrentProfile(profile); + // Update mapping with new actions + final Registry<ActionProvider> actions = PlayPadPlugin.getRegistries().getActions(); + actions.getComponents().forEach(provider -> provider.createDefaultActions(currentMapping)); + return profile; } throw new ProfileNotFoundException(ref); diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/project/ProjectSettings.java b/PlayWallCore/src/main/java/de/tobias/playpad/project/ProjectSettings.java index 34c065494f144ce1e3321292514e2b14a5f87c90..3752ac7216f80a8d5177323af98b2e88617285fb 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/project/ProjectSettings.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/project/ProjectSettings.java @@ -1,5 +1,6 @@ package de.tobias.playpad.project; +import de.thecodelabs.storage.settings.UserDefaults; import de.thecodelabs.storage.settings.annotation.Key; import de.thecodelabs.utils.application.ApplicationUtils; import de.tobias.playpad.project.api.IProjectSettings; @@ -8,14 +9,15 @@ import java.nio.file.Path; public class ProjectSettings implements IProjectSettings { - public static final int MAX_PAGES; + public static int MAX_PAGES = 10; static { - Object maxPages = ApplicationUtils.getApplication().getUserDefaults().getData("MAX_PAGES"); - if (maxPages != null) { - MAX_PAGES = Integer.parseInt(maxPages.toString()); - } else { - MAX_PAGES = 10; + final UserDefaults userDefaults = ApplicationUtils.getApplication().getUserDefaults(); + if (userDefaults != null) { + Object maxPages = userDefaults.getData("MAX_PAGES"); + if (maxPages != null) { + MAX_PAGES = Integer.parseInt(maxPages.toString()); + } } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignAddListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignAddListener.java index d4c9f6a550021f0a992569f8e7ab2baf36c7d286..9a395331ee727d6e45dba8468b68fcc50770653f 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignAddListener.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignAddListener.java @@ -31,9 +31,11 @@ public class DesignAddListener implements ServerListener { if (project != null) { Pad pad = project.getPad(padId); if (pad != null) { - ModernCartDesign modernCartDesign = new ModernCartDesign(pad, uuid); - modernCartDesign.setBackgroundColor(backgroundColor); - modernCartDesign.setPlayColor(playColor); + ModernCartDesign modernCartDesign = new ModernCartDesign.ModernCartDesignBuilder(pad, uuid) + .withBackgroundColor(backgroundColor, true) + .withPlayColor(playColor, true) + .build(); + pad.getPadSettings().setDesign(modernCartDesign); } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignUpdateListener.java b/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignUpdateListener.java index fd06d289d49901d970a3dcf8e980e9fe2822af26..5d84b107fb05ce49c99caedfa6a596cdd2c5ef1d 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignUpdateListener.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/server/sync/listener/downstream/pad/settings/design/DesignUpdateListener.java @@ -41,13 +41,13 @@ public class DesignUpdateListener implements ServerListener { if (field.equals(PropertyDef.DESIGN_BACKGROUND_COLOR)) { Platform.runLater(() -> { design.setBackgroundColor(color); - pad.getPadSettings().setCustomDesign(true); + design.setEnableCustomBackgroundColor(true); mainViewController.loadUserCss(); }); } else if (field.equals(PropertyDef.DESIGN_PLAY_COLOR)) { Platform.runLater(() -> { design.setPlayColor(color); - pad.getPadSettings().setCustomDesign(true); + design.setEnableCustomPlayColor(true); mainViewController.loadUserCss(); }); } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/tigger/Trigger.java b/PlayWallCore/src/main/java/de/tobias/playpad/tigger/Trigger.java index 39ece8a9fd18f427d10d0d3067dc1184a1b8a681..f6d5fda76ac66f14a09bf7759e569b7ad9357bcb 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/tigger/Trigger.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/tigger/Trigger.java @@ -118,6 +118,8 @@ public class Trigger { } else { handleEndPoint(pad, currentDuration, project, mainViewController, currentProfile, item); } + } else if (triggerPoint == TriggerPoint.PLAYLIST_NEXT) { + item.performAction(pad, project, mainViewController, currentProfile); } } } diff --git a/PlayWallCore/src/main/java/de/tobias/playpad/tigger/TriggerPoint.java b/PlayWallCore/src/main/java/de/tobias/playpad/tigger/TriggerPoint.java index ce08ec84067ac2b3cb2a89b44f7c17335558eba2..175f1517ebb0418ad0684ea6f2693853d1203fa3 100644 --- a/PlayWallCore/src/main/java/de/tobias/playpad/tigger/TriggerPoint.java +++ b/PlayWallCore/src/main/java/de/tobias/playpad/tigger/TriggerPoint.java @@ -4,7 +4,8 @@ public enum TriggerPoint { START(true), STOP(false), - EOF(true); + EOF(true), + PLAYLIST_NEXT(false); /** * Defines if a trigger can be run after, before a certain event. diff --git a/PlayWallCore/src/test/java/de/tobias/playpad/design/modern/serializer/ModernCartDesignSerializerTest.java b/PlayWallCore/src/test/java/de/tobias/playpad/design/modern/serializer/ModernCartDesignSerializerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a9d45ba434dc424b0be1f71e1c0f24cfe7492244 --- /dev/null +++ b/PlayWallCore/src/test/java/de/tobias/playpad/design/modern/serializer/ModernCartDesignSerializerTest.java @@ -0,0 +1,78 @@ +package de.tobias.playpad.design.modern.serializer; + +import de.tobias.playpad.design.modern.ModernColor; +import de.tobias.playpad.design.modern.model.ModernCartDesign; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.junit.Test; + +import java.io.InputStream; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ModernCartDesignSerializerTest { + private final ModernColor BACKGROUND_COLOR = ModernColor.BLUE1; + private final ModernColor PLAY_COLOR = ModernColor.GRAY5; + private final ModernColor CUE_IN_COLOR = ModernColor.PURPLE1; + + private final UUID DESIGN_UUID = UUID.fromString("33977b97-60d6-49f1-897a-2f6f80de74e4"); + + + @Test + public void testSave() { + // arrange + final ModernCartDesign design = new ModernCartDesign.ModernCartDesignBuilder(null, DESIGN_UUID) + .withBackgroundColor(BACKGROUND_COLOR, true) + .withPlayColor(PLAY_COLOR, true) + .withCueInColor(CUE_IN_COLOR, false) + .build(); + + final Document document = DocumentHelper.createDocument(); + final Element rootElement = document.addElement("Design"); + + // act + final ModernCartDesignSerializer serializer = new ModernCartDesignSerializer(); + serializer.save(rootElement, design); + + // assert + assertThat(rootElement.attributeValue("id")).isEqualTo(DESIGN_UUID.toString()); + + assertThat(rootElement.element("EnableCustomBackgroundColor").getStringValue()).isEqualTo("true"); + assertThat(rootElement.element("BackgroundColor").getStringValue()).isEqualTo(BACKGROUND_COLOR.name()); + + assertThat(rootElement.element("EnableCustomPlayColor").getStringValue()).isEqualTo("true"); + assertThat(rootElement.element("PlayColor").getStringValue()).isEqualTo(PLAY_COLOR.name()); + + assertThat(rootElement.element("EnableCustomCueInColor").getStringValue()).isEqualTo("false"); + assertThat(rootElement.element("CueInColor").getStringValue()).isEqualTo(CUE_IN_COLOR.name()); + } + + @Test + public void testLoad() throws DocumentException { + // arrange + final String filePath = "de/tobias/playpad/design/modern/serializer/modern_cart_design.xml"; + final InputStream inputStream = ModernCartDesignSerializerTest.class.getClassLoader().getResourceAsStream(filePath); + final SAXReader reader = new SAXReader(); + final Document document = reader.read(inputStream); + + // act + final ModernCartDesignSerializer serializer = new ModernCartDesignSerializer(); + final ModernCartDesign design = serializer.load(document.getRootElement(), null); + + // assert + assertThat(design.getId()).isEqualTo(DESIGN_UUID); + + assertThat(design.isEnableCustomBackgroundColor()).isTrue(); + assertThat(design.getBackgroundColor()).isEqualTo(BACKGROUND_COLOR); + + assertThat(design.isEnableCustomPlayColor()).isTrue(); + assertThat(design.getPlayColor()).isEqualTo(PLAY_COLOR); + + assertThat(design.isEnableCustomCueInColor()).isFalse(); + assertThat(design.getCueInColor()).isEqualTo(CUE_IN_COLOR); + } +} diff --git a/PlayWallCore/src/test/java/de/tobias/playpad/design/modern/serializer/ModernGlobalDesignSerializerTest.java b/PlayWallCore/src/test/java/de/tobias/playpad/design/modern/serializer/ModernGlobalDesignSerializerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..aa6ed525ff513e47619b066e52f5772edbc27a32 --- /dev/null +++ b/PlayWallCore/src/test/java/de/tobias/playpad/design/modern/serializer/ModernGlobalDesignSerializerTest.java @@ -0,0 +1,73 @@ +package de.tobias.playpad.design.modern.serializer; + +import de.tobias.playpad.design.modern.ModernColor; +import de.tobias.playpad.design.modern.model.ModernGlobalDesign; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.junit.Test; + +import java.io.InputStream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ModernGlobalDesignSerializerTest { + private final ModernColor BACKGROUND_COLOR = ModernColor.BLUE1; + private final ModernColor PLAY_COLOR = ModernColor.GRAY5; + private final ModernColor CUE_IN_COLOR = ModernColor.PURPLE1; + private final int INFO_FONT_SIZE = 12; + private final int TITLE_FONT_SIZE = 18; + + @Test + public void testSave() { + // arrange + final ModernGlobalDesign design = new ModernGlobalDesign(); + design.setFlatDesign(true); + design.setBackgroundColor(BACKGROUND_COLOR); + design.setPlayColor(PLAY_COLOR); + design.setCueInColor(CUE_IN_COLOR); + design.setInfoFontSize(INFO_FONT_SIZE); + design.setTitleFontSize(TITLE_FONT_SIZE); + design.setWarnAnimation(true); + + final Document document = DocumentHelper.createDocument(); + final Element rootElement = document.addElement("Design"); + + // act + final ModernGlobalDesignSerializer serializer = new ModernGlobalDesignSerializer(); + serializer.save(rootElement, design); + + // assert + assertThat(rootElement.element("FlatDesign").getStringValue()).isEqualTo("true"); + assertThat(rootElement.element("BackgroundColor").getStringValue()).isEqualTo(BACKGROUND_COLOR.name()); + assertThat(rootElement.element("PlayColor").getStringValue()).isEqualTo(PLAY_COLOR.name()); + assertThat(rootElement.element("CueInColor").getStringValue()).isEqualTo(CUE_IN_COLOR.name()); + assertThat(rootElement.element("InfoFontSize").getStringValue()).isEqualTo("12"); + assertThat(rootElement.element("TitleFontSize").getStringValue()).isEqualTo("18"); + assertThat(rootElement.element("Animation").element("Warn").getStringValue()).isEqualTo("true"); + } + + @Test + public void testLoad() throws DocumentException { + // arrange + final String filePath = "de/tobias/playpad/design/modern/serializer/modern_global_design.xml"; + final InputStream inputStream = ModernGlobalDesignSerializerTest.class.getClassLoader().getResourceAsStream(filePath); + final SAXReader reader = new SAXReader(); + final Document document = reader.read(inputStream); + + // act + final ModernGlobalDesignSerializer serializer = new ModernGlobalDesignSerializer(); + final ModernGlobalDesign design = serializer.load(document.getRootElement()); + + // assert + assertThat(design.isFlatDesign()).isTrue(); + assertThat(design.getBackgroundColor()).isEqualTo(BACKGROUND_COLOR); + assertThat(design.getPlayColor()).isEqualTo(PLAY_COLOR); + assertThat(design.getCueInColor()).isEqualTo(CUE_IN_COLOR); + assertThat(design.getInfoFontSize()).isEqualTo(INFO_FONT_SIZE); + assertThat(design.getTitleFontSize()).isEqualTo(TITLE_FONT_SIZE); + assertThat(design.isWarnAnimation()).isTrue(); + } +} diff --git a/PlayWallCore/src/test/java/de/tobias/playpad/pad/PadSettingsSerializerTest.java b/PlayWallCore/src/test/java/de/tobias/playpad/pad/PadSettingsSerializerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b7f994051511b68bb1ee5063d1cccd8aae2953f1 --- /dev/null +++ b/PlayWallCore/src/test/java/de/tobias/playpad/pad/PadSettingsSerializerTest.java @@ -0,0 +1,52 @@ +package de.tobias.playpad.pad; + +import de.tobias.playpad.project.Project; +import de.tobias.playpad.project.ref.ProjectReference; +import de.tobias.playpad.settings.FadeSettings; +import javafx.util.Duration; +import org.dom4j.Document; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.junit.Test; + +import java.util.UUID; + +import static de.tobias.playpad.pad.PadSerializer.SETTINGS_ELEMENT; +import static org.assertj.core.api.Assertions.assertThat; + +public class PadSettingsSerializerTest { + @Test + public void testSave_General() { + // arrange + final Document document = DocumentHelper.createDocument(); + final Element rootElement = document.addElement(SETTINGS_ELEMENT); + + final Project project = new Project(new ProjectReference(UUID.randomUUID(), "TestProject", false)); + final Pad pad = new Pad(project, 1, null); + + final UUID padUUID = UUID.randomUUID(); + final PadSettings padSettings = new PadSettings(pad, padUUID); + padSettings.setVolume(0.5); + padSettings.setLoop(true); + padSettings.setTimeMode(TimeMode.REST); + padSettings.setFade(new FadeSettings(Duration.seconds(1), Duration.seconds(2))); + + final Duration expectedWarningDuration = Duration.seconds(3); + padSettings.setWarning(expectedWarningDuration); + final Duration expectedCueInDuration = Duration.seconds(4); + padSettings.setCueIn(expectedCueInDuration); + + // act + final PadSettingsSerializer serializer = new PadSettingsSerializer(); + serializer.saveElement(rootElement, padSettings); + + // assert + assertThat(rootElement.attribute("id").getStringValue()).isEqualTo(padUUID.toString()); + assertThat(rootElement.element("Volume").getStringValue()).isEqualTo("0.5"); + assertThat(rootElement.element("Loop").getStringValue()).isEqualTo("true"); + assertThat(rootElement.element("TimeMode").getStringValue()).isEqualTo(TimeMode.REST.toString()); + assertThat(rootElement.element("Fade").getStringValue()).isNotNull(); + assertThat(rootElement.element("Warning").getStringValue()).isEqualTo(expectedWarningDuration.toString()); + assertThat(rootElement.element("CueIn").getStringValue()).isEqualTo(expectedCueInDuration.toString()); + } +} diff --git a/PlayWallCore/src/test/resources/colors/ModernColor.json b/PlayWallCore/src/test/resources/colors/ModernColor.json new file mode 100644 index 0000000000000000000000000000000000000000..eae7057a68a2decc1663d87c5c93690720c835ac --- /dev/null +++ b/PlayWallCore/src/test/resources/colors/ModernColor.json @@ -0,0 +1,470 @@ +[ + { + "name": "RED1", + "colors": { + "hi": "#ef9a9a", + "low": "#ef5350", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "RED2", + "colors": { + "hi": "#ef5350", + "low": "#e53935", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "RED3", + "colors": { + "hi": "#e53935", + "low": "#c62828", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "DARK_RED1", + "colors": { + "hi": "#D92349", + "low": "#AD2039", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "DARK_RED2", + "colors": { + "hi": "#C92349", + "low": "#8D2039", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "DARK_RED3", + "colors": { + "hi": "#A90329", + "low": "#6D0019", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "PINK1", + "colors": { + "hi": "#f48fb1", + "low": "#ec407a", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "PINK2", + "colors": { + "hi": "#ec407a", + "low": "#d81b60", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "PINK3", + "colors": { + "hi": "#d81b60", + "low": "#ad1457", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "PURPLE1", + "colors": { + "hi": "#ce93d8", + "low": "#ab47bc", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "PURPLE2", + "colors": { + "hi": "#ab47bc", + "low": "#8e24aa", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "PURPLE3", + "colors": { + "hi": "#8e24aa", + "low": "#6a1b9a", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIGHT_BLUE1", + "colors": { + "hi": "#80deea", + "low": "#26c6da", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIGHT_BLUE2", + "colors": { + "hi": "#26c6da", + "low": "#00acc1", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIGHT_BLUE3", + "colors": { + "hi": "#00acc1", + "low": "#00838f", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "BLUE1", + "colors": { + "hi": "#90caf9", + "low": "#42a5f5", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "BLUE2", + "colors": { + "hi": "#42a5f5", + "low": "#1e88e5", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "BLUE3", + "colors": { + "hi": "#1e88e5", + "low": "#1565c0", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIGHT_GREEN1", + "colors": { + "hi": "#c5e1a5", + "low": "#9ccc65", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIGHT_GREEN2", + "colors": { + "hi": "#9ccc65", + "low": "#7cb342", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIGHT_GREEN3", + "colors": { + "hi": "#7cb342", + "low": "#558b2f", + "font": "#ffffff", + "button": "#ffffff", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIME1", + "colors": { + "hi": "#e6ee9c", + "low": "#d4e157", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIME2", + "colors": { + "hi": "#d4e157", + "low": "#c0ca33", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "LIME3", + "colors": { + "hi": "#c0ca33", + "low": "#9e9d24", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "YELLOW1", + "colors": { + "hi": "#fff59d", + "low": "#ffee58", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#333333", + "track": "#FFFFFF" + } + } + }, + { + "name": "YELLOW2", + "colors": { + "hi": "#ffee58", + "low": "#fdd835", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#333333", + "track": "#FFFFFF" + } + } + }, + { + "name": "YELLOW3", + "colors": { + "hi": "#fdd835", + "low": "#f9a825", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "ORANGE1", + "colors": { + "hi": "#ffcc80", + "low": "#ffa726", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "ORANGE2", + "colors": { + "hi": "#ffa726", + "low": "#fb8c00", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "ORANGE3", + "colors": { + "hi": "#fb8c00", + "low": "#ef6c00", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "GRAY1", + "colors": { + "hi": "#eeeeee", + "low": "#cccccc", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#333333", + "track": "#FFFFFF" + } + } + }, + { + "name": "GRAY2", + "colors": { + "hi": "#cccccc", + "low": "#aaaaaa", + "font": "#000000", + "button": "#000000", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "GRAY3", + "colors": { + "hi": "#aaaaaa", + "low": "#888888", + "font": "#FFFFFF", + "button": "#FFFFFF", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "GRAY4", + "colors": { + "hi": "#888888", + "low": "#666666", + "font": "#FFFFFF", + "button": "#FFFFFF", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "GRAY5", + "colors": { + "hi": "#666666", + "low": "#444444", + "font": "#FFFFFF", + "button": "#FFFFFF", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + }, + { + "name": "GRAY6", + "colors": { + "hi": "#444444", + "low": "#222222", + "font": "#FFFFFF", + "button": "#FFFFFF", + "playbar": { + "background": "#ffffff", + "track": "#333333" + } + } + } +] \ No newline at end of file diff --git a/PlayWallCore/src/test/resources/de/tobias/playpad/design/modern/serializer/modern_cart_design.xml b/PlayWallCore/src/test/resources/de/tobias/playpad/design/modern/serializer/modern_cart_design.xml new file mode 100644 index 0000000000000000000000000000000000000000..88091f5a057ef3b5ee3c5d64cf4ff19209c5a755 --- /dev/null +++ b/PlayWallCore/src/test/resources/de/tobias/playpad/design/modern/serializer/modern_cart_design.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Design id="33977b97-60d6-49f1-897a-2f6f80de74e4"> + <EnableCustomBackgroundColor>true</EnableCustomBackgroundColor> + <BackgroundColor>BLUE1</BackgroundColor> + <EnableCustomPlayColor>true</EnableCustomPlayColor> + <PlayColor>GRAY5</PlayColor> + <EnableCustomCueInColor>false</EnableCustomCueInColor> + <CueInColor>PURPLE1</CueInColor> +</Design> \ No newline at end of file diff --git a/PlayWallCore/src/test/resources/de/tobias/playpad/design/modern/serializer/modern_global_design.xml b/PlayWallCore/src/test/resources/de/tobias/playpad/design/modern/serializer/modern_global_design.xml new file mode 100644 index 0000000000000000000000000000000000000000..da9d358e8053997445ffe9e9101893b38db1deed --- /dev/null +++ b/PlayWallCore/src/test/resources/de/tobias/playpad/design/modern/serializer/modern_global_design.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Design> + <BackgroundColor>BLUE1</BackgroundColor> + <PlayColor>GRAY5</PlayColor> + <CueInColor>PURPLE1</CueInColor> + <Animation> + <Warn>true</Warn> + </Animation> + <InfoFontSize>12</InfoFontSize> + <TitleFontSize>18</TitleFontSize> + <FlatDesign>true</FlatDesign> +</Design> \ No newline at end of file diff --git a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerMediaContainer.scala b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerMediaContainer.scala index e524e428994f4150d9f6873461cf6bce10dbbf74..8e50a952dbf1a8ecacfbfcc97e14e94e3d68cfc1 100644 --- a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerMediaContainer.scala +++ b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerMediaContainer.scala @@ -8,7 +8,7 @@ import de.tobias.playpad.plugin.content.util._ import javafx.beans.property.{ObjectProperty, ReadOnlyObjectProperty, SimpleObjectProperty} import javafx.util.Duration -import java.nio.file.Files +import java.nio.file.{Files, Path} class ContentPlayerMediaContainer(val content: ContentPlayerPadContent, private[pad] val mediaPath: MediaPath, val totalDuration: Duration) { @@ -16,17 +16,17 @@ class ContentPlayerMediaContainer(val content: ContentPlayerPadContent, private[ _totalDurationProperty.set(totalDuration) - def getPath: String = { + def getPath: Path = { val sourcePath = mediaPath.getPath.toAbsolutePath val globalSettings = PlayPadPlugin.getInstance.getGlobalSettings val convertPath = globalSettings.getCachePath.resolve(sourcePath.getFileName + ".mp4") if (Files.exists(convertPath)) { - return convertPath.toString + return convertPath } - sourcePath.toString + sourcePath } def getTotalDuration: Duration = _totalDurationProperty.get() @@ -49,16 +49,21 @@ class ContentPlayerMediaContainer(val content: ContentPlayerPadContent, private[ } def next(): Unit = { - stop() - val players = content.getMediaContainers val currentIndex = players.indexOf(this) content.currentPlayingMediaIndexProperty().set(currentIndex) + if (currentIndex + 1 < players.length) { - players(currentIndex + 1).play(false) + content.listeners.forEach(listener => listener.onNextItem(content.pad, currentIndex + 1, players.length)) + if (content.getPad.getStatus == PadStatus.PLAY) { + players(currentIndex + 1).play(false) + } } else if (content.getPad.getPadSettings.isLoop) { - players.head.play(false) + content.listeners.forEach(listener => listener.onNextItem(content.pad, 0, players.length)) + if (content.getPad.getStatus == PadStatus.PLAY) { + players.head.play(false) + } } else { content.getPad.setStatus(PadStatus.STOP) } diff --git a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadContent.scala b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadContent.scala index f6eb4ba5405c2bc4951ea23d3a767f149cd37a2c..94524b4c33bc1c535d9b9c094593b8b851fafb86 100644 --- a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadContent.scala +++ b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadContent.scala @@ -1,8 +1,7 @@ package de.tobias.playpad.plugin.content.pad -import de.thecodelabs.logger.Logger import de.tobias.playpad.pad.content.play.{Durationable, Pauseable} -import de.tobias.playpad.pad.content.{PadContent, Playlistable} +import de.tobias.playpad.pad.content.{PadContent, PlaylistListener, Playlistable} import de.tobias.playpad.pad.fade.{Fadeable, LinearFadeController} import de.tobias.playpad.pad.mediapath.MediaPath import de.tobias.playpad.pad.{Pad, PadStatus} @@ -20,8 +19,8 @@ import nativecontentplayerwindows.ContentPlayer import java.nio.file.Files import java.util -import java.util.UUID import java.util.stream.Collectors +import java.util.{Collections, UUID} import scala.jdk.CollectionConverters._ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadContent(pad) with Pauseable with Durationable with Playlistable with Fadeable { @@ -32,6 +31,8 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte private[content] val _durationProperty = new SimpleObjectProperty[Duration] private[content] val _positionProperty = new SimpleObjectProperty[Duration] + private[content] val listeners: util.Set[PlaylistListener] = new util.HashSet[PlaylistListener]() + private var showingLastFrame: Boolean = false private var isPause: Boolean = false @@ -61,6 +62,9 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte if (isPause) { mediaPlayers(getCurrentPlayingMediaIndex).resume(withFadeIn) } else { + if (isShuffle) { + Collections.shuffle(mediaPlayers) + } getPad.setEof(false) mediaPlayers.head.play(withFadeIn) } @@ -117,7 +121,11 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte } showingLastFrame = false - mediaPlayers(getCurrentPlayingMediaIndex).next() + // Only automatically go to the next playlist item, if auto next is active or + // the item is the last one (next() go into stop state if no item is left) + if (isAutoNext || noFurtherItemsInPlaylist) { + mediaPlayers(getCurrentPlayingMediaIndex).next() + } } private def hasPadTriggerInterferingZones(item: LocalPadTrigger): Boolean = { @@ -292,9 +300,11 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte Custom Settings */ - def shouldShowLastFrame(): Boolean = { - pad.getPadSettings.getCustomSettings.getOrDefault(ContentPlayerPadContentFactory.lastFrame, false).asInstanceOf[Boolean] - } + def shouldShowLastFrame(): Boolean = pad.getPadSettings.getCustomSettings.getOrDefault(ContentPlayerPadContentFactory.lastFrame, false).asInstanceOf[Boolean] + + def isShuffle: Boolean = pad.getPadSettings.getCustomSettings.getOrDefault(Playlistable.SHUFFLE_SETTINGS_KEY, false).asInstanceOf[Boolean] + + def isAutoNext: Boolean = pad.getPadSettings.getCustomSettings.getOrDefault(Playlistable.AUTO_NEXT_SETTINGS_KEY, false).asInstanceOf[Boolean] def getSelectedZones: Seq[Zone] = { val zoneConfiguration = Profile.currentProfile().getCustomSettings(ContentPluginMain.zoneConfigurationKey).asInstanceOf[ContentPlayerPluginConfiguration] @@ -306,4 +316,12 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte ).asInstanceOf[util.List[UUID]] zoneConfiguration.zones.asScala.filter(zone => selectedZoneIds.contains(zone.id)).toSeq } + + /* + Listener + */ + + override def addPlaylistListener(listener: PlaylistListener): Unit = listeners.add(listener) + + override def removePlaylistListener(listener: PlaylistListener): Unit = listeners.remove(listener) } diff --git a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadPreview.scala b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadPreview.scala index 6ff298194c1ec57c2f6e7262b8c1c96db6498476..cbc98c236cfa37aef6f74c0390dfbbe78a4820dc 100644 --- a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadPreview.scala +++ b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/pad/ContentPlayerPadPreview.scala @@ -43,7 +43,8 @@ class ContentPlayerPadPreview(pad: Pad, parent: Pane) extends VBox with IPadCont pad.getContent match { case content: ContentPlayerPadContent => subTitleLabel.textProperty().bind(Bindings.createStringBinding(() => { - if (content.getCurrentPlayingMediaIndex < 0) "" else PathUtils.getFilenameWithoutExtension(pad.getPaths.get(content.getCurrentPlayingMediaIndex).getPath.getFileName) + if (content.getCurrentPlayingMediaIndex < 0) "" + else PathUtils.getFilenameWithoutExtension(content.getMediaContainers.get(content.getCurrentPlayingMediaIndex).getPath.getFileName) }, content.currentPlayingMediaIndexProperty())) case _ => } diff --git a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/player/ContentPlayerBinding.scala b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/player/ContentPlayerBinding.scala index 44dd4a25fc6a66ef57f45b9266c38316ba16c749..9484ac9be1ede9d096d580c4fdd3b96e25756429 100644 --- a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/player/ContentPlayerBinding.scala +++ b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/player/ContentPlayerBinding.scala @@ -51,7 +51,7 @@ class ContentPlayerBinding(val nativePlayer: ContentPlayer, val zone: Zone) { currentMedia.get().content.getPad.stop() } } - nativePlayer.Play(media.getPath, withFadeIn) + nativePlayer.Play(media.getPath.toString, withFadeIn) currentMedia.set(media) } diff --git a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/settings/ContentPlayerSettingsViewController.scala b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/settings/ContentPlayerSettingsViewController.scala index b5995d4197018f4a0ecc77e2893db1f29d241050..232afcb4edf0fa98c5b8bbdd3a7236d8b2efa6dc 100644 --- a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/settings/ContentPlayerSettingsViewController.scala +++ b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/settings/ContentPlayerSettingsViewController.scala @@ -22,6 +22,7 @@ import java.net.URI class ContentPlayerSettingsViewController extends ProfileSettingsTabViewController with IProfileReloadTask { private var startZoneHash: Int = _ + private var startScreenHash: Int = _ @FXML var ffmpegButton: Button = _ @FXML var ffmpegTextField: TextField = _ @@ -155,7 +156,8 @@ class ContentPlayerSettingsViewController extends ProfileSettingsTabViewControll override def loadSettings(settings: Profile): Unit = { val configuration = ContentPlayerSettingsViewController.getZoneConfiguration - startZoneHash = configuration.zones.hashCode() + startZoneHash = configuration.zones.hashCode + startScreenHash = configuration.screen.hashCode listView.getItems.setAll(configuration.zones) @@ -185,7 +187,8 @@ class ContentPlayerSettingsViewController extends ProfileSettingsTabViewControll configuration.ffprobeExecutable = ffprobeTextField.getText } - override def needReload(): Boolean = startZoneHash != ContentPlayerSettingsViewController.getZoneConfiguration.zones.hashCode() || + override def needReload(): Boolean = startZoneHash != ContentPlayerSettingsViewController.getZoneConfiguration.zones.hashCode || + startScreenHash != ContentPlayerSettingsViewController.getZoneConfiguration.screen.hashCode || !listView.getSelectionModel.isEmpty override def validSettings(): Boolean = { diff --git a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/util/package.scala b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/util/package.scala index a03e9ed9cff725f64f68845f2b88fd7fd43b7cce..14526479256ffb973bc8fd278df46f82b2b82f32 100644 --- a/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/util/package.scala +++ b/PlayWallPlugins/PlayWallPluginContentPlayer/src/main/scala/de/tobias/playpad/plugin/content/util/package.scala @@ -17,7 +17,7 @@ package object util { def apply(index: Int): E = list.get(index) - def length: Long = list.size() + def length: Int = list.size() def isNotEmpty: Boolean = !list.isEmpty diff --git a/pom.xml b/pom.xml index 4e735ed3fdaf7d8165254248ab14d39fffd7fba2..c55300adc97f3a64a49997d54a7e54c79cd20602 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ <packaging>pom</packaging> <properties> - <project.build.code>43</project.build.code> + <project.build.code>44</project.build.code> <project.versionDate>${maven.build.timestamp}</project.versionDate> <maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>