Skip to content

Commit

Permalink
#494 Backglass images to media assets
Browse files Browse the repository at this point in the history
  • Loading branch information
leprinco committed Sep 30, 2024
1 parent 354969b commit 2afef50
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 13 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
- **Backglass Data Exporter**:
- Fixed wrong DMD image information (the data was always read from the backglass image).
- Added additional data from the backglass settings.
- **Backglass images to media assets**: Ability to extract the images inside the directb2s (Backglass + DMD) and use them as respective table media assets. If a media asset already exists, the image can replace or be appended to the collection.

## VPin Mania

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import de.mephisto.vpin.restclient.directb2s.DirectB2SData;
import de.mephisto.vpin.restclient.directb2s.DirectB2STableSettings;
import de.mephisto.vpin.restclient.directb2s.DirectB2ServerSettings;
import de.mephisto.vpin.restclient.frontend.FrontendType;
import de.mephisto.vpin.restclient.frontend.VPinScreen;
import de.mephisto.vpin.restclient.games.FrontendMediaRepresentation;
import de.mephisto.vpin.restclient.games.GameEmulatorRepresentation;
import de.mephisto.vpin.restclient.games.GameRepresentation;
import de.mephisto.vpin.ui.NavigationController;
Expand All @@ -17,6 +20,7 @@
import de.mephisto.vpin.ui.events.StudioEventListener;
import de.mephisto.vpin.ui.tables.TableDialogs;
import de.mephisto.vpin.ui.tables.TablesSidebarDirectB2SController;
import de.mephisto.vpin.ui.tables.dialogs.FrontendMediaUploadProgressModel;
import de.mephisto.vpin.ui.tables.models.B2SGlowing;
import de.mephisto.vpin.ui.tables.models.B2SLedType;
import de.mephisto.vpin.ui.tables.models.B2SVisibility;
Expand All @@ -33,6 +37,7 @@
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
Expand All @@ -42,6 +47,7 @@
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
Expand All @@ -53,10 +59,13 @@
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
Expand All @@ -65,6 +74,7 @@
import java.util.concurrent.CompletableFuture;

import javax.annotation.Nullable;
import javax.imageio.ImageIO;

import static de.mephisto.vpin.ui.Studio.client;
import static de.mephisto.vpin.ui.Studio.stage;
Expand Down Expand Up @@ -142,12 +152,16 @@ public class BackglassManagerController extends BaseTableController<DirectB2S, D

@FXML
private Button downloadBackglassBtn;
@FXML
private Button useAsMediaBackglassBtn;

@FXML
private Button uploadDMDBtn;
@FXML
private Button downloadDMDBtn;
@FXML
private Button useAsMediaDMDBtn;
@FXML
private Button deleteDMDBtn;

//-- Editors
Expand Down Expand Up @@ -296,7 +310,7 @@ private void onBackglassDownload() {
}
}

@FXML
@FXML
private void onDMDUpload() {
StudioFileChooser fileChooser = new StudioFileChooser();
fileChooser.setTitle("Select DMD Image");
Expand All @@ -321,6 +335,72 @@ private void onDMDDownload() {
}
}

@FXML
private void onBackglassUseAsMedia() {
if (tableData.isBackgroundAvailable()) {
try (InputStream in = client.getBackglassServiceClient().getDirectB2sBackground(tableData)) {
Image img = new Image(in);
if (tableData.getGrillHeight() > 0 && tableSettings != null && tableSettings.getHideGrill() == 1) {
PixelReader reader = img.getPixelReader();
img = new WritableImage(reader, 0, 0, (int) img.getWidth(), (int) (img.getHeight() - tableData.getGrillHeight()));
}

uploadImageAsMedia(VPinScreen.BackGlass, "Backglass", img);
}
catch (IOException ioe) {
LOG.error("Cannot download backglass and set as backglass media image for game " + tableData.getGameId(), ioe);
}
}
}

@FXML
private void onDMDUseAsMedia() {
if (tableData.isDmdImageAvailable()) {
try (InputStream in = client.getBackglassServiceClient().getDirectB2sDmd(tableData)) {
Image img = new Image(in);
uploadImageAsMedia(VPinScreen.Menu, "DMD", img);
}
catch (IOException ioe) {
LOG.error("Cannot download DMD and set as DMD media image for game " + tableData.getGameId(), ioe);
}
}
}

private void uploadImageAsMedia(VPinScreen screen, String screenName, Image img) throws IOException {

Path tmp = Files.createTempFile("tmp_" + screen, ".png");
RenderedImage renderedImage = SwingFXUtils.fromFXImage(img, null);
ImageIO.write(renderedImage, "png", tmp.toFile());

FrontendMediaRepresentation medias = client.getGameMediaService().getGameMedia(game.getId());
boolean append = false;
if (!medias.getMediaItems(screen).isEmpty()) {
Optional<ButtonType> buttonType = WidgetFactory.showConfirmationWithOption(Studio.stage, "Replace " + screenName + " Media ?",
"A " + screenName + " media asset already exists.",
"Append new asset or overwrite existing asset?", "Overwrite", "Append");
if (buttonType.isPresent() && buttonType.get().equals(ButtonType.OK)) {
}
else if (buttonType.isPresent() && buttonType.get().equals(ButtonType.APPLY)) {
append = true;
}
else {
return;
}
}
else {
Optional<ButtonType> buttonType = WidgetFactory.showConfirmation(Studio.stage, "Copy in " + screenName + " Media ?",
"Add the " + screenName + " image as media asset.", null, "Copy");
if (buttonType.isPresent() && buttonType.get().equals(ButtonType.OK)) {
}
else {
return;
}
}
FrontendMediaUploadProgressModel model = new FrontendMediaUploadProgressModel(game,
screenName + " Media Upload", Arrays.asList(tmp.toFile()), screen, append);
ProgressDialog.createProgressDialog(model);
}

@FXML
private void onDMDDelete() {
Optional<ButtonType> result = WidgetFactory.showConfirmation(Studio.stage, "Delete DMD Image",
Expand Down Expand Up @@ -497,6 +577,15 @@ public void initialize(URL url, ResourceBundle resourceBundle) {
this.deleteBtn.setDisable(true);
this.reloadBackglassBtn.setDisable(true);

FrontendType frontendType = Studio.client.getFrontendService().getFrontendType();
if (!frontendType.supportMedias()) {
HBox bgtoolbar = (HBox) this.useAsMediaBackglassBtn.getParent();
bgtoolbar.getChildren().remove(useAsMediaBackglassBtn);

HBox dmdtoolbar = (HBox) this.useAsMediaDMDBtn.getParent();
dmdtoolbar.getChildren().remove(useAsMediaDMDBtn);
}

this.openBtn.setVisible(false); //TODO

bindTable();
Expand Down Expand Up @@ -787,8 +876,10 @@ private JFXFuture<Void> refresh(@Nullable DirectB2S newValue) {
thumbnailImage.setImage(new Image(Studio.class.getResourceAsStream("empty-preview.png")));
dmdThumbnailImage.setImage(new Image(Studio.class.getResourceAsStream("empty-preview.png")));
downloadBackglassBtn.setDisable(true);
useAsMediaBackglassBtn.setDisable(true);
uploadDMDBtn.setDisable(true);
downloadDMDBtn.setDisable(true);
useAsMediaDMDBtn.setDisable(true);
deleteDMDBtn.setDisable(true);
resolutionLabel.setText("");
dmdResolutionLabel.setText("");
Expand Down Expand Up @@ -832,7 +923,7 @@ private JFXFuture<Void> refresh(@Nullable DirectB2S newValue) {
this.tableData = new DirectB2SData();
}

loadImages(tableSettings);
loadImages();

}).thenLater(() -> {

Expand Down Expand Up @@ -924,13 +1015,13 @@ private JFXFuture<Void> refresh(@Nullable DirectB2S newValue) {
}


private void loadImages(DirectB2STableSettings tmpTableSettings) {
private void loadImages() {
Image thumbnail = null;
String thumbnailError = null;
if (tableData.isBackgroundAvailable()) {
try (InputStream in = client.getBackglassServiceClient().getDirectB2sBackground(tableData)) {
thumbnail = new Image(in);
if (tableData.getGrillHeight() > 0 && tmpTableSettings != null && tmpTableSettings.getHideGrill() == 1) {
if (tableData.getGrillHeight() > 0 && tableSettings != null && tableSettings.getHideGrill() == 1) {
PixelReader reader = thumbnail.getPixelReader();
thumbnail = new WritableImage(reader, 0, 0, (int) thumbnail.getWidth(), (int) (thumbnail.getHeight() - tableData.getGrillHeight()));
}
Expand All @@ -951,6 +1042,7 @@ private void loadImages(DirectB2STableSettings tmpTableSettings) {
thumbnailImage.setImage(_thumbnail);
thumbnailImagePane.setCenter(thumbnailImage);
downloadBackglassBtn.setDisable(false);
useAsMediaBackglassBtn.setDisable(game==null);
resolutionLabel.setText("Resolution: " + (int) _thumbnail.getWidth() + " x " + (int) _thumbnail.getHeight());
}
else {
Expand Down Expand Up @@ -982,6 +1074,7 @@ private void loadImages(DirectB2STableSettings tmpTableSettings) {
dmdThumbnailImage.setImage(_dmdThumbnail);
dmdThumbnailImagePane.setCenter(dmdThumbnailImage);
downloadDMDBtn.setDisable(false);
useAsMediaDMDBtn.setDisable(game==null);
deleteDMDBtn.setDisable(false);
dmdResolutionLabel.setText("Resolution: " + (int) _dmdThumbnail.getWidth() + " x " + (int) _dmdThumbnail.getHeight());
fullDmdLabel.setText(isFullDmd(_dmdThumbnail.getWidth(), _dmdThumbnail.getHeight()) ? "Yes" : "No");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,21 @@
<Label fx:id="resolutionLabel" textFill="WHITE" BorderPane.alignment="CENTER" />
</left>
<right>
<Button fx:id="downloadBackglassBtn" mnemonicParsing="false" onAction="#onBackglassDownload" textFill="WHITE" BorderPane.alignment="CENTER">
<graphic>
<FontIcon iconColor="WHITE" iconLiteral="mdi2d-download" iconSize="14" />
</graphic>
</Button>
<HBox spacing="3.0">
<Button fx:id="downloadBackglassBtn" mnemonicParsing="false" onAction="#onBackglassDownload" textFill="WHITE" BorderPane.alignment="CENTER">
<graphic>
<FontIcon iconColor="WHITE" iconLiteral="mdi2d-download" iconSize="14" />
</graphic>
</Button>
<Button fx:id="useAsMediaBackglassBtn" mnemonicParsing="false" onAction="#onBackglassUseAsMedia" textFill="WHITE" BorderPane.alignment="CENTER">
<graphic>
<FontIcon iconColor="WHITE" iconLiteral="mdi2i-image-plus" iconSize="14" />
</graphic>
<tooltip>
<Tooltip prefWidth="400.0" text="Export the backglass image and use it as a backglass media asset in your frontend." wrapText="true" />
</tooltip>
</Button>
</HBox>
</right>
</BorderPane>
</bottom>
Expand Down Expand Up @@ -271,6 +281,14 @@
<FontIcon iconColor="WHITE" iconLiteral="mdi2d-download" iconSize="14" />
</graphic>
</Button>
<Button fx:id="useAsMediaDMDBtn" mnemonicParsing="false" onAction="#onDMDUseAsMedia" textFill="WHITE" BorderPane.alignment="CENTER">
<graphic>
<FontIcon iconColor="WHITE" iconLiteral="mdi2i-image-plus" iconSize="14" />
</graphic>
<tooltip>
<Tooltip prefWidth="400.0" text="Export the DMD image and use it as a DMD media asset in your frontend." wrapText="true" />
</tooltip>
</Button>
<Button fx:id="deleteDMDBtn" mnemonicParsing="false" onAction="#onDMDDelete" textFill="WHITE" BorderPane.alignment="CENTER">
<graphic>
<FontIcon iconColor="#ff3333" iconLiteral="mdi2d-delete-outline" iconSize="14" />
Expand Down Expand Up @@ -634,7 +652,7 @@
</font>
</Label>

<Label text="Number of Players:" textFill="WHITE" GridPane.rowIndex="10">
<Label text="Number of Players:" textFill="WHITE" GridPane.rowIndex="10">
<font>
<Font size="14.0" />
</font>
Expand All @@ -645,7 +663,7 @@
</font>
</Label>

<Label text="File Size:" textFill="WHITE" GridPane.rowIndex="11">
<Label text="File Size:" textFill="WHITE" GridPane.rowIndex="11">
<font>
<Font size="14.0" />
</font>
Expand All @@ -656,7 +674,7 @@
</font>
</Label>

<Label text="Modification Date:" textFill="WHITE" GridPane.rowIndex="12">
<Label text="Modification Date:" textFill="WHITE" GridPane.rowIndex="12">
<font>
<Font size="14.0" />
</font>
Expand All @@ -667,7 +685,7 @@
</font>
</Label>

</children>
</children>
<VBox.margin>
<Insets top="24.0" />
</VBox.margin>
Expand Down

0 comments on commit 2afef50

Please sign in to comment.