diff --git a/app/src/main/java/org/toop/app/view/displays/SongDisplay.java b/app/src/main/java/org/toop/app/view/displays/SongDisplay.java index 8090e5b..3dbd2e5 100644 --- a/app/src/main/java/org/toop/app/view/displays/SongDisplay.java +++ b/app/src/main/java/org/toop/app/view/displays/SongDisplay.java @@ -3,6 +3,7 @@ package org.toop.app.view.displays; import javafx.application.Platform; import javafx.scene.control.Button; import javafx.scene.control.ProgressBar; +import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import org.toop.framework.audio.AudioEventListener; @@ -38,12 +39,30 @@ public class SongDisplay extends VBox { // TODO ADD BETTER CSS FOR THE SKIPBUTTON WHERE ITS AT A NICER POSITION Button skipButton = new Button(">>"); + Button pauseButton = new Button("⏸"); + Button previousButton = new Button("<<"); + skipButton.getStyleClass().setAll("skip-button"); + pauseButton.getStyleClass().setAll("pause-button"); + previousButton.getStyleClass().setAll("previous-button"); + skipButton.setOnAction( event -> { GlobalEventBus.post(new AudioEvents.SkipMusic()); }); - getChildren().addAll(songTitle, progressBar, progressText, skipButton); + pauseButton.setOnAction(event -> { + GlobalEventBus.post(new AudioEvents.PauseMusic()); + }); + + previousButton.setOnAction( event -> { + GlobalEventBus.post(new AudioEvents.PreviousMusic()); + }); + + HBox control = new HBox(10, previousButton, pauseButton, skipButton); + control.setAlignment(Pos.CENTER); + control.getStyleClass().add("controls"); + + getChildren().addAll(songTitle, progressBar, progressText, control); } private void updateTheSong(AudioEvents.PlayingMusic event) { diff --git a/app/src/main/resources/assets/style/dark.css b/app/src/main/resources/assets/style/dark.css index 3d3cc77..da30eb0 100644 --- a/app/src/main/resources/assets/style/dark.css +++ b/app/src/main/resources/assets/style/dark.css @@ -55,6 +55,28 @@ -fx-fill: white; } +.pause-button { + -fx-background-color: transparent; + -fx-background-radius: 0; + -fx-cursor: hand; + -fx-text-fill: white; + } + +.pause-button .text { + -fx-fill: white; +} + +.previous-button { + -fx-background-color: transparent; + -fx-background-radius: 0; + -fx-cursor: hand; + -fx-text-fill: white; + } + +.previous-button .text { + -fx-fill: white; +} + .button { -fx-background-color: linear-gradient(to bottom, #1f5e20, #2e7d2e); -fx-background-radius: 8; diff --git a/app/src/main/resources/assets/style/high-contrast.css b/app/src/main/resources/assets/style/high-contrast.css index ef448ce..111449d 100644 --- a/app/src/main/resources/assets/style/high-contrast.css +++ b/app/src/main/resources/assets/style/high-contrast.css @@ -55,6 +55,28 @@ -fx-fill: white; } +.pause-button { + -fx-background-color: transparent; + -fx-background-radius: 0; + -fx-cursor: hand; + -fx-text-fill: white; + } + +.pause-button .text { + -fx-fill: white; +} + +.previous-button { + -fx-background-color: transparent; + -fx-background-radius: 0; + -fx-cursor: hand; + -fx-text-fill: white; + } + +.previous-button .text { + -fx-fill: white; +} + .button { -fx-background-color: linear-gradient(to bottom, #1b7a1b, #2da32d); -fx-background-radius: 8; diff --git a/app/src/main/resources/assets/style/light.css b/app/src/main/resources/assets/style/light.css index 0b5e1d7..0428f04 100644 --- a/app/src/main/resources/assets/style/light.css +++ b/app/src/main/resources/assets/style/light.css @@ -56,6 +56,28 @@ -fx-fill: black; } +.pause-button { + -fx-background-color: transparent; + -fx-background-radius: 0; + -fx-cursor: hand; + -fx-text-fill: black; + } + +.pause-button .text { + -fx-fill: black; +} + +.previous-button { + -fx-background-color: transparent; + -fx-background-radius: 0; + -fx-cursor: hand; + -fx-text-fill: black; + } + +.previous-button .text { + -fx-fill: black; +} + .button { -fx-background-color: linear-gradient(to bottom, #7ac27a, #90d090); -fx-background-radius: 8; diff --git a/framework/src/main/java/org/toop/framework/audio/AudioEventListener.java b/framework/src/main/java/org/toop/framework/audio/AudioEventListener.java index f971947..628eae6 100644 --- a/framework/src/main/java/org/toop/framework/audio/AudioEventListener.java +++ b/framework/src/main/java/org/toop/framework/audio/AudioEventListener.java @@ -28,6 +28,8 @@ public class AudioEventListener implements org.toop.framework private final List resources; private int playingIndex = 0; private boolean playing = false; + private long pausedPosition = 0; private ScheduledExecutorService scheduler; @@ -156,4 +157,29 @@ public class MusicManager implements org.toop.framework playing = false; dispatcher.run(() -> backgroundMusic.forEach(T::stop)); } + + public void pause() { + T current = backgroundMusic.get(playingIndex); + if (this.playing) { + current.pause(); + playing = false; + } + else { + this.playing = true; + dispatcher.run(() -> { + current.play(); + setTrackRunnable(current); + }); + } + } + + public void previous() { + if (backgroundMusic.isEmpty()) return; + if (playingIndex == 0) return; + stop(); + scheduler.shutdownNow(); + playingIndex = playingIndex - 1; + playing = true; + playCurrentTrack(); + } } diff --git a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java index 8ec0fcf..e416065 100644 --- a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java +++ b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java @@ -24,6 +24,10 @@ public class AudioEvents extends EventsBase { /** Skips the song to the last second of the song resulting in a skip effect */ public record SkipMusic() implements GenericEvent {} + public record PreviousMusic() implements GenericEvent {} + + public record PauseMusic() implements GenericEvent {} + /** Change volume, choose type with {@link VolumeControl}. */ public record ChangeVolume(double newVolume, VolumeControl controlType) implements GenericEvent {} diff --git a/framework/src/main/java/org/toop/framework/audio/interfaces/MusicManager.java b/framework/src/main/java/org/toop/framework/audio/interfaces/MusicManager.java index 0e197f8..8b59179 100644 --- a/framework/src/main/java/org/toop/framework/audio/interfaces/MusicManager.java +++ b/framework/src/main/java/org/toop/framework/audio/interfaces/MusicManager.java @@ -6,4 +6,6 @@ public interface MusicManager extends AudioManager { void play(); void stop(); void skip(); + void previous(); + void pause(); } diff --git a/framework/src/main/java/org/toop/framework/resource/resources/MusicAsset.java b/framework/src/main/java/org/toop/framework/resource/resources/MusicAsset.java index 005a0d9..530ca2f 100644 --- a/framework/src/main/java/org/toop/framework/resource/resources/MusicAsset.java +++ b/framework/src/main/java/org/toop/framework/resource/resources/MusicAsset.java @@ -78,6 +78,10 @@ public class MusicAsset extends BaseResource implements LoadableResource, AudioR getMediaPlayer().play(); } + public void pause() { + getMediaPlayer().pause(); + } + @Override public void stop() { getMediaPlayer().stop(); diff --git a/framework/src/main/java/org/toop/framework/resource/resources/SoundEffectAsset.java b/framework/src/main/java/org/toop/framework/resource/resources/SoundEffectAsset.java index c7298f9..13d5547 100644 --- a/framework/src/main/java/org/toop/framework/resource/resources/SoundEffectAsset.java +++ b/framework/src/main/java/org/toop/framework/resource/resources/SoundEffectAsset.java @@ -142,6 +142,12 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource, if (this.clip.isRunning()) this.clip.stop(); } + // had to be implemented for mediaplayer.pause() to work so: + // TODO: get this removed, somehow OR get a clip.pause which I have no idea why you would ever use + public void pause() { + this.clip.stop(); + } + @Override public long duration() { if (clip != null) { diff --git a/framework/src/main/java/org/toop/framework/resource/types/AudioResource.java b/framework/src/main/java/org/toop/framework/resource/types/AudioResource.java index d001aa8..c8161cc 100644 --- a/framework/src/main/java/org/toop/framework/resource/types/AudioResource.java +++ b/framework/src/main/java/org/toop/framework/resource/types/AudioResource.java @@ -9,4 +9,5 @@ public interface AudioResource { long currentPosition(); void setOnEnd(Runnable run); void setOnError(Runnable run); + void pause(); }