From 120dd91161fb118005e75681c4756cb2c2d19edb Mon Sep 17 00:00:00 2001 From: extio-de Date: Sun, 28 Dec 2025 11:47:21 +0100 Subject: [PATCH] Refactor theme management in G2D controls and introduce new themes - Updated G2DButtonControlImpl, G2DLabelControlImpl, G2DSliderControlImpl, G2DSwitchControlImpl, G2DTableControlImpl, G2DTextfieldControlImpl, G2DTextfieldControlImpl2, G2DToggleButtonControlImpl, G2DWindowCloseButtonControlImpl, and G2DWindowPanelControlImpl to use G2DThemeManager directly instead of casting from G2DRenderer. - Added new theme factory beans: BevelDarkThemeFactoryBean, BevelLightThemeFactoryBean, MetroPatternRenderer, and updated existing theme factory beans to improve theme consistency and aesthetics. - Modified audio settings in DemoModule for improved user experience. - Adjusted background and foreground colors in various themes for better visibility and aesthetics. --- data/audio/contact0.ogg | Bin 0 -> 11084 bytes .../renderer/RendererAutoConfiguration.java | 5 +- .../game_engine/renderer/RendererData.java | 10 +- .../renderer/g2d/G2DAutoConfiguration.java | 12 ++ .../game_engine/renderer/g2d/G2DRenderer.java | 4 - .../g2d/bo/rendering/G2DDrawEffect.java | 5 +- .../g2d/bo/rendering/G2DDrawFont.java | 3 +- .../g2d/control/components/CustomButton.java | 7 +- .../g2d/control/components/CustomLabel.java | 3 + .../g2d/control/components/CustomSwitch.java | 5 +- .../control/impl/G2DButtonControlImpl.java | 4 +- .../g2d/control/impl/G2DLabelControlImpl.java | 2 +- .../control/impl/G2DSliderControlImpl.java | 3 +- .../control/impl/G2DSwitchControlImpl.java | 4 +- .../g2d/control/impl/G2DTableControlImpl.java | 4 +- .../control/impl/G2DTextfieldControlImpl.java | 6 +- .../impl/G2DTextfieldControlImpl2.java | 6 +- .../impl/G2DToggleButtonControlImpl.java | 3 +- .../impl/G2DWindowCloseButtonControlImpl.java | 3 +- .../impl/G2DWindowPanelControlImpl.java | 3 +- .../g2d/theme/BevelDarkThemeFactoryBean.java | 46 +++++++ .../g2d/theme/BevelLightThemeFactoryBean.java | 46 +++++++ .../g2d/theme/BevelPatternRenderer.java | 121 ++++++++++++++++++ .../theme/ContemporaryThemeFactoryBean.java | 4 +- .../g2d/theme/DreamThemeFactoryBean.java | 4 +- .../g2d/theme/FantasyPatternRenderer.java | 3 +- .../g2d/theme/FantasyThemeFactoryBean.java | 14 +- .../g2d/theme/MetroPatternRenderer.java | 112 ++++++++++++++++ .../g2d/theme/ModernThemeFactoryBean.java | 4 +- .../g2d/theme/UrbanThemeFactoryBean.java | 22 ++-- .../de/extio/game_engine/demo/DemoModule.java | 14 +- 31 files changed, 422 insertions(+), 60 deletions(-) create mode 100644 data/audio/contact0.ogg create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelDarkThemeFactoryBean.java create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelLightThemeFactoryBean.java create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelPatternRenderer.java create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/MetroPatternRenderer.java diff --git a/data/audio/contact0.ogg b/data/audio/contact0.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5572eba0e6ff621231423ddda609643a332a800d GIT binary patch literal 11084 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 bevelLightTheme() { + return new BevelLightThemeFactoryBean(); + } + + @Bean + FactoryBean bevelDarkTheme() { + return new BevelDarkThemeFactoryBean(); + } + @Bean G2DThemeManager g2dThemeManager( final StaticResourceService staticResourceService, diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java index 34fac29..5599595 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java @@ -373,10 +373,6 @@ public class G2DRenderer implements Renderer { return this.title; } - public G2DThemeManager getThemeManager() { - return this.themeManager; - } - public void setThemeManager(final G2DThemeManager themeManager) { this.themeManager = themeManager; } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawEffect.java b/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawEffect.java index abd4077..08d8bed 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawEffect.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawEffect.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.G2DRendererCondition; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.g2d.theme.PatternRenderer; import de.extio.game_engine.renderer.model.RenderingBo; import de.extio.game_engine.renderer.model.RenderingBoLayer; @@ -219,9 +220,7 @@ public class G2DDrawEffect extends G2DAbstractRenderingBo implements DrawEffectR final var effectColor = this.color == null ? Color.WHITE : this.color.toAwtColor(); // Use PatternRenderer from ThemeManager - final var renderer = this.rendererData.getRenderer(); - final G2DRenderer g2dRenderer = (G2DRenderer) renderer; - final var themeManager = g2dRenderer.getThemeManager(); + final var themeManager = (G2DThemeManager) this.rendererData.getThemeManager(); final var theme = themeManager.getCurrentTheme(); final PatternRenderer patternRenderer = themeManager.getPatternRenderer(theme.getPatternRendererName()); if (patternRenderer != null) { diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawFont.java b/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawFont.java index 0c63f2d..f710146 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawFont.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/bo/rendering/G2DDrawFont.java @@ -12,6 +12,7 @@ import org.springframework.context.annotation.Conditional; import org.springframework.stereotype.Component; import de.extio.game_engine.renderer.g2d.G2DRendererCondition; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.model.RenderingBo; import de.extio.game_engine.renderer.model.RenderingBoLayer; import de.extio.game_engine.renderer.model.bo.DrawFontRenderingBo; @@ -85,7 +86,7 @@ public class G2DDrawFont extends G2DAbstractRenderingBo implements DrawFontRende return; } - graphics.setColor(this.color == null ? Color.WHITE : this.color.toAwtColor()); + graphics.setColor(this.color == null ? this.rendererData.getThemeManager().getCurrentTheme().getTextNormal().toColor() : this.color.toAwtColor()); if (this.text.contains("\n")) { final var lines = this.text.split("\n", -1); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomButton.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomButton.java index 5fc2c72..6dacb23 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomButton.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomButton.java @@ -80,8 +80,11 @@ public class CustomButton extends CustomAbstractButton { } else if (this.caption != null) { // Text color based on state - if ((this.state & (STATE_HOVERED | STATE_TOGGLED)) != 0) { - g2d.setColor(Color.WHITE); + if ((this.state & STATE_HOVERED) != 0) { + g2d.setColor(theme.getTextNormal().adjustBrightness(theme.getHoverBrightnessAdjustment()).toColor()); + } + else if ((this.state & STATE_TOGGLED) != 0) { + g2d.setColor(theme.getSelectionPrimary().toColor()); } else if (this.isEnabled()) { g2d.setColor(theme.getTextNormal().toColor()); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomLabel.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomLabel.java index 4588d9d..a9af5a7 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomLabel.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomLabel.java @@ -188,6 +188,9 @@ public class CustomLabel extends Component { } else if ((this.state & STATE_HOVERED) != 0) { b += theme.getHoverBrightnessAdjustment(); + if (theme.getTextNormal().getBrightness() < 0.3f) { + b += theme.getHoverBrightnessAdjustment(); + } } h = Math.max(0.0f, Math.min(1.0f, h)); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomSwitch.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomSwitch.java index db6fa52..2f2fdd6 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomSwitch.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/components/CustomSwitch.java @@ -82,7 +82,10 @@ public class CustomSwitch extends CustomAbstractButton { // Text color based on state if ((this.state & STATE_HOVERED) != 0) { - g2d.setColor(Color.WHITE); + g2d.setColor(theme.getTextNormal().adjustBrightness(theme.getHoverBrightnessAdjustment()).toColor()); + } + else if ((this.state & STATE_TOGGLED) != 0) { + g2d.setColor(theme.getSelectionPrimary().toColor()); } else if (this.isEnabled()) { g2d.setColor(theme.getTextNormal().toColor()); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DButtonControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DButtonControlImpl.java index 5eafacf..df7e519 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DButtonControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DButtonControlImpl.java @@ -5,6 +5,8 @@ import java.util.Objects; import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.control.components.CustomAbstractButton; import de.extio.game_engine.renderer.g2d.control.components.CustomButton; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.BaseControl; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.ButtonControl; import de.extio.game_engine.renderer.model.color.RgbaColor; @@ -71,7 +73,7 @@ public class G2DButtonControlImpl extends G2DBaseControlImpl implements ButtonCo } protected void createControl() { - this.control = new CustomButton(false, event -> this.performAction(), ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager()); + this.control = new CustomButton(false, event -> this.performAction(), (G2DThemeManager) this.rendererData.getThemeManager()); this.control.setName(this.id); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DLabelControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DLabelControlImpl.java index e8f6dca..49526ef 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DLabelControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DLabelControlImpl.java @@ -98,7 +98,7 @@ public class G2DLabelControlImpl extends G2DBaseControlImpl implements LabelCont } protected void createControl() { - this.control = new CustomLabel(event -> this.performAction(), ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager()); + this.control = new CustomLabel(event -> this.performAction(), this.rendererData.getThemeManager()); this.control.setName(this.id); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSliderControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSliderControlImpl.java index 5281035..5ee5727 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSliderControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSliderControlImpl.java @@ -4,6 +4,7 @@ import java.util.function.Consumer; import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.control.components.CustomSlider; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.SliderControl; import de.extio.game_engine.renderer.model.color.RgbaColor; import de.extio.game_engine.renderer.model.event.UiControlEvent; @@ -136,7 +137,7 @@ public class G2DSliderControlImpl extends G2DBaseControlImpl implements SliderCo if (this.enabled) { this.performAction(); } - }, ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager()); + }, (G2DThemeManager) this.rendererData.getThemeManager()); this.control.setName(this.id); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSwitchControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSwitchControlImpl.java index 05b98cd..81beefc 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSwitchControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DSwitchControlImpl.java @@ -1,13 +1,13 @@ package de.extio.game_engine.renderer.g2d.control.impl; -import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.control.components.CustomSwitch; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; public class G2DSwitchControlImpl extends G2DAbstractToggleButtonControlImpl { @Override protected void createControl() { - this.control = new CustomSwitch(true, event -> this.performAction(), ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager()); + this.control = new CustomSwitch(true, event -> this.performAction(), (G2DThemeManager) this.rendererData.getThemeManager()); this.control.setName(this.id); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTableControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTableControlImpl.java index c58de4b..34155f6 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTableControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTableControlImpl.java @@ -167,9 +167,9 @@ public class G2DTableControlImpl extends G2DBaseControlImpl implements TableCont this.control.setFont(G2DDrawFont.getFont(this.scaleFactor, this.fontSize)); this.control.setRowHeight((int) (this.control.getFont().getSize2D() * 1.25)); - final G2DThemeManager themeManager = ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager(); + final G2DThemeManager themeManager = (G2DThemeManager) this.rendererData.getThemeManager(); this.control.setBackground(themeManager.getCurrentTheme().getBackgroundNormal().toColor()); - this.control.setForeground(Color.WHITE); + this.control.setForeground(themeManager.getCurrentTheme().getTextNormal().toColor()); if (this.dataModified || this.scrollPositionModified) { // LOGGER.debug("Table data modified " + this.id); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl.java index 4edc642..f718420 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl.java @@ -11,6 +11,7 @@ import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawFont; import de.extio.game_engine.renderer.g2d.control.components.CustomTextArea; import de.extio.game_engine.renderer.g2d.control.components.CustomTextField; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.BaseControl; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.TextfieldControl; import de.extio.game_engine.renderer.model.color.RgbaColor; @@ -119,10 +120,11 @@ public class G2DTextfieldControlImpl extends G2DBaseControlImpl implements Textf } private void initTextField() { - final ThemeManager themeManager = ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager(); + final ThemeManager themeManager = (G2DThemeManager) this.rendererData.getThemeManager(); final Color bgColor = themeManager.getCurrentTheme().getBackgroundNormal().toColor(); + final Color fgColor = themeManager.getCurrentTheme().getTextNormal().toColor(); this.safeInvoke(() -> this.textComponent.setBackground(bgColor)); - this.safeInvoke(() -> this.textComponent.setForeground(Color.WHITE)); + this.safeInvoke(() -> this.textComponent.setForeground(fgColor)); this.safeInvoke(() -> this.textComponent.setLocation(this.x, this.y)); this.safeInvoke(() -> this.textComponent.setSize(this.width, this.height)); this.safeInvoke(() -> this.textComponent.setFont(G2DDrawFont.getFont(this.scaleFactor, this.fontSize))); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl2.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl2.java index 93bee45..58cffb2 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl2.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DTextfieldControlImpl2.java @@ -14,6 +14,7 @@ import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawFont; import de.extio.game_engine.renderer.g2d.control.components.CustomJTextArea; import de.extio.game_engine.renderer.g2d.control.components.CustomJTextField; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.BaseControl; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.TextfieldControl; import de.extio.game_engine.renderer.model.color.RgbaColor; @@ -227,15 +228,16 @@ public class G2DTextfieldControlImpl2 extends G2DBaseControlImpl implements Text } private void initControl() { - final ThemeManager themeManager = ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager(); + final ThemeManager themeManager = (G2DThemeManager) this.rendererData.getThemeManager(); final Color bgColor; if (this.backgroundColor != null) { bgColor = this.backgroundColor.toAwtColor(); } else { bgColor = themeManager.getCurrentTheme().getBackgroundNormal().toColor(); } + final var fgColor = themeManager.getCurrentTheme().getTextNormal().toColor(); this.safeInvoke(() -> this.textComponent.setBackground(bgColor)); - this.safeInvoke(() -> this.textComponent.setForeground(Color.WHITE)); + this.safeInvoke(() -> this.textComponent.setForeground(fgColor)); this.safeInvoke(() -> this.textComponent.setFont(G2DDrawFont.getFont(this.scaleFactor, this.fontSize))); if (this.multiLine) { // this.safeInvoke(() -> this.scrollPane.setLocation(this.x, this.y)); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DToggleButtonControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DToggleButtonControlImpl.java index 24a3d68..b162495 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DToggleButtonControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DToggleButtonControlImpl.java @@ -2,12 +2,13 @@ package de.extio.game_engine.renderer.g2d.control.impl; import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.control.components.CustomButton; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; public class G2DToggleButtonControlImpl extends G2DAbstractToggleButtonControlImpl { @Override protected void createControl() { - this.control = new CustomButton(true, event -> this.performAction(), ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager()); + this.control = new CustomButton(true, event -> this.performAction(), (G2DThemeManager) this.rendererData.getThemeManager()); this.control.setName(this.id); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowCloseButtonControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowCloseButtonControlImpl.java index 930edbb..2e97f3e 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowCloseButtonControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowCloseButtonControlImpl.java @@ -2,6 +2,7 @@ package de.extio.game_engine.renderer.g2d.control.impl; import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.control.components.CustomWindowCloseButton; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.WindowCloseButtonControl; public class G2DWindowCloseButtonControlImpl extends G2DButtonControlImpl implements WindowCloseButtonControl { @@ -12,7 +13,7 @@ public class G2DWindowCloseButtonControlImpl extends G2DButtonControlImpl implem @Override protected void createControl() { - this.control = new CustomWindowCloseButton(false, event -> this.performAction(), ((G2DRenderer) this.rendererData.getRenderer()).getThemeManager()); + this.control = new CustomWindowCloseButton(false, event -> this.performAction(), (G2DThemeManager) this.rendererData.getThemeManager()); this.control.setName(this.id); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowPanelControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowPanelControlImpl.java index cde1f34..0f4921f 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowPanelControlImpl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DWindowPanelControlImpl.java @@ -2,6 +2,7 @@ package de.extio.game_engine.renderer.g2d.control.impl; import de.extio.game_engine.renderer.g2d.G2DRenderer; import de.extio.game_engine.renderer.g2d.control.components.CustomWindowPanel; +import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager; import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.WindowPanelControl; import de.extio.game_engine.renderer.model.color.RgbaColor; @@ -77,7 +78,7 @@ public class G2DWindowPanelControlImpl extends G2DBaseControlImpl implements Win } protected void createControl() { - this.control = new CustomWindowPanel(((G2DRenderer) this.rendererData.getRenderer()).getThemeManager()); + this.control = new CustomWindowPanel((G2DThemeManager) this.rendererData.getThemeManager()); this.control.setName(this.id); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelDarkThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelDarkThemeFactoryBean.java new file mode 100644 index 0000000..63ee53f --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelDarkThemeFactoryBean.java @@ -0,0 +1,46 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import org.springframework.beans.factory.FactoryBean; + +public class BevelDarkThemeFactoryBean implements FactoryBean { + + @Override + public Theme getObject() { + return Theme.builder() + .name("Bevel Dark") + .patternRendererName("bevelPatternRenderer") + // Highlight (Light Grey) + .borderOuter(new HSBColor(0.0f, 0.0f, 0.6f)) + // Shadow (Black) + .borderInner(new HSBColor(0.0f, 0.0f, 0.0f)) + // Disabled Shadow + .borderInnerDisabled(new HSBColor(0.0f, 0.0f, 0.3f)) + // Background (Dark Grey) + .backgroundNormal(new HSBColor(0.0f, 0.0f, 0.25f)) + // Selected Background (Dark Blue) + .backgroundSelected(new HSBColor(0.6f, 0.8f, 0.4f)) + // Text (White) + .textNormal(new HSBColor(0.0f, 0.0f, 0.9f)) + // Text Disabled (Grey) + .textDisabled(new HSBColor(0.0f, 0.0f, 0.5f)) + // Selection Primary (Dark Blue) + .selectionPrimary(new HSBColor(0.6f, 0.2f, 0.4f)) + // Selection Secondary (Darker Blue) + .selectionSecondary(new HSBColor(0.6f, 0.1f, 0.3f)) + // Window Background (Dark Grey) + .windowBackground(new HSBColor(0.0f, 0.0f, 0.25f)) + .hoverBrightnessAdjustment(0.1f) + .pressedBrightnessAdjustment(0.2f) + .build(); + } + + @Override + public Class getObjectType() { + return Theme.class; + } + + @Override + public boolean isSingleton() { + return true; + } +} diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelLightThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelLightThemeFactoryBean.java new file mode 100644 index 0000000..74247f2 --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelLightThemeFactoryBean.java @@ -0,0 +1,46 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import org.springframework.beans.factory.FactoryBean; + +public class BevelLightThemeFactoryBean implements FactoryBean { + + @Override + public Theme getObject() { + return Theme.builder() + .name("Bevel Light") + .patternRendererName("bevelPatternRenderer") + // Highlight (White) + .borderOuter(new HSBColor(0.0f, 0.0f, 1.0f)) + // Shadow (Dark Grey) + .borderInner(new HSBColor(0.0f, 0.0f, 0.4f)) + // Disabled Shadow + .borderInnerDisabled(new HSBColor(0.0f, 0.0f, 0.6f)) + // Background (Light Grey) + .backgroundNormal(new HSBColor(0.0f, 0.0f, 0.85f)) + // Selected Background (Blueish) + .backgroundSelected(new HSBColor(0.6f, 0.5f, 0.9f)) + // Text (Black) + .textNormal(new HSBColor(0.0f, 0.0f, 0.05f)) + // Text Disabled (Grey) + .textDisabled(new HSBColor(0.0f, 0.0f, 0.5f)) + // Selection Primary (Blue) + .selectionPrimary(new HSBColor(0.6f, 0.1f, 0.3f)) + // Selection Secondary (Lighter Blue) + .selectionSecondary(new HSBColor(0.6f, 0.15f, 0.4f)) + // Window Background (Light Grey) + .windowBackground(new HSBColor(0.0f, 0.0f, 0.85f)) + .hoverBrightnessAdjustment(0.1f) + .pressedBrightnessAdjustment(0.2f) + .build(); + } + + @Override + public Class getObjectType() { + return Theme.class; + } + + @Override + public boolean isSingleton() { + return true; + } +} diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelPatternRenderer.java new file mode 100644 index 0000000..ca98c64 --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BevelPatternRenderer.java @@ -0,0 +1,121 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import java.awt.Color; +import java.awt.Graphics2D; + +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import de.extio.game_engine.renderer.g2d.G2DRendererCondition; + +/** + * Implementation of PatternRenderer that draws borders and panels in a classic "Bevel" style. + */ +@Conditional(G2DRendererCondition.class) +@Component +public class BevelPatternRenderer implements PatternRenderer { + + @Override + public void drawDecorativeBorder(final Graphics2D g2d, final int x, final int y, final int width, final int height, final int strength, final Color color) { + // Use the provided color as the base. + // For a simple border, we can try to make a bevel out of it. + // Let's assume 'color' is the shadow, and we need a highlight. + + final var hsb = new float[3]; + Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), hsb); + Color light, dark; + if (hsb[2] < 0.5f) { + light = color.brighter(); + dark = color; + } else { + light = color; + dark = color.darker(); + } + + // Outer bevel (raised) + drawBevel(g2d, x, y, width, height, strength, true, light, dark); + } + + @Override + public void drawDecorativeBorderFilled(final Graphics2D g2d, final int x, final int y, final int width, final int height, final int strength, final Color borderColor, final Color backgroundColor) { + // Fill background + g2d.setColor(backgroundColor); + g2d.fillRect(x + strength, y + strength, width - strength * 2, height - strength * 2); + + // Draw border + this.drawDecorativeBorder(g2d, x, y, width, height, strength, borderColor); + } + + @Override + public void drawWindowPanel(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean thickBorder, final Color innerBorderColor, final Color outerBorderColor, final Color backgroundColor, final double scaleFactor) { + final var strength = Math.max((thickBorder ? 3 : 2), (int) ((thickBorder ? 4 : 2) * scaleFactor)); + + // Main background + g2d.setColor(backgroundColor); + g2d.fillRect(x, y, width, height); + + // Raised window border + // Use outerBorderColor as highlight, innerBorderColor as shadow + drawBevel(g2d, x, y, width, height, strength, true, outerBorderColor, innerBorderColor); + } + + @Override + public void drawCloseButton(final Graphics2D g2d, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final var STATE_PRESSED = 2; + final var pressed = (state & STATE_PRESSED) != 0; + + // Button background + final Color btnBg = backgroundColor != null ? backgroundColor : theme.getBackgroundNormal().toColor(); + g2d.setColor(btnBg); + g2d.fillRect(0, 0, width, height); + + // Button bevel + int bevelStrength = (int) (2 * scaleFactor); + if (bevelStrength < 1) bevelStrength = 1; + + final Color highlight = theme.getBorderOuter().toColor(); + final Color shadow = theme.getBorderInner().toColor(); + + if (pressed) { + drawBevel(g2d, 0, 0, width, height, bevelStrength, false, highlight, shadow); + } else { + drawBevel(g2d, 0, 0, width, height, bevelStrength, true, highlight, shadow); + } + + // X icon + if (enabled) { + g2d.setColor(theme.getTextNormal().toColor()); + final int offset = pressed ? 1 : 0; + + // Draw a simple X + final int padding = (int)(4 * scaleFactor); + final int x1 = padding + offset; + final int y1 = padding + offset; + final int x2 = width - padding + offset; + final int y2 = height - padding + offset; + + final Graphics2D g2 = (Graphics2D) g2d.create(); + g2.setStroke(new java.awt.BasicStroke((float)(2 * scaleFactor))); + g2.drawLine(x1, y1, x2, y2); + g2.drawLine(x1, y2, x2, y1); + g2.dispose(); + } + } + + private void drawBevel(final Graphics2D g2d, final int x, final int y, final int width, final int height, final int strength, final boolean raised, final Color light, final Color dark) { + final Color topLeft = raised ? light : dark; + final Color bottomRight = raised ? dark : light; + + g2d.setColor(topLeft); + for (int i = 0; i < strength; i++) { + g2d.drawLine(x + i, y + i, x + width - 1 - i, y + i); // Top + g2d.drawLine(x + i, y + i, x + i, y + height - 1 - i); // Left + } + + g2d.setColor(bottomRight); + for (int i = 0; i < strength; i++) { + g2d.drawLine(x + i, y + height - 1 - i, x + width - 1 - i, y + height - 1 - i); // Bottom + g2d.drawLine(x + width - 1 - i, y + i, x + width - 1 - i, y + height - 1 - i); // Right + } + } +} diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/ContemporaryThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/ContemporaryThemeFactoryBean.java index fb7c7f1..ad4b877 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/ContemporaryThemeFactoryBean.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/ContemporaryThemeFactoryBean.java @@ -13,10 +13,10 @@ public class ContemporaryThemeFactoryBean implements FactoryBean { .borderInner(new HSBColor(0.88f, 0.10f, 0.92f)) .borderInnerDisabled(new HSBColor(0.88f, 0.06f, 0.42f)) .backgroundNormal(new HSBColor(0.92f, 0.55f, 0.22f)) - .backgroundSelected(new HSBColor(0.33f, 0.75f, 0.70f)) + .backgroundSelected(new HSBColor(0.92f, 0.35f, 0.70f)) .textNormal(new HSBColor(0.08f, 0.04f, 0.94f)) .textDisabled(new HSBColor(0.08f, 0.02f, 0.62f)) - .selectionPrimary(new HSBColor(0.33f, 0.75f, 0.70f)) + .selectionPrimary(new HSBColor(0.92f, 0.35f, 0.70f)) .selectionSecondary(new HSBColor(0.58f, 0.25f, 0.95f)) .windowBackground(new HSBColor(0.92f, 0.55f, 0.12f)) .hoverBrightnessAdjustment(0.22f) diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamThemeFactoryBean.java index 482b008..82cb7ac 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamThemeFactoryBean.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamThemeFactoryBean.java @@ -13,10 +13,10 @@ public class DreamThemeFactoryBean implements FactoryBean { .borderInner(new HSBColor(0.83f, 0.18f, 0.95f)) .borderInnerDisabled(new HSBColor(0.74f, 0.10f, 0.35f)) .backgroundNormal(new HSBColor(0.74f, 0.55f, 0.16f)) - .backgroundSelected(new HSBColor(0.88f, 0.55f, 0.85f)) + .backgroundSelected(new HSBColor(0.78f, 0.35f, 0.65f)) .textNormal(new HSBColor(0.12f, 0.03f, 0.96f)) .textDisabled(new HSBColor(0.12f, 0.02f, 0.70f)) - .selectionPrimary(new HSBColor(0.88f, 0.55f, 0.85f)) + .selectionPrimary(new HSBColor(0.78f, 0.35f, 0.65f)) .selectionSecondary(new HSBColor(0.55f, 0.30f, 0.95f)) .windowBackground(new HSBColor(0.74f, 0.70f, 0.07f)) .hoverBrightnessAdjustment(0.28f) diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyPatternRenderer.java index 6a8dfcf..01489e7 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyPatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyPatternRenderer.java @@ -47,7 +47,8 @@ public class FantasyPatternRenderer implements PatternRenderer { @Override public void drawWindowPanel(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean thickBorder, final Color innerBorderColor, final Color outerBorderColor, final Color backgroundColor, final double scaleFactor) { - final var s = Math.max((thickBorder ? 5 : 3), (int) ((thickBorder ? 7 : 4) * scaleFactor)); + // final var s = Math.max((thickBorder ? 3 : 2), (int) ((thickBorder ? 5 : 3) * scaleFactor)); + final var s = Math.max(2, (int) (3 * scaleFactor)); final var s2 = s * 2; final var bg = new Color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), 175); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyThemeFactoryBean.java index 6f5ef2c..da88c8d 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyThemeFactoryBean.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/FantasyThemeFactoryBean.java @@ -9,16 +9,16 @@ public class FantasyThemeFactoryBean implements FactoryBean { return Theme.builder() .name("Fantasy") .patternRendererName("fantasyPatternRenderer") - .borderOuter(new HSBColor(0.12f, 0.55f, 0.65f)) - .borderInner(new HSBColor(0.14f, 0.35f, 0.92f)) + .borderOuter(new HSBColor(0.12f, 0.55f, 0.48f)) + .borderInner(new HSBColor(0.14f, 0.25f, 0.72f)) .borderInnerDisabled(new HSBColor(0.12f, 0.25f, 0.25f)) - .backgroundNormal(new HSBColor(0.32f, 0.70f, 0.12f)) - .backgroundSelected(new HSBColor(0.13f, 0.80f, 0.75f)) + .backgroundNormal(new HSBColor(0.32f, 0.60f, 0.22f)) + .backgroundSelected(new HSBColor(0.13f, 0.65f, 0.68f)) .textNormal(new HSBColor(0.12f, 0.10f, 0.96f)) .textDisabled(new HSBColor(0.12f, 0.05f, 0.65f)) - .selectionPrimary(new HSBColor(0.13f, 0.80f, 0.75f)) - .selectionSecondary(new HSBColor(0.58f, 0.40f, 0.90f)) - .windowBackground(new HSBColor(0.32f, 0.75f, 0.06f)) + .selectionPrimary(new HSBColor(0.13f, 0.65f, 0.70f)) + .selectionSecondary(new HSBColor(0.58f, 0.35f, 0.88f)) + .windowBackground(new HSBColor(0.32f, 0.70f, 0.08f)) .hoverBrightnessAdjustment(0.18f) .pressedBrightnessAdjustment(0.34f) .build(); diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/MetroPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/MetroPatternRenderer.java new file mode 100644 index 0000000..0aee664 --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/MetroPatternRenderer.java @@ -0,0 +1,112 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import java.awt.Color; +import java.awt.Graphics2D; + +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import de.extio.game_engine.renderer.g2d.G2DRendererCondition; + +@Conditional(G2DRendererCondition.class) +@Component +public class MetroPatternRenderer implements PatternRenderer { + + @Override + public void drawDecorativeBorder(final Graphics2D g2d, final int x, final int y, final int width, final int height, final int strength, final Color color) { + drawDecorativeBordersMain(g2d, x, y, width, height, strength, true, color); + } + + private void drawDecorativeBordersMain(final Graphics2D g2d, final int x, final int y, final int width, final int height, final int strength, final boolean drawJunction, final Color color) { + final var s = Math.max(1, strength); + final var junction = Math.max(1, s / 2); + final var station = Math.max(5, s * 3); + + g2d.setColor(color); + + g2d.fillRect(x, y, width, s); + g2d.fillRect(x, y + height - s, width, s); + g2d.fillRect(x, y, s, height); + g2d.fillRect(x + width - s, y, s, height); + + final var inset = s * 2; + final var x1 = x + inset; + final var y1 = y + inset; + final var x2 = x + width - inset; + final var y2 = y + height - inset; + + if (drawJunction && x2 > x1 && y2 > y1) { + g2d.fillRect(x1, y1, Math.max(0, x2 - x1), junction); + g2d.fillRect(x1, y2 - junction, Math.max(0, x2 - x1), junction); + g2d.fillRect(x1, y1, junction, Math.max(0, y2 - y1)); + g2d.fillRect(x2 - junction, y1, junction, Math.max(0, y2 - y1)); + } + + if (drawJunction) { + g2d.fillOval(x + s, y + s, station, station); + g2d.fillOval(x + width - s - station, y + s, station, station); + g2d.fillOval(x + s, y + height - s - station, station, station); + g2d.fillOval(x + width - s - station, y + height - s - station, station, station); + } + } + + @Override + public void drawDecorativeBorderFilled(final Graphics2D g2d, final int x, final int y, final int width, final int height, final int strength, final Color borderColor, final Color backgroundColor) { + final var s = Math.max(1, strength); + g2d.setColor(backgroundColor); + g2d.fillRect(x + s, y + s, Math.max(0, width - s * 2), Math.max(0, height - s * 2)); + this.drawDecorativeBorder(g2d, x, y, width, height, s, borderColor); + } + + @Override + public void drawWindowPanel(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean thickBorder, final Color innerBorderColor, final Color outerBorderColor, final Color backgroundColor, final double scaleFactor) { + final var s = Math.max((thickBorder ? 4 : 2), (int) ((thickBorder ? 6 : 3) * scaleFactor)); + final var s2 = s * 2; + + final var bg = new Color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), 175); + + this.drawDecorativeBorderFilled(g2d, x, y, width, height, s, innerBorderColor, bg); + this.drawDecorativeBordersMain(g2d, x + s, y + s, width - s2, height - s2, s, false, outerBorderColor); + } + + @Override + public void drawCloseButton(final Graphics2D g2d, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final var STATE_HOVERED = 4; + final var STATE_TOGGLED = 1; + final var STATE_PRESSED = 2; + + final var highlight = (state & (STATE_HOVERED | STATE_TOGGLED)) != 0; + final var pressed = (state & STATE_PRESSED) != 0; + + Color bg = backgroundColor; + if (bg == null) { + bg = theme.getBorderInner().toColor(); + } + if (highlight) { + bg = theme.getSelectionSecondary().toColor(); + } + if (pressed) { + bg = theme.getSelectionPrimary().toColor(); + } + + g2d.setColor(bg); + g2d.fillRect(0, 0, width, height); + + final var s = Math.max(1, (int) (2 * scaleFactor)); + this.drawDecorativeBordersMain(g2d, 0, 0, width, height, s, false, theme.getBorderOuter().toColor()); + + if (!enabled) { + return; + } + + final var t = Math.max(1, (int) (2 * scaleFactor)); + final var crossSize = Math.min(width, height) / 2; + final var centerX = width / 2; + final var centerY = height / 2; + + final Color fg = pressed || highlight ? Color.BLACK : theme.getTextNormal().toColor(); + g2d.setColor(fg); + g2d.fillRect(centerX - crossSize / 2, centerY - t / 2, crossSize, t); + g2d.fillRect(centerX - t / 2, centerY - crossSize / 2, t, crossSize); + } +} diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernThemeFactoryBean.java index 2211bd2..a4833c1 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernThemeFactoryBean.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernThemeFactoryBean.java @@ -13,10 +13,10 @@ public class ModernThemeFactoryBean implements FactoryBean { .borderInner(new HSBColor(0.58f, 0.10f, 0.92f)) .borderInnerDisabled(new HSBColor(0.58f, 0.05f, 0.45f)) .backgroundNormal(new HSBColor(0.60f, 0.55f, 0.20f)) - .backgroundSelected(new HSBColor(0.14f, 0.75f, 0.78f)) + .backgroundSelected(new HSBColor(0.14f, 0.20f, 0.78f)) .textNormal(new HSBColor(0.00f, 0.00f, 0.92f)) .textDisabled(new HSBColor(0.00f, 0.00f, 0.65f)) - .selectionPrimary(new HSBColor(0.14f, 0.75f, 0.78f)) + .selectionPrimary(new HSBColor(0.14f, 0.20f, 0.78f)) .selectionSecondary(new HSBColor(0.50f, 0.20f, 0.98f)) .windowBackground(new HSBColor(0.60f, 0.45f, 0.10f)) .hoverBrightnessAdjustment(0.20f) diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanThemeFactoryBean.java index d918d7d..ef23efb 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanThemeFactoryBean.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanThemeFactoryBean.java @@ -8,17 +8,17 @@ public class UrbanThemeFactoryBean implements FactoryBean { public Theme getObject() { return Theme.builder() .name("Urban") - .patternRendererName("urbanPatternRenderer") - .borderOuter(new HSBColor(0.06f, 0.05f, 0.35f)) - .borderInner(new HSBColor(0.06f, 0.08f, 0.70f)) - .borderInnerDisabled(new HSBColor(0.06f, 0.04f, 0.22f)) - .backgroundNormal(new HSBColor(0.58f, 0.25f, 0.18f)) - .backgroundSelected(new HSBColor(0.02f, 0.75f, 0.70f)) - .textNormal(new HSBColor(0.12f, 0.05f, 0.92f)) - .textDisabled(new HSBColor(0.12f, 0.02f, 0.60f)) - .selectionPrimary(new HSBColor(0.02f, 0.75f, 0.70f)) - .selectionSecondary(new HSBColor(0.52f, 0.18f, 0.92f)) - .windowBackground(new HSBColor(0.58f, 0.30f, 0.10f)) + .patternRendererName("metroPatternRenderer") + .borderOuter(new HSBColor(0.58f, 0.08f, 0.30f)) + .borderInner(new HSBColor(0.58f, 0.06f, 0.72f)) + .borderInnerDisabled(new HSBColor(0.58f, 0.04f, 0.22f)) + .backgroundNormal(new HSBColor(0.58f, 0.22f, 0.16f)) + .backgroundSelected(new HSBColor(0.03f, 0.80f, 0.78f)) + .textNormal(new HSBColor(0.00f, 0.00f, 0.94f)) + .textDisabled(new HSBColor(0.00f, 0.00f, 0.62f)) + .selectionPrimary(new HSBColor(0.03f, 0.80f, 0.78f)) + .selectionSecondary(new HSBColor(0.48f, 0.65f, 0.88f)) + .windowBackground(new HSBColor(0.58f, 0.28f, 0.09f)) .hoverBrightnessAdjustment(0.18f) .pressedBrightnessAdjustment(0.32f) .build(); 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 b48500d..e80ca4c 100644 --- a/src/test/java/de/extio/game_engine/demo/DemoModule.java +++ b/src/test/java/de/extio/game_engine/demo/DemoModule.java @@ -87,8 +87,8 @@ public class DemoModule extends AbstractClientModule { @Override public void onActivate() { final var audioOptions = this.audioController.getAudioOptions(); - audioOptions.getMusicOptions().setVolume(0.0f); - audioOptions.getSfxOptions().setVolume(0.0f); + audioOptions.getMusicOptions().setVolume(0.8f); + audioOptions.getSfxOptions().setVolume(1.0f); this.audioController.applyAudioOptions(audioOptions); this.setupMainWindow(); @@ -120,30 +120,30 @@ public class DemoModule extends AbstractClientModule { private void onUiControlEvent(final UiControlEvent event) { switch (event.getId()) { case "DemoModule_MainWindow_Label_Welcome" -> { - this.audioController.play(new StaticResource(List.of("audio"), "alert0.ogg")); + this.audioController.play(new StaticResource(List.of("audio"), "contact0.ogg")); this.setupSecondaryWindow(); this.getModuleService().changeActiveState(this.secondaryWindow.getId(), true); this.getModuleService().changeDisplayState(this.secondaryWindow.getId(), true); } case "DemoModule_MainWindow_Label_Start" -> { - this.audioController.play(new StaticResource(List.of("audio"), "alert0.ogg")); + this.audioController.play(new StaticResource(List.of("audio"), "contact0.ogg")); this.setupThemeSelectionWindow(); this.getModuleService().changeActiveState(this.themeSelectionWindow.getId(), true); this.getModuleService().changeDisplayState(this.themeSelectionWindow.getId(), true); } case "DemoModule_SecondaryWindow_Button_Ok" -> { - this.audioController.play(new StaticResource(List.of("audio"), "alert2.ogg")); + this.audioController.play(new StaticResource(List.of("audio"), "alert0.ogg")); this.getModuleService().changeActiveState(this.secondaryWindow.getId(), false); } default -> { final var themeName = this.themeSelectionByControlId.get(event.getId()); if (themeName != null) { - this.audioController.play(new StaticResource(List.of("audio"), "alert2.ogg")); + this.audioController.play(new StaticResource(List.of("audio"), "alert0.ogg")); this.themeManager.setCurrentTheme(themeName); - this.getModuleService().changeActiveState(this.themeSelectionWindow.getId(), false); + // this.getModuleService().changeActiveState(this.themeSelectionWindow.getId(), false); } } }