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.
This commit is contained in:
extio-de
2025-12-28 11:47:21 +01:00
parent e87edd27a2
commit 120dd91161
31 changed files with 422 additions and 60 deletions

BIN
data/audio/contact0.ogg Normal file

Binary file not shown.

View File

@@ -59,9 +59,10 @@ public class RendererAutoConfiguration {
final RendererWorkingSet rendererWorkingSet,
final ModuleService moduleManager,
final ModuleExecutor moduleExecutor,
final StaticResourceService staticResourceService) {
final StaticResourceService staticResourceService,
final ThemeManager themeManager) {
final var rendererData = new RendererData(applicationContext, renderer, rendererControl, renderingBoPool, keycodeRegistry, eventService, storageService, rendererWorkingSet, moduleManager, moduleExecutor, staticResourceService);
final var rendererData = new RendererData(applicationContext, renderer, rendererControl, renderingBoPool, keycodeRegistry, eventService, storageService, rendererWorkingSet, moduleManager, moduleExecutor, staticResourceService, themeManager);
renderer.setRendererData(rendererData);
rendererControl.setRendererData(rendererData);
renderingBoPool.setRendererData(rendererData);

View File

@@ -45,9 +45,11 @@ public class RendererData {
private final StaticResourceService staticResourceService;
private final ThemeManager themeManager;
private RendererLoop rendererLoop;
public RendererData(final ApplicationContext applicationContext, final Renderer renderer, final RendererControl rendererControl, final RenderingBoPool renderingBoPool, final KeycodeRegistry keycodeRegistry, final EventService eventService, final StorageService storageService, final RendererWorkingSet rendererWorkingSet, final ModuleService moduleService, final ModuleExecutor moduleExecutor, final StaticResourceService staticResourceService) {
public RendererData(final ApplicationContext applicationContext, final Renderer renderer, final RendererControl rendererControl, final RenderingBoPool renderingBoPool, final KeycodeRegistry keycodeRegistry, final EventService eventService, final StorageService storageService, final RendererWorkingSet rendererWorkingSet, final ModuleService moduleService, final ModuleExecutor moduleExecutor, final StaticResourceService staticResourceService, final ThemeManager themeManager) {
this.applicationContext = applicationContext;
this.renderer = renderer;
this.rendererControl = rendererControl;
@@ -59,6 +61,7 @@ public class RendererData {
this.moduleService = moduleService;
this.moduleExecutor = moduleExecutor;
this.staticResourceService = staticResourceService;
this.themeManager = themeManager;
}
public ApplicationContext getApplicationContext() {
@@ -128,4 +131,9 @@ public class RendererData {
public StaticResourceService getStaticResourceService() {
return staticResourceService;
}
public ThemeManager getThemeManager() {
return themeManager;
}
}

View File

@@ -12,6 +12,8 @@ import org.springframework.context.annotation.Bean;
import de.extio.game_engine.renderer.g2d.theme.G2DThemeManager;
import de.extio.game_engine.renderer.g2d.theme.PatternRenderer;
import de.extio.game_engine.renderer.g2d.theme.BevelDarkThemeFactoryBean;
import de.extio.game_engine.renderer.g2d.theme.BevelLightThemeFactoryBean;
import de.extio.game_engine.renderer.g2d.theme.ContemporaryThemeFactoryBean;
import de.extio.game_engine.renderer.g2d.theme.DreamThemeFactoryBean;
import de.extio.game_engine.renderer.g2d.theme.FantasyThemeFactoryBean;
@@ -92,6 +94,16 @@ public class G2DAutoConfiguration {
return new NeonThemeFactoryBean();
}
@Bean
FactoryBean<Theme> bevelLightTheme() {
return new BevelLightThemeFactoryBean();
}
@Bean
FactoryBean<Theme> bevelDarkTheme() {
return new BevelDarkThemeFactoryBean();
}
@Bean
G2DThemeManager g2dThemeManager(
final StaticResourceService staticResourceService,

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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());

View File

@@ -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));

View File

@@ -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());

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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)));

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,46 @@
package de.extio.game_engine.renderer.g2d.theme;
import org.springframework.beans.factory.FactoryBean;
public class BevelDarkThemeFactoryBean implements FactoryBean<Theme> {
@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;
}
}

View File

@@ -0,0 +1,46 @@
package de.extio.game_engine.renderer.g2d.theme;
import org.springframework.beans.factory.FactoryBean;
public class BevelLightThemeFactoryBean implements FactoryBean<Theme> {
@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;
}
}

View File

@@ -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
}
}
}

View File

@@ -13,10 +13,10 @@ public class ContemporaryThemeFactoryBean implements FactoryBean<Theme> {
.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)

View File

@@ -13,10 +13,10 @@ public class DreamThemeFactoryBean implements FactoryBean<Theme> {
.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)

View File

@@ -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);

View File

@@ -9,16 +9,16 @@ public class FantasyThemeFactoryBean implements FactoryBean<Theme> {
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();

View File

@@ -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);
}
}

View File

@@ -13,10 +13,10 @@ public class ModernThemeFactoryBean implements FactoryBean<Theme> {
.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)

View File

@@ -8,17 +8,17 @@ public class UrbanThemeFactoryBean implements FactoryBean<Theme> {
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();

View File

@@ -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);
}
}
}