diff --git a/data/gfx/decline.png b/data/gfx/decline.png new file mode 100644 index 0000000..758054b Binary files /dev/null and b/data/gfx/decline.png differ diff --git a/data/gfx/settings.png b/data/gfx/settings.png new file mode 100644 index 0000000..80c4e36 Binary files /dev/null and b/data/gfx/settings.png differ diff --git a/data/i18n/i18n.yaml b/data/i18n/i18n.yaml index 8f3db17..1c957cf 100644 --- a/data/i18n/i18n.yaml +++ b/data/i18n/i18n.yaml @@ -1,8 +1,9 @@ --- -curId: 6 +curId: 7 descriptions: test-2: "" test-1: "aaa" + test-7: "" test-6: "" test-5: "" test-4: "" @@ -15,6 +16,7 @@ languages: test-4: "Start" test-5: "This is a message\\n\\nbla bla bla...\\n\\nHave a nice day!" test-6: "OK" + test-7: "Toggle Audio" de: test-1: "hallo" test-2: "welt" @@ -22,6 +24,7 @@ languages: test-4: "Start" test-5: "Dies ist eine Nachricht\\n\\nbla bla bla...\\n\\nSchönen Tag noch!" test-6: "Ok" + test-7: "Audio umschalten" languagesInfo: en: name: "English" diff --git a/src/main/java/de/extio/game_engine/i18n/LocalizationEditor.java b/src/main/java/de/extio/game_engine/i18n/LocalizationEditor.java index 0ba9c90..bc32e94 100644 --- a/src/main/java/de/extio/game_engine/i18n/LocalizationEditor.java +++ b/src/main/java/de/extio/game_engine/i18n/LocalizationEditor.java @@ -12,19 +12,16 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; -import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; -import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; diff --git a/src/test/java/de/extio/game_engine/demo/DemoModule.java b/src/test/java/de/extio/game_engine/demo/DemoModule.java index e80ca4c..55e9775 100644 --- a/src/test/java/de/extio/game_engine/demo/DemoModule.java +++ b/src/test/java/de/extio/game_engine/demo/DemoModule.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import de.extio.game_engine.audio.AudioController; +import de.extio.game_engine.audio.AudioOptions; import de.extio.game_engine.event.EventService; import de.extio.game_engine.i18n.LocalizationService; import de.extio.game_engine.module.AbstractClientModule; @@ -25,6 +26,7 @@ import de.extio.game_engine.renderer.model.event.UiControlEvent; import de.extio.game_engine.renderer.work.RenderingBoPool; import de.extio.game_engine.resource.StaticResource; import de.extio.game_engine.spatial2.model.ImmutableCoordI2; +import de.extio.game_engine.storage.StorageService; public class DemoModule extends AbstractClientModule { @@ -46,6 +48,9 @@ public class DemoModule extends AbstractClientModule { @Autowired private ThemeManager themeManager; + @Autowired + private StorageService storageService; + private Window mainWindow; private Window secondaryWindow; @@ -54,6 +59,8 @@ public class DemoModule extends AbstractClientModule { private final Map themeSelectionByControlId = new HashMap<>(); + private boolean audioMuted; + @Override public void onLoad() { this.mainWindow = this.applicationContext.getBean(Window.class); @@ -86,10 +93,14 @@ public class DemoModule extends AbstractClientModule { @Override public void onActivate() { + this.storageService.loadByPath(String.class, List.of("gameEngine"), "theme").ifPresent(themeName -> { + if (themeName != null && !themeName.isBlank()) { + this.themeManager.setCurrentTheme(themeName); + } + }); + final var audioOptions = this.audioController.getAudioOptions(); - audioOptions.getMusicOptions().setVolume(0.8f); - audioOptions.getSfxOptions().setVolume(1.0f); - this.audioController.applyAudioOptions(audioOptions); + this.audioMuted = isAudioMuted(audioOptions); this.setupMainWindow(); this.getModuleService().changeActiveState(this.mainWindow.getId(), true); @@ -119,6 +130,10 @@ public class DemoModule extends AbstractClientModule { private void onUiControlEvent(final UiControlEvent event) { switch (event.getId()) { + case "DemoModule_MainWindow_Button_Audio" -> { + this.toggleAudioMuted(); + } + case "DemoModule_MainWindow_Label_Welcome" -> { this.audioController.play(new StaticResource(List.of("audio"), "contact0.ogg")); this.setupSecondaryWindow(); @@ -143,7 +158,7 @@ public class DemoModule extends AbstractClientModule { if (themeName != null) { this.audioController.play(new StaticResource(List.of("audio"), "alert0.ogg")); this.themeManager.setCurrentTheme(themeName); - // this.getModuleService().changeActiveState(this.themeSelectionWindow.getId(), false); + this.storageService.store(List.of("gameEngine"), "theme", themeName); } } } @@ -161,6 +176,21 @@ public class DemoModule extends AbstractClientModule { .withPositionRelative(10, 100); this.mainWindow.putRenderingBo(bo); + final var buttonX = Math.max(0, this.mainWindow.getNormalizedDimension().getX() - 64 - 21); + final var buttonY = 20; + bo = this.renderingBoPool.acquire("DemoModule_MainWindow_Button_Audio", ControlRenderingBo.class) + .setCaption("") + .setType(ButtonControl.class) + .setTooltip(this.localizationService.translate("test-7")) + .setVisible(true) + .setEnabled(true) + .setCustomData2(new StaticResource(List.of("gfx"), "settings.png")) + .withDimensionAbsolute(64, 64) + .withPositionRelative(buttonX, buttonY); + this.mainWindow.putRenderingBo(bo); + + this.updateAudioButtonOverlay(); + bo = this.renderingBoPool.acquire("DemoModule_MainWindow_Logo", DrawImageRenderingBo.class) .setResource(new StaticResource(List.of("renderer"), "logo.png")) .withDimensionAbsolute(256, 256) @@ -179,6 +209,48 @@ public class DemoModule extends AbstractClientModule { this.mainWindow.putRenderingBo(bo); } + private void toggleAudioMuted() { + final var audioOptions = this.audioController.getAudioOptions(); + final var muted = isAudioMuted(audioOptions); + + if (muted) { + audioOptions.getMusicOptions().setVolume(0.8); + audioOptions.getSfxOptions().setVolume(1.0); + } + else { + audioOptions.getMusicOptions().setVolume(0.0); + audioOptions.getSfxOptions().setVolume(0.0); + } + + this.audioController.applyAudioOptions(audioOptions); + this.audioMuted = !muted; + this.updateAudioButtonOverlay(); + } + + private void updateAudioButtonOverlay() { + if (!this.audioMuted) { + this.mainWindow.removeRenderingBo("DemoModule_MainWindow_Button_Audio_Overlay"); + this.mainWindow.draw(); + return; + } + + final var buttonX = Math.max(0, this.mainWindow.getNormalizedDimension().getX() - 64 - 21); + final var buttonY = 20; + final DrawImageRenderingBo overlayBo = this.renderingBoPool.acquire("DemoModule_MainWindow_Button_Audio_Overlay", DrawImageRenderingBo.class); + overlayBo.setResource(new StaticResource(List.of("gfx"), "decline.png")); + overlayBo.withDimensionAbsolute(64, 64); + overlayBo.setLayer(RenderingBoLayer.UI1); + overlayBo.withPositionRelative(buttonX, buttonY); + this.mainWindow.putRenderingBo(overlayBo); + this.mainWindow.draw(); + } + + private static boolean isAudioMuted(final AudioOptions audioOptions) { + final var music = audioOptions.getMusicOptions().getVolume(); + final var sfx = audioOptions.getSfxOptions().getVolume(); + return music <= 0.000_001 && sfx <= 0.000_001; + } + private void setupSecondaryWindow() { this.secondaryWindow.clearRenderingBos(); this.themeSelectionByControlId.clear(); @@ -233,7 +305,7 @@ public class DemoModule extends AbstractClientModule { .setSize(42) .setAlignment(HorizontalAlignment.CENTER) .withDimensionAbsolute(desiredWidth - (paddingX * 2), headerHeight) - .withPositionRelative(paddingX, 30); + .withPositionRelative(paddingX, 40); this.themeSelectionWindow.putRenderingBo(bo); final var currentTheme = this.themeManager.getCurrentTheme();