Toegevoegd:

-Play Button + CSS + Events
-Previous Button + CSS + Events
-Changed interface for AudioResource to include a pause button which works really well with mediaplayer, however now SoundEffectAsset has an unnessescary pause
This commit is contained in:
michiel301b
2025-10-24 13:22:42 +02:00
parent b1589032be
commit 0c536b0f9b
11 changed files with 140 additions and 1 deletions

View File

@@ -3,6 +3,7 @@ package org.toop.app.view.displays;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar; import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import org.toop.framework.audio.AudioEventListener; 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 // TODO ADD BETTER CSS FOR THE SKIPBUTTON WHERE ITS AT A NICER POSITION
Button skipButton = new Button(">>"); Button skipButton = new Button(">>");
Button pauseButton = new Button("");
Button previousButton = new Button("<<");
skipButton.getStyleClass().setAll("skip-button"); skipButton.getStyleClass().setAll("skip-button");
pauseButton.getStyleClass().setAll("pause-button");
previousButton.getStyleClass().setAll("previous-button");
skipButton.setOnAction( event -> { skipButton.setOnAction( event -> {
GlobalEventBus.post(new AudioEvents.SkipMusic()); 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) { private void updateTheSong(AudioEvents.PlayingMusic event) {

View File

@@ -55,6 +55,28 @@
-fx-fill: white; -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 { .button {
-fx-background-color: linear-gradient(to bottom, #1f5e20, #2e7d2e); -fx-background-color: linear-gradient(to bottom, #1f5e20, #2e7d2e);
-fx-background-radius: 8; -fx-background-radius: 8;

View File

@@ -55,6 +55,28 @@
-fx-fill: white; -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 { .button {
-fx-background-color: linear-gradient(to bottom, #1b7a1b, #2da32d); -fx-background-color: linear-gradient(to bottom, #1b7a1b, #2da32d);
-fx-background-radius: 8; -fx-background-radius: 8;

View File

@@ -56,6 +56,28 @@
-fx-fill: black; -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 { .button {
-fx-background-color: linear-gradient(to bottom, #7ac27a, #90d090); -fx-background-color: linear-gradient(to bottom, #7ac27a, #90d090);
-fx-background-radius: 8; -fx-background-radius: 8;

View File

@@ -28,6 +28,8 @@ public class AudioEventListener<T extends AudioResource, K extends AudioResource
.listen(this::handleStopMusicManager) .listen(this::handleStopMusicManager)
.listen(this::handlePlaySound) .listen(this::handlePlaySound)
.listen(this::handleSkipSong) .listen(this::handleSkipSong)
.listen(this::handlePauseSong)
.listen(this::handlePreviousSong)
.listen(this::handleStopSound) .listen(this::handleStopSound)
.listen(this::handleMusicStart) .listen(this::handleMusicStart)
.listen(this::handleVolumeChange) .listen(this::handleVolumeChange)
@@ -50,6 +52,15 @@ public class AudioEventListener<T extends AudioResource, K extends AudioResource
this.musicManager.skip(); this.musicManager.skip();
} }
private void handlePauseSong(AudioEvents.PauseMusic event) {
this.musicManager.pause();
}
private void handlePreviousSong(AudioEvents.PreviousMusic event) {
this.musicManager.previous();
}
private void handleStopSound(AudioEvents.StopEffect event) { private void handleStopSound(AudioEvents.StopEffect event) {
this.soundEffectManager.stop(event.fileName()); this.soundEffectManager.stop(event.fileName());
} }

View File

@@ -23,6 +23,7 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
private final List<T> resources; private final List<T> resources;
private int playingIndex = 0; private int playingIndex = 0;
private boolean playing = false; private boolean playing = false;
private long pausedPosition = 0;
private ScheduledExecutorService scheduler; private ScheduledExecutorService scheduler;
@@ -156,4 +157,29 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
playing = false; playing = false;
dispatcher.run(() -> backgroundMusic.forEach(T::stop)); 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();
}
} }

View File

@@ -24,6 +24,10 @@ public class AudioEvents extends EventsBase {
/** Skips the song to the last second of the song resulting in a skip effect */ /** Skips the song to the last second of the song resulting in a skip effect */
public record SkipMusic() implements GenericEvent {} public record SkipMusic() implements GenericEvent {}
public record PreviousMusic() implements GenericEvent {}
public record PauseMusic() implements GenericEvent {}
/** Change volume, choose type with {@link VolumeControl}. */ /** Change volume, choose type with {@link VolumeControl}. */
public record ChangeVolume(double newVolume, VolumeControl controlType) implements GenericEvent {} public record ChangeVolume(double newVolume, VolumeControl controlType) implements GenericEvent {}

View File

@@ -6,4 +6,6 @@ public interface MusicManager<T extends AudioResource> extends AudioManager<T> {
void play(); void play();
void stop(); void stop();
void skip(); void skip();
void previous();
void pause();
} }

View File

@@ -78,6 +78,10 @@ public class MusicAsset extends BaseResource implements LoadableResource, AudioR
getMediaPlayer().play(); getMediaPlayer().play();
} }
public void pause() {
getMediaPlayer().pause();
}
@Override @Override
public void stop() { public void stop() {
getMediaPlayer().stop(); getMediaPlayer().stop();

View File

@@ -142,6 +142,12 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource,
if (this.clip.isRunning()) this.clip.stop(); 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 @Override
public long duration() { public long duration() {
if (clip != null) { if (clip != null) {

View File

@@ -9,4 +9,5 @@ public interface AudioResource {
long currentPosition(); long currentPosition();
void setOnEnd(Runnable run); void setOnEnd(Runnable run);
void setOnError(Runnable run); void setOnError(Runnable run);
void pause();
} }