Merge remote-tracking branch 'origin/AudioDisplay' into AudioDisplay

This commit is contained in:
lieght
2025-10-16 00:57:01 +02:00
14 changed files with 156 additions and 39 deletions

View File

@@ -3,64 +3,84 @@ package org.toop.app.view.displays;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.control.ProgressBar; import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import org.toop.app.App; import javafx.scene.paint.Color;
import org.toop.app.view.View; import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.audio.AudioEventListener; import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.resource.ResourceManager;
import org.toop.framework.resource.resources.MusicAsset;
import org.toop.local.AppContext;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import org.toop.framework.audio.MusicManager;
import java.util.ArrayList;
import java.util.List;
public class SongDisplay extends VBox { public class SongDisplay extends VBox {
private final Text songTitle; private final Text songTitle;
private final ProgressBar progressBar; private final ProgressBar progressBar;
private final Text progressText; private final Text progressText;
private MusicManager<MusicAsset> manager;
public SongDisplay() { public SongDisplay() {
new EventFlow()
.listen(this::updateTheSong);
//TODO ADD NICER CSS
setAlignment(Pos.CENTER); setAlignment(Pos.CENTER);
getStyleClass().add("song-display"); getStyleClass().add("song-display");
// TODO ADD GOOD SONG TITLES WITH ARTISTS DISPLAYED
songTitle = new Text("song playing"); songTitle = new Text("song playing");
songTitle.setFill(Color.WHITE);
songTitle.getStyleClass().add("song-title"); songTitle.getStyleClass().add("song-title");
progressBar = new ProgressBar(0); progressBar = new ProgressBar(0);
progressBar.getStyleClass().add("progress-bar"); progressBar.getStyleClass().add("progress-bar");
progressText = new Text("THIS IS AN EXAMPLE CUZ BAS DIDNT DECIDE TO MAKE EVENTS"); progressText = new Text("0:00/0:00");
progressText.setFill(Color.WHITE);
progressText.getStyleClass().add("progress-text"); progressText.getStyleClass().add("progress-text");
getChildren().addAll(songTitle, progressBar, progressText); //TODO ADD SKIP BUTTON
setMusicManager(); getChildren().addAll(songTitle, progressBar, progressText);
} }
public void updateTheSong(String title, double progress) { private void updateTheSong(AudioEvents.PlayingMusic event) {
songTitle.setText(title); Platform.runLater(() -> {
String text = event.name();
text = text.substring(0, text.length() - 4);
songTitle.setText(text);
double currentPos = event.currentPosition();
double duration = event.duration();
if (currentPos / duration > 0.05) {
double progress = currentPos / duration;
progressBar.setProgress(progress); progressBar.setProgress(progress);
} }
else if (currentPos / duration < 0.05) {
public String getPlayingSong() { progressBar.setProgress(0.05);
return manager.getCurrentTrack().getName(); }
progressText.setText(getTimeString(event.currentPosition(), event.duration()));
});
} }
public void setMusicManager() { private String getTimeString(long position, long duration) {
List<MusicAsset> tracks = ResourceManager.getAllOfTypeAndRemoveWrapper(MusicAsset.class); long positionMinutes = position / 60;
this.manager = new MusicManager<>(tracks); long durationMinutes = duration / 60;
long positionSeconds = position % 60;
long durationSeconds = duration % 60;
String positionSecondsStr = String.valueOf(positionSeconds);
String durationSecondsStr = String.valueOf(durationSeconds);
String song = getPlayingSong(); if (positionSeconds < 10) {
Platform.runLater(() -> songTitle.setText(song)); positionSecondsStr = "0" + positionSeconds;
}
if (durationSeconds < 10) {
durationSecondsStr = "0" + durationSeconds;
}
String time = positionMinutes + ":" + positionSecondsStr + " / " + durationMinutes + ":" + durationSecondsStr;
return time;
} }
} }

View File

@@ -4,6 +4,7 @@ import org.toop.app.GameInformation;
import org.toop.app.Server; import org.toop.app.Server;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -95,6 +96,14 @@ public final class ChallengeView extends View {
nodes.add(vbox(computerDifficultyText, computerDifficultySlider)); nodes.add(vbox(computerDifficultyText, computerDifficultySlider));
} }
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER, add(Pos.CENTER,
fit(hboxFill( fit(hboxFill(
vboxFill( vboxFill(

View File

@@ -3,6 +3,7 @@ package org.toop.app.view.views;
import org.toop.app.App; import org.toop.app.App;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import javafx.animation.KeyFrame; import javafx.animation.KeyFrame;
@@ -46,6 +47,14 @@ public final class CreditsView extends View {
final Text openglHeader = header(); final Text openglHeader = header();
openglHeader.setText(AppContext.getString("opengl") + ": Omar"); openglHeader.setText(AppContext.getString("opengl") + ": Omar");
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER, add(Pos.CENTER,
fit("credits-fit", vboxFill("credits-container", "credits-container", fit("credits-fit", vboxFill("credits-container", "credits-container",
vbox("credits-spacer-top", ""), vbox("credits-spacer-top", ""),

View File

@@ -2,6 +2,7 @@ package org.toop.app.view.views;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -85,6 +86,14 @@ public final class GameView extends View {
forfeitButton = null; forfeitButton = null;
} }
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
if (onMessage != null) { if (onMessage != null) {
chatListView = new ListView<Text>(); chatListView = new ListView<Text>();

View File

@@ -5,6 +5,7 @@ import org.toop.app.game.ReversiGame;
import org.toop.app.game.TicTacToeGame; import org.toop.app.game.TicTacToeGame;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -48,6 +49,14 @@ public final class LocalMultiplayerView extends View {
} }
}); });
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER, add(Pos.CENTER,
fit(vboxFill( fit(vboxFill(
hbox( hbox(

View File

@@ -3,6 +3,7 @@ package org.toop.app.view.views;
import org.toop.app.GameInformation; import org.toop.app.GameInformation;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -34,6 +35,14 @@ public final class LocalView extends View {
backButton.setText(AppContext.getString("back")); backButton.setText(AppContext.getString("back"));
backButton.setOnAction(_ -> { ViewStack.push(new MainView()); }); backButton.setOnAction(_ -> { ViewStack.push(new MainView()); });
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.BOTTOM_LEFT, add(Pos.BOTTOM_LEFT,
vboxFill( vboxFill(
backButton backButton

View File

@@ -37,7 +37,6 @@ public final class MainView extends View {
final SongDisplay songdisplay = new SongDisplay(); final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT, add(Pos.BOTTOM_RIGHT,
fit(vboxFill( fit(vboxFill(
songdisplay songdisplay

View File

@@ -3,6 +3,7 @@ package org.toop.app.view.views;
import org.toop.app.Server; import org.toop.app.Server;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -44,6 +45,13 @@ public class OnlineView extends View {
new Server(serverIPInput.getText(), serverPortInput.getText(), playerNameInput.getText()); new Server(serverIPInput.getText(), serverPortInput.getText(), playerNameInput.getText());
}); });
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER, add(Pos.CENTER,
fit(vboxFill( fit(vboxFill(
serverInformationHeader, serverInformationHeader,

View File

@@ -3,6 +3,7 @@ package org.toop.app.view.views;
import org.toop.app.App; import org.toop.app.App;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.framework.audio.VolumeControl; import org.toop.framework.audio.VolumeControl;
import org.toop.framework.audio.events.AudioEvents; import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow; import org.toop.framework.eventbus.EventFlow;
@@ -99,6 +100,14 @@ public final class OptionsView extends View {
backButton.setText(AppContext.getString("back")); backButton.setText(AppContext.getString("back"));
backButton.setOnAction(_ -> { ViewStack.pop(); }); backButton.setOnAction(_ -> { ViewStack.pop(); });
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.BOTTOM_LEFT, add(Pos.BOTTOM_LEFT,
vboxFill( vboxFill(
backButton backButton

View File

@@ -2,6 +2,7 @@ package org.toop.app.view.views;
import org.toop.app.view.View; import org.toop.app.view.View;
import org.toop.app.view.ViewStack; import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import javafx.application.Platform; import javafx.application.Platform;
@@ -53,6 +54,14 @@ public final class ServerView extends View {
listView = new ListView<Button>(); listView = new ListView<Button>();
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER, add(Pos.CENTER,
fit(vboxFill( fit(vboxFill(
vbox( vbox(

View File

@@ -12,6 +12,34 @@
-fx-effect: dropshadow(gaussian, #224455cc, 8, 0, 0, 2); -fx-effect: dropshadow(gaussian, #224455cc, 8, 0, 0, 2);
} }
.song-display {
-fx-background-color: rgba(30, 60, 30, 0.85);
-fx-background-radius: 10px;
-fx-padding: 8 12 8 12;
-fx-spacing: 6px;
-fx-alignment: center;
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 6, 0.5, 0, 2);
-fx-min-width: 220px;
-fx-max-width: 260px;
-fx-text-fill: white;
}
.song-title {
-fx-font-size: 14px;
-fx-font-weight: bold;
-fx-text-fill: white;
}
.progress-bar {
-fx-pref-width: 150px;
-fx-accent: red;
}
.progress-text {
-fx-font-size: 11px;
-fx-text-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

@@ -21,6 +21,7 @@
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 6, 0.5, 0, 2); -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 6, 0.5, 0, 2);
-fx-min-width: 220px; -fx-min-width: 220px;
-fx-max-width: 260px; -fx-max-width: 260px;
-fx-text-fill: white;
} }
.song-title { .song-title {
@@ -30,17 +31,15 @@
} }
.progress-bar { .progress-bar {
-fx-pref-width: 200px; -fx-pref-width: 150px;
-fx-pref-height: 6px; -fx-accent: red;
-fx-accent: #ff4d4d;
-fx-background-color: rgba(255, 255, 255, 0.15);
-fx-background-radius: 4px;
} }
.progress-text { .progress-text {
-fx-font-size: 11px; -fx-font-size: 11px;
-fx-text-fill: white; -fx-text-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

@@ -13,7 +13,7 @@
} }
.song-display { .song-display {
-fx-background-color: rgba(20, 20, 20, 0.75); -fx-background-color: rgba(30, 60, 30, 0.85);
-fx-background-radius: 10px; -fx-background-radius: 10px;
-fx-padding: 8 12 8 12; -fx-padding: 8 12 8 12;
-fx-spacing: 6px; -fx-spacing: 6px;
@@ -21,6 +21,7 @@
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 6, 0.5, 0, 2); -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 6, 0.5, 0, 2);
-fx-min-width: 220px; -fx-min-width: 220px;
-fx-max-width: 260px; -fx-max-width: 260px;
-fx-text-fill: white;
} }
.song-title { .song-title {
@@ -30,17 +31,15 @@
} }
.progress-bar { .progress-bar {
-fx-pref-width: 200px; -fx-pref-width: 150px;
-fx-pref-height: 6px; -fx-accent: red;
-fx-accent: #4dd0e1; /* bright cyan progress color */
-fx-background-color: rgba(255, 255, 255, 0.15);
-fx-background-radius: 4px;
} }
.progress-text { .progress-text {
-fx-font-size: 11px; -fx-font-size: 11px;
-fx-text-fill: #cccccc; -fx-text-fill: white;
} }
.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

@@ -18,6 +18,7 @@ public class AudioEvents extends EventsBase {
/** Start background music. */ /** Start background music. */
public record StartBackgroundMusic() implements GenericEvent {} public record StartBackgroundMusic() implements GenericEvent {}
/** Gives back the name of the song, the position its currently at (in seconds) and how long it takes (in seconds) */
public record PlayingMusic(String name, long currentPosition, long duration) implements GenericEvent {} public record PlayingMusic(String name, long currentPosition, long duration) implements GenericEvent {}
/** Change volume, choose type with {@link VolumeControl}. */ /** Change volume, choose type with {@link VolumeControl}. */