Skip to content
Snippets Groups Projects
Commit 4867df72 authored by Tobias Ullerich's avatar Tobias Ullerich
Browse files

#180 - Add playlist shuffle mode to content player

parent d1653d34
No related branches found
No related tags found
No related merge requests found
Showing
with 90 additions and 57 deletions
...@@ -4,7 +4,6 @@ import de.thecodelabs.utils.application.system.NativeApplication; ...@@ -4,7 +4,6 @@ import de.thecodelabs.utils.application.system.NativeApplication;
import de.thecodelabs.utils.ui.icon.FontAwesomeType; import de.thecodelabs.utils.ui.icon.FontAwesomeType;
import de.thecodelabs.utils.ui.icon.FontIcon; import de.thecodelabs.utils.ui.icon.FontIcon;
import de.thecodelabs.utils.util.Localization; import de.thecodelabs.utils.util.Localization;
import de.tobias.playpad.PlayPad;
import de.tobias.playpad.PlayPadPlugin; import de.tobias.playpad.PlayPadPlugin;
import de.tobias.playpad.Strings; import de.tobias.playpad.Strings;
import de.tobias.playpad.layout.desktop.listener.PadNewContentListener; import de.tobias.playpad.layout.desktop.listener.PadNewContentListener;
...@@ -19,10 +18,7 @@ import javafx.beans.binding.Bindings; ...@@ -19,10 +18,7 @@ import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Button; import javafx.scene.control.*;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import java.io.File; import java.io.File;
...@@ -31,6 +27,9 @@ import java.util.List; ...@@ -31,6 +27,9 @@ import java.util.List;
public class PlaylistTabViewController extends PadSettingsTabViewController { public class PlaylistTabViewController extends PadSettingsTabViewController {
@FXML
private CheckBox shuffleCheckbox;
@FXML @FXML
private ListView<MediaPath> mediaPathListView; private ListView<MediaPath> mediaPathListView;
...@@ -123,12 +122,12 @@ public class PlaylistTabViewController extends PadSettingsTabViewController { ...@@ -123,12 +122,12 @@ public class PlaylistTabViewController extends PadSettingsTabViewController {
@Override @Override
public void loadSettings(Pad pad) { public void loadSettings(Pad pad) {
// Not implemented shuffleCheckbox.setSelected((Boolean) pad.getPadSettings().getCustomSettings().getOrDefault(Playlistable.SHUFFLE_SETTINGS_KEY, false));
} }
@Override @Override
public void saveSettings(Pad pad) { public void saveSettings(Pad pad) {
// Not implemented pad.getPadSettings().getCustomSettings().put(Playlistable.SHUFFLE_SETTINGS_KEY, shuffleCheckbox.isSelected());
} }
@FXML @FXML
......
...@@ -137,6 +137,8 @@ padSettings.player.label.cueIn=Intro Dauer (in s): ...@@ -137,6 +137,8 @@ padSettings.player.label.cueIn=Intro Dauer (in s):
padSettings.player.label.fade=Ein-/Ausblenden: padSettings.player.label.fade=Ein-/Ausblenden:
padSettings.layout.label.custom=Eigenes Layout: padSettings.layout.label.custom=Eigenes Layout:
padSettings.layout.checkbox.custom=Aktiviert padSettings.layout.checkbox.custom=Aktiviert
padSettings.playlist.settings.title=Allgemeine Einstellungen
padSettings.playlist.settings.shuffle=Zuf\u00E4llige Wiedergabe
project.label.details=Projektinformationen: project.label.details=Projektinformationen:
project.label.name=Name: project.label.name=Name:
project.label.profile=Profil: project.label.profile=Profil:
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.Button?>
<?import javafx.scene.layout.*?> <?import javafx.scene.control.CheckBox?>
<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"> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/17" 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" />
</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> <children>
<VBox spacing="14.0"> <VBox spacing="14.0">
<children> <children>
...@@ -44,3 +63,5 @@ ...@@ -44,3 +63,5 @@
<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> </padding>
</HBox> </HBox>
</children>
</VBox>
...@@ -4,6 +4,9 @@ import de.tobias.playpad.pad.mediapath.MediaPath; ...@@ -4,6 +4,9 @@ import de.tobias.playpad.pad.mediapath.MediaPath;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
public interface Playlistable { public interface Playlistable {
String SHUFFLE_SETTINGS_KEY = "shuffle";
int getCurrentPlayingMediaIndex(); int getCurrentPlayingMediaIndex();
IntegerProperty currentPlayingMediaIndexProperty(); IntegerProperty currentPlayingMediaIndexProperty();
......
...@@ -8,7 +8,7 @@ import de.tobias.playpad.plugin.content.util._ ...@@ -8,7 +8,7 @@ import de.tobias.playpad.plugin.content.util._
import javafx.beans.property.{ObjectProperty, ReadOnlyObjectProperty, SimpleObjectProperty} import javafx.beans.property.{ObjectProperty, ReadOnlyObjectProperty, SimpleObjectProperty}
import javafx.util.Duration 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) { class ContentPlayerMediaContainer(val content: ContentPlayerPadContent, private[pad] val mediaPath: MediaPath, val totalDuration: Duration) {
...@@ -16,17 +16,17 @@ class ContentPlayerMediaContainer(val content: ContentPlayerPadContent, private[ ...@@ -16,17 +16,17 @@ class ContentPlayerMediaContainer(val content: ContentPlayerPadContent, private[
_totalDurationProperty.set(totalDuration) _totalDurationProperty.set(totalDuration)
def getPath: String = { def getPath: Path = {
val sourcePath = mediaPath.getPath.toAbsolutePath val sourcePath = mediaPath.getPath.toAbsolutePath
val globalSettings = PlayPadPlugin.getInstance.getGlobalSettings val globalSettings = PlayPadPlugin.getInstance.getGlobalSettings
val convertPath = globalSettings.getCachePath.resolve(sourcePath.getFileName + ".mp4") val convertPath = globalSettings.getCachePath.resolve(sourcePath.getFileName + ".mp4")
if (Files.exists(convertPath)) { if (Files.exists(convertPath)) {
return convertPath.toString return convertPath
} }
sourcePath.toString sourcePath
} }
def getTotalDuration: Duration = _totalDurationProperty.get() def getTotalDuration: Duration = _totalDurationProperty.get()
......
...@@ -20,7 +20,7 @@ import nativecontentplayerwindows.ContentPlayer ...@@ -20,7 +20,7 @@ import nativecontentplayerwindows.ContentPlayer
import java.nio.file.Files import java.nio.file.Files
import java.util import java.util
import java.util.UUID import java.util.{Collections, UUID}
import java.util.stream.Collectors import java.util.stream.Collectors
import scala.jdk.CollectionConverters._ import scala.jdk.CollectionConverters._
...@@ -61,6 +61,9 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte ...@@ -61,6 +61,9 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte
if (isPause) { if (isPause) {
mediaPlayers(getCurrentPlayingMediaIndex).resume(withFadeIn) mediaPlayers(getCurrentPlayingMediaIndex).resume(withFadeIn)
} else { } else {
if (isShuffle) {
Collections.shuffle(mediaPlayers)
}
getPad.setEof(false) getPad.setEof(false)
mediaPlayers.head.play(withFadeIn) mediaPlayers.head.play(withFadeIn)
} }
...@@ -296,6 +299,10 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte ...@@ -296,6 +299,10 @@ class ContentPlayerPadContent(val pad: Pad, val `type`: String) extends PadConte
pad.getPadSettings.getCustomSettings.getOrDefault(ContentPlayerPadContentFactory.lastFrame, false).asInstanceOf[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 getSelectedZones: Seq[Zone] = { def getSelectedZones: Seq[Zone] = {
val zoneConfiguration = Profile.currentProfile().getCustomSettings(ContentPluginMain.zoneConfigurationKey).asInstanceOf[ContentPlayerPluginConfiguration] val zoneConfiguration = Profile.currentProfile().getCustomSettings(ContentPluginMain.zoneConfigurationKey).asInstanceOf[ContentPlayerPluginConfiguration]
......
...@@ -43,7 +43,8 @@ class ContentPlayerPadPreview(pad: Pad, parent: Pane) extends VBox with IPadCont ...@@ -43,7 +43,8 @@ class ContentPlayerPadPreview(pad: Pad, parent: Pane) extends VBox with IPadCont
pad.getContent match { pad.getContent match {
case content: ContentPlayerPadContent => case content: ContentPlayerPadContent =>
subTitleLabel.textProperty().bind(Bindings.createStringBinding(() => { 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())) }, content.currentPlayingMediaIndexProperty()))
case _ => case _ =>
} }
......
...@@ -51,7 +51,7 @@ class ContentPlayerBinding(val nativePlayer: ContentPlayer, val zone: Zone) { ...@@ -51,7 +51,7 @@ class ContentPlayerBinding(val nativePlayer: ContentPlayer, val zone: Zone) {
currentMedia.get().content.getPad.stop() currentMedia.get().content.getPad.stop()
} }
} }
nativePlayer.Play(media.getPath, withFadeIn) nativePlayer.Play(media.getPath.toString, withFadeIn)
currentMedia.set(media) currentMedia.set(media)
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment