Merge remote-tracking branch 'origin/UI-Updates' into UI-Updates

This commit is contained in:
ramollia
2025-12-04 17:02:33 +01:00
9 changed files with 159 additions and 90 deletions

View File

@@ -1,5 +1,7 @@
package org.toop.app; package org.toop.app;
import javafx.application.Platform;
import javafx.scene.paint.Color;
import org.toop.Main; import org.toop.Main;
import org.toop.app.widget.Primitive; import org.toop.app.widget.Primitive;
import org.toop.app.widget.Widget; import org.toop.app.widget.Widget;
@@ -50,11 +52,13 @@ public final class App extends Application {
final StackPane root = WidgetContainer.setup(); final StackPane root = WidgetContainer.setup();
final Scene scene = new Scene(root); final Scene scene = new Scene(root);
stage.setOpacity(0.0);
stage.setTitle(AppContext.getString("app-title")); stage.setTitle(AppContext.getString("app-title"));
stage.titleProperty().bind(AppContext.bindToKey("app-title")); stage.titleProperty().bind(AppContext.bindToKey("app-title"));
stage.setWidth(1080); stage.setWidth(0);
stage.setHeight(720); stage.setHeight(0);
scene.getRoot(); scene.getRoot();
@@ -79,26 +83,40 @@ public final class App extends Application {
AppSettings.applySettings(); AppSettings.applySettings();
LoadingWidget loading = new LoadingWidget(Primitive.text( LoadingWidget loading = new LoadingWidget(Primitive.text(
"Loading...", false), 0, 0, Integer.MAX_VALUE, false // Just set a high default "Loading...", false), 0, 0, Integer.MAX_VALUE, false, false // Just set a high default
); );
WidgetContainer.add(Pos.CENTER, loading); WidgetContainer.setCurrentView(loading);
setOnLoadingSuccess(loading); setOnLoadingSuccess(loading);
EventFlow loadingFlow = new EventFlow(); EventFlow loadingFlow = new EventFlow();
final boolean[] hasRun = {false};
loadingFlow loadingFlow
.listen(AssetLoaderEvents.LoadingProgressUpdate.class, e -> { .listen(AssetLoaderEvents.LoadingProgressUpdate.class, e -> {
loading.setMaxAmount(e.isLoadingAmount()); if (!hasRun[0]) {
hasRun[0] = true;
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
Platform.runLater(() -> stage.setOpacity(1.0));
}
Platform.runLater(() -> loading.setMaxAmount(e.isLoadingAmount()));
Platform.runLater(() -> {
try { try {
loading.setAmount(e.hasLoadedAmount()); loading.setAmount(e.hasLoadedAmount());
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
});
if (e.hasLoadedAmount() >= e.isLoadingAmount()) { if (e.hasLoadedAmount() >= e.isLoadingAmount()) {
loading.triggerSuccess(); Platform.runLater(loading::triggerSuccess);
loadingFlow.unsubscribe("init_loading"); loadingFlow.unsubscribe("init_loading");
} }
@@ -107,7 +125,9 @@ public final class App extends Application {
// Start loading assets // Start loading assets
new Thread(() -> ResourceManager.loadAssets(new ResourceLoader("app/src/main/resources/assets"))) new Thread(() -> ResourceManager.loadAssets(new ResourceLoader("app/src/main/resources/assets")))
.start(); .start();
stage.show(); stage.show();
} }
private void setOnLoadingSuccess(LoadingWidget loading) { private void setOnLoadingSuccess(LoadingWidget loading) {

View File

@@ -86,7 +86,7 @@ public final class Server {
final int reconnectAttempts = 10; final int reconnectAttempts = 10;
LoadingWidget loading = new LoadingWidget( LoadingWidget loading = new LoadingWidget(
Primitive.text("connecting"), 0, 0, reconnectAttempts, true Primitive.text("connecting"), 0, 0, reconnectAttempts, true, true
); );
WidgetContainer.getCurrentView().transitionNext(loading); WidgetContainer.getCurrentView().transitionNext(loading);
@@ -100,6 +100,7 @@ public final class Server {
loading.setOnFailure(() -> { loading.setOnFailure(() -> {
WidgetContainer.getCurrentView().transitionPrevious(); WidgetContainer.getCurrentView().transitionPrevious();
a.unsubscribe("connecting"); a.unsubscribe("connecting");
a.unsubscribe("startclient");
WidgetContainer.add( WidgetContainer.add(
Pos.CENTER, Pos.CENTER,
new ErrorPopup(AppContext.getString("connecting-failed") + " " + ip + ":" + port) new ErrorPopup(AppContext.getString("connecting-failed") + " " + ip + ":" + port)

View File

@@ -2,19 +2,28 @@ package org.toop.app.widget;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.resource.ResourceLoader;
public interface Widget { public interface Widget {
Logger logger = LogManager.getLogger(Widget.class);
Node getNode(); Node getNode();
default void show(Pos position) { default void show(Pos position) {
logger.debug("Showing Widget: {} at position: {}", this.getNode(), position.toString());
WidgetContainer.add(position, this); WidgetContainer.add(position, this);
} }
default void hide() { default void hide() {
logger.debug("Hiding Widget: {}", this.getNode());
WidgetContainer.remove(this); WidgetContainer.remove(this);
} }
default void replace(Pos position, Widget widget) { default void replace(Pos position, Widget widget) {
logger.debug("Replacing Widget: {}, with widget: {}, to position: {}",
this.getNode(), widget.getNode(), position.toString());
widget.show(position); widget.show(position);
hide(); hide();
} }

View File

@@ -2,7 +2,9 @@ package org.toop.app.widget.complex;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Control;
import javafx.scene.control.ProgressBar; import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import org.toop.app.widget.Primitive; import org.toop.app.widget.Primitive;
@@ -12,7 +14,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class LoadingWidget extends ViewWidget implements Update { // TODO make of widget type public class LoadingWidget extends ViewWidget implements Update { // TODO make of widget type
private final Text loadingText; // TODO Make changeable private final Text loadingText; // TODO Make changeable
private final ProgressBar progressBar; private final ProgressIndicator progressBar;
private final AtomicBoolean successTriggered = new AtomicBoolean(false); private final AtomicBoolean successTriggered = new AtomicBoolean(false);
private final AtomicBoolean failureTriggered = new AtomicBoolean(false); private final AtomicBoolean failureTriggered = new AtomicBoolean(false);
@@ -25,7 +27,7 @@ public class LoadingWidget extends ViewWidget implements Update { // TODO make o
private Callable<Boolean> failureTrigger = () -> (amount < minAmount); private Callable<Boolean> failureTrigger = () -> (amount < minAmount);
private float percentage = 0.0f; private float percentage = 0.0f;
private boolean isInfiniteBar = false; private boolean isInfinite = false;
/** /**
* *
@@ -36,17 +38,18 @@ public class LoadingWidget extends ViewWidget implements Update { // TODO make o
* @param startAmount The starting amount. * @param startAmount The starting amount.
* @param maxAmount The max amount. * @param maxAmount The max amount.
*/ */
public LoadingWidget(Text loadingText, int minAmount, int startAmount, int maxAmount, boolean infiniteBar) { public LoadingWidget(Text loadingText, int minAmount, int startAmount, int maxAmount, boolean infinite, boolean circle) {
isInfiniteBar = infiniteBar; isInfinite = infinite;
this.maxAmount = maxAmount; this.maxAmount = maxAmount;
this.minAmount = minAmount; this.minAmount = minAmount;
amount = startAmount; amount = startAmount;
this.loadingText = loadingText; this.loadingText = loadingText;
progressBar = new ProgressBar(); progressBar = circle ? new ProgressIndicator() : new ProgressBar();
VBox box = Primitive.vbox(this.loadingText, progressBar); VBox box = Primitive.vbox(this.loadingText, progressBar);
progressBar.getStyleClass().add("loading-progress-bar");
add(Pos.CENTER, box); add(Pos.CENTER, box);
} }
@@ -75,6 +78,10 @@ public class LoadingWidget extends ViewWidget implements Update { // TODO make o
return (failureTriggered.get() || successTriggered.get()); return (failureTriggered.get() || successTriggered.get());
} }
public ProgressIndicator getProgressBar() {
return progressBar;
}
/** /**
* What to do when success is triggered. * What to do when success is triggered.
* @param onSuccess The lambda that gets run on success. * @param onSuccess The lambda that gets run on success.
@@ -148,6 +155,8 @@ public class LoadingWidget extends ViewWidget implements Update { // TODO make o
if (maxAmount != 0) { if (maxAmount != 0) {
percentage = (float) amount / maxAmount; percentage = (float) amount / maxAmount;
} }
if (!isInfiniteBar) progressBar.setProgress(percentage); if (!isInfinite) {
progressBar.setProgress(percentage);
}
} }
} }

View File

@@ -33,7 +33,7 @@ public class SongDisplay extends VBox implements Widget {
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("loading-progress-bar");
progressText = new Text("0:00/0:00"); progressText = new Text("0:00/0:00");
progressText.getStyleClass().add("progress-text"); progressText.getStyleClass().add("progress-text");

View File

@@ -16,7 +16,6 @@
-fx-padding: 8 12 8 12; -fx-padding: 8 12 8 12;
-fx-spacing: 6px; -fx-spacing: 6px;
-fx-alignment: center; -fx-alignment: center;
-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;
} }
@@ -39,6 +38,18 @@
-fx-background-radius: 30px; -fx-background-radius: 30px;
} }
.loading-progress-bar {
-fx-progress-color: #3caf3f;
}
.loading-progress-bar > .bar {
-fx-background-color: #3caf3f;
}
.loading-progress-bar > .track {
-fx-background-color: rgba(0,0,0,0.15);
}
.progress-text { .progress-text {
-fx-font-size: 11px; -fx-font-size: 11px;
-fx-fill: white; -fx-fill: white;

View File

@@ -16,7 +16,6 @@
-fx-padding: 8 12 8 12; -fx-padding: 8 12 8 12;
-fx-spacing: 6px; -fx-spacing: 6px;
-fx-alignment: center; -fx-alignment: center;
-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;
} }
@@ -27,6 +26,7 @@
} }
.progress-bar { .progress-bar {
-fx-inner-background-color: black;
-fx-pref-width: 200px; -fx-pref-width: 200px;
-fx-accent: red; -fx-accent: red;
} }
@@ -39,6 +39,18 @@
-fx-background-radius: 30px; -fx-background-radius: 30px;
} }
.loading-progress-bar {
-fx-progress-color: #28a428;
}
.loading-progress-bar > .bar {
-fx-background-color: #28a428;
}
.loading-progress-bar > .track {
-fx-background-color: rgba(0,0,0,0.15);
}
.progress-text { .progress-text {
-fx-font-size: 11px; -fx-font-size: 11px;
-fx-fill: white; -fx-fill: white;
@@ -48,10 +60,9 @@
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-background-radius: 0; -fx-background-radius: 0;
-fx-cursor: hand; -fx-cursor: hand;
-fx-text-fill: white;
} }
.skip-button .text { .skip-button > .text {
-fx-fill: white; -fx-fill: white;
} }
@@ -59,10 +70,9 @@
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-background-radius: 0; -fx-background-radius: 0;
-fx-cursor: hand; -fx-cursor: hand;
-fx-text-fill: white;
} }
.pause-button .text { .pause-button > .text {
-fx-fill: white; -fx-fill: white;
} }
@@ -70,10 +80,9 @@
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-background-radius: 0; -fx-background-radius: 0;
-fx-cursor: hand; -fx-cursor: hand;
-fx-text-fill: white;
} }
.previous-button .text { .previous-button > .text {
-fx-fill: white; -fx-fill: white;
} }

View File

@@ -16,14 +16,13 @@
-fx-padding: 8 12 8 12; -fx-padding: 8 12 8 12;
-fx-spacing: 6px; -fx-spacing: 6px;
-fx-alignment: center; -fx-alignment: center;
-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;
} }
.song-title { .song-title {
-fx-font-size: 14px; -fx-font-size: 14px;
-fx-fill: black; -fx-effect: null;
} }
.progress-bar { .progress-bar {
@@ -40,42 +39,53 @@
-fx-background-radius: 30px; -fx-background-radius: 30px;
} }
.loading-progress-bar {
-fx-progress-color: #3caf3f;
}
.loading-progress-bar > .bar {
-fx-background-color: linear-gradient(to bottom, #a2d1a1, #b8e3b9);
}
.loading-progress-bar > .track {
-fx-background-color: rgba(0,0,0,0.15);
}
.progress-text { .progress-text {
-fx-font-size: 11px; -fx-font-size: 11px;
-fx-fill: black; -fx-effect: null;
} }
.skip-button { .skip-button {
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-background-radius: 0; -fx-background-radius: 0;
-fx-cursor: hand; -fx-cursor: hand;
-fx-text-fill: black; -fx-effect: null;
} }
.skip-button .text { .skip-button .text {
-fx-fill: black;
} }
.pause-button { .pause-button {
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-background-radius: 0; -fx-background-radius: 0;
-fx-cursor: hand; -fx-cursor: hand;
-fx-text-fill: black; -fx-effect: null;
} }
.pause-button .text { .pause-button .text {
-fx-fill: black; -fx-effect: null;
} }
.previous-button { .previous-button {
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-background-radius: 0; -fx-background-radius: 0;
-fx-cursor: hand; -fx-cursor: hand;
-fx-text-fill: black; -fx-effect: null;
} }
.previous-button .text { .previous-button .text {
-fx-fill: black; -fx-effect: null;
} }
.button { .button {

View File

@@ -142,7 +142,7 @@ public final class GlobalEventBus {
try { try {
callListener(listener, event); callListener(listener, event);
} catch (Throwable e) { } catch (Throwable e) {
// e.printStackTrace(); e.printStackTrace();
} }
} }
} }
@@ -153,7 +153,7 @@ public final class GlobalEventBus {
try { try {
callListener(listener, event); callListener(listener, event);
} catch (Throwable e) { } catch (Throwable e) {
// e.printStackTrace(); e.printStackTrace();
} }
} }
} }