390 lines
13 KiB
Java
390 lines
13 KiB
Java
package id.co.gtc.erhacam;
|
|
|
|
import javafx.animation.KeyFrame;
|
|
import javafx.animation.PauseTransition;
|
|
import javafx.animation.Timeline;
|
|
import javafx.application.Platform;
|
|
|
|
import javafx.geometry.Insets;
|
|
import javafx.geometry.Pos;
|
|
import javafx.scene.Scene;
|
|
import javafx.scene.control.Label;
|
|
import javafx.scene.image.Image;
|
|
import javafx.scene.image.ImageView;
|
|
import javafx.scene.layout.*;
|
|
import javafx.scene.paint.Color;
|
|
import javafx.scene.shape.Circle;
|
|
import javafx.stage.*;
|
|
import javafx.util.Duration;
|
|
import org.tinylog.Logger;
|
|
|
|
import java.nio.file.Paths;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.function.Consumer;
|
|
|
|
import static Config.SomeCodes.*;
|
|
|
|
public class AutoCloseAlert {
|
|
|
|
private static Stage currentAlertStage;
|
|
public static String shownTitle = "";
|
|
public static String shownContent = "";
|
|
public static String shownHeader = "";
|
|
public static Image shownBanner = null;
|
|
public static Image banner_01;
|
|
public static Image banner_02;
|
|
private static Circle Cam1;
|
|
private static Circle Cam2;
|
|
private static Circle Cam3;
|
|
private static Circle Cam4;
|
|
private static Circle Cam5;
|
|
|
|
public static void init(){
|
|
String f_01 = ExtractResource("/IU photoboth-01.jpg");
|
|
//System.out.println("Banner 01 extracted as file: "+f_01);
|
|
String f_02 = ExtractResource("/IU photoboth-02.jpg");
|
|
//System.out.println("Banner 02 extracted as file: "+f_02);
|
|
banner_01 = LoadImage(f_01);
|
|
if (banner_01!=null) System.out.println("Banner 01 loaded"); else System.out.println("Banner 01 not loaded");
|
|
banner_02 = LoadImage(f_02);
|
|
if (banner_02!=null) System.out.println("Banner 02 loaded"); else System.out.println("Banner 02 not loaded");
|
|
Cam1 = new Circle(10, Color.RED);
|
|
Cam2 = new Circle(10, Color.RED);
|
|
Cam3 = new Circle(10, Color.RED);
|
|
if (!DermiesMode){
|
|
Cam4 = new Circle(10, Color.RED);
|
|
Cam5 = new Circle(10, Color.RED);
|
|
}
|
|
|
|
}
|
|
|
|
public static void ChangeCamStatus(int id, boolean active){
|
|
Circle x = switch (id){
|
|
case 1 -> Cam1;
|
|
case 2 -> Cam2;
|
|
case 3 -> Cam3;
|
|
case 4 -> DermiesMode? null: Cam4;
|
|
case 5 -> DermiesMode ? null : Cam5;
|
|
default -> null;
|
|
};
|
|
if (x!=null){
|
|
if (active){
|
|
x.setFill(Color.GREEN);
|
|
} else {
|
|
x.setFill(Color.RED);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Close the current alert if it is shown
|
|
*/
|
|
public static void close(){
|
|
if (currentAlertStage!=null){
|
|
try {
|
|
closeStage(currentAlertStage);
|
|
} catch (InterruptedException e) {
|
|
Logger.error("Error closing alert stage: " + e.getMessage());
|
|
}
|
|
currentAlertStage = null;
|
|
}
|
|
|
|
|
|
clear();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Show an alert with a title, header, content, and automatically close after a few seconds
|
|
* If called several times, the previous alert will be closed before showing a new one
|
|
* @param title the title of the alert
|
|
* @param header the header of the alert
|
|
* @param content the content of the alert
|
|
* @param seconds the number of seconds before the alert is closed, or put 0 to keep it open
|
|
* @param onClose What to do after auto close
|
|
*/
|
|
public static void show(String title, String header, String content, int seconds, Consumer<String> onClose) {
|
|
if (Platform.isFxApplicationThread()){
|
|
Stage alertStage = _showtext(title, header, content);
|
|
closeAlertStage(seconds, onClose, alertStage);
|
|
} else {
|
|
Platform.runLater(()->{
|
|
Stage alertStage = _showtext(title, header, content);
|
|
closeAlertStage(seconds, onClose, alertStage);
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Show a banner image
|
|
* @param b1 Image to show
|
|
* @param seconds the number of seconds before the alert is closed, or put 0 to keep it open
|
|
* @param onClose What to do after auto close
|
|
*/
|
|
public static void showbanner(Image b1, int seconds, Consumer<String> onClose){
|
|
if (Platform.isFxApplicationThread()){
|
|
Stage alertStage = _showbanner(b1);
|
|
closeAlertStage(seconds, onClose, alertStage);
|
|
} else {
|
|
Platform.runLater(()->{
|
|
Stage alertStage = _showbanner(b1);
|
|
closeAlertStage(seconds, onClose, alertStage);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
public static void showpictures(String[] pictures, int seconds, Consumer<String> onClose){
|
|
List<Image> images = new ArrayList<>();
|
|
|
|
if (pictures != null){
|
|
for(String pp : pictures){
|
|
Image ii = LoadImage(pp);
|
|
if (ii!=null) images.add(ii);
|
|
}
|
|
}
|
|
|
|
if (!images.isEmpty()){
|
|
Image[] source = images.toArray(new Image[0]);
|
|
if (Platform.isFxApplicationThread()){
|
|
_showpictures(source, seconds, onClose);
|
|
} else {
|
|
Platform.runLater(()-> _showpictures(source,seconds, onClose));
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private static void _showpictures(Image[] pictures, int seconds, Consumer<String> onClose){
|
|
close();
|
|
|
|
Stage alertStage = new Stage();
|
|
alertStage.initModality(Modality.APPLICATION_MODAL);
|
|
alertStage.initStyle(StageStyle.UTILITY);
|
|
alertStage.setAlwaysOnTop(true);
|
|
alertStage.setResizable(false);
|
|
int width = (int) Screen.getPrimary().getBounds().getWidth();
|
|
int height = (int) Screen.getPrimary().getBounds().getHeight();
|
|
|
|
HBox hbox = new HBox();
|
|
hbox.setAlignment(Pos.CENTER);
|
|
int fitwidth = width / pictures.length;
|
|
for(Image i : pictures){
|
|
ImageView iv = new ImageView(i);
|
|
iv.setPreserveRatio(true);
|
|
iv.setFitHeight(height);
|
|
iv.setFitWidth(fitwidth);
|
|
hbox.getChildren().add(iv);
|
|
}
|
|
|
|
BorderPane borderPane = new BorderPane();
|
|
borderPane.setCenter(hbox);
|
|
|
|
alertStage.setScene(new Scene(borderPane, width, height));
|
|
alertStage.centerOnScreen();
|
|
|
|
Timeline timeline = new Timeline();
|
|
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(0), event -> alertStage.show()));
|
|
|
|
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(seconds* (pictures.length)), event -> {
|
|
try {
|
|
closeStage(alertStage);
|
|
} catch (InterruptedException e) {
|
|
Logger.error("Error closing alert stage: " + e.getMessage());
|
|
}
|
|
//alertStage.close();
|
|
if (currentAlertStage == alertStage) {
|
|
currentAlertStage = null;
|
|
}
|
|
if (onClose!=null) onClose.accept(shownTitle);
|
|
clear();
|
|
}));
|
|
timeline.play();
|
|
|
|
currentAlertStage = alertStage;
|
|
shownTitle = "";
|
|
shownContent = "";
|
|
shownHeader = "";
|
|
shownBanner = null;
|
|
|
|
}
|
|
|
|
private static Stage _showbanner(Image image){
|
|
close();
|
|
|
|
Stage alertStage = new Stage();
|
|
alertStage.initModality(Modality.APPLICATION_MODAL);
|
|
alertStage.initStyle(StageStyle.UTILITY);
|
|
alertStage.setAlwaysOnTop(true);
|
|
alertStage.setResizable(false);
|
|
int width = (int) Screen.getPrimary().getBounds().getWidth();
|
|
int height = (int) Screen.getPrimary().getBounds().getHeight();
|
|
|
|
BorderPane borderPane = new BorderPane();
|
|
|
|
StackPane stackPane = new StackPane();
|
|
|
|
if (image!=null){
|
|
ImageView imageView = new ImageView(image);
|
|
imageView.setPreserveRatio(true);
|
|
imageView.setFitWidth(width);
|
|
imageView.setSmooth(true);
|
|
stackPane.getChildren().add(imageView);
|
|
}
|
|
|
|
HBox CamStatus = DermiesMode ? new HBox(30, Cam1, Cam2, Cam3) : new HBox(30, Cam1, Cam2, Cam3, Cam4, Cam5);
|
|
CamStatus.setMinHeight(60);
|
|
CamStatus.setAlignment(Pos.CENTER);
|
|
|
|
VBox vBox = new VBox(CamStatus);
|
|
vBox.setAlignment(Pos.BOTTOM_CENTER);
|
|
|
|
stackPane.getChildren().add(vBox);
|
|
|
|
borderPane.setCenter(stackPane);
|
|
|
|
alertStage.setScene(new Scene(borderPane, width, height));
|
|
alertStage.centerOnScreen();
|
|
alertStage.show();
|
|
|
|
currentAlertStage = alertStage;
|
|
shownBanner = image;
|
|
CamStatus.prefWidthProperty().bind(currentAlertStage.widthProperty());
|
|
|
|
|
|
|
|
shownTitle = "";
|
|
shownContent = "";
|
|
shownHeader = "";
|
|
|
|
return alertStage;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Create an alert with a title, header, and content
|
|
* @param title the title
|
|
* @param header the header
|
|
* @param content the content
|
|
* @return the alert stage
|
|
*/
|
|
private static Stage _showtext(String title, String header, String content){
|
|
// close previous alert before showing a new one
|
|
close();
|
|
|
|
Stage alertStage = new Stage();
|
|
alertStage.initModality(Modality.APPLICATION_MODAL);
|
|
alertStage.initStyle(StageStyle.UTILITY);
|
|
alertStage.setAlwaysOnTop(true);
|
|
alertStage.setResizable(false);
|
|
|
|
double screenwidth = Screen.getPrimary().getBounds().getWidth();
|
|
double screenheight = Screen.getPrimary().getBounds().getHeight();
|
|
|
|
double height = screenheight/4.0;
|
|
double width = height * 21.0/9.0;
|
|
|
|
VBox root = new VBox(10);
|
|
root.setPadding(new Insets(12));
|
|
root.setPrefSize(width, height);
|
|
root.setAlignment(Pos.CENTER);
|
|
|
|
if (ValidString(header)){
|
|
Label headerLabel = new Label(header);
|
|
headerLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 28px;");
|
|
headerLabel.setWrapText(true);
|
|
headerLabel.setMinHeight(height*0.25);
|
|
headerLabel.setMaxWidth(Double.MAX_VALUE);
|
|
headerLabel.prefWidthProperty().bind(root.widthProperty());
|
|
root.getChildren().add(headerLabel);
|
|
}
|
|
if (ValidString(content)){
|
|
Label contentLabel = new Label(content);
|
|
contentLabel.setWrapText(true);
|
|
contentLabel.setStyle("-fx-font-size: 24px;");
|
|
contentLabel.setMinHeight(height*0.75);
|
|
contentLabel.setMaxWidth(Double.MAX_VALUE);
|
|
contentLabel.prefWidthProperty().bind(root.widthProperty());
|
|
|
|
VBox.setVgrow(contentLabel, Priority.ALWAYS);
|
|
contentLabel.setAlignment(Pos.TOP_CENTER);
|
|
root.getChildren().add(contentLabel);
|
|
}
|
|
|
|
|
|
|
|
Scene scene = new Scene(root);
|
|
alertStage.setScene(scene);
|
|
|
|
alertStage.setTitle(title);
|
|
|
|
double x = screenwidth/2 - width/2;
|
|
double y = screenheight - height - 10;
|
|
alertStage.setX(x);
|
|
alertStage.setY(y);
|
|
|
|
alertStage.show();
|
|
currentAlertStage = alertStage;
|
|
shownHeader = ValidString(header) ? header : "";
|
|
shownContent = ValidString(content) ? content : "";
|
|
shownTitle = ValidString(title) ? title : "";
|
|
shownBanner = null;
|
|
|
|
return alertStage;
|
|
}
|
|
|
|
/**
|
|
* Close the alert after a few seconds
|
|
* @param seconds the number of seconds before the alert is closed, if 0, the alert will not be closed
|
|
* @param onClose What to do after auto close
|
|
* @param alertStage the alert stage to be closed
|
|
*/
|
|
private static void closeAlertStage(int seconds, Consumer<String> onClose, Stage alertStage) {
|
|
|
|
if (seconds>0){
|
|
PauseTransition delay = new PauseTransition(Duration.seconds(seconds));
|
|
delay.setOnFinished(e -> {
|
|
try {
|
|
closeStage(alertStage);
|
|
} catch (InterruptedException err) {
|
|
Logger.error("Error closing alert stage: " + err.getMessage());
|
|
}
|
|
//alertStage.close();
|
|
if (currentAlertStage == alertStage) {
|
|
currentAlertStage = null;
|
|
}
|
|
if (onClose!=null) onClose.accept(shownTitle);
|
|
clear();
|
|
} );
|
|
delay.play();
|
|
}
|
|
}
|
|
|
|
private static Image LoadImage(String filename){
|
|
if (ValidFile(filename)){
|
|
try{
|
|
return new Image(Paths.get(filename).toUri().toString());
|
|
} catch (Exception e){
|
|
Logger.error("Error loading image: " + filename+", Message: "+e.getMessage());
|
|
}
|
|
} else Logger.error("LoadImage: Invalid file: " + filename);
|
|
return null;
|
|
}
|
|
|
|
private static void clear(){
|
|
shownTitle = "";
|
|
shownContent = "";
|
|
shownHeader = "";
|
|
shownBanner= null;
|
|
}
|
|
}
|